Module: wine Branch: refs/heads/master Commit: 02ca30e8f9af333db53148cce2ba1ba9aae228d4 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=02ca30e8f9af333db53148cc...
Author: Hans Leidekker hans@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