2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/dnsapi/dnsapi/query.c
5 * PURPOSE: DNSAPI functions built on the ADNS library.
6 * PROGRAMER: Art Yerkes
16 /* DnsQuery ****************************
17 * Begin a DNS query, and allow the result to be placed in the application
18 * supplied result pointer. The result can be manipulated with the record
21 * Name -- The DNS object to be queried.
22 * Type -- The type of records to be returned. These are
24 * Options -- Query options. DNS_QUERY_STANDARD is the base
25 * state, and every other option takes precedence.
26 * multiple options can be combined. Listed in
28 * Servers -- List of alternate servers (optional)
29 * QueryResultSet -- Pointer to the result pointer that will be filled
30 * when the response is available.
31 * Reserved -- Response as it appears on the wire. Optional.
34 char *xstrsave(const char *str
) {
37 p
= RtlAllocateHeap( RtlGetProcessHeap(), 0, strlen(str
)+1 );
42 DNS_STATUS WINAPI DnsQuery_A
47 PDNS_RECORD
*QueryResultSet
,
58 adns_error
= adns_init( &astate
,
63 if( adns_error
!= adns_s_ok
) {
64 return DnsIntTranslateAdnsToDNS_STATUS( adns_error
);
67 adns_error
= adns_synchronous( astate
,
73 if( adns_error
!= adns_s_ok
) {
74 adns_finish( astate
);
75 return DnsIntTranslateAdnsToDNS_STATUS( adns_error
);
78 if( answer
&& answer
->rrs
.addr
) {
80 (PDNS_RECORD
)RtlAllocateHeap( RtlGetProcessHeap(), 0,
81 sizeof( DNS_RECORD
) );
82 (*QueryResultSet
)->pNext
= NULL
;
83 (*QueryResultSet
)->wType
= Type
;
84 (*QueryResultSet
)->pName
= xstrsave( Name
);
85 (*QueryResultSet
)->wDataLength
= sizeof(DNS_A_DATA
);
86 (*QueryResultSet
)->Data
.A
.IpAddress
=
87 answer
->rrs
.addr
->addr
.inet
.sin_addr
.s_addr
;
88 adns_finish( astate
);
91 return ERROR_FILE_NOT_FOUND
;
93 return ERROR_OUTOFMEMORY
; /* XXX arty: find a better error code. */
97 static PCHAR
DnsWToC( const WCHAR
*WideString
) {
98 int chars
= wcstombs( NULL
, WideString
, 0 );
99 PCHAR out
= RtlAllocateHeap( RtlGetProcessHeap(), 0, chars
+ 1 );
100 wcstombs( out
, WideString
, chars
+ 1 );
104 static PWCHAR
DnsCToW( const CHAR
*NarrowString
) {
105 int chars
= mbstowcs( NULL
, NarrowString
, 0 );
106 PWCHAR out
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
107 (chars
+ 1) * sizeof(WCHAR
) );
108 mbstowcs( out
, NarrowString
, chars
+ 1 );
112 DNS_STATUS WINAPI DnsQuery_W
117 PDNS_RECORD
*QueryResultSet
,
122 PDNS_RECORD QueryResultWide
;
123 PDNS_RECORD ConvertedRecord
= 0, LastRecord
= 0;
125 Buffer
= DnsWToC( Name
);
127 Status
= DnsQuery_A( Buffer
, Type
, Options
, Servers
, &QueryResultWide
,
130 while( Status
== ERROR_SUCCESS
&& QueryResultWide
) {
131 switch( QueryResultWide
->wType
) {
138 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
139 sizeof(DNS_RECORD
) );
140 ConvertedRecord
->pName
= (PCHAR
)DnsCToW( QueryResultWide
->pName
);
141 ConvertedRecord
->wType
= QueryResultWide
->wType
;
142 ConvertedRecord
->wDataLength
= QueryResultWide
->wDataLength
;
143 memcpy( ConvertedRecord
, QueryResultWide
,
144 QueryResultWide
->wDataLength
);
155 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
156 sizeof(DNS_RECORD
) );
157 ConvertedRecord
->pName
= (PCHAR
)DnsCToW( QueryResultWide
->pName
);
158 ConvertedRecord
->wType
= QueryResultWide
->wType
;
159 ConvertedRecord
->wDataLength
= sizeof(DNS_PTR_DATA
);
160 ConvertedRecord
->Data
.PTR
.pNameHost
=
161 (PCHAR
)DnsCToW( QueryResultWide
->Data
.PTR
.pNameHost
);
167 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
168 sizeof(DNS_RECORD
) );
169 ConvertedRecord
->pName
= (PCHAR
)DnsCToW( QueryResultWide
->pName
);
170 ConvertedRecord
->wType
= QueryResultWide
->wType
;
171 ConvertedRecord
->wDataLength
= sizeof(DNS_MINFO_DATA
);
172 ConvertedRecord
->Data
.MINFO
.pNameMailbox
=
173 (PCHAR
)DnsCToW( QueryResultWide
->Data
.MINFO
.pNameMailbox
);
174 ConvertedRecord
->Data
.MINFO
.pNameErrorsMailbox
=
175 (PCHAR
)DnsCToW( QueryResultWide
->Data
.MINFO
.pNameErrorsMailbox
);
183 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
184 sizeof(DNS_RECORD
) );
185 ConvertedRecord
->pName
= (PCHAR
)DnsCToW( QueryResultWide
->pName
);
186 ConvertedRecord
->wType
= QueryResultWide
->wType
;
187 ConvertedRecord
->wDataLength
= sizeof(DNS_MX_DATA
);
188 ConvertedRecord
->Data
.MX
.pNameExchange
=
189 (PCHAR
)DnsCToW( QueryResultWide
->Data
.MX
.pNameExchange
);
190 ConvertedRecord
->Data
.MX
.wPreference
=
191 QueryResultWide
->Data
.MX
.wPreference
;
199 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
200 sizeof(DNS_TXT_DATA
) +
202 Data
.TXT
.dwStringCount
);
203 ConvertedRecord
->pName
= (PCHAR
)DnsCToW( QueryResultWide
->pName
);
204 ConvertedRecord
->wType
= QueryResultWide
->wType
;
205 ConvertedRecord
->wDataLength
=
206 sizeof(DNS_TXT_DATA
) +
207 (sizeof(PWCHAR
) * QueryResultWide
->Data
.TXT
.dwStringCount
);
208 ConvertedRecord
->Data
.TXT
.dwStringCount
=
209 QueryResultWide
->Data
.TXT
.dwStringCount
;
210 for( i
= 0; i
< ConvertedRecord
->Data
.TXT
.dwStringCount
; i
++ ) {
211 ConvertedRecord
->Data
.TXT
.pStringArray
[i
] =
212 (PCHAR
)DnsCToW( QueryResultWide
->Data
.TXT
.pStringArray
[i
] );
217 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
218 sizeof(DNS_NULL_DATA
) +
220 Data
.Null
.dwByteCount
);
221 ConvertedRecord
->pName
= (PCHAR
)DnsCToW( QueryResultWide
->pName
);
222 ConvertedRecord
->wType
= QueryResultWide
->wType
;
223 ConvertedRecord
->wDataLength
=
224 sizeof(DNS_NULL_DATA
) + QueryResultWide
->Data
.Null
.dwByteCount
;
225 ConvertedRecord
->Data
.Null
.dwByteCount
=
226 QueryResultWide
->Data
.Null
.dwByteCount
;
227 memcpy( &ConvertedRecord
->Data
.Null
.Data
,
228 &QueryResultWide
->Data
.Null
.Data
,
229 QueryResultWide
->Data
.Null
.dwByteCount
);
234 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
235 sizeof(DNS_RECORDA
) );
236 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
237 ConvertedRecord
->wType
= QueryResultWide
->wType
;
238 ConvertedRecord
->wDataLength
= sizeof(DNS_SIG_DATAA
);
239 memcpy( &ConvertedRecord
->Data
.SIG
,
240 &QueryResultWide
->Data
.SIG
,
241 sizeof(QueryResultWide
->Data
.SIG
) );
242 ConvertedRecord
->Data
.SIG
.pNameSigner
=
243 DnsCToW( QueryResultWide
->Data
.SIG
.pNameSigner
);
247 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
248 sizeof(DNS_RECORDA
) );
249 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
250 ConvertedRecord
->wType
= QueryResultWide
->wType
;
251 ConvertedRecord
->wDataLength
= sizeof(DNS_NXT_DATAA
);
252 memcpy( &ConvertedRecord
->Data
.NXT
,
253 &QueryResultWide
->Data
.NXT
,
254 sizeof(QueryResultWide
->Data
.NXT
) );
255 ConvertedRecord
->Data
.NXT
.pNameNext
=
256 DnsCToW( QueryResultWide
->Data
.NXT
.pNameNext
);
260 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
261 sizeof(DNS_RECORDA
) );
262 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
263 ConvertedRecord
->wType
= QueryResultWide
->wType
;
264 ConvertedRecord
->wDataLength
= sizeof(DNS_SRV_DATAA
);
265 memcpy( &ConvertedRecord
->Data
.SRV
,
266 &QueryResultWide
->Data
.SRV
,
267 sizeof(QueryResultWide
->Data
.SRV
) );
268 ConvertedRecord
->Data
.SRV
.pNameTarget
=
269 DnsCToW( QueryResultWide
->Data
.SRV
.pNameTarget
);
275 LastRecord
->pNext
= ConvertedRecord
;
276 LastRecord
= LastRecord
->pNext
;
278 LastRecord
= *QueryResultSet
= ConvertedRecord
;
282 LastRecord
->pNext
= 0;
285 RtlFreeHeap( RtlGetProcessHeap(), 0, Buffer
);
290 DNS_STATUS WINAPI DnsQuery_UTF8
295 PDNS_RECORD
*QueryResultSet
,
297 return DnsQuery_UTF8( Name
, Type
, Options
, Servers
, QueryResultSet
,
301 void DnsIntFreeRecordList( PDNS_RECORD ToDelete
) {
303 PDNS_RECORD next
= 0;
306 if( ToDelete
->pName
)
307 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->pName
);
308 switch( ToDelete
->wType
) {
317 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.PTR
.pNameHost
);
322 RtlFreeHeap( RtlGetProcessHeap(), 0,
323 ToDelete
->Data
.MINFO
.pNameMailbox
);
324 RtlFreeHeap( RtlGetProcessHeap(), 0,
325 ToDelete
->Data
.MINFO
.pNameErrorsMailbox
);
332 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.MX
.pNameExchange
);
340 for( i
= 0; i
< ToDelete
->Data
.TXT
.dwStringCount
; i
++ ) {
341 RtlFreeHeap( RtlGetProcessHeap(), 0,
342 ToDelete
->Data
.TXT
.pStringArray
[i
] );
344 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.TXT
.pStringArray
);
349 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.SIG
.pNameSigner
);
353 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.NXT
.pNameNext
);
357 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.SRV
.pNameTarget
);
362 next
= ToDelete
->pNext
;
363 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
);