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

📄 extension.cpp

📁 < WINDOWS网络编程>>英文版,一本详细讲解WINDOWS平台下网络编程的国外经典书籍,适合英文水平高的牛人
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) 1998  Microsoft Corporation.  All Rights Reserved.
//
// Module Name: extension.cpp
//
// Description:
//
//    This sample illustrates how to develop a layered service provider that is
//    capable of counting all bytes transmitted through a TCP/IP socket.
//
//    This file contains all of the Winsock extension functions that can
//    be monitored by a service provider. This is done by intercepting any
//    WSAIoctl calls with the SIO_GET_EXTENSION_FUNCTION_POINTER (see spi.cpp
//    and WSPIoctl for more info). We substitute our own function pointer so
//    that an application calls into us. Currently we intercept only TransmitFile
//    and AcceptEx.
//

#include "provider.h"

//
// Used to output debug messages
//
static TCHAR Msg[512];

//
// Function: ExtTransmitFile
//
// Description:
//    This is our provider's TransmitFile function. When an app calls WSAIoctl
//    to request the function pointer to TransmitFile, we intercept the call
//    and return a pointer to our extension function instead.
//
BOOL PASCAL FAR ExtTransmitFile (
    IN SOCKET hSocket,
    IN HANDLE hFile,
    IN DWORD nNumberOfBytesToWrite,
    IN DWORD nNumberOfBytesPerSend,
    IN LPOVERLAPPED lpOverlapped,
    IN LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
    IN DWORD dwFlags)
{
	SOCK_INFO          *SocketContext;
	LPWSAOVERLAPPEDPLUS ProviderOverlapped;
	int                 Errno,
                        ret;

    SocketContext = FindAndLockSocketContext(hSocket, &Errno);
    if (SocketContext == NULL)
    {
        dbgprint("ExtTransmitFile: WPUQuerySocketHandleContext() failed: %d", Errno);
        WSASetLastError(Errno);
		return FALSE;
    }

    if (!SocketContext->Provider->NextProcTableExt.lpfnTransmitFile)
    {
        UnlockSocketContext(SocketContext, &Errno);
        dbgprint("Next proc table TransmitFile == NULL!");
        WSASetLastError(WSAEFAULT);
	    return FALSE;
    }

	// Check for overlapped I/O
	
	if (lpOverlapped)
	{
		ProviderOverlapped = GetOverlappedStructure(SocketContext);
        if (!ProviderOverlapped)
        {
            UnlockSocketContext(SocketContext, &Errno);
            dbgprint("ExtTransmitFile: GetOverlappedStructure() returned NULL!");
            WSASetLastError(WSAENOBUFS);
            return FALSE;
        }
        //
        // Save off the arguments and setup the overlapped structure
        //
        ProviderOverlapped->lpCallerOverlapped = lpOverlapped;
        CopyOffset(&ProviderOverlapped->ProviderOverlapped, lpOverlapped);
        ProviderOverlapped->SockInfo           = SocketContext;
        ProviderOverlapped->CallerSocket       = hSocket;
        ProviderOverlapped->ProviderSocket     = SocketContext->ProviderSocket;
        ProviderOverlapped->Error              = NO_ERROR;
        ProviderOverlapped->Operation          = LSP_OP_TRANSMITFILE;
        ProviderOverlapped->lpCallerThreadId   = NULL;
        ProviderOverlapped->lpCallerCompletionRoutine              = NULL;
        ProviderOverlapped->TransmitFileArgs.hFile                 = hFile;
        ProviderOverlapped->TransmitFileArgs.nNumberOfBytesToWrite = nNumberOfBytesToWrite;
        ProviderOverlapped->TransmitFileArgs.nNumberOfBytesPerSend = nNumberOfBytesPerSend;
        ProviderOverlapped->TransmitFileArgs.lpTransmitBuffers     = lpTransmitBuffers;
        ProviderOverlapped->TransmitFileArgs.dwFlags               = dwFlags;
        ProviderOverlapped->Provider = SocketContext->Provider;

        ret = QueueOverlappedOperation(ProviderOverlapped, SocketContext);

        if (ret != NO_ERROR)
        {
            WSASetLastError(ret);
            ret = FALSE;
        }
        else
        {
            ret = TRUE;
        }
	}
	else
	{
		ret = SocketContext->Provider->NextProcTableExt.lpfnTransmitFile(
			SocketContext->ProviderSocket,
			hFile,
			nNumberOfBytesToWrite,
			nNumberOfBytesPerSend,
			NULL,
			lpTransmitBuffers,
			dwFlags);
	}

    UnlockSocketContext(SocketContext, &Errno);

    return ret;
}

//
// Function: ExtAcceptEx
//
// Description:
//    This is our provider's AcceptEx function. When an app calls WSAIoctl
//    to request the function pointer to AcceptEx, we intercept the call
//    and return a pointer to our extension function instead.
//
BOOL PASCAL FAR ExtAcceptEx(
	IN SOCKET sListenSocket,
	IN SOCKET sAcceptSocket,
	IN PVOID lpOutputBuffer,
	IN DWORD dwReceiveDataLength,
	IN DWORD dwLocalAddressLength,
	IN DWORD dwRemoteAddressLength,
	OUT LPDWORD lpdwBytesReceived,
	IN LPOVERLAPPED lpOverlapped)
{
	LPWSAOVERLAPPEDPLUS ProviderOverlapped;
	SOCK_INFO          *ListenSocketContext=NULL,
	                   *AcceptSocketContext=NULL;
	int                 Errno,
                        ret;


    //
    // Query the socket context for the listening socket
    //
    ListenSocketContext = FindAndLockSocketContext(sListenSocket, &Errno);
    if (ListenSocketContext == NULL)
    {
        dbgprint("AcceptExExt: WPUQuerySocketHandleContext "
                  "on listen socket failed: %d", Errno);
        Errno = WSAENOTSOCK;
        WSASetLastError(Errno);
		return FALSE;
    }
    //
    // Also need to query the socket context for the accept socket
    //
    AcceptSocketContext = FindAndLockSocketContext(sAcceptSocket, &Errno);
    if (AcceptSocketContext == NULL)
    {
        UnlockSocketContext(ListenSocketContext, &Errno);

        dbgprint("AcceptExExt: WPUQuerySocketHandleContext "
                  "on accept socket failed: %d", Errno);
        Errno = WSAENOTSOCK;
        WSASetLastError(Errno);
		return FALSE;
    }

    if (!ListenSocketContext->Provider->NextProcTableExt.lpfnAcceptEx)
    {
        UnlockSocketContext(ListenSocketContext, &Errno);
        UnlockSocketContext(AcceptSocketContext, &Errno);

        dbgprint("Lower provider AcceptEx == NULL!");
        WSASetLastError(WSAEFAULT);
		return FALSE;
    }

	// Check for overlapped I/O

	if (lpOverlapped)
	{
		ProviderOverlapped = GetOverlappedStructure(ListenSocketContext);
        if (!ProviderOverlapped)
        {
            UnlockSocketContext(ListenSocketContext, &Errno);
            UnlockSocketContext(AcceptSocketContext, &Errno);

            dbgprint("ExtAcceptEx: GetOverlappedStructre() returne NULL!");
            WSASetLastError(WSAENOBUFS);
            return FALSE;
        }
        // Save off the paramters and initalize the overlapped structure
        //
        ProviderOverlapped->lpCallerOverlapped = lpOverlapped;
        CopyOffset(&ProviderOverlapped->ProviderOverlapped, lpOverlapped);
        ProviderOverlapped->SockInfo           = ListenSocketContext;
        ProviderOverlapped->CallerSocket       = sListenSocket;
        ProviderOverlapped->ProviderSocket     = ListenSocketContext->ProviderSocket;
        ProviderOverlapped->Error              = NO_ERROR;
        ProviderOverlapped->Operation          = LSP_OP_ACCEPTEX;
        ProviderOverlapped->lpCallerThreadId   = NULL;
        ProviderOverlapped->lpCallerCompletionRoutine          = NULL;
        ProviderOverlapped->AcceptExArgs.sAcceptSocket         = sAcceptSocket;
        ProviderOverlapped->AcceptExArgs.sProviderAcceptSocket = AcceptSocketContext->ProviderSocket;
        ProviderOverlapped->AcceptExArgs.lpOutputBuffer        = lpOutputBuffer;
        ProviderOverlapped->AcceptExArgs.dwReceiveDataLength   = dwReceiveDataLength;
        ProviderOverlapped->AcceptExArgs.dwLocalAddressLength  = dwLocalAddressLength;
        ProviderOverlapped->AcceptExArgs.dwRemoteAddressLength = dwRemoteAddressLength;
        ProviderOverlapped->AcceptExArgs.dwBytesReceived       = (lpdwBytesReceived ? *lpdwBytesReceived : 0);
        ProviderOverlapped->Provider = AcceptSocketContext->Provider;

        ret = QueueOverlappedOperation(ProviderOverlapped, ListenSocketContext);

        if (ret != NO_ERROR)
        {
            WSASetLastError(ret);
            ret = FALSE;
        }
        else
        {
            ret = TRUE;
        }
	}
	else
	{
		ret = ListenSocketContext->Provider->NextProcTableExt.lpfnAcceptEx(
			ListenSocketContext->ProviderSocket,
			AcceptSocketContext->ProviderSocket,
			lpOutputBuffer,
			dwReceiveDataLength,
			dwLocalAddressLength,
			dwRemoteAddressLength,
			lpdwBytesReceived,
			NULL);
	}

    UnlockSocketContext(ListenSocketContext, &Errno);
    UnlockSocketContext(AcceptSocketContext, &Errno);

    return ret;
}

BOOL PASCAL FAR ExtConnectEx(
    IN SOCKET s,
    IN const struct sockaddr FAR *name,
    IN int namelen,
    IN PVOID lpSendBuffer OPTIONAL,
    IN DWORD dwSendDataLength,
    OUT LPDWORD lpdwBytesSent,
    IN LPOVERLAPPED lpOverlapped)
{
    SOCK_INFO           *SocketContext=NULL;
    LPWSAOVERLAPPEDPLUS  ProviderOverlapped=NULL;
    int                  Errno,
                         ret;

    SocketContext = FindAndLockSocketContext(s, &Errno);
    if (SocketContext == NULL)
    {
        dbgprint("ExtConnectEx: WPUQuerySocketHandleContext() failed: %d", Errno);
        return FALSE;
    }

    if (!SocketContext->Provider->NextProcTableExt.lpfnConnectEx)
    {
        UnlockSocketContext(SocketContext, &Errno);

        dbgprint("Next proc table ConnectEx == NULL!");
        WSASetLastError(WSAEFAULT);
        return FALSE;
    }

    // Check for overlapped I/O

    if (lpOverlapped)
    {
        ProviderOverlapped = GetOverlappedStructure(SocketContext);
        if (!ProviderOverlapped)
        {
            UnlockSocketContext(SocketContext, &Errno);

            dbgprint("ExtConnectEx: GetOverlappedStructure() returned NULL");
            WSASetLastError(WSAENOBUFS);
            return FALSE;
        }
        //
        // Save off the arguments and setup the overlapped structure
        //

⌨️ 快捷键说明

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