Пример #1
0
PCATALOG_ENTRY
LocateProviderById(DWORD CatalogEntryId)
{
    PLIST_ENTRY CurrentEntry;
    PCATALOG_ENTRY Provider;

    WS_DbgPrint(MAX_TRACE, ("CatalogEntryId (%d).\n", CatalogEntryId));

    //EnterCriticalSection(&CatalogLock);
    CurrentEntry = CatalogListHead.Flink;
    while (CurrentEntry != &CatalogListHead)
    {
        Provider = CONTAINING_RECORD(CurrentEntry,
                                     CATALOG_ENTRY,
                                     ListEntry);

        if (Provider->ProtocolInfo.dwCatalogEntryId == CatalogEntryId)
        {
            //LeaveCriticalSection(&CatalogLock);
            WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X)  Name (%wZ).\n",
                        Provider, &Provider->LibraryName));
            return Provider;
        }

        CurrentEntry = CurrentEntry->Flink;
    }
    //LeaveCriticalSection(&CatalogLock);

    WS_DbgPrint(MID_TRACE, ("Provider was not found.\n"));

    return NULL;
}
Пример #2
0
VOID
DereferenceProviderByPointer(PCATALOG_ENTRY Provider)
{
    WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));

#if DBG
    if (Provider->ReferenceCount <= 0)
    {
        WS_DbgPrint(MIN_TRACE, ("Provider at 0x%X has invalid reference count (%ld).\n",
                    Provider, Provider->ReferenceCount));
    }
#endif

    //EnterCriticalSection(&Provider->Lock);
    Provider->ReferenceCount--;
    //LeaveCriticalSection(&Provider->Lock);

    if (Provider->ReferenceCount == 0)
    {
        WS_DbgPrint(MAX_TRACE, ("Provider at 0x%X has reference count 0 (unloading).\n",
                    Provider));

        DestroyCatalogEntry(Provider);
    }
}
Пример #3
0
INT
UnloadProvider(PCATALOG_ENTRY Provider)
{
    INT Status = NO_ERROR;

    WS_DbgPrint(MAX_TRACE, ("Unloading provider at (0x%X)\n", Provider));

    if (NULL != Provider->hModule)
    {
        WS_DbgPrint(MAX_TRACE, ("Calling WSPCleanup at (0x%X).\n",
        Provider->ProcTable.lpWSPCleanup));
        Provider->ProcTable.lpWSPCleanup(&Status);

        WS_DbgPrint(MAX_TRACE, ("Calling FreeLibrary(0x%X).\n", Provider->hModule));
        if (!FreeLibrary(Provider->hModule))
        {
            WS_DbgPrint(MIN_TRACE, ("Could not free library at (0x%X).\n", Provider->hModule));
            Status = GetLastError();
        }

        Provider->hModule = NULL;
    }

    WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));

    return Status;
}
Пример #4
0
BOOL
ReferenceProviderByHandle(HANDLE Handle,
                          PCATALOG_ENTRY* Provider)
/*
 * FUNCTION: Increments the reference count for a provider and returns a pointer to it
 * ARGUMENTS:
 *     Handle   = Handle for the provider
 *     Provider = Address of buffer to place pointer to provider
 * RETURNS:
 *     TRUE if handle was valid, FALSE if not
 */
{
    PPROVIDER_HANDLE ProviderHandle;

    WS_DbgPrint(MID_TRACE, ("Handle (0x%X)  Provider (0x%X).\n", Handle, Provider));

    EnterCriticalSection(&ProviderHandleTableLock);

    ProviderHandle = GetProviderByHandle(ProviderHandleTable,
                                         Handle);

    WS_DbgPrint(MID_TRACE, ("ProviderHandle is %x\n", ProviderHandle));

    LeaveCriticalSection(&ProviderHandleTableLock);

    if (ProviderHandle)
    {
        ReferenceProviderByPointer(ProviderHandle->Provider);
        *Provider = ProviderHandle->Provider;
    }

    return (ProviderHandle != NULL);
}
Пример #5
0
/*
 * @implemented
 */
SOCKET
EXPORT
WSAAccept(IN     SOCKET s,
          OUT    LPSOCKADDR addr,
          IN OUT LPINT addrlen,
          IN     LPCONDITIONPROC lpfnCondition,
          IN     DWORD_PTR dwCallbackData)
{
    PCATALOG_ENTRY Provider;
    SOCKET Socket;
    INT Errno;

    if (!WSAINITIALIZED)
    {
        WSASetLastError(WSANOTINITIALISED);
        return SOCKET_ERROR;
    }

    if (!ReferenceProviderByHandle((HANDLE)s, &Provider))
    {
        WSASetLastError(WSAENOTSOCK);
        return SOCKET_ERROR;
    }

    WS_DbgPrint(MAX_TRACE,("Calling provider accept\n"));

    Socket = Provider->ProcTable.lpWSPAccept(s,
                                             addr,
                                             addrlen,
                                             lpfnCondition,
                                             dwCallbackData,
                                             &Errno);

    WS_DbgPrint(MAX_TRACE,("Calling provider accept -> Socket %x, Errno %x\n",
                Socket, Errno));

    DereferenceProviderByPointer(Provider);

    if (Socket == INVALID_SOCKET)
        WSASetLastError(Errno);

    if ( addr && addrlen )
    {
#if DBG
        LPSOCKADDR_IN sa = (LPSOCKADDR_IN)addr;
        WS_DbgPrint(MAX_TRACE,("Returned address: %d %s:%d (len %d)\n",
                               sa->sin_family,
                               inet_ntoa(sa->sin_addr),
                               ntohs(sa->sin_port),
                               *addrlen));
#endif
    }

    return Socket;
}
Пример #6
0
VOID
ReferenceProviderByPointer(PCATALOG_ENTRY Provider)
{
    WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));

    //EnterCriticalSection(&Provider->Lock);
    Provider->ReferenceCount++;
    //LeaveCriticalSection(&Provider->Lock);

    WS_DbgPrint(MAX_TRACE, ("Leaving\n"));
}
Пример #7
0
HANDLE
CreateProviderHandleTable(PPROVIDER_HANDLE_BLOCK HandleTable,
                          HANDLE Handle,
                          PCATALOG_ENTRY Provider)
{
    PPROVIDER_HANDLE_BLOCK NewBlock;
    PLIST_ENTRY CurrentEntry;
    ULONG i;

    WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X)  Handle (0x%X)  Provider (0x%X).\n",
    HandleTable, Handle, Provider));

    /* Scan through the currently allocated handle blocks looking for a free slot */
    CurrentEntry = HandleTable->Entry.Flink;
    while (CurrentEntry != &HandleTable->Entry)
    {
        PPROVIDER_HANDLE_BLOCK Block = CONTAINING_RECORD(CurrentEntry,
                                                         PROVIDER_HANDLE_BLOCK,
                                                         Entry);

        for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
        {
            WS_DbgPrint(MAX_TRACE, ("Considering slot %ld containing 0x%X.\n",
                        i,
                        Block->Handles[i].Provider));
            if (Block->Handles[i].Provider == NULL)
            {
                Block->Handles[i].Handle   = Handle;
                Block->Handles[i].Provider = Provider;
                return Handle;
            }
        }
        CurrentEntry = CurrentEntry->Flink;
    }

    /* Add a new handle block to the end of the list */
    NewBlock = (PPROVIDER_HANDLE_BLOCK)HeapAlloc(GlobalHeap,
                                                 0,
                                                 sizeof(PROVIDER_HANDLE_BLOCK));

    WS_DbgPrint(MID_TRACE,("using table entry %x\n", NewBlock));

    if (!NewBlock)
        return (HANDLE)0;

    ZeroMemory(NewBlock, sizeof(PROVIDER_HANDLE_BLOCK));
    InsertTailList(&HandleTable->Entry,
                   &NewBlock->Entry);

    NewBlock->Handles[0].Handle   = Handle;
    NewBlock->Handles[0].Provider = Provider;

    return Handle;
}
Пример #8
0
/*
 * @implemented
 */
INT
EXPORT
WSAEnumNetworkEvents(IN  SOCKET s,
                     IN  WSAEVENT hEventObject,
                     OUT LPWSANETWORKEVENTS lpNetworkEvents)
{
    PCATALOG_ENTRY Provider;
    INT Status;
    INT Errno;

    WS_DbgPrint(MID_TRACE,("Called (Socket %x, hEventObject %x, "
                "lpNetworkEvents %x)\n",
                s,
                hEventObject,
                lpNetworkEvents));

    if (!lpNetworkEvents)
    {
        WSASetLastError(WSAEINVAL);
        return SOCKET_ERROR;
    }

    if (!WSAINITIALIZED)
    {
        WSASetLastError(WSANOTINITIALISED);
        return SOCKET_ERROR;
    }

    if (!ReferenceProviderByHandle((HANDLE)s,
                                   &Provider))
    {
        WSASetLastError(WSAENOTSOCK);
        return SOCKET_ERROR;
    }

    Status = Provider->ProcTable.lpWSPEnumNetworkEvents(s,
                                                        hEventObject,
                                                        lpNetworkEvents,
                                                        &Errno);

    DereferenceProviderByPointer(Provider);

    if (Status == SOCKET_ERROR)
        WSASetLastError(Errno);

    WS_DbgPrint(MID_TRACE,("Leaving %x\n", Status));

    return Status;
}
Пример #9
0
/*
 * @implemented
 */
INT
EXPORT
closesocket(IN  SOCKET s)
/*
 * FUNCTION: Closes a socket descriptor
 * ARGUMENTS:
 *     s = Socket descriptor
 * RETURNS:
 *     0, or SOCKET_ERROR if an error ocurred
 */
{
    PCATALOG_ENTRY Provider;
    INT Status;
    INT Errno;

    WS_DbgPrint(MAX_TRACE, ("s (0x%X).\n", s));

    if (!WSAINITIALIZED)
    {
        WSASetLastError(WSANOTINITIALISED);
        return SOCKET_ERROR;
    }

    if (!ReferenceProviderByHandle((HANDLE)s, &Provider))
    {
        WSASetLastError(WSAENOTSOCK);
        return SOCKET_ERROR;
    }

    CloseProviderHandle((HANDLE)s);

    WS_DbgPrint(MAX_TRACE,("DereferenceProviderByHandle\n"));

    DereferenceProviderByPointer(Provider);

    WS_DbgPrint(MAX_TRACE,("DereferenceProviderByHandle Done\n"));

    Status = Provider->ProcTable.lpWSPCloseSocket(s, &Errno);

    WS_DbgPrint(MAX_TRACE,("Provider Close Done\n"));

    if (Status == SOCKET_ERROR)
        WSASetLastError(Errno);

    WS_DbgPrint(MAX_TRACE,("Returning success\n"));

    return 0;
}
Пример #10
0
VOID
CloseAllHandles(PPROVIDER_HANDLE_BLOCK HandleTable)
{
    PPROVIDER_HANDLE_BLOCK Current;
    PLIST_ENTRY CurrentEntry;
    PCATALOG_ENTRY Provider;
    ULONG i;

    WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X).\n", HandleTable));

    CurrentEntry = HandleTable->Entry.Flink;

    while (CurrentEntry != &HandleTable->Entry)
    {
        Current = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);

        for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
        {
            Provider = Current->Handles[i].Provider;
            if (Provider != NULL)
            {
                DereferenceProviderByPointer(Provider);
                Current->Handles[i].Handle   = (HANDLE)0;
                Current->Handles[i].Provider = NULL;
            }
        }
        CurrentEntry = CurrentEntry->Flink;
    }
}
Пример #11
0
VOID
CreateCatalog(VOID)
{
    PCATALOG_ENTRY Provider;

    InitializeCriticalSection(&CatalogLock);

    InitializeListHead(&CatalogListHead);

    /* FIXME: Read service provider catalog from registry

    Catalog info is saved somewhere under
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinSock2
    */

#if 1
    Provider = CreateCatalogEntry(L"msafd.dll");
    if (!Provider)
    {
        WS_DbgPrint(MIN_TRACE, ("Could not create catalog entry.\n"));
        return;
    }

    /* Assume one Service Provider with id 1 */
    Provider->ProtocolInfo.dwCatalogEntryId = 1;

    Provider->Mapping = HeapAlloc(GlobalHeap,
                                  0,
                                  6 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
    if (!Provider->Mapping)
        return;

    Provider->Mapping->Rows    = 6;
    Provider->Mapping->Columns = 3;

    Provider->Mapping->Mapping[0].AddressFamily = AF_INET;
    Provider->Mapping->Mapping[0].SocketType    = SOCK_STREAM;
    Provider->Mapping->Mapping[0].Protocol      = 0;

    Provider->Mapping->Mapping[1].AddressFamily = AF_INET;
    Provider->Mapping->Mapping[1].SocketType    = SOCK_STREAM;
    Provider->Mapping->Mapping[1].Protocol      = IPPROTO_TCP;

    Provider->Mapping->Mapping[2].AddressFamily = AF_INET;
    Provider->Mapping->Mapping[2].SocketType    = SOCK_DGRAM;
    Provider->Mapping->Mapping[2].Protocol      = 0;

    Provider->Mapping->Mapping[3].AddressFamily = AF_INET;
    Provider->Mapping->Mapping[3].SocketType    = SOCK_DGRAM;
    Provider->Mapping->Mapping[3].Protocol      = IPPROTO_UDP;

    Provider->Mapping->Mapping[4].AddressFamily = AF_INET;
    Provider->Mapping->Mapping[4].SocketType    = SOCK_RAW;
    Provider->Mapping->Mapping[4].Protocol      = IPPROTO_ICMP;

    Provider->Mapping->Mapping[5].AddressFamily = AF_INET;
    Provider->Mapping->Mapping[5].SocketType    = SOCK_RAW;
    Provider->Mapping->Mapping[5].Protocol      = 0;
#endif
}
Пример #12
0
PCATALOG_ENTRY
CreateCatalogEntry(LPWSTR LibraryName)
{
    PCATALOG_ENTRY Provider;

    WS_DbgPrint(MAX_TRACE, ("LibraryName (%S).\n", LibraryName));

    Provider = HeapAlloc(GlobalHeap, 0, sizeof(CATALOG_ENTRY));
    if (!Provider)
        return NULL;

    ZeroMemory(Provider, sizeof(CATALOG_ENTRY));

    if (!RtlCreateUnicodeString(&Provider->LibraryName, LibraryName))
    {
        RtlFreeHeap(GlobalHeap, 0, Provider);
        return NULL;
    }

    Provider->ReferenceCount = 1;

    InitializeCriticalSection(&Provider->Lock);
    Provider->hModule = NULL;

    Provider->Mapping = NULL;

    //EnterCriticalSection(&CatalogLock);

    InsertTailList(&CatalogListHead, &Provider->ListEntry);

    //LeaveCriticalSection(&CatalogLock);

    return Provider;
}
Пример #13
0
INT
DestroyCatalogEntry(PCATALOG_ENTRY Provider)
{
    INT Status;

    WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));

    //EnterCriticalSection(&CatalogLock);
    RemoveEntryList(&Provider->ListEntry);
    //LeaveCriticalSection(&CatalogLock);

    HeapFree(GlobalHeap, 0, Provider->Mapping);

    if (NULL != Provider->hModule)
    {
        Status = UnloadProvider(Provider);
    }
    else
    {
        Status = NO_ERROR;
    }

    //DeleteCriticalSection(&Provider->Lock);

    HeapFree(GlobalHeap, 0, Provider);

    return Status;
}
Пример #14
0
INT
LoadProvider(PCATALOG_ENTRY Provider,
             LPWSAPROTOCOL_INFOW lpProtocolInfo)
{
    INT Status;

    WS_DbgPrint(MID_TRACE, ("Loading provider at (0x%X)  Name (%wZ).\n",
                Provider, &Provider->LibraryName));

    if (NULL == Provider->hModule)
    {
        /* DLL is not loaded so load it now
         * UNICODE_STRING objects are not null-terminated, but LoadLibraryW
         * expects a null-terminated string
         */
        Provider->LibraryName.Buffer[Provider->LibraryName.Length / sizeof(WCHAR)] = L'\0';
        Provider->hModule = LoadLibraryW(Provider->LibraryName.Buffer);
        if (NULL != Provider->hModule)
        {
            Provider->WSPStartup = (LPWSPSTARTUP)GetProcAddress(Provider->hModule,
                                                                "WSPStartup");
            if (Provider->WSPStartup)
            {
                WS_DbgPrint(MAX_TRACE, ("Calling WSPStartup at (0x%X).\n",
                            Provider->WSPStartup));
                Status = Provider->WSPStartup(MAKEWORD(2, 2),
                                              &Provider->WSPData,
                                              lpProtocolInfo,
                                              UpcallTable,
                                              &Provider->ProcTable);

                /* FIXME: Validate the procedure table */
            }
            else
                Status = ERROR_BAD_PROVIDER;
        }
        else
            Status = ERROR_DLL_NOT_FOUND;
    }
    else
        Status = NO_ERROR;

    WS_DbgPrint(MID_TRACE, ("Status (%d).\n", Status));

    return Status;
}
Пример #15
0
PCATALOG_ENTRY
LocateProvider(LPWSAPROTOCOL_INFOW lpProtocolInfo)
{
    PLIST_ENTRY CurrentEntry;
    PCATALOG_ENTRY Provider;
    UINT i;

    WS_DbgPrint(MAX_TRACE, ("lpProtocolInfo (0x%X).\n", lpProtocolInfo));

    //EnterCriticalSection(&CatalogLock);

    CurrentEntry = CatalogListHead.Flink;
    while (CurrentEntry != &CatalogListHead)
    {
        Provider = CONTAINING_RECORD(CurrentEntry,
                                     CATALOG_ENTRY,
                                     ListEntry);

        for (i = 0; i < Provider->Mapping->Rows; i++)
        {
            if ((lpProtocolInfo->iAddressFamily == (INT) Provider->Mapping->Mapping[i].AddressFamily) &&
                (lpProtocolInfo->iSocketType    == (INT) Provider->Mapping->Mapping[i].SocketType) &&
                ((lpProtocolInfo->iProtocol     == (INT) Provider->Mapping->Mapping[i].Protocol) ||
                (lpProtocolInfo->iSocketType    == SOCK_RAW)))
            {
                //LeaveCriticalSection(&CatalogLock);
                lpProtocolInfo->dwCatalogEntryId = Provider->ProtocolInfo.dwCatalogEntryId;
                WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X).\n", Provider));
                return Provider;
            }
        }

        CurrentEntry = CurrentEntry->Flink;
    }

    //LeaveCriticalSection(&CatalogLock);

    return NULL;
}
Пример #16
0
/*
 * @implemented
 */
