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

📄 addfilter.c

📁 Addfilter is a command-line application which adds and removes filter drivers for a given drive or v
💻 C
📖 第 1 页 / 共 3 页
字号:
            if( _tcsncmp(deviceName, _T("\\Device"), 7) == 0 )
            {
                memmove(deviceName,
                        deviceName+7,
                        (_tcslen(deviceName)-6)*sizeof(_TCHAR) );
            }

            // do the strings match?
            matching = (_tcscmp(deviceName, DeviceName) == 0);
        }
        free( deviceName );
    }
    else
    {
        printf("in DeviceNameMatches(): registry key is NULL!\n");
        matching = FALSE;
    }

    return (matching);
}

/*
 * A wrapper around SetupDiGetDeviceRegistryProperty, so that I don't have to
 * deal with memory allocation anywhere else
 *
 * parameters:
 *   DeviceInfoSet  - The device information set which contains DeviceInfoData
 *   DeviceInfoData - Information needed to deal with the given device
 *   Property       - which property to get (SPDRP_XXX)
 *   PropertyRegDataType - the type of registry property
 */
PBYTE
GetDeviceRegistryProperty(
    IN HDEVINFO DeviceInfoSet,
    IN PSP_DEVINFO_DATA DeviceInfoData,
    IN DWORD Property,
    OUT PDWORD PropertyRegDataType
    )
{
    DWORD length = 0;
    PBYTE buffer = NULL;

    // get the required length of the buffer
    if( SetupDiGetDeviceRegistryProperty( DeviceInfoSet,
                                          DeviceInfoData,
                                          Property,
                                          NULL,   // registry data type
                                          NULL,   // buffer
                                          0,      // buffer size
                                          &length // required size
        ) )
    {
        // we should not be successful at this point, so this call succeeding
        // is an error condition
        printf("in GetDeviceRegistryProperty(): "
               "call SetupDiGetDeviceRegistryProperty did not fail\n",
               GetLastError());
        return (NULL);
    }

    if( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
    {
        // this means there are no upper filter drivers loaded, so we can just
        // return.
        return (NULL);
    }

    // since we don't have a buffer yet, it is "insufficient"; we allocate
    // one and try again.
    buffer = malloc( length );
    if( buffer == NULL )
    {
        printf("in GetDeviceRegistryProperty(): "
               "unable to allocate memory!\n");
        return (NULL);
    }
    if( !SetupDiGetDeviceRegistryProperty( DeviceInfoSet,
                                           DeviceInfoData,
                                           Property,
                                           PropertyRegDataType,
                                           buffer,
                                           length,
                                           NULL // required size
        ) )
    {
        printf("in GetDeviceRegistryProperty(): "
               "couldn't get registry property! error: %i\n",
               GetLastError());
        free( buffer );
        return (NULL);
    }

    // ok, we are finally done, and can return the buffer
    return (buffer);
}


/*
 * restarts the given device
 *
 * call CM_Query_And_Remove_Subtree (to unload the driver)
 * call CM_Reenumerate_DevNode on the _parent_ (to reload the driver)
 *
 * parameters:
 *   DeviceInfoSet  - The device information set which contains DeviceInfoData
 *   DeviceInfoData - Information needed to deal with the given device
 */
BOOLEAN
RestartDevice(
    IN HDEVINFO DeviceInfoSet,
    IN OUT PSP_DEVINFO_DATA DeviceInfoData
    )
{
    SP_PROPCHANGE_PARAMS params;
    SP_DEVINSTALL_PARAMS installParams;

    // for future compatibility; this will zero out the entire struct, rather
    // than just the fields which exist now
    memset(&params, 0, sizeof(SP_PROPCHANGE_PARAMS));

    // initialize the SP_CLASSINSTALL_HEADER struct at the beginning of the
    // SP_PROPCHANGE_PARAMS struct, so that SetupDiSetClassInstallParams will
    // work
    params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
    params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;

    // initialize SP_PROPCHANGE_PARAMS such that the device will be stopped.
    params.StateChange = DICS_STOP;
    params.Scope       = DICS_FLAG_CONFIGSPECIFIC;
    params.HwProfile   = 0; // current profile

    // prepare for the call to SetupDiCallClassInstaller (to stop the device)
    if( !SetupDiSetClassInstallParams( DeviceInfoSet,
                                       DeviceInfoData,
                                       (PSP_CLASSINSTALL_HEADER) &params,
                                       sizeof(SP_PROPCHANGE_PARAMS)
        ) )
    {
        printf("in RestartDevice(): couldn't set the install parameters!");
        printf(" error: %u\n", GetLastError());
        return (FALSE);
    }

    // stop the device
    if( !SetupDiCallClassInstaller( DIF_PROPERTYCHANGE,
                                    DeviceInfoSet,
                                    DeviceInfoData )
        )
    {
        printf("in RestartDevice(): call to class installer (STOP) failed!");
        printf(" error: %u\n", GetLastError() );
        return (FALSE);
    }

    // restarting the device
    params.StateChange = DICS_START;

    // prepare for the call to SetupDiCallClassInstaller (to stop the device)
    if( !SetupDiSetClassInstallParams( DeviceInfoSet,
                                       DeviceInfoData,
                                       (PSP_CLASSINSTALL_HEADER) &params,
                                       sizeof(SP_PROPCHANGE_PARAMS)
        ) )
    {
        printf("in RestartDevice(): couldn't set the install parameters!");
        printf(" error: %u\n", GetLastError());
        return (FALSE);
    }

    // restart the device
    if( !SetupDiCallClassInstaller( DIF_PROPERTYCHANGE,
                                    DeviceInfoSet,
                                    DeviceInfoData )
        )
    {
        printf("in RestartDevice(): call to class installer (START) failed!");
        printf(" error: %u\n", GetLastError());
        return (FALSE);
    }

    installParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);

    // same as above, the call will succeed, but we still need to check status
    if( !SetupDiGetDeviceInstallParams( DeviceInfoSet,
                                        DeviceInfoData,
                                        &installParams )
        )
    {
        printf("in RestartDevice(): couldn't get the device install params!");
        printf(" error: %u\n", GetLastError() );
        return (FALSE);
    }

    // to see if the machine needs to be rebooted
    if( installParams.Flags & DI_NEEDREBOOT )
    {
        return (FALSE);
    }

    // if we get this far, then the device has been stopped and restarted
    return (TRUE);
}


