基于Visual C++之Windows核心编程代码分析(1)实现设备管理器枚举设备

我们进行Windows编程的时候,有些时候需要枚举设备,例如光盘,光驱,硬盘等等,

我们如何实现功能呢,请见代码分析

 

 

[cpp]  view plain  copy
  1. #include <windows.h>  
  2. #include <setupapi.h>  
  3. #include <stdio.h>  
  4. #include <devguid.h>  
  5. #include <regstr.h>  
  6. /* 函数声明 */  
  7. BOOL EnumPresentDevice( const GUID * InterfaceClassGuid );  
  8. BOOL EnumAllDevice();  
  9. /************************************* 
  10. * BOOL EnumClassDevice( const GUID * InterfaceClassGuid ) 
  11. * 功能    根据类型列举当前存在的设备 
  12. * 参数    InterfaceClassGuid,所需列举设备接口类的GUID 
  13. **************************************/  
  14. BOOL EnumClassDevice( const GUID * InterfaceClassGuid )  
  15.   
  16. {  
  17.     HDEVINFO DeviceInfoSet;  
  18.     HDEVINFO NewDeviceInfoSet;  
  19.   
  20.     SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;  
  21.     PSP_DEVICE_INTERFACE_DETAIL_DATA lpDeviceInterfaceDetailData;  
  22.   
  23.     DWORD dwBufferSize = 0;  
  24.     DWORD i;  
  25.     // 创建空设备信息列表  
  26.     DeviceInfoSet = SetupDiCreateDeviceInfoList(NULL, NULL);  
  27.   
  28.     if(DeviceInfoSet == INVALID_HANDLE_VALUE)   
  29.     {  
  30.         printf("CreateDeviceInfoList failed: %d\n", GetLastError());  
  31.         return 0;  
  32.     }  
  33.   
  34.     // 根据接口类型获得新的设备信息列表  
  35.   
  36.     NewDeviceInfoSet = SetupDiGetClassDevsEx(  
  37.         InterfaceClassGuid,  
  38.         NULL,  
  39.         NULL,  
  40.         DIGCF_PRESENT | DIGCF_DEVICEINTERFACE,  
  41.         DeviceInfoSet,// 之前创建的设备信息列表  
  42.         NULL,  
  43.         NULL  
  44.         );  
  45.     if(NewDeviceInfoSet == INVALID_HANDLE_VALUE)  
  46.     {  
  47.         printf( "SetupDiGetClassDevsEx failed: %d\n", GetLastError() );  
  48.         return 0;  
  49.     }  
  50.     // 设置 SP_DEVICE_INTERFACE_DATA 大小  
  51.     DeviceInterfaceData.cbSize   
  52.         = sizeof(SP_DEVICE_INTERFACE_DATA);  
  53.   
  54.     for (i=0; ;i++)  
  55.     {  
  56.         // 列举接口信息  
  57.         BOOL bResult = SetupDiEnumDeviceInterfaces(  
  58.             NewDeviceInfoSet,  
  59.             NULL,  
  60.             InterfaceClassGuid,  
  61.             i,  
  62.             &DeviceInterfaceData  
  63.             );  
  64.         if(!bResult)  
  65.         {  
  66.             if ( GetLastError()!=NO_ERROR &&  
  67.                 GetLastError()!=ERROR_NO_MORE_ITEMS )  
  68.             {  
  69.                 printf("ERROR: (%d)",GetLastError());  
  70.                 return FALSE;  
  71.             }  
  72.             break;  
  73.         }  
  74.         else  
  75.         {  
  76.             // 为PSP_DEVICE_INTERFACE_DETAIL_DATA结构分配内存,填充  
  77.             lpDeviceInterfaceDetailData = HeapAlloc(  
  78.                 GetProcessHeap(), 0,  
  79.                 sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA));  
  80.             lpDeviceInterfaceDetailData->cbSize   
  81.                 = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);  
  82.             dwBufferSize = lpDeviceInterfaceDetailData->cbSize;  
  83.             // 获得接口详细信息  
  84.             while(!SetupDiGetDeviceInterfaceDetail(  
  85.                 NewDeviceInfoSet,  
  86.                 &DeviceInterfaceData,  
  87.                 lpDeviceInterfaceDetailData,  
  88.                 dwBufferSize,  
  89.                 &dwBufferSize,  
  90.                 NULL))  
  91.             {  
  92.                 // 如果内存空间不足,再次分配,直到可以成功调用  
  93.                 if(ERROR_INSUFFICIENT_BUFFER==GetLastError())  
  94.                 {  
  95.                     lpDeviceInterfaceDetailData = HeapReAlloc(  
  96.                         GetProcessHeap(), 0,   
  97.                         lpDeviceInterfaceDetailData, dwBufferSize);  
  98.                     lpDeviceInterfaceDetailData->cbSize   
  99.                         = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);  
  100.                 }                 
  101.             }  
  102.             // 显示信息  
  103.             printf("DevicePath: %s\n",lpDeviceInterfaceDetailData->DevicePath);  
  104.             // lpDeviceInterfaceDetailData->DevicePath可作为CreateFile的参数,进行IO控制  
  105.               
  106.             // 释放内存  
  107.             HeapFree(GetProcessHeap(),0,lpDeviceInterfaceDetailData);  
  108.         }  
  109.     }  
  110.     SetupDiDestroyDeviceInfoList(DeviceInfoSet);  
  111.     return TRUE;  
  112. }  
  113. /************************************* 
  114. * BOOL EnumAllDevice( ) 
  115. * 功能    列举当前存在的设备 
  116. * 返回值   是否成功 
  117. **************************************/  
  118. BOOL EnumAllDevice()  
  119. {  
  120.     HDEVINFO hDevInfo;  
  121.     SP_DEVINFO_DATA DeviceInfoData;  
  122.     DWORD i;  
  123.   
  124.     printf("Displaying the Installed Devices\n\n");  
  125.   
  126.     // 得到所有设备 HDEVINFO   
  127.     hDevInfo = SetupDiGetClassDevs(NULL,  
  128.         0, // 无类型  
  129.         0, // 无回调函数  
  130.         DIGCF_PRESENT | DIGCF_ALLCLASSES );  
  131.     if (hDevInfo == INVALID_HANDLE_VALUE)  
  132.     {  
  133.         return FALSE;  
  134.     }  
  135.     // 循环列举  
  136.     DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);  
  137.     for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,  
  138.         &DeviceInfoData);i++)  
  139.     {  
  140.         DWORD DataT;  
  141.         LPTSTR buffer = NULL;  
  142.         DWORD buffersize = 0;  
  143.   
  144.         // 获取详细信息  
  145.         while (!SetupDiGetDeviceRegistryProperty(  
  146.             hDevInfo,  
  147.             &DeviceInfoData,  
  148.             SPDRP_DEVICEDESC,  
  149.             &DataT,  
  150.             (PBYTE)buffer,  
  151.             buffersize,  
  152.             &buffersize))  
  153.         {  
  154.             if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)  
  155.             {  
  156.                 // 内存不足  
  157.                 if (buffer) HeapFree(GetProcessHeap(), 0, buffer);  
  158.                 buffer = (LPTSTR)HeapAlloc(GetProcessHeap(), 0,  buffersize);  
  159.             }  
  160.             else  
  161.                 break;  
  162.         }  
  163. // 输出  
  164.         printf("GUID:{%.8X-%.4X-%.4X--%.2X%.2X-%.2X%.2X%.2X%.2X%.2X%.2X} "  
  165.             "Device: %s\n",  
  166.             DeviceInfoData.ClassGuid.Data1,  
  167.             DeviceInfoData.ClassGuid.Data2,  
  168.             DeviceInfoData.ClassGuid.Data3,  
  169.             DeviceInfoData.ClassGuid.Data4[0],  
  170.             DeviceInfoData.ClassGuid.Data4[1],  
  171.             DeviceInfoData.ClassGuid.Data4[2],  
  172.             DeviceInfoData.ClassGuid.Data4[3],  
  173.             DeviceInfoData.ClassGuid.Data4[4],  
  174.             DeviceInfoData.ClassGuid.Data4[5],  
  175.             DeviceInfoData.ClassGuid.Data4[6],  
  176.             DeviceInfoData.ClassGuid.Data4[7],buffer);  
  177.   
  178.         if (buffer) HeapFree(GetProcessHeap(), 0, buffer);  
  179.     }  
  180.   
  181.     if ( GetLastError()!=NO_ERROR &&  
  182.         GetLastError()!=ERROR_NO_MORE_ITEMS )  
  183.     {  
  184.         return FALSE;  
  185.     }  
  186.     //  释放  
  187.     SetupDiDestroyDeviceInfoList(hDevInfo);  
  188.     return TRUE;  
  189. }  
  190.   
  191. int main( int argc, char *argv[ ], char *envp[ ] )  
  192. {  
  193.     // 列举所有设备  
  194.     printf("Enumerating All Device\n\n");  
  195.     EnumAllDevice();  
  196.     // 列举磁盘分卷驱动器设备  
  197.     printf("\n\nEnumerating Present Volume \n\n");  
  198.     EnumClassDevice(&GUID_DEVINTERFACE_VOLUME);  
  199.     return 0;  
  200. }  