INT
EXPORT
WSACleanup(VOID)
{
    WS_DbgPrint(MAX_TRACE, ("WSACleanup of ws2_32.dll\n"));

    if (!WSAINITIALIZED)
    {
        WSASetLastError(WSANOTINITIALISED);
        return WSANOTINITIALISED;
    }

    return NO_ERROR;
}
Пример #17
0
PCATALOG_ENTRY
DeleteProviderHandle(PPROVIDER_HANDLE_BLOCK HandleTable,
                     HANDLE Handle)
{
    PPROVIDER_HANDLE Entry;
    PCATALOG_ENTRY Provider;

    WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X)  Handle (0x%X).\n", HandleTable, Handle));

    Entry = GetProviderByHandle(HandleTable, Handle);
    if (!Entry)
        return NULL;

    Provider = Entry->Provider;
    Entry->Handle = (HANDLE)0;
    Entry->Provider = NULL;

    return Provider;
}
Пример #18
0
/*
 * @implemented
 */
SOCKET
EXPORT
WSASocketA(IN  INT af,
           IN  INT type,
           IN  INT protocol,
           IN  LPWSAPROTOCOL_INFOA lpProtocolInfo,
           IN  GROUP g,
           IN  DWORD dwFlags)
/*
 * FUNCTION: Creates a new socket
 */
{
    WSAPROTOCOL_INFOW ProtocolInfoW;
    LPWSAPROTOCOL_INFOW p;
    UNICODE_STRING StringU;
    ANSI_STRING StringA;

    WS_DbgPrint(MAX_TRACE, ("af (%d)  type (%d)  protocol (%d).\n",
    af, type, protocol));

    if (lpProtocolInfo)
    {
        memcpy(&ProtocolInfoW,
               lpProtocolInfo,
               sizeof(WSAPROTOCOL_INFOA) - sizeof(CHAR) * (WSAPROTOCOL_LEN + 1));
        RtlInitAnsiString(&StringA, (LPSTR)lpProtocolInfo->szProtocol);
        RtlInitUnicodeString(&StringU, (LPWSTR)&ProtocolInfoW.szProtocol);
        RtlAnsiStringToUnicodeString(&StringU, &StringA, FALSE);
        p = &ProtocolInfoW;
    }
    else
    {
        p = NULL;
    }

    return WSASocketW(af,
                      type,
                      protocol,
                      p,
                      g,
                      dwFlags);
}
Пример #19
0
BOOL
CloseProviderHandle(HANDLE Handle)
{
    PCATALOG_ENTRY Provider;

    WS_DbgPrint(MAX_TRACE, ("Handle (0x%X).\n", Handle));

    EnterCriticalSection(&ProviderHandleTableLock);

    Provider = DeleteProviderHandle(ProviderHandleTable,
                                    Handle);

    LeaveCriticalSection(&ProviderHandleTableLock);

    if (!Provider)
        return FALSE;

    DereferenceProviderByPointer(Provider);

    return TRUE;
}
Пример #20
0
BOOL
InitProviderHandleTable(VOID)
{
    ProviderHandleTable =
        (PPROVIDER_HANDLE_BLOCK)HeapAlloc(GlobalHeap,
                                          0,
                                          sizeof(PROVIDER_HANDLE_BLOCK));
    if (!ProviderHandleTable)
        return FALSE;

    WS_DbgPrint(MID_TRACE,("Called\n"));

    ZeroMemory(ProviderHandleTable,
               sizeof(PROVIDER_HANDLE_BLOCK));

    InitializeListHead(&ProviderHandleTable->Entry);

    InitializeCriticalSection(&ProviderHandleTableLock);

    return TRUE;
}
Пример #21
0
PPROVIDER_HANDLE
GetProviderByHandle(PPROVIDER_HANDLE_BLOCK HandleTable,
                    HANDLE Handle)
