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

📄 spi.cpp

📁 这个是网络编程
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        return SOCKET_ERROR;
    }

    SetBlockingProvider(SocketContext->Provider);
    ret = SocketContext->Provider->NextProcTable.lpWSPEnumNetworkEvents(
                SocketContext->ProviderSocket,                             
                hEventObject, 
                lpNetworkEvents, 
                lpErrno);
    SetBlockingProvider(NULL);

    UnlockSocketContext(SocketContext, lpErrno);

    return ret;
}

//
// Function: WSPEventSelect
//
// Description:
//    Register the specified events on the socket with the given event handle.
//    All we need to do is translate the socket handle.
//
int WSPAPI WSPEventSelect(
    SOCKET   s,
    WSAEVENT hEventObject,
    long     lNetworkEvents,
    LPINT    lpErrno)
{
    SOCK_INFO *SocketContext;
    INT        ret;

    SocketContext = FindAndLockSocketContext(s, lpErrno);
    if (SocketContext == NULL)
    {
        dbgprint("WSPEventSelect: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
        *lpErrno = WSAENOTSOCK;
        return SOCKET_ERROR;
    }
    
    SetBlockingProvider(SocketContext->Provider);
    ret = SocketContext->Provider->NextProcTable.lpWSPEventSelect(
                SocketContext->ProviderSocket, 
                hEventObject,
                lNetworkEvents, 
                lpErrno);
    SetBlockingProvider(NULL);

    UnlockSocketContext(SocketContext, lpErrno);

    return ret;
}

//
// Function: WSPGetOverlappedResult
//
// Description:
//    This function reports whether the specified overlapped call has
//    completed. If it has, return the requested information. If not,
//    and fWait is true, wait until completion. Otherwise return an
//    error immediately.
//
BOOL WSPAPI WSPGetOverlappedResult (
    SOCKET          s,
    LPWSAOVERLAPPED lpOverlapped,
    LPDWORD         lpcbTransfer,
    BOOL            fWait,
    LPDWORD         lpdwFlags,
    LPINT           lpErrno)
{
    DWORD ret;

    s;
    if (lpOverlapped->Internal != WSS_OPERATION_IN_PROGRESS) 
    {
        // Operation has completed, update the parameters and return 
        //
        *lpcbTransfer = (DWORD)lpOverlapped->InternalHigh;
        *lpdwFlags = (DWORD)lpOverlapped->OffsetHigh;
        *lpErrno = (INT)lpOverlapped->Offset;

        return (lpOverlapped->Offset == 0 ? TRUE : FALSE);
    }
    else
    {
        // Operation is still in progress
        //
        if (fWait) 
        {
            // Wait on the app supplied event handle. Once the operation
            //  is completed the IOCP or completion routine will fire.
            //  Once that is handled, WPUCompleteOverlappedRequest will
            //  be called which will signal the app event.
            //
            ret = WaitForSingleObject(lpOverlapped->hEvent, INFINITE);
            if ( (ret == WAIT_OBJECT_0) &&
                 (lpOverlapped->Internal != WSS_OPERATION_IN_PROGRESS) )
            {
                *lpcbTransfer = (DWORD)lpOverlapped->InternalHigh;
                *lpdwFlags = (DWORD)lpOverlapped->OffsetHigh;
                *lpErrno = (INT)lpOverlapped->Offset;
                    
                return(lpOverlapped->Offset == 0 ? TRUE : FALSE);
            }
            else if (lpOverlapped->Internal == WSS_OPERATION_IN_PROGRESS)
                *lpErrno = WSA_IO_PENDING;
            else 
                *lpErrno = WSASYSCALLFAILURE;
        }
        else 
            *lpErrno = WSA_IO_INCOMPLETE;
    }
    return FALSE;
}

//
// Function: WSPGetPeerName
//
// Description:
//    Returns the address of the peer. The only thing we need to do is translate
//    the socket handle.
//
int WSPAPI WSPGetPeerName(  
    SOCKET          s,
    struct sockaddr FAR * name,
    LPINT           namelen,
    LPINT           lpErrno)
{
    SOCK_INFO *SocketContext;
    INT        ret;

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

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

    UnlockSocketContext(SocketContext, lpErrno);

    return ret;
}

//
// Function: WSPGetSockName
//
// Description:
//    Returns the local address of a socket. All we need to do is translate
//    the socket handle.
//
int WSPAPI WSPGetSockName(
    SOCKET          s,
    struct sockaddr FAR * name,
    LPINT           namelen,
    LPINT           lpErrno)
{
    SOCK_INFO *SocketContext;
    INT        ret;

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

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

    UnlockSocketContext(SocketContext, lpErrno);

    return ret;
}

//
// Function: WSPGetSockOpt
//
// Description:
//    Get the specified socket option. All we need to do is translate the
//    socket handle.
//
int WSPAPI WSPGetSockOpt(
    SOCKET     s,
    int        level,
    int        optname,
    char FAR * optval,
    LPINT      optlen,
    LPINT      lpErrno)
{
    SOCK_INFO *SocketContext;
    INT        ret=NO_ERROR;

    SocketContext = FindAndLockSocketContext(s, lpErrno);
    if (SocketContext == NULL)
    {
        dbgprint("WSPGetSockOpt: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
        *lpErrno = WSAENOTSOCK;
        return SOCKET_ERROR;
    }
    //
    // We need to capture this and return our own WSAPROTOCOL_INFO structure.
    // Otherwise, if we translate the handle and pass it to the lower provider
    // we'll return the lower provider's protocol info!
    //
    if ((level == SOL_SOCKET) && ((optname == SO_PROTOCOL_INFO) ||
                                  (optname == SO_PROTOCOL_INFOA) ||
                                  (optname == SO_PROTOCOL_INFOW) ))
    {
        if ((optname == SO_PROTOCOL_INFOW) && (*optlen >= sizeof(WSAPROTOCOL_INFOW)))
        {
            // No conversion necessary, just copy the data
            memcpy(optval, 
                   &SocketContext->Provider->LayeredProvider, 
                   sizeof(WSAPROTOCOL_INFOW));
        }
        else if ((optname == SO_PROTOCOL_INFOA) && (*optval >= sizeof(WSAPROTOCOL_INFOA)))
        {
            // Copy everything but the string
            memcpy(optval,
                   &SocketContext->Provider->LayeredProvider,
                   sizeof(WSAPROTOCOL_INFOW)-WSAPROTOCOL_LEN+1);
            // Convert our saved UNICODE string to ASCII
            WideCharToMultiByte(CP_ACP,
                                0,
                                SocketContext->Provider->LayeredProvider.szProtocol,
                                -1,
                                ((WSAPROTOCOL_INFOA *)optval)->szProtocol,
                                WSAPROTOCOL_LEN+1,
                                NULL,
                                NULL);
        }
        else
        {
            *lpErrno = WSAEFAULT;
            ret = SOCKET_ERROR;
        }
    }
    else
    {
        SetBlockingProvider(SocketContext->Provider);
        ret = SocketContext->Provider->NextProcTable.lpWSPGetSockOpt(
                    SocketContext->ProviderSocket, 
                    level,
                    optname, 
                    optval, 
                    optlen, 
                    lpErrno);
        SetBlockingProvider(NULL);
    }

    UnlockSocketContext(SocketContext, lpErrno);

    return ret;
}

//
// Function: WSPGetQOSByName
//
// Description:
//    Get a QOS template by name. All we need to do is translate the socket
//    handle.
//
BOOL WSPAPI WSPGetQOSByName(
    SOCKET   s,
    LPWSABUF lpQOSName,
    LPQOS    lpQOS,
    LPINT    lpErrno)
{
    SOCK_INFO *SocketContext;
    INT        ret;

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

    SetBlockingProvider(SocketContext->Provider);
    ret = SocketContext->Provider->NextProcTable.lpWSPGetQOSByName(
                SocketContext->ProviderSocket, 
                lpQOSName,
                lpQOS, 
                lpErrno);
    SetBlockingProvider(NULL);

    UnlockSocketContext(SocketContext, lpErrno);

    return ret;
}

//
// Function: WSPIoctl
//
// Description:
//    Invoke an ioctl. In most cases, we just need to translate the socket
//    handle. However, if the dwIoControlCode is SIO_GET_EXTENSION_FUNCTION_POINTER,
//    we'll need to intercept this and return our own function pointers when
//    they're requesting either TransmitFile or AcceptEx. This is necessary so
//    we can trap these calls. Also for PnP OS's (Win2k) we need to trap calls
//    to SIO_QUERY_TARGET_PNP_HANDLE. For this ioctl we simply have to return 
//    the provider socket.
//
int WSPAPI WSPIoctl(
    SOCKET          s,
    DWORD           dwIoControlCode,
    LPVOID          lpvInBuffer,
    DWORD           cbInBuffer,
    LPVOID          lpvOutBuffer,
    DWORD           cbOutBuffer,
    LPDWORD         lpcbBytesReturned,
    LPWSAOVERLAPPED lpOverlapped,
    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
    LPWSATHREADID   lpThreadId,
    LPINT           lpErrno)
{
    LPWSAOVERLAPPEDPLUS ProviderOverlapped=NULL;
    SOCK_INFO          *SocketContext;
    GUID                AcceptExGuid = WSAID_ACCEPTEX;
    GUID                TransmitFileGuid = WSAID_TRANSMITFILE;
    GUID                GetAcceptExSockAddrsGuid = WSAID_GETACCEPTEXSOCKADDRS;
    GUID                ConnectExGuid = WSAID_CONNECTEX;
    GUID                DisconnectExGuid = WSAID_DISCONNECTEX;
    GUID                TransmitPacketsGuid = WSAID_TRANSMITPACKETS;
    GUID                WSARecvMsgGuid = WSAID_WSARECVMSG;
    int                 ret=NO_ERROR;

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

    if (dwIoControlCode == SIO_GET_EXTENSION_FUNCTION_POINTER)
    {
        // Check to see which extension function is being requested.
        //
        if (memcmp (lpvInBuffer, &TransmitFileGuid, sizeof (GUID)) == 0)
        {
            // Return a pointer to our intermediate extesion function
            //
            *((LPFN_TRANSMITFILE *)lpvOutBuffer) = ExtTransmitFile;
            //
            // Attempt to load the lower provider's extension function
            //
            if (!SocketContext->Provider->NextProcTableExt.lpfnTransmitFile)
            {
                SetBlockingProvider(SocketContext->Provider);
                ret = SocketContext->Provider->NextProcTable.lpWSPIoctl(
                        SocketContext->ProviderSocket,
                        SIO_GET_EXTENSION_FUNCTION_POINTER,
                        &TransmitFileGuid,
                        sizeof(GUID),
                        (LPVOID) &SocketContext->Provider->NextProcTableExt.lpfnTransmitFile,
                        sizeof(LPFN_TRANSMITFILE),
                        lpcbBytesReturned,
                        NULL, 
                        NULL, 
                        NULL,
                        lpErrno);
                SetBlockingProvider(NULL);
            }

            UnlockSocketContext(SocketContext, lpErrno);

            return ret;
        }
        else if (memcmp(lpvInBuffer, &AcceptExGuid, sizeof(GUID)) == 0)
        {
            // Return a pointer to our intermediate extension function

⌨️ 快捷键说明

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