如何从CoInstaller代码中了解设备是否存在(存在=插入)?

时间:2016-12-15 13:05:22

标签: winapi

Windows设备CoInstaller功能如下所示,来自Microsoft WDK Toaster示例:

extern"C" __declspec(dllexport) DWORD CALLBACK
ToasterCoInstaller (
    __in    DI_FUNCTION               InstallFunction,
    __in    HDEVINFO                  Dis,
    __in    PSP_DEVINFO_DATA          Did,  
    __inout PCOINSTALLER_CONTEXT_DATA Context
    )
{
...
}

我知道Dis和Did对用于识别devnode。即使设备已从系统中拔出(例如拔下USB磁盘),用户仍可能告诉设备管理器显示不存在的设备,然后我们的协同安装程序仍可能从该未插入的设备接收DIS-DID--因为该devnode已在注册表中注册。

所以我的问题很明确,如何从ToasterCoInstaller()确定当前的DIS-DID是指现有设备还是不存在设备?

我能想到的一种方法是使用SetupDiGetClassDevs查找所有DIGCF_PRESENT devnode,然后将它们的Device-instance-id与查询对象进行比较,如果找不到匹配项,我可以推断出查询DIS-DID不存在。

但是有更简洁的方法吗?一些特定的SetupDi ......可以直接告诉答案吗?

1 个答案:

答案 0 :(得分:1)

您需要使用CM_Get_DevNode_Status并使用第三个参数

DEVINST dnDevInst 

使用SP_DEVINFO_DATA.DevInst

  

设备实例的不透明句柄(也称为句柄的句柄)   设备节点)。

     

某些功能,例如SetupDiXxx功能,整体而言   SP_DEVINFO_DATA结构作为识别设备中设备的输入   信息集。其他功能,如CM_Xxx等功能   CM_Get_DevNode_Status,将此DevInst句柄作为输入

ULONG devStatus, devProblemCode;
switch (CM_Get_DevNode_Status(&devStatus, &devProblemCode, Did->DevInst, 0))
{
case CR_SUCCESS:
    if (devStatus & DN_STARTED)
    {
        //present, started;
    }
    break;
case CR_NO_SUCH_DEVNODE:
    // not present
    break;
default:
    // some error
}