/*
 * FUNCTION: Get the data structure for a handle
 * ARGUMENTS:
 *     HandleTable = Pointer to handle table
 *     Handle      = Handle to get data structure for
 * RETURNS:
 *     Pointer to the data structure identified by the handle on success,
 *     NULL on failure
 */
{
    PPROVIDER_HANDLE_BLOCK Current;
    PLIST_ENTRY CurrentEntry;
    ULONG i;

    WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X)  Handle (0x%X).\n", HandleTable, Handle));

    CurrentEntry = HandleTable->Entry.Flink;

    while (CurrentEntry != &HandleTable->Entry)
    {
        Current = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);

        for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
        {
            if ((Current->Handles[i].Provider != NULL) &&
                (Current->Handles[i].Handle == Handle))
            {
                return &Current->Handles[i];
            }
        }
        CurrentEntry = CurrentEntry->Flink;
    }

    return NULL;
}
Пример #22
0
/*
 * @implemented
 */
INT
EXPORT
WSAStartup(IN  WORD wVersionRequested,
           OUT LPWSADATA lpWSAData)
{
    WORD VersionReturned = 0;
    DWORD ErrorCode = ERROR_SUCCESS;

    WS_DbgPrint(MAX_TRACE, ("WSAStartup of ws2_32.dll\n"));

    if (!g_hInstDll)
        return WSASYSNOTREADY;

    if (lpWSAData == NULL)
        return WSAEFAULT;

    /* Check which version is being requested */
    switch (LOBYTE(wVersionRequested))
    {
        case 0:

            /* We don't support this unknown version */
            ErrorCode = WSAVERNOTSUPPORTED;
            break;

        case 1:
            /* We support only 1.0 and 1.1 */
            if (HIBYTE(wVersionRequested) == 0)
            {
                /* Caller wants 1.0, return it */
                VersionReturned = wVersionRequested;
            }
            else
            {
                /* The only other version we support is 1.1 */
                VersionReturned = MAKEWORD(1, 1);
            }
            break;

        case 2:
            /* We support only 2.0, 2.1 and 2.2 */
            if (HIBYTE(wVersionRequested) <= 2)
            {
                /* Caller wants 2.0-2.2, return it */
                VersionReturned = MAKEWORD(2, HIBYTE(wVersionRequested));
            }
            else
            {
                /* The highest version we support is 2.2 */
                VersionReturned = MAKEWORD(2, 2);
            }
            break;

        default:

            /* Return 2.2 */
            VersionReturned = MAKEWORD(2, 2);;
            break;
    }

    /* Return the Version Requested, unless error */
    lpWSAData->wVersion = VersionReturned;

    lpWSAData->wHighVersion = MAKEWORD(2,2);
    lstrcpyA(lpWSAData->szDescription, "WinSock 2.0");
    lstrcpyA(lpWSAData->szSystemStatus, "Running");

    if (LOBYTE(wVersionRequested) == 1)
    {
        lpWSAData->iMaxSockets = 32767;
        lpWSAData->iMaxUdpDg = 65467;
    } 
    else
    {
        lpWSAData->iMaxSockets = 0;
        lpWSAData->iMaxUdpDg = 0;
    }
    
    /*FIXME: increment internal counter */

    if (ErrorCode == ERROR_SUCCESS)
        WSASETINITIALIZED;

    return ErrorCode;
}
Пример #23
0
/*
 * @implemented
 */
