Driver Version Check

来源:互联网 发布:西安python初级招聘 编辑:程序博客网 时间:2024/04/30 02:42

Driver Version Check

 

1. Why need this?

 

  NB开发过程中需要多个部门co-work,参与的部门和人员众多,每个部门,每个人的背景认知又有非常多的差异,所以就会产生很多问题。而且我们发现许多问题都是由于大家没有使用同一个环境造成的,最常见的是大家使用的driver的版本不一致,导致了大家看到的行为不一样。所以Driver Version这支tool就应运而生了。

 

2. What can it do

 

   该程序运行之后将会如下图1所示,它会抓取当前系统中正在使用的所有的driverdescription以及version信息,然后按照字母排序并将它们显示出来,它支持按照description中的关键字搜索出结果,而且该程式能够自动探测到设备状态变化进而刷新显示,然后它可以将上述内容保存到文件中方便用户使用比较工具比对。

 

 

 

 

3. How to implement?

 

  各位熟悉driver安装的大牛可能觉得该tooleasy了,嘿嘿小弟driver部分比较弱,所以当初写这个tool的时候,可是费了很多的精力。我最初写这只程式时将注册表中HKEY_LOCAL_MACHINE_SYSTEM_CLASS的所有driver以及version信息都读了个遍,可是后来发现它的version信息与当前正在工作的driver可能不一致,而且有些当前没有被加载的driver也被我抓出来了L,后来又去读WMI中有关pnp的一个class,这次版本对了,又发现只抓到了非常少的一部分L,几经周折总算让我找到了setupdi*这个系列的API,可是这一堆api非常难用,我最初是尝试抓出对应driverinf文件然后读其中的version,结果也是失败了,这个version 也不一定是正在使用的driverversion。最后我几乎要放弃的时候,想起设备管理器可以抓的到呢?于是继续试验最终找到了下述的解决方法J。下面是这支程序的核心部分的sourcecode这份code的流程是这样:先抓出目前系统出存在(DIGCF_PRESENT | DIGCF_ALLCLASSES)的所有device information,然后通过SetupDiGetDeviceRegistryProperty获得Device Description,最后通过SetupDiOpenDevRegKey&RegQueryValueEx获得driver version

 BOOL GetDriverVersion(void)
{
 HDEVINFO hDevInfo;

 SP_DEVINFO_DATA DeviceInfoData;

 DWORD i;

 

 // Create a HDEVINFO with all present devices.

 hDevInfo = SetupDiGetClassDevs(NULL,

  0, // Enumerator

  0,

  DIGCF_PRESENT | DIGCF_ALLCLASSES );

 

 if (hDevInfo == INVALID_HANDLE_VALUE)

 {

  // Insert error handling here.

  return 1;

 }

 

 // Enumerate through all devices in Set.

 

 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

 for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,

  &DeviceInfoData);i++)

 {

  DWORD DataT;

  LPTSTR buffer = NULL;

  DWORD buffersize = 0;

 

  //

  // Call function with null to begin with,

  // then use the returned buffer size

  // to Alloc the buffer. Keep calling until

  // success or an unknown failure.

  //

  while (!SetupDiGetDeviceRegistryProperty(

   hDevInfo,

   &DeviceInfoData,

   SPDRP_DEVICEDESC,

   &DataT,

   (PBYTE)buffer,

   buffersize,

   &buffersize))

  {

   if (GetLastError() ==

    ERROR_INSUFFICIENT_BUFFER)

   {

    // Change the buffer size.

    if (buffer) LocalFree(buffer);

    buffer = (LPTSTR)LocalAlloc(LPTR,buffersize);

   }

   else

   {

    // Insert error handling here.

    break;

   }

  }

 

 

  //query version infor through api recommended by msdn

  CString str;

  DWORD cbsize=MAX_PATH;

  DWORD dwType=REG_SZ;

  if(HKEY hKey=SetupDiOpenDevRegKey(hDevInfo,&DeviceInfoData,DICS_FLAG_GLOBAL, 0,DIREG_DRV ,KEY_ALL_ACCESS))

  {

   LONG    lres=RegQueryValueEx(hKey,"DriverVersion",0,(LPDWORD)&dwType,(LPBYTE)str.GetBuffer(MAX_PATH),(LPDWORD)&cbsize);

   if(lres==ERROR_SUCCESS)

   {

    str.ReleaseBuffer();

    if(!str.IsEmpty())//version exist

    {

     dd.SetDriverDesc(CString(buffer));

     dd.SetDriverVersion(str);

    }    

   }

  }

 

  //}

  if (buffer) LocalFree(buffer);

 }

 

 

 if ( GetLastError()!=NO_ERROR &&

  GetLastError()!=ERROR_NO_MORE_ITEMS )

 {

  // Insert error handling here.

  return 1;

 }

 

 //  Cleanup

 SetupDiDestroyDeviceInfoList(hDevInfo);

 return 0;
}

  

 

Peter