Type a page name and press Enter. You'll jump to the page if it exists, or you can create it if it doesn't.
To create a page in a module other than dnsapi, prefix the name with the module name and a period.
DnsQueryEx (dnsapi)
.
Provides a more customisable query than DNSQuery - uses an Async callback
**Fixed issue with contextBuffer getting freed prior to the callback returning.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
public class DNSQueryer
{
private const int DnsRecordsNoInfo = 9501;
private const int DnsRequestPending = 9506;
private const int DnsAddrMaxSockaddrLength = 32;
private const int DNSQueryCancelSize = 32;
private const short DNSPort = 53;
private const short AFInet = 2;
private const short AFInet16 = 23;
private const int IpAddressV6LengthBytes = 16;
private const int IpAddressV4LengthBytes = 4;
private const uint DnsQueryRequestVersion1 = 1;
public static IDictionary<string, object>[] QueryDNSForRecordTypeSpecificNameServers(string domainName, IPAddress[] dnsServers, DnsRecordTypes recordType)
{
if (dnsServers == null || dnsServers.Length == 0)
{
throw new Exception("At least one DNS Server must be provided to do the query");
}
Marshal.FreeHGlobal(sockAddrv6InPtr);
}
else
{
throw new Exception(string.Format("Address family {0} not supported", addr.AddressFamily.ToString()));
}
curAddress++;
}
int bufSize = Marshal.SizeOf(typeof(DNS_ADDR_ARRAY)) + (addrList.Length * Marshal.SizeOf(typeof(DNS_ADDR)));
IntPtr addrArrayPointer = new IntPtr(addrBuffer.ToInt64() + Marshal.SizeOf(typeof(DNS_ADDR_ARRAY)));
for (int i = 0; i < addrList.Length; i++)
{
Marshal.StructureToPtr(addrList[i], addrArrayPointer, false);
addrArrayPointer = new IntPtr(addrArrayPointer.ToInt64() + Marshal.SizeOf(typeof(DNS_ADDR)));
}
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();
}
private static IDictionary<string, object>[] ParseRecords(IntPtr result, DnsRecordTypes recordTypeAskedFor)
{
DNS_RECORD? record = Marshal.PtrToStructure(result, typeof(DNS_RECORD)) as DNS_RECORD?;
List<IDictionary<string, object>> records = new List<IDictionary<string, object>>();
[DllImport("dnsapi", SetLastError = true)]
private static extern int DnsCancelQuery(IntPtr cancelHandle);
[StructLayout(LayoutKind.Sequential)]
private struct QueryCompletionContext
{
public DnsRecordTypes requestType;
public EventWaitHandle eventHandle;
public IntPtr dnsRecords;
public IntPtr resultCode;
}
[StructLayout(LayoutKind.Sequential)]
private struct DNS_QUERY_REQUEST
{
public uint Version;
[MarshalAs(UnmanagedType.LPWStr)]
public string QueryName;
public ushort QueryType;
public ulong QueryOptions;
public IntPtr DnsServerList;
public uint InterfaceIndex;
public IntPtr QueryCompletionCallback;
public IntPtr QueryContext;
}
[StructLayout(LayoutKind.Sequential)]
private struct DNS_ADDR_ARRAY
{
public uint MaxCount;
public uint AddrCount;
public uint Tag;
public ushort Family;
public ushort WordReserved;
public uint Flags;
public uint MatchFlag;
public uint Reserved1;
public uint Reserved2;
//// the array of DNS_ADDR follows this
}
[StructLayout(LayoutKind.Sequential)]
private struct DNSQueryResult
{
public uint Version;
public int QueryStatus;
public ulong QueryOptions;
public IntPtr QueryRecords;
public IntPtr Reserved;
}
[StructLayout(LayoutKind.Sequential)]
private struct DNS_RECORD
{
public IntPtr Next;
public IntPtr Name;
public ushort Type;
public ushort DataLength;
public FlagsUnion Flags;
public uint TimeToLive;
public uint Reserved;
public DataUnion Data;
}
[StructLayout(LayoutKind.Explicit)]
private struct FlagsUnion
{
[FieldOffset(0)]
public uint DW;
[FieldOffset(0)]
public DNS_RECORD_FLAGS S;
}
[StructLayout(LayoutKind.Explicit)]
private struct DataUnion
{
[FieldOffset(0)]
public DNS_A_DATA A;
[FieldOffset(0)]
public DNS_PTR_DATA PTR, NS, CNAME;
[FieldOffset(0)]
public DNS_MX_DATA MX;
[FieldOffset(0)]
public DNS_TXT_DATA TXT;
[FieldOffset(0)]
public DNS_AAAA_DATA AAAA;
[FieldOffset(0)]
public DNS_SRV_DATA SRV;
}
[StructLayout(LayoutKind.Sequential)]
private struct DNS_A_DATA
{
public uint IpAddress;
}
[StructLayout(LayoutKind.Sequential)]
private struct DNS_PTR_DATA
{
public IntPtr NameHost;
}
[StructLayout(LayoutKind.Sequential)]
private struct DNS_MX_DATA
{
public IntPtr NameExchange;
public ushort Preference;
public ushort Pad;
}
[StructLayout(LayoutKind.Sequential)]
private struct DNS_TXT_DATA
{
public uint StringCount;
public IntPtr StringArray;
}
[StructLayout(LayoutKind.Sequential)]
private struct DNS_AAAA_DATA
{
public uint Ip6Address0;
public uint Ip6Address1;
public uint Ip6Address2;
public uint Ip6Address3;
}
[StructLayout(LayoutKind.Sequential)]
private struct DNS_SRV_DATA
{
public IntPtr NameTarget;
public ushort Priority;
public ushort Weight;
public ushort Port;
public ushort Pad;
}
public SockAddrIn6()
{
this.sin6Family = AFInet;
this.sin6Port = 0;
this.sin6Addr = new byte[IpAddressV6LengthBytes];
this.sin6ScopeId = 0;
}
public short Sin6Family
{
get
{
return this.sin6Family;
}
set
{
this.sin6Family = value;
}
}
public ushort Sin6Port
{
get
{
return this.sin6Port;
}
set
{
this.sin6Port = value;
}
}
public uint Sin6FlowInfo
public ulong Sin6FlowInfo
{
get
{
return this.sin6FlowInfo;
}
set
{
this.sin6FlowInfo = value;
}
}
public byte[] Sin6Addr
{
get
{
return this.sin6Addr;
}
}
public ulong Sin6ScopeId
{
get
{
return this.sin6ScopeId;
}
set
{
this.sin6ScopeId = value;
}
}
}
}
DNSQueryEx (built off DNSQuery page)
9/12/2018 4:44:25 AM - -149.13.177.34
A generic query interface to the DNS namespace, implemented in multiple forms to facilitate different character encoding.
9/13/2019 1:26:08 PM - -62.20.95.98
A generic query interface to the DNS namespace, implemented in multiple forms to facilitate different character encoding.
9/13/2019 1:26:08 PM - -62.20.95.98
Please edit this page!
Do you have...
helpful tips or sample code to share for using this API in managed code?
corrections to the existing content?
variations of the signature you want to share?
additional languages you want to include?
Select "Edit This Page" on the right hand toolbar and edit it! Or add new pages containing supporting types needed for this API (structures, delegates, and more).