SOCKET
EXPORT
WSASocketW(IN  INT af,
           IN  INT type,
           IN  INT protocol,
           IN  LPWSAPROTOCOL_INFOW lpProtocolInfo,
           IN  GROUP g,
           IN  DWORD dwFlags)
/*
 * FUNCTION: Creates a new socket descriptor
 * ARGUMENTS:
 *     af             = Address family
 *     type           = Socket type
 *     protocol       = Protocol type
 *     lpProtocolInfo = Pointer to protocol information
 *     g              = Reserved
 *     dwFlags        = Socket flags
 * RETURNS:
 *     Created socket descriptor, or INVALID_SOCKET if it could not be created
 */
{
    INT Status;
    SOCKET Socket;
    PCATALOG_ENTRY Provider;
    WSAPROTOCOL_INFOW ProtocolInfo;

    WS_DbgPrint(MAX_TRACE, ("af (%d)  type (%d)  protocol (%d).\n",
                af, type, protocol));

    if (!WSAINITIALIZED)
    {
        WS_DbgPrint(MAX_TRACE, ("af (%d)  type (%d)  protocol (%d) = WSANOTINITIALISED.\n",
                  af, type, protocol));
        WSASetLastError(WSANOTINITIALISED);
        return INVALID_SOCKET;
    }

    if (!lpProtocolInfo)
    {
        lpProtocolInfo = &ProtocolInfo;
        ZeroMemory(&ProtocolInfo, sizeof(WSAPROTOCOL_INFOW));

        ProtocolInfo.iAddressFamily = af;
        ProtocolInfo.iSocketType    = type;
        ProtocolInfo.iProtocol      = protocol;
    }

    Provider = LocateProvider(lpProtocolInfo);
    if (!Provider)
    {
        WS_DbgPrint(MAX_TRACE, ("af (%d)  type (%d)  protocol (%d) = WSAEAFNOSUPPORT.\n",
                    af, type, protocol));
        WSASetLastError(WSAEAFNOSUPPORT);
        return INVALID_SOCKET;
    }

    Status = LoadProvider(Provider, lpProtocolInfo);
    if (Status != NO_ERROR)
    {
        WS_DbgPrint(MAX_TRACE, ("af (%d)  type (%d)  protocol (%d) = %d.\n",
                    af, type, protocol, Status));
        WSASetLastError(Status);
        return INVALID_SOCKET;
    }

    WS_DbgPrint(MAX_TRACE, ("Calling WSPSocket at (0x%X).\n",
                Provider->ProcTable.lpWSPSocket));

    assert(Provider->ProcTable.lpWSPSocket);

    WS_DbgPrint(MAX_TRACE,("About to call provider socket fn\n"));

    Socket = Provider->ProcTable.lpWSPSocket(af,
                                             type,
                                             protocol,
                                             lpProtocolInfo,
                                             g,
                                             dwFlags,
                                             &Status);

    WS_DbgPrint(MAX_TRACE,("Socket: %x, Status: %x\n", Socket, Status));

    if (Status != NO_ERROR)
    {
        WSASetLastError(Status);
        return INVALID_SOCKET;
    }

    WS_DbgPrint(MAX_TRACE,("Status: %x\n", Status));

    return Socket;
}
Пример #24
0
/*
 * @implemented
 */
