Commit e2656c28 authored by longpanda's avatar longpanda
Browse files

Compatibility improvement for some WinPE

parent d8433985
...@@ -69,6 +69,9 @@ ...@@ -69,6 +69,9 @@
#define VTOY_ARCH_CPIO "ventoy_x86.cpio" #define VTOY_ARCH_CPIO "ventoy_x86.cpio"
#endif #endif
#define ventoy_varg_4(arg) arg[0], arg[1], arg[2], arg[3]
#define ventoy_varg_8(arg) arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7]
#define VTOY_PWD_CORRUPTED(err) \ #define VTOY_PWD_CORRUPTED(err) \
{\ {\
grub_printf("\n\n Password corrupted, will reboot after 5 seconds.\n\n"); \ grub_printf("\n\n Password corrupted, will reboot after 5 seconds.\n\n"); \
......
...@@ -660,30 +660,22 @@ static wim_directory_entry * search_full_wim_dirent ...@@ -660,30 +660,22 @@ static wim_directory_entry * search_full_wim_dirent
static wim_directory_entry * search_replace_wim_dirent(void *meta_data, wim_directory_entry *dir) static wim_directory_entry * search_replace_wim_dirent(void *meta_data, wim_directory_entry *dir)
{ {
wim_directory_entry *wim_dirent1 = NULL; wim_directory_entry *wim_dirent = NULL;
wim_directory_entry *wim_dirent2 = NULL;
const char *pecmd_path[] = { "Windows", "System32", "pecmd.exe", NULL }; const char *pecmd_path[] = { "Windows", "System32", "pecmd.exe", NULL };
const char *wpeinit_path[] = { "Windows", "System32", "wpeinit.exe", NULL };
const char *winpeshl_path[] = { "Windows", "System32", "winpeshl.exe", NULL }; const char *winpeshl_path[] = { "Windows", "System32", "winpeshl.exe", NULL };
wim_dirent1 = search_full_wim_dirent(meta_data, dir, pecmd_path); wim_dirent = search_full_wim_dirent(meta_data, dir, pecmd_path);
debug("search pecmd.exe %p\n", wim_dirent1); debug("search pecmd.exe %p\n", wim_dirent);
if (wim_dirent1) if (wim_dirent)
{ {
wim_dirent2 = search_full_wim_dirent(meta_data, dir, wpeinit_path); return wim_dirent;
debug("search wpeinit.exe %p\n", wim_dirent1);
if (wim_dirent2)
{
return wim_dirent2;
}
return wim_dirent1;
} }
wim_dirent1 = search_full_wim_dirent(meta_data, dir, winpeshl_path); wim_dirent = search_full_wim_dirent(meta_data, dir, winpeshl_path);
debug("search winpeshl.exe %p\n", wim_dirent1); debug("search winpeshl.exe %p\n", wim_dirent);
if (wim_dirent1) if (wim_dirent)
{ {
return wim_dirent1; return wim_dirent;
} }
return NULL; return NULL;
...@@ -745,6 +737,27 @@ static grub_uint64_t ventoy_get_stream_len(wim_directory_entry *dir) ...@@ -745,6 +737,27 @@ static grub_uint64_t ventoy_get_stream_len(wim_directory_entry *dir)
return offset; return offset;
} }
static int ventoy_update_stream_hash(wim_patch *patch, wim_directory_entry *dir)
{
grub_uint16_t i;
grub_uint64_t offset = 0;
wim_stream_entry *stream = (wim_stream_entry *)((char *)dir + dir->len);
for (i = 0; i < dir->streams; i++)
{
if (grub_memcmp(stream->hash.sha1, patch->old_hash.sha1, sizeof(wim_hash)) == 0)
{
debug("find target stream %u, name_len:%u upadte hash\n", i, stream->name_len);
grub_memcpy(stream->hash.sha1, &(patch->wim_data.bin_hash), sizeof(wim_hash));
}
offset += stream->len;
stream = (wim_stream_entry *)((char *)stream + stream->len);
}
return offset;
}
static int ventoy_update_all_hash(wim_patch *patch, void *meta_data, wim_directory_entry *dir) static int ventoy_update_all_hash(wim_patch *patch, void *meta_data, wim_directory_entry *dir)
{ {
if ((meta_data == NULL) || (dir == NULL)) if ((meta_data == NULL) || (dir == NULL))
...@@ -772,6 +785,7 @@ static int ventoy_update_all_hash(wim_patch *patch, void *meta_data, wim_directo ...@@ -772,6 +785,7 @@ static int ventoy_update_all_hash(wim_patch *patch, void *meta_data, wim_directo
if (dir->streams) if (dir->streams)
{ {
ventoy_update_stream_hash(patch, dir);
dir = (wim_directory_entry *)((char *)dir + dir->len + ventoy_get_stream_len(dir)); dir = (wim_directory_entry *)((char *)dir + dir->len + ventoy_get_stream_len(dir));
} }
else else
...@@ -932,6 +946,7 @@ static int ventoy_update_before_chain(ventoy_os_param *param, char *isopath) ...@@ -932,6 +946,7 @@ static int ventoy_update_before_chain(ventoy_os_param *param, char *isopath)
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 rc; int rc;
grub_uint16_t i;
grub_file_t file; grub_file_t file;
grub_uint32_t exe_len; grub_uint32_t exe_len;
grub_uint8_t *exe_data = NULL; grub_uint8_t *exe_data = NULL;
...@@ -940,6 +955,7 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch) ...@@ -940,6 +955,7 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch)
wim_security_header *security = NULL; wim_security_header *security = NULL;
wim_directory_entry *rootdir = NULL; wim_directory_entry *rootdir = NULL;
wim_directory_entry *search = NULL; wim_directory_entry *search = NULL;
wim_stream_entry *stream = NULL;
wim_header *head = &(patch->wim_data.wim_header); wim_header *head = &(patch->wim_data.wim_header);
wim_tail *wim_data = &patch->wim_data; wim_tail *wim_data = &patch->wim_data;
...@@ -1002,8 +1018,28 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch) ...@@ -1002,8 +1018,28 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch)
} }
debug("find replace file at %p\n", search); debug("find replace file at %p\n", search);
grub_memcpy(&patch->old_hash, search->hash.sha1, sizeof(wim_hash)); grub_memset(&patch->old_hash, 0, sizeof(wim_hash));
if (grub_memcmp(&patch->old_hash, search->hash.sha1, sizeof(wim_hash)) == 0)
{
debug("search hash all 0, now do deep search\n");
stream = (wim_stream_entry *)((char *)search + search->len);
for (i = 0; i < search->streams; i++)
{
if (stream->name_len == 0)
{
grub_memcpy(&patch->old_hash, stream->hash.sha1, sizeof(wim_hash));
debug("new search hash: %02x %02x %02x %02x %02x %02x %02x %02x\n",
ventoy_varg_8(patch->old_hash.sha1));
break;
}
stream = (wim_stream_entry *)((char *)stream + stream->len);
}
}
else
{
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); debug("read lookup offset:%llu size:%llu\n", (ulonglong)head->lookup.offset, (ulonglong)head->lookup.raw_size);
lookup = grub_malloc(head->lookup.raw_size); lookup = grub_malloc(head->lookup.raw_size);
...@@ -1030,8 +1066,8 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch) ...@@ -1030,8 +1066,8 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch)
} }
else else
{ {
debug("failed to find lookup entry for replace file 0x%02x 0x%02x\n", debug("failed to find lookup entry for replace file %02x %02x %02x %02x\n",
patch->old_hash.sha1[0], patch->old_hash.sha1[1]); ventoy_varg_4(patch->old_hash.sha1));
} }
wim_data->wim_raw_size = (grub_uint32_t)file->size; wim_data->wim_raw_size = (grub_uint32_t)file->size;
......
...@@ -45,6 +45,7 @@ if [ ! -f ./boot/boot.img ]; then ...@@ -45,6 +45,7 @@ if [ ! -f ./boot/boot.img ]; then
if [ -d ./grub ]; then if [ -d ./grub ]; then
echo "Don't run VentoyWeb.sh here, please download the released install package, and run the script in it." echo "Don't run VentoyWeb.sh here, please download the released install package, and run the script in it."
else else
echo "Current directory is $PWD"
echo "Please run under the correct directory!" echo "Please run under the correct directory!"
fi fi
exit 1 exit 1
......
...@@ -41,25 +41,26 @@ void Log(const char *Fmt, ...) ...@@ -41,25 +41,26 @@ void Log(const char *Fmt, ...)
FILE *File = NULL; FILE *File = NULL;
SYSTEMTIME Sys; SYSTEMTIME Sys;
char szBuf[1024]; char szBuf[1024];
DWORD PID = GetCurrentProcessId();
GetLocalTime(&Sys); GetLocalTime(&Sys);
Len += sprintf_s(szBuf, sizeof(szBuf), Len += sprintf_s(szBuf, sizeof(szBuf),
"[%4d/%02d/%02d %02d:%02d:%02d.%03d] ", "[%4d/%02d/%02d %02d:%02d:%02d.%03d] [%u] ",
Sys.wYear, Sys.wMonth, Sys.wDay, Sys.wYear, Sys.wMonth, Sys.wDay,
Sys.wHour, Sys.wMinute, Sys.wSecond, Sys.wHour, Sys.wMinute, Sys.wSecond,
Sys.wMilliseconds); Sys.wMilliseconds, PID);
va_start(Arg, Fmt); va_start(Arg, Fmt);
Len += vsnprintf_s(szBuf + Len, sizeof(szBuf)-Len, sizeof(szBuf)-Len, Fmt, Arg); Len += vsnprintf_s(szBuf + Len, sizeof(szBuf)-Len, sizeof(szBuf)-Len, Fmt, Arg);
va_end(Arg); va_end(Arg);
fopen_s(&File, "ventoy.log", "a+"); fopen_s(&File, "ventoy.log", "a+");
if (File) if (File)
{ {
fwrite(szBuf, 1, Len, File); fwrite(szBuf, 1, Len, File);
fwrite("\n", 1, 1, File); fwrite("\n", 1, 1, File);
fclose(File); fclose(File);
} }
} }
...@@ -1410,159 +1411,43 @@ End: ...@@ -1410,159 +1411,43 @@ End:
return rc; return rc;
} }
static int GetPecmdParam(const char *argv, char *CallParamBuf, DWORD BufLen) int main(int argc, char **argv)
{ {
HKEY hKey; int i = 0;
LSTATUS Ret; int rc = 0;
DWORD dw;
DWORD Type;
CHAR *Pos = NULL; CHAR *Pos = NULL;
CHAR CallParam[256] = { 0 }; CHAR CurDir[MAX_PATH];
CHAR FileName[MAX_PATH]; CHAR LunchFile[MAX_PATH];
CHAR CallParam[1024] = { 0 };
Log("GetPecmdParam <%s>", argv); STARTUPINFOA Si;
PROCESS_INFORMATION Pi;
*CallParamBuf = 0;
strcpy_s(FileName, sizeof(FileName), argv);
for (dw = 0, Pos = FileName; *Pos; Pos++)
{
dw++;
*Pos = toupper(*Pos);
}
Log("dw=%lu argv=<%s>", dw, FileName);
if (dw >= 9 && strcmp(FileName + dw - 9, "PECMD.EXE") == 0)
{
Log("Get parameters for pecmd.exe");
Ret = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "System\\Setup", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dw);
if (ERROR_SUCCESS == Ret)
{
memset(FileName, 0, sizeof(FileName));
dw = sizeof(FileName);
Ret = RegQueryValueEx(hKey, "CmdLine", NULL, &Type, FileName, &dw);
if (ERROR_SUCCESS == Ret && Type == REG_SZ)
{
strcpy_s(CallParam, sizeof(CallParam), FileName);
Log("CmdLine:<%s>", CallParam);
if (_strnicmp(CallParam, "PECMD.EXE", 9) == 0)
{
Pos = CallParam + 9;
if (*Pos == ' ' || *Pos == '\t')
{
Pos++;
}
}
else
{
Pos = CallParam;
}
Log("CmdLine2:<%s>", Pos);
sprintf_s(CallParamBuf, BufLen, " %s", Pos);
}
else
{
Log("Failed to RegQueryValueEx %lu %lu", Ret, Type);
}
RegCloseKey(hKey); if (argv[0] && argv[0][0] && argv[0][1] == ':')
return 1;
}
else
{
Log("Failed to create reg key %lu", Ret);
}
}
else
{ {
Log("This is NOT pecmd.exe"); GetCurrentDirectoryA(sizeof(CurDir), CurDir);
}
return 0;
}
static int GetWpeInitParam(char **argv, int argc, char *CallParamBuf, DWORD BufLen)
{
int i;
DWORD dw;
CHAR *Pos = NULL;
CHAR FileName[MAX_PATH];
Log("GetWpeInitParam argc=%d", argc);
*CallParamBuf = 0;
strcpy_s(FileName, sizeof(FileName), argv[0]); strcpy_s(LunchFile, sizeof(LunchFile), argv[0]);
for (dw = 0, Pos = FileName; *Pos; Pos++) Pos = (char *)GetFileNameInPath(LunchFile);
{
dw++;
*Pos = toupper(*Pos);
}
Log("dw=%lu argv=<%s>", dw, FileName); strcat_s(CurDir, sizeof(CurDir), "\\");
strcat_s(CurDir, sizeof(CurDir), Pos);
if (dw >= 11 && strcmp(FileName + dw - 11, "WPEINIT.EXE") == 0) if (_stricmp(argv[0], CurDir) != 0)
{
Log("Get parameters for WPEINIT.EXE");
for (i = 1; i < argc; i++)
{ {
strcat_s(CallParamBuf, BufLen, " "); *Pos = 0;
strcat_s(CallParamBuf, BufLen, argv[i]); SetCurrentDirectoryA(LunchFile);
} }
return 1;
}
else
{
Log("This is NOT wpeinit.exe");
} }
return 0;
}
int main(int argc, char **argv)
{
int i = 0;
int rc = 0;
CHAR *Pos = NULL;
CHAR CurDir[MAX_PATH];
CHAR LunchFile[MAX_PATH];
CHAR CallParam[1024] = { 0 };
STARTUPINFOA Si;
PROCESS_INFORMATION Pi;
if (argv[0] && argv[0][0] && argv[0][1] == ':') Log("######## VentoyJump ##########");
{ Log("argc = %d", argc);
GetCurrentDirectoryA(sizeof(CurDir), CurDir); for (i = 0; i < argc; i++)
strcpy_s(LunchFile, sizeof(LunchFile), argv[0]);
Pos = (char *)GetFileNameInPath(LunchFile);
strcat_s(CurDir, sizeof(CurDir), "\\");
strcat_s(CurDir, sizeof(CurDir), Pos);
if (_stricmp(argv[0], CurDir) != 0)
{
*Pos = 0;
SetCurrentDirectoryA(LunchFile);
}
}
Log("######## VentoyJump ##########");
Log("argc = %d argv[0] = <%s>", argc, argv[0]);
//special process for some WinPE
if (_stricmp(argv[0], "WPEINIT.EXE") == 0)
{ {
GetCurrentDirectoryA(sizeof(CurDir), CurDir); Log("argv[%d]=<%s>", i, argv[i]);
if (_stricmp(CurDir, "X:\\") == 0) if (i > 0)
{ {
Log("Set current directory to system32"); strcat_s(CallParam, sizeof(CallParam), " ");
SetCurrentDirectoryA("X:\\Windows\\System32"); strcat_s(CallParam, sizeof(CallParam), argv[i]);
} }
} }
...@@ -1577,11 +1462,6 @@ int main(int argc, char **argv) ...@@ -1577,11 +1462,6 @@ int main(int argc, char **argv)
Log("Current directory = <%s>", CurDir); Log("Current directory = <%s>", CurDir);
} }
if (0 == GetWpeInitParam(argv, argc, CallParam, sizeof(CallParam)))
{
GetPecmdParam(argv[0], CallParam, sizeof(CallParam));
}
GetStartupInfoA(&Si); GetStartupInfoA(&Si);
memset(LunchFile, 0, sizeof(LunchFile)); memset(LunchFile, 0, sizeof(LunchFile));
...@@ -1597,6 +1477,14 @@ int main(int argc, char **argv) ...@@ -1597,6 +1477,14 @@ int main(int argc, char **argv)
Log("LunchFile=<%s> CallParam=<%s>", LunchFile, CallParam); Log("LunchFile=<%s> CallParam=<%s>", LunchFile, CallParam);
if (_stricmp(argv[0], "PECMD.EXE") == 0 && _stricmp(LunchFile, "ventoy\\PECMD.EXE") == 0)
{
MoveFileA("PECMD.EXE", "PECMD_BACK.EXE");
MoveFileA("ventoy\\PECMD.EXE", "PECMD.EXE");
sprintf_s(LunchFile, sizeof(LunchFile), "%s", "PECMD.EXE");
Log("Move original PECMD.EXE <%s>", LunchFile);
}
if (g_os_param_reserved[0] == 3) if (g_os_param_reserved[0] == 3)
{ {
Log("Open log for debug ..."); Log("Open log for debug ...");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment