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
14 #include <internal/windns.h>
16 #define NTOS_MODE_USER
19 /* DnsQuery ****************************
20 * Begin a DNS query, and allow the result to be placed in the application
21 * supplied result pointer. The result can be manipulated with the record
24 * Name -- The DNS object to be queried.
25 * Type -- The type of records to be returned. These are
27 * Options -- Query options. DNS_QUERY_STANDARD is the base
28 * state, and every other option takes precedence.
29 * multiple options can be combined. Listed in
31 * Servers -- List of alternate servers (optional)
32 * QueryResultSet -- Pointer to the result pointer that will be filled
33 * when the response is available.
34 * Reserved -- Response as it appears on the wire. Optional.
37 char *xstrsave(const char *str
) {
40 p
= RtlAllocateHeap( RtlGetProcessHeap(), 0, strlen(str
)+1 );
45 DNS_STATUS WINAPI DnsQuery_A
50 PDNS_RECORD
*QueryResultSet
,
61 adns_error
= adns_init( &astate
,
66 if( adns_error
!= adns_s_ok
) {
67 adns_finish( astate
);
68 return DnsIntTranslateAdnsToDNS_STATUS( adns_error
);
71 adns_error
= adns_synchronous( astate
,
77 if( adns_error
!= adns_s_ok
) {
78 adns_finish( astate
);
79 return DnsIntTranslateAdnsToDNS_STATUS( adns_error
);
82 if( answer
&& answer
->rrs
.addr
) {
84 (PDNS_RECORD
)RtlAllocateHeap( RtlGetProcessHeap(), 0,
85 sizeof( DNS_RECORD
) );
86 (*QueryResultSet
)->pNext
= NULL
;
87 (*QueryResultSet
)->wType
= Type
;
88 (*QueryResultSet
)->pName
= xstrsave( Name
);
89 (*QueryResultSet
)->wDataLength
= sizeof(DNS_A_DATA
);
90 (*QueryResultSet
)->Data
.A
.IpAddress
=
91 answer
->rrs
.addr
->addr
.inet
.sin_addr
.s_addr
;
92 adns_finish( astate
);
95 return ERROR_FILE_NOT_FOUND
;
97 return ERROR_OUTOFMEMORY
; /* XXX arty: find a better error code. */
101 static PCHAR
DnsWToC( const WCHAR
*WideString
) {
102 int chars
= wcstombs( NULL
, WideString
, 0 );
103 PCHAR out
= RtlAllocateHeap( RtlGetProcessHeap(), 0, chars
+ 1 );
104 wcstombs( out
, WideString
, chars
+ 1 );
108 static PWCHAR
DnsCToW( const CHAR
*NarrowString
) {
109 int chars
= mbstowcs( NULL
, NarrowString
, 0 );
110 PWCHAR out
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
111 (chars
+ 1) * sizeof(WCHAR
) );
112 mbstowcs( out
, NarrowString
, chars
+ 1 );
116 DNS_STATUS WINAPI DnsQuery_W
121 PDNS_RECORD
*QueryResultSet
,
126 PDNS_RECORD QueryResultWide
;
127 PDNS_RECORD ConvertedRecord
= 0, LastRecord
= 0;
129 Buffer
= DnsWToC( Name
);
131 Status
= DnsQuery_A( Buffer
, Type
, Options
, Servers
, &QueryResultWide
,
134 while( Status
== ERROR_SUCCESS
&& QueryResultWide
) {
135 switch( QueryResultWide
->wType
) {
142 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
143 sizeof(DNS_RECORD
) );
144 ConvertedRecord
->pName
= (PCHAR
)DnsCToW( QueryResultWide
->pName
);
145 ConvertedRecord
->wType
= QueryResultWide
->wType
;
146 ConvertedRecord
->wDataLength
= QueryResultWide
->wDataLength
;
147 memcpy( ConvertedRecord
, QueryResultWide
,
148 QueryResultWide
->wDataLength
);
159 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
160 sizeof(DNS_RECORD
) );
161 ConvertedRecord
->pName
= (PCHAR
)DnsCToW( QueryResultWide
->pName
);
162 ConvertedRecord
->wType
= QueryResultWide
->wType
;
163 ConvertedRecord
->wDataLength
= sizeof(DNS_PTR_DATA
);
164 ConvertedRecord
->Data
.PTR
.pNameHost
=
165 (PCHAR
)DnsCToW( QueryResultWide
->Data
.PTR
.pNameHost
);
171 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
172 sizeof(DNS_RECORD
) );
173 ConvertedRecord
->pName
= (PCHAR
)DnsCToW( QueryResultWide
->pName
);
174 ConvertedRecord
->wType
= QueryResultWide
->wType
;
175 ConvertedRecord
->wDataLength
= sizeof(DNS_MINFO_DATA
);
176 ConvertedRecord
->Data
.MINFO
.pNameMailbox
=
177 (PCHAR
)DnsCToW( QueryResultWide
->Data
.MINFO
.pNameMailbox
);
178 ConvertedRecord
->Data
.MINFO
.pNameErrorsMailbox
=
179 (PCHAR
)DnsCToW( QueryResultWide
->Data
.MINFO
.pNameErrorsMailbox
);
187 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
188 sizeof(DNS_RECORD
) );
189 ConvertedRecord
->pName
= (PCHAR
)DnsCToW( QueryResultWide
->pName
);
190 ConvertedRecord
->wType
= QueryResultWide
->wType
;
191 ConvertedRecord
->wDataLength
= sizeof(DNS_MX_DATA
);
192 ConvertedRecord
->Data
.MX
.pNameExchange
=
193 (PCHAR
)DnsCToW( QueryResultWide
->Data
.MX
.pNameExchange
);
194 ConvertedRecord
->Data
.MX
.wPreference
=
195 QueryResultWide
->Data
.MX
.wPreference
;
203 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
204 sizeof(DNS_TXT_DATA
) +
206 Data
.TXT
.dwStringCount
);
207 ConvertedRecord
->pName
= (PCHAR
)DnsCToW( QueryResultWide
->pName
);
208 ConvertedRecord
->wType
= QueryResultWide
->wType
;
209 ConvertedRecord
->wDataLength
=
210 sizeof(DNS_TXT_DATA
) +
211 (sizeof(PWCHAR
) * QueryResultWide
->Data
.TXT
.dwStringCount
);
212 ConvertedRecord
->Data
.TXT
.dwStringCount
=
213 QueryResultWide
->Data
.TXT
.dwStringCount
;
214 for( i
= 0; i
< ConvertedRecord
->Data
.TXT
.dwStringCount
; i
++ ) {
215 ConvertedRecord
->Data
.TXT
.pStringArray
[i
] =
216 (PCHAR
)DnsCToW( QueryResultWide
->Data
.TXT
.pStringArray
[i
] );
221 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
222 sizeof(DNS_NULL_DATA
) +
224 Data
.Null
.dwByteCount
);
225 ConvertedRecord
->pName
= (PCHAR
)DnsCToW( QueryResultWide
->pName
);
226 ConvertedRecord
->wType
= QueryResultWide
->wType
;
227 ConvertedRecord
->wDataLength
=
228 sizeof(DNS_NULL_DATA
) + QueryResultWide
->Data
.Null
.dwByteCount
;
229 ConvertedRecord
->Data
.Null
.dwByteCount
=
230 QueryResultWide
->Data
.Null
.dwByteCount
;
231 memcpy( &ConvertedRecord
->Data
.Null
.Data
,
232 &QueryResultWide
->Data
.Null
.Data
,
233 QueryResultWide
->Data
.Null
.dwByteCount
);
238 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
239 sizeof(DNS_RECORDA
) );
240 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
241 ConvertedRecord
->wType
= QueryResultWide
->wType
;
242 ConvertedRecord
->wDataLength
= sizeof(DNS_SIG_DATAA
);
243 memcpy( &ConvertedRecord
->Data
.SIG
,
244 &QueryResultWide
->Data
.SIG
,
245 sizeof(QueryResultWide
->Data
.SIG
) );
246 ConvertedRecord
->Data
.SIG
.pNameSigner
=
247 DnsCToW( QueryResultWide
->Data
.SIG
.pNameSigner
);
251 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
252 sizeof(DNS_RECORDA
) );
253 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
254 ConvertedRecord
->wType
= QueryResultWide
->wType
;
255 ConvertedRecord
->wDataLength
= sizeof(DNS_NXT_DATAA
);
256 memcpy( &ConvertedRecord
->Data
.NXT
,
257 &QueryResultWide
->Data
.NXT
,
258 sizeof(QueryResultWide
->Data
.NXT
) );
259 ConvertedRecord
->Data
.NXT
.pNameNext
=
260 DnsCToW( QueryResultWide
->Data
.NXT
.pNameNext
);
264 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
265 sizeof(DNS_RECORDA
) );
266 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
267 ConvertedRecord
->wType
= QueryResultWide
->wType
;
268 ConvertedRecord
->wDataLength
= sizeof(DNS_SRV_DATAA
);
269 memcpy( &ConvertedRecord
->Data
.SRV
,
270 &QueryResultWide
->Data
.SRV
,
271 sizeof(QueryResultWide
->Data
.SRV
) );
272 ConvertedRecord
->Data
.SRV
.pNameTarget
=
273 DnsCToW( QueryResultWide
->Data
.SRV
.pNameTarget
);
279 LastRecord
->pNext
= ConvertedRecord
;
280 LastRecord
= LastRecord
->pNext
;
282 LastRecord
= *QueryResultSet
= ConvertedRecord
;
286 LastRecord
->pNext
= 0;
289 RtlFreeHeap( RtlGetProcessHeap(), 0, Buffer
);
294 DNS_STATUS WINAPI DnsQuery_UTF8
299 PDNS_RECORD
*QueryResultSet
,
301 return DnsQuery_UTF8( Name
, Type
, Options
, Servers
, QueryResultSet
,
305 void DnsIntFreeRecordList( PDNS_RECORD ToDelete
) {
307 PDNS_RECORD next
= 0;
310 if( ToDelete
->pName
)
311 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->pName
);
312 switch( ToDelete
->wType
) {
321 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.PTR
.pNameHost
);
326 RtlFreeHeap( RtlGetProcessHeap(), 0,
327 ToDelete
->Data
.MINFO
.pNameMailbox
);
328 RtlFreeHeap( RtlGetProcessHeap(), 0,
329 ToDelete
->Data
.MINFO
.pNameErrorsMailbox
);
336 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.MX
.pNameExchange
);
344 for( i
= 0; i
< ToDelete
->Data
.TXT
.dwStringCount
; i
++ ) {
345 RtlFreeHeap( RtlGetProcessHeap(), 0,
346 ToDelete
->Data
.TXT
.pStringArray
[i
] );
348 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.TXT
.pStringArray
);
353 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.SIG
.pNameSigner
);
357 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.NXT
.pNameNext
);
361 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.SRV
.pNameTarget
);
366 next
= ToDelete
->pNext
;
367 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
);