📄 addfilter.c
字号:
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(¶ms, 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) ¶ms,
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) ¶ms,
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 + -