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>
17 /* DnsQuery ****************************
18 * Begin a DNS query, and allow the result to be placed in the application
19 * supplied result pointer. The result can be manipulated with the record
22 * Name -- The DNS object to be queried.
23 * Type -- The type of records to be returned. These are
25 * Options -- Query options. DNS_QUERY_STANDARD is the base
26 * state, and every other option takes precedence.
27 * multiple options can be combined. Listed in
29 * Servers -- List of alternate servers (optional)
30 * QueryResultSet -- Pointer to the result pointer that will be filled
31 * when the response is available.
32 * Reserved -- Response as it appears on the wire. Optional.
35 char *xstrsave(const char *str
) {
38 p
= RtlAllocateHeap( RtlGetProcessHeap(), 0, strlen(str
)+1 );
43 DNS_STATUS WINAPI DnsQuery_A
48 PDNS_RECORDA
*QueryResultSet
,
59 adns_error
= adns_init( &astate
,
64 if( adns_error
!= adns_s_ok
) {
65 adns_finish( astate
);
66 return DnsIntTranslateAdnsToDNS_STATUS( adns_error
);
69 adns_error
= adns_synchronous( astate
,
75 if( adns_error
!= adns_s_ok
) {
76 adns_finish( astate
);
77 return DnsIntTranslateAdnsToDNS_STATUS( adns_error
);
80 *QueryResultSet
= (PDNS_RECORDA
)RtlAllocateHeap( RtlGetProcessHeap(), 0,
81 sizeof( DNS_RECORDA
) );
82 (*QueryResultSet
)->wType
= Type
;
83 (*QueryResultSet
)->pName
= xstrsave( Name
);
84 (*QueryResultSet
)->wDataLength
= sizeof(DNS_A_DATA
);
85 (*QueryResultSet
)->Data
.A
.IpAddress
=
86 answer
->rrs
.addr
->addr
.inet
.sin_addr
.s_addr
;
87 adns_finish( astate
);
91 return DNS_ERROR_NO_MEMORY
; /* XXX arty: find a better error code. */
95 static PCHAR
DnsWToC( const WCHAR
*WideString
) {
96 int chars
= wcstombs( NULL
, WideString
, 0 );
97 PCHAR out
= RtlAllocateHeap( RtlGetProcessHeap(), 0, chars
+ 1 );
98 wcstombs( out
, WideString
, chars
+ 1 );
102 static PWCHAR
DnsCToW( const CHAR
*NarrowString
) {
103 int chars
= mbstowcs( NULL
, NarrowString
, 0 );
104 PWCHAR out
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
105 (chars
+ 1) * sizeof(WCHAR
) );
106 mbstowcs( out
, NarrowString
, chars
+ 1 );
110 DNS_STATUS WINAPI DnsQuery_W
115 PDNS_RECORDW
*QueryResultSet
,
120 PDNS_RECORDA QueryResultWide
;
121 PDNS_RECORDW ConvertedRecord
= 0, LastRecord
= 0;
123 Buffer
= DnsWToC( Name
);
125 Status
= DnsQuery_A( Buffer
, Type
, Options
, Servers
, &QueryResultWide
,
128 while( Status
== ERROR_SUCCESS
&& QueryResultWide
) {
129 switch( QueryResultWide
->wType
) {
134 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
135 sizeof(DNS_RECORDA
) );
136 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
137 ConvertedRecord
->wType
= QueryResultWide
->wType
;
138 ConvertedRecord
->wDataLength
= QueryResultWide
->wDataLength
;
139 memcpy( ConvertedRecord
, QueryResultWide
,
140 QueryResultWide
->wDataLength
);
151 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
152 sizeof(DNS_RECORDA
) );
153 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
154 ConvertedRecord
->wType
= QueryResultWide
->wType
;
155 ConvertedRecord
->wDataLength
= sizeof(DNS_PTR_DATAA
);
156 ConvertedRecord
->Data
.PTR
.pNameHost
=
157 DnsCToW( QueryResultWide
->Data
.PTR
.pNameHost
);
161 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
162 sizeof(DNS_RECORDA
) );
163 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
164 ConvertedRecord
->wType
= QueryResultWide
->wType
;
165 ConvertedRecord
->wDataLength
= sizeof(DNS_MINFO_DATAA
);
166 ConvertedRecord
->Data
.MINFO
.pNameMailbox
=
167 DnsCToW( QueryResultWide
->Data
.MINFO
.pNameMailbox
);
168 ConvertedRecord
->Data
.MINFO
.pNameErrorsMailbox
=
169 DnsCToW( QueryResultWide
->Data
.MINFO
.pNameErrorsMailbox
);
175 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
176 sizeof(DNS_RECORDA
) );
177 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
178 ConvertedRecord
->wType
= QueryResultWide
->wType
;
179 ConvertedRecord
->wDataLength
= sizeof(DNS_MX_DATAW
);
180 ConvertedRecord
->Data
.MX
.pNameExchange
=
181 DnsCToW( QueryResultWide
->Data
.MX
.pNameExchange
);
182 ConvertedRecord
->Data
.MX
.wPreference
=
183 QueryResultWide
->Data
.MX
.wPreference
;
189 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
190 sizeof(DNS_TXT_DATAW
) +
192 Data
.TXT
.dwStringCount
);
193 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
194 ConvertedRecord
->wType
= QueryResultWide
->wType
;
195 ConvertedRecord
->wDataLength
=
196 sizeof(DNS_TXT_DATAW
) +
197 (sizeof(PWCHAR
) * QueryResultWide
->Data
.TXT
.dwStringCount
);
198 ConvertedRecord
->Data
.TXT
.dwStringCount
=
199 QueryResultWide
->Data
.TXT
.dwStringCount
;
200 for( i
= 0; i
< ConvertedRecord
->Data
.TXT
.dwStringCount
; i
++ ) {
201 ConvertedRecord
->Data
.TXT
.pStringArray
[i
] =
202 DnsCToW( QueryResultWide
->Data
.TXT
.pStringArray
[i
] );
207 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
208 sizeof(DNS_NULL_DATA
) +
210 Data
.Null
.dwByteCount
);
211 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
212 ConvertedRecord
->wType
= QueryResultWide
->wType
;
213 ConvertedRecord
->wDataLength
=
214 sizeof(DNS_NULL_DATA
) + QueryResultWide
->Data
.Null
.dwByteCount
;
215 ConvertedRecord
->Data
.Null
.dwByteCount
=
216 QueryResultWide
->Data
.Null
.dwByteCount
;
217 memcpy( &ConvertedRecord
->Data
.Null
.Data
,
218 &QueryResultWide
->Data
.Null
.Data
,
219 QueryResultWide
->Data
.Null
.dwByteCount
);
223 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
224 sizeof(DNS_RECORDA
) );
225 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
226 ConvertedRecord
->wType
= QueryResultWide
->wType
;
227 ConvertedRecord
->wDataLength
= sizeof(DNS_SIG_DATAA
);
228 memcpy( &ConvertedRecord
->Data
.SIG
,
229 &QueryResultWide
->Data
.SIG
,
230 sizeof(QueryResultWide
->Data
.SIG
) );
231 ConvertedRecord
->Data
.SIG
.pNameSigner
=
232 DnsCToW( QueryResultWide
->Data
.SIG
.pNameSigner
);
236 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
237 sizeof(DNS_RECORDA
) );
238 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
239 ConvertedRecord
->wType
= QueryResultWide
->wType
;
240 ConvertedRecord
->wDataLength
= sizeof(DNS_NXT_DATAA
);
241 memcpy( &ConvertedRecord
->Data
.NXT
,
242 &QueryResultWide
->Data
.NXT
,
243 sizeof(QueryResultWide
->Data
.NXT
) );
244 ConvertedRecord
->Data
.NXT
.pNameNext
=
245 DnsCToW( QueryResultWide
->Data
.NXT
.pNameNext
);
249 ConvertedRecord
= RtlAllocateHeap( RtlGetProcessHeap(), 0,
250 sizeof(DNS_RECORDA
) );
251 ConvertedRecord
->pName
= DnsCToW( QueryResultWide
->pName
);
252 ConvertedRecord
->wType
= QueryResultWide
->wType
;
253 ConvertedRecord
->wDataLength
= sizeof(DNS_SRV_DATAA
);
254 memcpy( &ConvertedRecord
->Data
.SRV
,
255 &QueryResultWide
->Data
.SRV
,
256 sizeof(QueryResultWide
->Data
.SRV
) );
257 ConvertedRecord
->Data
.SRV
.pNameTarget
=
258 DnsCToW( QueryResultWide
->Data
.SRV
.pNameTarget
);
263 LastRecord
->pNext
= ConvertedRecord
;
264 LastRecord
= LastRecord
->pNext
;
266 LastRecord
= *QueryResultSet
= ConvertedRecord
;
270 LastRecord
->pNext
= 0;
273 RtlFreeHeap( RtlGetProcessHeap(), 0, Buffer
);
278 DNS_STATUS WINAPI DnsQuery_UTF8
283 PDNS_RECORDA
*QueryResultSet
,
285 return DnsQuery_UTF8( Name
, Type
, Options
, Servers
, QueryResultSet
,
289 void DnsIntFreeRecordList( PDNS_RECORDA ToDelete
) {
291 PDNS_RECORDA next
= 0;
294 if( ToDelete
->pName
)
295 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->pName
);
296 switch( ToDelete
->wType
) {
305 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.PTR
.pNameHost
);
309 RtlFreeHeap( RtlGetProcessHeap(), 0,
310 ToDelete
->Data
.MINFO
.pNameMailbox
);
311 RtlFreeHeap( RtlGetProcessHeap(), 0,
312 ToDelete
->Data
.MINFO
.pNameErrorsMailbox
);
318 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.MX
.pNameExchange
);
324 for( i
= 0; i
< ToDelete
->Data
.TXT
.dwStringCount
; i
++ ) {
325 RtlFreeHeap( RtlGetProcessHeap(), 0,
326 ToDelete
->Data
.TXT
.pStringArray
[i
] );
328 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.TXT
.pStringArray
);
332 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.SIG
.pNameSigner
);
336 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.NXT
.pNameNext
);
340 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
->Data
.SRV
.pNameTarget
);
344 next
= ToDelete
->pNext
;
345 RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete
);