4 * Copyright (C) 2006 Hans Leidekker
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
23 #include "wine/debug.h"
27 #include <sys/types.h>
29 #ifdef HAVE_NETINET_IN_H
30 # include <netinet/in.h>
32 #ifdef HAVE_ARPA_NAMESER_H
33 # include <arpa/nameser.h>
51 WINE_DEFAULT_DEBUG_CHANNEL(dnsapi);
55 static CRITICAL_SECTION resolver_cs;
56 static CRITICAL_SECTION_DEBUG resolver_cs_debug =
59 { &resolver_cs_debug.ProcessLocksList,
60 &resolver_cs_debug.ProcessLocksList },
61 0, 0, { (DWORD_PTR)(__FILE__ ": resolver_cs") }
63 static CRITICAL_SECTION resolver_cs = { &resolver_cs_debug, -1, 0, 0, 0, 0 };
65 #define LOCK_RESOLVER() do { EnterCriticalSection( &resolver_cs ); } while (0)
66 #define UNLOCK_RESOLVER() do { LeaveCriticalSection( &resolver_cs ); } while (0)
69 static const char *dns_section_to_str( ns_sect section )
73 case ns_s_qd: return "Question";
74 case ns_s_an: return "Answer";
75 case ns_s_ns: return "Authority";
76 case ns_s_ar: return "Additional";
80 FIXME( "unknown section: 0x%02x\n", section );
81 sprintf( tmp, "0x%02x", section );
87 static unsigned long dns_map_options( DWORD options )
89 unsigned long ret = 0;
91 if (options & DNS_QUERY_STANDARD)
93 if (options & DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE)
95 if (options & DNS_QUERY_USE_TCP_ONLY)
97 if (options & DNS_QUERY_NO_RECURSION)
99 if (options & DNS_QUERY_NO_LOCAL_NAME)
101 if (options & DNS_QUERY_NO_HOSTS_FILE)
102 ret |= RES_NOALIASES;
103 if (options & DNS_QUERY_TREAT_AS_FQDN)
104 ret &= ~RES_DEFNAMES;
106 if (options & DNS_QUERY_DONT_RESET_TTL_VALUES)
107 FIXME( "option DNS_QUERY_DONT_RESET_TTL_VALUES not implemented\n" );
108 if (options & DNS_QUERY_RESERVED)
109 FIXME( "option DNS_QUERY_RESERVED not implemented\n" );
110 if (options & DNS_QUERY_WIRE_ONLY)
111 FIXME( "option DNS_QUERY_WIRE_ONLY not implemented\n" );
112 if (options & DNS_QUERY_NO_WIRE_QUERY)
113 FIXME( "option DNS_QUERY_NO_WIRE_QUERY not implemented\n" );
114 if (options & DNS_QUERY_BYPASS_CACHE)
115 FIXME( "option DNS_QUERY_BYPASS_CACHE not implemented\n" );
116 if (options & DNS_QUERY_RETURN_MESSAGE)
117 FIXME( "option DNS_QUERY_RETURN_MESSAGE not implemented\n" );
119 if (options & DNS_QUERY_NO_NETBT)
120 TRACE( "netbios query disabled\n" );
125 static DNS_STATUS dns_map_error( int error )
129 case ns_r_noerror: return ERROR_SUCCESS;
130 case ns_r_formerr: return DNS_ERROR_RCODE_FORMAT_ERROR;
131 case ns_r_servfail: return DNS_ERROR_RCODE_SERVER_FAILURE;
132 case ns_r_nxdomain: return DNS_ERROR_RCODE_NAME_ERROR;
133 case ns_r_notimpl: return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
134 case ns_r_refused: return DNS_ERROR_RCODE_REFUSED;
135 case ns_r_yxdomain: return DNS_ERROR_RCODE_YXDOMAIN;
136 case ns_r_yxrrset: return DNS_ERROR_RCODE_YXRRSET;
137 case ns_r_nxrrset: return DNS_ERROR_RCODE_NXRRSET;
138 case ns_r_notauth: return DNS_ERROR_RCODE_NOTAUTH;
139 case ns_r_notzone: return DNS_ERROR_RCODE_NOTZONE;
141 FIXME( "unmapped error code: %d\n", error );
142 return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
146 static DNS_STATUS dns_map_h_errno( int error )
151 case HOST_NOT_FOUND: return DNS_ERROR_RCODE_NAME_ERROR;
152 case TRY_AGAIN: return DNS_ERROR_RCODE_SERVER_FAILURE;
153 case NO_RECOVERY: return DNS_ERROR_RCODE_REFUSED;
154 case NETDB_INTERNAL: return DNS_ERROR_RCODE;
156 FIXME( "unmapped error code: %d\n", error );
157 return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
161 static char *dns_dname_from_msg( ns_msg msg, const unsigned char *pos )
164 char *str, dname[NS_MAXDNAME] = ".";
166 /* returns *compressed* length, ignore it */
167 len = dns_ns_name_uncompress( ns_msg_base( msg ), ns_msg_end( msg ),
168 pos, dname, sizeof(dname) );
170 len = strlen( dname );
171 str = dns_alloc( len + 1 );
172 if (str) strcpy( str, dname );
176 static char *dns_str_from_rdata( const unsigned char *rdata )
179 unsigned int len = rdata[0];
181 str = dns_alloc( len + 1 );
184 memcpy( str, ++rdata, len );
190 static unsigned int dns_get_record_size( ns_rr *rr )
192 const unsigned char *pos = rr->rdata;
193 unsigned int num = 0, size = sizeof(DNS_RECORDA);
199 pos += sizeof(WORD) + sizeof(BYTE) + sizeof(BYTE);
200 size += rr->rdata + rr->rdlength - pos - 1;
205 pos += sizeof(PCHAR) + sizeof(WORD) + 2 * sizeof(BYTE);
206 pos += 3 * sizeof(DWORD) + 2 * sizeof(WORD);
207 size += rr->rdata + rr->rdlength - pos - 1;
215 while (pos[0] && pos < rr->rdata + rr->rdlength)
220 size += (num - 1) * sizeof(PCHAR);
225 size += rr->rdlength - 1;
230 case 0xff01: /* WINS */
232 FIXME( "unhandled type: %s\n", dns_type_to_str( rr->type ) );
241 static DNS_STATUS dns_copy_rdata( ns_msg msg, ns_rr *rr, DNS_RECORDA *r, WORD *dlen )
243 DNS_STATUS ret = ERROR_SUCCESS;
244 const unsigned char *pos = rr->rdata;
245 unsigned int i, size;
251 r->Data.A.IpAddress = *(DWORD *)pos;
252 *dlen = sizeof(DNS_A_DATA);
257 for (i = 0; i < sizeof(IP6_ADDRESS)/sizeof(DWORD); i++)
259 r->Data.AAAA.Ip6Address.IP6Dword[i] = *(DWORD *)pos;
260 pos += sizeof(DWORD);
263 *dlen = sizeof(DNS_AAAA_DATA);
268 /* FIXME: byte order? */
269 r->Data.KEY.wFlags = *(WORD *)pos; pos += sizeof(WORD);
270 r->Data.KEY.chProtocol = *(BYTE *)pos++;
271 r->Data.KEY.chAlgorithm = *(BYTE *)pos++;
273 size = rr->rdata + rr->rdlength - pos;
275 for (i = 0; i < size; i++)
276 r->Data.KEY.Key[i] = *(BYTE *)pos++;
278 *dlen = sizeof(DNS_KEY_DATA) + (size - 1) * sizeof(BYTE);
284 r->Data.MINFO.pNameMailbox = dns_dname_from_msg( msg, pos );
285 if (!r->Data.MINFO.pNameMailbox) return ERROR_NOT_ENOUGH_MEMORY;
287 if (dns_ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
288 return DNS_ERROR_BAD_PACKET;
290 r->Data.MINFO.pNameErrorsMailbox = dns_dname_from_msg( msg, pos );
291 if (!r->Data.MINFO.pNameErrorsMailbox)
293 dns_free( r->Data.MINFO.pNameMailbox );
294 return ERROR_NOT_ENOUGH_MEMORY;
297 *dlen = sizeof(DNS_MINFO_DATAA);
304 r->Data.MX.wPreference = ntohs( *(WORD *)pos );
305 r->Data.MX.pNameExchange = dns_dname_from_msg( msg, pos + sizeof(WORD) );
306 if (!r->Data.MX.pNameExchange) return ERROR_NOT_ENOUGH_MEMORY;
308 *dlen = sizeof(DNS_MX_DATAA);
313 r->Data.Null.dwByteCount = rr->rdlength;
314 memcpy( r->Data.Null.Data, rr->rdata, rr->rdlength );
316 *dlen = sizeof(DNS_NULL_DATA) + rr->rdlength - 1;
328 r->Data.PTR.pNameHost = dns_dname_from_msg( msg, pos );
329 if (!r->Data.PTR.pNameHost) return ERROR_NOT_ENOUGH_MEMORY;
331 *dlen = sizeof(DNS_PTR_DATAA);
336 r->Data.SIG.pNameSigner = dns_dname_from_msg( msg, pos );
337 if (!r->Data.SIG.pNameSigner) return ERROR_NOT_ENOUGH_MEMORY;
339 if (dns_ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
340 return DNS_ERROR_BAD_PACKET;
342 /* FIXME: byte order? */
343 r->Data.SIG.wTypeCovered = *(WORD *)pos; pos += sizeof(WORD);
344 r->Data.SIG.chAlgorithm = *(BYTE *)pos++;
345 r->Data.SIG.chLabelCount = *(BYTE *)pos++;
346 r->Data.SIG.dwOriginalTtl = *(DWORD *)pos; pos += sizeof(DWORD);
347 r->Data.SIG.dwExpiration = *(DWORD *)pos; pos += sizeof(DWORD);
348 r->Data.SIG.dwTimeSigned = *(DWORD *)pos; pos += sizeof(DWORD);
349 r->Data.SIG.wKeyTag = *(WORD *)pos;
351 size = rr->rdata + rr->rdlength - pos;
353 for (i = 0; i < size; i++)
354 r->Data.SIG.Signature[i] = *(BYTE *)pos++;
356 *dlen = sizeof(DNS_SIG_DATAA) + (size - 1) * sizeof(BYTE);
361 r->Data.SOA.pNamePrimaryServer = dns_dname_from_msg( msg, pos );
362 if (!r->Data.SOA.pNamePrimaryServer) return ERROR_NOT_ENOUGH_MEMORY;
364 if (dns_ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
365 return DNS_ERROR_BAD_PACKET;
367 r->Data.SOA.pNameAdministrator = dns_dname_from_msg( msg, pos );
368 if (!r->Data.SOA.pNameAdministrator)
370 dns_free( r->Data.SOA.pNamePrimaryServer );
371 return ERROR_NOT_ENOUGH_MEMORY;
374 if (dns_ns_name_skip( &pos, ns_msg_end( msg ) ) < 0)
375 return DNS_ERROR_BAD_PACKET;
377 r->Data.SOA.dwSerialNo = ntohl( *(DWORD *)pos ); pos += sizeof(DWORD);
378 r->Data.SOA.dwRefresh = ntohl( *(DWORD *)pos ); pos += sizeof(DWORD);
379 r->Data.SOA.dwRetry = ntohl( *(DWORD *)pos ); pos += sizeof(DWORD);
380 r->Data.SOA.dwExpire = ntohl( *(DWORD *)pos ); pos += sizeof(DWORD);
381 r->Data.SOA.dwDefaultTtl = ntohl( *(DWORD *)pos ); pos += sizeof(DWORD);
383 *dlen = sizeof(DNS_SOA_DATAA);
388 r->Data.SRV.wPriority = ntohs( *(WORD *)pos ); pos += sizeof(WORD);
389 r->Data.SRV.wWeight = ntohs( *(WORD *)pos ); pos += sizeof(WORD);
390 r->Data.SRV.wPort = ntohs( *(WORD *)pos ); pos += sizeof(WORD);
392 r->Data.SRV.pNameTarget = dns_dname_from_msg( msg, pos );
393 if (!r->Data.SRV.pNameTarget) return ERROR_NOT_ENOUGH_MEMORY;
395 *dlen = sizeof(DNS_SRV_DATAA);
404 while (pos[0] && pos < rr->rdata + rr->rdlength)
406 r->Data.TXT.pStringArray[i] = dns_str_from_rdata( pos );
407 if (!r->Data.TXT.pStringArray[i])
409 for (--i; i >= 0; i--)
410 dns_free( r->Data.TXT.pStringArray[i] );
411 return ERROR_NOT_ENOUGH_MEMORY;
416 r->Data.TXT.dwStringCount = i;
417 *dlen = sizeof(DNS_TXT_DATAA) + (i - 1) * sizeof(PCHAR);
425 case 0x00f9: /* TKEY */
426 case 0xff01: /* WINS */
427 case 0xff02: /* WINSR */
429 FIXME( "unhandled type: %s\n", dns_type_to_str( rr->type ) );
430 return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
436 static DNS_STATUS dns_copy_record( ns_msg msg, ns_sect section,
437 unsigned short num, DNS_RECORDA **recp )
444 if (dns_ns_parserr( &msg, section, num, &rr ) < 0)
445 return DNS_ERROR_BAD_PACKET;
447 if (!(record = dns_zero_alloc( dns_get_record_size( &rr ) )))
448 return ERROR_NOT_ENOUGH_MEMORY;
450 record->pName = dns_strdup_u( rr.name );
454 return ERROR_NOT_ENOUGH_MEMORY;
457 record->wType = rr.type;
458 record->Flags.S.Section = section;
459 record->Flags.S.CharSet = DnsCharSetUtf8;
460 record->dwTtl = rr.ttl;
462 if ((ret = dns_copy_rdata( msg, &rr, record, &dlen )))
464 dns_free( record->pName );
468 record->wDataLength = dlen;
471 TRACE( "found %s record in %s section\n",
472 dns_type_to_str( rr.type ), dns_section_to_str( section ) );
473 return ERROR_SUCCESS;
476 #define DEFAULT_TTL 1200
478 static DNS_STATUS dns_do_query_netbios( PCSTR name, DNS_RECORDA **recp )
483 FIND_NAME_BUFFER *buffer;
484 FIND_NAME_HEADER *header;
485 DNS_RECORDA *record = NULL;
488 len = strlen( name );
489 if (len >= NCBNAMSZ) return DNS_ERROR_RCODE_NAME_ERROR;
491 DNS_RRSET_INIT( rrset );
493 memset( &ncb, 0, sizeof(ncb) );
494 ncb.ncb_command = NCBFINDNAME;
496 memset( ncb.ncb_callname, ' ', sizeof(ncb.ncb_callname) );
497 memcpy( ncb.ncb_callname, name, len );
498 ncb.ncb_callname[NCBNAMSZ] = '\0';
500 ret = Netbios( &ncb );
501 if (ret != NRC_GOODRET) return ERROR_INVALID_NAME;
503 header = (FIND_NAME_HEADER *)ncb.ncb_buffer;
504 buffer = (FIND_NAME_BUFFER *)((char *)header + sizeof(FIND_NAME_HEADER));
506 for (i = 0; i < header->node_count; i++)
508 record = dns_zero_alloc( sizeof(DNS_RECORDA) );
511 ret = ERROR_NOT_ENOUGH_MEMORY;
516 record->pName = dns_strdup_u( name );
519 ret = ERROR_NOT_ENOUGH_MEMORY;
523 record->wType = DNS_TYPE_A;
524 record->Flags.S.Section = DnsSectionAnswer;
525 record->Flags.S.CharSet = DnsCharSetUtf8;
526 record->dwTtl = DEFAULT_TTL;
528 /* FIXME: network byte order? */
529 record->Data.A.IpAddress = *(DWORD *)((char *)buffer[i].destination_addr + 2);
531 DNS_RRSET_ADD( rrset, (DNS_RECORD *)record );
536 DNS_RRSET_TERMINATE( rrset );
538 if (ret != ERROR_SUCCESS)
539 DnsRecordListFree( (DNS_RECORD *)record, DnsFreeRecordList );
541 *recp = (DNS_RECORDA *)rrset.pFirstRR;
546 /* The resolver lock must be held and res_init() must have been
547 * called before calling these three functions.
549 static DNS_STATUS dns_set_serverlist( PIP4_ARRAY addrs )
553 if (addrs->AddrCount > MAXNS)
555 WARN( "too many servers: %ld only using the first: %d\n",
556 addrs->AddrCount, MAXNS );
557 _res.nscount = MAXNS;
559 else _res.nscount = addrs->AddrCount;
561 for (i = 0; i < _res.nscount; i++)
562 _res.nsaddr_list[i].sin_addr.s_addr = addrs->AddrArray[i];
564 return ERROR_SUCCESS;
567 static DNS_STATUS dns_get_serverlist( PIP4_ARRAY addrs, PDWORD len )
569 unsigned int i, size;
571 size = sizeof(IP4_ARRAY) + sizeof(IP4_ADDRESS) * (_res.nscount - 1);
572 if (!addrs || *len < size)
575 return ERROR_INSUFFICIENT_BUFFER;
578 addrs->AddrCount = _res.nscount;
580 for (i = 0; i < _res.nscount; i++)
581 addrs->AddrArray[i] = _res.nsaddr_list[i].sin_addr.s_addr;
583 return ERROR_SUCCESS;
586 static DNS_STATUS dns_do_query( PCSTR name, WORD type, DWORD options,
587 PDNS_RECORDA *result )
589 DNS_STATUS ret = DNS_ERROR_RCODE_NOT_IMPLEMENTED;
592 unsigned char answer[NS_PACKETSZ];
593 ns_sect sections[] = { ns_s_an, ns_s_ar };
596 DNS_RECORDA *record = NULL;
600 DNS_RRSET_INIT( rrset );
602 len = res_query( name, ns_c_in, type, answer, sizeof(answer) );
605 ret = dns_map_h_errno( h_errno );
609 if (dns_ns_initparse( answer, len, &msg ) < 0)
611 ret = DNS_ERROR_BAD_PACKET;
615 #define RCODE_MASK 0x0f
616 if ((msg._flags & RCODE_MASK) != ns_r_noerror)
618 ret = dns_map_error( msg._flags & RCODE_MASK );
622 for (i = 0; i < sizeof(sections)/sizeof(sections[0]); i++)
624 for (num = 0; num < ns_msg_count( msg, sections[i] ); num++)
626 ret = dns_copy_record( msg, sections[i], num, &record );
627 if (ret != ERROR_SUCCESS) goto exit;
629 DNS_RRSET_ADD( rrset, (DNS_RECORD *)record );
634 DNS_RRSET_TERMINATE( rrset );
636 if (ret != ERROR_SUCCESS)
637 DnsRecordListFree( rrset.pFirstRR, DnsFreeRecordList );
639 *result = (DNS_RECORDA *)rrset.pFirstRR;
644 #endif /* HAVE_RESOLV */
646 /******************************************************************************
647 * DnsQuery_A [DNSAPI.@]
650 DNS_STATUS WINAPI DnsQuery_A( PCSTR name, WORD type, DWORD options, PIP4_ARRAY servers,
651 PDNS_RECORDA *result, PVOID *reserved )
654 DNS_RECORDW *resultW;
657 TRACE( "(%s,%s,0x%08lx,%p,%p,%p)\n", debugstr_a(name), dns_type_to_str( type ),
658 options, servers, result, reserved );
660 if (!name || !result)
661 return ERROR_INVALID_PARAMETER;
663 nameW = dns_strdup_aw( name );
664 if (!nameW) return ERROR_NOT_ENOUGH_MEMORY;
666 status = DnsQuery_W( nameW, type, options, servers, &resultW, reserved );
668 if (status == ERROR_SUCCESS)
670 *result = (DNS_RECORDA *)DnsRecordSetCopyEx(
671 (DNS_RECORD *)resultW, DnsCharSetUnicode, DnsCharSetAnsi );
673 if (!*result) status = ERROR_NOT_ENOUGH_MEMORY;
674 DnsRecordListFree( (DNS_RECORD *)resultW, DnsFreeRecordList );
681 /******************************************************************************
682 * DnsQuery_UTF8 [DNSAPI.@]
685 DNS_STATUS WINAPI DnsQuery_UTF8( PCSTR name, WORD type, DWORD options, PIP4_ARRAY servers,
686 PDNS_RECORDA *result, PVOID *reserved )
688 DNS_STATUS ret = DNS_ERROR_RCODE_NOT_IMPLEMENTED;
691 TRACE( "(%s,%s,0x%08lx,%p,%p,%p)\n", debugstr_a(name), dns_type_to_str( type ),
692 options, servers, result, reserved );
694 if (!name || !result)
695 return ERROR_INVALID_PARAMETER;
700 _res.options |= dns_map_options( options );
702 if (servers && (ret = dns_set_serverlist( servers )))
708 ret = dns_do_query( name, type, options, result );
710 if (ret == DNS_ERROR_RCODE_NAME_ERROR && type == DNS_TYPE_A &&
711 !(options & DNS_QUERY_NO_NETBT))
713 TRACE( "dns lookup failed, trying netbios query\n" );
714 ret = dns_do_query_netbios( name, result );
723 /******************************************************************************
724 * DnsQuery_W [DNSAPI.@]
727 DNS_STATUS WINAPI DnsQuery_W( PCWSTR name, WORD type, DWORD options, PIP4_ARRAY servers,
728 PDNS_RECORDW *result, PVOID *reserved )
731 DNS_RECORDA *resultA;
734 TRACE( "(%s,%s,0x%08lx,%p,%p,%p)\n", debugstr_w(name), dns_type_to_str( type ),
735 options, servers, result, reserved );
737 if (!name || !result)
738 return ERROR_INVALID_PARAMETER;
740 nameU = dns_strdup_wu( name );
741 if (!nameU) return ERROR_NOT_ENOUGH_MEMORY;
743 status = DnsQuery_UTF8( nameU, type, options, servers, &resultA, reserved );
745 if (status == ERROR_SUCCESS)
747 *result = (DNS_RECORDW *)DnsRecordSetCopyEx(
748 (DNS_RECORD *)resultA, DnsCharSetUtf8, DnsCharSetUnicode );
750 if (!*result) status = ERROR_NOT_ENOUGH_MEMORY;
751 DnsRecordListFree( (DNS_RECORD *)resultA, DnsFreeRecordList );
758 static DNS_STATUS dns_get_hostname_a( COMPUTER_NAME_FORMAT format,
759 LPSTR buffer, PDWORD len )
762 DWORD size = sizeof(name);
764 if (!GetComputerNameExA( format, name, &size ))
765 return DNS_ERROR_NAME_DOES_NOT_EXIST;
767 if (!buffer || (size = lstrlenA( name ) + 1) > *len)
770 return ERROR_INSUFFICIENT_BUFFER;
773 lstrcpyA( buffer, name );
774 return ERROR_SUCCESS;
777 static DNS_STATUS dns_get_hostname_w( COMPUTER_NAME_FORMAT format,
778 LPWSTR buffer, PDWORD len )
781 DWORD size = sizeof(name);
783 if (!GetComputerNameExW( format, name, &size ))
784 return DNS_ERROR_NAME_DOES_NOT_EXIST;
786 if (!buffer || (size = lstrlenW( name ) + 1) > *len)
789 return ERROR_INSUFFICIENT_BUFFER;
792 lstrcpyW( buffer, name );
793 return ERROR_SUCCESS;
796 /******************************************************************************
797 * DnsQueryConfig [DNSAPI.@]
800 DNS_STATUS WINAPI DnsQueryConfig( DNS_CONFIG_TYPE config, DWORD flag, PWSTR adapter,
801 PVOID reserved, PVOID buffer, PDWORD len )
803 DNS_STATUS ret = ERROR_INVALID_PARAMETER;
805 TRACE( "(%d,0x%08lx,%s,%p,%p,%p)\n", config, flag, debugstr_w(adapter),
806 reserved, buffer, len );
808 if (!len) return ERROR_INVALID_PARAMETER;
812 case DnsConfigDnsServerList:
818 ret = dns_get_serverlist( (IP4_ARRAY *)buffer, len );
823 WARN( "compiled without resolver support\n" );
827 case DnsConfigHostName_A:
828 case DnsConfigHostName_UTF8:
829 return dns_get_hostname_a( ComputerNameDnsHostname, buffer, len );
831 case DnsConfigFullHostName_A:
832 case DnsConfigFullHostName_UTF8:
833 return dns_get_hostname_a( ComputerNameDnsFullyQualified, buffer, len );
835 case DnsConfigPrimaryDomainName_A:
836 case DnsConfigPrimaryDomainName_UTF8:
837 return dns_get_hostname_a( ComputerNameDnsDomain, buffer, len );
839 case DnsConfigHostName_W:
840 return dns_get_hostname_w( ComputerNameDnsHostname, buffer, len );
842 case DnsConfigFullHostName_W:
843 return dns_get_hostname_w( ComputerNameDnsFullyQualified, buffer, len );
845 case DnsConfigPrimaryDomainName_W:
846 return dns_get_hostname_w( ComputerNameDnsDomain, buffer, len );
848 case DnsConfigAdapterDomainName_A:
849 case DnsConfigAdapterDomainName_W:
850 case DnsConfigAdapterDomainName_UTF8:
851 case DnsConfigSearchList:
852 case DnsConfigAdapterInfo:
853 case DnsConfigPrimaryHostNameRegistrationEnabled:
854 case DnsConfigAdapterHostNameRegistrationEnabled:
855 case DnsConfigAddressRegistrationMaxCount:
856 FIXME( "unimplemented config type %d\n", config );
860 WARN( "unknown config type: %d\n", config );