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

📄 spi.cpp

📁 这个是网络编程
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    ret = SOCKET_ERROR;
    if (IsWindow(hWnd))
    {
        // Verify only valid events have been set
        //
        if ( (lEvent & ~FD_ALL_EVENTS) == 0)
        {
            // Find our provider socket corresonding to this one
            //
            SocketContext = FindAndLockSocketContext(s, lpErrno);
            if (SocketContext != NULL)
            {
                SocketContext->hWnd = hWnd;
                SocketContext->uMsg = wMsg;

                // Get the handle to our hidden window
                //
                if ((hWorkerWindow = GetWorkerWindow()) != NULL)
                {
                    SetBlockingProvider(SocketContext->Provider);
                    ret = SocketContext->Provider->NextProcTable.lpWSPAsyncSelect(
                               SocketContext->ProviderSocket, 
                               hWorkerWindow, 
                               WM_SOCKET, 
                               lEvent, 
                               lpErrno);
                    SetBlockingProvider(NULL);
                }
                else
                {
                    *lpErrno = WSAEINVAL;
                }
                UnlockSocketContext(SocketContext, lpErrno);
            }
            else
            {
                dbgprint("WSPAsyncSelect: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
                *lpErrno = WSAENOTSOCK;
            }
        }
        else
        {
            *lpErrno = WSAEINVAL;
        }
    }
    else
    {
        *lpErrno = WSAEINVAL;
    }

    return ret;
}

