|
阅读:1998回复:3
怎么在驱动里实现U盘的re-plug?
希望对已经插入的U盘进行re-plug,或者相当于把U盘设备重启。使我的过滤驱动能不用重启就挂接上去。
DDK的src\storage\filters\addfilter中,用SetupApi可以实现这样的功能。但怎么在驱动内实现? SetupAPI实现的原理怎么样? 以下为addfilter中的代码 /*
* 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);
} |
|
|
沙发#
发布于:2008-07-01 09:26
SetupAPI的原理是用SetupDiCallClassInstaller切换设备的状态,相当于在设备管理器中,把设备禁用一下,然后再启用一下.
|
|
|
板凳#
发布于:2008-09-03 16:29
关注中~~
|
|
|
驱动小牛
|
地板#
发布于:2008-09-04 11:13
关注中...
|