查询电脑硬盘和盘符的方法各种各样都有,GitHub上也有很多示例项目,
这里只简单介绍使用vds.h中的类和方法查询硬件/盘符信息的一些常使用的结构和方法,包括获取磁盘的大小,分区内容,磁盘对象属性,电脑盘符等;
IVdsDisk 接口 提供查询和配置基本磁盘和动态磁盘的方法。
用于查询磁盘信息,与WMI查询方式相比调用更加复杂,但是可以直接对磁盘进行一系列的操作,比如说格式化磁盘分区,转换磁盘分区样式等;
VDS_DISK_PROP结构 定义 磁盘对象的属性。获取磁盘设备类型,媒体类型,磁盘的大小,字节数,扇区数,轨道数,分区类型,创建的对象的句柄的名称等数据。
多用于获取pwszName来创建句柄对象来获取其他信息,如硬盘柱面数等。
typedef struct _VDS_DISK_PROP {
VDS_OBJECT_ID id;
VDS_DISK_STATUS status;
VDS_LUN_RESERVE_MODE ReserveMode;
VDS_HEALTH health;
DWORD dwDeviceType;
DWORD dwMediaType;
ULONGLONG ullSize;
ULONG ulBytesPerSector;
ULONG ulSectorsPerTrack;
ULONG ulTracksPerCylinder;
ULONG ulFlags;
VDS_STORAGE_BUS_TYPE BusType;
VDS_PARTITION_STYLE PartitionStyle;
union {
DWORD dwSignature;
GUID DiskGuid;
};
LPWSTR pwszDiskAddress;
LPWSTR pwszName;
LPWSTR pwszFriendlyName;
LPWSTR pwszAdaptorName;
LPWSTR pwszDevicePath;
} VDS_DISK_PROP, *PVDS_DISK_PROP;
VDS_PARTITION_PROP 结构 定义分区的属性,获取分区偏移量,分区大小,分区类型,主启动记录。
VDS_PARTITION_PROP 结构需要先获取IVdsAdvancedDisk 接口示例,在通过QueryPartitions方法获取
在一些调用第三方软件需要传入操作分区的时候很有用。以及格式化分区时适用。
typedef struct _VDS_PARTITION_PROP {
VDS_PARTITION_STYLE PartitionStyle;
ULONG ulFlags;
ULONG ulPartitionNumber;
ULONGLONG ullOffset;
ULONGLONG ullSize;
union {
VDS_PARTITION_INFO_MBR Mbr;
VDS_PARTITION_INFO_GPT Gpt;
};
} VDS_PARTITION_PROP;
释放资源宏定义:
#define _SafeRelease(x) {if (NULL != x) { x->Release(); x = NULL; } }
IVdsService* pService= NULL;
IVdsServiceLoader* pLoader= NULL;
IEnumVdsObject* pEnum= NULL;
IUnknown * pUnk= NULL;
ULONG ulFetched=0;
HRESULT hResult = CoCreateInstance(CLSID_VdsLoader,NULL,CLSCTX_LOCAL_SERVER,IID_IVdsServiceLoader,(void **) &pLoader);
if(!SUCCEEDED(hResult))
{
qDebug()<<"CoCreateInstance 服务 VDS未启动 "<<GetLastError();
goto out;
}
hResult = pLoader->LoadService(NULL, &pService);
if(!SUCCEEDED(hResult))
{
qDebug()<<"VDS Service failed !"<<GetLastError();
goto out;
}
hResult = pService->WaitForServiceReady();
if (!SUCCEEDED(hResult))
{
qDebug()<<"VDS Service Loaded failed !"<<GetLastError();
goto out;
}
hResult= pService->QueryProviders( VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum);
if (!SUCCEEDED(hResult))
{
qDebug("Could not query VDS Service Providers: %s",GetLastError());
goto out;
}
while (pEnum->Next( 1, &pUnk, &ulFetched) == S_OK)
{
IVdsProvider* pProvider= NULL;
IVdsSwProvider* pSwProvider= NULL;
IEnumVdsObject* pEnumPack= NULL;
IUnknown* pPackUnk= NULL;
ULONG ulFetched2=0;
hResult = pUnk->QueryInterface(IID_IVdsProvider, (void **)&pProvider);
if (hResult != S_OK) {
qDebug("Could not get VDS Provider: %s", GetLastError());
goto out;
}
// Get VDS Software Provider
hResult = pProvider->QueryInterface(IID_IVdsSwProvider, (void **)&pSwProvider);
_SafeRelease(pProvider);
if (hResult != S_OK) {
qDebug("Could not get VDS Software Provider: %s", GetLastError());
goto out;
}
// Get VDS Software Provider Packs
hResult = pSwProvider->QueryPacks( &pEnumPack);
_SafeRelease(pSwProvider);
if (hResult != S_OK) {
qDebug("Could not get VDS Software Provider Packs: %s", GetLastError());
goto out;
}
while (pEnumPack->Next( 1, &pPackUnk, &ulFetched2) == S_OK)
{
IVdsPack* pPack= NULL;
IEnumVdsObject* pEnumDisk= NULL;
IUnknown* pDiskUnk= NULL;
ULONG ulFetched3=0;
hResult = pPackUnk->QueryInterface(IID_IVdsPack, (void**)&pPack);
if (hResult != S_OK) {
qDebug("Could not query VDS Software Provider Pack: %s", GetLastError());
break;
}
hResult = pPack->QueryDisks(&pEnumDisk);
_SafeRelease(pPack);
if (hResult != S_OK) {
qDebug("Could not query VDS disks: %s", GetLastError());
break;
}
while (pEnumDisk->Next( 1, &pDiskUnk, &ulFetched3) == S_OK)
{
VDS_DISK_PROP prop;
IVdsDisk* pDisk= NULL;
IVdsAdvancedDisk* pAdvancedDisk= NULL;
hResult = pDiskUnk->QueryInterface(IID_IVdsDisk, (void**)&pDisk);
if (hResult != S_OK) {
qDebug("Could not query VDS Disk Interface: %s", GetLastError());
continue;
}
hResult = pDisk->GetProperties(&prop);
if ((hResult != S_OK) && (hResult != VDS_S_PROPERTIES_INCOMPLETE)) {
qDebug("Could not query VDS Disk Properties: %s", GetLastError());
continue;
}
QString PwszName=QString::fromWCharArray(prop.pwszName);
HRESULT hResult= pDisk->QueryInterface(IID_IVdsAdvancedDisk,(void **)&pAdvancedDisk);
if (hResult != S_OK)
{
qDebug("Could not access the requested Disk interface: %s", GetLastError());
continue;
}
VDS_PARTITION_PROP* prop_array = NULL;
LONG prop_size=0;
hResult= pAdvancedDisk->QueryPartitions(&prop_array, &prop_size);
if(hResult != S_OK)
{
qDebug()<<"No partition on disk! ";
continue;
}
}
CoTaskMemFree(prop_array);
_SafeRelease(pDisk);
_SafeRelease(pAdvancedDisk);
}
_SafeRelease(pEnumDisk);
_SafeRelease(pDiskUnk);
}
_SafeRelease(pEnumPack);
_SafeRelease(pPackUnk);
}
out:
_SafeRelease(pService);
_SafeRelease(pLoader);
_SafeRelease(pEnum);
_SafeRelease(pUnk);
IVdsVolume 接口 提供管理卷的方法。
IVdsVolume 与IVdsDisk 接口调用声明方式差不多,只是调用的
pPack->QueryVolumes(&pEnumDisk);
实际使用也很少使用IVdsVolume 接口获取盘符信息
VDS_VOLUME_PROP结构 定义 卷对象的属性,
获取卷的大小,状态,类型,文件系统,卷句柄的名称等
typedef struct _VDS_VOLUME_PROP {
VDS_OBJECT_ID id;
VDS_VOLUME_TYPE type;
VDS_VOLUME_STATUS status;
VDS_HEALTH health;
VDS_TRANSITION_STATE TransitionState;
ULONGLONG ullSize;
ULONG ulFlags;
VDS_FILE_SYSTEM_TYPE RecommendedFileSystemType;
LPWSTR pwszName;
} VDS_VOLUME_PROP, *PVDS_VOLUME_PROP;
IVdsService* pService= NULL;
IVdsServiceLoader* pLoader= NULL;
IEnumVdsObject* pEnum= NULL;
IUnknown * pUnk= NULL;
ULONG ulFetched=0;
HRESULT hResult = CoCreateInstance(CLSID_VdsLoader,NULL,CLSCTX_LOCAL_SERVER,IID_IVdsServiceLoader,(void **) &pLoader);
if(!SUCCEEDED(hResult))
{
qDebug()<<"CoCreateInstance 服务 VDS未启动 "<<GetLastError();
goto out;
}
hResult = pLoader->LoadService(NULL, &pService);
if(!SUCCEEDED(hResult))
{
qDebug()<<"VDS Service failed !"<<GetLastError();
goto out;
}
hResult = pService->WaitForServiceReady();
if (!SUCCEEDED(hResult))
{
qDebug()<<"VDS Service Loaded failed !"<<GetLastError();
goto out;
}
hResult= pService->QueryProviders( VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum);
if (!SUCCEEDED(hResult))
{
qDebug("Could not query VDS Service Providers: %s",GetLastError());
goto out;
}
while (pEnum->Next( 1, &pUnk, &ulFetched) == S_OK)
{
IVdsProvider* pProvider= NULL;
IVdsSwProvider* pSwProvider= NULL;
IEnumVdsObject* pEnumPack= NULL;
IUnknown* pPackUnk= NULL;
ULONG ulFetched2=0;
hResult = pUnk->QueryInterface(IID_IVdsProvider, (void **)&pProvider);
if (hResult != S_OK) {
qDebug("Could not get VDS Provider: %s", GetLastError());
goto out;
}
// Get VDS Software Provider
hResult = pProvider->QueryInterface(IID_IVdsSwProvider, (void **)&pSwProvider);
_SafeRelease(pProvider);
if (hResult != S_OK) {
qDebug("Could not get VDS Software Provider: %s", GetLastError());
goto out;
}
// Get VDS Software Provider Packs
hResult = pSwProvider->QueryPacks( &pEnumPack);
_SafeRelease(pSwProvider);
if (hResult != S_OK) {
qDebug("Could not get VDS Software Provider Packs: %s", GetLastError());
goto out;
}
while (pEnumPack->Next( 1, &pPackUnk, &ulFetched2) == S_OK)
{
IVdsPack* pPack= NULL;
IEnumVdsObject* pEnumDisk= NULL;
IUnknown* pDiskUnk= NULL;
ULONG ulFetched3=0;
hResult = pPackUnk->QueryInterface(IID_IVdsPack, (void**)&pPack);
if (hResult != S_OK) {
qDebug("Could not query VDS Software Provider Pack: %s", GetLastError());
break;
}
hResult = pPack->QueryVolumes(&pEnumDisk);
_SafeRelease(pPack);
if (hResult != S_OK) {
qDebug("Could not query VDS disks: %s", GetLastError());
break;
}
while (pEnumDisk->Next( 1, &pDiskUnk, &ulFetched3) == S_OK)
{
IVdsVolume *pVolume;
VDS_VOLUME_PROP VolumeProps;
hResult = pDiskUnk->QueryInterface(IID_IVdsVolume, (void **)&pVolume);
pDiskUnk->Release();
if (hResult != S_OK) {
qDebug("Could not query VDS Volume Interface: %s", GetLastError());
goto out;
}
hResult = pVolume->GetProperties( &VolumeProps);
if ((hResult != S_OK) && (hResult != VDS_S_PROPERTIES_INCOMPLETE)) {
pVolume->Release();
qDebug("Could not query VDS Volume Properties: %s", GetLastError());
continue;
}
CoTaskMemFree (VolumeProps.pwszName);
_SafeRelease(pVolume);
}
_SafeRelease(pEnumDisk);
_SafeRelease(pDiskUnk);
}
_SafeRelease(pEnumPack);
_SafeRelease(pPackUnk);
}
out:
_SafeRelease(pService);
_SafeRelease(pLoader);
_SafeRelease(pEnum);
_SafeRelease(pUnk);
注:
#添加include 在 #include 前面
添加#include #include
添加#pragma comment(lib,"ole32.lib") 在 #pragma comment(lib,"virtdisk.lib") 前面
添加 #pragma comment(lib, "comsupp.lib") 在 #pragma comment(lib, "wininet.lib") 前面
添加 #pragma comment(lib, "wbemuuid.lib")