dnsapi: Build without -DWINE_NO_LONG_TYPES.
[wine.git] / dlls / dnsapi / tests / query.c
blob3307fcbe3cc739968c1e4f77fa7bee1b03ba1ee6
1 /*
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
19 #include <stdarg.h>
20 #include <stdio.h>
22 #include "windef.h"
23 #include "winbase.h"
24 #include "winnls.h"
25 #include "windns.h"
26 #include "winsock2.h"
27 #include "ws2ipdef.h"
28 #include "iphlpapi.h"
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];
38 DWORD ret, size;
39 DNS_RECORDW *rec;
40 DNS_STATUS status;
42 rec = NULL;
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");
47 return;
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 */,
54 "got %ld\n", status);
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 */,
59 "got %ld\n", status);
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());
65 if (!size)
67 skip("computer is not in a domain\n");
68 return;
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));
76 return;
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);
84 /* IPv4 */
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)
90 SOCKADDR_IN addr;
91 WCHAR buf[IP4_ADDRESS_STRING_LENGTH];
93 addr.sin_family = AF_INET;
94 addr.sin_port = 0;
95 addr.sin_addr.s_addr = rec->Data.A.IpAddress;
96 size = sizeof(buf);
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);
104 /* IPv6 */
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)
110 SOCKADDR_IN6 addr;
111 WCHAR buf[IP6_ADDRESS_STRING_LENGTH];
113 addr.sin6_family = AF_INET6;
114 addr.sin6_port = 0;
115 addr.sin6_scope_id = 0;
116 memcpy(addr.sin6_addr.s6_addr, &rec->Data.AAAA.Ip6Address, sizeof(rec->Data.AAAA.Ip6Address));
117 size = sizeof(buf);
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 );
130 for (;;)
132 err = GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
133 GAA_FLAG_SKIP_FRIENDLY_NAME,
134 NULL, ret, &size );
135 if (err != ERROR_BUFFER_OVERFLOW) break;
136 ret = realloc( ret, size );
138 if (err == ERROR_SUCCESS) return ret;
139 free( ret );
140 return NULL;
143 static void test_DnsQueryConfig( void )
145 DNS_STATUS err;
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;
159 size = 0;
160 err = DnsQueryConfig( DnsConfigDnsServersIpv4, 0, name, NULL, NULL, &size );
161 if (err) continue;
162 ipv4 = malloc( size );
163 size--;
164 err = DnsQueryConfig( DnsConfigDnsServersIpv4, 0, name, NULL, ipv4, &size );
165 ok( err == ERROR_MORE_DATA, "got %ld\n", err );
166 size++;
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 );
179 size = 0;
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] );
199 size = 0;
200 err = DnsQueryConfig( DnsConfigDnsServersIpv6, 0, name, NULL, NULL, &size );
201 ok( !err || err == DNS_ERROR_NO_DNS_SERVERS, "got %ld\n", err );
202 ipv6_count = 0;
203 ipv6 = NULL;
204 if (!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;
212 size = 0;
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 );
222 free( ip4_array );
223 free( unspec );
224 free( ipv6 );
225 free( ipv4 );
228 free( adapters );
231 START_TEST(query)
233 WSADATA data;
235 WSAStartup(MAKEWORD(2, 2), &data);
237 test_DnsQuery();
238 test_DnsQueryConfig();