//
// Function: WSPBind
//
// Description:
//    Bind the socket to a local address. We just map socket handles and
//    call the lower provider.
//
int WSPAPI WSPBind(
    SOCKET                s,
    const struct sockaddr FAR * name,
    int                   namelen,
    LPINT                 lpErrno)
{
    SOCK_INFO *SocketContext;
    INT        ret;

    SocketContext = FindAndLockSocketContext(s, lpErrno);
    if (SocketContext == NULL)
    {
        dbgprint("WSPBind: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
        *lpErrno = WSAENOTSOCK;
        return SOCKET_ERROR;
    }

    SetBlockingProvider(SocketContext->Provider);
    ret = SocketContext->Provider->NextProcTable.lpWSPBind(
        SocketContext->ProviderSocket, 
        name, 
        namelen, 
        lpErrno);
    SetBlockingProvider(NULL);

    UnlockSocketContext(SocketContext, lpErrno);

    return ret;
}

//
// Function: WSPCancelBlockingCall
//
// Description:
//    This call cancels any blocking Winsock call in the current thread only.
//    For every Winsock call that blocks we use thread local storage (TLS) to
//    store a pointer to the provider on which the blocking call was issued.
//    This is necessary since WSACancelBlockingCall takes no arguments (i.e.
//    the LSP needs to keep track of what calls are blocking).
//
int WSPAPI WSPCancelBlockingCall(
    LPINT lpErrno)
{
    PROVIDER *Provider=NULL;
    INT       ret = NO_ERROR;

    Provider = (PROVIDER *)TlsGetValue(TlsIndex);
    if (!Provider)
    {
        ret = Provider->NextProcTable.lpWSPCancelBlockingCall(lpErrno);
    }
    return ret;
}

// 
// Function: WSPCleanup
//
// Description:
//    Decrement the entry count. If equal to zero then we can prepare to have us
//    unloaded. Close any outstanding sockets and free up allocated memory.
//
int WSPAPI WSPCleanup(
    LPINT lpErrno  
    )
{
    int        ret=NO_ERROR;

    if (bDetached)
        return NO_ERROR;

    EnterCriticalSection(&gCriticalSection);

    if (!gEntryCount)
    {
        *lpErrno = WSANOTINITIALISED;

        dbgprint("WSPCleanup returning WSAENOTINITIALISED");

        LeaveCriticalSection(&gCriticalSection);
        return SOCKET_ERROR;
    }
    // Decrement the entry count
    //
    gEntryCount--;

    dbgprint("WSPCleanup: %d", gEntryCount);

    if (gEntryCount == 0)
    {
        dbgprint("WSPCleanup: gEntryCount == 0; cleaning up");

        StopAsyncWindowManager();
        StopOverlappedManager();

        Sleep(200);

        FreeSocketsAndMemory(lpErrno);
    /*
        DecrementLspUsage(hDllInstance, 1);
    */
    }
    LeaveCriticalSection(&gCriticalSection);

    return ret;
}

//
// Function: WSPCloseSocket
//
// Description:
//    Close the socket handle of the app socket as well as the provider socket.
//    However, if there are outstanding async IO requests on the app socket
//    we only close the provider socket. Only when all the IO requests complete
//    (with error) will we then close the app socket (this will occur in
//    the overlapped manager - overlapp.cpp).
//
int WSPAPI WSPCloseSocket(  
    SOCKET s,        
    LPINT  lpErrno
)
{
    SOCK_INFO *SocketContext;

    SocketContext = FindAndLockSocketContext(s, lpErrno);
    if (SocketContext == NULL)
    {
        dbgprint("WSPCloseSocket: WPUQuerySocketHandle() failed: %d", *lpErrno);

        *lpErrno = WSAENOTSOCK;
        return SOCKET_ERROR;
    }
    AcquireSocketLock(SocketContext);

    dbgprint("WSPCloseSocket: Closing layered socket 0x%p (provider 0x%p)",
        s, SocketContext->ProviderSocket);

    //
    // If we there are outstanding async calls on this handle don't close the app
    //  socket handle...only close the provider's handle.  Therefore any errors
    //  incurred can be propogated back to the app socket.
    //
    if ((SocketContext->dwOutstandingAsync != 0) || (SocketContext->RefCount != 1))
    {
        SocketContext->bClosing = TRUE;

        if (SocketContext->Provider->NextProcTable.lpWSPCloseSocket(
                SocketContext->ProviderSocket, 
                lpErrno) == SOCKET_ERROR) 
        {
            *lpErrno = WSAENOTSOCK;
            UnlockSocketContext(SocketContext, lpErrno);
            dbgprint("WSPCloseSocket: Invalid socket handle");
            return SOCKET_ERROR;
        }

        SocketContext->ProviderSocket = INVALID_SOCKET;

        UnlockSocketContext(SocketContext, lpErrno);
        return NO_ERROR;
    }
    //
    // Close the provider socket
    //
    SetBlockingProvider(SocketContext->Provider);
    if (SocketContext->Provider->NextProcTable.lpWSPCloseSocket(
            SocketContext->ProviderSocket, 
            lpErrno) == SOCKET_ERROR) 
    {
        SetBlockingProvider(NULL);
        UnlockSocketContext(SocketContext, lpErrno);
        dbgprint("WSPCloseSocket: Provider close failed");
        return SOCKET_ERROR;
    }
    SetBlockingProvider(NULL);

    SocketContext->ProviderSocket = INVALID_SOCKET;

    //
    // Remove the socket info
    //
    RemoveSocketInfo(SocketContext->Provider, SocketContext);

    //
    // Close the app socket
    //
    if (MainUpCallTable.lpWPUCloseSocketHandle(s, lpErrno) == SOCKET_ERROR)
    {
        dbgprint("WPUCloseSocketHandle failed: %d", *lpErrno);

        ReleaseSocketLock(SocketContext);
        return SOCKET_ERROR;
    }

    dbgprint("Closing socket %d Bytes Sent [%lu] Bytes Recv [%lu]", 
        s, SocketContext->BytesSent, SocketContext->BytesRecv);

    ReleaseSocketLock(SocketContext);

    DeleteCriticalSection(&SocketContext->SockCritSec);
    HeapFree(hLspHeap, 0, SocketContext);

    return NO_ERROR;
}

//
// Function: WSPConnect
//
// Description:
//    Performs a connect call. The only thing we need to do is translate
//    the socket handle.
//
int WSPAPI WSPConnect (
    SOCKET                s,
    const struct sockaddr FAR * name,
    int                   namelen,
    LPWSABUF              lpCallerData,
    LPWSABUF              lpCalleeData,
    LPQOS                 lpSQOS,
    LPQOS                 lpGQOS,
    LPINT                 lpErrno
)
{
    SOCK_INFO *SocketContext;
    INT        ret;

    SocketContext = FindAndLockSocketContext(s, lpErrno);
    if (SocketContext == NULL)
    {
        dbgprint("WSPConnect: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
        *lpErrno = WSAENOTSOCK;
        return SOCKET_ERROR;
    }

    SetBlockingProvider(SocketContext->Provider);
    ret = SocketContext->Provider->NextProcTable.lpWSPConnect(
                SocketContext->ProviderSocket, 
                name, 
                namelen, 
                lpCallerData, 
                lpCalleeData,
                lpSQOS, 
                lpGQOS, 
                lpErrno);
    SetBlockingProvider(NULL);

    UnlockSocketContext(SocketContext, lpErrno);

    return ret;
}

//
// Function: WSPDuplicateSocket
//
// Description:
//    This function provides a WSAPROTOCOL_INFOW structure which can be passed
//    to another process to open a handle to the same socket. First we need
//    to translate the user socket into the provider socket and call the underlying
//    WSPDuplicateSocket. Note that the lpProtocolInfo structure passed into us
//    is an out parameter only!
//
int WSPAPI WSPDuplicateSocket(
    SOCKET              s,
    DWORD               dwProcessId,                      
    LPWSAPROTOCOL_INFOW lpProtocolInfo,   
    LPINT               lpErrno)
{
    PROVIDER          *Provider=NULL;
    SOCK_INFO         *SocketContext=NULL;
    DWORD              dwReserved;
    int                ret;

    SocketContext = FindAndLockSocketContext(s, lpErrno);
    if (SocketContext == NULL)
    {
        dbgprint("WSPDuplicateSocket: WPUQuerySocketHandle() failed: %d", *lpErrno);
        *lpErrno = WSAENOTSOCK;
        return SOCKET_ERROR;
    }
    //
    // Find the underlying provider
    //
    Provider = SocketContext->Provider;

    SetBlockingProvider(Provider);
    ret = Provider->NextProcTable.lpWSPDuplicateSocket(
                SocketContext->ProviderSocket,
                dwProcessId,
                lpProtocolInfo,
                lpErrno);
    SetBlockingProvider(NULL);

    UnlockSocketContext(SocketContext, lpErrno);

    if (ret == NO_ERROR)
    {
        // We want to return the WSAPROTOCOL_INFOW structure of the underlying
        // provider but we need to preserve the reserved info returned by the
        // WSPDuplicateSocket call.
        //
        dwReserved = lpProtocolInfo->dwProviderReserved;
        memcpy(lpProtocolInfo, &Provider->LayeredProvider, sizeof(WSAPROTOCOL_INFOW));
        lpProtocolInfo->dwProviderReserved = dwReserved;
    }
    return ret;    
}

//
// Function: WSPEnumNetworkEvents
//
// Description:
//    Enumerate the network events for a socket. We only need to translate the
//    socket handle.
//
int WSPAPI WSPEnumNetworkEvents(  
    SOCKET             s,
    WSAEVENT           hEventObject,
    LPWSANETWORKEVENTS lpNetworkEvents,
    LPINT              lpErrno)
{
    SOCK_INFO *SocketContext;
    INT        ret;

    SocketContext = FindAndLockSocketContext(s, lpErrno);
    if (SocketContext == NULL)
    {
        dbgprint("WSPEnumNetworkEvents: WPUQuerySocketHandleContext() failed: %d",
            *lpErrno);
        *lpErrno = WSAENOTSOCK;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -