unit MDNS;

interface

uses
	Winapi.Windows,
	DNS;

const
	DNS_MAX_NAME_BUFFER_LENGTH = 256;

type
	TMDNSQueryRequestA = packed record
		Version: LongWord;
		ulRefCount: LongWord;
		Query: PAnsiChar;
		QueryType: Word;
		QueryOptions: UInt64;
		InterfaceIndex: LongWord;
		pQueryCallback: Pointer;
		pQueryContext: Pointer;
		fAnswerReceived: BOOL;
		ulResendCount: LongWord;
	end;
	TPMDNSQueryRequestA = ^TMDNSQueryRequestA;

	TMDNSQueryRequestW = packed record
		Version: LongWord;
		ulRefCount: LongWord;
		Query: PWideChar;
		QueryType: Word;
		QueryOptions: UInt64;
		InterfaceIndex: LongWord;
		pQueryCallback: Pointer;
		pQueryContext: Pointer;
		fAnswerReceived: BOOL;
		ulResendCount: LongWord;
	end;
	TPMDNSQueryRequestW = ^TMDNSQueryRequestW;

	TMDNSQueryRequest = TMDNSQueryRequestW;
	TPMDNSQueryRequest = TPMDNSQueryRequestW;



type
	TMDNSQueryHandleA = packed record
		nameBuf: array[0..DNS_MAX_NAME_BUFFER_LENGTH-1] of AnsiChar;
		wType: Word;
		pSubscription: Pointer;
		pWnfCallbackParams: Pointer;
		stateNameData: array[0..1] of LongWord;
	end;
	TPMDNSQueryHandleA = ^TMDNSQueryHandleA;

	TMDNSQueryHandleW = packed record
		nameBuf: array[0..DNS_MAX_NAME_BUFFER_LENGTH-1] of WideChar;
		wType: Word;
		pSubscription: Pointer;
		pWnfCallbackParams: Pointer;
		stateNameData: array[0..1] of LongWord;
	end;
	TPMDNSQueryHandleW = ^TMDNSQueryHandleW;

	TMDNSQueryHandle = TMDNSQueryHandleW;
	TPMDNSQueryHandle = TPMDNSQueryHandleW;



	TPMDNSQueryCallback = procedure (pQueryContext: Pointer; pQueryHandle: TPMDNSQueryHandle; pQueryResults: TPDNSQueryResult); stdcall;



type
	TDNSStartMulticastQuery = function (pQueryRequest: TPMDNSQueryRequest; pHandle: TPMDNSQueryHandle): LongWord; stdcall;
	TDNSStopMulticastQuery  = function (pHandle: TPMDNSQueryHandle): LongWord; stdcall;

var
	bMDNSLoaded: Boolean = False;
	DNSStartMulticastQuery: TDNSStartMulticastQuery;
	DNSStopMulticastQuery : TDNSStopMulticastQuery ;

procedure LoadMDNS;
procedure UnloadMDNS;

implementation

var
	hDNSAPIDLL: THandle = INVALID_HANDLE_VALUE;

procedure LoadMDNS;
var
	bLoadedOK: Boolean;

	function TryLoad(ByName: AnsiString): Pointer;
	begin
		Result := GetProcAddress(hDNSAPIDLL, @ByName[1]);
		if Result = nil then
			bLoadedOK := False
		;
	end;

begin
	bMDNSLoaded := False;
	if hDNSAPIDLL = INVALID_HANDLE_VALUE then begin
		hDNSAPIDLL := LoadLibrary('DNSAPI.dll');
		if hDNSAPIDLL = INVALID_HANDLE_VALUE then Exit;
	end;

	bLoadedOK := True;
	DNSStartMulticastQuery := TryLoad('DnsStartMulticastQuery');
	DNSStopMulticastQuery  := TryLoad('DnsStopMulticastQuery');

	if not bLoadedOK then UnloadMDNS;
	bMDNSLoaded := bLoadedOK;
end;

procedure UnloadMDNS;
begin
	bMDNSLoaded := False;

	DNSStartMulticastQuery := nil;
	DNSStopMulticastQuery  := nil;

	FreeLibrary(hDNSAPIDLL);
	hDNSAPIDLL := INVALID_HANDLE_VALUE;
end;

end.