[DNSAPI][DNSAPI_APITEST] Fix DnsQuery_UTF8 function and add tests 1857/head
authorKonstantin Motylkov <mkonst.reut@mail.ru>
Sun, 18 Aug 2019 22:56:27 +0000 (00:56 +0200)
committerMark Jansen <mark.jansen@reactos.org>
Mon, 19 Aug 2019 18:01:23 +0000 (20:01 +0200)
CORE-11634

dll/win32/dnsapi/dnsapi/query.c
modules/rostests/apitests/dnsapi/DnsQuery.c

index a57f0e6..7b40b09 100644 (file)
@@ -77,8 +77,7 @@ DnsCToW(const CHAR *NarrowString)
                                       0);
     if (WideLen == 0)
         return NULL;
-    WideLen *= sizeof(WCHAR);
-    WideString = RtlAllocateHeap(RtlGetProcessHeap(), 0, WideLen);
+    WideString = RtlAllocateHeap(RtlGetProcessHeap(), 0, WideLen * sizeof(WCHAR));
     if (WideString == NULL)
     {
         return NULL;
@@ -93,8 +92,67 @@ DnsCToW(const CHAR *NarrowString)
     return WideString;
 }
 
+static PCHAR
+DnsWToUTF8(const WCHAR *WideString)
+{
+    PCHAR AnsiString;
+    int AnsiLen = WideCharToMultiByte(CP_UTF8,
+                                      0,
+                                      WideString,
+                                      -1,
+                                      NULL,
+                                      0,
+                                      NULL,
+                                      0);
+    if (AnsiLen == 0)
+        return NULL;
+    AnsiString = RtlAllocateHeap(RtlGetProcessHeap(), 0, AnsiLen);
+    if (AnsiString == NULL)
+    {
+        return NULL;
+    }
+    WideCharToMultiByte(CP_UTF8,
+                        0,
+                        WideString,
+                        -1,
+                        AnsiString,
+                        AnsiLen,
+                        NULL,
+                        0);
+
+    return AnsiString;
+}
+
+static PWCHAR
+DnsUTF8ToW(const CHAR *NarrowString)
+{
+    PWCHAR WideString;
+    int WideLen = MultiByteToWideChar(CP_UTF8,
+                                      0,
+                                      NarrowString,
+                                      -1,
+                                      NULL,
+                                      0);
+    if (WideLen == 0)
+        return NULL;
+    WideString = RtlAllocateHeap(RtlGetProcessHeap(), 0, WideLen * sizeof(WCHAR));
+    if (WideString == NULL)
+    {
+        return NULL;
+    }
+    MultiByteToWideChar(CP_UTF8,
+                        0,
+                        NarrowString,
+                        -1,
+                        WideString,
+                        WideLen);
+
+    return WideString;
+}
+
 DNS_STATUS WINAPI
-DnsQuery_A(LPCSTR Name,
+DnsQuery_CodePage(UINT CodePage,
+           LPCSTR Name,
            WORD Type,
            DWORD Options,
            PIP4_ARRAY Servers,
@@ -112,7 +170,19 @@ DnsQuery_A(LPCSTR Name,
     if (QueryResultSet == NULL)
         return ERROR_INVALID_PARAMETER;
 
-    Buffer = DnsCToW(Name);
+    switch (CodePage)
+    {
+    case CP_ACP:
+        Buffer = DnsCToW(Name);
+        break;
+
+    case CP_UTF8:
+        Buffer = DnsUTF8ToW(Name);
+        break;
+
+    default:
+        return ERROR_INVALID_PARAMETER;
+    }
 
     Status = DnsQuery_W(Buffer, Type, Options, Servers, &QueryResultWide, Reserved);
 
@@ -122,9 +192,46 @@ DnsQuery_A(LPCSTR Name,
         {
         case DNS_TYPE_A:
         case DNS_TYPE_WKS:
+        case DNS_TYPE_CNAME:
+        case DNS_TYPE_PTR:
+        case DNS_TYPE_NS:
+        case DNS_TYPE_MB:
+        case DNS_TYPE_MD:
+        case DNS_TYPE_MF:
+        case DNS_TYPE_MG:
+        case DNS_TYPE_MR:
             ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_RECORD));
+            break;
+
+        case DNS_TYPE_MINFO:
+            ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_TXT_DATA) + QueryResultWide->Data.TXT.dwStringCount);
+            break;
+
+        case DNS_TYPE_NULL:
+            ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_NULL_DATA) + QueryResultWide->Data.Null.dwByteCount);
+            break;
+        }
+        if (ConvertedRecord == NULL)
+        {
+            /* The name */
+            RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+            /* The result*/
+            DnsIntFreeRecordList(QueryResultWide);
+            QueryResultSet = NULL;
+            return ERROR_OUTOFMEMORY;
+        }
+
+        if (CodePage == CP_ACP)
             ConvertedRecord->pName = DnsWToC((PWCHAR)QueryResultWide->pName);
