基於Visual C++之Windows核心程式設計程式碼分析(1)實現裝置管理器列舉裝置
阿新 • • 發佈:2018-11-12
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
我們進行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); } else break; }// 輸出 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;}