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

📄 addfilter.c

📁 Addfilter is a command-line application which adds and removes filter drivers for a given drive or v
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++

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
AddUpperFilterDriver(
    IN HDEVINFO DeviceInfoSet,
    IN PSP_DEVINFO_DATA DeviceInfoData,
    IN LPTSTR Filter
    );

BOOLEAN
RemoveUpperFilterDriver(
    IN HDEVINFO DeviceInfoSet,
    IN PSP_DEVINFO_DATA DeviceInfoData,
    IN LPTSTR Filter
    );

void
PrintUpperFilters(
    IN HDEVINFO DeviceInfoSet,
    IN PSP_DEVINFO_DATA DeviceInfoData
    );

LPTSTR
GetUpperFilters(
    IN HDEVINFO DeviceInfoSet,
    IN PSP_DEVINFO_DATA DeviceInfoData
    );

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
    };
    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;

    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;

    if( argIndex<argc && _tcscmp(argv[argIndex], _T("/listdevices")) == 0 )
    {
        listDevices = TRUE;
        argIndex++;
    }

    if( argIndex<argc && _tcscmp(argv[argIndex], _T("/device")) == 0 )
    {
        argIndex++;
        if( argIndex<argc )
        {
            deviceName = argv[argIndex];
        }
        else
        {
            PrintUsage();
            return (0);
        }
        argIndex++;
    }

    if( argIndex<argc && _tcscmp(argv[argIndex], _T("/add")) == 0 )
    {
        argIndex++;
        if( argIndex<argc )
        {
            filterToAdd = argv[argIndex];
        }
        else
        {
            PrintUsage();
            return (0);
        }
        argIndex++;
    }

    if( argIndex<argc && _tcscmp(argv[argIndex], _T("/remove")) == 0 )
    {
        argIndex++;
        if( argIndex<argc )
        {
            filterToRemove = argv[argIndex];
        }
        else
        {
            PrintUsage();
            return (0);
        }
        argIndex++;
    }

    if( argIndex<argc )
    {
        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 )
            {
                PrintUpperFilters( devInfo, &devInfoData );
            }

            // add the filter, then try to restart the device
            if( keepGoing && filterToAdd != NULL )
            {
                if( !AddUpperFilterDriver( devInfo,
                                           &devInfoData,
                                           filterToAdd ) )
                {
                    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( !RemoveUpperFilterDriver( devInfo,
                                              &devInfoData,
                                              filterToRemove ) )
                {
                    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());
            }

⌨️ 快捷键说明

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