int InitrdInjectFiles()

in lsvmutils/initrd.c [429:583]


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;
    Heap heap = HEAP_INITIALIZER;
    Buf buf = BUF_INITIALIZER;
    UINTN i;

    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 no subfiles found, then fail */
    if (numSubfiles == 0)
        goto done;

    /* Decompress all compressed subfiles */
    for (i = 0; i < numSubfiles; i++)
    {
        if (lzmaextras_test(subfilesData[i], subfilesSize[i]) == 0)
        {
            unsigned char* data = NULL;
            unsigned long size = 0;
            void* newData = NULL;
            UINTN newSize = 0;

            if (lzmaextras_decompress(
                subfilesData[i],
                subfilesSize[i],
                &data,
                &size) != 0)
            {
                goto done;
            }

            /* Free this later */
            HeapAdd(&heap, data);

            /* Inject the keys into this existing CPIO archive */
            if (_InjectFiles(
                data,
                size,
                bootkeyData,
                bootkeySize,
                rootkeyData,
                rootkeySize,
                &newData,
                &newSize) != 0)
            {
                goto done;
            }

            /* Free this later */
            HeapAdd(&heap, newData);

            subfilesData[i] = newData;
            subfilesSize[i] = newSize;
        }
        else if (zlibextras_test(subfilesData[i], subfilesSize[i]) == 0)
        {
            unsigned char* data = NULL;
            unsigned long size = 0;
            void* newData = NULL;
            UINTN newSize = 0;

            if (zlibextras_decompress(
                subfilesData[i],
                subfilesSize[i],
                &data,
                &size) != 0)
            {
                goto done;
            }

            /* Free this later */
            HeapAdd(&heap, data);

            /* Inject the keys into this existing CPIO archive */
            if (_InjectFiles(
                data,
                size,
                bootkeyData,
                bootkeySize,
                rootkeyData,
                rootkeySize,
                &newData,
                &newSize) != 0)
            {
                goto done;
            }

            /* Free this later */
            HeapAdd(&heap, newData);

            subfilesData[i] = newData;
            subfilesSize[i] = newSize;
        }
        else if (CPIOTest(subfilesData[i], subfilesSize[i]) != 0)
        {
            /* Unknown subfile type */
            goto done;
        }
    }

    /* Create new initrd image */
    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);

    HeapFree(&heap);

    return rc;
}