⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ns.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
#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 + -