c - Hvordan kan jeg erhverve en diskens identifikator på Windows?

Indlæg af Hanne Mølgaard Plasc

Problem



Hvordan kan jeg hente en disks identifikator på Windows? Dette skal ikke forveksles med volumenidentifikatoren, de er to forskellige ting. Diskidentifikatoren er 4-byte-identifikatoren, der befinder sig i MBR'en (eller 16-byte-identifikatoren, hvis den bruger GPT). Hvis du kører diskpart og spørger detaljerne på en disk, er det værdien mærket 'Disk ID'.


Jeg har gennemgået alle MSDN-dokumenterne, der så relevante, men jeg har ikke fundet noget i stand til at gøre dette; Det er tydeligvis muligt at se, da diskpart er i stand til at få denne værdi fra et eller andet sted.


Jeg kunne altid påberåbe diskpart som en sidste udvej og analysere dens output, men jeg ville helst undgå at gøre det. Er der nogen der ved, hvordan jeg kan få dette nummer programmatisk?

Bedste reference


Du kan bruge Win32\_DiskDrive WMi-klassen og Signature -egenskaben. [5]


Tjek denne prøve App


#include "stdafx.h"
#define \_WIN32\_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>
# pragma comment(lib, "wbemuuid.lib")


#pragma argsused
int main(int argc, char* argv[])
{
    BSTR strNetworkResource;
    //To use a WMI remote connection set localconn to false and configure the values of the pszName, pszPwd and the name of the remote machine in strNetworkResource
    strNetworkResource = L"\\.\root\CIMV2";

    COAUTHIDENTITY *userAcct =  NULL ;
    COAUTHIDENTITY authIdent;

    // Initialize COM. ------------------------------------------

    HRESULT hres;
    hres =  CoInitializeEx(0, COINIT\_MULTITHREADED);
    if (FAILED(hres))
    {
        cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl;
        cout << \_com\_error(hres).ErrorMessage() << endl;
        cout << "press enter to exit" << endl;
        cin.get();      
        return 1;                  // Program has failed.
    }

    // Set general COM security levels --------------------------


        hres =  CoInitializeSecurity(
            NULL,
            -1,                          // COM authentication
            NULL,                        // Authentication services
            NULL,                        // Reserved
            RPC\_C\_AUTHN\_LEVEL\_DEFAULT,   // Default authentication
            RPC\_C\_IMP\_LEVEL\_IMPERSONATE, // Default Impersonation
            NULL,                        // Authentication info
            EOAC\_NONE,                   // Additional capabilities
            NULL                         // Reserved
            );

    if (FAILED(hres))
    {
        cout << "Failed to initialize security. Error code = 0x" << hex << hres << endl;
        cout << \_com\_error(hres).ErrorMessage() << endl;
        CoUninitialize();
        cout << "press enter to exit" << endl;
        cin.get();      
        return 1;                    // Program has failed.
    }

    // Obtain the initial locator to WMI -------------------------

    IWbemLocator *pLoc = NULL;
    hres = CoCreateInstance(CLSID\_WbemLocator, 0, CLSCTX\_INPROC\_SERVER, IID\_IWbemLocator, (LPVOID *) &pLoc);

    if (FAILED(hres))
    {
        cout << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << hres << endl;
        cout << \_com\_error(hres).ErrorMessage() << endl;
        CoUninitialize();       
        cout << "press enter to exit" << endl;
        cin.get();      
        return 1;                 // Program has failed.
    }

    // Connect to WMI through the IWbemLocator::ConnectServer method

    IWbemServices *pSvc = NULL;

        hres = pLoc->ConnectServer(
             \_bstr\_t(strNetworkResource),      // Object path of WMI namespace
             NULL,                    // User name. NULL = current user
             NULL,                    // User password. NULL = current
             0,                       // Locale. NULL indicates current
             NULL,                    // Security flags.
             0,                       // Authority (e.g. Kerberos)
             0,                       // Context object
             &pSvc                    // pointer to IWbemServices proxy
             );

    if (FAILED(hres))
    {
        cout << "Could not connect. Error code = 0x" << hex << hres << endl;    
        cout << \_com\_error(hres).ErrorMessage() << endl;
        pLoc->Release();
        CoUninitialize();
        cout << "press enter to exit" << endl;
        cin.get();          
        return 1;                // Program has failed.
    }

    cout << "Connected to root\CIMV2 WMI namespace" << endl;

    // Set security levels on the proxy -------------------------
        hres = CoSetProxyBlanket(
           pSvc,                        // Indicates the proxy to set
           RPC\_C\_AUTHN\_WINNT,           // RPC\_C\_AUTHN\_xxx
           RPC\_C\_AUTHZ\_NONE,            // RPC\_C\_AUTHZ\_xxx
           NULL,                        // Server principal name
           RPC\_C\_AUTHN\_LEVEL\_CALL,      // RPC\_C\_AUTHN\_LEVEL\_xxx
           RPC\_C\_IMP\_LEVEL\_IMPERSONATE, // RPC\_C\_IMP\_LEVEL\_xxx
           NULL,                        // client identity
           EOAC\_NONE                    // proxy capabilities
        );


    if (FAILED(hres))
    {
        cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl;
        cout << \_com\_error(hres).ErrorMessage() << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        cout << "press enter to exit" << endl;
        cin.get();      
        return 1;               // Program has failed.
    }

    // Use the IWbemServices pointer to make requests of WMI ----

    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery( L"WQL", L"SELECT * FROM Win32\_DiskDrive",
    WBEM\_FLAG\_FORWARD\_ONLY | WBEM\_FLAG\_RETURN\_IMMEDIATELY, NULL, &pEnumerator);

    if (FAILED(hres))
    {
        cout << "ExecQuery failed" << " Error code = 0x"    << hex << hres << endl;
        cout << \_com\_error(hres).ErrorMessage() << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        cout << "press enter to exit" << endl;
        cin.get();      
        return 1;               // Program has failed.
    }

    // Secure the enumerator proxy


        hres = CoSetProxyBlanket(
            pEnumerator,                    // Indicates the proxy to set
            RPC\_C\_AUTHN\_DEFAULT,            // RPC\_C\_AUTHN\_xxx
            RPC\_C\_AUTHZ\_DEFAULT,            // RPC\_C\_AUTHZ\_xxx
            COLE\_DEFAULT\_PRINCIPAL,         // Server principal name
            RPC\_C\_AUTHN\_LEVEL\_PKT\_PRIVACY,  // RPC\_C\_AUTHN\_LEVEL\_xxx
            RPC\_C\_IMP\_LEVEL\_IMPERSONATE,    // RPC\_C\_IMP\_LEVEL\_xxx
            userAcct,                       // client identity
            EOAC\_NONE                       // proxy capabilities
            );



    // Get the data from the WQL sentence
    IWbemClassObject *pclsObj = NULL;
    ULONG uReturn = 0;

    while (pEnumerator)
    {
        HRESULT hr = pEnumerator->Next(WBEM\_INFINITE, 1, &pclsObj, &uReturn);

        if(0 == uReturn || FAILED(hr))
          break;

        VARIANT vtProp;

                hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);// String
                if (!FAILED(hr))
                {
                  if ((vtProp.vt==VT\_NULL) || (vtProp.vt==VT\_EMPTY))
                    wcout << "Name : " << ((vtProp.vt==VT\_NULL) ? "NULL" : "EMPTY") << endl;
                  else
                  if ((vtProp.vt & VT\_ARRAY))
                    wcout << "Name : " << "Array types not supported (yet)" << endl;
                  else
                    wcout << "Name : " << vtProp.bstrVal << endl;
                }
                VariantClear(&vtProp);

                hr = pclsObj->Get(L"Signature", 0, &vtProp, 0, 0);// Uint32
                if (!FAILED(hr))
                {
                  if ((vtProp.vt==VT\_NULL) || (vtProp.vt==VT\_EMPTY))
                    wcout << "Signature : " << ((vtProp.vt==VT\_NULL) ? "NULL" : "EMPTY") << endl;                   
                  else
                  if ((vtProp.vt & VT\_ARRAY))
                    wcout << "Signature : " << "Array types not supported (yet)" << endl;
                  else
                    wcout << "Signature : " << hex << vtProp.uintVal << endl;
                }
                VariantClear(&vtProp);


        pclsObj->Release();
        pclsObj=NULL;
    }

    // Cleanup

    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    if (pclsObj!=NULL)
     pclsObj->Release();

    CoUninitialize();
    cout << "press enter to exit" << endl;
    cin.get();
    return 0;   // Program successfully completed.
}


Denne kode returnerer


Indtast billedbeskrivelse her


Og DiskPart


Indtast billedbeskrivelse her

Andre referencer 1


Du skal kunne bruge WMI til denne opgave. [6]


De data, du søger, er sandsynligvis den i DeviceID medlem af Win32\_DiskDrive-klassen, ellers skal du eksperimentere:) [7]

Andre referencer 2


Hvis du kører følgende kode i kommandolinjen, vises Disk-ID'erne for enheder på systemet:


wmic diskdrive get serialnumber


Bemærk: Hvis eksterne drev som en Pendrive er tilsluttet til din maskine, vil den blive angivet i udgangen af ​​ovenstående kommando.