Hans Leidekker : dnsapi: Fall back to a netbios query when a dns query fails.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jun 1 06:48:32 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: 02ca30e8f9af333db53148cce2ba1ba9aae228d4
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=02ca30e8f9af333db53148cce2ba1ba9aae228d4

Author: Hans Leidekker <hans at it.vu.nl>
Date:   Wed May 31 15:46:58 2006 +0200

dnsapi: Fall back to a netbios query when a dns query fails.

---

 dlls/dnsapi/Makefile.in |    2 +
 dlls/dnsapi/query.c     |   78 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 1 deletions(-)

diff --git a/dlls/dnsapi/Makefile.in b/dlls/dnsapi/Makefile.in
index 2575b86..cad167e 100644
--- a/dlls/dnsapi/Makefile.in
+++ b/dlls/dnsapi/Makefile.in
@@ -4,7 +4,7 @@ SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = dnsapi.dll
 IMPORTLIB = libdnsapi.$(IMPLIBEXT)
-IMPORTS   = kernel32
+IMPORTS   = netapi32 kernel32
 EXTRALIBS = $(LIBUNICODE) @RESOLVLIBS@
 
 C_SRCS = \
diff --git a/dlls/dnsapi/query.c b/dlls/dnsapi/query.c
index 3af529e..f7f9271 100644
--- a/dlls/dnsapi/query.c
+++ b/dlls/dnsapi/query.c
@@ -44,6 +44,7 @@ #include "winbase.h"
 #include "winerror.h"
 #include "winnls.h"
 #include "windns.h"
+#include "nb30.h"
 
 #include "dnsapi.h"
 
@@ -472,6 +473,76 @@ static DNS_STATUS dns_copy_record( ns_ms
     return ERROR_SUCCESS;
 }
 
+#define DEFAULT_TTL  1200
+
+static DNS_STATUS dns_do_query_netbios( PCSTR name, DNS_RECORDA **recp )
+{
+    NCB ncb;
+    UCHAR ret;
+    DNS_RRSET rrset;
+    FIND_NAME_BUFFER *buffer;
+    FIND_NAME_HEADER *header;
+    DNS_RECORDA *record = NULL;
+    unsigned int i, len;
+
+    len = strlen( name );
+    if (len >= NCBNAMSZ) return DNS_ERROR_RCODE_NAME_ERROR;
+
+    DNS_RRSET_INIT( rrset );
+
+    memset( &ncb, 0, sizeof(ncb) );
+    ncb.ncb_command = NCBFINDNAME;
+
+    memset( ncb.ncb_callname, ' ', sizeof(ncb.ncb_callname) );
+    memcpy( ncb.ncb_callname, name, len );
+    ncb.ncb_callname[NCBNAMSZ] = '\0';
+
+    ret = Netbios( &ncb );
+    if (ret != NRC_GOODRET) return ERROR_INVALID_NAME;
+
+    header = (FIND_NAME_HEADER *)ncb.ncb_buffer;
+    buffer = (FIND_NAME_BUFFER *)((char *)header + sizeof(FIND_NAME_HEADER));
+
+    for (i = 0; i < header->node_count; i++) 
+    {
+        record = dns_zero_alloc( sizeof(DNS_RECORDA) );
+        if (!record)
+        {
+            ret = ERROR_NOT_ENOUGH_MEMORY;
+            goto exit;
+        }
+        else
+        {
+            record->pName = dns_strdup_u( name );
+            if (!record->pName)
+            {
+                ret = ERROR_NOT_ENOUGH_MEMORY;
+                goto exit;
+            }
+
+            record->wType = DNS_TYPE_A;
+            record->Flags.S.Section = DnsSectionAnswer;
+            record->Flags.S.CharSet = DnsCharSetUtf8;
+            record->dwTtl = DEFAULT_TTL;
+
+            /* FIXME: network byte order? */
+            record->Data.A.IpAddress = *(DWORD *)((char *)buffer[i].destination_addr + 2);
+
+            DNS_RRSET_ADD( rrset, (DNS_RECORD *)record );
+        }
+    }
+
+exit:
+    DNS_RRSET_TERMINATE( rrset );
+
+    if (ret != ERROR_SUCCESS)
+        DnsRecordListFree( (DNS_RECORD *)record, DnsFreeRecordList );
+    else
+        *recp = (DNS_RECORDA *)rrset.pFirstRR;
+
+    return ret;
+}
+
 /*  The resolver lock must be held and res_init() must have been
  *  called before calling these three functions.
  */
@@ -636,6 +707,13 @@ #ifdef HAVE_RESOLV
 
     ret = dns_do_query( name, type, options, result );
 
+    if (ret == DNS_ERROR_RCODE_NAME_ERROR && type == DNS_TYPE_A &&
+        !(options & DNS_QUERY_NO_NETBT))
+    {
+        TRACE( "dns lookup failed, trying netbios query\n" );
+        ret = dns_do_query_netbios( name, result );
+    }
+
     UNLOCK_RESOLVER();
 
 #endif




More information about the wine-cvs mailing list