int InitrdInjectFiles()

in lsvmutils/initrd.c [597:719]


int InitrdInjectFiles(
    const void* initrdData,
    UINTN initrdSize,
    const void* bootkeyData,
    UINTN bootkeySize,
    const void* rootkeyData,
    UINTN rootkeySize,
    void** initrdDataOut,
    UINTN* initrdSizeOut)
{
    int rc = -1;
    const void* subfilesData[CPIO_MAX_SUBFILES];
    UINTN subfilesSize[CPIO_MAX_SUBFILES];
    UINTN numSubfiles = 0;
    void* subfileData = NULL;
    UINTN subfileSize = 0;
    Buf buf = BUF_INITIALIZER;

    if (initrdDataOut)
        *initrdDataOut = NULL;

    if (initrdSizeOut)
        *initrdSizeOut = 0;

    /* Reject bad parameters */
    if (!initrdData || !initrdSize || !bootkeyData || !bootkeySize ||
        !rootkeyData || !rootkeySize || !initrdDataOut || !initrdSizeOut)
    {
        goto done;
    }

    /* Split initrd into subfiles */
    if (CPIOSplitFile(
        initrdData, 
        initrdSize, 
        subfilesData, 
        subfilesSize, 
        &numSubfiles) != 0)
    {
        goto done;
    }

    if (numSubfiles == 0)
        goto done;

    /* If first subfile is an uncompressed CPIO archive, update it. 
     * Else, prepend a new CPIO archive with the keys.
     */
    if (subfilesSize[0] >= sizeof(CPIOHeader) &&
        CPIOMatchMagicNumber(((const CPIOHeader*)subfilesData[0])->magic))
    {
        /* Inject the keys into this existing CPIO archive */
        if (_InjectFiles(
            subfilesData[0],
            subfilesSize[0],
            bootkeyData,
            bootkeySize,
            rootkeyData,
            rootkeySize,
            &subfileData,
            &subfileSize) != 0)
        {
            goto done;
        }

        /* Create new initrd image */
        {
            UINTN i;

            if (BufAppend(&buf, subfileData, subfileSize) != 0)
                goto done;

            for (i = 1; i < numSubfiles; i++)
            {
                if (BufAppend(&buf, subfilesData[i], subfilesSize[i]) != 0)
                    goto done;
            }
        }
    }
    else
    {
        /* Create a new CPIO archive that contains these keys */
        if (InitrdMakeArchive(
            bootkeyData,
            bootkeySize,
            rootkeyData,
            rootkeySize,
            &subfileData,
            &subfileSize) != 0)
        {
            goto done;
        }

        /* Create new initrd image */
        {
            UINTN i;

            if (BufAppend(&buf, subfileData, subfileSize) != 0)
                goto done;

            for (i = 0; i < numSubfiles; i++)
            {
                if (BufAppend(&buf, subfilesData[i], subfilesSize[i]) != 0)
                    goto done;
            }
        }
    }

    *initrdDataOut = buf.data;
    *initrdSizeOut = buf.size;

    rc = 0;

done:

    if (rc != 0)
        BufRelease(&buf);

    if (subfileData)
        Free(subfileData);

    return rc;
}