diff --git a/DOC/BuildVentoyFromSource.txt b/DOC/BuildVentoyFromSource.txt index 0a3e8fe1..64ffc842 100644 --- a/DOC/BuildVentoyFromSource.txt +++ b/DOC/BuildVentoyFromSource.txt @@ -202,3 +202,10 @@ https://busybox.net/downloads/binaries/1.31.0-i686-uclibc/ busybox_ASH SHA-256: 2943f02f85fee0c9551aec47110a558a73f919c032b3c51e56d6f197b5ec4d7b +5.12 7za.exe + download from https://www.7-zip.org/a/7z1900-extra.7z + ISNTALL/ventoy/7z/64/7za.exe SHA-256: 8117e40ee7f824f63373a4f5625bb62749f69159d0c449b3ce2f35aad3b83549 + ISNTALL/ventoy/7z/32/7za.exe SHA-256: ea308c76a2f927b160a143d94072b0dce232e04b751f0c6432a94e05164e716d + + + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c index 7c2267f5..bd28ca26 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c @@ -37,6 +37,7 @@ #include BOOLEAN gDebugPrint = FALSE; +BOOLEAN gLoadIsoEfi = FALSE; ventoy_ram_disk g_ramdisk_param; ventoy_chain_head *g_chain; ventoy_img_chunk *g_chunk; @@ -52,6 +53,10 @@ static grub_env_get_pf grub_env_get = NULL; ventoy_grub_param_file_replace *g_file_replace_list = NULL; ventoy_efi_file_replace g_efi_file_replace; +CONST CHAR16 gIso9660EfiDriverPath[] = ISO9660_EFI_DRIVER_PATH; + +BOOLEAN g_fix_windows_1st_cdrom_issue = FALSE; + STATIC BOOLEAN g_hook_keyboard = FALSE; CHAR16 gFirstTryBootFile[256] = {0}; @@ -482,6 +487,93 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle) } } + +STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk_fs(IN EFI_HANDLE ImageHandle) +{ + UINTN i = 0; + UINTN Count = 0; + EFI_HANDLE Parent = NULL; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = NULL; + EFI_DEVICE_PATH_PROTOCOL *pDevPath = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + debug("ventoy_find_iso_disk_fs fs count:%u", Count); + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile); + if (EFI_ERROR(Status)) + { + continue; + } + + Status = gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid, + (VOID **)&pDevPath, + ImageHandle, + Handles[i], + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) + { + debug("Failed to open device path protocol %r", Status); + continue; + } + + debug("Handle:%p FS DP: <%s>", Handles[i], ConvertDevicePathToText(pDevPath, FALSE, FALSE)); + Parent = ventoy_get_parent_handle(pDevPath); + + if (Parent == gBlockData.RawBlockIoHandle) + { + debug("Find ventoy disk fs"); + gBlockData.DiskFsHandle = Handles[i]; + gBlockData.pDiskFs = pFile; + gBlockData.pDiskFsDevPath = pDevPath; + break; + } + } + + FreePool(Handles); + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI ventoy_load_isoefi_driver(IN EFI_HANDLE ImageHandle) +{ + EFI_HANDLE Image = NULL; + EFI_STATUS Status = EFI_SUCCESS; + CHAR16 LogVar[4] = L"5"; + + Status = ventoy_load_image(ImageHandle, gBlockData.pDiskFsDevPath, + gIso9660EfiDriverPath, + sizeof(gIso9660EfiDriverPath), + &Image); + debug("load iso efi driver status:%r", Status); + + if (gDebugPrint) + { + gRT->SetVariable(L"FS_LOGGING", &gShellVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(LogVar), LogVar); + } + + gRT->SetVariable(L"FS_NAME_NOCASE", &gShellVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(LogVar), LogVar); + + gBlockData.IsoDriverImage = Image; + Status = gBS->StartImage(Image, NULL, NULL); + debug("Start iso efi driver status:%r", Status); + + return EFI_SUCCESS; +} + STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) { UINT32 i = 0; @@ -493,6 +585,7 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) EFI_STATUS Status = EFI_SUCCESS; ventoy_grub_param *pGrubParam = NULL; EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL; + ventoy_chain_head *chain = NULL; Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo); if (EFI_ERROR(Status)) @@ -510,6 +603,11 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) gDebugPrint = TRUE; } + if (StrStr(pCmdLine, L"isoefi=on")) + { + gLoadIsoEfi = TRUE; + } + pPos = StrStr(pCmdLine, L"FirstTry=@"); if (pPos) { @@ -559,12 +657,15 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) ); pPos = StrStr(pCmdLine, L"mem:"); - g_chain = (ventoy_chain_head *)StrHexToUintn(pPos + 4); + chain = (ventoy_chain_head *)StrHexToUintn(pPos + 4); pPos = StrStr(pPos, L"size:"); size = StrDecimalToUintn(pPos + 5); - debug("memory addr:%p size:%lu", g_chain, size); + debug("memory addr:%p size:%lu", chain, size); + + g_chain = AllocatePool(size); + CopyMem(g_chain, chain, size); if (StrStr(pCmdLine, L"memdisk")) { @@ -583,12 +684,12 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) g_os_param_reserved = (UINT8 *)(g_chain->os_param.vtoy_reserved); /* Workaround for Windows & ISO9660 */ - if (g_os_param_reserved[2] == 1 && g_os_param_reserved[3] == 0) + if (g_os_param_reserved[2] == ventoy_chain_windows && g_os_param_reserved[3] == 0) { g_fixup_iso9660_secover_enable = TRUE; } - if (g_os_param_reserved[2] == 1 && g_os_param_reserved[4] != 1) + if (g_os_param_reserved[2] == ventoy_chain_windows && g_os_param_reserved[4] != 1) { g_hook_keyboard = TRUE; } @@ -613,6 +714,17 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) } } + g_fix_windows_1st_cdrom_issue = FALSE; + if (ventoy_chain_windows == g_os_param_reserved[2] || + ventoy_chain_wim == g_os_param_reserved[2]) + { + if (ventoy_is_cdrom_dp_exist()) + { + debug("fixup the 1st cdrom influences when boot windows ..."); + g_fix_windows_1st_cdrom_issue = TRUE; + } + } + FreePool(pCmdLine); return EFI_SUCCESS; } @@ -622,6 +734,11 @@ EFI_STATUS EFIAPI ventoy_clean_env(VOID) FreePool(g_sector_flag); g_sector_flag_num = 0; + if (gLoadIsoEfi && gBlockData.IsoDriverImage) + { + gBS->UnloadImage(gBlockData.IsoDriverImage); + } + gBS->DisconnectController(gBlockData.Handle, NULL, NULL); gBS->UninstallMultipleProtocolInterfaces(gBlockData.Handle, @@ -636,6 +753,44 @@ EFI_STATUS EFIAPI ventoy_clean_env(VOID) FreePool((VOID *)(UINTN)g_chain->os_param.vtoy_img_location_addr); } + FreePool(g_chain); + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS ventoy_hook_start(VOID) +{ + /* don't add debug print in this function */ + + if (g_fix_windows_1st_cdrom_issue) + { + ventoy_hook_1st_cdrom_start(); + } + + /* let this the last */ + if (g_hook_keyboard) + { + ventoy_hook_keyboard_start(); + } + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS ventoy_hook_stop(VOID) +{ + /* don't add debug print in this function */ + + if (g_fix_windows_1st_cdrom_issue) + { + ventoy_hook_1st_cdrom_stop(); + } + + /* let this the last */ + if (g_hook_keyboard) + { + ventoy_hook_keyboard_stop(); + } + return EFI_SUCCESS; } @@ -725,17 +880,11 @@ EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle) pFile->OpenVolume = ventoy_wrapper_open_volume; } - if (g_hook_keyboard) - { - ventoy_hook_keyboard_start(); - } + ventoy_hook_start(); /* can't add debug print here */ //ventoy_wrapper_system(); Status = gBS->StartImage(Image, NULL, NULL); - if (g_hook_keyboard) - { - ventoy_hook_keyboard_stop(); - } + ventoy_hook_stop(); if (EFI_ERROR(Status)) { @@ -808,6 +957,12 @@ EFI_STATUS EFIAPI VentoyEfiMain ventoy_save_variable(); ventoy_find_iso_disk(ImageHandle); + if (gLoadIsoEfi) + { + ventoy_find_iso_disk_fs(ImageHandle); + ventoy_load_isoefi_driver(ImageHandle); + } + ventoy_debug_pause(); ventoy_install_blockio(ImageHandle, g_chain->virt_img_size_in_bytes); diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h index 354496e7..2e2ab031 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h @@ -25,6 +25,15 @@ #define VENTOY_GUID { 0x77772020, 0x2e77, 0x6576, { 0x6e, 0x74, 0x6f, 0x79, 0x2e, 0x6e, 0x65, 0x74 }} +typedef enum ventoy_chain_type +{ + ventoy_chain_linux = 0, /* 0: linux */ + ventoy_chain_windows, /* 1: windows */ + ventoy_chain_wim, /* 2: wim */ + + ventoy_chain_max +}ventoy_chain_type; + #pragma pack(1) typedef struct ventoy_guid @@ -159,6 +168,8 @@ typedef struct ventoy_virt_chunk #define VTOY_BLOCK_DEVICE_PATH_GUID \ { 0x37b87ac6, 0xc180, 0x4583, { 0xa7, 0x05, 0x41, 0x4d, 0xa8, 0xf7, 0x7e, 0xd2 }} +#define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_x64.efi" + #define VTOY_BLOCK_DEVICE_PATH_NAME L"ventoy" #if defined (MDE_CPU_IA32) @@ -199,6 +210,7 @@ typedef struct vtoy_block_data EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pDiskFs; EFI_DEVICE_PATH_PROTOCOL *pDiskFsDevPath; + EFI_HANDLE IsoDriverImage; }vtoy_block_data; @@ -216,6 +228,7 @@ if (gDebugPrint) \ } typedef const char * (*grub_env_get_pf)(const char *name); +typedef int (*grub_env_printf_pf)(const char *fmt, ...); #pragma pack(1) @@ -242,8 +255,8 @@ typedef struct ventoy_grub_param_file_replace typedef struct ventoy_grub_param { grub_env_get_pf grub_env_get; - ventoy_grub_param_file_replace file_replace; + grub_env_printf_pf grub_env_printf; }ventoy_grub_param; typedef struct ventoy_ram_disk @@ -279,6 +292,18 @@ typedef struct ventoy_system_wrapper EFI_OPEN_PROTOCOL NewOpenProtocol; EFI_OPEN_PROTOCOL OriOpenProtocol; + + EFI_LOCATE_HANDLE_BUFFER NewLocateHandleBuffer; + EFI_LOCATE_HANDLE_BUFFER OriLocateHandleBuffer; + + EFI_PROTOCOLS_PER_HANDLE NewProtocolsPerHandle; + EFI_PROTOCOLS_PER_HANDLE OriProtocolsPerHandle; + + EFI_LOCATE_HANDLE NewLocateHandle; + EFI_LOCATE_HANDLE OriLocateHandle; + + EFI_LOCATE_DEVICE_PATH NewLocateDevicePath; + EFI_LOCATE_DEVICE_PATH OriLocateDevicePath; } ventoy_system_wrapper; #define ventoy_wrapper(bs, wrapper, func, newfunc) \ @@ -317,6 +342,7 @@ extern UINTN g_iso_buf_size; extern ventoy_grub_param_file_replace *g_file_replace_list; extern BOOLEAN g_fixup_iso9660_secover_enable; extern EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *g_con_simple_input_ex; +extern BOOLEAN g_fix_windows_1st_cdrom_issue; EFI_STATUS EFIAPI ventoy_wrapper_open_volume ( @@ -327,6 +353,9 @@ EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 Im EFI_STATUS EFIAPI ventoy_wrapper_push_openvolume(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume); EFI_STATUS ventoy_hook_keyboard_start(VOID); EFI_STATUS ventoy_hook_keyboard_stop(VOID); +BOOLEAN ventoy_is_cdrom_dp_exist(VOID); +EFI_STATUS ventoy_hook_1st_cdrom_start(VOID); +EFI_STATUS ventoy_hook_1st_cdrom_stop(VOID); #endif diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyDebug.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyDebug.c index d96c6b2e..7af3349b 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyDebug.c +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyDebug.c @@ -36,9 +36,9 @@ #include #include -#define PROCOTOL_SLEEP_SECONDS 0 +#define PROCOTOL_SLEEP_MSECONDS 0 -#define debug_sleep() if (PROCOTOL_SLEEP_SECONDS) sleep(PROCOTOL_SLEEP_SECONDS) +#define debug_sleep() if (PROCOTOL_SLEEP_MSECONDS) gBS->Stall(1000 * PROCOTOL_SLEEP_MSECONDS) STATIC ventoy_system_wrapper g_system_wrapper; @@ -126,7 +126,7 @@ STATIC EFI_STATUS EFIAPI ventoy_open_protocol IN UINT32 Attributes ) { - debug("ventoy_open_protocol:%a", ventoy_get_guid_name(Protocol)); debug_sleep(); + debug("ventoy_open_protocol:<%p> %a", Handle, ventoy_get_guid_name(Protocol)); debug_sleep(); return g_system_wrapper.OriOpenProtocol(Handle, Protocol, Interface, AgentHandle, ControllerHandle, Attributes); } @@ -141,11 +141,87 @@ STATIC EFI_STATUS EFIAPI ventoy_locate_protocol return g_system_wrapper.OriLocateProtocol(Protocol, Registration, Interface); } +STATIC EFI_STATUS EFIAPI ventoy_locate_handle_buffer +( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol, OPTIONAL + IN VOID *SearchKey, OPTIONAL + IN OUT UINTN *NoHandles, + OUT EFI_HANDLE **Buffer +) +{ + debug("ventoy_locate_handle_buffer:%a", ventoy_get_guid_name(Protocol)); debug_sleep(); + return g_system_wrapper.OriLocateHandleBuffer(SearchType, Protocol, SearchKey, NoHandles, Buffer); +} + +STATIC EFI_STATUS EFIAPI ventoy_protocol_per_handle +( + IN EFI_HANDLE Handle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount +) +{ + debug("ventoy_protocol_per_handle:%p", Handle); debug_sleep(); + return g_system_wrapper.OriProtocolsPerHandle(Handle, ProtocolBuffer, ProtocolBufferCount); +} + +EFI_STATUS EFIAPI ventoy_locate_handle +( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol, OPTIONAL + IN VOID *SearchKey, OPTIONAL + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer +) +{ + UINTN i; + EFI_HANDLE Handle; + EFI_STATUS Status = EFI_SUCCESS; + + debug("ventoy_locate_handle: %d %a %p", SearchType, ventoy_get_guid_name(Protocol), SearchKey); + Status = g_system_wrapper.OriLocateHandle(SearchType, Protocol, SearchKey, BufferSize, Buffer); + debug("ventoy_locate_handle: %r Handle Count:%u", Status, *BufferSize/sizeof(EFI_HANDLE)); + + if (EFI_SUCCESS == Status) + { + for (i = 0; i < *BufferSize / sizeof(EFI_HANDLE); i++) + { + if (Buffer[i] == gBlockData.Handle) + { + Handle = Buffer[0]; + Buffer[0] = Buffer[i]; + Buffer[i] = Handle; + debug("####### Handle at %u", i); + break; + } + } + } + + debug_sleep(); + + return Status; +} + +STATIC EFI_STATUS EFIAPI ventoy_locate_device_path +( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, + OUT EFI_HANDLE *Device +) +{ + debug("ventoy_locate_device_path:%a", ventoy_get_guid_name(Protocol)); debug_sleep(); + return g_system_wrapper.OriLocateDevicePath(Protocol, DevicePath, Device); +} + EFI_STATUS EFIAPI ventoy_wrapper_system(VOID) { - ventoy_wrapper(gBS, g_system_wrapper, LocateProtocol, ventoy_locate_protocol); - ventoy_wrapper(gBS, g_system_wrapper, HandleProtocol, ventoy_handle_protocol); - ventoy_wrapper(gBS, g_system_wrapper, OpenProtocol, ventoy_open_protocol); + ventoy_wrapper(gBS, g_system_wrapper, LocateProtocol, ventoy_locate_protocol); + ventoy_wrapper(gBS, g_system_wrapper, HandleProtocol, ventoy_handle_protocol); + ventoy_wrapper(gBS, g_system_wrapper, OpenProtocol, ventoy_open_protocol); + ventoy_wrapper(gBS, g_system_wrapper, LocateHandleBuffer, ventoy_locate_handle_buffer); + ventoy_wrapper(gBS, g_system_wrapper, ProtocolsPerHandle, ventoy_protocol_per_handle); + ventoy_wrapper(gBS, g_system_wrapper, LocateHandle, ventoy_locate_handle); + ventoy_wrapper(gBS, g_system_wrapper, LocateDevicePath, ventoy_locate_device_path); return EFI_SUCCESS; } diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c index 0e19153c..004c83f9 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c @@ -65,6 +65,47 @@ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *g_con_simple_input_ex = NULL; STATIC EFI_INPUT_READ_KEY_EX g_org_read_key_ex = NULL; STATIC EFI_INPUT_READ_KEY g_org_read_key = NULL; +STATIC EFI_LOCATE_HANDLE g_org_locate_handle = NULL; + +BOOLEAN ventoy_is_cdrom_dp_exist(VOID) +{ + UINTN i = 0; + UINTN Count = 0; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiDevicePathProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return FALSE; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath); + if (EFI_ERROR(Status)) + { + continue; + } + + while (!IsDevicePathEnd(DevicePath)) + { + if (MEDIA_DEVICE_PATH == DevicePath->Type && MEDIA_CDROM_DP == DevicePath->SubType) + { + FreePool(Handles); + return TRUE; + } + + DevicePath = NextDevicePathNode(DevicePath); + } + } + + FreePool(Handles); + return FALSE; +} + #if 0 /* Block IO procotol */ #endif @@ -126,7 +167,7 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector MapLba, secRead * 2048, pCurBuf); if (EFI_ERROR(Status)) { - debug("Raw disk read block failed %r", Status); + debug("Raw disk read block failed %r LBA:%lu Count:%u", Status, MapLba, secRead); return Status; } @@ -475,7 +516,7 @@ EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST if (i < Count) { Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE); - debug("Connect partition driver:<%r>", Status); + debug("ventoy_connect_driver:<%s> <%r>", DrvName, Status); goto end; } @@ -517,7 +558,7 @@ EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST if (i < Count) { Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE); - debug("Connect partition driver:<%r>", Status); + debug("ventoy_connect_driver:<%s> <%r>", DrvName, Status); goto end; } @@ -535,6 +576,9 @@ EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 Im EFI_BLOCK_IO_PROTOCOL *pBlockIo = &(gBlockData.BlockIo); ventoy_fill_device_path(); + + debug("install block io protocol %p", ImageHandle); + ventoy_debug_pause(); gBlockData.Media.BlockSize = 2048; gBlockData.Media.LastBlock = ImgSize / 2048 - 1; @@ -561,7 +605,6 @@ EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 Im Status = ventoy_connect_driver(gBlockData.Handle, L"Disk I/O Driver"); debug("Connect disk IO driver %r", Status); - ventoy_debug_pause(); Status = ventoy_connect_driver(gBlockData.Handle, L"Partition Driver"); debug("Connect partition driver %r", Status); @@ -656,8 +699,16 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This, UINT64 Position) { (VOID)This; + + if (Position <= g_efi_file_replace.FileSizeBytes) + { + g_efi_file_replace.CurPos = Position; + } + else + { + g_efi_file_replace.CurPos = g_efi_file_replace.FileSizeBytes; + } - g_efi_file_replace.CurPos = Position; return EFI_SUCCESS; } @@ -772,6 +823,8 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open CHAR8 TmpName[256]; ventoy_virt_chunk *virt = NULL; + debug("## ventoy_wrapper_file_open <%s> ", Name); + Status = g_original_fopen(This, New, Name, Mode, Attributes); if (EFI_ERROR(Status)) { @@ -807,6 +860,11 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open return Status; } } + + if (StrCmp(Name, L"\\EFI\\BOOT") == 0) + { + (*New)->Open = ventoy_wrapper_file_open; + } } return Status; @@ -916,3 +974,55 @@ EFI_STATUS ventoy_hook_keyboard_stop(VOID) return EFI_SUCCESS; } +#if 0 +/* Fixup the 1st cdrom influnce for Windows boot */ +#endif + +STATIC EFI_STATUS EFIAPI ventoy_wrapper_locate_handle +( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol, OPTIONAL + IN VOID *SearchKey, OPTIONAL + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer +) +{ + UINTN i; + EFI_HANDLE Handle = NULL; + EFI_STATUS Status = EFI_SUCCESS; + + Status = g_org_locate_handle(SearchType, Protocol, SearchKey, BufferSize, Buffer); + + if (EFI_SUCCESS == Status && Protocol && CompareGuid(&gEfiBlockIoProtocolGuid, Protocol)) + { + for (i = 0; i < (*BufferSize) / sizeof(EFI_HANDLE); i++) + { + if (Buffer[i] == gBlockData.Handle) + { + Handle = Buffer[0]; + Buffer[0] = Buffer[i]; + Buffer[i] = Handle; + break; + } + } + } + + return Status; +} + +EFI_STATUS ventoy_hook_1st_cdrom_start(VOID) +{ + g_org_locate_handle = gBS->LocateHandle; + gBS->LocateHandle = ventoy_wrapper_locate_handle; + + return EFI_SUCCESS; +} + +EFI_STATUS ventoy_hook_1st_cdrom_stop(VOID) +{ + gBS->LocateHandle = g_org_locate_handle; + g_org_locate_handle = NULL; + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/Memhole.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/Memhole.c new file mode 100644 index 00000000..715d7bce --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/Memhole.c @@ -0,0 +1,179 @@ +/****************************************************************************** + * Memhole.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +STATIC BOOLEAN IsMemContiguous +( + IN CONST EFI_MEMORY_DESCRIPTOR *Prev, + IN CONST EFI_MEMORY_DESCRIPTOR *Curr, + IN CONST EFI_MEMORY_DESCRIPTOR *Next +) +{ + UINTN Addr1 = 0; + UINTN Addr2 = 0; + + if (Prev == NULL || Curr == NULL || Next == NULL) + { + return FALSE; + } + + if (Prev->Type == EfiBootServicesData && + Curr->Type == EfiConventionalMemory && + Next->Type == EfiBootServicesData) + { + Addr1 = Prev->PhysicalStart + MultU64x64(SIZE_4KB, Prev->NumberOfPages); + Addr2 = Curr->PhysicalStart + MultU64x64(SIZE_4KB, Curr->NumberOfPages); + + if (Addr1 == Curr->PhysicalStart && Addr2 == Next->PhysicalStart) + { + return TRUE; + } + } + + return FALSE; +} + +STATIC EFI_MEMORY_DESCRIPTOR* GetMemDesc +( + OUT UINTN *pSize, + OUT UINTN *pItemSize, + OUT UINTN *pDescCount +) +{ + UINTN Size = 0; + UINTN MapKey = 0; + UINTN ItemSize = 0; + UINTN DescCount = 0; + UINT32 Version = 0; + EFI_STATUS Status = EFI_SUCCESS; + EFI_MEMORY_DESCRIPTOR *pDesc = NULL; + EFI_MEMORY_DESCRIPTOR *Curr = NULL; + + Status = gBS->GetMemoryMap(&Size, pDesc, &MapKey, &ItemSize, &Version); + if (EFI_BUFFER_TOO_SMALL != Status) + { + debug("GetMemoryMap: %r", Status); + return NULL; + } + + Size += SIZE_1KB; + pDesc = AllocatePool(Size); + if (!pDesc) + { + debug("AllocatePool: %lu failed", Size); + return NULL; + } + + ZeroMem(pDesc, Size); + + Status = gBS->GetMemoryMap(&Size, pDesc, &MapKey, &ItemSize, &Version); + if (EFI_ERROR(Status)) + { + debug("GetMemoryMap: %r", Status); + FreePool(pDesc); + return NULL; + } + + Curr = pDesc; + while (Curr && Curr < (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)pDesc + Size)) + { + DescCount++; + Curr = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Curr + ItemSize); + } + + *pSize = Size; + *pItemSize = ItemSize; + *pDescCount = DescCount; + + debug("GetMemoryMap: ItemSize:%lu Count:%lu", ItemSize, DescCount); + + return pDesc; +} + +EFI_STATUS FixWindowsMemhole(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine) +{ + UINTN Size = 0; + UINTN ItemSize = 0; + UINTN DescCount = 0; + UINTN TotalMem = 0; + EFI_STATUS Status = EFI_SUCCESS; + EFI_PHYSICAL_ADDRESS AllocAddr = 0; + EFI_MEMORY_DESCRIPTOR *pDescs = NULL; + EFI_MEMORY_DESCRIPTOR *Prev = NULL; + EFI_MEMORY_DESCRIPTOR *Next = NULL; + EFI_MEMORY_DESCRIPTOR *Curr = NULL; + + (VOID)ImageHandle; + (VOID)CmdLine; + + pDescs = GetMemDesc(&Size, &ItemSize, &DescCount); + if (!pDescs) + { + return EFI_NOT_FOUND; + } + + if (DescCount < 500) + { + FreePool(pDescs); + Printf("There is no need to fixup (%lu)\n", DescCount); + return EFI_SUCCESS; + } + + Curr = pDescs; + while ((UINT8 *)Curr < (UINT8 *)pDescs + Size) + { + Next = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Curr + ItemSize); + + if (IsMemContiguous(Prev, Curr, Next)) + { + AllocAddr = Curr->PhysicalStart; + Status = gBS->AllocatePages(AllocateAddress, EfiBootServicesData, Curr->NumberOfPages, &AllocAddr); + if (EFI_SUCCESS == Status) + { + TotalMem += MultU64x64(SIZE_4KB, Curr->NumberOfPages); + } + } + + Prev = Curr; + Curr = Next; + } + + Printf("Fixup Windows mmap issue OK (%lu)\n", TotalMem); + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.c new file mode 100644 index 00000000..9f4d7b3a --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.c @@ -0,0 +1,135 @@ +/****************************************************************************** + * VtoyUtil.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BOOLEAN gVtoyDebugPrint = FALSE; +STATIC CONST CHAR16 *gCurFeature= NULL; +STATIC CHAR16 *gCmdLine = NULL; +STATIC grub_env_printf_pf g_env_printf = NULL; + +STATIC VtoyUtilFeature gFeatureList[] = +{ + { L"fix_windows_mmap", FixWindowsMemhole }, +}; + +VOID EFIAPI VtoyUtilDebug(IN CONST CHAR8 *Format, ...) +{ + VA_LIST Marker; + CHAR8 Buffer[512]; + + VA_START (Marker, Format); + AsciiVSPrint(Buffer, sizeof(Buffer), Format, Marker); + VA_END (Marker); + + if (g_env_printf) + { + g_env_printf("%s", Buffer); + } +} + +STATIC EFI_STATUS ParseCmdline(IN EFI_HANDLE ImageHandle) +{ + CHAR16 *pPos = NULL; + CHAR16 *pCmdLine = NULL; + EFI_STATUS Status = EFI_SUCCESS; + ventoy_grub_param *pGrubParam = NULL; + EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL; + + Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo); + if (EFI_ERROR(Status)) + { + return Status; + } + + pCmdLine = (CHAR16 *)AllocatePool(pImageInfo->LoadOptionsSize + 4); + SetMem(pCmdLine, pImageInfo->LoadOptionsSize + 4, 0); + CopyMem(pCmdLine, pImageInfo->LoadOptions, pImageInfo->LoadOptionsSize); + + if (StrStr(pCmdLine, L"debug")) + { + gVtoyDebugPrint = TRUE; + } + + pPos = StrStr(pCmdLine, L"env_param="); + if (!pPos) + { + return EFI_INVALID_PARAMETER; + } + + pGrubParam = (ventoy_grub_param *)StrHexToUintn(pPos + StrLen(L"env_param=")); + g_env_printf = pGrubParam->grub_env_printf; + + pPos = StrStr(pCmdLine, L"feature="); + if (!pPos) + { + return EFI_INVALID_PARAMETER; + } + + gCurFeature = pPos + StrLen(L"feature="); + + gCmdLine = pCmdLine; + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI VtoyUtilEfiMain +( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + UINTN i; + UINTN Len; + + ParseCmdline(ImageHandle); + + for (i = 0; i < ARRAY_SIZE(gFeatureList); i++) + { + Len = StrLen(gFeatureList[i].Cmd); + if (StrnCmp(gFeatureList[i].Cmd, gCurFeature, Len) == 0) + { + debug("Find main proc <%s>", gFeatureList[i].Cmd); + gFeatureList[i].MainProc(ImageHandle, gCurFeature + Len); + break; + } + } + + FreePool(gCmdLine); + gCmdLine = NULL; + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.h b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.h new file mode 100644 index 00000000..9adf6c70 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.h @@ -0,0 +1,61 @@ +/****************************************************************************** + * VtoyUtil.h + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#ifndef __VTOYUTIL_H__ +#define __VTOYUTIL_H__ + +#pragma pack(1) + +typedef EFI_STATUS (*VTOY_UTIL_PROC_PF)(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine); +typedef const char * (*grub_env_get_pf)(const char *name); +typedef int (*grub_env_printf_pf)(const char *fmt, ...); + +typedef struct ventoy_grub_param_file_replace +{ + UINT32 magic; + char old_file_name[4][256]; + UINT32 old_file_cnt; + UINT32 new_file_virtual_id; +}ventoy_grub_param_file_replace; + +typedef struct ventoy_grub_param +{ + grub_env_get_pf grub_env_get; + ventoy_grub_param_file_replace file_replace; + grub_env_printf_pf grub_env_printf; +}ventoy_grub_param; +#pragma pack() + + +typedef struct VtoyUtilFeature +{ + CONST CHAR16 *Cmd; + VTOY_UTIL_PROC_PF MainProc; +}VtoyUtilFeature; + +extern BOOLEAN gVtoyDebugPrint; +VOID EFIAPI VtoyUtilDebug(IN CONST CHAR8 *Format, ...); +#define debug(expr, ...) if (gVtoyDebugPrint) VtoyUtilDebug("[VTOY] "expr"\n", ##__VA_ARGS__) +#define Printf VtoyUtilDebug + +EFI_STATUS FixWindowsMemhole(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine); + +#endif + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf new file mode 100644 index 00000000..9a4fbf27 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf @@ -0,0 +1,80 @@ +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = VtoyUtil + FILE_GUID = a43466a0-68c6-469d-ba4b-678bbe90bc47 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = VtoyUtilEfiMain + + +[Sources] + VtoyUtil.h + VtoyUtil.c + Memhole.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + UefiLib + DebugLib + +[Guids] + gShellVariableGuid + gEfiVirtualCdGuid + gEfiFileInfoGuid + +[Protocols] + gEfiLoadedImageProtocolGuid + gEfiBlockIoProtocolGuid + gEfiDevicePathProtocolGuid + gEfiSimpleFileSystemProtocolGuid + gEfiRamDiskProtocolGuid + gEfiAbsolutePointerProtocolGuid + gEfiAcpiTableProtocolGuid + gEfiBlockIo2ProtocolGuid + gEfiBusSpecificDriverOverrideProtocolGuid + gEfiComponentNameProtocolGuid + gEfiComponentName2ProtocolGuid + gEfiDriverBindingProtocolGuid + gEfiDiskIoProtocolGuid + gEfiDiskIo2ProtocolGuid + gEfiGraphicsOutputProtocolGuid + gEfiHiiConfigAccessProtocolGuid + gEfiHiiFontProtocolGuid + gEfiLoadFileProtocolGuid + gEfiLoadFile2ProtocolGuid + gEfiLoadedImageProtocolGuid + gEfiLoadedImageDevicePathProtocolGuid + gEfiPciIoProtocolGuid + gEfiSerialIoProtocolGuid + gEfiSimpleTextInProtocolGuid + gEfiSimpleTextInputExProtocolGuid + gEfiSimpleTextOutProtocolGuid + + + + + + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc index 2bdadd28..f47ea6fb 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc @@ -204,6 +204,7 @@ [Components] MdeModulePkg/Application/Ventoy/Ventoy.inf + MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf MdeModulePkg/Application/HelloWorld/HelloWorld.inf MdeModulePkg/Application/DumpDynPcd/DumpDynPcd.inf MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def index d0455f9f..e8d4a7f4 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def @@ -1578,10 +1578,12 @@ module = { name = ventoy; common = ventoy/ventoy.c; common = ventoy/ventoy_linux.c; + common = ventoy/ventoy_unix.c; common = ventoy/ventoy_windows.c; common = ventoy/ventoy_plugin.c; common = ventoy/ventoy_json.c; common = ventoy/lzx.c; + common = ventoy/xpress.c; common = ventoy/huffman.c; }; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/context.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/context.c index 87edd254..9ed3c8d2 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/context.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/context.c @@ -99,7 +99,7 @@ grub_env_new_context (int export_all) grub_err_t grub_env_context_open (void) { - return grub_env_new_context (1); + return grub_env_new_context (grub_env_get("ventoy_new_context") ? 0 : 1); } int grub_extractor_level = 0; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c index e1033d18..e5d8b88c 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c @@ -853,12 +853,16 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) } break; case GRUB_TERM_KEY_F6: - cmdstr = grub_env_get("VTOY_F6_CMD"); - if (cmdstr) - { - menu_fini (); - grub_script_execute_sourcecode(cmdstr); - goto refresh; + if (0 == g_ventoy_fn_mutex) { + cmdstr = grub_env_get("VTOY_F6_CMD"); + if (cmdstr) + { + menu_fini (); + g_ventoy_fn_mutex = 1; + grub_script_execute_sourcecode(cmdstr); + g_ventoy_fn_mutex = 0; + goto refresh; + } } break; case GRUB_TERM_KEY_F7: diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c index 32200f14..2995bd30 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c @@ -305,6 +305,18 @@ static grub_err_t ventoy_cmd_break(grub_extcmd_context_t ctxt, int argc, char ** VENTOY_CMD_RETURN(GRUB_ERR_NONE); } +static grub_err_t ventoy_cmd_strstr(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + return (grub_strstr(args[0], args[1])) ? 0 : 1; +} + static grub_err_t ventoy_cmd_incr(grub_extcmd_context_t ctxt, int argc, char **args) { long value_long = 0; @@ -891,8 +903,8 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho *((img_info **)(node->tail)) = img; g_ventoy_img_count++; - img->alias = ventoy_plugin_get_menu_alias(img->path); - img->class = ventoy_plugin_get_menu_class(img->name); + img->alias = ventoy_plugin_get_menu_alias(vtoy_alias_image_file, img->path); + img->class = ventoy_plugin_get_menu_class(vtoy_class_image_file, img->name); if (!img->class) { img->class = g_menu_class[type]; @@ -1029,7 +1041,9 @@ static img_iterator_node * ventoy_get_min_child(img_iterator_node *node) static int ventoy_dynamic_tree_menu(img_iterator_node *node) { int offset = 1; - img_info *img; + img_info *img = NULL; + const char *dir_class = NULL; + const char *dir_alias = NULL; img_iterator_node *child = NULL; if (node->isocnt == 0 || node->done == 1) @@ -1055,9 +1069,25 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node) else { node->dir[node->dirlen - 1] = 0; - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "submenu \"%-10s [%s]\" --class=\"vtoydir\" {\n", - "DIR", node->dir + offset); + dir_class = ventoy_plugin_get_menu_class(vtoy_class_directory, node->dir); + if (!dir_class) + { + dir_class = "vtoydir"; + } + + dir_alias = ventoy_plugin_get_menu_alias(vtoy_alias_directory, node->dir); + if (dir_alias) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"%-10s %s\" --class=\"%s\" {\n", + "DIR", dir_alias, dir_class); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"%-10s [%s]\" --class=\"%s\" {\n", + "DIR", node->dir + offset, dir_class); + } vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "menuentry \"%-10s [../]\" --class=\"vtoyret\" VTOY_RET {\n " @@ -1371,7 +1401,7 @@ static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int arg VENTOY_CMD_RETURN(GRUB_ERR_NONE); } -static int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid) +int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid) { grub_disk_t disk; char *device_name; @@ -1441,6 +1471,7 @@ grub_uint32_t ventoy_get_iso_boot_catlog(grub_file_t file) int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector) { int i; + int x86count = 0; grub_uint8_t buf[512]; grub_file_seek(file, sector * 2048); @@ -1452,6 +1483,11 @@ int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector) return 1; } + if (buf[0] == 0x01 && buf[1] == 0x00) + { + x86count++; + } + for (i = 64; i < (int)sizeof(buf); i += 32) { if ((buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0xEF) @@ -1459,6 +1495,12 @@ int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector) debug("%s efi eltorito offset %d 0x%02x\n", file->name, i, buf[i]); return 1; } + + if ((buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0x00 && x86count == 1) + { + debug("0x9100 assume %s efi eltorito offset %d 0x%02x\n", file->name, i, buf[i]); + return 1; + } } debug("%s does not contain efi eltorito\n", file->name); @@ -1662,7 +1704,7 @@ static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int ar (void)argc; (void)args; - debug("select auto installation %d\n", argc); + debug("select auto installation argc:%d\n", argc); if (argc < 1) { @@ -1672,7 +1714,14 @@ static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int ar node = ventoy_plugin_find_install_template(args[0]); if (!node) { - debug("Install template not found for %s\n", args[0]); + debug("Auto install template not found for %s\n", args[0]); + return 0; + } + + if (node->autosel >= 0 && node->autosel <= node->templatenum) + { + node->cursel = node->autosel - 1; + debug("Auto install template auto select %d\n", node->autosel); return 0; } @@ -1720,7 +1769,7 @@ static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int arg (void)argc; (void)args; - debug("select persistece %d\n", argc); + debug("select persistence argc:%d\n", argc); if (argc < 1) { @@ -1734,6 +1783,13 @@ static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int arg return 0; } + if (node->autosel >= 0 && node->autosel <= node->backendnum) + { + node->cursel = node->autosel - 1; + debug("Persistence image auto select %d\n", node->autosel); + return 0; + } + buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF); if (!buf) { @@ -1973,32 +2029,22 @@ static grub_err_t ventoy_cmd_dump_img_list(grub_extcmd_context_t ctxt, int argc, return 0; } -static grub_err_t ventoy_cmd_dump_auto_install(grub_extcmd_context_t ctxt, int argc, char **args) +static grub_err_t ventoy_cmd_dump_injection(grub_extcmd_context_t ctxt, int argc, char **args) { (void)ctxt; (void)argc; (void)args; -{ - grub_file_t file; - char *buf; - char name[128]; + ventoy_plugin_dump_injection(); - file = grub_file_open("(hd0,1)/ventoy/ventoy.disk.img.xz", GRUB_FILE_TYPE_NONE); - if (file) - { - grub_printf("Open File OK (size:%llu)\n", (ulonglong)file->size); - - buf = grub_malloc(file->size); - grub_file_read(file, buf, file->size); - - grub_file_close(file); - - grub_snprintf(name, sizeof(name), "mem:0x%llx:size:%llu", (ulonglong)(ulong)buf, (ulonglong)file->size); - grub_printf("<%s>\n", name); - } + return 0; } +static grub_err_t ventoy_cmd_dump_auto_install(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; ventoy_plugin_dump_auto_install(); @@ -2144,7 +2190,7 @@ static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int a return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s variable\n", cmd_raw_name); } - isopath = grub_env_get("iso_path"); + isopath = grub_env_get("vtoy_iso_part"); if (!isopath) { debug("isopath is null %p\n", isopath); @@ -2197,6 +2243,129 @@ static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int a return 0; } +static grub_err_t ventoy_cmd_read_1st_line(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len = 1024; + grub_file_t file; + char *buf = NULL; + + (void)ctxt; + (void)argc; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s file var \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 0; + } + + buf = grub_malloc(len); + if (!buf) + { + goto end; + } + + buf[len - 1] = 0; + grub_file_read(file, buf, len - 1); + + ventoy_get_line(buf); + ventoy_set_env(args[1], buf); + +end: + + grub_check_free(buf); + grub_file_close(file); + + return 0; +} + +static grub_err_t ventoy_cmd_parse_volume(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len; + grub_file_t file; + char buf[64]; + ventoy_iso9660_vd pvd; + + (void)ctxt; + (void)argc; + + if (argc != 3) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s sysid volid \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 0; + } + + grub_file_seek(file, 16 * 2048); + len = (int)grub_file_read(file, &pvd, sizeof(pvd)); + if (len != sizeof(pvd)) + { + debug("failed to read pvd %d\n", len); + goto end; + } + + grub_memset(buf, 0, sizeof(buf)); + grub_memcpy(buf, pvd.sys, sizeof(pvd.sys)); + ventoy_set_env(args[1], buf); + + grub_memset(buf, 0, sizeof(buf)); + grub_memcpy(buf, pvd.vol, sizeof(pvd.vol)); + ventoy_set_env(args[2], buf); + +end: + grub_file_close(file); + + return 0; +} + +static grub_err_t ventoy_cmd_parse_create_date(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len; + grub_file_t file; + char buf[64]; + + (void)ctxt; + (void)argc; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s var \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 0; + } + + grub_memset(buf, 0, sizeof(buf)); + grub_file_seek(file, 16 * 2048 + 813); + len = (int)grub_file_read(file, buf, 17); + if (len != 17) + { + debug("failed to read create date %d\n", len); + goto end; + } + + ventoy_set_env(args[1], buf); + +end: + grub_file_close(file); + + return 0; +} + grub_uint64_t ventoy_grub_get_file_size(const char *fmt, ...) { grub_uint64_t size = 0; @@ -2267,14 +2436,37 @@ int ventoy_is_file_exist(const char *fmt, ...) return 0; } +int ventoy_is_dir_exist(const char *fmt, ...) +{ + va_list ap; + int len; + char *pos = NULL; + char buf[256] = {0}; + + grub_snprintf(buf, sizeof(buf), "%s", "[ -d "); + pos = buf + 5; + + va_start (ap, fmt); + len = grub_vsnprintf(pos, 255, fmt, ap); + va_end (ap); + + grub_strncpy(pos + len, " ]", 2); + + debug("script exec %s\n", buf); + + if (0 == grub_script_execute_sourcecode(buf)) + { + return 1; + } + + return 0; +} + static int ventoy_env_init(void) { char buf[64]; grub_env_set("vtdebug_flag", ""); - grub_env_export("vtdebug_flag"); - - g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); @@ -2285,6 +2477,7 @@ static int ventoy_env_init(void) if (g_grub_param) { g_grub_param->grub_env_get = grub_env_get; + g_grub_param->grub_env_printf = (grub_env_printf_pf)grub_printf; grub_snprintf(buf, sizeof(buf), "%p", g_grub_param); grub_env_set("env_param", buf); } @@ -2295,6 +2488,7 @@ static int ventoy_env_init(void) static cmd_para ventoy_cmds[] = { { "vt_incr", ventoy_cmd_incr, 0, NULL, "{Var} {INT}", "Increase integer variable", NULL }, + { "vt_strstr", ventoy_cmd_strstr, 0, NULL, "", "", NULL }, { "vt_debug", ventoy_cmd_debug, 0, NULL, "{on|off}", "turn debug on/off", NULL }, { "vtdebug", ventoy_cmd_debug, 0, NULL, "{on|off}", "turn debug on/off", NULL }, { "vtbreak", ventoy_cmd_break, 0, NULL, "{level}", "set debug break", NULL }, @@ -2314,6 +2508,7 @@ static cmd_para ventoy_cmds[] = { "vt_dynamic_menu", ventoy_cmd_dynamic_menu, 0, NULL, "", "", NULL }, { "vt_check_mode", ventoy_cmd_check_mode, 0, NULL, "", "", NULL }, { "vt_dump_img_list", ventoy_cmd_dump_img_list, 0, NULL, "", "", NULL }, + { "vt_dump_injection", ventoy_cmd_dump_injection, 0, NULL, "", "", NULL }, { "vt_dump_auto_install", ventoy_cmd_dump_auto_install, 0, NULL, "", "", NULL }, { "vt_dump_persistence", ventoy_cmd_dump_persistence, 0, NULL, "", "", NULL }, { "vt_select_auto_install", ventoy_cmd_sel_auto_install, 0, NULL, "", "", NULL }, @@ -2351,6 +2546,16 @@ static cmd_para ventoy_cmds[] = { "vt_load_plugin", ventoy_cmd_load_plugin, 0, NULL, "", "", NULL }, { "vt_check_plugin_json", ventoy_cmd_plugin_check_json, 0, NULL, "", "", NULL }, + + { "vt_1st_line", ventoy_cmd_read_1st_line, 0, NULL, "", "", NULL }, + { "vt_parse_iso_volume", ventoy_cmd_parse_volume, 0, NULL, "", "", NULL }, + { "vt_parse_iso_create_date", ventoy_cmd_parse_create_date, 0, NULL, "", "", NULL }, + { "vt_parse_freenas_ver", ventoy_cmd_parse_freenas_ver, 0, NULL, "", "", NULL }, + { "vt_unix_parse_freebsd_ver", ventoy_cmd_unix_freebsd_ver, 0, NULL, "", "", NULL }, + { "vt_unix_reset", ventoy_cmd_unix_reset, 0, NULL, "", "", NULL }, + { "vt_unix_replace_conf", ventoy_cmd_unix_replace_conf, 0, NULL, "", "", NULL }, + { "vt_unix_replace_ko", ventoy_cmd_unix_replace_ko, 0, NULL, "", "", NULL }, + { "vt_unix_chain_data", ventoy_cmd_unix_chain_data, 0, NULL, "", "", NULL }, }; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h index 4717f094..75c22215 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h @@ -123,6 +123,16 @@ typedef struct ventoy_udf_override grub_uint32_t position; }ventoy_udf_override; +typedef struct ventoy_iso9660_vd +{ + grub_uint8_t type; + grub_uint8_t id[5]; + grub_uint8_t ver; + grub_uint8_t res; + char sys[32]; + char vol[32]; +}ventoy_iso9660_vd; + #pragma pack() #define img_type_iso 0 @@ -225,6 +235,7 @@ void ventoy_debug(const char *fmt, ...); #define FLAG_HEADER_COMPRESS_RESERVED 0x00010000 #define FLAG_HEADER_COMPRESS_XPRESS 0x00020000 #define FLAG_HEADER_COMPRESS_LZX 0x00040000 +#define FLAG_HEADER_COMPRESS_LZMS 0x00080000 #define RESHDR_FLAG_FREE 0x01 #define RESHDR_FLAG_METADATA 0x02 @@ -460,6 +471,7 @@ int ventoy_cpio_newc_fill_head(void *buf, int filesize, const void *filedata, co grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...); grub_uint64_t ventoy_grub_get_file_size(const char *fmt, ...); int ventoy_is_file_exist(const char *fmt, ...); +int ventoy_is_dir_exist(const char *fmt, ...); int ventoy_fill_data(grub_uint32_t buflen, char *buffer); grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args); @@ -600,6 +612,7 @@ typedef struct install_template int pathlen; char isopath[256]; + int autosel; int cursel; int templatenum; file_fullpath *templatepath; @@ -612,6 +625,7 @@ typedef struct persistence_config int pathlen; char isopath[256]; + int autosel; int cursel; int backendnum; file_fullpath *backendpath; @@ -619,8 +633,12 @@ typedef struct persistence_config struct persistence_config *next; }persistence_config; +#define vtoy_alias_image_file 0 +#define vtoy_alias_directory 1 + typedef struct menu_alias { + int type; int pathlen; char isopath[256]; char alias[256]; @@ -628,8 +646,12 @@ typedef struct menu_alias struct menu_alias *next; }menu_alias; +#define vtoy_class_image_file 0 +#define vtoy_class_directory 1 + typedef struct menu_class { + int type; int patlen; char pattern[256]; char class[64]; @@ -637,6 +659,15 @@ typedef struct menu_class struct menu_class *next; }menu_class; +typedef struct injection_config +{ + int pathlen; + char isopath[256]; + char archive[256]; + + struct injection_config *next; +}injection_config; + extern int g_ventoy_menu_esc; extern int g_ventoy_suppress_esc; extern int g_ventoy_last_entry; @@ -646,16 +677,36 @@ extern int g_ventoy_iso_uefi_drv; extern int g_ventoy_case_insensitive; extern grub_uint8_t g_ventoy_chain_type; + +#define ventoy_unix_fill_virt(new_data, new_len) \ +{ \ + data_secs = (new_len + 2047) / 2048; \ + cur->mem_sector_start = sector; \ + cur->mem_sector_end = cur->mem_sector_start + data_secs; \ + cur->mem_sector_offset = offset; \ + cur->remap_sector_start = 0; \ + cur->remap_sector_end = 0; \ + cur->org_sector_start = 0; \ + grub_memcpy(override + offset, new_data, new_len); \ + cur++; \ + sector += data_secs; \ + offset += new_len; \ + chain->virt_img_size_in_bytes += data_secs * 2048; \ +} + +char * ventoy_get_line(char *start); int ventoy_cmp_img(img_info *img1, img_info *img2); void ventoy_swap_img(img_info *img1, img_info *img2); char * ventoy_plugin_get_cur_install_template(const char *isopath); install_template * ventoy_plugin_find_install_template(const char *isopath); persistence_config * ventoy_plugin_find_persistent(const char *isopath); +void ventoy_plugin_dump_injection(void); void ventoy_plugin_dump_auto_install(void); int ventoy_fill_windows_rtdata(void *buf, char *isopath); int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list); -const char * ventoy_plugin_get_menu_alias(const char *isopath); -const char * ventoy_plugin_get_menu_class(const char *isoname); +const char * ventoy_plugin_get_injection(const char *isopath); +const char * ventoy_plugin_get_menu_alias(int type, const char *isopath); +const char * ventoy_plugin_get_menu_class(int type, const char *name); int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start); int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start); void ventoy_plugin_dump_persistence(void); @@ -664,6 +715,13 @@ grub_err_t ventoy_cmd_linux_get_main_initrd_index(grub_extcmd_context_t ctxt, in grub_err_t ventoy_cmd_collect_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_wim_patch_count(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_locate_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); +int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid); +grub_err_t ventoy_cmd_unix_reset(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_replace_ko(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_freebsd_ver(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_parse_freenas_ver(grub_extcmd_context_t ctxt, int argc, char **args); #endif /* __VENTOY_DEF_H__ */ diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c index ddd7499a..ad871a10 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c @@ -38,8 +38,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); - -static char * ventoy_get_line(char *start) +char * ventoy_get_line(char *start) { if (start == NULL) { @@ -909,6 +908,8 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg char *template_file = NULL; char *template_buf = NULL; char *persistent_buf = NULL; + char *injection_buf = NULL; + const char *injection_file = NULL; grub_uint8_t *buf = NULL; grub_uint32_t mod; grub_uint32_t headlen; @@ -917,8 +918,9 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg grub_uint32_t img_chunk_size; grub_uint32_t template_size = 0; grub_uint32_t persistent_size = 0; + grub_uint32_t injection_size = 0; grub_file_t file; - grub_file_t scriptfile; + grub_file_t tmpfile; ventoy_img_chunk_list chunk_list; (void)ctxt; @@ -960,18 +962,18 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg if (template_file) { debug("auto install template: <%s>\n", template_file); - scriptfile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[2], template_file); - if (scriptfile) + tmpfile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[2], template_file); + if (tmpfile) { - debug("auto install script size %d\n", (int)scriptfile->size); - template_size = scriptfile->size; + debug("auto install script size %d\n", (int)tmpfile->size); + template_size = tmpfile->size; template_buf = grub_malloc(template_size); if (template_buf) { - grub_file_read(scriptfile, template_buf, template_size); + grub_file_read(tmpfile, template_buf, template_size); } - grub_file_close(scriptfile); + grub_file_close(tmpfile); } else { @@ -983,7 +985,34 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg debug("auto install script skipped or not configed %s\n", args[1]); } - g_ventoy_cpio_buf = grub_malloc(file->size + 4096 + template_size + persistent_size + img_chunk_size); + injection_file = ventoy_plugin_get_injection(args[1]); + if (injection_file) + { + debug("injection archive: <%s>\n", injection_file); + tmpfile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[2], injection_file); + if (tmpfile) + { + debug("injection archive size:%d\n", (int)tmpfile->size); + injection_size = tmpfile->size; + injection_buf = grub_malloc(injection_size); + if (injection_buf) + { + grub_file_read(tmpfile, injection_buf, injection_size); + } + + grub_file_close(tmpfile); + } + else + { + debug("Failed to open injection archive %s%s\n", args[2], injection_file); + } + } + else + { + debug("injection not configed %s\n", args[1]); + } + + g_ventoy_cpio_buf = grub_malloc(file->size + 4096 + template_size + persistent_size + injection_size + img_chunk_size); if (NULL == g_ventoy_cpio_buf) { grub_file_close(file); @@ -1020,6 +1049,15 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg persistent_buf = NULL; } + if (injection_size > 0 && injection_buf) + { + headlen = ventoy_cpio_newc_fill_head(buf, injection_size, injection_buf, "ventoy/ventoy_injection"); + buf += headlen + ventoy_align(injection_size, 4); + + grub_free(injection_buf); + injection_buf = NULL; + } + /* step2: insert os param to cpio */ headlen = ventoy_cpio_newc_fill_head(buf, 0, NULL, "ventoy/ventoy_os_param"); padlen = sizeof(ventoy_os_param); @@ -1144,7 +1182,7 @@ grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, cha grub_memset(chain, 0, sizeof(ventoy_chain_head)); /* part 1: os parameter */ - g_ventoy_chain_type = 0; + g_ventoy_chain_type = ventoy_chain_linux; ventoy_fill_os_param(file, &(chain->os_param)); /* part 2: chain head */ diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c index 6bb4e9c0..7fbe9db7 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c @@ -44,6 +44,7 @@ static install_template *g_install_template_head = NULL; static persistence_config *g_persistence_head = NULL; static menu_alias *g_menu_alias_head = NULL; static menu_class *g_menu_class_head = NULL; +static injection_config *g_injection_head = NULL; static int ventoy_plugin_control_check(VTOY_JSON *json, const char *isodisk) { @@ -310,11 +311,13 @@ static int ventoy_plugin_check_fullpath ( VTOY_JSON *json, const char *isodisk, - const char *key + const char *key, + int *pathnum ) { int rc = 0; int ret = 0; + int cnt = 0; VTOY_JSON *node = json; VTOY_JSON *child = NULL; @@ -334,6 +337,7 @@ static int ventoy_plugin_check_fullpath if (JSON_TYPE_STRING == node->enDataType) { + cnt = 1; ret = ventoy_plugin_check_path(isodisk, node->unData.pcStrVal); grub_printf("%s: %s [%s]\n", key, node->unData.pcStrVal, ret ? "FAIL" : "OK"); } @@ -350,10 +354,12 @@ static int ventoy_plugin_check_fullpath rc = ventoy_plugin_check_path(isodisk, child->unData.pcStrVal); grub_printf("%s: %s [%s]\n", key, child->unData.pcStrVal, rc ? "FAIL" : "OK"); ret += rc; + cnt++; } } } + *pathnum = cnt; return ret; } @@ -443,6 +449,8 @@ static int ventoy_plugin_parse_fullpath static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk) { + int pathnum = 0; + int autosel = 0; const char *iso = NULL; VTOY_JSON *pNode = NULL; @@ -465,7 +473,19 @@ static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk if (0 == ventoy_plugin_check_path(isodisk, iso)) { grub_printf("image: %s [OK]\n", iso); - ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "template"); + ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "template", &pathnum); + + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel)) + { + if (autosel >= 0 && autosel <= pathnum) + { + grub_printf("autosel: %d [OK]\n", autosel); + } + else + { + grub_printf("autosel: %d [FAIL]\n", autosel); + } + } } else { @@ -484,6 +504,7 @@ static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk) { int pathnum = 0; + int autosel = 0; const char *iso = NULL; VTOY_JSON *pNode = NULL; install_template *node = NULL; @@ -522,6 +543,15 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk node->templatepath = templatepath; node->templatenum = pathnum; + node->autosel = -1; + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel)) + { + if (autosel >= 0 && autosel <= pathnum) + { + node->autosel = autosel; + } + } + if (g_install_template_head) { node->next = g_install_template_head; @@ -538,6 +568,8 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk) { + int autosel = 0; + int pathnum = 0; const char *iso = NULL; VTOY_JSON *pNode = NULL; @@ -560,7 +592,19 @@ static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk) if (0 == ventoy_plugin_check_path(isodisk, iso)) { grub_printf("image: %s [OK]\n", iso); - ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "backend"); + ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "backend", &pathnum); + + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel)) + { + if (autosel >= 0 && autosel <= pathnum) + { + grub_printf("autosel: %d [OK]\n", autosel); + } + else + { + grub_printf("autosel: %d [FAIL]\n", autosel); + } + } } else { @@ -578,6 +622,7 @@ static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk) static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk) { + int autosel = 0; int pathnum = 0; const char *iso = NULL; VTOY_JSON *pNode = NULL; @@ -619,6 +664,15 @@ static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk) node->backendpath = backendpath; node->backendnum = pathnum; + node->autosel = -1; + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel)) + { + if (autosel >= 0 && autosel <= pathnum) + { + node->autosel = autosel; + } + } + if (g_persistence_head) { node->next = g_persistence_head; @@ -635,7 +689,8 @@ static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk) static int ventoy_plugin_menualias_check(VTOY_JSON *json, const char *isodisk) { - const char *iso = NULL; + int type; + const char *path = NULL; const char *alias = NULL; VTOY_JSON *pNode = NULL; @@ -649,17 +704,38 @@ static int ventoy_plugin_menualias_check(VTOY_JSON *json, const char *isodisk) for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) { - iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); - alias = vtoy_json_get_string_ex(pNode->pstChild, "alias"); - if (iso && iso[0] == '/' && alias) + type = vtoy_alias_image_file; + path = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!path) { - if (ventoy_is_file_exist("%s%s", isodisk, iso)) - { - grub_printf("image: <%s> [ OK ]\n", iso); + path = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_alias_directory; + } + + alias = vtoy_json_get_string_ex(pNode->pstChild, "alias"); + if (path && path[0] == '/' && alias) + { + if (vtoy_alias_image_file == type) + { + if (ventoy_is_file_exist("%s%s", isodisk, path)) + { + grub_printf("image: <%s> [ OK ]\n", path); + } + else + { + grub_printf("image: <%s> [ NOT EXIST ]\n", path); + } } else { - grub_printf("image: <%s> [ NOT EXIST ]\n", iso); + if (ventoy_is_dir_exist("%s%s", isodisk, path)) + { + grub_printf("dir: <%s> [ OK ]\n", path); + } + else + { + grub_printf("dir: <%s> [ NOT EXIST ]\n", path); + } } grub_printf("alias: <%s>\n\n", alias); @@ -671,7 +747,8 @@ static int ventoy_plugin_menualias_check(VTOY_JSON *json, const char *isodisk) static int ventoy_plugin_menualias_entry(VTOY_JSON *json, const char *isodisk) { - const char *iso = NULL; + int type; + const char *path = NULL; const char *alias = NULL; VTOY_JSON *pNode = NULL; menu_alias *node = NULL; @@ -698,14 +775,22 @@ static int ventoy_plugin_menualias_entry(VTOY_JSON *json, const char *isodisk) for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) { - iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); + type = vtoy_alias_image_file; + path = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!path) + { + path = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_alias_directory; + } + alias = vtoy_json_get_string_ex(pNode->pstChild, "alias"); - if (iso && iso[0] == '/' && alias) + if (path && path[0] == '/' && alias) { node = grub_zalloc(sizeof(menu_alias)); if (node) { - node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); + node->type = type; + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", path); grub_snprintf(node->alias, sizeof(node->alias), "%s", alias); if (g_menu_alias_head) @@ -721,8 +806,99 @@ static int ventoy_plugin_menualias_entry(VTOY_JSON *json, const char *isodisk) return 0; } + +static int ventoy_plugin_injection_check(VTOY_JSON *json, const char *isodisk) +{ + const char *path = NULL; + const char *archive = NULL; + VTOY_JSON *pNode = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array %d\n", json->enDataType); + return 0; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + path = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!path) + { + grub_printf("image not found\n"); + continue; + } + + archive = vtoy_json_get_string_ex(pNode->pstChild, "archive"); + if (!archive) + { + grub_printf("archive not found\n"); + continue; + } + + grub_printf("image: <%s> [%s]\n", path, ventoy_check_file_exist("%s%s", isodisk, path) ? "OK" : "NOT EXIST"); + grub_printf("archive: <%s> [%s]\n\n", archive, ventoy_check_file_exist("%s%s", isodisk, archive) ? "OK" : "NOT EXIST"); + } + + return 0; +} + +static int ventoy_plugin_injection_entry(VTOY_JSON *json, const char *isodisk) +{ + const char *path = NULL; + const char *archive = NULL; + VTOY_JSON *pNode = NULL; + injection_config *node = NULL; + injection_config *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_injection_head) + { + for (node = g_injection_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_injection_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + path = vtoy_json_get_string_ex(pNode->pstChild, "image"); + archive = vtoy_json_get_string_ex(pNode->pstChild, "archive"); + if (path && path[0] == '/' && archive && archive[0] == '/') + { + node = grub_zalloc(sizeof(injection_config)); + if (node) + { + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", path); + grub_snprintf(node->archive, sizeof(node->archive), "%s", archive); + + if (g_injection_head) + { + node->next = g_injection_head; + } + + g_injection_head = node; + } + } + } + + return 0; +} + static int ventoy_plugin_menuclass_entry(VTOY_JSON *json, const char *isodisk) { + int type; const char *key = NULL; const char *class = NULL; VTOY_JSON *pNode = NULL; @@ -751,13 +927,21 @@ static int ventoy_plugin_menuclass_entry(VTOY_JSON *json, const char *isodisk) for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) { + type = vtoy_class_image_file; key = vtoy_json_get_string_ex(pNode->pstChild, "key"); + if (!key) + { + key = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_class_directory; + } + class = vtoy_json_get_string_ex(pNode->pstChild, "class"); if (key && class) { node = grub_zalloc(sizeof(menu_class)); if (node) { + node->type = type; node->patlen = grub_snprintf(node->pattern, sizeof(node->pattern), "%s", key); grub_snprintf(node->class, sizeof(node->class), "%s", class); @@ -779,6 +963,7 @@ static int ventoy_plugin_menuclass_entry(VTOY_JSON *json, const char *isodisk) static int ventoy_plugin_menuclass_check(VTOY_JSON *json, const char *isodisk) { + int type; const char *key = NULL; const char *class = NULL; VTOY_JSON *pNode = NULL; @@ -793,11 +978,18 @@ static int ventoy_plugin_menuclass_check(VTOY_JSON *json, const char *isodisk) for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) { + type = vtoy_class_image_file; key = vtoy_json_get_string_ex(pNode->pstChild, "key"); + if (!key) + { + key = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_class_directory; + } + class = vtoy_json_get_string_ex(pNode->pstChild, "class"); if (key && class) { - grub_printf("key: <%s>\n", key); + grub_printf("%s: <%s>\n", (type == vtoy_class_directory) ? "dir" : "key", key); grub_printf("class: <%s>\n\n", class); } } @@ -813,6 +1005,7 @@ static plugin_entry g_plugin_entries[] = { "persistence", ventoy_plugin_persistence_entry, ventoy_plugin_persistence_check }, { "menu_alias", ventoy_plugin_menualias_entry, ventoy_plugin_menualias_check }, { "menu_class", ventoy_plugin_menuclass_entry, ventoy_plugin_menuclass_check }, + { "injection", ventoy_plugin_injection_entry, ventoy_plugin_injection_check }, }; static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk) @@ -894,6 +1087,20 @@ grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **a VENTOY_CMD_RETURN(GRUB_ERR_NONE); } +void ventoy_plugin_dump_injection(void) +{ + injection_config *node = NULL; + + for (node = g_injection_head; node; node = node->next) + { + grub_printf("\nIMAGE:<%s>\n", node->isopath); + grub_printf("ARCHIVE:<%s>\n", node->archive); + } + + return; +} + + void ventoy_plugin_dump_auto_install(void) { int i; @@ -901,7 +1108,7 @@ void ventoy_plugin_dump_auto_install(void) for (node = g_install_template_head; node; node = node->next) { - grub_printf("\nIMAGE:<%s>\n", node->isopath); + grub_printf("\nIMAGE:<%s> <%d>\n", node->isopath, node->templatenum); for (i = 0; i < node->templatenum; i++) { grub_printf("SCRIPT %d:<%s>\n", i, node->templatepath[i].path); @@ -920,7 +1127,7 @@ void ventoy_plugin_dump_persistence(void) for (node = g_persistence_head; node; node = node->next) { - grub_printf("\nIMAGE:<%s>\n", node->isopath); + grub_printf("\nIMAGE:<%s> <%d>\n", node->isopath, node->backendnum); for (i = 0; i < node->backendnum; i++) { @@ -1050,14 +1257,31 @@ end: return rc; } -const char * ventoy_plugin_get_menu_alias(const char *isopath) +const char * ventoy_plugin_get_injection(const char *isopath) +{ + injection_config *node = NULL; + int len = (int)grub_strlen(isopath); + + for (node = g_injection_head; node; node = node->next) + { + if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0) + { + return node->archive; + } + } + + return NULL; +} + +const char * ventoy_plugin_get_menu_alias(int type, const char *isopath) { menu_alias *node = NULL; int len = (int)grub_strlen(isopath); - + for (node = g_menu_alias_head; node; node = node->next) { - if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0) + if (node->type == type && node->pathlen && + node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0) { return node->alias; } @@ -1066,23 +1290,35 @@ const char * ventoy_plugin_get_menu_alias(const char *isopath) return NULL; } -const char * ventoy_plugin_get_menu_class(const char *isoname) +const char * ventoy_plugin_get_menu_class(int type, const char *name) { menu_class *node = NULL; - int len = (int)grub_strlen(isoname); - - for (node = g_menu_class_head; node; node = node->next) + int len = (int)grub_strlen(name); + + if (vtoy_class_image_file == type) { - if (node->patlen <= len && grub_strstr(isoname, node->pattern)) + for (node = g_menu_class_head; node; node = node->next) { - return node->class; + if (node->type == type && node->patlen <= len && grub_strstr(name, node->pattern)) + { + return node->class; + } + } + } + else + { + for (node = g_menu_class_head; node; node = node->next) + { + if (node->type == type && node->patlen == len && grub_strncmp(name, node->pattern, len) == 0) + { + return node->class; + } } } return NULL; } - grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args) { int i = 0; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c index 76975dbf..a9d3c81f 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c @@ -51,6 +51,7 @@ static grub_uint32_t g_suppress_wincd_override_data = 0; grub_uint8_t g_temp_buf[512]; grub_ssize_t lzx_decompress ( const void *data, grub_size_t len, void *buf ); +grub_ssize_t xca_decompress ( const void *data, grub_size_t len, void *buf ); static wim_patch *ventoy_find_wim_patch(const char *path) { @@ -332,7 +333,7 @@ grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char * g_wim_patch_head = NULL; g_wim_total_patch_count = 0; g_wim_valid_patch_count = 0; - + return 0; } @@ -427,7 +428,7 @@ static int ventoy_get_override_info(grub_file_t file, wim_tail *wim_data) return 0; } -static int ventoy_read_resource(grub_file_t fp, wim_resource_header *head, void **buffer) +static int ventoy_read_resource(grub_file_t fp, wim_header *wimhdr, wim_resource_header *head, void **buffer) { int decompress_len = 0; int total_decompress = 0; @@ -477,7 +478,14 @@ static int ventoy_read_resource(grub_file_t fp, wim_resource_header *head, void } else { - decompress_len = (int)lzx_decompress(buffer_compress + cur_offset, chunk_size, cur_dst); + if (wimhdr->flags & FLAG_HEADER_COMPRESS_XPRESS) + { + decompress_len = (int)xca_decompress(buffer_compress + cur_offset, chunk_size, cur_dst); + } + else + { + decompress_len = (int)lzx_decompress(buffer_compress + cur_offset, chunk_size, cur_dst); + } } //debug("chunk_size:%u decompresslen:%d\n", chunk_size, decompress_len); @@ -499,7 +507,14 @@ static int ventoy_read_resource(grub_file_t fp, wim_resource_header *head, void } else { - decompress_len = (int)lzx_decompress(buffer_compress + cur_offset, head->size_in_wim - cur_offset, cur_dst); + if (wimhdr->flags & FLAG_HEADER_COMPRESS_XPRESS) + { + decompress_len = (int)xca_decompress(buffer_compress + cur_offset, head->size_in_wim - cur_offset, cur_dst); + } + else + { + decompress_len = (int)lzx_decompress(buffer_compress + cur_offset, head->size_in_wim - cur_offset, cur_dst); + } } cur_dst += decompress_len; @@ -549,13 +564,9 @@ static wim_directory_entry * search_full_wim_dirent { subdir = (wim_directory_entry *)((char *)meta_data + search->subdir); search = search_wim_dirent(subdir, *path); - if (!search) - { - debug("%s search failed\n", *path); - } - path++; } + return search; } @@ -563,16 +574,18 @@ static wim_directory_entry * search_replace_wim_dirent(void *meta_data, wim_dire { wim_directory_entry *wim_dirent = NULL; const char *winpeshl_path[] = { "Windows", "System32", "winpeshl.exe", NULL }; - //const char *pecmd_path[] = { "Windows", "System32", "PECMD.exe", NULL }; + //const char *native_path[] = { "Windows", "System32", "native.exe", NULL }; wim_dirent = search_full_wim_dirent(meta_data, dir, winpeshl_path); + debug("search winpeshl.exe %p\n", wim_dirent); if (wim_dirent) { return wim_dirent; } - + #if 0 - wim_dirent = search_full_wim_dirent(meta_data, dir, pecmd_path); + wim_dirent = search_full_wim_dirent(meta_data, dir, native_path); + debug("search native.exe %p\n", wim_dirent); if (wim_dirent) { return wim_dirent; @@ -709,6 +722,24 @@ int ventoy_fill_windows_rtdata(void *buf, char *isopath) { debug("auto install script skipped or not configed %s\n", pos); } + + script = (char *)ventoy_plugin_get_injection(pos); + if (script) + { + if (ventoy_check_file_exist("%s%s", ventoy_get_env("vtoy_iso_part"), script)) + { + debug("injection archive <%s> OK\n", script); + grub_snprintf(data->injection_archive, sizeof(data->injection_archive) - 1, "%s", script); + } + else + { + debug("injection archive <%s> NOT exist\n", script); + } + } + else + { + debug("injection archive not configed %s\n", pos); + } return 0; } @@ -813,14 +844,14 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch) return 1; } - if (head->flags & FLAG_HEADER_COMPRESS_XPRESS) + if (head->flags & FLAG_HEADER_COMPRESS_LZMS) { - debug("Xpress compress is not supported 0x%x\n", head->flags); + debug("LZMS compress is not supported 0x%x\n", head->flags); grub_file_close(file); return 1; } - rc = ventoy_read_resource(file, &head->metadata, (void **)&decompress_data); + rc = ventoy_read_resource(file, head, &head->metadata, (void **)&decompress_data); if (rc) { grub_printf("failed to read meta data %d\n", rc); @@ -857,7 +888,7 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch) debug("find replace lookup entry_id:%ld raw_size:%u\n", ((long)patch->replace_look - (long)lookup) / sizeof(wim_lookup_entry), exe_len); - if (0 == ventoy_read_resource(file, &(patch->replace_look->resource), (void **)&(exe_data))) + if (0 == ventoy_read_resource(file, head, &(patch->replace_look->resource), (void **)&(exe_data))) { ventoy_cat_exe_file_data(wim_data, exe_len, exe_data); grub_free(exe_data); @@ -1385,7 +1416,7 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c grub_memset(chain, 0, sizeof(ventoy_chain_head)); /* part 1: os parameter */ - g_ventoy_chain_type = 1; + g_ventoy_chain_type = ventoy_chain_windows; ventoy_fill_os_param(file, &(chain->os_param)); if (0 == unknown_image) @@ -1597,7 +1628,7 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char grub_memset(chain, 0, sizeof(ventoy_chain_head)); /* part 1: os parameter */ - g_ventoy_chain_type = 0; + g_ventoy_chain_type = ventoy_chain_wim; ventoy_fill_os_param(file, &(chain->os_param)); /* part 2: chain head */ diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.c new file mode 100644 index 00000000..bfb3125e --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2012 Michael Brown . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * @file + * + * Xpress Compression Algorithm (MS-XCA) decompression + * + */ + +#include "wimboot.h" +#include "huffman.h" +#include "xpress.h" + +#pragma GCC diagnostic ignored "-Wcast-align" + +/** + * Decompress XCA-compressed data + * + * @v data Compressed data + * @v len Length of compressed data + * @v buf Decompression buffer, or NULL + * @ret out_len Length of decompressed data, or negative error + */ +ssize_t xca_decompress ( const void *data, size_t len, void *buf ) { + const void *src = data; + const void *end = ( uint8_t * ) src + len; + uint8_t *out = buf; + size_t out_len = 0; + size_t out_len_threshold = 0; + const struct xca_huf_len *lengths; + struct xca xca; + uint32_t accum = 0; + int extra_bits = 0; + unsigned int huf; + struct huffman_symbols *sym; + unsigned int raw; + unsigned int match_len; + unsigned int match_offset_bits; + unsigned int match_offset; + const uint8_t *copy; + int rc; + + /* Process data stream */ + while ( src < end ) { + + /* (Re)initialise decompressor if applicable */ + if ( out_len >= out_len_threshold ) { + + /* Construct symbol lengths */ + lengths = src; + src = ( uint8_t * ) src + sizeof ( *lengths ); + if ( src > end ) { + DBG ( "XCA too short to hold Huffman lengths table.\n"); + return -1; + } + for ( raw = 0 ; raw < XCA_CODES ; raw++ ) + xca.lengths[raw] = xca_huf_len ( lengths, raw ); + + /* Construct Huffman alphabet */ + if ( ( rc = huffman_alphabet ( &xca.alphabet, + xca.lengths, + XCA_CODES ) ) != 0 ) + return rc; + + /* Initialise state */ + accum = XCA_GET16 ( src ); + accum <<= 16; + accum |= XCA_GET16 ( src ); + extra_bits = 16; + + /* Determine next threshold */ + out_len_threshold = ( out_len + XCA_BLOCK_SIZE ); + } + + /* Determine symbol */ + huf = ( accum >> ( 32 - HUFFMAN_BITS ) ); + sym = huffman_sym ( &xca.alphabet, huf ); + raw = huffman_raw ( sym, huf ); + accum <<= huffman_len ( sym ); + extra_bits -= huffman_len ( sym ); + if ( extra_bits < 0 ) { + accum |= ( XCA_GET16 ( src ) << ( -extra_bits ) ); + extra_bits += 16; + } + + /* Process symbol */ + if ( raw < XCA_END_MARKER ) { + + /* Literal symbol - add to output stream */ + if ( buf ) + *(out++) = raw; + out_len++; + + } else if ( ( raw == XCA_END_MARKER ) && + ( (uint8_t *) src >= ( ( uint8_t * ) end - 1 ) ) ) { + + /* End marker symbol */ + return out_len; + + } else { + + /* LZ77 match symbol */ + raw -= XCA_END_MARKER; + match_offset_bits = ( raw >> 4 ); + match_len = ( raw & 0x0f ); + if ( match_len == 0x0f ) { + match_len = XCA_GET8 ( src ); + if ( match_len == 0xff ) { + match_len = XCA_GET16 ( src ); + } else { + match_len += 0x0f; + } + } + match_len += 3; + if ( match_offset_bits ) { + match_offset = + ( ( accum >> ( 32 - match_offset_bits )) + + ( 1 << match_offset_bits ) ); + } else { + match_offset = 1; + } + accum <<= match_offset_bits; + extra_bits -= match_offset_bits; + if ( extra_bits < 0 ) { + accum |= ( XCA_GET16 ( src ) << (-extra_bits) ); + extra_bits += 16; + } + + /* Copy data */ + out_len += match_len; + if ( buf ) { + copy = ( out - match_offset ); + while ( match_len-- ) + *(out++) = *(copy++); + } + } + } + + return out_len; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.h new file mode 100644 index 00000000..6a430f7f --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.h @@ -0,0 +1,87 @@ +#ifndef _XCA_H +#define _XCA_H + +/* + * Copyright (C) 2012 Michael Brown . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * @file + * + * Xpress Compression Algorithm (MS-XCA) decompression + * + */ + +#include "huffman.h" + +/** Number of XCA codes */ +#define XCA_CODES 512 + +/** XCA decompressor */ +struct xca { + /** Huffman alphabet */ + struct huffman_alphabet alphabet; + /** Raw symbols + * + * Must immediately follow the Huffman alphabet. + */ + huffman_raw_symbol_t raw[XCA_CODES]; + /** Code lengths */ + uint8_t lengths[XCA_CODES]; +}; + +/** XCA symbol Huffman lengths table */ +struct xca_huf_len { + /** Lengths of each symbol */ + uint8_t nibbles[ XCA_CODES / 2 ]; +} __attribute__ (( packed )); + +/** + * Extract Huffman-coded length of a raw symbol + * + * @v lengths Huffman lengths table + * @v symbol Raw symbol + * @ret len Huffman-coded length + */ +static inline unsigned int xca_huf_len ( const struct xca_huf_len *lengths, + unsigned int symbol ) { + return ( ( ( lengths->nibbles[ symbol / 2 ] ) >> + ( 4 * ( symbol % 2 ) ) ) & 0x0f ); +} + +/** Get word from source data stream */ +#define XCA_GET16( src ) ( { \ + const uint16_t *src16 = src; \ + src = ( uint8_t * ) src + sizeof ( *src16 ); \ + *src16; } ) + +/** Get byte from source data stream */ +#define XCA_GET8( src ) ( { \ + const uint8_t *src8 = src; \ + src = ( uint8_t * ) src + sizeof ( *src8 ); \ + *src8; } ) + +/** XCA source data stream end marker */ +#define XCA_END_MARKER 256 + +/** XCA block size */ +#define XCA_BLOCK_SIZE ( 64 * 1024 ) + +extern ssize_t xca_decompress ( const void *data, size_t len, void *buf ); + +#endif /* _XCA_H */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h index 5b684b49..029aec4e 100644 --- a/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h @@ -40,6 +40,15 @@ typedef enum ventoy_fs_type ventoy_fs_max }ventoy_fs_type; +typedef enum ventoy_chain_type +{ + ventoy_chain_linux = 0, /* 0: linux */ + ventoy_chain_windows, /* 1: windows */ + ventoy_chain_wim, /* 2: wim */ + + ventoy_chain_max +}ventoy_chain_type; + #pragma pack(1) typedef struct ventoy_guid @@ -109,7 +118,7 @@ typedef struct ventoy_os_param * * vtoy_reserved[0]: vtoy_break_level * vtoy_reserved[1]: vtoy_debug_level - * vtoy_reserved[2]: vtoy_chain_type 0:Linux 1:Windows + * vtoy_reserved[2]: vtoy_chain_type 0:Linux 1:Windows 2:wimfile * vtoy_reserved[3]: vtoy_iso_format 0:iso9660 1:udf * vtoy_reserved[4]: vtoy_windows_cd_prompt * @@ -123,7 +132,8 @@ typedef struct ventoy_os_param typedef struct ventoy_windows_data { char auto_install_script[384]; - grub_uint8_t reserved[128]; + char injection_archive[384]; + grub_uint8_t reserved[256]; }ventoy_windows_data; @@ -204,12 +214,13 @@ typedef struct ventoy_img_chunk_list #define ventoy_filt_register grub_file_filter_register -typedef const char * (*grub_env_get_pf)(const char *name); - #pragma pack(1) #define GRUB_FILE_REPLACE_MAGIC 0x1258BEEF +typedef const char * (*grub_env_get_pf)(const char *name); +typedef int (*grub_env_printf_pf)(const char *fmt, ...); + typedef struct ventoy_grub_param_file_replace { grub_uint32_t magic; @@ -221,8 +232,8 @@ typedef struct ventoy_grub_param_file_replace typedef struct ventoy_grub_param { grub_env_get_pf grub_env_get; - ventoy_grub_param_file_replace file_replace; + grub_env_printf_pf grub_env_printf; }ventoy_grub_param; #pragma pack() diff --git a/GRUB2/MOD_SRC/grub-2.04/install.sh b/GRUB2/MOD_SRC/grub-2.04/install.sh index 1dc952af..446816d5 100644 --- a/GRUB2/MOD_SRC/grub-2.04/install.sh +++ b/GRUB2/MOD_SRC/grub-2.04/install.sh @@ -12,19 +12,17 @@ make install PATH=$PATH:$VT_DIR/GRUB2/INSTALL/bin/:$VT_DIR/GRUB2/INSTALL/sbin/ net_modules_legacy="net tftp http" -all_modules_legacy="date drivemap blocklist ntldr search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio lspci pci ext2 xfs ventoy chain read halt iso9660 linux16 test true sleep reboot echo videotest videoinfo videotest_checksum video_colors video_cirrus video_bochs vga vbe video_fb font video gettext extcmd terminal linux minicmd help configfile tr trig boot biosdisk disk ls tar squash4 password_pbkdf2 all_video png jpeg part_gpt part_msdos fat exfat ntfs loopback gzio normal udf gfxmenu gfxterm gfxterm_background gfxterm_menu" +all_modules_legacy="date drivemap blocklist vga_text ntldr search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio lspci pci ext2 xfs ventoy chain read halt iso9660 linux16 test true sleep reboot echo videotest videoinfo videotest_checksum video_colors video_cirrus video_bochs vga vbe video_fb font video gettext extcmd terminal linux minicmd help configfile tr trig boot biosdisk disk ls tar squash4 password_pbkdf2 all_video png jpeg part_gpt part_msdos fat exfat ntfs loopback gzio normal udf gfxmenu gfxterm gfxterm_background gfxterm_menu" net_modules_uefi="efinet net tftp http" all_modules_uefi="blocklist ventoy test search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux relocator jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop efi_uga video_bochs video_cirrus video video_fb gfxterm_background gfxterm_menu" -all_extra_modules="elf macho offsetio regexp file" - if [ "$1" = "uefi" ]; then - all_modules="$net_modules_uefi $all_modules_uefi $all_extra_modules" - grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi" --prefix '(,msdos2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/grubx64_real.efi" --format 'x86_64-efi' --compression 'auto' $all_modules_uefi 'fat' 'part_msdos' + all_modules="$net_modules_uefi $all_modules_uefi " + grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/grubx64_real.efi" --format 'x86_64-efi' --compression 'auto' $all_modules_uefi 'fat' 'part_msdos' else - all_modules="$net_modules_legacy $all_modules_legacy" - grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc" --prefix '(,msdos2)/grub' --output "$VT_DIR/INSTALL/grub/i386-pc/core.img" --format 'i386-pc' --compression 'auto' $all_modules_legacy 'fat' 'part_msdos' 'biosdisk' + all_modules="$net_modules_legacy $all_modules_legacy " + grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/grub/i386-pc/core.img" --format 'i386-pc' --compression 'auto' $all_modules_legacy 'fat' 'part_msdos' 'biosdisk' fi grub-mknetdir --modules="$all_modules" --net-directory=$VT_DIR/GRUB2/PXE --subdir=grub2 --locales=en@quot || exit 1 @@ -34,16 +32,29 @@ if [ "$1" = "uefi" ]; then cp -a $VT_DIR/GRUB2/PXE/grub2/x86_64-efi/core.efi $VT_DIR/GRUB2/NBP/core.efi || exit 1 rm -f $VT_DIR/INSTALL/grub/x86_64-efi/normal.mod - cp -a $VT_DIR/GRUB2/PXE/grub2/x86_64-efi/normal.mod $VT_DIR/INSTALL/grub/x86_64-efi/normal.mod || exit 1 + cp -a $VT_DIR/GRUB2/PXE/grub2/x86_64-efi/normal.mod $VT_DIR/INSTALL/grub/x86_64-efi/normal.mod || exit 1 + + #copy other modules + ls -1 $VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi/ | egrep '\.(lst|mod)$' | while read line; do + if ! echo $all_modules | grep -q " ${line%.mod} "; then + echo "Copy $line ..." + rm -f $VT_DIR/INSTALL/grub/x86_64-efi/$line + cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi/$line $VT_DIR/INSTALL/grub/x86_64-efi/ + fi + done else rm -f $VT_DIR/GRUB2/NBP/core.0 cp -a $VT_DIR/GRUB2/PXE/grub2/i386-pc/core.0 $VT_DIR/GRUB2/NBP/core.0 || exit 1 - for md in $all_extra_modules; do - rm -f $VT_DIR/INSTALL/grub/i386-pc/${md}.mod - cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/${md}.mod $VT_DIR/INSTALL/grub/i386-pc/ - done - rm -f $VT_DIR/INSTALL/grub/i386-pc/boot.img cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/boot.img $VT_DIR/INSTALL/grub/i386-pc/boot.img || exit 1 + + #copy other modules + ls -1 $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/ | egrep '\.(lst|mod)$' | while read line; do + if ! echo $all_modules | grep -q " ${line%.mod} "; then + echo "Copy $line ..." + rm -f $VT_DIR/INSTALL/grub/i386-pc/$line + cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/$line $VT_DIR/INSTALL/grub/i386-pc/ + fi + done fi diff --git a/ICON/forums.png b/ICON/forums.png new file mode 100644 index 00000000..ca926982 Binary files /dev/null and b/ICON/forums.png differ diff --git a/ICON/logo_128.png b/ICON/logo_128.png new file mode 100644 index 00000000..a13884a4 Binary files /dev/null and b/ICON/logo_128.png differ diff --git a/ICON/logo_16.png b/ICON/logo_16.png new file mode 100644 index 00000000..a5b068f7 Binary files /dev/null and b/ICON/logo_16.png differ diff --git a/ICON/logo_256.png b/ICON/logo_256.png new file mode 100644 index 00000000..d6df64f6 Binary files /dev/null and b/ICON/logo_256.png differ diff --git a/ICON/logo_32.png b/ICON/logo_32.png new file mode 100644 index 00000000..6e6618eb Binary files /dev/null and b/ICON/logo_32.png differ diff --git a/ICON/logo_48.png b/ICON/logo_48.png new file mode 100644 index 00000000..9d0a332b Binary files /dev/null and b/ICON/logo_48.png differ diff --git a/ICON/logo_512.png b/ICON/logo_512.png new file mode 100644 index 00000000..6a1ec92b Binary files /dev/null and b/ICON/logo_512.png differ diff --git a/ICON/logo_64.png b/ICON/logo_64.png new file mode 100644 index 00000000..8b23b321 Binary files /dev/null and b/ICON/logo_64.png differ diff --git a/ICON/logo_72.png b/ICON/logo_72.png new file mode 100644 index 00000000..4f24cd0b Binary files /dev/null and b/ICON/logo_72.png differ diff --git a/IMG/cpio/ventoy/hook/cdlinux/disk-hook.sh b/IMG/cpio/ventoy/hook/cdlinux/disk-hook.sh new file mode 100644 index 00000000..3e46fbfd --- /dev/null +++ b/IMG/cpio/ventoy/hook/cdlinux/disk-hook.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0666 /dev/ventoy b $blkdev_num + + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/cdlinux/ventoy-hook.sh b/IMG/cpio/ventoy/hook/cdlinux/ventoy-hook.sh new file mode 100644 index 00000000..41ac545a --- /dev/null +++ b/IMG/cpio/ventoy/hook/cdlinux/ventoy-hook.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +echo "CDlinux process..." >> $VTLOG + +$BUSYBOX_PATH/mknod -m 0660 /ventoy/ram0 b 1 0 + +$BUSYBOX_PATH/mkdir /vtmnt /ventoy_rdroot +$BUSYBOX_PATH/mount -t squashfs /ventoy/ram0 /vtmnt + +$BUSYBOX_PATH/mount -nt tmpfs -o mode=755 tmpfs /ventoy_rdroot + +$BUSYBOX_PATH/cp -a /vtmnt/* /ventoy_rdroot +$BUSYBOX_PATH/ls -1a /vtmnt/ | $GREP '^\.[^.]' | while read vtLine; do + $BUSYBOX_PATH/cp -a /vtmnt/$vtLine /ventoy_rdroot +done + +$BUSYBOX_PATH/umount /vtmnt && $BUSYBOX_PATH/rm -rf /vtmnt +$BUSYBOX_PATH/cp -a /ventoy /ventoy_rdroot + +echo 'echo "CDL_DEV=/dev/mapper/ventoy" >>"$VAR_FILE"' >> /ventoy_rdroot/etc/rc.d/rc.var + +ventoy_set_rule_dir_prefix /ventoy_rdroot +ventoy_systemd_udevd_work_around +ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace" diff --git a/IMG/cpio/ventoy/hook/cucumber/disk-hook.sh b/IMG/cpio/ventoy/hook/cucumber/disk-hook.sh new file mode 100644 index 00000000..a5b7b955 --- /dev/null +++ b/IMG/cpio/ventoy/hook/cucumber/disk-hook.sh @@ -0,0 +1,52 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +vtlog "mount media /dev/$vtDM ..." +if ! [ -e /media/install ]; then + mkdir -p /media/install +fi +mount /dev/$vtDM /media/install + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/cucumber/ventoy-hook.sh b/IMG/cpio/ventoy/hook/cucumber/ventoy-hook.sh new file mode 100644 index 00000000..4f0363c2 --- /dev/null +++ b/IMG/cpio/ventoy/hook/cucumber/ventoy-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if [ -e /sbin/mount_installer ]; then + echo "hook at mount_installer ..." >> $VTLOG + $SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/cucumber/disk-hook.sh" -i /sbin/mount_installer +fi + diff --git a/IMG/cpio/ventoy/hook/debian/default-hook.sh b/IMG/cpio/ventoy/hook/debian/default-hook.sh index bd2dd1ea..234c6766 100644 --- a/IMG/cpio/ventoy/hook/debian/default-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/default-hook.sh @@ -17,6 +17,8 @@ # #************************************************************************************ +CD_DETECT="/var/lib/dpkg/info/cdrom-detect.postinst" + if [ -e /init ] && $GREP -q '^mountroot$' /init; then echo "Here before mountroot ..." >> $VTLOG @@ -29,7 +31,15 @@ if [ -e /init ] && $GREP -q '^mountroot$' /init; then $SED "s#^ *LIVEMEDIA=.*#LIVEMEDIA=/dev/mapper/ventoy#" -i /scripts/casper fi fi - +elif [ -e "$CD_DETECT" ]; then + echo "$CD_DETECT exist, now add hook in it..." >> $VTLOG + + $SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/disk_mount_hook.sh" -i "$CD_DETECT" + TITLE_LINE=$($GREP -m1 '^hw-detect.*detect_progress_title' "$CD_DETECT") + if [ $? -eq 0 ]; then + echo "add $TITLE_LINE for hook" >> $VTLOG + $SED "1 a$TITLE_LINE" -i "$CD_DETECT" + fi elif [ -e /init ] && $GREP -q '/start-udev$' /init; then echo "Here use notify ..." >> $VTLOG diff --git a/IMG/cpio/ventoy/hook/debian/linuxconsole-disk.sh b/IMG/cpio/ventoy/hook/debian/linuxconsole-disk.sh new file mode 100644 index 00000000..e5bb7cbb --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/linuxconsole-disk.sh @@ -0,0 +1,71 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + + +vtoydm -i -f $VTOY_PATH/ventoy_image_map -d $vtdiskname > $VTOY_PATH/iso_file_list + +vtline=$(grep '[-][-] drivers-.*\.squashfs' $VTOY_PATH/iso_file_list) +sector=$(echo $vtline | awk '{print $(NF-1)}') +length=$(echo $vtline | awk '{print $NF}') + +vtoydm -e -f $VTOY_PATH/ventoy_image_map -d $vtdiskname -s $sector -l $length -o $VTOY_PATH/driver.squashfs +mount -t squashfs $VTOY_PATH/driver.squashfs /lib/modules +modprobe dm-mod + +umount /lib/modules +rm -f $VTOY_PATH/driver.squashfs + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +blkdev_dev=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if ! [ -b /dev/$vtDM ]; then + mknod -m 0660 /dev/$vtDM b $blkdev_dev +fi + +if mount /dev/$vtDM /media/ydfs; then + vtlog "mount success" +else + vtlog "mount failed" +fi + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/linuxconsole-hook.sh b/IMG/cpio/ventoy/hook/debian/linuxconsole-hook.sh new file mode 100644 index 00000000..a8e1db71 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/linuxconsole-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +$SED "s#/busybox/bin/sleep 2#/busybox/bin/sleep 10#" -i /etc/init.d/tty1 +$SED "/install *-d *.media.ydfs/a return" -i /ydfs/detect/media +$SED "/install *-d *.media.ydfs/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/linuxconsole-disk.sh" -i /ydfs/detect/media + diff --git a/IMG/cpio/ventoy/hook/debian/tails-hook.sh b/IMG/cpio/ventoy/hook/debian/tails-hook.sh index dd880498..54a3e822 100644 --- a/IMG/cpio/ventoy/hook/debian/tails-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/tails-hook.sh @@ -20,5 +20,11 @@ $SED "s#.*livefs_root=.*find_livefs.*#$BUSYBOX_PATH/mount -t iso9660 /dev/mapper/ventoy \$mountpoint; livefs_root=\$mountpoint#" -i /usr/lib/live/boot/9990-main.sh $SED "s#.*livefs_root=.*find_livefs.*#$BUSYBOX_PATH/mount -t iso9660 /dev/mapper/ventoy \$mountpoint; livefs_root=\$mountpoint#" -i /usr/bin/boot/9990-main.sh -ventoy_systemd_udevd_work_around -ventoy_add_udev_rule "$VTOY_PATH/hook/debian/udev_disk_hook.sh %k" +if [ -e /init ] && $GREP -q '^mountroot$' /init; then + echo "Here before mountroot ..." >> $VTLOG + $SED "/^mountroot$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/disk_mount_hook.sh" -i /init +else + echo "Use default hook ..." >> $VTLOG + ventoy_systemd_udevd_work_around + ventoy_add_udev_rule "$VTOY_PATH/hook/debian/udev_disk_hook.sh %k" +fi diff --git a/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh index 6dd6882b..8cbda0e5 100644 --- a/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh +++ b/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh @@ -50,7 +50,7 @@ ventoy_os_install_dmsetup() { if $GREP -q 'device-mapper' /proc/devices; then vtlog "device mapper module is loaded" else - vtlog"device mapper module is NOT loaded, now load it..." + vtlog "device mapper module is NOT loaded, now load it..." VER=$($BUSYBOX_PATH/uname -r) KO=$($FIND /lib/modules/$VER/kernel/drivers/md -name "dm-mod*") @@ -99,7 +99,18 @@ ventoy_udev_disk_common_hook $* # So if ventoy is installed on a non-USB device, we just mount /cdrom here except # for these has boot=live or boot=casper parameter in cmdline # -if echo $ID_BUS | $GREP -q -i usb; then +VT_BUS_USB="" +if [ -n "$ID_BUS" ]; then + if echo $ID_BUS | $GREP -q -i usb; then + VT_BUS_USB="YES" + fi +else + if $BUSYBOX_PATH/ls -l /sys/class/block/${1:0:-1} | $GREP -q -i usb; then + VT_BUS_USB="YES" + fi +fi + +if [ -n "$VT_BUS_USB" ]; then vtlog "$1 is USB device" else vtlog "$1 is NOT USB device (bus $ID_BUS)" diff --git a/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh b/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh index 2bc7a860..f23aef65 100644 --- a/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh @@ -60,6 +60,10 @@ ventoy_get_debian_distro() { echo 'porteus'; return fi + if $GREP -q 'linuxconsole' /proc/version; then + echo 'linuxconsole'; return + fi + echo 'default' } diff --git a/IMG/cpio/ventoy/hook/debian/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/debian/ventoy-inotifyd-hook.sh index 53916c6a..e1547225 100644 --- a/IMG/cpio/ventoy/hook/debian/ventoy-inotifyd-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/ventoy-inotifyd-hook.sh @@ -23,13 +23,15 @@ if is_ventoy_hook_finished; then exit 0 fi -vtlog "##### INOTIFYD: $2/$3 is created ..." VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH if is_inotify_ventoy_part $3; then + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." vtlog "find ventoy partition $3 ..." $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/udev_disk_hook.sh "$3" +else + vtlog "##### INOTIFYD: $2/$3 is created (NO)..." fi PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/fatdog/disk-hook.sh b/IMG/cpio/ventoy/hook/fatdog/disk-hook.sh new file mode 100644 index 00000000..8ee05793 --- /dev/null +++ b/IMG/cpio/ventoy/hook/fatdog/disk-hook.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/fatdog/ventoy-hook.sh b/IMG/cpio/ventoy/hook/fatdog/ventoy-hook.sh new file mode 100644 index 00000000..8b164329 --- /dev/null +++ b/IMG/cpio/ventoy/hook/fatdog/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/find_local_device *(/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/fatdog/disk-hook.sh" -i /init +$SED "/find_and_choose_local_device *(/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/fatdog/disk-hook.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/gobo/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/gobo/ventoy-inotifyd-hook.sh index ff52bbb0..76009e86 100644 --- a/IMG/cpio/ventoy/hook/gobo/ventoy-inotifyd-hook.sh +++ b/IMG/cpio/ventoy/hook/gobo/ventoy-inotifyd-hook.sh @@ -23,11 +23,11 @@ if is_ventoy_hook_finished; then exit 0 fi -vtlog "##### INOTIFYD: $2/$3 is created ..." - VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH if is_inotify_ventoy_part $3; then + vtlog "##### INOTIFYD: $2/$3 is created (YES)..." + vtlog "find ventoy partition $3 ..." $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace @@ -42,6 +42,8 @@ if is_inotify_ventoy_part $3; then # fi set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO)..." fi PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/kwort/disk-hook.sh b/IMG/cpio/ventoy/hook/kwort/disk-hook.sh new file mode 100644 index 00000000..8ee05793 --- /dev/null +++ b/IMG/cpio/ventoy/hook/kwort/disk-hook.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/kwort/ventoy-hook.sh b/IMG/cpio/ventoy/hook/kwort/ventoy-hook.sh new file mode 100644 index 00000000..78f56150 --- /dev/null +++ b/IMG/cpio/ventoy/hook/kwort/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/kwort/disk-hook.sh" -i /etc/rc.d/init/media diff --git a/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh index bc604ffd..226cbcad 100644 --- a/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh +++ b/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh @@ -23,12 +23,11 @@ if is_ventoy_hook_finished; then exit 0 fi -vtlog "##### INOTIFYD: $2/$3 is created ..." - VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH if is_inotify_ventoy_part $3; then - + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + vtlog "find ventoy partition ..." $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace @@ -64,6 +63,8 @@ if is_inotify_ventoy_part $3; then fi set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." fi PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/manjaro/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/manjaro/ventoy-inotifyd-hook.sh index 60cff43a..5f2d45cb 100644 --- a/IMG/cpio/ventoy/hook/manjaro/ventoy-inotifyd-hook.sh +++ b/IMG/cpio/ventoy/hook/manjaro/ventoy-inotifyd-hook.sh @@ -23,11 +23,10 @@ if is_ventoy_hook_finished; then exit 0 fi -vtlog "##### INOTIFYD: $2/$3 is created ..." - VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH if is_inotify_ventoy_part $3; then + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." vtlog "find ventoy partition $3 ..." $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh "$3" @@ -41,6 +40,8 @@ if is_inotify_ventoy_part $3; then mkdir -p /dev/disk/by-label fi $BUSYBOX_PATH/cp -a /dev/$vtDM /dev/disk/by-label/$vtLABEL +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." fi PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/parabola/ventoy-disk.sh b/IMG/cpio/ventoy/hook/parabola/ventoy-disk.sh new file mode 100644 index 00000000..356c77f8 --- /dev/null +++ b/IMG/cpio/ventoy/hook/parabola/ventoy-disk.sh @@ -0,0 +1,48 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +if is_ventoy_hook_finished; then + exit 0 +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +if [ -n "$1" ]; then + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') + vtDM=$(ventoy_find_dm_id ${blkdev_num}) + + vtlog "ln -s /dev/$vtDM $1" + ln -s /dev/$vtDM "$1" +fi + +# OK finish +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/parabola/ventoy-hook.sh b/IMG/cpio/ventoy/hook/parabola/ventoy-hook.sh new file mode 100644 index 00000000..b8b3a5d5 --- /dev/null +++ b/IMG/cpio/ventoy/hook/parabola/ventoy-hook.sh @@ -0,0 +1,44 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if $GREP -q '^"$mount_handler"' /init; then + echo 'use mount_handler ...' >> $VTLOG + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/parabola/ventoy-disk.sh \"\$parabolaisodevice\"" -i /init + + if [ -f /hooks/parabolaiso ]; then + $SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/parabola/ventoy-timeout.sh ${dev}; then break; fi' -i /hooks/parabolaiso + fi + +else + # some archlinux initramfs doesn't contain device-mapper udev rules file + ARCH_UDEV_DIR=$(ventoy_get_udev_conf_dir) + if [ -s "$ARCH_UDEV_DIR/13-dm-disk.rules" ]; then + echo 'dm-disk rule exist' >> $VTLOG + else + echo 'Copy dm-disk rule file' >> $VTLOG + $CAT $VTOY_PATH/hook/default/13-dm-disk.rules > "$ARCH_UDEV_DIR/13-dm-disk.rules" + fi + + # use default proc + ventoy_systemd_udevd_work_around + + ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k" +fi diff --git a/IMG/cpio/ventoy/hook/parabola/ventoy-timeout.sh b/IMG/cpio/ventoy/hook/parabola/ventoy-timeout.sh new file mode 100644 index 00000000..fec9cc07 --- /dev/null +++ b/IMG/cpio/ventoy/hook/parabola/ventoy-timeout.sh @@ -0,0 +1,36 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if [ -b /dev/$vtDM ]; then + vtlog "ln -s /dev/$vtDM $1" + ln -s /dev/$vtDM "$1" + exit 0 +else + vtlog "Device-mapper not found" + exit 1 +fi + + diff --git a/IMG/cpio/ventoy/hook/pmagic/disk-hook.sh b/IMG/cpio/ventoy/hook/pmagic/disk-hook.sh new file mode 100644 index 00000000..3e46fbfd --- /dev/null +++ b/IMG/cpio/ventoy/hook/pmagic/disk-hook.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0666 /dev/ventoy b $blkdev_num + + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/pmagic/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/pmagic/udev_disk_hook.sh new file mode 100644 index 00000000..93e0548e --- /dev/null +++ b/IMG/cpio/ventoy/hook/pmagic/udev_disk_hook.sh @@ -0,0 +1,32 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then + exit 0 +fi + +ventoy_udev_disk_common_hook $* "noreplace" +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0666 /dev/ventoy b $blkdev_num + +# OK finish +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/pmagic/ventoy-hook.sh b/IMG/cpio/ventoy/hook/pmagic/ventoy-hook.sh new file mode 100644 index 00000000..d4768875 --- /dev/null +++ b/IMG/cpio/ventoy/hook/pmagic/ventoy-hook.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if $GREP -q 'Searching *for *PMAGIC' /init; then + echo "Find Searching PMAGIC" >> $VTLOG + $SED "/Searching *for *PMAGIC/a\ root=/dev/ventoy" -i /init + $SED "/Searching *for *PMAGIC/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/pmagic/disk-hook.sh" -i /init +else + echo "Use default..." >> $VTLOG + $SED "s#^root=.*cmdline.*#root=/dev/ventoy#g'" -i /init + ventoy_systemd_udevd_work_around + ventoy_add_udev_rule "$VTOY_PATH/hook/pmagic/udev_disk_hook.sh %k" +fi diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh index 1bb6a6b1..ed53f4ca 100644 --- a/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh @@ -60,6 +60,11 @@ fi $BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/${vtPriority}-ventoy-inotifyd-start.sh $BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-timeout.sh /lib/dracut/hooks/initqueue/timeout/${vtPriority}-ventoy-timeout.sh +if [ -e /sbin/dmsquash-live-root ]; then + echo "patch /sbin/dmsquash-live-root ..." >> $VTLOG + $SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/rhel7/ventoy-make-link.sh" -i /sbin/dmsquash-live-root +fi + # suppress write protected mount warning if [ -e /usr/sbin/anaconda-diskroot ]; then $SED 's/^mount $dev $repodir/mount -oro $dev $repodir/' -i /usr/sbin/anaconda-diskroot diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh index a565098b..a1431d07 100644 --- a/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh @@ -23,12 +23,12 @@ if is_ventoy_hook_finished; then exit 0 fi -vtlog "##### INOTIFYD: $2/$3 is created ..." - VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH if is_inotify_ventoy_part $3; then + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + vtGenRulFile='/etc/udev/rules.d/99-live-squash.rules' if [ -e $vtGenRulFile ] && $GREP -q dmsquash $vtGenRulFile; then vtScript=$($GREP -m1 'RUN.=' $vtGenRulFile | $AWK -F'RUN.=' '{print $2}' | $SED 's/"\(.*\)".*/\1/') @@ -57,6 +57,8 @@ if is_inotify_ventoy_part $3; then fi set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." fi PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-make-link.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-make-link.sh new file mode 100644 index 00000000..22a3dd4a --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-make-link.sh @@ -0,0 +1,35 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if ! [ -e /dev/mapper/ventoy ]; then + vtlog "link to /dev/mapper/ventoy" + ln -s /dev/dm-0 /dev/mapper/ventoy +fi + +VTLABEL=$($BUSYBOX_PATH/blkid /dev/dm-0 | $SED 's/.*LABEL="\([^"]*\)".*/\1/') +vtlog "VTLABEL=$VTLABEL" + +if [ -n "$VTLABEL" ]; then + if ! [ -e "/dev/disk/by-label/$VTLABEL" ]; then + vtlog "link to /dev/disk/by-label/$VTLABEL" + ln -s /dev/dm-0 "/dev/disk/by-label/$VTLABEL" + fi +fi diff --git a/IMG/cpio/ventoy/hook/vine/dev-listen.sh b/IMG/cpio/ventoy/hook/vine/dev-listen.sh new file mode 100644 index 00000000..97cddd60 --- /dev/null +++ b/IMG/cpio/ventoy/hook/vine/dev-listen.sh @@ -0,0 +1,63 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +while [ -n "1" ]; do + if [ -e /dev/null ]; then + break + else + $SLEEP 0.5 + fi +done + +while [ -n "1" ]; do + if [ -e /sys/block ]; then + break + else + $SLEEP 0.5 + fi +done + +while [ -n "Y" ]; do + vtdiskname=$(get_ventoy_disk_name) + if [ "$vtdiskname" != "unknown" ]; then + break + else + $SLEEP 0.5 + fi +done + +vtshortdev=${vtdiskname#/dev/} + +if ! [ -b $vtdiskname ]; then + blkdev=$($CAT /sys/class/block/$vtshortdev/dev | $SED 's/:/ /g') + $BUSYBOX_PATH/mknod -m 0660 $vtdiskname b $blkdev +fi + +if ! [ -b "${vtdiskname}2" ]; then + blkdev=$($CAT /sys/class/block/${vtshortdev}2/dev | $SED 's/:/ /g') + $BUSYBOX_PATH/mknod -m 0660 "${vtdiskname}2" b $blkdev +fi + +$BUSYBOX_PATH/ls /dev/ > /dev/console + +$BUSYBOX_PATH/sh $VTOY_PATH/hook/vine/udev_disk_hook.sh "${vtdiskname#/dev/}2" + + diff --git a/IMG/cpio/ventoy/hook/vine/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/vine/udev_disk_hook.sh new file mode 100644 index 00000000..8209095a --- /dev/null +++ b/IMG/cpio/ventoy/hook/vine/udev_disk_hook.sh @@ -0,0 +1,79 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtCheatLoop=loop6 + +ventoy_os_install_dmsetup() { + vtlog "ventoy_os_install_dmsetup $1" + + vt_usb_disk=$1 + + # dump iso file location + $VTOY_PATH/tool/vtoydm -i -f $VTOY_PATH/ventoy_image_map -d ${vt_usb_disk} > $VTOY_PATH/iso_file_list + + # install dmsetup + LINE=$($GREP 'kernel-[0-9].*\.rpm' $VTOY_PATH/iso_file_list) + if [ $? -eq 0 ]; then + install_rpm_from_line "$LINE" ${vt_usb_disk} + fi + + $BUSYBOX_PATH/modprobe dm-mod + + vtlog "dmsetup install finish, now check it..." + + dmsetup_path=/ventoy/tool/dmsetup + if [ -z "$dmsetup_path" ]; then + vterr "dmsetup still not found after install" + elif $dmsetup_path info >> $VTLOG 2>&1; then + vtlog "$dmsetup_path work ok" + else + vterr "$dmsetup_path not work" + fi +} + + +if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then + # /dev/vtCheatLoop come first + if [ "$1" = "$vtCheatLoop" ] && [ -b $VTOY_DM_PATH ]; then + ventoy_copy_device_mapper /dev/$vtCheatLoop + fi + exit 0 +fi + +ventoy_os_install_dmsetup "/dev/${1:0:-1}" + +ventoy_udev_disk_common_hook $* "noreplace" + +$BUSYBOX_PATH/mount $VTOY_DM_PATH /mnt/ventoy + +# +# We do a trick for rhel6 series here. +# Use /dev/$vtCheatLoop and wapper it as a removable cdrom with bind mount. +# Then the anaconda installer will accept /dev/$vtCheatLoop as the install medium. +# +ventoy_copy_device_mapper /dev/$vtCheatLoop + +$BUSYBOX_PATH/cp -a /sys/devices/virtual/block/$vtCheatLoop /tmp/ >> $VTLOG 2>&1 +echo 19 > /tmp/$vtCheatLoop/capability +$BUSYBOX_PATH/mount --bind /tmp/$vtCheatLoop /sys/block/$vtCheatLoop >> $VTLOG 2>&1 + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/vine/ventoy-hook.sh b/IMG/cpio/ventoy/hook/vine/ventoy-hook.sh new file mode 100644 index 00000000..a9deb408 --- /dev/null +++ b/IMG/cpio/ventoy/hook/vine/ventoy-hook.sh @@ -0,0 +1,28 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$BUSYBOX_PATH/mkdir -p /etc/anaconda.repos.d /mnt/ventoy +ventoy_print_yum_repo "ventoy" "file:///mnt/ventoy" > /etc/anaconda.repos.d/ventoy.repo + + +$BUSYBOX_PATH/mknod -m 0660 /dev/null c 1 3 +$VTOY_PATH/hook/vine/dev-listen.sh & + diff --git a/IMG/cpio/ventoy/init b/IMG/cpio/ventoy/init index 61659fc3..ad5ac3a9 100644 --- a/IMG/cpio/ventoy/init +++ b/IMG/cpio/ventoy/init @@ -72,6 +72,13 @@ ventoy_is_initrd_ramdisk() { fi } +ventoy_mount_squashfs() { + mkdir /dev + mount -t devtmpfs devtmpfs /dev + dd if=$1 of=/dev/ram0 status=none + umount /dev && rm -rf /dev +} + # param: file skip magic tmp ventoy_unpack_initramfs() { vtfile=$1; vtskip=$2; vtmagic=$3; vttmp=$4 @@ -83,6 +90,11 @@ ventoy_unpack_initramfs() { # vtmagic='1F8B' #fi + if [ "${vtmagic:0:4}" = '6873' ]; then + ventoy_mount_squashfs $vtfile + return + fi + for vtx in '1F8B zcat' '1F9E zcat' '425A bzcat' '5D00 lzcat' 'FD37 xzcat' '894C lzopcat' '0221 lz4cat' '28B5 zstdcat' '3037 cat'; do if [ "${vtx:0:4}" = "${vtmagic:0:4}" ]; then echo "vtx=$vtx" >> $VTLOG @@ -171,7 +183,40 @@ fi #################################################################### # # -# Step 3 : Hand over to ventoy.sh # +# Step 3 : Extract injection archive # +# # +#################################################################### +ventoy_unpack_injection() { + vtmagic=$(hexdump -n 2 -e '2/1 "%02X"' $VTOY_PATH/ventoy_injection) + echo "ventoy_unpack_injection vtmagic=$vtmagic ..." + + if [ "1F8B" = "$vtmagic" ] || [ "1F9E" = "$vtmagic" ]; then + echo "tar.gz tar -xzvf" + tar -xzvf $VTOY_PATH/ventoy_injection -C / + elif [ "425A" = "$vtmagic" ]; then + echo "tar.bz2 tar -xjvf" + tar -xjvf $VTOY_PATH/ventoy_injection -C / + elif [ "FD37" = "$vtmagic" ]; then + echo "tar.xz tar -xJvf" + tar -xJvf $VTOY_PATH/ventoy_injection -C / + elif [ "5D00" = "$vtmagic" ]; then + echo "tar.lzma tar -xavf" + tar -xavf $VTOY_PATH/ventoy_injection -C / + else + echo "unzip -o" + unzip -o $VTOY_PATH/ventoy_injection -d / + fi +} + +if [ -e $VTOY_PATH/ventoy_injection ]; then + echo "### decompress injection ... ###" >>$VTLOG + ventoy_unpack_injection > $VTOY_PATH/injection.log 2>&1 +fi + + +#################################################################### +# # +# Step 4 : Hand over to ventoy.sh # # # #################################################################### echo "Now hand over to ventoy.sh" >>$VTLOG diff --git a/IMG/cpio/ventoy/ventoy.sh b/IMG/cpio/ventoy/ventoy.sh index 640b08a9..c1cc897e 100644 --- a/IMG/cpio/ventoy/ventoy.sh +++ b/IMG/cpio/ventoy/ventoy.sh @@ -133,8 +133,9 @@ ventoy_get_os_type() { if $GREP -q 'XenServer' /etc/os-release; then echo 'xen'; return elif $GREP -q 'SUSE ' /etc/os-release; then - echo 'suse'; return - + echo 'suse'; return + elif $GREP -q 'uruk' /etc/os-release; then + echo 'debian'; return fi fi @@ -196,6 +197,34 @@ ventoy_get_os_type() { echo 'adelie'; return fi + if $GREP -q 'pmagic' /proc/version; then + echo 'pmagic'; return + fi + + if $GREP -q 'CDlinux' /proc/cmdline; then + echo 'cdlinux'; return + fi + + if $GREP -q 'parabola' /proc/version; then + echo 'parabola'; return + fi + + if $GREP -q 'cucumber' /proc/version; then + echo 'cucumber'; return + fi + + if $GREP -q 'fatdog' /proc/version; then + echo 'fatdog'; return + fi + + if $GREP -q 'KWORT' /proc/version; then + echo 'kwort'; return + fi + + if $GREP -q 'iwamoto' /proc/version; then + echo 'vine'; return + fi + echo "default" } @@ -222,6 +251,7 @@ if [ "$VTOY_BREAK_LEVEL" = "03" ] || [ "$VTOY_BREAK_LEVEL" = "13" ]; then exec $BUSYBOX_PATH/sh fi + #################################################################### # # # Step 4 : Hand over to real init # diff --git a/INSTALL/EFI/BOOT/grubx64_real.efi b/INSTALL/EFI/BOOT/grubx64_real.efi index c6874c33..b6533274 100644 Binary files a/INSTALL/EFI/BOOT/grubx64_real.efi and b/INSTALL/EFI/BOOT/grubx64_real.efi differ diff --git a/INSTALL/README b/INSTALL/README new file mode 100644 index 00000000..fad0c0bc --- /dev/null +++ b/INSTALL/README @@ -0,0 +1,28 @@ + +========== Ventoy2Disk.sh =============== + +sudo sh Ventoy2Disk.sh { -i | -I | -u } /dev/XXX XXX is the USB device, for example /dev/sdb. + +Ventoy2Disk.sh CMD [ OPTION ] /dev/sdX + CMD: + -i install ventoy to sdX (fail if disk already installed with ventoy) + -I force install ventoy to sdX (no matter installed or not) + -u update ventoy in sdX + + OPTION: (optional) + -r SIZE_MB preserve some space at the bottom of the disk (only for install) + -s enable secure boot support (default is disabled) + -g use GPT partition style, default is MBR style (only for install) + + +========== CreatePersistentImg.sh =============== + +sudo sh CreatePersistentImg.sh + +sh CreatePersistentImg.sh [ -s SIZE_IN_MB ] [ -t FSTYPE ] [ -l LABEL ] for example: + +sh CreatePersistentImg.sh ----> persistence.img in 1GB size and ext4 filesystem and casper-rw label +sh CreatePersistentImg.sh -l MX-Persist ----> persistence.img in 1GB size and ext4 filesystem and MX-Persist label +sh CreatePersistentImg.sh -s 2048 ----> persistence.img in 2GB size and ext4 filesystem and casper-rw label +sh CreatePersistentImg.sh -s 4096 -t xfs ----> persistence.img in 4GB size and xfs filesystem (ext2/3/4 xfs are supported) and casper-rw label + diff --git a/INSTALL/Ventoy2Disk.exe b/INSTALL/Ventoy2Disk.exe index 1539d7b0..c530a6b5 100644 Binary files a/INSTALL/Ventoy2Disk.exe and b/INSTALL/Ventoy2Disk.exe differ diff --git a/INSTALL/Ventoy2Disk.sh b/INSTALL/Ventoy2Disk.sh index 02a69060..06521af4 100644 --- a/INSTALL/Ventoy2Disk.sh +++ b/INSTALL/Ventoy2Disk.sh @@ -39,12 +39,17 @@ if ! [ -f ./tool/ash ]; then if ! [ -f ./tool/ash ]; then echo 'Failed to decompress tools ...' - cd $OLDDIR + if [ -n "$OLDDIR" ]; then + cd $OLDDIR + fi exit 1 fi fi ./tool/ash ./tool/VentoyWorker.sh $* -cd $OLDDIR +if [ -n "$OLDDIR" ]; then + cd $OLDDIR +fi + diff --git a/INSTALL/all_in_one.sh b/INSTALL/all_in_one.sh index 89484e7c..660b63be 100644 --- a/INSTALL/all_in_one.sh +++ b/INSTALL/all_in_one.sh @@ -23,6 +23,8 @@ sh buildlib.sh cd $VTOY_PATH/vtoyfat sh build.sh || exit 1 +cd $VTOY_PATH/vtoygpt +sh build.sh || exit 1 cd $VTOY_PATH/ExFAT sh buidlibfuse.sh || exit 1 diff --git a/INSTALL/grub/debug.cfg b/INSTALL/grub/debug.cfg index 0def325c..5abb3954 100644 --- a/INSTALL/grub/debug.cfg +++ b/INSTALL/grub/debug.cfg @@ -1,7 +1,7 @@ submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json { - menuentry 'Check global control plugin configuration' { + menuentry 'Check global control plugin configuration' --class=debug_control { set pager=1 - vt_check_plugin_json $vt_plugin_path control $iso_path + vt_check_plugin_json $vt_plugin_path control $vtoy_iso_part echo -e "\npress ENTER to exit ..." read vtInputKey @@ -10,7 +10,7 @@ submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json { menuentry 'Check theme plugin configuration' --class=debug_theme { set pager=1 - vt_check_plugin_json $vt_plugin_path theme $iso_path + vt_check_plugin_json $vt_plugin_path theme $vtoy_iso_part echo -e "\npress ENTER to exit ..." read vtInputKey @@ -19,7 +19,7 @@ submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json { menuentry 'Check auto install plugin configuration' --class=debug_autoinstall { set pager=1 - vt_check_plugin_json $vt_plugin_path auto_install $iso_path + vt_check_plugin_json $vt_plugin_path auto_install $vtoy_iso_part echo -e "\npress ENTER to exit ..." read vtInputKey @@ -28,7 +28,7 @@ submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json { menuentry 'Check persistence plugin configuration' --class=debug_persistence { set pager=1 - vt_check_plugin_json $vt_plugin_path persistence $iso_path + vt_check_plugin_json $vt_plugin_path persistence $vtoy_iso_part echo -e "\n############### dump persistence ###############" vt_dump_persistence @@ -40,7 +40,7 @@ submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json { menuentry 'Check menu alias plugin configuration' --class=debug_menualias { set pager=1 - vt_check_plugin_json $vt_plugin_path menu_alias $iso_path + vt_check_plugin_json $vt_plugin_path menu_alias $vtoy_iso_part echo -e "\npress ENTER to exit ..." read vtInputKey @@ -49,18 +49,43 @@ submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json { menuentry 'Check menu class plugin configuration' --class=debug_menuclass { set pager=1 - vt_check_plugin_json $vt_plugin_path menu_class $iso_path + vt_check_plugin_json $vt_plugin_path menu_class $vtoy_iso_part echo -e "\npress ENTER to exit ..." read vtInputKey unset pager - } + } + + menuentry 'Check injection plugin configuration' --class=debug_injection { + set pager=1 + vt_check_plugin_json $vt_plugin_path injection $vtoy_iso_part + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET { echo 'Return ...' } } + +if [ "$grub_platform" != "pc" ]; then + submenu 'Ventoy UEFI Utilities' --class=debug_util { + menuentry 'Fixup Windows BlinitializeLibrary Failure' { + chainloader ${vtoy_path}/vtoyutil_x64.efi env_param=${env_param} ${vtdebug_flag} feature=fix_windows_mmap + boot + echo -e "\npress ENTER to exit ..." + read vtInputKey + } + + menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET { + echo 'Return ...' + } + } +fi + menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET { echo 'Return ...' } diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index 144b78e1..f2ea24f5 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -30,6 +30,30 @@ function ventoy_debug_pause { fi } +function ventoy_cli_console { + if [ "$grub_platform" = "pc" ]; then + #terminal_output vga_text + terminal_output console + else + if [ "$vtoy_display_mode" != "CLI" ]; then + terminal_output console + fi + fi +} + +function ventoy_gui_console { + if [ "$grub_platform" = "pc" ]; then + if [ "$vtoy_display_mode" = "CLI" ]; then + terminal_output console + else + terminal_output gfxterm + fi + else + if [ "$vtoy_display_mode" != "CLI" ]; then + terminal_output gfxterm + fi + fi +} function ventoy_power { configfile $prefix/power.cfg @@ -43,6 +67,18 @@ function ventoy_localboot { configfile $prefix/localboot.cfg } +function ventoy_ext_menu { + if [ -e $vt_plugin_path/ventoy/ventoy_grub.cfg ]; then + set ventoy_new_context=1 + configfile $vt_plugin_path/ventoy/ventoy_grub.cfg + unset ventoy_new_context + else + echo "ventoy_grub.cfg NOT exist." + echo -e "\npress ENTER to exit ..." + read vtInputKey + fi +} + function get_os_type { set vtoy_os=Linux @@ -53,6 +89,26 @@ function get_os_type { fi done + if [ "$vtoy_os" = "Linux" ]; then + if vt_strstr "$vt_system_id" "FreeBSD"; then + set vtoy_os=Unix + set vt_unix_type=FreeBSD + elif [ -e (loop)/bin/freebsd-version ]; then + set vtoy_os=Unix + set vt_unix_type=FreeBSD + + + elif [ -e (loop)/boot/kernel/kernel ]; then + if file --is-x86-kfreebsd (loop)/boot/kernel/kernel; then + set vtoy_os=Unix + set vt_unix_type=FreeBSD + elif file --is-x86-knetbsd (loop)/boot/kernel/kernel; then + set vtoy_os=Unix + set vt_unix_type=NetBSD + fi + fi + fi + if [ -n "${vtdebug_flag}" ]; then echo ISO is $vtoy_os fi @@ -154,10 +210,150 @@ function distro_specify_initrd_file_phase2 { vt_linux_specify_initrd_file /initrd.img elif [ -f (loop)/sysresccd/boot/x86_64/sysresccd.img ]; then vt_linux_specify_initrd_file /sysresccd/boot/x86_64/sysresccd.img - + elif [ -f (loop)/CDlinux/initrd ]; then + vt_linux_specify_initrd_file /CDlinux/initrd + elif [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then + vt_linux_specify_initrd_file /parabola/boot/x86_64/parabolaiso.img + if [ -f (loop)/parabola/boot/i686/parabolaiso.img ]; then + vt_linux_specify_initrd_file /parabola/boot/i686/parabolaiso.img + fi + elif [ -f (loop)/EFI/BOOT/initrd.img ]; then + #Qubes + vt_linux_specify_initrd_file /EFI/BOOT/initrd.img + if [ "$grub_platform" != "pc" ]; then + vt_add_replace_file 0 "initrd.img" + fi + elif [ -f (loop)/initrd ]; then + vt_linux_specify_initrd_file /initrd + elif [ -f (loop)/live/initrd1 ]; then + vt_linux_specify_initrd_file /live/initrd1 + fi } +function ventoy_get_ghostbsd_ver { + + # vt_parse_iso_create_date $1/${chosen_path} vt_create_date + # if regexp "^202005" "$vt_create_date"; then + # set vt_freebsd_ver=12.x + # fi + + set vt_freebsd_ver=12.x +} + +function ventoy_get_freenas_ver { + set vt_freebsd_ver=11.x + + if [ -e (loop)/FreeNAS-MANIFEST ]; then + vt_parse_freenas_ver (loop)/FreeNAS-MANIFEST vt_freenas_ver + if regexp "^13\.[0-9]" "$vt_freenas_ver"; then + set vt_freebsd_ver=13.x + elif regexp "^12\.[0-9]" "$vt_freenas_ver"; then + set vt_freebsd_ver=12.x + elif regexp "^11\.[0-9]" "$vt_freenas_ver"; then + set vt_freebsd_ver=11.x + fi + fi +} + +function ventoy_freebsd_proc { + if vt_strstr "$vt_volume_id" "GHOSTBSD"; then + ventoy_get_ghostbsd_ver $1 ${chosen_path} + elif vt_strstr "$vt_volume_id" "FREENAS"; then + ventoy_get_freenas_ver $1 ${chosen_path} + elif regexp "^13_[0-9]" "$vt_volume_id"; then + set vt_freebsd_ver=13.x + elif regexp "^12_[0-9]" "$vt_volume_id"; then + set vt_freebsd_ver=12.x + elif regexp "^11_[0-9]" "$vt_volume_id"; then + set vt_freebsd_ver=11.x + elif regexp "^10_[0-9]" "$vt_volume_id"; then + set vt_freebsd_ver=10.x + elif regexp "^9_[0-9]" "$vt_volume_id"; then + set vt_freebsd_ver=9.x + elif [ -e (loop)/bin/freebsd-version ]; then + vt_unix_parse_freebsd_ver (loop)/bin/freebsd-version vt_userland_ver + if regexp "\"13\.[0-9]-" "$vt_userland_ver"; then + set vt_freebsd_ver=13.x + elif regexp "\"12\.[0-9]-" "$vt_userland_ver"; then + set vt_freebsd_ver=12.x + elif regexp "\"11\.[0-9]-" "$vt_userland_ver"; then + set vt_freebsd_ver=11.x + elif regexp "\"10\.[0-9]-" "$vt_userland_ver"; then + set vt_freebsd_ver=10.x + elif regexp "\"9\.[0-9]-" "$vt_userland_ver"; then + set vt_freebsd_ver=9.x + fi + elif [ -e (loop)/README.TXT ]; then + vt_1st_line (loop)/README.TXT vt_freebsd_line1 + if regexp "FreeBSD 13\.[0-9]-" "$vt_freebsd_line1"; then + set vt_freebsd_ver=13.x + elif regexp "FreeBSD 12\.[0-9]-" "$vt_freebsd_line1"; then + set vt_freebsd_ver=12.x + elif regexp "FreeBSD 11\.[0-9]-" "$vt_freebsd_line1"; then + set vt_freebsd_ver=11.x + elif regexp "FreeBSD 10\.[0-9]-" "$vt_freebsd_line1"; then + set vt_freebsd_ver=10.x + elif regexp "FreeBSD 9\.[0-9]-" "$vt_freebsd_line1"; then + set vt_freebsd_ver=9.x + fi + elif vt_strstr "${chosen_path}" "MidnightBSD"; then + set vt_freebsd_ver=9.x + else + set vt_freebsd_ver=12.x + fi + + set vt_freebsd_bit=64 + for file in "/boot/kernel/kernel" "/boot/kernel/kernel.gz"; do + if [ -e (loop)/$file ]; then + if file --is-i386-kfreebsd (loop)/$file; then + set vt_freebsd_bit=32 + fi + break + fi + done + + if [ -n "${vtdebug_flag}" ]; then + echo "This is FreeBSD $vt_freebsd_ver ${vt_freebsd_bit}bit" + fi + + unset vt_unix_mod_path + for file in "/COPYRIGHT" "/FreeNAS-MANIFEST" "/version"; do + if [ -e (loop)${file} ]; then + set vt_unix_mod_path=${file} + break + fi + done + + vt_unix_replace_ko $vt_unix_mod_path (vtunix)/ventoy_unix/FreeBSD/geom_ventoy_ko/$vt_freebsd_ver/$vt_freebsd_bit/geom_ventoy.ko.xz + vt_unix_replace_conf FreeBSD ${1}${chosen_path} +} + +function ventoy_unix_comm_proc { + vt_unix_reset + + if [ "$ventoy_compatible" = "NO" ]; then + loopback vtunix $vtoy_efi_part/ventoy/ventoy_unix.cpio + + if [ "$vt_unix_type" = "FreeBSD" ]; then + ventoy_freebsd_proc $1 ${chosen_path} + elif [ "$vt_unix_type" = "NetBSD" ]; then + echo "NetBSD not supported" + + + + else + if [ -n "${vtdebug_flag}" ]; then + echo "Unknown unix type" + fi + fi + fi + + vt_unix_chain_data ${1}${chosen_path} + ventoy_debug_pause +} + + function uefi_windows_menu_func { vt_windows_reset @@ -186,7 +382,7 @@ function uefi_windows_menu_func { ventoy_debug_pause if [ -n "$vtoy_chain_mem_addr" ]; then - terminal_output console + ventoy_cli_console chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} boot else @@ -251,6 +447,12 @@ function uefi_linux_menu_func { fi elif [ -f (loop)/EFI/BOOT/initrd.gz ]; then vt_add_replace_file $vtindex "EFI\\BOOT\\initrd.gz" + elif [ -f (loop)/loader/entries/thinstation.conf ]; then + vt_add_replace_file $vtindex "boot\\initrd" + fi + elif [ -d (loop)/EFI/boot/entries ]; then + if [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then + vt_add_replace_file 0 "EFI\\parabolaiso\\parabolaiso.img" fi elif [ -e (loop)/syslinux/alt0/full.cz ]; then vt_add_replace_file 0 "EFI\\BOOT\\full.cz" @@ -262,7 +464,7 @@ function uefi_linux_menu_func { vt_linux_chain_data ${1}${chosen_path} if [ -n "$vtoy_chain_mem_addr" ]; then - terminal_output console + ventoy_cli_console chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} boot else @@ -271,6 +473,18 @@ function uefi_linux_menu_func { fi } +function uefi_unix_menu_func { + ventoy_unix_comm_proc $1 ${chosen_path} + + if [ -n "$vtoy_chain_mem_addr" ]; then + ventoy_cli_console + chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + else + echo "chain empty failed" + ventoy_pause + fi +} function uefi_iso_menu_func { @@ -299,6 +513,7 @@ function uefi_iso_menu_func { fi loopback loop ${1}${chosen_path} + vt_parse_iso_volume ${1}${chosen_path} vt_system_id vt_volume_id get_os_type (loop) if [ -d (loop)/EFI ]; then @@ -323,11 +538,13 @@ function uefi_iso_menu_func { if [ "$vtoy_os" = "Windows" ]; then vt_check_compatible_pe (loop) uefi_windows_menu_func $1 ${chosen_path} + elif [ "$vtoy_os" = "Unix" ]; then + uefi_unix_menu_func $1 ${chosen_path} else uefi_linux_menu_func $1 ${chosen_path} fi - terminal_output gfxterm + ventoy_gui_console } function uefi_iso_memdisk { @@ -336,11 +553,11 @@ function uefi_iso_memdisk { echo 'Loading ISO file to memory ...' vt_load_iso_to_mem ${1}${chosen_path} vtoy_iso_buf - terminal_output console + ventoy_cli_console chainloader ${vtoy_path}/ventoy_x64.efi memdisk env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_iso_buf_addr}:size:${vtoy_iso_buf_size} boot - terminal_output gfxterm + ventoy_gui_console } @@ -442,6 +659,20 @@ function legacy_linux_menu_func { fi } + +function legacy_unix_menu_func { + ventoy_unix_comm_proc $1 ${chosen_path} + + if [ -n "$vtoy_chain_mem_addr" ]; then + linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + else + echo "chain empty failed" + ventoy_pause + fi +} + + function legacy_iso_menu_func { if [ -d (loop)/ ]; then @@ -460,6 +691,7 @@ function legacy_iso_menu_func { fi loopback loop ${1}${chosen_path} + vt_parse_iso_volume ${1}${chosen_path} vt_system_id vt_volume_id get_os_type (loop) if [ -n "$vtcompat" ]; then @@ -476,6 +708,8 @@ function legacy_iso_menu_func { if [ "$vtoy_os" = "Windows" ]; then vt_check_compatible_pe (loop) legacy_windows_menu_func $1 ${chosen_path} + elif [ "$vtoy_os" = "Unix" ]; then + legacy_unix_menu_func $1 ${chosen_path} else legacy_linux_menu_func $1 ${chosen_path} fi @@ -491,26 +725,29 @@ function legacy_iso_memdisk { } function iso_common_menuentry { + unset vt_system_id + unset vt_volume_id + if [ "$grub_platform" = "pc" ]; then if vt_check_mode 0; then - legacy_iso_memdisk $iso_path + legacy_iso_memdisk $vtoy_iso_part else - legacy_iso_menu_func $iso_path + legacy_iso_menu_func $vtoy_iso_part fi else if vt_check_mode 0; then - uefi_iso_memdisk $iso_path + uefi_iso_memdisk $vtoy_iso_part else - uefi_iso_menu_func $iso_path + uefi_iso_menu_func $vtoy_iso_part fi fi } function common_unsupport_menuentry { echo -e "\n The name of the iso file could NOT contain space or non-ascii characters. \n" - echo -e " 文件名中不能有中文或空格 \n" - echo -e "\n Will return to main menu after 10 seconds ...\n" - sleep 10 + echo -e " 文件名中不能有中文或空格 \n" + echo -e "\npress ENTER to exit (请按 回车 键返回) ..." + read vtInputKey } function iso_unsupport_menuentry { @@ -519,7 +756,7 @@ function iso_unsupport_menuentry { function wim_common_menuentry { vt_chosen_img_path chosen_path - vt_wim_chain_data ${iso_path}${chosen_path} + vt_wim_chain_data ${vtoy_iso_part}${chosen_path} ventoy_debug_pause @@ -527,9 +764,9 @@ function wim_common_menuentry { if [ "$grub_platform" = "pc" ]; then linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} else - terminal_output console + ventoy_cli_console chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} - terminal_output gfxterm + ventoy_gui_console fi boot else @@ -545,16 +782,18 @@ function wim_unsupport_menuentry { function efi_common_menuentry { vt_chosen_img_path chosen_path - terminal_output console - chainloader ${iso_path}${chosen_path} + ventoy_cli_console + chainloader ${vtoy_iso_part}${chosen_path} boot - terminal_output gfxterm + ventoy_gui_console } function efi_unsupport_menuentry { common_unsupport_menuentry } + + ############################################################# ############################################################# ############################################################# @@ -563,7 +802,7 @@ function efi_unsupport_menuentry { ############################################################# ############################################################# -set VENTOY_VERSION="1.0.14" +set VENTOY_VERSION="1.0.18" # Default menu display mode, you can change it as you want. # 0: List mode @@ -577,6 +816,7 @@ set VTOY_ISO_UEFI_DRV_STR="UEFI FS" set VTOY_F2_CMD="ventoy_power" set VTOY_F4_CMD="ventoy_localboot" set VTOY_F5_CMD="ventoy_diagnosis" +set VTOY_F6_CMD="ventoy_ext_menu" if [ "$grub_platform" = "pc" ]; then set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION BIOS www.ventoy.net" @@ -590,15 +830,15 @@ if [ "$vtoy_dev" = "tftp" ]; then set vtoy_path=($root) for vtid in 0 1 2 3; do if [ -d (hd$vtid,2)/ventoy ]; then - set iso_path=(hd$vtid,1) + set vtoy_iso_part=(hd$vtid,1) set vtoy_efi_part=(hd$vtid,2) break fi done loadfont ascii - if [ -f $iso_path/ventoy/ventoy.json ]; then - set vt_plugin_path=$iso_path + if [ -f $vtoy_iso_part/ventoy/ventoy.json ]; then + set vt_plugin_path=$vtoy_iso_part else set vt_plugin_path=$prefix vt_load_plugin $vt_plugin_path @@ -610,16 +850,16 @@ else set vtoy_path=($root)/ventoy fi - set iso_path=($vtoy_dev,1) + set vtoy_iso_part=($vtoy_dev,1) set vtoy_efi_part=($vtoy_dev,2) loadfont unicode - set vt_plugin_path=$iso_path + set vt_plugin_path=$vtoy_iso_part fi #Load Plugin -if [ -f $iso_path/ventoy/ventoy.json ]; then - vt_load_plugin $iso_path +if [ -f $vtoy_iso_part/ventoy/ventoy.json ]; then + vt_load_plugin $vtoy_iso_part fi if [ -n "$VTOY_MENU_TIMEOUT" ]; then @@ -628,8 +868,8 @@ else unset timeout fi -if [ -f $iso_path/ventoy/ventoy_wimboot.img ]; then - vt_load_wimboot $iso_path/ventoy/ventoy_wimboot.img +if [ -f $vtoy_iso_part/ventoy/ventoy_wimboot.img ]; then + vt_load_wimboot $vtoy_iso_part/ventoy/ventoy_wimboot.img elif [ -f $vtoy_efi_part/ventoy/ventoy_wimboot.img ]; then vt_load_wimboot $vtoy_efi_part/ventoy/ventoy_wimboot.img fi @@ -637,10 +877,10 @@ fi if [ $VTOY_DEFAULT_MENU_MODE -eq 0 ]; then set VTOY_F3_CMD="vt_dynamic_menu 1 1" - set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:TreeView F4:Localboot F5:Debug" + set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:TreeView F4:Localboot F5:Debug F6:ExMenu" else set VTOY_F3_CMD="vt_dynamic_menu 1 0" - set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:ListView F4:Localboot F5:Debug" + set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:ListView F4:Localboot F5:Debug F6:ExMenu" fi @@ -650,21 +890,31 @@ else set gfxmode=1920x1080,1366x768,1024x768 fi -if [ -n "$vtoy_theme" ]; then - set theme=$vtoy_theme -else - set theme=$prefix/themes/ventoy/theme.txt -fi - if [ "$vtoy_display_mode" = "CLI" ]; then terminal_output console -else +else + if [ -n "$vtoy_theme" ]; then + set theme=$vtoy_theme + else + set theme=$prefix/themes/ventoy/theme.txt + fi terminal_output gfxterm fi +#export necessary variable +export theme +export gfxmode +export vtoy_dev +export vtoy_iso_part +export vtoy_efi_part +export VENTOY_VERSION + + + + #colect all image files (iso files) set ventoy_img_count=0 -vt_list_img $iso_path ventoy_img_count +vt_list_img $vtoy_iso_part ventoy_img_count #Main menu if [ $ventoy_img_count -gt 0 ]; then diff --git a/INSTALL/grub/i386-pc/acpi.mod b/INSTALL/grub/i386-pc/acpi.mod new file mode 100644 index 00000000..8768848c Binary files /dev/null and b/INSTALL/grub/i386-pc/acpi.mod differ diff --git a/INSTALL/grub/i386-pc/adler32.mod b/INSTALL/grub/i386-pc/adler32.mod new file mode 100644 index 00000000..f6b7276c Binary files /dev/null and b/INSTALL/grub/i386-pc/adler32.mod differ diff --git a/INSTALL/grub/i386-pc/affs.mod b/INSTALL/grub/i386-pc/affs.mod new file mode 100644 index 00000000..1aabc41c Binary files /dev/null and b/INSTALL/grub/i386-pc/affs.mod differ diff --git a/INSTALL/grub/i386-pc/afs.mod b/INSTALL/grub/i386-pc/afs.mod new file mode 100644 index 00000000..020612f3 Binary files /dev/null and b/INSTALL/grub/i386-pc/afs.mod differ diff --git a/INSTALL/grub/i386-pc/ahci.mod b/INSTALL/grub/i386-pc/ahci.mod new file mode 100644 index 00000000..79278035 Binary files /dev/null and b/INSTALL/grub/i386-pc/ahci.mod differ diff --git a/INSTALL/grub/i386-pc/aout.mod b/INSTALL/grub/i386-pc/aout.mod new file mode 100644 index 00000000..e775a1eb Binary files /dev/null and b/INSTALL/grub/i386-pc/aout.mod differ diff --git a/INSTALL/grub/i386-pc/archelp.mod b/INSTALL/grub/i386-pc/archelp.mod new file mode 100644 index 00000000..0aa3bb90 Binary files /dev/null and b/INSTALL/grub/i386-pc/archelp.mod differ diff --git a/INSTALL/grub/i386-pc/ata.mod b/INSTALL/grub/i386-pc/ata.mod new file mode 100644 index 00000000..10d98eda Binary files /dev/null and b/INSTALL/grub/i386-pc/ata.mod differ diff --git a/INSTALL/grub/i386-pc/backtrace.mod b/INSTALL/grub/i386-pc/backtrace.mod new file mode 100644 index 00000000..78c7fc1d Binary files /dev/null and b/INSTALL/grub/i386-pc/backtrace.mod differ diff --git a/INSTALL/grub/i386-pc/bfs.mod b/INSTALL/grub/i386-pc/bfs.mod new file mode 100644 index 00000000..07ac6456 Binary files /dev/null and b/INSTALL/grub/i386-pc/bfs.mod differ diff --git a/INSTALL/grub/i386-pc/bitmap.mod b/INSTALL/grub/i386-pc/bitmap.mod new file mode 100644 index 00000000..42404635 Binary files /dev/null and b/INSTALL/grub/i386-pc/bitmap.mod differ diff --git a/INSTALL/grub/i386-pc/bitmap_scale.mod b/INSTALL/grub/i386-pc/bitmap_scale.mod new file mode 100644 index 00000000..8b46a187 Binary files /dev/null and b/INSTALL/grub/i386-pc/bitmap_scale.mod differ diff --git a/INSTALL/grub/i386-pc/bsd.mod b/INSTALL/grub/i386-pc/bsd.mod new file mode 100644 index 00000000..51d7358d Binary files /dev/null and b/INSTALL/grub/i386-pc/bsd.mod differ diff --git a/INSTALL/grub/i386-pc/bswap_test.mod b/INSTALL/grub/i386-pc/bswap_test.mod new file mode 100644 index 00000000..4112db95 Binary files /dev/null and b/INSTALL/grub/i386-pc/bswap_test.mod differ diff --git a/INSTALL/grub/i386-pc/btrfs.mod b/INSTALL/grub/i386-pc/btrfs.mod new file mode 100644 index 00000000..25aa06e2 Binary files /dev/null and b/INSTALL/grub/i386-pc/btrfs.mod differ diff --git a/INSTALL/grub/i386-pc/bufio.mod b/INSTALL/grub/i386-pc/bufio.mod new file mode 100644 index 00000000..73bd58e9 Binary files /dev/null and b/INSTALL/grub/i386-pc/bufio.mod differ diff --git a/INSTALL/grub/i386-pc/cat.mod b/INSTALL/grub/i386-pc/cat.mod new file mode 100644 index 00000000..4afb29f4 Binary files /dev/null and b/INSTALL/grub/i386-pc/cat.mod differ diff --git a/INSTALL/grub/i386-pc/cbfs.mod b/INSTALL/grub/i386-pc/cbfs.mod new file mode 100644 index 00000000..578ed2cd Binary files /dev/null and b/INSTALL/grub/i386-pc/cbfs.mod differ diff --git a/INSTALL/grub/i386-pc/cbls.mod b/INSTALL/grub/i386-pc/cbls.mod new file mode 100644 index 00000000..bb86e5ac Binary files /dev/null and b/INSTALL/grub/i386-pc/cbls.mod differ diff --git a/INSTALL/grub/i386-pc/cbmemc.mod b/INSTALL/grub/i386-pc/cbmemc.mod new file mode 100644 index 00000000..76253f79 Binary files /dev/null and b/INSTALL/grub/i386-pc/cbmemc.mod differ diff --git a/INSTALL/grub/i386-pc/cbtable.mod b/INSTALL/grub/i386-pc/cbtable.mod new file mode 100644 index 00000000..47ebd776 Binary files /dev/null and b/INSTALL/grub/i386-pc/cbtable.mod differ diff --git a/INSTALL/grub/i386-pc/cbtime.mod b/INSTALL/grub/i386-pc/cbtime.mod new file mode 100644 index 00000000..fde0d472 Binary files /dev/null and b/INSTALL/grub/i386-pc/cbtime.mod differ diff --git a/INSTALL/grub/i386-pc/cmdline_cat_test.mod b/INSTALL/grub/i386-pc/cmdline_cat_test.mod new file mode 100644 index 00000000..e22586dd Binary files /dev/null and b/INSTALL/grub/i386-pc/cmdline_cat_test.mod differ diff --git a/INSTALL/grub/i386-pc/cmosdump.mod b/INSTALL/grub/i386-pc/cmosdump.mod new file mode 100644 index 00000000..23d4b7d8 Binary files /dev/null and b/INSTALL/grub/i386-pc/cmosdump.mod differ diff --git a/INSTALL/grub/i386-pc/cmostest.mod b/INSTALL/grub/i386-pc/cmostest.mod new file mode 100644 index 00000000..d94f1c1a Binary files /dev/null and b/INSTALL/grub/i386-pc/cmostest.mod differ diff --git a/INSTALL/grub/i386-pc/cmp.mod b/INSTALL/grub/i386-pc/cmp.mod new file mode 100644 index 00000000..d5155d7e Binary files /dev/null and b/INSTALL/grub/i386-pc/cmp.mod differ diff --git a/INSTALL/grub/i386-pc/cmp_test.mod b/INSTALL/grub/i386-pc/cmp_test.mod new file mode 100644 index 00000000..f9a14230 Binary files /dev/null and b/INSTALL/grub/i386-pc/cmp_test.mod differ diff --git a/INSTALL/grub/i386-pc/command.lst b/INSTALL/grub/i386-pc/command.lst new file mode 100644 index 00000000..774f3c5e --- /dev/null +++ b/INSTALL/grub/i386-pc/command.lst @@ -0,0 +1,201 @@ +*acpi: acpi +*all_functional_test: functional_test +*background_image: gfxterm_background +*cat: cat +*cpuid: cpuid +*crc: hashsum +*cryptomount: cryptodisk +*drivemap: drivemap +*echo: echo +*extract_syslinux_entries_configfile: syslinuxcfg +*extract_syslinux_entries_source: syslinuxcfg +*file: file +*functional_test: functional_test +*gettext: gettext +*halt: halt +*hashsum: hashsum +*hdparm: hdparm +*hello: hello +*help: help +*hexdump: hexdump +*inb: iorw +*inl: iorw +*inw: iorw +*keystatus: keystatus +*kfreebsd: bsd +*knetbsd: bsd +*kopenbsd: bsd +*list_env: loadenv +*load_env: loadenv +*loopback: loopback +*ls: ls +*lsacpi: lsacpi +*lspci: lspci +*md5sum: hashsum +*menuentry: normal +*pcidump: pcidump +*plan9: plan9 +*probe: probe +*rdmsr: rdmsr +*read_byte: memrw +*read_dword: memrw +*read_word: memrw +*regexp: regexp +*save_env: loadenv +*search: search +*sendkey: sendkey +*serial: serial +*setpci: setpci +*sha1sum: hashsum +*sha256sum: hashsum +*sha512sum: hashsum +*sleep: sleep +*submenu: normal +*syslinux_configfile: syslinuxcfg +*syslinux_source: syslinuxcfg +*terminfo: terminfo +*test_blockarg: test_blockarg +*testspeed: testspeed +*tr: tr +*trust: pgp +*verify_detached: pgp +*xnu_splash: xnu +*zfskey: zfscrypt +.: configfile +[: test +authenticate: normal +background_color: gfxterm_background +backtrace: backtrace +badram: mmap +blocklist: blocklist +boot: boot +break: normal +cat: minicmd +cbmemc: cbmemc +chainloader: chain +clear: normal +cmosclean: cmostest +cmosdump: cmosdump +cmosset: cmostest +cmostest: cmostest +cmp: cmp +configfile: configfile +continue: normal +coreboot_boottime: cbtime +cutmem: mmap +date: date +distrust: pgp +dump: minicmd +efiemu_loadcore: efiemu +efiemu_prepare: efiemu +efiemu_unload: efiemu +eval: eval +exit: minicmd +export: normal +extract_entries_configfile: configfile +extract_entries_source: configfile +extract_legacy_entries_configfile: legacycfg +extract_legacy_entries_source: legacycfg +false: true +freedos: freedos +gdbstub: gdb +gdbstub_break: gdb +gdbstub_stop: gdb +gptsync: gptsync +help: minicmd +hexdump_random: random +initrd16: linux16 +initrd: linux +keymap: keylayouts +kfreebsd_loadenv: bsd +kfreebsd_module: bsd +kfreebsd_module_elf: bsd +knetbsd_module: bsd +knetbsd_module_elf: bsd +kopenbsd_ramdisk: bsd +legacy_check_password: legacycfg +legacy_configfile: legacycfg +legacy_initrd: legacycfg +legacy_initrd_nounzip: legacycfg +legacy_kernel: legacycfg +legacy_password: legacycfg +legacy_source: legacycfg +linux16: linux16 +linux: linux +list_trusted: pgp +loadfont: font +lsapm: lsapm +lscoreboot: cbls +lsfonts: font +lsmmap: lsmmap +lsmod: minicmd +macppcbless: macbless +mactelbless: macbless +module2: multiboot2 +module: multiboot +multiboot2: multiboot2 +multiboot: multiboot +nativedisk: nativedisk +net_add_addr: net +net_add_dns: net +net_add_route: net +net_bootp: net +net_del_addr: net +net_del_dns: net +net_del_route: net +net_dhcp: net +net_get_dhcp_option: net +net_ipv6_autoconf: net +net_ls_addr: net +net_ls_cards: net +net_ls_dns: net +net_ls_routes: net +net_nslookup: net +normal: normal +normal_exit: normal +ntldr: ntldr +outb: iorw +outl: iorw +outw: iorw +parttool: parttool +password: password +password_pbkdf2: password_pbkdf2 +play: play +pxechainloader: pxechain +read: read +reboot: reboot +return: normal +rmmod: minicmd +search.file: search_fs_file +search.fs_label: search_label +search.fs_uuid: search_fs_uuid +setparams: normal +shift: normal +source: configfile +terminal_input: terminal +terminal_output: terminal +test: test +testload: testload +time: time +true: true +truecrypt: truecrypt +usb: usbtest +vbeinfo: videoinfo +vbetest: videotest +videoinfo: videoinfo +videotest: videotest +write_byte: memrw +write_dword: memrw +write_word: memrw +wrmsr: wrmsr +xnu_devprop_load: xnu +xnu_kernel64: xnu +xnu_kernel: xnu +xnu_kext: xnu +xnu_kextdir: xnu +xnu_mkext: xnu +xnu_ramdisk: xnu +xnu_resume: xnu +xnu_uuid: xnu_uuid +zfs-bootfs: zfsinfo +zfsinfo: zfsinfo diff --git a/INSTALL/grub/i386-pc/core.img b/INSTALL/grub/i386-pc/core.img index fa74b5c9..7232ad16 100644 Binary files a/INSTALL/grub/i386-pc/core.img and b/INSTALL/grub/i386-pc/core.img differ diff --git a/INSTALL/grub/i386-pc/cpio.mod b/INSTALL/grub/i386-pc/cpio.mod new file mode 100644 index 00000000..550b2af1 Binary files /dev/null and b/INSTALL/grub/i386-pc/cpio.mod differ diff --git a/INSTALL/grub/i386-pc/cpio_be.mod b/INSTALL/grub/i386-pc/cpio_be.mod new file mode 100644 index 00000000..42776b17 Binary files /dev/null and b/INSTALL/grub/i386-pc/cpio_be.mod differ diff --git a/INSTALL/grub/i386-pc/cpuid.mod b/INSTALL/grub/i386-pc/cpuid.mod new file mode 100644 index 00000000..cc4471aa Binary files /dev/null and b/INSTALL/grub/i386-pc/cpuid.mod differ diff --git a/INSTALL/grub/i386-pc/crc64.mod b/INSTALL/grub/i386-pc/crc64.mod new file mode 100644 index 00000000..441fc4a6 Binary files /dev/null and b/INSTALL/grub/i386-pc/crc64.mod differ diff --git a/INSTALL/grub/i386-pc/crypto.lst b/INSTALL/grub/i386-pc/crypto.lst new file mode 100644 index 00000000..77d9efc0 --- /dev/null +++ b/INSTALL/grub/i386-pc/crypto.lst @@ -0,0 +1,45 @@ +RIJNDAEL: gcry_rijndael +RIJNDAEL192: gcry_rijndael +RIJNDAEL256: gcry_rijndael +AES128: gcry_rijndael +AES-128: gcry_rijndael +AES-192: gcry_rijndael +AES-256: gcry_rijndael +ADLER32: adler32 +CRC64: crc64 +ARCFOUR: gcry_arcfour +BLOWFISH: gcry_blowfish +CAMELLIA128: gcry_camellia +CAMELLIA192: gcry_camellia +CAMELLIA256: gcry_camellia +CAST5: gcry_cast5 +CRC32: gcry_crc +CRC32RFC1510: gcry_crc +CRC24RFC2440: gcry_crc +DES: gcry_des +3DES: gcry_des +DSA: gcry_dsa +IDEA: gcry_idea +MD4: gcry_md4 +MD5: gcry_md5 +RFC2268_40: gcry_rfc2268 +AES: gcry_rijndael +AES192: gcry_rijndael +AES256: gcry_rijndael +RIPEMD160: gcry_rmd160 +RSA: gcry_rsa +SEED: gcry_seed +SERPENT128: gcry_serpent +SERPENT192: gcry_serpent +SERPENT256: gcry_serpent +SHA1: gcry_sha1 +SHA224: gcry_sha256 +SHA256: gcry_sha256 +SHA512: gcry_sha512 +SHA384: gcry_sha512 +TIGER192: gcry_tiger +TIGER: gcry_tiger +TIGER2: gcry_tiger +TWOFISH: gcry_twofish +TWOFISH128: gcry_twofish +WHIRLPOOL: gcry_whirlpool diff --git a/INSTALL/grub/i386-pc/crypto.mod b/INSTALL/grub/i386-pc/crypto.mod new file mode 100644 index 00000000..d9914aed Binary files /dev/null and b/INSTALL/grub/i386-pc/crypto.mod differ diff --git a/INSTALL/grub/i386-pc/cryptodisk.mod b/INSTALL/grub/i386-pc/cryptodisk.mod new file mode 100644 index 00000000..ee52348e Binary files /dev/null and b/INSTALL/grub/i386-pc/cryptodisk.mod differ diff --git a/INSTALL/grub/i386-pc/cs5536.mod b/INSTALL/grub/i386-pc/cs5536.mod new file mode 100644 index 00000000..c8fdce8e Binary files /dev/null and b/INSTALL/grub/i386-pc/cs5536.mod differ diff --git a/INSTALL/grub/i386-pc/ctz_test.mod b/INSTALL/grub/i386-pc/ctz_test.mod new file mode 100644 index 00000000..232ffa80 Binary files /dev/null and b/INSTALL/grub/i386-pc/ctz_test.mod differ diff --git a/INSTALL/grub/i386-pc/datehook.mod b/INSTALL/grub/i386-pc/datehook.mod new file mode 100644 index 00000000..a42ca57a Binary files /dev/null and b/INSTALL/grub/i386-pc/datehook.mod differ diff --git a/INSTALL/grub/i386-pc/datetime.mod b/INSTALL/grub/i386-pc/datetime.mod new file mode 100644 index 00000000..5de1ad49 Binary files /dev/null and b/INSTALL/grub/i386-pc/datetime.mod differ diff --git a/INSTALL/grub/i386-pc/diskfilter.mod b/INSTALL/grub/i386-pc/diskfilter.mod new file mode 100644 index 00000000..cf81580f Binary files /dev/null and b/INSTALL/grub/i386-pc/diskfilter.mod differ diff --git a/INSTALL/grub/i386-pc/div.mod b/INSTALL/grub/i386-pc/div.mod new file mode 100644 index 00000000..f9a5d9d4 Binary files /dev/null and b/INSTALL/grub/i386-pc/div.mod differ diff --git a/INSTALL/grub/i386-pc/div_test.mod b/INSTALL/grub/i386-pc/div_test.mod new file mode 100644 index 00000000..4ec3622a Binary files /dev/null and b/INSTALL/grub/i386-pc/div_test.mod differ diff --git a/INSTALL/grub/i386-pc/dm_nv.mod b/INSTALL/grub/i386-pc/dm_nv.mod new file mode 100644 index 00000000..8b48ad51 Binary files /dev/null and b/INSTALL/grub/i386-pc/dm_nv.mod differ diff --git a/INSTALL/grub/i386-pc/efiemu.mod b/INSTALL/grub/i386-pc/efiemu.mod new file mode 100644 index 00000000..88fd5f0a Binary files /dev/null and b/INSTALL/grub/i386-pc/efiemu.mod differ diff --git a/INSTALL/grub/i386-pc/ehci.mod b/INSTALL/grub/i386-pc/ehci.mod new file mode 100644 index 00000000..17429f59 Binary files /dev/null and b/INSTALL/grub/i386-pc/ehci.mod differ diff --git a/INSTALL/grub/i386-pc/eval.mod b/INSTALL/grub/i386-pc/eval.mod new file mode 100644 index 00000000..417bb915 Binary files /dev/null and b/INSTALL/grub/i386-pc/eval.mod differ diff --git a/INSTALL/grub/i386-pc/exfctest.mod b/INSTALL/grub/i386-pc/exfctest.mod new file mode 100644 index 00000000..9cfe4923 Binary files /dev/null and b/INSTALL/grub/i386-pc/exfctest.mod differ diff --git a/INSTALL/grub/i386-pc/f2fs.mod b/INSTALL/grub/i386-pc/f2fs.mod new file mode 100644 index 00000000..f0fe6fd1 Binary files /dev/null and b/INSTALL/grub/i386-pc/f2fs.mod differ diff --git a/INSTALL/grub/i386-pc/fdt.lst b/INSTALL/grub/i386-pc/fdt.lst new file mode 100644 index 00000000..e69de29b diff --git a/INSTALL/grub/i386-pc/freedos.mod b/INSTALL/grub/i386-pc/freedos.mod new file mode 100644 index 00000000..08cabd0e Binary files /dev/null and b/INSTALL/grub/i386-pc/freedos.mod differ diff --git a/INSTALL/grub/i386-pc/fs.lst b/INSTALL/grub/i386-pc/fs.lst new file mode 100644 index 00000000..0acd240b --- /dev/null +++ b/INSTALL/grub/i386-pc/fs.lst @@ -0,0 +1,37 @@ +affs +afs +bfs +btrfs +cbfs +cpio +cpio_be +exfat +ext2 +f2fs +fat +hfs +hfsplus +iso9660 +jfs +minix +minix2 +minix2_be +minix3 +minix3_be +minix_be +newc +nilfs2 +ntfs +odc +procfs +reiserfs +romfs +sfs +squash4 +tar +udf +ufs1 +ufs1_be +ufs2 +xfs +zfs diff --git a/INSTALL/grub/i386-pc/fshelp.mod b/INSTALL/grub/i386-pc/fshelp.mod new file mode 100644 index 00000000..e986d45a Binary files /dev/null and b/INSTALL/grub/i386-pc/fshelp.mod differ diff --git a/INSTALL/grub/i386-pc/functional_test.mod b/INSTALL/grub/i386-pc/functional_test.mod new file mode 100644 index 00000000..2b498463 Binary files /dev/null and b/INSTALL/grub/i386-pc/functional_test.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_arcfour.mod b/INSTALL/grub/i386-pc/gcry_arcfour.mod new file mode 100644 index 00000000..c49de7a0 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_arcfour.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_blowfish.mod b/INSTALL/grub/i386-pc/gcry_blowfish.mod new file mode 100644 index 00000000..83285b38 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_blowfish.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_camellia.mod b/INSTALL/grub/i386-pc/gcry_camellia.mod new file mode 100644 index 00000000..337637e6 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_camellia.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_cast5.mod b/INSTALL/grub/i386-pc/gcry_cast5.mod new file mode 100644 index 00000000..8a742756 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_cast5.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_crc.mod b/INSTALL/grub/i386-pc/gcry_crc.mod new file mode 100644 index 00000000..d3f30c44 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_crc.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_des.mod b/INSTALL/grub/i386-pc/gcry_des.mod new file mode 100644 index 00000000..2b1f3dee Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_des.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_dsa.mod b/INSTALL/grub/i386-pc/gcry_dsa.mod new file mode 100644 index 00000000..ab382c86 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_dsa.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_idea.mod b/INSTALL/grub/i386-pc/gcry_idea.mod new file mode 100644 index 00000000..b939c0dd Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_idea.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_md4.mod b/INSTALL/grub/i386-pc/gcry_md4.mod new file mode 100644 index 00000000..16f78faf Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_md4.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_rfc2268.mod b/INSTALL/grub/i386-pc/gcry_rfc2268.mod new file mode 100644 index 00000000..db1c2b79 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_rfc2268.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_rijndael.mod b/INSTALL/grub/i386-pc/gcry_rijndael.mod new file mode 100644 index 00000000..6a93d1b3 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_rijndael.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_rmd160.mod b/INSTALL/grub/i386-pc/gcry_rmd160.mod new file mode 100644 index 00000000..24b37c5c Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_rmd160.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_rsa.mod b/INSTALL/grub/i386-pc/gcry_rsa.mod new file mode 100644 index 00000000..11dc6964 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_rsa.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_seed.mod b/INSTALL/grub/i386-pc/gcry_seed.mod new file mode 100644 index 00000000..157c74cc Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_seed.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_serpent.mod b/INSTALL/grub/i386-pc/gcry_serpent.mod new file mode 100644 index 00000000..8ed63641 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_serpent.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_sha1.mod b/INSTALL/grub/i386-pc/gcry_sha1.mod new file mode 100644 index 00000000..855afd66 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_sha1.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_sha256.mod b/INSTALL/grub/i386-pc/gcry_sha256.mod new file mode 100644 index 00000000..fc269cc4 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_sha256.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_sha512.mod b/INSTALL/grub/i386-pc/gcry_sha512.mod new file mode 100644 index 00000000..03b48b50 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_sha512.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_tiger.mod b/INSTALL/grub/i386-pc/gcry_tiger.mod new file mode 100644 index 00000000..a91e3152 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_tiger.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_twofish.mod b/INSTALL/grub/i386-pc/gcry_twofish.mod new file mode 100644 index 00000000..8b8efaef Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_twofish.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_whirlpool.mod b/INSTALL/grub/i386-pc/gcry_whirlpool.mod new file mode 100644 index 00000000..7918540b Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_whirlpool.mod differ diff --git a/INSTALL/grub/i386-pc/gdb.mod b/INSTALL/grub/i386-pc/gdb.mod new file mode 100644 index 00000000..fa88b7ce Binary files /dev/null and b/INSTALL/grub/i386-pc/gdb.mod differ diff --git a/INSTALL/grub/i386-pc/geli.mod b/INSTALL/grub/i386-pc/geli.mod new file mode 100644 index 00000000..3a59c1ae Binary files /dev/null and b/INSTALL/grub/i386-pc/geli.mod differ diff --git a/INSTALL/grub/i386-pc/gfxterm_menu.mod b/INSTALL/grub/i386-pc/gfxterm_menu.mod new file mode 100644 index 00000000..a6aba54a Binary files /dev/null and b/INSTALL/grub/i386-pc/gfxterm_menu.mod differ diff --git a/INSTALL/grub/i386-pc/gptsync.mod b/INSTALL/grub/i386-pc/gptsync.mod new file mode 100644 index 00000000..6c75de0d Binary files /dev/null and b/INSTALL/grub/i386-pc/gptsync.mod differ diff --git a/INSTALL/grub/i386-pc/hdparm.mod b/INSTALL/grub/i386-pc/hdparm.mod new file mode 100644 index 00000000..7cecce6b Binary files /dev/null and b/INSTALL/grub/i386-pc/hdparm.mod differ diff --git a/INSTALL/grub/i386-pc/hello.mod b/INSTALL/grub/i386-pc/hello.mod new file mode 100644 index 00000000..14fd0951 Binary files /dev/null and b/INSTALL/grub/i386-pc/hello.mod differ diff --git a/INSTALL/grub/i386-pc/hexdump.mod b/INSTALL/grub/i386-pc/hexdump.mod new file mode 100644 index 00000000..7ccea176 Binary files /dev/null and b/INSTALL/grub/i386-pc/hexdump.mod differ diff --git a/INSTALL/grub/i386-pc/hfs.mod b/INSTALL/grub/i386-pc/hfs.mod new file mode 100644 index 00000000..eb1134c6 Binary files /dev/null and b/INSTALL/grub/i386-pc/hfs.mod differ diff --git a/INSTALL/grub/i386-pc/hfsplus.mod b/INSTALL/grub/i386-pc/hfsplus.mod new file mode 100644 index 00000000..f07eedb4 Binary files /dev/null and b/INSTALL/grub/i386-pc/hfsplus.mod differ diff --git a/INSTALL/grub/i386-pc/hfspluscomp.mod b/INSTALL/grub/i386-pc/hfspluscomp.mod new file mode 100644 index 00000000..b2b40870 Binary files /dev/null and b/INSTALL/grub/i386-pc/hfspluscomp.mod differ diff --git a/INSTALL/grub/i386-pc/iorw.mod b/INSTALL/grub/i386-pc/iorw.mod new file mode 100644 index 00000000..8b636058 Binary files /dev/null and b/INSTALL/grub/i386-pc/iorw.mod differ diff --git a/INSTALL/grub/i386-pc/jfs.mod b/INSTALL/grub/i386-pc/jfs.mod new file mode 100644 index 00000000..1dbc2684 Binary files /dev/null and b/INSTALL/grub/i386-pc/jfs.mod differ diff --git a/INSTALL/grub/i386-pc/keylayouts.mod b/INSTALL/grub/i386-pc/keylayouts.mod new file mode 100644 index 00000000..50d81834 Binary files /dev/null and b/INSTALL/grub/i386-pc/keylayouts.mod differ diff --git a/INSTALL/grub/i386-pc/keystatus.mod b/INSTALL/grub/i386-pc/keystatus.mod new file mode 100644 index 00000000..8b5088a3 Binary files /dev/null and b/INSTALL/grub/i386-pc/keystatus.mod differ diff --git a/INSTALL/grub/i386-pc/ldm.mod b/INSTALL/grub/i386-pc/ldm.mod new file mode 100644 index 00000000..f2993156 Binary files /dev/null and b/INSTALL/grub/i386-pc/ldm.mod differ diff --git a/INSTALL/grub/i386-pc/legacy_password_test.mod b/INSTALL/grub/i386-pc/legacy_password_test.mod new file mode 100644 index 00000000..b5c58fa1 Binary files /dev/null and b/INSTALL/grub/i386-pc/legacy_password_test.mod differ diff --git a/INSTALL/grub/i386-pc/legacycfg.mod b/INSTALL/grub/i386-pc/legacycfg.mod new file mode 100644 index 00000000..850d9851 Binary files /dev/null and b/INSTALL/grub/i386-pc/legacycfg.mod differ diff --git a/INSTALL/grub/i386-pc/loadenv.mod b/INSTALL/grub/i386-pc/loadenv.mod new file mode 100644 index 00000000..683cd904 Binary files /dev/null and b/INSTALL/grub/i386-pc/loadenv.mod differ diff --git a/INSTALL/grub/i386-pc/lsacpi.mod b/INSTALL/grub/i386-pc/lsacpi.mod new file mode 100644 index 00000000..7e94483f Binary files /dev/null and b/INSTALL/grub/i386-pc/lsacpi.mod differ diff --git a/INSTALL/grub/i386-pc/lsapm.mod b/INSTALL/grub/i386-pc/lsapm.mod new file mode 100644 index 00000000..5a053d70 Binary files /dev/null and b/INSTALL/grub/i386-pc/lsapm.mod differ diff --git a/INSTALL/grub/i386-pc/lsmmap.mod b/INSTALL/grub/i386-pc/lsmmap.mod new file mode 100644 index 00000000..683ecfe8 Binary files /dev/null and b/INSTALL/grub/i386-pc/lsmmap.mod differ diff --git a/INSTALL/grub/i386-pc/luks.mod b/INSTALL/grub/i386-pc/luks.mod new file mode 100644 index 00000000..9c18afa6 Binary files /dev/null and b/INSTALL/grub/i386-pc/luks.mod differ diff --git a/INSTALL/grub/i386-pc/lvm.mod b/INSTALL/grub/i386-pc/lvm.mod new file mode 100644 index 00000000..10c1267b Binary files /dev/null and b/INSTALL/grub/i386-pc/lvm.mod differ diff --git a/INSTALL/grub/i386-pc/macbless.mod b/INSTALL/grub/i386-pc/macbless.mod new file mode 100644 index 00000000..c7ed444b Binary files /dev/null and b/INSTALL/grub/i386-pc/macbless.mod differ diff --git a/INSTALL/grub/i386-pc/mda_text.mod b/INSTALL/grub/i386-pc/mda_text.mod new file mode 100644 index 00000000..8f343cc6 Binary files /dev/null and b/INSTALL/grub/i386-pc/mda_text.mod differ diff --git a/INSTALL/grub/i386-pc/mdraid09.mod b/INSTALL/grub/i386-pc/mdraid09.mod new file mode 100644 index 00000000..ba29a59c Binary files /dev/null and b/INSTALL/grub/i386-pc/mdraid09.mod differ diff --git a/INSTALL/grub/i386-pc/mdraid09_be.mod b/INSTALL/grub/i386-pc/mdraid09_be.mod new file mode 100644 index 00000000..f53e40f6 Binary files /dev/null and b/INSTALL/grub/i386-pc/mdraid09_be.mod differ diff --git a/INSTALL/grub/i386-pc/mdraid1x.mod b/INSTALL/grub/i386-pc/mdraid1x.mod new file mode 100644 index 00000000..c00a9af0 Binary files /dev/null and b/INSTALL/grub/i386-pc/mdraid1x.mod differ diff --git a/INSTALL/grub/i386-pc/memdisk.mod b/INSTALL/grub/i386-pc/memdisk.mod new file mode 100644 index 00000000..83aaf1b9 Binary files /dev/null and b/INSTALL/grub/i386-pc/memdisk.mod differ diff --git a/INSTALL/grub/i386-pc/memrw.mod b/INSTALL/grub/i386-pc/memrw.mod new file mode 100644 index 00000000..db9ae48d Binary files /dev/null and b/INSTALL/grub/i386-pc/memrw.mod differ diff --git a/INSTALL/grub/i386-pc/minix.mod b/INSTALL/grub/i386-pc/minix.mod new file mode 100644 index 00000000..87477bff Binary files /dev/null and b/INSTALL/grub/i386-pc/minix.mod differ diff --git a/INSTALL/grub/i386-pc/minix2.mod b/INSTALL/grub/i386-pc/minix2.mod new file mode 100644 index 00000000..01d2f609 Binary files /dev/null and b/INSTALL/grub/i386-pc/minix2.mod differ diff --git a/INSTALL/grub/i386-pc/minix2_be.mod b/INSTALL/grub/i386-pc/minix2_be.mod new file mode 100644 index 00000000..260e1e7b Binary files /dev/null and b/INSTALL/grub/i386-pc/minix2_be.mod differ diff --git a/INSTALL/grub/i386-pc/minix3.mod b/INSTALL/grub/i386-pc/minix3.mod new file mode 100644 index 00000000..256f5d71 Binary files /dev/null and b/INSTALL/grub/i386-pc/minix3.mod differ diff --git a/INSTALL/grub/i386-pc/minix3_be.mod b/INSTALL/grub/i386-pc/minix3_be.mod new file mode 100644 index 00000000..7212cb60 Binary files /dev/null and b/INSTALL/grub/i386-pc/minix3_be.mod differ diff --git a/INSTALL/grub/i386-pc/minix_be.mod b/INSTALL/grub/i386-pc/minix_be.mod new file mode 100644 index 00000000..cf7f0462 Binary files /dev/null and b/INSTALL/grub/i386-pc/minix_be.mod differ diff --git a/INSTALL/grub/i386-pc/mmap.mod b/INSTALL/grub/i386-pc/mmap.mod new file mode 100644 index 00000000..f8b05f30 Binary files /dev/null and b/INSTALL/grub/i386-pc/mmap.mod differ diff --git a/INSTALL/grub/i386-pc/moddep.lst b/INSTALL/grub/i386-pc/moddep.lst new file mode 100644 index 00000000..5c5d59f4 --- /dev/null +++ b/INSTALL/grub/i386-pc/moddep.lst @@ -0,0 +1,271 @@ +videotest: font video gfxmenu +odc: archelp +loopback: extcmd +macho: +gcry_des: crypto +memrw: extcmd +terminfo: extcmd +f2fs: fshelp +part_gpt: +romfs: fshelp +read: +aout: +gcry_arcfour: crypto +vga_text: +tftp: net priority_queue +newc: archelp +minix2_be: +elf: +videotest_checksum: font functional_test video_fb +password_pbkdf2: crypto gcry_sha512 pbkdf2 normal +gcry_seed: crypto +pcidump: extcmd pci +bsd: elf serial crypto gcry_md5 verifiers extcmd vbe aout video boot cpuid relocator mmap +sfs: fshelp +reiserfs: fshelp +part_sunpc: +zstd: +gfxmenu: video_colors trig bitmap_scale gfxterm font normal bitmap video +backtrace: +jfs: +help: extcmd normal +configfile: normal +cbls: cbtable +gfxterm_menu: font functional_test procfs normal video_fb +gcry_idea: crypto +tr: extcmd +shift_test: functional_test +ohci: cs5536 usb boot pci +afs: fshelp +spkmodem: terminfo +usb_keyboard: keylayouts usb +xzio: crypto +syslinuxcfg: extcmd normal +search_fs_file: +wrmsr: +vga: video video_fb +usbms: scsi usb +test_blockarg: extcmd normal +true: +affs: fshelp +iso9660: fshelp +exfat: fshelp +setjmp_test: setjmp functional_test +gfxterm: font video +disk: +xfs: fshelp +testspeed: extcmd normal +cpio_be: archelp +functional_test: btrfs extcmd video video_fb +pxechain: pxe video boot relocator +bswap_test: functional_test +sleep: extcmd normal +memdisk: +gcry_rijndael: crypto +mdraid09_be: diskfilter +gettext: +gcry_sha1: crypto +hfspluscomp: gzio hfsplus +cmp: +random: hexdump acpi +offsetio: +file: elf macho extcmd offsetio +usbserial_usbdebug: serial usb usbserial_common +video_colors: +morse: +hashsum: crypto extcmd normal +usb: pci +halt: extcmd acpi +gdb: serial backtrace +gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap +search_fs_uuid: +gcry_dsa: pgp mpi +keystatus: extcmd +linux: verifiers normal vbe video boot relocator mmap +geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256 +cmdline_cat_test: font functional_test normal procfs video_fb +rdmsr: extcmd +part_sun: +cbtable: +plan9: verifiers extcmd boot video relocator +sendkey: extcmd boot +pbkdf2_test: functional_test pbkdf2 gcry_sha1 +video_bochs: pci video video_fb +verifiers: +bufio: +usbserial_ftdi: serial usb usbserial_common +legacy_password_test: functional_test legacycfg +cpuid: extcmd +hdparm: extcmd hexdump +bfs: fshelp +gcry_blowfish: crypto +test: +nilfs2: fshelp +gcry_rsa: pgp mpi +cryptodisk: crypto extcmd procfs +nativedisk: +minicmd: +signature_test: functional_test procfs +ata: scsi +udf: fshelp +gzio: gcry_crc +xnu_uuid: gcry_md5 +uhci: usb pci +pata: ata pci +mul_test: functional_test +adler32: crypto +terminal: +div: +ehci: cs5536 usb boot pci +crypto: +part_bsd: part_msdos +cs5536: pci +biosdisk: +ventoy: ext2 fshelp font crypto exfat udf extcmd normal relocator gcry_sha1 iso9660 +lsapm: +gcry_sha512: crypto +password: crypto normal +efiemu: gcry_crc crypto cpuid acpi +fshelp: +sleep_test: functional_test datetime +iorw: extcmd +xnu: macho bitmap_scale random verifiers extcmd video bitmap boot relocator efiemu mmap +mmap: boot +exfctest: functional_test +zfsinfo: zfs +ldm: part_gpt diskfilter part_msdos +cmostest: +eval: normal +part_dvh: +blocklist: +ext2: fshelp +net: priority_queue bufio datetime boot +drivemap: extcmd boot mmap +part_acorn: +videoinfo: video +btrfs: zstd lzopio raid6rec gzio +lsmmap: +strtoull_test: functional_test +bitmap: +vbe: video video_fb +ntfs: fshelp +multiboot: net linux vbe video boot relocator mmap lsapm +gcry_crc: crypto +png: bufio bitmap +jpeg: bufio bitmap +macbless: disk +div_test: functional_test div +regexp: extcmd normal +parttool: normal +usbserial_pl2303: serial usb usbserial_common +cpio: archelp +gcry_rmd160: crypto +fat: fshelp +ufs1_be: +truecrypt: video boot relocator gzio mmap +archelp: +ntldr: chain boot video relocator +http: net +zfs: gzio +raid6rec: diskfilter +minix2: +mda_text: +lsacpi: extcmd acpi +datehook: datetime normal +loadenv: disk extcmd +bitmap_scale: bitmap +probe: extcmd +minix3: +tar: archelp +hfs: fshelp +procfs: archelp +boot: +keylayouts: +progress: normal +kernel: +usbtest: usb +relocator: mmap +acpi: extcmd mmap +tga: bufio bitmap +reboot: relocator +serial: extcmd terminfo +zfscrypt: crypto pbkdf2 extcmd zfs gcry_sha1 gcry_rijndael +dm_nv: diskfilter +cmp_test: functional_test +luks: cryptodisk crypto pbkdf2 +font: bufio video +raid5rec: diskfilter +crc64: crypto +datetime: +ctz_test: functional_test +video: +pci: +cbmemc: cbtable normal terminfo +cmosdump: +hfsplus: fshelp +gcry_cast5: crypto +extcmd: +squash4: fshelp lzopio xzio gzio +part_plan: +minix_be: +gcry_whirlpool: crypto +pxe: net boot +gcry_tiger: crypto +search: search_fs_uuid search_fs_file extcmd search_label +lspci: extcmd pci +cbtime: cbtable +video_fb: +minix3_be: +trig: +msdospart: disk parttool +priority_queue: +gcry_twofish: crypto +part_dfly: +xnu_uuid_test: functional_test +diskfilter: +testload: +part_apple: +hexdump: extcmd +date: datetime normal +pbkdf2: crypto +gcry_sha256: crypto +ls: extcmd normal +usbserial_common: serial usb +ntfscomp: ntfs +lzopio: crypto +video_cirrus: pci video video_fb +hello: extcmd +scsi: +linux16: linux boot video relocator mmap +cat: extcmd +ahci: ata boot pci +pgp: crypto verifiers extcmd mpi gcry_sha1 +normal: terminal crypto verifiers bufio extcmd boot gettext +ufs1: +mdraid09: diskfilter +lvm: diskfilter +cbfs: archelp +chain: video boot relocator +ufs2: +time: +setpci: extcmd pci +gptsync: disk +freedos: chain boot video relocator +search_label: +setjmp: +multiboot2: linux net vbe boot video relocator mmap lsapm acpi +gcry_rfc2268: crypto +mdraid1x: diskfilter +mpi: crypto +legacycfg: linux crypto password gcry_md5 normal +play: +part_amiga: +minix: +echo: extcmd +gcry_serpent: crypto +gcry_md4: crypto +gcry_md5: crypto +part_msdos: +gcry_camellia: crypto +at_keyboard: keylayouts boot +all_video: vbe vga video_bochs video_cirrus diff --git a/INSTALL/grub/i386-pc/morse.mod b/INSTALL/grub/i386-pc/morse.mod new file mode 100644 index 00000000..b482e26b Binary files /dev/null and b/INSTALL/grub/i386-pc/morse.mod differ diff --git a/INSTALL/grub/i386-pc/mpi.mod b/INSTALL/grub/i386-pc/mpi.mod new file mode 100644 index 00000000..0f9ec718 Binary files /dev/null and b/INSTALL/grub/i386-pc/mpi.mod differ diff --git a/INSTALL/grub/i386-pc/msdospart.mod b/INSTALL/grub/i386-pc/msdospart.mod new file mode 100644 index 00000000..3c9d393c Binary files /dev/null and b/INSTALL/grub/i386-pc/msdospart.mod differ diff --git a/INSTALL/grub/i386-pc/mul_test.mod b/INSTALL/grub/i386-pc/mul_test.mod new file mode 100644 index 00000000..d86701a9 Binary files /dev/null and b/INSTALL/grub/i386-pc/mul_test.mod differ diff --git a/INSTALL/grub/i386-pc/multiboot.mod b/INSTALL/grub/i386-pc/multiboot.mod new file mode 100644 index 00000000..0547a54d Binary files /dev/null and b/INSTALL/grub/i386-pc/multiboot.mod differ diff --git a/INSTALL/grub/i386-pc/multiboot2.mod b/INSTALL/grub/i386-pc/multiboot2.mod new file mode 100644 index 00000000..a4879c75 Binary files /dev/null and b/INSTALL/grub/i386-pc/multiboot2.mod differ diff --git a/INSTALL/grub/i386-pc/nativedisk.mod b/INSTALL/grub/i386-pc/nativedisk.mod new file mode 100644 index 00000000..df1a07df Binary files /dev/null and b/INSTALL/grub/i386-pc/nativedisk.mod differ diff --git a/INSTALL/grub/i386-pc/net.mod b/INSTALL/grub/i386-pc/net.mod new file mode 100644 index 00000000..33752703 Binary files /dev/null and b/INSTALL/grub/i386-pc/net.mod differ diff --git a/INSTALL/grub/i386-pc/newc.mod b/INSTALL/grub/i386-pc/newc.mod new file mode 100644 index 00000000..a693778f Binary files /dev/null and b/INSTALL/grub/i386-pc/newc.mod differ diff --git a/INSTALL/grub/i386-pc/nilfs2.mod b/INSTALL/grub/i386-pc/nilfs2.mod new file mode 100644 index 00000000..3d2b1387 Binary files /dev/null and b/INSTALL/grub/i386-pc/nilfs2.mod differ diff --git a/INSTALL/grub/i386-pc/ntfscomp.mod b/INSTALL/grub/i386-pc/ntfscomp.mod new file mode 100644 index 00000000..5d0cbc7c Binary files /dev/null and b/INSTALL/grub/i386-pc/ntfscomp.mod differ diff --git a/INSTALL/grub/i386-pc/odc.mod b/INSTALL/grub/i386-pc/odc.mod new file mode 100644 index 00000000..bf6ef93f Binary files /dev/null and b/INSTALL/grub/i386-pc/odc.mod differ diff --git a/INSTALL/grub/i386-pc/ohci.mod b/INSTALL/grub/i386-pc/ohci.mod new file mode 100644 index 00000000..52060546 Binary files /dev/null and b/INSTALL/grub/i386-pc/ohci.mod differ diff --git a/INSTALL/grub/i386-pc/part_acorn.mod b/INSTALL/grub/i386-pc/part_acorn.mod new file mode 100644 index 00000000..3fe82b0c Binary files /dev/null and b/INSTALL/grub/i386-pc/part_acorn.mod differ diff --git a/INSTALL/grub/i386-pc/part_amiga.mod b/INSTALL/grub/i386-pc/part_amiga.mod new file mode 100644 index 00000000..a8411865 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_amiga.mod differ diff --git a/INSTALL/grub/i386-pc/part_apple.mod b/INSTALL/grub/i386-pc/part_apple.mod new file mode 100644 index 00000000..a30a0a09 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_apple.mod differ diff --git a/INSTALL/grub/i386-pc/part_bsd.mod b/INSTALL/grub/i386-pc/part_bsd.mod new file mode 100644 index 00000000..9c660b8f Binary files /dev/null and b/INSTALL/grub/i386-pc/part_bsd.mod differ diff --git a/INSTALL/grub/i386-pc/part_dfly.mod b/INSTALL/grub/i386-pc/part_dfly.mod new file mode 100644 index 00000000..d59ec333 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_dfly.mod differ diff --git a/INSTALL/grub/i386-pc/part_dvh.mod b/INSTALL/grub/i386-pc/part_dvh.mod new file mode 100644 index 00000000..21b6fec9 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_dvh.mod differ diff --git a/INSTALL/grub/i386-pc/part_plan.mod b/INSTALL/grub/i386-pc/part_plan.mod new file mode 100644 index 00000000..d074510b Binary files /dev/null and b/INSTALL/grub/i386-pc/part_plan.mod differ diff --git a/INSTALL/grub/i386-pc/part_sun.mod b/INSTALL/grub/i386-pc/part_sun.mod new file mode 100644 index 00000000..81edb5e0 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_sun.mod differ diff --git a/INSTALL/grub/i386-pc/part_sunpc.mod b/INSTALL/grub/i386-pc/part_sunpc.mod new file mode 100644 index 00000000..5c649b65 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_sunpc.mod differ diff --git a/INSTALL/grub/i386-pc/partmap.lst b/INSTALL/grub/i386-pc/partmap.lst new file mode 100644 index 00000000..761233aa --- /dev/null +++ b/INSTALL/grub/i386-pc/partmap.lst @@ -0,0 +1,11 @@ +part_acorn +part_amiga +part_apple +part_bsd +part_dfly +part_dvh +part_gpt +part_msdos +part_plan +part_sun +part_sunpc diff --git a/INSTALL/grub/i386-pc/parttool.lst b/INSTALL/grub/i386-pc/parttool.lst new file mode 100644 index 00000000..68b4b5c4 --- /dev/null +++ b/INSTALL/grub/i386-pc/parttool.lst @@ -0,0 +1 @@ +msdos: msdospart diff --git a/INSTALL/grub/i386-pc/parttool.mod b/INSTALL/grub/i386-pc/parttool.mod new file mode 100644 index 00000000..44ea3933 Binary files /dev/null and b/INSTALL/grub/i386-pc/parttool.mod differ diff --git a/INSTALL/grub/i386-pc/password.mod b/INSTALL/grub/i386-pc/password.mod new file mode 100644 index 00000000..783c3293 Binary files /dev/null and b/INSTALL/grub/i386-pc/password.mod differ diff --git a/INSTALL/grub/i386-pc/pata.mod b/INSTALL/grub/i386-pc/pata.mod new file mode 100644 index 00000000..0f8a55e0 Binary files /dev/null and b/INSTALL/grub/i386-pc/pata.mod differ diff --git a/INSTALL/grub/i386-pc/pbkdf2.mod b/INSTALL/grub/i386-pc/pbkdf2.mod new file mode 100644 index 00000000..84f05eaf Binary files /dev/null and b/INSTALL/grub/i386-pc/pbkdf2.mod differ diff --git a/INSTALL/grub/i386-pc/pbkdf2_test.mod b/INSTALL/grub/i386-pc/pbkdf2_test.mod new file mode 100644 index 00000000..a204632c Binary files /dev/null and b/INSTALL/grub/i386-pc/pbkdf2_test.mod differ diff --git a/INSTALL/grub/i386-pc/pcidump.mod b/INSTALL/grub/i386-pc/pcidump.mod new file mode 100644 index 00000000..66c16493 Binary files /dev/null and b/INSTALL/grub/i386-pc/pcidump.mod differ diff --git a/INSTALL/grub/i386-pc/pgp.mod b/INSTALL/grub/i386-pc/pgp.mod new file mode 100644 index 00000000..3270fff7 Binary files /dev/null and b/INSTALL/grub/i386-pc/pgp.mod differ diff --git a/INSTALL/grub/i386-pc/plan9.mod b/INSTALL/grub/i386-pc/plan9.mod new file mode 100644 index 00000000..4845df34 Binary files /dev/null and b/INSTALL/grub/i386-pc/plan9.mod differ diff --git a/INSTALL/grub/i386-pc/play.mod b/INSTALL/grub/i386-pc/play.mod new file mode 100644 index 00000000..9317d39f Binary files /dev/null and b/INSTALL/grub/i386-pc/play.mod differ diff --git a/INSTALL/grub/i386-pc/priority_queue.mod b/INSTALL/grub/i386-pc/priority_queue.mod new file mode 100644 index 00000000..4a1e167c Binary files /dev/null and b/INSTALL/grub/i386-pc/priority_queue.mod differ diff --git a/INSTALL/grub/i386-pc/probe.mod b/INSTALL/grub/i386-pc/probe.mod new file mode 100644 index 00000000..f880f85c Binary files /dev/null and b/INSTALL/grub/i386-pc/probe.mod differ diff --git a/INSTALL/grub/i386-pc/procfs.mod b/INSTALL/grub/i386-pc/procfs.mod new file mode 100644 index 00000000..a0e20ec4 Binary files /dev/null and b/INSTALL/grub/i386-pc/procfs.mod differ diff --git a/INSTALL/grub/i386-pc/progress.mod b/INSTALL/grub/i386-pc/progress.mod new file mode 100644 index 00000000..67dd96e8 Binary files /dev/null and b/INSTALL/grub/i386-pc/progress.mod differ diff --git a/INSTALL/grub/i386-pc/pxe.mod b/INSTALL/grub/i386-pc/pxe.mod new file mode 100644 index 00000000..1795ffda Binary files /dev/null and b/INSTALL/grub/i386-pc/pxe.mod differ diff --git a/INSTALL/grub/i386-pc/pxechain.mod b/INSTALL/grub/i386-pc/pxechain.mod new file mode 100644 index 00000000..2a1bc6af Binary files /dev/null and b/INSTALL/grub/i386-pc/pxechain.mod differ diff --git a/INSTALL/grub/i386-pc/raid5rec.mod b/INSTALL/grub/i386-pc/raid5rec.mod new file mode 100644 index 00000000..c31877f0 Binary files /dev/null and b/INSTALL/grub/i386-pc/raid5rec.mod differ diff --git a/INSTALL/grub/i386-pc/raid6rec.mod b/INSTALL/grub/i386-pc/raid6rec.mod new file mode 100644 index 00000000..f16634f6 Binary files /dev/null and b/INSTALL/grub/i386-pc/raid6rec.mod differ diff --git a/INSTALL/grub/i386-pc/random.mod b/INSTALL/grub/i386-pc/random.mod new file mode 100644 index 00000000..e15beb77 Binary files /dev/null and b/INSTALL/grub/i386-pc/random.mod differ diff --git a/INSTALL/grub/i386-pc/rdmsr.mod b/INSTALL/grub/i386-pc/rdmsr.mod new file mode 100644 index 00000000..02db1169 Binary files /dev/null and b/INSTALL/grub/i386-pc/rdmsr.mod differ diff --git a/INSTALL/grub/i386-pc/reiserfs.mod b/INSTALL/grub/i386-pc/reiserfs.mod new file mode 100644 index 00000000..c51d8f63 Binary files /dev/null and b/INSTALL/grub/i386-pc/reiserfs.mod differ diff --git a/INSTALL/grub/i386-pc/relocator.mod b/INSTALL/grub/i386-pc/relocator.mod new file mode 100644 index 00000000..aadaeaef Binary files /dev/null and b/INSTALL/grub/i386-pc/relocator.mod differ diff --git a/INSTALL/grub/i386-pc/romfs.mod b/INSTALL/grub/i386-pc/romfs.mod new file mode 100644 index 00000000..d420e236 Binary files /dev/null and b/INSTALL/grub/i386-pc/romfs.mod differ diff --git a/INSTALL/grub/i386-pc/scsi.mod b/INSTALL/grub/i386-pc/scsi.mod new file mode 100644 index 00000000..e764bcd9 Binary files /dev/null and b/INSTALL/grub/i386-pc/scsi.mod differ diff --git a/INSTALL/grub/i386-pc/search_fs_file.mod b/INSTALL/grub/i386-pc/search_fs_file.mod new file mode 100644 index 00000000..2ec78500 Binary files /dev/null and b/INSTALL/grub/i386-pc/search_fs_file.mod differ diff --git a/INSTALL/grub/i386-pc/search_fs_uuid.mod b/INSTALL/grub/i386-pc/search_fs_uuid.mod new file mode 100644 index 00000000..218adc71 Binary files /dev/null and b/INSTALL/grub/i386-pc/search_fs_uuid.mod differ diff --git a/INSTALL/grub/i386-pc/search_label.mod b/INSTALL/grub/i386-pc/search_label.mod new file mode 100644 index 00000000..71f941a2 Binary files /dev/null and b/INSTALL/grub/i386-pc/search_label.mod differ diff --git a/INSTALL/grub/i386-pc/sendkey.mod b/INSTALL/grub/i386-pc/sendkey.mod new file mode 100644 index 00000000..d8605d60 Binary files /dev/null and b/INSTALL/grub/i386-pc/sendkey.mod differ diff --git a/INSTALL/grub/i386-pc/serial.mod b/INSTALL/grub/i386-pc/serial.mod new file mode 100644 index 00000000..521e28ef Binary files /dev/null and b/INSTALL/grub/i386-pc/serial.mod differ diff --git a/INSTALL/grub/i386-pc/setjmp.mod b/INSTALL/grub/i386-pc/setjmp.mod new file mode 100644 index 00000000..2d35023b Binary files /dev/null and b/INSTALL/grub/i386-pc/setjmp.mod differ diff --git a/INSTALL/grub/i386-pc/setjmp_test.mod b/INSTALL/grub/i386-pc/setjmp_test.mod new file mode 100644 index 00000000..b337f7be Binary files /dev/null and b/INSTALL/grub/i386-pc/setjmp_test.mod differ diff --git a/INSTALL/grub/i386-pc/setpci.mod b/INSTALL/grub/i386-pc/setpci.mod new file mode 100644 index 00000000..f0b84d94 Binary files /dev/null and b/INSTALL/grub/i386-pc/setpci.mod differ diff --git a/INSTALL/grub/i386-pc/sfs.mod b/INSTALL/grub/i386-pc/sfs.mod new file mode 100644 index 00000000..3cf881b4 Binary files /dev/null and b/INSTALL/grub/i386-pc/sfs.mod differ diff --git a/INSTALL/grub/i386-pc/shift_test.mod b/INSTALL/grub/i386-pc/shift_test.mod new file mode 100644 index 00000000..8236137c Binary files /dev/null and b/INSTALL/grub/i386-pc/shift_test.mod differ diff --git a/INSTALL/grub/i386-pc/signature_test.mod b/INSTALL/grub/i386-pc/signature_test.mod new file mode 100644 index 00000000..62c1e533 Binary files /dev/null and b/INSTALL/grub/i386-pc/signature_test.mod differ diff --git a/INSTALL/grub/i386-pc/sleep_test.mod b/INSTALL/grub/i386-pc/sleep_test.mod new file mode 100644 index 00000000..78d66481 Binary files /dev/null and b/INSTALL/grub/i386-pc/sleep_test.mod differ diff --git a/INSTALL/grub/i386-pc/spkmodem.mod b/INSTALL/grub/i386-pc/spkmodem.mod new file mode 100644 index 00000000..c5e06b56 Binary files /dev/null and b/INSTALL/grub/i386-pc/spkmodem.mod differ diff --git a/INSTALL/grub/i386-pc/strtoull_test.mod b/INSTALL/grub/i386-pc/strtoull_test.mod new file mode 100644 index 00000000..38de07ef Binary files /dev/null and b/INSTALL/grub/i386-pc/strtoull_test.mod differ diff --git a/INSTALL/grub/i386-pc/syslinuxcfg.mod b/INSTALL/grub/i386-pc/syslinuxcfg.mod new file mode 100644 index 00000000..ebeda650 Binary files /dev/null and b/INSTALL/grub/i386-pc/syslinuxcfg.mod differ diff --git a/INSTALL/grub/i386-pc/terminal.lst b/INSTALL/grub/i386-pc/terminal.lst new file mode 100644 index 00000000..2cb224c4 --- /dev/null +++ b/INSTALL/grub/i386-pc/terminal.lst @@ -0,0 +1,11 @@ +iat_keyboard: at_keyboard +iserial: serial +iserial_*: serial +oaudio: morse +ocbmemc: cbmemc +ogfxterm: gfxterm +omda_text: mda_text +oserial: serial +oserial_*: serial +ospkmodem: spkmodem +ovga_text: vga_text diff --git a/INSTALL/grub/i386-pc/terminfo.mod b/INSTALL/grub/i386-pc/terminfo.mod new file mode 100644 index 00000000..a925b176 Binary files /dev/null and b/INSTALL/grub/i386-pc/terminfo.mod differ diff --git a/INSTALL/grub/i386-pc/test_blockarg.mod b/INSTALL/grub/i386-pc/test_blockarg.mod new file mode 100644 index 00000000..dde95fc4 Binary files /dev/null and b/INSTALL/grub/i386-pc/test_blockarg.mod differ diff --git a/INSTALL/grub/i386-pc/testload.mod b/INSTALL/grub/i386-pc/testload.mod new file mode 100644 index 00000000..1d428810 Binary files /dev/null and b/INSTALL/grub/i386-pc/testload.mod differ diff --git a/INSTALL/grub/i386-pc/testspeed.mod b/INSTALL/grub/i386-pc/testspeed.mod new file mode 100644 index 00000000..aa331842 Binary files /dev/null and b/INSTALL/grub/i386-pc/testspeed.mod differ diff --git a/INSTALL/grub/i386-pc/tga.mod b/INSTALL/grub/i386-pc/tga.mod new file mode 100644 index 00000000..c8fcd0b5 Binary files /dev/null and b/INSTALL/grub/i386-pc/tga.mod differ diff --git a/INSTALL/grub/i386-pc/time.mod b/INSTALL/grub/i386-pc/time.mod new file mode 100644 index 00000000..04d482d7 Binary files /dev/null and b/INSTALL/grub/i386-pc/time.mod differ diff --git a/INSTALL/grub/i386-pc/truecrypt.mod b/INSTALL/grub/i386-pc/truecrypt.mod new file mode 100644 index 00000000..6730bcd9 Binary files /dev/null and b/INSTALL/grub/i386-pc/truecrypt.mod differ diff --git a/INSTALL/grub/i386-pc/ufs1.mod b/INSTALL/grub/i386-pc/ufs1.mod new file mode 100644 index 00000000..4772a202 Binary files /dev/null and b/INSTALL/grub/i386-pc/ufs1.mod differ diff --git a/INSTALL/grub/i386-pc/ufs1_be.mod b/INSTALL/grub/i386-pc/ufs1_be.mod new file mode 100644 index 00000000..31a50d7c Binary files /dev/null and b/INSTALL/grub/i386-pc/ufs1_be.mod differ diff --git a/INSTALL/grub/i386-pc/ufs2.mod b/INSTALL/grub/i386-pc/ufs2.mod new file mode 100644 index 00000000..088fba39 Binary files /dev/null and b/INSTALL/grub/i386-pc/ufs2.mod differ diff --git a/INSTALL/grub/i386-pc/uhci.mod b/INSTALL/grub/i386-pc/uhci.mod new file mode 100644 index 00000000..0e714282 Binary files /dev/null and b/INSTALL/grub/i386-pc/uhci.mod differ diff --git a/INSTALL/grub/i386-pc/usb.mod b/INSTALL/grub/i386-pc/usb.mod new file mode 100644 index 00000000..3bf851ad Binary files /dev/null and b/INSTALL/grub/i386-pc/usb.mod differ diff --git a/INSTALL/grub/i386-pc/usbms.mod b/INSTALL/grub/i386-pc/usbms.mod new file mode 100644 index 00000000..3c41b5c9 Binary files /dev/null and b/INSTALL/grub/i386-pc/usbms.mod differ diff --git a/INSTALL/grub/i386-pc/usbserial_common.mod b/INSTALL/grub/i386-pc/usbserial_common.mod new file mode 100644 index 00000000..25d8b0af Binary files /dev/null and b/INSTALL/grub/i386-pc/usbserial_common.mod differ diff --git a/INSTALL/grub/i386-pc/usbserial_ftdi.mod b/INSTALL/grub/i386-pc/usbserial_ftdi.mod new file mode 100644 index 00000000..41eac15f Binary files /dev/null and b/INSTALL/grub/i386-pc/usbserial_ftdi.mod differ diff --git a/INSTALL/grub/i386-pc/usbserial_pl2303.mod b/INSTALL/grub/i386-pc/usbserial_pl2303.mod new file mode 100644 index 00000000..4dfbf9ae Binary files /dev/null and b/INSTALL/grub/i386-pc/usbserial_pl2303.mod differ diff --git a/INSTALL/grub/i386-pc/usbserial_usbdebug.mod b/INSTALL/grub/i386-pc/usbserial_usbdebug.mod new file mode 100644 index 00000000..e8f3c413 Binary files /dev/null and b/INSTALL/grub/i386-pc/usbserial_usbdebug.mod differ diff --git a/INSTALL/grub/i386-pc/usbtest.mod b/INSTALL/grub/i386-pc/usbtest.mod new file mode 100644 index 00000000..5c3a7fc1 Binary files /dev/null and b/INSTALL/grub/i386-pc/usbtest.mod differ diff --git a/INSTALL/grub/i386-pc/verifiers.mod b/INSTALL/grub/i386-pc/verifiers.mod new file mode 100644 index 00000000..f7b8ab91 Binary files /dev/null and b/INSTALL/grub/i386-pc/verifiers.mod differ diff --git a/INSTALL/grub/i386-pc/video.lst b/INSTALL/grub/i386-pc/video.lst new file mode 100644 index 00000000..6ca853e6 --- /dev/null +++ b/INSTALL/grub/i386-pc/video.lst @@ -0,0 +1,4 @@ +vbe +vga +video_bochs +video_cirrus diff --git a/INSTALL/grub/i386-pc/wrmsr.mod b/INSTALL/grub/i386-pc/wrmsr.mod new file mode 100644 index 00000000..1d7d2573 Binary files /dev/null and b/INSTALL/grub/i386-pc/wrmsr.mod differ diff --git a/INSTALL/grub/i386-pc/xnu.mod b/INSTALL/grub/i386-pc/xnu.mod new file mode 100644 index 00000000..96c2e583 Binary files /dev/null and b/INSTALL/grub/i386-pc/xnu.mod differ diff --git a/INSTALL/grub/i386-pc/xnu_uuid.mod b/INSTALL/grub/i386-pc/xnu_uuid.mod new file mode 100644 index 00000000..499f0b58 Binary files /dev/null and b/INSTALL/grub/i386-pc/xnu_uuid.mod differ diff --git a/INSTALL/grub/i386-pc/xnu_uuid_test.mod b/INSTALL/grub/i386-pc/xnu_uuid_test.mod new file mode 100644 index 00000000..a8532356 Binary files /dev/null and b/INSTALL/grub/i386-pc/xnu_uuid_test.mod differ diff --git a/INSTALL/grub/i386-pc/zfs.mod b/INSTALL/grub/i386-pc/zfs.mod new file mode 100644 index 00000000..28adaa65 Binary files /dev/null and b/INSTALL/grub/i386-pc/zfs.mod differ diff --git a/INSTALL/grub/i386-pc/zfscrypt.mod b/INSTALL/grub/i386-pc/zfscrypt.mod new file mode 100644 index 00000000..e684ccd2 Binary files /dev/null and b/INSTALL/grub/i386-pc/zfscrypt.mod differ diff --git a/INSTALL/grub/i386-pc/zfsinfo.mod b/INSTALL/grub/i386-pc/zfsinfo.mod new file mode 100644 index 00000000..68844f45 Binary files /dev/null and b/INSTALL/grub/i386-pc/zfsinfo.mod differ diff --git a/INSTALL/grub/i386-pc/zstd.mod b/INSTALL/grub/i386-pc/zstd.mod new file mode 100644 index 00000000..721fe202 Binary files /dev/null and b/INSTALL/grub/i386-pc/zstd.mod differ diff --git a/INSTALL/grub/localboot.cfg b/INSTALL/grub/localboot.cfg index 0afb3446..b60d54fc 100644 --- a/INSTALL/grub/localboot.cfg +++ b/INSTALL/grub/localboot.cfg @@ -3,8 +3,8 @@ if [ "$grub_platform" = "pc" ]; then menuentry 'Search and boot Windows' --class=boot_windows { if search -n -s -f /bootmgr; then ntldr /bootmgr - elif search -n -s -f /ntldr; then - ntldr /ntldr + elif search -n -s -f /NTLDR; then + ntldr /NTLDR else echo "Windows NOT found ..." fi @@ -60,6 +60,6 @@ else fi -menuentry 'Return to menu [Esc]' --class=vtoyret VTOY_RET { +menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET { echo 'Return ...' } diff --git a/INSTALL/grub/power.cfg b/INSTALL/grub/power.cfg index 7f6249f0..ede844c2 100644 --- a/INSTALL/grub/power.cfg +++ b/INSTALL/grub/power.cfg @@ -10,6 +10,6 @@ menuentry Halt --class=power_halt { halt } -menuentry 'Return to menu [Esc]' --class=vtoyret VTOY_RET { +menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET { echo 'Return ...' } diff --git a/INSTALL/grub/themes/ventoy/background.png b/INSTALL/grub/themes/ventoy/background.png index b0190fc6..8a4ac943 100644 Binary files a/INSTALL/grub/themes/ventoy/background.png and b/INSTALL/grub/themes/ventoy/background.png differ diff --git a/INSTALL/grub/x86_64-efi/adler32.mod b/INSTALL/grub/x86_64-efi/adler32.mod new file mode 100644 index 00000000..8df78d18 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/adler32.mod differ diff --git a/INSTALL/grub/x86_64-efi/affs.mod b/INSTALL/grub/x86_64-efi/affs.mod new file mode 100644 index 00000000..8c67092e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/affs.mod differ diff --git a/INSTALL/grub/x86_64-efi/afs.mod b/INSTALL/grub/x86_64-efi/afs.mod new file mode 100644 index 00000000..98157773 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/afs.mod differ diff --git a/INSTALL/grub/x86_64-efi/ahci.mod b/INSTALL/grub/x86_64-efi/ahci.mod new file mode 100644 index 00000000..86b274d8 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ahci.mod differ diff --git a/INSTALL/grub/x86_64-efi/aout.mod b/INSTALL/grub/x86_64-efi/aout.mod new file mode 100644 index 00000000..db8ab3ea Binary files /dev/null and b/INSTALL/grub/x86_64-efi/aout.mod differ diff --git a/INSTALL/grub/x86_64-efi/appleldr.mod b/INSTALL/grub/x86_64-efi/appleldr.mod new file mode 100644 index 00000000..a4505c39 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/appleldr.mod differ diff --git a/INSTALL/grub/x86_64-efi/archelp.mod b/INSTALL/grub/x86_64-efi/archelp.mod new file mode 100644 index 00000000..62463eec Binary files /dev/null and b/INSTALL/grub/x86_64-efi/archelp.mod differ diff --git a/INSTALL/grub/x86_64-efi/ata.mod b/INSTALL/grub/x86_64-efi/ata.mod new file mode 100644 index 00000000..825e4944 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ata.mod differ diff --git a/INSTALL/grub/x86_64-efi/backtrace.mod b/INSTALL/grub/x86_64-efi/backtrace.mod new file mode 100644 index 00000000..29f9fef5 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/backtrace.mod differ diff --git a/INSTALL/grub/x86_64-efi/bfs.mod b/INSTALL/grub/x86_64-efi/bfs.mod new file mode 100644 index 00000000..3065049f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/bfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/bsd.mod b/INSTALL/grub/x86_64-efi/bsd.mod new file mode 100644 index 00000000..9f5235b0 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/bsd.mod differ diff --git a/INSTALL/grub/x86_64-efi/bswap_test.mod b/INSTALL/grub/x86_64-efi/bswap_test.mod new file mode 100644 index 00000000..b80415a9 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/bswap_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/btrfs.mod b/INSTALL/grub/x86_64-efi/btrfs.mod new file mode 100644 index 00000000..af470c3d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/btrfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbfs.mod b/INSTALL/grub/x86_64-efi/cbfs.mod new file mode 100644 index 00000000..385069bb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbls.mod b/INSTALL/grub/x86_64-efi/cbls.mod new file mode 100644 index 00000000..325251ee Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbls.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbmemc.mod b/INSTALL/grub/x86_64-efi/cbmemc.mod new file mode 100644 index 00000000..1245aacf Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbmemc.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbtable.mod b/INSTALL/grub/x86_64-efi/cbtable.mod new file mode 100644 index 00000000..f46fe4f7 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbtable.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbtime.mod b/INSTALL/grub/x86_64-efi/cbtime.mod new file mode 100644 index 00000000..f685e5e7 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbtime.mod differ diff --git a/INSTALL/grub/x86_64-efi/cmdline_cat_test.mod b/INSTALL/grub/x86_64-efi/cmdline_cat_test.mod new file mode 100644 index 00000000..57c7bbe7 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cmdline_cat_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/cmp.mod b/INSTALL/grub/x86_64-efi/cmp.mod new file mode 100644 index 00000000..29dbd130 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cmp.mod differ diff --git a/INSTALL/grub/x86_64-efi/cmp_test.mod b/INSTALL/grub/x86_64-efi/cmp_test.mod new file mode 100644 index 00000000..e750bdb6 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cmp_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/command.lst b/INSTALL/grub/x86_64-efi/command.lst new file mode 100644 index 00000000..7239dd69 --- /dev/null +++ b/INSTALL/grub/x86_64-efi/command.lst @@ -0,0 +1,190 @@ +*acpi: acpi +*all_functional_test: functional_test +*background_image: gfxterm_background +*cat: cat +*cpuid: cpuid +*crc: hashsum +*cryptomount: cryptodisk +*echo: echo +*extract_syslinux_entries_configfile: syslinuxcfg +*extract_syslinux_entries_source: syslinuxcfg +*file: file +*functional_test: functional_test +*gettext: gettext +*hashsum: hashsum +*hdparm: hdparm +*hello: hello +*help: help +*hexdump: hexdump +*inb: iorw +*inl: iorw +*inw: iorw +*keystatus: keystatus +*kfreebsd: bsd +*knetbsd: bsd +*kopenbsd: bsd +*list_env: loadenv +*load_env: loadenv +*loopback: loopback +*ls: ls +*lsacpi: lsacpi +*lspci: lspci +*md5sum: hashsum +*menuentry: normal +*pcidump: pcidump +*probe: probe +*rdmsr: rdmsr +*read_byte: memrw +*read_dword: memrw +*read_word: memrw +*regexp: regexp +*save_env: loadenv +*search: search +*serial: serial +*setpci: setpci +*sha1sum: hashsum +*sha256sum: hashsum +*sha512sum: hashsum +*sleep: sleep +*submenu: normal +*syslinux_configfile: syslinuxcfg +*syslinux_source: syslinuxcfg +*terminfo: terminfo +*test_blockarg: test_blockarg +*testspeed: testspeed +*tr: tr +*trust: pgp +*verify_detached: pgp +*xnu_splash: xnu +*zfskey: zfscrypt +.: configfile +[: test +appleloader: appleldr +authenticate: normal +background_color: gfxterm_background +backtrace: backtrace +badram: mmap +blocklist: blocklist +boot: boot +break: normal +cat: minicmd +cbmemc: cbmemc +chainloader: chain +clear: normal +cmp: cmp +configfile: configfile +continue: normal +coreboot_boottime: cbtime +cutmem: mmap +date: date +distrust: pgp +dump: minicmd +eval: eval +exit: minicmd +export: normal +extract_entries_configfile: configfile +extract_entries_source: configfile +extract_legacy_entries_configfile: legacycfg +extract_legacy_entries_source: legacycfg +fakebios: loadbios +false: true +fix_video: fixvideo +fwsetup: efifwsetup +gptsync: gptsync +halt: halt +help: minicmd +hexdump_random: random +initrd16: linux16 +initrd: linux +keymap: keylayouts +kfreebsd_loadenv: bsd +kfreebsd_module: bsd +kfreebsd_module_elf: bsd +knetbsd_module: bsd +knetbsd_module_elf: bsd +kopenbsd_ramdisk: bsd +legacy_check_password: legacycfg +legacy_configfile: legacycfg +legacy_initrd: legacycfg +legacy_initrd_nounzip: legacycfg +legacy_kernel: legacycfg +legacy_password: legacycfg +legacy_source: legacycfg +linux16: linux16 +linux: linux +list_trusted: pgp +loadbios: loadbios +loadfont: font +lscoreboot: cbls +lsefi: lsefi +lsefimmap: lsefimmap +lsefisystab: lsefisystab +lsfonts: font +lsmmap: lsmmap +lsmod: minicmd +lssal: lssal +macppcbless: macbless +mactelbless: macbless +module2: multiboot2 +module: multiboot +multiboot2: multiboot2 +multiboot: multiboot +nativedisk: nativedisk +net_add_addr: net +net_add_dns: net +net_add_route: net +net_bootp: net +net_del_addr: net +net_del_dns: net +net_del_route: net +net_dhcp: net +net_get_dhcp_option: net +net_ipv6_autoconf: net +net_ls_addr: net +net_ls_cards: net +net_ls_dns: net +net_ls_routes: net +net_nslookup: net +normal: normal +normal_exit: normal +outb: iorw +outl: iorw +outw: iorw +parttool: parttool +password: password +password_pbkdf2: password_pbkdf2 +play: play +read: read +reboot: reboot +return: normal +rmmod: minicmd +search.file: search_fs_file +search.fs_label: search_label +search.fs_uuid: search_fs_uuid +setparams: normal +shift: normal +source: configfile +terminal_input: terminal +terminal_output: terminal +test: test +testload: testload +time: time +true: true +usb: usbtest +videoinfo: videoinfo +videotest: videotest +write_byte: memrw +write_dword: memrw +write_word: memrw +wrmsr: wrmsr +xnu_devprop_load: xnu +xnu_kernel64: xnu +xnu_kernel: xnu +xnu_kext: xnu +xnu_kextdir: xnu +xnu_mkext: xnu +xnu_ramdisk: xnu +xnu_resume: xnu +xnu_uuid: xnu_uuid +zfs-bootfs: zfsinfo +zfsinfo: zfsinfo diff --git a/INSTALL/grub/x86_64-efi/cpio.mod b/INSTALL/grub/x86_64-efi/cpio.mod new file mode 100644 index 00000000..e774c231 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cpio.mod differ diff --git a/INSTALL/grub/x86_64-efi/cpio_be.mod b/INSTALL/grub/x86_64-efi/cpio_be.mod new file mode 100644 index 00000000..621213fd Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cpio_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/cpuid.mod b/INSTALL/grub/x86_64-efi/cpuid.mod new file mode 100644 index 00000000..03e93898 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cpuid.mod differ diff --git a/INSTALL/grub/x86_64-efi/crc64.mod b/INSTALL/grub/x86_64-efi/crc64.mod new file mode 100644 index 00000000..ec5e9c0a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/crc64.mod differ diff --git a/INSTALL/grub/x86_64-efi/crypto.lst b/INSTALL/grub/x86_64-efi/crypto.lst new file mode 100644 index 00000000..77d9efc0 --- /dev/null +++ b/INSTALL/grub/x86_64-efi/crypto.lst @@ -0,0 +1,45 @@ +RIJNDAEL: gcry_rijndael +RIJNDAEL192: gcry_rijndael +RIJNDAEL256: gcry_rijndael +AES128: gcry_rijndael +AES-128: gcry_rijndael +AES-192: gcry_rijndael +AES-256: gcry_rijndael +ADLER32: adler32 +CRC64: crc64 +ARCFOUR: gcry_arcfour +BLOWFISH: gcry_blowfish +CAMELLIA128: gcry_camellia +CAMELLIA192: gcry_camellia +CAMELLIA256: gcry_camellia +CAST5: gcry_cast5 +CRC32: gcry_crc +CRC32RFC1510: gcry_crc +CRC24RFC2440: gcry_crc +DES: gcry_des +3DES: gcry_des +DSA: gcry_dsa +IDEA: gcry_idea +MD4: gcry_md4 +MD5: gcry_md5 +RFC2268_40: gcry_rfc2268 +AES: gcry_rijndael +AES192: gcry_rijndael +AES256: gcry_rijndael +RIPEMD160: gcry_rmd160 +RSA: gcry_rsa +SEED: gcry_seed +SERPENT128: gcry_serpent +SERPENT192: gcry_serpent +SERPENT256: gcry_serpent +SHA1: gcry_sha1 +SHA224: gcry_sha256 +SHA256: gcry_sha256 +SHA512: gcry_sha512 +SHA384: gcry_sha512 +TIGER192: gcry_tiger +TIGER: gcry_tiger +TIGER2: gcry_tiger +TWOFISH: gcry_twofish +TWOFISH128: gcry_twofish +WHIRLPOOL: gcry_whirlpool diff --git a/INSTALL/grub/x86_64-efi/cryptodisk.mod b/INSTALL/grub/x86_64-efi/cryptodisk.mod new file mode 100644 index 00000000..c56ebf5c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cryptodisk.mod differ diff --git a/INSTALL/grub/x86_64-efi/cs5536.mod b/INSTALL/grub/x86_64-efi/cs5536.mod new file mode 100644 index 00000000..b52ab088 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cs5536.mod differ diff --git a/INSTALL/grub/x86_64-efi/ctz_test.mod b/INSTALL/grub/x86_64-efi/ctz_test.mod new file mode 100644 index 00000000..e602fd1a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ctz_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/date.mod b/INSTALL/grub/x86_64-efi/date.mod new file mode 100644 index 00000000..5fec5bbe Binary files /dev/null and b/INSTALL/grub/x86_64-efi/date.mod differ diff --git a/INSTALL/grub/x86_64-efi/datehook.mod b/INSTALL/grub/x86_64-efi/datehook.mod new file mode 100644 index 00000000..f398c92f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/datehook.mod differ diff --git a/INSTALL/grub/x86_64-efi/disk.mod b/INSTALL/grub/x86_64-efi/disk.mod new file mode 100644 index 00000000..aab241b1 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/disk.mod differ diff --git a/INSTALL/grub/x86_64-efi/div.mod b/INSTALL/grub/x86_64-efi/div.mod new file mode 100644 index 00000000..374129fe Binary files /dev/null and b/INSTALL/grub/x86_64-efi/div.mod differ diff --git a/INSTALL/grub/x86_64-efi/div_test.mod b/INSTALL/grub/x86_64-efi/div_test.mod new file mode 100644 index 00000000..ede46a09 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/div_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/dm_nv.mod b/INSTALL/grub/x86_64-efi/dm_nv.mod new file mode 100644 index 00000000..19a46086 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/dm_nv.mod differ diff --git a/INSTALL/grub/x86_64-efi/efinet.mod b/INSTALL/grub/x86_64-efi/efinet.mod new file mode 100644 index 00000000..6cef7b1b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/efinet.mod differ diff --git a/INSTALL/grub/x86_64-efi/ehci.mod b/INSTALL/grub/x86_64-efi/ehci.mod new file mode 100644 index 00000000..841296f8 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ehci.mod differ diff --git a/INSTALL/grub/x86_64-efi/elf.mod b/INSTALL/grub/x86_64-efi/elf.mod new file mode 100644 index 00000000..d4811f86 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/elf.mod differ diff --git a/INSTALL/grub/x86_64-efi/eval.mod b/INSTALL/grub/x86_64-efi/eval.mod new file mode 100644 index 00000000..4c401f84 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/eval.mod differ diff --git a/INSTALL/grub/x86_64-efi/exfctest.mod b/INSTALL/grub/x86_64-efi/exfctest.mod new file mode 100644 index 00000000..fc8d158b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/exfctest.mod differ diff --git a/INSTALL/grub/x86_64-efi/f2fs.mod b/INSTALL/grub/x86_64-efi/f2fs.mod new file mode 100644 index 00000000..4d9e530c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/f2fs.mod differ diff --git a/INSTALL/grub/x86_64-efi/fdt.lst b/INSTALL/grub/x86_64-efi/fdt.lst new file mode 100644 index 00000000..e69de29b diff --git a/INSTALL/grub/x86_64-efi/file.mod b/INSTALL/grub/x86_64-efi/file.mod new file mode 100644 index 00000000..e727f5f7 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/file.mod differ diff --git a/INSTALL/grub/x86_64-efi/fixvideo.mod b/INSTALL/grub/x86_64-efi/fixvideo.mod new file mode 100644 index 00000000..625c52e3 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/fixvideo.mod differ diff --git a/INSTALL/grub/x86_64-efi/fs.lst b/INSTALL/grub/x86_64-efi/fs.lst new file mode 100644 index 00000000..0acd240b --- /dev/null +++ b/INSTALL/grub/x86_64-efi/fs.lst @@ -0,0 +1,37 @@ +affs +afs +bfs +btrfs +cbfs +cpio +cpio_be +exfat +ext2 +f2fs +fat +hfs +hfsplus +iso9660 +jfs +minix +minix2 +minix2_be +minix3 +minix3_be +minix_be +newc +nilfs2 +ntfs +odc +procfs +reiserfs +romfs +sfs +squash4 +tar +udf +ufs1 +ufs1_be +ufs2 +xfs +zfs diff --git a/INSTALL/grub/x86_64-efi/functional_test.mod b/INSTALL/grub/x86_64-efi/functional_test.mod new file mode 100644 index 00000000..0b2d1469 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/functional_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_arcfour.mod b/INSTALL/grub/x86_64-efi/gcry_arcfour.mod new file mode 100644 index 00000000..97568f76 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_arcfour.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_blowfish.mod b/INSTALL/grub/x86_64-efi/gcry_blowfish.mod new file mode 100644 index 00000000..5d962f43 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_blowfish.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_camellia.mod b/INSTALL/grub/x86_64-efi/gcry_camellia.mod new file mode 100644 index 00000000..b44663b0 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_camellia.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_cast5.mod b/INSTALL/grub/x86_64-efi/gcry_cast5.mod new file mode 100644 index 00000000..8a264bf2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_cast5.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_crc.mod b/INSTALL/grub/x86_64-efi/gcry_crc.mod new file mode 100644 index 00000000..7f71a65f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_crc.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_des.mod b/INSTALL/grub/x86_64-efi/gcry_des.mod new file mode 100644 index 00000000..919d2c33 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_des.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_dsa.mod b/INSTALL/grub/x86_64-efi/gcry_dsa.mod new file mode 100644 index 00000000..14134411 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_dsa.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_idea.mod b/INSTALL/grub/x86_64-efi/gcry_idea.mod new file mode 100644 index 00000000..b3043204 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_idea.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_md4.mod b/INSTALL/grub/x86_64-efi/gcry_md4.mod new file mode 100644 index 00000000..b4e2e603 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_md4.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_rfc2268.mod b/INSTALL/grub/x86_64-efi/gcry_rfc2268.mod new file mode 100644 index 00000000..fed34c01 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_rfc2268.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_rijndael.mod b/INSTALL/grub/x86_64-efi/gcry_rijndael.mod new file mode 100644 index 00000000..29ac30eb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_rijndael.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_rmd160.mod b/INSTALL/grub/x86_64-efi/gcry_rmd160.mod new file mode 100644 index 00000000..b8c35dc7 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_rmd160.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_rsa.mod b/INSTALL/grub/x86_64-efi/gcry_rsa.mod new file mode 100644 index 00000000..e3a58997 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_rsa.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_seed.mod b/INSTALL/grub/x86_64-efi/gcry_seed.mod new file mode 100644 index 00000000..1fa8178d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_seed.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_serpent.mod b/INSTALL/grub/x86_64-efi/gcry_serpent.mod new file mode 100644 index 00000000..fd12f884 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_serpent.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_sha1.mod b/INSTALL/grub/x86_64-efi/gcry_sha1.mod new file mode 100644 index 00000000..9c6a843c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_sha1.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_sha256.mod b/INSTALL/grub/x86_64-efi/gcry_sha256.mod new file mode 100644 index 00000000..973d7652 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_sha256.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_tiger.mod b/INSTALL/grub/x86_64-efi/gcry_tiger.mod new file mode 100644 index 00000000..686e70bd Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_tiger.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_twofish.mod b/INSTALL/grub/x86_64-efi/gcry_twofish.mod new file mode 100644 index 00000000..013c91ff Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_twofish.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_whirlpool.mod b/INSTALL/grub/x86_64-efi/gcry_whirlpool.mod new file mode 100644 index 00000000..e10c7859 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_whirlpool.mod differ diff --git a/INSTALL/grub/x86_64-efi/geli.mod b/INSTALL/grub/x86_64-efi/geli.mod new file mode 100644 index 00000000..c5db6467 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/geli.mod differ diff --git a/INSTALL/grub/x86_64-efi/gfxterm_menu.mod b/INSTALL/grub/x86_64-efi/gfxterm_menu.mod new file mode 100644 index 00000000..6783e078 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gfxterm_menu.mod differ diff --git a/INSTALL/grub/x86_64-efi/gptsync.mod b/INSTALL/grub/x86_64-efi/gptsync.mod new file mode 100644 index 00000000..86ecbbfb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gptsync.mod differ diff --git a/INSTALL/grub/x86_64-efi/hdparm.mod b/INSTALL/grub/x86_64-efi/hdparm.mod new file mode 100644 index 00000000..bd19f3f4 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hdparm.mod differ diff --git a/INSTALL/grub/x86_64-efi/hello.mod b/INSTALL/grub/x86_64-efi/hello.mod new file mode 100644 index 00000000..56921863 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hello.mod differ diff --git a/INSTALL/grub/x86_64-efi/help.mod b/INSTALL/grub/x86_64-efi/help.mod new file mode 100644 index 00000000..9c27d63d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/help.mod differ diff --git a/INSTALL/grub/x86_64-efi/hexdump.mod b/INSTALL/grub/x86_64-efi/hexdump.mod new file mode 100644 index 00000000..05c5722a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hexdump.mod differ diff --git a/INSTALL/grub/x86_64-efi/hfs.mod b/INSTALL/grub/x86_64-efi/hfs.mod new file mode 100644 index 00000000..d04180a9 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/hfspluscomp.mod b/INSTALL/grub/x86_64-efi/hfspluscomp.mod new file mode 100644 index 00000000..e206005f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hfspluscomp.mod differ diff --git a/INSTALL/grub/x86_64-efi/iorw.mod b/INSTALL/grub/x86_64-efi/iorw.mod new file mode 100644 index 00000000..707b405b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/iorw.mod differ diff --git a/INSTALL/grub/x86_64-efi/jfs.mod b/INSTALL/grub/x86_64-efi/jfs.mod new file mode 100644 index 00000000..776a758e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/jfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/keylayouts.mod b/INSTALL/grub/x86_64-efi/keylayouts.mod new file mode 100644 index 00000000..2c2f9e7f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/keylayouts.mod differ diff --git a/INSTALL/grub/x86_64-efi/keystatus.mod b/INSTALL/grub/x86_64-efi/keystatus.mod new file mode 100644 index 00000000..3cd5d7cc Binary files /dev/null and b/INSTALL/grub/x86_64-efi/keystatus.mod differ diff --git a/INSTALL/grub/x86_64-efi/ldm.mod b/INSTALL/grub/x86_64-efi/ldm.mod new file mode 100644 index 00000000..baa88e76 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ldm.mod differ diff --git a/INSTALL/grub/x86_64-efi/legacy_password_test.mod b/INSTALL/grub/x86_64-efi/legacy_password_test.mod new file mode 100644 index 00000000..225082ac Binary files /dev/null and b/INSTALL/grub/x86_64-efi/legacy_password_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/legacycfg.mod b/INSTALL/grub/x86_64-efi/legacycfg.mod new file mode 100644 index 00000000..752af40f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/legacycfg.mod differ diff --git a/INSTALL/grub/x86_64-efi/linux16.mod b/INSTALL/grub/x86_64-efi/linux16.mod new file mode 100644 index 00000000..1aa94eff Binary files /dev/null and b/INSTALL/grub/x86_64-efi/linux16.mod differ diff --git a/INSTALL/grub/x86_64-efi/loadbios.mod b/INSTALL/grub/x86_64-efi/loadbios.mod new file mode 100644 index 00000000..9dae5686 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/loadbios.mod differ diff --git a/INSTALL/grub/x86_64-efi/loadenv.mod b/INSTALL/grub/x86_64-efi/loadenv.mod new file mode 100644 index 00000000..6bfde6bb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/loadenv.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsacpi.mod b/INSTALL/grub/x86_64-efi/lsacpi.mod new file mode 100644 index 00000000..5bda6c1e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsacpi.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsefi.mod b/INSTALL/grub/x86_64-efi/lsefi.mod new file mode 100644 index 00000000..23e76746 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsefi.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsefimmap.mod b/INSTALL/grub/x86_64-efi/lsefimmap.mod new file mode 100644 index 00000000..3cef1a2e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsefimmap.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsefisystab.mod b/INSTALL/grub/x86_64-efi/lsefisystab.mod new file mode 100644 index 00000000..ebc59dfb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsefisystab.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsmmap.mod b/INSTALL/grub/x86_64-efi/lsmmap.mod new file mode 100644 index 00000000..b02fe98f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsmmap.mod differ diff --git a/INSTALL/grub/x86_64-efi/lspci.mod b/INSTALL/grub/x86_64-efi/lspci.mod new file mode 100644 index 00000000..39ef1bee Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lspci.mod differ diff --git a/INSTALL/grub/x86_64-efi/lssal.mod b/INSTALL/grub/x86_64-efi/lssal.mod new file mode 100644 index 00000000..7cfb71c2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lssal.mod differ diff --git a/INSTALL/grub/x86_64-efi/luks.mod b/INSTALL/grub/x86_64-efi/luks.mod new file mode 100644 index 00000000..e0d290f9 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/luks.mod differ diff --git a/INSTALL/grub/x86_64-efi/lvm.mod b/INSTALL/grub/x86_64-efi/lvm.mod new file mode 100644 index 00000000..68a81529 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lvm.mod differ diff --git a/INSTALL/grub/x86_64-efi/macbless.mod b/INSTALL/grub/x86_64-efi/macbless.mod new file mode 100644 index 00000000..4631c364 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/macbless.mod differ diff --git a/INSTALL/grub/x86_64-efi/macho.mod b/INSTALL/grub/x86_64-efi/macho.mod new file mode 100644 index 00000000..d8d73442 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/macho.mod differ diff --git a/INSTALL/grub/x86_64-efi/mdraid09.mod b/INSTALL/grub/x86_64-efi/mdraid09.mod new file mode 100644 index 00000000..b6768460 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mdraid09.mod differ diff --git a/INSTALL/grub/x86_64-efi/mdraid09_be.mod b/INSTALL/grub/x86_64-efi/mdraid09_be.mod new file mode 100644 index 00000000..c47e089e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mdraid09_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/mdraid1x.mod b/INSTALL/grub/x86_64-efi/mdraid1x.mod new file mode 100644 index 00000000..8cc64181 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mdraid1x.mod differ diff --git a/INSTALL/grub/x86_64-efi/memdisk.mod b/INSTALL/grub/x86_64-efi/memdisk.mod new file mode 100644 index 00000000..41c1270a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/memdisk.mod differ diff --git a/INSTALL/grub/x86_64-efi/memrw.mod b/INSTALL/grub/x86_64-efi/memrw.mod new file mode 100644 index 00000000..8d9893e1 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/memrw.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix.mod b/INSTALL/grub/x86_64-efi/minix.mod new file mode 100644 index 00000000..21548278 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix2.mod b/INSTALL/grub/x86_64-efi/minix2.mod new file mode 100644 index 00000000..402eb731 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix2.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix2_be.mod b/INSTALL/grub/x86_64-efi/minix2_be.mod new file mode 100644 index 00000000..1fd15f37 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix2_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix3.mod b/INSTALL/grub/x86_64-efi/minix3.mod new file mode 100644 index 00000000..b6312831 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix3.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix3_be.mod b/INSTALL/grub/x86_64-efi/minix3_be.mod new file mode 100644 index 00000000..2d24bad4 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix3_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix_be.mod b/INSTALL/grub/x86_64-efi/minix_be.mod new file mode 100644 index 00000000..a039b6da Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/moddep.lst b/INSTALL/grub/x86_64-efi/moddep.lst new file mode 100644 index 00000000..fa072559 --- /dev/null +++ b/INSTALL/grub/x86_64-efi/moddep.lst @@ -0,0 +1,265 @@ +videotest: font video gfxmenu +odc: archelp +loopback: extcmd +macho: +gcry_des: crypto +memrw: extcmd +terminfo: extcmd +f2fs: fshelp +part_gpt: +romfs: fshelp +read: +lsefimmap: +aout: +gcry_arcfour: crypto +tftp: net priority_queue +newc: archelp +minix2_be: +elf: +videotest_checksum: font functional_test video_fb +password_pbkdf2: crypto gcry_sha512 pbkdf2 normal +gcry_seed: crypto +pcidump: extcmd +bsd: elf serial crypto gcry_md5 verifiers extcmd aout video boot cpuid relocator mmap +sfs: fshelp +reiserfs: fshelp +part_sunpc: +zstd: +gfxmenu: video_colors trig bitmap_scale gfxterm font normal bitmap video +backtrace: +jfs: +help: extcmd normal +configfile: normal +cbls: cbtable +gfxterm_menu: font functional_test procfs normal video_fb +gcry_idea: crypto +tr: extcmd +shift_test: functional_test +ohci: cs5536 usb boot +afs: fshelp +spkmodem: terminfo +usb_keyboard: keylayouts usb +xzio: crypto +syslinuxcfg: extcmd normal +search_fs_file: +wrmsr: +usbms: scsi usb +test_blockarg: extcmd normal +true: +affs: fshelp +iso9660: fshelp +exfat: fshelp +setjmp_test: setjmp functional_test +gfxterm: font video +efinet: net +disk: +appleldr: boot +xfs: fshelp +testspeed: extcmd normal +cpio_be: archelp +functional_test: btrfs extcmd video video_fb +bswap_test: functional_test +sleep: extcmd normal +memdisk: +gcry_rijndael: crypto +mdraid09_be: diskfilter +gettext: +gcry_sha1: crypto +hfspluscomp: gzio hfsplus +cmp: +random: hexdump +offsetio: +file: elf macho extcmd offsetio +usbserial_usbdebug: serial usb usbserial_common +video_colors: +morse: +hashsum: crypto extcmd normal +usb: +halt: acpi +gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap +search_fs_uuid: +gcry_dsa: pgp mpi +keystatus: extcmd +linux: verifiers video boot relocator mmap +geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256 +cmdline_cat_test: font functional_test normal procfs video_fb +rdmsr: extcmd +part_sun: +cbtable: +pbkdf2_test: functional_test pbkdf2 gcry_sha1 +video_bochs: video video_fb +verifiers: +bufio: +usbserial_ftdi: serial usb usbserial_common +legacy_password_test: functional_test legacycfg +cpuid: extcmd +hdparm: extcmd hexdump +bfs: fshelp +gcry_blowfish: crypto +test: +nilfs2: fshelp +gcry_rsa: pgp mpi +cryptodisk: crypto extcmd procfs +nativedisk: +minicmd: +signature_test: functional_test procfs +ata: scsi +udf: fshelp +gzio: gcry_crc +xnu_uuid: gcry_md5 +uhci: usb +pata: ata +mul_test: functional_test +adler32: crypto +terminal: +shim_lock: verifiers +div: +ehci: cs5536 usb boot +crypto: +part_bsd: part_msdos +cs5536: +ventoy: ext2 fshelp crypto font exfat udf extcmd normal gcry_sha1 iso9660 +gcry_sha512: crypto +password: crypto normal +fshelp: +sleep_test: functional_test datetime +iorw: extcmd +xnu: macho bitmap_scale random verifiers extcmd boot video bitmap relocator mmap +mmap: +exfctest: functional_test +zfsinfo: zfs +ldm: part_gpt diskfilter part_msdos +eval: normal +part_dvh: +lssal: +blocklist: +ext2: fshelp +net: priority_queue bufio datetime boot +part_acorn: +videoinfo: video +btrfs: zstd lzopio raid6rec gzio +lsmmap: mmap +strtoull_test: functional_test +bitmap: +ntfs: fshelp +multiboot: net linux video boot relocator mmap +tpm: verifiers +gcry_crc: crypto +png: bufio bitmap +jpeg: bufio bitmap +macbless: disk +div_test: functional_test div +regexp: extcmd normal +parttool: normal +usbserial_pl2303: serial usb usbserial_common +cpio: archelp +gcry_rmd160: crypto +fat: fshelp +ufs1_be: +archelp: +http: net +zfs: gzio +raid6rec: diskfilter +lsefisystab: +minix2: +lsacpi: extcmd acpi +datehook: datetime normal +loadenv: disk extcmd +bitmap_scale: bitmap +probe: extcmd +minix3: +tar: archelp +loadbios: +hfs: fshelp +procfs: archelp +boot: +keylayouts: +progress: normal +kernel: +usbtest: usb +relocator: mmap +acpi: extcmd mmap +tga: bufio bitmap +reboot: +serial: extcmd terminfo +zfscrypt: crypto pbkdf2 extcmd zfs gcry_sha1 gcry_rijndael +efi_uga: video video_fb +dm_nv: diskfilter +cmp_test: functional_test +luks: cryptodisk crypto pbkdf2 +font: bufio video +raid5rec: diskfilter +crc64: crypto +datetime: +efifwsetup: +ctz_test: functional_test +video: +cbmemc: cbtable normal terminfo +hfsplus: fshelp +gcry_cast5: crypto +extcmd: +squash4: fshelp lzopio xzio gzio +part_plan: +minix_be: +gcry_whirlpool: crypto +gcry_tiger: crypto +fixvideo: +search: search_fs_uuid search_fs_file extcmd search_label +lspci: extcmd +cbtime: cbtable +video_fb: +minix3_be: +trig: +msdospart: disk parttool +priority_queue: +gcry_twofish: crypto +part_dfly: +xnu_uuid_test: functional_test +diskfilter: +testload: +part_apple: +hexdump: extcmd +date: datetime normal +pbkdf2: crypto +gcry_sha256: crypto +ls: extcmd normal +usbserial_common: serial usb +ntfscomp: ntfs +lzopio: crypto +video_cirrus: video video_fb +hello: extcmd +scsi: +linux16: linux boot video relocator mmap +cat: extcmd +ahci: ata boot +pgp: crypto verifiers extcmd mpi gcry_sha1 +normal: terminal crypto verifiers bufio extcmd boot gettext +ufs1: +mdraid09: diskfilter +lvm: diskfilter +chain: net efinet boot +cbfs: archelp +ufs2: +time: +setpci: extcmd +gptsync: disk +search_label: +setjmp: +multiboot2: linux net video boot relocator acpi mmap +gcry_rfc2268: crypto +mdraid1x: diskfilter +mpi: crypto +legacycfg: crypto password gcry_md5 normal +play: +part_amiga: +efi_gop: video video_fb +minix: +echo: extcmd +lsefi: +gcry_serpent: crypto +gcry_md4: crypto +gcry_md5: crypto +part_msdos: +gcry_camellia: crypto +at_keyboard: keylayouts boot +all_video: efi_gop efi_uga video_bochs video_cirrus diff --git a/INSTALL/grub/x86_64-efi/morse.mod b/INSTALL/grub/x86_64-efi/morse.mod new file mode 100644 index 00000000..123c9f46 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/morse.mod differ diff --git a/INSTALL/grub/x86_64-efi/mpi.mod b/INSTALL/grub/x86_64-efi/mpi.mod new file mode 100644 index 00000000..54689554 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mpi.mod differ diff --git a/INSTALL/grub/x86_64-efi/msdospart.mod b/INSTALL/grub/x86_64-efi/msdospart.mod new file mode 100644 index 00000000..96e3e8e5 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/msdospart.mod differ diff --git a/INSTALL/grub/x86_64-efi/mul_test.mod b/INSTALL/grub/x86_64-efi/mul_test.mod new file mode 100644 index 00000000..4a37424b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mul_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/multiboot.mod b/INSTALL/grub/x86_64-efi/multiboot.mod new file mode 100644 index 00000000..9a827f20 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/multiboot.mod differ diff --git a/INSTALL/grub/x86_64-efi/multiboot2.mod b/INSTALL/grub/x86_64-efi/multiboot2.mod new file mode 100644 index 00000000..057693d9 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/multiboot2.mod differ diff --git a/INSTALL/grub/x86_64-efi/nativedisk.mod b/INSTALL/grub/x86_64-efi/nativedisk.mod new file mode 100644 index 00000000..3061804f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/nativedisk.mod differ diff --git a/INSTALL/grub/x86_64-efi/newc.mod b/INSTALL/grub/x86_64-efi/newc.mod new file mode 100644 index 00000000..484fdf5b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/newc.mod differ diff --git a/INSTALL/grub/x86_64-efi/nilfs2.mod b/INSTALL/grub/x86_64-efi/nilfs2.mod new file mode 100644 index 00000000..2aa661da Binary files /dev/null and b/INSTALL/grub/x86_64-efi/nilfs2.mod differ diff --git a/INSTALL/grub/x86_64-efi/normal.mod b/INSTALL/grub/x86_64-efi/normal.mod index 2acecccc..d2c83bb1 100644 Binary files a/INSTALL/grub/x86_64-efi/normal.mod and b/INSTALL/grub/x86_64-efi/normal.mod differ diff --git a/INSTALL/grub/x86_64-efi/ntfscomp.mod b/INSTALL/grub/x86_64-efi/ntfscomp.mod new file mode 100644 index 00000000..9f35f838 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ntfscomp.mod differ diff --git a/INSTALL/grub/x86_64-efi/odc.mod b/INSTALL/grub/x86_64-efi/odc.mod new file mode 100644 index 00000000..512d7e70 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/odc.mod differ diff --git a/INSTALL/grub/x86_64-efi/offsetio.mod b/INSTALL/grub/x86_64-efi/offsetio.mod new file mode 100644 index 00000000..99c12779 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/offsetio.mod differ diff --git a/INSTALL/grub/x86_64-efi/ohci.mod b/INSTALL/grub/x86_64-efi/ohci.mod new file mode 100644 index 00000000..de29f2bb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ohci.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_acorn.mod b/INSTALL/grub/x86_64-efi/part_acorn.mod new file mode 100644 index 00000000..323854af Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_acorn.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_amiga.mod b/INSTALL/grub/x86_64-efi/part_amiga.mod new file mode 100644 index 00000000..b16590fe Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_amiga.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_bsd.mod b/INSTALL/grub/x86_64-efi/part_bsd.mod new file mode 100644 index 00000000..d4bf05e2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_bsd.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_dfly.mod b/INSTALL/grub/x86_64-efi/part_dfly.mod new file mode 100644 index 00000000..d7b1d8e4 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_dfly.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_dvh.mod b/INSTALL/grub/x86_64-efi/part_dvh.mod new file mode 100644 index 00000000..509c3a6e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_dvh.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_plan.mod b/INSTALL/grub/x86_64-efi/part_plan.mod new file mode 100644 index 00000000..826f54dc Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_plan.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_sun.mod b/INSTALL/grub/x86_64-efi/part_sun.mod new file mode 100644 index 00000000..d054e878 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_sun.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_sunpc.mod b/INSTALL/grub/x86_64-efi/part_sunpc.mod new file mode 100644 index 00000000..b17db009 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_sunpc.mod differ diff --git a/INSTALL/grub/x86_64-efi/partmap.lst b/INSTALL/grub/x86_64-efi/partmap.lst new file mode 100644 index 00000000..761233aa --- /dev/null +++ b/INSTALL/grub/x86_64-efi/partmap.lst @@ -0,0 +1,11 @@ +part_acorn +part_amiga +part_apple +part_bsd +part_dfly +part_dvh +part_gpt +part_msdos +part_plan +part_sun +part_sunpc diff --git a/INSTALL/grub/x86_64-efi/parttool.lst b/INSTALL/grub/x86_64-efi/parttool.lst new file mode 100644 index 00000000..68b4b5c4 --- /dev/null +++ b/INSTALL/grub/x86_64-efi/parttool.lst @@ -0,0 +1 @@ +msdos: msdospart diff --git a/INSTALL/grub/x86_64-efi/parttool.mod b/INSTALL/grub/x86_64-efi/parttool.mod new file mode 100644 index 00000000..fd631c01 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/parttool.mod differ diff --git a/INSTALL/grub/x86_64-efi/password.mod b/INSTALL/grub/x86_64-efi/password.mod new file mode 100644 index 00000000..a2dd92d5 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/password.mod differ diff --git a/INSTALL/grub/x86_64-efi/pata.mod b/INSTALL/grub/x86_64-efi/pata.mod new file mode 100644 index 00000000..d61ef8d0 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/pata.mod differ diff --git a/INSTALL/grub/x86_64-efi/pbkdf2_test.mod b/INSTALL/grub/x86_64-efi/pbkdf2_test.mod new file mode 100644 index 00000000..80c9e525 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/pbkdf2_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/pcidump.mod b/INSTALL/grub/x86_64-efi/pcidump.mod new file mode 100644 index 00000000..1cecc623 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/pcidump.mod differ diff --git a/INSTALL/grub/x86_64-efi/pgp.mod b/INSTALL/grub/x86_64-efi/pgp.mod new file mode 100644 index 00000000..309f6135 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/pgp.mod differ diff --git a/INSTALL/grub/x86_64-efi/play.mod b/INSTALL/grub/x86_64-efi/play.mod new file mode 100644 index 00000000..e101c82c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/play.mod differ diff --git a/INSTALL/grub/x86_64-efi/probe.mod b/INSTALL/grub/x86_64-efi/probe.mod new file mode 100644 index 00000000..af846021 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/probe.mod differ diff --git a/INSTALL/grub/x86_64-efi/procfs.mod b/INSTALL/grub/x86_64-efi/procfs.mod new file mode 100644 index 00000000..01d42e95 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/procfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/progress.mod b/INSTALL/grub/x86_64-efi/progress.mod new file mode 100644 index 00000000..e8448364 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/progress.mod differ diff --git a/INSTALL/grub/x86_64-efi/raid5rec.mod b/INSTALL/grub/x86_64-efi/raid5rec.mod new file mode 100644 index 00000000..b4786b29 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/raid5rec.mod differ diff --git a/INSTALL/grub/x86_64-efi/raid6rec.mod b/INSTALL/grub/x86_64-efi/raid6rec.mod new file mode 100644 index 00000000..bfd0d1b2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/raid6rec.mod differ diff --git a/INSTALL/grub/x86_64-efi/random.mod b/INSTALL/grub/x86_64-efi/random.mod new file mode 100644 index 00000000..83a6c80e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/random.mod differ diff --git a/INSTALL/grub/x86_64-efi/rdmsr.mod b/INSTALL/grub/x86_64-efi/rdmsr.mod new file mode 100644 index 00000000..9bf3269a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/rdmsr.mod differ diff --git a/INSTALL/grub/x86_64-efi/regexp.mod b/INSTALL/grub/x86_64-efi/regexp.mod new file mode 100644 index 00000000..bc3b3f2f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/regexp.mod differ diff --git a/INSTALL/grub/x86_64-efi/reiserfs.mod b/INSTALL/grub/x86_64-efi/reiserfs.mod new file mode 100644 index 00000000..542ae3ce Binary files /dev/null and b/INSTALL/grub/x86_64-efi/reiserfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/romfs.mod b/INSTALL/grub/x86_64-efi/romfs.mod new file mode 100644 index 00000000..c42d9c7e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/romfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/scsi.mod b/INSTALL/grub/x86_64-efi/scsi.mod new file mode 100644 index 00000000..a5e5e859 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/scsi.mod differ diff --git a/INSTALL/grub/x86_64-efi/search_fs_file.mod b/INSTALL/grub/x86_64-efi/search_fs_file.mod new file mode 100644 index 00000000..83720396 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/search_fs_file.mod differ diff --git a/INSTALL/grub/x86_64-efi/search_fs_uuid.mod b/INSTALL/grub/x86_64-efi/search_fs_uuid.mod new file mode 100644 index 00000000..63701d19 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/search_fs_uuid.mod differ diff --git a/INSTALL/grub/x86_64-efi/search_label.mod b/INSTALL/grub/x86_64-efi/search_label.mod new file mode 100644 index 00000000..f1b82658 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/search_label.mod differ diff --git a/INSTALL/grub/x86_64-efi/setjmp.mod b/INSTALL/grub/x86_64-efi/setjmp.mod new file mode 100644 index 00000000..a0b4e571 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/setjmp.mod differ diff --git a/INSTALL/grub/x86_64-efi/setjmp_test.mod b/INSTALL/grub/x86_64-efi/setjmp_test.mod new file mode 100644 index 00000000..291d9870 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/setjmp_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/setpci.mod b/INSTALL/grub/x86_64-efi/setpci.mod new file mode 100644 index 00000000..908a3ad2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/setpci.mod differ diff --git a/INSTALL/grub/x86_64-efi/sfs.mod b/INSTALL/grub/x86_64-efi/sfs.mod new file mode 100644 index 00000000..2e3a2142 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/sfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/shift_test.mod b/INSTALL/grub/x86_64-efi/shift_test.mod new file mode 100644 index 00000000..5a1321a9 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/shift_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/shim_lock.mod b/INSTALL/grub/x86_64-efi/shim_lock.mod new file mode 100644 index 00000000..3e4123a2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/shim_lock.mod differ diff --git a/INSTALL/grub/x86_64-efi/signature_test.mod b/INSTALL/grub/x86_64-efi/signature_test.mod new file mode 100644 index 00000000..54a3545b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/signature_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/sleep_test.mod b/INSTALL/grub/x86_64-efi/sleep_test.mod new file mode 100644 index 00000000..2722f351 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/sleep_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/spkmodem.mod b/INSTALL/grub/x86_64-efi/spkmodem.mod new file mode 100644 index 00000000..eac5b905 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/spkmodem.mod differ diff --git a/INSTALL/grub/x86_64-efi/strtoull_test.mod b/INSTALL/grub/x86_64-efi/strtoull_test.mod new file mode 100644 index 00000000..24b4245f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/strtoull_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/syslinuxcfg.mod b/INSTALL/grub/x86_64-efi/syslinuxcfg.mod new file mode 100644 index 00000000..fc621e99 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/syslinuxcfg.mod differ diff --git a/INSTALL/grub/x86_64-efi/terminal.lst b/INSTALL/grub/x86_64-efi/terminal.lst new file mode 100644 index 00000000..3c9a5a34 --- /dev/null +++ b/INSTALL/grub/x86_64-efi/terminal.lst @@ -0,0 +1,9 @@ +iat_keyboard: at_keyboard +iserial: serial +iserial_*: serial +oaudio: morse +ocbmemc: cbmemc +ogfxterm: gfxterm +oserial: serial +oserial_*: serial +ospkmodem: spkmodem diff --git a/INSTALL/grub/x86_64-efi/test_blockarg.mod b/INSTALL/grub/x86_64-efi/test_blockarg.mod new file mode 100644 index 00000000..742a4806 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/test_blockarg.mod differ diff --git a/INSTALL/grub/x86_64-efi/testload.mod b/INSTALL/grub/x86_64-efi/testload.mod new file mode 100644 index 00000000..1b58c210 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/testload.mod differ diff --git a/INSTALL/grub/x86_64-efi/testspeed.mod b/INSTALL/grub/x86_64-efi/testspeed.mod new file mode 100644 index 00000000..609b3a5d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/testspeed.mod differ diff --git a/INSTALL/grub/x86_64-efi/tga.mod b/INSTALL/grub/x86_64-efi/tga.mod new file mode 100644 index 00000000..02ce149e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/tga.mod differ diff --git a/INSTALL/grub/x86_64-efi/time.mod b/INSTALL/grub/x86_64-efi/time.mod new file mode 100644 index 00000000..7112f0cb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/time.mod differ diff --git a/INSTALL/grub/x86_64-efi/tpm.mod b/INSTALL/grub/x86_64-efi/tpm.mod new file mode 100644 index 00000000..811b7ce4 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/tpm.mod differ diff --git a/INSTALL/grub/x86_64-efi/tr.mod b/INSTALL/grub/x86_64-efi/tr.mod new file mode 100644 index 00000000..cc015283 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/tr.mod differ diff --git a/INSTALL/grub/x86_64-efi/true.mod b/INSTALL/grub/x86_64-efi/true.mod new file mode 100644 index 00000000..253c5e2e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/true.mod differ diff --git a/INSTALL/grub/x86_64-efi/ufs1.mod b/INSTALL/grub/x86_64-efi/ufs1.mod new file mode 100644 index 00000000..ab79b219 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ufs1.mod differ diff --git a/INSTALL/grub/x86_64-efi/ufs1_be.mod b/INSTALL/grub/x86_64-efi/ufs1_be.mod new file mode 100644 index 00000000..296c2fcb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ufs1_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/ufs2.mod b/INSTALL/grub/x86_64-efi/ufs2.mod new file mode 100644 index 00000000..c84e55a5 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ufs2.mod differ diff --git a/INSTALL/grub/x86_64-efi/uhci.mod b/INSTALL/grub/x86_64-efi/uhci.mod new file mode 100644 index 00000000..a9a490c1 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/uhci.mod differ diff --git a/INSTALL/grub/x86_64-efi/usb.mod b/INSTALL/grub/x86_64-efi/usb.mod new file mode 100644 index 00000000..423a4632 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usb.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbms.mod b/INSTALL/grub/x86_64-efi/usbms.mod new file mode 100644 index 00000000..ab5848d8 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbms.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbserial_common.mod b/INSTALL/grub/x86_64-efi/usbserial_common.mod new file mode 100644 index 00000000..5a33d89e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbserial_common.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbserial_ftdi.mod b/INSTALL/grub/x86_64-efi/usbserial_ftdi.mod new file mode 100644 index 00000000..35cc7afe Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbserial_ftdi.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbserial_pl2303.mod b/INSTALL/grub/x86_64-efi/usbserial_pl2303.mod new file mode 100644 index 00000000..1b93dec0 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbserial_pl2303.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbserial_usbdebug.mod b/INSTALL/grub/x86_64-efi/usbserial_usbdebug.mod new file mode 100644 index 00000000..6fd988aa Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbserial_usbdebug.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbtest.mod b/INSTALL/grub/x86_64-efi/usbtest.mod new file mode 100644 index 00000000..b2cc7666 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbtest.mod differ diff --git a/INSTALL/grub/x86_64-efi/verifiers.mod b/INSTALL/grub/x86_64-efi/verifiers.mod new file mode 100644 index 00000000..6cb24d3c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/verifiers.mod differ diff --git a/INSTALL/grub/x86_64-efi/video.lst b/INSTALL/grub/x86_64-efi/video.lst new file mode 100644 index 00000000..ae9ba23e --- /dev/null +++ b/INSTALL/grub/x86_64-efi/video.lst @@ -0,0 +1,4 @@ +efi_gop +efi_uga +video_bochs +video_cirrus diff --git a/INSTALL/grub/x86_64-efi/videoinfo.mod b/INSTALL/grub/x86_64-efi/videoinfo.mod new file mode 100644 index 00000000..d30ab126 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/videoinfo.mod differ diff --git a/INSTALL/grub/x86_64-efi/videotest.mod b/INSTALL/grub/x86_64-efi/videotest.mod new file mode 100644 index 00000000..9cd7cc55 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/videotest.mod differ diff --git a/INSTALL/grub/x86_64-efi/videotest_checksum.mod b/INSTALL/grub/x86_64-efi/videotest_checksum.mod new file mode 100644 index 00000000..afba542d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/videotest_checksum.mod differ diff --git a/INSTALL/grub/x86_64-efi/wrmsr.mod b/INSTALL/grub/x86_64-efi/wrmsr.mod new file mode 100644 index 00000000..66241828 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/wrmsr.mod differ diff --git a/INSTALL/grub/x86_64-efi/xnu.mod b/INSTALL/grub/x86_64-efi/xnu.mod new file mode 100644 index 00000000..ad4d811c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/xnu.mod differ diff --git a/INSTALL/grub/x86_64-efi/xnu_uuid.mod b/INSTALL/grub/x86_64-efi/xnu_uuid.mod new file mode 100644 index 00000000..f5cc67f3 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/xnu_uuid.mod differ diff --git a/INSTALL/grub/x86_64-efi/xnu_uuid_test.mod b/INSTALL/grub/x86_64-efi/xnu_uuid_test.mod new file mode 100644 index 00000000..d39261e9 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/xnu_uuid_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/zfs.mod b/INSTALL/grub/x86_64-efi/zfs.mod new file mode 100644 index 00000000..70f1d917 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/zfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/zfscrypt.mod b/INSTALL/grub/x86_64-efi/zfscrypt.mod new file mode 100644 index 00000000..cb2e7f8e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/zfscrypt.mod differ diff --git a/INSTALL/grub/x86_64-efi/zfsinfo.mod b/INSTALL/grub/x86_64-efi/zfsinfo.mod new file mode 100644 index 00000000..7a3af4cd Binary files /dev/null and b/INSTALL/grub/x86_64-efi/zfsinfo.mod differ diff --git a/INSTALL/grub/x86_64-efi/zstd.mod b/INSTALL/grub/x86_64-efi/zstd.mod new file mode 100644 index 00000000..9ba950f1 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/zstd.mod differ diff --git a/INSTALL/plugin/ventoy/theme/background.png b/INSTALL/plugin/ventoy/theme/background.png new file mode 100644 index 00000000..5a5c7710 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/background.png differ diff --git a/INSTALL/plugin/ventoy/theme/icons/deepin.png b/INSTALL/plugin/ventoy/theme/icons/deepin.png new file mode 100644 index 00000000..a071b753 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/icons/deepin.png differ diff --git a/INSTALL/plugin/ventoy/theme/icons/red-hat.png b/INSTALL/plugin/ventoy/theme/icons/red-hat.png new file mode 100644 index 00000000..df19452a Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/icons/red-hat.png differ diff --git a/INSTALL/plugin/ventoy/theme/icons/ubuntu.png b/INSTALL/plugin/ventoy/theme/icons/ubuntu.png new file mode 100644 index 00000000..a8ad2835 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/icons/ubuntu.png differ diff --git a/INSTALL/plugin/ventoy/theme/icons/vtoyiso.png b/INSTALL/plugin/ventoy/theme/icons/vtoyiso.png new file mode 100644 index 00000000..b4e80772 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/icons/vtoyiso.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_c.png b/INSTALL/plugin/ventoy/theme/menu_c.png new file mode 100644 index 00000000..75c165b2 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_c.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_e.png b/INSTALL/plugin/ventoy/theme/menu_e.png new file mode 100644 index 00000000..d4c7421b Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_e.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_n.png b/INSTALL/plugin/ventoy/theme/menu_n.png new file mode 100644 index 00000000..5af34692 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_n.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_ne.png b/INSTALL/plugin/ventoy/theme/menu_ne.png new file mode 100644 index 00000000..87578685 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_ne.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_nw.png b/INSTALL/plugin/ventoy/theme/menu_nw.png new file mode 100644 index 00000000..87578685 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_nw.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_s.png b/INSTALL/plugin/ventoy/theme/menu_s.png new file mode 100644 index 00000000..6ba27343 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_s.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_se.png b/INSTALL/plugin/ventoy/theme/menu_se.png new file mode 100644 index 00000000..959b6091 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_se.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_sw.png b/INSTALL/plugin/ventoy/theme/menu_sw.png new file mode 100644 index 00000000..959b6091 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_sw.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_w.png b/INSTALL/plugin/ventoy/theme/menu_w.png new file mode 100644 index 00000000..d4c7421b Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_w.png differ diff --git a/INSTALL/plugin/ventoy/theme/select_c.png b/INSTALL/plugin/ventoy/theme/select_c.png new file mode 100644 index 00000000..245259aa Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/select_c.png differ diff --git a/INSTALL/plugin/ventoy/theme/slider_c.png b/INSTALL/plugin/ventoy/theme/slider_c.png new file mode 100644 index 00000000..7d630fdf Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/slider_c.png differ diff --git a/INSTALL/plugin/ventoy/theme/slider_n.png b/INSTALL/plugin/ventoy/theme/slider_n.png new file mode 100644 index 00000000..41482c90 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/slider_n.png differ diff --git a/INSTALL/plugin/ventoy/theme/slider_s.png b/INSTALL/plugin/ventoy/theme/slider_s.png new file mode 100644 index 00000000..17adc2ab Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/slider_s.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_c.png b/INSTALL/plugin/ventoy/theme/terminal_box_c.png new file mode 100644 index 00000000..d0dd52a2 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_c.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_e.png b/INSTALL/plugin/ventoy/theme/terminal_box_e.png new file mode 100644 index 00000000..394cbe4f Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_e.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_n.png b/INSTALL/plugin/ventoy/theme/terminal_box_n.png new file mode 100644 index 00000000..476f8bc6 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_n.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_ne.png b/INSTALL/plugin/ventoy/theme/terminal_box_ne.png new file mode 100644 index 00000000..9e26959b Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_ne.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_nw.png b/INSTALL/plugin/ventoy/theme/terminal_box_nw.png new file mode 100644 index 00000000..5c3cba87 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_nw.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_s.png b/INSTALL/plugin/ventoy/theme/terminal_box_s.png new file mode 100644 index 00000000..85a8901d Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_s.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_se.png b/INSTALL/plugin/ventoy/theme/terminal_box_se.png new file mode 100644 index 00000000..d8627ee5 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_se.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_sw.png b/INSTALL/plugin/ventoy/theme/terminal_box_sw.png new file mode 100644 index 00000000..67c600c8 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_sw.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_w.png b/INSTALL/plugin/ventoy/theme/terminal_box_w.png new file mode 100644 index 00000000..d066e2db Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_w.png differ diff --git a/INSTALL/plugin/ventoy/theme/theme.txt b/INSTALL/plugin/ventoy/theme/theme.txt new file mode 100644 index 00000000..dda7f27f --- /dev/null +++ b/INSTALL/plugin/ventoy/theme/theme.txt @@ -0,0 +1,80 @@ + +desktop-image: "background.png" +title-text: " " +title-color: "#ffffff" +message-color: "#f2f2f2" + +terminal-box: "terminal_box_*.png" + ++ boot_menu { + left = 10% + width = 80% + top = 30% + height = 50% + + menu_pixmap_style = "menu_*.png" + + item_color = "#ffffff" + item_height = 30 + + item_spacing = 1 + item_padding = 1 + + selected_item_color= "#f2f2f2" + selected_item_pixmap_style = "select_*.png" + + item_icon_space = 0 + + scrollbar = true + scrollbar_width = 10 + scrollbar_thumb = "slider_*.png" +} + ++ progress_bar { + id = "__timeout__" + text = "@TIMEOUT_NOTIFICATION_SHORT@" + + left = 20% + width = 60% + top = 85% + + text_color = "red" + bar_style = "*" + highlight_style = "*" +} + ++ hbox{ + left = 30% + top = 95% + width = 10% + height = 25 + + label {text = "@VTOY_HOTKEY_TIP@" color = "blue" align = "left"} +} + + ++ hbox{ + left = 30% + top = 95%-25 + width = 10% + height = 25 + + label {text = "@VTOY_MEM_DISK@" color = "red" align = "left"} +} + + ++ hbox{ + left = 30% + top = 95%-50 + width = 10% + height = 25 + + label {text = "@VTOY_ISO_RAW@" color = "red" align = "left"} +} + + ++ hbox{ + left = 90% + top = 55 + width = 10% + height = 25 + + label {text = "@VTOY_ISO_UEFI_DRV@" color = "red" align = "left"} +} + diff --git a/INSTALL/plugin/ventoy/ventoy.json b/INSTALL/plugin/ventoy/ventoy.json new file mode 100644 index 00000000..0452aaba --- /dev/null +++ b/INSTALL/plugin/ventoy/ventoy.json @@ -0,0 +1,60 @@ +{ + "control": [ + { "VTOY_DEFAULT_MENU_MODE": "1" }, + { "VTOY_FILT_DOT_UNDERSCORE_FILE": "1" } + ], + + "theme": { + "file": "/ventoy/theme/theme.txt", + "display_mode": "GUI", + "ventoy_left": "5%", + "ventoy_top": "95%", + "ventoy_color": "#0000ff" + }, + + + "menu_class": [ + { + "key": "ubuntu", + "class": "ubuntu" + }, + { + "key": "deepin", + "class": "deepin" + }, + { + "dir": "rhel", + "class": "red-hat" + } + ], + + "menu_alias": [ + { + "image": "/ISO/MX-19.1_x64.iso", + "alias": "MX 19.1 ISO file For me" + }, + { + "image": "/cn_windows_10_enterprise_ltsc_2019_x64_dvd_9c09ff24.iso", + "alias": "我的 Windows 10 系统" + } + ], + + "auto_install": [ + { + "image": "/ISO/cn_windows_10.iso", + "template": "/ventoy/script/windows_unattended.cfg" + }, + { + "image": "/ISO/cn_windows_server_2012_r2_vl_x64_dvd_2979220.iso", + "template": [ + "/ventoy/script/windows_unattended1.xml", + "/ventoy/script/windows_unattended2.xml", + "/ventoy/script/windows_unattended3.xml", + "/ventoy/script/windows_unattended4.xml", + "/ventoy/script/windows_unattended5.xml", + "/ventoy/script/windows_unattended6.xml" + ] + } + ] + +} diff --git a/INSTALL/plugin/ventoy/ventoy_grub.cfg b/INSTALL/plugin/ventoy/ventoy_grub.cfg new file mode 100644 index 00000000..f736fb99 --- /dev/null +++ b/INSTALL/plugin/ventoy/ventoy_grub.cfg @@ -0,0 +1,19 @@ +menuentry "My Custom Menu" --class=custom { + echo 'This is custom menu ... ' + sleep 1 +} + +submenu 'My Custom SubMenu -->' --class=customsub { + menuentry "My Custom Menu2" --class=custom2 { + echo 'This is custom menu2 ... ' + sleep 1 + } + + menuentry '<-- Return to previous menu [Esc]' --class=vtoyret VTOY_RET { + echo 'Return ...' + } +} + +menuentry '<-- Return to previous menu [Esc]' --class=vtoyret VTOY_RET { + echo 'Return ...' +} diff --git a/INSTALL/tool/VentoyWorker.sh b/INSTALL/tool/VentoyWorker.sh index 9c6967b9..6f20a084 100644 --- a/INSTALL/tool/VentoyWorker.sh +++ b/INSTALL/tool/VentoyWorker.sh @@ -6,14 +6,14 @@ print_usage() { echo 'Usage: Ventoy2Disk.sh CMD [ OPTION ] /dev/sdX' echo ' CMD:' echo ' -i install ventoy to sdX (fail if disk already installed with ventoy)' - echo ' -u update ventoy in sdX' echo ' -I force install ventoy to sdX (no matter installed or not)' + echo ' -u update ventoy in sdX' echo '' echo ' OPTION: (optional)' echo ' -r SIZE_MB preserve some space at the bottom of the disk (only for install)' echo ' -s enable secure boot support (default is disabled)' + echo ' -g use GPT partition style, default is MBR (only for install)' echo '' - } RESERVE_SIZE_MB=0 @@ -27,6 +27,8 @@ while [ -n "$1" ]; do MODE="update" elif [ "$1" = "-s" ]; then SECUREBOOT="YES" + elif [ "$1" = "-g" ]; then + VTGPT="YES" elif [ "$1" = "-r" ]; then RESERVE_SPACE="YES" shift @@ -110,13 +112,22 @@ fi if [ "$MODE" = "install" ]; then vtdebug "install ventoy ..." - if parted -v > /dev/null 2>&1; then - PARTTOOL='parted' - elif fdisk -v >/dev/null 2>&1; then - PARTTOOL='fdisk' + if [ -n "$VTGPT" ]; then + if parted -v > /dev/null 2>&1; then + PARTTOOL='parted' + else + vterr "parted is not found in the sysstem, Ventoy can't create new partition." + exit 1 + fi else - vterr "Both parted and fdisk are not found in the sysstem, Ventoy can't create new partition." - exit 1 + if parted -v > /dev/null 2>&1; then + PARTTOOL='parted' + elif fdisk -v >/dev/null 2>&1; then + PARTTOOL='fdisk' + else + vterr "Both parted and fdisk are not found in the sysstem, Ventoy can't create new partition." + exit 1 + fi fi version=$(get_disk_ventoy_version $DISK) @@ -148,11 +159,15 @@ if [ "$MODE" = "install" ]; then fi fi - #Print disk info echo "Disk : $DISK" parted -s $DISK p 2>&1 | grep Model - echo "Size : $disk_size_gb GB" + echo "Size : $disk_size_gb GB" + if [ -n "$VTGPT" ]; then + echo "Style: GPT" + else + echo "Style: MBR" + fi echo '' if [ -n "$RESERVE_SPACE" ]; then @@ -192,7 +207,13 @@ if [ "$MODE" = "install" ]; then exit 1 fi - format_ventoy_disk $RESERVE_SIZE_MB $DISK $PARTTOOL + if [ -n "$VTGPT" ]; then + vtdebug "format_ventoy_disk_gpt $RESERVE_SIZE_MB $DISK $PARTTOOL ..." + format_ventoy_disk_gpt $RESERVE_SIZE_MB $DISK $PARTTOOL + else + vtdebug "format_ventoy_disk_mbr $RESERVE_SIZE_MB $DISK $PARTTOOL ..." + format_ventoy_disk_mbr $RESERVE_SIZE_MB $DISK $PARTTOOL + fi # format part1 if ventoy_is_linux64; then @@ -201,7 +222,9 @@ if [ "$MODE" = "install" ]; then cmd=./tool/mkexfatfs_32 fi - chmod +x ./tool/* + if [ -d ./tool/ ]; then + chmod +x -R ./tool/ + fi # DiskSize > 32GB Cluster Size use 128KB # DiskSize < 32GB Cluster Size use 32KB @@ -213,11 +236,18 @@ if [ "$MODE" = "install" ]; then $cmd -n ventoy -s $cluster_sectors ${DISK}1 - chmod +x ./tool/vtoy_gen_uuid - vtinfo "writing data to disk ..." + dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=446 - ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 + + if [ -n "$VTGPT" ]; then + echo -en '\x22' | dd status=none of=$DISK conv=fsync bs=1 count=1 seek=92 + ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34 + echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none + else + ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 + fi + ./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start_sector #disk uuid @@ -296,19 +326,28 @@ else SHORT_PART2=${PART2#/dev/} part2_start=$(cat /sys/class/block/$SHORT_PART2/start) - dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=440 + PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') - PART1_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=446 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') - PART2_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=462 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') + if [ "$PART1_TYPE" = "EE" ]; then + vtdebug "This is GPT partition style ..." + ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34 + echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none + else + vtdebug "This is MBR partition style ..." + dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=440 - vtdebug "PART1_ACTIVE=$PART1_ACTIVE PART2_ACTIVE=$PART2_ACTIVE" - if [ "$PART1_ACTIVE" = "00" ] && [ "$PART2_ACTIVE" = "80" ]; then - vtdebug "change 1st partition active, 2nd partition inactive ..." - echo -en '\x80' | dd of=$DISK conv=fsync bs=1 count=1 seek=446 status=none - echo -en '\x00' | dd of=$DISK conv=fsync bs=1 count=1 seek=462 status=none + PART1_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=446 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') + PART2_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=462 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') + + vtdebug "PART1_ACTIVE=$PART1_ACTIVE PART2_ACTIVE=$PART2_ACTIVE" + if [ "$PART1_ACTIVE" = "00" ] && [ "$PART2_ACTIVE" = "80" ]; then + vtdebug "change 1st partition active, 2nd partition inactive ..." + echo -en '\x80' | dd of=$DISK conv=fsync bs=1 count=1 seek=446 status=none + echo -en '\x00' | dd of=$DISK conv=fsync bs=1 count=1 seek=462 status=none + fi + ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 fi - - ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 + ./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start sync diff --git a/INSTALL/tool/ventoy_lib.sh b/INSTALL/tool/ventoy_lib.sh index 6fa869ae..78d93e9c 100644 --- a/INSTALL/tool/ventoy_lib.sh +++ b/INSTALL/tool/ventoy_lib.sh @@ -103,7 +103,7 @@ get_ventoy_version_from_cfg() { } is_disk_contains_ventoy() { - DISK=$1 + DISK=$1 PART1=$(get_disk_part_name $1 1) PART2=$(get_disk_part_name $1 2) @@ -126,12 +126,16 @@ is_disk_contains_ventoy() { return fi + PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') PART2_TYPE=$(dd if=$DISK bs=1 count=1 skip=466 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') - if [ "$PART2_TYPE" != "EF" ]; then - vtdebug "part2 type is $PART2_TYPE not EF" - ventoy_false - return - fi + + # if [ "$PART1_TYPE" != "EE" ]; then + # if [ "$PART2_TYPE" != "EF" ]; then + # vtdebug "part2 type is $PART2_TYPE not EF" + # ventoy_false + # return + # fi + # fi # PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') # if [ "$PART1_TYPE" != "07" ]; then @@ -185,7 +189,7 @@ get_disk_ventoy_version() { ventoy_false } -format_ventoy_disk() { +format_ventoy_disk_mbr() { reserve_mb=$1 DISK=$2 PARTTOOL=$3 @@ -218,7 +222,7 @@ format_ventoy_disk() { fi echo "" - echo "Create partitions on $DISK by $PARTTOOL ..." + echo "Create partitions on $DISK by $PARTTOOL in MBR style ..." if [ "$PARTTOOL" = "parted" ]; then vtdebug "format disk by parted ..." @@ -300,5 +304,103 @@ EOF } +format_ventoy_disk_gpt() { + reserve_mb=$1 + DISK=$2 + PARTTOOL=$3 + + PART1=$(get_disk_part_name $DISK 1) + PART2=$(get_disk_part_name $DISK 2) + + sector_num=$(cat /sys/block/${DISK#/dev/}/size) + + part1_start_sector=2048 + + if [ $reserve_mb -gt 0 ]; then + reserve_sector_num=$(expr $reserve_mb \* 2048 + 33) + part1_end_sector=$(expr $sector_num - $reserve_sector_num - $VENTOY_SECTOR_NUM - 1) + else + part1_end_sector=$(expr $sector_num - $VENTOY_SECTOR_NUM - 34) + fi + + part2_start_sector=$(expr $part1_end_sector + 1) + part2_end_sector=$(expr $part2_start_sector + $VENTOY_SECTOR_NUM - 1) + + export part2_start_sector + + vtdebug "part1_start_sector=$part1_start_sector part1_end_sector=$part1_end_sector" + vtdebug "part2_start_sector=$part2_start_sector part2_end_sector=$part2_end_sector" + + if [ -e $PART2 ]; then + echo "delete $PART2" + rm -f $PART2 + fi + + echo "" + echo "Create partitions on $DISK by $PARTTOOL in GPT style ..." + + vtdebug "format disk by parted ..." + parted -a none --script $DISK \ + mklabel gpt \ + unit s \ + mkpart Ventoy ntfs $part1_start_sector $part1_end_sector \ + mkpart VTOYEFI fat16 $part2_start_sector $part2_end_sector \ + set 2 msftdata on \ + set 2 hidden on \ + quit + + sync + + if ventoy_is_linux64; then + vtoygpt=./tool/vtoygpt_64 + else + vtoygpt=./tool/vtoygpt_32 + fi + + $vtoygpt -f $DISK + sync + + udevadm trigger >/dev/null 2>&1 + partprobe >/dev/null 2>&1 + sleep 3 + echo "Done" + + echo 'mkfs on disk partitions ...' + for i in 1 2 3 4 5 6 7; do + if [ -b $PART2 ]; then + break + else + echo "wait $PART2 ..." + sleep 1 + fi + done + + + if ! [ -b $PART2 ]; then + MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART2#/dev/}/dev) + echo "mknod -m 0660 $PART2 b $MajorMinor ..." + mknod -m 0660 $PART2 b $MajorMinor + + if ! [ -b $PART1 ]; then + MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART1#/dev/}/dev) + echo "mknod -m 0660 $PART1 b $MajorMinor ..." + mknod -m 0660 $PART1 b $MajorMinor + fi + fi + + echo "create efi fat fs $PART2 ..." + for i in 0 1 2 3 4 5 6 7 8 9; do + if mkfs.vfat -F 16 -n VTOYEFI $PART2; then + echo 'success' + break + else + echo "$? retry ..." + sleep 2 + fi + done +} + + + diff --git a/INSTALL/tool/vtoygpt_32 b/INSTALL/tool/vtoygpt_32 new file mode 100644 index 00000000..1916a57f Binary files /dev/null and b/INSTALL/tool/vtoygpt_32 differ diff --git a/INSTALL/tool/vtoygpt_64 b/INSTALL/tool/vtoygpt_64 new file mode 100644 index 00000000..e1501055 Binary files /dev/null and b/INSTALL/tool/vtoygpt_64 differ diff --git a/INSTALL/ventoy/7z/32/7za.exe b/INSTALL/ventoy/7z/32/7za.exe new file mode 100644 index 00000000..2bdd57d2 Binary files /dev/null and b/INSTALL/ventoy/7z/32/7za.exe differ diff --git a/INSTALL/ventoy/7z/64/7za.exe b/INSTALL/ventoy/7z/64/7za.exe new file mode 100644 index 00000000..9f27b20e Binary files /dev/null and b/INSTALL/ventoy/7z/64/7za.exe differ diff --git a/INSTALL/ventoy/ventoy.cpio b/INSTALL/ventoy/ventoy.cpio index 96816e8d..a6c4c460 100644 Binary files a/INSTALL/ventoy/ventoy.cpio and b/INSTALL/ventoy/ventoy.cpio differ diff --git a/INSTALL/ventoy/ventoy_unix.cpio b/INSTALL/ventoy/ventoy_unix.cpio new file mode 100644 index 00000000..0e65ebab Binary files /dev/null and b/INSTALL/ventoy/ventoy_unix.cpio differ diff --git a/INSTALL/ventoy/ventoy_x64.efi b/INSTALL/ventoy/ventoy_x64.efi index d9709732..df670586 100644 Binary files a/INSTALL/ventoy/ventoy_x64.efi and b/INSTALL/ventoy/ventoy_x64.efi differ diff --git a/INSTALL/ventoy/vtoyjump32.exe b/INSTALL/ventoy/vtoyjump32.exe index cc54475c..a2610ef0 100644 Binary files a/INSTALL/ventoy/vtoyjump32.exe and b/INSTALL/ventoy/vtoyjump32.exe differ diff --git a/INSTALL/ventoy/vtoyjump64.exe b/INSTALL/ventoy/vtoyjump64.exe index 9273282e..7881e63a 100644 Binary files a/INSTALL/ventoy/vtoyjump64.exe and b/INSTALL/ventoy/vtoyjump64.exe differ diff --git a/INSTALL/ventoy/vtoyutil_x64.efi b/INSTALL/ventoy/vtoyutil_x64.efi new file mode 100644 index 00000000..06bdae57 Binary files /dev/null and b/INSTALL/ventoy/vtoyutil_x64.efi differ diff --git a/INSTALL/ventoy_pack.sh b/INSTALL/ventoy_pack.sh index b17feeff..73eb819c 100644 --- a/INSTALL/ventoy_pack.sh +++ b/INSTALL/ventoy_pack.sh @@ -31,7 +31,7 @@ while ! grep -q 524288 /sys/block/${LOOP#/dev/}/size 2>/dev/null; do sleep 1 done -format_ventoy_disk 0 $LOOP fdisk +format_ventoy_disk_mbr 0 $LOOP fdisk $GRUB_DIR/sbin/grub-bios-setup --skip-fs-probe --directory="./grub/i386-pc" $LOOP @@ -62,7 +62,7 @@ cp -a ./tool/ENROLL_THIS_KEY_IN_MOKMANAGER.cer $tmpmnt/ mkdir -p $tmpmnt/tool cp -a ./tool/mount* $tmpmnt/tool/ -rm -f $tmpmnt/grub/i386-pc/* +rm -f $tmpmnt/grub/i386-pc/*.img umount $tmpmnt && rm -rf $tmpmnt @@ -77,7 +77,10 @@ dd if=$LOOP of=$tmpdir/boot/core.img bs=512 count=2047 skip=1 status=none xz --check=crc32 $tmpdir/boot/core.img cp -a ./tool $tmpdir/ +rm -f $tmpdir/ENROLL_THIS_KEY_IN_MOKMANAGER.cer cp -a Ventoy2Disk.sh $tmpdir/ +cp -a README $tmpdir/ +cp -a plugin $tmpdir/ cp -a CreatePersistentImg.sh $tmpdir/ dos2unix -q $tmpdir/Ventoy2Disk.sh dos2unix -q $tmpdir/CreatePersistentImg.sh @@ -104,10 +107,11 @@ cd $CurDir tar -czvf ventoy-${curver}-linux.tar.gz $tmpdir rm -f ventoy-${curver}-windows.zip -cp -a Ventoy2Disk.exe $tmpdir/ +cp -a Ventoy2Disk*.exe $tmpdir/ cp -a $LANG_DIR/languages.ini $tmpdir/ventoy/ rm -rf $tmpdir/tool rm -f $tmpdir/*.sh +rm -f $tmpdir/README zip -r ventoy-${curver}-windows.zip $tmpdir/ diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c index d3ccb2b4..fcc0c0e2 100644 --- a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c @@ -574,7 +574,7 @@ int ventoy_boot_vdisk(void *data) g_os_param_reserved = (uint8_t *)(g_chain->os_param.vtoy_reserved); /* Workaround for Windows & ISO9660 */ - if (g_os_param_reserved[2] == 1 && g_os_param_reserved[3] == 0) + if (g_os_param_reserved[2] == ventoy_chain_windows && g_os_param_reserved[3] == 0) { g_fixup_iso9660_secover_enable = 1; } diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h index 1898d7ac..286bb33c 100644 --- a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h @@ -13,6 +13,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #define VENTOY_GUID { 0x77772020, 0x2e77, 0x6576, { 0x6e, 0x74, 0x6f, 0x79, 0x2e, 0x6e, 0x65, 0x74 }} +typedef enum ventoy_chain_type +{ + ventoy_chain_linux = 0, /* 0: linux */ + ventoy_chain_windows, /* 1: windows */ + ventoy_chain_wim, /* 2: wim */ + + ventoy_chain_max +}ventoy_chain_type; + #pragma pack(1) typedef struct ventoy_guid diff --git a/LANGUAGES/languages.ini b/LANGUAGES/languages.ini index d08bfba0..e69de29b 100644 --- a/LANGUAGES/languages.ini +++ b/LANGUAGES/languages.ini @@ -1,1152 +0,0 @@ -[StringDefine] -0=STR_ERROR -1=STR_WARNING -2=STR_INFO -3=STR_INCORRECT_DIR -4=STR_INCORRECT_TREE_DIR -5=STR_DEVICE -6=STR_LOCAL_VER -7=STR_DISK_VER -8=STR_STATUS -9=STR_INSTALL -10=STR_UPDATE -11=STR_UPDATE_TIP -12=STR_INSTALL_TIP -13=STR_INSTALL_TIP2 -14=STR_INSTALL_SUCCESS -15=STR_INSTALL_FAILED -16=STR_UPDATE_SUCCESS -17=STR_UPDATE_FAILED -18=STR_WAIT_PROCESS -19=STR_MENU_OPTION -20=STR_MENU_SECURE_BOOT -21=STR_MENU_PART_CFG -22=STR_BTN_OK -23=STR_BTN_CANCEL -24=STR_PRESERVE_SPACE -25=STR_SPACE_VAL_INVALID -26=STR_MENU_CLEAR -27=STR_CLEAR_SUCCESS -28=STR_CLEAR_FAILED -29=STR_MENU_PART_STYLE -30=STR_DISK_2TB_MBR_ERROR - -; -; -; File encoding: UTF-16 (UCS-2 Little Endian) -; -; section name must in the format: [Language-XXX (YYY)] -; 1. Language- fixed 9 characters -; 2. XXX: name in English -; 3. a space (ASCII: 0x20) -; 4. a left brace (ASCII: 0x28) -; 5. YYY: name in the specified language -; 6. a right brace (ASCII: 0x29) -; -; string translation: -; all the String Define -; #@ will be replaced with \r\n -; -; All the languages will be sorted by the section name -; - -[Language-Arabic (العربية)] -FontFamily='Courier New' -FontSize=18 -Author=Omar Namis Mostafa - -STR_ERROR='خطأ' -STR_WARNING='تحذير' -STR_INFO='معلومات' -STR_INCORRECT_DIR='يرجى التشغيل من المسار الصحيح!' -STR_INCORRECT_TREE_DIR='لا تقم بالتشغيل من هنا، يرجى تحميل حزمة التثبيت، وتشغيلها من هناك.' -STR_DEVICE='الجهاز' -STR_LOCAL_VER='في الحزمة Ventoy' -STR_DISK_VER='في الجهاز Ventoy' -STR_STATUS='الحالة - جاهز' -STR_INSTALL='تثبيت' -STR_UPDATE='تحديث' -STR_UPDATE_TIP='عملية التحديث آمنة, لن يتم عمل تغييرات على ملفات الـISO.#@استمرار؟' -STR_INSTALL_TIP='سيتم تهيئة القرص وسيتم فقدان جميع البيانات.#@استمرار؟' -STR_INSTALL_TIP2='سيتم تهيئة القرص وسيتم فقدان جميع البيانات.#@استمرار؟ (التحقق مرة أخرى)' -STR_INSTALL_SUCCESS='مبروك!#@تم تثبيت Ventoy بنجاح على الجهاز.' -STR_INSTALL_FAILED='حدث خطأ أثناء التثبيت. يمكنك إعادة توصيل الـUSB والمحاولة مرة أخرى. تفقّد log.txt للتفاصيل.' -STR_UPDATE_SUCCESS='مبروك!#@تم تحديث Ventoy بنجاح على الجهاز.' -STR_UPDATE_FAILED='حدث خطأ أثناء التحديث. يمكنك إعادة توصيل الـUSB والمحاولة مرة أخرى. تفقّد log.txt للتفاصيل.' -STR_WAIT_PROCESS='هناك عملية نشطة، يرجى الانتظار...' -STR_MENU_OPTION='خيارات' -STR_MENU_SECURE_BOOT='تمهيد آمن' -STR_MENU_PART_CFG='تكوين التقسيم' -STR_BTN_OK='موافق' -STR_BTN_CANCEL='إلغاء' -STR_PRESERVE_SPACE='الحفاظ على بعض المساحة في الجزء السفلي من القرص' -STR_SPACE_VAL_INVALID='قيمة غير صالحة للمساحة المحجوزة' -STR_MENU_CLEAR='مسح Ventoy' -STR_CLEAR_SUCCESS='تمت إزالة Ventoy من الجهاز بنجاح.' -STR_CLEAR_FAILED='حدث خطأ عند مسح Ventoy من القرص. يمكنك إعادة توصيل الـUSB والمحاولة مرة أخرى. تفقد log.txt للتفاصيل.' -STR_MENU_PART_STYLE='أسلوب التقسيم' -STR_DISK_2TB_MBR_ERROR='يرجى اختيار GPT للقرص الأكبر من 2 تيرابايت' - - -[Language-Korean (한글)] -FontFamily='Courier New' -FontSize=16 -Author=Remiz - -STR_ERROR='에러' -STR_WARNING='경고' -STR_INFO='알림' -STR_INCORRECT_DIR='알맞은 위치에서 실행해 주세요.' -STR_INCORRECT_TREE_DIR='해당 위치에서 실행하기 위해선 설치 파일을 다운받아 설치해주시기 바랍니다.' -STR_DEVICE='USB 장치' -STR_LOCAL_VER='설치될 Ventoy 버전' -STR_DISK_VER='USB에 설치된 Ventoy 버전' -STR_STATUS='상태 - 준비완료' -STR_INSTALL='설치' -STR_UPDATE='업데이트' -STR_UPDATE_TIP='업데이트 시 ISO 파일은 지워지지 않습니다.#@계속 하시겠습니까?' -STR_INSTALL_TIP='USB 안의 모든 자료는 지워집니다!#@계속 하시겠습니까?' -STR_INSTALL_TIP2='USB 안의 모든 자료는 완전 지워집니다!#@정말 계속 하시겠습니까?' -STR_INSTALL_SUCCESS='축하합니다!#@Ventoy가 정상적으로 설치되었습니다.' -STR_INSTALL_FAILED='설치 중 에러가 발생했습니다. USB를 다른 포트에 꼽으신 후 다시 시도해 주세요. 에러 정보는 log.txt 파일을 참고해 주세요.' -STR_UPDATE_SUCCESS='축하합니다!#@USB의 Ventoy가 새버전으로 업데이트 되었습니다.' -STR_UPDATE_FAILED='업데이트 중 에러가 발생했습니다. USB를 다른 포트에 꼽으신 후 다시 시도해 주세요. 에러 정보는 log.txt 파일을 참고해 주세요.' -STR_WAIT_PROCESS='프로세스가 실행 중 입니다, 잠시 기다려주세요...' -STR_MENU_OPTION='옵션' -STR_MENU_SECURE_BOOT='Secure Boot' -STR_MENU_PART_CFG='파티션 설정' -STR_BTN_OK='확인' -STR_BTN_CANCEL='취소' -STR_PRESERVE_SPACE='USB에 예약 공간 설정' -STR_SPACE_VAL_INVALID='예약 공간 용량을 다시 설정해주세요' -STR_MENU_CLEAR='Ventoy 제거' -STR_CLEAR_SUCCESS='USB 장치에서 성공적으로 Ventoy를 제거하였습니다.' -STR_CLEAR_FAILED='Ventoy를 제거하던 중 오류가 발생되었습니다. USB를 다른 포트에 꼽은뒤 다시 시도해 주세요.' -STR_MENU_PART_STYLE='파티션 선택' -STR_DISK_2TB_MBR_ERROR='2TB가 초과하는 하드는 GPT를 선택해 주세요.' - -[Language-Chinese Simplified (简体中文)] -FontFamily='宋体' -FontSize=14 -Author=longpanda - -STR_ERROR='错误' -STR_WARNING='警告' -STR_INFO='提醒' -STR_INCORRECT_DIR='请在正确的目录下运行!' -STR_INCORRECT_TREE_DIR='请不要在代码树下运行此程序(INSTALL目录),请下载安装包,解压后在那里运行。' -STR_DEVICE='设备' -STR_LOCAL_VER='安装包内 Ventoy 版本' -STR_DISK_VER='设备内部 Ventoy 版本' -STR_STATUS='状态 - 准备就绪' -STR_INSTALL='安装' -STR_UPDATE='升级' -STR_UPDATE_TIP='升级操作是安全的, ISO文件不会丢失#@是否继续?' -STR_INSTALL_TIP='磁盘会被格式化, 所有数据都会丢失!#@是否继续?' -STR_INSTALL_TIP2='磁盘会被格式化, 所有数据都会丢失!#@再次确认是否继续?' -STR_INSTALL_SUCCESS='恭喜你! Ventoy 已经成功安装到此设备中.' -STR_INSTALL_FAILED='安装 Ventoy 过程中发生错误. 你可以重新拔插一下U盘然后重试一次, 详细信息请查阅 log.txt 文件.' -STR_UPDATE_SUCCESS='恭喜你! 新版本的 Ventoy 已经成功更新到此设备中.' -STR_UPDATE_FAILED='更新 Ventoy 过程中遇到错误. 你可以重新拔插一下U盘然后重试一次, 详细信息请查阅 log.txt 文件.' -STR_WAIT_PROCESS='当前有任务正在运行, 请等待...' -STR_MENU_OPTION='配置选项' -STR_MENU_SECURE_BOOT='安全启动支持' -STR_MENU_PART_CFG='分区设置' -STR_BTN_OK='确定' -STR_BTN_CANCEL='取消' -STR_PRESERVE_SPACE='在磁盘最后保留一段空间' -STR_SPACE_VAL_INVALID='保留空间的数值非法' -STR_MENU_CLEAR='清除 Ventoy' -STR_CLEAR_SUCCESS='Ventoy已经成功从此设备中清除.' -STR_CLEAR_FAILED='清除 Ventoy 过程中遇到错误. 你可以重新拔插一下U盘然后重试一次, 详细信息请查阅 log.txt 文件.' -STR_MENU_PART_STYLE='分区类型' -STR_DISK_2TB_MBR_ERROR='磁盘容量超过2TB,请选择GPT分区格式' - - -[Language-English (English)] -FontFamily='Courier New' -FontSize=16 -Author=longpanda - -STR_ERROR='Error' -STR_WARNING='Warning' -STR_INFO='Info' -STR_INCORRECT_DIR='Please run under the correct directory!' -STR_INCORRECT_TREE_DIR='Don't run me here, please download the released install package, and run there.' -STR_DEVICE='Device' -STR_LOCAL_VER='Ventoy In Package' -STR_DISK_VER='Ventoy In Device' -STR_STATUS='Status - READY' -STR_INSTALL='Install' -STR_UPDATE='Update' -STR_UPDATE_TIP='Upgrade operation is safe, ISO files will be unchanged.#@Continue?' -STR_INSTALL_TIP='The disk will be formatted and all the data will be lost.#@Continue?' -STR_INSTALL_TIP2='The disk will be formatted and all the data will be lost.#@Continue? (Double Check)' -STR_INSTALL_SUCCESS='Congratulations!#@Ventoy has been successfully installed to the device.' -STR_INSTALL_FAILED='An error occurred during the installation. You can replug the USB and try again. Check log.txt for detail.' -STR_UPDATE_SUCCESS='Congratulations!#@Ventoy has been successfully updated to the device.' -STR_UPDATE_FAILED='An error occurred during the update. You can replug the USB and try again. Check log.txt for detail.' -STR_WAIT_PROCESS='A thread is running, please wait...' -STR_MENU_OPTION='Option' -STR_MENU_SECURE_BOOT='Secure Boot Support' -STR_MENU_PART_CFG='Partition Configuration' -STR_BTN_OK='OK' -STR_BTN_CANCEL='Cancel' -STR_PRESERVE_SPACE='Preserve some space at the bottom of the disk' -STR_SPACE_VAL_INVALID='Invalid value for reserved space' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Persian (فارسی)] -FontFamily='Courier New' -FontSize=16 -Author=ivadham - -STR_ERROR='خطا' -STR_WARNING='هشدار' -STR_INFO='توضیحات' -STR_INCORRECT_DIR='.لطفاً در پوشه‌دان صحیح اجرا کنید' -STR_INCORRECT_TREE_DIR='.این‌جا اجرا نکنید، لطفاً بستهٔ نصب را دانلود و آن‌جا اجرا کنید' -STR_DEVICE='حافظهٔ قابل حمل' -STR_LOCAL_VER='آمادهٔ نصب Ventoy' -STR_DISK_VER='نصب‌شده روی حافظه Ventoy' -STR_STATUS='وضعیت - آماده' -STR_INSTALL='فرمت و نصب' -STR_UPDATE='به‌روزرسانی' -STR_UPDATE_TIP='عملیات به‌روزرسانی بی‌خطر است و داده‌های روی حافظهٔ قابل حمل سالم باقی خواهند ماند. ادامه؟' -STR_INSTALL_TIP='حافظهٔ قابل حمل فرمت و تمامی داده‌های آن پاک خواهد شد. ادامه؟' -STR_INSTALL_TIP2='توجه: این عملیات غیرقابل بازگشت است. ادامه؟' -STR_INSTALL_SUCCESS='.تبریک! عملیات نصب بر روی حافظهٔ قابل حمل با موفقیت پایان یافت' -STR_INSTALL_FAILED='.خطا در عملیات نصب! یو‌اس‌بی را از نو متصل و دوباره تلاش کنید' -STR_UPDATE_SUCCESS='.تبریک! نرم‌افزار با موفقیت بر روی حافظهٔ قابل حمل به‌روزرسانی شد' -STR_UPDATE_FAILED='.خطا در به‌روزرسانی! یو‌اس‌بی را از نو متصل و دوباره تلاش کنید' -STR_WAIT_PROCESS='...پروسه‌ای در حال اجرا است، لطفاً صبر کنید' -STR_MENU_OPTION='تنظیمات' -STR_MENU_SECURE_BOOT='(Secure Boot) بوت امن' -STR_MENU_PART_CFG='پیکربندی پارتیشن' -STR_BTN_OK='تأیید' -STR_BTN_CANCEL='انصراف' -STR_PRESERVE_SPACE='اختصاص مقداری فضا به انتهای حافظهٔ قابل حمل' -STR_SPACE_VAL_INVALID='.این مقدار فضا برای اختصاص‌یافتن نامعتبر است' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Polish (Polski)] -FontFamily='Courier New' -FontSize=16 -Author=B.O.S.S - -STR_ERROR='Błąd' -STR_WARNING='Ostrzeżenie' -STR_INFO='Informacja' -STR_INCORRECT_DIR='Proszę uruchom w odpowiednim katalogu!' -STR_INCORRECT_TREE_DIR='Nie uruchamiaj mnie tutaj, pobierz pakiet instalacyjny i uruchom go.' -STR_DEVICE='Urządzenie' -STR_LOCAL_VER='Ventoy w programie' -STR_DISK_VER='Ventoy na urządzeniu' -STR_STATUS='Status - GOTOWY' -STR_INSTALL='Zainstaluj' -STR_UPDATE='Zaktualizuj' -STR_UPDATE_TIP='Operacja aktualizacji jest bezpieczna, pliki ISO pozostaną niezmienione.#@Kontynuować?' -STR_INSTALL_TIP='Dysk zostanie sformatowany, a wszystkie dane zostaną utracone.#@Kontynuować?' -STR_INSTALL_TIP2='Dysk zostanie sformatowany, a wszystkie dane zostaną utracone.#@Kontynuować? (Podwójne sprawdzenie)' -STR_INSTALL_SUCCESS='Gratulacje!#@Ventoy został pomyślnie zainstalowany na urządzeniu.' -STR_INSTALL_FAILED='Wystąpił błąd podczas instalacji. Możesz ponownie podłączyć USB i spróbować jeszcze raz. Szczegóły w log.txt.' -STR_UPDATE_SUCCESS='Gratulacje!#@Ventoy zostało pomyślnie zaktualizowane na urządzeniu.' -STR_UPDATE_FAILED='Wystąpił błąd podczas aktualizacji. Możesz ponownie podłączyć USB i spróbować jeszcze raz. Szczegóły w log.txt.' -STR_WAIT_PROCESS='Wątek jest uruchomiony, proszę czekać...' -STR_MENU_OPTION='Opcje' -STR_MENU_SECURE_BOOT='Bezpieczny rozruch/Secure Boot' -STR_MENU_PART_CFG='Konfiguracja partycji' -STR_BTN_OK='OK' -STR_BTN_CANCEL='Anuluj' -STR_PRESERVE_SPACE='Zachowaj trochę miejsca na dole dysku' -STR_SPACE_VAL_INVALID='Nieprawidłowa wartość zarezerwowanego miejsca' -STR_MENU_CLEAR='Wyczyść Ventoy' -STR_CLEAR_SUCCESS='Ventoy został pomyślnie usunięty z urządzenia.' -STR_CLEAR_FAILED='Wystąpił błąd podczas usuwania Ventoy z dysku. Możesz podłączyć USB i spróbować jeszcze raz. Szczegóły w log.txt.' -STR_MENU_PART_STYLE='Schemat partycji' -STR_DISK_2TB_MBR_ERROR='Wybierz GPT dla dysku powyżej 2TB' - - -[Language-Portuguese Brazilian (Português do Brasil)] -FontFamily='Courier New' -FontSize=16 -Author=EstevaoCostaG3 - -STR_ERROR='Erro' -STR_WARNING='Atenção' -STR_INFO='Info' -STR_INCORRECT_DIR='Por favor, execute no diretório correto!' -STR_INCORRECT_TREE_DIR='Não me execute aqui, por favor baixe o pacote de instalação lançado, e me execute lá.' -STR_DEVICE='Dispositivo' -STR_LOCAL_VER='Ventoy em pacote' -STR_DISK_VER='Ventoy em dispositivo' -STR_STATUS='Status - PRONTO' -STR_INSTALL='Instalar' -STR_UPDATE='Atualizar' -STR_UPDATE_TIP='A operação de atualização é segura, os arquivos ISO não serão alterados.#@Continuar?' -STR_INSTALL_TIP='O disco será formatado e todos os dados serão perdidos.#@Continuar?' -STR_INSTALL_TIP2='O disco será formatado e todos os dados serão perdidos.#@Continuar? (Double Check)' -STR_INSTALL_SUCCESS='Parabéns!#@Ventoy foi instalado com sucesso no dispositivo.' -STR_INSTALL_FAILED='Um erro ocorreu durante a instalação. Você pode reconectar o dispositivo USB e tentar novamente. Verifique o arquivo log.txt para mais detalhes.' -STR_UPDATE_SUCCESS='Parabéns!#@Ventoy foi atualizado com sucesso no dispositivo.' -STR_UPDATE_FAILED='Um erro ocorreu durante a atualização. Você pode reconectar o dispositivo USB e tentar novamente. Verifique o arquivo log.txt para mais detalhes.' -STR_WAIT_PROCESS='Uma thread está em execução, por favor espere...' -STR_MENU_OPTION='Opção' -STR_MENU_SECURE_BOOT='Boot seguro' -STR_MENU_PART_CFG='Partition Configuration' -STR_BTN_OK='OK' -STR_BTN_CANCEL='Cancel' -STR_PRESERVE_SPACE='Preserve some space at the bottom of the disk' -STR_SPACE_VAL_INVALID='Invalid value for reserved space' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Turkish (Türkçe)] -FontFamily='Courier New' -FontSize=16 -Author=Erhan Kültür/crasadure - -STR_ERROR='Hata' -STR_WARNING='Uyarı' -STR_INFO='Bilgi' -STR_INCORRECT_DIR='Lütfen doğru dizin altında çalıştırın!' -STR_INCORRECT_TREE_DIR='Dosyayı burada çalıştırma, lütfen yayınlanan en son kurulum paketini indirin ve oradan çalıştırın.' -STR_DEVICE='Aygıt' -STR_LOCAL_VER='Ventoy GÜNCEL Sürüm' -STR_DISK_VER='Cihazdaki Ventoy Sürümü' -STR_STATUS='Durum - HAZIR' -STR_INSTALL='Kur' -STR_UPDATE='Güncelle' -STR_UPDATE_TIP='Ventoyun versiyon bilgisi güncellenecek, ISO dosyalarınız bundan etkilenmiyecek.#@Devam edilsinmi?' -STR_INSTALL_TIP='Disk biçimlendirilecek ve tüm veriler kaybolacak.#@Devam edilsinmi?' -STR_INSTALL_TIP2='Disk biçimlendirilecek ve tüm veriler kaybolacak.#@Devam edilsinmi? (Son UYARI!)' -STR_INSTALL_SUCCESS='Tebrikler!#@ventoy cihaza başarıyla kuruldu.' -STR_INSTALL_FAILED='Yükleme sırasında bir hata oluştu. USB'yi yeniden takıp tekrar deneyebilirsiniz. Ayrıntılar için log.txt dosyasına bakın.' -STR_UPDATE_SUCCESS='Tebrikler!#@ventoy cihazda başarıyla güncellendi.' -STR_UPDATE_FAILED='Güncelleme sırasında bir hata oluştu. USB'yi yeniden takıp tekrar deneyebilirsiniz. Ayrıntılar için log.txt dosyasına bakın.' -STR_WAIT_PROCESS='Mevcut işlem çalışıyor, lütfen bekleyiniz ...' -STR_MENU_OPTION='Seçenek' -STR_MENU_SECURE_BOOT='Güvenli Önyükleme' -STR_MENU_PART_CFG='Partisyon Yapılandırması' -STR_BTN_OK='Tamam' -STR_BTN_CANCEL='İptal et' -STR_PRESERVE_SPACE='Diskin sonunda ayrılmış disk partisyonu oluştur' -STR_SPACE_VAL_INVALID='Ayrılmış alan için geçersiz değer girdiniz' -STR_MENU_CLEAR='Ventoyu USB Diskten Sil' -STR_CLEAR_SUCCESS='Ventoy başarılı bir şekilde diskten silindi' -STR_CLEAR_FAILED='Ventoy USB diskten temizlenirken bir hata oluştu.Lütfen USB Diski tekrar takın ve tekrar deneyin.Hatanın detayları için Log.txt dosyasını okuyun' -STR_MENU_PART_STYLE='Partisyon Yapısı' -STR_DISK_2TB_MBR_ERROR='2TB üstündeki diskler için lütfen GPT disk yapısını seçiniz.' - - - -[Language-German (Deutsch)] -FontFamily='Courier New' -FontSize=16 -Author=luzea -STR_ERROR='Fehler' -STR_WARNING='Warnung' -STR_INFO='Info' -STR_INCORRECT_DIR='Bitte im richtigen Verzeichnis ausführen!' -STR_INCORRECT_TREE_DIR='Bitte nicht hier ausführen. Laden Sie das Installationspaket herunter und von dort aus ausführen.' -STR_DEVICE='Gerät' -STR_LOCAL_VER='Ventoy (lokal)' -STR_DISK_VER='Ventoy (Gerät)' -STR_STATUS='Status - BEREIT' -STR_INSTALL='Installieren' -STR_UPDATE='Aktualisieren' -STR_UPDATE_TIP='Die Aktualisierung ist sicher, ISO-Dateien bleiben unverändert.#@Fortfahren?' -STR_INSTALL_TIP='Das Gerät wird formatiert und alle Daten gehen verloren.#@Fortfahren?' -STR_INSTALL_TIP2='Das Gerät wird formatiert und alle Daten gehen verloren.#@Fortfahren? (erneute Überprüfung)' -STR_INSTALL_SUCCESS='Herzlichen Glückwunsch!#@Ventoy wurde erfolgreich auf dem Gerät installiert.' -STR_INSTALL_FAILED='Während der Installation ist ein Fehler aufgetreten. Stecken Sie das Gerät neu ein und versuchen Sie es erneut. Überprüfen Sie die log.txt auf Details.' -STR_UPDATE_SUCCESS='Herzlichen Glückwunsch!#@Ventoy wurde erfolgreich auf dem Gerät aktualisiert.' -STR_UPDATE_FAILED='Während der Aktualisierung ist ein Fehler aufgetreten. Stecken Sie das Gerät neu ein und versuchen Sie es erneut. Überprüfen sie die log.txt auf Details.' -STR_WAIT_PROCESS='Ein anderer Thread läuft, bitte warten...' -STR_MENU_OPTION='Option' -STR_MENU_SECURE_BOOT='Secure Boot' -STR_MENU_PART_CFG='Partitionskonfiguration' -STR_BTN_OK='OK' -STR_BTN_CANCEL='Stornieren' -STR_PRESERVE_SPACE='Bewahren Sie etwas Platz am unteren Rand der Festplatte auf' -STR_SPACE_VAL_INVALID='Ungültiger Wert für reservierten Speicherplatz' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Occitan (Occitan)] -FontFamily='Courier New' -FontSize=16 -Author=quentin - -STR_ERROR='Error' -STR_WARNING='Avertiment' -STR_INFO='Info' -STR_INCORRECT_DIR='Aqueste programa deu s’executar dins lo bon repertòri!' -STR_INCORRECT_TREE_DIR='Ne me lancez pas d'ici, veuillez télécharger le programme d'installation et relancez-le.' -STR_DEVICE='Periferic' -STR_LOCAL_VER='Ventoy en local' -STR_DISK_VER='Ventoy sul periferic' -STR_STATUS='Estat - prèst' -STR_INSTALL='Installacion' -STR_UPDATE='Mesa a jorn' -STR_UPDATE_TIP='La mesa a jorn es segura, los fichièrs ISO seràn pas modificats.#@Continhar ?' -STR_INSTALL_TIP='Lo disc serà formatat e totas sas donadas seràn perdudas.#@Continhar ?' -STR_INSTALL_TIP2='Le disque va être formaté et toutes ses données seront perdues.#@Continuer? (confirmation)' -STR_INSTALL_SUCCESS='Felicitacions !#@Ventoy es estat corrèctament installat sul periferic.' -STR_INSTALL_FAILED='Una error s’es producha pendent l’installacion. Podètz tornar brancar lo periferic USB e tornar ensajar. Agachatz lo fichièr log.txt per ne saber mai.' -STR_UPDATE_SUCCESS='Felicitacions !#@Ventoy es estat corrèctament mes a jorn sul periferic.' -STR_UPDATE_FAILED='Una error s’es producha pendent la mesa a jorn. Podètz tornar brancar lo periferic USB e tornar ensajar. Agachatz lo fichièr log.txt per ne saber mai.' -STR_WAIT_PROCESS='Una operacion es en cors, esperatz...' -STR_MENU_OPTION='Opcion' -STR_MENU_SECURE_BOOT='Secure Boot' -STR_MENU_PART_CFG='Partition Configuration' -STR_BTN_OK='OK' -STR_BTN_CANCEL='Cancel' -STR_PRESERVE_SPACE='Preserve some space at the bottom of the disk' -STR_SPACE_VAL_INVALID='Invalid value for reserved space' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-French (Français)] -FontFamily='Courier New' -FontSize=16 -Author=vboucard - -STR_ERROR='Erreur' -STR_WARNING='Avertissement' -STR_INFO='Info' -STR_INCORRECT_DIR='Ce programme doit s'exécuter dans le bon répertoire !' -STR_INCORRECT_TREE_DIR='Ne me lancez pas d'ici, veuillez télécharger le programme d'installation et relancez-le.' -STR_DEVICE='Périphérique' -STR_LOCAL_VER='Ventoy en local' -STR_DISK_VER='Ventoy sur le périphérique' -STR_STATUS='Etat - prêt' -STR_INSTALL='Installation' -STR_UPDATE='Mise à jour' -STR_UPDATE_TIP='La mise à jour est sûre, les fichiers ISO ne seront pas modifiés.#@Continuer?' -STR_INSTALL_TIP='Le disque va être formaté et toutes ses données seront perdues.#@Continuer?' -STR_INSTALL_TIP2='Le disque va être formaté et toutes ses données seront perdues.#@Continuer? (confirmation)' -STR_INSTALL_SUCCESS='Félicitations !#@Ventoy a été correctement installé sur le périphérique.' -STR_INSTALL_FAILED='Une erreur est survenue durant l'installation. Vous pouvez rebrancher le périphérique USB et réessayer. Vérifiez le fichier log.txt pour plus de détails.' -STR_UPDATE_SUCCESS='Félicitations !#@Ventoy a été correctement mis à jour sur le périphérique.' -STR_UPDATE_FAILED='Une erreur est survenue durant la mise à jour. Vous pouvez rebrancher le périphérique USB et réessayer. Vérifiez le fichier log.txt pour plus de détails.' -STR_WAIT_PROCESS='Une opération est en cours, veuillez patienter...' -STR_MENU_OPTION='Option' -STR_MENU_SECURE_BOOT='Secure Boot' -STR_MENU_PART_CFG='Configuration de partition' -STR_BTN_OK='D'accord' -STR_BTN_CANCEL='Annuler' -STR_PRESERVE_SPACE='Préservez de l'espace au bas du disque' -STR_SPACE_VAL_INVALID='Valeur non valide pour l'espace réservé' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Czech (Čeština)] -FontFamily='Courier New' -FontSize=16 -Author=vavanade - -STR_ERROR='Chyba' -STR_WARNING='Varování' -STR_INFO='Info' -STR_INCORRECT_DIR='Spusťte prosím ve správném adresáři!' -STR_INCORRECT_TREE_DIR='Nespouštějte mě zde, stáhněte si prosím vydaný instalační balík a spusťte v něm.' -STR_DEVICE='Zařízení' -STR_LOCAL_VER='Ventoy v balíčku' -STR_DISK_VER='Ventoy v zařízení' -STR_STATUS='Status - PŘIPRAVENO' -STR_INSTALL='Instalovat' -STR_UPDATE='Aktualizovat' -STR_UPDATE_TIP='Operace aktualizace je bezpečná, ISO soubory nebudou změněny.#@Pokračovat?' -STR_INSTALL_TIP='Disk bude zformátován a všechna data budou ztracena!#@Pokračovat?' -STR_INSTALL_TIP2='Disk bude zformátován a všechna data budou ztracena!#@Pokračovat? (druhá kontrola)' -STR_INSTALL_SUCCESS='Gratulujeme!#@Ventoy byla na zařízení úspěšně nainstalována.' -STR_INSTALL_FAILED='V průběhu instalace se vyskytla chyba. Můžete vyjmout a znovu zastrčit USB zařízení a zkusit to znovu. Pro podrobnosti se podívejte do souboru log.txt.' -STR_UPDATE_SUCCESS='Gratulujeme!#@Ventoy byla na zařízení úspěšně aktualizována.' -STR_UPDATE_FAILED='V průběhu aktualizace se vyskytla chyba. Můžete vyjmout a znovu zastrčit USB zařízení a zkusit to znovu. Pro podrobnosti se podívejte do souboru log.txt.' -STR_WAIT_PROCESS='Vlákno běží, prosíme vyčkejte...' -STR_MENU_OPTION='Možnosti' -STR_MENU_SECURE_BOOT='Secure Boot' -STR_MENU_PART_CFG='Konfigurace oddílu' -STR_BTN_OK='OK' -STR_BTN_CANCEL='zrušení' -STR_PRESERVE_SPACE='Zachovejte místo na spodní straně disku' -STR_SPACE_VAL_INVALID='Neplatná hodnota pro vyhrazený prostor' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Spanish (Español)] -FontFamily='Courier New' -FontSize=16 -Author=Carlos Sánchez - -STR_ERROR='Error' -STR_WARNING='Advertencia' -STR_INFO='Info' -STR_INCORRECT_DIR='¡Por favor, ejecute bajo el directorio correcto!' -STR_INCORRECT_TREE_DIR='No me ejecute aquí, descargue el paquete de instalación publicado y ejecute allí.' -STR_DEVICE='Dispositivo' -STR_LOCAL_VER='Ventoy en Paquete' -STR_DISK_VER='Ventoy en Dispositivo' -STR_STATUS='Estado - LISTO' -STR_INSTALL='Instalar' -STR_UPDATE='Actualizar' -STR_UPDATE_TIP='La operación de actualización es segura, Los archivos ISO no se modificarán.#@¿Continuar?' -STR_INSTALL_TIP='El disco se formateará y se perderán todos los datos.#@¿Continuar?' -STR_INSTALL_TIP2='El disco se formateará y se perderán todos los datos.#@¿Continuar? (Doble verificación)' -STR_INSTALL_SUCCESS='¡Felicidades!#@Ventoy se ha instalado correctamente en el dispositivo.' -STR_INSTALL_FAILED='Se produjo un error durante la instalación. Puede volver a conectar el USB e intentar nuevamente. Verifique log.txt para detalles.' -STR_UPDATE_SUCCESS='¡Felicidades!#@Ventoy ha sido actualizado con éxito al dispositivo.' -STR_UPDATE_FAILED='Se produjo un error durante la actualización. Puede volver a conectar el USB e intentar nuevamente. Verifique log.txt para detalles.' -STR_WAIT_PROCESS='Un hilo se está ejecutando, por favor espere...' -STR_MENU_OPTION='Opción' -STR_MENU_SECURE_BOOT='Arranque Seguro' -STR_MENU_PART_CFG='Configuración de partición' -STR_BTN_OK='Okay' -STR_BTN_CANCEL='Cancelar' -STR_PRESERVE_SPACE='Conservar espacio en la parte inferior del disco' -STR_SPACE_VAL_INVALID='Valor inválido para espacio reservado' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Russian (Pусский)] -FontFamily='Courier New' -FontSize=16 -Author=BL4CKH47H4CK3R - -STR_ERROR='Ошибка' -STR_WARNING='Предупреждение' -STR_INFO='Информация' -STR_INCORRECT_DIR='Пожалуйста, запустите в другом каталоге!' -STR_INCORRECT_TREE_DIR='Не запускайте меня здесь, пожалуйста, загрузите выпущенный установочный пакет и запустите его в другом месте.' -STR_DEVICE='Устройство' -STR_LOCAL_VER='Ventoy в пакете' -STR_DISK_VER='Ventoy на устройстве' -STR_STATUS='Статус - ГОТОВ' -STR_INSTALL='Установить' -STR_UPDATE='Обновить' -STR_UPDATE_TIP='Обновление безопасно, ISO-файлы останутся без изменений.#@Продолжить?' -STR_INSTALL_TIP='Диск будет отформатирован и все данные будут потеряны.#@Продолжить?' -STR_INSTALL_TIP2='Диск будет отформатирован и все данные будут потеряны.#@Вы ДЕЙСТВИТЕЛЬНО хотите продолжить?' -STR_INSTALL_SUCCESS='Поздравляем!#@Ventoy был успешно установлен на устройство.' -STR_INSTALL_FAILED='Во время установки Ventoy произошла ошибка. Переподключите устройство и попробуйте снова. Проверьте log.txt на ошибки.' -STR_UPDATE_SUCCESS='Поздравляем!#@Ventoy был успешно обновлен на устройстве.' -STR_UPDATE_FAILED='Во время обновления Ventoy произошла ошибка. Переподключите устройство и попробуйте снова. Проверьте log.txt на ошибки.' -STR_WAIT_PROCESS='Процесс запущен, пожалуйста подождите...' -STR_MENU_OPTION='Опции' -STR_MENU_SECURE_BOOT='Поддержка Secure Boot' -STR_MENU_PART_CFG='Дополнительный раздел' -STR_BTN_OK='ОК' -STR_BTN_CANCEL='Отмена' -STR_PRESERVE_SPACE='Создать дополнительный раздел в конце диска' -STR_SPACE_VAL_INVALID='Неверное значение размера раздела' -STR_MENU_CLEAR='Удалить Ventoy' -STR_CLEAR_SUCCESS='Ventoy был успешно удалён с устройства.' -STR_CLEAR_FAILED='Во время удаления Ventoy произошла ошибка. Переподключите устройство и попробуйте снова. Проверьте log.txt на ошибки.' -STR_MENU_PART_STYLE='Стиль разметки разделов' -STR_DISK_2TB_MBR_ERROR='Пожалуйста, выберите GPT для дисков более 2ТБ' - - -[Language-Bengali (বাংলা)] -FontFamily='Courier New' -FontSize=16 -Author=BL4CKH47H4CK3R - -STR_ERROR='ত্রুটি' -STR_WARNING='সতর্কতা' -STR_INFO='তথ্য' -STR_INCORRECT_DIR='দয়া করে সঠিক ডিরেক্টরিতে চালান!' -STR_INCORRECT_TREE_DIR='আমাকে এখানে চালাবেন না, দয়া করে প্রকাশিত ইনস্টল প্যাকেজটি ডাউনলোড করুন এবং সেখানে চালান।' -STR_DEVICE='ডিভাইস' -STR_LOCAL_VER='Ventoy প্যাকেজে আছে' -STR_DISK_VER='Ventoy ডিভাইসে আছে' -STR_STATUS='স্থিতি - প্রস্তুত' -STR_INSTALL='ইনস্টল করুন' -STR_UPDATE='আপডেট করুন' -STR_UPDATE_TIP='আপগ্রেড অপারেশন নিরাপদ, ISO ফাইলগুলি অপরিবর্তিত থাকবে।#@চালিয়ে যাবেন?' -STR_INSTALL_TIP='ডিস্কটি ফর্ম্যাট করা হবে এবং সমস্ত ডেটা হারিয়ে যাবে।#@চালিয়ে যাবেন?' -STR_INSTALL_TIP2='ডিস্কটি ফর্ম্যাট করা হবে এবং সমস্ত ডেটা হারিয়ে যাবে।#@চালিয়ে যাবেন? (পুনঃনিরীক্ষণ)' -STR_INSTALL_SUCCESS='অভিনন্দন! #@Ventoy সফলভাবে ডিভাইসে ইনস্টল করা হয়েছে।' -STR_INSTALL_FAILED='ইনস্টলেশন চলাকালীন একটি ত্রুটি ঘটেছে। আপনি USB পুনরায় প্লাগ করতে পারেন এবং আবার চেষ্টা করতে পারেন। বিস্তারিত জানার জন্য log.txt পরীক্ষা করুন।' -STR_UPDATE_SUCCESS='অভিনন্দন! #@Ventoy সফলভাবে ডিভাইসে আপডেট করা হয়েছে।' -STR_UPDATE_FAILED='আপডেটের সময় একটি ত্রুটি ঘটেছে। আপনি USB পুনরায় প্লাগ করতে পারেন এবং আবার চেষ্টা করতে পারেন। বিস্তারিত জানার জন্য log.txt পরীক্ষা করুন।' -STR_WAIT_PROCESS='একটি থ্রেড চলছে, দয়া করে অপেক্ষা করুন ...' -STR_MENU_OPTION='অপসন' -STR_MENU_SECURE_BOOT='নিরাপদ বুট' -STR_MENU_PART_CFG='পার্টিশন কনফিগারেশন' -STR_BTN_OK='ঠিক আছে' -STR_BTN_CANCEL='বাতিল' -STR_PRESERVE_SPACE='ডিস্কের নীচে কিছু স্থান সংরক্ষণ করুন' -STR_SPACE_VAL_INVALID='সংরক্ষিত জায়গার জন্য অবৈধ মান' -STR_MENU_CLEAR='Ventoy সাফ' -STR_CLEAR_SUCCESS='Ventoy সফলভাবে ডিভাইস থেকে সরানো হয়েছে।' -STR_CLEAR_FAILED='ডিস্ক থেকে Ventoy সাফ করার সময় একটি ত্রুটি ঘটেছে। আপনি USB পুনরায় প্লাগ করতে পারেন এবং আবার চেষ্টা করতে পারেন। বিস্তারিত জানার জন্য log.txt পরীক্ষা করুন।' -STR_MENU_PART_STYLE='পার্টিশন স্টাইল' -STR_DISK_2TB_MBR_ERROR='2TB এর বেশি ডিস্কের জন্য দয়া করে GPT নির্বাচন করুন' - - -[Language-Hindi (हिन्दी)] -FontFamily='Courier New' -FontSize=16 -Author=BL4CKH47H4CK3R - -STR_ERROR='त्रुटि' -STR_WARNING='चेतावनी' -STR_INFO='जानकारी' -STR_INCORRECT_DIR='कृपया सही निर्देशिका के तहत चलाएं!' -STR_INCORRECT_TREE_DIR='मुझे यहां न चलाएं, कृपया जारी किए गए इंस्टॉल पैकेज को डाउनलोड करें, और वहां चलाएं।' -STR_DEVICE='डिवाइस' -STR_LOCAL_VER='पैकेज में Ventoy' -STR_DISK_VER='डिवाइस में Ventoy' -STR_STATUS='स्थिति - तैयार' -STR_INSTALL='इंस्टॉल' -STR_UPDATE='अपडेट करें' -STR_UPDATE_TIP='नवीनीकरण ऑपरेशन सुरक्षित है, ISO फाइल अपरिवर्तित रहेंगी।#@जारी रखें?' -STR_INSTALL_TIP='डिस्क को स्वरूपित किया जाएगा और सभी डेटा खो जाएगा।#@जारी रखें?' -STR_INSTALL_TIP2='डिस्क को स्वरूपित किया जाएगा और सभी डेटा खो जाएगा।#@जारी रखें? (दोहरी जाँच)' -STR_INSTALL_SUCCESS='बधाई! #@Ventoy डिवाइस में सफलतापूर्वक स्थापित किया गया है।' -STR_INSTALL_FAILED='स्थापना के दौरान एक त्रुटि हुई। आप USB को पुन: स्थापित कर सकते हैं और पुनः प्रयास कर सकते हैं। विस्तार के लिए log.txt की जाँच करें।' -STR_UPDATE_SUCCESS='बधाई! #@Ventoy डिवाइस में सफलतापूर्वक अपडेट हो गई है।' -STR_UPDATE_FAILED='अपडेट के दौरान एक त्रुटि हुई। आप USB को पुन: भर सकते हैं और पुनः प्रयास कर सकते हैं। विस्तार के लिए log.txt की जाँच करें।' -STR_WAIT_PROCESS='एक धागा चल रहा है, कृपया प्रतीक्षा करें ...' -STR_MENU_OPTION='विकल्प' -STR_MENU_SECURE_BOOT='सुरक्षित बूट' -STR_MENU_PART_CFG='विभाजन विन्यास' -STR_BTN_OK='ठीक है' -STR_BTN_CANCEL='रद्द करना' -STR_PRESERVE_SPACE='डिस्क के निचले भाग में कुछ स्थान सुरक्षित रखें' -STR_SPACE_VAL_INVALID='आरक्षित स्थान के लिए अमान्य मान' -STR_MENU_CLEAR='Ventoy को हटा दें' -STR_CLEAR_SUCCESS='डिवाइस से Ventoy को सफलतापूर्वक हटा दिया गया है।' -STR_CLEAR_FAILED='डिस्क से Ventoy को साफ़ करते समय एक त्रुटि हुई। आप USB को पुन: भर सकते हैं और पुनः प्रयास कर सकते हैं। विस्तार के लिए log.txt की जाँच करें। -STR_MENU_PART_STYLE='विभाजन शैली' -STR_DISK_2TB_MBR_ERROR='कृपया 2TB से अधिक डिस्क के लिए GPT का चयन करें' - - -[Language-Dutch (Nederlands)] -FontFamily='Courier New' -FontSize=16 -Author=UmitCanbolat - -STR_ERROR='Fout' -STR_WARNING='Waarschuwing' -STR_INFO='Info' -STR_INCORRECT_DIR='Voer Ventoy uit in de juiste directory!' -STR_INCORRECT_TREE_DIR='Ventoy kan hier niet worden uitgevoerd. Download het installatiepakket en probeer Ventoy daarmee te starten.' -STR_DEVICE='Apparaat' -STR_LOCAL_VER='Ventoy in pakket' -STR_DISK_VER='Ventoy op apparaat' -STR_STATUS='Status - GEREED' -STR_INSTALL='Installeren' -STR_UPDATE='Bijwerken' -STR_UPDATE_TIP='Upgraden is veilig: ISO-bestanden blijven ongewijzigd.#@Doorgaan?' -STR_INSTALL_TIP='De schijf wordt geformatteerd en alle gegevens gaan verloren.#@Doorgaan?' -STR_INSTALL_TIP2='De schijf wordt geformatteerd en alle gegevens gaan verloren.#@Doorgaan? (Dubbelcheck)' -STR_INSTALL_SUCCESS='Gefeliciteerd!#@Ventoy is met succes op het apparaat geïnstalleerd.' -STR_INSTALL_FAILED='Er is een fout opgetreden tijdens de installatie. U kunt het apparaat opnieuw aansluiten en het nogmaals proberen. Controleer log.txt voor details.' -STR_UPDATE_SUCCESS='Gefeliciteerd!#@Ventoy is succesvol bijgewerkt op het apparaat.' -STR_UPDATE_FAILED='Er is een fout opgetreden tijdens de update. U kunt het apparaat opnieuw aansluiten en het nogmaals proberen. Controleer log.txt voor details.' -STR_WAIT_PROCESS='Ventoy is nog bezig, even geduld...' -STR_MENU_OPTION='Opties' -STR_MENU_SECURE_BOOT='Secure Boot' -STR_MENU_PART_CFG='Partitieconfiguratie' -STR_BTN_OK='OK' -STR_BTN_CANCEL='Annuleren' -STR_PRESERVE_SPACE='Ruimte aan het einde van de schijf reserveren' -STR_SPACE_VAL_INVALID='Ongeldige waarde voor gereserveerde ruimte' -STR_MENU_CLEAR='Ventoy verwijderen' -STR_CLEAR_SUCCESS='Ventoy is succesvol verwijderd van het apparaat.' -STR_CLEAR_FAILED='Er is een fout opgetreden bij het verwijderen van Ventoy. U kunt het apparaat opnieuw aansluiten en het nogmaals proberen. Controleer log.txt voor details.' -STR_MENU_PART_STYLE='Partitietabel' -STR_DISK_2TB_MBR_ERROR='Selecteer GPT als partitietabel voor schijven groter dan 2TB' - - -[Language-Romanian (Română)] -FontFamily='Courier New' -FontSize=16 -Author=DorinMol - -STR_ERROR='Eroare' -STR_WARNING='Avertisment' -STR_INFO='Informare' -STR_INCORRECT_DIR='Vă rugăm executați în directorul corect!' -STR_INCORRECT_TREE_DIR='Nu rulați aici, vă rugăm să descărcați pachetul de instalare și executati acolo.' -STR_DEVICE='Dispozitiv' -STR_LOCAL_VER='Ventoy În Pachet' -STR_DISK_VER='Ventoy În Dispozitiv' -STR_STATUS='Stare - PREGĂTIT' -STR_INSTALL='Instalare' -STR_UPDATE='Actualizare' -STR_UPDATE_TIP='Operația de actualizare este sigură, fișierele ISO nu vor fi alterate / modificate.#@Continuați?' -STR_INSTALL_TIP='Unitatea disc va fi formatată și toate datele vor fi pierdute.#@Continuați?' -STR_INSTALL_TIP2='Unitatea disc va fi formatată și toate datele vor fi pierdute.#@Continuați? (Verificare Dublă)' -STR_INSTALL_SUCCESS='Felicitări!#@Ventoy a fost instalat cu succes pe dispozitiv.' -STR_INSTALL_FAILED='A apărut o eroare în timpul instalării. Reintroduceți dispozitivul USB și încercați din nou. Verificați log.txt pentru detalii.' -STR_UPDATE_SUCCESS='Felicitări!#@Ventoy a fost actualizat cu succes pe dispozitiv.' -STR_UPDATE_FAILED='A apărut o eroare în timpul actualizării. Reintroduceți dispozitivul USB și încercați din nou. Verificați log.txt pentru detalii.' -STR_WAIT_PROCESS='Rulează un fir de execuție, vă rugăm așteptați...' -STR_MENU_OPTION='Opțiune' -STR_MENU_SECURE_BOOT='Încărcare Sigură' -STR_MENU_PART_CFG='Configurare partiție' -STR_BTN_OK='O.K' -STR_BTN_CANCEL='Anulare' -STR_PRESERVE_SPACE='Păstrați puțin spațiu în partea de jos a discului' -STR_SPACE_VAL_INVALID='Valoare nevalidă pentru spațiul rezervat' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Japanese (日本語)] -FontFamily='Courier New' -FontSize=16 -Author=taichi eto - -STR_ERROR='エラー' -STR_WARNING='警告' -STR_INFO='情報' -STR_INCORRECT_DIR='正しいディレクトリーで実行してください' -STR_INCORRECT_TREE_DIR='ここで実行するには、パッケージをインストールしてください。.' -STR_DEVICE='デバイス' -STR_LOCAL_VER='Ventoy In Package' -STR_DISK_VER='Ventoy In Device' -STR_STATUS='Status - 準備完了' -STR_INSTALL='インストール' -STR_UPDATE='更新' -STR_UPDATE_TIP='アップグレード可能です、ISOファイルは改変されません。.#@続行?' -STR_INSTALL_TIP='選択されたディスクは完全に初期化され、保存されたデータは二度と復元できません。#@続行?' -STR_INSTALL_TIP2='選択されたディスクは完全に初期化され、保存されたデータは二度と復元できません。#@続行? (再確認)' -STR_INSTALL_SUCCESS='Congratulations!#@Ventoy は正常にインストールされました' -STR_INSTALL_FAILED='インストール中にエラーが発生しました。デバイスを再接続してもう一度やり直してください。 詳細ログ log.txt ' -STR_UPDATE_SUCCESS='Congratulations!#@Ventoy は正常にアップデートされました.' -STR_UPDATE_FAILED='更新中にエラーが発生しました。デバイスを再接続してもう一度やり直してください。. 詳細ログ log.txt' -STR_WAIT_PROCESS='処理中...' -STR_MENU_OPTION='設定' -STR_MENU_SECURE_BOOT='Secure Boot' -STR_MENU_PART_CFG='パーティション構成' -STR_BTN_OK='OK' -STR_BTN_CANCEL='キャンセル' -STR_PRESERVE_SPACE='ディスクの下部にある程度のスペースを確保する' -STR_SPACE_VAL_INVALID='予約スペースの無効な値' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Italian (Italiano)] -FontFamily='Courier New' -FontSize=16 -Author=AverageUser2 - -STR_ERROR='Errore' -STR_WARNING='Attenzione' -STR_INFO='Info' -STR_INCORRECT_DIR='Si prega di eseguire nella directory corretta' -STR_INCORRECT_TREE_DIR='Non eseguirmi qui, scarica il pacchetto di installazione ed avvialo' -STR_DEVICE='Dispositivo' -STR_LOCAL_VER='Ventoy locale' -STR_DISK_VER='Ventoy nel dispositivo' -STR_STATUS='Stato - PRONTO' -STR_INSTALL='Installa' -STR_UPDATE='Aggiorna' -STR_UPDATE_TIP='L'operazione di aggiornamento è sicura, i file ISO rimarranno invariati.#@Continue?' -STR_INSTALL_TIP='Il disco verrà formattato e tutti i dati saranno persi.#@Continue?' -STR_INSTALL_TIP2='Il disco verrà formattato e tutti i dati saranno persi.#@Continue?' (Seconda Verifica)' -STR_INSTALL_SUCCESS='Congratulazioni!#@Ventoy è stato installato con successo nel dispositivo' -STR_INSTALL_FAILED='Si è verificato un errore durante l'installazione. Reinserisci l'USB e riprova. Controlla il file log.txt per i dettagli. -STR_UPDATE_SUCCESS='Congratulazioni!#@Ventoy è stato aggiornato con successo nel dispositivo' -STR_UPDATE_FAILED='Si è verificato un errore durante l'aggiornamento. Reinserisci l'USB e riprova. Controlla il file log.txt per i dettagli. -STR_WAIT_PROCESS='Un thread è in esecuzione, attendere prego...' -STR_MENU_OPTION='Opzioni' -STR_MENU_SECURE_BOOT='Avvio protetto (secure boot)' -STR_MENU_PART_CFG='Configurazione della partizione' -STR_BTN_OK='OK' -STR_BTN_CANCEL='Annulla' -STR_PRESERVE_SPACE='Conserva un po 'di spazio nella parte inferiore del disco' -STR_SPACE_VAL_INVALID='Valore non valido per lo spazio riservato' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Croatian (Hrvatski)] -FontFamily='Courier New' -FontSize=16 -Author=Valnjes - -STR_ERROR='Pogreška' -STR_WARNING='Upozorenje' -STR_INFO='Informacija' -STR_INCORRECT_DIR='Molim vas pokrenite unutar pravog direktorija!' -STR_INCORRECT_TREE_DIR='Ne pokrećite me ovdje, molim vas downloadajte poslijednju verziju, te ponovno pokrenite!' -STR_DEVICE='Uređaj' -STR_LOCAL_VER='Ventoy (lokalni)' -STR_DISK_VER='Ventoy (na uređaju)' -STR_STATUS='Status - SPREMAN' -STR_INSTALL='Instaliraj' -STR_UPDATE='Ažuriraj' -STR_UPDATE_TIP='Nadogradnja je sigurna, ISO datoteke neće biti promjenjene.#@Nastaviti?' -STR_INSTALL_TIP='USB disk će biti formatiran i svi podatci će biti izgubljeni!#@Nastaviti?' -STR_INSTALL_TIP2='USB disk će biti formatiran i svi podatci će biti izgubljeni!#@Nastaviti? (Dodatna provjera)' -STR_INSTALL_SUCCESS='Čestitam!#@Ventoy je uspješno instaliran na vaš uređaj.' -STR_INSTALL_FAILED='Dogodila se pogreška tokom instalacije. Pokušajte ponovno spojiti USB i pokušati ponovno. Provjerite log.txt za više detalja o nastaloj pogrešci.' -STR_UPDATE_SUCCESS='Čestitam!#@Ventoy je uspješno ažuriran na vašem uređaju.' -STR_UPDATE_FAILED='Dogodila se pogreška tokom ažuriranja. Pokušajte ponovno spojiti USB i pokušati ponovno. Provjerite log.txt za više detalja o nastaloj pogrešci.' -STR_WAIT_PROCESS='Instanca je vec pokrenuta, molimo vas pričekajte...' -STR_MENU_OPTION='Opcije' -STR_MENU_SECURE_BOOT='Secure Boot' -STR_MENU_PART_CFG='Konfiguracija particije' -STR_BTN_OK='u redu' -STR_BTN_CANCEL='Otkazati' -STR_PRESERVE_SPACE='Sačuvajte malo prostora na dnu diska' -STR_SPACE_VAL_INVALID='Nevažeća vrijednost rezerviranog prostora' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Hungarian (Magyar)] -FontFamily='Courier New' -FontSize=16 -Author=Bitfarago - -STR_ERROR='Hiba' -STR_WARNING='Figyelem' -STR_INFO='Infó' -STR_INCORRECT_DIR='Kérjük, futtasd a megfelelő könyvtárból!' -STR_INCORRECT_TREE_DIR='Ne futtasd innen. Töltsd le a kiadott telepítőcsomagot és onnan futtasd.' -STR_DEVICE='Eszköz' -STR_LOCAL_VER='Ventoy a csomagban' -STR_DISK_VER='Ventoy az eszközön' -STR_STATUS='Állapot - KÉSZ' -STR_INSTALL='Telepítés' -STR_UPDATE='Frissítés' -STR_UPDATE_TIP='A frissítés biztonságos, az ISO fájlok nem változnak.#@Folytatod?' -STR_INSTALL_TIP='A meghajtó formázva lesz és minden rajta lévő adat elveszik.#@Folytatod?' -STR_INSTALL_TIP2='A meghajtó formázva lesz és minden rajta lévő adat elveszik.#@Folytatod? (Második jóváhagyás)' -STR_INSTALL_SUCCESS='Gratulálunk!#@A Ventoy sikeresen telepítve lett az eszközön.' -STR_INSTALL_FAILED='Hiba történt a telepítés során. Csatlakoztasd újra az USB eszközt, és próbáld újra.#@A részleteket lásd a log.txt fájlban.' -STR_UPDATE_SUCCESS='Gratulálunk!#@A Ventoy sikeresen frissítve lett az eszközön.' -STR_UPDATE_FAILED='Hiba történt a frissítés során. Csatlakoztasd újra az USB eszközt, és próbáld újra.#@A részleteket lásd a log.txt fájlban.' -STR_WAIT_PROCESS='A feldolgozás még folyamatban van, kérlek várj...' -STR_MENU_OPTION='Opció' -STR_MENU_SECURE_BOOT='Biztonsági mód (Secure Boot)' -STR_MENU_PART_CFG='Partíciókonfiguráció' -STR_BTN_OK='rendben' -STR_BTN_CANCEL='Megszünteti' -STR_PRESERVE_SPACE='Tartson szabad helyet a lemez alján' -STR_SPACE_VAL_INVALID='A fenntartott hely érvénytelen értéke' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Chinese Traditional (繁體中文)] -FontFamily='新細明體' -FontSize=14 -Author=penut85420 - -STR_ERROR='錯誤' -STR_WARNING='警告' -STR_INFO='提醒' -STR_INCORRECT_DIR='請在正確的資料夾下開啟!' -STR_INCORRECT_TREE_DIR='請下載並使用發行版本的安裝包' -STR_DEVICE='裝置' -STR_LOCAL_VER='當前 Ventoy 版本' -STR_DISK_VER='裝置內部的 Ventoy 版本' -STR_STATUS='狀態 - 準備就緒' -STR_INSTALL='安裝' -STR_UPDATE='升級' -STR_UPDATE_TIP='升級操作是安全的,磁碟內的 ISO 文件不會被清除#@是否繼續?' -STR_INSTALL_TIP='磁碟將會被格式化,所有內容將會被清除!#@是否繼續?' -STR_INSTALL_TIP2='磁碟將會被格式化,所有內容將會被清除!#@再次確認是否繼續?' -STR_INSTALL_SUCCESS='恭喜,Ventoy 已經成功安裝到此裝置中!' -STR_INSTALL_FAILED='安裝 Ventoy 的過程中發生錯誤,請重新插入磁碟並重試一次,詳細訊息請調閱 log.txt 文件。' -STR_UPDATE_SUCCESS='恭喜,新版本的 Ventoy 已經成功更新到此裝置中!' -STR_UPDATE_FAILED='更新 Ventoy 的過程中發生錯誤,請重新插入磁碟並重試一次,詳細訊息請調閱 log.txt 文件。' -STR_WAIT_PROCESS='目前有執行緒正在運作中,請稍候' -STR_MENU_OPTION='選項' -STR_MENU_SECURE_BOOT='支援 Secure Boot' -STR_MENU_PART_CFG='分區配置' -STR_BTN_OK='確定' -STR_BTN_CANCEL='取消' -STR_PRESERVE_SPACE='在磁盤最後保留一部分空間' -STR_SPACE_VAL_INVALID='保留空間的大小不合法' -STR_MENU_CLEAR='清除Ventoy' -STR_CLEAR_SUCCESS='Ventoy已成功從設備中清除' -STR_CLEAR_FAILED='清除 Ventoy 的過程中發生錯誤,請重新插入磁碟並重試一次,詳細訊息請調閱 log.txt 文件。' -STR_MENU_PART_STYLE='分區格式' -STR_DISK_2TB_MBR_ERROR='對於超過2TB的磁片請選擇GPT分區格式' - - -[Language-Serbian Latin (Srpski)] -FontFamily='Courier New' -FontSize=16 -Author=Bojan Maksimović - -STR_ERROR='Greška' -STR_WARNING='Upozorenje' -STR_INFO='Informacija' -STR_INCORRECT_DIR='Molim pokrenite u ispravnom direktorijumu!' -STR_INCORRECT_TREE_DIR='Ne pokreći me ovde, molim preuzmi izdanje paketa za instalaciju, i pokreni tamo.' -STR_DEVICE='Uređaj' -STR_LOCAL_VER='Ventoy lokalni' -STR_DISK_VER='Ventoy na uređaju' -STR_STATUS='Status - SPREMAN' -STR_INSTALL='Instaliraj' -STR_UPDATE='Nadogradi' -STR_UPDATE_TIP='Nadogradnja je bezbedna, ISO datoteke će ostati nepromenjene.#@Nastaviti?' -STR_INSTALL_TIP='Uređaj će biti formatiran i svi podaci će biti izgubljeni.#@Nastaviti?' -STR_INSTALL_TIP2='Uređaj će biti formatiran i svi podaci će biti izgubljeni.#@Nastaviti? (Dvostruka provera)' -STR_INSTALL_SUCCESS='Čestitamo!#@Ventoy je uspešno instaliran na uređaj.' -STR_INSTALL_FAILED='Pojavila se greška tokom instalacije. Možeš da ubaciš USB i pokušaš ponovo. Pogledaj log.txt za detalje.' -STR_UPDATE_SUCCESS='Čestitamo!#@Ventoy je uspešno nadograđen na uređaju.' -STR_UPDATE_FAILED='Pojavila se greška tokom nadogradnje. Možeš da ubaciš USB i pokušaš ponovo. Pogledaj log.txt za detalje.' -STR_WAIT_PROCESS='Radnja se izvršava, molim sačekaj...' -STR_MENU_OPTION='Opcije' -STR_MENU_SECURE_BOOT='Bezbedno butovanje (Secure Boot)' -STR_MENU_PART_CFG='Partition Configuration' -STR_BTN_OK='OK' -STR_BTN_CANCEL='Cancel' -STR_PRESERVE_SPACE='Preserve some space at the bottom of the disk' -STR_SPACE_VAL_INVALID='Invalid value for reserved space' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Serbian Cyrilic (Српски)] -FontFamily='Courier New' -FontSize=16 -Author=Бојан Максимовић - -STR_ERROR='Грешка' -STR_WARNING='Упозорење' -STR_INFO='Информација' -STR_INCORRECT_DIR='Молим покрените у исправном директоријуму!' -STR_INCORRECT_TREE_DIR='Не покрећи ме овде, молим преузми издање пакета за инсталацију, и покрени тамо.' -STR_DEVICE='Уређај' -STR_LOCAL_VER='Ventoy локални' -STR_DISK_VER='Ventoy на уређају' -STR_STATUS='Статус - СПРЕМАН' -STR_INSTALL='Инсталирај' -STR_UPDATE='Надогради' -STR_UPDATE_TIP='Надоградња је безбедна, ISO датотеке ће остати непромењене.#@Наставити?' -STR_INSTALL_TIP='Уређај ће бити форматиран и сви подаци ће бити изгубљени.#@Наставити?' -STR_INSTALL_TIP2='Уређај ће бити форматиран и сви подаци ће бити изгубљени.#@Наставити? (Двострука провера)' -STR_INSTALL_SUCCESS='Честитамо!#@Ventoy је успешно инсталиран на уређај.' -STR_INSTALL_FAILED='Појавила се грешка током инсталације. Можеш да убациш USB и покушаш поново. Погледај log.txt за детаље.' -STR_UPDATE_SUCCESS='Честитамо!#@Ventoy је успешно надограђен на уређају.' -STR_UPDATE_FAILED='Појавила се грешка током надоградње. Можеш да убациш USB и покушаш поново. Погледај log.txt за детаље.' -STR_WAIT_PROCESS='Радња се извршава, молим сачекај...' -STR_MENU_OPTION='Опције' -STR_MENU_SECURE_BOOT='Безбедно бутовање (Secure Boot)' -STR_MENU_PART_CFG='Partition Configuration' -STR_BTN_OK='OK' -STR_BTN_CANCEL='Cancel' -STR_PRESERVE_SPACE='Preserve some space at the bottom of the disk' -STR_SPACE_VAL_INVALID='Invalid value for reserved space' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Thai (ไทย)] -FontFamily='Courier New' -FontSize=17 -Author=longpanda - -STR_ERROR='ผิดพลาด' -STR_WARNING='คำเตือน' -STR_INFO='ข้อมูล' -STR_INCORRECT_DIR='กรุณาเรียกใช้ในอุปกรณ์ที่ถูกต้อง!' -STR_INCORRECT_TREE_DIR='อย่าติดตั้งในนี้, โปรดดาวน์โหลดและใช้แพ็คเกจการติดตั้งของรุ่นที่วางจำหน่าย' -STR_DEVICE='อุปกรณ์' -STR_LOCAL_VER='เวอร์ชั่น Ventoy ' -STR_DISK_VER='ลง Ventoy ในอุปกรณ์' -STR_STATUS='สถานะ - พร้อม' -STR_INSTALL='ติดตั้ง' -STR_UPDATE='ปรับปรุง' -STR_UPDATE_TIP='การดำเนินการอัปเกรดปลอดภัย, ไฟล์ ISO จะไม่มีการเปลี่ยนแปลง.#@ต่อเนื่อง?' -STR_INSTALL_TIP='ดิสก์จะถูกฟอร์แมตและข้อมูลทั้งหมดจะสูญหาย.#@ต่อเนื่อง?' -STR_INSTALL_TIP2='ดิสก์จะถูกฟอร์แมตและข้อมูลทั้งหมดจะสูญหาย#@ต่อเนื่อง? (ตรวจสอบอีกครั้ง)' -STR_INSTALL_SUCCESS='ขอแสดงความยินดี!#@Ventoy ติดตั้งไปยังอุปกรณ์สำเร็จแล้ว' -STR_INSTALL_FAILED='เกิดข้อผิดพลาดระหว่างการติดตั้ง. คุณสามารถถอด USB และลองอีกครั้ง. ตรวจสอบรายละเอียดได้ที่ log.txt.' -STR_UPDATE_SUCCESS='ขอแสดงความยินดี!#@Ventoy อัปเดตไปยังอุปกรณ์สำเร็จแล้ว.' -STR_UPDATE_FAILED='เกิดข้อผิดพลาดระหว่างการอัพเดต. คุณสามารถถอด USB และลองอีกครั้ง. ตรวจสอบรายละเอียดได้ที่ log.txt.' -STR_WAIT_PROCESS='CPU กำลังทำงานอยู่,ได้โปรดรอ...' -STR_MENU_OPTION='ตัวเลือก' -STR_MENU_SECURE_BOOT='สนับสนุนการบูตที่ปลอดภัย' -STR_MENU_PART_CFG='กำหนดค่าพาร์ติชัน' -STR_BTN_OK='ตกลง' -STR_BTN_CANCEL='ยกเลิก' -STR_PRESERVE_SPACE='เก็บพื้นที่บางส่วนของอุปกรณ์ไว้' -STR_SPACE_VAL_INVALID='มีปัญหาสำหรับพื้นที่ที่สงวนไว้(กรุณา ฟอร์แมต และติดตั้งใหม่)' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - - -[Language-Norwegian (Norsk)] -FontFamily='Courier New' -FontSize=16 -Author=Stein-Ove Bøthun - -STR_ERROR='Feil' -STR_WARNING='Advarsel' -STR_INFO='Info' -STR_INCORRECT_DIR='Vennligst kjør fra den riktige mappen!' -STR_INCORRECT_TREE_DIR='Ikke kjør meg her, vennligst last ned den utgitte installasjonspakken og kjør den der.' -STR_DEVICE='Enhet' -STR_LOCAL_VER='Ventoy i Pakken' -STR_DISK_VER='Ventoy på Enheten' -STR_STATUS='Status - KLAR' -STR_INSTALL='Installer' -STR_UPDATE='Oppdater' -STR_UPDATE_TIP='Oppgraderingsoperasjonen er sikker, ISO-filene vil være uendret.#@Fortsette?' -STR_INSTALL_TIP='Disken blir formatert og alle dataene vil gå tapt.#@Fortsette?' -STR_INSTALL_TIP2='Disken blir formatert og alle dataene vil gå tapt.#@Fortsette? (Dobbelsjekk)' -STR_INSTALL_SUCCESS='Gratulerer!#@Ventoy har blitt installert på enheten.' -STR_INSTALL_FAILED='Det oppstod en feil under installasjonen. Du kan koble til USB-en på nytt og prøve igjen. Check log.txt for flere detaljer.' -STR_UPDATE_SUCCESS='Gratulerer!#@Ventoy har blitt oppdatert til enheten.' -STR_UPDATE_FAILED='Det oppstod en feil under oppdateringen. Du kan koble til USB-en på nytt og prøve igjen. Se log.txt for flere detaljer.' -STR_WAIT_PROCESS='En tråd kjører, vennligst vent...' -STR_MENU_OPTION='Alternativ' -STR_MENU_SECURE_BOOT='Støtte for sikker oppstart' -STR_MENU_PART_CFG='Partisjonskonfigirasjon' -STR_BTN_OK='OK' -STR_BTN_CANCEL='Avbryt' -STR_PRESERVE_SPACE='Bevar litt plass på bunnen av disken' -STR_SPACE_VAL_INVALID='Ugyldig verdi for reservert plass' -STR_MENU_CLEAR='Clear Ventoy' -STR_CLEAR_SUCCESS='Ventoy has been successfully removed from the device.' -STR_CLEAR_FAILED='An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.' -STR_MENU_PART_STYLE='Partition Style' -STR_DISK_2TB_MBR_ERROR='Please select GPT for disk over 2TB' - -[Language-Vietnamese (Tiếng Việt)] -FontFamily='Tahoma' -FontSize=14 -Author=Nguyen Quoc Hoang - cuumay.com - -STR_ERROR='Lỗi' -STR_WARNING='Cảnh báo' -STR_INFO='Thông tin' -STR_INCORRECT_DIR='Vui lòng chạy Ventoy2Disk tại đúng thư mục của nó !' -STR_INCORRECT_TREE_DIR='Không được chạy Ventoy2Disk ở đây, vui lòng tải gói cài đặt đã phát hành và chạy ở đó.' -STR_DEVICE='Thiết bị' -STR_LOCAL_VER='Phiên bản Ventoy' -STR_DISK_VER='Phiên bản Ventoy ở thiết bị' -STR_STATUS='Trạng thái - SẴN SÀNG' -STR_INSTALL='Cài đặt' -STR_UPDATE='Cập nhật' -STR_UPDATE_TIP='Việc cập nhật Ventoy là an toàn, các tập tin ISO của bạn sẽ được giữ nguyên trạng.#@ Bạn thật sự muốn tiếp tục ?.' -STR_INSTALL_TIP='Thiết bị sẽ được định dạng và do đó TẤT CẢ DỮ LIỆU trên thiết bị sẽ bị mất.#@ Bạn thật sự muốn tiếp tục ?.' -STR_INSTALL_TIP2='Thiết bị sẽ được định dạng và do đó TẤT CẢ DỮ LIỆU trên thiết bị sẽ bị mất.#@ Bạn thật sự muốn tiếp tục ?. (Xác nhận lần hai)' -STR_INSTALL_SUCCESS='Chúc mừng bạn !.#@ Thiết bị đã được cài Ventoy thành công.' -STR_INSTALL_FAILED='Đã xảy ra lỗi trong quá trình cài đặt Ventoy. Bạn có thể rút thiết bị ra và thử lại. Xem chi tiết ở tệp log.txt.' -STR_UPDATE_SUCCESS='Chúc mừng bạn !.#@ Thiết bị đã được cập nhật Ventoy thành công.' -STR_UPDATE_FAILED='Đã xảy ra lỗi trong quá trình cập nhật Ventoy. Bạn có thể rút thiết bị ra và thử lại. Xem chi tiết ở tệp log.txt.' -STR_WAIT_PROCESS='Một luồng xử lý đang chạy, vui lòng chờ...' -STR_MENU_OPTION='Tùy chọn' -STR_MENU_SECURE_BOOT='Bật hỗ trợ Secure Boot' -STR_MENU_PART_CFG='Cấu hình phân vùng' -STR_BTN_OK='OK' -STR_BTN_CANCEL='Hủy' -STR_PRESERVE_SPACE='Giữ lại phần dung lượng ở dưới cùng của thiết bị' -STR_SPACE_VAL_INVALID='Giá trị dung lượng giữ lại không hợp lệ.' -STR_MENU_CLEAR='Gỡ bỏ Ventoy' -STR_CLEAR_SUCCESS='Chúc mừng bạn !.#@ Thiết bị đã được gỡ bỏ Ventoy thành công.' -STR_CLEAR_FAILED='Đã xảy ra lỗi trong quá trình gỡ bỏ Ventoy. Bạn có thể rút thiết bị ra và thử lại. Xem chi tiết ở tệp log.txt.' -STR_MENU_PART_STYLE='Kiểu phân vùng' -STR_DISK_2TB_MBR_ERROR='Thiết bị có dung lượng lớn hơn 2TB. Vui lòng chọn Kiểu phân vùng là GPT.' - - -[Language-Lithuanian (Lietuvių)] -FontFamily='Courier New' -FontSize=16 -Author=r0manas - -STR_ERROR = 'Klaida' -STR_WARNING = 'Įspėjimas' -STR_INFO = 'Informacija' -STR_INCORRECT_DIR = 'Prašome paleisti teisingame kataloge!' -STR_INCORRECT_TREE_DIR = 'Nepaleiskite manęs čia, atsisiųskite išleistą diegimo paketą ir paleiskite ten.' -STR_DEVICE = 'Įrenginys' -STR_LOCAL_VER = '„Ventoy“ versija pakuotėje' -STR_DISK_VER = '„Ventoy“ versija įrenginyje' -STR_STATUS = 'Būsena - PASIRENGĘS' -STR_INSTALL = 'Įdiegti' -STR_UPDATE = 'Atnaujinti' -STR_UPDATE_TIP = 'Atnaujinti - saugu, ISO failai liks nepažeisti.#@Tęsti?' -STR_INSTALL_TIP = 'Įrenginys bus suformatuotas ir visi duomenys bus prarasti.#@Tęsti?' -STR_INSTALL_TIP2 = 'Įrenginys bus suformatuotas ir visi duomenys bus prarasti.#@Tęsti? (TIKRAI TĘSTI?)' -STR_INSTALL_SUCCESS = 'Sveikinu!#@Ventoy sėkmingai įdiegtas įrenginyje.' -STR_INSTALL_FAILED = 'Diegimo metu įvyko klaida. Galite iš naujo prijungti USB ir bandyti dar kartą. Patikrinkite log.txt, jei norite sužinoti daugiau.' -STR_UPDATE_SUCCESS = 'Sveikinu!#@Ventoy sėkmingai atnaujintas įrenginyje.' -STR_UPDATE_FAILED = 'Atnaujinant įvyko klaida. Galite iš naujo prijungti USB ir bandyti dar kartą. Patikrinkite log.txt, jei norite sužinoti daugiau.' -STR_WAIT_PROCESS = 'Pradėtas procesas, palaukite ...' -STR_MENU_OPTION = 'Nustatymai' -STR_MENU_SECURE_BOOT = 'Secure Boot palaikymas' -STR_MENU_PART_CFG = 'Skirsnio konfigūracija' -STR_BTN_OK = 'Gerai' -STR_BTN_CANCEL = 'Atšaukti' -STR_PRESERVE_SPACE = 'Rezervuoti vietos įrenginyje' -STR_SPACE_VAL_INVALID = 'Neteisinga rezervuotos vietos vertė' -STR_MENU_CLEAR = 'Pašalinti „Ventoy“' -STR_CLEAR_SUCCESS = '„Ventoy“ sėkmingai pašalintas iš įrenginio.' -STR_CLEAR_FAILED = 'Įvyko klaida pašalinant „Ventoy“ iš įrenginio. USB ir bandyti dar kartą. Patikrinkite log.txt, jei norite sužinoti daugiau.' -STR_MENU_PART_STYLE = 'Skirsnio formatas' -STR_DISK_2TB_MBR_ERROR = 'Prašome pasirinkti GPT, jei įrenginys didesnis nei 2 TB.' - - diff --git a/License/lgpl-3.0.txt b/License/lgpl-3.0.txt new file mode 100644 index 00000000..80d241e1 --- /dev/null +++ b/License/lgpl-3.0.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/License/license-7z.txt b/License/license-7z.txt new file mode 100644 index 00000000..41cc0322 --- /dev/null +++ b/License/license-7z.txt @@ -0,0 +1,37 @@ + +imdisk follows LGPL license (see lgpl-3.0.txt) + +Ventoy only use its binaries 7za.exe + +========7zip License Information=============== + 7-Zip Extra + ~~~~~~~~~~~ + License for use and distribution + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Copyright (C) 1999-2019 Igor Pavlov. + + 7-Zip Extra files are under the GNU LGPL license. + + + Notes: + You can use 7-Zip Extra on any computer, including a computer in a commercial + organization. You don't need to register or pay for 7-Zip. + + + GNU LGPL information + -------------------- + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You can receive a copy of the GNU Lesser General Public License from + http://www.gnu.org/ + diff --git a/README.md b/README.md index 9bfa1b41..6fbb9dde 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# Ventoy +# Ventoy [https://www.ventoy.net](https://www.ventoy.net) Ventoy is an open source tool to create bootable USB drive for ISO files. With ventoy, you don't need to format the disk over and over, you just need to copy the iso file to the USB drive and boot it. You can copy many iso files at a time and ventoy will give you a boot menu to select them. -Both Legacy BIOS and UEFI are supported in the same way. 200+ ISO files are tested. +Both Legacy BIOS and UEFI are supported in the same way. 420+ ISO files are tested. A "Ventoy Compatible" concept is introduced by ventoy, which can help to support any ISO file. See https://www.ventoy.net for detail. @@ -15,16 +15,17 @@ See https://www.ventoy.net for detail. * Legacy + UEFI supported in the same way * UEFI Secure Boot supported (since 1.0.07+) * Persistence supported (since 1.0.11+) +* MBR and GPT partition style supported (1.0.15+) * WIM files boot supported (Legacy + UEFI) (1.0.12+) * Auto installation supported (1.0.09+) * ISO files larger than 4GB supported * Native boot menu style for Legacy & UEFI -* Most type of OS supported, 200+ iso files tested +* Most type of OS supported, 420+ iso files tested * Not only boot but also complete installation process * ISO files can be listed in List mode/TreeView mode * "Ventoy Compatible" concept * Plugin Framework -* Readonly to USB drive during boot +* USB drive write-protected support * USB normal use unaffected * Data nondestructive during version upgrade * No need to update Ventoy when a new distro is released @@ -43,12 +44,18 @@ Title | Link -|- **Install & Update** | [https://www.ventoy.net/en/doc_start.html](https://www.ventoy.net/en/doc_start.html) **Customize Theme** | [https://www.ventoy.net/en/plugin_theme.html](https://www.ventoy.net/en/plugin_theme.html) +**Global Control** | [https://www.ventoy.net/en/plugin_control.html](https://www.ventoy.net/en/plugin_control.html) **Auto Installation** | [https://www.ventoy.net/en/plugin_autoinstall.html](https://www.ventoy.net/en/plugin_autoinstall.html) +**Injection Plugin** | [https://www.ventoy.net/en/plugin_injection.html](https://www.ventoy.net/en/plugin_injection.html) **Persistence Support** | [https://www.ventoy.net/en/plugin_persistence.html](https://www.ventoy.net/en/plugin_persistence.html) **Boot WIM file** | [https://www.ventoy.net/en/plugin_wimboot.html](https://www.ventoy.net/en/plugin_wimboot.html) +**Menu Class** | [https://www.ventoy.net/en/plugin_menuclass.html](https://www.ventoy.net/en/plugin_menuclass.html) +**Menu Alias** | [https://www.ventoy.net/en/plugin_menualias.html](https://www.ventoy.net/en/plugin_menualias.html) +**Menu Extension** | [https://www.ventoy.net/en/plugin_grubmenu.html](https://www.ventoy.net/en/plugin_grubmenu.html) **Memdisk Mode** | [https://www.ventoy.net/en/doc_memdisk.html](https://www.ventoy.net/en/doc_memdisk.html) **TreeView Mode** | [https://www.ventoy.net/en/doc_treeview.html](https://www.ventoy.net/en/doc_treeview.html) -**Disk Layout** | [https://www.ventoy.net/en/doc_disk_layout.html](https://www.ventoy.net/en/doc_disk_layout.html) +**Disk Layout MBR** | [https://www.ventoy.net/en/doc_disk_layout.html](https://www.ventoy.net/en/doc_disk_layout.html) +**Disk Layout GPT** | [https://www.ventoy.net/en/doc_disk_layout_gpt.html](https://www.ventoy.net/en/doc_disk_layout_gpt.html) # FAQ diff --git a/Unix/pack_unix.sh b/Unix/pack_unix.sh new file mode 100644 index 00000000..24048cff --- /dev/null +++ b/Unix/pack_unix.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +VENTOY_PATH=$PWD/../ + +rm -f ventoy_unix.cpio + +find ./ventoy_unix | cpio -o -H newc>ventoy_unix.cpio + +echo '======== SUCCESS =============' + +rm -f $VENTOY_PATH/INSTALL/ventoy/ventoy_unix.cpio +cp -a ventoy_unix.cpio $VENTOY_PATH/INSTALL/ventoy/ + diff --git a/Unix/ventoy_unix.cpio b/Unix/ventoy_unix.cpio new file mode 100644 index 00000000..0e65ebab Binary files /dev/null and b/Unix/ventoy_unix.cpio differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/32/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/32/geom_ventoy.ko.xz new file mode 100644 index 00000000..e1b5d090 Binary files /dev/null and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/32/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/64/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/64/geom_ventoy.ko.xz new file mode 100644 index 00000000..7bfa9793 Binary files /dev/null and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/64/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/32/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/32/geom_ventoy.ko.xz new file mode 100644 index 00000000..701274e9 Binary files /dev/null and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/32/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/64/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/64/geom_ventoy.ko.xz new file mode 100644 index 00000000..2fce19c3 Binary files /dev/null and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/64/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/32/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/32/geom_ventoy.ko.xz new file mode 100644 index 00000000..6e6d994b Binary files /dev/null and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/32/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/64/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/64/geom_ventoy.ko.xz new file mode 100644 index 00000000..c53c3631 Binary files /dev/null and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/64/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/32/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/32/geom_ventoy.ko.xz new file mode 100644 index 00000000..facac0e0 Binary files /dev/null and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/32/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/64/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/64/geom_ventoy.ko.xz new file mode 100644 index 00000000..22f55f70 Binary files /dev/null and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/64/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/32/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/32/geom_ventoy.ko.xz new file mode 100644 index 00000000..8963f9ec Binary files /dev/null and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/32/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/64/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/64/geom_ventoy.ko.xz new file mode 100644 index 00000000..49385f60 Binary files /dev/null and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/64/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.c b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.c new file mode 100644 index 00000000..332ddd2c --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.c @@ -0,0 +1,1032 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 longpanda + * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +FEATURE(geom_ventoy, "GEOM ventoy support"); + +static MALLOC_DEFINE(M_VENTOY, "ventoy_data", "GEOM_VENTOY Data"); + +SYSCTL_DECL(_kern_geom); +static SYSCTL_NODE(_kern_geom, OID_AUTO, ventoy, CTLFLAG_RW, 0, + "GEOM_VENTOY stuff"); +static u_int g_ventoy_debug = 0; +SYSCTL_UINT(_kern_geom_ventoy, OID_AUTO, debug, CTLFLAG_RWTUN, &g_ventoy_debug, 0, + "Debug level"); + +extern int resource_string_value(const char *name, int unit, const char *resname, const char **result); +extern int resource_int_value(const char *name, int unit, const char *resname, int *result); + +static int g_ventoy_destroy(struct g_ventoy_softc *sc, boolean_t force); +static int g_ventoy_destroy_geom(struct gctl_req *req, struct g_class *mp, + struct g_geom *gp); + +static g_taste_t g_ventoy_taste; +static g_ctl_req_t g_ventoy_config; +static g_dumpconf_t g_ventoy_dumpconf; + +static const char *g_ventoy_disk_uuid = NULL; +static bool g_ventoy_tasted = false; +static off_t g_ventoy_disk_size = 0; +static off_t g_disk_map_start = 0; +static off_t g_disk_map_end = 0; + +struct g_class g_ventoy_class = { + .name = G_VENTOY_CLASS_NAME, + .version = G_VERSION, + .ctlreq = g_ventoy_config, + .taste = g_ventoy_taste, + .destroy_geom = g_ventoy_destroy_geom +}; + + +/* + * Greatest Common Divisor. + */ +static u_int +gcd(u_int a, u_int b) +{ + u_int c; + + while (b != 0) { + c = a; + a = b; + b = (c % b); + } + return (a); +} + +/* + * Least Common Multiple. + */ +static u_int +lcm(u_int a, u_int b) +{ + + return ((a * b) / gcd(a, b)); +} + +/* + * Return the number of valid disks. + */ +static u_int +g_ventoy_nvalid(struct g_ventoy_softc *sc) +{ + u_int i, no; + + no = 0; + for (i = 0; i < sc->sc_ndisks; i++) { + if (sc->sc_disks[i].d_consumer != NULL) + no++; + } + + return (no); +} + +static void +g_ventoy_remove_disk(struct g_ventoy_disk *disk) +{ + struct g_consumer *cp; + struct g_ventoy_softc *sc; + + g_topology_assert(); + KASSERT(disk->d_consumer != NULL, ("Non-valid disk in %s.", __func__)); + sc = disk->d_softc; + cp = disk->d_consumer; + + if (!disk->d_removed) { + G_VENTOY_DEBUG(0, "Disk %s removed from %s.", + cp->provider->name, sc->sc_name); + disk->d_removed = 1; + } + + if (sc->sc_provider != NULL) { + sc->sc_provider->flags |= G_PF_WITHER; + G_VENTOY_DEBUG(0, "Device %s deactivated.", + sc->sc_provider->name); + g_orphan_provider(sc->sc_provider, ENXIO); + sc->sc_provider = NULL; + } + + if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0) + return; + disk->d_consumer = NULL; + g_detach(cp); + g_destroy_consumer(cp); + /* If there are no valid disks anymore, remove device. */ + if (LIST_EMPTY(&sc->sc_geom->consumer)) + g_ventoy_destroy(sc, 1); +} + +static void +g_ventoy_orphan(struct g_consumer *cp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_geom *gp; + + g_topology_assert(); + gp = cp->geom; + sc = gp->softc; + if (sc == NULL) + return; + + disk = cp->private; + if (disk == NULL) /* Possible? */ + return; + g_ventoy_remove_disk(disk); +} + +static int +g_ventoy_access(struct g_provider *pp, int dr, int dw, int de) +{ + struct g_consumer *cp1, *cp2, *tmp; + struct g_ventoy_disk *disk; + struct g_geom *gp; + int error; + + if (dw > 0) /* readonly */ + return (EPERM); + + g_topology_assert(); + gp = pp->geom; + + /* On first open, grab an extra "exclusive" bit */ + if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) + de++; + /* ... and let go of it on last close */ + if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) + de--; + + LIST_FOREACH_SAFE(cp1, &gp->consumer, consumer, tmp) { + error = g_access(cp1, dr, dw, de); + if (error != 0) + goto fail; + disk = cp1->private; + if (cp1->acr == 0 && cp1->acw == 0 && cp1->ace == 0 && + disk->d_removed) { + g_ventoy_remove_disk(disk); /* May destroy geom. */ + } + } + return (0); + +fail: + LIST_FOREACH(cp2, &gp->consumer, consumer) { + if (cp1 == cp2) + break; + g_access(cp2, -dr, -dw, -de); + } + return (error); +} + +static void +g_ventoy_kernel_dump(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct bio *cbp; + struct g_kerneldump *gkd; + u_int i; + + sc = bp->bio_to->geom->softc; + gkd = (struct g_kerneldump *)bp->bio_data; + for (i = 0; i < sc->sc_ndisks; i++) { + if (sc->sc_disks[i].d_start <= gkd->offset && + sc->sc_disks[i].d_end > gkd->offset) + break; + } + if (i == sc->sc_ndisks) + g_io_deliver(bp, EOPNOTSUPP); + disk = &sc->sc_disks[i]; + gkd->offset -= disk->d_start; + if (gkd->length > disk->d_end - disk->d_start - gkd->offset) + gkd->length = disk->d_end - disk->d_start - gkd->offset; + cbp = g_clone_bio(bp); + if (cbp == NULL) { + g_io_deliver(bp, ENOMEM); + return; + } + cbp->bio_done = g_std_done; + g_io_request(cbp, disk->d_consumer); + G_VENTOY_DEBUG(1, "Kernel dump will go to %s.", + disk->d_consumer->provider->name); +} + +static void +g_ventoy_flush(struct g_ventoy_softc *sc, struct bio *bp) +{ + struct bio_queue_head queue; + struct g_consumer *cp; + struct bio *cbp; + u_int no; + + bioq_init(&queue); + for (no = 0; no < sc->sc_ndisks; no++) { + cbp = g_clone_bio(bp); + if (cbp == NULL) { + for (cbp = bioq_first(&queue); cbp != NULL; + cbp = bioq_first(&queue)) { + bioq_remove(&queue, cbp); + g_destroy_bio(cbp); + } + if (bp->bio_error == 0) + bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); + return; + } + bioq_insert_tail(&queue, cbp); + cbp->bio_done = g_std_done; + cbp->bio_caller1 = sc->sc_disks[no].d_consumer; + cbp->bio_to = sc->sc_disks[no].d_consumer->provider; + } + for (cbp = bioq_first(&queue); cbp != NULL; cbp = bioq_first(&queue)) { + bioq_remove(&queue, cbp); + G_VENTOY_LOGREQ(cbp, "Sending request."); + cp = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, cp); + } +} + +static void +g_ventoy_start(struct bio *bp) +{ + struct bio_queue_head queue; + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_provider *pp; + off_t offset, end, length, off, len; + struct bio *cbp; + char *addr; + u_int no; + + pp = bp->bio_to; + sc = pp->geom->softc; + /* + * If sc == NULL, provider's error should be set and g_ventoy_start() + * should not be called at all. + */ + KASSERT(sc != NULL, + ("Provider's error should be set (error=%d)(device=%s).", + bp->bio_to->error, bp->bio_to->name)); + + G_VENTOY_LOGREQ(bp, "Request received."); + + switch (bp->bio_cmd) { + case BIO_READ: + case BIO_WRITE: + case BIO_DELETE: + break; + case BIO_FLUSH: + g_ventoy_flush(sc, bp); + return; + case BIO_GETATTR: + if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) { + g_ventoy_kernel_dump(bp); + return; + } + /* To which provider it should be delivered? */ + /* FALLTHROUGH */ + default: + g_io_deliver(bp, EOPNOTSUPP); + return; + } + + offset = bp->bio_offset; + length = bp->bio_length; + addr = bp->bio_data; + end = offset + length; + + bioq_init(&queue); + for (no = 0; no < sc->sc_ndisks; no++) { + disk = &sc->sc_disks[no]; + if (disk->d_end <= offset) + continue; + if (disk->d_start >= end) + break; + + off = offset - disk->d_start; + len = MIN(length, disk->d_end - offset); + length -= len; + offset += len; + + cbp = g_clone_bio(bp); + if (cbp == NULL) { + for (cbp = bioq_first(&queue); cbp != NULL; + cbp = bioq_first(&queue)) { + bioq_remove(&queue, cbp); + g_destroy_bio(cbp); + } + if (bp->bio_error == 0) + bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); + return; + } + bioq_insert_tail(&queue, cbp); + /* + * Fill in the component buf structure. + */ + cbp->bio_done = g_std_done; + cbp->bio_offset = off + disk->d_map_start; + cbp->bio_data = addr; + addr += len; + cbp->bio_length = len; + cbp->bio_to = disk->d_consumer->provider; + cbp->bio_caller1 = disk; + + if (length == 0) + break; + } + KASSERT(length == 0, + ("Length is still greater than 0 (class=%s, name=%s).", + bp->bio_to->geom->class->name, bp->bio_to->geom->name)); + for (cbp = bioq_first(&queue); cbp != NULL; cbp = bioq_first(&queue)) { + bioq_remove(&queue, cbp); + G_VENTOY_LOGREQ(cbp, "Sending request."); + disk = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, disk->d_consumer); + } +} + +static void +g_ventoy_check_and_run(struct g_ventoy_softc *sc) +{ + struct g_ventoy_disk *disk; + struct g_provider *dp, *pp; + u_int no, sectorsize = 0; + off_t start; + + g_topology_assert(); + if (g_ventoy_nvalid(sc) != sc->sc_ndisks) + return; + + pp = g_new_providerf(sc->sc_geom, "ventoy/%s", sc->sc_name); + start = 0; + for (no = 0; no < sc->sc_ndisks; no++) { + disk = &sc->sc_disks[no]; + dp = disk->d_consumer->provider; + disk->d_start = start; + disk->d_end = disk->d_start + (disk->d_map_end - disk->d_map_start); + if (sc->sc_type == G_VENTOY_TYPE_AUTOMATIC) + disk->d_end -= dp->sectorsize; + start = disk->d_end; + if (no == 0) + sectorsize = dp->sectorsize; + else { + sectorsize = lcm(sectorsize, dp->sectorsize); + + } + } + pp->sectorsize = sectorsize; + /* We have sc->sc_disks[sc->sc_ndisks - 1].d_end in 'start'. */ + pp->mediasize = start; + pp->stripesize = sc->sc_disks[0].d_consumer->provider->stripesize; + pp->stripeoffset = sc->sc_disks[0].d_consumer->provider->stripeoffset; + sc->sc_provider = pp; + g_error_provider(pp, 0); + + G_VENTOY_DEBUG(0, "Device %s activated.", sc->sc_provider->name); +} + +static int +g_ventoy_read_metadata(struct g_consumer *cp, struct g_ventoy_metadata *md) +{ + struct g_provider *pp; + u_char *buf; + int error; + + g_topology_assert(); + + error = g_access(cp, 1, 0, 0); + if (error != 0) + return (error); + pp = cp->provider; + g_topology_unlock(); + buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize, + &error); + g_topology_lock(); + g_access(cp, -1, 0, 0); + if (buf == NULL) + return (error); + + /* Decode metadata. */ + ventoy_metadata_decode(buf, md); + g_free(buf); + + return (0); +} + +/* + * Add disk to given device. + */ +static int +g_ventoy_add_disk(struct g_ventoy_softc *sc, struct g_provider *pp, u_int no) +{ + struct g_ventoy_disk *disk; + struct g_consumer *cp, *fcp; + struct g_geom *gp; + int error; + + g_topology_assert(); + /* Metadata corrupted? */ + if (no >= sc->sc_ndisks) + return (EINVAL); + + disk = &sc->sc_disks[no]; + /* Check if disk is not already attached. */ + if (disk->d_consumer != NULL) + return (EEXIST); + + gp = sc->sc_geom; + fcp = LIST_FIRST(&gp->consumer); + + cp = g_new_consumer(gp); + error = g_attach(cp, pp); + if (error != 0) { + g_destroy_consumer(cp); + return (error); + } + + if (fcp != NULL && (fcp->acr > 0 || fcp->acw > 0 || fcp->ace > 0)) { + error = g_access(cp, fcp->acr, fcp->acw, fcp->ace); + if (error != 0) { + g_detach(cp); + g_destroy_consumer(cp); + return (error); + } + } + if (sc->sc_type == G_VENTOY_TYPE_AUTOMATIC) { + struct g_ventoy_metadata md; + + /* Re-read metadata. */ + error = g_ventoy_read_metadata(cp, &md); + if (error != 0) + goto fail; + + if (strcmp(md.md_magic, G_VENTOY_MAGIC) != 0 || + strcmp(md.md_name, sc->sc_name) != 0 || + md.md_id != sc->sc_id) { + G_VENTOY_DEBUG(0, "Metadata on %s changed.", pp->name); + goto fail; + } + } + + cp->private = disk; + disk->d_consumer = cp; + disk->d_softc = sc; + disk->d_start = 0; /* not yet */ + disk->d_end = 0; /* not yet */ + disk->d_removed = 0; + + disk->d_map_start = g_disk_map_start; + disk->d_map_end = g_disk_map_end; + + G_VENTOY_DEBUG(0, "Disk %s attached to %s.", pp->name, sc->sc_name); + + g_ventoy_check_and_run(sc); + + return (0); +fail: + if (fcp != NULL && (fcp->acr > 0 || fcp->acw > 0 || fcp->ace > 0)) + g_access(cp, -fcp->acr, -fcp->acw, -fcp->ace); + g_detach(cp); + g_destroy_consumer(cp); + return (error); +} + +static struct g_geom * +g_ventoy_create(struct g_class *mp, const struct g_ventoy_metadata *md, + u_int type) +{ + struct g_ventoy_softc *sc; + struct g_geom *gp; + u_int no; + + G_VENTOY_DEBUG(1, "Creating device %s (id=%u).", md->md_name, + md->md_id); + + /* One disks is minimum. */ + if (md->md_all < 1) + return (NULL); + + /* Check for duplicate unit */ + LIST_FOREACH(gp, &mp->geom, geom) { + sc = gp->softc; + if (sc != NULL && strcmp(sc->sc_name, md->md_name) == 0) { + G_VENTOY_DEBUG(0, "Device %s already configured.", + gp->name); + return (NULL); + } + } + gp = g_new_geomf(mp, "%s", md->md_name); + sc = malloc(sizeof(*sc), M_VENTOY, M_WAITOK | M_ZERO); + gp->start = g_ventoy_start; + gp->spoiled = g_ventoy_orphan; + gp->orphan = g_ventoy_orphan; + gp->access = g_ventoy_access; + gp->dumpconf = g_ventoy_dumpconf; + + sc->sc_id = md->md_id; + sc->sc_ndisks = md->md_all; + sc->sc_disks = malloc(sizeof(struct g_ventoy_disk) * sc->sc_ndisks, + M_VENTOY, M_WAITOK | M_ZERO); + for (no = 0; no < sc->sc_ndisks; no++) + sc->sc_disks[no].d_consumer = NULL; + sc->sc_type = type; + + gp->softc = sc; + sc->sc_geom = gp; + sc->sc_provider = NULL; + + G_VENTOY_DEBUG(0, "Device %s created (id=%u).", sc->sc_name, sc->sc_id); + + return (gp); +} + +static int +g_ventoy_destroy(struct g_ventoy_softc *sc, boolean_t force) +{ + struct g_provider *pp; + struct g_consumer *cp, *cp1; + struct g_geom *gp; + + g_topology_assert(); + + if (sc == NULL) + return (ENXIO); + + pp = sc->sc_provider; + if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) { + if (force) { + G_VENTOY_DEBUG(0, "Device %s is still open, so it " + "can't be definitely removed.", pp->name); + } else { + G_VENTOY_DEBUG(1, + "Device %s is still open (r%dw%de%d).", pp->name, + pp->acr, pp->acw, pp->ace); + return (EBUSY); + } + } + + gp = sc->sc_geom; + LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp1) { + g_ventoy_remove_disk(cp->private); + if (cp1 == NULL) + return (0); /* Recursion happened. */ + } + if (!LIST_EMPTY(&gp->consumer)) + return (EINPROGRESS); + + gp->softc = NULL; + KASSERT(sc->sc_provider == NULL, ("Provider still exists? (device=%s)", + gp->name)); + free(sc->sc_disks, M_VENTOY); + free(sc, M_VENTOY); + + G_VENTOY_DEBUG(0, "Device %s destroyed.", gp->name); + g_wither_geom(gp, ENXIO); + return (0); +} + +static int +g_ventoy_destroy_geom(struct gctl_req *req __unused, + struct g_class *mp __unused, struct g_geom *gp) +{ + struct g_ventoy_softc *sc; + + sc = gp->softc; + return (g_ventoy_destroy(sc, 0)); +} + +static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) +{ + int i; + uint8_t *buf; + char uuid[64]; + const char *value; + struct g_consumer *cp; + struct g_geom *gp; + + if (g_ventoy_disk_size == 0) + { + if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + { + G_DEBUG("ventoy.disksize: %s\n", value); + g_ventoy_disk_size = strtouq(value, NULL, 0); + } + + if (resource_string_value("ventoy", 0, "diskuuid", &g_ventoy_disk_uuid) == 0) + { + G_DEBUG("ventoy.diskuuid: <%s>\n", g_ventoy_disk_uuid); + } + } + + if (g_ventoy_disk_size != pp->mediasize) + { + return false; + } + + if (strncmp(pp->name, "cd", 2) == 0 || strchr(pp->name, '/')) + { + return false; + } + + /* read UUID from disk */ + gp = g_new_geomf(mp, "ventoy:taste"); + gp->start = NULL; + gp->access = g_ventoy_access; + gp->orphan = g_ventoy_orphan; + cp = g_new_consumer(gp); + g_attach(cp, pp); + + g_access(cp, 1, 0, 0); + g_topology_unlock(); + buf = g_read_data(cp, 0, pp->sectorsize, NULL); + g_topology_lock(); + g_access(cp, -1, 0, 0); + + g_detach(cp); + g_destroy_consumer(cp); + g_destroy_geom(gp); + gp = NULL; + + if (!buf) + { + return false; + } + + for (i = 0; i < 16; i++) + { + sprintf(uuid + i * 2, "%02x", buf[0x180 + i]); + } + g_free(buf); + + if (strncmp(g_ventoy_disk_uuid, uuid, 32) == 0) + { + return true; + } + + return false; +} + +static struct g_geom * +g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) +{ + int i; + int error; + int disknum; + char *endpos; + const char *value; + struct g_geom *gp; + struct g_ventoy_metadata md; + struct g_ventoy_softc *sc; + + if (g_ventoy_tasted) + { + return NULL; + } + + G_DEBUG("%s(%s, %s)\n", __func__, mp->name, pp->name); + g_topology_assert(); + + /* Skip providers that are already open for writing. */ + if (pp->acw > 0) + return (NULL); + + if (!g_vtoy_check_disk(mp, pp)) + { + return NULL; + } + + g_ventoy_tasted = true; + + G_DEBUG("######### ventoy disk <%s> #############\n", pp->name); + + resource_int_value("ventoy", 0, "segnum", &disknum); + + strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); + md.md_version = G_VENTOY_VERSION; + strlcpy(md.md_name, "IMAGE", sizeof(md.md_name)); + md.md_id = arc4random(); + md.md_no = 0; + md.md_all = (uint16_t)disknum; + bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; + + gp = g_ventoy_create(mp, &md, G_VENTOY_TYPE_MANUAL); + if (gp == NULL) { + G_VENTOY_DEBUG(0, "Cannot create device %s.", + md.md_name); + return (NULL); + } + sc = gp->softc; + + for (i = 0; i < disknum; i ++) + { + if (resource_string_value("ventoy", i, "seg", &value) == 0) + { + g_disk_map_start = strtouq(value, &endpos, 0); + g_disk_map_end = strtouq(endpos + 1, NULL, 0); + } + else + { + printf("Failed to parse ventoy seg %d\n", i); + continue; + } + + G_DEBUG("ventoy segment%d: %s\n", i, value); + + G_VENTOY_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name); + error = g_ventoy_add_disk(sc, pp, i); + if (error != 0) { + G_VENTOY_DEBUG(0, + "Cannot add disk %s to %s (error=%d).", pp->name, + gp->name, error); + g_ventoy_destroy(sc, 1); + return (NULL); + } + + g_disk_map_start = 0; + g_disk_map_end = 0; + } + + return (gp); +} + +static void +g_ventoy_ctl_create(struct gctl_req *req, struct g_class *mp) +{ + u_int attached, no; + struct g_ventoy_metadata md; + struct g_provider *pp; + struct g_ventoy_softc *sc; + struct g_geom *gp; + struct sbuf *sb; + const char *name; + char param[16]; + int *nargs; + + g_topology_assert(); + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument.", "nargs"); + return; + } + if (*nargs < 2) { + gctl_error(req, "Too few arguments."); + return; + } + + strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); + md.md_version = G_VENTOY_VERSION; + name = gctl_get_asciiparam(req, "arg0"); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", 0); + return; + } + strlcpy(md.md_name, name, sizeof(md.md_name)); + md.md_id = arc4random(); + md.md_no = 0; + md.md_all = *nargs - 1; + bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; + + /* Check all providers are valid */ + for (no = 1; no < *nargs; no++) { + snprintf(param, sizeof(param), "arg%u", no); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", no); + return; + } + if (strncmp(name, "/dev/", strlen("/dev/")) == 0) + name += strlen("/dev/"); + pp = g_provider_by_name(name); + if (pp == NULL) { + G_VENTOY_DEBUG(1, "Disk %s is invalid.", name); + gctl_error(req, "Disk %s is invalid.", name); + return; + } + } + + gp = g_ventoy_create(mp, &md, G_VENTOY_TYPE_MANUAL); + if (gp == NULL) { + gctl_error(req, "Can't configure %s.", md.md_name); + return; + } + + sc = gp->softc; + sb = sbuf_new_auto(); + sbuf_printf(sb, "Can't attach disk(s) to %s:", gp->name); + for (attached = 0, no = 1; no < *nargs; no++) { + snprintf(param, sizeof(param), "arg%u", no); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%d' argument.", no); + return; + } + if (strncmp(name, "/dev/", strlen("/dev/")) == 0) + name += strlen("/dev/"); + pp = g_provider_by_name(name); + KASSERT(pp != NULL, ("Provider %s disappear?!", name)); + if (g_ventoy_add_disk(sc, pp, no - 1) != 0) { + G_VENTOY_DEBUG(1, "Disk %u (%s) not attached to %s.", + no, pp->name, gp->name); + sbuf_printf(sb, " %s", pp->name); + continue; + } + attached++; + } + sbuf_finish(sb); + if (md.md_all != attached) { + g_ventoy_destroy(gp->softc, 1); + gctl_error(req, "%s", sbuf_data(sb)); + } + sbuf_delete(sb); +} + +static struct g_ventoy_softc * +g_ventoy_find_device(struct g_class *mp, const char *name) +{ + struct g_ventoy_softc *sc; + struct g_geom *gp; + + LIST_FOREACH(gp, &mp->geom, geom) { + sc = gp->softc; + if (sc == NULL) + continue; + if (strcmp(sc->sc_name, name) == 0) + return (sc); + } + return (NULL); +} + +static void +g_ventoy_ctl_destroy(struct gctl_req *req, struct g_class *mp) +{ + struct g_ventoy_softc *sc; + int *force, *nargs, error; + const char *name; + char param[16]; + u_int i; + + g_topology_assert(); + + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument.", "nargs"); + return; + } + if (*nargs <= 0) { + gctl_error(req, "Missing device(s)."); + return; + } + force = gctl_get_paraml(req, "force", sizeof(*force)); + if (force == NULL) { + gctl_error(req, "No '%s' argument.", "force"); + return; + } + + for (i = 0; i < (u_int)*nargs; i++) { + snprintf(param, sizeof(param), "arg%u", i); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", i); + return; + } + sc = g_ventoy_find_device(mp, name); + if (sc == NULL) { + gctl_error(req, "No such device: %s.", name); + return; + } + error = g_ventoy_destroy(sc, *force); + if (error != 0) { + gctl_error(req, "Cannot destroy device %s (error=%d).", + sc->sc_name, error); + return; + } + } +} + +static void +g_ventoy_config(struct gctl_req *req, struct g_class *mp, const char *verb) +{ + uint32_t *version; + + return; + + g_topology_assert(); + + version = gctl_get_paraml(req, "version", sizeof(*version)); + if (version == NULL) { + gctl_error(req, "No '%s' argument.", "version"); + return; + } + if (*version != G_VENTOY_VERSION) { + gctl_error(req, "Userland and kernel parts are out of sync."); + return; + } + + if (strcmp(verb, "create") == 0) { + g_ventoy_ctl_create(req, mp); + return; + } else if (strcmp(verb, "destroy") == 0 || + strcmp(verb, "stop") == 0) { + g_ventoy_ctl_destroy(req, mp); + return; + } + gctl_error(req, "Unknown verb."); +} + +static void +g_ventoy_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, + struct g_consumer *cp, struct g_provider *pp) +{ + struct g_ventoy_softc *sc; + + g_topology_assert(); + sc = gp->softc; + if (sc == NULL) + return; + if (pp != NULL) { + /* Nothing here. */ + } else if (cp != NULL) { + struct g_ventoy_disk *disk; + + disk = cp->private; + if (disk == NULL) + return; + sbuf_printf(sb, "%s%jd\n", indent, + (intmax_t)disk->d_end); + sbuf_printf(sb, "%s%jd\n", indent, + (intmax_t)disk->d_start); + } else { + sbuf_printf(sb, "%s%u\n", indent, (u_int)sc->sc_id); + sbuf_printf(sb, "%s", indent); + switch (sc->sc_type) { + case G_VENTOY_TYPE_AUTOMATIC: + sbuf_cat(sb, "AUTOMATIC"); + break; + case G_VENTOY_TYPE_MANUAL: + sbuf_cat(sb, "MANUAL"); + break; + default: + sbuf_cat(sb, "UNKNOWN"); + break; + } + sbuf_cat(sb, "\n"); + sbuf_printf(sb, "%sTotal=%u, Online=%u\n", + indent, sc->sc_ndisks, g_ventoy_nvalid(sc)); + sbuf_printf(sb, "%s", indent); + if (sc->sc_provider != NULL && sc->sc_provider->error == 0) + sbuf_cat(sb, "UP"); + else + sbuf_cat(sb, "DOWN"); + sbuf_cat(sb, "\n"); + } +} + +DECLARE_GEOM_CLASS(g_ventoy_class, g_ventoy); diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.h b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.h new file mode 100644 index 00000000..e442b246 --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.h @@ -0,0 +1,117 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 longpanda + * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _G_VENTOY_H_ +#define _G_VENTOY_H_ + +#include + +#define G_VENTOY_CLASS_NAME "VENTOY" + +#define G_VENTOY_MAGIC "GEOM::VENTOY" +/* + * Version history: + * 1 - Initial version number. + * 2 - Added 'stop' command to gconcat(8). + * 3 - Added md_provider field to metadata and '-h' option to gconcat(8). + * 4 - Added md_provsize field to metadata. + */ +#define G_VENTOY_VERSION 4 + +#ifdef _KERNEL +#define G_VENTOY_TYPE_MANUAL 0 +#define G_VENTOY_TYPE_AUTOMATIC 1 + +#define G_DEBUG(...) if (bootverbose) printf(__VA_ARGS__) +#define G_VENTOY_DEBUG(lvl, ...) if (g_ventoy_debug) printf(__VA_ARGS__) +#define G_VENTOY_LOGREQ(bp, ...) if (g_ventoy_debug) printf(__VA_ARGS__) + +struct g_ventoy_disk { + struct g_consumer *d_consumer; + struct g_ventoy_softc *d_softc; + off_t d_start; + off_t d_end; + off_t d_map_start; + off_t d_map_end; + int d_candelete; + int d_removed; +}; + +struct g_ventoy_softc { + u_int sc_type; /* provider type */ + struct g_geom *sc_geom; + struct g_provider *sc_provider; + uint32_t sc_id; /* concat unique ID */ + + struct g_ventoy_disk *sc_disks; + uint16_t sc_ndisks; + struct mtx sc_lock; +}; +#define sc_name sc_geom->name +#endif /* _KERNEL */ + +struct g_ventoy_metadata { + char md_magic[16]; /* Magic value. */ + uint32_t md_version; /* Version number. */ + char md_name[16]; /* Concat name. */ + uint32_t md_id; /* Unique ID. */ + uint16_t md_no; /* Disk number. */ + uint16_t md_all; /* Number of all disks. */ + char md_provider[16]; /* Hardcoded provider. */ + uint64_t md_provsize; /* Provider's size. */ +}; +static __inline void +ventoy_metadata_encode(const struct g_ventoy_metadata *md, u_char *data) +{ + + bcopy(md->md_magic, data, sizeof(md->md_magic)); + le32enc(data + 16, md->md_version); + bcopy(md->md_name, data + 20, sizeof(md->md_name)); + le32enc(data + 36, md->md_id); + le16enc(data + 40, md->md_no); + le16enc(data + 42, md->md_all); + bcopy(md->md_provider, data + 44, sizeof(md->md_provider)); + le64enc(data + 60, md->md_provsize); +} +static __inline void +ventoy_metadata_decode(const u_char *data, struct g_ventoy_metadata *md) +{ + + bcopy(data, md->md_magic, sizeof(md->md_magic)); + md->md_version = le32dec(data + 16); + bcopy(data + 20, md->md_name, sizeof(md->md_name)); + md->md_id = le32dec(data + 36); + md->md_no = le16dec(data + 40); + md->md_all = le16dec(data + 42); + bcopy(data + 44, md->md_provider, sizeof(md->md_provider)); + md->md_provsize = le64dec(data + 60); +} +#endif /* _G_VENTOY_H_ */ diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/modules/geom/geom_ventoy/Makefile b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/modules/geom/geom_ventoy/Makefile new file mode 100644 index 00000000..165f1bdf --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/modules/geom/geom_ventoy/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/sys/geom/ventoy + +KMOD= geom_ventoy +SRCS= g_ventoy.c + +.include diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.c b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.c new file mode 100644 index 00000000..5e8642f7 --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.c @@ -0,0 +1,1068 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 longpanda + * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +FEATURE(geom_ventoy, "GEOM ventoy support"); + +static MALLOC_DEFINE(M_VENTOY, "ventoy_data", "GEOM_VENTOY Data"); + +SYSCTL_DECL(_kern_geom); +static SYSCTL_NODE(_kern_geom, OID_AUTO, ventoy, CTLFLAG_RW, 0, + "GEOM_VENTOY stuff"); +static u_int g_ventoy_debug = 0; +SYSCTL_UINT(_kern_geom_ventoy, OID_AUTO, debug, CTLFLAG_RWTUN, &g_ventoy_debug, 0, + "Debug level"); + +extern int resource_string_value(const char *name, int unit, const char *resname, const char **result); +extern int resource_int_value(const char *name, int unit, const char *resname, int *result); + +static int g_ventoy_destroy(struct g_ventoy_softc *sc, boolean_t force); +static int g_ventoy_destroy_geom(struct gctl_req *req, struct g_class *mp, + struct g_geom *gp); + +static g_taste_t g_ventoy_taste; +static g_ctl_req_t g_ventoy_config; +static g_dumpconf_t g_ventoy_dumpconf; + +static const char *g_ventoy_disk_uuid = NULL; +static bool g_ventoy_tasted = false; +static off_t g_ventoy_disk_size = 0; +static off_t g_disk_map_start = 0; +static off_t g_disk_map_end = 0; + +struct g_class g_ventoy_class = { + .name = G_VENTOY_CLASS_NAME, + .version = G_VERSION, + .ctlreq = g_ventoy_config, + .taste = g_ventoy_taste, + .destroy_geom = g_ventoy_destroy_geom +}; + + +/* + * Greatest Common Divisor. + */ +static u_int +gcd(u_int a, u_int b) +{ + u_int c; + + while (b != 0) { + c = a; + a = b; + b = (c % b); + } + return (a); +} + +/* + * Least Common Multiple. + */ +static u_int +lcm(u_int a, u_int b) +{ + + return ((a * b) / gcd(a, b)); +} + +/* + * Return the number of valid disks. + */ +static u_int +g_ventoy_nvalid(struct g_ventoy_softc *sc) +{ + u_int i, no; + + no = 0; + for (i = 0; i < sc->sc_ndisks; i++) { + if (sc->sc_disks[i].d_consumer != NULL) + no++; + } + + return (no); +} + +static void +g_ventoy_remove_disk(struct g_ventoy_disk *disk) +{ + struct g_consumer *cp; + struct g_ventoy_softc *sc; + + g_topology_assert(); + KASSERT(disk->d_consumer != NULL, ("Non-valid disk in %s.", __func__)); + sc = disk->d_softc; + cp = disk->d_consumer; + + if (!disk->d_removed) { + G_VENTOY_DEBUG(0, "Disk %s removed from %s.", + cp->provider->name, sc->sc_name); + disk->d_removed = 1; + } + + if (sc->sc_provider != NULL) { + sc->sc_provider->flags |= G_PF_WITHER; + G_VENTOY_DEBUG(0, "Device %s deactivated.", + sc->sc_provider->name); + g_orphan_provider(sc->sc_provider, ENXIO); + sc->sc_provider = NULL; + } + + if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0) + return; + disk->d_consumer = NULL; + g_detach(cp); + g_destroy_consumer(cp); + /* If there are no valid disks anymore, remove device. */ + if (LIST_EMPTY(&sc->sc_geom->consumer)) + g_ventoy_destroy(sc, 1); +} + +static void +g_ventoy_orphan(struct g_consumer *cp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_geom *gp; + + g_topology_assert(); + gp = cp->geom; + sc = gp->softc; + if (sc == NULL) + return; + + disk = cp->private; + if (disk == NULL) /* Possible? */ + return; + g_ventoy_remove_disk(disk); +} + +static int +g_ventoy_access(struct g_provider *pp, int dr, int dw, int de) +{ + struct g_consumer *cp1, *cp2, *tmp; + struct g_ventoy_disk *disk; + struct g_geom *gp; + int error; + + if (dw > 0) /* readonly */ + return (EPERM); + + g_topology_assert(); + gp = pp->geom; + + /* On first open, grab an extra "exclusive" bit */ + if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) + de++; + /* ... and let go of it on last close */ + if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) + de--; + + LIST_FOREACH_SAFE(cp1, &gp->consumer, consumer, tmp) { + error = g_access(cp1, dr, dw, de); + if (error != 0) + goto fail; + disk = cp1->private; + if (cp1->acr == 0 && cp1->acw == 0 && cp1->ace == 0 && + disk->d_removed) { + g_ventoy_remove_disk(disk); /* May destroy geom. */ + } + } + return (0); + +fail: + LIST_FOREACH(cp2, &gp->consumer, consumer) { + if (cp1 == cp2) + break; + g_access(cp2, -dr, -dw, -de); + } + return (error); +} + +static void +g_ventoy_kernel_dump(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct bio *cbp; + struct g_kerneldump *gkd; + u_int i; + + sc = bp->bio_to->geom->softc; + gkd = (struct g_kerneldump *)bp->bio_data; + for (i = 0; i < sc->sc_ndisks; i++) { + if (sc->sc_disks[i].d_start <= gkd->offset && + sc->sc_disks[i].d_end > gkd->offset) + break; + } + if (i == sc->sc_ndisks) + g_io_deliver(bp, EOPNOTSUPP); + disk = &sc->sc_disks[i]; + gkd->offset -= disk->d_start; + if (gkd->length > disk->d_end - disk->d_start - gkd->offset) + gkd->length = disk->d_end - disk->d_start - gkd->offset; + cbp = g_clone_bio(bp); + if (cbp == NULL) { + g_io_deliver(bp, ENOMEM); + return; + } + cbp->bio_done = g_std_done; + g_io_request(cbp, disk->d_consumer); + G_VENTOY_DEBUG(1, "Kernel dump will go to %s.", + disk->d_consumer->provider->name); +} + +static void +g_ventoy_done(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct bio *pbp; + + pbp = bp->bio_parent; + sc = pbp->bio_to->geom->softc; + mtx_lock(&sc->sc_lock); + if (pbp->bio_error == 0) + pbp->bio_error = bp->bio_error; + pbp->bio_completed += bp->bio_completed; + pbp->bio_inbed++; + if (pbp->bio_children == pbp->bio_inbed) { + mtx_unlock(&sc->sc_lock); + g_io_deliver(pbp, pbp->bio_error); + } else + mtx_unlock(&sc->sc_lock); + g_destroy_bio(bp); +} + +static void +g_ventoy_flush(struct g_ventoy_softc *sc, struct bio *bp) +{ + struct bio_queue_head queue; + struct g_consumer *cp; + struct bio *cbp; + u_int no; + + bioq_init(&queue); + for (no = 0; no < sc->sc_ndisks; no++) { + cbp = g_clone_bio(bp); + if (cbp == NULL) { + while ((cbp = bioq_takefirst(&queue)) != NULL) + g_destroy_bio(cbp); + if (bp->bio_error == 0) + bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); + return; + } + bioq_insert_tail(&queue, cbp); + cbp->bio_done = g_ventoy_done; + cbp->bio_caller1 = sc->sc_disks[no].d_consumer; + cbp->bio_to = sc->sc_disks[no].d_consumer->provider; + } + while ((cbp = bioq_takefirst(&queue)) != NULL) { + G_VENTOY_LOGREQ(cbp, "Sending request."); + cp = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, cp); + } +} + +static void +g_ventoy_start(struct bio *bp) +{ + struct bio_queue_head queue; + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_provider *pp; + off_t offset, end, length, off, len; + struct bio *cbp; + char *addr; + u_int no; + + pp = bp->bio_to; + sc = pp->geom->softc; + /* + * If sc == NULL, provider's error should be set and g_ventoy_start() + * should not be called at all. + */ + KASSERT(sc != NULL, + ("Provider's error should be set (error=%d)(device=%s).", + bp->bio_to->error, bp->bio_to->name)); + + G_VENTOY_LOGREQ(bp, "Request received."); + + switch (bp->bio_cmd) { + case BIO_READ: + case BIO_WRITE: + case BIO_DELETE: + break; + case BIO_FLUSH: + g_ventoy_flush(sc, bp); + return; + case BIO_GETATTR: + if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) { + g_ventoy_kernel_dump(bp); + return; + } + /* To which provider it should be delivered? */ + /* FALLTHROUGH */ + default: + g_io_deliver(bp, EOPNOTSUPP); + return; + } + + offset = bp->bio_offset; + length = bp->bio_length; + if ((bp->bio_flags & BIO_UNMAPPED) != 0) + addr = NULL; + else + addr = bp->bio_data; + end = offset + length; + + bioq_init(&queue); + for (no = 0; no < sc->sc_ndisks; no++) { + disk = &sc->sc_disks[no]; + if (disk->d_end <= offset) + continue; + if (disk->d_start >= end) + break; + + off = offset - disk->d_start; + len = MIN(length, disk->d_end - offset); + length -= len; + offset += len; + + cbp = g_clone_bio(bp); + if (cbp == NULL) { + while ((cbp = bioq_takefirst(&queue)) != NULL) + g_destroy_bio(cbp); + if (bp->bio_error == 0) + bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); + return; + } + bioq_insert_tail(&queue, cbp); + /* + * Fill in the component buf structure. + */ + if (len == bp->bio_length) + cbp->bio_done = g_std_done; + else + cbp->bio_done = g_ventoy_done; + cbp->bio_offset = off + disk->d_map_start; + cbp->bio_length = len; + if ((bp->bio_flags & BIO_UNMAPPED) != 0) { + cbp->bio_ma_offset += (uintptr_t)addr; + cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE; + cbp->bio_ma_offset %= PAGE_SIZE; + cbp->bio_ma_n = round_page(cbp->bio_ma_offset + + cbp->bio_length) / PAGE_SIZE; + } else + cbp->bio_data = addr; + addr += len; + cbp->bio_to = disk->d_consumer->provider; + cbp->bio_caller1 = disk; + + if (length == 0) + break; + } + KASSERT(length == 0, + ("Length is still greater than 0 (class=%s, name=%s).", + bp->bio_to->geom->class->name, bp->bio_to->geom->name)); + while ((cbp = bioq_takefirst(&queue)) != NULL) { + G_VENTOY_LOGREQ(cbp, "Sending request."); + disk = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, disk->d_consumer); + } +} + +static void +g_ventoy_check_and_run(struct g_ventoy_softc *sc) +{ + struct g_ventoy_disk *disk; + struct g_provider *dp, *pp; + u_int no, sectorsize = 0; + off_t start; + + g_topology_assert(); + if (g_ventoy_nvalid(sc) != sc->sc_ndisks) + return; + + pp = g_new_providerf(sc->sc_geom, "ventoy/%s", sc->sc_name); + pp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE | + G_PF_ACCEPT_UNMAPPED; + start = 0; + for (no = 0; no < sc->sc_ndisks; no++) { + disk = &sc->sc_disks[no]; + dp = disk->d_consumer->provider; + disk->d_start = start; + disk->d_end = disk->d_start + (disk->d_map_end - disk->d_map_start); + if (sc->sc_type == G_VENTOY_TYPE_AUTOMATIC) + disk->d_end -= dp->sectorsize; + start = disk->d_end; + if (no == 0) + sectorsize = dp->sectorsize; + else + sectorsize = lcm(sectorsize, dp->sectorsize); + + /* A provider underneath us doesn't support unmapped */ + if ((dp->flags & G_PF_ACCEPT_UNMAPPED) == 0) { + G_VENTOY_DEBUG(1, "Cancelling unmapped " + "because of %s.", dp->name); + pp->flags &= ~G_PF_ACCEPT_UNMAPPED; + } + } + pp->sectorsize = sectorsize; + /* We have sc->sc_disks[sc->sc_ndisks - 1].d_end in 'start'. */ + pp->mediasize = start; + pp->stripesize = sc->sc_disks[0].d_consumer->provider->stripesize; + pp->stripeoffset = sc->sc_disks[0].d_consumer->provider->stripeoffset; + sc->sc_provider = pp; + g_error_provider(pp, 0); + + G_VENTOY_DEBUG(0, "Device %s activated.", sc->sc_provider->name); +} + +static int +g_ventoy_read_metadata(struct g_consumer *cp, struct g_ventoy_metadata *md) +{ + struct g_provider *pp; + u_char *buf; + int error; + + g_topology_assert(); + + error = g_access(cp, 1, 0, 0); + if (error != 0) + return (error); + pp = cp->provider; + g_topology_unlock(); + buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize, + &error); + g_topology_lock(); + g_access(cp, -1, 0, 0); + if (buf == NULL) + return (error); + + /* Decode metadata. */ + ventoy_metadata_decode(buf, md); + g_free(buf); + + return (0); +} + +/* + * Add disk to given device. + */ +static int +g_ventoy_add_disk(struct g_ventoy_softc *sc, struct g_provider *pp, u_int no) +{ + struct g_ventoy_disk *disk; + struct g_consumer *cp, *fcp; + struct g_geom *gp; + int error; + + g_topology_assert(); + /* Metadata corrupted? */ + if (no >= sc->sc_ndisks) + return (EINVAL); + + disk = &sc->sc_disks[no]; + /* Check if disk is not already attached. */ + if (disk->d_consumer != NULL) + return (EEXIST); + + gp = sc->sc_geom; + fcp = LIST_FIRST(&gp->consumer); + + cp = g_new_consumer(gp); + cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE; + error = g_attach(cp, pp); + if (error != 0) { + g_destroy_consumer(cp); + return (error); + } + + if (fcp != NULL && (fcp->acr > 0 || fcp->acw > 0 || fcp->ace > 0)) { + error = g_access(cp, fcp->acr, fcp->acw, fcp->ace); + if (error != 0) { + g_detach(cp); + g_destroy_consumer(cp); + return (error); + } + } + if (sc->sc_type == G_VENTOY_TYPE_AUTOMATIC) { + struct g_ventoy_metadata md; + + /* Re-read metadata. */ + error = g_ventoy_read_metadata(cp, &md); + if (error != 0) + goto fail; + + if (strcmp(md.md_magic, G_VENTOY_MAGIC) != 0 || + strcmp(md.md_name, sc->sc_name) != 0 || + md.md_id != sc->sc_id) { + G_VENTOY_DEBUG(0, "Metadata on %s changed.", pp->name); + goto fail; + } + } + + cp->private = disk; + disk->d_consumer = cp; + disk->d_softc = sc; + disk->d_start = 0; /* not yet */ + disk->d_end = 0; /* not yet */ + disk->d_removed = 0; + + disk->d_map_start = g_disk_map_start; + disk->d_map_end = g_disk_map_end; + + G_VENTOY_DEBUG(0, "Disk %s attached to %s.", pp->name, sc->sc_name); + + g_ventoy_check_and_run(sc); + + return (0); +fail: + if (fcp != NULL && (fcp->acr > 0 || fcp->acw > 0 || fcp->ace > 0)) + g_access(cp, -fcp->acr, -fcp->acw, -fcp->ace); + g_detach(cp); + g_destroy_consumer(cp); + return (error); +} + +static struct g_geom * +g_ventoy_create(struct g_class *mp, const struct g_ventoy_metadata *md, + u_int type) +{ + struct g_ventoy_softc *sc; + struct g_geom *gp; + u_int no; + + G_VENTOY_DEBUG(1, "Creating device %s (id=%u).", md->md_name, + md->md_id); + + /* One disks is minimum. */ + if (md->md_all < 1) + return (NULL); + + /* Check for duplicate unit */ + LIST_FOREACH(gp, &mp->geom, geom) { + sc = gp->softc; + if (sc != NULL && strcmp(sc->sc_name, md->md_name) == 0) { + G_VENTOY_DEBUG(0, "Device %s already configured.", + gp->name); + return (NULL); + } + } + gp = g_new_geomf(mp, "%s", md->md_name); + sc = malloc(sizeof(*sc), M_VENTOY, M_WAITOK | M_ZERO); + gp->start = g_ventoy_start; + gp->spoiled = g_ventoy_orphan; + gp->orphan = g_ventoy_orphan; + gp->access = g_ventoy_access; + gp->dumpconf = g_ventoy_dumpconf; + + sc->sc_id = md->md_id; + sc->sc_ndisks = md->md_all; + sc->sc_disks = malloc(sizeof(struct g_ventoy_disk) * sc->sc_ndisks, + M_VENTOY, M_WAITOK | M_ZERO); + for (no = 0; no < sc->sc_ndisks; no++) + sc->sc_disks[no].d_consumer = NULL; + sc->sc_type = type; + mtx_init(&sc->sc_lock, "gventoy lock", NULL, MTX_DEF); + + gp->softc = sc; + sc->sc_geom = gp; + sc->sc_provider = NULL; + + G_VENTOY_DEBUG(0, "Device %s created (id=%u).", sc->sc_name, sc->sc_id); + + return (gp); +} + +static int +g_ventoy_destroy(struct g_ventoy_softc *sc, boolean_t force) +{ + struct g_provider *pp; + struct g_consumer *cp, *cp1; + struct g_geom *gp; + + g_topology_assert(); + + if (sc == NULL) + return (ENXIO); + + pp = sc->sc_provider; + if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) { + if (force) { + G_VENTOY_DEBUG(0, "Device %s is still open, so it " + "can't be definitely removed.", pp->name); + } else { + G_VENTOY_DEBUG(1, + "Device %s is still open (r%dw%de%d).", pp->name, + pp->acr, pp->acw, pp->ace); + return (EBUSY); + } + } + + gp = sc->sc_geom; + LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp1) { + g_ventoy_remove_disk(cp->private); + if (cp1 == NULL) + return (0); /* Recursion happened. */ + } + if (!LIST_EMPTY(&gp->consumer)) + return (EINPROGRESS); + + gp->softc = NULL; + KASSERT(sc->sc_provider == NULL, ("Provider still exists? (device=%s)", + gp->name)); + free(sc->sc_disks, M_VENTOY); + mtx_destroy(&sc->sc_lock); + free(sc, M_VENTOY); + + G_VENTOY_DEBUG(0, "Device %s destroyed.", gp->name); + g_wither_geom(gp, ENXIO); + return (0); +} + +static int +g_ventoy_destroy_geom(struct gctl_req *req __unused, + struct g_class *mp __unused, struct g_geom *gp) +{ + struct g_ventoy_softc *sc; + + sc = gp->softc; + return (g_ventoy_destroy(sc, 0)); +} + +static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) +{ + int i; + uint8_t *buf; + char uuid[64]; + const char *value; + struct g_consumer *cp; + struct g_geom *gp; + + if (g_ventoy_disk_size == 0) + { + if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + { + G_DEBUG("ventoy.disksize: %s\n", value); + g_ventoy_disk_size = strtouq(value, NULL, 0); + } + + if (resource_string_value("ventoy", 0, "diskuuid", &g_ventoy_disk_uuid) == 0) + { + G_DEBUG("ventoy.diskuuid: <%s>\n", g_ventoy_disk_uuid); + } + } + + if (g_ventoy_disk_size != pp->mediasize) + { + return false; + } + + if (strncmp(pp->name, "cd", 2) == 0 || strchr(pp->name, '/')) + { + return false; + } + + /* read UUID from disk */ + gp = g_new_geomf(mp, "ventoy:taste"); + gp->start = NULL; + gp->access = g_ventoy_access; + gp->orphan = g_ventoy_orphan; + cp = g_new_consumer(gp); + g_attach(cp, pp); + + g_access(cp, 1, 0, 0); + g_topology_unlock(); + buf = g_read_data(cp, 0, pp->sectorsize, NULL); + g_topology_lock(); + g_access(cp, -1, 0, 0); + + g_detach(cp); + g_destroy_consumer(cp); + g_destroy_geom(gp); + gp = NULL; + + if (!buf) + { + return false; + } + + for (i = 0; i < 16; i++) + { + sprintf(uuid + i * 2, "%02x", buf[0x180 + i]); + } + g_free(buf); + + if (strncmp(g_ventoy_disk_uuid, uuid, 32) == 0) + { + return true; + } + + return false; +} + +static struct g_geom * +g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) +{ + int i; + int error; + int disknum; + char *endpos; + const char *value; + struct g_geom *gp; + struct g_ventoy_metadata md; + struct g_ventoy_softc *sc; + + if (g_ventoy_tasted) + { + return NULL; + } + + G_DEBUG("%s(%s, %s)\n", __func__, mp->name, pp->name); + g_topology_assert(); + + /* Skip providers that are already open for writing. */ + if (pp->acw > 0) + return (NULL); + + if (!g_vtoy_check_disk(mp, pp)) + { + return NULL; + } + + g_ventoy_tasted = true; + + G_DEBUG("######### ventoy disk <%s> #############\n", pp->name); + + resource_int_value("ventoy", 0, "segnum", &disknum); + + strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); + md.md_version = G_VENTOY_VERSION; + strlcpy(md.md_name, "IMAGE", sizeof(md.md_name)); + md.md_id = arc4random(); + md.md_no = 0; + md.md_all = (uint16_t)disknum; + bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; + + gp = g_ventoy_create(mp, &md, G_VENTOY_TYPE_MANUAL); + if (gp == NULL) { + G_VENTOY_DEBUG(0, "Cannot create device %s.", + md.md_name); + return (NULL); + } + sc = gp->softc; + + for (i = 0; i < disknum; i ++) + { + if (resource_string_value("ventoy", i, "seg", &value) == 0) + { + g_disk_map_start = strtouq(value, &endpos, 0); + g_disk_map_end = strtouq(endpos + 1, NULL, 0); + } + else + { + printf("Failed to parse ventoy seg %d\n", i); + continue; + } + + G_DEBUG("ventoy segment%d: %s\n", i, value); + + G_VENTOY_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name); + error = g_ventoy_add_disk(sc, pp, i); + if (error != 0) { + G_VENTOY_DEBUG(0, + "Cannot add disk %s to %s (error=%d).", pp->name, + gp->name, error); + g_ventoy_destroy(sc, 1); + return (NULL); + } + + g_disk_map_start = 0; + g_disk_map_end = 0; + } + + return (gp); +} + +static void +g_ventoy_ctl_create(struct gctl_req *req, struct g_class *mp) +{ + u_int attached, no; + struct g_ventoy_metadata md; + struct g_provider *pp; + struct g_ventoy_softc *sc; + struct g_geom *gp; + struct sbuf *sb; + const char *name; + char param[16]; + int *nargs; + + g_topology_assert(); + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument.", "nargs"); + return; + } + if (*nargs < 2) { + gctl_error(req, "Too few arguments."); + return; + } + + strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); + md.md_version = G_VENTOY_VERSION; + name = gctl_get_asciiparam(req, "arg0"); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", 0); + return; + } + strlcpy(md.md_name, name, sizeof(md.md_name)); + md.md_id = arc4random(); + md.md_no = 0; + md.md_all = *nargs - 1; + bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; + + /* Check all providers are valid */ + for (no = 1; no < *nargs; no++) { + snprintf(param, sizeof(param), "arg%u", no); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", no); + return; + } + if (strncmp(name, "/dev/", strlen("/dev/")) == 0) + name += strlen("/dev/"); + pp = g_provider_by_name(name); + if (pp == NULL) { + G_VENTOY_DEBUG(1, "Disk %s is invalid.", name); + gctl_error(req, "Disk %s is invalid.", name); + return; + } + } + + gp = g_ventoy_create(mp, &md, G_VENTOY_TYPE_MANUAL); + if (gp == NULL) { + gctl_error(req, "Can't configure %s.", md.md_name); + return; + } + + sc = gp->softc; + sb = sbuf_new_auto(); + sbuf_printf(sb, "Can't attach disk(s) to %s:", gp->name); + for (attached = 0, no = 1; no < *nargs; no++) { + snprintf(param, sizeof(param), "arg%u", no); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%d' argument.", no); + return; + } + if (strncmp(name, "/dev/", strlen("/dev/")) == 0) + name += strlen("/dev/"); + pp = g_provider_by_name(name); + KASSERT(pp != NULL, ("Provider %s disappear?!", name)); + if (g_ventoy_add_disk(sc, pp, no - 1) != 0) { + G_VENTOY_DEBUG(1, "Disk %u (%s) not attached to %s.", + no, pp->name, gp->name); + sbuf_printf(sb, " %s", pp->name); + continue; + } + attached++; + } + sbuf_finish(sb); + if (md.md_all != attached) { + g_ventoy_destroy(gp->softc, 1); + gctl_error(req, "%s", sbuf_data(sb)); + } + sbuf_delete(sb); +} + +static struct g_ventoy_softc * +g_ventoy_find_device(struct g_class *mp, const char *name) +{ + struct g_ventoy_softc *sc; + struct g_geom *gp; + + LIST_FOREACH(gp, &mp->geom, geom) { + sc = gp->softc; + if (sc == NULL) + continue; + if (strcmp(sc->sc_name, name) == 0) + return (sc); + } + return (NULL); +} + +static void +g_ventoy_ctl_destroy(struct gctl_req *req, struct g_class *mp) +{ + struct g_ventoy_softc *sc; + int *force, *nargs, error; + const char *name; + char param[16]; + u_int i; + + g_topology_assert(); + + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument.", "nargs"); + return; + } + if (*nargs <= 0) { + gctl_error(req, "Missing device(s)."); + return; + } + force = gctl_get_paraml(req, "force", sizeof(*force)); + if (force == NULL) { + gctl_error(req, "No '%s' argument.", "force"); + return; + } + + for (i = 0; i < (u_int)*nargs; i++) { + snprintf(param, sizeof(param), "arg%u", i); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", i); + return; + } + sc = g_ventoy_find_device(mp, name); + if (sc == NULL) { + gctl_error(req, "No such device: %s.", name); + return; + } + error = g_ventoy_destroy(sc, *force); + if (error != 0) { + gctl_error(req, "Cannot destroy device %s (error=%d).", + sc->sc_name, error); + return; + } + } +} + +static void +g_ventoy_config(struct gctl_req *req, struct g_class *mp, const char *verb) +{ + uint32_t *version; + + return; + + g_topology_assert(); + + version = gctl_get_paraml(req, "version", sizeof(*version)); + if (version == NULL) { + gctl_error(req, "No '%s' argument.", "version"); + return; + } + if (*version != G_VENTOY_VERSION) { + gctl_error(req, "Userland and kernel parts are out of sync."); + return; + } + + if (strcmp(verb, "create") == 0) { + g_ventoy_ctl_create(req, mp); + return; + } else if (strcmp(verb, "destroy") == 0 || + strcmp(verb, "stop") == 0) { + g_ventoy_ctl_destroy(req, mp); + return; + } + gctl_error(req, "Unknown verb."); +} + +static void +g_ventoy_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, + struct g_consumer *cp, struct g_provider *pp) +{ + struct g_ventoy_softc *sc; + + g_topology_assert(); + sc = gp->softc; + if (sc == NULL) + return; + if (pp != NULL) { + /* Nothing here. */ + } else if (cp != NULL) { + struct g_ventoy_disk *disk; + + disk = cp->private; + if (disk == NULL) + return; + sbuf_printf(sb, "%s%jd\n", indent, + (intmax_t)disk->d_end); + sbuf_printf(sb, "%s%jd\n", indent, + (intmax_t)disk->d_start); + } else { + sbuf_printf(sb, "%s%u\n", indent, (u_int)sc->sc_id); + sbuf_printf(sb, "%s", indent); + switch (sc->sc_type) { + case G_VENTOY_TYPE_AUTOMATIC: + sbuf_cat(sb, "AUTOMATIC"); + break; + case G_VENTOY_TYPE_MANUAL: + sbuf_cat(sb, "MANUAL"); + break; + default: + sbuf_cat(sb, "UNKNOWN"); + break; + } + sbuf_cat(sb, "\n"); + sbuf_printf(sb, "%sTotal=%u, Online=%u\n", + indent, sc->sc_ndisks, g_ventoy_nvalid(sc)); + sbuf_printf(sb, "%s", indent); + if (sc->sc_provider != NULL && sc->sc_provider->error == 0) + sbuf_cat(sb, "UP"); + else + sbuf_cat(sb, "DOWN"); + sbuf_cat(sb, "\n"); + } +} + +DECLARE_GEOM_CLASS(g_ventoy_class, g_ventoy); diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.h b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.h new file mode 100644 index 00000000..e442b246 --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.h @@ -0,0 +1,117 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 longpanda + * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _G_VENTOY_H_ +#define _G_VENTOY_H_ + +#include + +#define G_VENTOY_CLASS_NAME "VENTOY" + +#define G_VENTOY_MAGIC "GEOM::VENTOY" +/* + * Version history: + * 1 - Initial version number. + * 2 - Added 'stop' command to gconcat(8). + * 3 - Added md_provider field to metadata and '-h' option to gconcat(8). + * 4 - Added md_provsize field to metadata. + */ +#define G_VENTOY_VERSION 4 + +#ifdef _KERNEL +#define G_VENTOY_TYPE_MANUAL 0 +#define G_VENTOY_TYPE_AUTOMATIC 1 + +#define G_DEBUG(...) if (bootverbose) printf(__VA_ARGS__) +#define G_VENTOY_DEBUG(lvl, ...) if (g_ventoy_debug) printf(__VA_ARGS__) +#define G_VENTOY_LOGREQ(bp, ...) if (g_ventoy_debug) printf(__VA_ARGS__) + +struct g_ventoy_disk { + struct g_consumer *d_consumer; + struct g_ventoy_softc *d_softc; + off_t d_start; + off_t d_end; + off_t d_map_start; + off_t d_map_end; + int d_candelete; + int d_removed; +}; + +struct g_ventoy_softc { + u_int sc_type; /* provider type */ + struct g_geom *sc_geom; + struct g_provider *sc_provider; + uint32_t sc_id; /* concat unique ID */ + + struct g_ventoy_disk *sc_disks; + uint16_t sc_ndisks; + struct mtx sc_lock; +}; +#define sc_name sc_geom->name +#endif /* _KERNEL */ + +struct g_ventoy_metadata { + char md_magic[16]; /* Magic value. */ + uint32_t md_version; /* Version number. */ + char md_name[16]; /* Concat name. */ + uint32_t md_id; /* Unique ID. */ + uint16_t md_no; /* Disk number. */ + uint16_t md_all; /* Number of all disks. */ + char md_provider[16]; /* Hardcoded provider. */ + uint64_t md_provsize; /* Provider's size. */ +}; +static __inline void +ventoy_metadata_encode(const struct g_ventoy_metadata *md, u_char *data) +{ + + bcopy(md->md_magic, data, sizeof(md->md_magic)); + le32enc(data + 16, md->md_version); + bcopy(md->md_name, data + 20, sizeof(md->md_name)); + le32enc(data + 36, md->md_id); + le16enc(data + 40, md->md_no); + le16enc(data + 42, md->md_all); + bcopy(md->md_provider, data + 44, sizeof(md->md_provider)); + le64enc(data + 60, md->md_provsize); +} +static __inline void +ventoy_metadata_decode(const u_char *data, struct g_ventoy_metadata *md) +{ + + bcopy(data, md->md_magic, sizeof(md->md_magic)); + md->md_version = le32dec(data + 16); + bcopy(data + 20, md->md_name, sizeof(md->md_name)); + md->md_id = le32dec(data + 36); + md->md_no = le16dec(data + 40); + md->md_all = le16dec(data + 42); + bcopy(data + 44, md->md_provider, sizeof(md->md_provider)); + md->md_provsize = le64dec(data + 60); +} +#endif /* _G_VENTOY_H_ */ diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/modules/geom/geom_ventoy/Makefile b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/modules/geom/geom_ventoy/Makefile new file mode 100644 index 00000000..165f1bdf --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/modules/geom/geom_ventoy/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/sys/geom/ventoy + +KMOD= geom_ventoy +SRCS= g_ventoy.c + +.include diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/12.x/sys/geom/ventoy/g_ventoy.c b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/12.x/sys/geom/ventoy/g_ventoy.c new file mode 100644 index 00000000..8de7a222 --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/12.x/sys/geom/ventoy/g_ventoy.c @@ -0,0 +1,1068 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 longpanda + * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +FEATURE(geom_ventoy, "GEOM ventoy support"); + +static MALLOC_DEFINE(M_VENTOY, "ventoy_data", "GEOM_VENTOY Data"); + +SYSCTL_DECL(_kern_geom); +static SYSCTL_NODE(_kern_geom, OID_AUTO, ventoy, CTLFLAG_RW, 0, + "GEOM_VENTOY stuff"); +static u_int g_ventoy_debug = 0; +SYSCTL_UINT(_kern_geom_ventoy, OID_AUTO, debug, CTLFLAG_RWTUN, &g_ventoy_debug, 0, + "Debug level"); + +extern int resource_string_value(const char *name, int unit, const char *resname, const char **result); +extern int resource_int_value(const char *name, int unit, const char *resname, int *result); + +static int g_ventoy_destroy(struct g_ventoy_softc *sc, boolean_t force); +static int g_ventoy_destroy_geom(struct gctl_req *req, struct g_class *mp, + struct g_geom *gp); + +static g_taste_t g_ventoy_taste; +static g_ctl_req_t g_ventoy_config; +static g_dumpconf_t g_ventoy_dumpconf; + +static const char *g_ventoy_disk_uuid = NULL; +static bool g_ventoy_tasted = false; +static off_t g_ventoy_disk_size = 0; +static off_t g_disk_map_start = 0; +static off_t g_disk_map_end = 0; + +struct g_class g_ventoy_class = { + .name = G_VENTOY_CLASS_NAME, + .version = G_VERSION, + .ctlreq = g_ventoy_config, + .taste = g_ventoy_taste, + .destroy_geom = g_ventoy_destroy_geom +}; + + +/* + * Greatest Common Divisor. + */ +static u_int +gcd(u_int a, u_int b) +{ + u_int c; + + while (b != 0) { + c = a; + a = b; + b = (c % b); + } + return (a); +} + +/* + * Least Common Multiple. + */ +static u_int +lcm(u_int a, u_int b) +{ + + return ((a * b) / gcd(a, b)); +} + +/* + * Return the number of valid disks. + */ +static u_int +g_ventoy_nvalid(struct g_ventoy_softc *sc) +{ + u_int i, no; + + no = 0; + for (i = 0; i < sc->sc_ndisks; i++) { + if (sc->sc_disks[i].d_consumer != NULL) + no++; + } + + return (no); +} + +static void +g_ventoy_remove_disk(struct g_ventoy_disk *disk) +{ + struct g_consumer *cp; + struct g_ventoy_softc *sc; + + g_topology_assert(); + KASSERT(disk->d_consumer != NULL, ("Non-valid disk in %s.", __func__)); + sc = disk->d_softc; + cp = disk->d_consumer; + + if (!disk->d_removed) { + G_VENTOY_DEBUG(0, "Disk %s removed from %s.", + cp->provider->name, sc->sc_name); + disk->d_removed = 1; + } + + if (sc->sc_provider != NULL) { + G_VENTOY_DEBUG(0, "Device %s deactivated.", + sc->sc_provider->name); + g_wither_provider(sc->sc_provider, ENXIO); + sc->sc_provider = NULL; + } + + if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0) + return; + disk->d_consumer = NULL; + g_detach(cp); + g_destroy_consumer(cp); + /* If there are no valid disks anymore, remove device. */ + if (LIST_EMPTY(&sc->sc_geom->consumer)) + g_ventoy_destroy(sc, 1); +} + +static void +g_ventoy_orphan(struct g_consumer *cp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_geom *gp; + + g_topology_assert(); + gp = cp->geom; + sc = gp->softc; + if (sc == NULL) + return; + + disk = cp->private; + if (disk == NULL) /* Possible? */ + return; + g_ventoy_remove_disk(disk); +} + +static int +g_ventoy_access(struct g_provider *pp, int dr, int dw, int de) +{ + struct g_consumer *cp1, *cp2, *tmp; + struct g_ventoy_disk *disk; + struct g_geom *gp; + int error; + + if (dw > 0) /* readonly */ + return (EPERM); + + g_topology_assert(); + gp = pp->geom; + + /* On first open, grab an extra "exclusive" bit */ + if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) + de++; + /* ... and let go of it on last close */ + if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) + de--; + + LIST_FOREACH_SAFE(cp1, &gp->consumer, consumer, tmp) { + error = g_access(cp1, dr, dw, de); + if (error != 0) + goto fail; + disk = cp1->private; + if (cp1->acr == 0 && cp1->acw == 0 && cp1->ace == 0 && + disk->d_removed) { + g_ventoy_remove_disk(disk); /* May destroy geom. */ + } + } + return (0); + +fail: + LIST_FOREACH(cp2, &gp->consumer, consumer) { + if (cp1 == cp2) + break; + g_access(cp2, -dr, -dw, -de); + } + return (error); +} + +static void +g_ventoy_kernel_dump(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct bio *cbp; + struct g_kerneldump *gkd; + u_int i; + + sc = bp->bio_to->geom->softc; + gkd = (struct g_kerneldump *)bp->bio_data; + for (i = 0; i < sc->sc_ndisks; i++) { + if (sc->sc_disks[i].d_start <= gkd->offset && + sc->sc_disks[i].d_end > gkd->offset) + break; + } + if (i == sc->sc_ndisks) + g_io_deliver(bp, EOPNOTSUPP); + disk = &sc->sc_disks[i]; + gkd->offset -= disk->d_start; + if (gkd->length > disk->d_end - disk->d_start - gkd->offset) + gkd->length = disk->d_end - disk->d_start - gkd->offset; + cbp = g_clone_bio(bp); + if (cbp == NULL) { + g_io_deliver(bp, ENOMEM); + return; + } + cbp->bio_done = g_std_done; + g_io_request(cbp, disk->d_consumer); + G_VENTOY_DEBUG(1, "Kernel dump will go to %s.", + disk->d_consumer->provider->name); +} + +static void +g_ventoy_done(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct bio *pbp; + + pbp = bp->bio_parent; + sc = pbp->bio_to->geom->softc; + mtx_lock(&sc->sc_lock); + if (pbp->bio_error == 0) + pbp->bio_error = bp->bio_error; + pbp->bio_completed += bp->bio_completed; + pbp->bio_inbed++; + if (pbp->bio_children == pbp->bio_inbed) { + mtx_unlock(&sc->sc_lock); + g_io_deliver(pbp, pbp->bio_error); + } else + mtx_unlock(&sc->sc_lock); + g_destroy_bio(bp); +} + +static void +g_ventoy_flush(struct g_ventoy_softc *sc, struct bio *bp) +{ + struct bio_queue_head queue; + struct g_consumer *cp; + struct bio *cbp; + u_int no; + + bioq_init(&queue); + for (no = 0; no < sc->sc_ndisks; no++) { + cbp = g_clone_bio(bp); + if (cbp == NULL) { + while ((cbp = bioq_takefirst(&queue)) != NULL) + g_destroy_bio(cbp); + if (bp->bio_error == 0) + bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); + return; + } + bioq_insert_tail(&queue, cbp); + cbp->bio_done = g_ventoy_done; + cbp->bio_caller1 = sc->sc_disks[no].d_consumer; + cbp->bio_to = sc->sc_disks[no].d_consumer->provider; + } + while ((cbp = bioq_takefirst(&queue)) != NULL) { + G_VENTOY_LOGREQ(cbp, "Sending request."); + cp = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, cp); + } +} + +static void +g_ventoy_start(struct bio *bp) +{ + struct bio_queue_head queue; + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_provider *pp; + off_t offset, end, length, off, len; + struct bio *cbp; + char *addr; + u_int no; + + pp = bp->bio_to; + sc = pp->geom->softc; + /* + * If sc == NULL, provider's error should be set and g_ventoy_start() + * should not be called at all. + */ + KASSERT(sc != NULL, + ("Provider's error should be set (error=%d)(device=%s).", + bp->bio_to->error, bp->bio_to->name)); + + G_VENTOY_LOGREQ(bp, "Request received."); + + switch (bp->bio_cmd) { + case BIO_READ: + case BIO_WRITE: + case BIO_DELETE: + break; + case BIO_FLUSH: + g_ventoy_flush(sc, bp); + return; + case BIO_GETATTR: + if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) { + g_ventoy_kernel_dump(bp); + return; + } + /* To which provider it should be delivered? */ + /* FALLTHROUGH */ + default: + g_io_deliver(bp, EOPNOTSUPP); + return; + } + + offset = bp->bio_offset; + length = bp->bio_length; + if ((bp->bio_flags & BIO_UNMAPPED) != 0) + addr = NULL; + else + addr = bp->bio_data; + end = offset + length; + + bioq_init(&queue); + for (no = 0; no < sc->sc_ndisks; no++) { + disk = &sc->sc_disks[no]; + if (disk->d_end <= offset) + continue; + if (disk->d_start >= end) + break; + + off = offset - disk->d_start; + len = MIN(length, disk->d_end - offset); + length -= len; + offset += len; + + cbp = g_clone_bio(bp); + if (cbp == NULL) { + while ((cbp = bioq_takefirst(&queue)) != NULL) + g_destroy_bio(cbp); + if (bp->bio_error == 0) + bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); + return; + } + bioq_insert_tail(&queue, cbp); + /* + * Fill in the component buf structure. + */ + if (len == bp->bio_length) + cbp->bio_done = g_std_done; + else + cbp->bio_done = g_ventoy_done; + cbp->bio_offset = off + disk->d_map_start; + cbp->bio_length = len; + if ((bp->bio_flags & BIO_UNMAPPED) != 0) { + cbp->bio_ma_offset += (uintptr_t)addr; + cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE; + cbp->bio_ma_offset %= PAGE_SIZE; + cbp->bio_ma_n = round_page(cbp->bio_ma_offset + + cbp->bio_length) / PAGE_SIZE; + } else + cbp->bio_data = addr; + addr += len; + cbp->bio_to = disk->d_consumer->provider; + cbp->bio_caller1 = disk; + + if (length == 0) + break; + } + KASSERT(length == 0, + ("Length is still greater than 0 (class=%s, name=%s).", + bp->bio_to->geom->class->name, bp->bio_to->geom->name)); + while ((cbp = bioq_takefirst(&queue)) != NULL) { + G_VENTOY_LOGREQ(cbp, "Sending request."); + disk = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, disk->d_consumer); + } +} + +static void +g_ventoy_check_and_run(struct g_ventoy_softc *sc) +{ + struct g_ventoy_disk *disk; + struct g_provider *dp, *pp; + u_int no, sectorsize = 0; + off_t start; + + g_topology_assert(); + if (g_ventoy_nvalid(sc) != sc->sc_ndisks) + return; + + pp = g_new_providerf(sc->sc_geom, "ventoy/%s", sc->sc_name); + pp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE | + G_PF_ACCEPT_UNMAPPED; + start = 0; + for (no = 0; no < sc->sc_ndisks; no++) { + disk = &sc->sc_disks[no]; + dp = disk->d_consumer->provider; + disk->d_start = start; + disk->d_end = disk->d_start + (disk->d_map_end - disk->d_map_start); + if (sc->sc_type == G_VENTOY_TYPE_AUTOMATIC) + disk->d_end -= dp->sectorsize; + start = disk->d_end; + if (no == 0) + sectorsize = dp->sectorsize; + else + sectorsize = lcm(sectorsize, dp->sectorsize); + + /* A provider underneath us doesn't support unmapped */ + if ((dp->flags & G_PF_ACCEPT_UNMAPPED) == 0) { + G_VENTOY_DEBUG(1, "Cancelling unmapped " + "because of %s.", dp->name); + pp->flags &= ~G_PF_ACCEPT_UNMAPPED; + } + } + pp->sectorsize = sectorsize; + /* We have sc->sc_disks[sc->sc_ndisks - 1].d_end in 'start'. */ + pp->mediasize = start; + pp->stripesize = sc->sc_disks[0].d_consumer->provider->stripesize; + pp->stripeoffset = sc->sc_disks[0].d_consumer->provider->stripeoffset; + sc->sc_provider = pp; + g_error_provider(pp, 0); + + G_VENTOY_DEBUG(0, "Device %s activated.", sc->sc_provider->name); +} + +static int +g_ventoy_read_metadata(struct g_consumer *cp, struct g_ventoy_metadata *md) +{ + struct g_provider *pp; + u_char *buf; + int error; + + g_topology_assert(); + + error = g_access(cp, 1, 0, 0); + if (error != 0) + return (error); + pp = cp->provider; + g_topology_unlock(); + buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize, + &error); + g_topology_lock(); + g_access(cp, -1, 0, 0); + if (buf == NULL) + return (error); + + /* Decode metadata. */ + ventoy_metadata_decode(buf, md); + g_free(buf); + + return (0); +} + +/* + * Add disk to given device. + */ +static int +g_ventoy_add_disk(struct g_ventoy_softc *sc, struct g_provider *pp, u_int no) +{ + struct g_ventoy_disk *disk; + struct g_consumer *cp, *fcp; + struct g_geom *gp; + int error; + + g_topology_assert(); + /* Metadata corrupted? */ + if (no >= sc->sc_ndisks) + return (EINVAL); + + disk = &sc->sc_disks[no]; + /* Check if disk is not already attached. */ + if (disk->d_consumer != NULL) + return (EEXIST); + + gp = sc->sc_geom; + fcp = LIST_FIRST(&gp->consumer); + + cp = g_new_consumer(gp); + cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE; + error = g_attach(cp, pp); + if (error != 0) { + g_destroy_consumer(cp); + return (error); + } + + if (fcp != NULL && (fcp->acr > 0 || fcp->acw > 0 || fcp->ace > 0)) { + error = g_access(cp, fcp->acr, fcp->acw, fcp->ace); + if (error != 0) { + g_detach(cp); + g_destroy_consumer(cp); + return (error); + } + } + if (sc->sc_type == G_VENTOY_TYPE_AUTOMATIC) { + struct g_ventoy_metadata md; + + /* Re-read metadata. */ + error = g_ventoy_read_metadata(cp, &md); + if (error != 0) + goto fail; + + if (strcmp(md.md_magic, G_VENTOY_MAGIC) != 0 || + strcmp(md.md_name, sc->sc_name) != 0 || + md.md_id != sc->sc_id) { + G_VENTOY_DEBUG(0, "Metadata on %s changed.", pp->name); + goto fail; + } + } + + cp->private = disk; + disk->d_consumer = cp; + disk->d_softc = sc; + disk->d_start = 0; /* not yet */ + disk->d_end = 0; /* not yet */ + disk->d_removed = 0; + + disk->d_map_start = g_disk_map_start; + disk->d_map_end = g_disk_map_end; + + G_VENTOY_DEBUG(0, "Disk %s attached to %s.", pp->name, sc->sc_name); + + g_ventoy_check_and_run(sc); + + return (0); +fail: + if (fcp != NULL && (fcp->acr > 0 || fcp->acw > 0 || fcp->ace > 0)) + g_access(cp, -fcp->acr, -fcp->acw, -fcp->ace); + g_detach(cp); + g_destroy_consumer(cp); + return (error); +} + +static struct g_geom * +g_ventoy_create(struct g_class *mp, const struct g_ventoy_metadata *md, + u_int type) +{ + struct g_ventoy_softc *sc; + struct g_geom *gp; + u_int no; + + G_VENTOY_DEBUG(1, "Creating device %s (id=%u).", md->md_name, + md->md_id); + + /* One disks is minimum. */ + if (md->md_all < 1) + return (NULL); + + /* Check for duplicate unit */ + LIST_FOREACH(gp, &mp->geom, geom) { + sc = gp->softc; + if (sc != NULL && strcmp(sc->sc_name, md->md_name) == 0) { + G_VENTOY_DEBUG(0, "Device %s already configured.", + gp->name); + return (NULL); + } + } + gp = g_new_geomf(mp, "%s", md->md_name); + sc = malloc(sizeof(*sc), M_VENTOY, M_WAITOK | M_ZERO); + gp->start = g_ventoy_start; + gp->spoiled = g_ventoy_orphan; + gp->orphan = g_ventoy_orphan; + gp->access = g_ventoy_access; + gp->dumpconf = g_ventoy_dumpconf; + + sc->sc_id = md->md_id; + sc->sc_ndisks = md->md_all; + sc->sc_disks = malloc(sizeof(struct g_ventoy_disk) * sc->sc_ndisks, + M_VENTOY, M_WAITOK | M_ZERO); + for (no = 0; no < sc->sc_ndisks; no++) + sc->sc_disks[no].d_consumer = NULL; + sc->sc_type = type; + mtx_init(&sc->sc_lock, "gventoy lock", NULL, MTX_DEF); + + gp->softc = sc; + sc->sc_geom = gp; + sc->sc_provider = NULL; + + G_VENTOY_DEBUG(0, "Device %s created (id=%u).", sc->sc_name, sc->sc_id); + + return (gp); +} + +static int +g_ventoy_destroy(struct g_ventoy_softc *sc, boolean_t force) +{ + struct g_provider *pp; + struct g_consumer *cp, *cp1; + struct g_geom *gp; + + g_topology_assert(); + + if (sc == NULL) + return (ENXIO); + + pp = sc->sc_provider; + if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) { + if (force) { + G_VENTOY_DEBUG(0, "Device %s is still open, so it " + "can't be definitely removed.", pp->name); + } else { + G_VENTOY_DEBUG(1, + "Device %s is still open (r%dw%de%d).", pp->name, + pp->acr, pp->acw, pp->ace); + return (EBUSY); + } + } + + gp = sc->sc_geom; + LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp1) { + g_ventoy_remove_disk(cp->private); + if (cp1 == NULL) + return (0); /* Recursion happened. */ + } + if (!LIST_EMPTY(&gp->consumer)) + return (EINPROGRESS); + + gp->softc = NULL; + KASSERT(sc->sc_provider == NULL, ("Provider still exists? (device=%s)", + gp->name)); + free(sc->sc_disks, M_VENTOY); + mtx_destroy(&sc->sc_lock); + free(sc, M_VENTOY); + + G_VENTOY_DEBUG(0, "Device %s destroyed.", gp->name); + g_wither_geom(gp, ENXIO); + return (0); +} + +static int +g_ventoy_destroy_geom(struct gctl_req *req __unused, + struct g_class *mp __unused, struct g_geom *gp) +{ + struct g_ventoy_softc *sc; + + sc = gp->softc; + return (g_ventoy_destroy(sc, 0)); +} + +static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) +{ + int i; + uint8_t *buf; + char uuid[64]; + const char *value; + struct g_consumer *cp; + struct g_geom *gp; + + if (g_ventoy_disk_size == 0) + { + if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + { + G_DEBUG("ventoy.disksize: %s\n", value); + g_ventoy_disk_size = strtouq(value, NULL, 0); + } + + if (resource_string_value("ventoy", 0, "diskuuid", &g_ventoy_disk_uuid) == 0) + { + G_DEBUG("ventoy.diskuuid: <%s>\n", g_ventoy_disk_uuid); + } + } + + if (g_ventoy_disk_size != pp->mediasize) + { + return false; + } + + if (strncmp(pp->name, "cd", 2) == 0 || strchr(pp->name, '/')) + { + return false; + } + + /* read UUID from disk */ + gp = g_new_geomf(mp, "ventoy:taste"); + gp->start = NULL; + gp->access = g_ventoy_access; + gp->orphan = g_ventoy_orphan; + cp = g_new_consumer(gp); + g_attach(cp, pp); + + g_access(cp, 1, 0, 0); + g_topology_unlock(); + buf = g_read_data(cp, 0, pp->sectorsize, NULL); + g_topology_lock(); + g_access(cp, -1, 0, 0); + + g_detach(cp); + g_destroy_consumer(cp); + g_destroy_geom(gp); + gp = NULL; + + if (!buf) + { + return false; + } + + for (i = 0; i < 16; i++) + { + sprintf(uuid + i * 2, "%02x", buf[0x180 + i]); + } + g_free(buf); + + if (strncmp(g_ventoy_disk_uuid, uuid, 32) == 0) + { + return true; + } + + return false; +} + +static struct g_geom * +g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) +{ + int i; + int error; + int disknum; + char *endpos; + const char *value; + struct g_geom *gp; + struct g_ventoy_metadata md; + struct g_ventoy_softc *sc; + + if (g_ventoy_tasted) + { + return NULL; + } + + G_DEBUG("%s(%s, %s)\n", __func__, mp->name, pp->name); + g_topology_assert(); + + /* Skip providers that are already open for writing. */ + if (pp->acw > 0) + return (NULL); + + if (!g_vtoy_check_disk(mp, pp)) + { + return NULL; + } + + g_ventoy_tasted = true; + + G_DEBUG("######### ventoy disk <%s> #############\n", pp->name); + + resource_int_value("ventoy", 0, "segnum", &disknum); + + strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); + md.md_version = G_VENTOY_VERSION; + strlcpy(md.md_name, "IMAGE", sizeof(md.md_name)); + md.md_id = arc4random(); + md.md_no = 0; + md.md_all = (uint16_t)disknum; + bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; + + gp = g_ventoy_create(mp, &md, G_VENTOY_TYPE_MANUAL); + if (gp == NULL) { + G_VENTOY_DEBUG(0, "Cannot create device %s.", + md.md_name); + return (NULL); + } + sc = gp->softc; + + for (i = 0; i < disknum; i ++) + { + if (resource_string_value("ventoy", i, "seg", &value) == 0) + { + g_disk_map_start = strtouq(value, &endpos, 0); + g_disk_map_end = strtouq(endpos + 1, NULL, 0); + } + else + { + printf("Failed to parse ventoy seg %d\n", i); + continue; + } + + G_DEBUG("ventoy segment%d: %s\n", i, value); + + G_VENTOY_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name); + error = g_ventoy_add_disk(sc, pp, i); + if (error != 0) { + G_VENTOY_DEBUG(0, + "Cannot add disk %s to %s (error=%d).", pp->name, + gp->name, error); + g_ventoy_destroy(sc, 1); + return (NULL); + } + + g_disk_map_start = 0; + g_disk_map_end = 0; + } + + return (gp); +} + +static void +g_ventoy_ctl_create(struct gctl_req *req, struct g_class *mp) +{ + u_int attached, no; + struct g_ventoy_metadata md; + struct g_provider *pp; + struct g_ventoy_softc *sc; + struct g_geom *gp; + struct sbuf *sb; + const char *name; + char param[16]; + int *nargs; + + g_topology_assert(); + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument.", "nargs"); + return; + } + if (*nargs < 2) { + gctl_error(req, "Too few arguments."); + return; + } + + strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); + md.md_version = G_VENTOY_VERSION; + name = gctl_get_asciiparam(req, "arg0"); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", 0); + return; + } + strlcpy(md.md_name, name, sizeof(md.md_name)); + md.md_id = arc4random(); + md.md_no = 0; + md.md_all = *nargs - 1; + bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; + + /* Check all providers are valid */ + for (no = 1; no < *nargs; no++) { + snprintf(param, sizeof(param), "arg%u", no); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", no); + return; + } + if (strncmp(name, "/dev/", strlen("/dev/")) == 0) + name += strlen("/dev/"); + pp = g_provider_by_name(name); + if (pp == NULL) { + G_VENTOY_DEBUG(1, "Disk %s is invalid.", name); + gctl_error(req, "Disk %s is invalid.", name); + return; + } + } + + gp = g_ventoy_create(mp, &md, G_VENTOY_TYPE_MANUAL); + if (gp == NULL) { + gctl_error(req, "Can't configure %s.", md.md_name); + return; + } + + sc = gp->softc; + sb = sbuf_new_auto(); + sbuf_printf(sb, "Can't attach disk(s) to %s:", gp->name); + for (attached = 0, no = 1; no < *nargs; no++) { + snprintf(param, sizeof(param), "arg%u", no); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%d' argument.", no); + return; + } + if (strncmp(name, "/dev/", strlen("/dev/")) == 0) + name += strlen("/dev/"); + pp = g_provider_by_name(name); + KASSERT(pp != NULL, ("Provider %s disappear?!", name)); + if (g_ventoy_add_disk(sc, pp, no - 1) != 0) { + G_VENTOY_DEBUG(1, "Disk %u (%s) not attached to %s.", + no, pp->name, gp->name); + sbuf_printf(sb, " %s", pp->name); + continue; + } + attached++; + } + sbuf_finish(sb); + if (md.md_all != attached) { + g_ventoy_destroy(gp->softc, 1); + gctl_error(req, "%s", sbuf_data(sb)); + } + sbuf_delete(sb); +} + +static struct g_ventoy_softc * +g_ventoy_find_device(struct g_class *mp, const char *name) +{ + struct g_ventoy_softc *sc; + struct g_geom *gp; + + LIST_FOREACH(gp, &mp->geom, geom) { + sc = gp->softc; + if (sc == NULL) + continue; + if (strcmp(sc->sc_name, name) == 0) + return (sc); + } + return (NULL); +} + +static void +g_ventoy_ctl_destroy(struct gctl_req *req, struct g_class *mp) +{ + struct g_ventoy_softc *sc; + int *force, *nargs, error; + const char *name; + char param[16]; + u_int i; + + g_topology_assert(); + + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument.", "nargs"); + return; + } + if (*nargs <= 0) { + gctl_error(req, "Missing device(s)."); + return; + } + force = gctl_get_paraml(req, "force", sizeof(*force)); + if (force == NULL) { + gctl_error(req, "No '%s' argument.", "force"); + return; + } + + for (i = 0; i < (u_int)*nargs; i++) { + snprintf(param, sizeof(param), "arg%u", i); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", i); + return; + } + sc = g_ventoy_find_device(mp, name); + if (sc == NULL) { + gctl_error(req, "No such device: %s.", name); + return; + } + error = g_ventoy_destroy(sc, *force); + if (error != 0) { + gctl_error(req, "Cannot destroy device %s (error=%d).", + sc->sc_name, error); + return; + } + } +} + +static void +g_ventoy_config(struct gctl_req *req, struct g_class *mp, const char *verb) +{ + uint32_t *version; + + return; + + g_topology_assert(); + + version = gctl_get_paraml(req, "version", sizeof(*version)); + if (version == NULL) { + gctl_error(req, "No '%s' argument.", "version"); + return; + } + if (*version != G_VENTOY_VERSION) { + gctl_error(req, "Userland and kernel parts are out of sync."); + return; + } + + if (strcmp(verb, "create") == 0) { + g_ventoy_ctl_create(req, mp); + return; + } else if (strcmp(verb, "destroy") == 0 || + strcmp(verb, "stop") == 0) { + g_ventoy_ctl_destroy(req, mp); + return; + } + gctl_error(req, "Unknown verb."); +} + +static void +g_ventoy_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, + struct g_consumer *cp, struct g_provider *pp) +{ + struct g_ventoy_softc *sc; + + g_topology_assert(); + sc = gp->softc; + if (sc == NULL) + return; + if (pp != NULL) { + /* Nothing here. */ + } else if (cp != NULL) { + struct g_ventoy_disk *disk; + + disk = cp->private; + if (disk == NULL) + return; + sbuf_printf(sb, "%s%jd\n", indent, + (intmax_t)disk->d_end); + sbuf_printf(sb, "%s%jd\n", indent, + (intmax_t)disk->d_start); + } else { + sbuf_printf(sb, "%s%u\n", indent, (u_int)sc->sc_id); + sbuf_printf(sb, "%s", indent); + switch (sc->sc_type) { + case G_VENTOY_TYPE_AUTOMATIC: + sbuf_cat(sb, "AUTOMATIC"); + break; + case G_VENTOY_TYPE_MANUAL: + sbuf_cat(sb, "MANUAL"); + break; + default: + sbuf_cat(sb, "UNKNOWN"); + break; + } + sbuf_cat(sb, "\n"); + sbuf_printf(sb, "%sTotal=%u, Online=%u\n", + indent, sc->sc_ndisks, g_ventoy_nvalid(sc)); + sbuf_printf(sb, "%s", indent); + if (sc->sc_provider != NULL && sc->sc_provider->error == 0) + sbuf_cat(sb, "UP"); + else + sbuf_cat(sb, "DOWN"); + sbuf_cat(sb, "\n"); + } +} + +DECLARE_GEOM_CLASS(g_ventoy_class, g_ventoy); +//MODULE_VERSION(geom_ventoy, 0); diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/12.x/sys/geom/ventoy/g_ventoy.h b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/12.x/sys/geom/ventoy/g_ventoy.h new file mode 100644 index 00000000..e442b246 --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/12.x/sys/geom/ventoy/g_ventoy.h @@ -0,0 +1,117 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 longpanda + * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _G_VENTOY_H_ +#define _G_VENTOY_H_ + +#include + +#define G_VENTOY_CLASS_NAME "VENTOY" + +#define G_VENTOY_MAGIC "GEOM::VENTOY" +/* + * Version history: + * 1 - Initial version number. + * 2 - Added 'stop' command to gconcat(8). + * 3 - Added md_provider field to metadata and '-h' option to gconcat(8). + * 4 - Added md_provsize field to metadata. + */ +#define G_VENTOY_VERSION 4 + +#ifdef _KERNEL +#define G_VENTOY_TYPE_MANUAL 0 +#define G_VENTOY_TYPE_AUTOMATIC 1 + +#define G_DEBUG(...) if (bootverbose) printf(__VA_ARGS__) +#define G_VENTOY_DEBUG(lvl, ...) if (g_ventoy_debug) printf(__VA_ARGS__) +#define G_VENTOY_LOGREQ(bp, ...) if (g_ventoy_debug) printf(__VA_ARGS__) + +struct g_ventoy_disk { + struct g_consumer *d_consumer; + struct g_ventoy_softc *d_softc; + off_t d_start; + off_t d_end; + off_t d_map_start; + off_t d_map_end; + int d_candelete; + int d_removed; +}; + +struct g_ventoy_softc { + u_int sc_type; /* provider type */ + struct g_geom *sc_geom; + struct g_provider *sc_provider; + uint32_t sc_id; /* concat unique ID */ + + struct g_ventoy_disk *sc_disks; + uint16_t sc_ndisks; + struct mtx sc_lock; +}; +#define sc_name sc_geom->name +#endif /* _KERNEL */ + +struct g_ventoy_metadata { + char md_magic[16]; /* Magic value. */ + uint32_t md_version; /* Version number. */ + char md_name[16]; /* Concat name. */ + uint32_t md_id; /* Unique ID. */ + uint16_t md_no; /* Disk number. */ + uint16_t md_all; /* Number of all disks. */ + char md_provider[16]; /* Hardcoded provider. */ + uint64_t md_provsize; /* Provider's size. */ +}; +static __inline void +ventoy_metadata_encode(const struct g_ventoy_metadata *md, u_char *data) +{ + + bcopy(md->md_magic, data, sizeof(md->md_magic)); + le32enc(data + 16, md->md_version); + bcopy(md->md_name, data + 20, sizeof(md->md_name)); + le32enc(data + 36, md->md_id); + le16enc(data + 40, md->md_no); + le16enc(data + 42, md->md_all); + bcopy(md->md_provider, data + 44, sizeof(md->md_provider)); + le64enc(data + 60, md->md_provsize); +} +static __inline void +ventoy_metadata_decode(const u_char *data, struct g_ventoy_metadata *md) +{ + + bcopy(data, md->md_magic, sizeof(md->md_magic)); + md->md_version = le32dec(data + 16); + bcopy(data + 20, md->md_name, sizeof(md->md_name)); + md->md_id = le32dec(data + 36); + md->md_no = le16dec(data + 40); + md->md_all = le16dec(data + 42); + bcopy(data + 44, md->md_provider, sizeof(md->md_provider)); + md->md_provsize = le64dec(data + 60); +} +#endif /* _G_VENTOY_H_ */ diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/12.x/sys/modules/geom/geom_ventoy/Makefile b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/12.x/sys/modules/geom/geom_ventoy/Makefile new file mode 100644 index 00000000..165f1bdf --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/12.x/sys/modules/geom/geom_ventoy/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/sys/geom/ventoy + +KMOD= geom_ventoy +SRCS= g_ventoy.c + +.include diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.c b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.c new file mode 100644 index 00000000..585c0537 --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.c @@ -0,0 +1,1093 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 longpanda + * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +FEATURE(geom_ventoy, "GEOM ventoy support"); + +static MALLOC_DEFINE(M_VENTOY, "ventoy_data", "GEOM_VENTOY Data"); + +SYSCTL_DECL(_kern_geom); +static SYSCTL_NODE(_kern_geom, OID_AUTO, ventoy, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, + "GEOM_VENTOY stuff"); +static u_int g_ventoy_debug = 0; +SYSCTL_UINT(_kern_geom_ventoy, OID_AUTO, debug, CTLFLAG_RWTUN, &g_ventoy_debug, 0, + "Debug level"); + +extern int resource_string_value(const char *name, int unit, const char *resname, const char **result); +extern int resource_int_value(const char *name, int unit, const char *resname, int *result); + +static int g_ventoy_destroy(struct g_ventoy_softc *sc, boolean_t force); +static int g_ventoy_destroy_geom(struct gctl_req *req, struct g_class *mp, + struct g_geom *gp); + +static g_taste_t g_ventoy_taste; +static g_ctl_req_t g_ventoy_config; +static g_dumpconf_t g_ventoy_dumpconf; + +static const char *g_ventoy_disk_uuid = NULL; +static bool g_ventoy_tasted = false; +static off_t g_ventoy_disk_size = 0; +static off_t g_disk_map_start = 0; +static off_t g_disk_map_end = 0; + +struct g_class g_ventoy_class = { + .name = G_VENTOY_CLASS_NAME, + .version = G_VERSION, + .ctlreq = g_ventoy_config, + .taste = g_ventoy_taste, + .destroy_geom = g_ventoy_destroy_geom +}; + + +/* + * Greatest Common Divisor. + */ +static u_int +gcd(u_int a, u_int b) +{ + u_int c; + + while (b != 0) { + c = a; + a = b; + b = (c % b); + } + return (a); +} + +/* + * Least Common Multiple. + */ +static u_int +lcm(u_int a, u_int b) +{ + + return ((a * b) / gcd(a, b)); +} + +/* + * Return the number of valid disks. + */ +static u_int +g_ventoy_nvalid(struct g_ventoy_softc *sc) +{ + u_int i, no; + + no = 0; + for (i = 0; i < sc->sc_ndisks; i++) { + if (sc->sc_disks[i].d_consumer != NULL) + no++; + } + + return (no); +} + +static void +g_ventoy_remove_disk(struct g_ventoy_disk *disk) +{ + struct g_consumer *cp; + struct g_ventoy_softc *sc; + + g_topology_assert(); + KASSERT(disk->d_consumer != NULL, ("Non-valid disk in %s.", __func__)); + sc = disk->d_softc; + cp = disk->d_consumer; + + if (!disk->d_removed) { + G_VENTOY_DEBUG(0, "Disk %s removed from %s.", + cp->provider->name, sc->sc_name); + disk->d_removed = 1; + } + + if (sc->sc_provider != NULL) { + G_VENTOY_DEBUG(0, "Device %s deactivated.", + sc->sc_provider->name); + g_wither_provider(sc->sc_provider, ENXIO); + sc->sc_provider = NULL; + } + + if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0) + return; + disk->d_consumer = NULL; + g_detach(cp); + g_destroy_consumer(cp); + /* If there are no valid disks anymore, remove device. */ + if (LIST_EMPTY(&sc->sc_geom->consumer)) + g_ventoy_destroy(sc, 1); +} + +static void +g_ventoy_orphan(struct g_consumer *cp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_geom *gp; + + g_topology_assert(); + gp = cp->geom; + sc = gp->softc; + if (sc == NULL) + return; + + disk = cp->private; + if (disk == NULL) /* Possible? */ + return; + g_ventoy_remove_disk(disk); +} + +static int +g_ventoy_access(struct g_provider *pp, int dr, int dw, int de) +{ + struct g_consumer *cp1, *cp2, *tmp; + struct g_ventoy_disk *disk; + struct g_geom *gp; + int error; + + if (dw > 0) /* readonly */ + return (EPERM); + + g_topology_assert(); + gp = pp->geom; + + /* On first open, grab an extra "exclusive" bit */ + if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) + de++; + /* ... and let go of it on last close */ + if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) + de--; + + LIST_FOREACH_SAFE(cp1, &gp->consumer, consumer, tmp) { + error = g_access(cp1, dr, dw, de); + if (error != 0) + goto fail; + disk = cp1->private; + if (cp1->acr == 0 && cp1->acw == 0 && cp1->ace == 0 && + disk->d_removed) { + g_ventoy_remove_disk(disk); /* May destroy geom. */ + } + } + return (0); + +fail: + LIST_FOREACH(cp2, &gp->consumer, consumer) { + if (cp1 == cp2) + break; + g_access(cp2, -dr, -dw, -de); + } + return (error); +} + +static void +g_ventoy_candelete(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + int i, val; + + sc = bp->bio_to->geom->softc; + for (i = 0; i < sc->sc_ndisks; i++) { + disk = &sc->sc_disks[i]; + if (!disk->d_removed && disk->d_candelete) + break; + } + val = i < sc->sc_ndisks; + g_handleattr(bp, "GEOM::candelete", &val, sizeof(val)); +} + +static void +g_ventoy_kernel_dump(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct bio *cbp; + struct g_kerneldump *gkd; + u_int i; + + sc = bp->bio_to->geom->softc; + gkd = (struct g_kerneldump *)bp->bio_data; + for (i = 0; i < sc->sc_ndisks; i++) { + if (sc->sc_disks[i].d_start <= gkd->offset && + sc->sc_disks[i].d_end > gkd->offset) + break; + } + if (i == sc->sc_ndisks) { + g_io_deliver(bp, EOPNOTSUPP); + return; + } + disk = &sc->sc_disks[i]; + gkd->offset -= disk->d_start; + if (gkd->length > disk->d_end - disk->d_start - gkd->offset) + gkd->length = disk->d_end - disk->d_start - gkd->offset; + cbp = g_clone_bio(bp); + if (cbp == NULL) { + g_io_deliver(bp, ENOMEM); + return; + } + cbp->bio_done = g_std_done; + g_io_request(cbp, disk->d_consumer); + G_VENTOY_DEBUG(1, "Kernel dump will go to %s.", + disk->d_consumer->provider->name); +} + +static void +g_ventoy_done(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct bio *pbp; + + pbp = bp->bio_parent; + sc = pbp->bio_to->geom->softc; + mtx_lock(&sc->sc_lock); + if (pbp->bio_error == 0) + pbp->bio_error = bp->bio_error; + pbp->bio_completed += bp->bio_completed; + pbp->bio_inbed++; + if (pbp->bio_children == pbp->bio_inbed) { + mtx_unlock(&sc->sc_lock); + g_io_deliver(pbp, pbp->bio_error); + } else + mtx_unlock(&sc->sc_lock); + g_destroy_bio(bp); +} + +static void +g_ventoy_flush(struct g_ventoy_softc *sc, struct bio *bp) +{ + struct bio_queue_head queue; + struct g_consumer *cp; + struct bio *cbp; + u_int no; + + bioq_init(&queue); + for (no = 0; no < sc->sc_ndisks; no++) { + cbp = g_clone_bio(bp); + if (cbp == NULL) { + while ((cbp = bioq_takefirst(&queue)) != NULL) + g_destroy_bio(cbp); + if (bp->bio_error == 0) + bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); + return; + } + bioq_insert_tail(&queue, cbp); + cbp->bio_done = g_ventoy_done; + cbp->bio_caller1 = sc->sc_disks[no].d_consumer; + cbp->bio_to = sc->sc_disks[no].d_consumer->provider; + } + while ((cbp = bioq_takefirst(&queue)) != NULL) { + G_VENTOY_LOGREQ(cbp, "Sending request."); + cp = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, cp); + } +} + +static void +g_ventoy_start(struct bio *bp) +{ + struct bio_queue_head queue; + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_provider *pp; + off_t offset, end, length, off, len; + struct bio *cbp; + char *addr; + u_int no; + + pp = bp->bio_to; + sc = pp->geom->softc; + /* + * If sc == NULL, provider's error should be set and g_ventoy_start() + * should not be called at all. + */ + KASSERT(sc != NULL, + ("Provider's error should be set (error=%d)(device=%s).", + bp->bio_to->error, bp->bio_to->name)); + + G_VENTOY_LOGREQ(bp, "Request received."); + + switch (bp->bio_cmd) { + case BIO_READ: + case BIO_WRITE: + case BIO_DELETE: + break; + case BIO_SPEEDUP: + case BIO_FLUSH: + g_ventoy_flush(sc, bp); + return; + case BIO_GETATTR: + if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) { + g_ventoy_kernel_dump(bp); + return; + } else if (strcmp("GEOM::candelete", bp->bio_attribute) == 0) { + g_ventoy_candelete(bp); + return; + } + /* To which provider it should be delivered? */ + /* FALLTHROUGH */ + default: + g_io_deliver(bp, EOPNOTSUPP); + return; + } + + offset = bp->bio_offset; + length = bp->bio_length; + if ((bp->bio_flags & BIO_UNMAPPED) != 0) + addr = NULL; + else + addr = bp->bio_data; + end = offset + length; + + bioq_init(&queue); + for (no = 0; no < sc->sc_ndisks; no++) { + disk = &sc->sc_disks[no]; + if (disk->d_end <= offset) + continue; + if (disk->d_start >= end) + break; + + off = offset - disk->d_start; + len = MIN(length, disk->d_end - offset); + length -= len; + offset += len; + + cbp = g_clone_bio(bp); + if (cbp == NULL) { + while ((cbp = bioq_takefirst(&queue)) != NULL) + g_destroy_bio(cbp); + if (bp->bio_error == 0) + bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); + return; + } + bioq_insert_tail(&queue, cbp); + /* + * Fill in the component buf structure. + */ + if (len == bp->bio_length) + cbp->bio_done = g_std_done; + else + cbp->bio_done = g_ventoy_done; + cbp->bio_offset = off + disk->d_map_start; + cbp->bio_length = len; + if ((bp->bio_flags & BIO_UNMAPPED) != 0) { + cbp->bio_ma_offset += (uintptr_t)addr; + cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE; + cbp->bio_ma_offset %= PAGE_SIZE; + cbp->bio_ma_n = round_page(cbp->bio_ma_offset + + cbp->bio_length) / PAGE_SIZE; + } else + cbp->bio_data = addr; + addr += len; + cbp->bio_to = disk->d_consumer->provider; + cbp->bio_caller1 = disk; + + if (length == 0) + break; + } + KASSERT(length == 0, + ("Length is still greater than 0 (class=%s, name=%s).", + bp->bio_to->geom->class->name, bp->bio_to->geom->name)); + while ((cbp = bioq_takefirst(&queue)) != NULL) { + G_VENTOY_LOGREQ(cbp, "Sending request."); + disk = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, disk->d_consumer); + } +} + +static void +g_ventoy_check_and_run(struct g_ventoy_softc *sc) +{ + struct g_ventoy_disk *disk; + struct g_provider *dp, *pp; + u_int no, sectorsize = 0; + off_t start; + int error; + + g_topology_assert(); + if (g_ventoy_nvalid(sc) != sc->sc_ndisks) + return; + + pp = g_new_providerf(sc->sc_geom, "ventoy/%s", sc->sc_name); + pp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE | + G_PF_ACCEPT_UNMAPPED; + start = 0; + for (no = 0; no < sc->sc_ndisks; no++) { + disk = &sc->sc_disks[no]; + dp = disk->d_consumer->provider; + disk->d_start = start; + disk->d_end = disk->d_start + (disk->d_map_end - disk->d_map_start); + if (sc->sc_type == G_VENTOY_TYPE_AUTOMATIC) + disk->d_end -= dp->sectorsize; + start = disk->d_end; + error = g_access(disk->d_consumer, 1, 0, 0); + if (error == 0) { + error = g_getattr("GEOM::candelete", disk->d_consumer, + &disk->d_candelete); + if (error != 0) + disk->d_candelete = 0; + (void)g_access(disk->d_consumer, -1, 0, 0); + } else + G_VENTOY_DEBUG(1, "Failed to access disk %s, error %d.", + dp->name, error); + if (no == 0) + sectorsize = dp->sectorsize; + else + sectorsize = lcm(sectorsize, dp->sectorsize); + + /* A provider underneath us doesn't support unmapped */ + if ((dp->flags & G_PF_ACCEPT_UNMAPPED) == 0) { + G_VENTOY_DEBUG(1, "Cancelling unmapped " + "because of %s.", dp->name); + pp->flags &= ~G_PF_ACCEPT_UNMAPPED; + } + } + pp->sectorsize = sectorsize; + /* We have sc->sc_disks[sc->sc_ndisks - 1].d_end in 'start'. */ + pp->mediasize = start; + pp->stripesize = sc->sc_disks[0].d_consumer->provider->stripesize; + pp->stripeoffset = sc->sc_disks[0].d_consumer->provider->stripeoffset; + sc->sc_provider = pp; + g_error_provider(pp, 0); + + G_VENTOY_DEBUG(0, "Device %s activated.", sc->sc_provider->name); +} + +static int +g_ventoy_read_metadata(struct g_consumer *cp, struct g_ventoy_metadata *md) +{ + struct g_provider *pp; + u_char *buf; + int error; + + g_topology_assert(); + + error = g_access(cp, 1, 0, 0); + if (error != 0) + return (error); + pp = cp->provider; + g_topology_unlock(); + buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize, + &error); + g_topology_lock(); + g_access(cp, -1, 0, 0); + if (buf == NULL) + return (error); + + /* Decode metadata. */ + ventoy_metadata_decode(buf, md); + g_free(buf); + + return (0); +} + +/* + * Add disk to given device. + */ +static int +g_ventoy_add_disk(struct g_ventoy_softc *sc, struct g_provider *pp, u_int no) +{ + struct g_ventoy_disk *disk; + struct g_consumer *cp, *fcp; + struct g_geom *gp; + int error; + + g_topology_assert(); + /* Metadata corrupted? */ + if (no >= sc->sc_ndisks) + return (EINVAL); + + disk = &sc->sc_disks[no]; + /* Check if disk is not already attached. */ + if (disk->d_consumer != NULL) + return (EEXIST); + + gp = sc->sc_geom; + fcp = LIST_FIRST(&gp->consumer); + + cp = g_new_consumer(gp); + cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE; + error = g_attach(cp, pp); + if (error != 0) { + g_destroy_consumer(cp); + return (error); + } + + if (fcp != NULL && (fcp->acr > 0 || fcp->acw > 0 || fcp->ace > 0)) { + error = g_access(cp, fcp->acr, fcp->acw, fcp->ace); + if (error != 0) { + g_detach(cp); + g_destroy_consumer(cp); + return (error); + } + } + if (sc->sc_type == G_VENTOY_TYPE_AUTOMATIC) { + struct g_ventoy_metadata md; + + /* Re-read metadata. */ + error = g_ventoy_read_metadata(cp, &md); + if (error != 0) + goto fail; + + if (strcmp(md.md_magic, G_VENTOY_MAGIC) != 0 || + strcmp(md.md_name, sc->sc_name) != 0 || + md.md_id != sc->sc_id) { + G_VENTOY_DEBUG(0, "Metadata on %s changed.", pp->name); + goto fail; + } + } + + cp->private = disk; + disk->d_consumer = cp; + disk->d_softc = sc; + disk->d_start = 0; /* not yet */ + disk->d_end = 0; /* not yet */ + disk->d_removed = 0; + + disk->d_map_start = g_disk_map_start; + disk->d_map_end = g_disk_map_end; + + G_VENTOY_DEBUG(0, "Disk %s attached to %s.", pp->name, sc->sc_name); + + g_ventoy_check_and_run(sc); + + return (0); +fail: + if (fcp != NULL && (fcp->acr > 0 || fcp->acw > 0 || fcp->ace > 0)) + g_access(cp, -fcp->acr, -fcp->acw, -fcp->ace); + g_detach(cp); + g_destroy_consumer(cp); + return (error); +} + +static struct g_geom * +g_ventoy_create(struct g_class *mp, const struct g_ventoy_metadata *md, + u_int type) +{ + struct g_ventoy_softc *sc; + struct g_geom *gp; + u_int no; + + G_VENTOY_DEBUG(1, "Creating device %s (id=%u).", md->md_name, + md->md_id); + + /* One disks is minimum. */ + if (md->md_all < 1) + return (NULL); + + /* Check for duplicate unit */ + LIST_FOREACH(gp, &mp->geom, geom) { + sc = gp->softc; + if (sc != NULL && strcmp(sc->sc_name, md->md_name) == 0) { + G_VENTOY_DEBUG(0, "Device %s already configured.", + gp->name); + return (NULL); + } + } + gp = g_new_geomf(mp, "%s", md->md_name); + sc = malloc(sizeof(*sc), M_VENTOY, M_WAITOK | M_ZERO); + gp->start = g_ventoy_start; + gp->spoiled = g_ventoy_orphan; + gp->orphan = g_ventoy_orphan; + gp->access = g_ventoy_access; + gp->dumpconf = g_ventoy_dumpconf; + + sc->sc_id = md->md_id; + sc->sc_ndisks = md->md_all; + sc->sc_disks = malloc(sizeof(struct g_ventoy_disk) * sc->sc_ndisks, + M_VENTOY, M_WAITOK | M_ZERO); + for (no = 0; no < sc->sc_ndisks; no++) + sc->sc_disks[no].d_consumer = NULL; + sc->sc_type = type; + mtx_init(&sc->sc_lock, "gventoy lock", NULL, MTX_DEF); + + gp->softc = sc; + sc->sc_geom = gp; + sc->sc_provider = NULL; + + G_VENTOY_DEBUG(0, "Device %s created (id=%u).", sc->sc_name, sc->sc_id); + + return (gp); +} + +static int +g_ventoy_destroy(struct g_ventoy_softc *sc, boolean_t force) +{ + struct g_provider *pp; + struct g_consumer *cp, *cp1; + struct g_geom *gp; + + g_topology_assert(); + + if (sc == NULL) + return (ENXIO); + + pp = sc->sc_provider; + if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) { + if (force) { + G_VENTOY_DEBUG(0, "Device %s is still open, so it " + "can't be definitely removed.", pp->name); + } else { + G_VENTOY_DEBUG(1, + "Device %s is still open (r%dw%de%d).", pp->name, + pp->acr, pp->acw, pp->ace); + return (EBUSY); + } + } + + gp = sc->sc_geom; + LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp1) { + g_ventoy_remove_disk(cp->private); + if (cp1 == NULL) + return (0); /* Recursion happened. */ + } + if (!LIST_EMPTY(&gp->consumer)) + return (EINPROGRESS); + + gp->softc = NULL; + KASSERT(sc->sc_provider == NULL, ("Provider still exists? (device=%s)", + gp->name)); + free(sc->sc_disks, M_VENTOY); + mtx_destroy(&sc->sc_lock); + free(sc, M_VENTOY); + + G_VENTOY_DEBUG(0, "Device %s destroyed.", gp->name); + g_wither_geom(gp, ENXIO); + return (0); +} + +static int +g_ventoy_destroy_geom(struct gctl_req *req __unused, + struct g_class *mp __unused, struct g_geom *gp) +{ + struct g_ventoy_softc *sc; + + sc = gp->softc; + return (g_ventoy_destroy(sc, 0)); +} + +static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) +{ + int i; + uint8_t *buf; + char uuid[64]; + const char *value; + struct g_consumer *cp; + struct g_geom *gp; + + if (g_ventoy_disk_size == 0) + { + if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + { + G_DEBUG("ventoy.disksize: %s\n", value); + g_ventoy_disk_size = strtouq(value, NULL, 0); + } + + if (resource_string_value("ventoy", 0, "diskuuid", &g_ventoy_disk_uuid) == 0) + { + G_DEBUG("ventoy.diskuuid: <%s>\n", g_ventoy_disk_uuid); + } + } + + if (g_ventoy_disk_size != pp->mediasize) + { + return false; + } + + if (strncmp(pp->name, "cd", 2) == 0 || strchr(pp->name, '/')) + { + return false; + } + + /* read UUID from disk */ + gp = g_new_geomf(mp, "ventoy:taste"); + gp->start = NULL; + gp->access = g_ventoy_access; + gp->orphan = g_ventoy_orphan; + cp = g_new_consumer(gp); + g_attach(cp, pp); + + g_access(cp, 1, 0, 0); + g_topology_unlock(); + buf = g_read_data(cp, 0, pp->sectorsize, NULL); + g_topology_lock(); + g_access(cp, -1, 0, 0); + + g_detach(cp); + g_destroy_consumer(cp); + g_destroy_geom(gp); + gp = NULL; + + if (!buf) + { + return false; + } + + for (i = 0; i < 16; i++) + { + sprintf(uuid + i * 2, "%02x", buf[0x180 + i]); + } + g_free(buf); + + if (strncmp(g_ventoy_disk_uuid, uuid, 32) == 0) + { + return true; + } + + return false; +} + +static struct g_geom * +g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) +{ + int i; + int error; + int disknum; + char *endpos; + const char *value; + struct g_geom *gp; + struct g_ventoy_metadata md; + struct g_ventoy_softc *sc; + + if (g_ventoy_tasted) + { + return NULL; + } + + G_DEBUG("%s(%s, %s)\n", __func__, mp->name, pp->name); + g_topology_assert(); + + /* Skip providers that are already open for writing. */ + if (pp->acw > 0) + return (NULL); + + if (!g_vtoy_check_disk(mp, pp)) + { + return NULL; + } + + g_ventoy_tasted = true; + + G_DEBUG("######### ventoy disk <%s> #############\n", pp->name); + + resource_int_value("ventoy", 0, "segnum", &disknum); + + strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); + md.md_version = G_VENTOY_VERSION; + strlcpy(md.md_name, "IMAGE", sizeof(md.md_name)); + md.md_id = arc4random(); + md.md_no = 0; + md.md_all = (uint16_t)disknum; + bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; + + gp = g_ventoy_create(mp, &md, G_VENTOY_TYPE_MANUAL); + if (gp == NULL) { + G_VENTOY_DEBUG(0, "Cannot create device %s.", + md.md_name); + return (NULL); + } + sc = gp->softc; + + for (i = 0; i < disknum; i ++) + { + if (resource_string_value("ventoy", i, "seg", &value) == 0) + { + g_disk_map_start = strtouq(value, &endpos, 0); + g_disk_map_end = strtouq(endpos + 1, NULL, 0); + } + else + { + printf("Failed to parse ventoy seg %d\n", i); + continue; + } + + G_DEBUG("ventoy segment%d: %s\n", i, value); + + G_VENTOY_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name); + error = g_ventoy_add_disk(sc, pp, i); + if (error != 0) { + G_VENTOY_DEBUG(0, + "Cannot add disk %s to %s (error=%d).", pp->name, + gp->name, error); + g_ventoy_destroy(sc, 1); + return (NULL); + } + + g_disk_map_start = 0; + g_disk_map_end = 0; + } + + return (gp); +} + +static void +g_ventoy_ctl_create(struct gctl_req *req, struct g_class *mp) +{ + u_int attached, no; + struct g_ventoy_metadata md; + struct g_provider *pp; + struct g_ventoy_softc *sc; + struct g_geom *gp; + struct sbuf *sb; + const char *name; + char param[16]; + int *nargs; + + g_topology_assert(); + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument.", "nargs"); + return; + } + if (*nargs < 2) { + gctl_error(req, "Too few arguments."); + return; + } + + strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); + md.md_version = G_VENTOY_VERSION; + name = gctl_get_asciiparam(req, "arg0"); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", 0); + return; + } + strlcpy(md.md_name, name, sizeof(md.md_name)); + md.md_id = arc4random(); + md.md_no = 0; + md.md_all = *nargs - 1; + bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; + + /* Check all providers are valid */ + for (no = 1; no < *nargs; no++) { + snprintf(param, sizeof(param), "arg%u", no); + pp = gctl_get_provider(req, param); + if (pp == NULL) + return; + } + + gp = g_ventoy_create(mp, &md, G_VENTOY_TYPE_MANUAL); + if (gp == NULL) { + gctl_error(req, "Can't configure %s.", md.md_name); + return; + } + + sc = gp->softc; + sb = sbuf_new_auto(); + sbuf_printf(sb, "Can't attach disk(s) to %s:", gp->name); + for (attached = 0, no = 1; no < *nargs; no++) { + snprintf(param, sizeof(param), "arg%u", no); + pp = gctl_get_provider(req, param); + if (pp == NULL) { + name = gctl_get_asciiparam(req, param); + MPASS(name != NULL); + sbuf_printf(sb, " %s", name); + continue; + } + if (g_ventoy_add_disk(sc, pp, no - 1) != 0) { + G_VENTOY_DEBUG(1, "Disk %u (%s) not attached to %s.", + no, pp->name, gp->name); + sbuf_printf(sb, " %s", pp->name); + continue; + } + attached++; + } + sbuf_finish(sb); + if (md.md_all != attached) { + g_ventoy_destroy(gp->softc, 1); + gctl_error(req, "%s", sbuf_data(sb)); + } + sbuf_delete(sb); +} + +static struct g_ventoy_softc * +g_ventoy_find_device(struct g_class *mp, const char *name) +{ + struct g_ventoy_softc *sc; + struct g_geom *gp; + + if (strncmp(name, _PATH_DEV, strlen(_PATH_DEV)) == 0) + name += strlen(_PATH_DEV); + + LIST_FOREACH(gp, &mp->geom, geom) { + sc = gp->softc; + if (sc == NULL) + continue; + if (strcmp(sc->sc_name, name) == 0) + return (sc); + } + return (NULL); +} + +static void +g_ventoy_ctl_destroy(struct gctl_req *req, struct g_class *mp) +{ + struct g_ventoy_softc *sc; + int *force, *nargs, error; + const char *name; + char param[16]; + u_int i; + + g_topology_assert(); + + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument.", "nargs"); + return; + } + if (*nargs <= 0) { + gctl_error(req, "Missing device(s)."); + return; + } + force = gctl_get_paraml(req, "force", sizeof(*force)); + if (force == NULL) { + gctl_error(req, "No '%s' argument.", "force"); + return; + } + + for (i = 0; i < (u_int)*nargs; i++) { + snprintf(param, sizeof(param), "arg%u", i); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", i); + return; + } + sc = g_ventoy_find_device(mp, name); + if (sc == NULL) { + gctl_error(req, "No such device: %s.", name); + return; + } + error = g_ventoy_destroy(sc, *force); + if (error != 0) { + gctl_error(req, "Cannot destroy device %s (error=%d).", + sc->sc_name, error); + return; + } + } +} + +static void +g_ventoy_config(struct gctl_req *req, struct g_class *mp, const char *verb) +{ + uint32_t *version; + + return; + + g_topology_assert(); + + version = gctl_get_paraml(req, "version", sizeof(*version)); + if (version == NULL) { + gctl_error(req, "No '%s' argument.", "version"); + return; + } + if (*version != G_VENTOY_VERSION) { + gctl_error(req, "Userland and kernel parts are out of sync."); + return; + } + + if (strcmp(verb, "create") == 0) { + g_ventoy_ctl_create(req, mp); + return; + } else if (strcmp(verb, "destroy") == 0 || + strcmp(verb, "stop") == 0) { + g_ventoy_ctl_destroy(req, mp); + return; + } + gctl_error(req, "Unknown verb."); +} + +static void +g_ventoy_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, + struct g_consumer *cp, struct g_provider *pp) +{ + struct g_ventoy_softc *sc; + + g_topology_assert(); + sc = gp->softc; + if (sc == NULL) + return; + if (pp != NULL) { + /* Nothing here. */ + } else if (cp != NULL) { + struct g_ventoy_disk *disk; + + disk = cp->private; + if (disk == NULL) + return; + sbuf_printf(sb, "%s%jd\n", indent, + (intmax_t)disk->d_end); + sbuf_printf(sb, "%s%jd\n", indent, + (intmax_t)disk->d_start); + } else { + sbuf_printf(sb, "%s%u\n", indent, (u_int)sc->sc_id); + sbuf_printf(sb, "%s", indent); + switch (sc->sc_type) { + case G_VENTOY_TYPE_AUTOMATIC: + sbuf_cat(sb, "AUTOMATIC"); + break; + case G_VENTOY_TYPE_MANUAL: + sbuf_cat(sb, "MANUAL"); + break; + default: + sbuf_cat(sb, "UNKNOWN"); + break; + } + sbuf_cat(sb, "\n"); + sbuf_printf(sb, "%sTotal=%u, Online=%u\n", + indent, sc->sc_ndisks, g_ventoy_nvalid(sc)); + sbuf_printf(sb, "%s", indent); + if (sc->sc_provider != NULL && sc->sc_provider->error == 0) + sbuf_cat(sb, "UP"); + else + sbuf_cat(sb, "DOWN"); + sbuf_cat(sb, "\n"); + } +} + +DECLARE_GEOM_CLASS(g_ventoy_class, g_ventoy); +//MODULE_VERSION(geom_ventoy, 0); diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.h b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.h new file mode 100644 index 00000000..e442b246 --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.h @@ -0,0 +1,117 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 longpanda + * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _G_VENTOY_H_ +#define _G_VENTOY_H_ + +#include + +#define G_VENTOY_CLASS_NAME "VENTOY" + +#define G_VENTOY_MAGIC "GEOM::VENTOY" +/* + * Version history: + * 1 - Initial version number. + * 2 - Added 'stop' command to gconcat(8). + * 3 - Added md_provider field to metadata and '-h' option to gconcat(8). + * 4 - Added md_provsize field to metadata. + */ +#define G_VENTOY_VERSION 4 + +#ifdef _KERNEL +#define G_VENTOY_TYPE_MANUAL 0 +#define G_VENTOY_TYPE_AUTOMATIC 1 + +#define G_DEBUG(...) if (bootverbose) printf(__VA_ARGS__) +#define G_VENTOY_DEBUG(lvl, ...) if (g_ventoy_debug) printf(__VA_ARGS__) +#define G_VENTOY_LOGREQ(bp, ...) if (g_ventoy_debug) printf(__VA_ARGS__) + +struct g_ventoy_disk { + struct g_consumer *d_consumer; + struct g_ventoy_softc *d_softc; + off_t d_start; + off_t d_end; + off_t d_map_start; + off_t d_map_end; + int d_candelete; + int d_removed; +}; + +struct g_ventoy_softc { + u_int sc_type; /* provider type */ + struct g_geom *sc_geom; + struct g_provider *sc_provider; + uint32_t sc_id; /* concat unique ID */ + + struct g_ventoy_disk *sc_disks; + uint16_t sc_ndisks; + struct mtx sc_lock; +}; +#define sc_name sc_geom->name +#endif /* _KERNEL */ + +struct g_ventoy_metadata { + char md_magic[16]; /* Magic value. */ + uint32_t md_version; /* Version number. */ + char md_name[16]; /* Concat name. */ + uint32_t md_id; /* Unique ID. */ + uint16_t md_no; /* Disk number. */ + uint16_t md_all; /* Number of all disks. */ + char md_provider[16]; /* Hardcoded provider. */ + uint64_t md_provsize; /* Provider's size. */ +}; +static __inline void +ventoy_metadata_encode(const struct g_ventoy_metadata *md, u_char *data) +{ + + bcopy(md->md_magic, data, sizeof(md->md_magic)); + le32enc(data + 16, md->md_version); + bcopy(md->md_name, data + 20, sizeof(md->md_name)); + le32enc(data + 36, md->md_id); + le16enc(data + 40, md->md_no); + le16enc(data + 42, md->md_all); + bcopy(md->md_provider, data + 44, sizeof(md->md_provider)); + le64enc(data + 60, md->md_provsize); +} +static __inline void +ventoy_metadata_decode(const u_char *data, struct g_ventoy_metadata *md) +{ + + bcopy(data, md->md_magic, sizeof(md->md_magic)); + md->md_version = le32dec(data + 16); + bcopy(data + 20, md->md_name, sizeof(md->md_name)); + md->md_id = le32dec(data + 36); + md->md_no = le16dec(data + 40); + md->md_all = le16dec(data + 42); + bcopy(data + 44, md->md_provider, sizeof(md->md_provider)); + md->md_provsize = le64dec(data + 60); +} +#endif /* _G_VENTOY_H_ */ diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/modules/geom/geom_ventoy/Makefile b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/modules/geom/geom_ventoy/Makefile new file mode 100644 index 00000000..165f1bdf --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/modules/geom/geom_ventoy/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/sys/geom/ventoy + +KMOD= geom_ventoy +SRCS= g_ventoy.c + +.include diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.c b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.c new file mode 100644 index 00000000..332ddd2c --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.c @@ -0,0 +1,1032 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 longpanda + * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +FEATURE(geom_ventoy, "GEOM ventoy support"); + +static MALLOC_DEFINE(M_VENTOY, "ventoy_data", "GEOM_VENTOY Data"); + +SYSCTL_DECL(_kern_geom); +static SYSCTL_NODE(_kern_geom, OID_AUTO, ventoy, CTLFLAG_RW, 0, + "GEOM_VENTOY stuff"); +static u_int g_ventoy_debug = 0; +SYSCTL_UINT(_kern_geom_ventoy, OID_AUTO, debug, CTLFLAG_RWTUN, &g_ventoy_debug, 0, + "Debug level"); + +extern int resource_string_value(const char *name, int unit, const char *resname, const char **result); +extern int resource_int_value(const char *name, int unit, const char *resname, int *result); + +static int g_ventoy_destroy(struct g_ventoy_softc *sc, boolean_t force); +static int g_ventoy_destroy_geom(struct gctl_req *req, struct g_class *mp, + struct g_geom *gp); + +static g_taste_t g_ventoy_taste; +static g_ctl_req_t g_ventoy_config; +static g_dumpconf_t g_ventoy_dumpconf; + +static const char *g_ventoy_disk_uuid = NULL; +static bool g_ventoy_tasted = false; +static off_t g_ventoy_disk_size = 0; +static off_t g_disk_map_start = 0; +static off_t g_disk_map_end = 0; + +struct g_class g_ventoy_class = { + .name = G_VENTOY_CLASS_NAME, + .version = G_VERSION, + .ctlreq = g_ventoy_config, + .taste = g_ventoy_taste, + .destroy_geom = g_ventoy_destroy_geom +}; + + +/* + * Greatest Common Divisor. + */ +static u_int +gcd(u_int a, u_int b) +{ + u_int c; + + while (b != 0) { + c = a; + a = b; + b = (c % b); + } + return (a); +} + +/* + * Least Common Multiple. + */ +static u_int +lcm(u_int a, u_int b) +{ + + return ((a * b) / gcd(a, b)); +} + +/* + * Return the number of valid disks. + */ +static u_int +g_ventoy_nvalid(struct g_ventoy_softc *sc) +{ + u_int i, no; + + no = 0; + for (i = 0; i < sc->sc_ndisks; i++) { + if (sc->sc_disks[i].d_consumer != NULL) + no++; + } + + return (no); +} + +static void +g_ventoy_remove_disk(struct g_ventoy_disk *disk) +{ + struct g_consumer *cp; + struct g_ventoy_softc *sc; + + g_topology_assert(); + KASSERT(disk->d_consumer != NULL, ("Non-valid disk in %s.", __func__)); + sc = disk->d_softc; + cp = disk->d_consumer; + + if (!disk->d_removed) { + G_VENTOY_DEBUG(0, "Disk %s removed from %s.", + cp->provider->name, sc->sc_name); + disk->d_removed = 1; + } + + if (sc->sc_provider != NULL) { + sc->sc_provider->flags |= G_PF_WITHER; + G_VENTOY_DEBUG(0, "Device %s deactivated.", + sc->sc_provider->name); + g_orphan_provider(sc->sc_provider, ENXIO); + sc->sc_provider = NULL; + } + + if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0) + return; + disk->d_consumer = NULL; + g_detach(cp); + g_destroy_consumer(cp); + /* If there are no valid disks anymore, remove device. */ + if (LIST_EMPTY(&sc->sc_geom->consumer)) + g_ventoy_destroy(sc, 1); +} + +static void +g_ventoy_orphan(struct g_consumer *cp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_geom *gp; + + g_topology_assert(); + gp = cp->geom; + sc = gp->softc; + if (sc == NULL) + return; + + disk = cp->private; + if (disk == NULL) /* Possible? */ + return; + g_ventoy_remove_disk(disk); +} + +static int +g_ventoy_access(struct g_provider *pp, int dr, int dw, int de) +{ + struct g_consumer *cp1, *cp2, *tmp; + struct g_ventoy_disk *disk; + struct g_geom *gp; + int error; + + if (dw > 0) /* readonly */ + return (EPERM); + + g_topology_assert(); + gp = pp->geom; + + /* On first open, grab an extra "exclusive" bit */ + if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) + de++; + /* ... and let go of it on last close */ + if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) + de--; + + LIST_FOREACH_SAFE(cp1, &gp->consumer, consumer, tmp) { + error = g_access(cp1, dr, dw, de); + if (error != 0) + goto fail; + disk = cp1->private; + if (cp1->acr == 0 && cp1->acw == 0 && cp1->ace == 0 && + disk->d_removed) { + g_ventoy_remove_disk(disk); /* May destroy geom. */ + } + } + return (0); + +fail: + LIST_FOREACH(cp2, &gp->consumer, consumer) { + if (cp1 == cp2) + break; + g_access(cp2, -dr, -dw, -de); + } + return (error); +} + +static void +g_ventoy_kernel_dump(struct bio *bp) +{ + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct bio *cbp; + struct g_kerneldump *gkd; + u_int i; + + sc = bp->bio_to->geom->softc; + gkd = (struct g_kerneldump *)bp->bio_data; + for (i = 0; i < sc->sc_ndisks; i++) { + if (sc->sc_disks[i].d_start <= gkd->offset && + sc->sc_disks[i].d_end > gkd->offset) + break; + } + if (i == sc->sc_ndisks) + g_io_deliver(bp, EOPNOTSUPP); + disk = &sc->sc_disks[i]; + gkd->offset -= disk->d_start; + if (gkd->length > disk->d_end - disk->d_start - gkd->offset) + gkd->length = disk->d_end - disk->d_start - gkd->offset; + cbp = g_clone_bio(bp); + if (cbp == NULL) { + g_io_deliver(bp, ENOMEM); + return; + } + cbp->bio_done = g_std_done; + g_io_request(cbp, disk->d_consumer); + G_VENTOY_DEBUG(1, "Kernel dump will go to %s.", + disk->d_consumer->provider->name); +} + +static void +g_ventoy_flush(struct g_ventoy_softc *sc, struct bio *bp) +{ + struct bio_queue_head queue; + struct g_consumer *cp; + struct bio *cbp; + u_int no; + + bioq_init(&queue); + for (no = 0; no < sc->sc_ndisks; no++) { + cbp = g_clone_bio(bp); + if (cbp == NULL) { + for (cbp = bioq_first(&queue); cbp != NULL; + cbp = bioq_first(&queue)) { + bioq_remove(&queue, cbp); + g_destroy_bio(cbp); + } + if (bp->bio_error == 0) + bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); + return; + } + bioq_insert_tail(&queue, cbp); + cbp->bio_done = g_std_done; + cbp->bio_caller1 = sc->sc_disks[no].d_consumer; + cbp->bio_to = sc->sc_disks[no].d_consumer->provider; + } + for (cbp = bioq_first(&queue); cbp != NULL; cbp = bioq_first(&queue)) { + bioq_remove(&queue, cbp); + G_VENTOY_LOGREQ(cbp, "Sending request."); + cp = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, cp); + } +} + +static void +g_ventoy_start(struct bio *bp) +{ + struct bio_queue_head queue; + struct g_ventoy_softc *sc; + struct g_ventoy_disk *disk; + struct g_provider *pp; + off_t offset, end, length, off, len; + struct bio *cbp; + char *addr; + u_int no; + + pp = bp->bio_to; + sc = pp->geom->softc; + /* + * If sc == NULL, provider's error should be set and g_ventoy_start() + * should not be called at all. + */ + KASSERT(sc != NULL, + ("Provider's error should be set (error=%d)(device=%s).", + bp->bio_to->error, bp->bio_to->name)); + + G_VENTOY_LOGREQ(bp, "Request received."); + + switch (bp->bio_cmd) { + case BIO_READ: + case BIO_WRITE: + case BIO_DELETE: + break; + case BIO_FLUSH: + g_ventoy_flush(sc, bp); + return; + case BIO_GETATTR: + if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) { + g_ventoy_kernel_dump(bp); + return; + } + /* To which provider it should be delivered? */ + /* FALLTHROUGH */ + default: + g_io_deliver(bp, EOPNOTSUPP); + return; + } + + offset = bp->bio_offset; + length = bp->bio_length; + addr = bp->bio_data; + end = offset + length; + + bioq_init(&queue); + for (no = 0; no < sc->sc_ndisks; no++) { + disk = &sc->sc_disks[no]; + if (disk->d_end <= offset) + continue; + if (disk->d_start >= end) + break; + + off = offset - disk->d_start; + len = MIN(length, disk->d_end - offset); + length -= len; + offset += len; + + cbp = g_clone_bio(bp); + if (cbp == NULL) { + for (cbp = bioq_first(&queue); cbp != NULL; + cbp = bioq_first(&queue)) { + bioq_remove(&queue, cbp); + g_destroy_bio(cbp); + } + if (bp->bio_error == 0) + bp->bio_error = ENOMEM; + g_io_deliver(bp, bp->bio_error); + return; + } + bioq_insert_tail(&queue, cbp); + /* + * Fill in the component buf structure. + */ + cbp->bio_done = g_std_done; + cbp->bio_offset = off + disk->d_map_start; + cbp->bio_data = addr; + addr += len; + cbp->bio_length = len; + cbp->bio_to = disk->d_consumer->provider; + cbp->bio_caller1 = disk; + + if (length == 0) + break; + } + KASSERT(length == 0, + ("Length is still greater than 0 (class=%s, name=%s).", + bp->bio_to->geom->class->name, bp->bio_to->geom->name)); + for (cbp = bioq_first(&queue); cbp != NULL; cbp = bioq_first(&queue)) { + bioq_remove(&queue, cbp); + G_VENTOY_LOGREQ(cbp, "Sending request."); + disk = cbp->bio_caller1; + cbp->bio_caller1 = NULL; + g_io_request(cbp, disk->d_consumer); + } +} + +static void +g_ventoy_check_and_run(struct g_ventoy_softc *sc) +{ + struct g_ventoy_disk *disk; + struct g_provider *dp, *pp; + u_int no, sectorsize = 0; + off_t start; + + g_topology_assert(); + if (g_ventoy_nvalid(sc) != sc->sc_ndisks) + return; + + pp = g_new_providerf(sc->sc_geom, "ventoy/%s", sc->sc_name); + start = 0; + for (no = 0; no < sc->sc_ndisks; no++) { + disk = &sc->sc_disks[no]; + dp = disk->d_consumer->provider; + disk->d_start = start; + disk->d_end = disk->d_start + (disk->d_map_end - disk->d_map_start); + if (sc->sc_type == G_VENTOY_TYPE_AUTOMATIC) + disk->d_end -= dp->sectorsize; + start = disk->d_end; + if (no == 0) + sectorsize = dp->sectorsize; + else { + sectorsize = lcm(sectorsize, dp->sectorsize); + + } + } + pp->sectorsize = sectorsize; + /* We have sc->sc_disks[sc->sc_ndisks - 1].d_end in 'start'. */ + pp->mediasize = start; + pp->stripesize = sc->sc_disks[0].d_consumer->provider->stripesize; + pp->stripeoffset = sc->sc_disks[0].d_consumer->provider->stripeoffset; + sc->sc_provider = pp; + g_error_provider(pp, 0); + + G_VENTOY_DEBUG(0, "Device %s activated.", sc->sc_provider->name); +} + +static int +g_ventoy_read_metadata(struct g_consumer *cp, struct g_ventoy_metadata *md) +{ + struct g_provider *pp; + u_char *buf; + int error; + + g_topology_assert(); + + error = g_access(cp, 1, 0, 0); + if (error != 0) + return (error); + pp = cp->provider; + g_topology_unlock(); + buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize, + &error); + g_topology_lock(); + g_access(cp, -1, 0, 0); + if (buf == NULL) + return (error); + + /* Decode metadata. */ + ventoy_metadata_decode(buf, md); + g_free(buf); + + return (0); +} + +/* + * Add disk to given device. + */ +static int +g_ventoy_add_disk(struct g_ventoy_softc *sc, struct g_provider *pp, u_int no) +{ + struct g_ventoy_disk *disk; + struct g_consumer *cp, *fcp; + struct g_geom *gp; + int error; + + g_topology_assert(); + /* Metadata corrupted? */ + if (no >= sc->sc_ndisks) + return (EINVAL); + + disk = &sc->sc_disks[no]; + /* Check if disk is not already attached. */ + if (disk->d_consumer != NULL) + return (EEXIST); + + gp = sc->sc_geom; + fcp = LIST_FIRST(&gp->consumer); + + cp = g_new_consumer(gp); + error = g_attach(cp, pp); + if (error != 0) { + g_destroy_consumer(cp); + return (error); + } + + if (fcp != NULL && (fcp->acr > 0 || fcp->acw > 0 || fcp->ace > 0)) { + error = g_access(cp, fcp->acr, fcp->acw, fcp->ace); + if (error != 0) { + g_detach(cp); + g_destroy_consumer(cp); + return (error); + } + } + if (sc->sc_type == G_VENTOY_TYPE_AUTOMATIC) { + struct g_ventoy_metadata md; + + /* Re-read metadata. */ + error = g_ventoy_read_metadata(cp, &md); + if (error != 0) + goto fail; + + if (strcmp(md.md_magic, G_VENTOY_MAGIC) != 0 || + strcmp(md.md_name, sc->sc_name) != 0 || + md.md_id != sc->sc_id) { + G_VENTOY_DEBUG(0, "Metadata on %s changed.", pp->name); + goto fail; + } + } + + cp->private = disk; + disk->d_consumer = cp; + disk->d_softc = sc; + disk->d_start = 0; /* not yet */ + disk->d_end = 0; /* not yet */ + disk->d_removed = 0; + + disk->d_map_start = g_disk_map_start; + disk->d_map_end = g_disk_map_end; + + G_VENTOY_DEBUG(0, "Disk %s attached to %s.", pp->name, sc->sc_name); + + g_ventoy_check_and_run(sc); + + return (0); +fail: + if (fcp != NULL && (fcp->acr > 0 || fcp->acw > 0 || fcp->ace > 0)) + g_access(cp, -fcp->acr, -fcp->acw, -fcp->ace); + g_detach(cp); + g_destroy_consumer(cp); + return (error); +} + +static struct g_geom * +g_ventoy_create(struct g_class *mp, const struct g_ventoy_metadata *md, + u_int type) +{ + struct g_ventoy_softc *sc; + struct g_geom *gp; + u_int no; + + G_VENTOY_DEBUG(1, "Creating device %s (id=%u).", md->md_name, + md->md_id); + + /* One disks is minimum. */ + if (md->md_all < 1) + return (NULL); + + /* Check for duplicate unit */ + LIST_FOREACH(gp, &mp->geom, geom) { + sc = gp->softc; + if (sc != NULL && strcmp(sc->sc_name, md->md_name) == 0) { + G_VENTOY_DEBUG(0, "Device %s already configured.", + gp->name); + return (NULL); + } + } + gp = g_new_geomf(mp, "%s", md->md_name); + sc = malloc(sizeof(*sc), M_VENTOY, M_WAITOK | M_ZERO); + gp->start = g_ventoy_start; + gp->spoiled = g_ventoy_orphan; + gp->orphan = g_ventoy_orphan; + gp->access = g_ventoy_access; + gp->dumpconf = g_ventoy_dumpconf; + + sc->sc_id = md->md_id; + sc->sc_ndisks = md->md_all; + sc->sc_disks = malloc(sizeof(struct g_ventoy_disk) * sc->sc_ndisks, + M_VENTOY, M_WAITOK | M_ZERO); + for (no = 0; no < sc->sc_ndisks; no++) + sc->sc_disks[no].d_consumer = NULL; + sc->sc_type = type; + + gp->softc = sc; + sc->sc_geom = gp; + sc->sc_provider = NULL; + + G_VENTOY_DEBUG(0, "Device %s created (id=%u).", sc->sc_name, sc->sc_id); + + return (gp); +} + +static int +g_ventoy_destroy(struct g_ventoy_softc *sc, boolean_t force) +{ + struct g_provider *pp; + struct g_consumer *cp, *cp1; + struct g_geom *gp; + + g_topology_assert(); + + if (sc == NULL) + return (ENXIO); + + pp = sc->sc_provider; + if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) { + if (force) { + G_VENTOY_DEBUG(0, "Device %s is still open, so it " + "can't be definitely removed.", pp->name); + } else { + G_VENTOY_DEBUG(1, + "Device %s is still open (r%dw%de%d).", pp->name, + pp->acr, pp->acw, pp->ace); + return (EBUSY); + } + } + + gp = sc->sc_geom; + LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp1) { + g_ventoy_remove_disk(cp->private); + if (cp1 == NULL) + return (0); /* Recursion happened. */ + } + if (!LIST_EMPTY(&gp->consumer)) + return (EINPROGRESS); + + gp->softc = NULL; + KASSERT(sc->sc_provider == NULL, ("Provider still exists? (device=%s)", + gp->name)); + free(sc->sc_disks, M_VENTOY); + free(sc, M_VENTOY); + + G_VENTOY_DEBUG(0, "Device %s destroyed.", gp->name); + g_wither_geom(gp, ENXIO); + return (0); +} + +static int +g_ventoy_destroy_geom(struct gctl_req *req __unused, + struct g_class *mp __unused, struct g_geom *gp) +{ + struct g_ventoy_softc *sc; + + sc = gp->softc; + return (g_ventoy_destroy(sc, 0)); +} + +static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) +{ + int i; + uint8_t *buf; + char uuid[64]; + const char *value; + struct g_consumer *cp; + struct g_geom *gp; + + if (g_ventoy_disk_size == 0) + { + if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + { + G_DEBUG("ventoy.disksize: %s\n", value); + g_ventoy_disk_size = strtouq(value, NULL, 0); + } + + if (resource_string_value("ventoy", 0, "diskuuid", &g_ventoy_disk_uuid) == 0) + { + G_DEBUG("ventoy.diskuuid: <%s>\n", g_ventoy_disk_uuid); + } + } + + if (g_ventoy_disk_size != pp->mediasize) + { + return false; + } + + if (strncmp(pp->name, "cd", 2) == 0 || strchr(pp->name, '/')) + { + return false; + } + + /* read UUID from disk */ + gp = g_new_geomf(mp, "ventoy:taste"); + gp->start = NULL; + gp->access = g_ventoy_access; + gp->orphan = g_ventoy_orphan; + cp = g_new_consumer(gp); + g_attach(cp, pp); + + g_access(cp, 1, 0, 0); + g_topology_unlock(); + buf = g_read_data(cp, 0, pp->sectorsize, NULL); + g_topology_lock(); + g_access(cp, -1, 0, 0); + + g_detach(cp); + g_destroy_consumer(cp); + g_destroy_geom(gp); + gp = NULL; + + if (!buf) + { + return false; + } + + for (i = 0; i < 16; i++) + { + sprintf(uuid + i * 2, "%02x", buf[0x180 + i]); + } + g_free(buf); + + if (strncmp(g_ventoy_disk_uuid, uuid, 32) == 0) + { + return true; + } + + return false; +} + +static struct g_geom * +g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) +{ + int i; + int error; + int disknum; + char *endpos; + const char *value; + struct g_geom *gp; + struct g_ventoy_metadata md; + struct g_ventoy_softc *sc; + + if (g_ventoy_tasted) + { + return NULL; + } + + G_DEBUG("%s(%s, %s)\n", __func__, mp->name, pp->name); + g_topology_assert(); + + /* Skip providers that are already open for writing. */ + if (pp->acw > 0) + return (NULL); + + if (!g_vtoy_check_disk(mp, pp)) + { + return NULL; + } + + g_ventoy_tasted = true; + + G_DEBUG("######### ventoy disk <%s> #############\n", pp->name); + + resource_int_value("ventoy", 0, "segnum", &disknum); + + strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); + md.md_version = G_VENTOY_VERSION; + strlcpy(md.md_name, "IMAGE", sizeof(md.md_name)); + md.md_id = arc4random(); + md.md_no = 0; + md.md_all = (uint16_t)disknum; + bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; + + gp = g_ventoy_create(mp, &md, G_VENTOY_TYPE_MANUAL); + if (gp == NULL) { + G_VENTOY_DEBUG(0, "Cannot create device %s.", + md.md_name); + return (NULL); + } + sc = gp->softc; + + for (i = 0; i < disknum; i ++) + { + if (resource_string_value("ventoy", i, "seg", &value) == 0) + { + g_disk_map_start = strtouq(value, &endpos, 0); + g_disk_map_end = strtouq(endpos + 1, NULL, 0); + } + else + { + printf("Failed to parse ventoy seg %d\n", i); + continue; + } + + G_DEBUG("ventoy segment%d: %s\n", i, value); + + G_VENTOY_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name); + error = g_ventoy_add_disk(sc, pp, i); + if (error != 0) { + G_VENTOY_DEBUG(0, + "Cannot add disk %s to %s (error=%d).", pp->name, + gp->name, error); + g_ventoy_destroy(sc, 1); + return (NULL); + } + + g_disk_map_start = 0; + g_disk_map_end = 0; + } + + return (gp); +} + +static void +g_ventoy_ctl_create(struct gctl_req *req, struct g_class *mp) +{ + u_int attached, no; + struct g_ventoy_metadata md; + struct g_provider *pp; + struct g_ventoy_softc *sc; + struct g_geom *gp; + struct sbuf *sb; + const char *name; + char param[16]; + int *nargs; + + g_topology_assert(); + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument.", "nargs"); + return; + } + if (*nargs < 2) { + gctl_error(req, "Too few arguments."); + return; + } + + strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); + md.md_version = G_VENTOY_VERSION; + name = gctl_get_asciiparam(req, "arg0"); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", 0); + return; + } + strlcpy(md.md_name, name, sizeof(md.md_name)); + md.md_id = arc4random(); + md.md_no = 0; + md.md_all = *nargs - 1; + bzero(md.md_provider, sizeof(md.md_provider)); + /* This field is not important here. */ + md.md_provsize = 0; + + /* Check all providers are valid */ + for (no = 1; no < *nargs; no++) { + snprintf(param, sizeof(param), "arg%u", no); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", no); + return; + } + if (strncmp(name, "/dev/", strlen("/dev/")) == 0) + name += strlen("/dev/"); + pp = g_provider_by_name(name); + if (pp == NULL) { + G_VENTOY_DEBUG(1, "Disk %s is invalid.", name); + gctl_error(req, "Disk %s is invalid.", name); + return; + } + } + + gp = g_ventoy_create(mp, &md, G_VENTOY_TYPE_MANUAL); + if (gp == NULL) { + gctl_error(req, "Can't configure %s.", md.md_name); + return; + } + + sc = gp->softc; + sb = sbuf_new_auto(); + sbuf_printf(sb, "Can't attach disk(s) to %s:", gp->name); + for (attached = 0, no = 1; no < *nargs; no++) { + snprintf(param, sizeof(param), "arg%u", no); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%d' argument.", no); + return; + } + if (strncmp(name, "/dev/", strlen("/dev/")) == 0) + name += strlen("/dev/"); + pp = g_provider_by_name(name); + KASSERT(pp != NULL, ("Provider %s disappear?!", name)); + if (g_ventoy_add_disk(sc, pp, no - 1) != 0) { + G_VENTOY_DEBUG(1, "Disk %u (%s) not attached to %s.", + no, pp->name, gp->name); + sbuf_printf(sb, " %s", pp->name); + continue; + } + attached++; + } + sbuf_finish(sb); + if (md.md_all != attached) { + g_ventoy_destroy(gp->softc, 1); + gctl_error(req, "%s", sbuf_data(sb)); + } + sbuf_delete(sb); +} + +static struct g_ventoy_softc * +g_ventoy_find_device(struct g_class *mp, const char *name) +{ + struct g_ventoy_softc *sc; + struct g_geom *gp; + + LIST_FOREACH(gp, &mp->geom, geom) { + sc = gp->softc; + if (sc == NULL) + continue; + if (strcmp(sc->sc_name, name) == 0) + return (sc); + } + return (NULL); +} + +static void +g_ventoy_ctl_destroy(struct gctl_req *req, struct g_class *mp) +{ + struct g_ventoy_softc *sc; + int *force, *nargs, error; + const char *name; + char param[16]; + u_int i; + + g_topology_assert(); + + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument.", "nargs"); + return; + } + if (*nargs <= 0) { + gctl_error(req, "Missing device(s)."); + return; + } + force = gctl_get_paraml(req, "force", sizeof(*force)); + if (force == NULL) { + gctl_error(req, "No '%s' argument.", "force"); + return; + } + + for (i = 0; i < (u_int)*nargs; i++) { + snprintf(param, sizeof(param), "arg%u", i); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%u' argument.", i); + return; + } + sc = g_ventoy_find_device(mp, name); + if (sc == NULL) { + gctl_error(req, "No such device: %s.", name); + return; + } + error = g_ventoy_destroy(sc, *force); + if (error != 0) { + gctl_error(req, "Cannot destroy device %s (error=%d).", + sc->sc_name, error); + return; + } + } +} + +static void +g_ventoy_config(struct gctl_req *req, struct g_class *mp, const char *verb) +{ + uint32_t *version; + + return; + + g_topology_assert(); + + version = gctl_get_paraml(req, "version", sizeof(*version)); + if (version == NULL) { + gctl_error(req, "No '%s' argument.", "version"); + return; + } + if (*version != G_VENTOY_VERSION) { + gctl_error(req, "Userland and kernel parts are out of sync."); + return; + } + + if (strcmp(verb, "create") == 0) { + g_ventoy_ctl_create(req, mp); + return; + } else if (strcmp(verb, "destroy") == 0 || + strcmp(verb, "stop") == 0) { + g_ventoy_ctl_destroy(req, mp); + return; + } + gctl_error(req, "Unknown verb."); +} + +static void +g_ventoy_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, + struct g_consumer *cp, struct g_provider *pp) +{ + struct g_ventoy_softc *sc; + + g_topology_assert(); + sc = gp->softc; + if (sc == NULL) + return; + if (pp != NULL) { + /* Nothing here. */ + } else if (cp != NULL) { + struct g_ventoy_disk *disk; + + disk = cp->private; + if (disk == NULL) + return; + sbuf_printf(sb, "%s%jd\n", indent, + (intmax_t)disk->d_end); + sbuf_printf(sb, "%s%jd\n", indent, + (intmax_t)disk->d_start); + } else { + sbuf_printf(sb, "%s%u\n", indent, (u_int)sc->sc_id); + sbuf_printf(sb, "%s", indent); + switch (sc->sc_type) { + case G_VENTOY_TYPE_AUTOMATIC: + sbuf_cat(sb, "AUTOMATIC"); + break; + case G_VENTOY_TYPE_MANUAL: + sbuf_cat(sb, "MANUAL"); + break; + default: + sbuf_cat(sb, "UNKNOWN"); + break; + } + sbuf_cat(sb, "\n"); + sbuf_printf(sb, "%sTotal=%u, Online=%u\n", + indent, sc->sc_ndisks, g_ventoy_nvalid(sc)); + sbuf_printf(sb, "%s", indent); + if (sc->sc_provider != NULL && sc->sc_provider->error == 0) + sbuf_cat(sb, "UP"); + else + sbuf_cat(sb, "DOWN"); + sbuf_cat(sb, "\n"); + } +} + +DECLARE_GEOM_CLASS(g_ventoy_class, g_ventoy); diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.h b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.h new file mode 100644 index 00000000..e442b246 --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.h @@ -0,0 +1,117 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 longpanda + * Copyright (c) 2004-2005 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _G_VENTOY_H_ +#define _G_VENTOY_H_ + +#include + +#define G_VENTOY_CLASS_NAME "VENTOY" + +#define G_VENTOY_MAGIC "GEOM::VENTOY" +/* + * Version history: + * 1 - Initial version number. + * 2 - Added 'stop' command to gconcat(8). + * 3 - Added md_provider field to metadata and '-h' option to gconcat(8). + * 4 - Added md_provsize field to metadata. + */ +#define G_VENTOY_VERSION 4 + +#ifdef _KERNEL +#define G_VENTOY_TYPE_MANUAL 0 +#define G_VENTOY_TYPE_AUTOMATIC 1 + +#define G_DEBUG(...) if (bootverbose) printf(__VA_ARGS__) +#define G_VENTOY_DEBUG(lvl, ...) if (g_ventoy_debug) printf(__VA_ARGS__) +#define G_VENTOY_LOGREQ(bp, ...) if (g_ventoy_debug) printf(__VA_ARGS__) + +struct g_ventoy_disk { + struct g_consumer *d_consumer; + struct g_ventoy_softc *d_softc; + off_t d_start; + off_t d_end; + off_t d_map_start; + off_t d_map_end; + int d_candelete; + int d_removed; +}; + +struct g_ventoy_softc { + u_int sc_type; /* provider type */ + struct g_geom *sc_geom; + struct g_provider *sc_provider; + uint32_t sc_id; /* concat unique ID */ + + struct g_ventoy_disk *sc_disks; + uint16_t sc_ndisks; + struct mtx sc_lock; +}; +#define sc_name sc_geom->name +#endif /* _KERNEL */ + +struct g_ventoy_metadata { + char md_magic[16]; /* Magic value. */ + uint32_t md_version; /* Version number. */ + char md_name[16]; /* Concat name. */ + uint32_t md_id; /* Unique ID. */ + uint16_t md_no; /* Disk number. */ + uint16_t md_all; /* Number of all disks. */ + char md_provider[16]; /* Hardcoded provider. */ + uint64_t md_provsize; /* Provider's size. */ +}; +static __inline void +ventoy_metadata_encode(const struct g_ventoy_metadata *md, u_char *data) +{ + + bcopy(md->md_magic, data, sizeof(md->md_magic)); + le32enc(data + 16, md->md_version); + bcopy(md->md_name, data + 20, sizeof(md->md_name)); + le32enc(data + 36, md->md_id); + le16enc(data + 40, md->md_no); + le16enc(data + 42, md->md_all); + bcopy(md->md_provider, data + 44, sizeof(md->md_provider)); + le64enc(data + 60, md->md_provsize); +} +static __inline void +ventoy_metadata_decode(const u_char *data, struct g_ventoy_metadata *md) +{ + + bcopy(data, md->md_magic, sizeof(md->md_magic)); + md->md_version = le32dec(data + 16); + bcopy(data + 20, md->md_name, sizeof(md->md_name)); + md->md_id = le32dec(data + 36); + md->md_no = le16dec(data + 40); + md->md_all = le16dec(data + 42); + bcopy(data + 44, md->md_provider, sizeof(md->md_provider)); + md->md_provsize = le64dec(data + 60); +} +#endif /* _G_VENTOY_H_ */ diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/modules/geom/geom_ventoy/Makefile b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/modules/geom/geom_ventoy/Makefile new file mode 100644 index 00000000..165f1bdf --- /dev/null +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/modules/geom/geom_ventoy/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/sys/geom/ventoy + +KMOD= geom_ventoy +SRCS= g_ventoy.c + +.include diff --git a/Ventoy2Disk/Ventoy2Disk/Language.h b/Ventoy2Disk/Ventoy2Disk/Language.h index 3623dc33..b365481f 100644 --- a/Ventoy2Disk/Ventoy2Disk/Language.h +++ b/Ventoy2Disk/Ventoy2Disk/Language.h @@ -57,6 +57,13 @@ typedef enum STR_ID STR_PRESERVE_SPACE,//24 STR_SPACE_VAL_INVALID,//25 + STR_MENU_CLEAR, //26 + STR_CLEAR_SUCCESS, //27 + STR_CLEAR_FAILED, //28 + STR_MENU_PART_STYLE, //29 + STR_DISK_2TB_MBR_ERROR,//30 + + STR_ID_MAX }STR_ID; @@ -64,6 +71,23 @@ extern BOOL g_SecureBoot; #define VTOY_MENU_SECURE_BOOT 0xA000 #define VTOY_MENU_PART_CFG 0xA001 +#define VTOY_MENU_CLEAN 0xA002 +#define VTOY_MENU_PART_STYLE 0xA003 +#define VTOY_MENU_PART_MBR 0xA004 +#define VTOY_MENU_PART_GPT 0xA005 + + +typedef enum OPT_SUBMENU +{ + OPT_SUBMENU_SECURE_BOOT = 0, + OPT_SUBMENU_PART_STYLE, + OPT_SUBMENU_PART_CFG, + OPT_SUBMENU_CLEAR, + + OPT_SUBMENU_MAX +}OPT_SUBMENU; + + #define VTOY_MENU_LANGUAGE_BEGIN 0xB000 diff --git a/Ventoy2Disk/Ventoy2Disk/PartDialog.c b/Ventoy2Disk/Ventoy2Disk/PartDialog.c index b5f737c0..f1659ccc 100644 Binary files a/Ventoy2Disk/Ventoy2Disk/PartDialog.c and b/Ventoy2Disk/Ventoy2Disk/PartDialog.c differ diff --git a/Ventoy2Disk/Ventoy2Disk/PhyDrive.c b/Ventoy2Disk/Ventoy2Disk/PhyDrive.c index 07c168cd..ec266eec 100644 --- a/Ventoy2Disk/Ventoy2Disk/PhyDrive.c +++ b/Ventoy2Disk/Ventoy2Disk/PhyDrive.c @@ -1,1623 +1,1962 @@ -/****************************************************************************** - * PhyDrive.c - * - * Copyright (c) 2020, longpanda - * Copyright (c) 2011-2020, Pete Batard - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - */ - -#include -#include -#include -#include -#include -#include "resource.h" -#include "Language.h" -#include "Ventoy2Disk.h" -#include "fat_filelib.h" -#include "ff.h" - -/* - * Some code and functions in the file are copied from rufus. - * https://github.com/pbatard/rufus - */ -#define VDS_SET_ERROR SetLastError -#define IVdsServiceLoader_LoadService(This, pwszMachineName, ppService) (This)->lpVtbl->LoadService(This, pwszMachineName, ppService) -#define IVdsServiceLoader_Release(This) (This)->lpVtbl->Release(This) -#define IVdsService_QueryProviders(This, masks, ppEnum) (This)->lpVtbl->QueryProviders(This, masks, ppEnum) -#define IVdsService_WaitForServiceReady(This) ((This)->lpVtbl->WaitForServiceReady(This)) -#define IVdsService_CleanupObsoleteMountPoints(This) ((This)->lpVtbl->CleanupObsoleteMountPoints(This)) -#define IVdsService_Refresh(This) ((This)->lpVtbl->Refresh(This)) -#define IVdsService_Reenumerate(This) ((This)->lpVtbl->Reenumerate(This)) -#define IVdsSwProvider_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject) -#define IVdsProvider_Release(This) (This)->lpVtbl->Release(This) -#define IVdsSwProvider_QueryPacks(This, ppEnum) (This)->lpVtbl->QueryPacks(This, ppEnum) -#define IVdsSwProvider_Release(This) (This)->lpVtbl->Release(This) -#define IVdsPack_QueryDisks(This, ppEnum) (This)->lpVtbl->QueryDisks(This, ppEnum) -#define IVdsDisk_GetProperties(This, pDiskProperties) (This)->lpVtbl->GetProperties(This, pDiskProperties) -#define IVdsDisk_Release(This) (This)->lpVtbl->Release(This) -#define IVdsDisk_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject) -#define IVdsAdvancedDisk_QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions) (This)->lpVtbl->QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions) -#define IVdsAdvancedDisk_DeletePartition(This, ullOffset, bForce, bForceProtected) (This)->lpVtbl->DeletePartition(This, ullOffset, bForce, bForceProtected) -#define IVdsAdvancedDisk_Clean(This, bForce, bForceOEM, bFullClean, ppAsync) (This)->lpVtbl->Clean(This, bForce, bForceOEM, bFullClean, ppAsync) -#define IVdsAdvancedDisk_Release(This) (This)->lpVtbl->Release(This) -#define IEnumVdsObject_Next(This, celt, ppObjectArray, pcFetched) (This)->lpVtbl->Next(This, celt, ppObjectArray, pcFetched) -#define IVdsPack_QueryVolumes(This, ppEnum) (This)->lpVtbl->QueryVolumes(This, ppEnum) -#define IVdsVolume_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject) -#define IVdsVolume_Release(This) (This)->lpVtbl->Release(This) -#define IVdsVolumeMF3_QueryVolumeGuidPathnames(This, pwszPathArray, pulNumberOfPaths) (This)->lpVtbl->QueryVolumeGuidPathnames(This,pwszPathArray,pulNumberOfPaths) -#define IVdsVolumeMF3_FormatEx2(This, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, Options, ppAsync) (This)->lpVtbl->FormatEx2(This, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, Options, ppAsync) -#define IVdsVolumeMF3_Release(This) (This)->lpVtbl->Release(This) -#define IVdsVolume_GetProperties(This, pVolumeProperties) (This)->lpVtbl->GetProperties(This,pVolumeProperties) -#define IVdsAsync_Cancel(This) (This)->lpVtbl->Cancel(This) -#define IVdsAsync_QueryStatus(This,pHrResult,pulPercentCompleted) (This)->lpVtbl->QueryStatus(This,pHrResult,pulPercentCompleted) -#define IVdsAsync_Wait(This,pHrResult,pAsyncOut) (This)->lpVtbl->Wait(This,pHrResult,pAsyncOut) -#define IVdsAsync_Release(This) (This)->lpVtbl->Release(This) - -#define IUnknown_QueryInterface(This, a, b) (This)->lpVtbl->QueryInterface(This,a,b) -#define IUnknown_Release(This) (This)->lpVtbl->Release(This) - -/* -* Delete all the partitions from a disk, using VDS -* Mostly copied from https://social.msdn.microsoft.com/Forums/vstudio/en-US/b90482ae-4e44-4b08-8731-81915030b32a/createpartition-using-vds-interface-throw-error-enointerface-dcom?forum=vcgeneral -*/ -BOOL DeletePartitions(DWORD DriveIndex, BOOL OnlyPart2) -{ - BOOL r = FALSE; - HRESULT hr; - ULONG ulFetched; - wchar_t wPhysicalName[48]; - IVdsServiceLoader *pLoader; - IVdsService *pService; - IEnumVdsObject *pEnum; - IUnknown *pUnk; - - swprintf_s(wPhysicalName, ARRAYSIZE(wPhysicalName), L"\\\\?\\PhysicalDrive%lu", DriveIndex); - - // Initialize COM - CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, - RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL); - - // Create a VDS Loader Instance - hr = CoCreateInstance(&CLSID_VdsLoader, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, - &IID_IVdsServiceLoader, (void **)&pLoader); - if (hr != S_OK) { - VDS_SET_ERROR(hr); - Log("Could not create VDS Loader Instance: %u", LASTERR); - goto out; - } - - // Load the VDS Service - hr = IVdsServiceLoader_LoadService(pLoader, L"", &pService); - IVdsServiceLoader_Release(pLoader); - if (hr != S_OK) { - VDS_SET_ERROR(hr); - Log("Could not load VDS Service: %u", LASTERR); - goto out; - } - - // Wait for the Service to become ready if needed - hr = IVdsService_WaitForServiceReady(pService); - if (hr != S_OK) { - VDS_SET_ERROR(hr); - Log("VDS Service is not ready: %u", LASTERR); - goto out; - } - - // Query the VDS Service Providers - hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum); - if (hr != S_OK) { - VDS_SET_ERROR(hr); - Log("Could not query VDS Service Providers: %u", LASTERR); - goto out; - } - - while (IEnumVdsObject_Next(pEnum, 1, &pUnk, &ulFetched) == S_OK) { - IVdsProvider *pProvider; - IVdsSwProvider *pSwProvider; - IEnumVdsObject *pEnumPack; - IUnknown *pPackUnk; - - // Get VDS Provider - hr = IUnknown_QueryInterface(pUnk, &IID_IVdsProvider, (void **)&pProvider); - IUnknown_Release(pUnk); - if (hr != S_OK) { - VDS_SET_ERROR(hr); - Log("Could not get VDS Provider: %u", LASTERR); - goto out; - } - - // Get VDS Software Provider - hr = IVdsSwProvider_QueryInterface(pProvider, &IID_IVdsSwProvider, (void **)&pSwProvider); - IVdsProvider_Release(pProvider); - if (hr != S_OK) { - VDS_SET_ERROR(hr); - Log("Could not get VDS Software Provider: %u", LASTERR); - goto out; - } - - // Get VDS Software Provider Packs - hr = IVdsSwProvider_QueryPacks(pSwProvider, &pEnumPack); - IVdsSwProvider_Release(pSwProvider); - if (hr != S_OK) { - VDS_SET_ERROR(hr); - Log("Could not get VDS Software Provider Packs: %u", LASTERR); - goto out; - } - - // Enumerate Provider Packs - while (IEnumVdsObject_Next(pEnumPack, 1, &pPackUnk, &ulFetched) == S_OK) { - IVdsPack *pPack; - IEnumVdsObject *pEnumDisk; - IUnknown *pDiskUnk; - - hr = IUnknown_QueryInterface(pPackUnk, &IID_IVdsPack, (void **)&pPack); - IUnknown_Release(pPackUnk); - if (hr != S_OK) { - VDS_SET_ERROR(hr); - Log("Could not query VDS Software Provider Pack: %u", LASTERR); - goto out; - } - - // Use the pack interface to access the disks - hr = IVdsPack_QueryDisks(pPack, &pEnumDisk); - if (hr != S_OK) { - VDS_SET_ERROR(hr); - Log("Could not query VDS disks: %u", LASTERR); - goto out; - } - - // List disks - while (IEnumVdsObject_Next(pEnumDisk, 1, &pDiskUnk, &ulFetched) == S_OK) { - VDS_DISK_PROP diskprop; - VDS_PARTITION_PROP* prop_array; - LONG i, prop_array_size; - IVdsDisk *pDisk; - IVdsAdvancedDisk *pAdvancedDisk; - - // Get the disk interface. - hr = IUnknown_QueryInterface(pDiskUnk, &IID_IVdsDisk, (void **)&pDisk); - if (hr != S_OK) { - VDS_SET_ERROR(hr); - Log("Could not query VDS Disk Interface: %u", LASTERR); - goto out; - } - - // Get the disk properties - hr = IVdsDisk_GetProperties(pDisk, &diskprop); - if (hr != S_OK) { - VDS_SET_ERROR(hr); - Log("Could not query VDS Disk Properties: %u", LASTERR); - goto out; - } - - // Isolate the disk we want - if (_wcsicmp(wPhysicalName, diskprop.pwszName) != 0) { - IVdsDisk_Release(pDisk); - continue; - } - - // Instantiate the AdvanceDisk interface for our disk. - hr = IVdsDisk_QueryInterface(pDisk, &IID_IVdsAdvancedDisk, (void **)&pAdvancedDisk); - IVdsDisk_Release(pDisk); - if (hr != S_OK) { - VDS_SET_ERROR(hr); - Log("Could not access VDS Advanced Disk interface: %u", LASTERR); - goto out; - } - - // Query the partition data, so we can get the start offset, which we need for deletion - hr = IVdsAdvancedDisk_QueryPartitions(pAdvancedDisk, &prop_array, &prop_array_size); - if (hr == S_OK) { - Log("Deleting ALL partition(s) from disk '%S':", diskprop.pwszName); - // Now go through each partition - for (i = 0; i < prop_array_size; i++) { - - Log("* Partition %d (offset: %lld, size: %llu)", prop_array[i].ulPartitionNumber, - prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize); - - if (OnlyPart2 && prop_array[i].ullOffset == 2048*512) - { - Log("Skip this partition..."); - continue; - } - - - hr = IVdsAdvancedDisk_DeletePartition(pAdvancedDisk, prop_array[i].ullOffset, TRUE, TRUE); - if (hr != S_OK) { - r = FALSE; - VDS_SET_ERROR(hr); - Log("Could not delete partitions: %u", LASTERR); - } - } - r = TRUE; - } - else { - Log("No partition to delete on disk '%S'", diskprop.pwszName); - r = TRUE; - } - CoTaskMemFree(prop_array); - -#if 0 - // Issue a Clean while we're at it - HRESULT hr2 = E_FAIL; - ULONG completed; - IVdsAsync* pAsync; - hr = IVdsAdvancedDisk_Clean(pAdvancedDisk, TRUE, FALSE, FALSE, &pAsync); - while (SUCCEEDED(hr)) { - if (IS_ERROR(FormatStatus)) { - IVdsAsync_Cancel(pAsync); - break; - } - hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed); - if (SUCCEEDED(hr)) { - hr = hr2; - if (hr == S_OK) - break; - if (hr == VDS_E_OPERATION_PENDING) - hr = S_OK; - } - Sleep(500); - } - if (hr != S_OK) { - VDS_SET_ERROR(hr); - Log("Could not clean disk: %s", LASTERR); - } -#endif - IVdsAdvancedDisk_Release(pAdvancedDisk); - goto out; - } - } - } - -out: - return r; -} - - -static DWORD GetVentoyVolumeName(int PhyDrive, UINT32 StartSectorId, CHAR *NameBuf, UINT32 BufLen, BOOL DelSlash) -{ - size_t len; - BOOL bRet; - DWORD dwSize; - HANDLE hDrive; - HANDLE hVolume; - UINT64 PartOffset; - DWORD Status = ERROR_NOT_FOUND; - DISK_EXTENT *pExtents = NULL; - CHAR VolumeName[MAX_PATH] = { 0 }; - VOLUME_DISK_EXTENTS DiskExtents; - - PartOffset = 512ULL * StartSectorId; - - Log("GetVentoyVolumeName PhyDrive %d SectorStart:%u PartOffset:%llu", PhyDrive, StartSectorId, (ULONGLONG)PartOffset); - - hVolume = FindFirstVolumeA(VolumeName, sizeof(VolumeName)); - if (hVolume == INVALID_HANDLE_VALUE) - { - return 1; - } - - do { - - len = strlen(VolumeName); - Log("Find volume:%s", VolumeName); - - VolumeName[len - 1] = 0; - - hDrive = CreateFileA(VolumeName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (hDrive == INVALID_HANDLE_VALUE) - { - continue; - } - - bRet = DeviceIoControl(hDrive, - IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, - NULL, - 0, - &DiskExtents, - (DWORD)(sizeof(DiskExtents)), - (LPDWORD)&dwSize, - NULL); - - Log("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS bRet:%u code:%u", bRet, LASTERR); - Log("NumberOfDiskExtents:%u DiskNumber:%u", DiskExtents.NumberOfDiskExtents, DiskExtents.Extents[0].DiskNumber); - - if (bRet && DiskExtents.NumberOfDiskExtents == 1) - { - pExtents = DiskExtents.Extents; - - Log("This volume DiskNumber:%u offset:%llu", pExtents->DiskNumber, (ULONGLONG)pExtents->StartingOffset.QuadPart); - if ((int)pExtents->DiskNumber == PhyDrive && pExtents->StartingOffset.QuadPart == PartOffset) - { - Log("This volume match"); - - if (!DelSlash) - { - VolumeName[len - 1] = '\\'; - } - - sprintf_s(NameBuf, BufLen, "%s", VolumeName); - Status = ERROR_SUCCESS; - CloseHandle(hDrive); - break; - } - } - - CloseHandle(hDrive); - } while (FindNextVolumeA(hVolume, VolumeName, sizeof(VolumeName))); - - FindVolumeClose(hVolume); - - Log("GetVentoyVolumeName return %u", Status); - return Status; -} - -static int GetLettersBelongPhyDrive(int PhyDrive, char *DriveLetters, size_t Length) -{ - int n = 0; - DWORD DataSize = 0; - CHAR *Pos = NULL; - CHAR *StringBuf = NULL; - - DataSize = GetLogicalDriveStringsA(0, NULL); - StringBuf = (CHAR *)malloc(DataSize + 1); - if (StringBuf == NULL) - { - return 1; - } - - GetLogicalDriveStringsA(DataSize, StringBuf); - - for (Pos = StringBuf; *Pos; Pos += strlen(Pos) + 1) - { - if (n < (int)Length && PhyDrive == GetPhyDriveByLogicalDrive(Pos[0])) - { - Log("%C: is belong to phydrive%d", Pos[0], PhyDrive); - DriveLetters[n++] = Pos[0]; - } - } - - free(StringBuf); - return 0; -} - -static HANDLE GetPhysicalHandle(int Drive, BOOLEAN bLockDrive, BOOLEAN bWriteAccess, BOOLEAN bWriteShare) -{ - int i; - DWORD dwSize; - DWORD LastError; - UINT64 EndTime; - HANDLE hDrive = INVALID_HANDLE_VALUE; - CHAR PhyDrive[128]; - CHAR DevPath[MAX_PATH] = { 0 }; - - safe_sprintf(PhyDrive, "\\\\.\\PhysicalDrive%d", Drive); - - if (0 == QueryDosDeviceA(PhyDrive + 4, DevPath, sizeof(DevPath))) - { - Log("QueryDosDeviceA failed error:%u", GetLastError()); - strcpy_s(DevPath, sizeof(DevPath), "???"); - } - else - { - Log("QueryDosDeviceA success %s", DevPath); - } - - for (i = 0; i < DRIVE_ACCESS_RETRIES; i++) - { - // Try without FILE_SHARE_WRITE (unless specifically requested) so that - // we won't be bothered by the OS or other apps when we set up our data. - // However this means we might have to wait for an access gap... - // We keep FILE_SHARE_READ though, as this shouldn't hurt us any, and is - // required for enumeration. - hDrive = CreateFileA(PhyDrive, - GENERIC_READ | (bWriteAccess ? GENERIC_WRITE : 0), - FILE_SHARE_READ | (bWriteShare ? FILE_SHARE_WRITE : 0), - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, - NULL); - - LastError = GetLastError(); - Log("[%d] CreateFileA %s code:%u %p", i, PhyDrive, LastError, hDrive); - - if (hDrive != INVALID_HANDLE_VALUE) - { - break; - } - - if ((LastError != ERROR_SHARING_VIOLATION) && (LastError != ERROR_ACCESS_DENIED)) - { - break; - } - - if (i == 0) - { - Log("Waiting for access on %s [%s]...", PhyDrive, DevPath); - } - else if (!bWriteShare && (i > DRIVE_ACCESS_RETRIES / 3)) - { - // If we can't seem to get a hold of the drive for some time, try to enable FILE_SHARE_WRITE... - Log("Warning: Could not obtain exclusive rights. Retrying with write sharing enabled..."); - bWriteShare = TRUE; - - // Try to report the process that is locking the drive - // We also use bit 6 as a flag to indicate that SearchProcess was called. - //access_mask = SearchProcess(DevPath, SEARCH_PROCESS_TIMEOUT, TRUE, TRUE, FALSE) | 0x40; - - } - Sleep(DRIVE_ACCESS_TIMEOUT / DRIVE_ACCESS_RETRIES); - } - - if (hDrive == INVALID_HANDLE_VALUE) - { - Log("Could not open %s %u", PhyDrive, LASTERR); - goto End; - } - - if (bWriteAccess) - { - Log("Opened %s for %s write access", PhyDrive, bWriteShare ? "shared" : "exclusive"); - } - - if (bLockDrive) - { - if (DeviceIoControl(hDrive, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0, &dwSize, NULL)) - { - Log("I/O boundary checks disabled"); - } - - EndTime = GetTickCount64() + DRIVE_ACCESS_TIMEOUT; - - do { - if (DeviceIoControl(hDrive, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL)) - { - Log("FSCTL_LOCK_VOLUME success"); - goto End; - } - Sleep(DRIVE_ACCESS_TIMEOUT / DRIVE_ACCESS_RETRIES); - } while (GetTickCount64() < EndTime); - - // If we reached this section, either we didn't manage to get a lock or the user cancelled - Log("Could not lock access to %s %u", PhyDrive, LASTERR); - - // See if we can report the processes are accessing the drive - //if (!IS_ERROR(FormatStatus) && (access_mask == 0)) - // access_mask = SearchProcess(DevPath, SEARCH_PROCESS_TIMEOUT, TRUE, TRUE, FALSE); - // Try to continue if the only access rights we saw were for read-only - //if ((access_mask & 0x07) != 0x01) - // safe_closehandle(hDrive); - - CHECK_CLOSE_HANDLE(hDrive); - } - -End: - - if (hDrive == INVALID_HANDLE_VALUE) - { - Log("Can get handle of %s, maybe some process control it.", DevPath); - } - - return hDrive; -} - -int GetPhyDriveByLogicalDrive(int DriveLetter) -{ - BOOL Ret; - DWORD dwSize; - HANDLE Handle; - VOLUME_DISK_EXTENTS DiskExtents; - CHAR PhyPath[128]; - - safe_sprintf(PhyPath, "\\\\.\\%C:", (CHAR)DriveLetter); - - Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); - if (Handle == INVALID_HANDLE_VALUE) - { - Log("Could not open the disk<%s>, error:%u", PhyPath, LASTERR); - return -1; - } - - Ret = DeviceIoControl(Handle, - IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, - NULL, - 0, - &DiskExtents, - (DWORD)(sizeof(DiskExtents)), - (LPDWORD)&dwSize, - NULL); - - if (!Ret || DiskExtents.NumberOfDiskExtents == 0) - { - Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed %s, error:%u", PhyPath, LASTERR); - CHECK_CLOSE_HANDLE(Handle); - return -1; - } - CHECK_CLOSE_HANDLE(Handle); - - Log("LogicalDrive:%s PhyDrive:%d Offset:%llu ExtentLength:%llu", - PhyPath, - DiskExtents.Extents[0].DiskNumber, - DiskExtents.Extents[0].StartingOffset.QuadPart, - DiskExtents.Extents[0].ExtentLength.QuadPart - ); - - return (int)DiskExtents.Extents[0].DiskNumber; -} - -int GetAllPhysicalDriveInfo(PHY_DRIVE_INFO *pDriveList, DWORD *pDriveCount) -{ - int i; - int Count; - int id; - int Letter = 'A'; - BOOL bRet; - DWORD dwBytes; - DWORD DriveCount = 0; - HANDLE Handle = INVALID_HANDLE_VALUE; - CHAR PhyDrive[128]; - PHY_DRIVE_INFO *CurDrive = pDriveList; - GET_LENGTH_INFORMATION LengthInfo; - STORAGE_PROPERTY_QUERY Query; - STORAGE_DESCRIPTOR_HEADER DevDescHeader; - STORAGE_DEVICE_DESCRIPTOR *pDevDesc; - int PhyDriveId[VENTOY_MAX_PHY_DRIVE]; - - Count = GetPhysicalDriveCount(); - - for (i = 0; i < Count && i < VENTOY_MAX_PHY_DRIVE; i++) - { - PhyDriveId[i] = i; - } - - dwBytes = GetLogicalDrives(); - Log("Logical Drives: 0x%x", dwBytes); - while (dwBytes) - { - if (dwBytes & 0x01) - { - id = GetPhyDriveByLogicalDrive(Letter); - Log("%C --> %d", Letter, id); - if (id >= 0) - { - for (i = 0; i < Count; i++) - { - if (PhyDriveId[i] == id) - { - break; - } - } - - if (i >= Count) - { - Log("Add phy%d to list", i); - PhyDriveId[Count] = id; - Count++; - } - } - } - - Letter++; - dwBytes >>= 1; - } - - for (i = 0; i < Count && DriveCount < VENTOY_MAX_PHY_DRIVE; i++) - { - CHECK_CLOSE_HANDLE(Handle); - - safe_sprintf(PhyDrive, "\\\\.\\PhysicalDrive%d", PhyDriveId[i]); - Handle = CreateFileA(PhyDrive, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - Log("Create file Handle:%p %s status:%u", Handle, PhyDrive, LASTERR); - - if (Handle == INVALID_HANDLE_VALUE) - { - continue; - } - - bRet = DeviceIoControl(Handle, - IOCTL_DISK_GET_LENGTH_INFO, NULL, - 0, - &LengthInfo, - sizeof(LengthInfo), - &dwBytes, - NULL); - if (!bRet) - { - Log("DeviceIoControl IOCTL_DISK_GET_LENGTH_INFO failed error:%u", LASTERR); - continue; - } - - Log("PHYSICALDRIVE%d size %llu bytes", i, (ULONGLONG)LengthInfo.Length.QuadPart); - - Query.PropertyId = StorageDeviceProperty; - Query.QueryType = PropertyStandardQuery; - - bRet = DeviceIoControl(Handle, - IOCTL_STORAGE_QUERY_PROPERTY, - &Query, - sizeof(Query), - &DevDescHeader, - sizeof(STORAGE_DESCRIPTOR_HEADER), - &dwBytes, - NULL); - if (!bRet) - { - Log("DeviceIoControl1 error:%u dwBytes:%u", LASTERR, dwBytes); - continue; - } - - if (DevDescHeader.Size < sizeof(STORAGE_DEVICE_DESCRIPTOR)) - { - Log("Invalid DevDescHeader.Size:%u", DevDescHeader.Size); - continue; - } - - pDevDesc = (STORAGE_DEVICE_DESCRIPTOR *)malloc(DevDescHeader.Size); - if (!pDevDesc) - { - Log("failed to malloc error:%u len:%u", LASTERR, DevDescHeader.Size); - continue; - } - - bRet = DeviceIoControl(Handle, - IOCTL_STORAGE_QUERY_PROPERTY, - &Query, - sizeof(Query), - pDevDesc, - DevDescHeader.Size, - &dwBytes, - NULL); - if (!bRet) - { - Log("DeviceIoControl2 error:%u dwBytes:%u", LASTERR, dwBytes); - free(pDevDesc); - continue; - } - - CurDrive->PhyDrive = i; - CurDrive->SizeInBytes = LengthInfo.Length.QuadPart; - CurDrive->DeviceType = pDevDesc->DeviceType; - CurDrive->RemovableMedia = pDevDesc->RemovableMedia; - CurDrive->BusType = pDevDesc->BusType; - - if (pDevDesc->VendorIdOffset) - { - safe_strcpy(CurDrive->VendorId, (char *)pDevDesc + pDevDesc->VendorIdOffset); - TrimString(CurDrive->VendorId); - } - - if (pDevDesc->ProductIdOffset) - { - safe_strcpy(CurDrive->ProductId, (char *)pDevDesc + pDevDesc->ProductIdOffset); - TrimString(CurDrive->ProductId); - } - - if (pDevDesc->ProductRevisionOffset) - { - safe_strcpy(CurDrive->ProductRev, (char *)pDevDesc + pDevDesc->ProductRevisionOffset); - TrimString(CurDrive->ProductRev); - } - - if (pDevDesc->SerialNumberOffset) - { - safe_strcpy(CurDrive->SerialNumber, (char *)pDevDesc + pDevDesc->SerialNumberOffset); - TrimString(CurDrive->SerialNumber); - } - - CurDrive++; - DriveCount++; - - free(pDevDesc); - - CHECK_CLOSE_HANDLE(Handle); - } - - for (i = 0, CurDrive = pDriveList; i < (int)DriveCount; i++, CurDrive++) - { - Log("PhyDrv:%d BusType:%-4s Removable:%u Size:%dGB(%llu) Name:%s %s", - CurDrive->PhyDrive, GetBusTypeString(CurDrive->BusType), CurDrive->RemovableMedia, - GetHumanReadableGBSize(CurDrive->SizeInBytes), CurDrive->SizeInBytes, - CurDrive->VendorId, CurDrive->ProductId); - } - - *pDriveCount = DriveCount; - - return 0; -} - - -static HANDLE g_FatPhyDrive; -static UINT64 g_Part2StartSec; -static int GetVentoyVersionFromFatFile(CHAR *VerBuf, size_t BufLen) -{ - int rc = 1; - int size = 0; - char *buf = NULL; - void *flfile = NULL; - - flfile = fl_fopen("/grub/grub.cfg", "rb"); - if (flfile) - { - fl_fseek(flfile, 0, SEEK_END); - size = (int)fl_ftell(flfile); - - fl_fseek(flfile, 0, SEEK_SET); - - buf = (char *)malloc(size + 1); - if (buf) - { - fl_fread(buf, 1, size, flfile); - buf[size] = 0; - - rc = 0; - sprintf_s(VerBuf, BufLen, "%s", ParseVentoyVersionFromString(buf)); - free(buf); - } - - fl_fclose(flfile); - } - - return rc; -} - -static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount) -{ - DWORD dwSize; - BOOL bRet; - DWORD ReadSize; - LARGE_INTEGER liCurrentPosition; - - liCurrentPosition.QuadPart = Sector + g_Part2StartSec; - liCurrentPosition.QuadPart *= 512; - SetFilePointerEx(g_FatPhyDrive, liCurrentPosition, &liCurrentPosition, FILE_BEGIN); - - ReadSize = (DWORD)(SectorCount * 512); - - bRet = ReadFile(g_FatPhyDrive, Buffer, ReadSize, &dwSize, NULL); - if (bRet == FALSE || dwSize != ReadSize) - { - Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u\n", bRet, ReadSize, dwSize, LASTERR); - } - - return 1; -} - - -int GetVentoyVerInPhyDrive(const PHY_DRIVE_INFO *pDriveInfo, MBR_HEAD *pMBR, CHAR *VerBuf, size_t BufLen) -{ - int rc = 0; - HANDLE hDrive; - - hDrive = GetPhysicalHandle(pDriveInfo->PhyDrive, FALSE, FALSE, FALSE); - if (hDrive == INVALID_HANDLE_VALUE) - { - return 1; - } - - g_FatPhyDrive = hDrive; - g_Part2StartSec = pMBR->PartTbl[1].StartSectorId; - - Log("Parse FAT fs..."); - - fl_init(); - - if (0 == fl_attach_media(VentoyFatDiskRead, NULL)) - { - rc = GetVentoyVersionFromFatFile(VerBuf, BufLen); - } - else - { - rc = 1; - } - - fl_shutdown(); - - CHECK_CLOSE_HANDLE(hDrive); - - return rc; -} - - - - - -static unsigned int g_disk_unxz_len = 0; -static BYTE *g_part_img_pos = NULL; -static BYTE *g_part_img_buf[VENTOY_EFI_PART_SIZE / SIZE_1MB]; - - -static int VentoyFatMemRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount) -{ - uint32 i; - uint32 offset; - BYTE *MbBuf = NULL; - - for (i = 0; i < SectorCount; i++) - { - offset = (Sector + i) * 512; - - if (g_part_img_buf[1] == NULL) - { - MbBuf = g_part_img_buf[0] + offset; - memcpy(Buffer + i * 512, MbBuf, 512); - } - else - { - MbBuf = g_part_img_buf[offset / SIZE_1MB]; - memcpy(Buffer + i * 512, MbBuf + (offset % SIZE_1MB), 512); - } - } - - return 1; -} - - -static int VentoyFatMemWrite(uint32 Sector, uint8 *Buffer, uint32 SectorCount) -{ - uint32 i; - uint32 offset; - BYTE *MbBuf = NULL; - - for (i = 0; i < SectorCount; i++) - { - offset = (Sector + i) * 512; - - if (g_part_img_buf[1] == NULL) - { - MbBuf = g_part_img_buf[0] + offset; - memcpy(MbBuf, Buffer + i * 512, 512); - } - else - { - MbBuf = g_part_img_buf[offset / SIZE_1MB]; - memcpy(MbBuf + (offset % SIZE_1MB), Buffer + i * 512, 512); - } - } - - return 1; -} - -int VentoyProcSecureBoot(BOOL SecureBoot) -{ - int rc = 0; - int size; - char *filebuf = NULL; - void *file = NULL; - - Log("VentoyProcSecureBoot %d ...", SecureBoot); - - if (SecureBoot) - { - Log("Secure boot is enabled ..."); - return 0; - } - - fl_init(); - - if (0 == fl_attach_media(VentoyFatMemRead, VentoyFatMemWrite)) - { - file = fl_fopen("/EFI/BOOT/grubx64_real.efi", "rb"); - Log("Open ventoy efi file %p ", file); - if (file) - { - fl_fseek(file, 0, SEEK_END); - size = (int)fl_ftell(file); - fl_fseek(file, 0, SEEK_SET); - - Log("ventoy efi file size %d ...", size); - - filebuf = (char *)malloc(size); - if (filebuf) - { - fl_fread(filebuf, 1, size, file); - } - - fl_fclose(file); - - Log("Now delete all efi files ..."); - fl_remove("/EFI/BOOT/BOOTX64.EFI"); - fl_remove("/EFI/BOOT/grubx64.efi"); - fl_remove("/EFI/BOOT/grubx64_real.efi"); - fl_remove("/EFI/BOOT/MokManager.efi"); - - file = fl_fopen("/EFI/BOOT/BOOTX64.EFI", "wb"); - Log("Open bootx64 efi file %p ", file); - if (file) - { - if (filebuf) - { - fl_fwrite(filebuf, 1, size, file); - } - - fl_fflush(file); - fl_fclose(file); - } - - if (filebuf) - { - free(filebuf); - } - } - } - else - { - rc = 1; - } - - fl_shutdown(); - - return rc; -} - - - -static int disk_xz_flush(void *src, unsigned int size) -{ - unsigned int i; - BYTE *buf = (BYTE *)src; - - for (i = 0; i < size; i++) - { - *g_part_img_pos = *buf++; - - g_disk_unxz_len++; - if ((g_disk_unxz_len % SIZE_1MB) == 0) - { - g_part_img_pos = g_part_img_buf[g_disk_unxz_len / SIZE_1MB]; - } - else - { - g_part_img_pos++; - } - } - - return (int)size; -} - -static void unxz_error(char *x) -{ - Log("%s", x); -} - -static BOOL TryWritePart2(HANDLE hDrive, UINT64 StartSectorId) -{ - BOOL bRet; - DWORD TrySize = 16 * 1024; - DWORD dwSize; - BYTE *Buffer = NULL; - unsigned char *data = NULL; - LARGE_INTEGER liCurrentPosition; - - liCurrentPosition.QuadPart = StartSectorId * 512; - SetFilePointerEx(hDrive, liCurrentPosition, &liCurrentPosition, FILE_BEGIN); - - Buffer = malloc(TrySize); - - bRet = WriteFile(hDrive, Buffer, TrySize, &dwSize, NULL); - - free(Buffer); - - Log("Try write part2 bRet:%u dwSize:%u code:%u", bRet, dwSize, LASTERR); - - if (bRet && dwSize == TrySize) - { - return TRUE; - } - - return FALSE; -} - -static int FormatPart2Fat(HANDLE hDrive, UINT64 StartSectorId) -{ - int i; - int rc = 0; - int len = 0; - int writelen = 0; - int partwrite = 0; - DWORD dwSize = 0; - BOOL bRet; - unsigned char *data = NULL; - LARGE_INTEGER liCurrentPosition; - LARGE_INTEGER liNewPosition; - - Log("FormatPart2Fat %llu...", StartSectorId); - - rc = ReadWholeFileToBuf(VENTOY_FILE_DISK_IMG, 0, (void **)&data, &len); - if (rc) - { - Log("Failed to read img file %p %u", data, len); - return 1; - } - - liCurrentPosition.QuadPart = StartSectorId * 512; - SetFilePointerEx(hDrive, liCurrentPosition, &liNewPosition, FILE_BEGIN); - - Log("Set file pointer: %llu New pointer:%llu", liCurrentPosition.QuadPart, liNewPosition.QuadPart); - - memset(g_part_img_buf, 0, sizeof(g_part_img_buf)); - - g_part_img_buf[0] = (BYTE *)malloc(VENTOY_EFI_PART_SIZE); - if (g_part_img_buf[0]) - { - Log("Malloc whole img buffer success, now decompress ..."); - unxz(data, len, NULL, NULL, g_part_img_buf[0], &writelen, unxz_error); - - if (len == writelen) - { - Log("decompress finished success"); - - VentoyProcSecureBoot(g_SecureBoot); - - for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++) - { - dwSize = 0; - bRet = WriteFile(hDrive, g_part_img_buf[0] + i * SIZE_1MB, SIZE_1MB, &dwSize, NULL); - Log("Write part data bRet:%u dwSize:%u code:%u", bRet, dwSize, LASTERR); - - if (!bRet) - { - rc = 1; - goto End; - } - - PROGRESS_BAR_SET_POS(PT_WRITE_VENTOY_START + i); - } - } - else - { - rc = 1; - Log("decompress finished failed"); - goto End; - } - } - else - { - Log("Failed to malloc whole img size %u, now split it", VENTOY_EFI_PART_SIZE); - - partwrite = 1; - for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++) - { - g_part_img_buf[i] = (BYTE *)malloc(SIZE_1MB); - if (g_part_img_buf[i] == NULL) - { - rc = 1; - goto End; - } - } - - Log("Malloc part img buffer success, now decompress ..."); - - g_part_img_pos = g_part_img_buf[0]; - - unxz(data, len, NULL, disk_xz_flush, NULL, NULL, unxz_error); - - if (g_disk_unxz_len == VENTOY_EFI_PART_SIZE) - { - Log("decompress finished success"); - - VentoyProcSecureBoot(g_SecureBoot); - - for (int i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++) - { - dwSize = 0; - bRet = WriteFile(hDrive, g_part_img_buf[i], SIZE_1MB, &dwSize, NULL); - Log("Write part data bRet:%u dwSize:%u code:%u", bRet, dwSize, LASTERR); - - if (!bRet) - { - rc = 1; - goto End; - } - - PROGRESS_BAR_SET_POS(PT_WRITE_VENTOY_START + i); - } - } - else - { - rc = 1; - Log("decompress finished failed"); - goto End; - } - } - -End: - - if (data) free(data); - - if (partwrite) - { - for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++) - { - if (g_part_img_buf[i]) free(g_part_img_buf[i]); - } - } - else - { - if (g_part_img_buf[0]) free(g_part_img_buf[0]); - } - - return rc; -} - -static int WriteGrubStage1ToPhyDrive(HANDLE hDrive) -{ - int Len = 0; - int readLen = 0; - BOOL bRet; - DWORD dwSize; - BYTE *ImgBuf = NULL; - BYTE *RawBuf = NULL; - - Log("WriteGrubStage1ToPhyDrive ..."); - - RawBuf = (BYTE *)malloc(SIZE_1MB); - if (!RawBuf) - { - return 1; - } - - if (ReadWholeFileToBuf(VENTOY_FILE_STG1_IMG, 0, (void **)&ImgBuf, &Len)) - { - Log("Failed to read stage1 img"); - free(RawBuf); - return 1; - } - - unxz(ImgBuf, Len, NULL, NULL, RawBuf, &readLen, unxz_error); - - SetFilePointer(hDrive, 512, NULL, FILE_BEGIN); - - bRet = WriteFile(hDrive, RawBuf, SIZE_1MB - 512, &dwSize, NULL); - Log("WriteFile Ret:%u dwSize:%u ErrCode:%u", bRet, dwSize, GetLastError()); - - free(RawBuf); - free(ImgBuf); - return 0; -} - - - -static int FormatPart1exFAT(UINT64 DiskSizeBytes) -{ - MKFS_PARM Option; - FRESULT Ret; - FATFS fs; - - Option.fmt = FM_EXFAT; - Option.n_fat = 1; - Option.align = 8; - Option.n_root = 1; - - // < 32GB select 32KB as cluster size - // > 32GB select 128KB as cluster size - if (DiskSizeBytes / 1024 / 1024 / 1024 <= 32) - { - Option.au_size = 32768; - } - else - { - Option.au_size = 131072; - } - - Log("Formatting Part1 exFAT ..."); - - Ret = f_mkfs(TEXT("0:"), &Option, 0, 8 * 1024 * 1024); - - if (FR_OK == Ret) - { - Log("Formatting Part1 exFAT success"); - - Ret = f_mount(&fs, TEXT("0:"), 1); - Log("mount part %d", Ret); - - if (FR_OK == Ret) - { - Ret = f_setlabel(TEXT("Ventoy")); - Log("f_setlabel %d", Ret); - - Ret = f_mount(0, TEXT("0:"), 1); - Log("umount part %d", Ret); - } - - return 0; - } - else - { - Log("Formatting Part1 exFAT failed"); - return 1; - } -} - - -int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) -{ - int i; - int rc = 0; - int state = 0; - HANDLE hDrive; - DWORD dwSize; - BOOL bRet; - CHAR MountDrive; - CHAR DriveName[] = "?:\\"; - CHAR DriveLetters[MAX_PATH] = { 0 }; - MBR_HEAD MBR; - - Log("InstallVentoy2PhyDrive PhyDrive%d <<%s %s %dGB>>", - pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId, - GetHumanReadableGBSize(pPhyDrive->SizeInBytes)); - - PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN); - - VentoyFillMBR(pPhyDrive->SizeInBytes, &MBR); - - Log("Lock disk for clean ............................. "); - - hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, FALSE, FALSE); - if (hDrive == INVALID_HANDLE_VALUE) - { - Log("Failed to open physical disk"); - return 1; - } - - GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters)); - - if (DriveLetters[0] == 0) - { - Log("No drive letter was assigned..."); - DriveName[0] = GetFirstUnusedDriveLetter(); - Log("GetFirstUnusedDriveLetter %C: ...", DriveName[0]); - } - else - { - // Unmount all mounted volumes that belong to this drive - // Do it in reverse so that we always end on the first volume letter - for (i = (int)strlen(DriveLetters); i > 0; i--) - { - DriveName[0] = DriveLetters[i - 1]; - bRet = DeleteVolumeMountPointA(DriveName); - Log("Delete mountpoint %s ret:%u code:%u", DriveName, bRet, GetLastError()); - } - } - - MountDrive = DriveName[0]; - Log("Will use '%C:' as volume mountpoint", DriveName[0]); - - // It kind of blows, but we have to relinquish access to the physical drive - // for VDS to be able to delete the partitions that reside on it... - DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL); - CHECK_CLOSE_HANDLE(hDrive); - - PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART); - - if (!DeletePartitions(pPhyDrive->PhyDrive, FALSE)) - { - Log("Notice: Could not delete partitions: %u", GetLastError()); - } - - Log("Deleting all partitions ......................... OK"); - - PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE); - - Log("Lock disk for write ............................. "); - hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE); - if (hDrive == INVALID_HANDLE_VALUE) - { - Log("Failed to GetPhysicalHandle for write."); - rc = 1; - goto End; - } - - //Refresh Drive Layout - DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL); - - disk_io_set_param(hDrive, MBR.PartTbl[0].StartSectorId + MBR.PartTbl[0].SectorCount); - - PROGRESS_BAR_SET_POS(PT_FORMAT_PART1); - - Log("Formatting part1 exFAT ..."); - if (0 != FormatPart1exFAT(pPhyDrive->SizeInBytes)) - { - rc = 1; - goto End; - } - - PROGRESS_BAR_SET_POS(PT_FORMAT_PART2); - Log("Writing part2 FAT img ..."); - if (0 != FormatPart2Fat(hDrive, MBR.PartTbl[1].StartSectorId)) - { - rc = 1; - goto End; - } - - PROGRESS_BAR_SET_POS(PT_WRITE_STG1_IMG); - Log("Writting Boot Image ............................. "); - if (WriteGrubStage1ToPhyDrive(hDrive) != 0) - { - rc = 1; - goto End; - } - - - PROGRESS_BAR_SET_POS(PT_WRITE_PART_TABLE); - Log("Writting Partition Table ........................ "); - SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); - if (!WriteFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL)) - { - rc = 1; - Log("Write MBR Failed, dwSize:%u ErrCode:%u", dwSize, GetLastError()); - goto End; - } - - Log("Write MBR OK ..."); - - //Refresh Drive Layout - DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL); - -End: - CHECK_CLOSE_HANDLE(hDrive); - - PROGRESS_BAR_SET_POS(PT_MOUNT_VOLUME); - Log("Mounting Ventoy Partition ....................... "); - Sleep(1000); - - state = 0; - memset(DriveLetters, 0, sizeof(DriveLetters)); - GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters)); - Log("Logical drive letter after write ventoy: <%s>", DriveLetters); - - for (i = 0; i < sizeof(DriveLetters) && DriveLetters[i]; i++) - { - DriveName[0] = DriveLetters[i]; - if (IsVentoyLogicalDrive(DriveName[0])) - { - Log("%s is ventoy part2, delete mountpoint", DriveName); - DeleteVolumeMountPointA(DriveName); - } - else - { - Log("%s is ventoy part1, already mounted", DriveName); - state = 1; - } - } - - if (state != 1) - { - Log("need to mount ventoy part1..."); - if (0 == GetVentoyVolumeName(pPhyDrive->PhyDrive, MBR.PartTbl[0].StartSectorId, DriveLetters, sizeof(DriveLetters), FALSE)) - { - DriveName[0] = MountDrive; - bRet = SetVolumeMountPointA(DriveName, DriveLetters); - Log("SetVolumeMountPoint <%s> <%s> bRet:%u code:%u", DriveName, DriveLetters, bRet, GetLastError()); - } - else - { - Log("Failed to find ventoy volume"); - } - } - - Log("OK\n"); - - return rc; -} - -int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) -{ - int i; - int rc = 0; - BOOL ForceMBR = FALSE; - HANDLE hVolume; - HANDLE hDrive; - DWORD Status; - DWORD dwSize; - BOOL bRet; - CHAR DriveName[] = "?:\\"; - CHAR DriveLetters[MAX_PATH] = { 0 }; - UINT32 StartSector; - UINT64 ReservedMB = 0; - MBR_HEAD BootImg; - MBR_HEAD MBR; - - Log("UpdateVentoy2PhyDrive PhyDrive%d <<%s %s %dGB>>", - pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId, - GetHumanReadableGBSize(pPhyDrive->SizeInBytes)); - - PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN); - - Log("Lock disk for umount ............................ "); - - hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, FALSE, FALSE); - if (hDrive == INVALID_HANDLE_VALUE) - { - Log("Failed to open physical disk"); - return 1; - } - - // Read MBR - SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); - ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL); - - StartSector = MBR.PartTbl[1].StartSectorId; - Log("StartSector in PartTbl:%u", StartSector); - - ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512)) / 2048; - Log("Reserved Disk Space:%u MB", ReservedMB); - - GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters)); - - if (DriveLetters[0] == 0) - { - Log("No drive letter was assigned..."); - } - else - { - // Unmount all mounted volumes that belong to this drive - // Do it in reverse so that we always end on the first volume letter - for (i = (int)strlen(DriveLetters); i > 0; i--) - { - DriveName[0] = DriveLetters[i - 1]; - if (IsVentoyLogicalDrive(DriveName[0])) - { - Log("%s is ventoy logical drive", DriveName); - bRet = DeleteVolumeMountPointA(DriveName); - Log("Delete mountpoint %s ret:%u code:%u", DriveName, bRet, LASTERR); - break; - } - } - } - - // It kind of blows, but we have to relinquish access to the physical drive - // for VDS to be able to delete the partitions that reside on it... - DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL); - CHECK_CLOSE_HANDLE(hDrive); - - PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE); - - Log("Lock disk for update ............................ "); - hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE); - if (hDrive == INVALID_HANDLE_VALUE) - { - Log("Failed to GetPhysicalHandle for write."); - rc = 1; - goto End; - } - - PROGRESS_BAR_SET_POS(PT_LOCK_VOLUME); - - Log("Lock volume for update .......................... "); - hVolume = INVALID_HANDLE_VALUE; - Status = GetVentoyVolumeName(pPhyDrive->PhyDrive, MBR.PartTbl[1].StartSectorId, DriveLetters, sizeof(DriveLetters), TRUE); - if (ERROR_SUCCESS == Status) - { - Log("Now lock and dismount volume <%s>", DriveLetters); - hVolume = CreateFileA(DriveLetters, - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, - NULL); - - if (hVolume == INVALID_HANDLE_VALUE) - { - Log("Failed to create file volume, errcode:%u", LASTERR); - rc = 1; - goto End; - } - - bRet = DeviceIoControl(hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL); - Log("FSCTL_LOCK_VOLUME bRet:%u code:%u", bRet, LASTERR); - - bRet = DeviceIoControl(hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL); - Log("FSCTL_DISMOUNT_VOLUME bRet:%u code:%u", bRet, LASTERR); - } - else if (ERROR_NOT_FOUND == Status) - { - Log("Volume not found, maybe not supported"); - } - else - { - rc = 1; - goto End; - } - - - if (!TryWritePart2(hDrive, StartSector)) - { - ForceMBR = TRUE; - Log("Try write failed, now delete partition 2..."); - - CHECK_CLOSE_HANDLE(hDrive); - - Log("Now delete partition 2..."); - DeletePartitions(pPhyDrive->PhyDrive, TRUE); - - hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE); - if (hDrive == INVALID_HANDLE_VALUE) - { - Log("Failed to GetPhysicalHandle for write."); - rc = 1; - goto End; - } - } - - - PROGRESS_BAR_SET_POS(PT_FORMAT_PART2); - - Log("Write Ventoy to disk ............................ "); - if (0 != FormatPart2Fat(hDrive, StartSector)) - { - rc = 1; - goto End; - } - - if (hVolume != INVALID_HANDLE_VALUE) - { - bRet = DeviceIoControl(hVolume, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL); - Log("FSCTL_UNLOCK_VOLUME bRet:%u code:%u", bRet, LASTERR); - CHECK_CLOSE_HANDLE(hVolume); - } - - Log("Updating Boot Image ............................. "); - if (WriteGrubStage1ToPhyDrive(hDrive) != 0) - { - rc = 1; - goto End; - } - - // Boot Image - VentoyGetLocalBootImg(&BootImg); - - // Use Old UUID - memcpy(BootImg.BootCode + 0x180, MBR.BootCode + 0x180, 16); - - if (ForceMBR == FALSE && memcmp(BootImg.BootCode, MBR.BootCode, 440) == 0) - { - Log("Boot image has no difference, no need to write."); - } - else - { - Log("Boot image need to write %u.", ForceMBR); - - SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); - - memcpy(MBR.BootCode, BootImg.BootCode, 440); - bRet = WriteFile(hDrive, &MBR, 512, &dwSize, NULL); - Log("Write Boot Image ret:%u dwSize:%u Error:%u", bRet, dwSize, LASTERR); - } - - if (0x00 == MBR.PartTbl[0].Active && 0x80 == MBR.PartTbl[1].Active) - { - Log("Need to chage 1st partition active and 2nd partition inactive."); - - MBR.PartTbl[0].Active = 0x80; - MBR.PartTbl[1].Active = 0x00; - - SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); - bRet = WriteFile(hDrive, &MBR, 512, &dwSize, NULL); - Log("Write NEW MBR ret:%u dwSize:%u Error:%u", bRet, dwSize, LASTERR); - } - - //Refresh Drive Layout - DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL); - -End: - CHECK_CLOSE_HANDLE(hDrive); - - return rc; -} - +/****************************************************************************** + * PhyDrive.c + * + * Copyright (c) 2020, longpanda + * Copyright (c) 2011-2020, Pete Batard + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include "resource.h" +#include "Language.h" +#include "Ventoy2Disk.h" +#include "fat_filelib.h" +#include "ff.h" + +/* + * Some code and functions in the file are copied from rufus. + * https://github.com/pbatard/rufus + */ +#define VDS_SET_ERROR SetLastError +#define IVdsServiceLoader_LoadService(This, pwszMachineName, ppService) (This)->lpVtbl->LoadService(This, pwszMachineName, ppService) +#define IVdsServiceLoader_Release(This) (This)->lpVtbl->Release(This) +#define IVdsService_QueryProviders(This, masks, ppEnum) (This)->lpVtbl->QueryProviders(This, masks, ppEnum) +#define IVdsService_WaitForServiceReady(This) ((This)->lpVtbl->WaitForServiceReady(This)) +#define IVdsService_CleanupObsoleteMountPoints(This) ((This)->lpVtbl->CleanupObsoleteMountPoints(This)) +#define IVdsService_Refresh(This) ((This)->lpVtbl->Refresh(This)) +#define IVdsService_Reenumerate(This) ((This)->lpVtbl->Reenumerate(This)) +#define IVdsSwProvider_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject) +#define IVdsProvider_Release(This) (This)->lpVtbl->Release(This) +#define IVdsSwProvider_QueryPacks(This, ppEnum) (This)->lpVtbl->QueryPacks(This, ppEnum) +#define IVdsSwProvider_Release(This) (This)->lpVtbl->Release(This) +#define IVdsPack_QueryDisks(This, ppEnum) (This)->lpVtbl->QueryDisks(This, ppEnum) +#define IVdsDisk_GetProperties(This, pDiskProperties) (This)->lpVtbl->GetProperties(This, pDiskProperties) +#define IVdsDisk_Release(This) (This)->lpVtbl->Release(This) +#define IVdsDisk_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject) +#define IVdsAdvancedDisk_QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions) (This)->lpVtbl->QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions) +#define IVdsAdvancedDisk_DeletePartition(This, ullOffset, bForce, bForceProtected) (This)->lpVtbl->DeletePartition(This, ullOffset, bForce, bForceProtected) +#define IVdsAdvancedDisk_Clean(This, bForce, bForceOEM, bFullClean, ppAsync) (This)->lpVtbl->Clean(This, bForce, bForceOEM, bFullClean, ppAsync) +#define IVdsAdvancedDisk_Release(This) (This)->lpVtbl->Release(This) +#define IEnumVdsObject_Next(This, celt, ppObjectArray, pcFetched) (This)->lpVtbl->Next(This, celt, ppObjectArray, pcFetched) +#define IVdsPack_QueryVolumes(This, ppEnum) (This)->lpVtbl->QueryVolumes(This, ppEnum) +#define IVdsVolume_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject) +#define IVdsVolume_Release(This) (This)->lpVtbl->Release(This) +#define IVdsVolumeMF3_QueryVolumeGuidPathnames(This, pwszPathArray, pulNumberOfPaths) (This)->lpVtbl->QueryVolumeGuidPathnames(This,pwszPathArray,pulNumberOfPaths) +#define IVdsVolumeMF3_FormatEx2(This, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, Options, ppAsync) (This)->lpVtbl->FormatEx2(This, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, Options, ppAsync) +#define IVdsVolumeMF3_Release(This) (This)->lpVtbl->Release(This) +#define IVdsVolume_GetProperties(This, pVolumeProperties) (This)->lpVtbl->GetProperties(This,pVolumeProperties) +#define IVdsAsync_Cancel(This) (This)->lpVtbl->Cancel(This) +#define IVdsAsync_QueryStatus(This,pHrResult,pulPercentCompleted) (This)->lpVtbl->QueryStatus(This,pHrResult,pulPercentCompleted) +#define IVdsAsync_Wait(This,pHrResult,pAsyncOut) (This)->lpVtbl->Wait(This,pHrResult,pAsyncOut) +#define IVdsAsync_Release(This) (This)->lpVtbl->Release(This) + +#define IUnknown_QueryInterface(This, a, b) (This)->lpVtbl->QueryInterface(This,a,b) +#define IUnknown_Release(This) (This)->lpVtbl->Release(This) + +/* +* Delete all the partitions from a disk, using VDS +* Mostly copied from https://social.msdn.microsoft.com/Forums/vstudio/en-US/b90482ae-4e44-4b08-8731-81915030b32a/createpartition-using-vds-interface-throw-error-enointerface-dcom?forum=vcgeneral +*/ +BOOL DeletePartitions(DWORD DriveIndex, BOOL OnlyPart2) +{ + BOOL r = FALSE; + HRESULT hr; + ULONG ulFetched; + wchar_t wPhysicalName[48]; + IVdsServiceLoader *pLoader; + IVdsService *pService; + IEnumVdsObject *pEnum; + IUnknown *pUnk; + + swprintf_s(wPhysicalName, ARRAYSIZE(wPhysicalName), L"\\\\?\\PhysicalDrive%lu", DriveIndex); + + // Initialize COM + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, + RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL); + + // Create a VDS Loader Instance + hr = CoCreateInstance(&CLSID_VdsLoader, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, + &IID_IVdsServiceLoader, (void **)&pLoader); + if (hr != S_OK) { + VDS_SET_ERROR(hr); + Log("Could not create VDS Loader Instance: %u", LASTERR); + goto out; + } + + // Load the VDS Service + hr = IVdsServiceLoader_LoadService(pLoader, L"", &pService); + IVdsServiceLoader_Release(pLoader); + if (hr != S_OK) { + VDS_SET_ERROR(hr); + Log("Could not load VDS Service: %u", LASTERR); + goto out; + } + + // Wait for the Service to become ready if needed + hr = IVdsService_WaitForServiceReady(pService); + if (hr != S_OK) { + VDS_SET_ERROR(hr); + Log("VDS Service is not ready: %u", LASTERR); + goto out; + } + + // Query the VDS Service Providers + hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum); + if (hr != S_OK) { + VDS_SET_ERROR(hr); + Log("Could not query VDS Service Providers: %u", LASTERR); + goto out; + } + + while (IEnumVdsObject_Next(pEnum, 1, &pUnk, &ulFetched) == S_OK) { + IVdsProvider *pProvider; + IVdsSwProvider *pSwProvider; + IEnumVdsObject *pEnumPack; + IUnknown *pPackUnk; + + // Get VDS Provider + hr = IUnknown_QueryInterface(pUnk, &IID_IVdsProvider, (void **)&pProvider); + IUnknown_Release(pUnk); + if (hr != S_OK) { + VDS_SET_ERROR(hr); + Log("Could not get VDS Provider: %u", LASTERR); + goto out; + } + + // Get VDS Software Provider + hr = IVdsSwProvider_QueryInterface(pProvider, &IID_IVdsSwProvider, (void **)&pSwProvider); + IVdsProvider_Release(pProvider); + if (hr != S_OK) { + VDS_SET_ERROR(hr); + Log("Could not get VDS Software Provider: %u", LASTERR); + goto out; + } + + // Get VDS Software Provider Packs + hr = IVdsSwProvider_QueryPacks(pSwProvider, &pEnumPack); + IVdsSwProvider_Release(pSwProvider); + if (hr != S_OK) { + VDS_SET_ERROR(hr); + Log("Could not get VDS Software Provider Packs: %u", LASTERR); + goto out; + } + + // Enumerate Provider Packs + while (IEnumVdsObject_Next(pEnumPack, 1, &pPackUnk, &ulFetched) == S_OK) { + IVdsPack *pPack; + IEnumVdsObject *pEnumDisk; + IUnknown *pDiskUnk; + + hr = IUnknown_QueryInterface(pPackUnk, &IID_IVdsPack, (void **)&pPack); + IUnknown_Release(pPackUnk); + if (hr != S_OK) { + VDS_SET_ERROR(hr); + Log("Could not query VDS Software Provider Pack: %u", LASTERR); + goto out; + } + + // Use the pack interface to access the disks + hr = IVdsPack_QueryDisks(pPack, &pEnumDisk); + if (hr != S_OK) { + VDS_SET_ERROR(hr); + Log("Could not query VDS disks: %u", LASTERR); + goto out; + } + + // List disks + while (IEnumVdsObject_Next(pEnumDisk, 1, &pDiskUnk, &ulFetched) == S_OK) { + VDS_DISK_PROP diskprop; + VDS_PARTITION_PROP* prop_array; + LONG i, prop_array_size; + IVdsDisk *pDisk; + IVdsAdvancedDisk *pAdvancedDisk; + + // Get the disk interface. + hr = IUnknown_QueryInterface(pDiskUnk, &IID_IVdsDisk, (void **)&pDisk); + if (hr != S_OK) { + VDS_SET_ERROR(hr); + Log("Could not query VDS Disk Interface: %u", LASTERR); + goto out; + } + + // Get the disk properties + hr = IVdsDisk_GetProperties(pDisk, &diskprop); + if (hr != S_OK) { + VDS_SET_ERROR(hr); + Log("Could not query VDS Disk Properties: %u", LASTERR); + goto out; + } + + // Isolate the disk we want + if (_wcsicmp(wPhysicalName, diskprop.pwszName) != 0) { + IVdsDisk_Release(pDisk); + continue; + } + + // Instantiate the AdvanceDisk interface for our disk. + hr = IVdsDisk_QueryInterface(pDisk, &IID_IVdsAdvancedDisk, (void **)&pAdvancedDisk); + IVdsDisk_Release(pDisk); + if (hr != S_OK) { + VDS_SET_ERROR(hr); + Log("Could not access VDS Advanced Disk interface: %u", LASTERR); + goto out; + } + + // Query the partition data, so we can get the start offset, which we need for deletion + hr = IVdsAdvancedDisk_QueryPartitions(pAdvancedDisk, &prop_array, &prop_array_size); + if (hr == S_OK) { + Log("Deleting ALL partition(s) from disk '%S':", diskprop.pwszName); + // Now go through each partition + for (i = 0; i < prop_array_size; i++) { + + Log("* Partition %d (offset: %lld, size: %llu)", prop_array[i].ulPartitionNumber, + prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize); + + if (OnlyPart2 && prop_array[i].ullOffset == 2048*512) + { + Log("Skip this partition..."); + continue; + } + + + hr = IVdsAdvancedDisk_DeletePartition(pAdvancedDisk, prop_array[i].ullOffset, TRUE, TRUE); + if (hr != S_OK) { + r = FALSE; + VDS_SET_ERROR(hr); + Log("Could not delete partitions: %u", LASTERR); + } + } + r = TRUE; + } + else { + Log("No partition to delete on disk '%S'", diskprop.pwszName); + r = TRUE; + } + CoTaskMemFree(prop_array); + +#if 0 + // Issue a Clean while we're at it + HRESULT hr2 = E_FAIL; + ULONG completed; + IVdsAsync* pAsync; + hr = IVdsAdvancedDisk_Clean(pAdvancedDisk, TRUE, FALSE, FALSE, &pAsync); + while (SUCCEEDED(hr)) { + if (IS_ERROR(FormatStatus)) { + IVdsAsync_Cancel(pAsync); + break; + } + hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed); + if (SUCCEEDED(hr)) { + hr = hr2; + if (hr == S_OK) + break; + if (hr == VDS_E_OPERATION_PENDING) + hr = S_OK; + } + Sleep(500); + } + if (hr != S_OK) { + VDS_SET_ERROR(hr); + Log("Could not clean disk: %s", LASTERR); + } +#endif + IVdsAdvancedDisk_Release(pAdvancedDisk); + goto out; + } + } + } + +out: + return r; +} + + +static DWORD GetVentoyVolumeName(int PhyDrive, UINT32 StartSectorId, CHAR *NameBuf, UINT32 BufLen, BOOL DelSlash) +{ + size_t len; + BOOL bRet; + DWORD dwSize; + HANDLE hDrive; + HANDLE hVolume; + UINT64 PartOffset; + DWORD Status = ERROR_NOT_FOUND; + DISK_EXTENT *pExtents = NULL; + CHAR VolumeName[MAX_PATH] = { 0 }; + VOLUME_DISK_EXTENTS DiskExtents; + + PartOffset = 512ULL * StartSectorId; + + Log("GetVentoyVolumeName PhyDrive %d SectorStart:%u PartOffset:%llu", PhyDrive, StartSectorId, (ULONGLONG)PartOffset); + + hVolume = FindFirstVolumeA(VolumeName, sizeof(VolumeName)); + if (hVolume == INVALID_HANDLE_VALUE) + { + return 1; + } + + do { + + len = strlen(VolumeName); + Log("Find volume:%s", VolumeName); + + VolumeName[len - 1] = 0; + + hDrive = CreateFileA(VolumeName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hDrive == INVALID_HANDLE_VALUE) + { + continue; + } + + bRet = DeviceIoControl(hDrive, + IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, + NULL, + 0, + &DiskExtents, + (DWORD)(sizeof(DiskExtents)), + (LPDWORD)&dwSize, + NULL); + + Log("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS bRet:%u code:%u", bRet, LASTERR); + Log("NumberOfDiskExtents:%u DiskNumber:%u", DiskExtents.NumberOfDiskExtents, DiskExtents.Extents[0].DiskNumber); + + if (bRet && DiskExtents.NumberOfDiskExtents == 1) + { + pExtents = DiskExtents.Extents; + + Log("This volume DiskNumber:%u offset:%llu", pExtents->DiskNumber, (ULONGLONG)pExtents->StartingOffset.QuadPart); + if ((int)pExtents->DiskNumber == PhyDrive && pExtents->StartingOffset.QuadPart == PartOffset) + { + Log("This volume match"); + + if (!DelSlash) + { + VolumeName[len - 1] = '\\'; + } + + sprintf_s(NameBuf, BufLen, "%s", VolumeName); + Status = ERROR_SUCCESS; + CloseHandle(hDrive); + break; + } + } + + CloseHandle(hDrive); + } while (FindNextVolumeA(hVolume, VolumeName, sizeof(VolumeName))); + + FindVolumeClose(hVolume); + + Log("GetVentoyVolumeName return %u", Status); + return Status; +} + +static int GetLettersBelongPhyDrive(int PhyDrive, char *DriveLetters, size_t Length) +{ + int n = 0; + DWORD DataSize = 0; + CHAR *Pos = NULL; + CHAR *StringBuf = NULL; + + DataSize = GetLogicalDriveStringsA(0, NULL); + StringBuf = (CHAR *)malloc(DataSize + 1); + if (StringBuf == NULL) + { + return 1; + } + + GetLogicalDriveStringsA(DataSize, StringBuf); + + for (Pos = StringBuf; *Pos; Pos += strlen(Pos) + 1) + { + if (n < (int)Length && PhyDrive == GetPhyDriveByLogicalDrive(Pos[0])) + { + Log("%C: is belong to phydrive%d", Pos[0], PhyDrive); + DriveLetters[n++] = Pos[0]; + } + } + + free(StringBuf); + return 0; +} + +static HANDLE GetPhysicalHandle(int Drive, BOOLEAN bLockDrive, BOOLEAN bWriteAccess, BOOLEAN bWriteShare) +{ + int i; + DWORD dwSize; + DWORD LastError; + UINT64 EndTime; + HANDLE hDrive = INVALID_HANDLE_VALUE; + CHAR PhyDrive[128]; + CHAR DevPath[MAX_PATH] = { 0 }; + + safe_sprintf(PhyDrive, "\\\\.\\PhysicalDrive%d", Drive); + + if (0 == QueryDosDeviceA(PhyDrive + 4, DevPath, sizeof(DevPath))) + { + Log("QueryDosDeviceA failed error:%u", GetLastError()); + strcpy_s(DevPath, sizeof(DevPath), "???"); + } + else + { + Log("QueryDosDeviceA success %s", DevPath); + } + + for (i = 0; i < DRIVE_ACCESS_RETRIES; i++) + { + // Try without FILE_SHARE_WRITE (unless specifically requested) so that + // we won't be bothered by the OS or other apps when we set up our data. + // However this means we might have to wait for an access gap... + // We keep FILE_SHARE_READ though, as this shouldn't hurt us any, and is + // required for enumeration. + hDrive = CreateFileA(PhyDrive, + GENERIC_READ | (bWriteAccess ? GENERIC_WRITE : 0), + FILE_SHARE_READ | (bWriteShare ? FILE_SHARE_WRITE : 0), + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, + NULL); + + LastError = GetLastError(); + Log("[%d] CreateFileA %s code:%u %p", i, PhyDrive, LastError, hDrive); + + if (hDrive != INVALID_HANDLE_VALUE) + { + break; + } + + if ((LastError != ERROR_SHARING_VIOLATION) && (LastError != ERROR_ACCESS_DENIED)) + { + break; + } + + if (i == 0) + { + Log("Waiting for access on %s [%s]...", PhyDrive, DevPath); + } + else if (!bWriteShare && (i > DRIVE_ACCESS_RETRIES / 3)) + { + // If we can't seem to get a hold of the drive for some time, try to enable FILE_SHARE_WRITE... + Log("Warning: Could not obtain exclusive rights. Retrying with write sharing enabled..."); + bWriteShare = TRUE; + + // Try to report the process that is locking the drive + // We also use bit 6 as a flag to indicate that SearchProcess was called. + //access_mask = SearchProcess(DevPath, SEARCH_PROCESS_TIMEOUT, TRUE, TRUE, FALSE) | 0x40; + + } + Sleep(DRIVE_ACCESS_TIMEOUT / DRIVE_ACCESS_RETRIES); + } + + if (hDrive == INVALID_HANDLE_VALUE) + { + Log("Could not open %s %u", PhyDrive, LASTERR); + goto End; + } + + if (bWriteAccess) + { + Log("Opened %s for %s write access", PhyDrive, bWriteShare ? "shared" : "exclusive"); + } + + if (bLockDrive) + { + if (DeviceIoControl(hDrive, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0, &dwSize, NULL)) + { + Log("I/O boundary checks disabled"); + } + + EndTime = GetTickCount64() + DRIVE_ACCESS_TIMEOUT; + + do { + if (DeviceIoControl(hDrive, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL)) + { + Log("FSCTL_LOCK_VOLUME success"); + goto End; + } + Sleep(DRIVE_ACCESS_TIMEOUT / DRIVE_ACCESS_RETRIES); + } while (GetTickCount64() < EndTime); + + // If we reached this section, either we didn't manage to get a lock or the user cancelled + Log("Could not lock access to %s %u", PhyDrive, LASTERR); + + // See if we can report the processes are accessing the drive + //if (!IS_ERROR(FormatStatus) && (access_mask == 0)) + // access_mask = SearchProcess(DevPath, SEARCH_PROCESS_TIMEOUT, TRUE, TRUE, FALSE); + // Try to continue if the only access rights we saw were for read-only + //if ((access_mask & 0x07) != 0x01) + // safe_closehandle(hDrive); + + CHECK_CLOSE_HANDLE(hDrive); + } + +End: + + if (hDrive == INVALID_HANDLE_VALUE) + { + Log("Can get handle of %s, maybe some process control it.", DevPath); + } + + return hDrive; +} + +int GetPhyDriveByLogicalDrive(int DriveLetter) +{ + BOOL Ret; + DWORD dwSize; + HANDLE Handle; + VOLUME_DISK_EXTENTS DiskExtents; + CHAR PhyPath[128]; + + safe_sprintf(PhyPath, "\\\\.\\%C:", (CHAR)DriveLetter); + + Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + if (Handle == INVALID_HANDLE_VALUE) + { + Log("Could not open the disk<%s>, error:%u", PhyPath, LASTERR); + return -1; + } + + Ret = DeviceIoControl(Handle, + IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, + NULL, + 0, + &DiskExtents, + (DWORD)(sizeof(DiskExtents)), + (LPDWORD)&dwSize, + NULL); + + if (!Ret || DiskExtents.NumberOfDiskExtents == 0) + { + Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed %s, error:%u", PhyPath, LASTERR); + CHECK_CLOSE_HANDLE(Handle); + return -1; + } + CHECK_CLOSE_HANDLE(Handle); + + Log("LogicalDrive:%s PhyDrive:%d Offset:%llu ExtentLength:%llu", + PhyPath, + DiskExtents.Extents[0].DiskNumber, + DiskExtents.Extents[0].StartingOffset.QuadPart, + DiskExtents.Extents[0].ExtentLength.QuadPart + ); + + return (int)DiskExtents.Extents[0].DiskNumber; +} + +int GetAllPhysicalDriveInfo(PHY_DRIVE_INFO *pDriveList, DWORD *pDriveCount) +{ + int i; + int Count; + int id; + int Letter = 'A'; + BOOL bRet; + DWORD dwBytes; + DWORD DriveCount = 0; + HANDLE Handle = INVALID_HANDLE_VALUE; + CHAR PhyDrive[128]; + PHY_DRIVE_INFO *CurDrive = pDriveList; + GET_LENGTH_INFORMATION LengthInfo; + STORAGE_PROPERTY_QUERY Query; + STORAGE_DESCRIPTOR_HEADER DevDescHeader; + STORAGE_DEVICE_DESCRIPTOR *pDevDesc; + int PhyDriveId[VENTOY_MAX_PHY_DRIVE]; + + Count = GetPhysicalDriveCount(); + + for (i = 0; i < Count && i < VENTOY_MAX_PHY_DRIVE; i++) + { + PhyDriveId[i] = i; + } + + dwBytes = GetLogicalDrives(); + Log("Logical Drives: 0x%x", dwBytes); + while (dwBytes) + { + if (dwBytes & 0x01) + { + id = GetPhyDriveByLogicalDrive(Letter); + Log("%C --> %d", Letter, id); + if (id >= 0) + { + for (i = 0; i < Count; i++) + { + if (PhyDriveId[i] == id) + { + break; + } + } + + if (i >= Count) + { + Log("Add phy%d to list", i); + PhyDriveId[Count] = id; + Count++; + } + } + } + + Letter++; + dwBytes >>= 1; + } + + for (i = 0; i < Count && DriveCount < VENTOY_MAX_PHY_DRIVE; i++) + { + CHECK_CLOSE_HANDLE(Handle); + + safe_sprintf(PhyDrive, "\\\\.\\PhysicalDrive%d", PhyDriveId[i]); + Handle = CreateFileA(PhyDrive, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + Log("Create file Handle:%p %s status:%u", Handle, PhyDrive, LASTERR); + + if (Handle == INVALID_HANDLE_VALUE) + { + continue; + } + + bRet = DeviceIoControl(Handle, + IOCTL_DISK_GET_LENGTH_INFO, NULL, + 0, + &LengthInfo, + sizeof(LengthInfo), + &dwBytes, + NULL); + if (!bRet) + { + Log("DeviceIoControl IOCTL_DISK_GET_LENGTH_INFO failed error:%u", LASTERR); + continue; + } + + Log("PHYSICALDRIVE%d size %llu bytes", i, (ULONGLONG)LengthInfo.Length.QuadPart); + + Query.PropertyId = StorageDeviceProperty; + Query.QueryType = PropertyStandardQuery; + + bRet = DeviceIoControl(Handle, + IOCTL_STORAGE_QUERY_PROPERTY, + &Query, + sizeof(Query), + &DevDescHeader, + sizeof(STORAGE_DESCRIPTOR_HEADER), + &dwBytes, + NULL); + if (!bRet) + { + Log("DeviceIoControl1 error:%u dwBytes:%u", LASTERR, dwBytes); + continue; + } + + if (DevDescHeader.Size < sizeof(STORAGE_DEVICE_DESCRIPTOR)) + { + Log("Invalid DevDescHeader.Size:%u", DevDescHeader.Size); + continue; + } + + pDevDesc = (STORAGE_DEVICE_DESCRIPTOR *)malloc(DevDescHeader.Size); + if (!pDevDesc) + { + Log("failed to malloc error:%u len:%u", LASTERR, DevDescHeader.Size); + continue; + } + + bRet = DeviceIoControl(Handle, + IOCTL_STORAGE_QUERY_PROPERTY, + &Query, + sizeof(Query), + pDevDesc, + DevDescHeader.Size, + &dwBytes, + NULL); + if (!bRet) + { + Log("DeviceIoControl2 error:%u dwBytes:%u", LASTERR, dwBytes); + free(pDevDesc); + continue; + } + + CurDrive->PhyDrive = i; + CurDrive->SizeInBytes = LengthInfo.Length.QuadPart; + CurDrive->DeviceType = pDevDesc->DeviceType; + CurDrive->RemovableMedia = pDevDesc->RemovableMedia; + CurDrive->BusType = pDevDesc->BusType; + + if (pDevDesc->VendorIdOffset) + { + safe_strcpy(CurDrive->VendorId, (char *)pDevDesc + pDevDesc->VendorIdOffset); + TrimString(CurDrive->VendorId); + } + + if (pDevDesc->ProductIdOffset) + { + safe_strcpy(CurDrive->ProductId, (char *)pDevDesc + pDevDesc->ProductIdOffset); + TrimString(CurDrive->ProductId); + } + + if (pDevDesc->ProductRevisionOffset) + { + safe_strcpy(CurDrive->ProductRev, (char *)pDevDesc + pDevDesc->ProductRevisionOffset); + TrimString(CurDrive->ProductRev); + } + + if (pDevDesc->SerialNumberOffset) + { + safe_strcpy(CurDrive->SerialNumber, (char *)pDevDesc + pDevDesc->SerialNumberOffset); + TrimString(CurDrive->SerialNumber); + } + + CurDrive++; + DriveCount++; + + free(pDevDesc); + + CHECK_CLOSE_HANDLE(Handle); + } + + for (i = 0, CurDrive = pDriveList; i < (int)DriveCount; i++, CurDrive++) + { + Log("PhyDrv:%d BusType:%-4s Removable:%u Size:%dGB(%llu) Name:%s %s", + CurDrive->PhyDrive, GetBusTypeString(CurDrive->BusType), CurDrive->RemovableMedia, + GetHumanReadableGBSize(CurDrive->SizeInBytes), CurDrive->SizeInBytes, + CurDrive->VendorId, CurDrive->ProductId); + } + + *pDriveCount = DriveCount; + + return 0; +} + + +static HANDLE g_FatPhyDrive; +static UINT64 g_Part2StartSec; +static int GetVentoyVersionFromFatFile(CHAR *VerBuf, size_t BufLen) +{ + int rc = 1; + int size = 0; + char *buf = NULL; + void *flfile = NULL; + + flfile = fl_fopen("/grub/grub.cfg", "rb"); + if (flfile) + { + fl_fseek(flfile, 0, SEEK_END); + size = (int)fl_ftell(flfile); + + fl_fseek(flfile, 0, SEEK_SET); + + buf = (char *)malloc(size + 1); + if (buf) + { + fl_fread(buf, 1, size, flfile); + buf[size] = 0; + + rc = 0; + sprintf_s(VerBuf, BufLen, "%s", ParseVentoyVersionFromString(buf)); + free(buf); + } + + fl_fclose(flfile); + } + + return rc; +} + +static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount) +{ + DWORD dwSize; + BOOL bRet; + DWORD ReadSize; + LARGE_INTEGER liCurrentPosition; + + liCurrentPosition.QuadPart = Sector + g_Part2StartSec; + liCurrentPosition.QuadPart *= 512; + SetFilePointerEx(g_FatPhyDrive, liCurrentPosition, &liCurrentPosition, FILE_BEGIN); + + ReadSize = (DWORD)(SectorCount * 512); + + bRet = ReadFile(g_FatPhyDrive, Buffer, ReadSize, &dwSize, NULL); + if (bRet == FALSE || dwSize != ReadSize) + { + Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u\n", bRet, ReadSize, dwSize, LASTERR); + } + + return 1; +} + + +int GetVentoyVerInPhyDrive(const PHY_DRIVE_INFO *pDriveInfo, UINT64 Part2StartSector, CHAR *VerBuf, size_t BufLen) +{ + int rc = 0; + HANDLE hDrive; + + hDrive = GetPhysicalHandle(pDriveInfo->PhyDrive, FALSE, FALSE, FALSE); + if (hDrive == INVALID_HANDLE_VALUE) + { + return 1; + } + + g_FatPhyDrive = hDrive; + g_Part2StartSec = Part2StartSector; + + Log("Parse FAT fs..."); + + fl_init(); + + if (0 == fl_attach_media(VentoyFatDiskRead, NULL)) + { + Log("attach media success..."); + rc = GetVentoyVersionFromFatFile(VerBuf, BufLen); + } + else + { + Log("attach media failed..."); + rc = 1; + } + + Log("GetVentoyVerInPhyDrive rc=%d...", rc); + if (rc == 0) + { + Log("VentoyVerInPhyDrive %d is <%s>...", pDriveInfo->PhyDrive, VerBuf); + } + + fl_shutdown(); + + CHECK_CLOSE_HANDLE(hDrive); + + return rc; +} + + + + + +static unsigned int g_disk_unxz_len = 0; +static BYTE *g_part_img_pos = NULL; +static BYTE *g_part_img_buf[VENTOY_EFI_PART_SIZE / SIZE_1MB]; + + +static int VentoyFatMemRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount) +{ + uint32 i; + uint32 offset; + BYTE *MbBuf = NULL; + + for (i = 0; i < SectorCount; i++) + { + offset = (Sector + i) * 512; + + if (g_part_img_buf[1] == NULL) + { + MbBuf = g_part_img_buf[0] + offset; + memcpy(Buffer + i * 512, MbBuf, 512); + } + else + { + MbBuf = g_part_img_buf[offset / SIZE_1MB]; + memcpy(Buffer + i * 512, MbBuf + (offset % SIZE_1MB), 512); + } + } + + return 1; +} + + +static int VentoyFatMemWrite(uint32 Sector, uint8 *Buffer, uint32 SectorCount) +{ + uint32 i; + uint32 offset; + BYTE *MbBuf = NULL; + + for (i = 0; i < SectorCount; i++) + { + offset = (Sector + i) * 512; + + if (g_part_img_buf[1] == NULL) + { + MbBuf = g_part_img_buf[0] + offset; + memcpy(MbBuf, Buffer + i * 512, 512); + } + else + { + MbBuf = g_part_img_buf[offset / SIZE_1MB]; + memcpy(MbBuf + (offset % SIZE_1MB), Buffer + i * 512, 512); + } + } + + return 1; +} + +int VentoyProcSecureBoot(BOOL SecureBoot) +{ + int rc = 0; + int size; + char *filebuf = NULL; + void *file = NULL; + + Log("VentoyProcSecureBoot %d ...", SecureBoot); + + if (SecureBoot) + { + Log("Secure boot is enabled ..."); + return 0; + } + + fl_init(); + + if (0 == fl_attach_media(VentoyFatMemRead, VentoyFatMemWrite)) + { + file = fl_fopen("/EFI/BOOT/grubx64_real.efi", "rb"); + Log("Open ventoy efi file %p ", file); + if (file) + { + fl_fseek(file, 0, SEEK_END); + size = (int)fl_ftell(file); + fl_fseek(file, 0, SEEK_SET); + + Log("ventoy efi file size %d ...", size); + + filebuf = (char *)malloc(size); + if (filebuf) + { + fl_fread(filebuf, 1, size, file); + } + + fl_fclose(file); + + Log("Now delete all efi files ..."); + fl_remove("/EFI/BOOT/BOOTX64.EFI"); + fl_remove("/EFI/BOOT/grubx64.efi"); + fl_remove("/EFI/BOOT/grubx64_real.efi"); + fl_remove("/EFI/BOOT/MokManager.efi"); + fl_remove("/ENROLL_THIS_KEY_IN_MOKMANAGER.cer"); + + file = fl_fopen("/EFI/BOOT/BOOTX64.EFI", "wb"); + Log("Open bootx64 efi file %p ", file); + if (file) + { + if (filebuf) + { + fl_fwrite(filebuf, 1, size, file); + } + + fl_fflush(file); + fl_fclose(file); + } + + if (filebuf) + { + free(filebuf); + } + } + } + else + { + rc = 1; + } + + fl_shutdown(); + + return rc; +} + + + +static int disk_xz_flush(void *src, unsigned int size) +{ + unsigned int i; + BYTE *buf = (BYTE *)src; + + for (i = 0; i < size; i++) + { + *g_part_img_pos = *buf++; + + g_disk_unxz_len++; + if ((g_disk_unxz_len % SIZE_1MB) == 0) + { + g_part_img_pos = g_part_img_buf[g_disk_unxz_len / SIZE_1MB]; + } + else + { + g_part_img_pos++; + } + } + + return (int)size; +} + +static void unxz_error(char *x) +{ + Log("%s", x); +} + +static BOOL TryWritePart2(HANDLE hDrive, UINT64 StartSectorId) +{ + BOOL bRet; + DWORD TrySize = 16 * 1024; + DWORD dwSize; + BYTE *Buffer = NULL; + unsigned char *data = NULL; + LARGE_INTEGER liCurrentPosition; + + liCurrentPosition.QuadPart = StartSectorId * 512; + SetFilePointerEx(hDrive, liCurrentPosition, &liCurrentPosition, FILE_BEGIN); + + Buffer = malloc(TrySize); + + bRet = WriteFile(hDrive, Buffer, TrySize, &dwSize, NULL); + + free(Buffer); + + Log("Try write part2 bRet:%u dwSize:%u code:%u", bRet, dwSize, LASTERR); + + if (bRet && dwSize == TrySize) + { + return TRUE; + } + + return FALSE; +} + +static int FormatPart2Fat(HANDLE hDrive, UINT64 StartSectorId) +{ + int i; + int rc = 0; + int len = 0; + int writelen = 0; + int partwrite = 0; + DWORD dwSize = 0; + BOOL bRet; + unsigned char *data = NULL; + LARGE_INTEGER liCurrentPosition; + LARGE_INTEGER liNewPosition; + + Log("FormatPart2Fat %llu...", StartSectorId); + + rc = ReadWholeFileToBuf(VENTOY_FILE_DISK_IMG, 0, (void **)&data, &len); + if (rc) + { + Log("Failed to read img file %p %u", data, len); + return 1; + } + + liCurrentPosition.QuadPart = StartSectorId * 512; + SetFilePointerEx(hDrive, liCurrentPosition, &liNewPosition, FILE_BEGIN); + + Log("Set file pointer: %llu New pointer:%llu", liCurrentPosition.QuadPart, liNewPosition.QuadPart); + + memset(g_part_img_buf, 0, sizeof(g_part_img_buf)); + + g_part_img_buf[0] = (BYTE *)malloc(VENTOY_EFI_PART_SIZE); + if (g_part_img_buf[0]) + { + Log("Malloc whole img buffer success, now decompress ..."); + unxz(data, len, NULL, NULL, g_part_img_buf[0], &writelen, unxz_error); + + if (len == writelen) + { + Log("decompress finished success"); + + VentoyProcSecureBoot(g_SecureBoot); + + for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++) + { + dwSize = 0; + bRet = WriteFile(hDrive, g_part_img_buf[0] + i * SIZE_1MB, SIZE_1MB, &dwSize, NULL); + Log("Write part data bRet:%u dwSize:%u code:%u", bRet, dwSize, LASTERR); + + if (!bRet) + { + rc = 1; + goto End; + } + + PROGRESS_BAR_SET_POS(PT_WRITE_VENTOY_START + i); + } + } + else + { + rc = 1; + Log("decompress finished failed"); + goto End; + } + } + else + { + Log("Failed to malloc whole img size %u, now split it", VENTOY_EFI_PART_SIZE); + + partwrite = 1; + for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++) + { + g_part_img_buf[i] = (BYTE *)malloc(SIZE_1MB); + if (g_part_img_buf[i] == NULL) + { + rc = 1; + goto End; + } + } + + Log("Malloc part img buffer success, now decompress ..."); + + g_part_img_pos = g_part_img_buf[0]; + + unxz(data, len, NULL, disk_xz_flush, NULL, NULL, unxz_error); + + if (g_disk_unxz_len == VENTOY_EFI_PART_SIZE) + { + Log("decompress finished success"); + + VentoyProcSecureBoot(g_SecureBoot); + + for (int i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++) + { + dwSize = 0; + bRet = WriteFile(hDrive, g_part_img_buf[i], SIZE_1MB, &dwSize, NULL); + Log("Write part data bRet:%u dwSize:%u code:%u", bRet, dwSize, LASTERR); + + if (!bRet) + { + rc = 1; + goto End; + } + + PROGRESS_BAR_SET_POS(PT_WRITE_VENTOY_START + i); + } + } + else + { + rc = 1; + Log("decompress finished failed"); + goto End; + } + } + +End: + + if (data) free(data); + + if (partwrite) + { + for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++) + { + if (g_part_img_buf[i]) free(g_part_img_buf[i]); + } + } + else + { + if (g_part_img_buf[0]) free(g_part_img_buf[0]); + } + + return rc; +} + +static int WriteGrubStage1ToPhyDrive(HANDLE hDrive, int PartStyle) +{ + int Len = 0; + int readLen = 0; + BOOL bRet; + DWORD dwSize; + BYTE *ImgBuf = NULL; + BYTE *RawBuf = NULL; + + Log("WriteGrubStage1ToPhyDrive ..."); + + RawBuf = (BYTE *)malloc(SIZE_1MB); + if (!RawBuf) + { + return 1; + } + + if (ReadWholeFileToBuf(VENTOY_FILE_STG1_IMG, 0, (void **)&ImgBuf, &Len)) + { + Log("Failed to read stage1 img"); + free(RawBuf); + return 1; + } + + unxz(ImgBuf, Len, NULL, NULL, RawBuf, &readLen, unxz_error); + + if (PartStyle) + { + Log("Write GPT stage1 ..."); + RawBuf[500] = 35;//update blocklist + SetFilePointer(hDrive, 512 * 34, NULL, FILE_BEGIN); + bRet = WriteFile(hDrive, RawBuf, SIZE_1MB - 512 * 34, &dwSize, NULL); + } + else + { + Log("Write MBR stage1 ..."); + SetFilePointer(hDrive, 512, NULL, FILE_BEGIN); + bRet = WriteFile(hDrive, RawBuf, SIZE_1MB - 512, &dwSize, NULL); + } + + Log("WriteFile Ret:%u dwSize:%u ErrCode:%u", bRet, dwSize, GetLastError()); + + free(RawBuf); + free(ImgBuf); + return 0; +} + + + +static int FormatPart1exFAT(UINT64 DiskSizeBytes) +{ + MKFS_PARM Option; + FRESULT Ret; + FATFS fs; + + Option.fmt = FM_EXFAT; + Option.n_fat = 1; + Option.align = 8; + Option.n_root = 1; + + // < 32GB select 32KB as cluster size + // > 32GB select 128KB as cluster size + if (DiskSizeBytes / 1024 / 1024 / 1024 <= 32) + { + Option.au_size = 32768; + } + else + { + Option.au_size = 131072; + } + + Log("Formatting Part1 exFAT ..."); + + Ret = f_mkfs(TEXT("0:"), &Option, 0, 8 * 1024 * 1024); + + if (FR_OK == Ret) + { + Log("Formatting Part1 exFAT success"); + + Ret = f_mount(&fs, TEXT("0:"), 1); + Log("mount part %d", Ret); + + if (FR_OK == Ret) + { + Ret = f_setlabel(TEXT("Ventoy")); + Log("f_setlabel %d", Ret); + + Ret = f_mount(0, TEXT("0:"), 1); + Log("umount part %d", Ret); + return 0; + } + else + { + Log("mount exfat failed %d", Ret); + return 1; + } + } + else + { + Log("Formatting Part1 exFAT failed"); + return 1; + } +} + + + +int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLetter) +{ + int i; + int rc = 0; + int state = 0; + HANDLE hDrive; + DWORD dwSize; + BOOL bRet; + CHAR MountDrive; + CHAR DriveName[] = "?:\\"; + CHAR DriveLetters[MAX_PATH] = { 0 }; + LARGE_INTEGER liCurrentPosition; + char *pTmpBuf = NULL; + MBR_HEAD MBR; + + *pDrvLetter = 0; + + Log("ClearVentoyFromPhyDrive PhyDrive%d <<%s %s %dGB>>", + pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId, + GetHumanReadableGBSize(pPhyDrive->SizeInBytes)); + + PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN); + + Log("Lock disk for clean ............................. "); + + hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, FALSE, FALSE); + if (hDrive == INVALID_HANDLE_VALUE) + { + Log("Failed to open physical disk"); + return 1; + } + + GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters)); + + if (DriveLetters[0] == 0) + { + Log("No drive letter was assigned..."); + DriveName[0] = GetFirstUnusedDriveLetter(); + Log("GetFirstUnusedDriveLetter %C: ...", DriveName[0]); + } + else + { + // Unmount all mounted volumes that belong to this drive + // Do it in reverse so that we always end on the first volume letter + for (i = (int)strlen(DriveLetters); i > 0; i--) + { + DriveName[0] = DriveLetters[i - 1]; + bRet = DeleteVolumeMountPointA(DriveName); + Log("Delete mountpoint %s ret:%u code:%u", DriveName, bRet, GetLastError()); + } + } + + MountDrive = DriveName[0]; + Log("Will use '%C:' as volume mountpoint", DriveName[0]); + + // It kind of blows, but we have to relinquish access to the physical drive + // for VDS to be able to delete the partitions that reside on it... + DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL); + CHECK_CLOSE_HANDLE(hDrive); + + PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART); + + if (!DeletePartitions(pPhyDrive->PhyDrive, FALSE)) + { + Log("Notice: Could not delete partitions: %u", GetLastError()); + } + + Log("Deleting all partitions ......................... OK"); + + PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE); + + Log("Lock disk for write ............................. "); + hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE); + if (hDrive == INVALID_HANDLE_VALUE) + { + Log("Failed to GetPhysicalHandle for write."); + rc = 1; + goto End; + } + + // clear first and last 1MB space + pTmpBuf = malloc(SIZE_1MB); + if (!pTmpBuf) + { + Log("Failed to alloc memory."); + rc = 1; + goto End; + } + memset(pTmpBuf, 0, SIZE_1MB); + + SET_FILE_POS(512); + bRet = WriteFile(hDrive, pTmpBuf, SIZE_1MB - 512, &dwSize, NULL); + Log("Write fisrt 1MB ret:%d size:%u err:%d", bRet, dwSize, LASTERR); + if (!bRet) + { + rc = 1; + goto End; + } + + SET_FILE_POS(SIZE_1MB); + bRet = WriteFile(hDrive, pTmpBuf, SIZE_1MB, &dwSize, NULL); + Log("Write 2nd 1MB ret:%d size:%u err:%d", bRet, dwSize, LASTERR); + if (!bRet) + { + rc = 1; + goto End; + } + + SET_FILE_POS(0); + bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL); + Log("Read MBR ret:%d size:%u err:%d", bRet, dwSize, LASTERR); + if (!bRet) + { + rc = 1; + goto End; + } + + //clear boot code and partition table (reserved disk signature) + memset(MBR.BootCode, 0, 440); + memset(MBR.PartTbl, 0, sizeof(MBR.PartTbl)); + + VentoyFillLocation(pPhyDrive->SizeInBytes, 2048, (UINT32)(pPhyDrive->SizeInBytes / 512 - 2048), MBR.PartTbl); + + MBR.PartTbl[0].Active = 0x00; // bootable + MBR.PartTbl[0].FsFlag = 0x07; // exFAT/NTFS/HPFS + + SET_FILE_POS(0); + bRet = WriteFile(hDrive, &MBR, 512, &dwSize, NULL); + Log("Write MBR ret:%d size:%u err:%d", bRet, dwSize, LASTERR); + if (!bRet) + { + rc = 1; + goto End; + } + + Log("Clear Ventoy successfully finished"); + + //Refresh Drive Layout + DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL); + +End: + + PROGRESS_BAR_SET_POS(PT_MOUNT_VOLUME); + + if (pTmpBuf) + { + free(pTmpBuf); + } + + if (rc == 0) + { + Log("Mounting Ventoy Partition ....................... "); + Sleep(1000); + + state = 0; + memset(DriveLetters, 0, sizeof(DriveLetters)); + GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters)); + Log("Logical drive letter after write ventoy: <%s>", DriveLetters); + + for (i = 0; i < sizeof(DriveLetters) && DriveLetters[i]; i++) + { + DriveName[0] = DriveLetters[i]; + Log("%s is ventoy part1, already mounted", DriveName); + state = 1; + } + + if (state != 1) + { + Log("need to mount ventoy part1..."); + if (0 == GetVentoyVolumeName(pPhyDrive->PhyDrive, MBR.PartTbl[0].StartSectorId, DriveLetters, sizeof(DriveLetters), FALSE)) + { + DriveName[0] = MountDrive; + bRet = SetVolumeMountPointA(DriveName, DriveLetters); + Log("SetVolumeMountPoint <%s> <%s> bRet:%u code:%u", DriveName, DriveLetters, bRet, GetLastError()); + + *pDrvLetter = MountDrive; + } + else + { + Log("Failed to find ventoy volume"); + } + } + + Log("OK\n"); + } + else + { + FindProcessOccupyDisk(hDrive, pPhyDrive); + } + + CHECK_CLOSE_HANDLE(hDrive); + return rc; +} + +int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle) +{ + int i; + int rc = 0; + int state = 0; + HANDLE hDrive; + DWORD dwSize; + BOOL bRet; + CHAR MountDrive; + CHAR DriveName[] = "?:\\"; + CHAR DriveLetters[MAX_PATH] = { 0 }; + MBR_HEAD MBR; + VTOY_GPT_INFO *pGptInfo = NULL; + + Log("InstallVentoy2PhyDrive %s PhyDrive%d <<%s %s %dGB>>", + PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId, + GetHumanReadableGBSize(pPhyDrive->SizeInBytes)); + + if (PartStyle) + { + pGptInfo = malloc(sizeof(VTOY_GPT_INFO)); + memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO)); + } + + PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN); + + VentoyFillMBR(pPhyDrive->SizeInBytes, &MBR, PartStyle);//also used to format 1st partition in GPT mode + if (PartStyle) + { + VentoyFillGpt(pPhyDrive->SizeInBytes, pGptInfo); + } + + Log("Lock disk for clean ............................. "); + + hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, FALSE, FALSE); + if (hDrive == INVALID_HANDLE_VALUE) + { + Log("Failed to open physical disk"); + free(pGptInfo); + return 1; + } + + GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters)); + + if (DriveLetters[0] == 0) + { + Log("No drive letter was assigned..."); + DriveName[0] = GetFirstUnusedDriveLetter(); + Log("GetFirstUnusedDriveLetter %C: ...", DriveName[0]); + } + else + { + // Unmount all mounted volumes that belong to this drive + // Do it in reverse so that we always end on the first volume letter + for (i = (int)strlen(DriveLetters); i > 0; i--) + { + DriveName[0] = DriveLetters[i - 1]; + bRet = DeleteVolumeMountPointA(DriveName); + Log("Delete mountpoint %s ret:%u code:%u", DriveName, bRet, GetLastError()); + } + } + + MountDrive = DriveName[0]; + Log("Will use '%C:' as volume mountpoint", DriveName[0]); + + // It kind of blows, but we have to relinquish access to the physical drive + // for VDS to be able to delete the partitions that reside on it... + DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL); + CHECK_CLOSE_HANDLE(hDrive); + + PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART); + + if (!DeletePartitions(pPhyDrive->PhyDrive, FALSE)) + { + Log("Notice: Could not delete partitions: %u", GetLastError()); + } + + Log("Deleting all partitions ......................... OK"); + + PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE); + + Log("Lock disk for write ............................. "); + hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE); + if (hDrive == INVALID_HANDLE_VALUE) + { + Log("Failed to GetPhysicalHandle for write."); + rc = 1; + goto End; + } + + //Refresh Drive Layout + DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL); + + disk_io_set_param(hDrive, MBR.PartTbl[0].StartSectorId + MBR.PartTbl[0].SectorCount); + + PROGRESS_BAR_SET_POS(PT_FORMAT_PART1); + + if (PartStyle == 1 && pPhyDrive->PartStyle == 0) + { + Log("Wait for format part1 ..."); + Sleep(1000 * 5); + } + + Log("Formatting part1 exFAT ..."); + if (0 != FormatPart1exFAT(pPhyDrive->SizeInBytes)) + { + Log("FormatPart1exFAT failed."); + rc = 1; + goto End; + } + + PROGRESS_BAR_SET_POS(PT_FORMAT_PART2); + Log("Writing part2 FAT img ..."); + if (0 != FormatPart2Fat(hDrive, MBR.PartTbl[1].StartSectorId)) + { + Log("FormatPart2Fat failed."); + rc = 1; + goto End; + } + + PROGRESS_BAR_SET_POS(PT_WRITE_STG1_IMG); + Log("Writting Boot Image ............................. "); + if (WriteGrubStage1ToPhyDrive(hDrive, PartStyle) != 0) + { + Log("WriteGrubStage1ToPhyDrive failed."); + rc = 1; + goto End; + } + + PROGRESS_BAR_SET_POS(PT_WRITE_PART_TABLE); + Log("Writting Partition Table ........................ "); + SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); + + if (PartStyle) + { + VTOY_GPT_HDR BackupHead; + LARGE_INTEGER liCurrentPosition; + + SET_FILE_POS(pPhyDrive->SizeInBytes - 512); + VentoyFillBackupGptHead(pGptInfo, &BackupHead); + if (!WriteFile(hDrive, &BackupHead, sizeof(VTOY_GPT_HDR), &dwSize, NULL)) + { + rc = 1; + Log("Write GPT Backup Head Failed, dwSize:%u (%u) ErrCode:%u", dwSize, sizeof(VTOY_GPT_INFO), GetLastError()); + goto End; + } + + SET_FILE_POS(pPhyDrive->SizeInBytes - 512 * 33); + if (!WriteFile(hDrive, pGptInfo->PartTbl, sizeof(pGptInfo->PartTbl), &dwSize, NULL)) + { + rc = 1; + Log("Write GPT Backup Part Table Failed, dwSize:%u (%u) ErrCode:%u", dwSize, sizeof(VTOY_GPT_INFO), GetLastError()); + goto End; + } + + SET_FILE_POS(0); + if (!WriteFile(hDrive, pGptInfo, sizeof(VTOY_GPT_INFO), &dwSize, NULL)) + { + rc = 1; + Log("Write GPT Info Failed, dwSize:%u (%u) ErrCode:%u", dwSize, sizeof(VTOY_GPT_INFO), GetLastError()); + goto End; + } + + Log("Write GPT Info OK ..."); + } + else + { + if (!WriteFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL)) + { + rc = 1; + Log("Write MBR Failed, dwSize:%u ErrCode:%u", dwSize, GetLastError()); + goto End; + } + Log("Write MBR OK ..."); + } + + + //Refresh Drive Layout + DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL); + +End: + + PROGRESS_BAR_SET_POS(PT_MOUNT_VOLUME); + + if (rc == 0) + { + Log("Mounting Ventoy Partition ....................... "); + Sleep(1000); + + state = 0; + memset(DriveLetters, 0, sizeof(DriveLetters)); + GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters)); + Log("Logical drive letter after write ventoy: <%s>", DriveLetters); + + for (i = 0; i < sizeof(DriveLetters) && DriveLetters[i]; i++) + { + DriveName[0] = DriveLetters[i]; + if (IsVentoyLogicalDrive(DriveName[0])) + { + Log("%s is ventoy part2, delete mountpoint", DriveName); + DeleteVolumeMountPointA(DriveName); + } + else + { + Log("%s is ventoy part1, already mounted", DriveName); + state = 1; + } + } + + if (state != 1) + { + Log("need to mount ventoy part1..."); + if (0 == GetVentoyVolumeName(pPhyDrive->PhyDrive, MBR.PartTbl[0].StartSectorId, DriveLetters, sizeof(DriveLetters), FALSE)) + { + DriveName[0] = MountDrive; + bRet = SetVolumeMountPointA(DriveName, DriveLetters); + Log("SetVolumeMountPoint <%s> <%s> bRet:%u code:%u", DriveName, DriveLetters, bRet, GetLastError()); + } + else + { + Log("Failed to find ventoy volume"); + } + } + Log("OK\n"); + } + else + { + FindProcessOccupyDisk(hDrive, pPhyDrive); + } + + if (pGptInfo) + { + free(pGptInfo); + } + + CHECK_CLOSE_HANDLE(hDrive); + return rc; +} + +int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) +{ + int i; + int rc = 0; + BOOL ForceMBR = FALSE; + HANDLE hVolume; + HANDLE hDrive; + DWORD Status; + DWORD dwSize; + BOOL bRet; + CHAR DriveName[] = "?:\\"; + CHAR DriveLetters[MAX_PATH] = { 0 }; + UINT64 StartSector; + UINT64 ReservedMB = 0; + MBR_HEAD BootImg; + MBR_HEAD MBR; + VTOY_GPT_INFO *pGptInfo = NULL; + + Log("UpdateVentoy2PhyDrive %s PhyDrive%d <<%s %s %dGB>>", + pPhyDrive->PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId, + GetHumanReadableGBSize(pPhyDrive->SizeInBytes)); + + PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN); + + Log("Lock disk for umount ............................ "); + + hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, FALSE, FALSE); + if (hDrive == INVALID_HANDLE_VALUE) + { + Log("Failed to open physical disk"); + return 1; + } + + if (pPhyDrive->PartStyle) + { + pGptInfo = malloc(sizeof(VTOY_GPT_INFO)); + if (!pGptInfo) + { + return 1; + } + + memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO)); + + // Read GPT Info + SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); + ReadFile(hDrive, pGptInfo, sizeof(VTOY_GPT_INFO), &dwSize, NULL); + + //MBR will be used to compare with local boot image + memcpy(&MBR, &pGptInfo->MBR, sizeof(MBR_HEAD)); + + StartSector = pGptInfo->PartTbl[1].StartLBA; + Log("GPT StartSector in PartTbl:%llu", (ULONGLONG)StartSector); + + ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512) - 33) / 2048; + Log("GPT Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB); + } + else + { + // Read MBR + SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); + ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL); + + StartSector = MBR.PartTbl[1].StartSectorId; + Log("MBR StartSector in PartTbl:%llu", (ULONGLONG)StartSector); + + ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512)) / 2048; + Log("MBR Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB); + } + + GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters)); + + if (DriveLetters[0] == 0) + { + Log("No drive letter was assigned..."); + } + else + { + // Unmount all mounted volumes that belong to this drive + // Do it in reverse so that we always end on the first volume letter + for (i = (int)strlen(DriveLetters); i > 0; i--) + { + DriveName[0] = DriveLetters[i - 1]; + if (IsVentoyLogicalDrive(DriveName[0])) + { + Log("%s is ventoy logical drive", DriveName); + bRet = DeleteVolumeMountPointA(DriveName); + Log("Delete mountpoint %s ret:%u code:%u", DriveName, bRet, LASTERR); + break; + } + } + } + + // It kind of blows, but we have to relinquish access to the physical drive + // for VDS to be able to delete the partitions that reside on it... + DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL); + CHECK_CLOSE_HANDLE(hDrive); + + PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE); + + Log("Lock disk for update ............................ "); + hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE); + if (hDrive == INVALID_HANDLE_VALUE) + { + Log("Failed to GetPhysicalHandle for write."); + rc = 1; + goto End; + } + + PROGRESS_BAR_SET_POS(PT_LOCK_VOLUME); + + Log("Lock volume for update .......................... "); + hVolume = INVALID_HANDLE_VALUE; + Status = GetVentoyVolumeName(pPhyDrive->PhyDrive, (UINT32)StartSector, DriveLetters, sizeof(DriveLetters), TRUE); + if (ERROR_SUCCESS == Status) + { + Log("Now lock and dismount volume <%s>", DriveLetters); + hVolume = CreateFileA(DriveLetters, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, + NULL); + + if (hVolume == INVALID_HANDLE_VALUE) + { + Log("Failed to create file volume, errcode:%u", LASTERR); + rc = 1; + goto End; + } + + bRet = DeviceIoControl(hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL); + Log("FSCTL_LOCK_VOLUME bRet:%u code:%u", bRet, LASTERR); + + bRet = DeviceIoControl(hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL); + Log("FSCTL_DISMOUNT_VOLUME bRet:%u code:%u", bRet, LASTERR); + } + else if (ERROR_NOT_FOUND == Status) + { + Log("Volume not found, maybe not supported"); + } + else + { + rc = 1; + goto End; + } + + + if (!TryWritePart2(hDrive, StartSector)) + { + if (pPhyDrive->PartStyle == 0) + { + ForceMBR = TRUE; + Log("Try write failed, now delete partition 2..."); + + CHECK_CLOSE_HANDLE(hDrive); + + Log("Now delete partition 2..."); + DeletePartitions(pPhyDrive->PhyDrive, TRUE); + + hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE); + if (hDrive == INVALID_HANDLE_VALUE) + { + Log("Failed to GetPhysicalHandle for write."); + rc = 1; + goto End; + } + } + } + + PROGRESS_BAR_SET_POS(PT_FORMAT_PART2); + + Log("Write Ventoy to disk ............................ "); + if (0 != FormatPart2Fat(hDrive, StartSector)) + { + rc = 1; + goto End; + } + + if (hVolume != INVALID_HANDLE_VALUE) + { + bRet = DeviceIoControl(hVolume, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL); + Log("FSCTL_UNLOCK_VOLUME bRet:%u code:%u", bRet, LASTERR); + CHECK_CLOSE_HANDLE(hVolume); + } + + Log("Updating Boot Image ............................. "); + if (WriteGrubStage1ToPhyDrive(hDrive, pPhyDrive->PartStyle) != 0) + { + rc = 1; + goto End; + } + + // Boot Image + VentoyGetLocalBootImg(&BootImg); + + // Use Old UUID + memcpy(BootImg.BootCode + 0x180, MBR.BootCode + 0x180, 16); + if (pPhyDrive->PartStyle) + { + BootImg.BootCode[92] = 0x22; + } + + if (ForceMBR == FALSE && memcmp(BootImg.BootCode, MBR.BootCode, 440) == 0) + { + Log("Boot image has no difference, no need to write."); + } + else + { + Log("Boot image need to write %u.", ForceMBR); + + SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); + + memcpy(MBR.BootCode, BootImg.BootCode, 440); + bRet = WriteFile(hDrive, &MBR, 512, &dwSize, NULL); + Log("Write Boot Image ret:%u dwSize:%u Error:%u", bRet, dwSize, LASTERR); + } + + if (pPhyDrive->PartStyle == 0) + { + if (0x00 == MBR.PartTbl[0].Active && 0x80 == MBR.PartTbl[1].Active) + { + Log("Need to chage 1st partition active and 2nd partition inactive."); + + MBR.PartTbl[0].Active = 0x80; + MBR.PartTbl[1].Active = 0x00; + + SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); + bRet = WriteFile(hDrive, &MBR, 512, &dwSize, NULL); + Log("Write NEW MBR ret:%u dwSize:%u Error:%u", bRet, dwSize, LASTERR); + } + } + + //Refresh Drive Layout + DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL); + +End: + + if (rc == 0) + { + Log("OK"); + } + else + { + FindProcessOccupyDisk(hDrive, pPhyDrive); + } + + CHECK_CLOSE_HANDLE(hDrive); + + if (pGptInfo) + { + free(pGptInfo); + } + + return rc; +} + + diff --git a/Ventoy2Disk/Ventoy2Disk/Res/refresh.ico b/Ventoy2Disk/Ventoy2Disk/Res/refresh.ico new file mode 100644 index 00000000..c2bc3388 Binary files /dev/null and b/Ventoy2Disk/Ventoy2Disk/Res/refresh.ico differ diff --git a/Ventoy2Disk/Ventoy2Disk/Utility.c b/Ventoy2Disk/Ventoy2Disk/Utility.c index 21b0245d..ff77db55 100644 --- a/Ventoy2Disk/Ventoy2Disk/Utility.c +++ b/Ventoy2Disk/Ventoy2Disk/Utility.c @@ -1,659 +1,805 @@ -/****************************************************************************** - * Utility.c - * - * Copyright (c) 2020, longpanda - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - */ -#include -#include "Ventoy2Disk.h" - -void Log(const char *Fmt, ...) -{ - va_list Arg; - int Len = 0; - FILE *File = NULL; - SYSTEMTIME Sys; - char szBuf[1024]; - - GetLocalTime(&Sys); - Len += safe_sprintf(szBuf, - "[%4d/%02d/%02d %02d:%02d:%02d.%03d] ", - Sys.wYear, Sys.wMonth, Sys.wDay, - Sys.wHour, Sys.wMinute, Sys.wSecond, - Sys.wMilliseconds); - - va_start(Arg, Fmt); - Len += vsnprintf_s(szBuf + Len, sizeof(szBuf)-Len, sizeof(szBuf)-Len, Fmt, Arg); - va_end(Arg); - - //printf("%s\n", szBuf); - -#if 1 - fopen_s(&File, VENTOY_FILE_LOG, "a+"); - if (File) - { - fwrite(szBuf, 1, Len, File); - fwrite("\n", 1, 1, File); - fclose(File); - } -#endif - -} - -BOOL IsPathExist(BOOL Dir, const char *Fmt, ...) -{ - va_list Arg; - HANDLE hFile; - DWORD Attr; - CHAR FilePath[MAX_PATH]; - - va_start(Arg, Fmt); - vsnprintf_s(FilePath, sizeof(FilePath), sizeof(FilePath), Fmt, Arg); - va_end(Arg); - - hFile = CreateFileA(FilePath, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); - if (INVALID_HANDLE_VALUE == hFile) - { - return FALSE; - } - - CloseHandle(hFile); - - Attr = GetFileAttributesA(FilePath); - - if (Dir) - { - if ((Attr & FILE_ATTRIBUTE_DIRECTORY) == 0) - { - return FALSE; - } - } - else - { - if (Attr & FILE_ATTRIBUTE_DIRECTORY) - { - return FALSE; - } - } - - return TRUE; -} - - -int ReadWholeFileToBuf(const CHAR *FileName, int ExtLen, void **Bufer, int *BufLen) -{ - int FileSize; - FILE *File = NULL; - void *Data = NULL; - - fopen_s(&File, FileName, "rb"); - if (File == NULL) - { - Log("Failed to open file %s", FileName); - return 1; - } - - fseek(File, 0, SEEK_END); - FileSize = (int)ftell(File); - - Data = malloc(FileSize + ExtLen); - if (!Data) - { - fclose(File); - return 1; - } - - fseek(File, 0, SEEK_SET); - fread(Data, 1, FileSize, File); - - fclose(File); - - *Bufer = Data; - *BufLen = FileSize; - - return 0; -} - -const CHAR* GetLocalVentoyVersion(void) -{ - int rc; - int FileSize; - CHAR *Pos = NULL; - CHAR *Buf = NULL; - static CHAR LocalVersion[64] = { 0 }; - - if (LocalVersion[0] == 0) - { - rc = ReadWholeFileToBuf(VENTOY_FILE_VERSION, 1, (void **)&Buf, &FileSize); - if (rc) - { - return ""; - } - Buf[FileSize] = 0; - - for (Pos = Buf; *Pos; Pos++) - { - if (*Pos == '\r' || *Pos == '\n') - { - *Pos = 0; - break; - } - } - - safe_sprintf(LocalVersion, "%s", Buf); - free(Buf); - } - - return LocalVersion; -} - -const CHAR* ParseVentoyVersionFromString(CHAR *Buf) -{ - CHAR *Pos = NULL; - CHAR *End = NULL; - static CHAR LocalVersion[64] = { 0 }; - - Pos = strstr(Buf, "VENTOY_VERSION="); - if (Pos) - { - Pos += strlen("VENTOY_VERSION="); - if (*Pos == '"') - { - Pos++; - } - - End = Pos; - while (*End != 0 && *End != '"' && *End != '\r' && *End != '\n') - { - End++; - } - - *End = 0; - - safe_sprintf(LocalVersion, "%s", Pos); - return LocalVersion; - } - - return ""; -} - -BOOL IsWow64(void) -{ - typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL); - LPFN_ISWOW64PROCESS fnIsWow64Process; - BOOL bIsWow64 = FALSE; - - fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandleA("kernel32"), "IsWow64Process"); - if (NULL != fnIsWow64Process) - { - fnIsWow64Process(GetCurrentProcess(), &bIsWow64); - } - - return bIsWow64; -} - -void DumpWindowsVersion(void) -{ - int Bit; - BOOL WsVer; - DWORD Major, Minor; - ULONGLONG MajorEqual, MinorEqual; - OSVERSIONINFOEXA Ver1, Ver2; - const CHAR *Ver = NULL; - CHAR WinVer[256] = { 0 }; - - memset(&Ver1, 0, sizeof(Ver1)); - memset(&Ver2, 0, sizeof(Ver2)); - - Ver1.dwOSVersionInfoSize = sizeof(Ver1); - - // suppress the C4996 warning for GetVersionExA - #pragma warning(push) - #pragma warning(disable:4996) - if (!GetVersionExA((OSVERSIONINFOA *)&Ver1)) - { - memset(&Ver1, 0, sizeof(Ver1)); - Ver1.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); - if (!GetVersionExA((OSVERSIONINFOA *)&Ver1)) - { - return; - } - } - #pragma warning(pop) - - if (Ver1.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - if (Ver1.dwMajorVersion > 6 || (Ver1.dwMajorVersion == 6 && Ver1.dwMinorVersion >= 2)) - { - // GetVersionEx() has problem on some Windows version - - MajorEqual = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL); - for (Major = Ver1.dwMajorVersion; Major <= 9; Major++) - { - memset(&Ver2, 0, sizeof(Ver2)); - Ver2.dwOSVersionInfoSize = sizeof(Ver2); - Ver2.dwMajorVersion = Major; - - if (!VerifyVersionInfoA(&Ver2, VER_MAJORVERSION, MajorEqual)) - { - continue; - } - - if (Ver1.dwMajorVersion < Major) - { - Ver1.dwMajorVersion = Major; - Ver1.dwMinorVersion = 0; - } - - MinorEqual = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL); - for (Minor = Ver1.dwMinorVersion; Minor <= 9; Minor++) - { - memset(&Ver2, 0, sizeof(Ver2)); - - Ver2.dwOSVersionInfoSize = sizeof(Ver2); - Ver2.dwMinorVersion = Minor; - - if (!VerifyVersionInfoA(&Ver2, VER_MINORVERSION, MinorEqual)) - { - continue; - } - - Ver1.dwMinorVersion = Minor; - break; - } - - break; - } - } - - if (Ver1.dwMajorVersion <= 0xF && Ver1.dwMinorVersion <= 0xF) - { - WsVer = (Ver1.wProductType <= VER_NT_WORKSTATION); - switch ((Ver1.dwMajorVersion << 4) | Ver2.dwMinorVersion) - { - case 0x51: - { - Ver = "XP"; - break; - } - case 0x52: - { - Ver = GetSystemMetrics(89) ? "Server 2003 R2" : "Server 2003"; - break; - } - case 0x60: - { - Ver = WsVer ? "Vista" : "Server 2008"; - break; - } - case 0x61: - { - Ver = WsVer ? "7" : "Server 2008 R2"; - break; - } - case 0x62: - { - Ver = WsVer ? "8" : "Server 2012"; - break; - } - case 0x63: - { - Ver = WsVer ? "8.1" : "Server 2012 R2"; - break; - } - case 0x64: - { - Ver = WsVer ? "10 (Preview 1)" : "Server 10 (Preview 1)"; - break; - } - case 0xA0: - { - Ver = WsVer ? "10" : ((Ver1.dwBuildNumber > 15000) ? "Server 2019" : "Server 2016"); - break; - } - default: - { - Ver = "10 or later"; - break; - } - } - } - } - - Bit = IsWow64() ? 64 : 32; - - if (Ver1.wServicePackMinor) - { - safe_sprintf(WinVer, "Windows %s SP%u.%u %d-bit", Ver, Ver1.wServicePackMajor, Ver1.wServicePackMinor, Bit); - } - else if (Ver1.wServicePackMajor) - { - safe_sprintf(WinVer, "Windows %s SP%u %d-bit", Ver, Ver1.wServicePackMajor, Bit); - } - else - { - safe_sprintf(WinVer, "Windows %s %d-bit", Ver, Bit); - } - - if (((Ver1.dwMajorVersion << 4) | Ver2.dwMinorVersion) >= 0x62) - { - Log("Windows Version : %s (Build %u)", WinVer, Ver1.dwBuildNumber); - } - else - { - Log("Windows Version : %s", WinVer); - } - - return; -} - -BOOL IsVentoyLogicalDrive(CHAR DriveLetter) -{ - int i; - CONST CHAR *Files[] = - { - "EFI\\BOOT\\BOOTX64.EFI", - "grub\\themes\\ventoy\\theme.txt", - "ventoy\\ventoy.cpio", - }; - - for (i = 0; i < sizeof(Files) / sizeof(Files[0]); i++) - { - if (!IsFileExist("%C:\\%s", DriveLetter, Files[i])) - { - return FALSE; - } - } - - return TRUE; -} - - -static int VentoyFillLocation(UINT64 DiskSizeInBytes, UINT32 StartSectorId, UINT32 SectorCount, PART_TABLE *Table) -{ - BYTE Head; - BYTE Sector; - BYTE nSector = 63; - BYTE nHead = 8; - UINT32 Cylinder; - UINT32 EndSectorId; - - while (nHead != 0 && (DiskSizeInBytes / 512 / nSector / nHead) > 1024) - { - nHead = (BYTE)nHead * 2; - } - - if (nHead == 0) - { - nHead = 255; - } - - Cylinder = StartSectorId / nSector / nHead; - Head = StartSectorId / nSector % nHead; - Sector = StartSectorId % nSector + 1; - - Table->StartHead = Head; - Table->StartSector = Sector; - Table->StartCylinder = Cylinder; - - EndSectorId = StartSectorId + SectorCount - 1; - Cylinder = EndSectorId / nSector / nHead; - Head = EndSectorId / nSector % nHead; - Sector = EndSectorId % nSector + 1; - - Table->EndHead = Head; - Table->EndSector = Sector; - Table->EndCylinder = Cylinder; - - Table->StartSectorId = StartSectorId; - Table->SectorCount = SectorCount; - - return 0; -} - -int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR) -{ - GUID Guid; - int ReservedValue; - UINT32 DiskSignature; - UINT32 DiskSectorCount; - UINT32 PartSectorCount; - UINT32 PartStartSector; - UINT32 ReservedSector; - - VentoyGetLocalBootImg(pMBR); - - CoCreateGuid(&Guid); - - memcpy(&DiskSignature, &Guid, sizeof(UINT32)); - - Log("Disk signature: 0x%08x", DiskSignature); - - *((UINT32 *)(pMBR->BootCode + 0x1B8)) = DiskSignature; - - DiskSectorCount = (UINT32)(DiskSizeBytes / 512); - - ReservedValue = GetReservedSpaceInMB(); - if (ReservedValue <= 0) - { - ReservedSector = 0; - } - else - { - ReservedSector = (UINT32)(ReservedValue * 2048); - } - - Log("ReservedSector: %u", ReservedSector); - - //Part1 - PartStartSector = VENTOY_PART1_START_SECTOR; - PartSectorCount = DiskSectorCount - ReservedSector - VENTOY_EFI_PART_SIZE / 512 - PartStartSector; - VentoyFillLocation(DiskSizeBytes, PartStartSector, PartSectorCount, pMBR->PartTbl); - - pMBR->PartTbl[0].Active = 0x80; // bootable - pMBR->PartTbl[0].FsFlag = 0x07; // exFAT/NTFS/HPFS - - //Part2 - PartStartSector += PartSectorCount; - PartSectorCount = VENTOY_EFI_PART_SIZE / 512; - VentoyFillLocation(DiskSizeBytes, PartStartSector, PartSectorCount, pMBR->PartTbl + 1); - - pMBR->PartTbl[1].Active = 0x00; - pMBR->PartTbl[1].FsFlag = 0xEF; // EFI System Partition - - pMBR->Byte55 = 0x55; - pMBR->ByteAA = 0xAA; - - return 0; -} - -CHAR GetFirstUnusedDriveLetter(void) -{ - CHAR Letter = 'D'; - DWORD Drives = GetLogicalDrives(); - - Drives >>= 3; - while (Drives & 0x1) - { - Letter++; - Drives >>= 1; - } - - return Letter; -} - -const CHAR * GetBusTypeString(STORAGE_BUS_TYPE Type) -{ - switch (Type) - { - case BusTypeUnknown: return "unknown"; - case BusTypeScsi: return "SCSI"; - case BusTypeAtapi: return "Atapi"; - case BusTypeAta: return "ATA"; - case BusType1394: return "1394"; - case BusTypeSsa: return "SSA"; - case BusTypeFibre: return "Fibre"; - case BusTypeUsb: return "USB"; - case BusTypeRAID: return "RAID"; - case BusTypeiScsi: return "iSCSI"; - case BusTypeSas: return "SAS"; - case BusTypeSata: return "SATA"; - case BusTypeSd: return "SD"; - case BusTypeMmc: return "MMC"; - case BusTypeVirtual: return "Virtual"; - case BusTypeFileBackedVirtual: return "FileBackedVirtual"; - case BusTypeSpaces: return "Spaces"; - case BusTypeNvme: return "Nvme"; - } - return "unknown"; -} - -int VentoyGetLocalBootImg(MBR_HEAD *pMBR) -{ - int Len = 0; - BYTE *ImgBuf = NULL; - static int Loaded = 0; - static MBR_HEAD MBR; - - if (Loaded) - { - memcpy(pMBR, &MBR, 512); - return 0; - } - - if (0 == ReadWholeFileToBuf(VENTOY_FILE_BOOT_IMG, 0, (void **)&ImgBuf, &Len)) - { - Log("Copy boot img success"); - memcpy(pMBR, ImgBuf, 512); - free(ImgBuf); - - CoCreateGuid((GUID *)(pMBR->BootCode + 0x180)); - - memcpy(&MBR, pMBR, 512); - Loaded = 1; - - return 0; - } - else - { - Log("Copy boot img failed"); - return 1; - } -} - -int GetHumanReadableGBSize(UINT64 SizeBytes) -{ - int i; - int Pow2 = 1; - double Delta; - double GB = SizeBytes * 1.0 / 1000 / 1000 / 1000; - - for (i = 0; i < 12; i++) - { - if (Pow2 > GB) - { - Delta = (Pow2 - GB) / Pow2; - } - else - { - Delta = (GB - Pow2) / Pow2; - } - - if (Delta < 0.05) - { - return Pow2; - } - - Pow2 <<= 1; - } - - return (int)GB; -} - -void TrimString(CHAR *String) -{ - CHAR *Pos1 = String; - CHAR *Pos2 = String; - size_t Len = strlen(String); - - while (Len > 0) - { - if (String[Len - 1] != ' ' && String[Len - 1] != '\t') - { - break; - } - String[Len - 1] = 0; - Len--; - } - - while (*Pos1 == ' ' || *Pos1 == '\t') - { - Pos1++; - } - - while (*Pos1) - { - *Pos2++ = *Pos1++; - } - *Pos2++ = 0; - - return; -} - -int GetRegDwordValue(HKEY Key, LPCSTR SubKey, LPCSTR ValueName, DWORD *pValue) -{ - HKEY hKey; - DWORD Type; - DWORD Size; - LSTATUS lRet; - DWORD Value; - - lRet = RegOpenKeyExA(Key, SubKey, 0, KEY_QUERY_VALUE, &hKey); - Log("RegOpenKeyExA <%s> Ret:%ld", SubKey, lRet); - - if (ERROR_SUCCESS == lRet) - { - Size = sizeof(Value); - lRet = RegQueryValueExA(hKey, ValueName, NULL, &Type, (LPBYTE)&Value, &Size); - Log("RegQueryValueExA <%s> ret:%u Size:%u Value:%u", ValueName, lRet, Size, Value); - - *pValue = Value; - RegCloseKey(hKey); - - return 0; - } - else - { - return 1; - } -} - -int GetPhysicalDriveCount(void) -{ - DWORD Value; - int Count = 0; - - if (GetRegDwordValue(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\disk\\Enum", "Count", &Value) == 0) - { - Count = (int)Value; - } - - Log("GetPhysicalDriveCount: %d", Count); - return Count; -} - - - +/****************************************************************************** + * Utility.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include "Ventoy2Disk.h" + +void Log(const char *Fmt, ...) +{ + va_list Arg; + int Len = 0; + FILE *File = NULL; + SYSTEMTIME Sys; + char szBuf[1024]; + + GetLocalTime(&Sys); + Len += safe_sprintf(szBuf, + "[%4d/%02d/%02d %02d:%02d:%02d.%03d] ", + Sys.wYear, Sys.wMonth, Sys.wDay, + Sys.wHour, Sys.wMinute, Sys.wSecond, + Sys.wMilliseconds); + + va_start(Arg, Fmt); + Len += vsnprintf_s(szBuf + Len, sizeof(szBuf)-Len, sizeof(szBuf)-Len, Fmt, Arg); + va_end(Arg); + + //printf("%s\n", szBuf); + +#if 1 + fopen_s(&File, VENTOY_FILE_LOG, "a+"); + if (File) + { + fwrite(szBuf, 1, Len, File); + fwrite("\n", 1, 1, File); + fclose(File); + } +#endif + +} + +BOOL IsPathExist(BOOL Dir, const char *Fmt, ...) +{ + va_list Arg; + HANDLE hFile; + DWORD Attr; + CHAR FilePath[MAX_PATH]; + + va_start(Arg, Fmt); + vsnprintf_s(FilePath, sizeof(FilePath), sizeof(FilePath), Fmt, Arg); + va_end(Arg); + + hFile = CreateFileA(FilePath, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + if (INVALID_HANDLE_VALUE == hFile) + { + return FALSE; + } + + CloseHandle(hFile); + + Attr = GetFileAttributesA(FilePath); + + if (Dir) + { + if ((Attr & FILE_ATTRIBUTE_DIRECTORY) == 0) + { + return FALSE; + } + } + else + { + if (Attr & FILE_ATTRIBUTE_DIRECTORY) + { + return FALSE; + } + } + + return TRUE; +} + + +int ReadWholeFileToBuf(const CHAR *FileName, int ExtLen, void **Bufer, int *BufLen) +{ + int FileSize; + FILE *File = NULL; + void *Data = NULL; + + fopen_s(&File, FileName, "rb"); + if (File == NULL) + { + Log("Failed to open file %s", FileName); + return 1; + } + + fseek(File, 0, SEEK_END); + FileSize = (int)ftell(File); + + Data = malloc(FileSize + ExtLen); + if (!Data) + { + fclose(File); + return 1; + } + + fseek(File, 0, SEEK_SET); + fread(Data, 1, FileSize, File); + + fclose(File); + + *Bufer = Data; + *BufLen = FileSize; + + return 0; +} + +const CHAR* GetLocalVentoyVersion(void) +{ + int rc; + int FileSize; + CHAR *Pos = NULL; + CHAR *Buf = NULL; + static CHAR LocalVersion[64] = { 0 }; + + if (LocalVersion[0] == 0) + { + rc = ReadWholeFileToBuf(VENTOY_FILE_VERSION, 1, (void **)&Buf, &FileSize); + if (rc) + { + return ""; + } + Buf[FileSize] = 0; + + for (Pos = Buf; *Pos; Pos++) + { + if (*Pos == '\r' || *Pos == '\n') + { + *Pos = 0; + break; + } + } + + safe_sprintf(LocalVersion, "%s", Buf); + free(Buf); + } + + return LocalVersion; +} + +const CHAR* ParseVentoyVersionFromString(CHAR *Buf) +{ + CHAR *Pos = NULL; + CHAR *End = NULL; + static CHAR LocalVersion[64] = { 0 }; + + Pos = strstr(Buf, "VENTOY_VERSION="); + if (Pos) + { + Pos += strlen("VENTOY_VERSION="); + if (*Pos == '"') + { + Pos++; + } + + End = Pos; + while (*End != 0 && *End != '"' && *End != '\r' && *End != '\n') + { + End++; + } + + *End = 0; + + safe_sprintf(LocalVersion, "%s", Pos); + return LocalVersion; + } + + return ""; +} + +BOOL IsWow64(void) +{ + typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL); + LPFN_ISWOW64PROCESS fnIsWow64Process; + BOOL bIsWow64 = FALSE; + + fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandleA("kernel32"), "IsWow64Process"); + if (NULL != fnIsWow64Process) + { + fnIsWow64Process(GetCurrentProcess(), &bIsWow64); + } + + return bIsWow64; +} + +void DumpWindowsVersion(void) +{ + int Bit; + BOOL WsVer; + DWORD Major, Minor; + ULONGLONG MajorEqual, MinorEqual; + OSVERSIONINFOEXA Ver1, Ver2; + const CHAR *Ver = NULL; + CHAR WinVer[256] = { 0 }; + + memset(&Ver1, 0, sizeof(Ver1)); + memset(&Ver2, 0, sizeof(Ver2)); + + Ver1.dwOSVersionInfoSize = sizeof(Ver1); + + // suppress the C4996 warning for GetVersionExA + #pragma warning(push) + #pragma warning(disable:4996) + if (!GetVersionExA((OSVERSIONINFOA *)&Ver1)) + { + memset(&Ver1, 0, sizeof(Ver1)); + Ver1.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + if (!GetVersionExA((OSVERSIONINFOA *)&Ver1)) + { + return; + } + } + #pragma warning(pop) + + if (Ver1.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + if (Ver1.dwMajorVersion > 6 || (Ver1.dwMajorVersion == 6 && Ver1.dwMinorVersion >= 2)) + { + // GetVersionEx() has problem on some Windows version + + MajorEqual = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL); + for (Major = Ver1.dwMajorVersion; Major <= 9; Major++) + { + memset(&Ver2, 0, sizeof(Ver2)); + Ver2.dwOSVersionInfoSize = sizeof(Ver2); + Ver2.dwMajorVersion = Major; + + if (!VerifyVersionInfoA(&Ver2, VER_MAJORVERSION, MajorEqual)) + { + continue; + } + + if (Ver1.dwMajorVersion < Major) + { + Ver1.dwMajorVersion = Major; + Ver1.dwMinorVersion = 0; + } + + MinorEqual = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL); + for (Minor = Ver1.dwMinorVersion; Minor <= 9; Minor++) + { + memset(&Ver2, 0, sizeof(Ver2)); + + Ver2.dwOSVersionInfoSize = sizeof(Ver2); + Ver2.dwMinorVersion = Minor; + + if (!VerifyVersionInfoA(&Ver2, VER_MINORVERSION, MinorEqual)) + { + continue; + } + + Ver1.dwMinorVersion = Minor; + break; + } + + break; + } + } + + if (Ver1.dwMajorVersion <= 0xF && Ver1.dwMinorVersion <= 0xF) + { + WsVer = (Ver1.wProductType <= VER_NT_WORKSTATION); + switch ((Ver1.dwMajorVersion << 4) | Ver2.dwMinorVersion) + { + case 0x51: + { + Ver = "XP"; + break; + } + case 0x52: + { + Ver = GetSystemMetrics(89) ? "Server 2003 R2" : "Server 2003"; + break; + } + case 0x60: + { + Ver = WsVer ? "Vista" : "Server 2008"; + break; + } + case 0x61: + { + Ver = WsVer ? "7" : "Server 2008 R2"; + break; + } + case 0x62: + { + Ver = WsVer ? "8" : "Server 2012"; + break; + } + case 0x63: + { + Ver = WsVer ? "8.1" : "Server 2012 R2"; + break; + } + case 0x64: + { + Ver = WsVer ? "10 (Preview 1)" : "Server 10 (Preview 1)"; + break; + } + case 0xA0: + { + Ver = WsVer ? "10" : ((Ver1.dwBuildNumber > 15000) ? "Server 2019" : "Server 2016"); + break; + } + default: + { + Ver = "10 or later"; + break; + } + } + } + } + + Bit = IsWow64() ? 64 : 32; + + if (Ver1.wServicePackMinor) + { + safe_sprintf(WinVer, "Windows %s SP%u.%u %d-bit", Ver, Ver1.wServicePackMajor, Ver1.wServicePackMinor, Bit); + } + else if (Ver1.wServicePackMajor) + { + safe_sprintf(WinVer, "Windows %s SP%u %d-bit", Ver, Ver1.wServicePackMajor, Bit); + } + else + { + safe_sprintf(WinVer, "Windows %s %d-bit", Ver, Bit); + } + + if (((Ver1.dwMajorVersion << 4) | Ver2.dwMinorVersion) >= 0x62) + { + Log("Windows Version : %s (Build %u)", WinVer, Ver1.dwBuildNumber); + } + else + { + Log("Windows Version : %s", WinVer); + } + + return; +} + +BOOL IsVentoyLogicalDrive(CHAR DriveLetter) +{ + int i; + CONST CHAR *Files[] = + { + "EFI\\BOOT\\BOOTX64.EFI", + "grub\\themes\\ventoy\\theme.txt", + "ventoy\\ventoy.cpio", + }; + + for (i = 0; i < sizeof(Files) / sizeof(Files[0]); i++) + { + if (!IsFileExist("%C:\\%s", DriveLetter, Files[i])) + { + return FALSE; + } + } + + return TRUE; +} + + +int VentoyFillLocation(UINT64 DiskSizeInBytes, UINT32 StartSectorId, UINT32 SectorCount, PART_TABLE *Table) +{ + BYTE Head; + BYTE Sector; + BYTE nSector = 63; + BYTE nHead = 8; + UINT32 Cylinder; + UINT32 EndSectorId; + + while (nHead != 0 && (DiskSizeInBytes / 512 / nSector / nHead) > 1024) + { + nHead = (BYTE)nHead * 2; + } + + if (nHead == 0) + { + nHead = 255; + } + + Cylinder = StartSectorId / nSector / nHead; + Head = StartSectorId / nSector % nHead; + Sector = StartSectorId % nSector + 1; + + Table->StartHead = Head; + Table->StartSector = Sector; + Table->StartCylinder = Cylinder; + + EndSectorId = StartSectorId + SectorCount - 1; + Cylinder = EndSectorId / nSector / nHead; + Head = EndSectorId / nSector % nHead; + Sector = EndSectorId % nSector + 1; + + Table->EndHead = Head; + Table->EndSector = Sector; + Table->EndCylinder = Cylinder; + + Table->StartSectorId = StartSectorId; + Table->SectorCount = SectorCount; + + return 0; +} + +int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR, int PartStyle) +{ + GUID Guid; + int ReservedValue; + UINT32 DiskSignature; + UINT32 DiskSectorCount; + UINT32 PartSectorCount; + UINT32 PartStartSector; + UINT32 ReservedSector; + + VentoyGetLocalBootImg(pMBR); + + CoCreateGuid(&Guid); + + memcpy(&DiskSignature, &Guid, sizeof(UINT32)); + + Log("Disk signature: 0x%08x", DiskSignature); + + *((UINT32 *)(pMBR->BootCode + 0x1B8)) = DiskSignature; + + if (DiskSizeBytes / 512 > 0xFFFFFFFF) + { + DiskSectorCount = 0xFFFFFFFF; + } + else + { + DiskSectorCount = (UINT32)(DiskSizeBytes / 512); + } + + ReservedValue = GetReservedSpaceInMB(); + if (ReservedValue <= 0) + { + ReservedSector = 0; + } + else + { + ReservedSector = (UINT32)(ReservedValue * 2048); + } + + if (PartStyle) + { + ReservedSector += 33; // backup GPT part table + } + + Log("ReservedSector: %u", ReservedSector); + + //Part1 + PartStartSector = VENTOY_PART1_START_SECTOR; + PartSectorCount = DiskSectorCount - ReservedSector - VENTOY_EFI_PART_SIZE / 512 - PartStartSector; + VentoyFillLocation(DiskSizeBytes, PartStartSector, PartSectorCount, pMBR->PartTbl); + + pMBR->PartTbl[0].Active = 0x80; // bootable + pMBR->PartTbl[0].FsFlag = 0x07; // exFAT/NTFS/HPFS + + //Part2 + PartStartSector += PartSectorCount; + PartSectorCount = VENTOY_EFI_PART_SIZE / 512; + VentoyFillLocation(DiskSizeBytes, PartStartSector, PartSectorCount, pMBR->PartTbl + 1); + + pMBR->PartTbl[1].Active = 0x00; + pMBR->PartTbl[1].FsFlag = 0xEF; // EFI System Partition + + pMBR->Byte55 = 0x55; + pMBR->ByteAA = 0xAA; + + return 0; +} + + +static int VentoyFillProtectMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR) +{ + GUID Guid; + UINT32 DiskSignature; + UINT64 DiskSectorCount; + + VentoyGetLocalBootImg(pMBR); + + CoCreateGuid(&Guid); + + memcpy(&DiskSignature, &Guid, sizeof(UINT32)); + + Log("Disk signature: 0x%08x", DiskSignature); + + *((UINT32 *)(pMBR->BootCode + 0x1B8)) = DiskSignature; + + DiskSectorCount = DiskSizeBytes / 512 - 1; + if (DiskSectorCount > 0xFFFFFFFF) + { + DiskSectorCount = 0xFFFFFFFF; + } + + memset(pMBR->PartTbl, 0, sizeof(pMBR->PartTbl)); + + pMBR->PartTbl[0].Active = 0x00; + pMBR->PartTbl[0].FsFlag = 0xee; // EE + + pMBR->PartTbl[0].StartHead = 0; + pMBR->PartTbl[0].StartSector = 1; + pMBR->PartTbl[0].StartCylinder = 0; + pMBR->PartTbl[0].EndHead = 254; + pMBR->PartTbl[0].EndSector = 63; + pMBR->PartTbl[0].EndCylinder = 1023; + + pMBR->PartTbl[0].StartSectorId = 1; + pMBR->PartTbl[0].SectorCount = (UINT32)DiskSectorCount; + + pMBR->Byte55 = 0x55; + pMBR->ByteAA = 0xAA; + + pMBR->BootCode[92] = 0x22; + + return 0; +} + + +int VentoyFillGpt(UINT64 DiskSizeBytes, VTOY_GPT_INFO *pInfo) +{ + INT64 ReservedValue = 0; + UINT64 ReservedSector = 33; + UINT64 Part1SectorCount = 0; + UINT64 DiskSectorCount = DiskSizeBytes / 512; + VTOY_GPT_HDR *Head = &pInfo->Head; + VTOY_GPT_PART_TBL *Table = pInfo->PartTbl; + static GUID WindowsDataPartType = { 0xebd0a0a2, 0xb9e5, 0x4433, { 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } }; + static GUID EspPartType = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } }; + static GUID BiosGrubPartType = { 0x21686148, 0x6449, 0x6e6f, { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } }; + + VentoyFillProtectMBR(DiskSizeBytes, &pInfo->MBR); + + ReservedValue = GetReservedSpaceInMB(); + if (ReservedValue > 0) + { + ReservedSector += ReservedValue * 2048; + } + + Part1SectorCount = DiskSectorCount - ReservedSector - (VENTOY_EFI_PART_SIZE / 512) - 2048; + + memcpy(Head->Signature, "EFI PART", 8); + Head->Version[2] = 0x01; + Head->Length = 92; + Head->Crc = 0; + Head->EfiStartLBA = 1; + Head->EfiBackupLBA = DiskSectorCount - 1; + Head->PartAreaStartLBA = 34; + Head->PartAreaEndLBA = DiskSectorCount - 34; + CoCreateGuid(&Head->DiskGuid); + Head->PartTblStartLBA = 2; + Head->PartTblTotNum = 128; + Head->PartTblEntryLen = 128; + + + memcpy(&(Table[0].PartType), &WindowsDataPartType, sizeof(GUID)); + CoCreateGuid(&(Table[0].PartGuid)); + Table[0].StartLBA = 2048; + Table[0].LastLBA = 2048 + Part1SectorCount - 1; + Table[0].Attr = 0; + memcpy(Table[0].Name, L"Ventoy", 6 * 2); + + // to fix windows issue + //memcpy(&(Table[1].PartType), &EspPartType, sizeof(GUID)); + memcpy(&(Table[1].PartType), &WindowsDataPartType, sizeof(GUID)); + CoCreateGuid(&(Table[1].PartGuid)); + Table[1].StartLBA = Table[0].LastLBA + 1; + Table[1].LastLBA = Table[1].StartLBA + VENTOY_EFI_PART_SIZE / 512 - 1; + Table[1].Attr = 0x8000000000000001ULL; + memcpy(Table[1].Name, L"VTOYEFI", 7 * 2); + +#if 0 + memcpy(&(Table[2].PartType), &BiosGrubPartType, sizeof(GUID)); + CoCreateGuid(&(Table[2].PartGuid)); + Table[2].StartLBA = 34; + Table[2].LastLBA = 2047; + Table[2].Attr = 0; +#endif + + //Update CRC + Head->PartTblCrc = VentoyCrc32(Table, sizeof(pInfo->PartTbl)); + Head->Crc = VentoyCrc32(Head, Head->Length); + + return 0; +} + +int VentoyFillBackupGptHead(VTOY_GPT_INFO *pInfo, VTOY_GPT_HDR *pHead) +{ + UINT64 LBA; + UINT64 BackupLBA; + + memcpy(pHead, &pInfo->Head, sizeof(VTOY_GPT_HDR)); + + LBA = pHead->EfiStartLBA; + BackupLBA = pHead->EfiBackupLBA; + + pHead->EfiStartLBA = BackupLBA; + pHead->EfiBackupLBA = LBA; + pHead->PartTblStartLBA = BackupLBA + 1 - 33; + + pHead->Crc = 0; + pHead->Crc = VentoyCrc32(pHead, pHead->Length); + + return 0; +} + +CHAR GetFirstUnusedDriveLetter(void) +{ + CHAR Letter = 'D'; + DWORD Drives = GetLogicalDrives(); + + Drives >>= 3; + while (Drives & 0x1) + { + Letter++; + Drives >>= 1; + } + + return Letter; +} + +const CHAR * GetBusTypeString(STORAGE_BUS_TYPE Type) +{ + switch (Type) + { + case BusTypeUnknown: return "unknown"; + case BusTypeScsi: return "SCSI"; + case BusTypeAtapi: return "Atapi"; + case BusTypeAta: return "ATA"; + case BusType1394: return "1394"; + case BusTypeSsa: return "SSA"; + case BusTypeFibre: return "Fibre"; + case BusTypeUsb: return "USB"; + case BusTypeRAID: return "RAID"; + case BusTypeiScsi: return "iSCSI"; + case BusTypeSas: return "SAS"; + case BusTypeSata: return "SATA"; + case BusTypeSd: return "SD"; + case BusTypeMmc: return "MMC"; + case BusTypeVirtual: return "Virtual"; + case BusTypeFileBackedVirtual: return "FileBackedVirtual"; + case BusTypeSpaces: return "Spaces"; + case BusTypeNvme: return "Nvme"; + } + return "unknown"; +} + +int VentoyGetLocalBootImg(MBR_HEAD *pMBR) +{ + int Len = 0; + BYTE *ImgBuf = NULL; + static int Loaded = 0; + static MBR_HEAD MBR; + + if (Loaded) + { + memcpy(pMBR, &MBR, 512); + return 0; + } + + if (0 == ReadWholeFileToBuf(VENTOY_FILE_BOOT_IMG, 0, (void **)&ImgBuf, &Len)) + { + Log("Copy boot img success"); + memcpy(pMBR, ImgBuf, 512); + free(ImgBuf); + + CoCreateGuid((GUID *)(pMBR->BootCode + 0x180)); + + memcpy(&MBR, pMBR, 512); + Loaded = 1; + + return 0; + } + else + { + Log("Copy boot img failed"); + return 1; + } +} + +int GetHumanReadableGBSize(UINT64 SizeBytes) +{ + int i; + int Pow2 = 1; + double Delta; + double GB = SizeBytes * 1.0 / 1000 / 1000 / 1000; + + for (i = 0; i < 12; i++) + { + if (Pow2 > GB) + { + Delta = (Pow2 - GB) / Pow2; + } + else + { + Delta = (GB - Pow2) / Pow2; + } + + if (Delta < 0.05) + { + return Pow2; + } + + Pow2 <<= 1; + } + + return (int)GB; +} + +void TrimString(CHAR *String) +{ + CHAR *Pos1 = String; + CHAR *Pos2 = String; + size_t Len = strlen(String); + + while (Len > 0) + { + if (String[Len - 1] != ' ' && String[Len - 1] != '\t') + { + break; + } + String[Len - 1] = 0; + Len--; + } + + while (*Pos1 == ' ' || *Pos1 == '\t') + { + Pos1++; + } + + while (*Pos1) + { + *Pos2++ = *Pos1++; + } + *Pos2++ = 0; + + return; +} + +int GetRegDwordValue(HKEY Key, LPCSTR SubKey, LPCSTR ValueName, DWORD *pValue) +{ + HKEY hKey; + DWORD Type; + DWORD Size; + LSTATUS lRet; + DWORD Value; + + lRet = RegOpenKeyExA(Key, SubKey, 0, KEY_QUERY_VALUE, &hKey); + Log("RegOpenKeyExA <%s> Ret:%ld", SubKey, lRet); + + if (ERROR_SUCCESS == lRet) + { + Size = sizeof(Value); + lRet = RegQueryValueExA(hKey, ValueName, NULL, &Type, (LPBYTE)&Value, &Size); + Log("RegQueryValueExA <%s> ret:%u Size:%u Value:%u", ValueName, lRet, Size, Value); + + *pValue = Value; + RegCloseKey(hKey); + + return 0; + } + else + { + return 1; + } +} + +int GetPhysicalDriveCount(void) +{ + DWORD Value; + int Count = 0; + + if (GetRegDwordValue(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\disk\\Enum", "Count", &Value) == 0) + { + Count = (int)Value; + } + + Log("GetPhysicalDriveCount: %d", Count); + return Count; +} + + + diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c index f0ea679b..557bdfc1 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c @@ -1,300 +1,345 @@ -/****************************************************************************** - * Ventoy2Disk.c - * - * Copyright (c) 2020, longpanda - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - */ - -#include -#include "resource.h" -#include "Language.h" -#include "Ventoy2Disk.h" - -PHY_DRIVE_INFO *g_PhyDriveList = NULL; -DWORD g_PhyDriveCount = 0; -static int g_FilterRemovable = 0; -static int g_FilterUSB = 1; -int g_ForceOperation = 1; - -int ParseCmdLineOption(LPSTR lpCmdLine) -{ - int i; - char cfgfile[MAX_PATH]; - - if (lpCmdLine && lpCmdLine[0]) - { - Log("CmdLine:<%s>", lpCmdLine); - } - - for (i = 0; i < __argc; i++) - { - if (strncmp(__argv[i], "-U", 2) == 0 || - strncmp(__argv[i], "-u", 2) == 0) - { - g_FilterUSB = 0; - } - else if (strncmp(__argv[i], "-F", 2) == 0) - { - g_ForceOperation = 1; - } - } - - GetCurrentDirectoryA(sizeof(cfgfile), cfgfile); - strcat_s(cfgfile, sizeof(cfgfile), "\\Ventoy2Disk.ini"); - - if (0 == GetPrivateProfileIntA("Filter", "USB", 1, cfgfile)) - { - g_FilterUSB = 0; - } - - if (1 == GetPrivateProfileIntA("Operation", "Force", 0, cfgfile)) - { - g_ForceOperation = 1; - } - - Log("Control Flag: %d %d %d", g_FilterRemovable, g_FilterUSB, g_ForceOperation); - - return 0; -} - -static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR) -{ - int i; - BOOL bRet; - DWORD dwSize; - HANDLE hDrive; - MBR_HEAD MBR; - UINT32 PartStartSector; - UINT32 PartSectorCount; - CHAR PhyDrivePath[128]; - - safe_sprintf(PhyDrivePath, "\\\\.\\PhysicalDrive%d", PhyDrive); - hDrive = CreateFileA(PhyDrivePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - Log("Create file Handle:%p %s status:%u", hDrive, PhyDrivePath, LASTERR); - - if (hDrive == INVALID_HANDLE_VALUE) - { - return FALSE; - } - - bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL); - CHECK_CLOSE_HANDLE(hDrive); - - Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR); - - if ((!bRet) || (dwSize != sizeof(MBR))) - { - return FALSE; - } - - if (MBR.Byte55 != 0x55 || MBR.ByteAA != 0xAA) - { - Log("Byte55 ByteAA not match 0x%x 0x%x", MBR.Byte55, MBR.ByteAA); - return FALSE; - } - - for (i = 0; i < 4; i++) - { - Log("=========== Partition Table %d ============", i + 1); - Log("PartTbl.Active = 0x%x", MBR.PartTbl[i].Active); - Log("PartTbl.FsFlag = 0x%x", MBR.PartTbl[i].FsFlag); - Log("PartTbl.StartSectorId = %u", MBR.PartTbl[i].StartSectorId); - Log("PartTbl.SectorCount = %u", MBR.PartTbl[i].SectorCount); - Log("PartTbl.StartHead = %u", MBR.PartTbl[i].StartHead); - Log("PartTbl.StartSector = %u", MBR.PartTbl[i].StartSector); - Log("PartTbl.StartCylinder = %u", MBR.PartTbl[i].StartCylinder); - Log("PartTbl.EndHead = %u", MBR.PartTbl[i].EndHead); - Log("PartTbl.EndSector = %u", MBR.PartTbl[i].EndSector); - Log("PartTbl.EndCylinder = %u", MBR.PartTbl[i].EndCylinder); - } - - - if (MBR.PartTbl[0].StartSectorId != 2048) - { - Log("Part1 not match %u", MBR.PartTbl[0].StartSectorId); - return FALSE; - } - - PartStartSector = MBR.PartTbl[0].StartSectorId + MBR.PartTbl[0].SectorCount; - PartSectorCount = VENTOY_EFI_PART_SIZE / 512; - - if (MBR.PartTbl[1].FsFlag != 0xEF || - MBR.PartTbl[1].StartSectorId != PartStartSector || - MBR.PartTbl[1].SectorCount != PartSectorCount) - { - Log("Part2 not match [0x%x 0x%x] [%u %u] [%u %u]", - MBR.PartTbl[1].FsFlag, 0xEF, - MBR.PartTbl[1].StartSectorId, PartStartSector, - MBR.PartTbl[1].SectorCount, PartSectorCount); - return FALSE; - } - - if (MBR.PartTbl[0].Active != 0x80 && MBR.PartTbl[1].Active != 0x80) - { - Log("Part1 and Part2 are both NOT active 0x%x 0x%x", MBR.PartTbl[0].Active, MBR.PartTbl[1].Active); - return FALSE; - } - - memcpy(pMBR, &MBR, sizeof(MBR_HEAD)); - Log("PhysicalDrive%d is ventoy disk", PhyDrive); - return TRUE; -} - - -static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount) -{ - DWORD i; - DWORD LogDrive; - int Letter = 'A'; - int Id = 0; - int LetterCount = 0; - PHY_DRIVE_INFO *CurDrive; - MBR_HEAD MBR; - int LogLetter[VENTOY_MAX_PHY_DRIVE]; - int PhyDriveId[VENTOY_MAX_PHY_DRIVE]; - - for (LogDrive = GetLogicalDrives(); LogDrive > 0; LogDrive >>= 1) - { - if (LogDrive & 0x01) - { - LogLetter[LetterCount] = Letter; - PhyDriveId[LetterCount] = GetPhyDriveByLogicalDrive(Letter); - - Log("Logical Drive:%C ===> PhyDrive:%d", LogLetter[LetterCount], PhyDriveId[LetterCount]); - LetterCount++; - } - - Letter++; - } - - for (i = 0; i < DriveCount; i++) - { - CurDrive = pDriveList + i; - - CurDrive->Id = -1; - CurDrive->FirstDriveLetter = -1; - - // Too big for MBR - if (CurDrive->SizeInBytes > 2199023255552ULL) - { - Log("<%s %s> is filtered for too big for MBR.", CurDrive->VendorId, CurDrive->ProductId); - continue; - } - - if (g_FilterRemovable && (!CurDrive->RemovableMedia)) - { - Log("<%s %s> is filtered for not removable.", CurDrive->VendorId, CurDrive->ProductId); - continue; - } - - if (g_FilterUSB && CurDrive->BusType != BusTypeUsb) - { - Log("<%s %s> is filtered for not USB type.", CurDrive->VendorId, CurDrive->ProductId); - continue; - } - - CurDrive->Id = Id++; - - for (Letter = 0; Letter < LetterCount; Letter++) - { - if (PhyDriveId[Letter] == CurDrive->PhyDrive) - { - CurDrive->FirstDriveLetter = LogLetter[Letter]; - break; - } - } - - if (IsVentoyPhyDrive(CurDrive->PhyDrive, CurDrive->SizeInBytes, &MBR)) - { - GetVentoyVerInPhyDrive(CurDrive, &MBR, CurDrive->VentoyVersion, sizeof(CurDrive->VentoyVersion)); - } - } - - // for safe - for (i = 0; i < DriveCount; i++) - { - CurDrive = pDriveList + i; - if (CurDrive->Id < 0) - { - CurDrive->PhyDrive = 0x00FFFFFF; - } - } - - return Id; -} - -PHY_DRIVE_INFO * GetPhyDriveInfoById(int Id) -{ - DWORD i; - for (i = 0; i < g_PhyDriveCount; i++) - { - if (g_PhyDriveList[i].Id >= 0 && g_PhyDriveList[i].Id == Id) - { - return g_PhyDriveList + i; - } - } - - return NULL; -} - -int SortPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount) -{ - DWORD i, j; - PHY_DRIVE_INFO TmpDriveInfo; - - for (i = 0; i < DriveCount; i++) - { - for (j = i + 1; j < DriveCount; j++) - { - if (pDriveList[i].BusType == BusTypeUsb && pDriveList[j].BusType == BusTypeUsb) - { - if (pDriveList[i].RemovableMedia == FALSE && pDriveList[j].RemovableMedia == TRUE) - { - memcpy(&TmpDriveInfo, pDriveList + i, sizeof(PHY_DRIVE_INFO)); - memcpy(pDriveList + i, pDriveList + j, sizeof(PHY_DRIVE_INFO)); - memcpy(pDriveList + j, &TmpDriveInfo, sizeof(PHY_DRIVE_INFO)); - } - } - } - } - - return 0; -} - -int Ventoy2DiskInit(void) -{ - g_PhyDriveList = (PHY_DRIVE_INFO *)malloc(sizeof(PHY_DRIVE_INFO)* VENTOY_MAX_PHY_DRIVE); - if (NULL == g_PhyDriveList) - { - Log("Failed to alloc phy drive memory"); - return FALSE; - } - memset(g_PhyDriveList, 0, sizeof(PHY_DRIVE_INFO)* VENTOY_MAX_PHY_DRIVE); - - GetAllPhysicalDriveInfo(g_PhyDriveList, &g_PhyDriveCount); - - SortPhysicalDrive(g_PhyDriveList, g_PhyDriveCount); - - FilterPhysicalDrive(g_PhyDriveList, g_PhyDriveCount); - - return 0; -} - -int Ventoy2DiskDestroy(void) -{ - free(g_PhyDriveList); - return 0; -} +/****************************************************************************** + * Ventoy2Disk.c + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include "resource.h" +#include "Language.h" +#include "Ventoy2Disk.h" + +PHY_DRIVE_INFO *g_PhyDriveList = NULL; +DWORD g_PhyDriveCount = 0; +static int g_FilterRemovable = 0; +static int g_FilterUSB = 1; +int g_ForceOperation = 1; + +int ParseCmdLineOption(LPSTR lpCmdLine) +{ + int i; + char cfgfile[MAX_PATH]; + + if (lpCmdLine && lpCmdLine[0]) + { + Log("CmdLine:<%s>", lpCmdLine); + } + + for (i = 0; i < __argc; i++) + { + if (strncmp(__argv[i], "-U", 2) == 0 || + strncmp(__argv[i], "-u", 2) == 0) + { + g_FilterUSB = 0; + } + else if (strncmp(__argv[i], "-F", 2) == 0) + { + g_ForceOperation = 1; + } + } + + GetCurrentDirectoryA(sizeof(cfgfile), cfgfile); + strcat_s(cfgfile, sizeof(cfgfile), "\\Ventoy2Disk.ini"); + + if (0 == GetPrivateProfileIntA("Filter", "USB", 1, cfgfile)) + { + g_FilterUSB = 0; + } + + if (1 == GetPrivateProfileIntA("Operation", "Force", 0, cfgfile)) + { + g_ForceOperation = 1; + } + + Log("Control Flag: %d %d %d", g_FilterRemovable, g_FilterUSB, g_ForceOperation); + + return 0; +} + +static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UINT64 *Part2StartSector) +{ + int i; + BOOL bRet; + DWORD dwSize; + HANDLE hDrive; + MBR_HEAD MBR; + UINT32 PartStartSector; + UINT32 PartSectorCount; + CHAR PhyDrivePath[128]; + VTOY_GPT_INFO *pGpt = NULL; + + safe_sprintf(PhyDrivePath, "\\\\.\\PhysicalDrive%d", PhyDrive); + hDrive = CreateFileA(PhyDrivePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + Log("Create file Handle:%p %s status:%u", hDrive, PhyDrivePath, LASTERR); + + if (hDrive == INVALID_HANDLE_VALUE) + { + return FALSE; + } + + bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL); + Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR); + + if ((!bRet) || (dwSize != sizeof(MBR))) + { + CHECK_CLOSE_HANDLE(hDrive); + return FALSE; + } + + if (MBR.Byte55 != 0x55 || MBR.ByteAA != 0xAA) + { + Log("Byte55 ByteAA not match 0x%x 0x%x", MBR.Byte55, MBR.ByteAA); + CHECK_CLOSE_HANDLE(hDrive); + return FALSE; + } + + for (i = 0; i < 4; i++) + { + Log("=========== Partition Table %d ============", i + 1); + Log("PartTbl.Active = 0x%x", MBR.PartTbl[i].Active); + Log("PartTbl.FsFlag = 0x%x", MBR.PartTbl[i].FsFlag); + Log("PartTbl.StartSectorId = %u", MBR.PartTbl[i].StartSectorId); + Log("PartTbl.SectorCount = %u", MBR.PartTbl[i].SectorCount); + Log("PartTbl.StartHead = %u", MBR.PartTbl[i].StartHead); + Log("PartTbl.StartSector = %u", MBR.PartTbl[i].StartSector); + Log("PartTbl.StartCylinder = %u", MBR.PartTbl[i].StartCylinder); + Log("PartTbl.EndHead = %u", MBR.PartTbl[i].EndHead); + Log("PartTbl.EndSector = %u", MBR.PartTbl[i].EndSector); + Log("PartTbl.EndCylinder = %u", MBR.PartTbl[i].EndCylinder); + } + + if (MBR.PartTbl[0].FsFlag == 0xEE) + { + pGpt = malloc(sizeof(VTOY_GPT_INFO)); + if (!pGpt) + { + CHECK_CLOSE_HANDLE(hDrive); + return FALSE; + } + + SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); + bRet = ReadFile(hDrive, pGpt, sizeof(VTOY_GPT_INFO), &dwSize, NULL); + CHECK_CLOSE_HANDLE(hDrive); + if ((!bRet) || (dwSize != sizeof(VTOY_GPT_INFO))) + { + Log("Failed to read gpt info %d %u %d", bRet, dwSize, LASTERR); + return FALSE; + } + + if (memcmp(pGpt->Head.Signature, "EFI PART", 8)) + { + Log("Invalid GPT signature"); + return FALSE; + } + + if (memcmp(pGpt->PartTbl[1].Name, L"VTOYEFI", 7 * 2)) + { + Log("Invalid ventoy efi part name"); + return FALSE; + } + + *Part2StartSector = pGpt->PartTbl[1].StartLBA; + } + else + { + CHECK_CLOSE_HANDLE(hDrive); + + if (MBR.PartTbl[0].StartSectorId != 2048) + { + Log("Part1 not match %u", MBR.PartTbl[0].StartSectorId); + return FALSE; + } + + PartStartSector = MBR.PartTbl[0].StartSectorId + MBR.PartTbl[0].SectorCount; + PartSectorCount = VENTOY_EFI_PART_SIZE / 512; + + if (MBR.PartTbl[1].StartSectorId != PartStartSector || + MBR.PartTbl[1].SectorCount != PartSectorCount) + { + Log("Part2 not match [0x%x 0x%x] [%u %u] [%u %u]", + MBR.PartTbl[1].FsFlag, 0xEF, + MBR.PartTbl[1].StartSectorId, PartStartSector, + MBR.PartTbl[1].SectorCount, PartSectorCount); + return FALSE; + } + + if (MBR.PartTbl[0].Active != 0x80 && MBR.PartTbl[1].Active != 0x80) + { + Log("Part1 and Part2 are both NOT active 0x%x 0x%x", MBR.PartTbl[0].Active, MBR.PartTbl[1].Active); + return FALSE; + } + + *Part2StartSector = MBR.PartTbl[1].StartSectorId; + } + + memcpy(pMBR, &MBR, sizeof(MBR_HEAD)); + Log("PhysicalDrive%d is ventoy disk", PhyDrive); + return TRUE; +} + + +static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount) +{ + DWORD i; + DWORD LogDrive; + int Count = 0; + int Letter = 'A'; + int Id = 0; + int LetterCount = 0; + UINT64 Part2StartSector = 0; + PHY_DRIVE_INFO *CurDrive; + MBR_HEAD MBR; + int LogLetter[VENTOY_MAX_PHY_DRIVE]; + int PhyDriveId[VENTOY_MAX_PHY_DRIVE]; + + for (LogDrive = GetLogicalDrives(); LogDrive > 0; LogDrive >>= 1) + { + if (LogDrive & 0x01) + { + LogLetter[LetterCount] = Letter; + PhyDriveId[LetterCount] = GetPhyDriveByLogicalDrive(Letter); + + Log("Logical Drive:%C ===> PhyDrive:%d", LogLetter[LetterCount], PhyDriveId[LetterCount]); + LetterCount++; + } + + Letter++; + } + + for (i = 0; i < DriveCount; i++) + { + CurDrive = pDriveList + i; + + CurDrive->Id = -1; + memset(CurDrive->DriveLetters, 0, sizeof(CurDrive->DriveLetters)); + + // Too big for MBR + if (CurDrive->SizeInBytes > 2199023255552ULL) + { + Log("<%s %s> is filtered for too big for MBR.", CurDrive->VendorId, CurDrive->ProductId); + continue; + } + + if (g_FilterRemovable && (!CurDrive->RemovableMedia)) + { + Log("<%s %s> is filtered for not removable.", CurDrive->VendorId, CurDrive->ProductId); + continue; + } + + if (g_FilterUSB && CurDrive->BusType != BusTypeUsb) + { + Log("<%s %s> is filtered for not USB type.", CurDrive->VendorId, CurDrive->ProductId); + continue; + } + + CurDrive->Id = Id++; + + for (Count = 0, Letter = 0; Letter < LetterCount; Letter++) + { + if (PhyDriveId[Letter] == CurDrive->PhyDrive) + { + if (Count + 1 < sizeof(CurDrive->DriveLetters) / sizeof(CHAR)) + { + CurDrive->DriveLetters[Count] = LogLetter[Letter]; + } + Count++; + } + } + + if (IsVentoyPhyDrive(CurDrive->PhyDrive, CurDrive->SizeInBytes, &MBR, &Part2StartSector)) + { + CurDrive->PartStyle = (MBR.PartTbl[0].FsFlag == 0xEE) ? 1 : 0; + GetVentoyVerInPhyDrive(CurDrive, Part2StartSector, CurDrive->VentoyVersion, sizeof(CurDrive->VentoyVersion)); + } + } + + // for safe + for (i = 0; i < DriveCount; i++) + { + CurDrive = pDriveList + i; + if (CurDrive->Id < 0) + { + CurDrive->PhyDrive = 0x00FFFFFF; + } + } + + return Id; +} + +PHY_DRIVE_INFO * GetPhyDriveInfoById(int Id) +{ + DWORD i; + for (i = 0; i < g_PhyDriveCount; i++) + { + if (g_PhyDriveList[i].Id >= 0 && g_PhyDriveList[i].Id == Id) + { + return g_PhyDriveList + i; + } + } + + return NULL; +} + +int SortPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount) +{ + DWORD i, j; + PHY_DRIVE_INFO TmpDriveInfo; + + for (i = 0; i < DriveCount; i++) + { + for (j = i + 1; j < DriveCount; j++) + { + if (pDriveList[i].BusType == BusTypeUsb && pDriveList[j].BusType == BusTypeUsb) + { + if (pDriveList[i].RemovableMedia == FALSE && pDriveList[j].RemovableMedia == TRUE) + { + memcpy(&TmpDriveInfo, pDriveList + i, sizeof(PHY_DRIVE_INFO)); + memcpy(pDriveList + i, pDriveList + j, sizeof(PHY_DRIVE_INFO)); + memcpy(pDriveList + j, &TmpDriveInfo, sizeof(PHY_DRIVE_INFO)); + } + } + } + } + + return 0; +} + +int Ventoy2DiskInit(void) +{ + Log("\n===================== Enum All PhyDrives ====================="); + g_PhyDriveList = (PHY_DRIVE_INFO *)malloc(sizeof(PHY_DRIVE_INFO)* VENTOY_MAX_PHY_DRIVE); + if (NULL == g_PhyDriveList) + { + Log("Failed to alloc phy drive memory"); + return FALSE; + } + memset(g_PhyDriveList, 0, sizeof(PHY_DRIVE_INFO)* VENTOY_MAX_PHY_DRIVE); + + GetAllPhysicalDriveInfo(g_PhyDriveList, &g_PhyDriveCount); + + SortPhysicalDrive(g_PhyDriveList, g_PhyDriveCount); + + FilterPhysicalDrive(g_PhyDriveList, g_PhyDriveCount); + + return 0; +} + +int Ventoy2DiskDestroy(void) +{ + free(g_PhyDriveList); + return 0; +} diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h index 26352ddf..61566bf8 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h @@ -1,165 +1,217 @@ -/****************************************************************************** - * Ventoy2Disk.h - * - * Copyright (c) 2020, longpanda - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - */ - -#ifndef __VENTOY2DISK_H__ -#define __VENTOY2DISK_H__ - -#include - -#define SIZE_1MB (1024 * 1024) -#define VENTOY_EFI_PART_SIZE (32 * SIZE_1MB) -#define VENTOY_PART1_START_SECTOR 2048 - -#define VENTOY_FILE_BOOT_IMG "boot\\boot.img" -#define VENTOY_FILE_STG1_IMG "boot\\core.img.xz" -#define VENTOY_FILE_DISK_IMG "ventoy\\ventoy.disk.img.xz" -#define VENTOY_FILE_LOG "log.txt" -#define VENTOY_FILE_VERSION "ventoy\\version" - -#define DRIVE_ACCESS_TIMEOUT 15000 // How long we should retry drive access (in ms) -#define DRIVE_ACCESS_RETRIES 150 // How many times we should retry - -#define IsFileExist(Fmt, ...) IsPathExist(FALSE, Fmt, __VA_ARGS__) -#define IsDirExist(Fmt, ...) IsPathExist(TRUE, Fmt, __VA_ARGS__) - -#define safe_sprintf(dst, fmt, ...) sprintf_s(dst, sizeof(dst), fmt, __VA_ARGS__) -#define safe_strcpy(dst, src) strcpy_s(dst, sizeof(dst), src) - -#define CHECK_CLOSE_HANDLE(Handle) \ -{\ - if (Handle != INVALID_HANDLE_VALUE) \ - {\ - CloseHandle(Handle); \ - Handle = INVALID_HANDLE_VALUE; \ - }\ -} - -#define LASTERR GetLastError() - -#pragma pack(1) -typedef struct PART_TABLE -{ - UINT8 Active; // 0x00 0x80 - - UINT8 StartHead; - UINT16 StartSector : 6; - UINT16 StartCylinder : 10; - - UINT8 FsFlag; - - UINT8 EndHead; - UINT16 EndSector : 6; - UINT16 EndCylinder : 10; - - UINT32 StartSectorId; - UINT32 SectorCount; -}PART_TABLE; - -typedef struct MBR_HEAD -{ - UINT8 BootCode[446]; - PART_TABLE PartTbl[4]; - UINT8 Byte55; - UINT8 ByteAA; -}MBR_HEAD; -#pragma pack() - -#define VENTOY_MAX_PHY_DRIVE 128 - -typedef struct PHY_DRIVE_INFO -{ - int Id; - int PhyDrive; - UINT64 SizeInBytes; - BYTE DeviceType; - BOOL RemovableMedia; - CHAR VendorId[128]; - CHAR ProductId[128]; - CHAR ProductRev[128]; - CHAR SerialNumber[128]; - STORAGE_BUS_TYPE BusType; - - int FirstDriveLetter; - CHAR VentoyVersion[32]; - -}PHY_DRIVE_INFO; - -typedef enum PROGRESS_POINT -{ - PT_START = 0, - PT_LOCK_FOR_CLEAN, - PT_DEL_ALL_PART, - PT_LOCK_FOR_WRITE, - PT_FORMAT_PART1, - PT_LOCK_VOLUME = PT_FORMAT_PART1, - PT_FORMAT_PART2, - - PT_WRITE_VENTOY_START, - PT_WRITE_VENTOY_FINISH = PT_WRITE_VENTOY_START + 32, - - PT_WRITE_STG1_IMG, - PT_WRITE_PART_TABLE, - PT_MOUNT_VOLUME, - - PT_FINISH -}PROGRESS_POINT; - -#define PROGRESS_BAR_SET_POS(pos) SetProgressBarPos(pos) - -extern PHY_DRIVE_INFO *g_PhyDriveList; -extern DWORD g_PhyDriveCount; -extern int g_ForceOperation; -extern HWND g_ProgressBarHwnd; - -void Log(const char *Fmt, ...); -BOOL IsPathExist(BOOL Dir, const char *Fmt, ...); -void DumpWindowsVersion(void); -const CHAR* GetLocalVentoyVersion(void); -const CHAR* ParseVentoyVersionFromString(CHAR *Buf); -CHAR GetFirstUnusedDriveLetter(void); -const CHAR * GetBusTypeString(STORAGE_BUS_TYPE Type); -int VentoyGetLocalBootImg(MBR_HEAD *pMBR); -int GetHumanReadableGBSize(UINT64 SizeBytes); -void TrimString(CHAR *String); -int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR); -BOOL IsVentoyLogicalDrive(CHAR DriveLetter); -int GetRegDwordValue(HKEY Key, LPCSTR SubKey, LPCSTR ValueName, DWORD *pValue); -int GetPhysicalDriveCount(void); -int GetAllPhysicalDriveInfo(PHY_DRIVE_INFO *pDriveList, DWORD *pDriveCount); -int GetPhyDriveByLogicalDrive(int DriveLetter); -int GetVentoyVerInPhyDrive(const PHY_DRIVE_INFO *pDriveInfo, MBR_HEAD *pMBR, CHAR *VerBuf, size_t BufLen); -int Ventoy2DiskInit(void); -int Ventoy2DiskDestroy(void); -PHY_DRIVE_INFO * GetPhyDriveInfoById(int Id); -int ParseCmdLineOption(LPSTR lpCmdLine); -int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive); -int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive); -void SetProgressBarPos(int Pos); -int ReadWholeFileToBuf(const CHAR *FileName, int ExtLen, void **Bufer, int *BufLen); -int INIT unxz(unsigned char *in, int in_size, - int(*fill)(void *dest, unsigned int size), - int(*flush)(void *src, unsigned int size), - unsigned char *out, int *in_used, - void(*error)(char *x)); -void disk_io_set_param(HANDLE Handle, UINT64 SectorCount); -INT_PTR CALLBACK PartDialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam); -int GetReservedSpaceInMB(void); - -#endif +/****************************************************************************** + * Ventoy2Disk.h + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#ifndef __VENTOY2DISK_H__ +#define __VENTOY2DISK_H__ + +#include + +#define SIZE_1MB (1024 * 1024) +#define VENTOY_EFI_PART_SIZE (32 * SIZE_1MB) +#define VENTOY_PART1_START_SECTOR 2048 + +#define VENTOY_FILE_BOOT_IMG "boot\\boot.img" +#define VENTOY_FILE_STG1_IMG "boot\\core.img.xz" +#define VENTOY_FILE_DISK_IMG "ventoy\\ventoy.disk.img.xz" +#define VENTOY_FILE_LOG "log.txt" +#define VENTOY_FILE_VERSION "ventoy\\version" + +#define DRIVE_ACCESS_TIMEOUT 15000 // How long we should retry drive access (in ms) +#define DRIVE_ACCESS_RETRIES 150 // How many times we should retry + +#define IsFileExist(Fmt, ...) IsPathExist(FALSE, Fmt, __VA_ARGS__) +#define IsDirExist(Fmt, ...) IsPathExist(TRUE, Fmt, __VA_ARGS__) + +#define safe_sprintf(dst, fmt, ...) sprintf_s(dst, sizeof(dst), fmt, __VA_ARGS__) +#define safe_strcpy(dst, src) strcpy_s(dst, sizeof(dst), src) + +#define CHECK_CLOSE_HANDLE(Handle) \ +{\ + if (Handle != INVALID_HANDLE_VALUE) \ + {\ + CloseHandle(Handle); \ + Handle = INVALID_HANDLE_VALUE; \ + }\ +} + +#define LASTERR GetLastError() + +#pragma pack(1) +typedef struct PART_TABLE +{ + UINT8 Active; // 0x00 0x80 + + UINT8 StartHead; + UINT16 StartSector : 6; + UINT16 StartCylinder : 10; + + UINT8 FsFlag; + + UINT8 EndHead; + UINT16 EndSector : 6; + UINT16 EndCylinder : 10; + + UINT32 StartSectorId; + UINT32 SectorCount; +}PART_TABLE; + +typedef struct MBR_HEAD +{ + UINT8 BootCode[446]; + PART_TABLE PartTbl[4]; + UINT8 Byte55; + UINT8 ByteAA; +}MBR_HEAD; + +typedef struct VTOY_GPT_HDR +{ + CHAR Signature[8]; /* EFI PART */ + UINT8 Version[4]; + UINT32 Length; + UINT32 Crc; + UINT8 Reserved1[4]; + UINT64 EfiStartLBA; + UINT64 EfiBackupLBA; + UINT64 PartAreaStartLBA; + UINT64 PartAreaEndLBA; + GUID DiskGuid; + UINT64 PartTblStartLBA; + UINT32 PartTblTotNum; + UINT32 PartTblEntryLen; + UINT32 PartTblCrc; + UINT8 Reserved2[420]; +}VTOY_GPT_HDR; + +typedef struct VTOY_GPT_PART_TBL +{ + GUID PartType; + GUID PartGuid; + UINT64 StartLBA; + UINT64 LastLBA; + UINT64 Attr; + UINT16 Name[36]; +}VTOY_GPT_PART_TBL; + +typedef struct VTOY_GPT_INFO +{ + MBR_HEAD MBR; + VTOY_GPT_HDR Head; + VTOY_GPT_PART_TBL PartTbl[128]; +}VTOY_GPT_INFO; + +#pragma pack() + +#define VENTOY_MAX_PHY_DRIVE 128 + +typedef struct PHY_DRIVE_INFO +{ + int Id; + int PhyDrive; + int PartStyle;//0:MBR 1:GPT + UINT64 SizeInBytes; + BYTE DeviceType; + BOOL RemovableMedia; + CHAR VendorId[128]; + CHAR ProductId[128]; + CHAR ProductRev[128]; + CHAR SerialNumber[128]; + STORAGE_BUS_TYPE BusType; + + CHAR DriveLetters[64]; + + CHAR VentoyVersion[32]; + +}PHY_DRIVE_INFO; + +typedef enum PROGRESS_POINT +{ + PT_START = 0, + PT_LOCK_FOR_CLEAN, + PT_DEL_ALL_PART, + PT_LOCK_FOR_WRITE, + PT_FORMAT_PART1, + PT_LOCK_VOLUME = PT_FORMAT_PART1, + PT_FORMAT_PART2, + + PT_WRITE_VENTOY_START, + PT_WRITE_VENTOY_FINISH = PT_WRITE_VENTOY_START + 32, + + PT_WRITE_STG1_IMG, + PT_WRITE_PART_TABLE, + PT_MOUNT_VOLUME, + + PT_FINISH +}PROGRESS_POINT; + +#define PROGRESS_BAR_SET_POS(pos) SetProgressBarPos(pos) + +extern PHY_DRIVE_INFO *g_PhyDriveList; +extern DWORD g_PhyDriveCount; +extern int g_ForceOperation; +extern HWND g_ProgressBarHwnd; +extern HFONT g_language_normal_font; +extern HFONT g_language_bold_font; + +void Log(const char *Fmt, ...); +BOOL IsPathExist(BOOL Dir, const char *Fmt, ...); +void DumpWindowsVersion(void); +const CHAR* GetLocalVentoyVersion(void); +const CHAR* ParseVentoyVersionFromString(CHAR *Buf); +CHAR GetFirstUnusedDriveLetter(void); +const CHAR * GetBusTypeString(STORAGE_BUS_TYPE Type); +int VentoyGetLocalBootImg(MBR_HEAD *pMBR); +int GetHumanReadableGBSize(UINT64 SizeBytes); +void TrimString(CHAR *String); +int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR, int PartStyle); +int VentoyFillGpt(UINT64 DiskSizeBytes, VTOY_GPT_INFO *pInfo); +BOOL IsVentoyLogicalDrive(CHAR DriveLetter); +int GetRegDwordValue(HKEY Key, LPCSTR SubKey, LPCSTR ValueName, DWORD *pValue); +int GetPhysicalDriveCount(void); +int GetAllPhysicalDriveInfo(PHY_DRIVE_INFO *pDriveList, DWORD *pDriveCount); +int GetPhyDriveByLogicalDrive(int DriveLetter); +int GetVentoyVerInPhyDrive(const PHY_DRIVE_INFO *pDriveInfo, UINT64 Part2StartSector, CHAR *VerBuf, size_t BufLen); +int Ventoy2DiskInit(void); +int Ventoy2DiskDestroy(void); +PHY_DRIVE_INFO * GetPhyDriveInfoById(int Id); +int ParseCmdLineOption(LPSTR lpCmdLine); +int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle); +int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive); +int VentoyFillBackupGptHead(VTOY_GPT_INFO *pInfo, VTOY_GPT_HDR *pHead); +void SetProgressBarPos(int Pos); +int ReadWholeFileToBuf(const CHAR *FileName, int ExtLen, void **Bufer, int *BufLen); +int INIT unxz(unsigned char *in, int in_size, + int(*fill)(void *dest, unsigned int size), + int(*flush)(void *src, unsigned int size), + unsigned char *out, int *in_used, + void(*error)(char *x)); +void disk_io_set_param(HANDLE Handle, UINT64 SectorCount); +INT_PTR CALLBACK PartDialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam); +int GetReservedSpaceInMB(void); +int FindProcessOccupyDisk(HANDLE hDrive, PHY_DRIVE_INFO *pPhyDrive); +int VentoyFillLocation(UINT64 DiskSizeInBytes, UINT32 StartSectorId, UINT32 SectorCount, PART_TABLE *Table); +int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLetter); +UINT32 VentoyCrc32(void *Buffer, UINT32 Length); + +#define SET_FILE_POS(pos) \ + liCurrentPosition.QuadPart = pos; \ + SetFilePointerEx(hDrive, liCurrentPosition, &liCurrentPosition, FILE_BEGIN)\ + + +#endif diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.rc b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.rc index 2df0e8af..e454bb56 100644 Binary files a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.rc and b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.rc differ diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj index 4b9ccf82..821d13e5 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj @@ -91,6 +91,7 @@ + @@ -106,6 +107,7 @@ + @@ -128,6 +130,7 @@ + @@ -135,6 +138,8 @@ + + diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters index 8370af2c..1eac7fbb 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters @@ -72,6 +72,12 @@ 源文件 + + 源文件 + + + 源文件 + @@ -128,6 +134,9 @@ 头文件 + + 头文件 + @@ -138,5 +147,11 @@ 资源文件 + + 资源文件 + + + 资源文件 + \ No newline at end of file diff --git a/Ventoy2Disk/Ventoy2Disk/WinDialog.c b/Ventoy2Disk/Ventoy2Disk/WinDialog.c index afceab56..49179344 100644 Binary files a/Ventoy2Disk/Ventoy2Disk/WinDialog.c and b/Ventoy2Disk/Ventoy2Disk/WinDialog.c differ diff --git a/Ventoy2Disk/Ventoy2Disk/crc32.c b/Ventoy2Disk/Ventoy2Disk/crc32.c new file mode 100644 index 00000000..3af9d20a --- /dev/null +++ b/Ventoy2Disk/Ventoy2Disk/crc32.c @@ -0,0 +1,275 @@ +#include + +static UINT32 g_CrcTable[256] = { + 0x00000000, + 0x77073096, + 0xEE0E612C, + 0x990951BA, + 0x076DC419, + 0x706AF48F, + 0xE963A535, + 0x9E6495A3, + 0x0EDB8832, + 0x79DCB8A4, + 0xE0D5E91E, + 0x97D2D988, + 0x09B64C2B, + 0x7EB17CBD, + 0xE7B82D07, + 0x90BF1D91, + 0x1DB71064, + 0x6AB020F2, + 0xF3B97148, + 0x84BE41DE, + 0x1ADAD47D, + 0x6DDDE4EB, + 0xF4D4B551, + 0x83D385C7, + 0x136C9856, + 0x646BA8C0, + 0xFD62F97A, + 0x8A65C9EC, + 0x14015C4F, + 0x63066CD9, + 0xFA0F3D63, + 0x8D080DF5, + 0x3B6E20C8, + 0x4C69105E, + 0xD56041E4, + 0xA2677172, + 0x3C03E4D1, + 0x4B04D447, + 0xD20D85FD, + 0xA50AB56B, + 0x35B5A8FA, + 0x42B2986C, + 0xDBBBC9D6, + 0xACBCF940, + 0x32D86CE3, + 0x45DF5C75, + 0xDCD60DCF, + 0xABD13D59, + 0x26D930AC, + 0x51DE003A, + 0xC8D75180, + 0xBFD06116, + 0x21B4F4B5, + 0x56B3C423, + 0xCFBA9599, + 0xB8BDA50F, + 0x2802B89E, + 0x5F058808, + 0xC60CD9B2, + 0xB10BE924, + 0x2F6F7C87, + 0x58684C11, + 0xC1611DAB, + 0xB6662D3D, + 0x76DC4190, + 0x01DB7106, + 0x98D220BC, + 0xEFD5102A, + 0x71B18589, + 0x06B6B51F, + 0x9FBFE4A5, + 0xE8B8D433, + 0x7807C9A2, + 0x0F00F934, + 0x9609A88E, + 0xE10E9818, + 0x7F6A0DBB, + 0x086D3D2D, + 0x91646C97, + 0xE6635C01, + 0x6B6B51F4, + 0x1C6C6162, + 0x856530D8, + 0xF262004E, + 0x6C0695ED, + 0x1B01A57B, + 0x8208F4C1, + 0xF50FC457, + 0x65B0D9C6, + 0x12B7E950, + 0x8BBEB8EA, + 0xFCB9887C, + 0x62DD1DDF, + 0x15DA2D49, + 0x8CD37CF3, + 0xFBD44C65, + 0x4DB26158, + 0x3AB551CE, + 0xA3BC0074, + 0xD4BB30E2, + 0x4ADFA541, + 0x3DD895D7, + 0xA4D1C46D, + 0xD3D6F4FB, + 0x4369E96A, + 0x346ED9FC, + 0xAD678846, + 0xDA60B8D0, + 0x44042D73, + 0x33031DE5, + 0xAA0A4C5F, + 0xDD0D7CC9, + 0x5005713C, + 0x270241AA, + 0xBE0B1010, + 0xC90C2086, + 0x5768B525, + 0x206F85B3, + 0xB966D409, + 0xCE61E49F, + 0x5EDEF90E, + 0x29D9C998, + 0xB0D09822, + 0xC7D7A8B4, + 0x59B33D17, + 0x2EB40D81, + 0xB7BD5C3B, + 0xC0BA6CAD, + 0xEDB88320, + 0x9ABFB3B6, + 0x03B6E20C, + 0x74B1D29A, + 0xEAD54739, + 0x9DD277AF, + 0x04DB2615, + 0x73DC1683, + 0xE3630B12, + 0x94643B84, + 0x0D6D6A3E, + 0x7A6A5AA8, + 0xE40ECF0B, + 0x9309FF9D, + 0x0A00AE27, + 0x7D079EB1, + 0xF00F9344, + 0x8708A3D2, + 0x1E01F268, + 0x6906C2FE, + 0xF762575D, + 0x806567CB, + 0x196C3671, + 0x6E6B06E7, + 0xFED41B76, + 0x89D32BE0, + 0x10DA7A5A, + 0x67DD4ACC, + 0xF9B9DF6F, + 0x8EBEEFF9, + 0x17B7BE43, + 0x60B08ED5, + 0xD6D6A3E8, + 0xA1D1937E, + 0x38D8C2C4, + 0x4FDFF252, + 0xD1BB67F1, + 0xA6BC5767, + 0x3FB506DD, + 0x48B2364B, + 0xD80D2BDA, + 0xAF0A1B4C, + 0x36034AF6, + 0x41047A60, + 0xDF60EFC3, + 0xA867DF55, + 0x316E8EEF, + 0x4669BE79, + 0xCB61B38C, + 0xBC66831A, + 0x256FD2A0, + 0x5268E236, + 0xCC0C7795, + 0xBB0B4703, + 0x220216B9, + 0x5505262F, + 0xC5BA3BBE, + 0xB2BD0B28, + 0x2BB45A92, + 0x5CB36A04, + 0xC2D7FFA7, + 0xB5D0CF31, + 0x2CD99E8B, + 0x5BDEAE1D, + 0x9B64C2B0, + 0xEC63F226, + 0x756AA39C, + 0x026D930A, + 0x9C0906A9, + 0xEB0E363F, + 0x72076785, + 0x05005713, + 0x95BF4A82, + 0xE2B87A14, + 0x7BB12BAE, + 0x0CB61B38, + 0x92D28E9B, + 0xE5D5BE0D, + 0x7CDCEFB7, + 0x0BDBDF21, + 0x86D3D2D4, + 0xF1D4E242, + 0x68DDB3F8, + 0x1FDA836E, + 0x81BE16CD, + 0xF6B9265B, + 0x6FB077E1, + 0x18B74777, + 0x88085AE6, + 0xFF0F6A70, + 0x66063BCA, + 0x11010B5C, + 0x8F659EFF, + 0xF862AE69, + 0x616BFFD3, + 0x166CCF45, + 0xA00AE278, + 0xD70DD2EE, + 0x4E048354, + 0x3903B3C2, + 0xA7672661, + 0xD06016F7, + 0x4969474D, + 0x3E6E77DB, + 0xAED16A4A, + 0xD9D65ADC, + 0x40DF0B66, + 0x37D83BF0, + 0xA9BCAE53, + 0xDEBB9EC5, + 0x47B2CF7F, + 0x30B5FFE9, + 0xBDBDF21C, + 0xCABAC28A, + 0x53B39330, + 0x24B4A3A6, + 0xBAD03605, + 0xCDD70693, + 0x54DE5729, + 0x23D967BF, + 0xB3667A2E, + 0xC4614AB8, + 0x5D681B02, + 0x2A6F2B94, + 0xB40BBE37, + 0xC30C8EA1, + 0x5A05DF1B, + 0x2D02EF8D +}; + +UINT32 VentoyCrc32(void *Buffer, UINT32 Length) +{ + UINT32 Index; + UINT32 Crc; + UINT8 *Byte = Buffer; + + Crc = 0xffffffff; + for (Index = 0; Index < Length; Index++, Byte++) + { + Crc = (Crc >> 8) ^ g_CrcTable[(UINT8)Crc ^ *Byte]; + } + + return Crc ^ 0xffffffff; +} diff --git a/Ventoy2Disk/Ventoy2Disk/process.c b/Ventoy2Disk/Ventoy2Disk/process.c new file mode 100644 index 00000000..5064d1f3 --- /dev/null +++ b/Ventoy2Disk/Ventoy2Disk/process.c @@ -0,0 +1,672 @@ +/* +* Rufus: The Reliable USB Formatting Utility +* Process search functionality +* +* Modified from Process Hacker: +* https://github.com/processhacker2/processhacker2/ +* Copyright © 2017-2019 Pete Batard +* Copyright © 2017 dmex +* Copyright © 2009-2016 wj32 +* Copyright (c) 2020, longpanda +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + + +#include +#include +#include +#include +#include +#include "resource.h" +#include "Language.h" +#include "Ventoy2Disk.h" +#include "fat_filelib.h" +#include "ff.h" +#include "process.h" +#include + + +OPENED_LIBRARIES_VARS; + +STATIC WCHAR *_wHandleName = NULL; +static PVOID PhHeapHandle = NULL; + + +/* +* Convert an NT Status to an error message +* +* \param Status An operattonal status. +* +* \return An error message string. +* +*/ +char* NtStatusError(NTSTATUS Status) { + static char unknown[32]; + + switch (Status) { + case STATUS_SUCCESS: + return "Operation Successful"; + case STATUS_UNSUCCESSFUL: + return "Operation Failed"; + case STATUS_BUFFER_OVERFLOW: + return "Buffer Overflow"; + case STATUS_NOT_IMPLEMENTED: + return "Not Implemented"; + case STATUS_INFO_LENGTH_MISMATCH: + return "Info Length Mismatch"; + case STATUS_INVALID_HANDLE: + return "Invalid Handle."; + case STATUS_INVALID_PARAMETER: + return "Invalid Parameter"; + case STATUS_NO_MEMORY: + return "Not Enough Quota"; + case STATUS_ACCESS_DENIED: + return "Access Denied"; + case STATUS_BUFFER_TOO_SMALL: + return "Buffer Too Small"; + case STATUS_OBJECT_TYPE_MISMATCH: + return "Wrong Type"; + case STATUS_OBJECT_NAME_INVALID: + return "Object Name Invalid"; + case STATUS_OBJECT_NAME_NOT_FOUND: + return "Object Name not found"; + case STATUS_OBJECT_PATH_INVALID: + return "Object Path Invalid"; + case STATUS_SHARING_VIOLATION: + return "Sharing Violation"; + case STATUS_INSUFFICIENT_RESOURCES: + return "Insufficient resources"; + case STATUS_NOT_SUPPORTED: + return "Operation is not supported"; + default: + safe_sprintf(unknown, "Unknown error 0x%08lx", Status); + return unknown; + } +} + + +static NTSTATUS PhCreateHeap(VOID) +{ + NTSTATUS status = STATUS_SUCCESS; + + if (PhHeapHandle != NULL) + return STATUS_ALREADY_COMPLETE; + + PF_INIT_OR_SET_STATUS(RtlCreateHeap, Ntdll); + + if (NT_SUCCESS(status)) { + PhHeapHandle = pfRtlCreateHeap(HEAP_NO_SERIALIZE | HEAP_GROWABLE, NULL, 2 * MB, 1 * MB, NULL, NULL); + if (PhHeapHandle == NULL) + status = STATUS_UNSUCCESSFUL; + } + + return status; +} + +static NTSTATUS PhDestroyHeap(VOID) +{ + NTSTATUS status = STATUS_SUCCESS; + + if (PhHeapHandle == NULL) + return STATUS_ALREADY_COMPLETE; + + PF_INIT_OR_SET_STATUS(RtlDestroyHeap, Ntdll); + + if (NT_SUCCESS(status)) { + if (pfRtlDestroyHeap(PhHeapHandle) == NULL) { + PhHeapHandle = NULL; + } + else { + status = STATUS_UNSUCCESSFUL; + } + } + + return status; +} + +/** +* Allocates a block of memory. +* +* \param Size The number of bytes to allocate. +* +* \return A pointer to the allocated block of memory. +* +*/ +static PVOID PhAllocate(SIZE_T Size) +{ + PF_INIT(RtlAllocateHeap, Ntdll); + if (pfRtlAllocateHeap == NULL) + return NULL; + + return pfRtlAllocateHeap(PhHeapHandle, 0, Size); +} + +/** +* Frees a block of memory allocated with PhAllocate(). +* +* \param Memory A pointer to a block of memory. +* +*/ +static VOID PhFree(PVOID Memory) +{ + PF_INIT(RtlFreeHeap, Ntdll); + + if (pfRtlFreeHeap != NULL) + pfRtlFreeHeap(PhHeapHandle, 0, Memory); +} + +/** +* Enumerates all open handles. +* +* \param Handles A variable which receives a pointer to a structure containing information about +* all opened handles. You must free the structure using PhFree() when you no longer need it. +* +* \return An NTStatus indicating success or the error code. +*/ +NTSTATUS PhEnumHandlesEx(PSYSTEM_HANDLE_INFORMATION_EX *Handles) +{ + static ULONG initialBufferSize = 0x10000; + NTSTATUS status = STATUS_SUCCESS; + PVOID buffer; + ULONG bufferSize; + + PF_INIT_OR_SET_STATUS(NtQuerySystemInformation, Ntdll); + if (!NT_SUCCESS(status)) + return status; + + bufferSize = initialBufferSize; + buffer = PhAllocate(bufferSize); + if (buffer == NULL) + return STATUS_NO_MEMORY; + + while ((status = pfNtQuerySystemInformation(SystemExtendedHandleInformation, + buffer, bufferSize, NULL)) == STATUS_INFO_LENGTH_MISMATCH) { + PhFree(buffer); + bufferSize *= 2; + + // Fail if we're resizing the buffer to something very large. + if (bufferSize > PH_LARGE_BUFFER_SIZE) + return STATUS_INSUFFICIENT_RESOURCES; + + buffer = PhAllocate(bufferSize); + if (buffer == NULL) + return STATUS_NO_MEMORY; + } + + if (!NT_SUCCESS(status)) { + PhFree(buffer); + return status; + } + + if (bufferSize <= 0x200000) + initialBufferSize = bufferSize; + *Handles = (PSYSTEM_HANDLE_INFORMATION_EX)buffer; + + return status; +} + +/** +* Opens a process. +* +* \param ProcessHandle A variable which receives a handle to the process. +* \param DesiredAccess The desired access to the process. +* \param ProcessId The ID of the process. +* +* \return An NTStatus indicating success or the error code. +*/ +NTSTATUS PhOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, HANDLE ProcessId) +{ + NTSTATUS status = STATUS_SUCCESS; + OBJECT_ATTRIBUTES objectAttributes; + CLIENT_ID clientId; + + if ((LONG_PTR)ProcessId == (LONG_PTR)GetCurrentProcessId()) { + *ProcessHandle = NtCurrentProcess(); + return 0; + } + + PF_INIT_OR_SET_STATUS(NtOpenProcess, Ntdll); + if (!NT_SUCCESS(status)) + return status; + + clientId.UniqueProcess = ProcessId; + clientId.UniqueThread = NULL; + + InitializeObjectAttributes(&objectAttributes, NULL, 0, NULL, NULL); + status = pfNtOpenProcess(ProcessHandle, DesiredAccess, &objectAttributes, &clientId); + + return status; +} + +/** +* Query processes with open handles to a file, volume or disk. +* +* \param VolumeOrFileHandle The handle to the target. +* \param Information The returned list of processes. +* +* \return An NTStatus indicating success or the error code. +*/ +NTSTATUS PhQueryProcessesUsingVolumeOrFile(HANDLE VolumeOrFileHandle, + PFILE_PROCESS_IDS_USING_FILE_INFORMATION *Information) +{ + static ULONG initialBufferSize = 16 * KB; + NTSTATUS status = STATUS_SUCCESS; + PVOID buffer; + ULONG bufferSize; + IO_STATUS_BLOCK isb; + + PF_INIT_OR_SET_STATUS(NtQueryInformationFile, NtDll); + if (!NT_SUCCESS(status)) + return status; + + bufferSize = initialBufferSize; + buffer = PhAllocate(bufferSize); + if (buffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + while ((status = pfNtQueryInformationFile(VolumeOrFileHandle, &isb, buffer, bufferSize, + FileProcessIdsUsingFileInformation)) == STATUS_INFO_LENGTH_MISMATCH) { + PhFree(buffer); + bufferSize *= 2; + // Fail if we're resizing the buffer to something very large. + if (bufferSize > 64 * MB) + return STATUS_INSUFFICIENT_RESOURCES; + buffer = PhAllocate(bufferSize); + } + + if (!NT_SUCCESS(status)) { + PhFree(buffer); + return status; + } + + if (bufferSize <= 64 * MB) + initialBufferSize = bufferSize; + *Information = (PFILE_PROCESS_IDS_USING_FILE_INFORMATION)buffer; + + return status; +} + +/** +* Query the full commandline that was used to create a process. +* This can be helpful to differentiate between service instances (svchost.exe). +* Taken from: https://stackoverflow.com/a/14012919/1069307 +* +* \param hProcess A handle to a process. +* +* \return A Unicode commandline string, or NULL on error. +* The returned string must be freed by the caller. +*/ +static PWSTR GetProcessCommandLine(HANDLE hProcess) +{ + PWSTR wcmdline = NULL; + BOOL wow; + DWORD pp_offset, cmd_offset; + NTSTATUS status = STATUS_SUCCESS; + SYSTEM_INFO si; + PBYTE peb = NULL, pp = NULL; + + // Determine if 64 or 32-bit processor + GetNativeSystemInfo(&si); + if ((si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) || (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64)) { + pp_offset = 0x20; + cmd_offset = 0x70; + } + else { + pp_offset = 0x10; + cmd_offset = 0x40; + } + + // PEB and Process Parameters (we only need the beginning of these structs) + peb = (PBYTE)calloc(pp_offset + 8, 1); + if (peb == NULL) + goto out; + pp = (PBYTE)calloc(cmd_offset + 16, 1); + if (pp == NULL) + goto out; + + IsWow64Process(GetCurrentProcess(), &wow); + if (wow) { + // 32-bit process running on a 64-bit OS + PROCESS_BASIC_INFORMATION_WOW64 pbi = { 0 }; + ULONGLONG params; + UNICODE_STRING_WOW64* ucmdline; + + PF_INIT_OR_OUT(NtWow64QueryInformationProcess64, NtDll); + PF_INIT_OR_OUT(NtWow64ReadVirtualMemory64, NtDll); + + status = pfNtWow64QueryInformationProcess64(hProcess, 0, &pbi, sizeof(pbi), NULL); + if (!NT_SUCCESS(status)) + goto out; + + status = pfNtWow64ReadVirtualMemory64(hProcess, pbi.PebBaseAddress, peb, pp_offset + 8, NULL); + if (!NT_SUCCESS(status)) + goto out; + + // Read Process Parameters from the 64-bit address space + params = (ULONGLONG)*((ULONGLONG*)(peb + pp_offset)); + status = pfNtWow64ReadVirtualMemory64(hProcess, params, pp, cmd_offset + 16, NULL); + if (!NT_SUCCESS(status)) + goto out; + + ucmdline = (UNICODE_STRING_WOW64*)(pp + cmd_offset); + wcmdline = (PWSTR)calloc(ucmdline->Length + 1, sizeof(WCHAR)); + if (wcmdline == NULL) + goto out; + status = pfNtWow64ReadVirtualMemory64(hProcess, ucmdline->Buffer, wcmdline, ucmdline->Length, NULL); + if (!NT_SUCCESS(status)) { + safe_free(wcmdline); + goto out; + } + } + else { + // 32-bit process on a 32-bit OS, or 64-bit process on a 64-bit OS + PROCESS_BASIC_INFORMATION pbi = { 0 }; + PBYTE* params; + UNICODE_STRING* ucmdline; + + PF_INIT_OR_OUT(NtQueryInformationProcess, NtDll); + + status = pfNtQueryInformationProcess(hProcess, 0, &pbi, sizeof(pbi), NULL); + if (!NT_SUCCESS(status)) + goto out; + + // Read PEB + if (!ReadProcessMemory(hProcess, pbi.PebBaseAddress, peb, pp_offset + 8, NULL)) + goto out; + + // Read Process Parameters + params = (PBYTE*)*(LPVOID*)(peb + pp_offset); + if (!ReadProcessMemory(hProcess, params, pp, cmd_offset + 16, NULL)) + goto out; + + ucmdline = (UNICODE_STRING*)(pp + cmd_offset); + // In the absolute, someone could craft a process with dodgy attributes to try to cause an overflow + ucmdline->Length = min(ucmdline->Length, 512); + wcmdline = (PWSTR)calloc(ucmdline->Length + 1, sizeof(WCHAR)); + if (!ReadProcessMemory(hProcess, ucmdline->Buffer, wcmdline, ucmdline->Length, NULL)) { + safe_free(wcmdline); + goto out; + } + } + +out: + free(peb); + free(pp); + return wcmdline; +} + + +static int GetDevicePathName(PHY_DRIVE_INFO *pPhyDrive, WCHAR *wDevPath) +{ + int i; + CHAR PhyDrive[128]; + CHAR DevPath[MAX_PATH] = { 0 }; + + safe_sprintf(PhyDrive, "\\\\.\\PhysicalDrive%d", pPhyDrive->PhyDrive); + + if (0 == QueryDosDeviceA(PhyDrive + 4, DevPath, sizeof(DevPath))) + { + Log("QueryDosDeviceA failed error:%u", GetLastError()); + strcpy_s(DevPath, sizeof(DevPath), "???"); + } + else + { + Log("QueryDosDeviceA success %s", DevPath); + } + + for (i = 0; DevPath[i] && i < MAX_PATH; i++) + { + wDevPath[i] = DevPath[i]; + } + + return 0; +} + + +static __inline DWORD GetModuleFileNameExU(HANDLE hProcess, HMODULE hModule, char* lpFilename, DWORD nSize) +{ + DWORD ret = 0, err = ERROR_INVALID_DATA; + // coverity[returned_null] + walloc(lpFilename, nSize); + ret = GetModuleFileNameExW(hProcess, hModule, wlpFilename, nSize); + err = GetLastError(); + if ((ret != 0) + && ((ret = wchar_to_utf8_no_alloc(wlpFilename, lpFilename, nSize)) == 0)) { + err = GetLastError(); + } + wfree(lpFilename); + SetLastError(err); + return ret; +} + +int FindProcessOccupyDisk(HANDLE hDrive, PHY_DRIVE_INFO *pPhyDrive) +{ + WCHAR wDevPath[MAX_PATH] = { 0 }; + const char *access_rights_str[8] = { "n", "r", "w", "rw", "x", "rx", "wx", "rwx" }; + NTSTATUS status = STATUS_SUCCESS; + PSYSTEM_HANDLE_INFORMATION_EX handles = NULL; + POBJECT_NAME_INFORMATION buffer = NULL; + ULONG_PTR i; + ULONG_PTR pid[2]; + ULONG_PTR last_access_denied_pid = 0; + ULONG bufferSize; + USHORT wHandleNameLen; + HANDLE dupHandle = NULL; + HANDLE processHandle = NULL; + BOOLEAN bFound = FALSE, bGotCmdLine, verbose = TRUE; + ULONG access_rights = 0; + DWORD size; + char cmdline[MAX_PATH] = { 0 }; + wchar_t wexe_path[MAX_PATH], *wcmdline; + int cur_pid; + + + Log("FindProcessOccupyDisk for PhyDrive %d", pPhyDrive->PhyDrive); + + GetDevicePathName(pPhyDrive, wDevPath); + _wHandleName = wDevPath; + + + PF_INIT_OR_SET_STATUS(NtQueryObject, Ntdll); + PF_INIT_OR_SET_STATUS(NtDuplicateObject, NtDll); + PF_INIT_OR_SET_STATUS(NtClose, NtDll); + + if (NT_SUCCESS(status)) + status = PhCreateHeap(); + + if (NT_SUCCESS(status)) + status = PhEnumHandlesEx(&handles); + + if (!NT_SUCCESS(status)) { + Log("Warning: Could not enumerate process handles: %s", NtStatusError(status)); + goto out; + } + + pid[0] = (ULONG_PTR)0; + cur_pid = 1; + + wHandleNameLen = (USHORT)wcslen(_wHandleName); + + bufferSize = 0x200; + buffer = PhAllocate(bufferSize); + if (buffer == NULL) + goto out; + + for (i = 0;; i++) { + ULONG attempts = 8; + PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo = + (i < handles->NumberOfHandles) ? &handles->Handles[i] : NULL; + + if ((dupHandle != NULL) && (processHandle != NtCurrentProcess())) { + pfNtClose(dupHandle); + dupHandle = NULL; + } + + // Update the current handle's process PID and compare against last + // Note: Be careful about not trying to overflow our list! + pid[cur_pid] = (handleInfo != NULL) ? handleInfo->UniqueProcessId : -1; + + if (pid[0] != pid[1]) { + cur_pid = (cur_pid + 1) % 2; + + // If we're switching process and found a match, print it + if (bFound) { + Log("* [%06u] %s (%s)", (UINT32)pid[cur_pid], cmdline, access_rights_str[access_rights & 0x7]); + bFound = FALSE; + access_rights = 0; + } + + // Close the previous handle + if (processHandle != NULL) { + if (processHandle != NtCurrentProcess()) + pfNtClose(processHandle); + processHandle = NULL; + } + } + + // Exit loop condition + if (i >= handles->NumberOfHandles) + break; + + // Don't bother with processes we can't access + if (handleInfo->UniqueProcessId == last_access_denied_pid) + continue; + + // Filter out handles that aren't opened with Read (bit 0), Write (bit 1) or Execute (bit 5) access + if ((handleInfo->GrantedAccess & 0x23) == 0) + continue; + + // Open the process to which the handle we are after belongs, if not already opened + if (pid[0] != pid[1]) { + status = PhOpenProcess(&processHandle, PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, + (HANDLE)handleInfo->UniqueProcessId); + // There exists some processes we can't access + if (!NT_SUCCESS(status)) { + //Log("SearchProcess: Could not open process %ld: %s", + // handleInfo->UniqueProcessId, NtStatusError(status)); + processHandle = NULL; + if (status == STATUS_ACCESS_DENIED) { + last_access_denied_pid = handleInfo->UniqueProcessId; + } + continue; + } + } + + // Now duplicate this handle onto our own process, so that we can access its properties + if (processHandle == NtCurrentProcess()) { + continue; + } + else { + status = pfNtDuplicateObject(processHandle, (HANDLE)handleInfo->HandleValue, + NtCurrentProcess(), &dupHandle, 0, 0, 0); + if (!NT_SUCCESS(status)) + continue; + } + + // Filter non-storage handles. We're not interested in them and they make NtQueryObject() freeze + if (GetFileType(dupHandle) != FILE_TYPE_DISK) + continue; + + // A loop is needed because the I/O subsystem likes to give us the wrong return lengths... + do { + ULONG returnSize; + // TODO: We might potentially still need a timeout on ObjectName queries, as PH does... + status = pfNtQueryObject(dupHandle, ObjectNameInformation, buffer, bufferSize, &returnSize); + if (status == STATUS_BUFFER_OVERFLOW || status == STATUS_INFO_LENGTH_MISMATCH || + status == STATUS_BUFFER_TOO_SMALL) { + Log("SearchProcess: Realloc from %d to %d", bufferSize, returnSize); + bufferSize = returnSize; + PhFree(buffer); + buffer = PhAllocate(bufferSize); + } + else { + break; + } + } while (--attempts); + if (!NT_SUCCESS(status)) { + Log("SearchProcess: NtQueryObject failed for handle %X of process %ld: %s", + handleInfo->HandleValue, handleInfo->UniqueProcessId, NtStatusError(status)); + continue; + } + + // we are looking for a partial match and the current length is smaller + if (wHandleNameLen > buffer->Name.Length) + continue; + + // Match against our target string + if (wcsncmp(_wHandleName, buffer->Name.Buffer, wHandleNameLen) != 0) + continue; + + // If we are here, we have a process accessing our target! + bFound = TRUE; + + // Keep a mask of all the access rights being used + access_rights |= handleInfo->GrantedAccess; + // The Executable bit is in a place we don't like => reposition it + if (access_rights & 0x20) + access_rights = (access_rights & 0x03) | 0x04; + + // If this is the very first process we find, print a header + if (cmdline[0] == 0) + Log("WARNING: The following process(es) or service(s) are accessing %S:", _wHandleName); + + // Where possible, try to get the full command line + bGotCmdLine = FALSE; + size = MAX_PATH; + wcmdline = GetProcessCommandLine(processHandle); + if (wcmdline != NULL) { + bGotCmdLine = TRUE; + wchar_to_utf8_no_alloc(wcmdline, cmdline, sizeof(cmdline)); + free(wcmdline); + } + + // If we couldn't get the full commandline, try to get the executable path + if (!bGotCmdLine) + bGotCmdLine = (GetModuleFileNameExU(processHandle, 0, cmdline, MAX_PATH - 1) != 0); + + // The above may not work on Windows 7, so try QueryFullProcessImageName (Vista or later) + if (!bGotCmdLine) { + bGotCmdLine = QueryFullProcessImageNameW(processHandle, 0, wexe_path, &size); + if (bGotCmdLine) + wchar_to_utf8_no_alloc(wexe_path, cmdline, sizeof(cmdline)); + } + + // Still nothing? Try GetProcessImageFileName. Note that GetProcessImageFileName uses + // '\Device\Harddisk#\Partition#\' instead drive letters + if (!bGotCmdLine) { + bGotCmdLine = (GetProcessImageFileNameW(processHandle, wexe_path, MAX_PATH) != 0); + if (bGotCmdLine) + wchar_to_utf8_no_alloc(wexe_path, cmdline, sizeof(cmdline)); + } + + // Complete failure => Just craft a default process name that includes the PID + if (!bGotCmdLine) { + safe_sprintf(cmdline, "Unknown_Process_0x%llx", (ULONGLONG)handleInfo->UniqueProcessId); + } + } + +out: + if (cmdline[0] != 0) + Log("You should close these applications before attempting to reformat the drive."); + else + Log("NOTE: Could not identify the process(es) or service(s) accessing %S", _wHandleName); + + PhFree(buffer); + PhFree(handles); + PhDestroyHeap(); + + return 0; +} + diff --git a/Ventoy2Disk/Ventoy2Disk/process.h b/Ventoy2Disk/Ventoy2Disk/process.h new file mode 100644 index 00000000..39ebe404 --- /dev/null +++ b/Ventoy2Disk/Ventoy2Disk/process.h @@ -0,0 +1,405 @@ +/* +* Rufus: The Reliable USB Formatting Utility +* Process search functionality +* +* Modified from Process Hacker: +* https://github.com/processhacker2/processhacker2/ +* Copyright © 2017-2019 Pete Batard +* Copyright © 2017 dmex +* Copyright © 2009-2016 wj32 +* Copyright (c) 2020, longpanda +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#include +#include +#include + +#pragma once + +#define PH_LARGE_BUFFER_SIZE (256 * 1024 * 1024) + +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) +#define STATUS_ALREADY_COMPLETE ((NTSTATUS)0x000000FFL) +#define STATUS_UNSUCCESSFUL ((NTSTATUS)0x80000001L) +#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L) +#define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L) +#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) +//#define STATUS_INVALID_HANDLE ((NTSTATUS)0xC0000008L) +#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) +#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L) +#define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS)0xC0000024L) +#define STATUS_OBJECT_NAME_INVALID ((NTSTATUS)0xC0000033L) +#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L) +#define STATUS_OBJECT_PATH_INVALID ((NTSTATUS)0xC0000039L) +#define STATUS_SHARING_VIOLATION ((NTSTATUS)0xC0000043L) +#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS)0xC000009AL) +#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL) + +#define SystemExtendedHandleInformation 64 +#define FileProcessIdsUsingFileInformation 47 + +// MinGW doesn't know this one yet +#if !defined(PROCESSOR_ARCHITECTURE_ARM64) +#define PROCESSOR_ARCHITECTURE_ARM64 12 +#endif + +#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1) + +typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX +{ + PVOID Object; + ULONG_PTR UniqueProcessId; + ULONG_PTR HandleValue; + ULONG GrantedAccess; + USHORT CreatorBackTraceIndex; + USHORT ObjectTypeIndex; + ULONG HandleAttributes; + ULONG Reserved; +} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX; + +typedef struct _SYSTEM_HANDLE_INFORMATION_EX +{ + ULONG_PTR NumberOfHandles; + ULONG_PTR Reserved; + SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1]; +} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX; + +#if defined(_MSC_VER) +typedef struct _OBJECT_NAME_INFORMATION +{ + UNICODE_STRING Name; +} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; + +typedef struct _OBJECT_TYPE_INFORMATION +{ + UNICODE_STRING TypeName; + ULONG TotalNumberOfObjects; + ULONG TotalNumberOfHandles; + ULONG TotalPagedPoolUsage; + ULONG TotalNonPagedPoolUsage; + ULONG TotalNamePoolUsage; + ULONG TotalHandleTableUsage; + ULONG HighWaterNumberOfObjects; + ULONG HighWaterNumberOfHandles; + ULONG HighWaterPagedPoolUsage; + ULONG HighWaterNonPagedPoolUsage; + ULONG HighWaterNamePoolUsage; + ULONG HighWaterHandleTableUsage; + ULONG InvalidAttributes; + GENERIC_MAPPING GenericMapping; + ULONG ValidAccessMask; + BOOLEAN SecurityRequired; + BOOLEAN MaintainHandleCount; + UCHAR TypeIndex; // since WINBLUE + CHAR ReservedByte; + ULONG PoolType; + ULONG DefaultPagedPoolCharge; + ULONG DefaultNonPagedPoolCharge; +} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; + +#define ObjectNameInformation 1 +#endif +#define ObjectTypesInformation 3 + +typedef struct _OBJECT_TYPES_INFORMATION +{ + ULONG NumberOfTypes; +} OBJECT_TYPES_INFORMATION, *POBJECT_TYPES_INFORMATION; + +typedef struct _PROCESS_BASIC_INFORMATION_WOW64 +{ + PVOID Reserved1[2]; + // MinGW32 screws us with a sizeof(PVOID64) of 4 instead of 8 => Use ULONGLONG instead + ULONGLONG PebBaseAddress; + PVOID Reserved2[4]; + ULONG_PTR UniqueProcessId[2]; + PVOID Reserved3[2]; +} PROCESS_BASIC_INFORMATION_WOW64; + +typedef struct _UNICODE_STRING_WOW64 +{ + USHORT Length; + USHORT MaximumLength; + ULONGLONG Buffer; +} UNICODE_STRING_WOW64; + +typedef struct _FILE_PROCESS_IDS_USING_FILE_INFORMATION +{ + ULONG NumberOfProcessIdsInList; + ULONG_PTR ProcessIdList[1]; +} FILE_PROCESS_IDS_USING_FILE_INFORMATION, *PFILE_PROCESS_IDS_USING_FILE_INFORMATION; + +#define ALIGN_UP_BY(Address, Align) (((ULONG_PTR)(Address) + (Align) - 1) & ~((Align) - 1)) +#define ALIGN_UP(Address, Type) ALIGN_UP_BY(Address, sizeof(Type)) + +#define PH_FIRST_OBJECT_TYPE(ObjectTypes) \ + (POBJECT_TYPE_INFORMATION)((PCHAR)(ObjectTypes)+ALIGN_UP(sizeof(OBJECT_TYPES_INFORMATION), ULONG_PTR)) + +#define PH_NEXT_OBJECT_TYPE(ObjectType) \ + (POBJECT_TYPE_INFORMATION)((PCHAR)(ObjectType)+sizeof(OBJECT_TYPE_INFORMATION)+\ + ALIGN_UP(ObjectType->TypeName.MaximumLength, ULONG_PTR)) + +// Heaps + +typedef struct _RTL_HEAP_ENTRY +{ + SIZE_T Size; + USHORT Flags; + USHORT AllocatorBackTraceIndex; + union + { + struct + { + SIZE_T Settable; + ULONG Tag; + } s1; + struct + { + SIZE_T CommittedSize; + PVOID FirstBlock; + } s2; + } u; +} RTL_HEAP_ENTRY, *PRTL_HEAP_ENTRY; + +#define RTL_HEAP_BUSY (USHORT)0x0001 +#define RTL_HEAP_SEGMENT (USHORT)0x0002 +#define RTL_HEAP_SETTABLE_VALUE (USHORT)0x0010 +#define RTL_HEAP_SETTABLE_FLAG1 (USHORT)0x0020 +#define RTL_HEAP_SETTABLE_FLAG2 (USHORT)0x0040 +#define RTL_HEAP_SETTABLE_FLAG3 (USHORT)0x0080 +#define RTL_HEAP_SETTABLE_FLAGS (USHORT)0x00e0 +#define RTL_HEAP_UNCOMMITTED_RANGE (USHORT)0x0100 +#define RTL_HEAP_PROTECTED_ENTRY (USHORT)0x0200 + +typedef struct _RTL_HEAP_TAG +{ + ULONG NumberOfAllocations; + ULONG NumberOfFrees; + SIZE_T BytesAllocated; + USHORT TagIndex; + USHORT CreatorBackTraceIndex; + WCHAR TagName[24]; +} RTL_HEAP_TAG, *PRTL_HEAP_TAG; + +typedef struct _RTL_HEAP_INFORMATION +{ + PVOID BaseAddress; + ULONG Flags; + USHORT EntryOverhead; + USHORT CreatorBackTraceIndex; + SIZE_T BytesAllocated; + SIZE_T BytesCommitted; + ULONG NumberOfTags; + ULONG NumberOfEntries; + ULONG NumberOfPseudoTags; + ULONG PseudoTagGranularity; + ULONG Reserved[5]; + PRTL_HEAP_TAG Tags; + PRTL_HEAP_ENTRY Entries; +} RTL_HEAP_INFORMATION, *PRTL_HEAP_INFORMATION; + +typedef struct _RTL_PROCESS_HEAPS +{ + ULONG NumberOfHeaps; + RTL_HEAP_INFORMATION Heaps[1]; +} RTL_PROCESS_HEAPS, *PRTL_PROCESS_HEAPS; + +typedef NTSTATUS(NTAPI *PRTL_HEAP_COMMIT_ROUTINE)( + _In_ PVOID Base, + _Inout_ PVOID *CommitAddress, + _Inout_ PSIZE_T CommitSize + ); + +#if defined(_MSC_VER) +typedef struct _RTL_HEAP_PARAMETERS +{ + ULONG Length; + SIZE_T SegmentReserve; + SIZE_T SegmentCommit; + SIZE_T DeCommitFreeBlockThreshold; + SIZE_T DeCommitTotalFreeThreshold; + SIZE_T MaximumAllocationSize; + SIZE_T VirtualMemoryThreshold; + SIZE_T InitialCommit; + SIZE_T InitialReserve; + PRTL_HEAP_COMMIT_ROUTINE CommitRoutine; + SIZE_T Reserved[2]; +} RTL_HEAP_PARAMETERS, *PRTL_HEAP_PARAMETERS; +#endif + +#define HEAP_SETTABLE_USER_VALUE 0x00000100 +#define HEAP_SETTABLE_USER_FLAG1 0x00000200 +#define HEAP_SETTABLE_USER_FLAG2 0x00000400 +#define HEAP_SETTABLE_USER_FLAG3 0x00000800 +#define HEAP_SETTABLE_USER_FLAGS 0x00000e00 + +#define HEAP_CLASS_0 0x00000000 // Process heap +#define HEAP_CLASS_1 0x00001000 // Private heap +#define HEAP_CLASS_2 0x00002000 // Kernel heap +#define HEAP_CLASS_3 0x00003000 // GDI heap +#define HEAP_CLASS_4 0x00004000 // User heap +#define HEAP_CLASS_5 0x00005000 // Console heap +#define HEAP_CLASS_6 0x00006000 // User desktop heap +#define HEAP_CLASS_7 0x00007000 // CSR shared heap +#define HEAP_CLASS_8 0x00008000 // CSR port heap +#define HEAP_CLASS_MASK 0x0000f000 + +// Privileges + +#define SE_MIN_WELL_KNOWN_PRIVILEGE (2L) +#define SE_CREATE_TOKEN_PRIVILEGE (2L) +#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE (3L) +#define SE_LOCK_MEMORY_PRIVILEGE (4L) +#define SE_INCREASE_QUOTA_PRIVILEGE (5L) +#define SE_MACHINE_ACCOUNT_PRIVILEGE (6L) +#define SE_TCB_PRIVILEGE (7L) +#define SE_SECURITY_PRIVILEGE (8L) +#define SE_TAKE_OWNERSHIP_PRIVILEGE (9L) +#define SE_LOAD_DRIVER_PRIVILEGE (10L) +#define SE_SYSTEM_PROFILE_PRIVILEGE (11L) +#define SE_SYSTEMTIME_PRIVILEGE (12L) +#define SE_PROF_SINGLE_PROCESS_PRIVILEGE (13L) +#define SE_INC_BASE_PRIORITY_PRIVILEGE (14L) +#define SE_CREATE_PAGEFILE_PRIVILEGE (15L) +#define SE_CREATE_PERMANENT_PRIVILEGE (16L) +#define SE_BACKUP_PRIVILEGE (17L) +#define SE_RESTORE_PRIVILEGE (18L) +#define SE_SHUTDOWN_PRIVILEGE (19L) +#define SE_DEBUG_PRIVILEGE (20L) +#define SE_AUDIT_PRIVILEGE (21L) +#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE (22L) +#define SE_CHANGE_NOTIFY_PRIVILEGE (23L) +#define SE_REMOTE_SHUTDOWN_PRIVILEGE (24L) +#define SE_UNDOCK_PRIVILEGE (25L) +#define SE_SYNC_AGENT_PRIVILEGE (26L) +#define SE_ENABLE_DELEGATION_PRIVILEGE (27L) +#define SE_MANAGE_VOLUME_PRIVILEGE (28L) +#define SE_IMPERSONATE_PRIVILEGE (29L) +#define SE_CREATE_GLOBAL_PRIVILEGE (30L) +#define SE_TRUSTED_CREDMAN_ACCESS_PRIVILEGE (31L) +#define SE_RELABEL_PRIVILEGE (32L) +#define SE_INC_WORKING_SET_PRIVILEGE (33L) +#define SE_TIME_ZONE_PRIVILEGE (34L) +#define SE_CREATE_SYMBOLIC_LINK_PRIVILEGE (35L) +#define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_SYMBOLIC_LINK_PRIVILEGE + + + +/* +* typedefs for the function prototypes. Use the something like: +* PF_DECL(FormatEx); +* which translates to: +* FormatEx_t pfFormatEx = NULL; +* in your code, to declare the entrypoint and then use: +* PF_INIT(FormatEx, Fmifs); +* which translates to: +* pfFormatEx = (FormatEx_t) GetProcAddress(GetDLLHandle("fmifs"), "FormatEx"); +* to make it accessible. +*/ +#define MAX_LIBRARY_HANDLES 32 +extern HMODULE OpenedLibrariesHandle[MAX_LIBRARY_HANDLES]; +extern UINT16 OpenedLibrariesHandleSize; +#define OPENED_LIBRARIES_VARS HMODULE OpenedLibrariesHandle[MAX_LIBRARY_HANDLES]; UINT16 OpenedLibrariesHandleSize = 0 +#define CLOSE_OPENED_LIBRARIES while(OpenedLibrariesHandleSize > 0) FreeLibrary(OpenedLibrariesHandle[--OpenedLibrariesHandleSize]) +static __inline HMODULE GetLibraryHandle(char* szLibraryName) { + HMODULE h = NULL; + if ((h = GetModuleHandleA(szLibraryName)) == NULL) { + if (OpenedLibrariesHandleSize >= MAX_LIBRARY_HANDLES) { + Log("Error: MAX_LIBRARY_HANDLES is too small\n"); + } + else { + h = LoadLibraryA(szLibraryName); + if (h != NULL) + OpenedLibrariesHandle[OpenedLibrariesHandleSize++] = h; + } + } + return h; +} +#define PF_TYPE(api, ret, proc, args) typedef ret (api *proc##_t)args +#define PF_DECL(proc) static proc##_t pf##proc = NULL +#define PF_TYPE_DECL(api, ret, proc, args) PF_TYPE(api, ret, proc, args); PF_DECL(proc) +#define PF_INIT(proc, name) if (pf##proc == NULL) pf##proc = \ + (proc##_t) GetProcAddress(GetLibraryHandle(#name), #proc) +#define PF_INIT_OR_OUT(proc, name) do {PF_INIT(proc, name); \ +if (pf##proc == NULL) { Log("Unable to locate %s() in %s.dll: %d\n", \ +#proc, #name, GetLastError()); goto out;} } while (0) + +#define PF_INIT_OR_SET_STATUS(proc, name) do {PF_INIT(proc, name); \ +if ((pf##proc == NULL) && (NT_SUCCESS(status))) status = STATUS_NOT_IMPLEMENTED; \ + } while (0) + +/* Custom application errors */ +#define FAC(f) ((f)<<16) +#define APPERR(err) (APPLICATION_ERROR_MASK|(err)) +#define ERROR_INCOMPATIBLE_FS 0x1201 +#define ERROR_CANT_QUICK_FORMAT 0x1202 +#define ERROR_INVALID_CLUSTER_SIZE 0x1203 +#define ERROR_INVALID_VOLUME_SIZE 0x1204 +#define ERROR_CANT_START_THREAD 0x1205 +#define ERROR_BADBLOCKS_FAILURE 0x1206 +#define ERROR_ISO_SCAN 0x1207 +#define ERROR_ISO_EXTRACT 0x1208 +#define ERROR_CANT_REMOUNT_VOLUME 0x1209 +#define ERROR_CANT_PATCH 0x120A +#define ERROR_CANT_ASSIGN_LETTER 0x120B +#define ERROR_CANT_MOUNT_VOLUME 0x120C +#define ERROR_BAD_SIGNATURE 0x120D +#define ERROR_CANT_DOWNLOAD 0x120E + + +#define KB 1024LL +#define MB 1048576LL +#define GB 1073741824LL +#define TB 1099511627776LL + +typedef struct _CLIENT_ID { + HANDLE UniqueProcess; + HANDLE UniqueThread; +} CLIENT_ID; + + + + +PF_TYPE_DECL(NTAPI, PVOID, RtlCreateHeap, (ULONG, PVOID, SIZE_T, SIZE_T, PVOID, PRTL_HEAP_PARAMETERS)); +PF_TYPE_DECL(NTAPI, PVOID, RtlDestroyHeap, (PVOID)); +PF_TYPE_DECL(NTAPI, PVOID, RtlAllocateHeap, (PVOID, ULONG, SIZE_T)); +PF_TYPE_DECL(NTAPI, BOOLEAN, RtlFreeHeap, (PVOID, ULONG, PVOID)); + +PF_TYPE_DECL(NTAPI, NTSTATUS, NtQuerySystemInformation, (SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG)); +PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryInformationFile, (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS)); +PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryInformationProcess, (HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG)); +PF_TYPE_DECL(NTAPI, NTSTATUS, NtWow64QueryInformationProcess64, (HANDLE, ULONG, PVOID, ULONG, PULONG)); +PF_TYPE_DECL(NTAPI, NTSTATUS, NtWow64ReadVirtualMemory64, (HANDLE, ULONGLONG, PVOID, ULONG64, PULONG64)); +PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryObject, (HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG)); +PF_TYPE_DECL(NTAPI, NTSTATUS, NtDuplicateObject, (HANDLE, HANDLE, HANDLE, PHANDLE, ACCESS_MASK, ULONG, ULONG)); +PF_TYPE_DECL(NTAPI, NTSTATUS, NtOpenProcess, (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, CLIENT_ID*)); +PF_TYPE_DECL(NTAPI, NTSTATUS, NtOpenProcessToken, (HANDLE, ACCESS_MASK, PHANDLE)); +PF_TYPE_DECL(NTAPI, NTSTATUS, NtAdjustPrivilegesToken, (HANDLE, BOOLEAN, PTOKEN_PRIVILEGES, ULONG, PTOKEN_PRIVILEGES, PULONG)); +PF_TYPE_DECL(NTAPI, NTSTATUS, NtClose, (HANDLE)); + + +#define safe_free(p) do {free((void*)p); p = NULL;} while(0) + +#define wchar_to_utf8_no_alloc(wsrc, dest, dest_size) \ + WideCharToMultiByte(CP_UTF8, 0, wsrc, -1, dest, dest_size, NULL, NULL) +#define utf8_to_wchar_no_alloc(src, wdest, wdest_size) \ + MultiByteToWideChar(CP_UTF8, 0, src, -1, wdest, wdest_size) + +#define sfree(p) do {if (p != NULL) {free((void*)(p)); p = NULL;}} while(0) +#define wconvert(p) wchar_t* w ## p = utf8_to_wchar(p) +#define walloc(p, size) wchar_t* w ## p = (p == NULL)?NULL:(wchar_t*)calloc(size, sizeof(wchar_t)) +#define wfree(p) sfree(w ## p) + diff --git a/Ventoy2Disk/Ventoy2Disk/resource.h b/Ventoy2Disk/Ventoy2Disk/resource.h index 9626e52e..fa0b4ab1 100644 Binary files a/Ventoy2Disk/Ventoy2Disk/resource.h and b/Ventoy2Disk/Ventoy2Disk/resource.h differ diff --git a/vtoygpt/build.sh b/vtoygpt/build.sh new file mode 100644 index 00000000..a8c3f7ed --- /dev/null +++ b/vtoygpt/build.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +rm -f vtoytool/00/* + +/opt/diet64/bin/diet -Os gcc -D_FILE_OFFSET_BITS=64 vtoygpt.c crc32.c -o vtoygpt_64 +/opt/diet32/bin/diet -Os gcc -D_FILE_OFFSET_BITS=64 -m32 vtoygpt.c crc32.c -o vtoygpt_32 + +#gcc -D_FILE_OFFSET_BITS=64 -static -Wall vtoygpt.c -o vtoytool_64 +#gcc -D_FILE_OFFSET_BITS=64 -Wall -m32 vtoygpt.c -o vtoytool_32 + +if [ -e vtoygpt_64 ] && [ -e vtoygpt_32 ]; then + echo -e '\n############### SUCCESS ###############\n' + mv vtoygpt_64 ../INSTALL/tool/ + mv vtoygpt_32 ../INSTALL/tool/ +else + echo -e '\n############### FAILED ################\n' + exit 1 +fi + diff --git a/vtoygpt/crc32.c b/vtoygpt/crc32.c new file mode 100644 index 00000000..354372b8 --- /dev/null +++ b/vtoygpt/crc32.c @@ -0,0 +1,315 @@ +/****************************************************************************** + * vtoygpt.c ---- ventoy gpt util + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VOID void +#define CHAR char +#define UINT64 unsigned long long +#define UINT32 unsigned int +#define UINT16 unsigned short +#define CHAR16 unsigned short +#define UINT8 unsigned char + +UINT32 g_crc_table[256] = { + 0x00000000, + 0x77073096, + 0xEE0E612C, + 0x990951BA, + 0x076DC419, + 0x706AF48F, + 0xE963A535, + 0x9E6495A3, + 0x0EDB8832, + 0x79DCB8A4, + 0xE0D5E91E, + 0x97D2D988, + 0x09B64C2B, + 0x7EB17CBD, + 0xE7B82D07, + 0x90BF1D91, + 0x1DB71064, + 0x6AB020F2, + 0xF3B97148, + 0x84BE41DE, + 0x1ADAD47D, + 0x6DDDE4EB, + 0xF4D4B551, + 0x83D385C7, + 0x136C9856, + 0x646BA8C0, + 0xFD62F97A, + 0x8A65C9EC, + 0x14015C4F, + 0x63066CD9, + 0xFA0F3D63, + 0x8D080DF5, + 0x3B6E20C8, + 0x4C69105E, + 0xD56041E4, + 0xA2677172, + 0x3C03E4D1, + 0x4B04D447, + 0xD20D85FD, + 0xA50AB56B, + 0x35B5A8FA, + 0x42B2986C, + 0xDBBBC9D6, + 0xACBCF940, + 0x32D86CE3, + 0x45DF5C75, + 0xDCD60DCF, + 0xABD13D59, + 0x26D930AC, + 0x51DE003A, + 0xC8D75180, + 0xBFD06116, + 0x21B4F4B5, + 0x56B3C423, + 0xCFBA9599, + 0xB8BDA50F, + 0x2802B89E, + 0x5F058808, + 0xC60CD9B2, + 0xB10BE924, + 0x2F6F7C87, + 0x58684C11, + 0xC1611DAB, + 0xB6662D3D, + 0x76DC4190, + 0x01DB7106, + 0x98D220BC, + 0xEFD5102A, + 0x71B18589, + 0x06B6B51F, + 0x9FBFE4A5, + 0xE8B8D433, + 0x7807C9A2, + 0x0F00F934, + 0x9609A88E, + 0xE10E9818, + 0x7F6A0DBB, + 0x086D3D2D, + 0x91646C97, + 0xE6635C01, + 0x6B6B51F4, + 0x1C6C6162, + 0x856530D8, + 0xF262004E, + 0x6C0695ED, + 0x1B01A57B, + 0x8208F4C1, + 0xF50FC457, + 0x65B0D9C6, + 0x12B7E950, + 0x8BBEB8EA, + 0xFCB9887C, + 0x62DD1DDF, + 0x15DA2D49, + 0x8CD37CF3, + 0xFBD44C65, + 0x4DB26158, + 0x3AB551CE, + 0xA3BC0074, + 0xD4BB30E2, + 0x4ADFA541, + 0x3DD895D7, + 0xA4D1C46D, + 0xD3D6F4FB, + 0x4369E96A, + 0x346ED9FC, + 0xAD678846, + 0xDA60B8D0, + 0x44042D73, + 0x33031DE5, + 0xAA0A4C5F, + 0xDD0D7CC9, + 0x5005713C, + 0x270241AA, + 0xBE0B1010, + 0xC90C2086, + 0x5768B525, + 0x206F85B3, + 0xB966D409, + 0xCE61E49F, + 0x5EDEF90E, + 0x29D9C998, + 0xB0D09822, + 0xC7D7A8B4, + 0x59B33D17, + 0x2EB40D81, + 0xB7BD5C3B, + 0xC0BA6CAD, + 0xEDB88320, + 0x9ABFB3B6, + 0x03B6E20C, + 0x74B1D29A, + 0xEAD54739, + 0x9DD277AF, + 0x04DB2615, + 0x73DC1683, + 0xE3630B12, + 0x94643B84, + 0x0D6D6A3E, + 0x7A6A5AA8, + 0xE40ECF0B, + 0x9309FF9D, + 0x0A00AE27, + 0x7D079EB1, + 0xF00F9344, + 0x8708A3D2, + 0x1E01F268, + 0x6906C2FE, + 0xF762575D, + 0x806567CB, + 0x196C3671, + 0x6E6B06E7, + 0xFED41B76, + 0x89D32BE0, + 0x10DA7A5A, + 0x67DD4ACC, + 0xF9B9DF6F, + 0x8EBEEFF9, + 0x17B7BE43, + 0x60B08ED5, + 0xD6D6A3E8, + 0xA1D1937E, + 0x38D8C2C4, + 0x4FDFF252, + 0xD1BB67F1, + 0xA6BC5767, + 0x3FB506DD, + 0x48B2364B, + 0xD80D2BDA, + 0xAF0A1B4C, + 0x36034AF6, + 0x41047A60, + 0xDF60EFC3, + 0xA867DF55, + 0x316E8EEF, + 0x4669BE79, + 0xCB61B38C, + 0xBC66831A, + 0x256FD2A0, + 0x5268E236, + 0xCC0C7795, + 0xBB0B4703, + 0x220216B9, + 0x5505262F, + 0xC5BA3BBE, + 0xB2BD0B28, + 0x2BB45A92, + 0x5CB36A04, + 0xC2D7FFA7, + 0xB5D0CF31, + 0x2CD99E8B, + 0x5BDEAE1D, + 0x9B64C2B0, + 0xEC63F226, + 0x756AA39C, + 0x026D930A, + 0x9C0906A9, + 0xEB0E363F, + 0x72076785, + 0x05005713, + 0x95BF4A82, + 0xE2B87A14, + 0x7BB12BAE, + 0x0CB61B38, + 0x92D28E9B, + 0xE5D5BE0D, + 0x7CDCEFB7, + 0x0BDBDF21, + 0x86D3D2D4, + 0xF1D4E242, + 0x68DDB3F8, + 0x1FDA836E, + 0x81BE16CD, + 0xF6B9265B, + 0x6FB077E1, + 0x18B74777, + 0x88085AE6, + 0xFF0F6A70, + 0x66063BCA, + 0x11010B5C, + 0x8F659EFF, + 0xF862AE69, + 0x616BFFD3, + 0x166CCF45, + 0xA00AE278, + 0xD70DD2EE, + 0x4E048354, + 0x3903B3C2, + 0xA7672661, + 0xD06016F7, + 0x4969474D, + 0x3E6E77DB, + 0xAED16A4A, + 0xD9D65ADC, + 0x40DF0B66, + 0x37D83BF0, + 0xA9BCAE53, + 0xDEBB9EC5, + 0x47B2CF7F, + 0x30B5FFE9, + 0xBDBDF21C, + 0xCABAC28A, + 0x53B39330, + 0x24B4A3A6, + 0xBAD03605, + 0xCDD70693, + 0x54DE5729, + 0x23D967BF, + 0xB3667A2E, + 0xC4614AB8, + 0x5D681B02, + 0x2A6F2B94, + 0xB40BBE37, + 0xC30C8EA1, + 0x5A05DF1B, + 0x2D02EF8D +}; + +UINT32 VtoyCrc32(VOID *Buffer, UINT32 Length) +{ + UINT32 i; + UINT8 *Ptr = Buffer; + UINT32 Crc = 0xFFFFFFFF; + + for (i = 0; i < Length; i++, Ptr++) + { + Crc = (Crc >> 8) ^ g_crc_table[(UINT8) Crc ^ *Ptr]; + } + + return Crc ^ 0xffffffff; +} + diff --git a/vtoygpt/vtoygpt.c b/vtoygpt/vtoygpt.c new file mode 100644 index 00000000..f9c953a2 --- /dev/null +++ b/vtoygpt/vtoygpt.c @@ -0,0 +1,320 @@ +/****************************************************************************** + * vtoygpt.c ---- ventoy gpt util + * + * Copyright (c) 2020, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VOID void +#define CHAR char +#define UINT64 unsigned long long +#define UINT32 unsigned int +#define UINT16 unsigned short +#define CHAR16 unsigned short +#define UINT8 unsigned char + +UINT32 VtoyCrc32(VOID *Buffer, UINT32 Length); + +#define COMPILE_ASSERT(expr) extern char __compile_assert[(expr) ? 1 : -1] + +#pragma pack(1) + +typedef struct PART_TABLE +{ + UINT8 Active; + + UINT8 StartHead; + UINT16 StartSector : 6; + UINT16 StartCylinder : 10; + + UINT8 FsFlag; + + UINT8 EndHead; + UINT16 EndSector : 6; + UINT16 EndCylinder : 10; + + UINT32 StartSectorId; + UINT32 SectorCount; +}PART_TABLE; + +typedef struct MBR_HEAD +{ + UINT8 BootCode[446]; + PART_TABLE PartTbl[4]; + UINT8 Byte55; + UINT8 ByteAA; +}MBR_HEAD; + +typedef struct GUID +{ + UINT32 data1; + UINT16 data2; + UINT16 data3; + UINT8 data4[8]; +}GUID; + +typedef struct VTOY_GPT_HDR +{ + CHAR Signature[8]; /* EFI PART */ + UINT8 Version[4]; + UINT32 Length; + UINT32 Crc; + UINT8 Reserved1[4]; + UINT64 EfiStartLBA; + UINT64 EfiBackupLBA; + UINT64 PartAreaStartLBA; + UINT64 PartAreaEndLBA; + GUID DiskGuid; + UINT64 PartTblStartLBA; + UINT32 PartTblTotNum; + UINT32 PartTblEntryLen; + UINT32 PartTblCrc; + UINT8 Reserved2[420]; +}VTOY_GPT_HDR; + +COMPILE_ASSERT(sizeof(VTOY_GPT_HDR) == 512); + +typedef struct VTOY_GPT_PART_TBL +{ + GUID PartType; + GUID PartGuid; + UINT64 StartLBA; + UINT64 LastLBA; + UINT64 Attr; + CHAR16 Name[36]; +}VTOY_GPT_PART_TBL; +COMPILE_ASSERT(sizeof(VTOY_GPT_PART_TBL) == 128); + +typedef struct VTOY_GPT_INFO +{ + MBR_HEAD MBR; + VTOY_GPT_HDR Head; + VTOY_GPT_PART_TBL PartTbl[128]; +}VTOY_GPT_INFO; + +typedef struct VTOY_BK_GPT_INFO +{ + VTOY_GPT_PART_TBL PartTbl[128]; + VTOY_GPT_HDR Head; +}VTOY_BK_GPT_INFO; + +COMPILE_ASSERT(sizeof(VTOY_GPT_INFO) == 512 * 34); +COMPILE_ASSERT(sizeof(VTOY_BK_GPT_INFO) == 512 * 33); + +#pragma pack() + +void DumpGuid(const char *prefix, GUID *guid) +{ + printf("%s: %08x-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n", + prefix, + guid->data1, guid->data2, guid->data3, + guid->data4[0], guid->data4[1], guid->data4[2], guid->data4[3], + guid->data4[4], guid->data4[5], guid->data4[6], guid->data4[7] + ); +} + +void DumpHead(VTOY_GPT_HDR *pHead) +{ + UINT32 CrcRead; + UINT32 CrcCalc; + + printf("Signature:<%s>\n", pHead->Signature); + printf("Version:<%02x %02x %02x %02x>\n", pHead->Version[0], pHead->Version[1], pHead->Version[2], pHead->Version[3]); + printf("Length:%u\n", pHead->Length); + printf("Crc:0x%08x\n", pHead->Crc); + printf("EfiStartLBA:%lu\n", pHead->EfiStartLBA); + printf("EfiBackupLBA:%lu\n", pHead->EfiBackupLBA); + printf("PartAreaStartLBA:%lu\n", pHead->PartAreaStartLBA); + printf("PartAreaEndLBA:%lu\n", pHead->PartAreaEndLBA); + DumpGuid("DiskGuid", &pHead->DiskGuid); + + printf("PartTblStartLBA:%lu\n", pHead->PartTblStartLBA); + printf("PartTblTotNum:%u\n", pHead->PartTblTotNum); + printf("PartTblEntryLen:%u\n", pHead->PartTblEntryLen); + printf("PartTblCrc:0x%08x\n", pHead->PartTblCrc); + + CrcRead = pHead->Crc; + pHead->Crc = 0; + CrcCalc = VtoyCrc32(pHead, pHead->Length); + + if (CrcCalc != CrcRead) + { + printf("Head CRC Check Failed\n"); + } + else + { + printf("Head CRC Check SUCCESS [%x] [%x]\n", CrcCalc, CrcRead); + } + + CrcRead = pHead->PartTblCrc; + CrcCalc = VtoyCrc32(pHead + 1, pHead->PartTblEntryLen * pHead->PartTblTotNum); + if (CrcCalc != CrcRead) + { + printf("Part Table CRC Check Failed\n"); + } + else + { + printf("Part Table CRC Check SUCCESS [%x] [%x]\n", CrcCalc, CrcRead); + } +} + +void DumpPartTable(VTOY_GPT_PART_TBL *Tbl) +{ + int i; + + DumpGuid("PartType", &Tbl->PartType); + DumpGuid("PartGuid", &Tbl->PartGuid); + printf("StartLBA:%lu\n", Tbl->StartLBA); + printf("LastLBA:%lu\n", Tbl->LastLBA); + printf("Attr:0x%lx\n", Tbl->Attr); + printf("Name:"); + + for (i = 0; i < 36 && Tbl->Name[i]; i++) + { + printf("%c", (CHAR)(Tbl->Name[i])); + } + printf("\n"); +} + +void DumpMBR(MBR_HEAD *pMBR) +{ + int i; + + for (i = 0; i < 4; i++) + { + printf("=========== Partition Table %d ============\n", i + 1); + printf("PartTbl.Active = 0x%x\n", pMBR->PartTbl[i].Active); + printf("PartTbl.FsFlag = 0x%x\n", pMBR->PartTbl[i].FsFlag); + printf("PartTbl.StartSectorId = %u\n", pMBR->PartTbl[i].StartSectorId); + printf("PartTbl.SectorCount = %u\n", pMBR->PartTbl[i].SectorCount); + printf("PartTbl.StartHead = %u\n", pMBR->PartTbl[i].StartHead); + printf("PartTbl.StartSector = %u\n", pMBR->PartTbl[i].StartSector); + printf("PartTbl.StartCylinder = %u\n", pMBR->PartTbl[i].StartCylinder); + printf("PartTbl.EndHead = %u\n", pMBR->PartTbl[i].EndHead); + printf("PartTbl.EndSector = %u\n", pMBR->PartTbl[i].EndSector); + printf("PartTbl.EndCylinder = %u\n", pMBR->PartTbl[i].EndCylinder); + } +} + +int DumpGptInfo(VTOY_GPT_INFO *pGptInfo) +{ + int i; + + DumpMBR(&pGptInfo->MBR); + DumpHead(&pGptInfo->Head); + + for (i = 0; i < 128; i++) + { + if (pGptInfo->PartTbl[i].StartLBA == 0) + { + break; + } + + printf("=====Part %d=====\n", i); + DumpPartTable(pGptInfo->PartTbl + i); + } + + return 0; +} + +#define VENTOY_EFI_PART_ATTR 0x8000000000000001ULL + +int main(int argc, const char **argv) +{ + int i; + int fd; + UINT64 DiskSize; + CHAR16 *Name = NULL; + VTOY_GPT_INFO *pMainGptInfo = NULL; + VTOY_BK_GPT_INFO *pBackGptInfo = NULL; + + if (argc != 3) + { + printf("usage: vtoygpt -f /dev/sdb\n"); + return 1; + } + + fd = open(argv[2], O_RDWR); + if (fd < 0) + { + printf("Failed to open %s\n", argv[2]); + return 1; + } + + pMainGptInfo = malloc(sizeof(VTOY_GPT_INFO)); + pBackGptInfo = malloc(sizeof(VTOY_BK_GPT_INFO)); + if (NULL == pMainGptInfo || NULL == pBackGptInfo) + { + close(fd); + return 1; + } + + read(fd, pMainGptInfo, sizeof(VTOY_GPT_INFO)); + + if (argv[1][0] == '-' && argv[1][1] == 'd') + { + DumpGptInfo(pMainGptInfo); + } + else + { + DiskSize = lseek(fd, 0, SEEK_END); + lseek(fd, DiskSize - 33 * 512, SEEK_SET); + read(fd, pBackGptInfo, sizeof(VTOY_BK_GPT_INFO)); + + Name = pMainGptInfo->PartTbl[1].Name; + if (Name[0] == 'V' && Name[1] == 'T' && Name[2] == 'O' && Name[3] == 'Y') + { + pMainGptInfo->PartTbl[1].Attr = VENTOY_EFI_PART_ATTR; + pMainGptInfo->Head.PartTblCrc = VtoyCrc32(pMainGptInfo->PartTbl, sizeof(pMainGptInfo->PartTbl)); + pMainGptInfo->Head.Crc = 0; + pMainGptInfo->Head.Crc = VtoyCrc32(&pMainGptInfo->Head, pMainGptInfo->Head.Length); + + pBackGptInfo->PartTbl[1].Attr = VENTOY_EFI_PART_ATTR; + pBackGptInfo->Head.PartTblCrc = VtoyCrc32(pBackGptInfo->PartTbl, sizeof(pBackGptInfo->PartTbl)); + pBackGptInfo->Head.Crc = 0; + pBackGptInfo->Head.Crc = VtoyCrc32(&pBackGptInfo->Head, pBackGptInfo->Head.Length); + + lseek(fd, 512, SEEK_SET); + write(fd, (UINT8 *)pMainGptInfo + 512, sizeof(VTOY_GPT_INFO) - 512); + + lseek(fd, DiskSize - 33 * 512, SEEK_SET); + write(fd, pBackGptInfo, sizeof(VTOY_BK_GPT_INFO)); + + fsync(fd); + } + } + + free(pMainGptInfo); + free(pBackGptInfo); + close(fd); + + return 0; +} + diff --git a/vtoyjump/vtoyjump/vtoyjump.c b/vtoyjump/vtoyjump/vtoyjump.c index 0ee4ae46..ec671f59 100644 --- a/vtoyjump/vtoyjump/vtoyjump.c +++ b/vtoyjump/vtoyjump/vtoyjump.c @@ -513,6 +513,55 @@ static CHAR GetMountLogicalDrive(void) return Letter; } +UINT64 GetVentoyEfiPartStartSector(HANDLE hDrive) +{ + BOOL bRet; + DWORD dwSize; + MBR_HEAD MBR; + VTOY_GPT_INFO *pGpt = NULL; + UINT64 StartSector = 0; + + SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); + + bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL); + Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR); + + if ((!bRet) || (dwSize != sizeof(MBR))) + { + 0; + } + + if (MBR.PartTbl[0].FsFlag == 0xEE) + { + Log("GPT partition style"); + + pGpt = malloc(sizeof(VTOY_GPT_INFO)); + if (!pGpt) + { + return 0; + } + + SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); + bRet = ReadFile(hDrive, pGpt, sizeof(VTOY_GPT_INFO), &dwSize, NULL); + if ((!bRet) || (dwSize != sizeof(VTOY_GPT_INFO))) + { + Log("Failed to read gpt info %d %u %d", bRet, dwSize, LASTERR); + return 0; + } + + StartSector = pGpt->PartTbl[1].StartLBA; + free(pGpt); + } + else + { + Log("MBR partition style"); + StartSector = MBR.PartTbl[1].StartSectorId; + } + + Log("GetVentoyEfiPart StartSector: %llu", StartSector); + return StartSector; +} + int VentoyMountISOByImdisk(const char *IsoPath, DWORD PhyDrive) { int rc = 1; @@ -543,7 +592,7 @@ int VentoyMountISOByImdisk(const char *IsoPath, DWORD PhyDrive) } g_FatPhyDrive = hDrive; - g_Part2StartSec = (LengthInfo.Length.QuadPart - VENTOY_EFI_PART_SIZE) / 512; + g_Part2StartSec = GetVentoyEfiPartStartSector(hDrive); Log("Parse FAT fs..."); @@ -704,6 +753,150 @@ static int DeleteVentoyPart2MountPoint(DWORD PhyDrive) return 1; } +static BOOL check_tar_archive(const char *archive, CHAR *tarName) +{ + int len; + int nameLen; + const char *pos = archive; + const char *slash = archive; + + while (*pos) + { + if (*pos == '\\' || *pos == '/') + { + slash = pos; + } + pos++; + } + + len = (int)strlen(slash); + + if (len > 7 && (strncmp(slash + len - 7, ".tar.gz", 7) == 0 || strncmp(slash + len - 7, ".tar.xz", 7) == 0)) + { + nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash); + tarName[nameLen - 3] = 0; + return TRUE; + } + else if (len > 8 && strncmp(slash + len - 8, ".tar.bz2", 8) == 0) + { + nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash); + tarName[nameLen - 4] = 0; + return TRUE; + } + else if (len > 9 && strncmp(slash + len - 9, ".tar.lzma", 9) == 0) + { + nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash); + tarName[nameLen - 5] = 0; + return TRUE; + } + + return FALSE; +} + +static int DecompressInjectionArchive(const char *archive, DWORD PhyDrive) +{ + int rc = 1; + BOOL bRet; + DWORD dwBytes; + HANDLE hDrive; + HANDLE hOut; + DWORD flags = CREATE_NO_WINDOW; + CHAR StrBuf[MAX_PATH]; + CHAR tarName[MAX_PATH]; + STARTUPINFOA Si; + PROCESS_INFORMATION Pi; + PROCESS_INFORMATION NewPi; + GET_LENGTH_INFORMATION LengthInfo; + SECURITY_ATTRIBUTES Sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + + Log("DecompressInjectionArchive %s", archive); + + sprintf_s(StrBuf, sizeof(StrBuf), "\\\\.\\PhysicalDrive%d", PhyDrive); + hDrive = CreateFileA(StrBuf, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + if (hDrive == INVALID_HANDLE_VALUE) + { + Log("Could not open the disk<%s>, error:%u", StrBuf, GetLastError()); + goto End; + } + + bRet = DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &LengthInfo, sizeof(LengthInfo), &dwBytes, NULL); + if (!bRet) + { + Log("Could not get phy disk %s size, error:%u", StrBuf, GetLastError()); + goto End; + } + + g_FatPhyDrive = hDrive; + g_Part2StartSec = GetVentoyEfiPartStartSector(hDrive); + + Log("Parse FAT fs..."); + + fl_init(); + + if (0 == fl_attach_media(VentoyFatDiskRead, NULL)) + { + if (g_64bit_system) + { + CopyFileFromFatDisk("/ventoy/7z/64/7za.exe", "ventoy\\7za.exe"); + } + else + { + CopyFileFromFatDisk("/ventoy/7z/32/7za.exe", "ventoy\\7za.exe"); + } + + sprintf_s(StrBuf, sizeof(StrBuf), "ventoy\\7za.exe x -y -aoa -oX:\\ %s", archive); + + Log("extract inject to X:"); + Log("cmdline:<%s>", StrBuf); + + GetStartupInfoA(&Si); + + hOut = CreateFileA("ventoy\\7z.log", + FILE_APPEND_DATA, + FILE_SHARE_WRITE | FILE_SHARE_READ, + &Sa, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + Si.dwFlags |= STARTF_USESTDHANDLES; + + if (hOut != INVALID_HANDLE_VALUE) + { + Si.hStdError = hOut; + Si.hStdOutput = hOut; + } + + CreateProcessA(NULL, StrBuf, NULL, NULL, TRUE, flags, NULL, NULL, &Si, &Pi); + WaitForSingleObject(Pi.hProcess, INFINITE); + + // + // decompress tar archive, for tar.gz/tar.xz/tar.bz2 + // + if (check_tar_archive(archive, tarName)) + { + Log("Decompress tar archive...<%s>", tarName); + + sprintf_s(StrBuf, sizeof(StrBuf), "ventoy\\7za.exe x -y -aoa -oX:\\ %s", tarName); + + CreateProcessA(NULL, StrBuf, NULL, NULL, TRUE, flags, NULL, NULL, &Si, &NewPi); + WaitForSingleObject(NewPi.hProcess, INFINITE); + + Log("Now delete %s", tarName); + DeleteFileA(tarName); + } + + SAFE_CLOSE_HANDLE(hOut); + } + fl_shutdown(); + +End: + + SAFE_CLOSE_HANDLE(hDrive); + + return rc; +} + static int ProcessUnattendedInstallation(const char *script) { DWORD dw; @@ -809,6 +1002,24 @@ static int VentoyHook(ventoy_os_param *param) Log("auto install no need"); } + if (g_windows_data.injection_archive[0]) + { + sprintf_s(IsoPath, sizeof(IsoPath), "%C:%s", Letter, g_windows_data.injection_archive); + if (IsPathExist(FALSE, "%s", IsoPath)) + { + Log("decompress injection archive %s...", IsoPath); + DecompressInjectionArchive(IsoPath, DiskExtent.DiskNumber); + } + else + { + Log("injection archive %s not exist", IsoPath); + } + } + else + { + Log("no injection archive found"); + } + return 0; } diff --git a/vtoyjump/vtoyjump/vtoyjump.h b/vtoyjump/vtoyjump/vtoyjump.h index 35fa7276..01b96eed 100644 --- a/vtoyjump/vtoyjump/vtoyjump.h +++ b/vtoyjump/vtoyjump/vtoyjump.h @@ -68,9 +68,76 @@ typedef struct ventoy_os_param typedef struct ventoy_windows_data { char auto_install_script[384]; - UINT8 reserved[128]; + char injection_archive[384]; + UINT8 reserved[256]; }ventoy_windows_data; + + +typedef struct PART_TABLE +{ + UINT8 Active; // 0x00 0x80 + + UINT8 StartHead; + UINT16 StartSector : 6; + UINT16 StartCylinder : 10; + + UINT8 FsFlag; + + UINT8 EndHead; + UINT16 EndSector : 6; + UINT16 EndCylinder : 10; + + UINT32 StartSectorId; + UINT32 SectorCount; +}PART_TABLE; + +typedef struct MBR_HEAD +{ + UINT8 BootCode[446]; + PART_TABLE PartTbl[4]; + UINT8 Byte55; + UINT8 ByteAA; +}MBR_HEAD; + +typedef struct VTOY_GPT_HDR +{ + CHAR Signature[8]; /* EFI PART */ + UINT8 Version[4]; + UINT32 Length; + UINT32 Crc; + UINT8 Reserved1[4]; + UINT64 EfiStartLBA; + UINT64 EfiBackupLBA; + UINT64 PartAreaStartLBA; + UINT64 PartAreaEndLBA; + GUID DiskGuid; + UINT64 PartTblStartLBA; + UINT32 PartTblTotNum; + UINT32 PartTblEntryLen; + UINT32 PartTblCrc; + UINT8 Reserved2[420]; +}VTOY_GPT_HDR; + +typedef struct VTOY_GPT_PART_TBL +{ + GUID PartType; + GUID PartGuid; + UINT64 StartLBA; + UINT64 LastLBA; + UINT64 Attr; + UINT16 Name[36]; +}VTOY_GPT_PART_TBL; + +typedef struct VTOY_GPT_INFO +{ + MBR_HEAD MBR; + VTOY_GPT_HDR Head; + VTOY_GPT_PART_TBL PartTbl[128]; +}VTOY_GPT_INFO; + + + #pragma pack() @@ -83,5 +150,6 @@ typedef struct ventoy_windows_data }\ } +#define LASTERR GetLastError() #endif