int LoadEFIVar()

in lsvmutils/measure.c [239:400]


int LoadEFIVar(
    const char* guidstr,
    const char* name,
    unsigned char** dataOut,
    UINTN* sizeOut)
{
#if defined(BUILD_EFI)

    int rc = -1;
    CHAR16 wcsname[PATH_MAX];
    static EFI_GUID guid;
    EFI_STATUS status;
    const UINTN KILOBYTE = 1024;

    if (dataOut)
        *dataOut = NULL;

    if (sizeOut)
        *sizeOut = 0;

    /* Reject null parameters */
    if (!guidstr || !name || !dataOut || !sizeOut)
        goto done;

    /* Convert variable to wide character */
    WcsStrlcpy(wcsname, name, PATH_MAX);

    /* Convert guidstr string to GUID */
    if (StrToGUID(guidstr, &guid) != 0)
        goto done;

    /* Set initial size of buffer */
    *sizeOut = KILOBYTE;

    /* Allocate memory to hold the variable data */
    if (!(*dataOut = Malloc(*sizeOut)))
        goto done;

    /* Load the EFI variable */
    status = RT->GetVariable(wcsname, &guid, NULL, sizeOut, *dataOut);

    /* If buffer too small, try again with larger buffer */
    if (status == EFI_BUFFER_TOO_SMALL)
    {
        /* Expand buffer to size returned by previous call to GetVariable() */
        if (!(*dataOut = Realloc(*dataOut, KILOBYTE, *sizeOut)))
            goto done;

        status = RT->GetVariable(wcsname, &guid, NULL, sizeOut, *dataOut);
    }

    if (status != EFI_SUCCESS)
        goto done;

    rc = 0;

done:

    if (rc != 0)
    {
        if (dataOut && *dataOut)
            Free(*dataOut);

        *dataOut = NULL;
        *sizeOut = 0;
    }

    return rc;

#else /* defined(BUILD_EFI) */

    int rc = 0;
    static EFI_GUID guid;
    char path[256];
    unsigned char* data = NULL;
    size_t size;

    if (!guidstr || !name)
    {
        rc = -1;
        goto done;
    }

    /* Convert guidstr string to GUID */
    if (StrToGUID(guidstr, &guid) != 0)
    {
        rc = -1;
        goto done;
    }

    /* Format the GUID */
    {
        unsigned int w = guid.Data1;
        unsigned short x = guid.Data2;
        unsigned short y = guid.Data3;
        unsigned char z[8];
        memcpy(z, guid.Data4, sizeof(z));

        sprintf(path, "/sys/firmware/efi/efivars/%s-"
            "%02x%02x%02x%02x-"
            "%02x%02x-"
            "%02x%02x-"
            "%02x%02x-"
            "%02x%02x%02x%02x%02x%02x",
            name,
            (w & 0xFF000000) >> 24,
            (w & 0x00FF0000) >> 16,
            (w & 0x0000FF00) >> 8,
            (w & 0x000000FF),
            (x & 0xFF00) >> 8,
            (x & 0x00FF),
            (y & 0xFF00) >> 8,
            (y & 0x00FF),
            z[0],
            z[1],
            z[2],
            z[3],
            z[4],
            z[5],
            z[6],
            z[7]);
    }

    /* Load the file */
    {
        if (LoadFile(path, 0, &data, &size) != 0)
        {
            rc = -1;
            goto done;
        }

        if (size < 4)
        {
            rc = -1;
            goto done;
        }

        /* Remove the 4-byte header */
        memmove(data, data + 4, size - 4);
        size -= 4;
    }

done:

    if (rc == 0)
    {
        *dataOut = data;
        *sizeOut = size;
    }
    else
    {
        *dataOut = NULL;
        *sizeOut = 0;

        if (data)
            Free(data);
    }

    return rc;

#endif
}