int MapEFIVFAT()

in lsvmload/efivfat.c [174:338]


int MapEFIVFAT(
    EFI_HANDLE imageHandle)
{
    int rc = -1;
    GPTEntry* entry = NULL;
    const int partitionNumber = 1;
    Blkdev* memdev = NULL;
    VFAT* vfat = NULL;

    /* Check parameters */
    if (!imageHandle || !globals.bootfs || !globals.efiVendorDir)
    {
        LOGE(L"%a: bad parameter", __FUNCTION__);
        goto done;
    }

    /* Load grub.cfg from the boot partition */
    if (!globals.grubcfgData)
    {
        const CHAR16 PATH1[] = L"/grub2/grub.cfg";
        const CHAR16 PATH2[] = L"/grub/grub.cfg";

        if (LoadFileFromBootFS(
            imageHandle,
            globals.tcg2Protocol,
            globals.bootfs,
            PATH1,
            &globals.grubcfgData,
            &globals.grubcfgSize) == EFI_SUCCESS)
        {
            LOGI(L"Loaded %s", Wcs(PATH1));
        }
        else if (LoadFileFromBootFS(
            imageHandle,
            globals.tcg2Protocol,
            globals.bootfs,
            PATH2,
            &globals.grubcfgData,
            &globals.grubcfgSize) == EFI_SUCCESS)
        {
            LOGI(L"Loaded %s", Wcs(PATH2));
        }
        else
        {
            LOGE(L"Failed to load grub.cfg");
            goto done;
        }
    }

    /* Apply patches to grub.cfg */
    GrubcfgPatch(globals.grubcfgData, globals.grubcfgSize);

    /* Create "/EFI/<VENDOR-EFI-DIR>/GRUB.CFG" file in embedded-VFAT parition */
    {
        /* Create a memory block device to be used by VFAT */
        if (!(memdev = BlkdevFromMemory((void*)efivfat, efivfat_size)))
        {
            LOGE(L"BlkdevFromMemory() failed");
            goto done;
        }

        /* Initialize the VFAT object */
        if (VFATInit(memdev, &vfat) != 0)
        {
            LOGE(L"VFATInit() failed");
            goto done;
        }

        /* Create the "EFI" directory */
        if (VFATMkdir(vfat, "/EFI") != 0)
        {
            LOGE(L"VFATMkdir(): failed to create /EFI");
            goto done;
        }

        /* Create the EFI vendor directory ("/EFI/UBUNTU") */
        {
            char path[EXT2_PATH_MAX];

            Strlcpy(path, "/EFI/", ARRSIZE(path));
            StrWcslcat(path, globals.efiVendorDir, ARRSIZE(path));

            if (VFATMkdir(vfat, path) != 0)
            {
                LOGE(L"VFATMkdir(): failed to create %a", Str(path));
                goto done;
            }
        }

        /* Create GRUB.CFG under vendor directory ("/EFI/UBUNTU/GRUB.CFG") */
        {
            char path[EXT2_PATH_MAX];

            Strlcpy(path, "/EFI/", ARRSIZE(path));
            StrWcslcat(path, globals.efiVendorDir, ARRSIZE(path));
            Strlcat(path, "/GRUB.CFG", ARRSIZE(path));

            if (VFATPutFile(
                vfat, 
                path,
                globals.grubcfgData, 
                globals.grubcfgSize) != 0)
            {
                LOGE(L"VFATPutFile(): failed to create %a", path);
                goto done;
            }
        }

        /* SUSE uses the current directory to find the grub.cfg. So, put there as well. */
        {
            char path[EXT2_PATH_MAX];
            const char* skip[2];

            skip[0] = "/EFI";
            Strlcpy(path, "/EFI/", ARRSIZE(path));
            StrWcslcat(path, globals.efiVendorDir, ARRSIZE(path));
            skip[1] = path;

            if (_AddCwdGrubcfg(vfat, skip, ARRSIZE(skip), '/') != 0)
            {
                LOGE(L"_AddCwdGrubcfg() failed");
                goto done;
            }
        }
	
    }

#if 0
    /* Log the hash of this memory */
    {
        SHA1Hash sha1;
        ComputeSHA1(efivfat, efivfat_size, &sha1);
        LogHash1(L"VFAT", &sha1);
    }
#endif

    /* Assuming EFI partition is /dev/sda1 (use detection) */
    if (GetGPTEntry(partitionNumber, &entry) != 0)
        goto done;

    /* Add a region to handle these blocks */
    if (AddRegion(
        REGION_ID_ESP,
        entry->startingLBA,
        entry->endingLBA,
        efivfat_size / GPT_BLOCK_SIZE,
        TRUE,
        (Block*)efivfat,
        NULL) != 0)
    {
        goto done;
    }

    /* Success! */
    rc = 0;

done:

    if (vfat)
        VFATRelease(vfat);
    else if (memdev)
        memdev->Close(memdev);

    return rc;
}