如何实现设备管理器功能?
枚举设备的方法
众所周知Windows自带的设备管理器是查看设备类型、运行卸载设备、调整设备属性的一个非常实用的工具。为了仿照Windows自带的设备管理器,做出同样的效果,必须解决两个问题:第一、获得系统设备的类型;第二、在每个类型下面枚举出该类型的所有设备对象。在Windows有关设备枚举方面主要有两种函数,一种是以CM_XXX开头的PnP Configuration Manager Functions函数,这种函数中的很多函数现在在MSDN中都不推荐使用了,而代替它的是另一种以SetupDi开头的Device Installation Functions,但是两种类型的函数中都有一定的功能缺陷,需要配合使用才能完成设备枚举的任务。
先解决第一个问题:获得系统设备的类型。先说说如何手工就能获知系统设备的类型,系统设备的类型都存储在注册表中,具体位置在HKEY LOCAL MACHINE/SYSTEM/CurrentControlSet/Control/Class下可以看到有许多很长的字符串,点击任意一个可以看到其中有一个名称为(默认)类型为REG_SZ的项可以看到它的项值就是系统设备的类型,具体在编程时需要用到CM_Enumerate_Classes和SetupDiClassNameFromGuid这两个函数,其中第一个函数主要是枚举出所有系统设备的GUID,就是注册表中很长的字符串,第二个函数则是通过第一个函数枚举的GUID来得到每一个类型的名称。通过这两个函数就可以完成系统设备类型的枚举,具体用法请参照程序或MSDN。
现在就需要根据已经得到的系统设备类型来枚举具体每种类型下的具体设备,即解决第二个问题。枚举每种具体设备对象时主要用到了以下两个函数:SetupDiClassGuidsFromName和SetupDiGetClassDevs,其中第一个主要是根据系统设备类型的名称获得其的GUID,第二个函数根据第一个函数获得的GUID来具体得到每种系统设备类型的设备。通过这两个函数就可以完成具体设备的枚举,具体用法请参照程序或MSDN。
得到了所有的系统设备类型和设备后,为了使自己编制的设备管理器尽量形象上接近Windows自带的设备管理器,还需给每种设备类型和设备前面加上图标,这可以使用SetupDiGetClassImageList来解决,通过这个函数就可以得到和Windows设备管理器相同的图标。
最后将所有的设备类型和具体设备还有图标插入做成树装结构即可实现和Windows设备管理器一样的枚举设备的效果。
调用设备的属性页的方法
上一节主要介绍了如何枚举设备类型及每种具体设备,但是此时从功能上,还仅仅只能看到设备对象,而不能对其进行安装卸载和调整属性。下面将介绍如何实现这些功能。
首先先介绍一下,在设备管理器中每一个设备对象称为一个设备节点,在DDK中有一个DEVNODE的数据结构与其相对应,在编程的时候一个DEVNODE就代表一个设备节点。
在自带的Windows设备管理器中对设备对象的操作都是是在一个属性页上来完成的,但是如何在自己的程序中来实现这个属性页呢?在DDK的API中并没有实现此功能的函数,所以想直接通过编程来实现几乎是不可能的。但是分析Windows设备管理器的devmgr.dll中的函数可以知道在devmgr.dll中提供了一个名为DeviceProperties_RunDLL的函数,可以通过这个函数来实现具体设备对象属性页的显示。
void DeviceProperties_RunDLL( HWND hwndStub, HINSTANCE hAppInstance, LPCTSTR lpCmdLine, int nCmdShow )
This function can be executed by means of a rundll command line and will have the following form: rundll32.exe devmgr.dll, DeviceProperties_RunDLL <options>
Arguments:
hwndStub - Windows handle to receive any message boxes that might appear. hAppInstance - HINSTANCE.
lpCmdLine - Command line options passed in (for example, /DeviceID <device instance Id>).
nCmdShow - Flag that specifies how device manager should be shown when it is opened. It can be one of the SW_ values (for example, SW_SHOW).
上面这一段摘自Microsoft,可以看出这个函数中最重要的参数是lpCmdLine,具体为/DeviceID <device instance Id>,关键是现在需要获得具体设备对象的device instance Id,刚好在DDK中有这个函数CM_Get_DevNode_Registry_Property_Ex可以获得注册表中device instance Id,只需为每个设备对象节点赋一个lpCmdLine参数就可以实现属性页的调用了。具体请参照程序,至此就可以在自己编制的设备管理器中实现设备对象属性页的调用了,也就可以卸载设备和调整设备属性了。
参考资料
1. Enumerate Hardware Devices by Using SetupDi Calls. www.microsoft.com . July 21, 2004
2. Invoke the Device Properties Dialog Box from the Application or from a Command Prompt. www.microsoft.com . July 22, 2004
3. How to Configure Device Manager to Display Detailed Information. www.microsoft.com October 18, 2001
4. www.codeproject.com
5. MSDN Library ------October 2004
6. Windows XP DDK Documentation
本文地址:http://www.45fan.com/dnjc/67539.html