unit DNSSD;

interface

uses
	Winapi.Windows,
	DNS;

type
	TDNSServiceBrowseRequest = packed record
		Version: LongWord;
		InterfaceIndex: LongWord;
		QueryName: PWideChar;
		pBrowseCallback: Pointer;
		pQueryContext: Pointer;
	end;
	TPDNSServiceBrowseRequest = ^TDNSServiceBrowseRequest;

	//v1
	TDNSServiceBrowseCallback = procedure (Status: LongWord; pQueryContext: Pointer; pDNSRecord: TPDNSRecord); stdcall;
	//v2
	TDNSQueryCompletionRoutine = procedure (pQueryContext: Pointer; pQueryResults: TPDNSQueryResult); stdcall;

	TDNSServiceCancel = packed record
		Reserved: Pointer;
	end;
	TPDNSServiceCancel = ^TDNSServiceCancel;

type
	TDNSServiceBrowse = function (pRequest: TPDNSServiceBrowseRequest; pCancel: TPDNSServiceCancel): LongWord; stdcall;
	TDNSServiceBrowseCancel = function (pCancel: TPDNSServiceCancel): LongWord; stdcall;

var
	bDNSSDLoaded: Boolean = False;
	DNSServiceBrowse: TDNSServiceBrowse;
	DNSServiceBrowseCancel: TDNSServiceBrowseCancel;

procedure LoadDNSSD;
procedure UnloadDNSSD;

implementation

var
	hDNSAPIDLL: THandle = INVALID_HANDLE_VALUE;

procedure LoadDNSSD;
var
	bLoadedOK: Boolean;

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

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

	bLoadedOK := True;
	DNSServiceBrowse       := TryLoad('DnsServiceBrowse');
	DNSServiceBrowseCancel := TryLoad('DnsServiceBrowseCancel');

	if bLoadedOK then
		bDNSSDLoaded := True
	else
		UnloadDNSSD
	;
end;

procedure UnloadDNSSD;
begin
	bDNSSDLoaded := False;

	DNSServiceBrowse       := nil;
	DNSServiceBrowseCancel := nil;

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

end.
