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

📄 sockinfo.cpp

📁 < WINDOWS网络编程>>英文版,一本详细讲解WINDOWS平台下网络编程的国外经典书籍,适合英文水平高的牛人
💻 CPP
字号:
// 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) 1999  Microsoft Corporation.  All Rights Reserved.
//
// Module Name: provider.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 support functions that are common to the lsp and
//    the instlsp sample for enumerating the Winsock catalog of service
//    providers.
//    

#include "provider.h"

//
// External variable definitions
//
extern CRITICAL_SECTION gCriticalSection;
extern INT              gLayerCount;
extern PROVIDER        *gBaseInfo;
extern HANDLE           hLspHeap;

static char Msg[512];

SOCK_INFO *FindAndLockSocketContext(SOCKET s, int *lpErrno)
{
    SOCK_INFO *SocketContext=NULL;
    int        ret;

    EnterCriticalSection(&gCriticalSection);

    ret = MainUpCallTable.lpWPUQuerySocketHandleContext(
            s,
            (PDWORD_PTR) &SocketContext,
            lpErrno
            );
    if (ret == SOCKET_ERROR)
    {
        dbgprint("FindAndLockSocketContext: WPUQuerySocketHandleContext failed: %d", *lpErrno);
    }
    else
    {
        InterlockedIncrement(&SocketContext->RefCount);
    }
    LeaveCriticalSection(&gCriticalSection);

    return SocketContext;
}

void UnlockSocketContext(SOCK_INFO *context, int *lpErrno)
{
    LONG    newval;

    EnterCriticalSection(&gCriticalSection);

    newval = InterlockedDecrement(&context->RefCount);
    if ((newval == 0) && (context->bClosing))
    {
        if (MainUpCallTable.lpWPUCloseSocketHandle(context->LayeredSocket, lpErrno) == SOCKET_ERROR)
        {
            dbgprint("UnlockSocketContext: WPUCloseSocketHandle() failed: %d", *lpErrno);
        }

        context->LayeredSocket = INVALID_SOCKET;

        RemoveSocketInfo(context->Provider, context);

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

        ReleaseSocketLock(context);

        DeleteCriticalSection(&context->SockCritSec);
        dbgprint("Freeing a SOCK_INFO (SocketContext) structure");
        HeapFree(hLspHeap, 0, context);
    }

    LeaveCriticalSection(&gCriticalSection);
}

void AcquireSocketLock(SOCK_INFO *SockInfo)
{
    EnterCriticalSection(&SockInfo->SockCritSec);
}

void ReleaseSocketLock(SOCK_INFO *SockInfo)
{
    LeaveCriticalSection(&SockInfo->SockCritSec);
}

SOCK_INFO *CreateSockInfo(PROVIDER *Provider, SOCKET ProviderSocket, SOCK_INFO *Inherit)
{
    SOCK_INFO   *NewInfo=NULL;

    NewInfo = (SOCK_INFO *)HeapAlloc(hLspHeap,
                                     HEAP_ZERO_MEMORY,
                                     sizeof(SOCK_INFO));
    if (NewInfo == NULL)
    {
        dbgprint("HeapAlloc() failed: %d", GetLastError());
        return NULL;
    }
    NewInfo->ProviderSocket     = ProviderSocket;
    NewInfo->bClosing           = FALSE;
    NewInfo->dwOutstandingAsync = 0;
    NewInfo->BytesRecv          = 0;
    NewInfo->BytesSent          = 0;
    NewInfo->Provider           = Provider;
    NewInfo->hWnd               = (Inherit ? Inherit->hWnd : 0);
    NewInfo->uMsg               = (Inherit ? Inherit->uMsg : 0);

    InitializeCriticalSection(&NewInfo->SockCritSec);

    InsertSocketInfo(Provider, NewInfo);

    return NewInfo;
}