-            ConvertedRecord->wType = QueryResultWide->wType;
+        else
+            ConvertedRecord->pName = DnsWToUTF8((PWCHAR)QueryResultWide->pName);
+
+        ConvertedRecord->wType = QueryResultWide->wType;
+
+        switch (QueryResultWide->wType)
+        {
+        case DNS_TYPE_A:
+        case DNS_TYPE_WKS:
             ConvertedRecord->wDataLength = QueryResultWide->wDataLength;
             memcpy(&ConvertedRecord->Data, &QueryResultWide->Data, QueryResultWide->wDataLength);
             break;
@@ -137,47 +244,50 @@ DnsQuery_A(LPCSTR Name,
         case DNS_TYPE_MF:
         case DNS_TYPE_MG:
         case DNS_TYPE_MR:
-            ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_RECORD));
-            ConvertedRecord->pName = DnsWToC((PWCHAR)QueryResultWide->pName);
-            ConvertedRecord->wType = QueryResultWide->wType;
             ConvertedRecord->wDataLength = sizeof(DNS_PTR_DATA);
-            ConvertedRecord->Data.PTR.pNameHost = DnsWToC((PWCHAR)QueryResultWide->Data.PTR.pNameHost);
+            if (CodePage == CP_ACP)
+                ConvertedRecord->Data.PTR.pNameHost = DnsWToC((PWCHAR)QueryResultWide->Data.PTR.pNameHost);
+            else
+                ConvertedRecord->Data.PTR.pNameHost = DnsWToUTF8((PWCHAR)QueryResultWide->Data.PTR.pNameHost);
             break;
 
         case DNS_TYPE_MINFO:
-            ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_RECORD));
-            ConvertedRecord->pName = DnsWToC((PWCHAR)QueryResultWide->pName);
-            ConvertedRecord->wType = QueryResultWide->wType;
             ConvertedRecord->wDataLength = sizeof(DNS_MINFO_DATA);
-            ConvertedRecord->Data.MINFO.pNameMailbox = DnsWToC((PWCHAR)QueryResultWide->Data.MINFO.pNameMailbox);
-            ConvertedRecord->Data.MINFO.pNameErrorsMailbox = DnsWToC((PWCHAR)QueryResultWide->Data.MINFO.pNameErrorsMailbox);
+            if (CodePage == CP_ACP)
+            {
+                ConvertedRecord->Data.MINFO.pNameMailbox = DnsWToC((PWCHAR)QueryResultWide->Data.MINFO.pNameMailbox);
+                ConvertedRecord->Data.MINFO.pNameErrorsMailbox = DnsWToC((PWCHAR)QueryResultWide->Data.MINFO.pNameErrorsMailbox);
+            }
+            else
+            {
+                ConvertedRecord->Data.MINFO.pNameMailbox = DnsWToUTF8((PWCHAR)QueryResultWide->Data.MINFO.pNameMailbox);
+                ConvertedRecord->Data.MINFO.pNameErrorsMailbox = DnsWToUTF8((PWCHAR)QueryResultWide->Data.MINFO.pNameErrorsMailbox);
+            }
             break;
 
         case DNS_TYPE_MX:
-            ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_RECORD));
-            ConvertedRecord->pName = DnsWToC((PWCHAR)QueryResultWide->pName);
-            ConvertedRecord->wType = QueryResultWide->wType;
             ConvertedRecord->wDataLength = sizeof(DNS_MX_DATA);
-            ConvertedRecord->Data.MX.pNameExchange = DnsWToC((PWCHAR)QueryResultWide->Data.MX.pNameExchange);
+            if (CodePage == CP_ACP)
+                ConvertedRecord->Data.MX.pNameExchange = DnsWToC((PWCHAR)QueryResultWide->Data.MX.pNameExchange);
+            else
+                ConvertedRecord->Data.MX.pNameExchange = DnsWToUTF8((PWCHAR)QueryResultWide->Data.MX.pNameExchange);
             ConvertedRecord->Data.MX.wPreference = QueryResultWide->Data.MX.wPreference;
             break;
 
         case DNS_TYPE_HINFO:
-            ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_TXT_DATA) + QueryResultWide->Data.TXT.dwStringCount);
-            ConvertedRecord->pName = DnsWToC((PWCHAR)QueryResultWide->pName);
-            ConvertedRecord->wType = QueryResultWide->wType;
             ConvertedRecord->wDataLength = sizeof(DNS_TXT_DATA) + (sizeof(PCHAR) * QueryResultWide->Data.TXT.dwStringCount);
             ConvertedRecord->Data.TXT.dwStringCount = QueryResultWide->Data.TXT.dwStringCount;
 
-            for (i = 0; i < ConvertedRecord->Data.TXT.dwStringCount; i++)
-                ConvertedRecord->Data.TXT.pStringArray[i] = DnsWToC((PWCHAR)QueryResultWide->Data.TXT.pStringArray[i]);
+            if (CodePage == CP_ACP)
+                for (i = 0; i < ConvertedRecord->Data.TXT.dwStringCount; i++)
+                    ConvertedRecord->Data.TXT.pStringArray[i] = DnsWToC((PWCHAR)QueryResultWide->Data.TXT.pStringArray[i]);
+            else
+                for (i = 0; i < ConvertedRecord->Data.TXT.dwStringCount; i++)
+                    ConvertedRecord->Data.TXT.pStringArray[i] = DnsWToUTF8((PWCHAR)QueryResultWide->Data.TXT.pStringArray[i]);
 
             break;
 
         case DNS_TYPE_NULL:
-            ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_NULL_DATA) + QueryResultWide->Data.Null.dwByteCount);
-            ConvertedRecord->pName = DnsWToC((PWCHAR)QueryResultWide->pName);
-            ConvertedRecord->wType = QueryResultWide->wType;
             ConvertedRecord->wDataLength = sizeof(DNS_NULL_DATA) + QueryResultWide->Data.Null.dwByteCount;
             ConvertedRecord->Data.Null.dwByteCount = QueryResultWide->Data.Null.dwByteCount;
             memcpy(&ConvertedRecord->Data.Null.Data, &QueryResultWide->Data.Null.Data, QueryResultWide->Data.Null.dwByteCount);
@@ -208,6 +318,28 @@ DnsQuery_A(LPCSTR Name,
     return Status;
 }
 
+DNS_STATUS WINAPI
+DnsQuery_A(LPCSTR Name,
+           WORD Type,
+           DWORD Options,
+           PIP4_ARRAY Servers,
+           PDNS_RECORD *QueryResultSet,
+           PVOID *Reserved)
+{
+    return DnsQuery_CodePage(CP_ACP, Name, Type, Options, Servers, QueryResultSet, Reserved);
+}
+
+DNS_STATUS WINAPI
+DnsQuery_UTF8(LPCSTR Name,
+              WORD Type,
+              DWORD Options,
+              PIP4_ARRAY Servers,
+              PDNS_RECORD *QueryResultSet,
+              PVOID *Reserved)
+{
+    return DnsQuery_CodePage(CP_UTF8, Name, Type, Options, Servers, QueryResultSet, Reserved);
+}
+
 WCHAR
 *xstrsave(const WCHAR *str)
 {
@@ -687,7 +819,7 @@ DnsQuery_W(LPCWSTR Name,
                   AnsiName[i] == '-' || AnsiName[i] == '_' || AnsiName[i] == '.'))
             {
                 RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiName);
-                return ERROR_INVALID_NAME;
+                return DNS_ERROR_INVALID_NAME_CHAR;
             }
             i++;
         }
@@ -898,18 +1030,6 @@ DnsQuery_W(LPCWSTR Name,
     }
 }
 
-DNS_STATUS WINAPI
-DnsQuery_UTF8(LPCSTR Name,
-              WORD Type,
-              DWORD Options,
-              PIP4_ARRAY Servers,
-              PDNS_RECORD *QueryResultSet,
-              PVOID *Reserved)
-{
-    UNIMPLEMENTED;
-    return ERROR_OUTOFMEMORY;
-}
-
 void
 DnsIntFreeRecordList(PDNS_RECORD ToDelete)
 {
index a659154..c487347 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * PROJECT:         ReactOS api tests
  * LICENSE:         GPLv2+ - See COPYING in the top level directory
- * PURPOSE:         Test for DnsQuery_A
+ * PURPOSE:         Test for DnsQuery_A, DnsQuery_UTF8
  * PROGRAMMER:      Victor Martinez Calvo <victor.martinez@reactos.org>
  */
 
@@ -19,6 +19,8 @@ void TestHostName(void)
     DNS_STATUS dns_status;
     char host_name[255];
     char test_name[255];
+    char host_nameUTF8[255];
+    char test_nameUTF8[255];
     PDNS_RECORD dp;
     WCHAR host_nameW[255];
     WCHAR test_nameW[255];
@@ -51,6 +53,7 @@ void TestHostName(void)
         }
         HeapFree(GetProcessHeap(), 0, network_info);
         mbstowcs(host_nameW, host_name, 255);
+        wcstombs(host_nameUTF8, host_nameW, 255);
     }
 
     //DnsQuery_A:
@@ -266,6 +269,246 @@ void TestHostName(void)
     ok(dp == InvalidPointer || broken(dp == NULL), "dp = %p\n", dp);
     if (dp != InvalidPointer && dns_status == NO_ERROR) DnsRecordListFree(dp, DnsFreeRecordList);
 
