mirror of
https://github.com/ventoy/Ventoy.git
synced 2024-09-19 23:48:49 -04:00
Support WinPE with PESET.EXE
This commit is contained in:
parent
c18399e8b4
commit
67b8a34e8c
5 changed files with 207 additions and 61 deletions
|
@ -53,6 +53,26 @@ void ventoy_debug(const char *fmt, ...)
|
||||||
va_end (args);
|
va_end (args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ventoy_str_tolower(char *str)
|
||||||
|
{
|
||||||
|
while (*str)
|
||||||
|
{
|
||||||
|
*str = grub_tolower(*str);
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ventoy_str_toupper(char *str)
|
||||||
|
{
|
||||||
|
while (*str)
|
||||||
|
{
|
||||||
|
*str = grub_toupper(*str);
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int ventoy_strcmp(const char *pattern, const char *str)
|
int ventoy_strcmp(const char *pattern, const char *str)
|
||||||
{
|
{
|
||||||
while (*pattern && *str)
|
while (*pattern && *str)
|
||||||
|
|
|
@ -5087,7 +5087,6 @@ static cmd_para ventoy_cmds[] =
|
||||||
{ "vt_check_json_path_case", ventoy_cmd_chk_json_pathcase, 0, NULL, "", "", NULL },
|
{ "vt_check_json_path_case", ventoy_cmd_chk_json_pathcase, 0, NULL, "", "", NULL },
|
||||||
{ "vt_append_extra_sector", ventoy_cmd_append_ext_sector, 0, NULL, "", "", NULL },
|
{ "vt_append_extra_sector", ventoy_cmd_append_ext_sector, 0, NULL, "", "", NULL },
|
||||||
{ "gptpriority", grub_cmd_gptpriority, 0, NULL, "", "", NULL },
|
{ "gptpriority", grub_cmd_gptpriority, 0, NULL, "", "", NULL },
|
||||||
{ "vt_wim_peset", ventoy_cmd_wim_peset, 0, NULL, "", "", NULL },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int ventoy_register_all_cmd(void)
|
int ventoy_register_all_cmd(void)
|
||||||
|
|
|
@ -434,6 +434,18 @@ typedef struct wim_directory_entry
|
||||||
/** No security information exists for this file */
|
/** No security information exists for this file */
|
||||||
#define WIM_NO_SECURITY 0xffffffffUL
|
#define WIM_NO_SECURITY 0xffffffffUL
|
||||||
|
|
||||||
|
typedef struct reg_vk
|
||||||
|
{
|
||||||
|
grub_uint32_t res1;
|
||||||
|
grub_uint16_t sig;
|
||||||
|
grub_uint16_t namesize;
|
||||||
|
grub_uint32_t datasize;
|
||||||
|
grub_uint32_t dataoffset;
|
||||||
|
grub_uint32_t datatype;
|
||||||
|
grub_uint16_t flag;
|
||||||
|
grub_uint16_t res2;
|
||||||
|
}reg_vk;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
|
||||||
|
@ -586,7 +598,6 @@ grub_err_t ventoy_cmd_is_pe64(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
|
grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||||
grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc, char **args);
|
grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||||
grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
|
grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||||
grub_err_t ventoy_cmd_wim_peset(grub_extcmd_context_t ctxt, int argc, char **args);
|
|
||||||
grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args);
|
grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||||
grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args);
|
grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||||
grub_err_t ventoy_cmd_sel_wimboot(grub_extcmd_context_t ctxt, int argc, char **args);
|
grub_err_t ventoy_cmd_sel_wimboot(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||||
|
@ -1018,6 +1029,8 @@ extern grub_uint32_t g_ventoy_plat_data;
|
||||||
#define ventoy_syscall0(name) grub_##name()
|
#define ventoy_syscall0(name) grub_##name()
|
||||||
#define ventoy_syscall1(name, a) grub_##name(a)
|
#define ventoy_syscall1(name, a) grub_##name(a)
|
||||||
|
|
||||||
|
void ventoy_str_tolower(char *str);
|
||||||
|
void ventoy_str_toupper(char *str);
|
||||||
char * ventoy_get_line(char *start);
|
char * ventoy_get_line(char *start);
|
||||||
int ventoy_cmp_img(img_info *img1, img_info *img2);
|
int ventoy_cmp_img(img_info *img1, img_info *img2);
|
||||||
void ventoy_swap_img(img_info *img1, img_info *img2);
|
void ventoy_swap_img(img_info *img1, img_info *img2);
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
static int g_peset_flag = 0;
|
|
||||||
static int g_iso_fs_type = 0;
|
static int g_iso_fs_type = 0;
|
||||||
static int g_wim_total_patch_count = 0;
|
static int g_wim_total_patch_count = 0;
|
||||||
static int g_wim_valid_patch_count = 0;
|
static int g_wim_valid_patch_count = 0;
|
||||||
|
@ -418,7 +417,6 @@ grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char *
|
||||||
g_wim_patch_head = NULL;
|
g_wim_patch_head = NULL;
|
||||||
g_wim_total_patch_count = 0;
|
g_wim_total_patch_count = 0;
|
||||||
g_wim_valid_patch_count = 0;
|
g_wim_valid_patch_count = 0;
|
||||||
g_peset_flag = 0;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -660,40 +658,6 @@ static wim_directory_entry * search_full_wim_dirent
|
||||||
return search;
|
return search;
|
||||||
}
|
}
|
||||||
|
|
||||||
static wim_directory_entry * search_replace_wim_dirent(void *meta_data, wim_directory_entry *dir)
|
|
||||||
{
|
|
||||||
wim_directory_entry *tmp_dirent = NULL;
|
|
||||||
wim_directory_entry *wim_dirent = NULL;
|
|
||||||
const char *peset_path[] = { "Windows", "System32", "peset.exe", NULL };
|
|
||||||
const char *pecmd_path[] = { "Windows", "System32", "pecmd.exe", NULL };
|
|
||||||
const char *winpeshl_path[] = { "Windows", "System32", "winpeshl.exe", NULL };
|
|
||||||
|
|
||||||
wim_dirent = search_full_wim_dirent(meta_data, dir, pecmd_path);
|
|
||||||
debug("search pecmd.exe %p\n", wim_dirent);
|
|
||||||
if (wim_dirent)
|
|
||||||
{
|
|
||||||
if (g_peset_flag)
|
|
||||||
{
|
|
||||||
tmp_dirent = search_full_wim_dirent(meta_data, dir, peset_path);
|
|
||||||
debug("search peset.exe %p\n", tmp_dirent);
|
|
||||||
if (tmp_dirent)
|
|
||||||
{
|
|
||||||
return tmp_dirent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return wim_dirent;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static wim_lookup_entry * ventoy_find_look_entry(wim_header *header, wim_lookup_entry *lookup, wim_hash *hash)
|
static wim_lookup_entry * ventoy_find_look_entry(wim_header *header, wim_lookup_entry *lookup, wim_hash *hash)
|
||||||
|
@ -711,6 +675,169 @@ static wim_lookup_entry * ventoy_find_look_entry(wim_header *header, wim_lookup_
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_registry_setup_cmdline
|
||||||
|
(
|
||||||
|
grub_file_t file,
|
||||||
|
wim_header *head,
|
||||||
|
wim_lookup_entry *lookup,
|
||||||
|
void *meta_data,
|
||||||
|
wim_directory_entry *dir,
|
||||||
|
char *buf,
|
||||||
|
grub_uint32_t buflen
|
||||||
|
)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
grub_uint32_t i = 0;
|
||||||
|
grub_uint32_t reglen = 0;
|
||||||
|
wim_hash zerohash;
|
||||||
|
reg_vk *regvk = NULL;
|
||||||
|
wim_lookup_entry *look = NULL;
|
||||||
|
wim_directory_entry *wim_dirent = NULL;
|
||||||
|
char *decompress_data = NULL;
|
||||||
|
const char *reg_path[] = { "Windows", "System32", "config", "SYSTEM", NULL };
|
||||||
|
|
||||||
|
wim_dirent = search_full_wim_dirent(meta_data, dir, reg_path);
|
||||||
|
debug("search reg SYSTEM %p\n", wim_dirent);
|
||||||
|
if (!wim_dirent)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_memset(&zerohash, 0, sizeof(zerohash));
|
||||||
|
if (grub_memcmp(&zerohash, wim_dirent->hash.sha1, sizeof(wim_hash)) == 0)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
look = ventoy_find_look_entry(head, lookup, &wim_dirent->hash);
|
||||||
|
if (!look)
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
reglen = (grub_uint32_t)look->resource.raw_size;
|
||||||
|
debug("find system lookup entry_id:%ld raw_size:%u\n",
|
||||||
|
((long)look - (long)lookup) / sizeof(wim_lookup_entry), reglen);
|
||||||
|
|
||||||
|
if (0 != ventoy_read_resource(file, head, &(look->resource), (void **)&(decompress_data)))
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_strncmp(decompress_data + 0x1000, "hbin", 4))
|
||||||
|
{
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0x1000; i + sizeof(reg_vk) < reglen; i += 8)
|
||||||
|
{
|
||||||
|
regvk = (reg_vk *)(decompress_data + i);
|
||||||
|
if (regvk->sig == 0x6B76 && regvk->namesize == 7 &&
|
||||||
|
regvk->datatype == 1 && regvk->flag == 1)
|
||||||
|
{
|
||||||
|
if (grub_strncasecmp((char *)(regvk + 1), "cmdline", 7) == 0)
|
||||||
|
{
|
||||||
|
debug("find registry cmdline i:%u offset:(0x%x)%u size:(0x%x)%u\n",
|
||||||
|
i, regvk->dataoffset, regvk->dataoffset, regvk->datasize, regvk->datasize);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i + sizeof(reg_vk) >= reglen || regvk == NULL)
|
||||||
|
{
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regvk->datasize == 0 || (regvk->datasize & 0x80000000) > 0 ||
|
||||||
|
regvk->dataoffset == 0 || regvk->dataoffset == 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regvk->datasize / 2 >= buflen)
|
||||||
|
{
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("start offset is 0x%x(%u)\n", 0x1000 + regvk->dataoffset + 4, 0x1000 + regvk->dataoffset + 4);
|
||||||
|
|
||||||
|
for (i = 0; i < regvk->datasize; i+=2)
|
||||||
|
{
|
||||||
|
c = (char)(*(grub_uint16_t *)(decompress_data + 0x1000 + regvk->dataoffset + 4 + i));
|
||||||
|
*buf++ = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_free(decompress_data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static wim_directory_entry * search_replace_wim_dirent
|
||||||
|
(
|
||||||
|
grub_file_t file,
|
||||||
|
wim_header *head,
|
||||||
|
wim_lookup_entry *lookup,
|
||||||
|
void *meta_data,
|
||||||
|
wim_directory_entry *dir
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char cmdline[256] = {0};
|
||||||
|
wim_directory_entry *wim_dirent = NULL;
|
||||||
|
const char *peset_path[] = { "Windows", "System32", "peset.exe", NULL };
|
||||||
|
const char *pecmd_path[] = { "Windows", "System32", "pecmd.exe", NULL };
|
||||||
|
const char *winpeshl_path[] = { "Windows", "System32", "winpeshl.exe", NULL };
|
||||||
|
|
||||||
|
ret = parse_registry_setup_cmdline(file, head, lookup, meta_data, dir, cmdline, sizeof(cmdline));
|
||||||
|
if (0 == ret)
|
||||||
|
{
|
||||||
|
debug("registry setup cmdline:<%s>\n", cmdline);
|
||||||
|
ventoy_str_toupper(cmdline);
|
||||||
|
|
||||||
|
if (grub_strncmp(cmdline, "PECMD", 5) == 0)
|
||||||
|
{
|
||||||
|
wim_dirent = search_full_wim_dirent(meta_data, dir, pecmd_path);
|
||||||
|
debug("search pecmd.exe %p\n", wim_dirent);
|
||||||
|
}
|
||||||
|
else if (grub_strncmp(cmdline, "PESET", 5) == 0)
|
||||||
|
{
|
||||||
|
wim_dirent = search_full_wim_dirent(meta_data, dir, peset_path);
|
||||||
|
debug("search peset.exe %p\n", wim_dirent);
|
||||||
|
}
|
||||||
|
else if (grub_strncmp(cmdline, "WINPESHL", 8) == 0)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debug("registry setup cmdline failed : %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
wim_dirent = search_full_wim_dirent(meta_data, dir, pecmd_path);
|
||||||
|
debug("search pecmd.exe %p\n", wim_dirent);
|
||||||
|
if (wim_dirent)
|
||||||
|
{
|
||||||
|
return wim_dirent;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static wim_lookup_entry * ventoy_find_meta_entry(wim_header *header, wim_lookup_entry *lookup)
|
static wim_lookup_entry * ventoy_find_meta_entry(wim_header *header, wim_lookup_entry *lookup)
|
||||||
{
|
{
|
||||||
grub_uint32_t i = 0;
|
grub_uint32_t i = 0;
|
||||||
|
@ -1022,8 +1149,16 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch)
|
||||||
rootdir = (wim_directory_entry *)(decompress_data + 8);
|
rootdir = (wim_directory_entry *)(decompress_data + 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
debug("read lookup offset:%llu size:%llu\n", (ulonglong)head->lookup.offset, (ulonglong)head->lookup.raw_size);
|
||||||
|
lookup = grub_malloc(head->lookup.raw_size);
|
||||||
|
grub_file_seek(file, head->lookup.offset);
|
||||||
|
grub_file_read(file, lookup, head->lookup.raw_size);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* search winpeshl.exe dirent entry */
|
/* search winpeshl.exe dirent entry */
|
||||||
search = search_replace_wim_dirent(decompress_data, rootdir);
|
search = search_replace_wim_dirent(file, head, lookup, decompress_data, rootdir);
|
||||||
if (!search)
|
if (!search)
|
||||||
{
|
{
|
||||||
debug("Failed to find replace file %p\n", search);
|
debug("Failed to find replace file %p\n", search);
|
||||||
|
@ -1055,10 +1190,6 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch)
|
||||||
grub_memcpy(&patch->old_hash, search->hash.sha1, sizeof(wim_hash));
|
grub_memcpy(&patch->old_hash, search->hash.sha1, sizeof(wim_hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("read lookup offset:%llu size:%llu\n", (ulonglong)head->lookup.offset, (ulonglong)head->lookup.raw_size);
|
|
||||||
lookup = grub_malloc(head->lookup.raw_size);
|
|
||||||
grub_file_seek(file, head->lookup.offset);
|
|
||||||
grub_file_read(file, lookup, head->lookup.raw_size);
|
|
||||||
|
|
||||||
/* find and extact winpeshl.exe */
|
/* find and extact winpeshl.exe */
|
||||||
patch->replace_look = ventoy_find_look_entry(head, lookup, &patch->old_hash);
|
patch->replace_look = ventoy_find_look_entry(head, lookup, &patch->old_hash);
|
||||||
|
@ -1843,17 +1974,6 @@ grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, c
|
||||||
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_err_t ventoy_cmd_wim_peset(grub_extcmd_context_t ctxt, int argc, char **args)
|
|
||||||
{
|
|
||||||
(void)ctxt;
|
|
||||||
(void)argc;
|
|
||||||
(void)args;
|
|
||||||
|
|
||||||
g_peset_flag = 1;
|
|
||||||
|
|
||||||
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args)
|
grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
{
|
{
|
||||||
grub_uint32_t i = 0;
|
grub_uint32_t i = 0;
|
||||||
|
|
|
@ -156,12 +156,6 @@ function locate_initrd {
|
||||||
}
|
}
|
||||||
|
|
||||||
function locate_wim {
|
function locate_wim {
|
||||||
if vt_strstr "$vt_volume_id" "yr"; then
|
|
||||||
if [ -f (loop)/isyl/isyl ]; then
|
|
||||||
vt_wim_peset
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
vt_windows_locate_wim_patch (loop)
|
vt_windows_locate_wim_patch (loop)
|
||||||
|
|
||||||
if [ -n "${vtdebug_flag}" ]; then
|
if [ -n "${vtdebug_flag}" ]; then
|
||||||
|
|
Loading…
Reference in a new issue