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/CMakeList…
==============================================================================
--- 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/qu…
==============================================================================
--- 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/CMakeLis…
==============================================================================
--- 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/mswhelpe…
==============================================================================
--- 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/nsplooku…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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);
+}