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
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
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");
}
IntPtr dnsRequest, addrRequestBuffer, contextBuffer;
StringBuilder builder = new StringBuilder();
foreach (IPAddress dnsServer in dnsServers)
{
builder.Append("," + dnsServer.ToString());
}
QueryCompletionContext context = new QueryCompletionContext();
context.eventHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
context.requestType = recordType;
context.resultCode = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
IntPtr dnsRequest, addrRequestBuffer, contextBuffer;
List<IDictionary<string, object>> dnsRecords = new List<IDictionary<string, object>>();
QueryCompletionContext context = new QueryCompletionContext();
context.eventHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
context.requestType = recordType;
context.resultCode = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
MakeDnsRequest(domainName, dnsServers, context, out dnsRequest, out addrRequestBuffer, out contextBuffer);
context.dnsRecords = GCHandle.ToIntPtr(handle);
DNSQueryResult queryResult = new DNSQueryResult();
queryResult.Version = DnsQueryRequestVersion1;
MakeDnsRequest(domainName, dnsServers, context, out dnsRequest, out addrRequestBuffer, out contextBuffer);
IntPtr result = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(DNSQueryResult)));
Marshal.StructureToPtr(queryResult, result, false);
DNSQueryResult queryResult = new DNSQueryResult();
queryResult.Version = DnsQueryRequestVersion1;
if (queryResult.QueryStatus != 0)
{
if (queryResult.QueryRecords != IntPtr.Zero)
{
DnsRecordListFree(queryResult.QueryRecords, DNS_FREE_TYPE.DnsFreeRecordList);
Marshal.FreeHGlobal(sockAddrv6InPtr);
}
else
{
throw new Exception(string.Format("Address family {0} not supported", addr.AddressFamily.ToString()));
}
record = Marshal.PtrToStructure(record.Value.Next, typeof(DNS_RECORD)) as DNS_RECORD?;
if (queryResult.QueryRecords != IntPtr.Zero)
{
DnsRecordListFree(queryResult.QueryRecords, DNS_FREE_TYPE.DnsFreeRecordList);
}
[DllImport("dnsapi", SetLastError = true)]
private static extern int DnsCancelQuery(IntPtr cancelHandle);
case (ushort)DnsRecordTypes.DNS_TYPE_TXT:
{
IntPtr stringsCursor = record.Value.Data.TXT.StringArray;
[StructLayout(LayoutKind.Sequential)]
private struct QueryCompletionContext
{
public DnsRecordTypes requestType;
public EventWaitHandle eventHandle;
public IntPtr dnsRecords;
public IntPtr resultCode;
}
StringBuilder valuesBuffer = new StringBuilder();
[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;
}
for (uint i = 0; i < record.Value.Data.TXT.StringCount; i++)
{
IntPtr txtString = Marshal.ReadIntPtr(stringsCursor);
[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
}
string value = Marshal.PtrToStringUni(stringsCursor);
[StructLayout(LayoutKind.Sequential)]
private struct DNSQueryResult
{
public uint Version;
public int QueryStatus;
public ulong QueryOptions;
public IntPtr QueryRecords;
public IntPtr Reserved;
}
IDictionary<string, object> txtRecord = new Dictionary<string, object>();
txtRecord.Add("Type", "TXT");
txtRecord.Add("Name", recordName);
txtRecord.Add("Value", value);
records.Add(txtRecord);
[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;
}
valuesBuffer.Append(";" + value);
[StructLayout(LayoutKind.Explicit)]
private struct FlagsUnion
{
[FieldOffset(0)]
public uint DW;
[FieldOffset(0)]
public DNS_RECORD_FLAGS S;
}
stringsCursor += Marshal.SizeOf(typeof(IntPtr));
}
[StructLayout(LayoutKind.Sequential)]
private struct DNS_AAAA_DATA
{
public uint Ip6Address0;
public uint Ip6Address1;
public uint Ip6Address2;
public uint Ip6Address3;
}
[DllImport("dnsapi", SetLastError = true)]
private static extern int DnsCancelQuery(IntPtr cancelHandle);
[StructLayout(LayoutKind.Sequential)]
private struct DNS_SRV_DATA
private struct QueryCompletionContext
{
public IntPtr NameTarget;
public ushort Priority;
public ushort Weight;
public ushort Port;
public ushort Pad;
public DnsRecordTypes requestType;
public EventWaitHandle eventHandle;
public IntPtr dnsRecords;
public IntPtr resultCode;
}
public DNS_ADDR()
{
this.maxSa = new byte[DnsAddrMaxSockaddrLength];
this.dnsAddrUserDword = new uint[8];
}
public byte[] MaxSa
{
get
{
return this.maxSa;
}
}
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 class SockAddrIn
private struct DNS_ADDR_ARRAY
{
private short sinFamily;
private ushort sinPort;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IpAddressV4LengthBytes)]
private byte[] sinAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
private byte[] sinZero;
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
}
public SockAddrIn()
{
this.sinFamily = 0;
this.sinPort = 0;
this.sinAddr = new byte[IpAddressV4LengthBytes];
this.sinZero = new byte[8];
}
[StructLayout(LayoutKind.Sequential)]
private struct DNSQueryResult
{
public uint Version;
public int QueryStatus;
public ulong QueryOptions;
public IntPtr QueryRecords;
public IntPtr Reserved;
}
public short SinFamily
{
get
{
return this.sinFamily;
}
[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;
}
set
{
this.sinFamily = value;
}
}
[StructLayout(LayoutKind.Explicit)]
private struct FlagsUnion
{
[FieldOffset(0)]
public uint DW;
[FieldOffset(0)]
public DNS_RECORD_FLAGS S;
}
public ushort SinPort
{
get
{
return this.sinPort;
}
set
{
this.sinPort = value;
}
}
public byte[] SinAddr
{
get
{
return this.sinAddr;
}
}
}
public byte[] Sin6Addr
public uint Reserved
{
get
{
return this.sin6Addr;
}
get { return (this.Data >> 8) & 0xFFFFFFu; }
set { this.Data = (this.Data & ~(0xFFFFFFu << 8)) | (value & 0xFFFFFFu) << 8; }
}
public ulong Sin6ScopeId
{
get
{
return this.sin6ScopeId;
}
set
{
this.sin6ScopeId = value;
}
}
}
}
[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 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)
7/5/2016 12:30:57 AM - -213.171.217.185
DNSQueryEx (built off DNSQuery page)
7/18/2016 3:46:41 PM - -95.93.140.43
DNSQueryEx (built off DNSQuery page)
7/18/2016 3:46:41 PM - -95.93.140.43
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).