windows - Null, når du åbner adgangsegenskaben til en Win32\_Volume-instans

Indlæg af Hanne Mølgaard Plasc

Problem



Som en måde at løse GetVolumeInformation () ikke rapportering FILE\_READ\_ONLY\_VOLUME til et låst SD-kort uden filsystem, fandt jeg, at klassen Win32\_Volume har en Access uint16 egenskab, som: [24]



  Beskriver, om medierne er læsbare. Denne ejendom er arvet fra CIM\_StorageExtent. Dette kan være en af ​​følgende værdier.



Jeg interagerer med WMI fra et C ++-program, så når jeg læser egenskaben Access får jeg en VARIANT struktur med resultatet. [25]


Ifølge docs indeholder en VARIANT en union, så jeg skal først kontrollere vt egenskaben for at bestemme dens type. vt er en VARTYPE, som er en int ifølge docs. Den vt -værdi, jeg får efter adgang til egenskaben Access er 1, som igen ifølge dokumenterne er null. Jeg kan bekræfte dette resultat ved at prøve at få adgang til de fleste union medlemmer, som slet ikke er angivet. [26]


Her er et komplet runnable eksempel (køre med 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;
}


Dette er et eksempel output fra mit system (Windows 10 Pro x86\_64):


 DriveLetter : C
Access VARTYPE -> 1
 DriveLetter : F
Access VARTYPE -> 1
 DriveLetter : E
Access VARTYPE -> 1


Jeg kan få adgang til andre strengegenskaber, som DriveLetter, bare fint, hvilket får mig til at tro, at jeg gør noget galt med denne egenskab.


UPDATE 1: Det ser ud til, at jeg får de samme resultater med nogen uint16 ejendom, men ikke med uint32 eller uint64, som synes at fungere fint.

Bedste reference