typedef struct _GUID
{
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID, *PGUID;
const GUID DiskClassGuid = {0x53f56307L, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b)};
DEFINE_GUID(DiskClassGuid, 0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
// SetupDiGetInterfaceDeviceDetail所需要的輸出長度,定義足夠大
#define INTERFACE_DETAIL_SIZE (1024)
// 根據GUID獲得設備路徑
// lpGuid: GUID指針
// pszDevicePath: 設備路徑指針的指針
// 返回: 成功得到的設備路徑個數,可能不止1個
int GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath)
{
HDEVINFO hDevInfoSet;
SP_DEVICE_INTERFACE_DATA ifdata;
PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail;
int nCount;
BOOL bResult;
// 取得一個該GUID相關的設備信息集句柄
hDevInfoSet = ::SetupDiGetClassDevs(lpGuid, // class GUID
NULL, // 無關鍵字
NULL, // 不指定父窗口句柄
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的設備
// 失敗...
if (hDevInfoSet == INVALID_HANDLE_VALUE)
{
return 0;
}
// 申請設備接口數據空間
pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE);
pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
nCount = 0;
bResult = TRUE;
// 設備序號=0,1,2... 逐一測試設備接口,到失敗爲止
while (bResult)
{
ifdata.cbSize = sizeof(ifdata);
// 枚舉符合該GUID的設備接口
bResult = ::SetupDiEnumDeviceInterfaces(
hDevInfoSet, // 設備信息集句柄
NULL, // 不需額外的設備描述
lpGuid, // GUID
(ULONG)nCount, // 設備信息集裏的設備序號
&ifdata); // 設備接口信息
if (bResult)
{
// 取得該設備接口的細節(設備路徑)
bResult = SetupDiGetInterfaceDeviceDetail(
hDevInfoSet, // 設備信息集句柄
&ifdata, // 設備接口信息
pDetail, // 設備接口細節(設備路徑)
INTERFACE_DETAIL_SIZE, // 輸出緩衝區大小
NULL, // 不需計算輸出緩衝區大小(直接用設定值)
NULL); // 不需額外的設備描述
if (bResult)
{
// 複製設備路徑到輸出緩衝區
::strcpy(pszDevicePath[nCount], pDetail->DevicePath);
// 調整計數值
nCount++;
}
}
}
// 釋放設備接口數據空間
::GlobalFree(pDetail);
// 關閉設備信息集句柄
::SetupDiDestroyDeviceInfoList(hDevInfoSet);
return nCount;
}
int i;
char* szDevicePath[MAX_DEVICE]; // 設備路徑
// 分配需要的空間
for (i = 0; i < MAX_DEVICE; i++)
{
szDevicePath[i] = new char[256];
}
// 取設備路徑
nDevice = ::GetDevicePath((LPGUID)&DiskClassGuid, szDevicePath);
// 逐一獲取設備信息
for (i = 0; i < nDevice; i++)
{
// 打開設備
hDevice = ::OpenDevice(szDevicePath[i]);
if (hDevice != INVALID_HANDLE_VALUE)
{
... ... // I/O操作
::CloseHandle(hDevice);
}
}
// 釋放空間
for (i = 0; i & lt; MAX_DEVICE; i++)
{
delete []szDevicePath[i];
}
// IOCTL控制碼
#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)
// 存儲設備的總線類型
typedef enum _STORAGE_BUS_TYPE {
BusTypeUnknown = 0x00,
BusTypeScsi,
BusTypeAtapi,
BusTypeAta,
BusType1394,
BusTypeSsa,
BusTypeFibre,
BusTypeUsb,
BusTypeRAID,
BusTypeMaxReserved = 0x7F
} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE;
// 查詢存儲設備屬性的類型
typedef enum _STORAGE_QUERY_TYPE {
PropertyStandardQuery = 0, // 讀取描述
PropertyExistsQuery, // 測試是否支持
PropertyMaskQuery, // 讀取指定的描述
PropertyQueryMaxDefined // 驗證數據
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;
// 查詢存儲設備還是適配器屬性
typedef enum _STORAGE_PROPERTY_ID {
StorageDeviceProperty = 0, // 查詢設備屬性
StorageAdapterProperty // 查詢適配器屬性
} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;
// 查詢屬性輸入的數據結構
typedef struct _STORAGE_PROPERTY_QUERY {
STORAGE_PROPERTY_ID PropertyId; // 設備/適配器
STORAGE_QUERY_TYPE QueryType; // 查詢類型
UCHAR AdditionalParameters[1]; // 額外的數據(僅定義了象徵性的1個字節)
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
// 查詢屬性輸出的數據結構
typedef struct _STORAGE_DEVICE_DESCRIPTOR {
ULONG Version; // 版本
ULONG Size; // 結構大小
UCHAR DeviceType; // 設備類型
UCHAR DeviceTypeModifier; // SCSI-2額外的設備類型
BOOLEAN RemovableMedia; // 是否可移動
BOOLEAN CommandQueueing; // 是否支持命令隊列
ULONG VendorIdOffset; // 廠家設定值的偏移
ULONG ProductIdOffset; // 產品ID的偏移
ULONG ProductRevisionOffset; // 產品版本的偏移
ULONG SerialNumberOffset; // 序列號的偏移
STORAGE_BUS_TYPE BusType; // 總線類型
ULONG RawPropertiesLength; // 額外的屬性數據長度
UCHAR RawDeviceProperties[1]; // 額外的屬性數據(僅定義了象徵性的1個字節)
} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;
// 取設備屬性信息
// hDevice -- 設備句柄
// pDevDesc -- 輸出的設備描述和屬性信息緩衝區指針(包含連接在一起的兩部分)
BOOL GetDriveProperty(HANDLE hDevice, PSTORAGE_DEVICE_DESCRIPTOR pDevDesc)
{
STORAGE_PROPERTY_QUERY Query; // 查詢輸入參數
DWORD dwOutBytes; // IOCTL輸出數據長度
BOOL bResult; // IOCTL返回值
// 指定查詢方式
Query.PropertyId = StorageDeviceProperty;
Query.QueryType = PropertyStandardQuery;
// 用IOCTL_STORAGE_QUERY_PROPERTY取設備屬性信息
bResult = ::DeviceIoControl(hDevice, // 設備句柄
IOCTL_STORAGE_QUERY_PROPERTY, // 取設備屬性信息
&Query, sizeof(STORAGE_PROPERTY_QUERY), // 輸入數據緩衝區
pDevDesc, pDevDesc->Size, // 輸出數據緩衝區
&dwOutBytes, // 輸出數據長度
(LPOVERLAPPED)NULL); // 用同步I/O
return bResult;
}
[相關資源]
0
收藏
推薦專欄更多
猜你喜歡
掃一掃,領取大禮包
Ctrl+Enter 發佈
發佈
取消