访问Win32_Volume实例

时间:2017-06-22 16:22:45

标签: windows winapi wmi

作为解决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属性以确定其类型。 vtVARTYPE,根据文档是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 ,似乎工作正常。

0 个答案:

没有答案