+    //DnsQuery_UTF8:
+    //NULL
+    dp = InvalidPointer;
+    dns_status = DnsQuery_UTF8(NULL, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    ok(dns_status == ERROR_INVALID_PARAMETER, "DnsQuery_UTF8 failed with error %lu\n", dns_status);
+    ok(dp == InvalidPointer, "dp = %p\n", dp);
+
+    //NULL dp
+    dns_status = DnsQuery_UTF8(host_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, NULL, 0);
+    ok(dns_status == ERROR_INVALID_PARAMETER, "DnsQuery_UTF8 failed with error %lu\n", dns_status);
+
+    //Testing HostName
+    dp = InvalidPointer;
+    dns_status = DnsQuery_UTF8(host_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    ok(dns_status == NO_ERROR, "DnsQuery_UTF8 failed with error %lu\n", dns_status);
+    if (dp != InvalidPointer)
+    {
+        ok(strcmp(dp->pName, host_name) == 0, "DnsQuery_UTF8 returned wrong answer '%s' expected '%s'\n", dp->pName, host_name);
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+    }
+    ok(dp != InvalidPointer && dp != NULL, "dp = %p\n", dp);
+    if (dp != InvalidPointer) DnsRecordListFree(dp, DnsFreeRecordList);
+
+    //127.0.0.1
+    dp = InvalidPointer;
+    wcscpy(test_nameW, L"127.0.0.1");
+    wcstombs(test_nameUTF8, test_nameW, 255);
+    dns_status = DnsQuery_UTF8(test_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    ok(dns_status == NO_ERROR, "DnsQuery_UTF8 failed with error %lu\n", dns_status);
+    if (dp != InvalidPointer)
+    {
+        ok(strcmp(dp->pName, "127.0.0.1") == 0, "DnsQuery_UTF8 returned wrong answer '%s' expected '%s'\n", dp->pName, "127.0.0.1");
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+        ok(dp->Data.A.IpAddress == ntohl(INADDR_LOOPBACK), "DnsQuery_UTF8 returned wrong data %ld expected %ld\n", dp->Data.A.IpAddress, ntohl(INADDR_LOOPBACK));
+    }
+    ok(dp != InvalidPointer && dp != NULL, "dp = %p\n", dp);
+    if (dp != InvalidPointer) DnsRecordListFree(dp, DnsFreeRecordList);
+
+    //Localhost strings
+    dp = InvalidPointer;
+    wcscpy(test_nameW, L"LocalHost");
+    wcstombs(test_nameUTF8, test_nameW, 255);
+    dns_status = DnsQuery_UTF8(test_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    ok(dns_status == NO_ERROR, "DnsQuery_UTF8 failed with error %lu\n", dns_status);
+    if (dp != InvalidPointer)
+    {
+        /* On Windows 7 is unchanged on XP is lowercased */
+        ok(strcmp(dp->pName, "localhost") == 0 || broken(strcmp(dp->pName, "LocalHost") == 0), "DnsQuery_UTF8 returned wrong answer '%s' expected '%s'\n", dp->pName, "localhost");
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+        ok(dp->Data.A.IpAddress == ntohl(INADDR_LOOPBACK), "DnsQuery_UTF8 returned wrong data %ld expected %ld\n", dp->Data.A.IpAddress, ntohl(INADDR_LOOPBACK));
+    }
+    ok(dp != InvalidPointer && dp != NULL, "dp = %p\n", dp);
+    if (dp != InvalidPointer) DnsRecordListFree(dp, DnsFreeRecordList);
+
+    dp = InvalidPointer;
+    wcscpy(test_nameW, L"Localhost");
+    wcstombs(test_nameUTF8, test_nameW, 255);
+    dns_status = DnsQuery_UTF8(test_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    ok(dns_status == NO_ERROR, "DnsQuery_UTF8 failed with error %lu\n", dns_status);
+    if (dp != InvalidPointer)
+    {
+        /* On Windows 7 is unchanged on XP is lowercased */
+        ok(strcmp(dp->pName, "localhost") == 0 || broken(strcmp(dp->pName, "Localhost") == 0), "DnsQuery_UTF8 returned wrong answer '%s' expected '%s'\n", dp->pName, "localhost");
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+        ok(dp->Data.A.IpAddress == ntohl(INADDR_LOOPBACK), "DnsQuery_UTF8 returned wrong data %ld expected %ld\n", dp->Data.A.IpAddress, ntohl(INADDR_LOOPBACK));
+    }
+    ok(dp != InvalidPointer && dp != NULL, "dp = %p\n", dp);
+    if (dp != InvalidPointer) DnsRecordListFree(dp, DnsFreeRecordList);
+
+    dp = InvalidPointer;
+    wcscpy(test_nameW, L"localhost");
+    wcstombs(test_nameUTF8, test_nameW, 255);
+    dns_status = DnsQuery_UTF8(test_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    ok(dns_status == NO_ERROR, "DnsQuery_UTF8 failed with error %lu\n", dns_status);
+    if (dp != InvalidPointer)
+    {
+        ok(strcmp(dp->pName, "localhost") == 0, "DnsQuery_UTF8 returned wrong answer '%s' expected '%s'\n", dp->pName, "localhost");
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+        ok(dp->Data.A.IpAddress == ntohl(INADDR_LOOPBACK), "DnsQuery_UTF8 returned wrong data %ld expected %ld\n", dp->Data.A.IpAddress, ntohl(INADDR_LOOPBACK));
+    }
+    ok(dp != InvalidPointer && dp != NULL, "dp = %p\n", dp);
+    if (dp != InvalidPointer) DnsRecordListFree(dp, DnsFreeRecordList);
+
+    dp = InvalidPointer;
+    wcscpy(test_nameW, L"");
+    wcstombs(test_nameUTF8, test_nameW, 255);
+    dns_status = DnsQuery_UTF8(test_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    ok(dns_status == NO_ERROR, "DnsQuery_UTF8 failed with error %lu\n", dns_status);
+    if (dp != InvalidPointer)
+    {
+        /* On Windows 7 is the host on XP is dot ??? */
+        ok(strcmp(dp->pName, ".") == 0 || broken(strcmp(dp->pName, host_name) == 0), "DnsQuery_UTF8 returned wrong answer '%s' expected '%s' or '.'\n", dp->pName, host_name);
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+    }
+    ok(dp != InvalidPointer && dp != NULL, "dp = %p\n", dp);
+    if (dp != InvalidPointer) DnsRecordListFree(dp, DnsFreeRecordList);
+
+    dp = InvalidPointer;
+    wcscpy(test_nameW, L" ");
+    wcstombs(test_nameUTF8, test_nameW, 255);
+    dns_status = DnsQuery_UTF8(test_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    /* On Windows 7 is DNS_ERROR_INVALID_NAME_CHAR on XP is ERROR_TIMEOUT on Win 2k3 is ERROR_INVALID_NAME*/
+    ok(dns_status == ERROR_INVALID_NAME || broken(dns_status == ERROR_TIMEOUT) || broken(dns_status == DNS_ERROR_INVALID_NAME_CHAR), "DnsQuery_UTF8 failed with error %lu expected %u or %u or %u\n", dns_status, ERROR_INVALID_NAME, ERROR_TIMEOUT, DNS_ERROR_INVALID_NAME_CHAR);
+    if (dp != InvalidPointer && dns_status == NO_ERROR)
+    {
+        ok(strcmp(dp->pName, host_name) == 0, "DnsQuery_UTF8 returned wrong answer '%s' expected '%s'\n", dp->pName, host_name);
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+    }
+    ok(dp == InvalidPointer || broken(dp == NULL), "dp = %p\n", dp);
+    if (dp != InvalidPointer && dns_status == NO_ERROR) DnsRecordListFree(dp, DnsFreeRecordList);
+
+    dp = InvalidPointer;
+    wcscpy(test_nameW, L"0.0.0.0");
+    wcstombs(test_nameUTF8, test_nameW, 255);
+    dns_status = DnsQuery_UTF8(test_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    ok(dns_status == NO_ERROR, "DnsQuery_UTF8 failed with error %lu\n", dns_status);
+    if (dp != InvalidPointer)
+    {
+        ok(strcmp(dp->pName, "0.0.0.0") == 0, "DnsQuery_UTF8 returned wrong answer '%s' expected '%s'\n", dp->pName, "0.0.0.0");
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+        ok(dp->Data.A.IpAddress == ntohl(INADDR_ANY), "DnsQuery_UTF8 returned wrong data %ld expected %ld\n", dp->Data.A.IpAddress, ntohl(INADDR_ANY));
+    }
+    ok(dp != InvalidPointer && dp != NULL, "dp = %p\n", dp);
+    if (dp != InvalidPointer) DnsRecordListFree(dp, DnsFreeRecordList);
+
+    dp = InvalidPointer;
+    wcscpy(test_nameW, L"0.0.0.0 ");
+    wcstombs(test_nameUTF8, test_nameW, 255);
+    dns_status = DnsQuery_UTF8(test_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    /* On windows 7 fails with DNS_ERROR_INVALID_NAME_CHAR on XP no error */
+    ok(dns_status == NO_ERROR || broken(dns_status == DNS_ERROR_INVALID_NAME_CHAR), "DnsQuery_UTF8 wrong status %lu expected %u or %u\n", dns_status, NO_ERROR, DNS_ERROR_INVALID_NAME_CHAR);
+    if (dp != InvalidPointer && dns_status == NO_ERROR)
+    {
+        ok(strcmp(dp->pName, "0.0.0.0") == 0 || broken(strcmp(dp->pName, "0.0.0.0 ") == 0), "DnsQuery_UTF8 returned wrong answer '%s' expected '%s' or '%s'\n", dp->pName, "0.0.0.0", "0.0.0.0 ");
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+        ok(dp->Data.A.IpAddress == ntohl(INADDR_ANY), "DnsQuery_UTF8 returned wrong data %ld expected %ld\n", dp->Data.A.IpAddress, ntohl(INADDR_ANY));
+    }
+    ok(dp != InvalidPointer || broken(dp == InvalidPointer) || broken(dp == NULL), "dp = %p\n", dp);
+    if (dp != InvalidPointer && dns_status == NO_ERROR) DnsRecordListFree(dp, DnsFreeRecordList);
+
+    dp = InvalidPointer;
+    wcscpy(test_nameW, L"127.0.0.1 ");
+    wcstombs(test_nameUTF8, test_nameW, 255);
+    dns_status = DnsQuery_UTF8(test_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    /* On windows 7 fails with DNS_ERROR_INVALID_NAME_CHAR on XP no error */
+    ok(dns_status == NO_ERROR || broken(dns_status == DNS_ERROR_INVALID_NAME_CHAR), "DnsQuery_UTF8 wrong status %lu expected %u or %u\n", dns_status, NO_ERROR, DNS_ERROR_INVALID_NAME_CHAR);
+    if (dp != InvalidPointer && dns_status == NO_ERROR)
+    {
+        ok(strcmp(dp->pName, "127.0.0.1") == 0 || strcmp(dp->pName, "127.0.0.1 ") == 0, "DnsQuery_UTF8 returned wrong answer '%s' expected '%s' or '%s'\n", dp->pName, "127.0.0.1", "127.0.0.1 ");
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+        ok(dp->Data.A.IpAddress == ntohl(INADDR_LOOPBACK), "DnsQuery_UTF8 returned wrong data %ld expected %ld\n", dp->Data.A.IpAddress, ntohl(INADDR_LOOPBACK));
+    }
+    ok(dp != InvalidPointer || broken(dp == InvalidPointer) || broken(dp == NULL), "dp = %p\n", dp);
+    if (dp != InvalidPointer && dns_status == NO_ERROR) DnsRecordListFree(dp, DnsFreeRecordList);
+
+    dp = InvalidPointer;
+    wcscpy(test_nameW, L" 127.0.0.1 ");
+    wcstombs(test_nameUTF8, test_nameW, 255);
+    dns_status = DnsQuery_UTF8(test_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    ok(dns_status == DNS_ERROR_RCODE_NAME_ERROR || broken(dns_status == DNS_ERROR_INVALID_NAME_CHAR), "DnsQuery_UTF8 wrong status %lu expected %u or %u\n", dns_status, DNS_ERROR_RCODE_NAME_ERROR, DNS_ERROR_INVALID_NAME_CHAR);
+    if (dp != InvalidPointer && dns_status == NO_ERROR)
+    {
+        ok(strcmp(dp->pName, "127.0.0.1") == 0, "DnsQuery_UTF8 returned wrong answer '%s' expected '%s'\n", dp->pName, "127.0.0.1");
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+        ok(dp->Data.A.IpAddress == ntohl(INADDR_LOOPBACK), "DnsQuery_UTF8 returned wrong data %ld expected %ld\n", dp->Data.A.IpAddress, ntohl(INADDR_LOOPBACK));
+    }
+    ok(dp == InvalidPointer || broken(dp == NULL), "dp = %p\n", dp);
+    if (dp != InvalidPointer && dns_status == NO_ERROR) DnsRecordListFree(dp, DnsFreeRecordList);
+
+    dp = InvalidPointer;
+    wcscpy(test_nameW, L" 127.0. 0.1 ");
+    wcstombs(test_nameUTF8, test_nameW, 255);
+    dns_status = DnsQuery_UTF8(test_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    ok(dns_status == DNS_ERROR_RCODE_NAME_ERROR || broken(dns_status == DNS_ERROR_INVALID_NAME_CHAR), "DnsQuery_UTF8 wrong status %lu expected %u or %u\n", dns_status, DNS_ERROR_RCODE_NAME_ERROR, DNS_ERROR_INVALID_NAME_CHAR);
+    if (dp == InvalidPointer && dns_status == NO_ERROR)
+    {
+        ok(strcmp(dp->pName, "127.0.0.1") == 0, "DnsQuery_UTF8 returned wrong answer '%s' expected '%s'\n", dp->pName, "127.0.0.1");
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+        ok(dp->Data.A.IpAddress == ntohl(INADDR_LOOPBACK), "DnsQuery_UTF8 returned wrong data %ld expected %ld\n", dp->Data.A.IpAddress, ntohl(INADDR_LOOPBACK));
+    }
+    ok(dp == InvalidPointer || broken(dp == NULL), "dp = %p\n", dp);
+    if (dp != InvalidPointer && dns_status == NO_ERROR) DnsRecordListFree(dp, DnsFreeRecordList);
+
+    dp = InvalidPointer;
+    wcscpy(test_nameW, L"localhost ");
+    wcstombs(test_nameUTF8, test_nameW, 255);
+    dns_status = DnsQuery_UTF8(test_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    ok(dns_status == ERROR_INVALID_NAME || broken(dns_status == ERROR_TIMEOUT) || broken(dns_status == DNS_ERROR_INVALID_NAME_CHAR), "DnsQuery_UTF8 wrong status %lu expected %u or %u or %u\n", dns_status, ERROR_INVALID_NAME, ERROR_TIMEOUT, DNS_ERROR_INVALID_NAME_CHAR);
+    if (dp != InvalidPointer && dns_status == NO_ERROR)
+    {
+        ok(strcmp(dp->pName, "localhost") == 0, "DnsQuery_UTF8 returned wrong answer '%s' expected '%s'\n", dp->pName, "localhost");
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+        ok(dp->Data.A.IpAddress == ntohl(INADDR_LOOPBACK), "DnsQuery_UTF8 returned wrong data %ld expected %ld\n", dp->Data.A.IpAddress, ntohl(INADDR_LOOPBACK));
+    }
+    ok(dp == InvalidPointer || broken(dp == NULL), "dp = %p\n", dp);
+    if (dp != InvalidPointer && dns_status == NO_ERROR) DnsRecordListFree(dp, DnsFreeRecordList);
+
+    dp = InvalidPointer;
+    wcscpy(test_nameW, L" localhost");
+    wcstombs(test_nameUTF8, test_nameW, 255);
+    dns_status = DnsQuery_UTF8(test_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    ok(dns_status == ERROR_INVALID_NAME || broken(dns_status == ERROR_TIMEOUT) || broken(dns_status == DNS_ERROR_INVALID_NAME_CHAR), "DnsQuery_UTF8 wrong status %lu expected %u or %u or %u\n", dns_status, ERROR_INVALID_NAME, ERROR_TIMEOUT, DNS_ERROR_INVALID_NAME_CHAR);
+    if (dp != InvalidPointer && dns_status == NO_ERROR)
+    {
+        ok(strcmp(dp->pName, "localhost") == 0, "DnsQuery_UTF8 returned wrong answer '%s' expected '%s'\n", dp->pName, "localhost");
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+        ok(dp->Data.A.IpAddress == ntohl(INADDR_LOOPBACK), "DnsQuery_UTF8 returned wrong data %ld expected %ld\n", dp->Data.A.IpAddress, ntohl(INADDR_LOOPBACK));
+    }
+    ok(dp == InvalidPointer || broken(dp == NULL), "dp = %p\n", dp);
+    if (dp != InvalidPointer && dns_status == NO_ERROR) DnsRecordListFree(dp, DnsFreeRecordList);
+
+    dp = InvalidPointer;
+    wcscpy(test_nameW, L" local host ");
+    wcstombs(test_nameUTF8, test_nameW, 255);
+    dns_status = DnsQuery_UTF8(test_nameUTF8, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
+    ok(dns_status == ERROR_INVALID_NAME || broken(dns_status == ERROR_TIMEOUT) || broken(dns_status == DNS_ERROR_INVALID_NAME_CHAR), "DnsQuery_UTF8 wrong status %lu expected %u or %u or %u\n", dns_status, ERROR_INVALID_NAME, ERROR_TIMEOUT, DNS_ERROR_INVALID_NAME_CHAR);
+    if (dp != InvalidPointer && dns_status == NO_ERROR)
+    {
+        ok(strcmp(dp->pName, "localhost") == 0, "DnsQuery_UTF8 returned wrong answer '%s' expected '%s'\n", dp->pName, "localhost");
+        ok(dp->wType == DNS_TYPE_A, "DnsQuery_UTF8 returned wrong type %d expected %d\n", dp->wType, DNS_TYPE_A);
+        ok(dp->wDataLength == sizeof(IP4_ADDRESS), "DnsQuery_UTF8 returned wrong data size %d\n", dp->wDataLength);
+        ok(dp->Data.A.IpAddress == ntohl(INADDR_LOOPBACK), "DnsQuery_UTF8 returned wrong data %ld expected %ld\n", dp->Data.A.IpAddress, ntohl(INADDR_LOOPBACK));
+    }
+    ok(dp == InvalidPointer || broken(dp == NULL), "dp = %p\n", dp);
+    if (dp != InvalidPointer && dns_status == NO_ERROR) DnsRecordListFree(dp, DnsFreeRecordList);
+
     //DnsQuery_W:
     //NULL
     dp = InvalidPointer;
@@ -288,7 +531,7 @@ void TestHostName(void)
     dns_status = DnsQuery_W(host_nameW, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, NULL, 0);
     ok(dns_status == ERROR_INVALID_PARAMETER, "DnsQuery_W failed with error %lu\n", dns_status);
 
-    //Testing HostName 
+    //Testing HostName
     dns_status = DnsQuery_W(host_nameW, DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
     ok(dns_status == NO_ERROR, "DnsQuery_W failed with error %lu\n", dns_status);
     if (dp != InvalidPointer)
@@ -299,7 +542,7 @@ void TestHostName(void)
     }
     ok(dp != InvalidPointer && dp != NULL, "dp = %p\n", dp);
     if (dp != InvalidPointer) DnsRecordListFree(dp, DnsFreeRecordList);
-    
+
     //127.0.0.1
     dns_status = DnsQuery_W(L"127.0.0.1", DNS_TYPE_A, DNS_QUERY_STANDARD, 0, &dp, 0);
     ok(dns_status == NO_ERROR, "DnsQuery_W failed with error %lu\n", dns_status);