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

来源:互联网 发布:致远oaa8 v5数据字典 编辑:程序博客网 时间:2024/05/05 16:16

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

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

 

 

#include <windows.h>#include <setupapi.h>#include <stdio.h>#include <devguid.h>#include <regstr.h>/* 函数声明 */BOOL EnumPresentDevice( const GUID * InterfaceClassGuid );BOOL EnumAllDevice();/************************************** BOOL EnumClassDevice( const GUID * InterfaceClassGuid )* 功能根据类型列举当前存在的设备* 参数InterfaceClassGuid,所需列举设备接口类的GUID**************************************/BOOL EnumClassDevice( const GUID * InterfaceClassGuid ){HDEVINFO DeviceInfoSet;HDEVINFO NewDeviceInfoSet;SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;PSP_DEVICE_INTERFACE_DETAIL_DATA lpDeviceInterfaceDetailData;DWORD dwBufferSize = 0;DWORD i;// 创建空设备信息列表DeviceInfoSet = SetupDiCreateDeviceInfoList(NULL, NULL);if(DeviceInfoSet == INVALID_HANDLE_VALUE) {printf("CreateDeviceInfoList failed: %d\n", GetLastError());return 0;}// 根据接口类型获得新的设备信息列表NewDeviceInfoSet = SetupDiGetClassDevsEx(InterfaceClassGuid,NULL,NULL,DIGCF_PRESENT | DIGCF_DEVICEINTERFACE,DeviceInfoSet,// 之前创建的设备信息列表NULL,NULL);if(NewDeviceInfoSet == INVALID_HANDLE_VALUE){printf( "SetupDiGetClassDevsEx failed: %d\n", GetLastError() );return 0;}// 设置 SP_DEVICE_INTERFACE_DATA 大小DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);for (i=0; ;i++){// 列举接口信息BOOL bResult = SetupDiEnumDeviceInterfaces(NewDeviceInfoSet,NULL,InterfaceClassGuid,i,&DeviceInterfaceData);if(!bResult){if ( GetLastError()!=NO_ERROR &&GetLastError()!=ERROR_NO_MORE_ITEMS ){printf("ERROR: (%d)",GetLastError());return FALSE;}break;}else{// 为PSP_DEVICE_INTERFACE_DETAIL_DATA结构分配内存,填充lpDeviceInterfaceDetailData = HeapAlloc(GetProcessHeap(), 0,sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA));lpDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);dwBufferSize = lpDeviceInterfaceDetailData->cbSize;// 获得接口详细信息while(!SetupDiGetDeviceInterfaceDetail(NewDeviceInfoSet,&DeviceInterfaceData,lpDeviceInterfaceDetailData,dwBufferSize,&dwBufferSize,NULL)){// 如果内存空间不足,再次分配,直到可以成功调用if(ERROR_INSUFFICIENT_BUFFER==GetLastError()){lpDeviceInterfaceDetailData = HeapReAlloc(GetProcessHeap(), 0, lpDeviceInterfaceDetailData, dwBufferSize);lpDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);}               }// 显示信息printf("DevicePath: %s\n",lpDeviceInterfaceDetailData->DevicePath);// lpDeviceInterfaceDetailData->DevicePath可作为CreateFile的参数,进行IO控制// 释放内存HeapFree(GetProcessHeap(),0,lpDeviceInterfaceDetailData);}}SetupDiDestroyDeviceInfoList(DeviceInfoSet);return TRUE;}/************************************** BOOL EnumAllDevice( )* 功能列举当前存在的设备* 返回值是否成功**************************************/BOOL EnumAllDevice(){HDEVINFO hDevInfo;SP_DEVINFO_DATA DeviceInfoData;DWORD i;printf("Displaying the Installed Devices\n\n");// 得到所有设备 HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL,0, // 无类型0, // 无回调函数DIGCF_PRESENT | DIGCF_ALLCLASSES );if (hDevInfo == INVALID_HANDLE_VALUE){return FALSE;}// 循环列举DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,&DeviceInfoData);i++){DWORD DataT;LPTSTR buffer = NULL;DWORD buffersize = 0;// 获取详细信息while (!SetupDiGetDeviceRegistryProperty(hDevInfo,&DeviceInfoData,SPDRP_DEVICEDESC,&DataT,(PBYTE)buffer,buffersize,&buffersize)){if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){// 内存不足if (buffer) HeapFree(GetProcessHeap(), 0, buffer);buffer = (LPTSTR)HeapAlloc(GetProcessHeap(), 0,  buffersize);}elsebreak;}// 输出printf("GUID:{%.8X-%.4X-%.4X--%.2X%.2X-%.2X%.2X%.2X%.2X%.2X%.2X} ""Device: %s\n",DeviceInfoData.ClassGuid.Data1,DeviceInfoData.ClassGuid.Data2,DeviceInfoData.ClassGuid.Data3,DeviceInfoData.ClassGuid.Data4[0],DeviceInfoData.ClassGuid.Data4[1],DeviceInfoData.ClassGuid.Data4[2],DeviceInfoData.ClassGuid.Data4[3],DeviceInfoData.ClassGuid.Data4[4],DeviceInfoData.ClassGuid.Data4[5],DeviceInfoData.ClassGuid.Data4[6],DeviceInfoData.ClassGuid.Data4[7],buffer);if (buffer) HeapFree(GetProcessHeap(), 0, buffer);}if ( GetLastError()!=NO_ERROR &&GetLastError()!=ERROR_NO_MORE_ITEMS ){return FALSE;}//  释放SetupDiDestroyDeviceInfoList(hDevInfo);return TRUE;}int main( int argc, char *argv[ ], char *envp[ ] ){// 列举所有设备printf("Enumerating All Device\n\n");EnumAllDevice();// 列举磁盘分卷驱动器设备printf("\n\nEnumerating Present Volume \n\n");EnumClassDevice(&GUID_DEVINTERFACE_VOLUME);return 0;}


 

原创粉丝点击