mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
[WS2_32]
- Add support for reading the hosts file - Fix an off-by-one error which prevented reading the last value in the services file - Fixes bug 4410 and bug 4880 svn path=/trunk/; revision=47020
This commit is contained in:
parent
318eee8241
commit
98acf217f9
1 changed files with 201 additions and 2 deletions
|
@ -640,7 +640,199 @@ void free_servent(struct servent* s)
|
||||||
HFREE(s);
|
HFREE(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function is far from perfect but it works enough */
|
||||||
|
static
|
||||||
|
LPHOSTENT
|
||||||
|
FindEntryInHosts(IN CONST CHAR FAR* name)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
ULONG Address;
|
||||||
|
PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;
|
||||||
|
|
||||||
|
/* 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 NULL; /* 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 NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !p->Hostent )
|
||||||
|
{
|
||||||
|
p->Hostent = HeapAlloc(GlobalHeap, 0, sizeof(*p->Hostent));
|
||||||
|
if( !p->Hostent )
|
||||||
|
{
|
||||||
|
WSASetLastError( WSATRY_AGAIN );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p->Hostent->h_name = HeapAlloc(GlobalHeap, 0, strlen(DnsName));
|
||||||
|
if( !p->Hostent->h_name )
|
||||||
|
{
|
||||||
|
WSASetLastError( WSATRY_AGAIN );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlCopyMemory(p->Hostent->h_name,
|
||||||
|
DnsName,
|
||||||
|
strlen(DnsName));
|
||||||
|
|
||||||
|
p->Hostent->h_aliases = HeapAlloc(GlobalHeap, 0, sizeof(char *));
|
||||||
|
if( !p->Hostent->h_aliases )
|
||||||
|
{
|
||||||
|
WSASetLastError( WSATRY_AGAIN );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->Hostent->h_aliases[0] = 0;
|
||||||
|
|
||||||
|
if (strstr(AddressStr, ":"))
|
||||||
|
{
|
||||||
|
DbgPrint("AF_INET6 NOT SUPPORTED!\n");
|
||||||
|
WSASetLastError(WSAEINVAL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
p->Hostent->h_addrtype = AF_INET;
|
||||||
|
|
||||||
|
p->Hostent->h_addr_list = HeapAlloc(GlobalHeap, 0, sizeof(char *));
|
||||||
|
if( !p->Hostent->h_addr_list )
|
||||||
|
{
|
||||||
|
WSASetLastError( WSATRY_AGAIN );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Address = inet_addr(AddressStr);
|
||||||
|
if (Address == INADDR_NONE)
|
||||||
|
{
|
||||||
|
WSASetLastError(WSAEINVAL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->Hostent->h_addr_list[0] = HeapAlloc(GlobalHeap, 0, sizeof(Address));
|
||||||
|
if( !p->Hostent->h_addr_list[0] )
|
||||||
|
{
|
||||||
|
WSASetLastError( WSATRY_AGAIN );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlCopyMemory(p->Hostent->h_addr_list[0],
|
||||||
|
&Address,
|
||||||
|
sizeof(Address));
|
||||||
|
|
||||||
|
p->Hostent->h_length = sizeof(Address);
|
||||||
|
|
||||||
|
return p->Hostent;
|
||||||
|
}
|
||||||
|
|
||||||
LPHOSTENT
|
LPHOSTENT
|
||||||
EXPORT
|
EXPORT
|
||||||
|
@ -661,6 +853,7 @@ gethostbyname(IN CONST CHAR FAR* name)
|
||||||
/* include/WinDNS.h -- look up DNS_RECORD on MSDN */
|
/* include/WinDNS.h -- look up DNS_RECORD on MSDN */
|
||||||
PDNS_RECORD dp = 0;
|
PDNS_RECORD dp = 0;
|
||||||
PWINSOCK_THREAD_BLOCK p;
|
PWINSOCK_THREAD_BLOCK p;
|
||||||
|
LPHOSTENT Hostent;
|
||||||
|
|
||||||
addr = GH_INVALID;
|
addr = GH_INVALID;
|
||||||
|
|
||||||
|
@ -726,6 +919,12 @@ gethostbyname(IN CONST CHAR FAR* name)
|
||||||
case GH_RFC1123_DNS:
|
case GH_RFC1123_DNS:
|
||||||
/* DNS_TYPE_A: include/WinDNS.h */
|
/* DNS_TYPE_A: include/WinDNS.h */
|
||||||
/* DnsQuery -- lib/dnsapi/dnsapi/query.c */
|
/* DnsQuery -- lib/dnsapi/dnsapi/query.c */
|
||||||
|
|
||||||
|
/* Look for the DNS name in the hosts file */
|
||||||
|
Hostent = FindEntryInHosts(name);
|
||||||
|
if (Hostent)
|
||||||
|
return Hostent;
|
||||||
|
|
||||||
dns_status = DnsQuery_A(name,
|
dns_status = DnsQuery_A(name,
|
||||||
DNS_TYPE_A,
|
DNS_TYPE_A,
|
||||||
DNS_QUERY_STANDARD,
|
DNS_QUERY_STANDARD,
|
||||||
|
@ -993,7 +1192,7 @@ getservbyname(IN CONST CHAR FAR* name,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zero and skip, so we can treat what we have as a string */
|
/* Zero and skip, so we can treat what we have as a string */
|
||||||
if( NextLine >= ServiceDBData + ValidData )
|
if( NextLine > ServiceDBData + ValidData )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
*NextLine = 0; NextLine++;
|
*NextLine = 0; NextLine++;
|
||||||
|
@ -1174,7 +1373,7 @@ getservbyport(IN INT port,
|
||||||
*NextLine != '\r' && *NextLine != '\n' ) NextLine++;
|
*NextLine != '\r' && *NextLine != '\n' ) NextLine++;
|
||||||
|
|
||||||
/* Zero and skip, so we can treat what we have as a string */
|
/* Zero and skip, so we can treat what we have as a string */
|
||||||
if( NextLine >= ServiceDBData + ValidData )
|
if( NextLine > ServiceDBData + ValidData )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
*NextLine = 0; NextLine++;
|
*NextLine = 0; NextLine++;
|
||||||
|
|
Loading…
Reference in a new issue