获取WinCE已加载驱动的信息

来源:互联网 发布:软件破解网站 编辑:程序博客网 时间:2024/05/21 17:19

http://blog.csdn.net/norains/article/details/5317083

//=====================================================================
//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对应即可。因此,我先声明如下一个结构体:  

[cpp] view plaincopyprint?
  1. namespace Device  
  2. {  
  3.  struct ExtendParam  
  4.  {  
  5.   std::map<TSTRING,DWORD> mpDWORD;  
  6.   std::map<TSTRING,TSTRING> mpSTRING;  
  7.   
  8.  };  
  9.   
  10.  struct DeviceInfo  
  11.  {  
  12.   TSTRING strName;  //The driver name. If would be set as the registry key in the Drivers/Builtin/ path.  
  13.   TSTRING strPrefix;  //The prefix name.  
  14.   DWORD dwIndex;   //The index  
  15.   TSTRING strDll;   //The path for the device file.  
  16.   ExtendParam extend;  //The extend value would be set to the registry before active the device.  
  17.       };  
  18.      }  


  
  我们获取已加载驱动的函数定义如下:  

[cpp] view plaincopyprint?
  1. BOOL GetActive(std::vector<Device::DeviceInfo> &vtDeviceInfo,Device::CALLBACK_FUNCTION_FOR_RECEIVE_ACTIVE_DEVICE pCallbackFunc)  


  
  当函数执行失败,直接返回FALSE;如果执行成功,那么会返回TRUE,并且将信息存储到vtDeviceInfo中。pCallbackFunc是回调函数,每找到一个驱动信息就会调用该函数。如果该函数返回为TRUE,则继续搜索;反之,则停止。如果不使用回调函数,那么直接设置为NULL即可。
  
  关于该回调函数,定义如下:
  

[cpp] view plaincopyprint?
  1. namespace Device  
  2. {  
  3.   //-----------------------------------------------------------------------------------------  
  4.  //Description:   
  5.  // It's the callback funtion for receive active device.  
  6.  //   
  7.  //Parameters:   
  8.  // deviceInfo : [in] The input device information  
  9.  //   
  10.  //Return Values:   
  11.  // If TRUE, it would continue enumerating. If FALSE, it would stop enumerating.  
  12.  //-----------------------------------------------------------------------------------------  
  13.  typedef BOOL (*CALLBACK_FUNCTION_FOR_RECEIVE_ACTIVE_DEVICE)(const DeviceInfo &deviceInfo);  
  14.      };  
  15.     


  接下来,我们看看GetActive函数的实现部分:
  

[cpp] view plaincopyprint?
  1. BOOL GetActive(std::vector<Device::DeviceInfo> &vtDeviceInfo,Device::CALLBACK_FUNCTION_FOR_RECEIVE_ACTIVE_DEVICE pCallbackFunc)  
  2. {  
  3.  TSTRING strRegDriveActive = TEXT("Drivers//Active//");  
  4.   
  5.  //Enumerate the active registry   
  6.  CReg regKey;  
  7.  if(regKey.Open(HKEY_LOCAL_MACHINE,strRegDriveActive.c_str()) == FALSE)  
  8.  {  
  9.   return FALSE;  
  10.  }  
  11.   
  12.  //Enumerate the key   
  13.  TSTRING strKey;  
  14.  while(regKey.EnumKey(strKey))  
  15.  {  
  16.   //The registry value   
  17.   TSTRING strRegVal = strRegDriveActive + strKey;  
  18.   
  19.   Device::DeviceInfo deviceInfo;  
  20.   if(AnalyzeDeviceInfo(strRegVal,deviceInfo) != FALSE)  
  21.   {  
  22.    vtDeviceInfo.push_back(deviceInfo);  
  23.   
  24.    if(pCallbackFunc != NULL)  
  25.    {  
  26.     if((*pCallbackFunc)(deviceInfo) == FALSE)  
  27.     {  
  28.      break;  
  29.     }  
  30.    }  
  31.   }  
  32.  }  
  33.   
  34.  return TRUE;  
  35.      }  
  36.     



  函数意思很明了,无非是枚举Active下的键值,然后将相关信息送到AnalyzeDeviceInfo中进行分析。
  
  AnalyzeDeviceInfo的实现如下:
  

[cpp] view plaincopyprint?
  1. BOOL AnalyzeDeviceInfo(const TSTRING &strReg,Device::DeviceInfo &deviceInfo)  
  2. {  
  3.  CReg reg;  
  4.  if(reg.Open(HKEY_LOCAL_MACHINE,strReg.c_str()) == FALSE)  
  5.  {  
  6.   return FALSE;  
  7.  }  
  8.   
  9.  TSTRING strKey;  
  10.  std::vector<BYTE>vtData(MAX_PATH,0);  
  11.  DWORD dwType = 0;  
  12.   
  13.  while(reg.EnumValue(strKey,vtData,dwType) != FALSE)  
  14.  {  
  15.   std::transform(strKey.begin(), strKey.end(), strKey.begin(),toupper);  
  16.   
  17.   if(strKey == TEXT("KEY"))  
  18.   {  
  19.    AnalyzeBuiltInInfo(ConvertToTSTRING(vtData),deviceInfo);  
  20.   }  
  21.   else if(strKey == TEXT("NAME"))  
  22.   {  
  23.    //Do nothing.   
  24.   }  
  25.   else  
  26.   {  
  27.    AnalyzeExtendParam(deviceInfo.extend,strKey,vtData,dwType);  
  28.   }  
  29.   
  30.  }  
  31.   
  32.  return TRUE;  
  33.      }  
  34.     


  函数也没什么比较晦涩的地方,无非就是列举注册表的数值。不过,这里稍微有点不同,但为KEY值时,我们会将注册表的路径传递给AnalyzeBuiltInInfo函数对BuiltIn字段进行分析。如果是NAME值,那么我们直接忽略过去,因为该数值我们采用的是BuiltIn的子根值。
  
  那么接下来,我们就是看AnalyzeBuiltInInfo函数了:
  