/*
 * prepend the given string to a MultiSz
 *
 * returns true if successful, false if not (will only fail in memory
 * allocation)
 *
 * note: This WILL allocate and free memory, so don't keep pointers to the
 * MultiSz passed in.
 *
 * parameters:
 *   SzToPrepend - string to prepend
 *   MultiSz     - pointer to a MultiSz which will be prepended-to
 */
BOOLEAN
PrependSzToMultiSz(
    IN     LPTSTR  SzToPrepend,
    IN OUT LPTSTR *MultiSz
    )
{
    size_t szLen;
    size_t multiSzLen;
    LPTSTR newMultiSz = NULL;

    ASSERT(SzToPrepend != NULL);
    ASSERT(MultiSz != NULL);

    // get the size, in bytes, of the two buffers
    szLen = (_tcslen(SzToPrepend)+1)*sizeof(_TCHAR);
    multiSzLen = MultiSzLength(*MultiSz)*sizeof(_TCHAR);
    newMultiSz = (LPTSTR)malloc( szLen+multiSzLen );

    if( newMultiSz == NULL )
    {
        return (FALSE);
    }

    // recopy the old MultiSz into proper position into the new buffer.
    // the (char*) cast is necessary, because newMultiSz may be a wchar*, and
    // szLen is in bytes.

    memcpy( ((char*)newMultiSz) + szLen, *MultiSz, multiSzLen );

    // copy in the new string
    _tcscpy( newMultiSz, SzToPrepend );

    free( *MultiSz );
    *MultiSz = newMultiSz;

    return (TRUE);
}


/*
 * returns the length (in characters) of the buffer required to hold this
 * MultiSz, INCLUDING the trailing null.
 *
 * example: MultiSzLength("foo\0bar\0") returns 9
 *
 * note: since MultiSz cannot be null, a number >= 1 will always be returned
 *
 * parameters:
 *   MultiSz - the MultiSz to get the length of
 */
size_t
MultiSzLength(
    IN LPTSTR MultiSz
    )
{
    size_t len = 0;
    size_t totalLen = 0;

    ASSERT( MultiSz != NULL );

    // search for trailing null character
    while( *MultiSz != _T('\0') )
    {
        len = _tcslen(MultiSz)+1;
        MultiSz += len;
        totalLen += len;
    }

    // add one for the trailing null character
    return (totalLen+1);
}


/*
 * Deletes all instances of a string from within a multi-sz.
 *
 * parameters:
 *   FindThis        - the string to find and remove
 *   FindWithin      - the string having the instances removed
 *   NewStringLength - the new string length
 */
size_t
MultiSzSearchAndDeleteCaseInsensitive(
    IN  LPTSTR FindThis,
    IN  LPTSTR FindWithin,
    OUT size_t *NewLength
    )
{
    LPTSTR search;
    size_t currentOffset;
    DWORD  instancesDeleted;
    size_t searchLen;

    ASSERT(FindThis != NULL);
    ASSERT(FindWithin != NULL);
    ASSERT(NewLength != NULL);

    currentOffset = 0;
    instancesDeleted = 0;
    search = FindWithin;

    *NewLength = MultiSzLength(FindWithin);

    // loop while the multisz null terminator is not found
    while ( *search != _T('\0') )
    {
        // length of string + null char; used in more than a couple places
        searchLen = _tcslen(search) + 1;

        // if this string matches the current one in the multisz...
        if( _tcsicmp(search, FindThis) == 0 )
        {
            // they match, shift the contents of the multisz, to overwrite the
            // string (and terminating null), and update the length
            instancesDeleted++;
            *NewLength -= searchLen;
            memmove( search,
                     search + searchLen,
                     (*NewLength - currentOffset) * sizeof(TCHAR) );
        }
        else
        {
            // they don't mactch, so move pointers, increment counters
            currentOffset += searchLen;
            search        += searchLen;
        }
    }

    return (instancesDeleted);
}


/*
 * print usage
 */
void PrintUsage()
{
    printf("usage:\n\n"
           "addfilter"
           " [/listdevices]"
           " [/device device_name]"
           " [/add filter]"
           " [/remove filter]"
           " [/lower]"
           "\n\n");
    printf("If device_name is not supplied, settings will apply "
           "to all devices.\n");
    printf("If there is no /add or /remove argument, a list of currently"
           " installed drivers\n"
           "will be printed.\n");
    printf("The default is to process upper filters.  Use the /lower switch"
           " to process lower filters instead.\n");
    return;
}

⌨️ 快捷键说明

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