mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / dnsapi / query.c
bloba7ae77148bee05780cb070ead652f2988f5a1a9b
1 /*
2 * DNS support
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
21 #include <stdarg.h>
22 #include "windef.h"
23 #include "winbase.h"
24 #include "winerror.h"
25 #include "winnls.h"
26 #include "windns.h"
27 #include "nb30.h"
29 #include "wine/debug.h"
30 #include "dnsapi.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(dnsapi);
34 #define DEFAULT_TTL 1200
36 static DNS_STATUS do_query_netbios( PCSTR name, DNS_RECORDA **recp )
38 NCB ncb;
39 UCHAR ret;
40 DNS_RRSET rrset;
41 FIND_NAME_BUFFER *buffer;
42 FIND_NAME_HEADER *header;
43 DNS_RECORDA *record = NULL;
44 unsigned int i, len;
45 DNS_STATUS status = ERROR_INVALID_NAME;
47 len = strlen( name );
48 if (len >= NCBNAMSZ) return DNS_ERROR_RCODE_NAME_ERROR;
50 DNS_RRSET_INIT( rrset );
52 memset( &ncb, 0, sizeof(ncb) );
53 ncb.ncb_command = NCBFINDNAME;
55 memset( ncb.ncb_callname, ' ', sizeof(ncb.ncb_callname) );
56 memcpy( ncb.ncb_callname, name, len );
57 ncb.ncb_callname[NCBNAMSZ - 1] = '\0';
59 ret = Netbios( &ncb );
60 if (ret != NRC_GOODRET) return ERROR_INVALID_NAME;
62 header = (FIND_NAME_HEADER *)ncb.ncb_buffer;
63 buffer = (FIND_NAME_BUFFER *)((char *)header + sizeof(FIND_NAME_HEADER));
65 for (i = 0; i < header->node_count; i++)
67 record = heap_alloc_zero( sizeof(DNS_RECORDA) );
68 if (!record)
70 status = ERROR_NOT_ENOUGH_MEMORY;
71 goto exit;
73 else
75 record->pName = strdup_u( name );
76 if (!record->pName)
78 status = ERROR_NOT_ENOUGH_MEMORY;
79 goto exit;
82 record->wType = DNS_TYPE_A;
83 record->Flags.S.Section = DnsSectionAnswer;
84 record->Flags.S.CharSet = DnsCharSetUtf8;
85 record->dwTtl = DEFAULT_TTL;
87 /* FIXME: network byte order? */
88 record->Data.A.IpAddress = *(DWORD *)((char *)buffer[i].destination_addr + 2);
90 DNS_RRSET_ADD( rrset, (DNS_RECORD *)record );
93 status = ERROR_SUCCESS;
95 exit:
96 DNS_RRSET_TERMINATE( rrset );
98 if (status != ERROR_SUCCESS)
99 DnsRecordListFree( rrset.pFirstRR, DnsFreeRecordList );
100 else
101 *recp = (DNS_RECORDA *)rrset.pFirstRR;
103 return status;
106 static const char *debugstr_query_request(const DNS_QUERY_REQUEST *req)
108 if (!req)
109 return "(null)";
111 return wine_dbg_sprintf("{%d %s %s %x%08x %p %d %p %p}", req->Version,
112 debugstr_w(req->QueryName), type_to_str(req->QueryType),
113 (UINT32)(req->QueryOptions>>32u), (UINT32)req->QueryOptions, req->pDnsServerList,
114 req->InterfaceIndex, req->pQueryCompletionCallback, req->pQueryContext);
117 /******************************************************************************
118 * DnsQueryEx [DNSAPI.@]
121 DNS_STATUS WINAPI DnsQueryEx(DNS_QUERY_REQUEST *request, DNS_QUERY_RESULT *result, DNS_QUERY_CANCEL *cancel)
123 FIXME("(%s %p %p)\n", debugstr_query_request(request), result, cancel);
124 return DNS_ERROR_RCODE_NOT_IMPLEMENTED;
127 /******************************************************************************
128 * DnsQuery_A [DNSAPI.@]
131 DNS_STATUS WINAPI DnsQuery_A( PCSTR name, WORD type, DWORD options, PVOID servers,
132 PDNS_RECORDA *result, PVOID *reserved )
134 WCHAR *nameW;
135 DNS_RECORDW *resultW;
136 DNS_STATUS status;
138 TRACE( "(%s,%s,0x%08x,%p,%p,%p)\n", debugstr_a(name), type_to_str( type ),
139 options, servers, result, reserved );
141 if (!name || !result)
142 return ERROR_INVALID_PARAMETER;
144 nameW = strdup_aw( name );
145 if (!nameW) return ERROR_NOT_ENOUGH_MEMORY;
147 status = DnsQuery_W( nameW, type, options, servers, &resultW, reserved );
149 if (status == ERROR_SUCCESS)
151 *result = (DNS_RECORDA *)DnsRecordSetCopyEx(
152 (DNS_RECORD *)resultW, DnsCharSetUnicode, DnsCharSetAnsi );
154 if (!*result) status = ERROR_NOT_ENOUGH_MEMORY;
155 DnsRecordListFree( (DNS_RECORD *)resultW, DnsFreeRecordList );
158 heap_free( nameW );
159 return status;
162 /******************************************************************************
163 * DnsQuery_UTF8 [DNSAPI.@]
166 DNS_STATUS WINAPI DnsQuery_UTF8( PCSTR name, WORD type, DWORD options, PVOID servers,
167 PDNS_RECORDA *result, PVOID *reserved )
169 DNS_STATUS ret = DNS_ERROR_RCODE_NOT_IMPLEMENTED;
171 TRACE( "(%s,%s,0x%08x,%p,%p,%p)\n", debugstr_a(name), type_to_str( type ),
172 options, servers, result, reserved );
174 if (!name || !result)
175 return ERROR_INVALID_PARAMETER;
177 if ((ret = resolv_funcs->set_serverlist( servers ))) return ret;
179 ret = resolv_funcs->query( name, type, options, result );
181 if (ret == DNS_ERROR_RCODE_NAME_ERROR && type == DNS_TYPE_A &&
182 !(options & DNS_QUERY_NO_NETBT))
184 TRACE( "dns lookup failed, trying netbios query\n" );
185 ret = do_query_netbios( name, result );
188 return ret;
191 /******************************************************************************
192 * DnsQuery_W [DNSAPI.@]
195 DNS_STATUS WINAPI DnsQuery_W( PCWSTR name, WORD type, DWORD options, PVOID servers,
196 PDNS_RECORDW *result, PVOID *reserved )
198 char *nameU;
199 DNS_RECORDA *resultA;
200 DNS_STATUS status;
202 TRACE( "(%s,%s,0x%08x,%p,%p,%p)\n", debugstr_w(name), type_to_str( type ),
203 options, servers, result, reserved );
205 if (!name || !result)
206 return ERROR_INVALID_PARAMETER;
208 nameU = strdup_wu( name );
209 if (!nameU) return ERROR_NOT_ENOUGH_MEMORY;
211 status = DnsQuery_UTF8( nameU, type, options, servers, &resultA, reserved );
213 if (status == ERROR_SUCCESS)
215 *result = (DNS_RECORDW *)DnsRecordSetCopyEx(
216 (DNS_RECORD *)resultA, DnsCharSetUtf8, DnsCharSetUnicode );
218 if (!*result) status = ERROR_NOT_ENOUGH_MEMORY;
219 DnsRecordListFree( (DNS_RECORD *)resultA, DnsFreeRecordList );
222 heap_free( nameU );
223 return status;
226 static DNS_STATUS get_hostname_a( COMPUTER_NAME_FORMAT format, PSTR buffer, PDWORD len )
228 char name[256];
229 DWORD size = ARRAY_SIZE(name);
231 if (!GetComputerNameExA( format, name, &size ))
232 return DNS_ERROR_NAME_DOES_NOT_EXIST;
234 if (!buffer || (size = lstrlenA( name ) + 1) > *len)
236 *len = size;
237 return ERROR_INSUFFICIENT_BUFFER;
240 lstrcpyA( buffer, name );
241 return ERROR_SUCCESS;
244 static DNS_STATUS get_hostname_w( COMPUTER_NAME_FORMAT format, PWSTR buffer, PDWORD len )
246 WCHAR name[256];
247 DWORD size = ARRAY_SIZE(name);
249 if (!GetComputerNameExW( format, name, &size ))
250 return DNS_ERROR_NAME_DOES_NOT_EXIST;
252 if (!buffer || (size = lstrlenW( name ) + 1) > *len)
254 *len = size;
255 return ERROR_INSUFFICIENT_BUFFER;
258 lstrcpyW( buffer, name );
259 return ERROR_SUCCESS;
262 /******************************************************************************
263 * DnsQueryConfig [DNSAPI.@]
266 DNS_STATUS WINAPI DnsQueryConfig( DNS_CONFIG_TYPE config, DWORD flag, PCWSTR adapter,
267 PVOID reserved, PVOID buffer, PDWORD len )
269 DNS_STATUS ret = ERROR_INVALID_PARAMETER;
271 TRACE( "(%d,0x%08x,%s,%p,%p,%p)\n", config, flag, debugstr_w(adapter),
272 reserved, buffer, len );
274 if (!len) return ERROR_INVALID_PARAMETER;
276 switch (config)
278 case DnsConfigDnsServerList:
280 ret = resolv_funcs->get_serverlist( buffer, len );
281 break;
283 case DnsConfigHostName_A:
284 case DnsConfigHostName_UTF8:
285 return get_hostname_a( ComputerNameDnsHostname, buffer, len );
287 case DnsConfigFullHostName_A:
288 case DnsConfigFullHostName_UTF8:
289 return get_hostname_a( ComputerNameDnsFullyQualified, buffer, len );
291 case DnsConfigPrimaryDomainName_A:
292 case DnsConfigPrimaryDomainName_UTF8:
293 return get_hostname_a( ComputerNameDnsDomain, buffer, len );
295 case DnsConfigHostName_W:
296 return get_hostname_w( ComputerNameDnsHostname, buffer, len );
298 case DnsConfigFullHostName_W:
299 return get_hostname_w( ComputerNameDnsFullyQualified, buffer, len );
301 case DnsConfigPrimaryDomainName_W:
302 return get_hostname_w( ComputerNameDnsDomain, buffer, len );
304 case DnsConfigAdapterDomainName_A:
305 case DnsConfigAdapterDomainName_W:
306 case DnsConfigAdapterDomainName_UTF8:
307 case DnsConfigSearchList:
308 case DnsConfigAdapterInfo:
309 case DnsConfigPrimaryHostNameRegistrationEnabled:
310 case DnsConfigAdapterHostNameRegistrationEnabled:
311 case DnsConfigAddressRegistrationMaxCount:
312 FIXME( "unimplemented config type %d\n", config );
313 break;
315 default:
316 WARN( "unknown config type: %d\n", config );
317 break;
319 return ret;