[cpp] view plaincopyprint?
  1. BOOL CDevice::AnalyzeBuiltInInfo(const TSTRING &strReg,Device::DeviceInfo &deviceInfo)  
  2. {  
  3.  CReg reg;  
  4.  if(reg.Open(HKEY_LOCAL_MACHINE,strReg.c_str()) == FALSE)  
  5.  {  
  6.   return FALSE;  
  7.  }  
  8.   
  9.  //The name   
  10.  TSTRING::size_type stPosBeginCpy = strReg.rfind(TEXT("//"));  
  11.  if(stPosBeginCpy != TSTRING::npos && stPosBeginCpy + 1 != strReg.size())  
  12.  {  
  13.   stPosBeginCpy += 1;  
  14.   
  15.   if(stPosBeginCpy != strReg.size())  
  16.   {  
  17.    deviceInfo.strName.assign(strReg.begin() + stPosBeginCpy,strReg.end());  
  18.   }  
  19.  }  
  20.   
  21.  TSTRING strKey;  
  22.  std::vector<BYTE>vtData(MAX_PATH,0);  
  23.  DWORD dwType = 0;  
  24.  while(reg.EnumValue(strKey,vtData,dwType) != FALSE)  
  25.  {  
  26.   std::transform(strKey.begin(), strKey.end(), strKey.begin(),toupper);  
  27.   
  28.   if(strKey == TEXT("DLL"))  
  29.   {   
  30.    deviceInfo.strDll = ConvertToTSTRING(vtData);  
  31.   }  
  32.   else if(strKey == TEXT("PREFIX"))  
  33.   {  
  34.    deviceInfo.strPrefix = ConvertToTSTRING(vtData);  
  35.   }  
  36.   else if(strKey == TEXT("INDEX"))  
  37.   {  
  38.    DWORD dwVal = 0;  
  39.    memcpy(&dwVal,&vtData[0],sizeof(DWORD));  
  40.    deviceInfo.dwIndex = dwVal;  
  41.   }  
  42.   else  
  43.   {  
  44.    AnalyzeExtendParam(deviceInfo.extend,strKey,vtData,dwType);  
  45.   }  
  46.  }  
  47.   
  48.  return TRUE;  
  49.      }  

  函数很简单,也只有DLL,Prefix和Index我们才进行分析,其它的就直接丢给AnalyzeExtendParam函数即可。
  
  这里还有一小点,就是ConvertToTSTRING函数的调用。因为对于Win32 API函数来说,返回的是一个VOID指针的缓冲区,如果想转换为UNICODE的字符串,那么我们需要将高位和低位互换。所以,这才有了ConvertToTSTRING函数:
  

[cpp] view plaincopyprint?
  1. TSTRING ConvertToTSTRING(const std::vector<BYTE> &vtData)  
  2. {  
  3. #ifdef UNICODE   
  4.   
  5.  //The buffer for storing the converting value  
  6.  std::vector<TCHAR> vtBuf(vtData.size() / 2,0);  
  7.   
  8.  std::vector<BYTE>::size_type stIndex = 0;   
  9.  while(TRUE)  
  10.  {  
  11.   if(stIndex + 1 > vtData.size())  
  12.   {  
  13.    break;  
  14.   }  
  15.   
  16.   //Swap the low and high byte   
  17.   vtBuf[stIndex / 2] = vtData[stIndex + 1] << sizeof(BYTE);  
  18.   vtBuf[stIndex / 2] += vtData[stIndex];  
  19.   
  20.   stIndex += 2;  
  21.  }  
  22.   
  23.  return TSTRING(vtBuf.begin(),vtBuf.end());  
  24.   
  25. #else   
  26.  return &vtData[0];  
  27. #endif //#ifdef UNICODE   
  28.      }  
  29.     



  最后的最后,就是AnalyzeExtendParam函数,也就是最简单的函数了:  

[cpp] view plaincopyprint?
  1. void AnalyzeExtendParam(Device::ExtendParam &extend,const TSTRING &strKey,const std::vector<BYTE> &vtData,DWORD dwType)  
  2. {  
  3.  switch(dwType)  
  4.  {  
  5.   case REG_SZ:  
  6.   {  
  7.    extend.mpSTRING.insert(std::make_pair(strKey,ConvertToTSTRING(vtData)));  
  8.    break;  
  9.   }  
  10.   case REG_DWORD:  
  11.   {  
  12.    DWORD dwVal = 0;  
  13.    memcpy(&dwVal,&vtData[0],sizeof(DWORD));  
  14.    extend.mpDWORD.insert(std::make_pair(strKey,dwVal));  
  15.    break;  
  16.   }  
  17.  }  
  18.      }  


 

0 0
原创粉丝点击