|
|
|
@ -49,6 +49,7 @@ static int g_vhdboot_bcd_len = 0;
|
|
|
|
|
static int g_vhdboot_isolen = 0;
|
|
|
|
|
static char *g_vhdboot_totbuf = NULL;
|
|
|
|
|
static char *g_vhdboot_isobuf = NULL;
|
|
|
|
|
static grub_uint64_t g_img_trim_head_secnum = 0;
|
|
|
|
|
|
|
|
|
|
static int ventoy_vhd_find_bcd(int *bcdoffset, int *bcdlen)
|
|
|
|
|
{
|
|
|
|
@ -273,6 +274,71 @@ grub_err_t ventoy_cmd_load_vhdboot(grub_extcmd_context_t ctxt, int argc, char **
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int ventoy_raw_trim_head(grub_uint64_t offset)
|
|
|
|
|
{
|
|
|
|
|
grub_uint32_t i;
|
|
|
|
|
grub_uint32_t memsize;
|
|
|
|
|
grub_uint32_t imgstart = 0;
|
|
|
|
|
grub_uint32_t imgsecs = 0;
|
|
|
|
|
grub_uint64_t sectors = 0;
|
|
|
|
|
grub_uint64_t cursecs = 0;
|
|
|
|
|
grub_uint64_t delta = 0;
|
|
|
|
|
|
|
|
|
|
if ((!g_img_chunk_list.chunk) || (!offset))
|
|
|
|
|
{
|
|
|
|
|
debug("image chunk not ready %p %lu\n", g_img_chunk_list.chunk, (ulong)offset);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
debug("image trim head %lu\n", (ulong)offset);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < g_img_chunk_list.cur_chunk; i++)
|
|
|
|
|
{
|
|
|
|
|
cursecs = g_img_chunk_list.chunk[i].disk_end_sector + 1 - g_img_chunk_list.chunk[i].disk_start_sector;
|
|
|
|
|
sectors += cursecs;
|
|
|
|
|
if (sectors >= offset)
|
|
|
|
|
{
|
|
|
|
|
delta = cursecs - (sectors - offset);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sectors < offset || i >= g_img_chunk_list.cur_chunk)
|
|
|
|
|
{
|
|
|
|
|
debug("Invalid size %lu %lu\n", (ulong)sectors, (ulong)offset);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sectors == offset)
|
|
|
|
|
{
|
|
|
|
|
memsize = (g_img_chunk_list.cur_chunk - (i + 1)) * sizeof(ventoy_img_chunk);
|
|
|
|
|
grub_memmove(g_img_chunk_list.chunk, g_img_chunk_list.chunk + i + 1, memsize);
|
|
|
|
|
g_img_chunk_list.cur_chunk -= (i + 1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_img_chunk_list.chunk[i].disk_start_sector += delta;
|
|
|
|
|
g_img_chunk_list.chunk[i].img_start_sector += (grub_uint32_t)(delta / 4);
|
|
|
|
|
|
|
|
|
|
if (i > 0)
|
|
|
|
|
{
|
|
|
|
|
memsize = (g_img_chunk_list.cur_chunk - i) * sizeof(ventoy_img_chunk);
|
|
|
|
|
grub_memmove(g_img_chunk_list.chunk, g_img_chunk_list.chunk + i, memsize);
|
|
|
|
|
g_img_chunk_list.cur_chunk -= i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < g_img_chunk_list.cur_chunk; i++)
|
|
|
|
|
{
|
|
|
|
|
imgsecs = g_img_chunk_list.chunk[i].img_end_sector + 1 - g_img_chunk_list.chunk[i].img_start_sector;
|
|
|
|
|
g_img_chunk_list.chunk[i].img_start_sector = imgstart;
|
|
|
|
|
g_img_chunk_list.chunk[i].img_end_sector = imgstart + (imgsecs - 1);
|
|
|
|
|
imgstart += imgsecs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char **args)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
@ -281,11 +347,12 @@ grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char *
|
|
|
|
|
vhd_footer_t vhdfoot;
|
|
|
|
|
VDIPREHEADER vdihdr;
|
|
|
|
|
char type[16] = {0};
|
|
|
|
|
ventoy_mbr_head mbr;
|
|
|
|
|
ventoy_gpt_info *gpt;
|
|
|
|
|
|
|
|
|
|
(void)ctxt;
|
|
|
|
|
|
|
|
|
|
g_img_trim_head_secnum = 0;
|
|
|
|
|
|
|
|
|
|
if (argc != 4)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
@ -316,6 +383,7 @@ grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char *
|
|
|
|
|
grub_strncmp(vdihdr.szFileInfo, VDI_IMAGE_FILE_INFO, grub_strlen(VDI_IMAGE_FILE_INFO)) == 0)
|
|
|
|
|
{
|
|
|
|
|
offset = 2 * 1048576;
|
|
|
|
|
g_img_trim_head_secnum = offset / 512;
|
|
|
|
|
grub_snprintf(type, sizeof(type), "vdi");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -330,27 +398,30 @@ grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char *
|
|
|
|
|
|
|
|
|
|
if (offset >= 0)
|
|
|
|
|
{
|
|
|
|
|
gpt = grub_zalloc(sizeof(ventoy_gpt_info));
|
|
|
|
|
if (!gpt)
|
|
|
|
|
{
|
|
|
|
|
grub_env_set(args[1], "unknown");
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
grub_file_seek(file, offset);
|
|
|
|
|
grub_file_read(file, &mbr, sizeof(mbr));
|
|
|
|
|
grub_file_read(file, gpt, sizeof(ventoy_gpt_info));
|
|
|
|
|
|
|
|
|
|
if (mbr.Byte55 != 0x55 || mbr.ByteAA != 0xAA)
|
|
|
|
|
if (gpt->MBR.Byte55 != 0x55 || gpt->MBR.ByteAA != 0xAA)
|
|
|
|
|
{
|
|
|
|
|
grub_env_set(args[1], "unknown");
|
|
|
|
|
debug("invalid mbr signature: 0x%x 0x%x\n", mbr.Byte55, mbr.ByteAA);
|
|
|
|
|
debug("invalid mbr signature: 0x%x 0x%x\n", gpt->MBR.Byte55, gpt->MBR.ByteAA);
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mbr.PartTbl[0].FsFlag == 0xEE)
|
|
|
|
|
if (grub_memcmp(gpt->Head.Signature, "EFI PART", 8) == 0)
|
|
|
|
|
{
|
|
|
|
|
grub_env_set(args[2], "gpt");
|
|
|
|
|
debug("part type: %s\n", "GPT");
|
|
|
|
|
|
|
|
|
|
gpt = grub_zalloc(sizeof(ventoy_gpt_info));
|
|
|
|
|
if (gpt)
|
|
|
|
|
if (gpt->MBR.PartTbl[0].FsFlag == 0xEE)
|
|
|
|
|
{
|
|
|
|
|
grub_file_seek(file, offset);
|
|
|
|
|
grub_file_read(file, gpt, sizeof(ventoy_gpt_info));
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 128; i++)
|
|
|
|
|
{
|
|
|
|
|
if (grub_memcmp(gpt->PartTbl[i].PartType, "Hah!IdontNeedEFI", 16) == 0)
|
|
|
|
@ -364,14 +435,22 @@ grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char *
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
grub_free(gpt);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
grub_env_set(args[2], "mbr");
|
|
|
|
|
debug("part type: %s\n", "MBR");
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
if (gpt->MBR.PartTbl[i].FsFlag == 0xEF)
|
|
|
|
|
{
|
|
|
|
|
debug("part %d is esp part in MBR mode\n", i);
|
|
|
|
|
grub_env_set(args[3], "1");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -380,6 +459,7 @@ grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char *
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
end:
|
|
|
|
|
grub_check_free(gpt);
|
|
|
|
|
grub_file_close(file);
|
|
|
|
|
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
|
|
|
|
}
|
|
|
|
@ -403,6 +483,11 @@ grub_err_t ventoy_cmd_raw_chain_data(grub_extcmd_context_t ctxt, int argc, char
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (g_img_trim_head_secnum > 0)
|
|
|
|
|
{
|
|
|
|
|
ventoy_raw_trim_head(g_img_trim_head_secnum);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
|
|
|
|
|
if (!file)
|
|
|
|
|
{
|
|
|
|
@ -450,8 +535,14 @@ grub_err_t ventoy_cmd_raw_chain_data(grub_extcmd_context_t ctxt, int argc, char
|
|
|
|
|
disk = file->device->disk;
|
|
|
|
|
chain->disk_drive = disk->id;
|
|
|
|
|
chain->disk_sector_size = (1 << disk->log_sector_size);
|
|
|
|
|
|
|
|
|
|
chain->real_img_size_in_bytes = file->size;
|
|
|
|
|
chain->virt_img_size_in_bytes = (file->size + 2047) / 2048 * 2048;
|
|
|
|
|
if (g_img_trim_head_secnum > 0)
|
|
|
|
|
{
|
|
|
|
|
chain->real_img_size_in_bytes -= g_img_trim_head_secnum * 512;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
chain->virt_img_size_in_bytes = chain->real_img_size_in_bytes;
|
|
|
|
|
chain->boot_catalog = 0;
|
|
|
|
|
|
|
|
|
|
/* part 3: image chunk */
|
|
|
|
@ -459,7 +550,7 @@ grub_err_t ventoy_cmd_raw_chain_data(grub_extcmd_context_t ctxt, int argc, char
|
|
|
|
|
chain->img_chunk_num = g_img_chunk_list.cur_chunk;
|
|
|
|
|
grub_memcpy((char *)chain + chain->img_chunk_offset, g_img_chunk_list.chunk, img_chunk_size);
|
|
|
|
|
|
|
|
|
|
grub_file_seek(file, 0);
|
|
|
|
|
grub_file_seek(file, g_img_trim_head_secnum * 512);
|
|
|
|
|
grub_file_read(file, chain->boot_catalog_sector, 512);
|
|
|
|
|
|
|
|
|
|
grub_file_close(file);
|
|
|
|
|