2 * Copyright 2020 Dmitry Timoshkov
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "wine/test.h"
32 #define NS_MAXDNAME 1025
34 static void test_DnsQuery(void)
36 WCHAR domain
[MAX_PATH
];
37 WCHAR name
[NS_MAXDNAME
];
43 status
= DnsQuery_W(L
"winehq.org", DNS_TYPE_A
, DNS_QUERY_STANDARD
, NULL
, &rec
, NULL
);
44 if (status
== ERROR_TIMEOUT
)
46 skip("query timed out\n");
49 ok(status
== ERROR_SUCCESS
, "got %ld\n", status
);
50 DnsRecordListFree(rec
, DnsFreeRecordList
);
52 status
= DnsQuery_W(L
"", DNS_TYPE_SRV
, DNS_QUERY_STANDARD
, NULL
, &rec
, NULL
);
53 ok(status
== DNS_ERROR_RCODE_NAME_ERROR
|| status
== DNS_INFO_NO_RECORDS
|| status
== ERROR_INVALID_NAME
/* XP */,
56 wcscpy(domain
, L
"_ldap._tcp.deadbeef");
57 status
= DnsQuery_W(domain
, DNS_TYPE_SRV
, DNS_QUERY_STANDARD
, NULL
, &rec
, NULL
);
58 ok(status
== DNS_ERROR_RCODE_NAME_ERROR
|| status
== DNS_INFO_NO_RECORDS
|| status
== ERROR_INVALID_NAME
/* XP */,
61 wcscpy(domain
, L
"_ldap._tcp.dc._msdcs.");
62 size
= ARRAY_SIZE(domain
) - wcslen(domain
);
63 ret
= GetComputerNameExW(ComputerNameDnsDomain
, domain
+ wcslen(domain
), &size
);
64 ok(ret
, "GetComputerNameEx error %lu\n", GetLastError());
67 skip("computer is not in a domain\n");
71 status
= DnsQuery_W(domain
, DNS_TYPE_SRV
, DNS_QUERY_STANDARD
, NULL
, &rec
, NULL
);
72 trace("DnsQuery_W(%s) => %ld\n", wine_dbgstr_w(domain
), status
);
73 if (status
!= ERROR_SUCCESS
)
75 skip("domain %s doesn't have an SRV entry\n", wine_dbgstr_w(domain
));
79 trace("target %s, port %d\n", wine_dbgstr_w(rec
->Data
.Srv
.pNameTarget
), rec
->Data
.Srv
.wPort
);
81 lstrcpynW(name
, rec
->Data
.Srv
.pNameTarget
, ARRAY_SIZE(name
));
82 DnsRecordListFree(rec
, DnsFreeRecordList
);
85 status
= DnsQuery_W(name
, DNS_TYPE_A
, DNS_QUERY_STANDARD
, NULL
, &rec
, NULL
);
86 ok(status
== ERROR_SUCCESS
|| status
== DNS_ERROR_RCODE_NAME_ERROR
, "DnsQuery_W(%s) => %ld\n",
87 wine_dbgstr_w(name
), status
);
88 if (status
== ERROR_SUCCESS
)
91 WCHAR buf
[IP4_ADDRESS_STRING_LENGTH
];
93 addr
.sin_family
= AF_INET
;
95 addr
.sin_addr
.s_addr
= rec
->Data
.A
.IpAddress
;
97 ret
= WSAAddressToStringW((SOCKADDR
*)&addr
, sizeof(addr
), NULL
, buf
, &size
);
98 ok(!ret
, "WSAAddressToStringW error %lu\n", ret
);
99 trace("WSAAddressToStringW => %s\n", wine_dbgstr_w(buf
));
101 DnsRecordListFree(rec
, DnsFreeRecordList
);
105 status
= DnsQuery_W(name
, DNS_TYPE_AAAA
, DNS_QUERY_STANDARD
, NULL
, &rec
, NULL
);
106 ok(status
== ERROR_SUCCESS
|| status
== DNS_ERROR_RCODE_NAME_ERROR
, "DnsQuery_W(%s) => %ld\n",
107 wine_dbgstr_w(name
), status
);
108 if (status
== ERROR_SUCCESS
)
111 WCHAR buf
[IP6_ADDRESS_STRING_LENGTH
];
113 addr
.sin6_family
= AF_INET6
;
115 addr
.sin6_scope_id
= 0;
116 memcpy(addr
.sin6_addr
.s6_addr
, &rec
->Data
.AAAA
.Ip6Address
, sizeof(rec
->Data
.AAAA
.Ip6Address
));
118 ret
= WSAAddressToStringW((SOCKADDR
*)&addr
, sizeof(addr
), NULL
, buf
, &size
);
119 ok(!ret
, "WSAAddressToStringW error %lu\n", ret
);
120 trace("WSAAddressToStringW => %s\n", wine_dbgstr_w(buf
));
122 DnsRecordListFree(rec
, DnsFreeRecordList
);
126 static IP_ADAPTER_ADDRESSES
*get_adapters(void)
128 ULONG err
, size
= 1024;
129 IP_ADAPTER_ADDRESSES
*ret
= malloc( size
);
132 err
= GetAdaptersAddresses( AF_UNSPEC
, GAA_FLAG_SKIP_ANYCAST
| GAA_FLAG_SKIP_MULTICAST
|
133 GAA_FLAG_SKIP_FRIENDLY_NAME
,
135 if (err
!= ERROR_BUFFER_OVERFLOW
) break;
136 ret
= realloc( ret
, size
);
138 if (err
== ERROR_SUCCESS
) return ret
;
143 static void test_DnsQueryConfig( void )
146 DWORD size
, i
, ipv6_count
;
147 WCHAR name
[MAX_ADAPTER_NAME_LENGTH
+ 1];
148 IP_ADAPTER_ADDRESSES
*adapters
, *ptr
;
149 DNS_ADDR_ARRAY
*ipv4
, *ipv6
, *unspec
;
150 IP4_ARRAY
*ip4_array
;
152 if (!(adapters
= get_adapters())) return;
154 for (ptr
= adapters
; ptr
; ptr
= ptr
->Next
)
156 MultiByteToWideChar( CP_ACP
, 0, ptr
->AdapterName
, -1, name
, ARRAY_SIZE(name
) );
157 if (ptr
->IfType
== IF_TYPE_SOFTWARE_LOOPBACK
) continue;
160 err
= DnsQueryConfig( DnsConfigDnsServersIpv4
, 0, name
, NULL
, NULL
, &size
);
162 ipv4
= malloc( size
);
164 err
= DnsQueryConfig( DnsConfigDnsServersIpv4
, 0, name
, NULL
, ipv4
, &size
);
165 ok( err
== ERROR_MORE_DATA
, "got %ld\n", err
);
167 err
= DnsQueryConfig( DnsConfigDnsServersIpv4
, 0, name
, NULL
, ipv4
, &size
);
168 ok( !err
, "got %ld\n", err
);
170 ok( ipv4
->AddrCount
== ipv4
->MaxCount
, "got %lu vs %lu\n", ipv4
->AddrCount
, ipv4
->MaxCount
);
171 ok( !ipv4
->Tag
, "got %#lx\n", ipv4
->Tag
);
172 ok( !ipv4
->Family
, "got %d\n", ipv4
->Family
);
173 ok( !ipv4
->WordReserved
, "got %#x\n", ipv4
->WordReserved
);
174 ok( !ipv4
->Flags
, "got %#lx\n", ipv4
->Flags
);
175 ok( !ipv4
->MatchFlag
, "got %#lx\n", ipv4
->MatchFlag
);
176 ok( !ipv4
->Reserved1
, "got %#lx\n", ipv4
->Reserved1
);
177 ok( !ipv4
->Reserved2
, "got %#lx\n", ipv4
->Reserved2
);
180 err
= DnsQueryConfig( DnsConfigDnsServerList
, 0, name
, NULL
, NULL
, &size
);
181 ok( !err
, "got %ld\n", err
);
182 ip4_array
= malloc( size
);
183 err
= DnsQueryConfig( DnsConfigDnsServerList
, 0, name
, NULL
, ip4_array
, &size
);
184 ok( !err
, "got %ld\n", err
);
186 ok( ipv4
->AddrCount
== ip4_array
->AddrCount
, "got %lu vs %lu\n", ipv4
->AddrCount
, ip4_array
->AddrCount
);
188 for (i
= 0; i
< ipv4
->AddrCount
; i
++)
190 SOCKADDR_IN
*sa
= (SOCKADDR_IN
*)ipv4
->AddrArray
[i
].MaxSa
;
192 ok( sa
->sin_family
== AF_INET
, "got %d\n", sa
->sin_family
);
193 ok( sa
->sin_addr
.s_addr
== ip4_array
->AddrArray
[i
], "got %#lx vs %#lx\n",
194 sa
->sin_addr
.s_addr
, ip4_array
->AddrArray
[i
] );
195 ok( ipv4
->AddrArray
[i
].Data
.DnsAddrUserDword
[0] == sizeof(*sa
), "got %lu\n",
196 ipv4
->AddrArray
[i
].Data
.DnsAddrUserDword
[0] );
200 err
= DnsQueryConfig( DnsConfigDnsServersIpv6
, 0, name
, NULL
, NULL
, &size
);
201 ok( !err
|| err
== DNS_ERROR_NO_DNS_SERVERS
, "got %ld\n", err
);
206 ipv6
= malloc( size
);
207 err
= DnsQueryConfig( DnsConfigDnsServersIpv6
, 0, name
, NULL
, ipv6
, &size
);
208 ok( !err
, "got %ld\n", err
);
209 ipv6_count
= ipv6
->AddrCount
;
213 err
= DnsQueryConfig( DnsConfigDnsServersUnspec
, 0, name
, NULL
, NULL
, &size
);
214 ok( !err
, "got %ld\n", err
);
215 unspec
= malloc( size
);
216 err
= DnsQueryConfig( DnsConfigDnsServersUnspec
, 0, name
, NULL
, unspec
, &size
);
217 ok( !err
, "got %ld\n", err
);
219 ok( unspec
->AddrCount
== ipv4
->AddrCount
+ ipv6_count
, "got %lu vs %lu + %lu\n",
220 unspec
->AddrCount
, ipv4
->AddrCount
, ipv6_count
);
235 WSAStartup(MAKEWORD(2, 2), &data
);
238 test_DnsQueryConfig();