感觉这篇文章步是我自己写,如果是哪位老大写的,可联系本人,在此对于没有给出原链接深感歉意

 

由于系统加载的流驱动我们不知道其句柄,但是可以通过FindFirstDevice函数来获得。该函数的原型如下:

HANDLE FindFirstDevice(

  DeviceSearchType searchType,

  LPCVOID pvSearchParam,

  PDEVMGR_DEVICE_INFORMATION pdi

);

 

    形参只有三个,很简单。

 

    searchType指示的是pvSearchParam传入的类型,有如下数值可以选择:

     1.DeviceSearchByLegacyNameL"COM*" for all COMx: devices.

     2.DeviceSearchByDeviceNameL"COM*" for all COMx devices.

     3.DeviceSearchByBusNameL"PCI_0_3*" for PCI_0_3_0, PCI_0_3_1 and so on.

     4.DeviceSearchByGuidPointer to a GUID.

     5.DeviceSearchByParentActivation handle value from ActivateDeviceEx.

 

  简单点来说,如果我们传递给pvSearchParam的是"COM1:",那么searchType取值应该为DeviceSearchByLegacyName;如果是"COM1",则为DeviceSearchByDeviceName

  

  Pdi是返回数据的存储缓存。这里有一个小细节需要注意,pdi.dwSize在函数调用前必须要设置,否则函数很可能无法执行成功。

  

  还有一点不要搞混,FindFirstDevice返回的句柄不能直接传递给DeactivateDevice函数,因为该句柄是用来给FindNextDevice使用的,和设备无关。而传递给DeactivateDevice函数的句柄,是pbihDevice成员。

  

  要点我们理清之后,剩下的函数实现就非常简单了。我们声明一个函数名为Unload,它可以智能判断传入的形参是否带":",进而选择相应的搜索方式。闲话不多说,我们来看看该函数的完整实现:

  

view plaincopy to clipboardprint?

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;  

 

}