]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c
1ce835a94ea205f1f0f70627c791baedf2428526
[Ventoy.git] / EDK2 / edk2_mod / edk2-edk2-stable201911 / MdeModulePkg / Application / Ventoy / VentoyProtocol.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 <Protocol/DriverBinding.h>
38 #include <Ventoy.h>
39
40 UINT8 *g_iso_data_buf = NULL;
41 UINTN g_iso_buf_size = 0;
42 BOOLEAN gMemdiskMode = FALSE;
43 BOOLEAN gSector512Mode = FALSE;
44
45 ventoy_sector_flag *g_sector_flag = NULL;
46 UINT32 g_sector_flag_num = 0;
47
48 EFI_FILE_OPEN g_original_fopen = NULL;
49 EFI_FILE_CLOSE g_original_fclose = NULL;
50 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME g_original_open_volume = NULL;
51
52 /* EFI block device vendor device path GUID */
53 EFI_GUID gVtoyBlockDevicePathGuid = VTOY_BLOCK_DEVICE_PATH_GUID;
54
55 #define VENTOY_ISO9660_SECTOR_OVERFLOW 2097152
56
57 BOOLEAN g_fixup_iso9660_secover_enable = FALSE;
58 BOOLEAN g_fixup_iso9660_secover_start = FALSE;
59 UINT64 g_fixup_iso9660_secover_1st_secs = 0;
60 UINT64 g_fixup_iso9660_secover_cur_secs = 0;
61 UINT64 g_fixup_iso9660_secover_tot_secs = 0;
62
63 STATIC UINTN g_keyboard_hook_count = 0;
64 STATIC BOOLEAN g_blockio_start_record_bcd = FALSE;
65 STATIC BOOLEAN g_blockio_bcd_read_done = FALSE;
66
67 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *g_con_simple_input_ex = NULL;
68 STATIC EFI_INPUT_READ_KEY_EX g_org_read_key_ex = NULL;
69 STATIC EFI_INPUT_READ_KEY g_org_read_key = NULL;
70
71 STATIC EFI_LOCATE_HANDLE g_org_locate_handle = NULL;
72
73 STATIC UINT8 g_sector_buf[2048];
74 STATIC EFI_BLOCK_READ g_sector_2048_read = NULL;
75 STATIC EFI_BLOCK_WRITE g_sector_2048_write = NULL;
76
77 STATIC UINTN g_DriverBindWrapperCnt = 0;
78 STATIC DRIVER_BIND_WRAPPER g_DriverBindWrapperList[MAX_DRIVER_BIND_WRAPPER];
79
80 BOOLEAN ventoy_is_cdrom_dp_exist(VOID)
81 {
82 UINTN i = 0;
83 UINTN Count = 0;
84 EFI_HANDLE *Handles = NULL;
85 EFI_STATUS Status = EFI_SUCCESS;
86 EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL;
87
88 Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiDevicePathProtocolGuid,
89 NULL, &Count, &Handles);
90 if (EFI_ERROR(Status))
91 {
92 return FALSE;
93 }
94
95 for (i = 0; i < Count; i++)
96 {
97 Status = gBS->HandleProtocol(Handles[i], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
98 if (EFI_ERROR(Status))
99 {
100 continue;
101 }
102
103 while (!IsDevicePathEnd(DevicePath))
104 {
105 if (MEDIA_DEVICE_PATH == DevicePath->Type && MEDIA_CDROM_DP == DevicePath->SubType)
106 {
107 FreePool(Handles);
108 return TRUE;
109 }
110
111 DevicePath = NextDevicePathNode(DevicePath);
112 }
113 }
114
115 FreePool(Handles);
116 return FALSE;
117 }
118
119 #if 0
120 /* Block IO procotol */
121 #endif
122
123 EFI_STATUS EFIAPI ventoy_block_io_reset
124 (
125 IN EFI_BLOCK_IO_PROTOCOL *This,
126 IN BOOLEAN ExtendedVerification
127 )
128 {
129 (VOID)This;
130 (VOID)ExtendedVerification;
131 return EFI_SUCCESS;
132 }
133
134 STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector
135 (
136 IN UINT64 Sector,
137 IN UINTN Count,
138 OUT VOID *Buffer
139 )
140 {
141 EFI_STATUS Status = EFI_SUCCESS;
142 EFI_LBA MapLba = 0;
143 UINT32 i = 0;
144 UINTN secLeft = 0;
145 UINTN secRead = 0;
146 UINT64 ReadStart = 0;
147 UINT64 ReadEnd = 0;
148 UINT64 OverrideStart = 0;
149 UINT64 OverrideEnd= 0;
150 UINT8 *pCurBuf = (UINT8 *)Buffer;
151 ventoy_img_chunk *pchunk = g_chunk;
152 ventoy_override_chunk *pOverride = g_override_chunk;
153 EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo;
154
155 debug("read iso sector %lu count %u Buffer:%p Align:%u", Sector, Count, Buffer, pRawBlockIo->Media->IoAlign);
156
157 ReadStart = Sector * 2048;
158 ReadEnd = (Sector + Count) * 2048;
159
160 for (i = 0; Count > 0 && i < g_img_chunk_num; i++, pchunk++)
161 {
162 if (Sector >= pchunk->img_start_sector && Sector <= pchunk->img_end_sector)
163 {
164 if (g_chain->disk_sector_size == 512)
165 {
166 MapLba = (Sector - pchunk->img_start_sector) * 4 + pchunk->disk_start_sector;
167 }
168 else if (g_chain->disk_sector_size == 1024)
169 {
170 MapLba = (Sector - pchunk->img_start_sector) * 2 + pchunk->disk_start_sector;
171 }
172 else if (g_chain->disk_sector_size == 2048)
173 {
174 MapLba = (Sector - pchunk->img_start_sector) + pchunk->disk_start_sector;
175 }
176 else if (g_chain->disk_sector_size == 4096)
177 {
178 MapLba = ((Sector - pchunk->img_start_sector) >> 1) + pchunk->disk_start_sector;
179 }
180
181 secLeft = pchunk->img_end_sector + 1 - Sector;
182 secRead = (Count < secLeft) ? Count : secLeft;
183
184 Status = pRawBlockIo->ReadBlocks(pRawBlockIo, pRawBlockIo->Media->MediaId,
185 MapLba, secRead * 2048, pCurBuf);
186 if (EFI_ERROR(Status))
187 {
188 debug("Raw disk read block failed %r LBA:%lu Count:%u %p", Status, MapLba, secRead, pCurBuf);
189 return Status;
190 }
191
192 Count -= secRead;
193 Sector += secRead;
194 pCurBuf += secRead * 2048;
195 }
196 }
197
198 if (ReadStart > g_chain->real_img_size_in_bytes)
199 {
200 return EFI_SUCCESS;
201 }
202
203 /* override data */
204 pCurBuf = (UINT8 *)Buffer;
205 for (i = 0; i < g_override_chunk_num; i++, pOverride++)
206 {
207 OverrideStart = pOverride->img_offset;
208 OverrideEnd = pOverride->img_offset + pOverride->override_size;
209
210 if (OverrideStart >= ReadEnd || ReadStart >= OverrideEnd)
211 {
212 continue;
213 }
214
215 if (ReadStart <= OverrideStart)
216 {
217 if (ReadEnd <= OverrideEnd)
218 {
219 CopyMem(pCurBuf + OverrideStart - ReadStart, pOverride->override_data, ReadEnd - OverrideStart);
220 }
221 else
222 {
223 CopyMem(pCurBuf + OverrideStart - ReadStart, pOverride->override_data, pOverride->override_size);
224 }
225 }
226 else
227 {
228 if (ReadEnd <= OverrideEnd)
229 {
230 CopyMem(pCurBuf, pOverride->override_data + ReadStart - OverrideStart, ReadEnd - ReadStart);
231 }
232 else
233 {
234 CopyMem(pCurBuf, pOverride->override_data + ReadStart - OverrideStart, OverrideEnd - ReadStart);
235 }
236 }
237
238 if (g_fixup_iso9660_secover_enable && (!g_fixup_iso9660_secover_start) &&
239 pOverride->override_size == sizeof(ventoy_iso9660_override))
240 {
241 ventoy_iso9660_override *dirent = (ventoy_iso9660_override *)pOverride->override_data;
242 if (dirent->first_sector >= VENTOY_ISO9660_SECTOR_OVERFLOW)
243 {
244 g_fixup_iso9660_secover_start = TRUE;
245 g_fixup_iso9660_secover_cur_secs = 0;
246 }
247 }
248 }
249
250 if (g_blockio_start_record_bcd && FALSE == g_blockio_bcd_read_done)
251 {
252 if (*(UINT32 *)Buffer == 0x66676572)
253 {
254 g_blockio_bcd_read_done = TRUE;
255 }
256 }
257
258 return EFI_SUCCESS;
259 }
260
261 STATIC EFI_STATUS EFIAPI ventoy_write_iso_sector
262 (
263 IN UINT64 Sector,
264 IN UINTN Count,
265 IN VOID *Buffer
266 )
267 {
268 EFI_STATUS Status = EFI_SUCCESS;
269 EFI_LBA MapLba = 0;
270 UINT32 i = 0;
271 UINTN secLeft = 0;
272 UINTN secRead = 0;
273 UINT64 ReadStart = 0;
274 UINT64 ReadEnd = 0;
275 UINT8 *pCurBuf = (UINT8 *)Buffer;
276 ventoy_img_chunk *pchunk = g_chunk;
277 EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo;
278
279 debug("write iso sector %lu count %u", Sector, Count);
280
281 ReadStart = Sector * 2048;
282 ReadEnd = (Sector + Count) * 2048;
283
284 for (i = 0; Count > 0 && i < g_img_chunk_num; i++, pchunk++)
285 {
286 if (Sector >= pchunk->img_start_sector && Sector <= pchunk->img_end_sector)
287 {
288 if (g_chain->disk_sector_size == 512)
289 {
290 MapLba = (Sector - pchunk->img_start_sector) * 4 + pchunk->disk_start_sector;
291 }
292 else if (g_chain->disk_sector_size == 1024)
293 {
294 MapLba = (Sector - pchunk->img_start_sector) * 2 + pchunk->disk_start_sector;
295 }
296 else if (g_chain->disk_sector_size == 2048)
297 {
298 MapLba = (Sector - pchunk->img_start_sector) + pchunk->disk_start_sector;
299 }
300 else if (g_chain->disk_sector_size == 4096)
301 {
302 MapLba = ((Sector - pchunk->img_start_sector) >> 1) + pchunk->disk_start_sector;
303 }
304
305
306 secLeft = pchunk->img_end_sector + 1 - Sector;
307 secRead = (Count < secLeft) ? Count : secLeft;
308
309 Status = pRawBlockIo->WriteBlocks(pRawBlockIo, pRawBlockIo->Media->MediaId,
310 MapLba, secRead * 2048, pCurBuf);
311 if (EFI_ERROR(Status))
312 {
313 debug("Raw disk write block failed %r LBA:%lu Count:%u", Status, MapLba, secRead);
314 return Status;
315 }
316
317 Count -= secRead;
318 Sector += secRead;
319 pCurBuf += secRead * 2048;
320 }
321 }
322
323 return EFI_SUCCESS;
324 }
325
326 EFI_STATUS EFIAPI ventoy_block_io_ramdisk_write
327 (
328 IN EFI_BLOCK_IO_PROTOCOL *This,
329 IN UINT32 MediaId,
330 IN EFI_LBA Lba,
331 IN UINTN BufferSize,
332 IN VOID *Buffer
333 )
334 {
335 (VOID)This;
336 (VOID)MediaId;
337 (VOID)Lba;
338 (VOID)BufferSize;
339 (VOID)Buffer;
340
341 if (!gSector512Mode)
342 {
343 return EFI_WRITE_PROTECTED;
344 }
345
346 CopyMem(g_iso_data_buf + (Lba * 2048), Buffer, BufferSize);
347
348 return EFI_SUCCESS;
349 }
350
351 EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read
352 (
353 IN EFI_BLOCK_IO_PROTOCOL *This,
354 IN UINT32 MediaId,
355 IN EFI_LBA Lba,
356 IN UINTN BufferSize,
357 OUT VOID *Buffer
358 )
359 {
360 //debug("### ventoy_block_io_ramdisk_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048);
361
362 (VOID)This;
363 (VOID)MediaId;
364
365 CopyMem(Buffer, g_iso_data_buf + (Lba * 2048), BufferSize);
366
367 if (g_blockio_start_record_bcd && FALSE == g_blockio_bcd_read_done)
368 {
369 if (*(UINT32 *)Buffer == 0x66676572)
370 {
371 g_blockio_bcd_read_done = TRUE;
372 }
373 }
374
375 return EFI_SUCCESS;
376 }
377
378 EFI_LBA EFIAPI ventoy_fixup_iso9660_sector(IN EFI_LBA Lba, UINT32 secNum)
379 {
380 UINT32 i = 0;
381
382 if (g_fixup_iso9660_secover_cur_secs > 0)
383 {
384 Lba += VENTOY_ISO9660_SECTOR_OVERFLOW;
385 g_fixup_iso9660_secover_cur_secs += secNum;
386 if (g_fixup_iso9660_secover_cur_secs >= g_fixup_iso9660_secover_tot_secs)
387 {
388 g_fixup_iso9660_secover_start = FALSE;
389 goto end;
390 }
391 }
392 else
393 {
394 ventoy_iso9660_override *dirent;
395 ventoy_override_chunk *pOverride;
396
397 for (i = 0, pOverride = g_override_chunk; i < g_override_chunk_num; i++, pOverride++)
398 {
399 dirent = (ventoy_iso9660_override *)pOverride->override_data;
400 if (Lba == dirent->first_sector)
401 {
402 g_fixup_iso9660_secover_start = FALSE;
403 goto end;
404 }
405 }
406
407 if (g_fixup_iso9660_secover_start)
408 {
409 for (i = 0, pOverride = g_override_chunk; i < g_override_chunk_num; i++, pOverride++)
410 {
411 dirent = (ventoy_iso9660_override *)pOverride->override_data;
412 if (Lba + VENTOY_ISO9660_SECTOR_OVERFLOW == dirent->first_sector)
413 {
414 g_fixup_iso9660_secover_tot_secs = (dirent->size + 2047) / 2048;
415 g_fixup_iso9660_secover_cur_secs = secNum;
416 if (g_fixup_iso9660_secover_cur_secs >= g_fixup_iso9660_secover_tot_secs)
417 {
418 g_fixup_iso9660_secover_start = FALSE;
419 }
420 Lba += VENTOY_ISO9660_SECTOR_OVERFLOW;
421 goto end;
422 }
423 }
424 }
425 }
426
427 end:
428 return Lba;
429 }
430
431 EFI_STATUS EFIAPI ventoy_block_io_read_real
432 (
433 IN EFI_BLOCK_IO_PROTOCOL *This,
434 IN UINT32 MediaId,
435 IN EFI_LBA Lba,
436 IN UINTN BufferSize,
437 OUT VOID *Buffer
438 )
439 {
440 UINT32 i = 0;
441 UINT32 j = 0;
442 UINT32 lbacount = 0;
443 UINT32 secNum = 0;
444 UINT32 TmpNum = 0;
445 UINT64 VirtSec = 0;
446 UINT64 offset = 0;
447 EFI_LBA curlba = 0;
448 EFI_LBA lastlba = 0;
449 UINT8 *lastbuffer;
450 ventoy_sector_flag *cur_flag;
451 ventoy_virt_chunk *node;
452
453 debug("### block_io_read_real sector:%u count:%u Buffer:%p", (UINT32)Lba, (UINT32)BufferSize / 2048, Buffer);
454
455 secNum = BufferSize / 2048;
456
457 /* Workaround for SSTR PE loader error */
458 if (g_fixup_iso9660_secover_start)
459 {
460 Lba = ventoy_fixup_iso9660_sector(Lba, secNum);
461 }
462
463 offset = Lba * 2048;
464
465 if (offset + BufferSize <= g_chain->real_img_size_in_bytes)
466 {
467 return ventoy_read_iso_sector(Lba, secNum, Buffer);
468 }
469 else if (offset < g_chain->real_img_size_in_bytes)
470 {
471 TmpNum = (g_chain->real_img_size_in_bytes - offset) / 2048;
472 ventoy_read_iso_sector(Lba, TmpNum, Buffer);
473
474 Lba += TmpNum;
475 secNum -= TmpNum;
476 Buffer = (UINT8 *)Buffer + (g_chain->real_img_size_in_bytes - offset);
477 offset = Lba * 2048;
478 }
479
480 VirtSec = g_chain->virt_img_size_in_bytes / 2048;
481 if (Lba >= VirtSec)
482 {
483 return EFI_SUCCESS;
484 }
485 else if (Lba + secNum > VirtSec)
486 {
487 secNum = VirtSec - Lba;
488 }
489
490 debug("XXX block_io_read_real sector:%u count:%u Buffer:%p", (UINT32)Lba, (UINT32)BufferSize / 2048, Buffer);
491
492 if (secNum > g_sector_flag_num)
493 {
494 cur_flag = AllocatePool(secNum * sizeof(ventoy_sector_flag));
495 if (NULL == cur_flag)
496 {
497 return EFI_OUT_OF_RESOURCES;
498 }
499
500 FreePool(g_sector_flag);
501 g_sector_flag = cur_flag;
502 g_sector_flag_num = secNum;
503 }
504
505 for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++)
506 {
507 cur_flag->flag = 0;
508 for (node = g_virt_chunk, i = 0; i < g_virt_chunk_num; i++, node++)
509 {
510 if (curlba >= node->mem_sector_start && curlba < node->mem_sector_end)
511 {
512 CopyMem((UINT8 *)Buffer + j * 2048,
513 (char *)g_virt_chunk + node->mem_sector_offset + (curlba - node->mem_sector_start) * 2048,
514 2048);
515 cur_flag->flag = 1;
516 break;
517 }
518 else if (curlba >= node->remap_sector_start && curlba < node->remap_sector_end)
519 {
520 cur_flag->remap_lba = node->org_sector_start + curlba - node->remap_sector_start;
521 cur_flag->flag = 2;
522 break;
523 }
524 }
525 }
526
527 for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++)
528 {
529 if (cur_flag->flag == 2)
530 {
531 if (lastlba == 0)
532 {
533 lastbuffer = (UINT8 *)Buffer + j * 2048;
534 lastlba = cur_flag->remap_lba;
535 lbacount = 1;
536 }
537 else if (lastlba + lbacount == cur_flag->remap_lba)
538 {
539 lbacount++;
540 }
541 else
542 {
543 ventoy_read_iso_sector(lastlba, lbacount, lastbuffer);
544 lastbuffer = (UINT8 *)Buffer + j * 2048;
545 lastlba = cur_flag->remap_lba;
546 lbacount = 1;
547 }
548 }
549 }
550
551 if (lbacount > 0)
552 {
553 ventoy_read_iso_sector(lastlba, lbacount, lastbuffer);
554 }
555
556 return EFI_SUCCESS;
557 }
558
559 EFI_STATUS EFIAPI ventoy_block_io_read
560 (
561 IN EFI_BLOCK_IO_PROTOCOL *This,
562 IN UINT32 MediaId,
563 IN EFI_LBA Lba,
564 IN UINTN BufferSize,
565 OUT VOID *Buffer
566 )
567 {
568 UINT32 IoAlign = 0;
569 VOID *NewBuf = NULL;
570 EFI_STATUS Status = EFI_OUT_OF_RESOURCES;
571
572 if (gBlockData.pRawBlockIo && gBlockData.pRawBlockIo->Media)
573 {
574 IoAlign = gBlockData.pRawBlockIo->Media->IoAlign;
575 }
576
577 if ((IoAlign == 0) || (((UINTN) Buffer & (IoAlign - 1)) == 0))
578 {
579 Status = ventoy_block_io_read_real(This, MediaId, Lba, BufferSize, Buffer);
580 }
581 else
582 {
583 NewBuf = AllocatePages(EFI_SIZE_TO_PAGES(BufferSize + IoAlign));
584 if (NewBuf)
585 {
586 Status = ventoy_block_io_read_real(This, MediaId, Lba, BufferSize, NewBuf);
587 CopyMem(Buffer, NewBuf, BufferSize);
588 FreePages(NewBuf, EFI_SIZE_TO_PAGES(BufferSize + IoAlign));
589 }
590 }
591
592 return Status;
593 }
594
595 EFI_STATUS EFIAPI ventoy_block_io_write
596 (
597 IN EFI_BLOCK_IO_PROTOCOL *This,
598 IN UINT32 MediaId,
599 IN EFI_LBA Lba,
600 IN UINTN BufferSize,
601 IN VOID *Buffer
602 )
603 {
604 UINT32 secNum = 0;
605 UINT64 offset = 0;
606
607 (VOID)This;
608 (VOID)MediaId;
609
610 if (!gSector512Mode)
611 {
612 return EFI_WRITE_PROTECTED;
613 }
614
615 secNum = BufferSize / 2048;
616 offset = Lba * 2048;
617
618 return ventoy_write_iso_sector(Lba, secNum, Buffer);
619 }
620
621 EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This)
622 {
623 (VOID)This;
624 return EFI_SUCCESS;
625 }
626
627
628 EFI_STATUS EFIAPI ventoy_fill_device_path(VOID)
629 {
630 UINTN NameLen = 0;
631 UINT8 TmpBuf[128] = {0};
632 VENDOR_DEVICE_PATH *venPath = NULL;
633
634 venPath = (VENDOR_DEVICE_PATH *)TmpBuf;
635 NameLen = StrSize(VTOY_BLOCK_DEVICE_PATH_NAME);
636 venPath->Header.Type = HARDWARE_DEVICE_PATH;
637 venPath->Header.SubType = HW_VENDOR_DP;
638 venPath->Header.Length[0] = sizeof(VENDOR_DEVICE_PATH) + NameLen;
639 venPath->Header.Length[1] = 0;
640 CopyMem(&venPath->Guid, &gVtoyBlockDevicePathGuid, sizeof(EFI_GUID));
641 CopyMem(venPath + 1, VTOY_BLOCK_DEVICE_PATH_NAME, NameLen);
642
643 gBlockData.Path = AppendDevicePathNode(NULL, (EFI_DEVICE_PATH_PROTOCOL *)TmpBuf);
644 gBlockData.DevicePathCompareLen = sizeof(VENDOR_DEVICE_PATH) + NameLen;
645
646 debug("gBlockData.Path=<%s>\n", ConvertDevicePathToText(gBlockData.Path, FALSE, FALSE));
647
648 return EFI_SUCCESS;
649 }
650
651 EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST CHAR16 *DrvName)
652 {
653 UINTN i = 0;
654 UINTN Count = 0;
655 CHAR16 *DriverName = NULL;
656 EFI_HANDLE *Handles = NULL;
657 EFI_HANDLE DrvHandles[2] = { NULL };
658 EFI_STATUS Status = EFI_SUCCESS;
659 EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL;
660 EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL;
661
662 debug("ventoy_connect_driver <%s>...", DrvName);
663
664 Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentName2ProtocolGuid,
665 NULL, &Count, &Handles);
666 if (EFI_ERROR(Status))
667 {
668 return Status;
669 }
670
671 for (i = 0; i < Count; i++)
672 {
673 Status = gBS->HandleProtocol(Handles[i], &gEfiComponentName2ProtocolGuid, (VOID **)&Name2Protocol);
674 if (EFI_ERROR(Status))
675 {
676 continue;
677 }
678
679 VENTOY_GET_COMPONENT_NAME(Name2Protocol, DriverName);
680
681 if (StrStr(DriverName, DrvName))
682 {
683 debug("Find driver name2:<%s>: <%s>", DriverName, DrvName);
684 DrvHandles[0] = Handles[i];
685 break;
686 }
687 }
688
689 if (i < Count)
690 {
691 Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE);
692 debug("ventoy_connect_driver:<%s> <%r>", DrvName, Status);
693 goto end;
694 }
695
696 debug("%s NOT found, now try COMPONENT_NAME", DrvName);
697
698 Count = 0;
699 FreePool(Handles);
700 Handles = NULL;
701
702 Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid,
703 NULL, &Count, &Handles);
704 if (EFI_ERROR(Status))
705 {
706 return Status;
707 }
708
709 for (i = 0; i < Count; i++)
710 {
711 Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol);
712 if (EFI_ERROR(Status))
713 {
714 continue;
715 }
716
717 VENTOY_GET_COMPONENT_NAME(NameProtocol, DriverName);
718
719 if (StrStr(DriverName, DrvName))
720 {
721 debug("Find driver name:<%s>: <%s>", DriverName, DrvName);
722 DrvHandles[0] = Handles[i];
723 break;
724 }
725 }
726
727 if (i < Count)
728 {
729 Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE);
730 debug("ventoy_connect_driver:<%s> <%r>", DrvName, Status);
731 goto end;
732 }
733
734 Status = EFI_NOT_FOUND;
735
736 end:
737 FreePool(Handles);
738
739 return Status;
740 }
741
742
743 STATIC BOOLEAN ventoy_filesystem_need_wrapper(IN CONST CHAR16 *DrvName)
744 {
745 UINTN i;
746 CHAR16 UpperDrvName[256];
747
748 StrCpyS(UpperDrvName, 256, DrvName);
749
750 for (i = 0; i < 256 && UpperDrvName[i]; i++)
751 {
752 if (UpperDrvName[i] >= 'a' && UpperDrvName[i] <= 'z')
753 {
754 UpperDrvName[i] = 'A' + (UpperDrvName[i] - 'a');
755 }
756 }
757
758 /*
759 * suppress some file system drivers
760 * 1. rEFInd File System Driver
761 *
762 */
763
764 if (StrStr(UpperDrvName, L"ISO9660") || StrStr(UpperDrvName, L"UDF"))
765 {
766 return TRUE;
767 }
768
769 if (StrStr(UpperDrvName, L"REFIND") && StrStr(UpperDrvName, L"FILE SYSTEM"))
770 {
771 return TRUE;
772 }
773
774 return FALSE;
775 }
776
777 STATIC VOID ventoy_add_filesystem_wrapper
778 (
779 IN EFI_DRIVER_BINDING_PROTOCOL *DriverBindProtocol,
780 IN CONST CHAR16 *DriverName
781 )
782 {
783 UINTN j;
784
785 if (g_DriverBindWrapperCnt >= MAX_DRIVER_BIND_WRAPPER)
786 {
787 debug("driver binding wrapper overflow %lu", g_DriverBindWrapperCnt);
788 return;
789 }
790
791 if (!ventoy_filesystem_need_wrapper(DriverName))
792 {
793 return;
794 }
795
796 for (j = 0; j < g_DriverBindWrapperCnt; j++)
797 {
798 if (g_DriverBindWrapperList[j].DriverBinding == DriverBindProtocol)
799 {
800 debug("Duplicate driverbinding <%s> %p %lu %lu", DriverName, DriverBindProtocol, j, g_DriverBindWrapperCnt);
801 break;
802 }
803 }
804
805 if (j >= g_DriverBindWrapperCnt)
806 {
807 g_DriverBindWrapperList[g_DriverBindWrapperCnt].DriverBinding = DriverBindProtocol;
808 g_DriverBindWrapperList[g_DriverBindWrapperCnt].pfOldSupport = DriverBindProtocol->Supported;
809 g_DriverBindWrapperCnt++;
810 debug("Add driverbinding <%s> %p %lu", DriverName, DriverBindProtocol, g_DriverBindWrapperCnt);
811 }
812 }
813
814 STATIC EFI_STATUS ventoy_find_filesystem_driverbind(VOID)
815 {
816 UINTN i = 0;
817 UINTN Count = 0;
818 CHAR16 *DriverName = NULL;
819 EFI_HANDLE *Handles = NULL;
820 EFI_STATUS Status = EFI_SUCCESS;
821 EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL;
822 EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL;
823 EFI_DRIVER_BINDING_PROTOCOL *DriverBindProtocol = NULL;
824
825 debug("ventoy_find_filesystem_driverbind...");
826
827 Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentName2ProtocolGuid,
828 NULL, &Count, &Handles);
829 if (EFI_ERROR(Status))
830 {
831 return Status;
832 }
833
834 for (i = 0; i < Count; i++)
835 {
836 Status = gBS->HandleProtocol(Handles[i], &gEfiComponentName2ProtocolGuid, (VOID **)&Name2Protocol);
837 if (EFI_ERROR(Status))
838 {
839 continue;
840 }
841
842 VENTOY_GET_COMPONENT_NAME(Name2Protocol, DriverName);
843
844 Status = gBS->HandleProtocol(Handles[i], &gEfiDriverBindingProtocolGuid, (VOID **)&DriverBindProtocol);
845 if (EFI_ERROR(Status))
846 {
847 debug("### 2 No DriverBind <%s> <%r>", DriverName, Status);
848 continue;
849 }
850
851 ventoy_add_filesystem_wrapper(DriverBindProtocol, DriverName);
852 }
853
854 Count = 0;
855 FreePool(Handles);
856 Handles = NULL;
857
858 Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid,
859 NULL, &Count, &Handles);
860 if (EFI_ERROR(Status))
861 {
862 return Status;
863 }
864
865 for (i = 0; i < Count; i++)
866 {
867 Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol);
868 if (EFI_ERROR(Status))
869 {
870 debug();
871 continue;
872 }
873
874 VENTOY_GET_COMPONENT_NAME(NameProtocol, DriverName);
875
876 Status = gBS->HandleProtocol(Handles[i], &gEfiDriverBindingProtocolGuid, (VOID **)&DriverBindProtocol);
877 if (EFI_ERROR(Status))
878 {
879 debug("### 1 No DriverBind <%s> <%r>", DriverName, Status);
880 continue;
881 }
882
883 ventoy_add_filesystem_wrapper(DriverBindProtocol, DriverName);
884 }
885
886 FreePool(Handles);
887
888 return EFI_SUCCESS;
889 }
890
891 STATIC EFI_STATUS EFIAPI ventoy_wrapper_driver_bind_support
892 (
893 IN EFI_DRIVER_BINDING_PROTOCOL *This,
894 IN EFI_HANDLE ControllerHandle,
895 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
896 )
897 {
898 UINTN i;
899 EFI_STATUS Status = EFI_SUCCESS;
900 EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL;
901 EFI_DRIVER_BINDING_SUPPORTED pfOldSupport = NULL;
902
903 for (i = 0; i < g_DriverBindWrapperCnt; i++)
904 {
905 if (g_DriverBindWrapperList[i].DriverBinding == This)
906 {
907 pfOldSupport = g_DriverBindWrapperList[i].pfOldSupport;
908 break;
909 }
910 }
911
912 debug("ventoy_wrapper_driver_bind_support %lu %p", i, pfOldSupport);
913
914 if (!pfOldSupport)
915 {
916 return EFI_UNSUPPORTED;
917 }
918
919 Status = gBS->HandleProtocol(ControllerHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
920 if (EFI_ERROR(Status))
921 {
922 goto out;
923 }
924
925 if (0 == CompareMem(gBlockData.Path, DevicePath, gBlockData.DevicePathCompareLen))
926 {
927 debug("return EFI_UNSUPPORTED for ventoy");
928 return EFI_UNSUPPORTED;
929 }
930
931 out:
932 return pfOldSupport(This, ControllerHandle, RemainingDevicePath);
933 }
934
935 EFI_STATUS ventoy_disable_ex_filesystem(VOID)
936 {
937 UINTN i;
938
939 ventoy_find_filesystem_driverbind();
940
941 for (i = 0; i < g_DriverBindWrapperCnt; i++)
942 {
943 g_DriverBindWrapperList[i].DriverBinding->Supported = ventoy_wrapper_driver_bind_support;
944 }
945
946 debug("Wrapper Ex Driver Binding %lu", g_DriverBindWrapperCnt);
947 ventoy_debug_pause();
948
949 return EFI_SUCCESS;
950 }
951
952 EFI_STATUS ventoy_enable_ex_filesystem(VOID)
953 {
954 UINTN i;
955
956 for (i = 0; i < g_DriverBindWrapperCnt; i++)
957 {
958 g_DriverBindWrapperList[i].DriverBinding->Supported = g_DriverBindWrapperList[i].pfOldSupport;
959 }
960 g_DriverBindWrapperCnt = 0;
961
962 return EFI_SUCCESS;
963 }
964
965 EFI_STATUS EFIAPI ventoy_block_io_read_512
966 (
967 IN EFI_BLOCK_IO_PROTOCOL *This,
968 IN UINT32 MediaId,
969 IN EFI_LBA Lba,
970 IN UINTN BufferSize,
971 OUT VOID *Buffer
972 )
973 {
974 EFI_LBA Mod;
975 UINTN ReadSize;
976 UINT8 *CurBuf = NULL;
977 EFI_STATUS Status = EFI_SUCCESS;
978
979 debug("ventoy_block_io_read_512 %lu %lu Buffer:%p\n", Lba, BufferSize / 512, Buffer);
980
981 CurBuf = (UINT8 *)Buffer;
982
983 Mod = Lba % 4;
984 if (Mod > 0)
985 {
986 Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf);
987
988 if (BufferSize <= (4 - Mod) * 512)
989 {
990 CopyMem(CurBuf, g_sector_buf + Mod * 512, BufferSize);
991 return EFI_SUCCESS;
992 }
993 else
994 {
995 ReadSize = (4 - Mod) * 512;
996 CopyMem(CurBuf, g_sector_buf + Mod * 512, ReadSize);
997 CurBuf += ReadSize;
998 Lba += (4 - Mod);
999 BufferSize -= ReadSize;
1000 }
1001 }
1002
1003 if (BufferSize >= 2048)
1004 {
1005 ReadSize = BufferSize / 2048 * 2048;
1006
1007 Status |= g_sector_2048_read(This, MediaId, Lba / 4, ReadSize, CurBuf);
1008 CurBuf += ReadSize;
1009
1010 Lba += ReadSize / 512;
1011 BufferSize -= ReadSize;
1012 }
1013
1014 if (BufferSize > 0)
1015 {
1016 Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf);
1017 CopyMem(CurBuf, g_sector_buf, BufferSize);
1018 }
1019
1020 return Status;
1021 }
1022
1023 EFI_STATUS EFIAPI ventoy_block_io_write_512
1024 (
1025 IN EFI_BLOCK_IO_PROTOCOL *This,
1026 IN UINT32 MediaId,
1027 IN EFI_LBA Lba,
1028 IN UINTN BufferSize,
1029 IN VOID *Buffer
1030 )
1031 {
1032 EFI_LBA Mod;
1033 UINTN ReadSize;
1034 UINT8 *CurBuf = NULL;
1035 EFI_STATUS Status = EFI_SUCCESS;
1036
1037 debug("ventoy_block_io_write_512 %lu %lu\n", Lba, BufferSize / 512);
1038
1039 CurBuf = (UINT8 *)Buffer;
1040
1041 Mod = Lba % 4;
1042 if (Mod > 0)
1043 {
1044 Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf);
1045
1046 if (BufferSize <= (4 - Mod) * 512)
1047 {
1048 CopyMem(g_sector_buf + Mod * 512, CurBuf, BufferSize);
1049 return g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf);
1050 }
1051 else
1052 {
1053 ReadSize = (4 - Mod) * 512;
1054 CopyMem(g_sector_buf + Mod * 512, CurBuf, ReadSize);
1055 g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf);
1056
1057 CurBuf += ReadSize;
1058 Lba += (4 - Mod);
1059 BufferSize -= ReadSize;
1060 }
1061 }
1062
1063 if (BufferSize >= 2048)
1064 {
1065 ReadSize = BufferSize / 2048 * 2048;
1066
1067 Status |= g_sector_2048_write(This, MediaId, Lba / 4, ReadSize, CurBuf);
1068 CurBuf += ReadSize;
1069
1070 Lba += ReadSize / 512;
1071 BufferSize -= ReadSize;
1072 }
1073
1074 if (BufferSize > 0)
1075 {
1076 Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf);
1077
1078 CopyMem(g_sector_buf, CurBuf, BufferSize);
1079 g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf);
1080 }
1081
1082 return Status;
1083 }
1084
1085 EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize)
1086 {
1087 EFI_STATUS Status = EFI_SUCCESS;
1088 EFI_BLOCK_IO_PROTOCOL *pBlockIo = &(gBlockData.BlockIo);
1089
1090 ventoy_fill_device_path();
1091
1092 debug("install block io protocol %p", ImageHandle);
1093 ventoy_debug_pause();
1094
1095 if (gSector512Mode)
1096 {
1097 gBlockData.Media.BlockSize = 512;
1098 gBlockData.Media.LastBlock = ImgSize / 512 - 1;
1099 }
1100 else
1101 {
1102 gBlockData.Media.BlockSize = 2048;
1103 gBlockData.Media.LastBlock = ImgSize / 2048 - 1;
1104 }
1105
1106 gBlockData.Media.ReadOnly = TRUE;
1107 gBlockData.Media.MediaPresent = 1;
1108 gBlockData.Media.LogicalBlocksPerPhysicalBlock = 1;
1109
1110 pBlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
1111 pBlockIo->Media = &(gBlockData.Media);
1112 pBlockIo->Reset = ventoy_block_io_reset;
1113
1114 if (gSector512Mode)
1115 {
1116 g_sector_2048_read = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read;
1117 g_sector_2048_write = gMemdiskMode ? ventoy_block_io_ramdisk_write : ventoy_block_io_write;
1118 pBlockIo->ReadBlocks = ventoy_block_io_read_512;
1119 pBlockIo->WriteBlocks = ventoy_block_io_write_512;
1120 }
1121 else
1122 {
1123 pBlockIo->ReadBlocks = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read;
1124 pBlockIo->WriteBlocks = ventoy_block_io_write;
1125 }
1126
1127 pBlockIo->FlushBlocks = ventoy_block_io_flush;
1128
1129 Status = gBS->InstallMultipleProtocolInterfaces(&gBlockData.Handle,
1130 &gEfiBlockIoProtocolGuid, &gBlockData.BlockIo,
1131 &gEfiDevicePathProtocolGuid, gBlockData.Path,
1132 NULL);
1133 debug("Install protocol %r %p", Status, gBlockData.Handle);
1134 if (EFI_ERROR(Status))
1135 {
1136 return Status;
1137 }
1138
1139 Status = ventoy_connect_driver(gBlockData.Handle, L"Disk I/O Driver");
1140 debug("Connect disk IO driver %r", Status);
1141
1142 Status = ventoy_connect_driver(gBlockData.Handle, L"Partition Driver");
1143 debug("Connect partition driver %r", Status);
1144 if (EFI_ERROR(Status))
1145 {
1146 Status = gBS->ConnectController(gBlockData.Handle, NULL, NULL, TRUE);
1147 debug("Connect all controller %r", Status);
1148 }
1149
1150 ventoy_debug_pause();
1151
1152 return EFI_SUCCESS;
1153 }
1154
1155 #if 0
1156 /* For file replace */
1157 #endif
1158
1159 STATIC EFI_STATUS EFIAPI
1160 ventoy_wrapper_fs_open(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, CHAR16 *Name, UINT64 Mode, UINT64 Attributes)
1161 {
1162 (VOID)This;
1163 (VOID)New;
1164 (VOID)Name;
1165 (VOID)Mode;
1166 (VOID)Attributes;
1167 return EFI_SUCCESS;
1168 }
1169
1170 STATIC EFI_STATUS EFIAPI
1171 ventoy_wrapper_file_open_ex(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, CHAR16 *Name, UINT64 Mode, UINT64 Attributes, EFI_FILE_IO_TOKEN *Token)
1172 {
1173 return ventoy_wrapper_fs_open(This, New, Name, Mode, Attributes);
1174 }
1175
1176 STATIC EFI_STATUS EFIAPI
1177 ventoy_wrapper_file_delete(EFI_FILE_HANDLE This)
1178 {
1179 (VOID)This;
1180 return EFI_SUCCESS;
1181 }
1182
1183 STATIC EFI_STATUS EFIAPI
1184 ventoy_wrapper_file_set_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN Len, VOID *Data)
1185 {
1186 return EFI_SUCCESS;
1187 }
1188
1189 STATIC EFI_STATUS EFIAPI
1190 ventoy_wrapper_file_flush(EFI_FILE_HANDLE This)
1191 {
1192 (VOID)This;
1193 return EFI_SUCCESS;
1194 }
1195
1196 /* Ex version */
1197 STATIC EFI_STATUS EFIAPI
1198 ventoy_wrapper_file_flush_ex(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token)
1199 {
1200 (VOID)This;
1201 (VOID)Token;
1202 return EFI_SUCCESS;
1203 }
1204
1205
1206 STATIC EFI_STATUS EFIAPI
1207 ventoy_wrapper_file_write(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data)
1208 {
1209 (VOID)This;
1210 (VOID)Len;
1211 (VOID)Data;
1212
1213 return EFI_WRITE_PROTECTED;
1214 }
1215
1216 STATIC EFI_STATUS EFIAPI
1217 ventoy_wrapper_file_write_ex(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token)
1218 {
1219 return ventoy_wrapper_file_write(This, &(Token->BufferSize), Token->Buffer);
1220 }
1221
1222
1223 STATIC EFI_STATUS EFIAPI
1224 ventoy_wrapper_file_close(EFI_FILE_HANDLE This)
1225 {
1226 (VOID)This;
1227 return EFI_SUCCESS;
1228 }
1229
1230
1231 STATIC EFI_STATUS EFIAPI
1232 ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This, UINT64 Position)
1233 {
1234 (VOID)This;
1235
1236 if (Position <= g_efi_file_replace.FileSizeBytes)
1237 {
1238 g_efi_file_replace.CurPos = Position;
1239 }
1240 else
1241 {
1242 g_efi_file_replace.CurPos = g_efi_file_replace.FileSizeBytes;
1243 }
1244
1245 return EFI_SUCCESS;
1246 }
1247
1248 STATIC EFI_STATUS EFIAPI
1249 ventoy_wrapper_file_get_pos(EFI_FILE_HANDLE This, UINT64 *Position)
1250 {
1251 (VOID)This;
1252
1253 *Position = g_efi_file_replace.CurPos;
1254
1255 return EFI_SUCCESS;
1256 }
1257
1258
1259 STATIC EFI_STATUS EFIAPI
1260 ventoy_wrapper_file_get_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN *Len, VOID *Data)
1261 {
1262 EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data;
1263
1264 debug("ventoy_wrapper_file_get_info ... %u", *Len);
1265
1266 if (!CompareGuid(Type, &gEfiFileInfoGuid))
1267 {
1268 return EFI_INVALID_PARAMETER;
1269 }
1270
1271 if (*Len == 0)
1272 {
1273 *Len = 384;
1274 return EFI_BUFFER_TOO_SMALL;
1275 }
1276
1277 ZeroMem(Data, sizeof(EFI_FILE_INFO));
1278
1279 Info->Size = sizeof(EFI_FILE_INFO);
1280 Info->FileSize = g_efi_file_replace.FileSizeBytes;
1281 Info->PhysicalSize = g_efi_file_replace.FileSizeBytes;
1282 Info->Attribute = EFI_FILE_READ_ONLY;
1283 //Info->FileName = EFI_FILE_READ_ONLY;
1284
1285 *Len = Info->Size;
1286
1287 return EFI_SUCCESS;
1288 }
1289
1290 STATIC EFI_STATUS EFIAPI
1291 ventoy_wrapper_file_read(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data)
1292 {
1293 EFI_LBA Lba;
1294 UINTN ReadLen = *Len;
1295
1296 (VOID)This;
1297
1298 debug("ventoy_wrapper_file_read ... %u", *Len);
1299
1300 if (g_efi_file_replace.CurPos + ReadLen > g_efi_file_replace.FileSizeBytes)
1301 {
1302 ReadLen = g_efi_file_replace.FileSizeBytes - g_efi_file_replace.CurPos;
1303 }
1304
1305 Lba = g_efi_file_replace.CurPos / 2048 + g_efi_file_replace.BlockIoSectorStart;
1306
1307 ventoy_block_io_read(NULL, 0, Lba, ReadLen, Data);
1308
1309 *Len = ReadLen;
1310
1311 g_efi_file_replace.CurPos += ReadLen;
1312
1313 return EFI_SUCCESS;
1314 }
1315
1316 STATIC EFI_STATUS EFIAPI
1317 ventoy_wrapper_file_read_ex(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token)
1318 {
1319 return ventoy_wrapper_file_read(This, &(Token->BufferSize), Token->Buffer);
1320 }
1321
1322 STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File)
1323 {
1324 File->Revision = EFI_FILE_PROTOCOL_REVISION2;
1325 File->Open = ventoy_wrapper_fs_open;
1326 File->Close = ventoy_wrapper_file_close;
1327 File->Delete = ventoy_wrapper_file_delete;
1328 File->Read = ventoy_wrapper_file_read;
1329 File->Write = ventoy_wrapper_file_write;
1330 File->GetPosition = ventoy_wrapper_file_get_pos;
1331 File->SetPosition = ventoy_wrapper_file_set_pos;
1332 File->GetInfo = ventoy_wrapper_file_get_info;
1333 File->SetInfo = ventoy_wrapper_file_set_info;
1334 File->Flush = ventoy_wrapper_file_flush;
1335 File->OpenEx = ventoy_wrapper_file_open_ex;
1336 File->ReadEx = ventoy_wrapper_file_read_ex;
1337 File->WriteEx = ventoy_wrapper_file_write_ex;
1338 File->FlushEx = ventoy_wrapper_file_flush_ex;
1339
1340 return EFI_SUCCESS;
1341 }
1342
1343 STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open
1344 (
1345 EFI_FILE_HANDLE This,
1346 EFI_FILE_HANDLE *New,
1347 CHAR16 *Name,
1348 UINT64 Mode,
1349 UINT64 Attributes
1350 )
1351 {
1352 UINT32 i = 0;
1353 UINT32 j = 0;
1354 UINT64 Sectors = 0;
1355 EFI_STATUS Status = EFI_SUCCESS;
1356 CHAR8 TmpName[256];
1357 ventoy_virt_chunk *virt = NULL;
1358
1359 debug("## ventoy_wrapper_file_open <%s> ", Name);
1360
1361 Status = g_original_fopen(This, New, Name, Mode, Attributes);
1362 if (EFI_ERROR(Status))
1363 {
1364 return Status;
1365 }
1366
1367 if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC &&
1368 g_file_replace_list->new_file_virtual_id < g_virt_chunk_num)
1369 {
1370 AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name);
1371 for (j = 0; j < 4; j++)
1372 {
1373 if (0 == AsciiStrCmp(g_file_replace_list[i].old_file_name[j], TmpName))
1374 {
1375 g_original_fclose(*New);
1376 *New = &g_efi_file_replace.WrapperHandle;
1377 ventoy_wrapper_file_procotol(*New);
1378
1379 virt = g_virt_chunk + g_file_replace_list->new_file_virtual_id;
1380
1381 Sectors = (virt->mem_sector_end - virt->mem_sector_start) + (virt->remap_sector_end - virt->remap_sector_start);
1382
1383 g_efi_file_replace.BlockIoSectorStart = virt->mem_sector_start;
1384 g_efi_file_replace.FileSizeBytes = Sectors * 2048;
1385
1386 if (gDebugPrint)
1387 {
1388 debug("## ventoy_wrapper_file_open <%s> BlockStart:%lu Sectors:%lu Bytes:%lu", Name,
1389 g_efi_file_replace.BlockIoSectorStart, Sectors, Sectors * 2048);
1390 sleep(3);
1391 }
1392
1393 return Status;
1394 }
1395 }
1396
1397 if (StrCmp(Name, L"\\EFI\\BOOT") == 0)
1398 {
1399 (*New)->Open = ventoy_wrapper_file_open;
1400 }
1401 }
1402
1403 return Status;
1404 }
1405
1406 EFI_STATUS EFIAPI ventoy_wrapper_open_volume
1407 (
1408 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
1409 OUT EFI_FILE_PROTOCOL **Root
1410 )
1411 {
1412 EFI_STATUS Status = EFI_SUCCESS;
1413
1414 Status = g_original_open_volume(This, Root);
1415 if (!EFI_ERROR(Status))
1416 {
1417 g_original_fopen = (*Root)->Open;
1418 g_original_fclose = (*Root)->Close;
1419 (*Root)->Open = ventoy_wrapper_file_open;
1420 }
1421
1422 return Status;
1423 }
1424
1425 EFI_STATUS EFIAPI ventoy_wrapper_push_openvolume(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume)
1426 {
1427 g_original_open_volume = OpenVolume;
1428 return EFI_SUCCESS;
1429 }
1430
1431 #if 0
1432 /* For auto skip Windows 'Press any key to boot from CD or DVD ...' */
1433 #endif
1434
1435 STATIC EFI_STATUS EFIAPI ventoy_wrapper_read_key_ex
1436 (
1437 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
1438 OUT EFI_KEY_DATA *KeyData
1439 )
1440 {
1441 /* only hook once before BCD file read */
1442 if (g_keyboard_hook_count == 0 && g_blockio_bcd_read_done == FALSE)
1443 {
1444 g_keyboard_hook_count++;
1445
1446 KeyData->Key.ScanCode = SCAN_DELETE;
1447 KeyData->Key.UnicodeChar = 0;
1448 KeyData->KeyState.KeyShiftState = 0;
1449 KeyData->KeyState.KeyToggleState = 0;
1450
1451 return EFI_SUCCESS;
1452 }
1453
1454 return g_org_read_key_ex(This, KeyData);
1455 }
1456
1457 EFI_STATUS EFIAPI ventoy_wrapper_read_key
1458 (
1459 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
1460 OUT EFI_INPUT_KEY *Key
1461 )
1462 {
1463 /* only hook once before BCD file read */
1464 if (g_keyboard_hook_count == 0 && g_blockio_bcd_read_done == FALSE)
1465 {
1466 g_keyboard_hook_count++;
1467
1468 Key->ScanCode = SCAN_DELETE;
1469 Key->UnicodeChar = 0;
1470 return EFI_SUCCESS;
1471 }
1472
1473 return g_org_read_key(This, Key);
1474 }
1475
1476 EFI_STATUS ventoy_hook_keyboard_start(VOID)
1477 {
1478 g_blockio_start_record_bcd = TRUE;
1479 g_blockio_bcd_read_done = FALSE;
1480 g_keyboard_hook_count = 0;
1481
1482 if (g_con_simple_input_ex)
1483 {
1484 g_org_read_key_ex = g_con_simple_input_ex->ReadKeyStrokeEx;
1485 g_con_simple_input_ex->ReadKeyStrokeEx = ventoy_wrapper_read_key_ex;
1486 }
1487
1488 g_org_read_key = gST->ConIn->ReadKeyStroke;
1489 gST->ConIn->ReadKeyStroke = ventoy_wrapper_read_key;
1490
1491 return EFI_SUCCESS;
1492 }
1493
1494 EFI_STATUS ventoy_hook_keyboard_stop(VOID)
1495 {
1496 g_blockio_start_record_bcd = FALSE;
1497 g_blockio_bcd_read_done = FALSE;
1498 g_keyboard_hook_count = 0;
1499
1500 if (g_con_simple_input_ex)
1501 {
1502 g_con_simple_input_ex->ReadKeyStrokeEx = g_org_read_key_ex;
1503 }
1504
1505 gST->ConIn->ReadKeyStroke = g_org_read_key;
1506
1507 return EFI_SUCCESS;
1508 }
1509
1510 #if 0
1511 /* Fixup the 1st cdrom influnce for Windows boot */
1512 #endif
1513
1514 STATIC EFI_STATUS EFIAPI ventoy_wrapper_locate_handle
1515 (
1516 IN EFI_LOCATE_SEARCH_TYPE SearchType,
1517 IN EFI_GUID *Protocol, OPTIONAL
1518 IN VOID *SearchKey, OPTIONAL
1519 IN OUT UINTN *BufferSize,
1520 OUT EFI_HANDLE *Buffer
1521 )
1522 {
1523 UINTN i;
1524 EFI_HANDLE Handle = NULL;
1525 EFI_STATUS Status = EFI_SUCCESS;
1526
1527 Status = g_org_locate_handle(SearchType, Protocol, SearchKey, BufferSize, Buffer);
1528
1529 if (EFI_SUCCESS == Status && Protocol && CompareGuid(&gEfiBlockIoProtocolGuid, Protocol))
1530 {
1531 for (i = 0; i < (*BufferSize) / sizeof(EFI_HANDLE); i++)
1532 {
1533 if (Buffer[i] == gBlockData.Handle)
1534 {
1535 Handle = Buffer[0];
1536 Buffer[0] = Buffer[i];
1537 Buffer[i] = Handle;
1538 break;
1539 }
1540 }
1541 }
1542
1543 return Status;
1544 }
1545
1546 EFI_STATUS ventoy_hook_1st_cdrom_start(VOID)
1547 {
1548 g_org_locate_handle = gBS->LocateHandle;
1549 gBS->LocateHandle = ventoy_wrapper_locate_handle;
1550
1551 return EFI_SUCCESS;
1552 }
1553
1554 EFI_STATUS ventoy_hook_1st_cdrom_stop(VOID)
1555 {
1556 gBS->LocateHandle = g_org_locate_handle;
1557 g_org_locate_handle = NULL;
1558
1559 return EFI_SUCCESS;
1560 }
1561