VirtualBox

Ignore:
Timestamp:
Sep 29, 2021 2:08:32 PM (3 years ago)
Author:
vboxsync
Message:

Main,FE/VBoxManage: Implement functionality to list and query UEFI variables, bugref:9580

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyNvram.cpp

    r91433 r91457  
    164164
    165165/**
     166 * Handles the 'modifynvram myvm listvars' sub-command.
     167 * @returns Exit code.
     168 * @param   a               The handler argument package.
     169 * @param   nvram           Reference to the NVRAM store interface.
     170 */
     171static RTEXITCODE handleModifyNvramListUefiVars(HandlerArg *a, ComPtr<INvramStore> &nvramStore)
     172{
     173    RT_NOREF(a);
     174
     175    ComPtr<IUefiVariableStore> uefiVarStore;
     176    CHECK_ERROR2I_RET(nvramStore, COMGETTER(UefiVariableStore)(uefiVarStore.asOutParam()), RTEXITCODE_FAILURE);
     177
     178    com::SafeArray<BSTR> aNames;
     179    com::SafeArray<BSTR> aOwnerGuids;
     180    CHECK_ERROR2I_RET(uefiVarStore, QueryVariables(ComSafeArrayAsOutParam(aNames), ComSafeArrayAsOutParam(aOwnerGuids)), RTEXITCODE_FAILURE);
     181    for (size_t i = 0; i < aNames.size(); i++)
     182    {
     183        Bstr strName      = aNames[i];
     184        Bstr strOwnerGuid = aOwnerGuids[i];
     185
     186        RTPrintf("%-32ls {%ls}\n", strName.raw(), strOwnerGuid.raw());
     187    }
     188
     189    return RTEXITCODE_SUCCESS;
     190}
     191
     192
     193/**
     194 * Handles the 'modifynvram myvm queryvar' sub-command.
     195 * @returns Exit code.
     196 * @param   a               The handler argument package.
     197 * @param   nvram           Reference to the NVRAM store interface.
     198 */
     199static RTEXITCODE handleModifyNvramQueryUefiVar(HandlerArg *a, ComPtr<INvramStore> &nvramStore)
     200{
     201    static const RTGETOPTDEF s_aOptions[] =
     202    {
     203        /* common options */
     204        { "--name",       'n', RTGETOPT_REQ_STRING },
     205        { "--filename",   'f', RTGETOPT_REQ_STRING }
     206    };
     207
     208    const char *pszVarName = NULL;
     209    const char *pszVarDataFilename = NULL;
     210
     211    RTGETOPTSTATE GetState;
     212    int vrc = RTGetOptInit(&GetState, a->argc - 2, &a->argv[2], s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
     213    AssertRCReturn(vrc, RTEXITCODE_FAILURE);
     214
     215    int c;
     216    RTGETOPTUNION ValueUnion;
     217    while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
     218    {
     219        switch (c)
     220        {
     221            case 'n':
     222                pszVarName = ValueUnion.psz;
     223                break;
     224            case 'f':
     225                pszVarDataFilename = ValueUnion.psz;
     226                break;
     227            default:
     228                return errorGetOpt(c, &ValueUnion);
     229        }
     230    }
     231
     232    if (!pszVarName)
     233        return errorSyntax("No variable name was given to \"queryvar\"");
     234
     235    ComPtr<IUefiVariableStore> uefiVarStore;
     236    CHECK_ERROR2I_RET(nvramStore, COMGETTER(UefiVariableStore)(uefiVarStore.asOutParam()), RTEXITCODE_FAILURE);
     237
     238    Bstr strOwnerGuid;
     239    com::SafeArray<UefiVariableAttributes_T> aVarAttrs;
     240    com::SafeArray<BYTE> aData;
     241    CHECK_ERROR2I_RET(uefiVarStore, QueryVariableByName(Bstr(pszVarName).raw(), strOwnerGuid.asOutParam(),
     242                                                        ComSafeArrayAsOutParam(aVarAttrs), ComSafeArrayAsOutParam(aData)),
     243                      RTEXITCODE_FAILURE);
     244
     245    RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
     246    if (!pszVarDataFilename)
     247    {
     248        RTPrintf("%s {%ls}:\n"
     249                 "%.*Rhxd\n", pszVarName, strOwnerGuid.raw(), aData.size(), aData.raw());
     250    }
     251    else
     252    {
     253        /* Just write the data to the file. */
     254        RTFILE hFile = NIL_RTFILE;
     255        vrc = RTFileOpen(&hFile, pszVarDataFilename, RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
     256        if (RT_SUCCESS(vrc))
     257        {
     258            vrc = RTFileWrite(hFile, aData.raw(), aData.size(), NULL /*pcbWritten*/);
     259            if (RT_FAILURE(vrc))
     260                rcExit = RTMsgErrorExitFailure("Error writing to '%s': %Rrc", pszVarDataFilename, vrc);
     261
     262            RTFileClose(hFile);
     263        }
     264        else
     265           rcExit = RTMsgErrorExitFailure("Error opening '%s': %Rrc", pszVarDataFilename, vrc);
     266    }
     267
     268    return rcExit;
     269}
     270
     271
     272/**
    166273 * Handles the 'modifynvram' command.
    167274 * @returns Exit code.
     
    195302    else if (!strcmp(a->argv[1], "enrollpk"))
    196303        rc = handleModifyNvramEnrollPlatformKey(a, nvramStore) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
     304    else if (!strcmp(a->argv[1], "listvars"))
     305        rc = handleModifyNvramListUefiVars(a, nvramStore) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
     306    else if (!strcmp(a->argv[1], "queryvar"))
     307        rc = handleModifyNvramQueryUefiVar(a, nvramStore) == RTEXITCODE_SUCCESS ? S_OK : E_FAIL;
    197308    else
    198309        return errorUnknownSubcommand(a->argv[0]);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette