Author: akhaldi
Date: Fri Sep 30 15:19:29 2016
New Revision: 72867

URL: http://svn.reactos.org/svn/reactos?rev=72867&view=rev
Log:
[ADNS][DNSAPI][MSWSOCK] Several fixes and improvements to DnsQuery and co, 
detailed in CORE-11394. This also fixes CORE-7441, many tests in 
dnsapi:DnsQuery, ws2_32:getaddrinfo and more. Brought to you by Peter Hater.

Modified:
    trunk/reactos/dll/win32/dnsapi/CMakeLists.txt
    trunk/reactos/dll/win32/dnsapi/dnsapi/query.c
    trunk/reactos/dll/win32/mswsock/CMakeLists.txt
    trunk/reactos/dll/win32/mswsock/mswhelper.c
    trunk/reactos/dll/win32/mswsock/nsplookup.c
    trunk/reactos/sdk/lib/3rdparty/adns/src/adns.h
    trunk/reactos/sdk/lib/3rdparty/adns/src/setup.c

Modified: trunk/reactos/dll/win32/dnsapi/CMakeLists.txt
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/dnsapi/CMakeLists.txt?rev=72867&r1=72866&r2=72867&view=diff
==============================================================================
--- trunk/reactos/dll/win32/dnsapi/CMakeLists.txt       [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/dnsapi/CMakeLists.txt       [iso-8859-1] Fri Sep 30 
15:19:29 2016
@@ -24,6 +24,6 @@
 
 set_module_type(dnsapi win32dll)
 target_link_libraries(dnsapi adns)
-add_importlibs(dnsapi user32 ws2_32 iphlpapi msvcrt kernel32 ntdll)
+add_importlibs(dnsapi advapi32 user32 ws2_32 iphlpapi msvcrt kernel32 ntdll)
 add_pch(dnsapi dnsapi/precomp.h SOURCE)
 add_cd_file(TARGET dnsapi DESTINATION reactos/system32 FOR all)

Modified: trunk/reactos/dll/win32/dnsapi/dnsapi/query.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/dnsapi/dnsapi/query.c?rev=72867&r1=72866&r2=72867&view=diff
==============================================================================
--- trunk/reactos/dll/win32/dnsapi/dnsapi/query.c       [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/dnsapi/dnsapi/query.c       [iso-8859-1] Fri Sep 30 
15:19:29 2016
@@ -9,6 +9,9 @@
  */
 
 #include "precomp.h"
+#include <winreg.h>
+#include <iphlpapi.h>
+#include <strsafe.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -31,17 +34,63 @@
  * Reserved             -- Response as it appears on the wire.  Optional.
  */
 
-char
-*xstrsave(const char *str)
-{
-    char *p;
-
-    p = RtlAllocateHeap(RtlGetProcessHeap(), 0, strlen(str) + 1);
-
-    if(p)
-        strcpy(p, str);
-
-    return p;
+static PCHAR
+DnsWToC(const WCHAR *WideString)
+{
+    PCHAR AnsiString;
+    int AnsiLen = WideCharToMultiByte(CP_ACP,
+                                      0,
+                                      WideString,
+                                      -1,
+                                      NULL,
+                                      0,
+                                      NULL,
+                                      0);
+    if (AnsiLen == 0)
+        return NULL;
+    AnsiString = RtlAllocateHeap(RtlGetProcessHeap(), 0, AnsiLen);
+    if (AnsiString == NULL)
+    {
+        return NULL;
+    }
+    WideCharToMultiByte(CP_ACP,
+                        0,
+                        WideString,
+                        -1,
+                        AnsiString,
+                        AnsiLen,
+                        NULL,
+                        0);
+
+    return AnsiString;
+}
+
+static PWCHAR
+DnsCToW(const CHAR *NarrowString)
+{
+    PWCHAR WideString;
+    int WideLen = MultiByteToWideChar(CP_ACP,
+                                      0,
+                                      NarrowString,
+                                      -1,
+                                      NULL,
+                                      0);
+    if (WideLen == 0)
+        return NULL;
+    WideLen *= sizeof(WCHAR);
+    WideString = RtlAllocateHeap(RtlGetProcessHeap(), 0, WideLen);
+    if (WideString == NULL)
+    {
+        return NULL;
+    }
+    MultiByteToWideChar(CP_ACP,
+                        0,
+                        NarrowString,
+                        -1,
+                        WideString,
+                        WideLen);
+
+    return WideString;
 }
 
 DNS_STATUS WINAPI
@@ -52,141 +101,491 @@
            PDNS_RECORD *QueryResultSet,
            PVOID *Reserved)
 {
-    adns_state astate;
-    int quflags = adns_qf_search;
-    int adns_error;
-    adns_answer *answer;
-    LPSTR CurrentName;
-    unsigned i, CNameLoop;
+    UINT i;
+    PWCHAR Buffer;
+    DNS_STATUS Status;
+    PDNS_RECORD QueryResultWide;
+    PDNS_RECORD ConvertedRecord = 0, LastRecord = 0;
 
     if (Name == NULL)
         return ERROR_INVALID_PARAMETER;
-
-    *QueryResultSet = 0;
-
-    switch(Type)
-    {
+    if (QueryResultSet == NULL)
+        return ERROR_INVALID_PARAMETER;
+
+    Buffer = DnsCToW(Name);
+
+    Status = DnsQuery_W(Buffer, Type, Options, Servers, &QueryResultWide, 
Reserved);
+
+    while (Status == ERROR_SUCCESS && QueryResultWide)
+    {
+        switch (QueryResultWide->wType)
+        {
         case DNS_TYPE_A:
-            adns_error = adns_init(&astate, adns_if_noenv | adns_if_noerrprint 
| adns_if_noserverwarn, 0);
-
-            if(adns_error != adns_s_ok)
-                return DnsIntTranslateAdnsToDNS_STATUS(adns_error);
-
-            if (Servers)
-            {
-                for(i = 0; i < Servers->AddrCount; i++)
-                {
-                    adns_addserver(astate, *((struct in_addr 
*)&Servers->AddrArray[i]));
-                }
-            }
-
-            /*
-             * adns doesn't resolve chained CNAME records (a CNAME which 
points to
-             * another CNAME pointing to another... pointing to an A record), 
according
-             * to a mailing list thread the authors believe that chained CNAME 
records
-             * are invalid and the DNS entries should be fixed. That's a nice 
academic
-             * standpoint, but there certainly are chained CNAME records out 
there,
-             * even some fairly major ones (at the time of this writing
-             * download.mozilla.org is a chained CNAME). Everyone else seems 
to resolve
-             * these fine, so we should too. So we loop here to try to resolve 
CNAME
-             * chains ourselves. Of course, there must be a limit to protect 
against
-             * CNAME loops.
-             */
-
-#define CNAME_LOOP_MAX 16
-
-            CurrentName = (LPSTR) Name;
-
-            for (CNameLoop = 0; CNameLoop < CNAME_LOOP_MAX; CNameLoop++)
-            {
-                adns_error = adns_synchronous(astate, CurrentName, 
adns_r_addr, quflags, &answer);
-
-                if(adns_error != adns_s_ok)
-                {
-                    adns_finish(astate);
-
-                    if (CurrentName != Name)
-                        RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName);
-
-                    return DnsIntTranslateAdnsToDNS_STATUS(adns_error);
-                }
-
-                if(answer && answer->rrs.addr)
-                {
-                    if (CurrentName != Name)
-                        RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName);
-
-                    *QueryResultSet = 
(PDNS_RECORD)RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_RECORD));
-
-                    if (NULL == *QueryResultSet)
-                    {
-                        adns_finish( astate );
-                        return ERROR_OUTOFMEMORY;
-                    }
-
-                    (*QueryResultSet)->pNext = NULL;
-                    (*QueryResultSet)->wType = Type;
-                    (*QueryResultSet)->wDataLength = sizeof(DNS_A_DATA);
-                    (*QueryResultSet)->Data.A.IpAddress = 
answer->rrs.addr->addr.inet.sin_addr.s_addr;
-
-                    adns_finish(astate);
-
-                    (*QueryResultSet)->pName = xstrsave( Name );
-
-                    return NULL != (*QueryResultSet)->pName ? ERROR_SUCCESS : 
ERROR_OUTOFMEMORY;
-                }
-
-                if (NULL == answer || adns_s_prohibitedcname != answer->status 
|| NULL == answer->cname)
-                {
-                    adns_finish(astate);
-
-                    if (CurrentName != Name)
-                        RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName);
-
-                    return ERROR_FILE_NOT_FOUND;
-                }
-
-                if (CurrentName != Name)
-                    RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName);
-
-                CurrentName = xstrsave(answer->cname);
-
-                if (!CurrentName)
-                {
-                    adns_finish(astate);
-                    return ERROR_OUTOFMEMORY;
-                }
-            }
-
-            adns_finish(astate);
-            RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName);
-            return ERROR_FILE_NOT_FOUND;
-
-        default:
-            return ERROR_OUTOFMEMORY; /* XXX arty: find a better error code. */
-    }
-}
-
-static PCHAR
-DnsWToC(const WCHAR *WideString)
-{
-    int chars = wcstombs(NULL, WideString, 0);
-    PCHAR out = RtlAllocateHeap(RtlGetProcessHeap(), 0, chars + 1);
-
-    wcstombs(out, WideString, chars + 1);
-
-    return out;
-}
-
-static PWCHAR
-DnsCToW(const CHAR *NarrowString)
-{
-    int chars = mbstowcs(NULL, NarrowString, 0);
-    PWCHAR out = RtlAllocateHeap(RtlGetProcessHeap(), 0, (chars + 1) * 
sizeof(WCHAR));
-
-    mbstowcs(out, NarrowString, chars + 1);
-
-    return out;
+        case DNS_TYPE_WKS:
+            ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, 
sizeof(DNS_RECORD));
+            ConvertedRecord->pName = DnsWToC((PWCHAR)QueryResultWide->pName);
+            ConvertedRecord->wType = QueryResultWide->wType;
+            ConvertedRecord->wDataLength = QueryResultWide->wDataLength;
+            memcpy(&ConvertedRecord->Data, &QueryResultWide->Data, 
QueryResultWide->wDataLength);
+            break;
+
+        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));
+            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);
+            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);
+            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);
+            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]);
+
+            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);
+            break;
+        }
+
+        if (LastRecord)
+        {
+            LastRecord->pNext = ConvertedRecord;
+            LastRecord = LastRecord->pNext;
+        }
+        else
+        {
+            LastRecord = *QueryResultSet = ConvertedRecord;
+        }
+
+        QueryResultWide = QueryResultWide->pNext;
+    }
+
+    if (LastRecord)
+        LastRecord->pNext = 0;
+
+    /* The name */
+    RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+    /* The result*/
+    if (QueryResultWide) DnsIntFreeRecordList(QueryResultWide);
+
+    return Status;
+}
+
+WCHAR
+*xstrsave(const WCHAR *str)
+{
+    WCHAR *p;
+    size_t len = 0;
+
+    /* FIXME: how much instead of MAX_PATH? */
+    StringCbLengthW(str, MAX_PATH, &len);
+    len+=sizeof(WCHAR);
+
+    p = RtlAllocateHeap(RtlGetProcessHeap(), 0, len);
+
+    if (p)
+        StringCbCopyW(p, len, str);
+
+    return p;
+}
+
+CHAR
+*xstrsaveA(const CHAR *str)
+{
+    CHAR *p;
+    size_t len = 0;
+
+    /* FIXME: how much instead of MAX_PATH? */
+    StringCbLengthA(str, MAX_PATH, &len);
+    len++;
+
+    p = RtlAllocateHeap(RtlGetProcessHeap(), 0, len);
+
+    if (p)
+        StringCbCopyA(p, len, str);
+
+    return p;
+}
+
+HANDLE
+OpenNetworkDatabase(LPCWSTR Name)
+{
+    PWSTR ExpandedPath;
+    PWSTR DatabasePath;
+    INT ErrorCode;
+    HKEY DatabaseKey;
+    DWORD RegType;
+    DWORD RegSize = 0;
+    size_t StringLength;
+    HANDLE ret;
+
+    ExpandedPath = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
+    if (!ExpandedPath)
+        return INVALID_HANDLE_VALUE;
+
+    /* Open the database path key */
+    ErrorCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                              
L"System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+                              0,
+                              KEY_READ,
+                              &DatabaseKey);
+    if (ErrorCode == NO_ERROR)
+    {
+        /* Read the actual path */
+        ErrorCode = RegQueryValueExW(DatabaseKey,
+                                     L"DatabasePath",
+                                     NULL,
+                                     &RegType,
+                                     NULL,
+                                     &RegSize);
+
+        DatabasePath = HeapAlloc(GetProcessHeap(), 0, RegSize);
+        if (!DatabasePath)
+        {
+            HeapFree(GetProcessHeap(), 0, ExpandedPath);
+            return INVALID_HANDLE_VALUE;
+        }
+
+        /* Read the actual path */
+        ErrorCode = RegQueryValueExW(DatabaseKey,
+                                     L"DatabasePath",
+                                     NULL,
+                                     &RegType,
+                                     (LPBYTE)DatabasePath,
+                                     &RegSize);
+
+        /* Close the key */
+        RegCloseKey(DatabaseKey);
+
+        /* Expand the name */
+        ExpandEnvironmentStringsW(DatabasePath, ExpandedPath, MAX_PATH);
+
+        HeapFree(GetProcessHeap(), 0, DatabasePath);
+    }
+    else
+    {
+        /* Use defalt path */
+        GetSystemDirectoryW(ExpandedPath, MAX_PATH);
+        StringCchLength(ExpandedPath, MAX_PATH, &StringLength);
+        if (ExpandedPath[StringLength - 1] != L'\\')
+        {
+            /* It isn't, so add it ourselves */
+            StringCchCat(ExpandedPath, MAX_PATH, L"\\");
+        }
+        StringCchCat(ExpandedPath, MAX_PATH, L"DRIVERS\\ETC\\");
+    }
+
+    /* Make sure that the path is backslash-terminated */
+    StringCchLength(ExpandedPath, MAX_PATH, &StringLength);
+    if (ExpandedPath[StringLength - 1] != L'\\')
+    {
+        /* It isn't, so add it ourselves */
+        StringCchCat(ExpandedPath, MAX_PATH, L"\\");
+    }
+
+    /* Add the database name */
+    StringCchCat(ExpandedPath, MAX_PATH, Name);
+
+    /* Return a handle to the file */
+    ret = CreateFileW(ExpandedPath,
+                      FILE_READ_DATA,
+                      FILE_SHARE_READ,
+                      NULL,
+                      OPEN_EXISTING,
+                      FILE_ATTRIBUTE_NORMAL,
+                      NULL);
+
+    HeapFree(GetProcessHeap(), 0, ExpandedPath);
+    return ret;
+}
+
+/* This function is far from perfect but it works enough */
+IP4_ADDRESS
+CheckForCurrentHostname(CONST CHAR * Name, PFIXED_INFO network_info)
+{
+    PCHAR TempName;
+    DWORD AdapterAddressesSize, Status;
+    IP4_ADDRESS ret = 0, Address;
+    PIP_ADAPTER_ADDRESSES Addresses = NULL, pip;
+    BOOL Found = FALSE;
+
+    if (network_info->DomainName)
+    {
+        size_t StringLength;
+        size_t TempSize = 2;
+        StringCchLengthA(network_info->HostName, 
sizeof(network_info->HostName), &StringLength);
+        TempSize += StringLength;
+        StringCchLengthA(network_info->DomainName, 
sizeof(network_info->DomainName), &StringLength);
+        TempSize += StringLength;
+        TempName = RtlAllocateHeap(RtlGetProcessHeap(), 0, TempSize);
+        StringCchCopyA(TempName, TempSize, network_info->HostName);
+        StringCchCatA(TempName, TempSize, ".");
+        StringCchCatA(TempName, TempSize, network_info->DomainName);
+    }
+    else
+    {
+        TempName = RtlAllocateHeap(RtlGetProcessHeap(), 0, 1);
+        TempName[0] = 0;
+    }
+    Found = !stricmp(Name, network_info->HostName) || !stricmp(Name, TempName);
+    RtlFreeHeap(RtlGetProcessHeap(), 0, TempName);
+    if (!Found)
+    {
+        return 0;
+    }
+    /* get adapter info */
+    AdapterAddressesSize = 0;
+    GetAdaptersAddresses(AF_INET,
+                         GAA_FLAG_SKIP_FRIENDLY_NAME | 
GAA_FLAG_SKIP_DNS_SERVER |
+                         GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST,
+                         NULL,
+                         Addresses,
+                         &AdapterAddressesSize);
+    if (!AdapterAddressesSize)
+    {
+        return 0;
+    }
+    Addresses = RtlAllocateHeap(RtlGetProcessHeap(), 0, AdapterAddressesSize);
+    Status = GetAdaptersAddresses(AF_INET,
+                                  GAA_FLAG_SKIP_FRIENDLY_NAME | 
GAA_FLAG_SKIP_DNS_SERVER |
+                                  GAA_FLAG_SKIP_ANYCAST | 
GAA_FLAG_SKIP_MULTICAST,
+                                  NULL,
+                                  Addresses,
+                                  &AdapterAddressesSize);
+    if (Status)
+    {
+        RtlFreeHeap(RtlGetProcessHeap(), 0, Addresses);
+        return 0;
+    }
+    for (pip = Addresses; pip != NULL; pip = pip->Next) {
+        Address = 
((LPSOCKADDR_IN)pip->FirstUnicastAddress->Address.lpSockaddr)->sin_addr.S_un.S_addr;
+        if (Address != ntohl(INADDR_LOOPBACK))
+            break;
+    }
+    if (Address && Address != ntohl(INADDR_LOOPBACK))
+    {
+        ret = Address;
+    }
+    RtlFreeHeap(RtlGetProcessHeap(), 0, Addresses);
+    return ret;
+}
+
+BOOL
+ParseV4Address(LPCSTR AddressString,
+    OUT PDWORD pAddress)
+{
+    CHAR * cp = (CHAR *)AddressString;
+    DWORD val, base;
+    unsigned char c;
+    DWORD parts[4], *pp = parts;
+    if (!AddressString)
+        return FALSE;
+    if (!isdigit(*cp)) return FALSE;
+
+again:
+    /*
+    * Collect number up to ``.''.
+    * Values are specified as for C:
+    * 0x=hex, 0=octal, other=decimal.
+    */
+    val = 0; base = 10;
+    if (*cp == '0') {
+        if (*++cp == 'x' || *cp == 'X')
+            base = 16, cp++;
+        else
+            base = 8;
+    }
+    while ((c = *cp)) {
+        if (isdigit(c)) {
+            val = (val * base) + (c - '0');
+            cp++;
+            continue;
+        }
+        if (base == 16 && isxdigit(c)) {
+            val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
+            cp++;
+            continue;
+        }
+        break;
+    }
+    if (*cp == '.') {
+        /*
+        * Internet format:
+        *    a.b.c.d
+        */
+        if (pp >= parts + 4) return FALSE;
+        *pp++ = val;
+        cp++;
+        goto again;
+    }
+    /*
+    * Check for trailing characters.
+    */
+    if (*cp && *cp > ' ') return FALSE;
+
+    *pp++ = val;
+    /*
+    * Concoct the address according to
+    * the number of parts specified.
+    */
+    if ((DWORD)(pp - parts) != 4) return FALSE;
+    if (parts[0] > 0xff || parts[1] > 0xff || parts[2] > 0xff || parts[3] > 
0xff) return FALSE;
+    val = (parts[3] << 24) | (parts[2] << 16) | (parts[1] << 8) | parts[0];
+
+    if (pAddress)
+        *pAddress = val;
+
+    return TRUE;
+}
+
+/* This function is far from perfect but it works enough */
+IP4_ADDRESS
+FindEntryInHosts(CONST CHAR * name)
+{
+    BOOL Found = FALSE;
+    HANDLE HostsFile;
+    CHAR HostsDBData[BUFSIZ] = { 0 };
+    PCHAR AddressStr, DnsName = NULL, AddrTerm, NameSt, NextLine, ThisLine, 
Comment;
+    UINT ValidData = 0;
+    DWORD ReadSize;
+    DWORD Address;
+
+    /* Open the network database */
+    HostsFile = OpenNetworkDatabase(L"hosts");
+    if (HostsFile == INVALID_HANDLE_VALUE)
+    {
+        WSASetLastError(WSANO_RECOVERY);
+        return 0;
+    }
+
+    while (!Found && ReadFile(HostsFile,
+        HostsDBData + ValidData,
+        sizeof(HostsDBData) - ValidData,
+        &ReadSize,
+        NULL))
+    {
+        ValidData += ReadSize;
+        ReadSize = 0;
+        NextLine = ThisLine = HostsDBData;
+
+        /* Find the beginning of the next line */
+        while ((NextLine < HostsDBData + ValidData) &&
+               (*NextLine != '\r') &&
+               (*NextLine != '\n'))
+        {
+            NextLine++;
+        }
+
+        /* Zero and skip, so we can treat what we have as a string */
+        if (NextLine > HostsDBData + ValidData)
+            break;
+
+        *NextLine = 0;
+        NextLine++;
+
+        Comment = strchr(ThisLine, '#');
+        if (Comment)
+            *Comment = 0; /* Terminate at comment start */
+
+        AddressStr = ThisLine;
+        /* Find the first space separating the IP address from the DNS name */
+        AddrTerm = strchr(ThisLine, ' ');
+        if (AddrTerm)
+        {
+            /* Terminate the address string */
+            *AddrTerm = 0;
+
+            /* Find the last space before the DNS name */
+            NameSt = strrchr(ThisLine, ' ');
+
+            /* If there is only one space (the one we removed above), then 
just use the address terminator */
+            if (!NameSt)
+                NameSt = AddrTerm;
+
+            /* Move from the space to the first character of the DNS name */
+            NameSt++;
+
+            DnsName = NameSt;
+
+            if (!stricmp(name, DnsName) || !stricmp(name, AddressStr))
+            {
+                Found = TRUE;
+                break;
+            }
+        }
+
+        /* Get rid of everything we read so far */
+        while (NextLine <= HostsDBData + ValidData &&
+            isspace(*NextLine))
+        {
+            NextLine++;
+        }
+
+        if (HostsDBData + ValidData - NextLine <= 0)
+            break;
+
+        memmove(HostsDBData, NextLine, HostsDBData + ValidData - NextLine);
+        ValidData -= NextLine - HostsDBData;
+    }
+
+    CloseHandle(HostsFile);
+
+    if (!Found)
+    {
+        WSASetLastError(WSANO_DATA);
+        return 0;
+    }
+
+    if (strstr(AddressStr, ":"))
+    {
+        WSASetLastError(WSAEINVAL);
+        return 0;
+    }
+
+    if (!ParseV4Address(AddressStr, &Address))
+    {
+        WSASetLastError(WSAEINVAL);
+        return 0;
+    }
+
+    return Address;
 }
 
 DNS_STATUS WINAPI
@@ -197,107 +596,297 @@
            PDNS_RECORD *QueryResultSet,
            PVOID *Reserved)
 {
-    UINT i;
-    PCHAR Buffer;
-    DNS_STATUS Status;
-    PDNS_RECORD QueryResultWide;
-    PDNS_RECORD ConvertedRecord = 0, LastRecord = 0;
+    adns_state astate;
+    int quflags = (Options & DNS_QUERY_NO_RECURSION) == 0 ? adns_qf_search : 0;
+    int adns_error;
+    adns_answer *answer;
+    LPSTR CurrentName;
+    unsigned i, CNameLoop;
+    PFIXED_INFO network_info;
+    ULONG network_info_blen = 0;
+    DWORD network_info_result;
+    PIP_ADDR_STRING pip;
+    IP4_ADDRESS Address;
+    struct in_addr addr;
+    PCHAR HostWithDomainName;
+    PCHAR AnsiName;
+    size_t NameLen = 0;
 
     if (Name == NULL)
         return ERROR_INVALID_PARAMETER;
-
-    Buffer = DnsWToC(Name);
-
-    Status = DnsQuery_A(Buffer, Type, Options, Servers, &QueryResultWide, 
Reserved);
-
-    while(Status == ERROR_SUCCESS && QueryResultWide)
-    {
-        switch(QueryResultWide->wType)
-        {
-            case DNS_TYPE_A:
-            case DNS_TYPE_WKS:
-                ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, 
sizeof(DNS_RECORD));
-                ConvertedRecord->pName = 
(PCHAR)DnsCToW(QueryResultWide->pName);
-                ConvertedRecord->wType = QueryResultWide->wType;
-                ConvertedRecord->wDataLength = QueryResultWide->wDataLength;
-                memcpy(ConvertedRecord, QueryResultWide, 
QueryResultWide->wDataLength);
-                break;
-
-            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));
-                ConvertedRecord->pName = 
(PCHAR)DnsCToW(QueryResultWide->pName);
-                ConvertedRecord->wType = QueryResultWide->wType;
-                ConvertedRecord->wDataLength = sizeof(DNS_PTR_DATA);
-                ConvertedRecord->Data.PTR.pNameHost = 
(PCHAR)DnsCToW(QueryResultWide->Data.PTR.pNameHost);
-                break;
-
-            case DNS_TYPE_MINFO:
-                ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, 
sizeof(DNS_RECORD));
-                ConvertedRecord->pName = 
(PCHAR)DnsCToW(QueryResultWide->pName);
-                ConvertedRecord->wType = QueryResultWide->wType;
-                ConvertedRecord->wDataLength = sizeof(DNS_MINFO_DATA);
-                ConvertedRecord->Data.MINFO.pNameMailbox = 
(PCHAR)DnsCToW(QueryResultWide->Data.MINFO.pNameMailbox);
-                ConvertedRecord->Data.MINFO.pNameErrorsMailbox = 
(PCHAR)DnsCToW(QueryResultWide->Data.MINFO.pNameErrorsMailbox);
-                break;
-
-            case DNS_TYPE_MX:
-                ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, 
sizeof(DNS_RECORD));
-                ConvertedRecord->pName = 
(PCHAR)DnsCToW(QueryResultWide->pName);
-                ConvertedRecord->wType = QueryResultWide->wType;
-                ConvertedRecord->wDataLength = sizeof(DNS_MX_DATA);
-                ConvertedRecord->Data.MX.pNameExchange = (PCHAR)DnsCToW( 
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 = (PCHAR)DnsCToW( 
QueryResultWide->pName );
-                ConvertedRecord->wType = QueryResultWide->wType;
-                ConvertedRecord->wDataLength = sizeof(DNS_TXT_DATA) + 
(sizeof(PWCHAR) * 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] = 
(PCHAR)DnsCToW(QueryResultWide->Data.TXT.pStringArray[i]);
-
-                break;
-
-            case DNS_TYPE_NULL:
-                ConvertedRecord = RtlAllocateHeap(RtlGetProcessHeap(), 0, 
sizeof(DNS_NULL_DATA) + QueryResultWide->Data.Null.dwByteCount);
-                ConvertedRecord->pName = 
(PCHAR)DnsCToW(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);
-                break;
-        }
-
-        if(LastRecord)
-        {
-            LastRecord->pNext = ConvertedRecord;
-            LastRecord = LastRecord->pNext;
-        }
-        else
-        {
-            LastRecord = *QueryResultSet = ConvertedRecord;
-        }
-
-        QueryResultWide = QueryResultWide->pNext;
-    }
-
-    if (LastRecord)
-        LastRecord->pNext = 0;
-
-    /* The name */
-    RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
-
-    return Status;
+    if (QueryResultSet == NULL)
+        return ERROR_INVALID_PARAMETER;
+    if ((Options & DNS_QUERY_WIRE_ONLY) != 0 && (Options & 
DNS_QUERY_NO_WIRE_QUERY) != 0)
+        return ERROR_INVALID_PARAMETER;
+
+    *QueryResultSet = 0;
+
+    switch (Type)
+    {
+    case DNS_TYPE_A:
+        /* FIXME: how much instead of MAX_PATH? */
+        NameLen = WideCharToMultiByte(CP_ACP,
+                                      0,
+                                      Name,
+                                      -1,
+                                      NULL,
+                                      0,
+                                      NULL,
+                                      0);
+        AnsiName = RtlAllocateHeap(RtlGetProcessHeap(), 0, NameLen);
+        if (NULL == AnsiName)
+        {
+            return ERROR_OUTOFMEMORY;
+        }
+        WideCharToMultiByte(CP_ACP,
+                            0,
+                            Name,
+                            -1,
+                            AnsiName,
+                            NameLen,
+                            NULL,
+                            0);
+        NameLen--;
+        /* Is it an IPv4 address? */
+        if (ParseV4Address(AnsiName, &Address))
+        {
+            RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiName);
+            *QueryResultSet = 
(PDNS_RECORD)RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_RECORD));
+
+            if (NULL == *QueryResultSet)
+            {
+                return ERROR_OUTOFMEMORY;
+            }
+
+            (*QueryResultSet)->pNext = NULL;
+            (*QueryResultSet)->wType = Type;
+            (*QueryResultSet)->wDataLength = sizeof(DNS_A_DATA);
+            (*QueryResultSet)->Data.A.IpAddress = Address;
+
+            (*QueryResultSet)->pName = (LPSTR)xstrsave(Name);
+
+            return (*QueryResultSet)->pName ? ERROR_SUCCESS : 
ERROR_OUTOFMEMORY;
+        }
+
+        /* Check allowed characters
+        * According to RFC a-z,A-Z,0-9,-,_, but can't start or end with - or _
+        */
+        if (AnsiName[0] == '-' || AnsiName[0] == '_' || AnsiName[NameLen - 1] 
== '-' ||
+            AnsiName[NameLen - 1] == '_' || strstr(AnsiName, "..") != NULL)
+        {
+            RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiName);
+            return ERROR_INVALID_NAME;
+        }
+        i = 0;
+        while (i < NameLen)
+        {
+            if (!((AnsiName[i] >= 'a' && AnsiName[i] <= 'z') ||
+                  (AnsiName[i] >= 'A' && AnsiName[i] <= 'Z') ||
+                  (AnsiName[i] >= '0' && AnsiName[i] <= '9') ||
+                  AnsiName[i] == '-' || AnsiName[i] == '_' || AnsiName[i] == 
'.'))
+            {
+                RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiName);
+                return ERROR_INVALID_NAME;
+            }
+            i++;
+        }
+
+        if ((Options & DNS_QUERY_NO_HOSTS_FILE) == 0)
+        {
+            if ((Address = FindEntryInHosts(AnsiName)) != 0)
+            {
+                RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiName);
+                *QueryResultSet = 
(PDNS_RECORD)RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_RECORD));
+
+                if (NULL == *QueryResultSet)
+                {
+                    return ERROR_OUTOFMEMORY;
+                }
+
+                (*QueryResultSet)->pNext = NULL;
+                (*QueryResultSet)->wType = Type;
+                (*QueryResultSet)->wDataLength = sizeof(DNS_A_DATA);
+                (*QueryResultSet)->Data.A.IpAddress = Address;
+
+                (*QueryResultSet)->pName = (LPSTR)xstrsave(Name);
+
+                return (*QueryResultSet)->pName ? ERROR_SUCCESS : 
ERROR_OUTOFMEMORY;
+            }
+        }
+
+        network_info_result = GetNetworkParams(NULL, &network_info_blen);
+        network_info = (PFIXED_INFO)RtlAllocateHeap(RtlGetProcessHeap(), 0, 
(size_t)network_info_blen);
+        if (NULL == network_info)
+        {
+            return ERROR_OUTOFMEMORY;
+        }
+
+        network_info_result = GetNetworkParams(network_info, 
&network_info_blen);
+        if (network_info_result != ERROR_SUCCESS)
+        {
+            RtlFreeHeap(RtlGetProcessHeap(), 0, network_info);
+            return network_info_result;
+        }
+
+        if ((Address = CheckForCurrentHostname(NameLen != 0 ? AnsiName : 
network_info->HostName, network_info)) != 0)
+        {
+            size_t TempLen = 2, StringLength = 0;
+            RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiName);
+            StringCchLengthA(network_info->HostName, 
sizeof(network_info->HostName), &StringLength);
+            TempLen += StringLength;
+            StringCchLengthA(network_info->DomainName, 
sizeof(network_info->DomainName), &StringLength);
+            TempLen += StringLength;
+            HostWithDomainName = (PCHAR)RtlAllocateHeap(RtlGetProcessHeap(), 
0, TempLen);
+            StringCchCopyA(HostWithDomainName, TempLen, 
network_info->HostName);
+            if (network_info->DomainName)
+            {
+                StringCchCatA(HostWithDomainName, TempLen, ".");
+                StringCchCatA(HostWithDomainName, TempLen, 
network_info->DomainName);
+            }
+            RtlFreeHeap(RtlGetProcessHeap(), 0, network_info);
+            *QueryResultSet = 
(PDNS_RECORD)RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_RECORD));
+
+            if (NULL == *QueryResultSet)
+            {
+                RtlFreeHeap(RtlGetProcessHeap(), 0, HostWithDomainName);
+                return ERROR_OUTOFMEMORY;
+            }
+
+            (*QueryResultSet)->pNext = NULL;
+            (*QueryResultSet)->wType = Type;
+            (*QueryResultSet)->wDataLength = sizeof(DNS_A_DATA);
+            (*QueryResultSet)->Data.A.IpAddress = Address;
+
+            (*QueryResultSet)->pName = (LPSTR)DnsCToW(HostWithDomainName);
+
+            RtlFreeHeap(RtlGetProcessHeap(), 0, HostWithDomainName);
+            return (*QueryResultSet)->pName ? ERROR_SUCCESS : 
ERROR_OUTOFMEMORY;
+        }
+
+        if ((Options & DNS_QUERY_NO_WIRE_QUERY) != 0)
+        {
+            RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiName);
+            RtlFreeHeap(RtlGetProcessHeap(), 0, network_info);
+            return ERROR_FILE_NOT_FOUND;
+        }
+
+        adns_error = adns_init(&astate, adns_if_noenv | adns_if_noerrprint | 
adns_if_noserverwarn, 0);
+        for (pip = &(network_info->DnsServerList); pip; pip = pip->Next)
+        {
+            addr.s_addr = inet_addr(pip->IpAddress.String);
+            if ((addr.s_addr != INADDR_ANY) && (addr.s_addr != INADDR_NONE))
+                adns_addserver(astate, addr);
+        }
+        if (network_info->DomainName)
+        {
+            adns_ccf_search(astate, "LOCALDOMAIN", -1, 
network_info->DomainName);
+        }
+        RtlFreeHeap(RtlGetProcessHeap(), 0, network_info);
+
+        if (adns_error != adns_s_ok)
+        {
+            RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiName);
+            return DnsIntTranslateAdnsToDNS_STATUS(adns_error);
+        }
+
+        if (Servers)
+        {
+            for (i = 0; i < Servers->AddrCount; i++)
+            {
+                adns_addserver(astate, *((struct in_addr 
*)&Servers->AddrArray[i]));
+            }
+        }
+
+        /*
+        * adns doesn't resolve chained CNAME records (a CNAME which points to
+        * another CNAME pointing to another... pointing to an A record), 
according
+        * to a mailing list thread the authors believe that chained CNAME 
records
+        * are invalid and the DNS entries should be fixed. That's a nice 
academic
+        * standpoint, but there certainly are chained CNAME records out there,
+        * even some fairly major ones (at the time of this writing
+        * download.mozilla.org is a chained CNAME). Everyone else seems to 
resolve
+        * these fine, so we should too. So we loop here to try to resolve CNAME
+        * chains ourselves. Of course, there must be a limit to protect against
+        * CNAME loops.
+        */
+
+#define CNAME_LOOP_MAX 16
+
+        CurrentName = AnsiName;
+
+        for (CNameLoop = 0; CNameLoop < CNAME_LOOP_MAX; CNameLoop++)
+        {
+            adns_error = adns_synchronous(astate, CurrentName, adns_r_addr, 
quflags, &answer);
+
+            if (adns_error != adns_s_ok)
+            {
+                adns_finish(astate);
+
+                if (CurrentName != AnsiName)
+                    RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName);
+
+                RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiName);
+                return DnsIntTranslateAdnsToDNS_STATUS(adns_error);
+            }
+
+            if (answer && answer->rrs.addr)
+            {
+                if (CurrentName != AnsiName)
+                    RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName);
+
+                RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiName);
+                *QueryResultSet = 
(PDNS_RECORD)RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_RECORD));
+
+                if (NULL == *QueryResultSet)
+                {
+                    adns_finish(astate);
+                    return ERROR_OUTOFMEMORY;
+                }
+
+                (*QueryResultSet)->pNext = NULL;
+                (*QueryResultSet)->wType = Type;
+                (*QueryResultSet)->wDataLength = sizeof(DNS_A_DATA);
+                (*QueryResultSet)->Data.A.IpAddress = 
answer->rrs.addr->addr.inet.sin_addr.s_addr;
+
+                adns_finish(astate);
+
+                (*QueryResultSet)->pName = (LPSTR)xstrsave(Name);
+
+                return (*QueryResultSet)->pName ? ERROR_SUCCESS : 
ERROR_OUTOFMEMORY;
+            }
+
+            if (NULL == answer || adns_s_prohibitedcname != answer->status || 
NULL == answer->cname)
+            {
+                adns_finish(astate);
+
+                if (CurrentName != AnsiName)
+                    RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName);
+
+                RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiName);
+                return ERROR_FILE_NOT_FOUND;
+            }
+
+            if (CurrentName != AnsiName)
+                RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName);
+
+            CurrentName = (LPSTR)xstrsaveA(answer->cname);
+
+            if (!CurrentName)
+            {
+                RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiName);
+                adns_finish(astate);
+                return ERROR_OUTOFMEMORY;
+            }
+        }
+
+        adns_finish(astate);
+        RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiName);
+        RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName);
+        return ERROR_FILE_NOT_FOUND;
+
+    default:
+        return ERROR_OUTOFMEMORY; /* XXX arty: find a better error code. */
+    }
 }
 
 DNS_STATUS WINAPI

