作为解决GetVolumeInformation() not reporting FILE_READ_ONLY_VOLUME for a locked SD Card without any file-system的一种方法,我发现Win32_Volume
类有一个Access
uint16
属性:
描述媒体是否可读。此属性继承自CIM_StorageExtent。这可以是以下值之一。
我正在从C ++程序中与WMI进行交互,因此在阅读Access
属性时,我会得到一个VARIANT
结构。
根据文档,VARIANT
包含union
,因此我应首先检查vt
属性以确定其类型。 vt
是VARTYPE
,根据文档是int
。访问vt
属性后,我获得的Access
值为1
,根据文档,该值为空。我可以通过尝试访问大多数未设置的union
成员来确认此结果。
这是一个完整的可运行示例(使用cl /EHsc test.cpp
运行):
#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
int main(int argc, char **argv) {
IWbemLocator *locator = NULL;
IWbemServices *services = NULL;
IEnumWbemClassObject* enumerator = NULL;
IWbemClassObject *classObject = NULL;
if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) return 1;
if (FAILED(CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL))) return 1;
if (FAILED(CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&locator))) return 1;
if (FAILED(locator->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &services))) return 1;
if (FAILED(CoSetProxyBlanket(services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE))) return 1;
if (FAILED(services->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM Win32_Volume"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &enumerator))) return 1;
while (enumerator) {
ULONG code = 0;
if (FAILED(enumerator->Next(WBEM_INFINITE, 1, &classObject, &code))) return 1;
if (code == 0) break;
VARIANT variant;
if (FAILED(classObject->Get(L"DriveLetter", 0, &variant, NULL, NULL))) return 1;
if (variant.bstrVal == NULL) {
VariantClear(&variant);
classObject->Release();
continue;
};
std::wcout << " DriveLetter : " << variant.bstrVal[0] << std::endl;
VariantClear(&variant);
if (FAILED(classObject->Get(L"Access", 0, &variant, NULL, NULL))) return 1;
std::wcout << "Access VARTYPE -> " << variant.vt << std::endl;
VariantClear(&variant);
classObject->Release();
}
enumerator->Release();
services->Release();
locator->Release();
CoUninitialize();
return 0;
}
这是我的系统(Windows 10 Pro x86_64)的示例输出:
DriveLetter : C
Access VARTYPE -> 1
DriveLetter : F
Access VARTYPE -> 1
DriveLetter : E
Access VARTYPE -> 1
我可以访问其他字符串属性,例如DriveLetter
,就好了,这让我觉得我对这个特殊属性做错了。
更新1:看起来我使用任何 uint16
属性获得了相同的结果,但是uint32
没有,uint64
,似乎工作正常。