Devcon Rescan命令代码实现 使用SetupAPI函数实现设备管理器重新搜索枚举系统子设备
2022-01-27
230
0
在Windows的设备管理器工具栏有一个小电脑的图标,点击后,系统会强制设备管理器树进行更新并重新枚举卸载掉(devcon的remove用法)的设备并安装驱动程序。
这个功能在devcon.exe的源代码中有,其对应的devcon命令为
devcon.exe resan
函数原型:
CM_Locate_DevNode_Ex,获取设备根(pDeviceID=NULL)节点的句柄
CMAPI CONFIGRET WINAPI CM_Locate_DevNode_Ex( OUT PDEVINST pdnDevInst, IN DEVINSTID pDeviceID OPTIONAL, IN ULONG ulFlags, IN HMACHINE hMachine );
CM_Reenumerate_DevNode_Ex,枚举该节点下的所有子设备
CMAPI CONFIGRET WINAPI CM_Reenumerate_DevNode_Ex( IN DEVINST dnDevInst, IN ULONG ulFlags, IN HMACHINE hMachine );
源代码实现:
int cmdRescan(_In_ LPCTSTR BaseName, _In_opt_ LPCTSTR Machine, _In_ DWORD Flags, _In_ int argc, _In_reads_(argc) PTSTR argv[])
/*++
Routine Description:
RESCAN
rescan for new devices
Arguments:
BaseName - name of executable
Machine - machine name, must be NULL
argc/argv - remaining parameters
Return Value:
EXIT_xxxx
--*/
{
//
// reenumerate from the root of the devnode tree
// totally CM based
//
int failcode = EXIT_FAIL;
HMACHINE machineHandle = NULL;
DEVINST devRoot;
UNREFERENCED_PARAMETER(BaseName);
UNREFERENCED_PARAMETER(Flags);
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
if(Machine) {
if(CM_Connect_Machine(Machine,&machineHandle) != CR_SUCCESS) {
return failcode;
}
}
if(CM_Locate_DevNode_Ex(&devRoot,NULL,CM_LOCATE_DEVNODE_NORMAL,machineHandle) != CR_SUCCESS) {
goto final;
}
FormatToStream(stdout,Machine ? MSG_RESCAN : MSG_RESCAN_LOCAL);
if(CM_Reenumerate_DevNode_Ex(devRoot, 0, machineHandle) != CR_SUCCESS) {
goto final;
}
FormatToStream(stdout,MSG_RESCAN_OK);
failcode = EXIT_OK;
final:
if(machineHandle) {
CM_Disconnect_Machine(machineHandle);
}
return failcode;
}