📄 ns.c
字号:
#define ADJ_PTR(p,b1,b2) p = (p - b1) + b2
/*
* @implemented
*/
LPSERVENT
EXPORT
getservbyname(IN CONST CHAR FAR* name,
IN CONST CHAR FAR* proto)
{
BOOL Found = FALSE;
HANDLE ServicesFile;
CHAR ServiceDBData[BUFSIZ] = { 0 };
PCHAR SystemDirectory = ServiceDBData; /* Reuse this stack space */
PCHAR ServicesFileLocation = "\\drivers\\etc\\services";
PCHAR ThisLine = 0, NextLine = 0, ServiceName = 0, PortNumberStr = 0,
ProtocolStr = 0, Comment = 0;
PCHAR Aliases[WS2_INTERNAL_MAX_ALIAS] = { 0 };
UINT i,SizeNeeded = 0,
SystemDirSize = sizeof(ServiceDBData) - 1;
DWORD ReadSize = 0, ValidData = 0;
PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;
if( !p )
{
WSASetLastError( WSANOTINITIALISED );
return NULL;
}
if( !name )
{
WSASetLastError( WSANO_RECOVERY );
return NULL;
}
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,
ServicesFileLocation,
SystemDirSize );
ServicesFile = CreateFileA(SystemDirectory,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
NULL );
if( ServicesFile == INVALID_HANDLE_VALUE )
{
WSASetLastError( WSANO_RECOVERY );
return NULL;
}
/* Scan the services file ...
*
* We will read up to BUFSIZ bytes per pass, until the buffer does not
* contain a full line, then we will try to read more.
*
* We fall from the loop if the buffer does not have a line terminator.
*/
/* Initial Read */
while(!Found &&
ReadFile(ServicesFile,
ServiceDBData + ValidData,
sizeof( ServiceDBData ) - ValidData,
&ReadSize,
NULL))
{
ValidData += ReadSize;
ReadSize = 0;
NextLine = ThisLine = ServiceDBData;
/* Find the beginning of the next line */
while(NextLine < ServiceDBData + ValidData &&
*NextLine != '\r' && *NextLine != '\n' )
{
NextLine++;
}
/* Zero and skip, so we can treat what we have as a string */
if( NextLine >= ServiceDBData + ValidData )
break;
*NextLine = 0; NextLine++;
Comment = strchr( ThisLine, '#' );
if( Comment ) *Comment = 0; /* Terminate at comment start */
if(DecodeServEntFromString(ThisLine,
&ServiceName,
&PortNumberStr,
&ProtocolStr,
Aliases,
WS2_INTERNAL_MAX_ALIAS) &&
!strcmp( ServiceName, name ) &&
(proto ? !strcmp( ProtocolStr, proto ) : TRUE) )
{
WS_DbgPrint(MAX_TRACE,("Found the service entry.\n"));
Found = TRUE;
SizeNeeded = sizeof(WINSOCK_GETSERVBYNAME_CACHE) +
(NextLine - ThisLine);
break;
}
/* Get rid of everything we read so far */
while( NextLine <= ServiceDBData + ValidData &&
isspace( *NextLine ) )
{
NextLine++;
}
WS_DbgPrint(MAX_TRACE,("About to move %d chars\n",
ServiceDBData + ValidData - NextLine));
memmove(ServiceDBData,
NextLine,
ServiceDBData + ValidData - NextLine );
ValidData -= NextLine - ServiceDBData;
WS_DbgPrint(MAX_TRACE,("Valid bytes: %d\n", ValidData));
}
/* This we'll do no matter what */
CloseHandle( ServicesFile );
if( !Found )
{
WS_DbgPrint(MAX_TRACE,("Not found\n"));
WSASetLastError( WSANO_DATA );
return NULL;
}
if( !p->Getservbyname || p->Getservbyname->Size < SizeNeeded )
{
/* Free previous getservbyname buffer, allocate bigger */
if( p->Getservbyname )
HeapFree(GlobalHeap, 0, p->Getservbyname);
p->Getservbyname = HeapAlloc(GlobalHeap, 0, SizeNeeded);
if( !p->Getservbyname )
{
WS_DbgPrint(MIN_TRACE,("Couldn't allocate %d bytes\n",
SizeNeeded));
WSASetLastError( WSATRY_AGAIN );
return NULL;
}
p->Getservbyname->Size = SizeNeeded;
}
/* Copy the data */
memmove(p->Getservbyname->Data,
ThisLine,
NextLine - ThisLine );
ADJ_PTR(ServiceName,ThisLine,p->Getservbyname->Data);
ADJ_PTR(ProtocolStr,ThisLine,p->Getservbyname->Data);
WS_DbgPrint(MAX_TRACE, ("ServiceName: %s, Protocol: %s\n",
ServiceName,
ProtocolStr));
for( i = 0; Aliases[i]; i++ )
{
ADJ_PTR(Aliases[i],ThisLine,p->Getservbyname->Data);
WS_DbgPrint(MAX_TRACE,("Aliase %d: %s\n", i, Aliases[i]));
}
memcpy(p->Getservbyname,
Aliases,
sizeof(Aliases));
/* Create the struct proper */
p->Getservbyname->ServerEntry.s_name = ServiceName;
p->Getservbyname->ServerEntry.s_aliases = p->Getservbyname->Aliases;
p->Getservbyname->ServerEntry.s_port = htons(atoi(PortNumberStr));
p->Getservbyname->ServerEntry.s_proto = ProtocolStr;
return &p->Getservbyname->ServerEntry;
}
/*
* @implemented
*/
LPSERVENT
EXPORT
getservbyport(IN INT port,
IN CONST CHAR FAR* proto)
{
BOOL Found = FALSE;
HANDLE ServicesFile;
CHAR ServiceDBData[BUFSIZ] = { 0 };
PCHAR SystemDirectory = ServiceDBData; /* Reuse this stack space */
PCHAR ServicesFileLocation = "\\drivers\\etc\\services";
PCHAR ThisLine = 0, NextLine = 0, ServiceName = 0, PortNumberStr = 0,
ProtocolStr = 0, Comment = 0;
PCHAR Aliases[WS2_INTERNAL_MAX_ALIAS] = { 0 };
UINT i,SizeNeeded = 0,
SystemDirSize = sizeof(ServiceDBData) - 1;
DWORD ReadSize = 0, ValidData = 0;
PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;
if( !p )
{
WSASetLastError( WSANOTINITIALISED );
return NULL;
}
if ( !port )
{
WSASetLastError( WSANO_RECOVERY );
return NULL;
}
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,
ServicesFileLocation,
SystemDirSize );
ServicesFile = CreateFileA(SystemDirectory,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
NULL );
if( ServicesFile == INVALID_HANDLE_VALUE )
{
WSASetLastError( WSANO_RECOVERY );
return NULL;
}
/* Scan the services file ...
*
* We will read up to BUFSIZ bytes per pass, until the buffer does not
* contain a full line, then we will try to read more.
*
* We fall from the loop if the buffer does not have a line terminator.
*/
/* Initial Read */
while(!Found &&
ReadFile(ServicesFile,
ServiceDBData + ValidData,
sizeof( ServiceDBData ) - ValidData,
&ReadSize, NULL ) )
{
ValidData += ReadSize;
ReadSize = 0;
NextLine = ThisLine = ServiceDBData;
/* Find the beginning of the next line */
while( NextLine < ServiceDBData + ValidData &&
*NextLine != '\r' && *NextLine != '\n' ) NextLine++;
/* Zero and skip, so we can treat what we have as a string */
if( NextLine >= ServiceDBData + ValidData )
break;
*NextLine = 0; NextLine++;
Comment = strchr( ThisLine, '#' );
if( Comment ) *Comment = 0; /* Terminate at comment start */
if(DecodeServEntFromString(ThisLine,
&ServiceName,
&PortNumberStr,
&ProtocolStr,
Aliases,
WS2_INTERNAL_MAX_ALIAS ) &&
(htons(atoi( PortNumberStr )) == port ) &&
(proto ? !strcmp( ProtocolStr, proto ) : TRUE) )
{
WS_DbgPrint(MAX_TRACE,("Found the port entry.\n"));
Found = TRUE;
SizeNeeded = sizeof(WINSOCK_GETSERVBYPORT_CACHE) +
(NextLine - ThisLine);
break;
}
/* Get rid of everything we read so far */
while( NextLine <= ServiceDBData + ValidData &&
isspace( *NextLine ) )
{
NextLine++;
}
WS_DbgPrint(MAX_TRACE,("About to move %d chars\n",
ServiceDBData + ValidData - NextLine));
memmove(ServiceDBData,
NextLine,
ServiceDBData + ValidData - NextLine );
ValidData -= NextLine - ServiceDBData;
WS_DbgPrint(MAX_TRACE,("Valid bytes: %d\n", ValidData));
}
/* This we'll do no matter what */
CloseHandle( ServicesFile );
if( !Found )
{
WS_DbgPrint(MAX_TRACE,("Not found\n"));
WSASetLastError( WSANO_DATA );
return NULL;
}
if( !p->Getservbyport || p->Getservbyport->Size < SizeNeeded )
{
/* Free previous getservbyport buffer, allocate bigger */
if( p->Getservbyport )
HeapFree(GlobalHeap, 0, p->Getservbyport);
p->Getservbyport = HeapAlloc(GlobalHeap,
0,
SizeNeeded);
if( !p->Getservbyport )
{
WS_DbgPrint(MIN_TRACE,("Couldn't allocate %d bytes\n",
SizeNeeded));
WSASetLastError( WSATRY_AGAIN );
return NULL;
}
p->Getservbyport->Size = SizeNeeded;
}
/* Copy the data */
memmove(p->Getservbyport->Data,
ThisLine,
NextLine - ThisLine );
ADJ_PTR(PortNumberStr,ThisLine,p->Getservbyport->Data);
ADJ_PTR(ProtocolStr,ThisLine,p->Getservbyport->Data);
WS_DbgPrint(MAX_TRACE, ("Port Number: %s, Protocol: %s\n",
PortNumberStr, ProtocolStr));
for( i = 0; Aliases[i]; i++ )
{
ADJ_PTR(Aliases[i],ThisLine,p->Getservbyport->Data);
WS_DbgPrint(MAX_TRACE,("Aliases %d: %s\n", i, Aliases[i]));
}
memcpy(p->Getservbyport,Aliases,sizeof(Aliases));
/* Create the struct proper */
p->Getservbyport->ServerEntry.s_name = ServiceName;
p->Getservbyport->ServerEntry.s_aliases = p->Getservbyport->Aliases;
p->Getservbyport->ServerEntry.s_port = port;
p->Getservbyport->ServerEntry.s_proto = ProtocolStr;
WS_DbgPrint(MID_TRACE,("s_name: %s\n", ServiceName));
return &p->Getservbyport->ServerEntry;
}
/*
* @implemented
*/
ULONG
EXPORT
inet_addr(IN CONST CHAR FAR* cp)
/*
* FUNCTION: Converts a string containing an IPv4 address to an unsigned long
* ARGUMENTS:
* cp = Pointer to string with address to convert
* RETURNS:
* Binary representation of IPv4 address, or INADDR_NONE
*/
{
UINT i;
PCHAR p;
ULONG u = 0;
p = (PCHAR)cp;
if (strlen(p) == 0)
return INADDR_NONE;
if (strcmp(p, " ") == 0)
return 0;
for (i = 0; i <= 3; i++)
{
u += (strtoul(p, &p, 0) << (i * 8));
if (strlen(p) == 0)
return u;
if (p[0] != '.')
return INADDR_NONE;
p++;
}
return u;
}
/*
* @implemented
*/
CHAR FAR*
EXPORT
inet_ntoa(IN IN_ADDR in)
{
CHAR b[10];
PCHAR p;
p = ((PWINSOCK_THREAD_BLOCK)NtCurrentTeb()->WinSockData)->Intoa;
_itoa(in.S_un.S_addr & 0xFF, b, 10);
strcpy(p, b);
_itoa((in.S_un.S_addr >> 8) & 0xFF, b, 10);
strcat(p, ".");
strcat(p, b);
_itoa((in.S_un.S_addr >> 16) & 0xFF, b, 10);
strcat(p, ".");
strcat(p, b);
_itoa((in.S_un.S_addr >> 24) & 0xFF, b, 10);
strcat(p, ".");
strcat(p, b);
return (CHAR FAR*)p;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -