SetupDiGetClassDevs:取得裝置資訊集合 (依類別 GUID)。SetupDiEnumDeviceInfo:列舉集合中每個裝置。SetupDiSetClassInstallParams + SetupDiCallClassInstaller:發送 DIF_PROPERTYCHANGE 啟用/禁用。| 裝置類別 | GUID |
|---|---|
| 軟碟機控制器 | {4D36E980-E325-11CE-BFC1-08002BE10318} |
| 光碟機 | {4D36E965-E325-11CE-BFC1-08002BE10318} |
| USB 控制器 | {36FC9E60-C465-11CF-8056-444553540000} |
更多 GUID 見 devguid.h 或登錄表 HKLM\SYSTEM\CurrentControlSet\Control\Class\。
#include <windows.h>
#include <setupapi.h>
#include <shlwapi.h>
#pragma comment(lib, "setupapi.lib")
#pragma comment(lib, "shlwapi.lib")
void FormatMsg(DWORD err, LPTSTR* msg) {
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, err, MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), (LPTSTR)msg, 0, NULL);
if (!*msg) { // 嘗試 netmsg.dll
HMODULE h = LoadLibraryEx(_T("netmsg.dll"), NULL, DONT_RESOLVE_DLL_REFERENCES);
if (h) {
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM,
h, err, MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), (LPTSTR)msg, 0, NULL);
FreeLibrary(h);
}
}
}
BOOL ChangeStatus(DWORD newState, DWORD index, HDEVINFO hDevInfo) {
SP_PROPCHANGE_PARAMS pcp = { sizeof(SP_CLASSINSTALL_HEADER) };
SP_DEVINFO_DATA did = { sizeof(SP_DEVINFO_DATA) };
HCURSOR hCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
if (!SetupDiEnumDeviceInfo(hDevInfo, index, &did)) { FormatMsg(GetLastError(), msg); throw msg; }
pcp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
pcp.Scope = DICS_FLAG_GLOBAL;
pcp.StateChange = newState; // DICS_ENABLE / DICS_DISABLE
if (!SetupDiSetClassInstallParams(hDevInfo, &did, (SP_CLASSINSTALL_HEADER*)&pcp, sizeof(pcp))) { FormatMsg(GetLastError(), msg); throw msg; }
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &did)) { FormatMsg(GetLastError(), msg); throw msg; }
SetCursor(hCur);
return TRUE;
}
bool ControlDisk(int action, int devType) {
// action: 1=啟用, 0=禁用, -1=不處理
// devType: 0=軟碟機, 1=光碟機, 2=USB
if (action == -1) return false;
const TCHAR* guids[] = {
_T("4D36E980-E325-11CE-BFC1-08002BE10318"), // FDC
_T("4D36E965-E325-11CE-BFC1-08002BE10318"), // CDROM
_T("36FC9E60-C465-11CF-8056-444553540000") // USB
};
if (devType < 0 || devType > 2) return false;
GUID guid; UuidFromString((RPC_CSTR)guids[devType], &guid);
HDEVINFO hDevInfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT);
if (hDevInfo == INVALID_HANDLE_VALUE) return false;
SP_DEVINFO_DATA did = { sizeof(SP_DEVINFO_DATA) };
for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &did); ++i) {
ChangeStatus(action ? DICS_ENABLE : DICS_DISABLE, i, hDevInfo);
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return true;
}
ControlDisk(1, 2) 才能成功啟用 (原因未深究,可能需重新列舉)。FormatMessage 取得系統中文化說明。