[PATCH 3/5] dnsapi: Move libresolv support to a new Unix library.
Hans Leidekker
hans at codeweavers.com
Tue Mar 30 03:35:28 CDT 2021
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/dnsapi/Makefile.in | 1 +
dlls/dnsapi/dnsapi.h | 19 +-
dlls/dnsapi/libresolv.c | 742 ++++++++++++++++++++++++++++++++++++++++
dlls/dnsapi/main.c | 20 ++
dlls/dnsapi/name.c | 23 +-
dlls/dnsapi/query.c | 582 +------------------------------
dlls/dnsapi/record.c | 66 +---
7 files changed, 809 insertions(+), 644 deletions(-)
create mode 100644 dlls/dnsapi/libresolv.c
diff --git a/dlls/dnsapi/Makefile.in b/dlls/dnsapi/Makefile.in
index d1f66723fc6..a4f80e83fd4 100644
--- a/dlls/dnsapi/Makefile.in
+++ b/dlls/dnsapi/Makefile.in
@@ -4,6 +4,7 @@ IMPORTS = netapi32
EXTRALIBS = $(RESOLV_LIBS)
C_SRCS = \
+ libresolv.c \
main.c \
name.c \
query.c \
diff --git a/dlls/dnsapi/dnsapi.h b/dlls/dnsapi/dnsapi.h
index d0a31ea0981..bcd6a6d5bc3 100644
--- a/dlls/dnsapi/dnsapi.h
+++ b/dlls/dnsapi/dnsapi.h
@@ -18,10 +18,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#ifndef __WINE_CONFIG_H
-# error You must include config.h to use this header
-#endif
-
#include "wine/heap.h"
static inline char *strdup_a( const char *src )
@@ -123,4 +119,17 @@ static inline char *strdup_ua( const char *src )
return dst;
}
-const char *type_to_str( unsigned short ) DECLSPEC_HIDDEN;
+extern const char *type_to_str( unsigned short ) DECLSPEC_HIDDEN;
+
+extern DNS_STATUS CDECL resolv_get_serverlist( IP4_ARRAY *, DWORD * ) DECLSPEC_HIDDEN;
+extern DNS_STATUS CDECL resolv_query( const char *, WORD, DWORD, DNS_RECORDA ** ) DECLSPEC_HIDDEN;
+extern DNS_STATUS CDECL resolv_set_serverlist( const IP4_ARRAY * ) DECLSPEC_HIDDEN;
+
+struct resolv_funcs
+{
+ DNS_STATUS (CDECL *get_serverlist)( IP4_ARRAY *addrs, DWORD *len );
+ DNS_STATUS (CDECL *query)( const char *name, WORD type, DWORD options, DNS_RECORDA **result );
+ DNS_STATUS (CDECL *set_serverlist)( const IP4_ARRAY *addrs );
+};
+
+extern const struct resolv_funcs *resolv_funcs;
diff --git a/dlls/dnsapi/libresolv.c b/dlls/dnsapi/libresolv.c
new file mode 100644
index 00000000000..ac52147af01
--- /dev/null
+++ b/dlls/dnsapi/libresolv.c
@@ -0,0 +1,742 @@
+/*
+ * Unix interface for libresolv
+ *
+ * Copyright 2021 Hans Leidekker for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#if 0
+#pragma makedep unix
+#endif
+
+#include "config.h"
+
+#ifdef HAVE_RESOLV
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#endif
+#ifdef HAVE_RESOLV_H
+# include <resolv.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winternl.h"
+#include "winbase.h"
+#include "winnls.h"
+#include "windns.h"
+
+#include "wine/debug.h"
+#include "wine/heap.h"
+#include "dnsapi.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dnsapi);
+
+static const char *debugstr_type( unsigned short type )
+{
+ const char *str;
+
+ switch (type)
+ {
+#define X(x) case (x): str = #x; break;
+ X(DNS_TYPE_ZERO)
+ X(DNS_TYPE_A)
+ X(DNS_TYPE_NS)
+ X(DNS_TYPE_MD)
+ X(DNS_TYPE_MF)
+ X(DNS_TYPE_CNAME)
+ X(DNS_TYPE_SOA)
+ X(DNS_TYPE_MB)
+ X(DNS_TYPE_MG)
+ X(DNS_TYPE_MR)
+ X(DNS_TYPE_NULL)
+ X(DNS_TYPE_WKS)
+ X(DNS_TYPE_PTR)
+ X(DNS_TYPE_HINFO)
+ X(DNS_TYPE_MINFO)
+ X(DNS_TYPE_MX)
+ X(DNS_TYPE_TEXT)
+ X(DNS_TYPE_RP)
+ X(DNS_TYPE_AFSDB)
+ X(DNS_TYPE_X25)
+ X(DNS_TYPE_ISDN)
+ X(DNS_TYPE_RT)
+ X(DNS_TYPE_NSAP)
+ X(DNS_TYPE_NSAPPTR)
+ X(DNS_TYPE_SIG)
+ X(DNS_TYPE_KEY)
+ X(DNS_TYPE_PX)
+ X(DNS_TYPE_GPOS)
+ X(DNS_TYPE_AAAA)
+ X(DNS_TYPE_LOC)
+ X(DNS_TYPE_NXT)
+ X(DNS_TYPE_EID)
+ X(DNS_TYPE_NIMLOC)
+ X(DNS_TYPE_SRV)
+ X(DNS_TYPE_ATMA)
+ X(DNS_TYPE_NAPTR)
+ X(DNS_TYPE_KX)
+ X(DNS_TYPE_CERT)
+ X(DNS_TYPE_A6)
+ X(DNS_TYPE_DNAME)
+ X(DNS_TYPE_SINK)
+ X(DNS_TYPE_OPT)
+ X(DNS_TYPE_UINFO)
+ X(DNS_TYPE_UID)
+ X(DNS_TYPE_GID)
+ X(DNS_TYPE_UNSPEC)
+ X(DNS_TYPE_ADDRS)
+ X(DNS_TYPE_TKEY)
+ X(DNS_TYPE_TSIG)
+ X(DNS_TYPE_IXFR)
+ X(DNS_TYPE_AXFR)
+ X(DNS_TYPE_MAILB)
+ X(DNS_TYPE_MAILA)
+ X(DNS_TYPE_ANY)
+ X(DNS_TYPE_WINS)
+ X(DNS_TYPE_WINSR)
+#undef X
+ default:
+ return wine_dbg_sprintf( "0x%04x", type );
+ }
+
+ return wine_dbg_sprintf( "%s", str );
+}
+
+static const char *debugstr_section( ns_sect section )
+{
+ switch (section)
+ {
+ case ns_s_qd: return "Question";
+ case ns_s_an: return "Answer";
+ case ns_s_ns: return "Authority";
+ case ns_s_ar: return "Additional";
+ default:
+ return wine_dbg_sprintf( "0x%02x", section );
+ }
+}
+
+/* call res_init() just once because of a bug in Mac OS X 10.4 */
+/* call once per thread on systems that have per-thread _res */
+static void init_resolver( void )
+{
+ if (!(_res.options & RES_INIT)) res_init();
+}
+
+static unsigned long map_options( DWORD options )
+{
+ unsigned long ret = 0;
+
+ if (options == DNS_QUERY_STANDARD)
+ return RES_DEFAULT;
+
+ if (options & DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE)
+ ret |= RES_IGNTC;
+ if (options & DNS_QUERY_USE_TCP_ONLY)
+ ret |= RES_USEVC;
+ if (options & DNS_QUERY_NO_RECURSION)
+ ret &= ~RES_RECURSE;
+ if (options & DNS_QUERY_NO_LOCAL_NAME)
+ ret &= ~RES_DNSRCH;
+ if (options & DNS_QUERY_NO_HOSTS_FILE)
+ ret |= RES_NOALIASES;
+ if (options & DNS_QUERY_TREAT_AS_FQDN)
+ ret &= ~RES_DEFNAMES;
+
+ if (options & DNS_QUERY_DONT_RESET_TTL_VALUES)
+ FIXME( "option DNS_QUERY_DONT_RESET_TTL_VALUES not implemented\n" );
+ if (options & DNS_QUERY_RESERVED)
+ FIXME( "option DNS_QUERY_RESERVED not implemented\n" );
+ if (options & DNS_QUERY_WIRE_ONLY)
+ FIXME( "option DNS_QUERY_WIRE_ONLY not implemented\n" );
+ if (options & DNS_QUERY_NO_WIRE_QUERY)
+ FIXME( "option DNS_QUERY_NO_WIRE_QUERY not implemented\n" );
+ if (options & DNS_QUERY_BYPASS_CACHE)
+ FIXME( "option DNS_QUERY_BYPASS_CACHE not implemented\n" );
+ if (options & DNS_QUERY_RETURN_MESSAGE)
+ FIXME( "option DNS_QUERY_RETURN_MESSAGE not implemented\n" );
+
+ if (options & DNS_QUERY_NO_NETBT)
+ TRACE( "netbios query disabled\n" );
+
+ return ret;
+}
+
+static DNS_STATUS map_error( int error )
+{
+ switch (error)
+ {
+ case ns_r_noerror: return ERROR_SUCCESS;
+ case ns_r_formerr: return DNS_ERROR_RCODE_FORMAT_ERROR;
+ case ns_r_servfail: return DNS_ERROR_RCODE_SERVER_FAILURE;
+ case ns_r_nxdomain: return DNS_ERROR_RCODE_NAME_ERROR;
+ case ns_r_notimpl: return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
+ case ns_r_refused: return DNS_ERROR_RCODE_REFUSED;
+ case ns_r_yxdomain: return DNS_ERROR_RCODE_YXDOMAIN;
+ case ns_r_yxrrset: return DNS_ERROR_RCODE_YXRRSET;
+ case ns_r_nxrrset: return DNS_ERROR_RCODE_NXRRSET;
+ case ns_r_notauth: return DNS_ERROR_RCODE_NOTAUTH;
+ case ns_r_notzone: return DNS_ERROR_RCODE_NOTZONE;
+ default:
+ FIXME( "unmapped error code: %d\n", error );
+ return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
+ }
+}
+
+static DNS_STATUS map_h_errno( int error )
+{
+ switch (error)
+ {
+ case NO_DATA:
+ case HOST_NOT_FOUND: return DNS_ERROR_RCODE_NAME_ERROR;
+ case TRY_AGAIN: return DNS_ERROR_RCODE_SERVER_FAILURE;
+ case NO_RECOVERY: return DNS_ERROR_RCODE_REFUSED;
+#ifdef NETDB_INTERNAL
+ case NETDB_INTERNAL: return DNS_ERROR_RCODE;
+#endif
+ default:
+ FIXME( "unmapped error code: %d\n", error );
+ return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
+ }
+}
+
+DNS_STATUS CDECL resolv_get_serverlist( IP4_ARRAY *addrs, DWORD *len )
+{
+ unsigned int size;
+ int i;
+
+ init_resolver();
+
+ size = FIELD_OFFSET(IP4_ARRAY, AddrArray[_res.nscount]);
+ if (!addrs || *len < size)
+ {
+ *len = size;
+ return ERROR_INSUFFICIENT_BUFFER;
+ }
+
+ addrs->AddrCount = _res.nscount;
+
+ for (i = 0; i < _res.nscount; i++)
+ addrs->AddrArray[i] = _res.nsaddr_list[i].sin_addr.s_addr;
+
+ return ERROR_SUCCESS;
+}
+
+DNS_STATUS CDECL resolv_set_serverlist( const IP4_ARRAY *addrs )
+{
+ int i;
+
+ init_resolver();
+
+ if (!addrs || !addrs->AddrCount) return ERROR_SUCCESS;
+ if (addrs->AddrCount > MAXNS)
+ {
+ WARN( "too many servers: %d only using the first: %d\n",
+ addrs->AddrCount, MAXNS );
+ _res.nscount = MAXNS;
+ }
+ else _res.nscount = addrs->AddrCount;
+
+ for (i = 0; i < _res.nscount; i++)
+ _res.nsaddr_list[i].sin_addr.s_addr = addrs->AddrArray[i];
+
+ return ERROR_SUCCESS;
+}
+
+static char *dname_from_msg( ns_msg msg, const unsigned char *pos )
+{
+ char *str, dname[NS_MAXDNAME] = ".";
+
+ /* returns *compressed* length, ignore it */
+ ns_name_uncompress( ns_msg_base(msg), ns_msg_end(msg), pos, dname, sizeof(dname) );
+
+ if ((str = RtlAllocateHeap( GetProcessHeap(), 0, strlen(dname) + 1 ))) strcpy( str, dname );
+ return str;
+}
+
+static char *str_from_rdata( const unsigned char *rdata )
+{
+ char *str;
+ unsigned int len = rdata[0];
+
+ if ((str = RtlAllocateHeap( GetProcessHeap(), 0, len + 1 )))
+ {
+ memcpy( str, ++rdata, len );
+ str[len] = 0;
+ }
+ return str;
+}
+
+static unsigned int get_record_size( const ns_rr *rr )
+{
+ const unsigned char *pos = rr->rdata;
+ unsigned int num = 0, size = sizeof(DNS_RECORDA);
+
+ switch (rr->type)
+ {
+ case ns_t_key:
+ {
+ pos += sizeof(WORD) + sizeof(BYTE) + sizeof(BYTE);
+ size += rr->rdata + rr->rdlength - pos - 1;
+ break;
+ }
+ case ns_t_sig:
+ {
+ pos += sizeof(PCHAR) + sizeof(WORD) + 2 * sizeof(BYTE);
+ pos += 3 * sizeof(DWORD) + 2 * sizeof(WORD);
+ size += rr->rdata + rr->rdlength - pos - 1;
+ break;
+ }
+ case ns_t_hinfo:
+ case ns_t_isdn:
+ case ns_t_txt:
+ case ns_t_x25:
+ {
+ while (pos[0] && pos < rr->rdata + rr->rdlength)
+ {
+ num++;
+ pos += pos[0] + 1;
+ }
+ size += (num - 1) * sizeof(PCHAR);
+ break;
+ }
+ case ns_t_null:
+ case ns_t_opt:
+ {
+ size += rr->rdlength - 1;
+ break;
+ }
+ case ns_t_nxt:
+ case ns_t_wks:
+ case 0xff01: /* WINS */
+ {
+ FIXME( "unhandled type: %s\n", debugstr_type( rr->type ) );
+ break;
+ }
+ default:
+ break;
+ }
+ return size;
+}
+
+static DNS_STATUS copy_rdata( ns_msg msg, const ns_rr *rr, DNS_RECORDA *r, WORD *dlen )
+{
+ DNS_STATUS ret = ERROR_SUCCESS;
+ const unsigned char *pos = rr->rdata;
+ unsigned int i, size;
+
+ switch (rr->type)
+ {
+ case ns_t_a:
+ {
+ r->Data.A.IpAddress = *(const DWORD *)pos;
+ *dlen = sizeof(DNS_A_DATA);
+ break;
+ }
+ case ns_t_aaaa:
+ {
+ for (i = 0; i < sizeof(IP6_ADDRESS)/sizeof(DWORD); i++)
+ {
+ r->Data.AAAA.Ip6Address.IP6Dword[i] = *(const DWORD *)pos;
+ pos += sizeof(DWORD);
+ }
+
+ *dlen = sizeof(DNS_AAAA_DATA);
+ break;
+ }
+ case ns_t_key:
+ {
+ /* FIXME: byte order? */
+ r->Data.KEY.wFlags = *(const WORD *)pos; pos += sizeof(WORD);
+ r->Data.KEY.chProtocol = *pos++;
+ r->Data.KEY.chAlgorithm = *pos++;
+
+ size = rr->rdata + rr->rdlength - pos;
+
+ for (i = 0; i < size; i++)
+ r->Data.KEY.Key[i] = *pos++;
+
+ *dlen = sizeof(DNS_KEY_DATA) + (size - 1) * sizeof(BYTE);
+ break;
+ }
+ case ns_t_rp:
+ case ns_t_minfo:
+ {
+ r->Data.MINFO.pNameMailbox = dname_from_msg( msg, pos );
+ if (!r->Data.MINFO.pNameMailbox) return ERROR_NOT_ENOUGH_MEMORY;
+
+ if (ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
+ return DNS_ERROR_BAD_PACKET;
+
+ r->Data.MINFO.pNameErrorsMailbox = dname_from_msg( msg, pos );
+ if (!r->Data.MINFO.pNameErrorsMailbox)
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, r->Data.MINFO.pNameMailbox );
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ *dlen = sizeof(DNS_MINFO_DATAA);
+ break;
+ }
+ case ns_t_afsdb:
+ case ns_t_rt:
+ case ns_t_mx:
+ {
+ r->Data.MX.wPreference = ntohs( *(const WORD *)pos );
+ r->Data.MX.pNameExchange = dname_from_msg( msg, pos + sizeof(WORD) );
+ if (!r->Data.MX.pNameExchange) return ERROR_NOT_ENOUGH_MEMORY;
+
+ *dlen = sizeof(DNS_MX_DATAA);
+ break;
+ }
+ case ns_t_null:
+ {
+ r->Data.Null.dwByteCount = rr->rdlength;
+ memcpy( r->Data.Null.Data, rr->rdata, rr->rdlength );
+
+ *dlen = sizeof(DNS_NULL_DATA) + rr->rdlength - 1;
+ break;
+ }
+ case ns_t_opt:
+ {
+ r->Data.OPT.wDataLength = rr->rdlength;
+ r->Data.OPT.wPad = 0;
+ memcpy( r->Data.OPT.Data, rr->rdata, rr->rdlength );
+
+ *dlen = sizeof(DNS_OPT_DATA) + rr->rdlength - 1;
+ break;
+ }
+ case ns_t_cname:
+ case ns_t_ns:
+ case ns_t_mb:
+ case ns_t_md:
+ case ns_t_mf:
+ case ns_t_mg:
+ case ns_t_mr:
+ case ns_t_ptr:
+ {
+ r->Data.PTR.pNameHost = dname_from_msg( msg, pos );
+ if (!r->Data.PTR.pNameHost) return ERROR_NOT_ENOUGH_MEMORY;
+
+ *dlen = sizeof(DNS_PTR_DATAA);
+ break;
+ }
+ case ns_t_sig:
+ {
+ r->Data.SIG.pNameSigner = dname_from_msg( msg, pos );
+ if (!r->Data.SIG.pNameSigner) return ERROR_NOT_ENOUGH_MEMORY;
+
+ if (ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
+ return DNS_ERROR_BAD_PACKET;
+
+ /* FIXME: byte order? */
+ r->Data.SIG.wTypeCovered = *(const WORD *)pos; pos += sizeof(WORD);
+ r->Data.SIG.chAlgorithm = *pos++;
+ r->Data.SIG.chLabelCount = *pos++;
+ r->Data.SIG.dwOriginalTtl = *(const DWORD *)pos; pos += sizeof(DWORD);
+ r->Data.SIG.dwExpiration = *(const DWORD *)pos; pos += sizeof(DWORD);
+ r->Data.SIG.dwTimeSigned = *(const DWORD *)pos; pos += sizeof(DWORD);
+ r->Data.SIG.wKeyTag = *(const WORD *)pos;
+
+ size = rr->rdata + rr->rdlength - pos;
+
+ for (i = 0; i < size; i++)
+ r->Data.SIG.Signature[i] = *pos++;
+
+ *dlen = sizeof(DNS_SIG_DATAA) + (size - 1) * sizeof(BYTE);
+ break;
+ }
+ case ns_t_soa:
+ {
+ r->Data.SOA.pNamePrimaryServer = dname_from_msg( msg, pos );
+ if (!r->Data.SOA.pNamePrimaryServer) return ERROR_NOT_ENOUGH_MEMORY;
+
+ if (ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
+ return DNS_ERROR_BAD_PACKET;
+
+ r->Data.SOA.pNameAdministrator = dname_from_msg( msg, pos );
+ if (!r->Data.SOA.pNameAdministrator)
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, r->Data.SOA.pNamePrimaryServer );
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ if (ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
+ return DNS_ERROR_BAD_PACKET;
+
+ r->Data.SOA.dwSerialNo = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);
+ r->Data.SOA.dwRefresh = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);
+ r->Data.SOA.dwRetry = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);
+ r->Data.SOA.dwExpire = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);
+ r->Data.SOA.dwDefaultTtl = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);
+
+ *dlen = sizeof(DNS_SOA_DATAA);
+ break;
+ }
+ case ns_t_srv:
+ {
+ r->Data.SRV.wPriority = ntohs( *(const WORD *)pos ); pos += sizeof(WORD);
+ r->Data.SRV.wWeight = ntohs( *(const WORD *)pos ); pos += sizeof(WORD);
+ r->Data.SRV.wPort = ntohs( *(const WORD *)pos ); pos += sizeof(WORD);
+
+ r->Data.SRV.pNameTarget = dname_from_msg( msg, pos );
+ if (!r->Data.SRV.pNameTarget) return ERROR_NOT_ENOUGH_MEMORY;
+
+ *dlen = sizeof(DNS_SRV_DATAA);
+ break;
+ }
+ case ns_t_hinfo:
+ case ns_t_isdn:
+ case ns_t_x25:
+ case ns_t_txt:
+ {
+ i = 0;
+ while (pos[0] && pos < rr->rdata + rr->rdlength)
+ {
+ r->Data.TXT.pStringArray[i] = str_from_rdata( pos );
+ if (!r->Data.TXT.pStringArray[i])
+ {
+ while (i > 0) RtlFreeHeap( GetProcessHeap(), 0, r->Data.TXT.pStringArray[--i] );
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ i++;
+ pos += pos[0] + 1;
+ }
+ r->Data.TXT.dwStringCount = i;
+ *dlen = sizeof(DNS_TXT_DATAA) + (i - 1) * sizeof(PCHAR);
+ break;
+ }
+ case ns_t_atma:
+ case ns_t_loc:
+ case ns_t_nxt:
+ case ns_t_tsig:
+ case ns_t_wks:
+ case 0x00f9: /* TKEY */
+ case 0xff01: /* WINS */
+ case 0xff02: /* WINSR */
+ default:
+ FIXME( "unhandled type: %s\n", debugstr_type( rr->type ) );
+ return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
+ }
+
+ return ret;
+}
+
+static inline char *heap_strdup( const char *src )
+{
+ char *dst;
+ if (!src) return NULL;
+ if ((dst = RtlAllocateHeap( GetProcessHeap(), 0, (strlen( src ) + 1) * sizeof(char) ))) strcpy( dst, src );
+ return dst;
+}
+
+static DNS_STATUS copy_record( ns_msg msg, ns_sect section, unsigned short num, DNS_RECORDA **recp )
+{
+ DNS_STATUS ret;
+ DNS_RECORDA *record;
+ WORD dlen;
+ ns_rr rr;
+
+ if (ns_parserr( &msg, section, num, &rr ) < 0)
+ return DNS_ERROR_BAD_PACKET;
+
+ if (!(record = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, get_record_size( &rr ) )))
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ if (!(record->pName = heap_strdup( rr.name )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, record );
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ record->wType = rr.type;
+ record->Flags.S.Section = section;
+ record->Flags.S.CharSet = DnsCharSetUtf8;
+ record->dwTtl = rr.ttl;
+
+ if ((ret = copy_rdata( msg, &rr, record, &dlen )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, record->pName );
+ RtlFreeHeap( GetProcessHeap(), 0, record );
+ return ret;
+ }
+ record->wDataLength = dlen;
+ *recp = record;
+
+ TRACE( "found %s record in %s section\n", debugstr_type( rr.type ), debugstr_section( section ) );
+ return ERROR_SUCCESS;
+}
+
+static void free_record_list( DNS_RECORD *list )
+{
+ DNS_RECORD *r, *next;
+ unsigned int i;
+
+ for (r = list; (list = r); r = next)
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, r->pName );
+
+ switch (r->wType)
+ {
+ case DNS_TYPE_HINFO:
+ case DNS_TYPE_ISDN:
+ case DNS_TYPE_TEXT:
+ case DNS_TYPE_X25:
+ {
+ for (i = 0; i < r->Data.TXT.dwStringCount; i++)
+ RtlFreeHeap( GetProcessHeap(), 0, r->Data.TXT.pStringArray[i] );
+ break;
+ }
+ case DNS_TYPE_MINFO:
+ case DNS_TYPE_RP:
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, r->Data.MINFO.pNameMailbox );
+ RtlFreeHeap( GetProcessHeap(), 0, r->Data.MINFO.pNameErrorsMailbox );
+ break;
+ }
+ case DNS_TYPE_AFSDB:
+ case DNS_TYPE_RT:
+ case DNS_TYPE_MX:
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, r->Data.MX.pNameExchange );
+ break;
+ }
+ case DNS_TYPE_NXT:
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, r->Data.NXT.pNameNext );
+ break;
+ }
+ case DNS_TYPE_CNAME:
+ case DNS_TYPE_MB:
+ case DNS_TYPE_MD:
+ case DNS_TYPE_MF:
+ case DNS_TYPE_MG:
+ case DNS_TYPE_MR:
+ case DNS_TYPE_NS:
+ case DNS_TYPE_PTR:
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, r->Data.PTR.pNameHost );
+ break;
+ }
+ case DNS_TYPE_SIG:
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, r->Data.SIG.pNameSigner );
+ break;
+ }
+ case DNS_TYPE_SOA:
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, r->Data.SOA.pNamePrimaryServer );
+ RtlFreeHeap( GetProcessHeap(), 0, r->Data.SOA.pNameAdministrator );
+ break;
+ }
+ case DNS_TYPE_SRV:
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, r->Data.SRV.pNameTarget );
+ break;
+ }
+ default: break;
+ }
+
+ next = r->pNext;
+ RtlFreeHeap( GetProcessHeap(), 0, r );
+ }
+}
+
+#define DNS_MAX_PACKET_SIZE 4096
+DNS_STATUS CDECL resolv_query( const char *name, WORD type, DWORD options, DNS_RECORDA **result )
+{
+ DNS_STATUS ret = DNS_ERROR_RCODE_NOT_IMPLEMENTED;
+ unsigned int i, num;
+ unsigned char answer[DNS_MAX_PACKET_SIZE];
+ ns_sect sections[] = { ns_s_an, ns_s_ar };
+ ns_msg msg;
+ DNS_RECORDA *record = NULL;
+ DNS_RRSET rrset;
+ int len;
+
+ DNS_RRSET_INIT( rrset );
+
+ init_resolver();
+ _res.options |= map_options( options );
+
+ if ((len = res_query( name, ns_c_in, type, answer, sizeof(answer) )) < 0)
+ {
+ ret = map_h_errno( h_errno );
+ goto exit;
+ }
+
+ if (ns_initparse( answer, len, &msg ) < 0)
+ {
+ ret = DNS_ERROR_BAD_PACKET;
+ goto exit;
+ }
+
+#define RCODE_MASK 0x0f
+ if ((msg._flags & RCODE_MASK) != ns_r_noerror)
+ {
+ ret = map_error( msg._flags & RCODE_MASK );
+ goto exit;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(sections); i++)
+ {
+ for (num = 0; num < ns_msg_count( msg, sections[i] ); num++)
+ {
+ ret = copy_record( msg, sections[i], num, &record );
+ if (ret != ERROR_SUCCESS) goto exit;
+
+ DNS_RRSET_ADD( rrset, (DNS_RECORD *)record );
+ }
+ }
+
+exit:
+ DNS_RRSET_TERMINATE( rrset );
+
+ if (ret != ERROR_SUCCESS)
+ free_record_list( rrset.pFirstRR );
+ else
+ *result = (DNS_RECORDA *)rrset.pFirstRR;
+
+ return ret;
+}
+
+static const struct resolv_funcs funcs =
+{
+ resolv_get_serverlist,
+ resolv_query,
+ resolv_set_serverlist
+};
+
+NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
+{
+ if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS;
+ *(const struct resolv_funcs **)ptr_out = &funcs;
+ return STATUS_SUCCESS;
+}
+
+#endif /* HAVE_RESOLV */
diff --git a/dlls/dnsapi/main.c b/dlls/dnsapi/main.c
index 4ab294c7c07..f83a54d1469 100644
--- a/dlls/dnsapi/main.c
+++ b/dlls/dnsapi/main.c
@@ -22,6 +22,7 @@
#include <stdarg.h>
#include "windef.h"
+#include "winternl.h"
#include "winbase.h"
#include "winerror.h"
#include "windns.h"
@@ -30,6 +31,25 @@
WINE_DEFAULT_DEBUG_CHANNEL(dnsapi);
+const struct resolv_funcs *resolv_funcs = NULL;
+
+BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
+{
+ TRACE( "(%p,%u,%p)\n", hinst, reason, reserved );
+
+ switch (reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls( hinst );
+ if (__wine_init_unix_lib( hinst, reason, NULL, &resolv_funcs ))
+ ERR( "No libresolv support, expect problems\n" );
+ break;
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
/******************************************************************************
* DnsAcquireContextHandle_A [DNSAPI.@]
*
diff --git a/dlls/dnsapi/name.c b/dlls/dnsapi/name.c
index 9404200e443..4f4ba507cac 100644
--- a/dlls/dnsapi/name.c
+++ b/dlls/dnsapi/name.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2006 Matthew Kehrer
* Copyright (C) 2006 Hans Leidekker
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -19,30 +19,15 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-#include "wine/debug.h"
-#include "wine/unicode.h"
-
#include <stdarg.h>
-#include <sys/types.h>
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-# undef NOERROR
-#endif
-#ifdef HAVE_RESOLV_H
-# include <resolv.h>
-#endif
-
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winnls.h"
#include "windns.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
#include "dnsapi.h"
WINE_DEFAULT_DEBUG_CHANNEL(dnsapi);
@@ -81,7 +66,7 @@ BOOL WINAPI DnsNameCompare_W( PCWSTR name1, PCWSTR name2 )
if (!name1 && !name2) return TRUE;
if (!name1 || !name2) return FALSE;
-
+
p = name1 + lstrlenW( name1 ) - 1;
q = name2 + lstrlenW( name2 ) - 1;
diff --git a/dlls/dnsapi/query.c b/dlls/dnsapi/query.c
index 3bef65e9731..a7ae77148be 100644
--- a/dlls/dnsapi/query.c
+++ b/dlls/dnsapi/query.c
@@ -2,7 +2,7 @@
* DNS support
*
* Copyright (C) 2006 Hans Leidekker
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -18,28 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-#include "wine/port.h"
-#include "wine/debug.h"
-
#include <stdarg.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#endif
-#ifdef HAVE_RESOLV_H
-# include <resolv.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
@@ -47,438 +26,11 @@
#include "windns.h"
#include "nb30.h"
+#include "wine/debug.h"
#include "dnsapi.h"
WINE_DEFAULT_DEBUG_CHANNEL(dnsapi);
-#ifdef HAVE_RESOLV
-
-/* call res_init() just once because of a bug in Mac OS X 10.4 */
-/* call once per thread on systems that have per-thread _res */
-static void initialise_resolver( void )
-{
- if ((_res.options & RES_INIT) == 0)
- res_init();
-}
-
-static const char *section_to_str( ns_sect section )
-{
- switch (section)
- {
- case ns_s_qd: return "Question";
- case ns_s_an: return "Answer";
- case ns_s_ns: return "Authority";
- case ns_s_ar: return "Additional";
- default:
- {
- static char tmp[11];
- FIXME( "unknown section: 0x%02x\n", section );
- sprintf( tmp, "0x%02x", section );
- return tmp;
- }
- }
-}
-
-static unsigned long map_options( DWORD options )
-{
- unsigned long ret = 0;
-
- if (options == DNS_QUERY_STANDARD)
- return RES_DEFAULT;
-
- if (options & DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE)
- ret |= RES_IGNTC;
- if (options & DNS_QUERY_USE_TCP_ONLY)
- ret |= RES_USEVC;
- if (options & DNS_QUERY_NO_RECURSION)
- ret &= ~RES_RECURSE;
- if (options & DNS_QUERY_NO_LOCAL_NAME)
- ret &= ~RES_DNSRCH;
- if (options & DNS_QUERY_NO_HOSTS_FILE)
- ret |= RES_NOALIASES;
- if (options & DNS_QUERY_TREAT_AS_FQDN)
- ret &= ~RES_DEFNAMES;
-
- if (options & DNS_QUERY_DONT_RESET_TTL_VALUES)
- FIXME( "option DNS_QUERY_DONT_RESET_TTL_VALUES not implemented\n" );
- if (options & DNS_QUERY_RESERVED)
- FIXME( "option DNS_QUERY_RESERVED not implemented\n" );
- if (options & DNS_QUERY_WIRE_ONLY)
- FIXME( "option DNS_QUERY_WIRE_ONLY not implemented\n" );
- if (options & DNS_QUERY_NO_WIRE_QUERY)
- FIXME( "option DNS_QUERY_NO_WIRE_QUERY not implemented\n" );
- if (options & DNS_QUERY_BYPASS_CACHE)
- FIXME( "option DNS_QUERY_BYPASS_CACHE not implemented\n" );
- if (options & DNS_QUERY_RETURN_MESSAGE)
- FIXME( "option DNS_QUERY_RETURN_MESSAGE not implemented\n" );
-
- if (options & DNS_QUERY_NO_NETBT)
- TRACE( "netbios query disabled\n" );
-
- return ret;
-}
-
-static DNS_STATUS map_error( int error )
-{
- switch (error)
- {
- case ns_r_noerror: return ERROR_SUCCESS;
- case ns_r_formerr: return DNS_ERROR_RCODE_FORMAT_ERROR;
- case ns_r_servfail: return DNS_ERROR_RCODE_SERVER_FAILURE;
- case ns_r_nxdomain: return DNS_ERROR_RCODE_NAME_ERROR;
- case ns_r_notimpl: return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
- case ns_r_refused: return DNS_ERROR_RCODE_REFUSED;
- case ns_r_yxdomain: return DNS_ERROR_RCODE_YXDOMAIN;
- case ns_r_yxrrset: return DNS_ERROR_RCODE_YXRRSET;
- case ns_r_nxrrset: return DNS_ERROR_RCODE_NXRRSET;
- case ns_r_notauth: return DNS_ERROR_RCODE_NOTAUTH;
- case ns_r_notzone: return DNS_ERROR_RCODE_NOTZONE;
- default:
- FIXME( "unmapped error code: %d\n", error );
- return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
- }
-}
-
-static DNS_STATUS map_h_errno( int error )
-{
- switch (error)
- {
- case NO_DATA:
- case HOST_NOT_FOUND: return DNS_ERROR_RCODE_NAME_ERROR;
- case TRY_AGAIN: return DNS_ERROR_RCODE_SERVER_FAILURE;
- case NO_RECOVERY: return DNS_ERROR_RCODE_REFUSED;
-#ifdef NETDB_INTERNAL
- case NETDB_INTERNAL: return DNS_ERROR_RCODE;
-#endif
- default:
- FIXME( "unmapped error code: %d\n", error );
- return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
- }
-}
-
-static char *dname_from_msg( ns_msg msg, const unsigned char *pos )
-{
- int len;
- char *str, dname[NS_MAXDNAME] = ".";
-
- /* returns *compressed* length, ignore it */
- ns_name_uncompress( ns_msg_base(msg), ns_msg_end(msg), pos, dname, sizeof(dname) );
-
- len = strlen( dname );
- str = heap_alloc( len + 1 );
- if (str) strcpy( str, dname );
- return str;
-}
-
-static char *str_from_rdata( const unsigned char *rdata )
-{
- char *str;
- unsigned int len = rdata[0];
-
- str = heap_alloc( len + 1 );
- if (str)
- {
- memcpy( str, ++rdata, len );
- str[len] = '\0';
- }
- return str;
-}
-
-static unsigned int get_record_size( const ns_rr *rr )
-{
- const unsigned char *pos = rr->rdata;
- unsigned int num = 0, size = sizeof(DNS_RECORDA);
-
- switch (rr->type)
- {
- case ns_t_key:
- {
- pos += sizeof(WORD) + sizeof(BYTE) + sizeof(BYTE);
- size += rr->rdata + rr->rdlength - pos - 1;
- break;
- }
- case ns_t_sig:
- {
- pos += sizeof(PCHAR) + sizeof(WORD) + 2 * sizeof(BYTE);
- pos += 3 * sizeof(DWORD) + 2 * sizeof(WORD);
- size += rr->rdata + rr->rdlength - pos - 1;
- break;
- }
- case ns_t_hinfo:
- case ns_t_isdn:
- case ns_t_txt:
- case ns_t_x25:
- {
- while (pos[0] && pos < rr->rdata + rr->rdlength)
- {
- num++;
- pos += pos[0] + 1;
- }
- size += (num - 1) * sizeof(PCHAR);
- break;
- }
- case ns_t_null:
- case ns_t_opt:
- {
- size += rr->rdlength - 1;
- break;
- }
- case ns_t_nxt:
- case ns_t_wks:
- case 0xff01: /* WINS */
- {
- FIXME( "unhandled type: %s\n", type_to_str( rr->type ) );
- break;
- }
- default:
- break;
- }
- return size;
-}
-
-static DNS_STATUS copy_rdata( ns_msg msg, const ns_rr *rr, DNS_RECORDA *r, WORD *dlen )
-{
- DNS_STATUS ret = ERROR_SUCCESS;
- const unsigned char *pos = rr->rdata;
- unsigned int i, size;
-
- switch (rr->type)
- {
- case ns_t_a:
- {
- r->Data.A.IpAddress = *(const DWORD *)pos;
- *dlen = sizeof(DNS_A_DATA);
- break;
- }
- case ns_t_aaaa:
- {
- for (i = 0; i < sizeof(IP6_ADDRESS)/sizeof(DWORD); i++)
- {
- r->Data.AAAA.Ip6Address.IP6Dword[i] = *(const DWORD *)pos;
- pos += sizeof(DWORD);
- }
-
- *dlen = sizeof(DNS_AAAA_DATA);
- break;
- }
- case ns_t_key:
- {
- /* FIXME: byte order? */
- r->Data.KEY.wFlags = *(const WORD *)pos; pos += sizeof(WORD);
- r->Data.KEY.chProtocol = *pos++;
- r->Data.KEY.chAlgorithm = *pos++;
-
- size = rr->rdata + rr->rdlength - pos;
-
- for (i = 0; i < size; i++)
- r->Data.KEY.Key[i] = *pos++;
-
- *dlen = sizeof(DNS_KEY_DATA) + (size - 1) * sizeof(BYTE);
- break;
- }
- case ns_t_rp:
- case ns_t_minfo:
- {
- r->Data.MINFO.pNameMailbox = dname_from_msg( msg, pos );
- if (!r->Data.MINFO.pNameMailbox) return ERROR_NOT_ENOUGH_MEMORY;
-
- if (ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
- return DNS_ERROR_BAD_PACKET;
-
- r->Data.MINFO.pNameErrorsMailbox = dname_from_msg( msg, pos );
- if (!r->Data.MINFO.pNameErrorsMailbox)
- {
- heap_free( r->Data.MINFO.pNameMailbox );
- return ERROR_NOT_ENOUGH_MEMORY;
- }
-
- *dlen = sizeof(DNS_MINFO_DATAA);
- break;
- }
- case ns_t_afsdb:
- case ns_t_rt:
- case ns_t_mx:
- {
- r->Data.MX.wPreference = ntohs( *(const WORD *)pos );
- r->Data.MX.pNameExchange = dname_from_msg( msg, pos + sizeof(WORD) );
- if (!r->Data.MX.pNameExchange) return ERROR_NOT_ENOUGH_MEMORY;
-
- *dlen = sizeof(DNS_MX_DATAA);
- break;
- }
- case ns_t_null:
- {
- r->Data.Null.dwByteCount = rr->rdlength;
- memcpy( r->Data.Null.Data, rr->rdata, rr->rdlength );
-
- *dlen = sizeof(DNS_NULL_DATA) + rr->rdlength - 1;
- break;
- }
- case ns_t_opt:
- {
- r->Data.OPT.wDataLength = rr->rdlength;
- r->Data.OPT.wPad = 0;
- memcpy( r->Data.OPT.Data, rr->rdata, rr->rdlength );
-
- *dlen = sizeof(DNS_OPT_DATA) + rr->rdlength - 1;
- break;
- }
- case ns_t_cname:
- case ns_t_ns:
- case ns_t_mb:
- case ns_t_md:
- case ns_t_mf:
- case ns_t_mg:
- case ns_t_mr:
- case ns_t_ptr:
- {
- r->Data.PTR.pNameHost = dname_from_msg( msg, pos );
- if (!r->Data.PTR.pNameHost) return ERROR_NOT_ENOUGH_MEMORY;
-
- *dlen = sizeof(DNS_PTR_DATAA);
- break;
- }
- case ns_t_sig:
- {
- r->Data.SIG.pNameSigner = dname_from_msg( msg, pos );
- if (!r->Data.SIG.pNameSigner) return ERROR_NOT_ENOUGH_MEMORY;
-
- if (ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
- return DNS_ERROR_BAD_PACKET;
-
- /* FIXME: byte order? */
- r->Data.SIG.wTypeCovered = *(const WORD *)pos; pos += sizeof(WORD);
- r->Data.SIG.chAlgorithm = *pos++;
- r->Data.SIG.chLabelCount = *pos++;
- r->Data.SIG.dwOriginalTtl = *(const DWORD *)pos; pos += sizeof(DWORD);
- r->Data.SIG.dwExpiration = *(const DWORD *)pos; pos += sizeof(DWORD);
- r->Data.SIG.dwTimeSigned = *(const DWORD *)pos; pos += sizeof(DWORD);
- r->Data.SIG.wKeyTag = *(const WORD *)pos;
-
- size = rr->rdata + rr->rdlength - pos;
-
- for (i = 0; i < size; i++)
- r->Data.SIG.Signature[i] = *pos++;
-
- *dlen = sizeof(DNS_SIG_DATAA) + (size - 1) * sizeof(BYTE);
- break;
- }
- case ns_t_soa:
- {
- r->Data.SOA.pNamePrimaryServer = dname_from_msg( msg, pos );
- if (!r->Data.SOA.pNamePrimaryServer) return ERROR_NOT_ENOUGH_MEMORY;
-
- if (ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
- return DNS_ERROR_BAD_PACKET;
-
- r->Data.SOA.pNameAdministrator = dname_from_msg( msg, pos );
- if (!r->Data.SOA.pNameAdministrator)
- {
- heap_free( r->Data.SOA.pNamePrimaryServer );
- return ERROR_NOT_ENOUGH_MEMORY;
- }
-
- if (ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
- return DNS_ERROR_BAD_PACKET;
-
- r->Data.SOA.dwSerialNo = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);
- r->Data.SOA.dwRefresh = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);
- r->Data.SOA.dwRetry = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);
- r->Data.SOA.dwExpire = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);
- r->Data.SOA.dwDefaultTtl = ntohl( *(const DWORD *)pos ); pos += sizeof(DWORD);
-
- *dlen = sizeof(DNS_SOA_DATAA);
- break;
- }
- case ns_t_srv:
- {
- r->Data.SRV.wPriority = ntohs( *(const WORD *)pos ); pos += sizeof(WORD);
- r->Data.SRV.wWeight = ntohs( *(const WORD *)pos ); pos += sizeof(WORD);
- r->Data.SRV.wPort = ntohs( *(const WORD *)pos ); pos += sizeof(WORD);
-
- r->Data.SRV.pNameTarget = dname_from_msg( msg, pos );
- if (!r->Data.SRV.pNameTarget) return ERROR_NOT_ENOUGH_MEMORY;
-
- *dlen = sizeof(DNS_SRV_DATAA);
- break;
- }
- case ns_t_hinfo:
- case ns_t_isdn:
- case ns_t_x25:
- case ns_t_txt:
- {
- i = 0;
- while (pos[0] && pos < rr->rdata + rr->rdlength)
- {
- r->Data.TXT.pStringArray[i] = str_from_rdata( pos );
- if (!r->Data.TXT.pStringArray[i])
- {
- while (i > 0) heap_free( r->Data.TXT.pStringArray[--i] );
- return ERROR_NOT_ENOUGH_MEMORY;
- }
- i++;
- pos += pos[0] + 1;
- }
- r->Data.TXT.dwStringCount = i;
- *dlen = sizeof(DNS_TXT_DATAA) + (i - 1) * sizeof(PCHAR);
- break;
- }
- case ns_t_atma:
- case ns_t_loc:
- case ns_t_nxt:
- case ns_t_tsig:
- case ns_t_wks:
- case 0x00f9: /* TKEY */
- case 0xff01: /* WINS */
- case 0xff02: /* WINSR */
- default:
- FIXME( "unhandled type: %s\n", type_to_str( rr->type ) );
- return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
- }
-
- return ret;
-}
-
-static DNS_STATUS copy_record( ns_msg msg, ns_sect section,
- unsigned short num, DNS_RECORDA **recp )
-{
- DNS_STATUS ret;
- DNS_RECORDA *record;
- WORD dlen;
- ns_rr rr;
-
- if (ns_parserr( &msg, section, num, &rr ) < 0)
- return DNS_ERROR_BAD_PACKET;
-
- if (!(record = heap_alloc_zero( get_record_size( &rr ) )))
- return ERROR_NOT_ENOUGH_MEMORY;
-
- record->pName = strdup_u( rr.name );
- if (!record->pName)
- {
- heap_free( record );
- return ERROR_NOT_ENOUGH_MEMORY;
- }
-
- record->wType = rr.type;
- record->Flags.S.Section = section;
- record->Flags.S.CharSet = DnsCharSetUtf8;
- record->dwTtl = rr.ttl;
-
- if ((ret = copy_rdata( msg, &rr, record, &dlen )))
- {
- heap_free( record->pName );
- heap_free( record );
- return ret;
- }
- record->wDataLength = dlen;
- *recp = record;
-
- TRACE( "found %s record in %s section\n",
- type_to_str( rr.type ), section_to_str( section ) );
- return ERROR_SUCCESS;
-}
-
#define DEFAULT_TTL 1200
static DNS_STATUS do_query_netbios( PCSTR name, DNS_RECORDA **recp )
@@ -510,7 +62,7 @@ static DNS_STATUS do_query_netbios( PCSTR name, DNS_RECORDA **recp )
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++)
+ for (i = 0; i < header->node_count; i++)
{
record = heap_alloc_zero( sizeof(DNS_RECORDA) );
if (!record)
@@ -551,107 +103,6 @@ exit:
return status;
}
-/* res_init() must have been called before calling these three functions.
- */
-static DNS_STATUS set_serverlist( const IP4_ARRAY *addrs )
-{
- int i;
-
- if (!addrs || !addrs->AddrCount) return ERROR_SUCCESS;
- if (addrs->AddrCount > MAXNS)
- {
- WARN( "too many servers: %d only using the first: %d\n",
- addrs->AddrCount, MAXNS );
- _res.nscount = MAXNS;
- }
- else _res.nscount = addrs->AddrCount;
-
- for (i = 0; i < _res.nscount; i++)
- _res.nsaddr_list[i].sin_addr.s_addr = addrs->AddrArray[i];
-
- return ERROR_SUCCESS;
-}
-
-static DNS_STATUS get_serverlist( PIP4_ARRAY addrs, PDWORD len )
-{
- unsigned int size;
- int i;
-
- size = FIELD_OFFSET(IP4_ARRAY, AddrArray[_res.nscount]);
- if (!addrs || *len < size)
- {
- *len = size;
- return ERROR_INSUFFICIENT_BUFFER;
- }
-
- addrs->AddrCount = _res.nscount;
-
- for (i = 0; i < _res.nscount; i++)
- addrs->AddrArray[i] = _res.nsaddr_list[i].sin_addr.s_addr;
-
- return ERROR_SUCCESS;
-}
-
-#define DNS_MAX_PACKET_SIZE 4096
-static DNS_STATUS do_query( PCSTR name, WORD type, DWORD options, PDNS_RECORDA *result )
-{
- DNS_STATUS ret = DNS_ERROR_RCODE_NOT_IMPLEMENTED;
-
- unsigned int i, num;
- unsigned char answer[DNS_MAX_PACKET_SIZE];
- ns_sect sections[] = { ns_s_an, ns_s_ar };
- ns_msg msg;
-
- DNS_RECORDA *record = NULL;
- DNS_RRSET rrset;
- int len;
-
- DNS_RRSET_INIT( rrset );
-
- len = res_query( name, ns_c_in, type, answer, sizeof(answer) );
- if (len < 0)
- {
- ret = map_h_errno( h_errno );
- goto exit;
- }
-
- if (ns_initparse( answer, len, &msg ) < 0)
- {
- ret = DNS_ERROR_BAD_PACKET;
- goto exit;
- }
-
-#define RCODE_MASK 0x0f
- if ((msg._flags & RCODE_MASK) != ns_r_noerror)
- {
- ret = map_error( msg._flags & RCODE_MASK );
- goto exit;
- }
-
- for (i = 0; i < ARRAY_SIZE(sections); i++)
- {
- for (num = 0; num < ns_msg_count( msg, sections[i] ); num++)
- {
- ret = copy_record( msg, sections[i], num, &record );
- if (ret != ERROR_SUCCESS) goto exit;
-
- DNS_RRSET_ADD( rrset, (DNS_RECORD *)record );
- }
- }
-
-exit:
- DNS_RRSET_TERMINATE( rrset );
-
- if (ret != ERROR_SUCCESS)
- DnsRecordListFree( rrset.pFirstRR, DnsFreeRecordList );
- else
- *result = (DNS_RECORDA *)rrset.pFirstRR;
-
- return ret;
-}
-
-#endif /* HAVE_RESOLV */
-
static const char *debugstr_query_request(const DNS_QUERY_REQUEST *req)
{
if (!req)
@@ -693,7 +144,7 @@ DNS_STATUS WINAPI DnsQuery_A( PCSTR name, WORD type, DWORD options, PVOID server
nameW = strdup_aw( name );
if (!nameW) return ERROR_NOT_ENOUGH_MEMORY;
- status = DnsQuery_W( nameW, type, options, servers, &resultW, reserved );
+ status = DnsQuery_W( nameW, type, options, servers, &resultW, reserved );
if (status == ERROR_SUCCESS)
{
@@ -716,7 +167,6 @@ DNS_STATUS WINAPI DnsQuery_UTF8( PCSTR name, WORD type, DWORD options, PVOID ser
PDNS_RECORDA *result, PVOID *reserved )
{
DNS_STATUS ret = DNS_ERROR_RCODE_NOT_IMPLEMENTED;
-#ifdef HAVE_RESOLV
TRACE( "(%s,%s,0x%08x,%p,%p,%p)\n", debugstr_a(name), type_to_str( type ),
options, servers, result, reserved );
@@ -724,12 +174,9 @@ DNS_STATUS WINAPI DnsQuery_UTF8( PCSTR name, WORD type, DWORD options, PVOID ser
if (!name || !result)
return ERROR_INVALID_PARAMETER;
- initialise_resolver();
- _res.options |= map_options( options );
-
- if ((ret = set_serverlist( servers ))) return ret;
+ if ((ret = resolv_funcs->set_serverlist( servers ))) return ret;
- ret = do_query( name, type, options, result );
+ ret = resolv_funcs->query( name, type, options, result );
if (ret == DNS_ERROR_RCODE_NAME_ERROR && type == DNS_TYPE_A &&
!(options & DNS_QUERY_NO_NETBT))
@@ -738,7 +185,6 @@ DNS_STATUS WINAPI DnsQuery_UTF8( PCSTR name, WORD type, DWORD options, PVOID ser
ret = do_query_netbios( name, result );
}
-#endif
return ret;
}
@@ -762,7 +208,7 @@ DNS_STATUS WINAPI DnsQuery_W( PCWSTR name, WORD type, DWORD options, PVOID serve
nameU = strdup_wu( name );
if (!nameU) return ERROR_NOT_ENOUGH_MEMORY;
- status = DnsQuery_UTF8( nameU, type, options, servers, &resultA, reserved );
+ status = DnsQuery_UTF8( nameU, type, options, servers, &resultA, reserved );
if (status == ERROR_SUCCESS)
{
@@ -777,8 +223,7 @@ DNS_STATUS WINAPI DnsQuery_W( PCWSTR name, WORD type, DWORD options, PVOID serve
return status;
}
-static DNS_STATUS get_hostname_a( COMPUTER_NAME_FORMAT format,
- PSTR buffer, PDWORD len )
+static DNS_STATUS get_hostname_a( COMPUTER_NAME_FORMAT format, PSTR buffer, PDWORD len )
{
char name[256];
DWORD size = ARRAY_SIZE(name);
@@ -796,8 +241,7 @@ static DNS_STATUS get_hostname_a( COMPUTER_NAME_FORMAT format,
return ERROR_SUCCESS;
}
-static DNS_STATUS get_hostname_w( COMPUTER_NAME_FORMAT format,
- PWSTR buffer, PDWORD len )
+static DNS_STATUS get_hostname_w( COMPUTER_NAME_FORMAT format, PWSTR buffer, PDWORD len )
{
WCHAR name[256];
DWORD size = ARRAY_SIZE(name);
@@ -833,14 +277,8 @@ DNS_STATUS WINAPI DnsQueryConfig( DNS_CONFIG_TYPE config, DWORD flag, PCWSTR ada
{
case DnsConfigDnsServerList:
{
-#ifdef HAVE_RESOLV
- initialise_resolver();
- ret = get_serverlist( buffer, len );
- break;
-#else
- WARN( "compiled without resolver support\n" );
+ ret = resolv_funcs->get_serverlist( buffer, len );
break;
-#endif
}
case DnsConfigHostName_A:
case DnsConfigHostName_UTF8:
diff --git a/dlls/dnsapi/record.c b/dlls/dnsapi/record.c
index 51d9e8fd2d7..4697438df57 100644
--- a/dlls/dnsapi/record.c
+++ b/dlls/dnsapi/record.c
@@ -2,7 +2,7 @@
* DNS support
*
* Copyright (C) 2006 Hans Leidekker
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -18,31 +18,14 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-#include "wine/port.h"
-#include "wine/debug.h"
-#include "wine/unicode.h"
-
#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#endif
-#ifdef HAVE_RESOLV_H
-# include <resolv.h>
-#endif
-
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "windns.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
#include "dnsapi.h"
WINE_DEFAULT_DEBUG_CHANNEL(dnsapi);
@@ -158,10 +141,8 @@ BOOL WINAPI DnsRecordCompare( PDNS_RECORD r1, PDNS_RECORD r2 )
r1->Data.SOA.dwExpire != r2->Data.SOA.dwExpire ||
r1->Data.SOA.dwDefaultTtl != r2->Data.SOA.dwDefaultTtl)
return FALSE;
- if (strcmpX( r1->Data.SOA.pNamePrimaryServer,
- r2->Data.SOA.pNamePrimaryServer, wide ) ||
- strcmpX( r1->Data.SOA.pNameAdministrator,
- r2->Data.SOA.pNameAdministrator, wide ))
+ if (strcmpX( r1->Data.SOA.pNamePrimaryServer, r2->Data.SOA.pNamePrimaryServer, wide ) ||
+ strcmpX( r1->Data.SOA.pNameAdministrator, r2->Data.SOA.pNameAdministrator, wide ))
return FALSE;
break;
}
@@ -174,17 +155,14 @@ BOOL WINAPI DnsRecordCompare( PDNS_RECORD r1, PDNS_RECORD r2 )
case DNS_TYPE_MG:
case DNS_TYPE_MR:
{
- if (strcmpX( r1->Data.PTR.pNameHost,
- r2->Data.PTR.pNameHost, wide )) return FALSE;
+ if (strcmpX( r1->Data.PTR.pNameHost, r2->Data.PTR.pNameHost, wide )) return FALSE;
break;
}
case DNS_TYPE_MINFO:
case DNS_TYPE_RP:
{
- if (strcmpX( r1->Data.MINFO.pNameMailbox,
- r2->Data.MINFO.pNameMailbox, wide ) ||
- strcmpX( r1->Data.MINFO.pNameErrorsMailbox,
- r2->Data.MINFO.pNameErrorsMailbox, wide ))
+ if (strcmpX( r1->Data.MINFO.pNameMailbox, r2->Data.MINFO.pNameMailbox, wide ) ||
+ strcmpX( r1->Data.MINFO.pNameErrorsMailbox, r2->Data.MINFO.pNameErrorsMailbox, wide ))
return FALSE;
break;
}
@@ -194,8 +172,7 @@ BOOL WINAPI DnsRecordCompare( PDNS_RECORD r1, PDNS_RECORD r2 )
{
if (r1->Data.MX.wPreference != r2->Data.MX.wPreference)
return FALSE;
- if (strcmpX( r1->Data.MX.pNameExchange,
- r2->Data.MX.pNameExchange, wide ))
+ if (strcmpX( r1->Data.MX.pNameExchange, r2->Data.MX.pNameExchange, wide ))
return FALSE;
break;
}
@@ -208,8 +185,7 @@ BOOL WINAPI DnsRecordCompare( PDNS_RECORD r1, PDNS_RECORD r2 )
return FALSE;
for (i = 0; i < r1->Data.TXT.dwStringCount; i++)
{
- if (strcmpX( r1->Data.TXT.pStringArray[i],
- r2->Data.TXT.pStringArray[i], wide ))
+ if (strcmpX( r1->Data.TXT.pStringArray[i], r2->Data.TXT.pStringArray[i], wide ))
return FALSE;
}
break;
@@ -255,8 +231,7 @@ BOOL WINAPI DnsRecordCompare( PDNS_RECORD r1, PDNS_RECORD r2 )
}
case DNS_TYPE_SIG:
{
- if (strcmpX( r1->Data.SIG.pNameSigner,
- r2->Data.SIG.pNameSigner, wide ))
+ if (strcmpX( r1->Data.SIG.pNameSigner, r2->Data.SIG.pNameSigner, wide ))
return FALSE;
if (r1->Data.SIG.wTypeCovered != r2->Data.SIG.wTypeCovered ||
r1->Data.SIG.chAlgorithm != r2->Data.SIG.chAlgorithm ||
@@ -284,8 +259,7 @@ BOOL WINAPI DnsRecordCompare( PDNS_RECORD r1, PDNS_RECORD r2 )
}
case DNS_TYPE_NXT:
{
- if (strcmpX( r1->Data.NXT.pNameNext,
- r2->Data.NXT.pNameNext, wide )) return FALSE;
+ if (strcmpX( r1->Data.NXT.pNameNext, r2->Data.NXT.pNameNext, wide )) return FALSE;
if (r1->Data.NXT.wNumTypes != r2->Data.NXT.wNumTypes) return FALSE;
if (memcmp( r1->Data.NXT.wTypes, r2->Data.NXT.wTypes,
r1->wDataLength - sizeof(DNS_NXT_DATAA) + sizeof(WORD) ))
@@ -294,8 +268,7 @@ BOOL WINAPI DnsRecordCompare( PDNS_RECORD r1, PDNS_RECORD r2 )
}
case DNS_TYPE_SRV:
{
- if (strcmpX( r1->Data.SRV.pNameTarget,
- r2->Data.SRV.pNameTarget, wide )) return FALSE;
+ if (strcmpX( r1->Data.SRV.pNameTarget, r2->Data.SRV.pNameTarget, wide )) return FALSE;
if (r1->Data.SRV.wPriority != r2->Data.SRV.wPriority ||
r1->Data.SRV.wWeight != r2->Data.SRV.wWeight ||
r1->Data.SRV.wPort != r2->Data.SRV.wPort)
@@ -304,8 +277,7 @@ BOOL WINAPI DnsRecordCompare( PDNS_RECORD r1, PDNS_RECORD r2 )
}
case DNS_TYPE_TKEY:
{
- if (strcmpX( r1->Data.TKEY.pNameAlgorithm,
- r2->Data.TKEY.pNameAlgorithm, wide ))
+ if (strcmpX( r1->Data.TKEY.pNameAlgorithm, r2->Data.TKEY.pNameAlgorithm, wide ))
return FALSE;
if (r1->Data.TKEY.dwCreateTime != r2->Data.TKEY.dwCreateTime ||
r1->Data.TKEY.dwExpireTime != r2->Data.TKEY.dwExpireTime ||
@@ -326,8 +298,7 @@ BOOL WINAPI DnsRecordCompare( PDNS_RECORD r1, PDNS_RECORD r2 )
}
case DNS_TYPE_TSIG:
{
- if (strcmpX( r1->Data.TSIG.pNameAlgorithm,
- r2->Data.TSIG.pNameAlgorithm, wide ))
+ if (strcmpX( r1->Data.TSIG.pNameAlgorithm, r2->Data.TSIG.pNameAlgorithm, wide ))
return FALSE;
if (r1->Data.TSIG.i64CreateTime != r2->Data.TSIG.i64CreateTime ||
r1->Data.TSIG.wFudgeTime != r2->Data.TSIG.wFudgeTime ||
@@ -364,8 +335,7 @@ BOOL WINAPI DnsRecordCompare( PDNS_RECORD r1, PDNS_RECORD r2 )
r1->Data.WINSR.dwLookupTimeout != r2->Data.WINSR.dwLookupTimeout ||
r1->Data.WINSR.dwCacheTimeout != r2->Data.WINSR.dwCacheTimeout)
return FALSE;
- if (strcmpX( r1->Data.WINSR.pNameResultDomain,
- r2->Data.WINSR.pNameResultDomain, wide ))
+ if (strcmpX( r1->Data.WINSR.pNameResultDomain, r2->Data.WINSR.pNameResultDomain, wide ))
return FALSE;
break;
}
@@ -748,7 +718,7 @@ BOOL WINAPI DnsRecordSetCompare( PDNS_RECORD set1, PDNS_RECORD set2,
DNS_RRSET_TERMINATE( rr1 );
DNS_RRSET_TERMINATE( rr2 );
-
+
if (diff1) *diff1 = rr1.pFirstRR;
else DnsRecordListFree( rr1.pFirstRR, DnsFreeRecordList );
@@ -763,7 +733,7 @@ error:
DnsRecordListFree( rr1.pFirstRR, DnsFreeRecordList );
DnsRecordListFree( rr2.pFirstRR, DnsFreeRecordList );
-
+
return FALSE;
}
--
2.30.2
More information about the wine-devel
mailing list