📄 instlsp.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: 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 + -