//
// Function: InsertSocketInfo
//
// Description:
//    We keep track of all the sockets created for a particulare provider.
//    This routine inserts a newly created socket (and its SOCK_INFO) into
//    the list.
//
void InsertSocketInfo(PROVIDER *provider, SOCK_INFO *sock)
{
    EnterCriticalSection(&provider->ProviderCritSec);

    if (!provider || !sock)
    {
        dbgprint("InsertSocketInfo: PROVIDER or SOCK_INFO == NULL!");
        LeaveCriticalSection(&provider->ProviderCritSec);
        return;
    }

    sock->next = sock->prev = NULL;

    sock->next = provider->SocketList;
    if (provider->SocketList)
    {
        provider->SocketList->prev = sock;
    }
    provider->SocketList = sock;

    LeaveCriticalSection(&provider->ProviderCritSec);
}

// 
// Function: RemoveSocketInfo
//
// Description:
//    This function removes a given SOCK_INFO structure from the referenced
//    provider. It doesn't free the structure, it just removes it from the 
//    list.
//
void RemoveSocketInfo(PROVIDER *provider, SOCK_INFO *si)
{
    EnterCriticalSection(&provider->ProviderCritSec);
    if (si->prev == NULL)
    {
        provider->SocketList = si->next;
        if (provider->SocketList)
            provider->SocketList->prev = NULL;
    }
    else
    {
        si->prev->next = si->next;
        if (si->next)
            si->next->prev = si->prev;
    }

    LeaveCriticalSection(&provider->ProviderCritSec);
}

void CloseAndFreeSocketInfo(PROVIDER *provider)
{
    SOCK_INFO    *si=NULL,
                 *siprev=NULL;
    struct linger linger;
    int           Error, ret;

    linger.l_onoff = 1;
    linger.l_linger = 0;

    si = provider->SocketList;
    while (si)
    {
        ret = provider->NextProcTable.lpWSPSetSockOpt(
            si->ProviderSocket,
            SOL_SOCKET,
            SO_LINGER,
            (char *)&linger,
            sizeof(linger),
            &Error);
        if (ret == SOCKET_ERROR)
        {
            dbgprint("WSPSetSockOpt(SO_LINGER) failed: %d", Error);
        }
        else
        {
            dbgprint("SO_LINGER set to abortive on socket: %d", si->ProviderSocket);
        }

        ret = provider->NextProcTable.lpWSPCloseSocket(
            si->ProviderSocket,
            &Error);
        if (ret == SOCKET_ERROR)
        {
            dbgprint("WSPCloseSocket() on handle %d failed: %d", si->ProviderSocket, Error);
        }
        else
        {
            dbgprint("Successfully closed socket %d", si->ProviderSocket);
        }

        MainUpCallTable.lpWPUCloseSocketHandle(
            si->LayeredSocket, 
            &Error);

        siprev = si;
        si = si->next;

        HeapFree(hLspHeap, 0, siprev);
    }
    return;
}

//
// Function: GetCallerSocket
//
// Description:
//    This function returns the SOCK_INFO structure for the given
//    provider socket. If provider is NULL then we'll search all
//    providers for the socket info.
//
SOCK_INFO *GetCallerSocket(PROVIDER *provider, SOCKET ProviderSock)
{
    SOCK_INFO *si;

    EnterCriticalSection(&gCriticalSection);

    if (provider)
    {
        si = provider->SocketList;
        while(si)
        {
            if (si->ProviderSocket == ProviderSock)
            {
                LeaveCriticalSection(&gCriticalSection);
                return si;
            }
            si = si->next;
        }
    }
    else
    {
        for(INT i=0; i < gLayerCount ;i++)
        {
            si = gBaseInfo[i].SocketList;
            while (si)
            {
                if (si->ProviderSocket == ProviderSock)
                {
                    LeaveCriticalSection(&gCriticalSection);
                    return si;
                }
                si = si->next;
            }
        }
    }

    LeaveCriticalSection(&gCriticalSection);
    return NULL;
}

⌨️ 快捷键说明

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