Modified: trunk/reactos/dll/win32/mswsock/CMakeLists.txt
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mswsock/CMakeLists.txt?rev=72867&r1=72866&r2=72867&view=diff
==============================================================================
--- trunk/reactos/dll/win32/mswsock/CMakeLists.txt      [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mswsock/CMakeLists.txt      [iso-8859-1] Fri Sep 30 
15:19:29 2016
@@ -15,7 +15,7 @@
     mswsock.rc
     ${CMAKE_CURRENT_BINARY_DIR}/mswsock.def)
 
-set_module_type(mswsock win32dll)
-add_importlibs(mswsock ws2_32 dnsapi msvcrt kernel32)
+set_module_type(mswsock win32dll UNICODE)
+add_importlibs(mswsock ws2_32 advapi32 dnsapi msvcrt kernel32)
 add_pch(mswsock precomp.h SOURCE)
 add_cd_file(TARGET mswsock DESTINATION reactos/system32 FOR all)

Modified: trunk/reactos/dll/win32/mswsock/mswhelper.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mswsock/mswhelper.c?rev=72867&r1=72866&r2=72867&view=diff
==============================================================================
--- trunk/reactos/dll/win32/mswsock/mswhelper.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mswsock/mswhelper.c [iso-8859-1] Fri Sep 30 
15:19:29 2016
@@ -263,8 +263,7 @@
     /* addr_list */
     RtlZeroMemory(lst, sizeof(lst));
 
