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

📄 spi.cpp

📁 这个是网络编程
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            //
            *((LPFN_ACCEPTEX *)lpvOutBuffer) = ExtAcceptEx;
            //
            // Attempt to load the lower provider's extension function
            //
            if (!SocketContext->Provider->NextProcTableExt.lpfnAcceptEx)
            {
                SetBlockingProvider(SocketContext->Provider);
                ret = SocketContext->Provider->NextProcTable.lpWSPIoctl(
                        SocketContext->ProviderSocket,
                        SIO_GET_EXTENSION_FUNCTION_POINTER,
                        &AcceptExGuid,
                        sizeof(GUID),
                        (LPVOID) &SocketContext->Provider->NextProcTableExt.lpfnAcceptEx,
                        sizeof(LPFN_ACCEPTEX),
                        lpcbBytesReturned,
                        NULL,
                        NULL,
                        NULL,
                        lpErrno);
                SetBlockingProvider(NULL);
            }

            UnlockSocketContext(SocketContext, lpErrno);

            return ret;
        }
        else if (memcmp (lpvInBuffer, &ConnectExGuid, sizeof(GUID)) == 0)
        {
            // Return a pointer to our intermediate extension function
            //
            *((LPFN_CONNECTEX *)lpvOutBuffer) = ExtConnectEx;
            //
            // Attempt to load the lower provider's extension function
            //
            if (!SocketContext->Provider->NextProcTableExt.lpfnConnectEx)
            {
                SetBlockingProvider(SocketContext->Provider);
                ret = SocketContext->Provider->NextProcTable.lpWSPIoctl(
                        SocketContext->ProviderSocket,
                        SIO_GET_EXTENSION_FUNCTION_POINTER,
                        &ConnectExGuid,
                        sizeof(GUID),
                        (LPVOID) &SocketContext->Provider->NextProcTableExt.lpfnConnectEx,
                        sizeof(LPFN_CONNECTEX),
                        lpcbBytesReturned,
                        NULL,
                        NULL,
                        NULL,
                        lpErrno);
                SetBlockingProvider(NULL);
            }

            UnlockSocketContext(SocketContext, lpErrno);

            return ret;
        }
        else if (memcmp (lpvInBuffer, &DisconnectExGuid, sizeof(GUID)) == 0)
        {
            // Return a pointer to our intermediate extension function
            //
            *((LPFN_DISCONNECTEX *)lpvOutBuffer) = ExtDisconnectEx;
            //
            // Attempt to load the lower provider's extension function
            //
            if (!SocketContext->Provider->NextProcTableExt.lpfnDisconnectEx)
            {
                SetBlockingProvider(SocketContext->Provider);
                ret = SocketContext->Provider->NextProcTable.lpWSPIoctl(
                        SocketContext->ProviderSocket,
                        SIO_GET_EXTENSION_FUNCTION_POINTER,
                        &DisconnectExGuid,
                        sizeof(GUID),
                        (LPVOID) &SocketContext->Provider->NextProcTableExt.lpfnDisconnectEx,
                        sizeof(LPFN_DISCONNECTEX),
                        lpcbBytesReturned,
                        NULL,
                        NULL,
                        NULL,
                        lpErrno);
                SetBlockingProvider(NULL);
            }

            UnlockSocketContext(SocketContext, lpErrno);

            return ret;
        }
        else if (memcmp (lpvInBuffer, &TransmitPacketsGuid, sizeof(GUID)) == 0)
        {
            // Return a pointer to our intermediate extension function
            //
            *((LPFN_TRANSMITPACKETS *)lpvOutBuffer) = ExtTransmitPackets;
            //
            // Attempt to load the lower provider's extension function
            //
            if (!SocketContext->Provider->NextProcTableExt.lpfnTransmitPackets)
            {
                SetBlockingProvider(SocketContext->Provider);
                ret = SocketContext->Provider->NextProcTable.lpWSPIoctl(
                        SocketContext->ProviderSocket,
                        SIO_GET_EXTENSION_FUNCTION_POINTER,
                        &TransmitPacketsGuid,
                        sizeof(GUID),
                        (LPVOID) &SocketContext->Provider->NextProcTableExt.lpfnTransmitPackets,
                        sizeof(LPFN_TRANSMITPACKETS),
                        lpcbBytesReturned,
                        NULL,
                        NULL,
                        NULL,
                        lpErrno);
                SetBlockingProvider(NULL);
            }

            UnlockSocketContext(SocketContext, lpErrno);

            return ret;
        }
        else if (memcmp (lpvInBuffer, &WSARecvMsgGuid, sizeof(GUID)) == 0)
        {
            // Return a pointer to our intermediate extension function
            //
            *((LPFN_WSARECVMSG *)lpvOutBuffer) = ExtWSARecvMsg;
            //
            // Attempt to load the lower provider's extension function
            //
            if (!SocketContext->Provider->NextProcTableExt.lpfnWSARecvMsg)
            {
                SetBlockingProvider(SocketContext->Provider);
                ret = SocketContext->Provider->NextProcTable.lpWSPIoctl(
                        SocketContext->ProviderSocket,
                        SIO_GET_EXTENSION_FUNCTION_POINTER,
                        &WSARecvMsgGuid,
                        sizeof(GUID),
                        (LPVOID) &SocketContext->Provider->NextProcTableExt.lpfnWSARecvMsg,
                        sizeof(LPFN_WSARECVMSG),
                        lpcbBytesReturned,
                        NULL,
                        NULL,
                        NULL,
                        lpErrno);
                SetBlockingProvider(NULL);
            }

            UnlockSocketContext(SocketContext, lpErrno);

            return ret;
        }
        else if (memcmp (lpvInBuffer, &GetAcceptExSockAddrsGuid, sizeof (GUID)) == 0)
        {
            // No socket handle translation needed, let the call pass through below
            // (i.e. we really don't have any need to intercept this call)
        }
        else 
        {
            UnlockSocketContext(SocketContext, lpErrno);

            *lpErrno = WSAEINVAL;
            return SOCKET_ERROR;
        }
    }
    else if (dwIoControlCode == SIO_QUERY_TARGET_PNP_HANDLE)
    {
        dbgprint("SIO_QUERY_PNP_HANDLE requested");

        *((SOCKET *)lpvOutBuffer) = SocketContext->ProviderSocket;
        *lpcbBytesReturned = sizeof(SocketContext->ProviderSocket);

        if (lpOverlapped)
        {
            ProviderOverlapped = GetOverlappedStructure(SocketContext);
            if (ProviderOverlapped == NULL)
            {
                UnlockSocketContext(SocketContext, lpErrno);

                *lpErrno = WSAENOBUFS;
                return SOCKET_ERROR;
            }

            ProviderOverlapped->lpCallerOverlapped = lpOverlapped;
            CopyOffset(&ProviderOverlapped->ProviderOverlapped, lpOverlapped);
            ProviderOverlapped->SockInfo           = SocketContext;
            ProviderOverlapped->CallerSocket       = s;
            ProviderOverlapped->ProviderSocket     = SocketContext->ProviderSocket;
            ProviderOverlapped->Error              = NO_ERROR;
            ProviderOverlapped->Operation          = LSP_OP_IOCTL;
            ProviderOverlapped->lpCallerThreadId   = lpThreadId;
            ProviderOverlapped->lpCallerCompletionRoutine   = lpCompletionRoutine;
            ProviderOverlapped->Provider = SocketContext->Provider;

            lpOverlapped->Internal = (DWORD_PTR)lpCompletionRoutine;
            lpOverlapped->InternalHigh = *lpcbBytesReturned;

            //
            // Call the completion routine immediately since there is nothing
            //  else to do. For this ioctl all we do is return the provider
            //  socket. If it was called overlapped just complete the operation.
            //

            dbgprint("SIO_QUERY_PNP_HANDLE overlapped");

            IntermediateCompletionRoutine(0,
                                         *lpcbBytesReturned,
                                         (WSAOVERLAPPED *)ProviderOverlapped,
                                          0);
        }
        UnlockSocketContext(SocketContext, lpErrno);

        return NO_ERROR;
    }

    //
    // Check for overlapped I/O
    // 
    if (lpOverlapped)
    {
        ProviderOverlapped = GetOverlappedStructure(SocketContext);
        if (!ProviderOverlapped)
        {
            UnlockSocketContext(SocketContext, lpErrno);

            *lpErrno = WSAENOBUFS;
            return SOCKET_ERROR;
        }

        ProviderOverlapped->lpCallerOverlapped = lpOverlapped;
        CopyOffset(&ProviderOverlapped->ProviderOverlapped, lpOverlapped);
        ProviderOverlapped->SockInfo           = SocketContext;
        ProviderOverlapped->CallerSocket       = s;
        ProviderOverlapped->ProviderSocket     = SocketContext->ProviderSocket;
        ProviderOverlapped->Error              = NO_ERROR;
        ProviderOverlapped->Operation          = LSP_OP_IOCTL;
        ProviderOverlapped->lpCallerThreadId   = lpThreadId;
        ProviderOverlapped->lpCallerCompletionRoutine   = lpCompletionRoutine;
        ProviderOverlapped->IoctlArgs.dwIoControlCode   = dwIoControlCode;
        ProviderOverlapped->IoctlArgs.lpvInBuffer       = lpvInBuffer;
        ProviderOverlapped->IoctlArgs.cbInBuffer        = cbInBuffer;
        ProviderOverlapped->IoctlArgs.lpvOutBuffer      = lpvOutBuffer;
        ProviderOverlapped->IoctlArgs.cbOutBuffer       = cbOutBuffer;
        ProviderOverlapped->IoctlArgs.cbBytesReturned   = (lpcbBytesReturned ? *lpcbBytesReturned : 0);
        ProviderOverlapped->Provider = SocketContext->Provider;

        ret = QueueOverlappedOperation(ProviderOverlapped, SocketContext);

        if (ret != NO_ERROR)
        {
            *lpErrno = ret;
            ret = SOCKET_ERROR;
        }
    }
    else
    {
        SetBlockingProvider(SocketContext->Provider);
        ret = SocketContext->Provider->NextProcTable.lpWSPIoctl(
                SocketContext->ProviderSocket, 
                dwIoControlCode, 
                lpvInBuffer,
                cbInBuffer, 
                lpvOutBuffer, 
                cbOutBuffer, 
                lpcbBytesReturned, 
                lpOverlapped, 
                lpCompletionRoutine, 
                lpThreadId, 
                lpErrno);
        SetBlockingProvider(NULL);
    }

    UnlockSocketContext(SocketContext, lpErrno);

    return ret;
}