虽然简单,但是实用 HDEVINFO hDevInfo; SP_DEVINFO_DATA DeviceInfoData; DWORD i,j; int ret=0; hDevInfo = SetupDiGetClassDevs((LPGUID) &GUID;_DEVCLASS_MOUSE, 0, 0,DIGCF_PRESENT);//DIGCF_PROFILE);// /*   GUID_DEVCLASS_FDC软盘控制器   GUID_DEVCLASS_DISPLAY显示卡   GUID_DEVCLASS_CDROM光驱   GUID_DEVCLASS_KEYBOARD键盘   GUID_DEVCLASS_COMPUTER计算机   GUID_DEVCLASS_SYSTEM系统   GUID_DEVCLASS_DISKDRIVE磁盘驱动器   GUID_DEVCLASS_MEDIA声音、视频和游戏控制器   GUID_DEVCLASS_MODEMMODEM   GUID_DEVCLASS_MOUSE鼠标和其他指针设备   GUID_DEVCLASS_NET网络设备器   GUID_DEVCLASS_USB通用串行总线控制器   GUID_DEVCLASS_FLOPPYDISK软盘驱动器   GUID_DEVCLASS_UNKNOWN未知设备   GUID_DEVCLASS_SCSIADAPTERSCSI 和 RAID 控制器   GUID_DEVCLASS_HDCIDE ATA/ATAPI 控制器   GUID_DEVCLASS_PORTS端口(COM 和 LPT)   GUID_DEVCLASS_MONITOR监视器   */ if (hDevInfo == INVALID_HANDLE_VALUE){ // Insert error handling here. // return ; } // 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; char buffer[2048]; DWORD buffersize =sizeof(buffer); while (!SetupDiGetDeviceRegistryProperty( hDevInfo, &DeviceInfoData;, SPDRP_FRIENDLYNAME, &DataT;, (PBYTE)buffer, buffersize, &buffersize;)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Change the buffer size. //if (buffer) LocalFree(buffer); //buffer = (PSP_INF_INFORMATION)LocalAlloc(LPTR,buffersize); // <!--[if !supportEmptyParas]--><!--[endif]--> } else { // Insert error handling here. break; } } if (buffer != NULL && i == 0) { // temp.Format(""); // str += temp; } // temp.Format("%s",buffer); // str += temp; if (buffer) LocalFree(buffer); } if (i != 0) { // temp.Format(""); // str += temp; } if ( GetLastError()!=NO_ERROR && GetLastError()!=ERROR_NO_MORE_ITEMS ) { return ; } // <!--[if !supportEmptyParas]--><!--[endif]--> // Cleanup SetupDiDestroyDeviceInfoList(hDevInfo);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值