private static void QueryCompletionRoutine(IntPtr queryContext, IntPtr queryResults) { QueryCompletionContext context = (QueryCompletionContext)Marshal.PtrToStructure(queryContext, typeof(QueryCompletionContext)); DNSQueryResult queryResult = (DNSQueryResult)Marshal.PtrToStructure(queryResults, typeof(DNSQueryResult)); Marshal.WriteInt32(context.resultCode, queryResult.QueryStatus); if (queryResult.QueryStatus != 0) { if (queryResult.QueryRecords != IntPtr.Zero) { DnsRecordListFree(queryResult.QueryRecords, DNS_FREE_TYPE.DnsFreeRecordList); } context.eventHandle.Set(); return; } List <IDictionary <string, object> > records = GCHandle.FromIntPtr(context.dnsRecords).Target as List <IDictionary <string, object> >; records.AddRange(ParseRecords(queryResult.QueryRecords, context.requestType)); if (queryResult.QueryRecords != IntPtr.Zero) { DnsRecordListFree(queryResult.QueryRecords, DNS_FREE_TYPE.DnsFreeRecordList); } context.eventHandle.Set(); }
public static IDictionary <string, object>[] QueryDNSForRecordTypeSpecificNameServers(string domainName, IPEndPoint[] dnsServers, DnsRecordTypes recordType) { if (dnsServers == null || dnsServers.Length == 0) { throw new Exception("At least one DNS Server must be provided to do the query"); } IntPtr dnsRequest, addrRequestBuffer, contextBuffer; QueryCompletionContext context = new QueryCompletionContext(); context.eventHandle = new EventWaitHandle(false, EventResetMode.ManualReset); context.requestType = recordType; context.resultCode = Marshal.AllocHGlobal(Marshal.SizeOf <int>()); List <IDictionary <string, object> > dnsRecords = new List <IDictionary <string, object> >(); GCHandle handle = GCHandle.Alloc(dnsRecords, GCHandleType.Normal); context.dnsRecords = GCHandle.ToIntPtr(handle); MakeDnsRequest(domainName, dnsServers, context, out dnsRequest, out addrRequestBuffer, out contextBuffer); DNSQueryResult queryResult = new DNSQueryResult(); queryResult.Version = DnsQueryRequestVersion1; IntPtr result = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(DNSQueryResult))); Marshal.StructureToPtr(queryResult, result, false); IntPtr cancelBuffer = Marshal.AllocHGlobal(DNSQueryCancelSize); int resCode = DnsQueryEx(dnsRequest, result, cancelBuffer); FreeDnsRequest(dnsRequest, addrRequestBuffer, contextBuffer); bool requestPending = false; switch (resCode) { case 0: { queryResult = (DNSQueryResult)Marshal.PtrToStructure(result, typeof(DNSQueryResult)); Marshal.FreeHGlobal(result); } break; case DnsRequestPending: { Marshal.FreeHGlobal(result); requestPending = true; } break; case DnsRecordsNoInfo: { Marshal.FreeHGlobal(result); Marshal.FreeHGlobal(cancelBuffer); handle.Free(); return(new Dictionary <string, object> [0]); } default: { Marshal.FreeHGlobal(result); Marshal.FreeHGlobal(cancelBuffer); handle.Free(); throw new Win32Exception(resCode); } } if (!requestPending) { Marshal.FreeHGlobal(cancelBuffer); handle.Free(); if (queryResult.QueryStatus != 0) { if (queryResult.QueryRecords != IntPtr.Zero) { DnsRecordListFree(queryResult.QueryRecords, DNS_FREE_TYPE.DnsFreeRecordList); } throw new Win32Exception(queryResult.QueryStatus); } dnsRecords.AddRange(ParseRecords(queryResult.QueryRecords, recordType)); if (queryResult.QueryRecords != IntPtr.Zero) { DnsRecordListFree(queryResult.QueryRecords, DNS_FREE_TYPE.DnsFreeRecordList); } return(dnsRecords.ToArray()); } if (!context.eventHandle.WaitOne(5000)) { resCode = DnsCancelQuery(cancelBuffer); context.eventHandle.WaitOne(); if (resCode != 0) { Marshal.FreeHGlobal(cancelBuffer); handle.Free(); throw new Win32Exception(resCode); } } Marshal.FreeHGlobal(cancelBuffer); handle.Free(); int retCode = Marshal.ReadInt32(context.resultCode); Marshal.FreeHGlobal(context.resultCode); if (retCode != 0) { throw new Win32Exception(retCode); } return(dnsRecords.ToArray()); }