📄 addfilter.c
字号:
/*++
Copyright (C) Microsoft Corporation, 1999 - 1999
Module Name:
addfilter.c
Abstract:
This command line utility adds and removes upper filter drivers
for a given drive or volume
Author:
Benjamin Strautin (t-bensta)
Environment:
User mode only
Notes:
- the filter is not checked for validity before it is added to the driver
stack; if an invalid filter is added, the device may no longer be
accessible.
- all code works irrespective of character set (ANSI, Unicode, ...)
Revision History:
05-24-99 : created
--*/
#include <windows.h>
#include <stdio.h>
#include <malloc.h>
// defines GUID
#include <initguid.h>
// the SetupDiXXX api (from the DDK)
#include <setupapi.h>
// defines guids for device classes (DiskClassGuid, etc)
#include <devioctl.h>
#include <ntddstor.h>
// for all of the _t stuff (to allow compiling for both Unicode/Ansi)
#include <tchar.h>
#if DBG
#include <assert.h>
#define ASSERT(condition) assert(condition)
#else
#define ASSERT(condition)
#endif
BOOLEAN
AddFilterDriver(
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData,
IN LPTSTR Filter,
IN BOOLEAN UpperFilter
);
BOOLEAN
RemoveFilterDriver(
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData,
IN LPTSTR Filter,
IN BOOLEAN UpperFilter
);
void
PrintFilters(
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData,
IN BOOLEAN UpperFilters
);
LPTSTR
GetFilters(
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData,
IN BOOLEAN UpperFilters
);
void PrintDeviceName(
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData
);
BOOLEAN
DeviceNameMatches(
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData,
IN LPTSTR DeviceName
);
PBYTE
GetDeviceRegistryProperty(
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData,
IN DWORD Property,
OUT PDWORD PropertyRegDataType
);
BOOLEAN
RestartDevice(
IN HDEVINFO DeviceInfoSet,
IN OUT PSP_DEVINFO_DATA DeviceInfoData
);
BOOLEAN
PrependSzToMultiSz(
IN LPTSTR SzToPrepend,
IN OUT LPTSTR *MultiSz
);
size_t
MultiSzLength(
IN LPTSTR MultiSz
);
size_t
MultiSzSearchAndDeleteCaseInsensitive(
IN LPTSTR FindThis,
IN LPTSTR FindWithin,
OUT size_t *NewStringLength
);
void
PrintUsage();
// To add/remove filter drivers:
// - use SetupDiGetClassDevs to get a list of devices of the given interface
// class
// - use SetupDiEnumDeviceInfo to enumerate the items in that list and
// obtain a SP_DEVINFO_DATA
// - use SetupDiGetDeviceRegistryProperty to get the list of filter drivers
// - add/remove items in the filter list
// - use SetupDiSetDeviceRegistryProperty to put the list back in place
// To restart the device:
// - use SetupDiCallClassInstaller with DIF_PROPERTYCHANGE and DICS_STOP to
// stop the device
// - use SetupDiCallClassInstaller with DIF_PROPERTYCHANGE and DICS_START to
// restart the device
int __cdecl _tmain(int argc, _TCHAR ** argv, _TCHAR ** envp)
{
// these two constants are used to help enumerate through the list of all
// disks and volumes on the system. Adding another GUID should "just work"
static const GUID * deviceGuids[] = {
&DiskClassGuid,
&VolumeClassGuid,
&CdRomClassGuid
};
static const int numdeviceGuids = sizeof(deviceGuids) / sizeof(LPGUID);
// structs needed to contain information about devices
HDEVINFO devInfo = INVALID_HANDLE_VALUE;
SP_DEVINFO_DATA devInfoData;
// indices for stepping through devices, and device interface guids
int argIndex;
int devGuidIndex;
int deviceIndex;
// variables used to deal with the command-line options of this program
BOOLEAN listDevices = FALSE;
BOOLEAN upperFilter = TRUE;
LPTSTR deviceName = NULL;
LPTSTR filterToAdd = NULL;
LPTSTR filterToRemove = NULL;
BOOLEAN keepGoing = TRUE;
BOOLEAN needReboot = FALSE;
BOOLEAN deviceMatch = FALSE;
////////////////////////////////////////////////
// parse arguments; nothing too exciting here //
////////////////////////////////////////////////
if( argc < 2 || _tcscmp(argv[1], _T("/?")) == 0 )
{
PrintUsage();
return (0);
}
argIndex=1;
for (argIndex = 1; argIndex < argc; argIndex++) {
if( _tcscmp(argv[argIndex], _T("/listdevices")) == 0 ) {
listDevices = TRUE;
} else if( _tcscmp(argv[argIndex], _T("/lower")) == 0 ) {
upperFilter = FALSE;
printf("Using Lower Filters\n");
} else if( _tcscmp(argv[argIndex], _T("/device")) == 0 ) {
argIndex++;
if( argIndex < argc ) {
deviceName = argv[argIndex];
} else {
PrintUsage();
return (0);
}
} else if( _tcscmp(argv[argIndex], _T("/add")) == 0 ) {
argIndex++;
if( argIndex<argc ) {
filterToAdd = argv[argIndex];
} else {
PrintUsage();
return (0);
}
} else if( _tcscmp(argv[argIndex], _T("/remove")) == 0 ) {
argIndex++;
if( argIndex<argc ) {
filterToRemove = argv[argIndex];
} else {
PrintUsage();
return (0);
}
} else {
PrintUsage();
return (0);
}
}
//////////////////////////////////////////////////////
// done parsing arguments, move onto the good stuff //
//////////////////////////////////////////////////////
// This outer loop steps through the array of device guid pointers that is
// defined above main(). It was just the easiest way to deal with both
// Disks and Volumes (and it is easy to add other types of devices)
for(devGuidIndex = 0; devGuidIndex<numdeviceGuids; devGuidIndex++) {
// get a list of devices which support the given interface
devInfo = SetupDiGetClassDevs( deviceGuids[devGuidIndex],
NULL,
NULL,
DIGCF_PROFILE |
DIGCF_DEVICEINTERFACE |
DIGCF_PRESENT );
if( devInfo == INVALID_HANDLE_VALUE ) {
printf("got INVALID_HANDLE_VALUE!\n");
return (1);
}
// as per DDK docs on SetupDiEnumDeviceInfo
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
// step through the list of devices for this handle
// get device info at index deviceIndex, the function returns FALSE
// when there is no device at the given index.
for( deviceIndex=0;
SetupDiEnumDeviceInfo( devInfo, deviceIndex, &devInfoData );
deviceIndex++ ) {
// setting this variable to FALSE will cause all of the if
// statements to fall through, cutting off processing for this
// device.
keepGoing = TRUE;
// if a device name was specified, and it doesn't match this one,
// stop. If there is a match (or no name was specified), mark that
// there was a match.
if( deviceName != NULL &&
!DeviceNameMatches( devInfo, &devInfoData, deviceName )
) {
keepGoing = FALSE;
} else {
deviceMatch = TRUE;
}
// print the device name
if( keepGoing && listDevices ) {
PrintDeviceName( devInfo, &devInfoData );
}
// print the drivers, if we are not adding or removing one
if( keepGoing && filterToAdd == NULL && filterToRemove == NULL ) {
PrintFilters( devInfo, &devInfoData, upperFilter );
}
// add the filter, then try to restart the device
if( keepGoing && filterToAdd != NULL ) {
if( !AddFilterDriver(devInfo,
&devInfoData,
filterToAdd,
upperFilter)) {
printf("Unable to add filter!\n");
} else {
if( !RestartDevice( devInfo, &devInfoData) ) {
needReboot = TRUE;
}
}
}
// remove the filter, then try to restart the device
if( keepGoing && filterToRemove != NULL ) {
if( !RemoveFilterDriver(devInfo,
&devInfoData,
filterToRemove,
upperFilter)) {
printf("Unable to remove filter!\n");
} else {
if( !RestartDevice( devInfo, &devInfoData) ) {
needReboot = TRUE;
}
}
}
if( listDevices )
{
printf("\n");
}
// end of main processing loop
}
// clean up the device list
if( devInfo != INVALID_HANDLE_VALUE ) {
if( !SetupDiDestroyDeviceInfoList( devInfo ) ) {
printf("unable to delete device info list! error: %u\n",
GetLastError());
}
}
} // loop for each GUID index
if( !deviceMatch ) {
printf("No devices matched that name\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -