获取WinCE已加载驱动的信息

//=====================================================================
//TITLE:
//    获取WinCE已加载驱动的信息
//AUTHOR:
//    norains
//DATE:
//    Monday 22- February-2010
//Environment:
//     WINDOWS CE 5.0
//=====================================================================

 

     众所周知,WinCE下的驱动,只要不是通过RegisterDevice进行加载,那么我们都能够在注册表找到蛛丝马迹。说明白点,我们只要搜寻HKEY_LOCAL_MACHINE/Driver/Active/下的键值,就知道哪些驱动已经被成功加载,然后再根据其已加载信息,我们就能在BuiltIn获取更多。

 

  所以,本文的立足点,就在于注册表。为了简化操作,关于注册表的操作,我会使用一个CReg类,该类的完全代码可以在此找到:(http://blog.csdn.net/norains/archive/2007/06/20/1659925.aspx
  
  在开始讲述之前,我们先来约定一些数值。因为驱动各有不同,所以所需要的参数是不一致的。但有一些数值,却是必备的:驱动名,驱动前缀,驱动序号,驱动的文件。所以这四个形参我们单独列出来,至于其它的数值,我们之前用map对应即可。因此,我先声明如下一个结构体:  
namespace Device { struct ExtendParam { std::map<TSTRING,DWORD> mpDWORD; std::map<TSTRING,TSTRING> mpSTRING; }; struct DeviceInfo { TSTRING strName; //The driver name. If would be set as the registry key in the Drivers/Builtin/ path. TSTRING strPrefix; //The prefix name. DWORD dwIndex; //The index TSTRING strDll; //The path for the device file. ExtendParam extend; //The extend value would be set to the registry before active the device. }; }
  
  我们获取已加载驱动的函数定义如下:  
BOOL GetActive(std::vector<Device::DeviceInfo> &vtDeviceInfo,Device::CALLBACK_FUNCTION_FOR_RECEIVE_ACTIVE_DEVICE pCallbackFunc)
  
  当函数执行失败,直接返回FALSE;如果执行成功,那么会返回TRUE,并且将信息存储到vtDeviceInfo中。pCallbackFunc是回调函数,每找到一个驱动信息就会调用该函数。如果该函数返回为TRUE,则继续搜索;反之,则停止。如果不使用回调函数,那么直接设置为NULL即可。
  
  关于该回调函数,定义如下:
  namespace Device { //----------------------------------------------------------------------------------------- //Description: // It's the callback funtion for receive active device. // //Parameters: // deviceInfo : [in] The input device information // //Return Values: // If TRUE, it would continue enumerating. If FALSE, it would stop enumerating. //----------------------------------------------------------------------------------------- typedef BOOL (*CALLBACK_FUNCTION_FOR_RECEIVE_ACTIVE_DEVICE)(const DeviceInfo &deviceInfo); };   


  接下来,我们看看GetActive函数的实现部分:
  BOOL GetActive(std::vector<Device::DeviceInfo> &vtDeviceInfo,Device::CALLBACK_FUNCTION_FOR_RECEIVE_ACTIVE_DEVICE pCallbackFunc) { TSTRING strRegDriveActive = TEXT("Drivers//Active//"); //Enumerate the active registry CReg regKey; if(regKey.Open(HKEY_LOCAL_MACHINE,strRegDriveActive.c_str()) == FALSE) { return FALSE; } //Enumerate the key TSTRING strKey; while(regKey.EnumKey(strKey)) { //The registry value TSTRING strRegVal = strRegDriveActive + strKey; Device::DeviceInfo deviceInfo; if(AnalyzeDeviceInfo(strRegVal,deviceInfo) != FALSE) { vtDeviceInfo.push_back(deviceInfo); if(pCallbackFunc != NULL) { if((*pCallbackFunc)(deviceInfo) == FALSE) { break; } } } } return TRUE; }   

  函数意思很明了,无非是枚举Active下的键值,然后将相关信息送到AnalyzeDeviceInfo中进行分析。
  
  AnalyzeDeviceInfo的实现如下:
  BOOL AnalyzeDeviceInfo(const TSTRING &strReg,Device::DeviceInfo &deviceInfo) { CReg reg; if(reg.Open(HKEY_LOCAL_MACHINE,strReg.c_str()) == FALSE) { return FALSE; } TSTRING strKey; std::vector<BYTE>vtData(MAX_PATH,0); DWORD dwType = 0; while(reg.EnumValue(strKey,vtData,dwType) != FALSE) { std::transform(strKey.begin(), strKey.end(), strKey.begin(),toupper); if(strKey == TEXT("KEY")) { AnalyzeBuiltInInfo(ConvertToTSTRING(vtData),deviceInfo); } else if(strKey == TEXT("NAME")) { //Do nothing. } else { AnalyzeExtendParam(deviceInfo.extend,strKey,vtData,dwType); } } return TRUE; }   


  函数也没什么比较晦涩的地方,无非就是列举注册表的数值。不过,这里稍微有点不同,但为KEY值时,我们会将注册表的路径传递给AnalyzeBuiltInInfo函数对BuiltIn字段进行分析。如果是NAME值,那么我们直接忽略过去,因为该数值我们采用的是BuiltIn的子根值。
  
  那么接下来,我们就是看AnalyzeBuiltInInfo函数了:
  BOOL CDevice::AnalyzeBuiltInInfo(const TSTRING &strReg,Device::DeviceInfo &deviceInfo) { CReg reg; if(reg.Open(HKEY_LOCAL_MACHINE,strReg.c_str()) == FALSE) { return FALSE; } //The name TSTRING::size_type stPosBeginCpy = strReg.rfind(TEXT("//")); if(stPosBeginCpy != TSTRING::npos && stPosBeginCpy + 1 != strReg.size()) { stPosBeginCpy += 1; if(stPosBeginCpy != strReg.size()) { deviceInfo.strName.assign(strReg.begin() + stPosBeginCpy,strReg.end()); } } TSTRING strKey; std::vector<BYTE>vtData(MAX_PATH,0); DWORD dwType = 0; while(reg.EnumValue(strKey,vtData,dwType) != FALSE) { std::transform(strKey.begin(), strKey.end(), strKey.begin(),toupper); if(strKey == TEXT("DLL")) { deviceInfo.strDll = ConvertToTSTRING(vtData); } else if(strKey == TEXT("PREFIX")) { deviceInfo.strPrefix = ConvertToTSTRING(vtData); } else if(strKey == TEXT("INDEX")) { DWORD dwVal = 0; memcpy(&dwVal,&vtData[0],sizeof(DWORD)); deviceInfo.dwIndex = dwVal; } else { AnalyzeExtendParam(deviceInfo.extend,strKey,vtData,dwType); } } return TRUE; }

  函数很简单,也只有DLL,Prefix和Index我们才进行分析,其它的就直接丢给AnalyzeExtendParam函数即可。
  
  这里还有一小点,就是ConvertToTSTRING函数的调用。因为对于Win32 API函数来说,返回的是一个VOID指针的缓冲区,如果想转换为UNICODE的字符串,那么我们需要将高位和低位互换。所以,这才有了ConvertToTSTRING函数:
  TSTRING ConvertToTSTRING(const std::vector<BYTE> &vtData) { #ifdef UNICODE //The buffer for storing the converting value std::vector<TCHAR> vtBuf(vtData.size() / 2,0); std::vector<BYTE>::size_type stIndex = 0; while(TRUE) { if(stIndex + 1 > vtData.size()) { break; } //Swap the low and high byte vtBuf[stIndex / 2] = vtData[stIndex + 1] << sizeof(BYTE); vtBuf[stIndex / 2] += vtData[stIndex]; stIndex += 2; } return TSTRING(vtBuf.begin(),vtBuf.end()); #else return &vtData[0]; #endif //#ifdef UNICODE }   

  最后的最后,就是AnalyzeExtendParam函数,也就是最简单的函数了:  
void AnalyzeExtendParam(Device::ExtendParam &extend,const TSTRING &strKey,const std::vector<BYTE> &vtData,DWORD dwType) { switch(dwType) { case REG_SZ: { extend.mpSTRING.insert(std::make_pair(strKey,ConvertToTSTRING(vtData))); break; } case REG_DWORD: { DWORD dwVal = 0; memcpy(&dwVal,&vtData[0],sizeof(DWORD)); extend.mpDWORD.insert(std::make_pair(strKey,dwVal)); break; } } }
  

转载于:https://www.cnblogs.com/wodeyitian/archive/2010/02/22/2460352.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值