Пример #1
0
            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();
            }
Пример #2
0
            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());
            }