This commit is contained in:
longpanda
2020-07-03 23:20:35 +08:00
parent 0ddc76a3aa
commit 1d034f0a24
33 changed files with 2364 additions and 140 deletions

View File

@@ -52,6 +52,8 @@ 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;
BOOLEAN g_fix_windows_1st_cdrom_issue = FALSE;
STATIC BOOLEAN g_hook_keyboard = FALSE;
CHAR16 gFirstTryBootFile[256] = {0};
@@ -493,6 +495,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))
@@ -559,12 +562,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 +589,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 +619,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;
}
@@ -636,6 +653,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 +780,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))
{

View File

@@ -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
@@ -216,6 +225,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 +252,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 +289,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 +339,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 +350,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

View File

@@ -36,9 +36,9 @@
#include <Protocol/SimpleFileSystem.h>
#include <Ventoy.h>
#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;
}

View File

@@ -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
@@ -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);
@@ -916,3 +959,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;
}

View File

@@ -0,0 +1,179 @@
/******************************************************************************
* Memhole.c
*
* Copyright (c) 2020, longpanda <admin@ventoy.net>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include <Uefi.h>
#include <Library/DebugLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Protocol/LoadedImage.h>
#include <Guid/FileInfo.h>
#include <Guid/FileSystemInfo.h>
#include <Protocol/BlockIo.h>
#include <Protocol/RamDisk.h>
#include <Protocol/SimpleFileSystem.h>
#include <VtoyUtil.h>
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;
}

View File

@@ -0,0 +1,135 @@
/******************************************************************************
* VtoyUtil.c
*
* Copyright (c) 2020, longpanda <admin@ventoy.net>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include <Uefi.h>
#include <Library/DebugLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Protocol/LoadedImage.h>
#include <Guid/FileInfo.h>
#include <Guid/FileSystemInfo.h>
#include <Protocol/BlockIo.h>
#include <Protocol/RamDisk.h>
#include <Protocol/SimpleFileSystem.h>
#include <VtoyUtil.h>
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;
}

View File

@@ -0,0 +1,61 @@
/******************************************************************************
* VtoyUtil.h
*
* Copyright (c) 2020, longpanda <admin@ventoy.net>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#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

View File

@@ -0,0 +1,80 @@
#************************************************************************************
# Copyright (c) 2020, longpanda <admin@ventoy.net>
#
# 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 <http://www.gnu.org/licenses/>.
#
#************************************************************************************
[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

View File

@@ -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