-    if (ip4addr != 0)
-        lst[0] = (void*)&ip4addr;
+    lst[0] = (void*)&ip4addr;
 
     phe->h_addr_list = (char**)(mswBufferEndPtr(mswBuf) - bytesOfs);
 

Modified: trunk/reactos/dll/win32/mswsock/nsplookup.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mswsock/nsplookup.c?rev=72867&r1=72866&r2=72867&view=diff
==============================================================================
--- trunk/reactos/dll/win32/mswsock/nsplookup.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mswsock/nsplookup.c [iso-8859-1] Fri Sep 30 
15:19:29 2016
@@ -10,6 +10,7 @@
 #include <svcguid.h>
 #include <iptypes.h>
 #include <strsafe.h>
+#include <winreg.h>
 
 #include "mswhelper.h"
 
@@ -459,177 +460,20 @@
     return ERROR_SUCCESS;
 }
 
-/* This function is far from perfect but it works enough */
-IP4_ADDRESS
-FindEntryInHosts(IN CONST WCHAR FAR* wname)
-{
-    BOOL Found = FALSE;
-    HANDLE HostsFile;
-    CHAR HostsDBData[BUFSIZ] = {0};
-    PCHAR SystemDirectory = HostsDBData;
-    PCHAR HostsLocation = "\\drivers\\etc\\hosts";
-    PCHAR AddressStr, DnsName = NULL, AddrTerm, NameSt, NextLine, ThisLine, 
Comment;
-    UINT SystemDirSize = sizeof(HostsDBData) - 1, ValidData = 0;
-    DWORD ReadSize;
-    DWORD Address;
-    CHAR name[MAX_HOSTNAME_LEN + 1];
-
-    wcstombs(name, wname, MAX_HOSTNAME_LEN);
-
-    /* We assume that the parameters are valid */
-    if (!GetSystemDirectoryA(SystemDirectory, SystemDirSize))
-    {
-        WSASetLastError(WSANO_RECOVERY);
-        //WS_DbgPrint(MIN_TRACE, ("Could not get windows system 
directory.\n"));
-        return 0; /* Can't get system directory */
-    }
-
-    strncat(SystemDirectory, HostsLocation, SystemDirSize);
-
-    HostsFile = CreateFileA(SystemDirectory,
-                            GENERIC_READ,
-                            FILE_SHARE_READ,
-                            NULL,
-                            OPEN_EXISTING,
-                            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
-                            NULL);
-    if (HostsFile == INVALID_HANDLE_VALUE)
-    {
-        WSASetLastError(WSANO_RECOVERY);
-        return 0;
-    }
-
-    while (!Found && ReadFile(HostsFile,
-                              HostsDBData + ValidData,
-                              sizeof(HostsDBData) - ValidData,
-                              &ReadSize,
-                              NULL))
-    {
-        ValidData += ReadSize;
-        ReadSize = 0;
-        NextLine = ThisLine = HostsDBData;
-
-        /* Find the beginning of the next line */
-        while ((NextLine < HostsDBData + ValidData) &&
-               (*NextLine != '\r') &&
-               (*NextLine != '\n'))
-        {
-            NextLine++;
-        }
-
-        /* Zero and skip, so we can treat what we have as a string */
-        if (NextLine > HostsDBData + ValidData)
-            break;
-
-        *NextLine = 0;
-        NextLine++;
-
-        Comment = strchr(ThisLine, '#');
-        if (Comment)
-            *Comment = 0; /* Terminate at comment start */
-
-        AddressStr = ThisLine;
-        /* Find the first space separating the IP address from the DNS name */
-        AddrTerm = strchr(ThisLine, ' ');
-        if (AddrTerm)
-        {
-            /* Terminate the address string */
-            *AddrTerm = 0;
-
-            /* Find the last space before the DNS name */
-            NameSt = strrchr(ThisLine, ' ');
-
-            /* If there is only one space (the one we removed above), then 
just use the address terminator */
-            if (!NameSt)
-                NameSt = AddrTerm;
-
-            /* Move from the space to the first character of the DNS name */
-            NameSt++;
-
-            DnsName = NameSt;
-
-            if (!strcmp(name, DnsName))
-            {
-                Found = TRUE;
-                break;
-            }
-        }
-
-        /* Get rid of everything we read so far */
-        while (NextLine <= HostsDBData + ValidData &&
-               isspace (*NextLine))
-        {
-            NextLine++;
-        }
-
-        if (HostsDBData + ValidData - NextLine <= 0)
-            break;
-
-        //WS_DbgPrint(MAX_TRACE,("About to move %d chars\n",
-        //            HostsDBData + ValidData - NextLine));
-
-        memmove(HostsDBData, NextLine, HostsDBData + ValidData - NextLine);
-        ValidData -= NextLine - HostsDBData;
-        //WS_DbgPrint(MAX_TRACE,("Valid bytes: %d\n", ValidData));
-    }
-
-    CloseHandle(HostsFile);
-
-    if (!Found)
-    {
-        //WS_DbgPrint(MAX_TRACE,("Not found\n"));
-        WSASetLastError(WSANO_DATA);
-        return 0;
-    }
-
-    if (strstr(AddressStr, ":"))
-    {
-       //DbgPrint("AF_INET6 NOT SUPPORTED!\n");
-       WSASetLastError(WSAEINVAL);
-       return 0;
-    }
-
-    Address = inet_addr(AddressStr);
-    if (Address == INADDR_NONE)
-    {
-        WSASetLastError(WSAEINVAL);
-        return 0;
-    }
-
-    return Address;
-}
-
 INT
 NSP_GetHostByNameHeapAllocW(_In_ WCHAR* name,
                             _In_ GUID* lpProviderId,
                             _Out_ PWSHOSTINFOINTERN hostinfo)
 {
     HANDLE hHeap = GetProcessHeap();
-    enum addr_type
-    {
-        GH_INVALID,
-        GH_IPV6,
-        GH_IPV4,
-        GH_RFC1123_DNS
-    };
-    typedef enum addr_type addr_type;
-    addr_type addr;
-    INT ret = 0;
-    WCHAR* found = 0;
     DNS_STATUS dns_status = {0};
     /* include/WinDNS.h -- look up DNS_RECORD on MSDN */
     PDNS_RECORD dp;
     PDNS_RECORD curr;
-    WCHAR* tmpHostnameW;
-    CHAR* tmpHostnameA;
-    IP4_ADDRESS address;
     INT result = ERROR_SUCCESS;
 
     /* needed to be cleaned up if != NULL */
-    tmpHostnameW = NULL;
     dp = NULL;
-
-    addr = GH_INVALID;
 
     if (name == NULL)
     {
@@ -637,131 +481,49 @@
         goto cleanup;
     }
 
-    /* Hostname "" / "localhost"
-       - convert to "computername" */
-    if ((wcscmp(L"", name) == 0) /*||
-        (wcsicmp(L"localhost", name) == 0)*/)
-    {
-        ret = NSP_GetHostNameHeapAllocW(&tmpHostnameW);
-        if (ret != ERROR_SUCCESS)
-        {
-            result = ret;
-            goto cleanup;
-        }
-        name = tmpHostnameW;
-    }
-
-    /* Is it an IPv6 address? */
-    found = wcschr(name, L':');
-    if (found != NULL)
-    {
-        addr = GH_IPV6;
-        goto act;
-    }
-
-    /* Is it an IPv4 address? */
-    if (!iswalpha(name[0]))
-    {
-        addr = GH_IPV4;
-        goto act;
-    }
-
-    addr = GH_RFC1123_DNS;
-
-/* Broken out in case we want to get fancy later */
-act:
-    switch (addr)
-    {
-        case GH_IPV6:
-            WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-            result = ERROR_CALL_NOT_IMPLEMENTED;
-            goto cleanup;
-        break;
-
-        case GH_INVALID:
-            WSASetLastError(WSAEFAULT);
-            result = ERROR_INVALID_PARAMETER;
-            goto cleanup;
-        break;
-
-        /* Note: If passed an IP address, MSDN says that gethostbyname()
-                 treats it as an unknown host.
-           This is different from the unix implementation. Use inet_addr()
-        */
-        case GH_IPV4:
-        case GH_RFC1123_DNS:
-        /* DNS_TYPE_A: include/WinDNS.h */
-        /* DnsQuery -- lib/dnsapi/dnsapi/query.c */
-
-        /* Look for the DNS name in the hosts file */
-        if ((address = FindEntryInHosts(name)) != 0)
-        {
-            hostinfo->hostnameW = StrCpyHeapAllocW(hHeap, name);
-            hostinfo->addr4 = address;
-            result = ERROR_SUCCESS;
-            goto cleanup;
-        }
-
-        tmpHostnameA = StrW2AHeapAlloc(hHeap, name);
-        dns_status = DnsQuery(tmpHostnameA,
-                              DNS_TYPE_A,
-                              DNS_QUERY_STANDARD,
-                              /* extra dns servers */ 0,
-                              &dp,
-                              0);
-        HeapFree(hHeap, 0, tmpHostnameA);
-
-        if ((dns_status != 0) || (dp == NULL))
-        {
-            result = WSAHOST_NOT_FOUND;
-            goto cleanup;
-        }
-
-        //ASSERT(dp->wType == DNS_TYPE_A);
-        //ASSERT(dp->wDataLength == sizeof(DNS_A_DATA));
-        curr = dp;
-        while ((curr->pNext != NULL) || (curr->wType != DNS_TYPE_A))
-        {
-            curr = curr->pNext;
-        }
-
-        if (curr->wType != DNS_TYPE_A)
-        {
-            result = WSASERVICE_NOT_FOUND;
-            goto cleanup;
-        }
-
-        //WS_DbgPrint(MID_TRACE,("populating hostent\n"));
-        //WS_DbgPrint(MID_TRACE,("pName is (%s)\n", curr->pName));
-        //populate_hostent(p->Hostent,
-        //                 (PCHAR)curr->pName,
-        //                 curr->Data.A.IpAddress);
-        hostinfo->hostnameW = StrA2WHeapAlloc(hHeap, curr->pName);
-        hostinfo->addr4 = curr->Data.A.IpAddress;
-        result = ERROR_SUCCESS;
+    /* DNS_TYPE_A: include/WinDNS.h */
+    /* DnsQuery -- lib/dnsapi/dnsapi/query.c */
+    dns_status = DnsQuery(name,
+                          DNS_TYPE_A,
+                          DNS_QUERY_STANDARD,
+                          /* extra dns servers */ 0,
+                          &dp,
+                          0);
+
+    if (dns_status == ERROR_INVALID_NAME)
+    {
+        WSASetLastError(WSAEFAULT);
+        result = ERROR_INVALID_PARAMETER;
         goto cleanup;
-
-        //WS_DbgPrint(MID_TRACE,("Called DnsQuery, but host not found. Err: 
%i\n",
-        //            dns_status));
-        //WSASetLastError(WSAHOST_NOT_FOUND);
-        //return NULL;
-
-        break;
-
-        default:
-            result = WSANO_RECOVERY;
-            goto cleanup;
-        break;
-    }
-
-    result = WSANO_RECOVERY;
+    }
+
+    if ((dns_status != 0) || (dp == NULL))
+    {
+        result = WSAHOST_NOT_FOUND;
+        goto cleanup;
+    }
+
+    //ASSERT(dp->wType == DNS_TYPE_A);
+    //ASSERT(dp->wDataLength == sizeof(DNS_A_DATA));
+    curr = dp;
+    while ((curr->pNext != NULL) || (curr->wType != DNS_TYPE_A))
+    {
+        curr = curr->pNext;
+    }
+
+    if (curr->wType != DNS_TYPE_A)
+    {
+        result = WSASERVICE_NOT_FOUND;
+        goto cleanup;
+    }
+
+    hostinfo->hostnameW = StrCpyHeapAllocW(hHeap, curr->pName);
+    hostinfo->addr4 = curr->Data.A.IpAddress;
+    result = ERROR_SUCCESS;
 
 cleanup:
     if (dp != NULL)
         DnsRecordListFree(dp, DnsFreeRecordList);
-
-    if (tmpHostnameW != NULL)
-        HeapFree(hHeap, 0, tmpHostnameW);
 
     return result;
 }
