Index: dll/win32/dnsapi/CMakeLists.txt =================================================================== --- dll/win32/dnsapi/CMakeLists.txt (revision 72853) +++ dll/win32/dnsapi/CMakeLists.txt (working copy) @@ -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) Index: dll/win32/dnsapi/dnsapi/query.c =================================================================== --- dll/win32/dnsapi/dnsapi/query.c (revision 72853) +++ dll/win32/dnsapi/dnsapi/query.c (working copy) @@ -9,6 +9,9 @@ */ #include "precomp.h" +#include +#include +#include #define NDEBUG #include @@ -31,17 +34,63 @@ * Reserved -- Response as it appears on the wire. Optional. */ -char -*xstrsave(const char *str) +static PCHAR +DnsWToC(const WCHAR *WideString) { - char *p; + 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); - p = RtlAllocateHeap(RtlGetProcessHeap(), 0, strlen(str) + 1); + return AnsiString; +} - if(p) - strcpy(p, str); +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 p; + 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; + if (QueryResultSet == NULL) + return ERROR_INVALID_PARAMETER; - *QueryResultSet = 0; + Buffer = DnsCToW(Name); - switch(Type) + 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); + 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; - if(adns_error != adns_s_ok) - return DnsIntTranslateAdnsToDNS_STATUS(adns_error); + 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; - if (Servers) - { - for(i = 0; i < Servers->AddrCount; i++) - { - adns_addserver(astate, *((struct in_addr *)&Servers->AddrArray[i])); - } - } + 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; - /* - * 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. - */ + 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; -#define CNAME_LOOP_MAX 16 + 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; - CurrentName = (LPSTR) Name; + for (i = 0; i < ConvertedRecord->Data.TXT.dwStringCount; i++) + ConvertedRecord->Data.TXT.pStringArray[i] = DnsWToC((PWCHAR)QueryResultWide->Data.TXT.pStringArray[i]); - for (CNameLoop = 0; CNameLoop < CNAME_LOOP_MAX; CNameLoop++) - { - adns_error = adns_synchronous(astate, CurrentName, adns_r_addr, quflags, &answer); + break; - if(adns_error != adns_s_ok) - { - adns_finish(astate); + 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 (CurrentName != Name) - RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName); + if (LastRecord) + { + LastRecord->pNext = ConvertedRecord; + LastRecord = LastRecord->pNext; + } + else + { + LastRecord = *QueryResultSet = ConvertedRecord; + } - return DnsIntTranslateAdnsToDNS_STATUS(adns_error); - } + QueryResultWide = QueryResultWide->pNext; + } - if(answer && answer->rrs.addr) - { - if (CurrentName != Name) - RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName); + if (LastRecord) + LastRecord->pNext = 0; - *QueryResultSet = (PDNS_RECORD)RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(DNS_RECORD)); + /* The name */ + RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); + /* The result*/ + if (QueryResultWide) DnsIntFreeRecordList(QueryResultWide); - if (NULL == *QueryResultSet) - { - adns_finish( astate ); - return ERROR_OUTOFMEMORY; - } + return Status; +} - (*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; +WCHAR +*xstrsave(const WCHAR *str) +{ + WCHAR *p; + size_t len = 0; - adns_finish(astate); + /* FIXME: how much instead of MAX_PATH? */ + StringCbLengthW(str, MAX_PATH, &len); + len+=sizeof(WCHAR); - (*QueryResultSet)->pName = xstrsave( Name ); + p = RtlAllocateHeap(RtlGetProcessHeap(), 0, len); - return NULL != (*QueryResultSet)->pName ? ERROR_SUCCESS : ERROR_OUTOFMEMORY; - } + if (p) + StringCbCopyW(p, len, str); - if (NULL == answer || adns_s_prohibitedcname != answer->status || NULL == answer->cname) - { - adns_finish(astate); + return p; +} - if (CurrentName != Name) - RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName); +CHAR +*xstrsaveA(const CHAR *str) +{ + CHAR *p; + size_t len = 0; - return ERROR_FILE_NOT_FOUND; - } + /* FIXME: how much instead of MAX_PATH? */ + StringCbLengthA(str, MAX_PATH, &len); + len++; - if (CurrentName != Name) - RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName); + p = RtlAllocateHeap(RtlGetProcessHeap(), 0, len); - CurrentName = xstrsave(answer->cname); + if (p) + StringCbCopyA(p, len, str); - if (!CurrentName) - { - adns_finish(astate); - return ERROR_OUTOFMEMORY; - } - } + return p; +} - adns_finish(astate); - RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentName); - return ERROR_FILE_NOT_FOUND; +HANDLE +OpenNetworkDatabase(LPCWSTR Name) +{ + PWSTR ExpandedPath; + PWSTR DatabasePath; + INT ErrorCode; + HKEY DatabaseKey; + DWORD RegType; + DWORD RegSize = 0; + size_t StringLength; + HANDLE ret; - default: - return ERROR_OUTOFMEMORY; /* XXX arty: find a better error code. */ + 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; } -static PCHAR -DnsWToC(const WCHAR *WideString) +/* This function is far from perfect but it works enough */ +IP4_ADDRESS +CheckForCurrentHostname(CONST CHAR * Name, PFIXED_INFO network_info) { - int chars = wcstombs(NULL, WideString, 0); - PCHAR out = RtlAllocateHeap(RtlGetProcessHeap(), 0, chars + 1); + PCHAR TempName; + DWORD AdapterAddressesSize, Status; + IP4_ADDRESS ret = 0, Address; + PIP_ADAPTER_ADDRESSES Addresses = NULL, pip; + BOOL Found = FALSE; - wcstombs(out, WideString, chars + 1); + 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; +} - return out; +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; } -static PWCHAR -DnsCToW(const CHAR *NarrowString) +/* This function is far from perfect but it works enough */ +IP4_ADDRESS +FindEntryInHosts(CONST CHAR * name) { - int chars = mbstowcs(NULL, NarrowString, 0); - PWCHAR out = RtlAllocateHeap(RtlGetProcessHeap(), 0, (chars + 1) * sizeof(WCHAR)); + 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; - mbstowcs(out, NarrowString, chars + 1); + /* Open the network database */ + HostsFile = OpenNetworkDatabase(L"hosts"); + if (HostsFile == INVALID_HANDLE_VALUE) + { + WSASetLastError(WSANO_RECOVERY); + return 0; + } - return out; + 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; + 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; - Buffer = DnsWToC(Name); + *QueryResultSet = 0; - Status = DnsQuery_A(Buffer, Type, Options, Servers, &QueryResultWide, Reserved); - - while(Status == ERROR_SUCCESS && QueryResultWide) + switch (Type) { - switch(QueryResultWide->wType) + 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) { - 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; + 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)); - 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; + if (NULL == *QueryResultSet) + { + return ERROR_OUTOFMEMORY; + } - 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; + (*QueryResultSet)->pNext = NULL; + (*QueryResultSet)->wType = Type; + (*QueryResultSet)->wDataLength = sizeof(DNS_A_DATA); + (*QueryResultSet)->Data.A.IpAddress = Address; - 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; + (*QueryResultSet)->pName = (LPSTR)xstrsave(Name); - 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; + return (*QueryResultSet)->pName ? ERROR_SUCCESS : ERROR_OUTOFMEMORY; + } - for(i = 0; i < ConvertedRecord->Data.TXT.dwStringCount; i++) - ConvertedRecord->Data.TXT.pStringArray[i] = (PCHAR)DnsCToW(QueryResultWide->Data.TXT.pStringArray[i]); + /* 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++; + } - break; + 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)); - 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 (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; + } } - if(LastRecord) + network_info_result = GetNetworkParams(NULL, &network_info_blen); + network_info = (PFIXED_INFO)RtlAllocateHeap(RtlGetProcessHeap(), 0, (size_t)network_info_blen); + if (NULL == network_info) { - LastRecord->pNext = ConvertedRecord; - LastRecord = LastRecord->pNext; + return ERROR_OUTOFMEMORY; } - else + + network_info_result = GetNetworkParams(network_info, &network_info_blen); + if (network_info_result != ERROR_SUCCESS) { - LastRecord = *QueryResultSet = ConvertedRecord; + RtlFreeHeap(RtlGetProcessHeap(), 0, network_info); + return network_info_result; } - QueryResultWide = QueryResultWide->pNext; - } + 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 (LastRecord) - LastRecord->pNext = 0; + if (NULL == *QueryResultSet) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, HostWithDomainName); + return ERROR_OUTOFMEMORY; + } - /* The name */ - RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); + (*QueryResultSet)->pNext = NULL; + (*QueryResultSet)->wType = Type; + (*QueryResultSet)->wDataLength = sizeof(DNS_A_DATA); + (*QueryResultSet)->Data.A.IpAddress = Address; - return Status; + (*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 Index: dll/win32/mswsock/CMakeLists.txt =================================================================== --- dll/win32/mswsock/CMakeLists.txt (revision 72853) +++ dll/win32/mswsock/CMakeLists.txt (working copy) @@ -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) Index: dll/win32/mswsock/mswhelper.c =================================================================== --- dll/win32/mswsock/mswhelper.c (revision 72853) +++ dll/win32/mswsock/mswhelper.c (working copy) @@ -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); Index: dll/win32/mswsock/nsplookup.c =================================================================== --- dll/win32/mswsock/nsplookup.c (revision 72853) +++ dll/win32/mswsock/nsplookup.c (working copy) @@ -10,6 +10,7 @@ #include #include #include +#include #include "mswhelper.h" @@ -459,146 +460,6 @@ 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, @@ -605,32 +466,15 @@ _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) { result = ERROR_INVALID_PARAMETER; @@ -637,132 +481,50 @@ goto cleanup; } - /* Hostname "" / "localhost" - - convert to "computername" */ - if ((wcscmp(L"", name) == 0) /*|| - (wcsicmp(L"localhost", name) == 0)*/) + /* 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) { - ret = NSP_GetHostNameHeapAllocW(&tmpHostnameW); - if (ret != ERROR_SUCCESS) - { - result = ret; - goto cleanup; - } - name = tmpHostnameW; + WSASetLastError(WSAEFAULT); + result = ERROR_INVALID_PARAMETER; + goto cleanup; } - /* Is it an IPv6 address? */ - found = wcschr(name, L':'); - if (found != NULL) + if ((dns_status != 0) || (dp == NULL)) { - addr = GH_IPV6; - goto act; + result = WSAHOST_NOT_FOUND; + goto cleanup; } - /* Is it an IPv4 address? */ - if (!iswalpha(name[0])) + //ASSERT(dp->wType == DNS_TYPE_A); + //ASSERT(dp->wDataLength == sizeof(DNS_A_DATA)); + curr = dp; + while ((curr->pNext != NULL) || (curr->wType != DNS_TYPE_A)) { - addr = GH_IPV4; - goto act; + curr = curr->pNext; } - addr = GH_RFC1123_DNS; - -/* Broken out in case we want to get fancy later */ -act: - switch (addr) + if (curr->wType != DNS_TYPE_A) { - 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; + result = WSASERVICE_NOT_FOUND; 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; + 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; Index: sdk/lib/3rdparty/adns/src/adns.h =================================================================== --- sdk/lib/3rdparty/adns/src/adns.h (revision 72853) +++ sdk/lib/3rdparty/adns/src/adns.h (working copy) @@ -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); Index: sdk/lib/3rdparty/adns/src/setup.c =================================================================== --- sdk/lib/3rdparty/adns/src/setup.c (revision 72853) +++ sdk/lib/3rdparty/adns/src/setup.c (working copy) @@ -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); +}