Search
Module:
Directory

   Desktop Functions:

   Smart Device Functions:


Show Recent Changes
Subscribe (RSS)
Misc. Pages
Comments
FAQ
Helpful Tools
Playground
Suggested Reading
Website TODO List
Download Visual Studio Add-In

DnsQueryEx (dnsapi)
 
.
Summary
DNSQueryEx (built off DNSQuery page)

Provides a more customisable query than DNSQuery - uses an Async callback

C# Signature:

[DllImport("dnsapi", EntryPoint = "DnsQueryEx", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
    private static extern int DnsQueryEx(IntPtr queryRequest, IntPtr queryResults, IntPtr cancelHandle);

None.

Notes:

None.

Sample Code:

   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;

    private delegate void QueryCompletionRoutineFunctionPointer(IntPtr queryContext, IntPtr queryResults);

    [Flags]
    private enum DnsQueryOptions
    {
        DNS_QUERY_STANDARD = 0x0,
        DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE = 0x1,
        DNS_QUERY_USE_TCP_ONLY = 0x2,
        DNS_QUERY_NO_RECURSION = 0x4,
        DNS_QUERY_BYPASS_CACHE = 0x8,
        DNS_QUERY_NO_WIRE_QUERY = 0x10,
        DNS_QUERY_NO_LOCAL_NAME = 0x20,
        DNS_QUERY_NO_HOSTS_FILE = 0x40,
        DNS_QUERY_NO_NETBT = 0x80,
        DNS_QUERY_WIRE_ONLY = 0x100,
        DNS_QUERY_RETURN_MESSAGE = 0x200,
        DNS_QUERY_MULTICAST_ONLY = 0x400,
        DNS_QUERY_NO_MULTICAST = 0x800,
        DNS_QUERY_TREAT_AS_FQDN = 0x1000,
        DNS_QUERY_ADDRCONFIG = 0x2000,
        DNS_QUERY_DUAL_ADDR = 0x4000,
        DNS_QUERY_MULTICAST_WAIT = 0x20000,
        DNS_QUERY_MULTICAST_VERIFY = 0x40000,
        DNS_QUERY_DONT_RESET_TTL_VALUES = 0x100000,
        DNS_QUERY_DISABLE_IDN_ENCODING = 0x200000,
        DNS_QUERY_APPEND_MULTILABEL = 0x800000,
        DNS_QUERY_RESERVED = unchecked((int)0xF0000000)
    }

    public enum DnsRecordTypes
    {
        DNS_TYPE_A = 0x1,
        DNS_TYPE_NS = 0x2,
        DNS_TYPE_CNAME = 0x5,
        DNS_TYPE_PTR = 0xC,
        DNS_TYPE_MX = 0xF,
        DNS_TYPE_TXT = 0x10,
        DNS_TYPE_AAAA = 0x1C,
        DNS_TYPE_SRV = 0x21
    }

    private enum DNS_FREE_TYPE
    {
        DnsFreeFlat = 0,
        DnsFreeRecordList = 1,
        DnsFreeParsedMessageFields = 2
    }

    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)));

        GCHandle handle = GCHandle.Alloc(dnsRecords, GCHandleType.Normal);
        List<IDictionary<string, object>> dnsRecords = new List<IDictionary<string, object>>();

        context.dnsRecords = GCHandle.ToIntPtr(handle);
        GCHandle handle = GCHandle.Alloc(dnsRecords, GCHandleType.Normal);

        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;

        IntPtr cancelBuffer = Marshal.AllocHGlobal(DNSQueryCancelSize);
        IntPtr result = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(DNSQueryResult)));
        Marshal.StructureToPtr(queryResult, result, false);

        int resCode = DnsQueryEx(dnsRequest, result, cancelBuffer);
        IntPtr cancelBuffer = Marshal.AllocHGlobal(DNSQueryCancelSize);

        FreeDnsRequest(dnsRequest, addrRequestBuffer, contextBuffer);
        int resCode = DnsQueryEx(dnsRequest, result, cancelBuffer);

        bool requestPending = false;
        FreeDnsRequest(dnsRequest, addrRequestBuffer, contextBuffer);

        switch (resCode)
        {
        case 0:
            {
            queryResult = (DNSQueryResult)Marshal.PtrToStructure(result, typeof(DNSQueryResult));
            Marshal.FreeHGlobal(result);
            }
        bool requestPending = false;

            break;
        case DnsRequestPending:
        switch (resCode)
        {
        case 0:
            {
            queryResult = (DNSQueryResult)Marshal.PtrToStructure(result, typeof(DNSQueryResult));
            Marshal.FreeHGlobal(result);
            requestPending = true;
            }
            break;
        case DnsRecordsNoInfo:
            {
            Marshal.FreeHGlobal(result);
            Marshal.FreeHGlobal(cancelBuffer);
            handle.Free();
            return new Dictionary<string, object>[0];
            }

        default:
            break;
        case DnsRequestPending:
            {
            Marshal.FreeHGlobal(result);
            Marshal.FreeHGlobal(cancelBuffer);
            handle.Free();
            throw new Win32Exception(resCode);
            requestPending = true;
            }
        }

        if (!requestPending)
        {
        Marshal.FreeHGlobal(cancelBuffer);
        handle.Free();

        if (queryResult.QueryStatus != 0)
        {
            if (queryResult.QueryRecords != IntPtr.Zero)
            break;
        case DnsRecordsNoInfo:
            {
            DnsRecordListFree(queryResult.QueryRecords, DNS_FREE_TYPE.DnsFreeRecordList);
            Marshal.FreeHGlobal(result);
            Marshal.FreeHGlobal(cancelBuffer);
            handle.Free();
            return new Dictionary<string, object>[0];
            }

            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();
        default:
            {
            Marshal.FreeHGlobal(result);
            Marshal.FreeHGlobal(cancelBuffer);
            handle.Free();
            throw new Win32Exception(resCode);
            }
        }

        if (!context.eventHandle.WaitOne(5000))
        if (!requestPending)
        {
        resCode = DnsCancelQuery(cancelBuffer);
        context.eventHandle.WaitOne();
        if (resCode != 0)
        {
            Marshal.FreeHGlobal(cancelBuffer);
            handle.Free();
            throw new Win32Exception(resCode);
        }
        }
        Marshal.FreeHGlobal(cancelBuffer);
        handle.Free();

        Marshal.FreeHGlobal(cancelBuffer);
        if (queryResult.QueryStatus != 0)
        {
            if (queryResult.QueryRecords != IntPtr.Zero)
            {
            DnsRecordListFree(queryResult.QueryRecords, DNS_FREE_TYPE.DnsFreeRecordList);
            }

        handle.Free();
            throw new Win32Exception(queryResult.QueryStatus);
        }

        int retCode = Marshal.ReadInt32(context.resultCode);
        dnsRecords.AddRange(ParseRecords(queryResult.QueryRecords, recordType));

        Marshal.FreeHGlobal(context.resultCode);
        if (queryResult.QueryRecords != IntPtr.Zero)
        {
            DnsRecordListFree(queryResult.QueryRecords, DNS_FREE_TYPE.DnsFreeRecordList);
        }

        if (retCode != 0)
        {
        throw new Win32Exception(retCode);
        return dnsRecords.ToArray();
        }

        return dnsRecords.ToArray();
    }

    private static void FreeDnsRequest(IntPtr requestBuffer, IntPtr addrBuffer, IntPtr contextBuffer)
    {
        if (requestBuffer != IntPtr.Zero)
        if (!context.eventHandle.WaitOne(5000))
        {
        Marshal.FreeHGlobal(requestBuffer);
        requestBuffer = IntPtr.Zero;
        resCode = DnsCancelQuery(cancelBuffer);
        context.eventHandle.WaitOne();
        if (resCode != 0)
        {
            Marshal.FreeHGlobal(cancelBuffer);
            handle.Free();
            throw new Win32Exception(resCode);
        }
        }

        if (addrBuffer != IntPtr.Zero)
        {
        Marshal.FreeHGlobal(addrBuffer);
        addrBuffer = IntPtr.Zero;
        }
        Marshal.FreeHGlobal(cancelBuffer);

        if (contextBuffer != IntPtr.Zero)
        {
        Marshal.FreeHGlobal(contextBuffer);
        contextBuffer = IntPtr.Zero;
        }
    }
        handle.Free();

    private static void MakeDnsRequest(string domainName, IPAddress[] dnsServers, QueryCompletionContext context, out IntPtr requestBuffer, out IntPtr addrBuffer, out IntPtr contextBuffer)
    {
        requestBuffer = IntPtr.Zero;
        addrBuffer = IntPtr.Zero;
        contextBuffer = IntPtr.Zero;
        int retCode = Marshal.ReadInt32(context.resultCode);

        DNS_ADDR[] addrList = new DNS_ADDR[dnsServers.Length];
        int curAddress = 0;
        Marshal.FreeHGlobal(context.resultCode);

        foreach (IPAddress addr in dnsServers)
        if (retCode != 0)
        {
        addrList[curAddress] = new DNS_ADDR();
        throw new Win32Exception(retCode);
        }

        if (addr.AddressFamily == AddressFamily.InterNetwork)
        {
            byte[] ipv4AddressBytes = addr.GetAddressBytes();
        return dnsRecords.ToArray();
    }

            SockAddrIn sockAddrIn = new SockAddrIn();

            Buffer.BlockCopy(ipv4AddressBytes, 0, sockAddrIn.SinAddr, 0, IpAddressV4LengthBytes);
    private static void FreeDnsRequest(IntPtr requestBuffer, IntPtr addrBuffer, IntPtr contextBuffer)
    {
        if (requestBuffer != IntPtr.Zero)
        {
        Marshal.FreeHGlobal(requestBuffer);
        requestBuffer = IntPtr.Zero;
        }

            sockAddrIn.SinFamily = AFInet;
            sockAddrIn.SinPort = (ushort)IPAddress.HostToNetworkOrder(DNSPort);
        if (addrBuffer != IntPtr.Zero)
        {
        Marshal.FreeHGlobal(addrBuffer);
        addrBuffer = IntPtr.Zero;
        }

            IntPtr sockAddrInPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SockAddrIn)));
            Marshal.StructureToPtr(sockAddrIn, sockAddrInPtr, false);
        if (contextBuffer != IntPtr.Zero)
        {
        Marshal.FreeHGlobal(contextBuffer);
        contextBuffer = IntPtr.Zero;
        }
    }

            Marshal.Copy(sockAddrInPtr, addrList[curAddress].MaxSa, 0, Marshal.SizeOf(typeof(SockAddrIn)));
    private static void MakeDnsRequest(string domainName, IPAddress[] dnsServers, QueryCompletionContext context, out IntPtr requestBuffer, out IntPtr addrBuffer, out IntPtr contextBuffer)
    {
        requestBuffer = IntPtr.Zero;
        addrBuffer = IntPtr.Zero;
        contextBuffer = IntPtr.Zero;

            Marshal.FreeHGlobal(sockAddrInPtr);
        }
        else if (addr.AddressFamily == AddressFamily.InterNetworkV6)
        {
            SockAddrIn6 sockAddrIn6 = new SockAddrIn6();
        DNS_ADDR[] addrList = new DNS_ADDR[dnsServers.Length];
        int curAddress = 0;

            sockAddrIn6.Sin6Family = AFInet16;
            sockAddrIn6.Sin6Port = (ushort)IPAddress.HostToNetworkOrder(DNSPort);
            sockAddrIn6.Sin6FlowInfo = 0;
        foreach (IPAddress addr in dnsServers)
        {
        addrList[curAddress] = new DNS_ADDR();

            byte[] ipv6AddressBytes = addr.GetAddressBytes();

            Buffer.BlockCopy(ipv6AddressBytes, 0, sockAddrIn6.Sin6Addr, 0, IpAddressV6LengthBytes);

            sockAddrIn6.Sin6ScopeId = 0;

            IntPtr sockAddrv6InPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SockAddrIn6)));
            Marshal.StructureToPtr(sockAddrIn6, sockAddrv6InPtr, false);

            Marshal.Copy(sockAddrv6InPtr, addrList[curAddress].MaxSa, 0, Marshal.SizeOf(typeof(SockAddrIn6)));

            Marshal.FreeHGlobal(sockAddrv6InPtr);
        }
        else
        if (addr.AddressFamily == AddressFamily.InterNetwork)
        {
            throw new Exception(string.Format("Address family {0} not supported", addr.AddressFamily.ToString()));
        }
            byte[] ipv4AddressBytes = addr.GetAddressBytes();

        curAddress++;
        }
            SockAddrIn sockAddrIn = new SockAddrIn();

        int bufSize = Marshal.SizeOf(typeof(DNS_ADDR_ARRAY)) + (addrList.Length * Marshal.SizeOf(typeof(DNS_ADDR)));
            Buffer.BlockCopy(ipv4AddressBytes, 0, sockAddrIn.SinAddr, 0, IpAddressV4LengthBytes);

        DNS_ADDR_ARRAY addrArray = new DNS_ADDR_ARRAY();
        addrArray.MaxCount = (uint)dnsServers.Length;
        addrArray.AddrCount = (uint)dnsServers.Length;
            sockAddrIn.SinFamily = AFInet;
            sockAddrIn.SinPort = (ushort)IPAddress.HostToNetworkOrder(DNSPort);

        addrBuffer = Marshal.AllocHGlobal(bufSize);
        Marshal.StructureToPtr(addrArray, addrBuffer, false);
            IntPtr sockAddrInPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SockAddrIn)));
            Marshal.StructureToPtr(sockAddrIn, sockAddrInPtr, false);

        IntPtr addrArrayPointer = new IntPtr(addrBuffer.ToInt64() + Marshal.SizeOf(typeof(DNS_ADDR_ARRAY)));
            Marshal.Copy(sockAddrInPtr, addrList[curAddress].MaxSa, 0, Marshal.SizeOf(typeof(SockAddrIn)));

        for (int i = 0; i < addrList.Length; i++)
        {
        Marshal.StructureToPtr(addrList[i], addrArrayPointer, false);
        addrArrayPointer = new IntPtr(addrArrayPointer.ToInt64() + Marshal.SizeOf(typeof(DNS_ADDR)));
        }
            Marshal.FreeHGlobal(sockAddrInPtr);
        }
        else if (addr.AddressFamily == AddressFamily.InterNetworkV6)
        {
            SockAddrIn6 sockAddrIn6 = new SockAddrIn6();

        DNS_QUERY_REQUEST request = new DNS_QUERY_REQUEST();
        request.Version = DnsQueryRequestVersion1;
        request.QueryName = domainName;
        request.QueryType = (ushort)context.requestType;
        request.QueryOptions = (ulong)DnsQueryOptions.DNS_QUERY_STANDARD;
        request.DnsServerList = addrBuffer;
        request.InterfaceIndex = 0;
        request.QueryCompletionCallback = Marshal.GetFunctionPointerForDelegate(new QueryCompletionRoutineFunctionPointer(QueryCompletionRoutine));
            sockAddrIn6.Sin6Family = AFInet16;
            sockAddrIn6.Sin6Port = (ushort)IPAddress.HostToNetworkOrder(DNSPort);
            sockAddrIn6.Sin6FlowInfo = 0;

        contextBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(context));
        Marshal.StructureToPtr(context, contextBuffer, false);
            byte[] ipv6AddressBytes = addr.GetAddressBytes();

        request.QueryContext = contextBuffer;
            Buffer.BlockCopy(ipv6AddressBytes, 0, sockAddrIn6.Sin6Addr, 0, IpAddressV6LengthBytes);

        requestBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(request));
        Marshal.StructureToPtr(request, requestBuffer, false);
    }
            sockAddrIn6.Sin6ScopeId = 0;

    private static void QueryCompletionRoutine(IntPtr queryContext, IntPtr queryResults)
    {
        QueryCompletionContext context = (QueryCompletionContext)Marshal.PtrToStructure(queryContext, typeof(QueryCompletionContext));
            IntPtr sockAddrv6InPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SockAddrIn6)));
            Marshal.StructureToPtr(sockAddrIn6, sockAddrv6InPtr, false);

        DNSQueryResult queryResult = (DNSQueryResult)Marshal.PtrToStructure(queryResults, typeof(DNSQueryResult));
            Marshal.Copy(sockAddrv6InPtr, addrList[curAddress].MaxSa, 0, Marshal.SizeOf(typeof(SockAddrIn6)));

        Marshal.WriteInt32(context.resultCode, queryResult.QueryStatus);

        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()));
        }

        context.eventHandle.Set();
        return;
        curAddress++;
        }

        List<IDictionary<string, object>> records = GCHandle.FromIntPtr(context.dnsRecords).Target as List<IDictionary<string, object>>;
        int bufSize = Marshal.SizeOf(typeof(DNS_ADDR_ARRAY)) + (addrList.Length * Marshal.SizeOf(typeof(DNS_ADDR)));

        records.AddRange(ParseRecords(queryResult.QueryRecords, context.requestType));
        DNS_ADDR_ARRAY addrArray = new DNS_ADDR_ARRAY();
        addrArray.MaxCount = (uint)dnsServers.Length;
        addrArray.AddrCount = (uint)dnsServers.Length;

        if (queryResult.QueryRecords != IntPtr.Zero)
        {
        DnsRecordListFree(queryResult.QueryRecords, DNS_FREE_TYPE.DnsFreeRecordList);
        }
        addrBuffer = Marshal.AllocHGlobal(bufSize);
        Marshal.StructureToPtr(addrArray, addrBuffer, false);

        context.eventHandle.Set();
    }
        IntPtr addrArrayPointer = new IntPtr(addrBuffer.ToInt64() + Marshal.SizeOf(typeof(DNS_ADDR_ARRAY)));

    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>>();

        while (record.HasValue)
        for (int i = 0; i < addrList.Length; i++)
        {
        if (record.Value.Type == (ushort)recordTypeAskedFor)
        {
            string recordName = Marshal.PtrToStringUni(record.Value.Name);
            switch (record.Value.Type)
            {
            case (ushort)DnsRecordTypes.DNS_TYPE_A:
                {
                string recordValue = ConvertUintToIpAddress(record.Value.Data.A.IpAddress).ToString();
                records.Add(new Dictionary<string, object> { { "Type", "A" }, { "Name", recordName }, { "Value", recordValue } });
                break;
                }
        Marshal.StructureToPtr(addrList[i], addrArrayPointer, false);
        addrArrayPointer = new IntPtr(addrArrayPointer.ToInt64() + Marshal.SizeOf(typeof(DNS_ADDR)));
        }

            case (ushort)DnsRecordTypes.DNS_TYPE_MX:
                {
                string nameExchange = Marshal.PtrToStringUni(record.Value.Data.MX.NameExchange);
                ushort preference = record.Value.Data.MX.Preference;
                records.Add(new Dictionary<string, object> { { "Type", "MX" }, { "Name", recordName }, { "NameExchange", nameExchange }, { "Preference", preference.ToString() } });
                break;
                }
        DNS_QUERY_REQUEST request = new DNS_QUERY_REQUEST();
        request.Version = DnsQueryRequestVersion1;
        request.QueryName = domainName;
        request.QueryType = (ushort)context.requestType;
        request.QueryOptions = (ulong)DnsQueryOptions.DNS_QUERY_STANDARD;
        request.DnsServerList = addrBuffer;
        request.InterfaceIndex = 0;
        request.QueryCompletionCallback = Marshal.GetFunctionPointerForDelegate(new QueryCompletionRoutineFunctionPointer(QueryCompletionRoutine));

            case (ushort)DnsRecordTypes.DNS_TYPE_NS:
            case (ushort)DnsRecordTypes.DNS_TYPE_PTR:
            case (ushort)DnsRecordTypes.DNS_TYPE_CNAME:
                {
                string type = record.Value.Type == (ushort)DnsRecordTypes.DNS_TYPE_NS ? "NS " :
                    (record.Value.Type == (ushort)DnsRecordTypes.DNS_TYPE_PTR ? "PTR" : "CNAME");
                string nameHost = Marshal.PtrToStringUni(record.Value.Data.PTR.NameHost);
                records.Add(new Dictionary<string, object> { { "Type", type }, { "Name", recordName }, { "NameHost", nameHost } });
                break;
                }
        contextBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(context));
        Marshal.StructureToPtr(context, contextBuffer, false);

            case (ushort)DnsRecordTypes.DNS_TYPE_TXT:
                {
                IntPtr stringsCursor = record.Value.Data.TXT.StringArray;
        request.QueryContext = contextBuffer;

                StringBuilder valuesBuffer = new StringBuilder();
        requestBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(request));
        Marshal.StructureToPtr(request, requestBuffer, false);
    }

                for (uint i = 0; i < record.Value.Data.TXT.StringCount; i++)
                {
                    IntPtr txtString = Marshal.ReadIntPtr(stringsCursor);
    private static void QueryCompletionRoutine(IntPtr queryContext, IntPtr queryResults)
    {
        QueryCompletionContext context = (QueryCompletionContext)Marshal.PtrToStructure(queryContext, typeof(QueryCompletionContext));

                    string value = Marshal.PtrToStringUni(stringsCursor);
        DNSQueryResult queryResult = (DNSQueryResult)Marshal.PtrToStructure(queryResults, typeof(DNSQueryResult));

                    IDictionary<string, object> txtRecord = new Dictionary<string, object>();
                    txtRecord.Add("Type", "TXT");
                    txtRecord.Add("Name", recordName);
                    txtRecord.Add("Value", value);
                    records.Add(txtRecord);
        Marshal.WriteInt32(context.resultCode, queryResult.QueryStatus);

                    valuesBuffer.Append(";" + value);
        if (queryResult.QueryStatus != 0)
        {
        if (queryResult.QueryRecords != IntPtr.Zero)
        {
            DnsRecordListFree(queryResult.QueryRecords, DNS_FREE_TYPE.DnsFreeRecordList);
        }

                    stringsCursor += Marshal.SizeOf(typeof(IntPtr));
                }
        context.eventHandle.Set();
        return;
        }

                break;
                }
        List<IDictionary<string, object>> records = GCHandle.FromIntPtr(context.dnsRecords).Target as List<IDictionary<string, object>>;

            case (ushort)DnsRecordTypes.DNS_TYPE_AAAA:
                {
                string recordValue = ConvertAAAAToIpAddress(record.Value.Data.AAAA).ToString();
                records.Add(new Dictionary<string, object> { { "Type", "AAAA" }, { "Name", recordName }, { "Value", recordValue } });
                break;
                }
        records.AddRange(ParseRecords(queryResult.QueryRecords, context.requestType));

            case (ushort)DnsRecordTypes.DNS_TYPE_SRV:
                {
                string nameTarget = Marshal.PtrToStringUni(record.Value.Data.SRV.NameTarget);
                ushort priority = record.Value.Data.SRV.Priority;
                ushort weight = record.Value.Data.SRV.Weight;
                ushort port = record.Value.Data.SRV.Port;
                records.Add(new Dictionary<string, object> { { "Type", "SRV" }, { "Name", recordName }, { "NameTarget", nameTarget }, { "Priority", priority.ToString() }, { "Weight", weight.ToString() }, { "Port", port.ToString() } });
                break;
                }
            }
        }

        record = Marshal.PtrToStructure(record.Value.Next, typeof(DNS_RECORD)) as DNS_RECORD?;
        if (queryResult.QueryRecords != IntPtr.Zero)
        {
        DnsRecordListFree(queryResult.QueryRecords, DNS_FREE_TYPE.DnsFreeRecordList);
        }

        return records.ToArray();
        context.eventHandle.Set();
    }

    private static IPAddress ConvertUintToIpAddress(uint ipAddress)
    private static IDictionary<string, object>[] ParseRecords(IntPtr result, DnsRecordTypes recordTypeAskedFor)
    {
        var addressBytes = new byte[4];
        addressBytes[0] = (byte)((ipAddress & 0xFF000000u) >> 24);
        addressBytes[1] = (byte)((ipAddress & 0x00FF0000u) >> 16);
        addressBytes[2] = (byte)((ipAddress & 0x0000FF00u) >> 8);
        addressBytes[3] = (byte)(ipAddress & 0x000000FFu);
        return new IPAddress(addressBytes);
    }
        DNS_RECORD? record = Marshal.PtrToStructure(result, typeof(DNS_RECORD)) as DNS_RECORD?;

    private static IPAddress ConvertAAAAToIpAddress(DNS_AAAA_DATA data)
    {
        var addressBytes = new byte[16];
        addressBytes[0] = (byte)(data.Ip6Address0 & 0x000000FF);
        addressBytes[1] = (byte)((data.Ip6Address0 & 0x0000FF00) >> 8);
        addressBytes[2] = (byte)((data.Ip6Address0 & 0x00FF0000) >> 16);
        addressBytes[3] = (byte)((data.Ip6Address0 & 0xFF000000) >> 24);
        addressBytes[4] = (byte)(data.Ip6Address1 & 0x000000FF);
        addressBytes[5] = (byte)((data.Ip6Address1 & 0x0000FF00) >> 8);
        addressBytes[6] = (byte)((data.Ip6Address1 & 0x00FF0000) >> 16);
        addressBytes[7] = (byte)((data.Ip6Address1 & 0xFF000000) >> 24);
        addressBytes[8] = (byte)(data.Ip6Address2 & 0x000000FF);
        addressBytes[9] = (byte)((data.Ip6Address2 & 0x0000FF00) >> 8);
        addressBytes[10] = (byte)((data.Ip6Address2 & 0x00FF0000) >> 16);
        addressBytes[11] = (byte)((data.Ip6Address2 & 0xFF000000) >> 24);
        addressBytes[12] = (byte)(data.Ip6Address3 & 0x000000FF);
        addressBytes[13] = (byte)((data.Ip6Address3 & 0x0000FF00) >> 8);
        addressBytes[14] = (byte)((data.Ip6Address3 & 0x00FF0000) >> 16);
        addressBytes[15] = (byte)((data.Ip6Address3 & 0xFF000000) >> 24);
        List<IDictionary<string, object>> records = new List<IDictionary<string, object>>();

        return new IPAddress(addressBytes);
    }
        while (record.HasValue)
        {
        if (record.Value.Type == (ushort)recordTypeAskedFor)
        {
            string recordName = Marshal.PtrToStringUni(record.Value.Name);
            switch (record.Value.Type)
            {
            case (ushort)DnsRecordTypes.DNS_TYPE_A:
                {
                string recordValue = ConvertUintToIpAddress(record.Value.Data.A.IpAddress).ToString();
                records.Add(new Dictionary<string, object> { { "Type", "A" }, { "Name", recordName }, { "Value", recordValue } });
                break;
                }

    [DllImport("dnsapi", EntryPoint = "DnsQueryEx", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
    private static extern int DnsQueryEx(IntPtr queryRequest, IntPtr queryResults, IntPtr cancelHandle);
            case (ushort)DnsRecordTypes.DNS_TYPE_MX:
                {
                string nameExchange = Marshal.PtrToStringUni(record.Value.Data.MX.NameExchange);
                ushort preference = record.Value.Data.MX.Preference;
                records.Add(new Dictionary<string, object> { { "Type", "MX" }, { "Name", recordName }, { "NameExchange", nameExchange }, { "Preference", preference.ToString() } });
                break;
                }

    [DllImport("dnsapi", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern void DnsRecordListFree(IntPtr recordList, DNS_FREE_TYPE freeType);
            case (ushort)DnsRecordTypes.DNS_TYPE_NS:
            case (ushort)DnsRecordTypes.DNS_TYPE_PTR:
            case (ushort)DnsRecordTypes.DNS_TYPE_CNAME:
                {
                string type = record.Value.Type == (ushort)DnsRecordTypes.DNS_TYPE_NS ? "NS " :
                    (record.Value.Type == (ushort)DnsRecordTypes.DNS_TYPE_PTR ? "PTR" : "CNAME");
                string nameHost = Marshal.PtrToStringUni(record.Value.Data.PTR.NameHost);
                records.Add(new Dictionary<string, object> { { "Type", type }, { "Name", recordName }, { "NameHost", nameHost } });
                break;
                }

    [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_RECORD_FLAGS
    {
        internal uint Data;
                break;
                }

        public uint Section
        {
        get { return this.Data & 0x3u; }
        set { this.Data = (this.Data & ~0x3u) | (value & 0x3u); }
        }
            case (ushort)DnsRecordTypes.DNS_TYPE_AAAA:
                {
                string recordValue = ConvertAAAAToIpAddress(record.Value.Data.AAAA).ToString();
                records.Add(new Dictionary<string, object> { { "Type", "AAAA" }, { "Name", recordName }, { "Value", recordValue } });
                break;
                }

        public uint Delete
        {
        get { return (this.Data >> 2) & 0x1u; }
        set { this.Data = (this.Data & ~(0x1u << 2)) | (value & 0x1u) << 2; }
        }
            case (ushort)DnsRecordTypes.DNS_TYPE_SRV:
                {
                string nameTarget = Marshal.PtrToStringUni(record.Value.Data.SRV.NameTarget);
                ushort priority = record.Value.Data.SRV.Priority;
                ushort weight = record.Value.Data.SRV.Weight;
                ushort port = record.Value.Data.SRV.Port;
                records.Add(new Dictionary<string, object> { { "Type", "SRV" }, { "Name", recordName }, { "NameTarget", nameTarget }, { "Priority", priority.ToString() }, { "Weight", weight.ToString() }, { "Port", port.ToString() } });
                break;
                }
            }
        }

        public uint CharSet
        {
        get { return (this.Data >> 3) & 0x3u; }
        set { this.Data = (this.Data & ~(0x3u << 3)) | (value & 0x3u) << 3; }
        record = Marshal.PtrToStructure(record.Value.Next, typeof(DNS_RECORD)) as DNS_RECORD?;
        }

        public uint Unused
        {
        get { return (this.Data >> 5) & 0x7u; }
        set { this.Data = (this.Data & ~(0x7u << 5)) | (value & 0x7u) << 5; }
        }

        public uint Reserved
        {
        get { return (this.Data >> 8) & 0xFFFFFFu; }
        set { this.Data = (this.Data & ~(0xFFFFFFu << 8)) | (value & 0xFFFFFFu) << 8; }
        }
        return records.ToArray();
    }

    [StructLayout(LayoutKind.Explicit)]
    private struct DataUnion
    private static IPAddress ConvertUintToIpAddress(uint ipAddress)
    {
        [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;
        var addressBytes = new byte[4];
        addressBytes[0] = (byte)((ipAddress & 0xFF000000u) >> 24);
        addressBytes[1] = (byte)((ipAddress & 0x00FF0000u) >> 16);
        addressBytes[2] = (byte)((ipAddress & 0x0000FF00u) >> 8);
        addressBytes[3] = (byte)(ipAddress & 0x000000FFu);
        return new IPAddress(addressBytes);
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct DNS_A_DATA
    private static IPAddress ConvertAAAAToIpAddress(DNS_AAAA_DATA data)
    {
        public uint IpAddress;
    }
        var addressBytes = new byte[16];
        addressBytes[0] = (byte)(data.Ip6Address0 & 0x000000FF);
        addressBytes[1] = (byte)((data.Ip6Address0 & 0x0000FF00) >> 8);
        addressBytes[2] = (byte)((data.Ip6Address0 & 0x00FF0000) >> 16);
        addressBytes[3] = (byte)((data.Ip6Address0 & 0xFF000000) >> 24);
        addressBytes[4] = (byte)(data.Ip6Address1 & 0x000000FF);
        addressBytes[5] = (byte)((data.Ip6Address1 & 0x0000FF00) >> 8);
        addressBytes[6] = (byte)((data.Ip6Address1 & 0x00FF0000) >> 16);
        addressBytes[7] = (byte)((data.Ip6Address1 & 0xFF000000) >> 24);
        addressBytes[8] = (byte)(data.Ip6Address2 & 0x000000FF);
        addressBytes[9] = (byte)((data.Ip6Address2 & 0x0000FF00) >> 8);
        addressBytes[10] = (byte)((data.Ip6Address2 & 0x00FF0000) >> 16);
        addressBytes[11] = (byte)((data.Ip6Address2 & 0xFF000000) >> 24);
        addressBytes[12] = (byte)(data.Ip6Address3 & 0x000000FF);
        addressBytes[13] = (byte)((data.Ip6Address3 & 0x0000FF00) >> 8);
        addressBytes[14] = (byte)((data.Ip6Address3 & 0x00FF0000) >> 16);
        addressBytes[15] = (byte)((data.Ip6Address3 & 0xFF000000) >> 24);

    [StructLayout(LayoutKind.Sequential)]
    private struct DNS_PTR_DATA
    {
        public IntPtr NameHost;
        return new IPAddress(addressBytes);
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct DNS_MX_DATA
    {
        public IntPtr NameExchange;
        public ushort Preference;
        public ushort Pad;
    }
    [DllImport("dnsapi", EntryPoint = "DnsQueryEx", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
    private static extern int DnsQueryEx(IntPtr queryRequest, IntPtr queryResults, IntPtr cancelHandle);

    [StructLayout(LayoutKind.Sequential)]
    private struct DNS_TXT_DATA
    {
        public uint StringCount;
        public IntPtr StringArray;
    }
    [DllImport("dnsapi", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern void DnsRecordListFree(IntPtr recordList, DNS_FREE_TYPE freeType);

    [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;
    }

    [StructLayout(LayoutKind.Sequential)]
    private class DNS_ADDR
    private struct DNS_QUERY_REQUEST
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = DnsAddrMaxSockaddrLength)]
        private byte[] maxSa;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        private uint[] dnsAddrUserDword;

        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;
        }
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    private class SockAddrIn6
    private struct DNS_RECORD_FLAGS
    {
        private short sin6Family;
        private ushort sin6Port;
        private ulong sin6FlowInfo;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = IpAddressV6LengthBytes)]
        private byte[] sin6Addr;
        private ulong sin6ScopeId;
        internal uint Data;

        public SockAddrIn6()
        public uint Section
        {
        this.sin6Family = AFInet;
        this.sin6Port = 0;
        this.sin6Addr = new byte[IpAddressV6LengthBytes];
        this.sin6ScopeId = 0;
        get { return this.Data & 0x3u; }
        set { this.Data = (this.Data & ~0x3u) | (value & 0x3u); }
        }

        public short Sin6Family
        public uint Delete
        {
        get
        {
            return this.sin6Family;
        }

        set
        {
            this.sin6Family = value;
        }
        get { return (this.Data >> 2) & 0x1u; }
        set { this.Data = (this.Data & ~(0x1u << 2)) | (value & 0x1u) << 2; }
        }

        public ushort Sin6Port
        public uint CharSet
        {
        get
        {
            return this.sin6Port;
        }

        set
        {
            this.sin6Port = value;
        }
        get { return (this.Data >> 3) & 0x3u; }
        set { this.Data = (this.Data & ~(0x3u << 3)) | (value & 0x3u) << 3; }
        }

        public ulong Sin6FlowInfo
        public uint Unused
        {
        get
        {
            return this.sin6FlowInfo;
        }

        set
        {
            this.sin6FlowInfo = value;
        }
        get { return (this.Data >> 5) & 0x7u; }
        set { this.Data = (this.Data & ~(0x7u << 5)) | (value & 0x7u) << 5; }
        }

        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;
    }

    [StructLayout(LayoutKind.Sequential)]
    private class DNS_ADDR
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = DnsAddrMaxSockaddrLength)]
        private byte[] maxSa;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        private uint[] dnsAddrUserDword;

        public DNS_ADDR()
        {
        this.maxSa = new byte[DnsAddrMaxSockaddrLength];
        this.dnsAddrUserDword = new uint[8];
        }

        public byte[] MaxSa
        {
        get
        {
            return this.maxSa;
        }
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    private class SockAddrIn
    {
        private short sinFamily;
        private ushort sinPort;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = IpAddressV4LengthBytes)]
        private byte[] sinAddr;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        private byte[] sinZero;

        public SockAddrIn()
        {
        this.sinFamily = 0;
        this.sinPort = 0;
        this.sinAddr = new byte[IpAddressV4LengthBytes];
        this.sinZero = new byte[8];
        }

        public short SinFamily
        {
        get
        {
            return this.sinFamily;
        }

        set
        {
            this.sinFamily = value;
        }
        }

        public ushort SinPort
        {
        get
        {
            return this.sinPort;
        }

        set
        {
            this.sinPort = value;
        }
        }

        public byte[] SinAddr
        {
        get
        {
            return this.sinAddr;
        }
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    private class SockAddrIn6
    {
        private short sin6Family;
        private ushort sin6Port;
        private ulong sin6FlowInfo;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = IpAddressV6LengthBytes)]
        private byte[] sin6Addr;
        private ulong sin6ScopeId;

        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;
        }
        }
    }
    }

Documentation
DnsQueryEx on MSDN

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).

 
Access PInvoke.net directly from VS:
Terms of Use
Edit This Page
Find References
Show Printable Version
Revisions