@@ -825,6 +587,99 @@
     return TRUE;
 }
 
+HANDLE
+WSAAPI
+OpenNetworkDatabase(_In_ LPCWSTR Name)
+{
+    PWSTR ExpandedPath;
+    PWSTR DatabasePath;
+    INT ErrorCode;
+    HKEY DatabaseKey;
+    DWORD RegType;
+    DWORD RegSize = 0;
+    size_t StringLength;
+    HANDLE ret;
+
+    ExpandedPath = HeapAlloc(GetProcessHeap(), 0, MAX_PATH*sizeof(WCHAR));
+    if (!ExpandedPath)
+        return INVALID_HANDLE_VALUE;
+
+    /* Open the database path key */
+    ErrorCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                             
L"System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+                             0,
+                             KEY_READ,
+                             &DatabaseKey);
+    if (ErrorCode == NO_ERROR)
+    {
+        /* Read the actual path */
+        ErrorCode = RegQueryValueEx(DatabaseKey,
+                                    L"DatabasePath",
+                                    NULL,
+                                    &RegType,
+                                    NULL,
+                                    &RegSize);
+
+        DatabasePath = HeapAlloc(GetProcessHeap(), 0, RegSize);
+        if (!DatabasePath)
+        {
+            HeapFree(GetProcessHeap(), 0, ExpandedPath);
+            return INVALID_HANDLE_VALUE;
+        }
+
+        /* Read the actual path */
+        ErrorCode = RegQueryValueEx(DatabaseKey,
+                                    L"DatabasePath",
+                                    NULL,
+                                    &RegType,
+                                    (LPBYTE)DatabasePath,
+                                    &RegSize);
+
+        /* Close the key */
+        RegCloseKey(DatabaseKey);
+
+        /* Expand the name */
+        ExpandEnvironmentStrings(DatabasePath, ExpandedPath, MAX_PATH);
+
+        HeapFree(GetProcessHeap(), 0, DatabasePath);
+    }
+    else
+    {
+        /* Use defalt path */
+        GetSystemDirectory(ExpandedPath, MAX_PATH);
+        StringCchLength(ExpandedPath, MAX_PATH, &StringLength);
+        if (ExpandedPath[StringLength - 1] != L'\\')
+        {
+            /* It isn't, so add it ourselves */
+            StringCchCat(ExpandedPath, MAX_PATH, L"\\");
+        }
+        StringCchCat(ExpandedPath, MAX_PATH, L"DRIVERS\\ETC\\");
+    }
+
+    /* Make sure that the path is backslash-terminated */
+    StringCchLength(ExpandedPath, MAX_PATH, &StringLength);
+    if (ExpandedPath[StringLength - 1] != L'\\')
+    {
+        /* It isn't, so add it ourselves */
+        StringCchCat(ExpandedPath, MAX_PATH, L"\\");
+    }
+
+    /* Add the database name */
+    StringCchCat(ExpandedPath, MAX_PATH, Name);
+
+    /* Return a handle to the file */
+    ret = CreateFile(ExpandedPath,
+                      FILE_READ_DATA,
+                      FILE_SHARE_READ,
+                      NULL,
+                      OPEN_EXISTING,
+                      FILE_ATTRIBUTE_NORMAL,
+                      NULL);
+
+    HeapFree(GetProcessHeap(), 0, ExpandedPath);
+    return ret;
+}
+
 INT
 NSP_GetServiceByNameHeapAllocW(_In_ WCHAR* nameW,
                                _In_ GUID* lpProviderId,
@@ -833,14 +688,11 @@
     BOOL Found = FALSE;
     HANDLE ServicesFile;
     CHAR ServiceDBData[BUFSIZ * sizeof(WCHAR)] = {0};
-    PWCHAR SystemDirectory = (PWCHAR)ServiceDBData; /* Reuse this stack space 
*/
-    PWCHAR ServicesFileLocation = L"\\drivers\\etc\\services";
     PCHAR ThisLine = 0, NextLine = 0, ServiceName = 0, PortNumberStr = 0,
     ProtocolStr = 0, Comment = 0, EndValid;
     PCHAR Aliases[WS2_INTERNAL_MAX_ALIAS] = {0};
     PCHAR* AliasPtr;
-    UINT i = 0,
-    SystemDirSize = (sizeof(ServiceDBData) / sizeof(WCHAR)) - 1;
+    UINT i = 0;
     DWORD ReadSize = 0;
     HANDLE hHeap;
     PCHAR nameA = NULL;
@@ -872,23 +724,7 @@
     StringCbCopyA(nameServiceA, i + 1, nameA);
     nameServiceA[i] = '\0';
 
-    if (!GetSystemDirectoryW(SystemDirectory, SystemDirSize))
-    {
-        /* Can't get system directory */
-        res = WSANO_RECOVERY;
-        goto End;
-    }
-
-    wcsncat(SystemDirectory, ServicesFileLocation, SystemDirSize);
-
-    ServicesFile = CreateFileW(SystemDirectory,
-                               GENERIC_READ,
-                               FILE_SHARE_READ,
-                               NULL,
-                               OPEN_EXISTING,
-                               FILE_ATTRIBUTE_NORMAL | 
FILE_FLAG_SEQUENTIAL_SCAN,
-                               NULL);
-
+    ServicesFile = OpenNetworkDatabase(L"services");
     if (ServicesFile == INVALID_HANDLE_VALUE)
     {
         return WSANO_RECOVERY;

Modified: trunk/reactos/sdk/lib/3rdparty/adns/src/adns.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/3rdparty/adns/src/adns.h?rev=72867&r1=72866&r2=72867&view=diff
==============================================================================
--- trunk/reactos/sdk/lib/3rdparty/adns/src/adns.h      [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/3rdparty/adns/src/adns.h      [iso-8859-1] Fri Sep 30 
15:19:29 2016
@@ -368,6 +368,7 @@
 
 /* ReactOS addition */
 ADNS_API void adns_addserver(adns_state state, struct in_addr server);
+ADNS_API void adns_ccf_search(adns_state ads, const char *fn, int lno, const 
char *buf);
 
 ADNS_API int adns_init_strcfg(adns_state *newstate_r, adns_initflags flags,
                     FILE *diagfile /*0=>discard*/, const char *configtext);

Modified: trunk/reactos/sdk/lib/3rdparty/adns/src/setup.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/3rdparty/adns/src/setup.c?rev=72867&r1=72866&r2=72867&view=diff
==============================================================================
--- trunk/reactos/sdk/lib/3rdparty/adns/src/setup.c     [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/3rdparty/adns/src/setup.c     [iso-8859-1] Fri Sep 30 
15:19:29 2016
@@ -571,18 +571,6 @@
 #ifdef ADNS_JGAA_WIN32
   #define SECURE_PATH_LEN (MAX_PATH - 64)
   char PathBuf[MAX_PATH];
-  struct in_addr addr;
-#ifdef __REACTOS__
-  PFIXED_INFO network_info;
-  ULONG network_info_blen = 0;
-#else
-  #define ADNS_PFIXED_INFO_BLEN (2048)
-  PFIXED_INFO network_info = (PFIXED_INFO)_alloca(ADNS_PFIXED_INFO_BLEN);
-  ULONG network_info_blen = ADNS_PFIXED_INFO_BLEN;
-#endif /* __REACTOS__ */
-  DWORD network_info_result;
-  PIP_ADDR_STRING pip;
-  const char *network_err_str = "";
 #endif
 
   r= init_begin(&ads, flags, diagfile ? diagfile : stderr);
@@ -606,36 +594,6 @@
   GetWindowsDirectory(PathBuf, SECURE_PATH_LEN);
   strcat(PathBuf,"\\System32\\Drivers\\etc\\resolv-adns.conf");
   readconfig(ads,PathBuf,0);
-#ifdef __REACTOS__
-  network_info_result = GetNetworkParams(NULL, &network_info_blen);
-  network_info = (PFIXED_INFO)malloc((size_t)network_info_blen);
-#endif
-  network_info_result = GetNetworkParams(network_info, &network_info_blen);
-  if (network_info_result != ERROR_SUCCESS){
-    switch(network_info_result) {
-    case ERROR_BUFFER_OVERFLOW: network_err_str = "ERROR_BUFFER_OVERFLOW"; 
break;
-    case ERROR_INVALID_PARAMETER: network_err_str = "ERROR_INVALID_PARAMETER"; 
break;
-    case ERROR_NO_DATA: network_err_str = "ERROR_NO_DATA"; break;
-    case ERROR_NOT_SUPPORTED: network_err_str = "ERROR_NOT_SUPPORTED"; break;}
-    adns__diag(ads,-1,0,"GetNetworkParams() failed with error [%d] %s",
-      network_info_result,network_err_str);
-    }
-  else {
-    for(pip = &(network_info->DnsServerList); pip; pip = pip->Next) {
-      addr.s_addr = inet_addr(pip->IpAddress.String);
-      if ((addr.s_addr != INADDR_ANY) && (addr.s_addr != INADDR_NONE))
-        addserver(ads, addr);
-#ifdef __REACTOS__
-      if (network_info->DomainName)
-        ccf_search(ads, "LOCALDOMAIN", -1, network_info->DomainName);
-      else
-        ccf_search(ads, "LOCALDOMAIN", -1, "");
-#endif
-    }
-  }
-#ifdef __REACTOS__
-  if (network_info) free(network_info);
-#endif
 #else
   readconfig(ads,"/etc/resolv.conf",1);
   readconfig(ads,"/etc/resolv-adns.conf",0);
@@ -753,3 +711,6 @@
 void adns_addserver(adns_state ads, struct in_addr addr) {
     addserver(ads, addr);
 }
+void adns_ccf_search(adns_state ads, const char *fn, int lno, const char *buf) 
{
+    ccf_search(ads, fn, lno, buf);
+}


Reply via email to