//=====================================================================
//TITLE:
// WinCE驱动的动态卸载
//AUTHOR:
// norains
//DATE:
// Wednesday 21-April-2010
//Environment:
// Windows CE 5.0
//=====================================================================
在之前的一篇《WinCE驱动的动态加载》(http://blog.csdn.net/norains/archive/2010/02/22/5316923.aspx)中有谈到,驱动的卸载可以通过调用DeactivateDevice函数。但在那篇文章中,我们传递给DeactivateDevice函数的句柄形参是ActivateDeviceEx函数返回的。如果不是我们主动调用ActivateDeviceEx函数,而是系统自己加载的驱动,我们能不能动态卸载呢?
答案是肯定的。
难点只在于,我们如何获取已加载的驱动句柄。具体点来说,如果我想卸载串口的驱动,并且我也只知道它名为"COM1:",我如何将它转换为句柄?
其实问题并不难,因为微软早就为我们准备好了,我们只要调用FindFirstDevice函数即可。该函数的原型如下:
HANDLE FindFirstDevice( DeviceSearchType searchType, LPCVOID pvSearchParam, PDEVMGR_DEVICE_INFORMATION pdi);
形参只有三个,很简单。
searchType指示的是pvSearchParam传入的类型,有如下数值可以选择:
1.DeviceSearchByLegacyName:L"COM*" for all COMx: devices.
2.DeviceSearchByDeviceName:L"COM*" for all COMx devices.
3.DeviceSearchByBusName:L"PCI_0_3*" for PCI_0_3_0, PCI_0_3_1 and so on.
4.DeviceSearchByGuid:Pointer to a GUID.
5.DeviceSearchByParent:Activation handle value from ActivateDeviceEx.
简单点来说,如果我们传递给pvSearchParam的是"COM1:",那么searchType取值应该为DeviceSearchByLegacyName;如果是"COM1",则为DeviceSearchByDeviceName。
Pdi是返回数据的存储缓存。这里有一个小细节需要注意,pdi.dwSize在函数调用前必须要设置,否则函数很可能无法执行成功。
还有一点不要搞混,FindFirstDevice返回的句柄不能直接传递给DeactivateDevice函数,因为该句柄是用来给FindNextDevice使用的,和设备无关。而传递给DeactivateDevice函数的句柄,是pbi的hDevice成员。
要点我们理清之后,剩下的函数实现就非常简单了。我们声明一个函数名为Unload,它可以智能判断传入的形参是否带":",进而选择相应的搜索方式。闲话不多说,我们来看看该函数的完整实现:
BOOL Unload(const TSTRING &strDev){ BOOL bRes = FALSE; HANDLE hFind = INVALID_HANDLE_VALUE; __try { if(strDev.empty() != FALSE) { __leave; } //确定搜索的方式 DeviceSearchType searchType; if(strDev[strDev.size() - 1] == ':') { searchType = DeviceSearchByLegacyName; } else { searchType = DeviceSearchByDeviceName; } DEVMGR_DEVICE_INFORMATION devInfo = {0}; devInfo.dwSize = sizeof(devInfo); //寻找驱动的句柄 hFind = FindFirstDevice(searchType,strDev.c_str(),&devInfo); if(hFind == INVALID_HANDLE_VALUE) { __leave; } //卸载驱动 bRes = DeactivateDevice(devInfo.hDevice); } __finally { FindClose(hFind); } return bRes;}
函数写完之后,剩下的事情就异常简单了。比如我们需要卸载设备的串口驱动,只要简单地写下这行代码:
Unload(TEXT("COM1:"));
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow