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

📄 instlsp.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) 1999  Microsoft Corporation.  All Rights Reserved.
//
// Module Name: instlsp.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 an installation program to insert the layered sample
//    into the Winsock catalog of providers.
//    
//
// Compile:
//
//    Compile with the Makefile:
//      nmake /f Makefile
//
// Execute:
//
//    This project produces a executable file instlsp.exe. The installation app
//    allows you to install the LSP over any provider. Note however that if you
//    choose to install over a single provider, you should install over all 
//    providers of that address family (e.g. if you install over UDP, install
//    over TCP and RAW providers as well). The arguments are:
//
//       -i             Install the LSP
//       -r             Remove the LSP
//       -o  CatID      Layer over the given provider (indicated by the catalog id)
//       -a             Install over all providers
//       -p             Print the Winsock catalog (and catalog ids)
//       -l             Print the layered entries only
//       -n "String"    Name of the layered provider (catalog name, not dll name)
//       -f             Remove all layered providers (last ditch recovery)
//
//    For example, first print out the catalog:
//       instlsp.exe -p
//        1001 - MSAFD ATM AAL5
//        1002 - MSAFD Tcpip [TCP/IP]
//        1003 - MSAFD Tcpip [UDP/IP]
//        1004 - MSAFD Tcpip [RAW/IP]
//        1005 - RSVP UDP Service Provider
//        1006 - RSVP TCP Service Provider
//        1019 - MSAFD AppleTalk [ADSP]
//        1020 - MSAFD AppleTalk [ADSP] [Pseudo Stream]
//        1021 - MSAFD AppleTalk [PAP]
//        1022 - MSAFD AppleTalk [RTMP]
//        1023 - MSAFD AppleTalk [ZIP]
//
//    To install over AppleTalk
//       instlsp.exe -i -o 1019 -o 1020 -o 1021 -o 1022 -o 1023 -n "Foobar LSP"
//
//    To remove an LSP:
//       instlsp.exe -r 
//
#include <winsock2.h>
#include <ws2spi.h>

#include <rpc.h>
#include <rpcdce.h>

#include <sporder.h>
#include <winnt.h>
#include <windows.h>

#include "install.h"

#include <stdio.h>
#include <stdlib.h>

#define DEFAULT_PATH_LEN        128
#define MAX_PROVIDERS           256     

//
// Function prototypes
//
void PrintProviders(BOOL bLayeredOnly);
int  InstallProvider(void);
void RemoveProvider(void);
void usage(char *progname);
BOOL IsIdinChain(WSAPROTOCOL_INFOW *pinfo, DWORD Id);
void RemoveAllLayeredEntries();

//
// Global variables
//
static LPWSAPROTOCOL_INFOW ProtocolInfo = NULL;
static DWORD               ProtocolInfoSize = 0;
static INT                 TotalProtocols = 0;
static DWORD               CatalogIdArray[MAX_PROVIDERS],
                           CatalogIdArrayCount = 0;       // How many to install over
static BOOL                bInstall = TRUE;
static WCHAR               wszLSPName[64];

