}
}
+char *ventoy_str_last(char *str, char ch)
+{
+ char *pos = NULL;
+ char *last = NULL;
+
+ if (!str)
+ {
+ return NULL;
+ }
+ for (pos = str; *pos; pos++)
+ {
+ if (*pos == ch)
+ {
+ last = pos;
+ }
+ }
+
+ return last;
+}
int ventoy_strcmp(const char *pattern, const char *str)
{
#include <grub/charset.h>
#include <grub/crypto.h>
#include <grub/lib/crc.h>
+#include <grub/random.h>
#include <grub/ventoy.h>
#include "ventoy_def.h"
#include "miniz.h"
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
+static int ventoy_var_expand(int *flag, const char *var, char *value, int len)
+{
+ int i = 0;
+ int n = 0;
+ char c;
+ grub_uint8_t bytes[32];
+
+ if (grub_strncmp(var, "VT_RAND_", 8) == 0)
+ {
+ grub_crypto_get_random(bytes, sizeof(bytes));
+ if (grub_strcmp(var + 8, "9") == 0)
+ {
+ n = 1;
+ }
+ else if (grub_strcmp(var + 8, "99") == 0)
+ {
+ n = 2;
+ }
+ else if (grub_strcmp(var + 8, "999") == 0)
+ {
+ n = 3;
+ }
+ else if (grub_strcmp(var + 8, "9999") == 0)
+ {
+ n = 4;
+ }
+
+ for (i = 0; i < n; i++)
+ {
+ value[i] = '0' + (bytes[i] % 10);
+ }
+ }
+ else
+ {
+ if (*flag == 0)
+ {
+ *flag = 1;
+ grub_printf("\n=================== Parameter Expansion ===================\n\n");
+ }
+
+ grub_printf("<%s>: ", var);
+ grub_refresh();
+
+ while (i < (len - 1))
+ {
+ c = grub_getkey();
+ if ((c == '\n') || (c == '\r'))
+ {
+ grub_printf("\n");
+ grub_refresh();
+ break;
+ }
+
+ if (grub_isprint(c))
+ {
+ grub_printf("%c", c);
+ grub_refresh();
+ value[i++] = c;
+ value[i] = 0;
+ }
+ else if (c == '\b')
+ {
+ if (i > 0)
+ {
+ value[i - 1] = ' ';
+ grub_printf("\r<%s>: %s", var, value);
+
+ value[i - 1] = 0;
+ grub_printf("\r<%s>: %s", var, value);
+
+ grub_refresh();
+ i--;
+ }
+ }
+ }
+ }
+
+ if (value[0] == 0)
+ {
+ grub_snprintf(value, len, "%s", var);
+ }
+
+ return 0;
+}
+
+static int ventoy_auto_install_var_expand(install_template *node)
+{
+ int pos = 0;
+ int flag = 0;
+ int newlen = 0;
+ char *start = NULL;
+ char *end = NULL;
+ char *newbuf = NULL;
+ char *curline = NULL;
+ char *nextline = NULL;
+ grub_uint8_t *code = NULL;
+ char value[512];
+
+ code = (grub_uint8_t *)node->filebuf;
+
+ if ((code[0] == 0xff && code[1] == 0xfe) || (code[0] == 0xfe && code[1] == 0xff))
+ {
+ debug("UCS-2 encoding NOT supported\n");
+ return 0;
+ }
+
+ start = grub_strstr(node->filebuf, "$<");
+ if (!start)
+ {
+ debug("no need to expand variable, no start.\n");
+ return 0;
+ }
+
+ end = grub_strstr(start + 2, ">$");
+ if (!end)
+ {
+ debug("no need to expand variable, no end.\n");
+ return 0;
+ }
+
+ newlen = grub_max(node->filelen * 10, VTOY_SIZE_128KB);
+ newbuf = grub_malloc(newlen);
+ if (!newbuf)
+ {
+ debug("Failed to alloc newbuf %d\n", newlen);
+ return 0;
+ }
+
+ for (curline = node->filebuf; curline; curline = nextline)
+ {
+ nextline = ventoy_get_line(curline);
+
+ start = grub_strstr(curline, "$<");
+ if (start)
+ {
+ end = grub_strstr(start + 2, ">$");
+ }
+
+ if (start && end)
+ {
+ *start = *end = 0;
+ VTOY_APPEND_NEWBUF(curline);
+
+ value[sizeof(value) - 1] = 0;
+ ventoy_var_expand(&flag, start + 2, value, sizeof(value) - 1);
+ VTOY_APPEND_NEWBUF(value);
+
+ VTOY_APPEND_NEWBUF(end + 2);
+ }
+ else
+ {
+ VTOY_APPEND_NEWBUF(curline);
+ }
+
+ newbuf[pos++] = '\n';
+ }
+
+ grub_free(node->filebuf);
+ node->filebuf = newbuf;
+ node->filelen = pos;
+
+ return 0;
+}
+
static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int argc, char **args)
{
int i = 0;
int pos = 0;
int defidx = 1;
char *buf = NULL;
+ grub_file_t file = NULL;
char configfile[128];
install_template *node = NULL;
node->cursel = g_ventoy_last_entry - 1;
+ grub_check_free(node->filebuf);
+ node->filelen = 0;
+
+ if (node->cursel >= 0 && node->cursel < node->templatenum)
+ {
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", ventoy_get_env("vtoy_iso_part"),
+ node->templatepath[node->cursel].path);
+ if (file)
+ {
+ node->filebuf = grub_malloc(file->size + 1);
+ if (node->filebuf)
+ {
+ grub_file_read(file, node->filebuf, file->size);
+ grub_file_close(file);
+ node->filebuf[file->size] = 0;
+ node->filelen = (int)file->size;
+
+ ventoy_auto_install_var_expand(node);
+ }
+ }
+ else
+ {
+ debug("Failed to open auto install script <%s%s>\n",
+ ventoy_get_env("vtoy_iso_part"), node->templatepath[node->cursel].path);
+ }
+ }
+
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
#define VTOY_SIZE_512KB (512 * 1024)
#define VTOY_SIZE_1KB 1024
#define VTOY_SIZE_32KB (32 * 1024)
+#define VTOY_SIZE_128KB (128 * 1024)
#define JSON_SUCCESS 0
#define JSON_FAILED 1
#define JSON_NOT_FOUND 2
+#define WINDATA_FLAG_TEMPLATE 1
+
#define ulong unsigned long
#define ulonglong unsigned long long
return (err);\
}
+#define VTOY_APPEND_NEWBUF(buf) \
+{\
+ char *__c = buf;\
+ while (*__c)\
+ {\
+ newbuf[pos++] = *__c;\
+ __c++;\
+ }\
+}
+
typedef enum VTOY_FILE_FLT
{
VTOY_FILE_FLT_ISO = 0, /* .iso */
grub_uint8_t *jump_bin_data;
grub_uint32_t bin_raw_len;
grub_uint32_t bin_align_len;
+ grub_uint32_t windata_flag;
grub_uint8_t *new_meta_data;
grub_uint32_t new_meta_len;
int templatenum;
file_fullpath *templatepath;
+ char *filebuf;
+ int filelen;
+
struct install_template *next;
}install_template;
void ventoy_str_tolower(char *str);
void ventoy_str_toupper(char *str);
char * ventoy_get_line(char *start);
+char *ventoy_str_last(char *str, char ch);
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);
+char * ventoy_plugin_get_cur_install_template(const char *isopath, install_template **cur);
install_template * ventoy_plugin_find_install_template(const char *isopath);
persistence_config * ventoy_plugin_find_persistent(const char *isopath);
grub_uint64_t ventoy_get_vtoy_partsize(int part);
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_injection(const char *isopath);
const char * ventoy_plugin_get_menu_alias(int type, const char *isopath);
grub_file_t file;
grub_file_t archfile;
grub_file_t tmpfile;
+ install_template *template_node = NULL;
ventoy_img_chunk_list chunk_list;
(void)ctxt;
persistent_buf = (char *)(chunk_list.chunk);
}
- template_file = ventoy_plugin_get_cur_install_template(args[1]);
+ template_file = ventoy_plugin_get_cur_install_template(args[1], &template_node);
if (template_file)
{
- debug("auto install template: <%s>\n", template_file);
- tmpfile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[2], template_file);
- if (tmpfile)
- {
- 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(tmpfile, template_buf, template_size);
- }
-
- grub_file_close(tmpfile);
- }
- else
+ debug("auto install template: <%s> <addr:%p> <len:%d>\n",
+ template_file, template_node->filebuf, template_node->filelen);
+
+ template_size = template_node->filelen;
+ template_buf = grub_malloc(template_size);
+ if (template_buf)
{
- debug("Failed to open install script %s%s\n", args[2], template_file);
+ grub_memcpy(template_buf, template_node->filebuf, template_size);
}
}
else
{
headlen = ventoy_cpio_newc_fill_head(buf, template_size, template_buf, "ventoy/autoinstall");
buf += headlen + ventoy_align(template_size, 4);
+ grub_check_free(template_buf);
}
if (persistent_size > 0 && persistent_buf)
{
headlen = ventoy_cpio_newc_fill_head(buf, persistent_size, persistent_buf, "ventoy/ventoy_persistent_map");
buf += headlen + ventoy_align(persistent_size, 4);
-
- grub_free(persistent_buf);
- persistent_buf = NULL;
+ grub_check_free(persistent_buf);
}
if (injection_size > 0 && injection_buf)
return NULL;
}
-char * ventoy_plugin_get_cur_install_template(const char *isopath)
+char * ventoy_plugin_get_cur_install_template(const char *isopath, install_template **cur)
{
install_template *node = NULL;
+ if (cur)
+ {
+ *cur = NULL;
+ }
+
node = ventoy_plugin_find_install_template(isopath);
if ((!node) || (!node->templatepath))
{
return NULL;
}
+ if (cur)
+ {
+ *cur = node;
+ }
+
return node->templatepath[node->cursel].path;
}
return 0;
}
-static int ventoy_cat_exe_file_data(wim_tail *wim_data, grub_uint32_t exe_len, grub_uint8_t *exe_data)
+static int ventoy_cat_exe_file_data(wim_tail *wim_data, grub_uint32_t exe_len, grub_uint8_t *exe_data, int windatalen)
{
int pe64 = 0;
char file[256];
jump_align = ventoy_align(jump_len, 16);
wim_data->jump_exe_len = jump_len;
- wim_data->bin_raw_len = jump_align + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data) + exe_len;
+ wim_data->bin_raw_len = jump_align + sizeof(ventoy_os_param) + windatalen + exe_len;
wim_data->bin_align_len = ventoy_align(wim_data->bin_raw_len, 2048);
wim_data->jump_bin_data = grub_malloc(wim_data->bin_align_len);
if (wim_data->jump_bin_data)
{
grub_memcpy(wim_data->jump_bin_data, jump_data, jump_len);
- grub_memcpy(wim_data->jump_bin_data + jump_align + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data), exe_data, exe_len);
+ grub_memcpy(wim_data->jump_bin_data + jump_align + sizeof(ventoy_os_param) + windatalen, exe_data, exe_len);
}
debug("jump_exe_len:%u bin_raw_len:%u bin_align_len:%u\n",
return 0;
}
-int ventoy_fill_windows_rtdata(void *buf, char *isopath)
+static int ventoy_get_windows_rtdata_len(const char *iso, int *flag)
{
+ int size = 0;
+ int template_file_len = 0;
char *pos = NULL;
char *script = NULL;
+ install_template *template_node = NULL;
+
+ *flag = 0;
+ size = (int)sizeof(ventoy_windows_data);
+
+ pos = grub_strstr(iso, "/");
+ if (!pos)
+ {
+ return size;
+ }
+
+ script = ventoy_plugin_get_cur_install_template(pos, &template_node);
+ if (script)
+ {
+ (*flag) |= WINDATA_FLAG_TEMPLATE;
+ template_file_len = template_node->filelen;
+ }
+
+ return size + template_file_len;
+}
+
+static int ventoy_fill_windows_rtdata(void *buf, char *isopath, int dataflag)
+{
+ int template_len = 0;
+ char *pos = NULL;
+ char *end = NULL;
+ char *script = NULL;
const char *env = NULL;
+ install_template *template_node = NULL;
ventoy_windows_data *data = (ventoy_windows_data *)buf;
grub_memset(data, 0, sizeof(ventoy_windows_data));
+ env = grub_env_get("VTOY_WIN11_BYPASS_CHECK");
+ if (env && env[0] == '1' && env[1] == 0)
+ {
+ data->windows11_bypass_check = 1;
+ }
+
pos = grub_strstr(isopath, "/");
if (!pos)
{
return 1;
}
- script = ventoy_plugin_get_cur_install_template(pos);
- if (script)
+ if (dataflag & WINDATA_FLAG_TEMPLATE)
{
- debug("auto install script <%s>\n", script);
- grub_snprintf(data->auto_install_script, sizeof(data->auto_install_script) - 1, "%s", script);
+ script = ventoy_plugin_get_cur_install_template(pos, &template_node);
+ if (script)
+ {
+ data->auto_install_len = template_len = template_node->filelen;
+ debug("auto install script OK <%s> <len:%d>\n", script, template_len);
+ end = ventoy_str_last(script, '/');
+ grub_snprintf(data->auto_install_script, sizeof(data->auto_install_script) - 1, "%s", end ? end + 1 : script);
+ grub_memcpy(data + 1, template_node->filebuf, template_len);
+ }
}
else
{
debug("injection archive not configed %s\n", pos);
}
- env = grub_env_get("VTOY_WIN11_BYPASS_CHECK");
- if (env && env[0] == '1' && env[1] == 0)
- {
- data->windows11_bypass_check = 1;
- }
-
return 0;
}
if (wim_data->jump_bin_data)
{
grub_memcpy(wim_data->jump_bin_data + jump_align, param, sizeof(ventoy_os_param));
- ventoy_fill_windows_rtdata(wim_data->jump_bin_data + jump_align + sizeof(ventoy_os_param), isopath);
+ ventoy_fill_windows_rtdata(wim_data->jump_bin_data + jump_align + sizeof(ventoy_os_param), isopath, wim_data->windata_flag);
}
grub_crypto_hash(GRUB_MD_SHA1, wim_data->bin_hash.sha1, wim_data->jump_bin_data, wim_data->bin_raw_len);
return 0;
}
-static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch)
+static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch, int windatalen)
{
int rc;
grub_uint16_t i;
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);
+ ventoy_cat_exe_file_data(wim_data, exe_len, exe_data, windatalen);
grub_free(exe_data);
}
else
grub_err_t ventoy_cmd_locate_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args)
{
+ int datalen = 0;
+ int dataflag = 0;
wim_patch *node = g_wim_patch_head;
(void)ctxt;
(void)argc;
(void)args;
+ datalen = ventoy_get_windows_rtdata_len(args[1], &dataflag);
+
while (node)
{
- if (0 == ventoy_wimdows_locate_wim(args[0], node))
+ node->wim_data.windata_flag = dataflag;
+ if (0 == ventoy_wimdows_locate_wim(args[0], node, datalen))
{
node->valid = 1;
g_wim_valid_patch_count++;
grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc, char **args)
{
+ int datalen = 0;
+ int dataflag = 0;
grub_uint32_t size = 0;
const char *addr = NULL;
ventoy_chain_head *chain = NULL;
return 1;
}
- size = sizeof(ventoy_os_param) + sizeof(ventoy_windows_data);
+ datalen = ventoy_get_windows_rtdata_len(chain->os_param.vtoy_img_path, &dataflag);
+
+ size = sizeof(ventoy_os_param) + datalen;
param = (ventoy_os_param *)grub_zalloc(size);
if (!param)
{
}
grub_memcpy(param, &chain->os_param, sizeof(ventoy_os_param));
- ventoy_fill_windows_rtdata(param + 1, param->vtoy_img_path);
+ ventoy_fill_windows_rtdata(param + 1, param->vtoy_img_path, dataflag);
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)param);
grub_env_set("vtoy_wimboot_mem_addr", envbuf);
char auto_install_script[384];
char injection_archive[384];
grub_uint8_t windows11_bypass_check;
- grub_uint8_t reserved[255];
+
+ grub_uint32_t auto_install_len;
+
+ grub_uint8_t reserved[255 - 4];
+
+ /* auto_intall file buf */
+ /* ...... + auto_install_len */
}ventoy_windows_data;
#define AUTO_RUN_BAT "X:\\VentoyAutoRun.bat"\r
#define AUTO_RUN_LOG "X:\\VentoyAutoRun.log"\r
\r
+#define VTOY_AUTO_FILE "X:\\_vtoy_auto_install"\r
+\r
#define LOG_FILE "X:\\Windows\\system32\\ventoy.log"\r
#define MUTEX_LOCK(hmutex) if (hmutex != NULL) LockStatus = WaitForSingleObject(hmutex, INFINITE)\r
#define MUTEX_UNLOCK(hmutex) if (hmutex != NULL && WAIT_OBJECT_0 == LockStatus) ReleaseMutex(hmutex)\r
return rc;\r
}\r
\r
-static BOOL CheckPeHead(BYTE *Head)\r
+static BOOL CheckPeHead(BYTE *Buffer, DWORD Size, DWORD Offset)\r
{\r
UINT32 PeOffset;\r
+ BYTE *Head = NULL;\r
+ DWORD End;\r
+ ventoy_windows_data *pdata = NULL;\r
+\r
+ Head = Buffer + Offset;\r
+ pdata = (ventoy_windows_data *)Head;\r
+ Head += sizeof(ventoy_windows_data);\r
+\r
+ if (pdata->auto_install_script[0] && pdata->auto_install_len > 0)\r
+ {\r
+ End = Offset + sizeof(ventoy_windows_data) + pdata->auto_install_len + 60;\r
+ if (End < Size)\r
+ {\r
+ Head += pdata->auto_install_len;\r
+ }\r
+ }\r
\r
if (Head[0] != 'M' || Head[1] != 'Z')\r
{\r
\r
if (g_windows_data.auto_install_script[0])\r
{\r
- sprintf_s(IsoPath, sizeof(IsoPath), "%C:%s", VtoyLetter, g_windows_data.auto_install_script);\r
- if (IsFileExist("%s", IsoPath))\r
+ if (IsFileExist("%s", VTOY_AUTO_FILE))\r
{\r
- Log("use auto install script %s...", IsoPath);\r
- ProcessUnattendedInstallation(IsoPath);\r
+ Log("use auto install script %s...", VTOY_AUTO_FILE);\r
+ ProcessUnattendedInstallation(VTOY_AUTO_FILE);\r
}\r
else\r
{\r
return 0;\r
}\r
\r
+static int ExtractWindowsDataFile(char *databuf)\r
+{\r
+ int len = 0;\r
+ char *filedata = NULL;\r
+ ventoy_windows_data *pdata = (ventoy_windows_data *)databuf;\r
+\r
+ Log("ExtractWindowsDataFile: auto install <%s:%d>", pdata->auto_install_script, pdata->auto_install_len);\r
+\r
+ filedata = databuf + sizeof(ventoy_windows_data);\r
+\r
+ if (pdata->auto_install_script[0] && pdata->auto_install_len > 0)\r
+ {\r
+ SaveBuffer2File(VTOY_AUTO_FILE, filedata, pdata->auto_install_len);\r
+ filedata += pdata->auto_install_len;\r
+ len = pdata->auto_install_len;\r
+ }\r
+ \r
+ return len;\r
+}\r
\r
int VentoyJumpWimboot(INT argc, CHAR **argv, CHAR *LunchFile)\r
{\r
\r
memcpy(&g_os_param, buf, sizeof(ventoy_os_param));\r
memcpy(&g_windows_data, buf + sizeof(ventoy_os_param), sizeof(ventoy_windows_data));\r
+ ExtractWindowsDataFile(buf + sizeof(ventoy_os_param));\r
memcpy(g_os_param_reserved, g_os_param.vtoy_reserved, sizeof(g_os_param_reserved));\r
\r
if (g_os_param_reserved[0] == 1)\r
{\r
int rc = 1;\r
int stat = 0;\r
+ int exlen = 0;\r
DWORD Pos;\r
DWORD PeStart;\r
DWORD FileSize;\r
for (PeStart = 0; PeStart < FileSize; PeStart += 16)\r
{\r
if (CheckOsParam((ventoy_os_param *)(Buffer + PeStart)) && \r
- CheckPeHead(Buffer + PeStart + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data)))\r
+ CheckPeHead(Buffer, FileSize, PeStart + sizeof(ventoy_os_param)))\r
{\r
Log("Find os pararm at %u", PeStart);\r
\r
memcpy(&g_os_param, Buffer + PeStart, sizeof(ventoy_os_param));\r
- memcpy(&g_windows_data, Buffer + PeStart + sizeof(ventoy_os_param), sizeof(ventoy_windows_data)); \r
+ memcpy(&g_windows_data, Buffer + PeStart + sizeof(ventoy_os_param), sizeof(ventoy_windows_data)); \r
+ exlen = ExtractWindowsDataFile(Buffer + PeStart + sizeof(ventoy_os_param));\r
memcpy(g_os_param_reserved, g_os_param.vtoy_reserved, sizeof(g_os_param_reserved));\r
\r
if (g_os_param_reserved[0] == 1)\r
}\r
}\r
\r
- PeStart += sizeof(ventoy_os_param) + sizeof(ventoy_windows_data);\r
+ PeStart += sizeof(ventoy_os_param) + sizeof(ventoy_windows_data) + exlen;\r
sprintf_s(LunchFile, MAX_PATH, "ventoy\\%s", GetFileNameInPath(ExeFileName));\r
\r
MUTEX_LOCK(g_vtoyins_mutex);\r
char auto_install_script[384];
char injection_archive[384];
UINT8 windows11_bypass_check;
- UINT8 reserved[255];
+
+ UINT32 auto_install_len;
+
+ UINT8 reserved[255 - 4];
+
+ /* auto install script file data ... + auto_install_len */
+ /* ...... */
+
+
}ventoy_windows_data;