[PATCH 2/2] dnsapi/tests: Add DnsQueryEx and DnsQuery_W tests
Donat Enikeev
donat at enikeev.net
Sun Jan 10 07:55:18 CST 2016
Signed-off-by: Donat Enikeev <donat at enikeev.net>
---
dlls/dnsapi/tests/Makefile.in | 5 +-
dlls/dnsapi/tests/query.c | 546 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 549 insertions(+), 2 deletions(-)
create mode 100644 dlls/dnsapi/tests/query.c
diff --git a/dlls/dnsapi/tests/Makefile.in b/dlls/dnsapi/tests/Makefile.in
index 20412e8..e23e25c 100644
--- a/dlls/dnsapi/tests/Makefile.in
+++ b/dlls/dnsapi/tests/Makefile.in
@@ -2,5 +2,6 @@ TESTDLL = dnsapi.dll
IMPORTS = dnsapi
C_SRCS = \
- name.c \
- record.c
+ name.c \
+ record.c \
+ query.c
diff --git a/dlls/dnsapi/tests/query.c b/dlls/dnsapi/tests/query.c
new file mode 100644
index 0000000..7a59706
--- /dev/null
+++ b/dlls/dnsapi/tests/query.c
@@ -0,0 +1,546 @@
+/* Unit test suite for DnsQuery* API functions
+ *
+ * Copyright (C) 2016 Donat Enikeev
+
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "ntstatus.h"
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winnt.h"
+#include "winternl.h"
+#include "wine/test.h"
+
+#include "inaddr.h"
+#include "in6addr.h"
+#include "ws2tcpip.h"
+
+#include "winnls.h"
+#include "windns.h"
+#include "wine/test.h"
+
+#define DNS_QUERY_TEST_SHOW_TRACE 1
+#define dns_test_trace(args...) if (DNS_QUERY_TEST_SHOW_TRACE) winetest_trace(args);
+
+/* Function ptrs for helper data conversion calls when inet_ntop not available (ie mingw) */
+static HMODULE hntdll = 0;
+static CHAR * (WINAPI *pRtlIpv6AddressToStringA)(const IN6_ADDR *, LPSTR);
+
+static HMODULE hdnsapi = 0;
+static DNS_STATUS(WINAPI *pDnsQueryEx) (DNS_QUERY_REQUEST *, DNS_QUERY_RESULT *, DNS_QUERY_CANCEL *);
+static DNS_STATUS(WINAPI *pDnsQuery_W) (PCWSTR , WORD , DWORD , PVOID , PDNS_RECORDW *, PVOID * );
+
+#ifndef AF_INET
+#define AF_INET 2
+#endif
+#ifndef AF_INET6
+#define AF_INET6 23
+#endif
+
+#define EXPECT_RECORD 1
+#define EXPECT_SEVERAL_RECORDS 2
+#define RESULT_TO_DO_WINE 4
+/* different windows platform reacts differently on non-existent domains or NS servers */
+#define RESULT_OK_ANY_NON_SUCCESS 8
+
+#define TODO_OR_OK(todo_condition,test_condition,subject...) if (todo_condition) { for (winetest_start_todo("wine"); \
+ winetest_loop_todo(); \
+ winetest_end_todo("wine")) { ok(test_condition, ##subject); } } else { ok(test_condition, ##subject) ; }
+
+struct dnsqueryex_test_data {
+ LPCSTR query_name;
+ WORD query_type;
+ ULONG64 query_options;
+ DNS_STATUS expected_status;
+ ULONG flags;
+ LPCSTR dns_server_ip;
+};
+
+static struct dnsqueryex_test_data dnsqueryex_tests[] =
+{
+ /* These entries - to test an usage of particular DNS server.
+ `Family` DNS returns stub for known adult domain (details https://dns.yandex.com/),
+ Please compare IPs with what usual DNS returns for some popular adult domain.
+ Commented for ethic reasons */
+/* { "xxxx", DNS_TYPE_A, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD, "77.88.8.7" },
+ { "xxxx", DNS_TYPE_A, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD, "8.8.8.8" }, */
+
+
+ { "example.com", DNS_TYPE_A, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD, "8.8.4.4" },
+ { "example.org", DNS_TYPE_A, DNS_QUERY_USE_TCP_ONLY, ERROR_SUCCESS, EXPECT_RECORD, NULL },
+
+ /* Wine returns same error code for no records and wrong name DNS_ERROR_RCODE_NAME_ERROR */
+ { "google.com", DNS_TYPE_SIG, DNS_QUERY_STANDARD, DNS_INFO_NO_RECORDS, RESULT_TO_DO_WINE, NULL },
+
+ /* PTR returned here, not SRV */
+ { "test.winehq.org", DNS_TYPE_SRV, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD, NULL },
+ { "test.winehq.org", DNS_TYPE_SRV, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD, "8.8.8.8" },
+
+ /* Please replace with known-to widely work SRV record, this one unstable */
+ /* { "_nicname._tcp.us", DNS_TYPE_SRV, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD, "8.8.4.4" }, */
+
+ { "winehq.org", DNS_TYPE_SOA, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD, NULL },
+ { "winehq.org", DNS_TYPE_SOA, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD, "8.8.4.4" },
+
+ { "winehq.org", DNS_TYPE_MX, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD, NULL },
+ { "winehq.org", DNS_TYPE_MX, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD, "8.8.8.8" },
+
+ { "winehq.org", DNS_TYPE_NS, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD | EXPECT_SEVERAL_RECORDS, NULL },
+ { "winehq.org", DNS_TYPE_NS, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD | EXPECT_SEVERAL_RECORDS, "8.8.8.8" },
+
+ { "test.winehq.org", DNS_TYPE_A, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD, NULL },
+
+ /* Wine returns ERROR_INVALID_NAME */
+ { "_._", DNS_TYPE_A, DNS_QUERY_STANDARD, DNS_ERROR_RCODE_NAME_ERROR, RESULT_TO_DO_WINE, "8.8.8.8" },
+
+ { "test.wine.org_or", DNS_TYPE_AAAA, DNS_QUERY_STANDARD, DNS_ERROR_RCODE_NAME_ERROR, 0, NULL },
+
+ /** windows 8 returns DNS_ERROR_RCODE_NAME_ERROR */
+ { "unexistent", DNS_TYPE_A, DNS_QUERY_STANDARD, ERROR_INVALID_NAME, RESULT_OK_ANY_NON_SUCCESS, NULL },
+
+ /* Punycoded domain */
+ { "xn--c1aay4a.xn--p1ai", DNS_TYPE_AAAA,DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD, "8.8.4.4" },
+
+ { "google.com", DNS_TYPE_A, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD | EXPECT_SEVERAL_RECORDS, NULL },
+ { "google.com", DNS_TYPE_A, DNS_QUERY_USE_TCP_ONLY, ERROR_SUCCESS, EXPECT_RECORD | EXPECT_SEVERAL_RECORDS, "8.8.4.4" },
+ { "google.com", DNS_TYPE_AAAA, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD, "8.8.8.8" },
+ { "google.com", DNS_TYPE_AAAA, DNS_QUERY_USE_TCP_ONLY, ERROR_SUCCESS, EXPECT_RECORD, "8.8.4.4" },
+
+ { "winehq.org", DNS_TYPE_TEXT, DNS_QUERY_STANDARD, ERROR_SUCCESS, EXPECT_RECORD, NULL},
+
+ /* Wine returns same error code for no records and wrong name DNS_ERROR_RCODE_NAME_ERROR */
+ { "winehq.org", DNS_TYPE_AAAA, DNS_QUERY_STANDARD, DNS_INFO_NO_RECORDS, RESULT_TO_DO_WINE, NULL},
+ { "winehq.org", DNS_TYPE_CNAME, DNS_QUERY_STANDARD, DNS_INFO_NO_RECORDS, RESULT_TO_DO_WINE, NULL },
+ { "winehq.org", DNS_TYPE_CNAME, DNS_QUERY_STANDARD, DNS_INFO_NO_RECORDS, RESULT_TO_DO_WINE, "8.8.4.4" },
+
+ { "localhost", DNS_TYPE_A, DNS_QUERY_NO_LOCAL_NAME
+ | DNS_QUERY_NO_HOSTS_FILE, ERROR_INVALID_NAME, 0, "8.8.4.4" },
+
+ /* Wine returns DNS_ERROR_RCODE_NAME_ERROR for AAAA */
+ { "localhost", DNS_TYPE_AAAA, DNS_QUERY_NO_LOCAL_NAME
+ | DNS_QUERY_NO_HOSTS_FILE, ERROR_INVALID_NAME, RESULT_TO_DO_WINE, "8.8.8.8" },
+ /* Wine returns DNS_ERROR_RCODE_SERVER_FAILURE */
+ { "example.com", DNS_TYPE_A, DNS_QUERY_STANDARD, ERROR_TIMEOUT, RESULT_TO_DO_WINE, "1.0.0.0" },
+};
+
+/** For easier cross-compile **/
+DWORD helper_ip2int(const char *ip)
+{
+ const char *end = ip + strlen(ip);
+ DWORD n = 0;
+ while (ip < end) {
+ n <<= 8;
+ n |= strtoul(ip, (char **)&ip, 10);
+ ip++;
+ }
+
+ return htonl(n);
+}
+
+const char *helper_dns_type_to_str( unsigned short type )
+{
+ switch (type)
+ {
+#define X(x) case (x): return #x;
+ X(DNS_TYPE_ZERO)
+ X(DNS_TYPE_A)
+ X(DNS_TYPE_NS)
+ X(DNS_TYPE_MD)
+ X(DNS_TYPE_MF)
+ X(DNS_TYPE_CNAME)
+ X(DNS_TYPE_SOA)
+ X(DNS_TYPE_MB)
+ X(DNS_TYPE_MG)
+ X(DNS_TYPE_MR)
+ X(DNS_TYPE_NULL)
+ X(DNS_TYPE_WKS)
+ X(DNS_TYPE_PTR)
+ X(DNS_TYPE_HINFO)
+ X(DNS_TYPE_MINFO)
+ X(DNS_TYPE_MX)
+ X(DNS_TYPE_TEXT)
+ X(DNS_TYPE_RP)
+ X(DNS_TYPE_AFSDB)
+ X(DNS_TYPE_X25)
+ X(DNS_TYPE_ISDN)
+ X(DNS_TYPE_RT)
+ X(DNS_TYPE_NSAP)
+ X(DNS_TYPE_NSAPPTR)
+ X(DNS_TYPE_SIG)
+ X(DNS_TYPE_KEY)
+ X(DNS_TYPE_PX)
+ X(DNS_TYPE_GPOS)
+ X(DNS_TYPE_AAAA)
+ X(DNS_TYPE_LOC)
+ X(DNS_TYPE_NXT)
+ X(DNS_TYPE_EID)
+ X(DNS_TYPE_NIMLOC)
+ X(DNS_TYPE_SRV)
+ X(DNS_TYPE_ATMA)
+ X(DNS_TYPE_NAPTR)
+ X(DNS_TYPE_KX)
+ X(DNS_TYPE_CERT)
+ X(DNS_TYPE_A6)
+ X(DNS_TYPE_DNAME)
+ X(DNS_TYPE_SINK)
+ X(DNS_TYPE_OPT)
+ X(DNS_TYPE_UINFO)
+ X(DNS_TYPE_UID)
+ X(DNS_TYPE_GID)
+ X(DNS_TYPE_UNSPEC)
+ X(DNS_TYPE_ADDRS)
+ X(DNS_TYPE_TKEY)
+ X(DNS_TYPE_TSIG)
+ X(DNS_TYPE_IXFR)
+ X(DNS_TYPE_AXFR)
+ X(DNS_TYPE_MAILB)
+ X(DNS_TYPE_MAILA)
+ X(DNS_TYPE_ANY)
+ X(DNS_TYPE_WINS)
+ X(DNS_TYPE_WINSR)
+#undef X
+ default: { static char tmp[7]; sprintf( tmp, "0x%04x", type ); return tmp; }
+ }
+}
+
+void helper_check_record(PDNS_RECORD record, struct dnsqueryex_test_data * test) {
+
+ dns_test_trace("Found record %p of type %s (%d) for %s; requested: %s (%d) \n", record,
+ helper_dns_type_to_str(record->wType), record->wType, test->query_name,
+ helper_dns_type_to_str(test->query_type), test->query_type);
+
+ switch (record->wType)
+ {
+ case DNS_TYPE_A:
+ {
+ CHAR data[IP4_ADDRESS_STRING_LENGTH];
+ DWORD i = record->Data.A.IpAddress;
+
+ ok ( i, "Zero ip returned %d for record %p\n", record->Data.A.IpAddress, record);
+
+ sprintf(data, "%i.%i.%i.%i", i & 0xFF, (i >> 8) & 0xFF, (i >> 16) & 0xFF, (i >> 24) & 0xFF);
+
+ dns_test_trace("IP address from A record: %s\n", (char *)&data);
+
+ ok ( strlen(data) >= 8,
+ "Unexpected length of IPv4 '%s' in resulting record, at least 8 characters expected \n", (char *)&data);
+ return;
+ }
+ case DNS_TYPE_AAAA:
+ {
+ CHAR data[IP6_ADDRESS_STRING_LENGTH];
+ int converted = 0;
+#ifdef HAVE_INET_NTOP
+ inet_ntop(AF_INET6, &record->Data.AAAA.Ip6Address, &data, IP6_ADDRESS_STRING_LENGTH);
+ converted = 1;
+#else
+ if (pRtlIpv6AddressToStringA && !converted)
+ {
+ pRtlIpv6AddressToStringA( (const IN6_ADDR *)&record->Data.AAAA.Ip6Address, (LPSTR) &data );
+ converted = 1;
+ }
+#endif
+ if (converted)
+ {
+ dns_test_trace("IPv6 address from AAAA record: %s\n", (char *)&data);
+ ok ( strlen(data) >= 3 ,
+ "Unexpected length of IPv6 '%s' in resulting record, at least 3 characters expected \n", (char *)&data);
+ } else
+ skip("No conversion available for a IPv6 test, skipping\n");
+ return;
+ }
+ case DNS_TYPE_DNAME:
+ case DNS_TYPE_NS:
+ case DNS_TYPE_CNAME:
+ case DNS_TYPE_PTR:
+ {
+ ok (lstrlenW(record->Data.PTR.pNameHost),
+ "NameHost expected, got %p\n", record->Data.PTR.pNameHost);
+
+ dns_test_trace("NameHost: %s\n", wine_dbgstr_w(record->Data.PTR.pNameHost));
+
+ return;
+ }
+ case DNS_TYPE_TEXT:
+ { int i;
+ LPWSTR *string_array;
+
+ dns_test_trace("Strings count: %d\n", record->Data.TXT.dwStringCount);
+
+ string_array = (LPWSTR *)record->Data.TXT.pStringArray;
+
+ dns_test_trace("Strings count: %d\n", record->Data.TXT.dwStringCount);
+
+ ok (record->Data.TXT.dwStringCount,
+ "At least one TXT record expected at %p \n", &record->Data);
+
+ for (i=0; i<record->Data.TXT.dwStringCount; i++)
+ {
+ dns_test_trace("String[%d] = %s\n", i+1, wine_dbgstr_w(*string_array));
+ string_array++;
+ }
+ return;
+ }
+ case DNS_TYPE_MX:
+ {
+ dns_test_trace("NameExchange: %s, preference %d\n", wine_dbgstr_w(record->Data.MX.pNameExchange), record->Data.MX.wPreference);
+
+ ok (lstrlenW(record->Data.MX.pNameExchange),
+ "NameExchange expected at %p\n", record->Data.MX.pNameExchange);
+
+ return;
+ }
+ case DNS_TYPE_SOA:
+ {
+ dns_test_trace("n\tNamePrimaryServer = %s, NameAdministrator = %s, expire = %d\n",
+ wine_dbgstr_w(record->Data.SOA.pNamePrimaryServer), wine_dbgstr_w(record->Data.SOA.pNameAdministrator), record->Data.SOA.dwExpire);
+
+ ok (lstrlenW(record->Data.SOA.pNamePrimaryServer),
+ "NamePrimaryServer expected at %p\n", record->Data.SOA.pNamePrimaryServer);
+
+ ok (lstrlenW(record->Data.SOA.pNameAdministrator),
+ "NameNameAdministrator expected at %p\n", record->Data.SOA.pNameAdministrator);
+
+ return;
+ }
+ case DNS_TYPE_SRV:
+ {
+ dns_test_trace("n\tNameTarget = %s, port = %d, priority = %d, weight = %d\n",
+ wine_dbgstr_w(record->Data.SRV.pNameTarget), record->Data.SRV.wPort, record->Data.SRV.wPriority, record->Data.SRV.wWeight );
+
+ ok (lstrlenW(record->Data.SRV.pNameTarget),
+ "NameTarget expected at %p\n", record->Data.SRV.pNameTarget);
+
+ return;
+ }
+ case DNS_TYPE_SIG:
+ {
+ dns_test_trace("NameSigner = %s, TimeSigned = %d, Expiration %d \n",
+ wine_dbgstr_w(record->Data.SIG.pNameSigner), record->Data.SIG.dwTimeSigned, record->Data.SIG.dwExpiration);
+
+ ok (lstrlenW(record->Data.SIG.pNameSigner),
+ "NameTarget expected at %p\n", record->Data.SIG.pNameSigner);
+
+ return;
+ }
+ default:
+ {
+ ok(0, " Seems tests are broken or irrelevant, unexpected type record %s (%d)\n", helper_dns_type_to_str(record->wType), record->wType);
+ return;
+ }
+ }
+}
+
+static void test_DnsQuery_W(void)
+{
+ const int test_count = sizeof(dnsqueryex_tests) / sizeof(dnsqueryex_tests[0]);
+ int i;
+
+ if (!pDnsQuery_W)
+ {
+ win_skip("DnsQuery_W not available on the platform; skipping\n");
+ return;
+ }
+
+ for (i=0; i<test_count; i++)
+ {
+ int res, records_cnt, query_name_len, test_flags;
+ PDNS_RECORD record = NULL;
+ LPWSTR query_name_W;
+ IP4_ARRAY t_ip;
+ PIP4_ARRAY p_dns_server;
+
+ p_dns_server = NULL;
+ memset(&t_ip, 0, sizeof(t_ip));
+
+ test_flags = dnsqueryex_tests[i].flags;
+
+ /* IP address to binary representation if particular DNS server defined*/
+ if ( dnsqueryex_tests[i].dns_server_ip )
+ {
+ t_ip.AddrArray[0] = helper_ip2int(dnsqueryex_tests[i].dns_server_ip);
+ t_ip.AddrCount = 1;
+
+ p_dns_server = &t_ip;
+ }
+
+ query_name_len = MultiByteToWideChar(CP_ACP, 0, dnsqueryex_tests[i].query_name, -1, NULL, 0);
+ query_name_W = HeapAlloc(GetProcessHeap(), 0, query_name_len*sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, dnsqueryex_tests[i].query_name, -1, query_name_W, query_name_len);
+
+ res = pDnsQuery_W (query_name_W, dnsqueryex_tests[i].query_type, dnsqueryex_tests[i].query_options, p_dns_server, &record, NULL);
+
+ dns_test_trace("DnsQuery_W result = %d (test #%d - %s %s)\n", res, i,
+ wine_dbgstr_w(query_name_W), helper_dns_type_to_str(dnsqueryex_tests[i].query_type));
+
+ TODO_OR_OK(test_flags & RESULT_TO_DO_WINE,
+ res==dnsqueryex_tests[i].expected_status || (res != ERROR_SUCCESS && test_flags & RESULT_OK_ANY_NON_SUCCESS),
+ "Unexpected status in result for test %d (%s %s), waited %u, got %u \n",
+ i, wine_dbgstr_w(query_name_W), helper_dns_type_to_str(dnsqueryex_tests[i].query_type), dnsqueryex_tests[i].expected_status, res);
+
+ ok ( dnsqueryex_tests[i].flags & EXPECT_RECORD || !record,
+ "Waited for at least one record in test %d, no records received\n", i);
+
+ records_cnt = 0;
+
+ while(record) {
+ records_cnt++;
+ helper_check_record(record, &dnsqueryex_tests[i]);
+ record = record->pNext;
+ }
+
+ dns_test_trace("Total records in response: %d\n", records_cnt);
+
+ ok( !record || (dnsqueryex_tests[i].flags & EXPECT_SEVERAL_RECORDS) || (records_cnt>1),
+ "Flags (%d) Expected several records in result for %d test ('%s' for type %d), got %d \n", dnsqueryex_tests[i].flags & EXPECT_SEVERAL_RECORDS,
+ i, wine_dbgstr_w(query_name_W), dnsqueryex_tests[i].query_type, records_cnt);
+
+ HeapFree(GetProcessHeap(), 0, query_name_W);
+ }
+}
+
+static void test_DnsQueryEx(void)
+{
+ const int test_count = sizeof(dnsqueryex_tests) / sizeof(dnsqueryex_tests[0]);
+ int i;
+
+ if (!pDnsQueryEx)
+ {
+ win_skip("DnsQueryEx not available on the platform; skipping\n");
+ return;
+ }
+
+ for (i=0; i<test_count; i++)
+ {
+ int query_name_len;
+ DNS_STATUS status;
+ ULONG test_flags;
+ LPWSTR query_name_W;
+ DNS_QUERY_REQUEST request;
+ DNS_QUERY_RESULT result;
+ DNS_ADDR_ARRAY dns_addr_array;
+ SOCKADDR_IN t_sockaddr;
+
+ PDNS_RECORD record;
+ int records_cnt;
+
+ memset(&dns_addr_array, 0, sizeof(dns_addr_array));
+ memset(&request,0,sizeof(request));
+ memset(&result,0,sizeof(result));
+ memset(&t_sockaddr, 0, sizeof(t_sockaddr));
+
+ query_name_len = MultiByteToWideChar(CP_ACP, 0, dnsqueryex_tests[i].query_name, -1, NULL, 0);
+ query_name_W = HeapAlloc(GetProcessHeap(), 0, query_name_len*sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, dnsqueryex_tests[i].query_name, -1, query_name_W, query_name_len);
+
+ request.Version = DNS_QUERY_REQUEST_VERSION1;
+ request.QueryName = query_name_W;
+ request.QueryType = dnsqueryex_tests[i].query_type;
+ request.QueryOptions = dnsqueryex_tests[i].query_options;
+ request.pQueryCompletionCallback = NULL;
+
+ /** Not clearly defined in documentation of DnsQueryEx itself, but Version should be defined for a Result as well,
+ otherwise DnsQueryEx will always return ERROR_INVALID_PARAMETER (87) **/
+ result.Version = DNS_QUERY_RESULTS_VERSION1;
+
+ test_flags = dnsqueryex_tests[i].flags;
+
+ /* IP address to binary representation if particular DNS server defined*/
+ if ( dnsqueryex_tests[i].dns_server_ip ) {
+
+ t_sockaddr.sin_addr.s_addr = helper_ip2int(dnsqueryex_tests[i].dns_server_ip);
+ t_sockaddr.sin_family = AF_INET;
+
+ dns_addr_array.MaxCount = 1;
+ dns_addr_array.AddrCount = 1;
+ dns_addr_array.Family = AF_INET;
+
+ memcpy(&dns_addr_array.AddrArray[0].MaxSa, &t_sockaddr, sizeof(SOCKADDR_IN));
+
+ request.pDnsServerList = &dns_addr_array;
+ }
+
+ status = pDnsQueryEx(&request, &result, NULL);
+
+ dns_test_trace("DnsQueryEx status = %d (test #%d - %s:%s)\n", status, i,
+ wine_dbgstr_w(query_name_W), helper_dns_type_to_str(dnsqueryex_tests[i].query_type));
+
+ TODO_OR_OK(test_flags & RESULT_TO_DO_WINE,
+ status == dnsqueryex_tests[i].expected_status || (status != ERROR_SUCCESS && test_flags & RESULT_OK_ANY_NON_SUCCESS),
+ "Unexpected status in result for test %d ('%s' %s), waited %u, got %u \n",
+ i, wine_dbgstr_w(query_name_W), helper_dns_type_to_str(dnsqueryex_tests[i].query_type), dnsqueryex_tests[i].expected_status, status );
+
+ record = result.pQueryRecords;
+
+ ok( test_flags & EXPECT_RECORD || !record,
+ "Waited for at least one record in test %d, no records received\n", i);
+
+ records_cnt = 0;
+
+ while(record) {
+ records_cnt++;
+ helper_check_record(record, &dnsqueryex_tests[i]);
+ record = record->pNext;
+ }
+
+ dns_test_trace("Total records in response: %d\n", records_cnt);
+
+ ok( !record || (test_flags & EXPECT_SEVERAL_RECORDS) || (records_cnt>1),
+ "Flags (%d) Expected several records in result for %d test ('%s' for type %d), got %d \n", test_flags & EXPECT_SEVERAL_RECORDS,
+ i, wine_dbgstr_w(query_name_W), dnsqueryex_tests[i].query_type, records_cnt);
+
+ HeapFree(GetProcessHeap(), 0, query_name_W);
+ }
+}
+
+static void InitFunctionPtrs(void)
+{
+
+ hntdll = LoadLibraryA("ntdll.dll");
+ ok(hntdll != 0, "LoadLibrary failed\n");
+ if (hntdll) {
+ pRtlIpv6AddressToStringA = (void *)GetProcAddress(hntdll, "RtlIpv6AddressToStringA");
+ }
+
+ hdnsapi = LoadLibraryA("dnsapi.dll");
+ ok(hdnsapi != 0, "LoadLibrary failed\n");
+ if (hdnsapi) {
+ pDnsQueryEx = (void *)GetProcAddress(hdnsapi, "DnsQueryEx");
+ pDnsQuery_W = (void *)GetProcAddress(hdnsapi, "DnsQuery_W");
+ }
+}
+
+
+START_TEST(query)
+{
+ winetest_debug = 1;
+ winetest_interactive = 1;
+
+ InitFunctionPtrs();
+
+ test_DnsQuery_W();
+
+ test_DnsQueryEx();
+}
\ No newline at end of file
--
2.5.0
More information about the wine-patches
mailing list