//
// Function: main
//
// Description:
//    Parse the command line arguments and call either the install or remove
//    routine.
//
void _cdecl main(int argc, char *argv[])
{
    WSADATA     wsd;
    BOOL        bOpSpecified = FALSE;
    int         i, j;

    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        fprintf(stderr, "Unable to load Winsock: %d\n", GetLastError());
        return;
    }

    for(i=1; i < argc ;i++)
    {
        if ( (strlen(argv[i]) != 2) &&
             ( (argv[i][0] != '-')    ||
               (argv[i][0] != '/') ) )
        {
            usage(argv[0]);
        }
        switch (tolower(argv[i][1]))
        {
            case 'i':               // install
                bOpSpecified = TRUE;
                bInstall = TRUE;
                break;
            case 'r':               // remove
                bOpSpecified = TRUE;
                bInstall = FALSE;
                break;
            case 'o':               // catalog id (to install over)
                if (i+1 >= argc)
                    usage(argv[0]);
                CatalogIdArray[CatalogIdArrayCount++] = atoi(argv[i+1]);
                i++;
                break;
            case 'p':               // print the catalog
                PrintProviders(FALSE);
                ExitProcess(-1);
                break;
            case 'l':               // print the layered providers only
                PrintProviders(TRUE);
                ExitProcess(0);
                break;
            case 'n':               // name of the LSP to install (not the DLL name)
                if (i+1 >= argc)
                    usage(argv[0]);
                MultiByteToWideChar(CP_ACP, 0, argv[i+1], strlen(argv[i+1]), wszLSPName, 64);
                i++;
                break;
            case 'a':
                ProtocolInfo = GetProviders(&TotalProtocols);
                if (!ProtocolInfo)
                {
                    printf("Unable to enumerate providers!\n");
                    ExitProcess(-1);
                }
                for(j=0; j < TotalProtocols ;j++)
                {
                    CatalogIdArray[CatalogIdArrayCount++] = ProtocolInfo[j].dwCatalogEntryId;
                }
                FreeProviders(ProtocolInfo);
                break;
            case 'f':
                RemoveAllLayeredEntries();
                ExitProcess(0);
            default:
                usage(argv[0]);
                break;
        }
    }
    if (!bOpSpecified)
        usage(argv[0]);

    if (bInstall)
    {
        printf("LSP name is '%S'\n", wszLSPName);
        InstallProvider();
    }
    else
        RemoveProvider();

    WSACleanup();
    return;
}

//
// Function: usage
//
// Description:
//    Prints usage information.
//
void usage(char *progname)
{
    printf("usage: %s -i -r [CatId] -o [CatId] -p\n", progname);
    printf("       -i       Install LSP\n"
           "       -r       Remove LSP\n"
           "       -o CatId Install over specified LSP\n"
           "                This option may be specified multiple times\n"
           "       -a       Install over all providers (base or layered)\n"
           "       -p       Print all layers and their catalog IDs\n"
           "       -l       Print layered providers only\n"
           "       -n Str   Name of LSP\n"
           "       -f       Remove all layered entries\n");
    ExitProcess(-1);
}

//
// Function: PrintProviders
//
// Description: 
//    This function prints out each entry in the Winsock catalog and its
//    catalog ID if the parameter, bLayeredOnly, is FALSE. If TRUE then
//    print only those layered catalog entries.
//
void PrintProviders(BOOL bLayeredOnly)
{

	ProtocolInfo = GetProviders(&TotalProtocols);
    if (!ProtocolInfo)
    {
        return;
    }
    for(int i=0; i < TotalProtocols ;i++)
    {
        if (!bLayeredOnly)
            printf("%04d - %S\n", ProtocolInfo[i].dwCatalogEntryId,
                                  ProtocolInfo[i].szProtocol);
        else if (ProtocolInfo[i].ProtocolChain.ChainLen == LAYERED_PROTOCOL)
            printf("%04d - %S\n", ProtocolInfo[i].dwCatalogEntryId,
                                  ProtocolInfo[i].szProtocol);
    }
    FreeProviders(ProtocolInfo);

    return;
}

