?? dostorageenum.cpp
字號:
#include "stdafx.h"#include "DoStorageEnum.h"
// SetupDiGetInterfaceDeviceDetail所需要的輸出長度
#define INTERFACE_DETAIL_SIZE (1024)
// IOCTL_STORAGE_GET_MEDIA_TYPES_EX可能返回不止一條DEVICE_MEDIA_INFO,故定義足夠的空間
#define MEDIA_INFO_SIZE (sizeof(GET_MEDIA_TYPES) + sizeof(DEVICE_MEDIA_INFO) * 15)
// 從GUID獲得設備路徑
// lpGuid: GUID指針
// pszDevicePath: 設備路徑指針的指針
// 返回值: 成功得到的設備路徑個數
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;
}
// 打開設備
// pszDevicePath: 設備的路徑
HANDLE OpenDevice(LPCTSTR pszDevicePath)
{
HANDLE hDevice;
// 打開設備
hDevice= ::CreateFile(pszDevicePath, // 設備路徑
GENERIC_READ | GENERIC_WRITE, // 讀寫方式
FILE_SHARE_READ | FILE_SHARE_WRITE, // 共享方式
NULL, // 默認的安全描述符
OPEN_EXISTING, // 創建方式
0, // 不需設置文件屬性
NULL); // 不需參照模板文件
return hDevice;
}
// hDevice -- 設備句柄
// pGeometry -- 參數緩沖區指針
BOOL GetDriveGeometry(HANDLE hDevice, PDISK_GEOMETRY pGeometry)
{
PGET_MEDIA_TYPES pMediaTypes; // 內部用的輸出緩沖區
DWORD dwOutBytes; // 輸出數據長度
BOOL bResult; // DeviceIoControl的返回結果
// 申請內部用的輸出緩沖區
pMediaTypes = (PGET_MEDIA_TYPES)::GlobalAlloc(LMEM_ZEROINIT, MEDIA_INFO_SIZE);
// 用IOCTL_STORAGE_GET_MEDIA_TYPES_EX取介質類型參數
bResult = ::DeviceIoControl(hDevice, // 設備句柄
IOCTL_STORAGE_GET_MEDIA_TYPES_EX, // 取介質類型參數
NULL, 0, // 不需要輸入數據
pMediaTypes, MEDIA_INFO_SIZE, // 輸出數據緩沖區
&dwOutBytes, // 輸出數據長度
(LPOVERLAPPED)NULL); // 用同步I/O
if(bResult)
{
// 注意到結構DEVICE_MEDIA_INFO是在結構DISK_GEOMETRY的基礎上擴充的
// 為簡化程序,用memcpy代替如下多條賦值語句:
// pGeometry->MediaType = (MEDIA_TYPE)pMediaTypes->MediaInfo[0].DeviceSpecific.DiskInfo.MediaType;
// pGeometry->Cylinders = pMediaTypes->MediaInfo[0].DeviceSpecific.DiskInfo.Cylinders;
// pGeometry->TracksPerCylinder = pMediaTypes->MediaInfo[0].DeviceSpecific.DiskInfo.TracksPerCylinder;
// ... ...
::memcpy(pGeometry, pMediaTypes->MediaInfo, sizeof(DISK_GEOMETRY));
}
// 釋放內部緩沖區
::GlobalFree(pMediaTypes);
return bResult;
}
// 取設備屬性信息
// 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;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -