核心流程
SetupDiGetClassDevs(&GUID_DEVCLASS_CDROM, ...) 取得裝置資訊集合。
SetupDiEnumDeviceInfo 逐一列舉。
SetupDiGetDeviceRegistryProperty(..., SPDRP_FRIENDLYNAME, ...) 取得裝置友善名稱。
常用裝置類別 GUID (devguid.h)
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_MODEM // Modem
GUID_DEVCLASS_MOUSE // 滑鼠/指標裝置
GUID_DEVCLASS_NET // 網路裝置
GUID_DEVCLASS_USB // USB 控制器
GUID_DEVCLASS_FLOPPYDISK // 軟碟機
GUID_DEVCLASS_UNKNOWN // 未知裝置
GUID_DEVCLASS_SCSIADAPTER // SCSI/RAID 控制器
GUID_DEVCLASS_HDC // IDE ATA/ATAPI 控制器
GUID_DEVCLASS_PORTS // 連接埠 (COM/LPT)
GUID_DEVCLASS_MONITOR // 監視器
完整列舉程式碼
#include <windows.h>
#include <stdio.h>
#include <setupapi.h>
#include <devguid.h>
#include <regstr.h>
#pragma comment(lib, "setupapi.lib")
void main() {
HDEVINFO hDevInfo = SetupDiGetClassDevs((LPGUID)&GUID_DEVCLASS_CDROM, 0, 0, DIGCF_PRESENT);
if (hDevInfo == INVALID_HANDLE_VALUE) return;
SP_DEVINFO_DATA did = { sizeof(SP_DEVINFO_DATA) };
char buffer[2048];
DWORD bufSize, dataType, i;
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &did); i++) {
bufSize = sizeof(buffer);
while (!SetupDiGetDeviceRegistryProperty(hDevInfo, &did, SPDRP_FRIENDLYNAME,
&dataType, (PBYTE)buffer, bufSize, &bufSize)) {
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// 理論上需重新分配緩衝區,此處固定 2048 通常足夠
} else break;
}
if (i == 0) printf("<光碟機>\n");
printf("%s\n", buffer);
}
if (i > 0) printf("光碟機>\n");
SetupDiDestroyDeviceInfoList(hDevInfo);
}
擴展應用
- 將
GUID_DEVCLASS_CDROM 替換為其他 GUID 即可列舉對應裝置。
- 屬性代碼
SPDRP_FRIENDLYNAME 可換為 SPDRP_DEVICEDESC (描述)、SPDRP_HARDWAREID (硬體 ID)、SPDRP_LOCATION_INFORMATION (位置) 等。
- 搭配
SetupDiGetDeviceRegistryProperty 取得 SPDRP_CLASS 可驗證裝置類別。
錯誤處理要點
ERROR_INSUFFICIENT_BUFFER:增加緩衝區重試。
ERROR_NO_MORE_ITEMS:列舉結束,正常。
- 其他錯誤碼需記錄並中斷。