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);
|
||||
}
|
||||
|
||||
/* 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
|
||||
EXPORT
|
||||
|
@ -661,6 +853,7 @@ gethostbyname(IN CONST CHAR FAR* name)
|
|||
/* include/WinDNS.h -- look up DNS_RECORD on MSDN */
|
||||
PDNS_RECORD dp = 0;
|
||||
PWINSOCK_THREAD_BLOCK p;
|
||||
LPHOSTENT Hostent;
|
||||
|
||||
addr = GH_INVALID;
|
||||
|
||||
|
@ -726,6 +919,12 @@ gethostbyname(IN CONST CHAR FAR* name)
|
|||
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 */
|
||||
Hostent = FindEntryInHosts(name);
|
||||
if (Hostent)
|
||||
return Hostent;
|
||||
|
||||
dns_status = DnsQuery_A(name,
|
||||
DNS_TYPE_A,
|
||||
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 */
|
||||
if( NextLine >= ServiceDBData + ValidData )
|
||||
if( NextLine > ServiceDBData + ValidData )
|
||||
break;
|
||||
|
||||
*NextLine = 0; NextLine++;
|
||||
|
@ -1174,7 +1373,7 @@ getservbyport(IN INT port,
|
|||
*NextLine != '\r' && *NextLine != '\n' ) NextLine++;
|
||||
|
||||
/* Zero and skip, so we can treat what we have as a string */
|
||||
if( NextLine >= ServiceDBData + ValidData )
|
||||
if( NextLine > ServiceDBData + ValidData )
|
||||
break;
|
||||
|
||||
*NextLine = 0; NextLine++;
|
||||
|
|
Loading…
Reference in a new issue