//
// Function: WSPJoinLeaf
//
// Description:
//    This function joins a socket to a multipoint session. For those providers
//    that support multipoint semantics there are 2 possible behaviors. First,
//    for IP, WSAJoinLeaf always returns the same socket handle which was passed
//    into it. In this case there is no new socket so we don't want to create
//    any socket context once the lower provider WSPJoinLeaf is called. In the
//    second case, for ATM, a new socket IS created when we call the lower
//    provider. In this case we do want to create a new user socket and create
//    a socket context.
//
SOCKET WSPAPI WSPJoinLeaf(
    SOCKET       s,
    const struct sockaddr FAR * name,
    int          namelen,
    LPWSABUF     lpCallerData,
    LPWSABUF     lpCalleeData,
    LPQOS        lpSQOS,
    LPQOS        lpGQOS,
    DWORD        dwFlags,
    LPINT        lpErrno)
{
    SOCK_INFO *SocketContext;
    SOCKET     NextProviderSocket = INVALID_SOCKET,
               NewSocket = INVALID_SOCKET;

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

    SetBlockingProvider(SocketContext->Provider);
    NextProviderSocket = SocketContext->Provider->NextProcTable.lpWSPJoinLeaf(
            SocketContext->ProviderSocket,                           
            name, 
            namelen, 
            lpCallerData, 
            lpCalleeData, 
            lpSQOS, 
            lpGQOS, 
            dwFlags,                        
            lpErrno);
    SetBlockingProvider(NULL);
    //    
    // If the socket returned from the lower provider is the same as the socket
    //  passed into it then there really isn't a new socket - just return. 
    //  Otherwise, a new socket has been created and we need to create the socket
    //  context and create a user socket to pass back.
    //
    if (NextProviderSocket != SocketContext->ProviderSocket)
    {
        SOCK_INFO *NewSocketContext;

        // Create a new socket context structure
        //
        if ((NewSocketContext = CreateSockInfo(SocketContext->Provider,
                                               NextProviderSocket,
                                               SocketContext)) == NULL)
        {
            *lpErrno = WSAENOBUFS;
        }
        else
        {
            // Create a socket handle to pass to app
            //
            NewSocket = MainUpCallTable.lpWPUCreateSocketHandle(
                        SocketContext->Provider->LayeredProvider.ProtocolChain.ChainEntries[0],
                        (DWORD_PTR)NewSocketContext,
                        lpErrno);
            if (NewSocket == INVALID_SOCKET)
            {
                dbgprint("WSPJoinLeaf: WPUCreateSocketHandle() failed: %d", *lpErrno);
        
                HeapFree(hLspHeap, 0, NewSocketContext);

                UnlockSocketContext(SocketContext, lpErrno);

                *lpErrno = WSAENOBUFS;
                return INVALID_SOCKET;
            }
            NewSocketContext->LayeredSocket = NewSocket;
        }

        UnlockSocketContext(SocketContext, lpErrno);

        return NewSocket;
    }
    else
    {
        UnlockSocketContext(SocketContext, lpErrno);

        return s;
    }
}

//
// Function: WSPListen
//
// Description:
//    This function sets the backlog value on a listening socket. All we need to
//    do is translate the socket handle to the correct provider.
//
int WSPAPI WSPListen(
    SOCKET s,        
    int    backlog,     
    LPINT  lpErrno)
{
    SOCK_INFO *SocketContext;
    INT        ret;

    SocketContext = FindAndLockSocketContext(s, lpErrno);

⌨️ 快捷键说明

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