Compatibility improvement for some WinPE

This commit is contained in:
longpanda 2021-08-02 21:03:43 +08:00
parent d8433985e7
commit e2656c287b
6 changed files with 107 additions and 179 deletions

View File

@ -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"); \

View File

@ -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)
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
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)
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)
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;
@ -1003,7 +1019,27 @@ 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)
} }
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;

View File

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

Binary file not shown.

Binary file not shown.

View File

@ -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:
return rc; return rc;
} }
static int GetPecmdParam(const char *argv, char *CallParamBuf, DWORD BufLen)
{
HKEY hKey;
LSTATUS Ret;
DWORD dw;
DWORD Type;
CHAR *Pos = NULL;
CHAR CallParam[256] = { 0 };
CHAR FileName[MAX_PATH];
Log("GetPecmdParam <%s>", argv);
*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);
return 1;
}
else
{
Log("Failed to create reg key %lu", Ret);
}
}
else
{
Log("This is NOT pecmd.exe");
}
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]);
for (dw = 0, Pos = FileName; *Pos; Pos++)
{
dw++;
*Pos = toupper(*Pos);
}
Log("dw=%lu argv=<%s>", dw, FileName);
if (dw >= 11 && strcmp(FileName + dw - 11, "WPEINIT.EXE") == 0)
{
Log("Get parameters for WPEINIT.EXE");
for (i = 1; i < argc; i++)
{
strcat_s(CallParamBuf, BufLen, " ");
strcat_s(CallParamBuf, BufLen, argv[i]);
}
return 1;
}
else
{
Log("This is NOT wpeinit.exe");
}
return 0;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int i = 0; int i = 0;
int rc = 0; int rc = 0;
CHAR *Pos = NULL; CHAR *Pos = NULL;
CHAR CurDir[MAX_PATH]; CHAR CurDir[MAX_PATH];
CHAR LunchFile[MAX_PATH]; CHAR LunchFile[MAX_PATH];
CHAR CallParam[1024] = { 0 }; CHAR CallParam[1024] = { 0 };
STARTUPINFOA Si; STARTUPINFOA Si;
PROCESS_INFORMATION Pi; PROCESS_INFORMATION Pi;
if (argv[0] && argv[0][0] && argv[0][1] == ':') if (argv[0] && argv[0][0] && argv[0][1] == ':')
{
GetCurrentDirectoryA(sizeof(CurDir), CurDir);
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); GetCurrentDirectoryA(sizeof(CurDir), CurDir);
if (_stricmp(CurDir, "X:\\") == 0)
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)
{ {
Log("Set current directory to system32"); *Pos = 0;
SetCurrentDirectoryA("X:\\Windows\\System32"); SetCurrentDirectoryA(LunchFile);
}
}
Log("######## VentoyJump ##########");
Log("argc = %d", argc);
for (i = 0; i < argc; i++)
{
Log("argv[%d]=<%s>", i, argv[i]);
if (i > 0)
{
strcat_s(CallParam, sizeof(CallParam), " ");
strcat_s(CallParam, sizeof(CallParam), argv[i]);
} }
} }
@ -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)
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 ...");