]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c
1. change some directory structure for the build script
[Ventoy.git] / EDK2 / edk2_mod / edk2-edk2-stable201911 / MdeModulePkg / Application / Ventoy / Ventoy.c
1 /******************************************************************************
2 * Ventoy.c
3 *
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21 #include <Uefi.h>
22 #include <Library/DebugLib.h>
23 #include <Library/PrintLib.h>
24 #include <Library/UefiLib.h>
25 #include <Library/BaseMemoryLib.h>
26 #include <Library/DevicePathLib.h>
27 #include <Library/MemoryAllocationLib.h>
28 #include <Library/UefiBootServicesTableLib.h>
29 #include <Library/UefiRuntimeServicesTableLib.h>
30 #include <Library/UefiApplicationEntryPoint.h>
31 #include <Protocol/LoadedImage.h>
32 #include <Guid/FileInfo.h>
33 #include <Guid/FileSystemInfo.h>
34 #include <Protocol/BlockIo.h>
35 #include <Protocol/RamDisk.h>
36 #include <Protocol/SimpleFileSystem.h>
37 #include <Ventoy.h>
38
39 UINTN g_iso_buf_size = 0;
40 BOOLEAN gMemdiskMode = FALSE;
41 BOOLEAN gDebugPrint = FALSE;
42 BOOLEAN gLoadIsoEfi = FALSE;
43 ventoy_ram_disk g_ramdisk_param;
44 ventoy_chain_head *g_chain;
45 ventoy_img_chunk *g_chunk;
46 UINT32 g_img_chunk_num;
47 ventoy_override_chunk *g_override_chunk;
48 UINT32 g_override_chunk_num;
49 ventoy_virt_chunk *g_virt_chunk;
50 UINT32 g_virt_chunk_num;
51 vtoy_block_data gBlockData;
52 ventoy_sector_flag *g_sector_flag = NULL;
53 UINT32 g_sector_flag_num = 0;
54 static grub_env_get_pf grub_env_get = NULL;
55
56 EFI_FILE_OPEN g_original_fopen = NULL;
57 EFI_FILE_CLOSE g_original_fclose = NULL;
58 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME g_original_open_volume = NULL;
59
60 ventoy_grub_param_file_replace *g_file_replace_list = NULL;
61 ventoy_efi_file_replace g_efi_file_replace;
62
63 CHAR16 gFirstTryBootFile[256] = {0};
64
65 CONST CHAR16 gIso9660EfiDriverPath[] = ISO9660_EFI_DRIVER_PATH;
66
67 /* Boot filename */
68 UINTN gBootFileStartIndex = 1;
69 CONST CHAR16 *gEfiBootFileName[] =
70 {
71 L"@",
72 EFI_REMOVABLE_MEDIA_FILE_NAME,
73 L"\\EFI\\BOOT\\GRUBX64.EFI",
74 L"\\EFI\\BOOT\\BOOTx64.EFI",
75 L"\\EFI\\BOOT\\bootx64.efi",
76 L"\\efi\\boot\\bootx64.efi",
77 };
78
79 /* EFI block device vendor device path GUID */
80 EFI_GUID gVtoyBlockDevicePathGuid = VTOY_BLOCK_DEVICE_PATH_GUID;
81
82 VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...)
83 {
84 VA_LIST Marker;
85 CHAR16 Buffer[512];
86
87 VA_START (Marker, Format);
88 UnicodeVSPrintAsciiFormat(Buffer, sizeof(Buffer), Format, Marker);
89 VA_END (Marker);
90
91 gST->ConOut->OutputString(gST->ConOut, Buffer);
92 }
93
94 VOID EFIAPI ventoy_clear_input(VOID)
95 {
96 EFI_INPUT_KEY Key;
97
98 gST->ConIn->Reset(gST->ConIn, FALSE);
99 while (EFI_SUCCESS == gST->ConIn->ReadKeyStroke(gST->ConIn, &Key))
100 {
101 ;
102 }
103 gST->ConIn->Reset(gST->ConIn, FALSE);
104 }
105
106 static void EFIAPI ventoy_dump_img_chunk(ventoy_chain_head *chain)
107 {
108 UINT32 i;
109 int errcnt = 0;
110 UINT64 img_sec = 0;
111 ventoy_img_chunk *chunk;
112
113 chunk = (ventoy_img_chunk *)((char *)chain + chain->img_chunk_offset);
114
115 debug("##################### ventoy_dump_img_chunk #######################");
116
117 for (i = 0; i < chain->img_chunk_num; i++)
118 {
119 debug("%2u: [ %u - %u ] <==> [ %llu - %llu ]",
120 i, chunk[i].img_start_sector, chunk[i].img_end_sector,
121 chunk[i].disk_start_sector, chunk[i].disk_end_sector);
122
123 if (i > 0 && (chunk[i].img_start_sector != chunk[i - 1].img_end_sector + 1))
124 {
125 errcnt++;
126 }
127
128 img_sec += chunk[i].img_end_sector - chunk[i].img_start_sector + 1;
129 }
130
131 if (errcnt == 0 && (img_sec * 2048 == g_chain->real_img_size_in_bytes))
132 {
133 debug("image chunk size check success");
134 }
135 else
136 {
137 debug("image chunk size check failed %d", errcnt);
138 }
139
140 ventoy_debug_pause();
141 }
142
143 static void EFIAPI ventoy_dump_override_chunk(ventoy_chain_head *chain)
144 {
145 UINT32 i;
146 ventoy_override_chunk *chunk;
147
148 chunk = (ventoy_override_chunk *)((char *)chain + chain->override_chunk_offset);
149
150 debug("##################### ventoy_dump_override_chunk #######################");
151
152 for (i = 0; i < g_override_chunk_num; i++)
153 {
154 debug("%2u: [ %llu, %u ]", i, chunk[i].img_offset, chunk[i].override_size);
155 }
156
157 ventoy_debug_pause();
158 }
159
160 static void EFIAPI ventoy_dump_virt_chunk(ventoy_chain_head *chain)
161 {
162 UINT32 i;
163 ventoy_virt_chunk *node;
164
165 debug("##################### ventoy_dump_virt_chunk #######################");
166 debug("virt_chunk_offset=%u", chain->virt_chunk_offset);
167 debug("virt_chunk_num=%u", chain->virt_chunk_num);
168
169 node = (ventoy_virt_chunk *)((char *)chain + chain->virt_chunk_offset);
170 for (i = 0; i < chain->virt_chunk_num; i++, node++)
171 {
172 debug("%2u: mem:[ %u, %u, %u ] remap:[ %u, %u, %u ]", i,
173 node->mem_sector_start,
174 node->mem_sector_end,
175 node->mem_sector_offset,
176 node->remap_sector_start,
177 node->remap_sector_end,
178 node->org_sector_start);
179 }
180
181 ventoy_debug_pause();
182 }
183
184 static void EFIAPI ventoy_dump_chain(ventoy_chain_head *chain)
185 {
186 UINT32 i = 0;
187 UINT8 chksum = 0;
188 UINT8 *guid;
189
190 guid = chain->os_param.vtoy_disk_guid;
191 for (i = 0; i < sizeof(ventoy_os_param); i++)
192 {
193 chksum += *((UINT8 *)(&(chain->os_param)) + i);
194 }
195
196 debug("##################### ventoy_dump_chain #######################");
197
198 debug("os_param->chksum=0x%x (%a)", chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS");
199 debug("os_param->vtoy_disk_guid=%02x%02x%02x%02x", guid[0], guid[1], guid[2], guid[3]);
200 debug("os_param->vtoy_disk_size=%llu", chain->os_param.vtoy_disk_size);
201 debug("os_param->vtoy_disk_part_id=%u", chain->os_param.vtoy_disk_part_id);
202 debug("os_param->vtoy_disk_part_type=%u", chain->os_param.vtoy_disk_part_type);
203 debug("os_param->vtoy_img_path=<%a>", chain->os_param.vtoy_img_path);
204 debug("os_param->vtoy_img_size=<%llu>", chain->os_param.vtoy_img_size);
205 debug("os_param->vtoy_img_location_addr=<0x%llx>", chain->os_param.vtoy_img_location_addr);
206 debug("os_param->vtoy_img_location_len=<%u>", chain->os_param.vtoy_img_location_len);
207
208 ventoy_debug_pause();
209
210 debug("chain->disk_drive=0x%x", chain->disk_drive);
211 debug("chain->disk_sector_size=%u", chain->disk_sector_size);
212 debug("chain->real_img_size_in_bytes=%llu", chain->real_img_size_in_bytes);
213 debug("chain->virt_img_size_in_bytes=%llu", chain->virt_img_size_in_bytes);
214 debug("chain->boot_catalog=%u", chain->boot_catalog);
215 debug("chain->img_chunk_offset=%u", chain->img_chunk_offset);
216 debug("chain->img_chunk_num=%u", chain->img_chunk_num);
217 debug("chain->override_chunk_offset=%u", chain->override_chunk_offset);
218 debug("chain->override_chunk_num=%u", chain->override_chunk_num);
219
220 ventoy_debug_pause();
221
222 ventoy_dump_img_chunk(chain);
223 ventoy_dump_override_chunk(chain);
224 ventoy_dump_virt_chunk(chain);
225 }
226
227 EFI_HANDLE EFIAPI ventoy_get_parent_handle(IN EFI_DEVICE_PATH_PROTOCOL *pDevPath)
228 {
229 EFI_HANDLE Handle = NULL;
230 EFI_STATUS Status = EFI_SUCCESS;
231 EFI_DEVICE_PATH_PROTOCOL *pLastNode = NULL;
232 EFI_DEVICE_PATH_PROTOCOL *pCurNode = NULL;
233 EFI_DEVICE_PATH_PROTOCOL *pTmpDevPath = NULL;
234
235 pTmpDevPath = DuplicateDevicePath(pDevPath);
236 if (!pTmpDevPath)
237 {
238 return NULL;
239 }
240
241 pCurNode = pTmpDevPath;
242 while (!IsDevicePathEnd(pCurNode))
243 {
244 pLastNode = pCurNode;
245 pCurNode = NextDevicePathNode(pCurNode);
246 }
247 if (pLastNode)
248 {
249 CopyMem(pLastNode, pCurNode, sizeof(EFI_DEVICE_PATH_PROTOCOL));
250 }
251
252 pCurNode = pTmpDevPath;
253 Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid, &pCurNode, &Handle);
254 debug("Status:%r Parent Handle:%p DP:%s", Status, Handle, ConvertDevicePathToText(pTmpDevPath, FALSE, FALSE));
255
256 FreePool(pTmpDevPath);
257
258 return Handle;
259 }
260
261 EFI_STATUS EFIAPI ventoy_block_io_reset
262 (
263 IN EFI_BLOCK_IO_PROTOCOL *This,
264 IN BOOLEAN ExtendedVerification
265 )
266 {
267 (VOID)This;
268 (VOID)ExtendedVerification;
269 return EFI_SUCCESS;
270 }
271
272 STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector
273 (
274 IN UINT64 Sector,
275 IN UINTN Count,
276 OUT VOID *Buffer
277 )
278 {
279 EFI_STATUS Status = EFI_SUCCESS;
280 EFI_LBA MapLba = 0;
281 UINT32 i = 0;
282 UINTN secLeft = 0;
283 UINTN secRead = 0;
284 UINT64 ReadStart = 0;
285 UINT64 ReadEnd = 0;
286 UINT64 OverrideStart = 0;
287 UINT64 OverrideEnd= 0;
288 UINT8 *pCurBuf = (UINT8 *)Buffer;
289 ventoy_img_chunk *pchunk = g_chunk;
290 ventoy_override_chunk *pOverride = g_override_chunk;
291 EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo;
292
293 debug("read iso sector %lu count %u", Sector, Count);
294
295 ReadStart = Sector * 2048;
296 ReadEnd = (Sector + Count) * 2048;
297
298 for (i = 0; Count > 0 && i < g_img_chunk_num; i++, pchunk++)
299 {
300 if (Sector >= pchunk->img_start_sector && Sector <= pchunk->img_end_sector)
301 {
302 if (g_chain->disk_sector_size == 512)
303 {
304 MapLba = (Sector - pchunk->img_start_sector) * 4 + pchunk->disk_start_sector;
305 }
306 else
307 {
308 MapLba = (Sector - pchunk->img_start_sector) * 2048 / g_chain->disk_sector_size + pchunk->disk_start_sector;
309 }
310
311 secLeft = pchunk->img_end_sector + 1 - Sector;
312 secRead = (Count < secLeft) ? Count : secLeft;
313
314 Status = pRawBlockIo->ReadBlocks(pRawBlockIo, pRawBlockIo->Media->MediaId,
315 MapLba, secRead * 2048, pCurBuf);
316 if (EFI_ERROR(Status))
317 {
318 debug("Raw disk read block failed %r", Status);
319 return Status;
320 }
321
322 Count -= secRead;
323 Sector += secRead;
324 pCurBuf += secRead * 2048;
325 }
326 }
327
328 if (ReadStart > g_chain->real_img_size_in_bytes)
329 {
330 return EFI_SUCCESS;
331 }
332
333 /* override data */
334 pCurBuf = (UINT8 *)Buffer;
335 for (i = 0; i < g_override_chunk_num; i++, pOverride++)
336 {
337 OverrideStart = pOverride->img_offset;
338 OverrideEnd = pOverride->img_offset + pOverride->override_size;
339
340 if (OverrideStart >= ReadEnd || ReadStart >= OverrideEnd)
341 {
342 continue;
343 }
344
345 if (ReadStart <= OverrideStart)
346 {
347 if (ReadEnd <= OverrideEnd)
348 {
349 CopyMem(pCurBuf + OverrideStart - ReadStart, pOverride->override_data, ReadEnd - OverrideStart);
350 }
351 else
352 {
353 CopyMem(pCurBuf + OverrideStart - ReadStart, pOverride->override_data, pOverride->override_size);
354 }
355 }
356 else
357 {
358 if (ReadEnd <= OverrideEnd)
359 {
360 CopyMem(pCurBuf, pOverride->override_data + ReadStart - OverrideStart, ReadEnd - ReadStart);
361 }
362 else
363 {
364 CopyMem(pCurBuf, pOverride->override_data + ReadStart - OverrideStart, OverrideEnd - ReadStart);
365 }
366 }
367 }
368
369 return EFI_SUCCESS;
370 }
371
372 EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read
373 (
374 IN EFI_BLOCK_IO_PROTOCOL *This,
375 IN UINT32 MediaId,
376 IN EFI_LBA Lba,
377 IN UINTN BufferSize,
378 OUT VOID *Buffer
379 )
380 {
381 //debug("### ventoy_block_io_ramdisk_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048);
382
383 (VOID)This;
384 (VOID)MediaId;
385
386 CopyMem(Buffer, (char *)g_chain + (Lba * 2048), BufferSize);
387
388 return EFI_SUCCESS;
389 }
390
391 EFI_STATUS EFIAPI ventoy_block_io_read
392 (
393 IN EFI_BLOCK_IO_PROTOCOL *This,
394 IN UINT32 MediaId,
395 IN EFI_LBA Lba,
396 IN UINTN BufferSize,
397 OUT VOID *Buffer
398 )
399 {
400 UINT32 i = 0;
401 UINT32 j = 0;
402 UINT32 lbacount = 0;
403 UINT32 secNum = 0;
404 UINT64 offset = 0;
405 EFI_LBA curlba = 0;
406 EFI_LBA lastlba = 0;
407 UINT8 *lastbuffer;
408 ventoy_sector_flag *cur_flag;
409 ventoy_virt_chunk *node;
410
411 //debug("### ventoy_block_io_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048);
412
413 secNum = BufferSize / 2048;
414 offset = Lba * 2048;
415
416 if (offset + BufferSize < g_chain->real_img_size_in_bytes)
417 {
418 return ventoy_read_iso_sector(Lba, secNum, Buffer);
419 }
420
421 if (secNum > g_sector_flag_num)
422 {
423 cur_flag = AllocatePool(secNum * sizeof(ventoy_sector_flag));
424 if (NULL == cur_flag)
425 {
426 return EFI_OUT_OF_RESOURCES;
427 }
428
429 FreePool(g_sector_flag);
430 g_sector_flag = cur_flag;
431 g_sector_flag_num = secNum;
432 }
433
434 for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++)
435 {
436 cur_flag->flag = 0;
437 for (node = g_virt_chunk, i = 0; i < g_virt_chunk_num; i++, node++)
438 {
439 if (curlba >= node->mem_sector_start && curlba < node->mem_sector_end)
440 {
441 CopyMem((UINT8 *)Buffer + j * 2048,
442 (char *)g_virt_chunk + node->mem_sector_offset + (curlba - node->mem_sector_start) * 2048,
443 2048);
444 cur_flag->flag = 1;
445 break;
446 }
447 else if (curlba >= node->remap_sector_start && curlba < node->remap_sector_end)
448 {
449 cur_flag->remap_lba = node->org_sector_start + curlba - node->remap_sector_start;
450 cur_flag->flag = 2;
451 break;
452 }
453 }
454 }
455
456 for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++)
457 {
458 if (cur_flag->flag == 2)
459 {
460 if (lastlba == 0)
461 {
462 lastbuffer = (UINT8 *)Buffer + j * 2048;
463 lastlba = cur_flag->remap_lba;
464 lbacount = 1;
465 }
466 else if (lastlba + lbacount == cur_flag->remap_lba)
467 {
468 lbacount++;
469 }
470 else
471 {
472 ventoy_read_iso_sector(lastlba, lbacount, lastbuffer);
473 lastbuffer = (UINT8 *)Buffer + j * 2048;
474 lastlba = cur_flag->remap_lba;
475 lbacount = 1;
476 }
477 }
478 }
479
480 if (lbacount > 0)
481 {
482 ventoy_read_iso_sector(lastlba, lbacount, lastbuffer);
483 }
484
485 return EFI_SUCCESS;
486 }
487
488 EFI_STATUS EFIAPI ventoy_block_io_write
489 (
490 IN EFI_BLOCK_IO_PROTOCOL *This,
491 IN UINT32 MediaId,
492 IN EFI_LBA Lba,
493 IN UINTN BufferSize,
494 IN VOID *Buffer
495 )
496 {
497 (VOID)This;
498 (VOID)MediaId;
499 (VOID)Lba;
500 (VOID)BufferSize;
501 (VOID)Buffer;
502 return EFI_WRITE_PROTECTED;
503 }
504
505 EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This)
506 {
507 (VOID)This;
508 return EFI_SUCCESS;
509 }
510
511
512 EFI_STATUS EFIAPI ventoy_fill_device_path(VOID)
513 {
514 UINTN NameLen = 0;
515 UINT8 TmpBuf[128] = {0};
516 VENDOR_DEVICE_PATH *venPath = NULL;
517
518 venPath = (VENDOR_DEVICE_PATH *)TmpBuf;
519 NameLen = StrSize(VTOY_BLOCK_DEVICE_PATH_NAME);
520 venPath->Header.Type = HARDWARE_DEVICE_PATH;
521 venPath->Header.SubType = HW_VENDOR_DP;
522 venPath->Header.Length[0] = sizeof(VENDOR_DEVICE_PATH) + NameLen;
523 venPath->Header.Length[1] = 0;
524 CopyMem(&venPath->Guid, &gVtoyBlockDevicePathGuid, sizeof(EFI_GUID));
525 CopyMem(venPath + 1, VTOY_BLOCK_DEVICE_PATH_NAME, NameLen);
526
527 gBlockData.Path = AppendDevicePathNode(NULL, (EFI_DEVICE_PATH_PROTOCOL *)TmpBuf);
528 gBlockData.DevicePathCompareLen = sizeof(VENDOR_DEVICE_PATH) + NameLen;
529
530 debug("gBlockData.Path=<%s>\n", ConvertDevicePathToText(gBlockData.Path, FALSE, FALSE));
531
532 return EFI_SUCCESS;
533 }
534
535 EFI_STATUS EFIAPI ventoy_save_ramdisk_param(VOID)
536 {
537 EFI_STATUS Status = EFI_SUCCESS;
538 EFI_GUID VarGuid = VENTOY_GUID;
539
540 Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid,
541 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
542 sizeof(g_ramdisk_param), &(g_ramdisk_param));
543 debug("set efi variable %r", Status);
544
545 return Status;
546 }
547
548 EFI_STATUS EFIAPI ventoy_del_ramdisk_param(VOID)
549 {
550 EFI_STATUS Status = EFI_SUCCESS;
551 EFI_GUID VarGuid = VENTOY_GUID;
552
553 Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid,
554 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
555 0, NULL);
556 debug("delete efi variable %r", Status);
557
558 return Status;
559 }
560
561
562 EFI_STATUS EFIAPI ventoy_set_variable(VOID)
563 {
564 EFI_STATUS Status = EFI_SUCCESS;
565 EFI_GUID VarGuid = VENTOY_GUID;
566
567 Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid,
568 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
569 sizeof(g_chain->os_param), &(g_chain->os_param));
570 debug("set efi variable %r", Status);
571
572 return Status;
573 }
574
575 EFI_STATUS EFIAPI ventoy_delete_variable(VOID)
576 {
577 EFI_STATUS Status = EFI_SUCCESS;
578 EFI_GUID VarGuid = VENTOY_GUID;
579
580 Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid,
581 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
582 0, NULL);
583 debug("delete efi variable %r", Status);
584
585 return Status;
586 }
587
588
589 EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize)
590 {
591 EFI_STATUS Status = EFI_SUCCESS;
592 EFI_BLOCK_IO_PROTOCOL *pBlockIo = &(gBlockData.BlockIo);
593
594 ventoy_fill_device_path();
595
596 gBlockData.Media.BlockSize = 2048;
597 gBlockData.Media.LastBlock = ImgSize / 2048 - 1;
598 gBlockData.Media.ReadOnly = TRUE;
599 gBlockData.Media.MediaPresent = 1;
600 gBlockData.Media.LogicalBlocksPerPhysicalBlock = 1;
601
602 pBlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
603 pBlockIo->Media = &(gBlockData.Media);
604 pBlockIo->Reset = ventoy_block_io_reset;
605
606 if (gMemdiskMode)
607 {
608 pBlockIo->ReadBlocks = ventoy_block_io_ramdisk_read;
609 }
610 else
611 {
612 pBlockIo->ReadBlocks = ventoy_block_io_read;
613 }
614
615 pBlockIo->WriteBlocks = ventoy_block_io_write;
616 pBlockIo->FlushBlocks = ventoy_block_io_flush;
617
618 Status = gBS->InstallMultipleProtocolInterfaces(&gBlockData.Handle,
619 &gEfiBlockIoProtocolGuid, &gBlockData.BlockIo,
620 &gEfiDevicePathProtocolGuid, gBlockData.Path,
621 NULL);
622
623 debug("Install protocol %r", Status);
624
625 if (EFI_ERROR(Status))
626 {
627 return Status;
628 }
629
630 Status = gBS->ConnectController(gBlockData.Handle, NULL, NULL, 1);
631 debug("Connect controller %r", Status);
632
633 return EFI_SUCCESS;
634 }
635
636
637 EFI_STATUS EFIAPI ventoy_load_image
638 (
639 IN EFI_HANDLE ImageHandle,
640 IN EFI_DEVICE_PATH_PROTOCOL *pDevicePath,
641 IN CONST CHAR16 *FileName,
642 IN UINTN FileNameLen,
643 OUT EFI_HANDLE *Image
644 )
645 {
646 EFI_STATUS Status = EFI_SUCCESS;
647 CHAR16 TmpBuf[256] = {0};
648 FILEPATH_DEVICE_PATH *pFilePath = NULL;
649 EFI_DEVICE_PATH_PROTOCOL *pImgPath = NULL;
650
651 pFilePath = (FILEPATH_DEVICE_PATH *)TmpBuf;
652 pFilePath->Header.Type = MEDIA_DEVICE_PATH;
653 pFilePath->Header.SubType = MEDIA_FILEPATH_DP;
654 pFilePath->Header.Length[0] = FileNameLen + sizeof(EFI_DEVICE_PATH_PROTOCOL);
655 pFilePath->Header.Length[1] = 0;
656 CopyMem(pFilePath->PathName, FileName, FileNameLen);
657
658 pImgPath = AppendDevicePathNode(pDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)pFilePath);
659 if (!pImgPath)
660 {
661 return EFI_NOT_FOUND;
662 }
663
664 Status = gBS->LoadImage(FALSE, ImageHandle, pImgPath, NULL, 0, Image);
665
666 debug("Load Image File %r DP: <%s>", Status, ConvertDevicePathToText(pImgPath, FALSE, FALSE));
667
668 FreePool(pImgPath);
669
670 return Status;
671 }
672
673
674 STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle)
675 {
676 UINTN i = 0;
677 UINTN Count = 0;
678 UINT64 DiskSize = 0;
679 UINT8 *pBuffer = NULL;
680 EFI_HANDLE *Handles;
681 EFI_STATUS Status = EFI_SUCCESS;
682 EFI_BLOCK_IO_PROTOCOL *pBlockIo;
683
684 pBuffer = AllocatePool(2048);
685 if (!pBuffer)
686 {
687 return EFI_OUT_OF_RESOURCES;
688 }
689
690 Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiBlockIoProtocolGuid,
691 NULL, &Count, &Handles);
692 if (EFI_ERROR(Status))
693 {
694 FreePool(pBuffer);
695 return Status;
696 }
697
698 for (i = 0; i < Count; i++)
699 {
700 Status = gBS->HandleProtocol(Handles[i], &gEfiBlockIoProtocolGuid, (VOID **)&pBlockIo);
701 if (EFI_ERROR(Status))
702 {
703 continue;
704 }
705
706 DiskSize = (pBlockIo->Media->LastBlock + 1) * pBlockIo->Media->BlockSize;
707 debug("This Disk size: %llu", DiskSize);
708 if (g_chain->os_param.vtoy_disk_size != DiskSize)
709 {
710 continue;
711 }
712
713 Status = pBlockIo->ReadBlocks(pBlockIo, pBlockIo->Media->MediaId, 0, 512, pBuffer);
714 if (EFI_ERROR(Status))
715 {
716 debug("ReadBlocks filed %r", Status);
717 continue;
718 }
719
720 if (CompareMem(g_chain->os_param.vtoy_disk_guid, pBuffer + 0x180, 16) == 0)
721 {
722 gBlockData.RawBlockIoHandle = Handles[i];
723 gBlockData.pRawBlockIo = pBlockIo;
724 gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid,
725 (VOID **)&(gBlockData.pDiskDevPath),
726 ImageHandle,
727 Handles[i],
728 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
729
730 debug("Find Ventoy Disk Handle:%p DP:%s", Handles[i],
731 ConvertDevicePathToText(gBlockData.pDiskDevPath, FALSE, FALSE));
732 break;
733 }
734 }
735
736 FreePool(Handles);
737
738 if (i >= Count)
739 {
740 return EFI_NOT_FOUND;
741 }
742 else
743 {
744 return EFI_SUCCESS;
745 }
746 }
747
748 STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk_fs(IN EFI_HANDLE ImageHandle)
749 {
750 UINTN i = 0;
751 UINTN Count = 0;
752 EFI_HANDLE Parent = NULL;
753 EFI_HANDLE *Handles = NULL;
754 EFI_STATUS Status = EFI_SUCCESS;
755 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = NULL;
756 EFI_DEVICE_PATH_PROTOCOL *pDevPath = NULL;
757
758 Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid,
759 NULL, &Count, &Handles);
760 if (EFI_ERROR(Status))
761 {
762 return Status;
763 }
764
765 debug("ventoy_find_iso_disk_fs fs count:%u", Count);
766
767 for (i = 0; i < Count; i++)
768 {
769 Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile);
770 if (EFI_ERROR(Status))
771 {
772 continue;
773 }
774
775 Status = gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid,
776 (VOID **)&pDevPath,
777 ImageHandle,
778 Handles[i],
779 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
780 if (EFI_ERROR(Status))
781 {
782 debug("Failed to open device path protocol %r", Status);
783 continue;
784 }
785
786 debug("Handle:%p FS DP: <%s>", Handles[i], ConvertDevicePathToText(pDevPath, FALSE, FALSE));
787 Parent = ventoy_get_parent_handle(pDevPath);
788
789 if (Parent == gBlockData.RawBlockIoHandle)
790 {
791 debug("Find ventoy disk fs");
792 gBlockData.DiskFsHandle = Handles[i];
793 gBlockData.pDiskFs = pFile;
794 gBlockData.pDiskFsDevPath = pDevPath;
795 break;
796 }
797 }
798
799 FreePool(Handles);
800
801 return EFI_SUCCESS;
802 }
803
804 STATIC EFI_STATUS EFIAPI ventoy_load_isoefi_driver(IN EFI_HANDLE ImageHandle)
805 {
806 EFI_HANDLE Image = NULL;
807 EFI_STATUS Status = EFI_SUCCESS;
808 CHAR16 LogVar[4] = L"5";
809
810 Status = ventoy_load_image(ImageHandle, gBlockData.pDiskFsDevPath,
811 gIso9660EfiDriverPath,
812 sizeof(gIso9660EfiDriverPath),
813 &Image);
814 debug("load iso efi driver status:%r", Status);
815
816 if (gDebugPrint)
817 {
818 gRT->SetVariable(L"FS_LOGGING", &gShellVariableGuid,
819 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
820 sizeof(LogVar), LogVar);
821 }
822
823 gRT->SetVariable(L"FS_NAME_NOCASE", &gShellVariableGuid,
824 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
825 sizeof(LogVar), LogVar);
826
827 gBlockData.IsoDriverImage = Image;
828 Status = gBS->StartImage(Image, NULL, NULL);
829 debug("Start iso efi driver status:%r", Status);
830
831 return EFI_SUCCESS;
832 }
833
834 static int ventoy_update_image_location(ventoy_os_param *param)
835 {
836 EFI_STATUS Status = EFI_SUCCESS;
837 UINT8 chksum = 0;
838 unsigned int i;
839 unsigned int length;
840 UINTN address = 0;
841 void *buffer = NULL;
842 ventoy_image_location *location = NULL;
843 ventoy_image_disk_region *region = NULL;
844 ventoy_img_chunk *chunk = g_chunk;
845
846 length = sizeof(ventoy_image_location) + (g_img_chunk_num - 1) * sizeof(ventoy_image_disk_region);
847
848 Status = gBS->AllocatePool(EfiRuntimeServicesData, length + 4096 * 2, &buffer);
849 if (EFI_ERROR(Status) || NULL == buffer)
850 {
851 debug("Failed to allocate runtime pool %r\n", Status);
852 return 1;
853 }
854
855 address = (UINTN)buffer;
856
857 if (address % 4096)
858 {
859 address += 4096 - (address % 4096);
860 }
861
862 param->chksum = 0;
863 param->vtoy_img_location_addr = address;
864 param->vtoy_img_location_len = length;
865
866 /* update check sum */
867 for (i = 0; i < sizeof(ventoy_os_param); i++)
868 {
869 chksum += *((UINT8 *)param + i);
870 }
871 param->chksum = (chksum == 0) ? 0 : (UINT8)(0x100 - chksum);
872
873 location = (ventoy_image_location *)(unsigned long)(param->vtoy_img_location_addr);
874 if (NULL == location)
875 {
876 return 0;
877 }
878
879 CopyMem(&location->guid, &param->guid, sizeof(ventoy_guid));
880 location->image_sector_size = 2048;
881 location->disk_sector_size = g_chain->disk_sector_size;
882 location->region_count = g_img_chunk_num;
883
884 region = location->regions;
885
886 for (i = 0; i < g_img_chunk_num; i++)
887 {
888 region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1;
889 region->image_start_sector = chunk->img_start_sector;
890 region->disk_start_sector = chunk->disk_start_sector;
891 region++;
892 chunk++;
893 }
894
895 return 0;
896 }
897
898 STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
899 {
900 UINT32 i = 0;
901 UINT32 old_cnt = 0;
902 UINTN size = 0;
903 UINT8 chksum = 0;
904 CHAR16 *pPos = NULL;
905 CHAR16 *pCmdLine = NULL;
906 EFI_STATUS Status = EFI_SUCCESS;
907 ventoy_grub_param *pGrubParam = NULL;
908 EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL;
909
910 Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo);
911 if (EFI_ERROR(Status))
912 {
913 VtoyDebug("Failed to handle load image protocol %r", Status);
914 return Status;
915 }
916
917 pCmdLine = (CHAR16 *)AllocatePool(pImageInfo->LoadOptionsSize + 4);
918 SetMem(pCmdLine, pImageInfo->LoadOptionsSize + 4, 0);
919 CopyMem(pCmdLine, pImageInfo->LoadOptions, pImageInfo->LoadOptionsSize);
920
921 if (StrStr(pCmdLine, L"debug"))
922 {
923 gDebugPrint = TRUE;
924 }
925
926 if (StrStr(pCmdLine, L"isoefi=on"))
927 {
928 gLoadIsoEfi = TRUE;
929 }
930
931 pPos = StrStr(pCmdLine, L"FirstTry=@");
932 if (pPos)
933 {
934 pPos += StrLen(L"FirstTry=");
935 for (i = 0; i < ARRAY_SIZE(gFirstTryBootFile); i++, pPos++)
936 {
937 if (*pPos != L' ' && *pPos != L'\t' && *pPos)
938 {
939 gFirstTryBootFile[i] = (*pPos == '@') ? '\\' : *pPos;
940 }
941 else
942 {
943 break;
944 }
945 }
946
947 gEfiBootFileName[0] = gFirstTryBootFile;
948 gBootFileStartIndex = 0;
949 }
950
951 debug("cmdline:<%s>", pCmdLine);
952
953 if (gFirstTryBootFile[0])
954 {
955 debug("First Try:<%s>", gFirstTryBootFile);
956 }
957
958 pPos = StrStr(pCmdLine, L"env_param=");
959 if (!pPos)
960 {
961 return EFI_INVALID_PARAMETER;
962 }
963
964 pGrubParam = (ventoy_grub_param *)StrHexToUintn(pPos + StrLen(L"env_param="));
965 grub_env_get = pGrubParam->grub_env_get;
966
967 g_file_replace_list = &pGrubParam->file_replace;
968 old_cnt = g_file_replace_list->old_file_cnt;
969 debug("file replace: magic:0x%x virtid:%u name count:%u <%a> <%a> <%a> <%a>",
970 g_file_replace_list->magic,
971 g_file_replace_list->new_file_virtual_id,
972 old_cnt,
973 old_cnt > 0 ? g_file_replace_list->old_file_name[0] : "",
974 old_cnt > 1 ? g_file_replace_list->old_file_name[1] : "",
975 old_cnt > 2 ? g_file_replace_list->old_file_name[2] : "",
976 old_cnt > 3 ? g_file_replace_list->old_file_name[3] : ""
977 );
978
979 pPos = StrStr(pCmdLine, L"mem:");
980 g_chain = (ventoy_chain_head *)StrHexToUintn(pPos + 4);
981
982 pPos = StrStr(pPos, L"size:");
983 size = StrDecimalToUintn(pPos + 5);
984
985 debug("memory addr:%p size:%lu", g_chain, size);
986
987 if (StrStr(pCmdLine, L"memdisk"))
988 {
989 g_iso_buf_size = size;
990 gMemdiskMode = TRUE;
991 }
992 else
993 {
994 g_chunk = (ventoy_img_chunk *)((char *)g_chain + g_chain->img_chunk_offset);
995 g_img_chunk_num = g_chain->img_chunk_num;
996 g_override_chunk = (ventoy_override_chunk *)((char *)g_chain + g_chain->override_chunk_offset);
997 g_override_chunk_num = g_chain->override_chunk_num;
998 g_virt_chunk = (ventoy_virt_chunk *)((char *)g_chain + g_chain->virt_chunk_offset);
999 g_virt_chunk_num = g_chain->virt_chunk_num;
1000
1001 for (i = 0; i < sizeof(ventoy_os_param); i++)
1002 {
1003 chksum += *((UINT8 *)(&(g_chain->os_param)) + i);
1004 }
1005
1006 if (gDebugPrint)
1007 {
1008 debug("os param checksum: 0x%x %a", g_chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS");
1009 }
1010
1011 ventoy_update_image_location(&(g_chain->os_param));
1012
1013 if (gDebugPrint)
1014 {
1015 ventoy_dump_chain(g_chain);
1016 }
1017 }
1018
1019 FreePool(pCmdLine);
1020 return EFI_SUCCESS;
1021 }
1022
1023 EFI_STATUS EFIAPI ventoy_wrapper_file_open
1024 (
1025 EFI_FILE_HANDLE This,
1026 EFI_FILE_HANDLE *New,
1027 CHAR16 *Name,
1028 UINT64 Mode,
1029 UINT64 Attributes
1030 )
1031 {
1032 UINT32 i = 0;
1033 UINT32 j = 0;
1034 UINT64 Sectors = 0;
1035 EFI_STATUS Status = EFI_SUCCESS;
1036 CHAR8 TmpName[256];
1037 ventoy_virt_chunk *virt = NULL;
1038
1039 Status = g_original_fopen(This, New, Name, Mode, Attributes);
1040 if (EFI_ERROR(Status))
1041 {
1042 return Status;
1043 }
1044
1045 if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC &&
1046 g_file_replace_list->new_file_virtual_id < g_virt_chunk_num)
1047 {
1048 AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name);
1049 for (j = 0; j < 4; j++)
1050 {
1051 if (0 == AsciiStrCmp(g_file_replace_list[i].old_file_name[j], TmpName))
1052 {
1053 g_original_fclose(*New);
1054 *New = &g_efi_file_replace.WrapperHandle;
1055 ventoy_wrapper_file_procotol(*New);
1056
1057 virt = g_virt_chunk + g_file_replace_list->new_file_virtual_id;
1058
1059 Sectors = (virt->mem_sector_end - virt->mem_sector_start) + (virt->remap_sector_end - virt->remap_sector_start);
1060
1061 g_efi_file_replace.BlockIoSectorStart = virt->mem_sector_start;
1062 g_efi_file_replace.FileSizeBytes = Sectors * 2048;
1063
1064 if (gDebugPrint)
1065 {
1066 debug("## ventoy_wrapper_file_open <%s> BlockStart:%lu Sectors:%lu Bytes:%lu", Name,
1067 g_efi_file_replace.BlockIoSectorStart, Sectors, Sectors * 2048);
1068 sleep(3);
1069 }
1070
1071 return Status;
1072 }
1073 }
1074 }
1075
1076 return Status;
1077 }
1078
1079 EFI_STATUS EFIAPI ventoy_wrapper_open_volume
1080 (
1081 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
1082 OUT EFI_FILE_PROTOCOL **Root
1083 )
1084 {
1085 EFI_STATUS Status = EFI_SUCCESS;
1086
1087 Status = g_original_open_volume(This, Root);
1088 if (!EFI_ERROR(Status))
1089 {
1090 g_original_fopen = (*Root)->Open;
1091 g_original_fclose = (*Root)->Close;
1092 (*Root)->Open = ventoy_wrapper_file_open;
1093 }
1094
1095 return Status;
1096 }
1097
1098
1099 EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle)
1100 {
1101 UINTN t = 0;
1102 UINTN i = 0;
1103 UINTN j = 0;
1104 UINTN Find = 0;
1105 UINTN Count = 0;
1106 EFI_HANDLE Image = NULL;
1107 EFI_HANDLE *Handles = NULL;
1108 EFI_STATUS Status = EFI_SUCCESS;
1109 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = NULL;
1110 EFI_DEVICE_PATH_PROTOCOL *pDevPath = NULL;
1111
1112 for (t = 0; t < 3; t++)
1113 {
1114 Count = 0;
1115 Handles = NULL;
1116
1117 Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid,
1118 NULL, &Count, &Handles);
1119 if (EFI_ERROR(Status))
1120 {
1121 return Status;
1122 }
1123
1124 debug("ventoy_boot fs count:%u", Count);
1125
1126 for (i = 0; i < Count; i++)
1127 {
1128 Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile);
1129 if (EFI_ERROR(Status))
1130 {
1131 continue;
1132 }
1133
1134 debug("FS:%u Protocol:%p OpenVolume:%p", i, pFile, pFile->OpenVolume);
1135
1136 Status = gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid,
1137 (VOID **)&pDevPath,
1138 ImageHandle,
1139 Handles[i],
1140 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
1141 if (EFI_ERROR(Status))
1142 {
1143 debug("Failed to open device path protocol %r", Status);
1144 continue;
1145 }
1146
1147 debug("Handle:%p FS DP: <%s>", Handles[i], ConvertDevicePathToText(pDevPath, FALSE, FALSE));
1148 if (CompareMem(gBlockData.Path, pDevPath, gBlockData.DevicePathCompareLen))
1149 {
1150 debug("Not ventoy disk file system");
1151 continue;
1152 }
1153
1154 for (j = gBootFileStartIndex; j < ARRAY_SIZE(gEfiBootFileName); j++)
1155 {
1156 Status = ventoy_load_image(ImageHandle, pDevPath, gEfiBootFileName[j],
1157 StrSize(gEfiBootFileName[j]), &Image);
1158 if (EFI_SUCCESS == Status)
1159 {
1160 break;
1161 }
1162 debug("Failed to load image %r <%s>", Status, gEfiBootFileName[j]);
1163 }
1164
1165 if (j >= ARRAY_SIZE(gEfiBootFileName))
1166 {
1167 continue;
1168 }
1169
1170 Find++;
1171 debug("Find boot file, now try to boot .....");
1172 ventoy_debug_pause();
1173
1174 if (gDebugPrint)
1175 {
1176 gST->ConIn->Reset(gST->ConIn, FALSE);
1177 //ventoy_wrapper_system();
1178 }
1179
1180 if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC)
1181 {
1182 g_original_open_volume = pFile->OpenVolume;
1183 pFile->OpenVolume = ventoy_wrapper_open_volume;
1184 }
1185
1186 Status = gBS->StartImage(Image, NULL, NULL);
1187 if (EFI_ERROR(Status))
1188 {
1189 debug("Failed to start image %r", Status);
1190 sleep(3);
1191 gBS->UnloadImage(Image);
1192 break;
1193 }
1194 }
1195
1196 FreePool(Handles);
1197
1198 if (Find == 0)
1199 {
1200 debug("Fs not found, now wait and retry...");
1201 sleep(2);
1202 }
1203 }
1204
1205 if (Find == 0)
1206 {
1207 return EFI_NOT_FOUND;
1208 }
1209
1210 return EFI_SUCCESS;
1211 }
1212
1213 EFI_STATUS EFIAPI ventoy_clean_env(VOID)
1214 {
1215 FreePool(g_sector_flag);
1216 g_sector_flag_num = 0;
1217
1218 if (gLoadIsoEfi && gBlockData.IsoDriverImage)
1219 {
1220 gBS->UnloadImage(gBlockData.IsoDriverImage);
1221 }
1222
1223 gBS->DisconnectController(gBlockData.Handle, NULL, NULL);
1224
1225 gBS->UninstallMultipleProtocolInterfaces(gBlockData.Handle,
1226 &gEfiBlockIoProtocolGuid, &gBlockData.BlockIo,
1227 &gEfiDevicePathProtocolGuid, gBlockData.Path,
1228 NULL);
1229
1230 ventoy_delete_variable();
1231
1232 if (g_chain->os_param.vtoy_img_location_addr)
1233 {
1234 FreePool((VOID *)(UINTN)g_chain->os_param.vtoy_img_location_addr);
1235 }
1236
1237 return EFI_SUCCESS;
1238 }
1239
1240 EFI_STATUS EFIAPI ventoy_ramdisk_boot(IN EFI_HANDLE ImageHandle)
1241 {
1242 EFI_STATUS Status = EFI_SUCCESS;
1243 EFI_RAM_DISK_PROTOCOL *RamDisk = NULL;
1244 EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL;
1245
1246 debug("RamDisk Boot ...");
1247
1248 Status = gBS->LocateProtocol(&gEfiRamDiskProtocolGuid, NULL, (VOID **)&RamDisk);
1249 if (EFI_ERROR(Status))
1250 {
1251 debug("Failed to locate ramdisk protocol %r", Status);
1252 return Status;
1253 }
1254 debug("Locate RamDisk Protocol %r ...", Status);
1255
1256 Status = RamDisk->Register((UINTN)g_chain, (UINT64)g_iso_buf_size, &gEfiVirtualCdGuid, NULL, &DevicePath);
1257 if (EFI_ERROR(Status))
1258 {
1259 debug("Failed to register ramdisk %r", Status);
1260 return Status;
1261 }
1262
1263 debug("Register RamDisk %r ...", Status);
1264 debug("RamDisk DevicePath:<%s> ...", ConvertDevicePathToText(DevicePath, FALSE, FALSE));
1265
1266 ventoy_debug_pause();
1267
1268 gBlockData.Path = DevicePath;
1269 gBlockData.DevicePathCompareLen = GetDevicePathSize(DevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);
1270
1271 Status = ventoy_boot(ImageHandle);
1272 if (EFI_NOT_FOUND == Status)
1273 {
1274 gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n");
1275 gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n");
1276 sleep(300);
1277 }
1278
1279 return EFI_SUCCESS;
1280 }
1281
1282 EFI_STATUS EFIAPI VentoyEfiMain
1283 (
1284 IN EFI_HANDLE ImageHandle,
1285 IN EFI_SYSTEM_TABLE *SystemTable
1286 )
1287 {
1288 EFI_STATUS Status = EFI_SUCCESS;
1289
1290 g_sector_flag_num = 512; /* initial value */
1291
1292 g_sector_flag = AllocatePool(g_sector_flag_num * sizeof(ventoy_sector_flag));
1293 if (NULL == g_sector_flag)
1294 {
1295 return EFI_OUT_OF_RESOURCES;
1296 }
1297
1298 gST->ConOut->ClearScreen(gST->ConOut);
1299 ventoy_clear_input();
1300
1301 ventoy_parse_cmdline(ImageHandle);
1302
1303 if (gMemdiskMode)
1304 {
1305 g_ramdisk_param.PhyAddr = (UINT64)(UINTN)g_chain;
1306 g_ramdisk_param.DiskSize = (UINT64)g_iso_buf_size;
1307
1308 ventoy_save_ramdisk_param();
1309
1310 ventoy_install_blockio(ImageHandle, g_iso_buf_size);
1311 Status = ventoy_boot(ImageHandle);
1312 if (EFI_NOT_FOUND == Status)
1313 {
1314 gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n");
1315 gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n");
1316 sleep(300);
1317 }
1318
1319 ventoy_del_ramdisk_param();
1320 }
1321 else
1322 {
1323 ventoy_set_variable();
1324 ventoy_find_iso_disk(ImageHandle);
1325
1326 if (gLoadIsoEfi)
1327 {
1328 ventoy_find_iso_disk_fs(ImageHandle);
1329 ventoy_load_isoefi_driver(ImageHandle);
1330 }
1331
1332 ventoy_debug_pause();
1333
1334 ventoy_install_blockio(ImageHandle, g_chain->virt_img_size_in_bytes);
1335
1336 ventoy_debug_pause();
1337
1338 Status = ventoy_boot(ImageHandle);
1339 if (EFI_NOT_FOUND == Status)
1340 {
1341 if (!gLoadIsoEfi)
1342 {
1343 gLoadIsoEfi = TRUE;
1344 ventoy_find_iso_disk_fs(ImageHandle);
1345 ventoy_load_isoefi_driver(ImageHandle);
1346
1347 Status = ventoy_boot(ImageHandle);
1348 }
1349
1350 if (EFI_NOT_FOUND == Status)
1351 {
1352 gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n");
1353 gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n");
1354 sleep(60);
1355 }
1356 }
1357
1358 ventoy_clean_env();
1359 }
1360
1361 ventoy_clear_input();
1362 gST->ConOut->ClearScreen(gST->ConOut);
1363
1364 return EFI_SUCCESS;
1365 }
1366
1367