//
// Function: InstallProvider
//
// Description:
//   This function installs the provider over the given catalogs.
//
int  InstallProvider(void)
{
    WSAPROTOCOL_INFOW  *OriginalProtocolInfo,
                        DummyProtocolInfo;
    GUID                ProviderChainGuid;
    WCHAR               ChainName[WSAPROTOCOL_LEN+1];
    DWORD               LayeredCatalogId,
                        OriginalCatalogId,
                       *CatalogEntries=NULL,
                        i;
    INT                 j,
                        k,
                        idx,
                        CatIndex,
                        ErrorCode;


	ProtocolInfo = GetProviders(&TotalProtocols);
    //
    // Allocate protocol info structures for each entry we want to layer over
    //
    OriginalProtocolInfo = (WSAPROTOCOL_INFOW *)HeapAlloc(
                                GetProcessHeap(),
                                HEAP_ZERO_MEMORY,
                                sizeof(WSAPROTOCOL_INFOW) * CatalogIdArrayCount);
    if (!OriginalProtocolInfo)
    {
        printf("InstallProviders: HeapAlloc() failed: %d\n", GetLastError());
        FreeProviders(ProtocolInfo);
        return -1;
    }
    //
    // Go through the catalog, and save off the WSAPROTOCOL_INFOW structures for
    // those entries we're layering over.
    //
    idx = 0;
    for(i=0; i < CatalogIdArrayCount ;i++)
    {
        for(j=0; j < TotalProtocols ;j++)
        {
            // See if this is a protocol we're layering over
            //
            if (ProtocolInfo[j].dwCatalogEntryId == CatalogIdArray[i])
            {
                memcpy(&OriginalProtocolInfo[idx],
                       &ProtocolInfo[j],
                        sizeof(WSAPROTOCOL_INFOW));
                //
                // Make our provider a non-IFS handle provider
                //
                OriginalProtocolInfo[idx].dwServiceFlags1 = 
                    ProtocolInfo[j].dwServiceFlags1 & (~XP1_IFS_HANDLES); 
                idx++;

                break;
            }
        }
    }
    // Prepare our dummy (hidden) entry for our LSP
    //  Note that the data contained within this structure is ignored by Winsock.
    //
    memcpy(&DummyProtocolInfo, &OriginalProtocolInfo[0], sizeof(WSAPROTOCOL_INFOW));

    wcsncpy(DummyProtocolInfo.szProtocol, wszLSPName, WSAPROTOCOL_LEN+1);
    DummyProtocolInfo.ProtocolChain.ChainLen = LAYERED_PROTOCOL;
    DummyProtocolInfo.dwProviderFlags |= PFL_HIDDEN;
    //
    // Install the dummy entry 
    //
    if (WSCInstallProvider(&ProviderGuid, PROVIDER_PATH, &DummyProtocolInfo, 1, &ErrorCode) == SOCKET_ERROR)
    {
        printf("WSCInstallProvider() failed: %d\n", ErrorCode);
        return -1;
    }
    //
    // Get the Winsock catalog again so we can find our catalog entry ID.
    // The whole purpose to installing the dummy entry is to obtain a catalog ID
    //  which we'll use in the protocol chains of those entries we're layering over.
    //
    FreeProviders(ProtocolInfo);
    ProtocolInfo = GetProviders(&TotalProtocols);

    for(j=0; j < TotalProtocols ;j++)
    {
        if (!memcmp(&ProtocolInfo[j].ProviderId, &ProviderGuid, sizeof(GUID)))
        {
            LayeredCatalogId = ProtocolInfo[j].dwCatalogEntryId;
            break;
        }
    }
    //
    // Find each entry that we're layering over and fix the protocols chains
    //  to reference our LSP
    //
    for(i=0; i < CatalogIdArrayCount ;i++)
    {
        OriginalCatalogId = OriginalProtocolInfo[i].dwCatalogEntryId;
        //
        // Name our layered entry
        //
        swprintf(ChainName, L"%s over [%s]", wszLSPName, OriginalProtocolInfo[i].szProtocol);
        ChainName[WSAPROTOCOL_LEN] = 0;     // Make sure not to overrun the buffer
        wcsncpy(OriginalProtocolInfo[i].szProtocol, ChainName, WSAPROTOCOL_LEN+1);

        if (OriginalProtocolInfo[i].ProtocolChain.ChainLen == BASE_PROTOCOL)
        {
            // Setup a new protocol chain
            OriginalProtocolInfo[i].ProtocolChain.ChainEntries[1] = OriginalProtocolInfo[i].dwCatalogEntryId;
        }
        else
        {

⌨️ 快捷键说明

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