INT
EXPORT
select(IN      INT nfds,
       IN OUT  LPFD_SET readfds,
       IN OUT  LPFD_SET writefds,
       IN OUT  LPFD_SET exceptfds,
       IN      CONST struct timeval *timeout)
/*
 * FUNCTION: Returns status of one or more sockets
 * ARGUMENTS:
 *     nfds      = Always ignored
 *     readfds   = Pointer to socket set to be checked for readability (optional)
 *     writefds  = Pointer to socket set to be checked for writability (optional)
 *     exceptfds = Pointer to socket set to be checked for errors (optional)
 *     timeout   = Pointer to a TIMEVAL structure indicating maximum wait time
 *                 (NULL means wait forever)
 * RETURNS:
 *     Number of ready socket descriptors, or SOCKET_ERROR if an error ocurred
 */
{
    PCATALOG_ENTRY Provider = NULL;
    INT Count;
    INT Errno;

    WS_DbgPrint(MAX_TRACE, ("readfds (0x%X)  writefds (0x%X)  exceptfds (0x%X).\n",
                readfds, writefds, exceptfds));

    if (!WSAINITIALIZED)
    {
        WSASetLastError(WSANOTINITIALISED);
        WS_DbgPrint(MID_TRACE,("Not initialized\n"));
        return SOCKET_ERROR;
    }

    /* FIXME: Sockets in FD_SETs should be sorted by their provider */

    /* FIXME: For now, assume only one service provider */
    if ((readfds != NULL) && (readfds->fd_count > 0))
    {
        if (!ReferenceProviderByHandle((HANDLE)readfds->fd_array[0],
                                       &Provider))
        {
            WSASetLastError(WSAENOTSOCK);
            WS_DbgPrint(MID_TRACE,("No provider (read)\n"));
            return SOCKET_ERROR;
        }
    }
    else if ((writefds != NULL) && (writefds->fd_count > 0))
    {
        if (!ReferenceProviderByHandle((HANDLE)writefds->fd_array[0],
                                       &Provider))
        {
            WSASetLastError(WSAENOTSOCK);
            WS_DbgPrint(MID_TRACE,("No provider (write)\n"));
            return SOCKET_ERROR;
        }
    }
    else if ((exceptfds != NULL) && (exceptfds->fd_count > 0))
    {
        if (!ReferenceProviderByHandle((HANDLE)exceptfds->fd_array[0], &Provider))
        {
            WSASetLastError(WSAENOTSOCK);
            WS_DbgPrint(MID_TRACE,("No provider (err)\n"));
            return SOCKET_ERROR;
        }
#if 0 /* XXX empty select is not an error */
    }
    else
    {
        WSASetLastError(WSAEINVAL);
        return SOCKET_ERROR;
#endif
    }

    if ( !Provider )
    {
        if ( timeout )
        {
            WS_DbgPrint(MID_TRACE,("Select: used as timer\n"));
            Sleep( timeout->tv_sec * 1000 + (timeout->tv_usec / 1000) );
        }
        return 0;
    }
    else if (Provider->ProcTable.lpWSPSelect)
    {
        WS_DbgPrint(MID_TRACE,("Calling WSPSelect:%x\n", Provider->ProcTable.lpWSPSelect));
        Count = Provider->ProcTable.lpWSPSelect(nfds,
                                                readfds,
                                                writefds,
                                                exceptfds,
                                                (LPTIMEVAL)timeout,
                                                &Errno);

        WS_DbgPrint(MAX_TRACE, ("[%x] Select: Count %d Errno %x\n",
                    Provider, Count, Errno));

        DereferenceProviderByPointer(Provider);

        if (Count == SOCKET_ERROR)
        {
            WSASetLastError(Errno);
            return SOCKET_ERROR;
        }
    }
    else
    {
        WSASetLastError(WSAEINVAL);
        return SOCKET_ERROR;
    }

    return Count;
}
Пример #25
0
BOOL
WINAPI
DllMain(HANDLE hInstDll,
        ULONG dwReason,
        LPVOID lpReserved)
{
    PWINSOCK_THREAD_BLOCK p;

    WS_DbgPrint(MAX_TRACE, ("DllMain of ws2_32.dll.\n"));

    switch (dwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            GlobalHeap = GetProcessHeap();

            g_hInstDll = hInstDll;

            CreateCatalog();

            InitProviderHandleTable();

            UpcallTable.lpWPUCloseEvent         = WPUCloseEvent;
            UpcallTable.lpWPUCloseSocketHandle  = WPUCloseSocketHandle;
            UpcallTable.lpWPUCreateEvent        = WPUCreateEvent;
            UpcallTable.lpWPUCreateSocketHandle = WPUCreateSocketHandle;
            UpcallTable.lpWPUFDIsSet            = WPUFDIsSet;
            UpcallTable.lpWPUGetProviderPath    = WPUGetProviderPath;
            UpcallTable.lpWPUModifyIFSHandle    = WPUModifyIFSHandle;
            UpcallTable.lpWPUPostMessage        = PostMessageW;
            UpcallTable.lpWPUQueryBlockingCallback    = WPUQueryBlockingCallback;
            UpcallTable.lpWPUQuerySocketHandleContext = WPUQuerySocketHandleContext;
            UpcallTable.lpWPUQueueApc           = WPUQueueApc;
            UpcallTable.lpWPUResetEvent         = WPUResetEvent;
            UpcallTable.lpWPUSetEvent           = WPUSetEvent;
            UpcallTable.lpWPUOpenCurrentThread  = WPUOpenCurrentThread;
            UpcallTable.lpWPUCloseThread        = WPUCloseThread;

            /* Fall through to thread attachment handler */
        }
        case DLL_THREAD_ATTACH:
        {
            p = HeapAlloc(GlobalHeap, 0, sizeof(WINSOCK_THREAD_BLOCK));

            WS_DbgPrint(MAX_TRACE, ("Thread block at 0x%X.\n", p));

            if (!p) {
              return FALSE;
            }

            p->Hostent = NULL;
            p->LastErrorValue = NO_ERROR;
            p->Getservbyname  = NULL;
            p->Getservbyport  = NULL;

            NtCurrentTeb()->WinSockData = p;
        }
        break;

        case DLL_PROCESS_DETACH:
        {
            DestroyCatalog();

            FreeProviderHandleTable();
        }
        break;

        case DLL_THREAD_DETACH:
        {
            p = NtCurrentTeb()->WinSockData;

            if (p)
              HeapFree(GlobalHeap, 0, p);
        }
        break;
    }

    WS_DbgPrint(MAX_TRACE, ("DllMain of ws2_32.dll. Leaving.\n"));

    return TRUE;
}