none
Help on code to edit BCD data using WMI APIs

    Question

  • Hi,

    I need to edit VISTA based BCD store file using WMI APIs provided by Microsoft. My goal is to modify the given BCD file and edit osdevice and device attributes to replace WinPE.wim ramdisk file name with some given .wim file name.

    Currently I have implemented below partial code in C++ which reads BCD file and successfully loads BcdStore class object out of that. But after that I cannot get BcdObject instance for the BCD identifier. And I guess I would need BcdObject instance to set the required attribute values.

    O/P of the program is:

    M:\>MyBCDedit.exe

    Connected to WMI

    IWbemClassObject retrieved.

    Parameter to OpenStore Created.

    Exec Method OpenStore successful.

    Got BCD Store object.

    OpenObject method found.

    Parameter setting worked for OpenObject method.

    OpenObject method failed to execute. Hex:8004102f

     

    Execute call for OpenObject method of BcdStore class fails.

    hr = pSvc->ExecMethod(bstrObjectName, bstrMthdName, 0, NULL, pInParam, &pOutParam, &pCallResult);


    It would be grateful if someone can provide help on how to edit attribute values of BCD using WMI APIs.

    Thanks.

    ------------

    #define _WIN32_DCOM
    #include <iostream>
    using namespace std;
    #include <wbemidl.h>
    # pragma comment(lib, "wbemuuid.lib")


    int main()
    {

        // 1. Initialize COM with a call to CoInitializeEx.
        HRESULT hr;
        hr = CoInitializeEx(0, COINIT_MULTITHREADED);
        if (FAILED(hr))
        {
            cout << "Failed to initialize COM library. Error code = 0x"<< hex << hr << endl;
            return hr;
        }

        // 2. Set the general COM security levels with a call to the CoInitializeSecurity interface.
        hr =  CoInitializeSecurity(
        NULL,                      // Security descriptor   
        -1,                        // COM negotiates authentication service
        NULL,                      // Authentication services
        NULL,                      // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication level for proxies
        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation level for proxies
        NULL,                        // Authentication info
        EOAC_NONE,                   // Additional capabilities of the client or server
        NULL);                       // Reserved

        if (FAILED(hr))
        {
            cout << "Failed to initialize security. Error code = 0x" << hex << hr << endl;
            CoUninitialize();
            return hr;                  // Program has failed.
        }

        // 3. Initialize the IWbemLocator interface through a call to CoCreateInstance.

        IWbemLocator *pLoc = 0;

        hr = CoCreateInstance(CLSID_WbemLocator, 0,
            CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
     
        if (FAILED(hr))
        {
            cout << "Failed to create IWbemLocator object. Err code = 0x"<< hex << hr << endl;
            CoUninitialize();
            return hr;     // Program has failed.
        }

        // 4. Connect to WMI through a call to the IWbemLocator::ConnectServer method.
        IWbemServices *pSvc = 0;

        // Connect to the root\default namespace with the current user.
        hr = pLoc->ConnectServer(BSTR(L"root\\wmi"), NULL, NULL, 0, NULL, 0, 0, &pSvc);

        if (FAILED(hr))
        {
            cout << "Could not connect. Error code = 0x"
                 << hex << hr << endl;
            pLoc->Release();
            CoUninitialize();
            return hr;      // Program has failed.
        }
        else
            cout << "Connected to WMI" << endl;


        // 5. Setting the Security Levels on a WMI Connection

        HRESULT hres;
        // Set the proxy so that impersonation of the client occurs.
        hres = CoSetProxyBlanket(pSvc,
           RPC_C_AUTHN_WINNT,
           RPC_C_AUTHZ_NONE,
           NULL,
           RPC_C_AUTHN_LEVEL_CALL,
           RPC_C_IMP_LEVEL_IMPERSONATE,
           NULL,
           EOAC_NONE
        );

        if (FAILED(hres))
        {
            cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl;
            pSvc->Release();
            pLoc->Release();    
            CoUninitialize();
            return hres;      // Program has failed.
        }

        // Modification of BCD logic is here
        BSTR bstrClsName = SysAllocString(L"BcdStore");
        IWbemClassObject *pWbmBcd = NULL;   
        hr = pSvc->GetObject( bstrClsName, 0, NULL, &pWbmBcd, NULL);
        if (FAILED(hr))
        {
            cout << "Failed to get BcdStore class. Error code = 0x" << hex << hr << endl;
            pSvc->Release();
            pLoc->Release();    
            CoUninitialize();
            return hr;      // Program has failed.
        }
        else
        {
            cout << "IWbemClassObject retrieved." << endl;

            VARIANT variant1;
            IWbemClassObject *pInParamaterClass = NULL;
            IWbemClassObject *pOutParamaterClass = NULL;
            IWbemClassObject *pInParam = NULL;
            IWbemClassObject *pOutParam = NULL;
            IWbemCallResult *pCallResult = NULL;

            BSTR bstrMthdName = SysAllocString (L"OpenStore");
            hr = pWbmBcd->GetMethod(bstrMthdName, 0, &pInParamaterClass, NULL);

            if (hr == WBEM_S_NO_ERROR)
            {
                if( NULL != pInParamaterClass)
                {
                    hr=pInParamaterClass->SpawnInstance(0, &pInParam);
                    // create instance copy
                    if(WBEM_S_NO_ERROR ==  hr)
                    {
                        // set each property
                        VariantInit(&variant1);
                        V_VT(&variant1) = VT_BSTR;
                        V_BSTR(&variant1) = SysAllocString(L"m:\\BCD");
                        hr = pInParam->Put(L"File", 0, &variant1, 0);
                        VariantClear(&variant1);               
                    }
                }
                else
                {
                    // ERROR HANDLING
                    cout << "Parameter setting failed for OpenStore." << endl;
                    return 0;
                }
            }
            else
            {
                // ERROR HANDLING
                cout << "getMethod failed for OpenStore." << endl;
                return 0;
            }
            if (WBEM_S_NO_ERROR == hr && pInParam != NULL)
            {
                cout << "Parameter to OpenStore Created." << endl;
               
                BSTR bstrObjectName = SysAllocString (L"\\\\.\\ROOT\\WMI:BcdStore");
                hr = pSvc->ExecMethod(bstrObjectName, bstrMthdName, 0, NULL, pInParam, &pOutParam, &pCallResult);

                long lResult = 0;
                if (pCallResult != NULL)
                {
                     cout << "Exec Method OpenStore successful." << endl;
                     pCallResult->GetCallStatus(WBEM_INFINITE, &lResult);
                     hr = pCallResult->GetResultObject(0, &pOutParamaterClass);
                     pCallResult->Release();
                     pCallResult = NULL;
                }
                pInParam->Release();
                pInParam = NULL;
                pInParamaterClass ->Release();
                pInParamaterClass = NULL;

                SysFreeString(bstrMthdName);

                if (pOutParamaterClass != NULL && hr == WBEM_S_NO_ERROR)
                {
                    VariantInit(&variant1);
                    hr = pOutParamaterClass->Get(L"Store", 0, &variant1, 0, 0);
                    if (variant1.punkVal != NULL)
                    {
                        IWbemClassObject *pGotBcdStore = NULL;
                        hr = variant1.punkVal->QueryInterface(IID_IWbemClassObject, (void **)&pGotBcdStore);
                       
                        if (SUCCEEDED(hr))
                        {                       
                            cout << "Got BCD Store object." << endl;

                            BSTR bstrMthdName = SysAllocString (L"OpenObject");
                            hr = pWbmBcd->GetMethod(bstrMthdName, 0, &pInParamaterClass, NULL);
                            if (SUCCEEDED(hr))
                            {
                                cout << "OpenObject method found." << endl;

                                if( NULL != pInParamaterClass)
                                {
                                    hr=pInParamaterClass->SpawnInstance(0, &pInParam);
                                    // create instance copy
                                    if(WBEM_S_NO_ERROR ==  hr)
                                    {
                                        // set each property
                                        VariantInit(&variant1);
                                        V_VT(&variant1) = VT_BSTR;
                                        V_BSTR(&variant1) = SysAllocString(L"{59d0fcd2-dbab-11dc-a605-00123f5ace8b}");
                                        hr = pInParam->Put(L"Id", 0, &variant1, 0);
                                        VariantClear(&variant1);

                                        if (WBEM_S_NO_ERROR == hr && pInParam != NULL)
                                        {
                                            cout << "Parameter setting worked for OpenObject method." << endl;                           
                                            BSTR bstrObjectName = SysAllocString (L"\\\\.\\ROOT\\WMI:BcdStore");
                                            hr = pSvc->ExecMethod(bstrObjectName, bstrMthdName, 0, NULL, pInParam, &pOutParam, &pCallResult);
                                                                                   
                                            if (WBEM_S_NO_ERROR == hr)
                                            {
                                                cout << "OpenObject method executed successfully.";
                                                return 0;
                                            }
                                            else
                                            {
                                                cout << "OpenObject method failed to execute. Hex:" << hex << hr;
                                                return 0;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        // ERROR HANDLING
                                        cout << "Parameter setting failed for OpenObject method." << endl;
                                        return 0;
                                    }
                                }                           
                            }
                            else
                            {
                                // ERROR HANDLING
                                cout << "getMethod failed for OpenObject." << endl;
                                return 0;
                            }
                           
                        }
                        else
                        {
                            // TODO: ERROR HANDLING NEEDS TO BE ADDED.
                            cout << "FAILUE-4" << endl;
                            return 0;
                        }
                    }
                    else
                    {
                        // TODO: ERROR HANDLING NEEDS TO BE ADDED.
                        cout << "FAILUE-3" << endl;
                        return 0;
                    }
                }
                else
                {
                    // TODO: ERROR HANDLING NEEDS TO BE ADDED.
                    cout << "FAILUE-1" << endl;
                    return 0;
                }
            }
            else
            {
                // TODO: ERROR HANDLING NEEDS TO BE ADDED.
                cout << "FAILUE=2" << endl;
                return 0;
            }

        }

        // 6. Last step: Cleanup
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();

        return 0;
    }
    Thursday, August 07, 2008 2:34 PM

All replies

  • Replace this:

        hr = pSvc->ExecMethod(bstrObjectName, bstrMthdName, 0, NULL, pInParam, &pOutParam, &pCallResult);
     
    With this:

    VARIANT vPath;

    BSTR strClassProp = SysAllocString(L"__RELPATH");

    HRESULT hr;

    hr = pGotBcdStore->Get(strClassProp, 0, &vPath, 0, 0);

    SysFreeString(strClassProp);

    // check the HRESULT to see if the action succeeded.

    if (SUCCEEDED(hr) && (V_VT(&vPath) == VT_BSTR))

    {

        wprintf(L"The class name is %s\n.", V_BSTR(&vPath));

    }

    else

    {

    wprintf(L"Error in getting specified object\n");

    }

    hr = pSvc->ExecMethod(V_BSTR(&vPath), bstrMthdName, 0, NULL, pInParam, &pOutParam, &pCallResult);

    VariantClear(&vPath);

    • Proposed as answer by Dave SS Thursday, December 11, 2008 10:43 PM
    Thursday, December 11, 2008 10:42 PM