/******************************************************************************\r
* vtoyjump.c\r
*\r
-* Copyright (c) 2020, longpanda <admin@ventoy.net>\r
+* Copyright (c) 2021, longpanda <admin@ventoy.net>\r
*\r
* This program is free software; you can redistribute it and/or\r
* modify it under the terms of the GNU General Public License as\r
static ventoy_os_param g_os_param;\r
static ventoy_windows_data g_windows_data;\r
static UINT8 g_os_param_reserved[32];\r
-static BOOL g_64bit_system = FALSE;\r
+static INT g_system_bit = VTOY_BIT;\r
static ventoy_guid g_ventoy_guid = VENTOY_GUID;\r
static HANDLE g_vtoylog_mutex = NULL;\r
static HANDLE g_vtoyins_mutex = NULL;\r
\r
-//Unicode "CmdLine"\r
-static BOOL g_PecmdHasCmdLine = FALSE;\r
-static UCHAR g_aucCmdLineHex[] = \r
-{\r
- 0x43, 0x00, 0x6D, 0x00, 0x64, 0x00, 0x4C, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x65, 0x00\r
-};\r
+static CHAR g_prog_full_path[MAX_PATH];\r
+static CHAR g_prog_dir[MAX_PATH];\r
+static CHAR g_prog_name[MAX_PATH];\r
\r
-#define VTOY_PID_FILE "X:\\Windows\\System32\\pidventoy"\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
\r
+static const char * GetFileNameInPath(const char *fullpath)\r
+{\r
+ int i;\r
+\r
+ if (strstr(fullpath, ":"))\r
+ {\r
+ for (i = (int)strlen(fullpath); i > 0; i--)\r
+ {\r
+ if (fullpath[i - 1] == '/' || fullpath[i - 1] == '\\')\r
+ {\r
+ return fullpath + i;\r
+ }\r
+ }\r
+ }\r
+\r
+ return fullpath;\r
+}\r
+\r
+static int split_path_name(char *fullpath, char *dir, char *name)\r
+{\r
+ CHAR ch;\r
+ CHAR *Pos = NULL;\r
+\r
+ Pos = (CHAR *)GetFileNameInPath(fullpath);\r
+\r
+ strcpy_s(name, MAX_PATH, Pos);\r
+\r
+ ch = *(Pos - 1);\r
+ *(Pos - 1) = 0;\r
+ strcpy_s(dir, MAX_PATH, fullpath);\r
+ *(Pos - 1) = ch;\r
+\r
+ return 0;\r
+}\r
+\r
+\r
void Log(const char *Fmt, ...)\r
{\r
va_list Arg;\r
\r
MUTEX_LOCK(g_vtoylog_mutex);\r
\r
- fopen_s(&File, "ventoy.log", "a+");\r
+ fopen_s(&File, LOG_FILE, "a+");\r
if (File)\r
{\r
fwrite(szBuf, 1, Len, File);\r
return TRUE;\r
}\r
\r
-static BOOL IsPe64(BYTE *buffer)\r
-{\r
- DWORD pe_off;\r
-\r
- if (!CheckPeHead(buffer))\r
- {\r
- return FALSE;\r
- }\r
-\r
- pe_off = *(UINT32 *)(buffer + 60);\r
- if (*(UINT16 *)(buffer + pe_off + 24) == 0x020b)\r
- {\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
\r
static BOOL CheckOsParam(ventoy_os_param *param)\r
{\r
\r
for (i = 0; physicalDriveName[i]; i++)\r
{\r
- physicalDriveNameA[i] = toupper((CHAR)(physicalDriveName[i]));\r
+ physicalDriveNameA[i] = (CHAR)toupper((CHAR)(physicalDriveName[i]));\r
}\r
\r
Log("physicalDriveNameA=<%s>", physicalDriveNameA);\r
return bRet ? 0 : 1;\r
}\r
\r
-static BOOL VentoyNeedMountY(const char *IsoPath)\r
+static BOOL VentoyAPINeedMountY(const char *IsoPath)\r
{\r
+ (void)IsoPath;\r
+\r
/* TBD */\r
return FALSE;\r
}\r
DriveYFree = 1;\r
}\r
\r
- if (DriveYFree && VentoyNeedMountY(IsoPath))\r
+ if (DriveYFree && VentoyAPINeedMountY(IsoPath))\r
{\r
return VentoyMountY(Handle);\r
}\r
return bRet;\r
}\r
\r
-static CHAR GetMountLogicalDrive(void)\r
+static CHAR GetIMDiskMountLogicalDrive(void)\r
{\r
CHAR Letter = 'Y';\r
DWORD Drives;\r
\r
Log("VentoyRunImdisk <%s> <%s>", IsoPath, imdiskexe);\r
\r
- Letter = GetMountLogicalDrive();\r
+ Letter = GetIMDiskMountLogicalDrive();\r
sprintf_s(Cmdline, sizeof(Cmdline), "%s -a -o ro -f \"%s\" -m %C:", imdiskexe, IsoPath, Letter);\r
Log("mount iso to %C: use imdisk cmd <%s>", Letter, Cmdline);\r
\r
\r
if (0 == fl_attach_media(VentoyFatDiskRead, NULL))\r
{\r
- if (g_64bit_system)\r
+ if (g_system_bit == 64)\r
{\r
CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.sys", "ventoy\\imdisk.sys");\r
CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.exe", "ventoy\\imdisk.exe");\r
\r
if (0 == fl_attach_media(VentoyFatDiskRead, NULL))\r
{\r
- if (g_64bit_system)\r
+ if (g_system_bit == 64)\r
{\r
CopyFileFromFatDisk("/ventoy/7z/64/7za.exe", "ventoy\\7za.exe");\r
}\r
return 0;\r
}\r
\r
-const char * GetFileNameInPath(const char *fullpath)\r
-{\r
- int i;\r
- const char *pos = NULL;\r
-\r
- if (strstr(fullpath, ":"))\r
- {\r
- for (i = (int)strlen(fullpath); i > 0; i--)\r
- {\r
- if (fullpath[i - 1] == '/' || fullpath[i - 1] == '\\')\r
- {\r
- return fullpath + i;\r
- }\r
- }\r
- }\r
- \r
- return fullpath;\r
-}\r
\r
int VentoyJumpWimboot(INT argc, CHAR **argv, CHAR *LunchFile)\r
{\r
DWORD size = 0;\r
DWORD Pos;\r
\r
-#ifdef VTOY_32\r
- g_64bit_system = FALSE;\r
-#else\r
- g_64bit_system = TRUE;\r
-#endif\r
- \r
- Log("VentoyJumpWimboot %dbit", g_64bit_system ? 64 : 32);\r
+ Log("VentoyJumpWimboot %dbit", g_system_bit);\r
\r
sprintf_s(LunchFile, MAX_PATH, "X:\\setup.exe");\r
\r
return 0;\r
}\r
\r
-static BOOL VentoyFindCmdLineStr(BYTE *buf, DWORD size)\r
-{\r
- DWORD i = 0;\r
- UINT32 uiDataChk;\r
- UINT32 uiDataHex = *(UINT32 *)(g_aucCmdLineHex);\r
-\r
- for (i = 0; i < size - sizeof(g_aucCmdLineHex); i += 16)\r
- {\r
- uiDataChk = *(UINT32 *)(buf + i);\r
- if (uiDataChk == uiDataHex && memcmp(buf + i, g_aucCmdLineHex, sizeof(g_aucCmdLineHex)) == 0)\r
- {\r
- return TRUE;\r
- }\r
- }\r
- \r
- return FALSE;\r
-}\r
-\r
int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile)\r
{\r
int rc = 1;\r
goto End;\r
}\r
\r
- g_64bit_system = IsPe64(Buffer);\r
- Log("VentoyJump %dbit", g_64bit_system ? 64 : 32);\r
+ Log("VentoyJump %dbit", g_system_bit);\r
\r
MUTEX_LOCK(g_vtoyins_mutex);\r
stat = ventoy_check_create_directory();\r
SaveBuffer2File(LunchFile, Buffer + PeStart, FileSize - PeStart);\r
MUTEX_UNLOCK(g_vtoyins_mutex);\r
\r
- #ifdef VTOY_REJUMP_SUPPORTED\r
- if (_stricmp(LunchFile, "ventoy\\PECMD.EXE") == 0)\r
- {\r
- g_PecmdHasCmdLine = VentoyFindCmdLineStr(Buffer + PeStart, FileSize - PeStart);\r
- }\r
- #endif\r
-\r
break;\r
}\r
}\r
}\r
\r
\r
-\r
-static int ventoy_append_process_id(const char *pidfile)\r
+int real_main(int argc, char **argv)\r
{\r
- DWORD PID = 0;\r
- FILE *fp = NULL;\r
-\r
- PID = GetCurrentProcessId();\r
-\r
- fopen_s(&fp, pidfile, "a+");\r
- if (!fp)\r
- {\r
- return 1;\r
- }\r
-\r
- fprintf_s(fp, "%u\n", PID);\r
-\r
- fclose(fp);\r
- return 0;\r
-}\r
-\r
-static int ventoy_get_instance_id(const char *pidfile)\r
-{\r
- int instance = 0;\r
- FILE *fp = NULL;\r
- char line[256];\r
+ int i = 0;\r
+ int rc = 0;\r
+ CHAR NewFile[MAX_PATH];\r
+ CHAR LunchFile[MAX_PATH];\r
+ CHAR CallParam[1024] = { 0 };\r
+ STARTUPINFOA Si;\r
+ PROCESS_INFORMATION Pi;\r
\r
- fopen_s(&fp, pidfile, "r");\r
- if (!fp)\r
- {\r
- return 1;\r
- }\r
+ Log("#### real_main #### argc = %d", argc);\r
+ Log("program full path: <%s>", g_prog_full_path);\r
+ Log("program dir: <%s>", g_prog_dir);\r
+ Log("program name:: <%s>", g_prog_name);\r
\r
- while (fgets(line, sizeof(line), fp))\r
- {\r
- instance++;\r
- }\r
+ Log("argc = %d", argc);\r
+ for (i = 0; i < argc; i++)\r
+ {\r
+ Log("argv[%d]=<%s>", i, argv[i]);\r
+ if (i > 0)\r
+ {\r
+ strcat_s(CallParam, sizeof(CallParam), " ");\r
+ strcat_s(CallParam, sizeof(CallParam), argv[i]);\r
+ }\r
+ }\r
\r
- fclose(fp);\r
- return instance + 1;\r
-}\r
+ GetStartupInfoA(&Si);\r
+ memset(LunchFile, 0, sizeof(LunchFile));\r
\r
-int main(int argc, char **argv)\r
-{\r
- int i = 0;\r
- int rc = 0;\r
- int id = 0;\r
- BOOL ReJump = FALSE;\r
- CHAR *Pos = NULL;\r
- CHAR CurDir[MAX_PATH];\r
- CHAR LunchFile[MAX_PATH];\r
- CHAR CallParam[1024] = { 0 };\r
- DWORD LockStatus = 0;\r
- STARTUPINFOA Si;\r
- PROCESS_INFORMATION Pi;\r
-\r
-#ifdef VTOY_REJUMP_SUPPORTED\r
- if (argv[0] && strcmp(argv[0], "ventoy\\WinLogon.exe") == 0)\r
- {\r
- GetStartupInfoA(&Si);\r
- Si.dwFlags |= STARTF_USESHOWWINDOW;\r
- Si.wShowWindow = SW_HIDE;\r
+ if (strstr(argv[0], "vtoyjump.exe"))\r
+ {\r
+ rc = VentoyJumpWimboot(argc, argv, LunchFile);\r
+ }\r
+ else\r
+ {\r
+ rc = VentoyJump(argc, argv, LunchFile);\r
+ }\r
\r
- sprintf_s(LunchFile, sizeof(LunchFile), "PECMD.EXE");\r
- for (i = 1; i < argc; i++)\r
- {\r
- strcat_s(LunchFile, sizeof(LunchFile), " ");\r
- strcat_s(LunchFile, sizeof(LunchFile), argv[i]);\r
- }\r
+ Log("LunchFile=<%s> CallParam=<%s>", LunchFile, CallParam);\r
\r
- CreateProcessA(NULL, LunchFile, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);\r
- WaitForSingleObject(Pi.hProcess, INFINITE);\r
- return 0;\r
- }\r
-#endif\r
+ if (_stricmp(g_prog_name, "winpeshl.exe") != 0 && IsFileExist("ventoy\\%s", g_prog_name))\r
+ {\r
+ sprintf_s(NewFile, sizeof(NewFile), "%s_BACK.EXE", g_prog_full_path);\r
+ MoveFileA(g_prog_full_path, NewFile);\r
+ Log("Move <%s> to <%s>", g_prog_full_path, NewFile);\r
\r
- g_PecmdHasCmdLine = 0;\r
- g_vtoylog_mutex = CreateMutexA(NULL, FALSE, "VTOYLOG_LOCK");\r
- g_vtoyins_mutex = CreateMutexA(NULL, FALSE, "VTOYINS_LOCK");\r
+ sprintf_s(NewFile, sizeof(NewFile), "ventoy\\%s", g_prog_name);\r
+ CopyFileA(NewFile, g_prog_full_path, TRUE);\r
+ Log("Copy <%s> to <%s>", NewFile, g_prog_full_path);\r
\r
- MUTEX_LOCK(g_vtoyins_mutex);\r
- if (IsFileExist(VTOY_PID_FILE))\r
- {\r
- id = ventoy_get_instance_id(VTOY_PID_FILE);\r
- }\r
+ sprintf_s(LunchFile, sizeof(LunchFile), "%s", g_prog_full_path);\r
+ Log("Final lunchFile is <%s>", LunchFile);\r
+ }\r
else\r
{\r
- id = 1;\r
+ Log("We don't need to recover original <%s>", g_prog_name);\r
}\r
- ventoy_append_process_id(VTOY_PID_FILE);\r
- MUTEX_UNLOCK(g_vtoyins_mutex);\r
\r
- if (argv[0] && argv[0][0] && argv[0][1] == ':')\r
- {\r
- GetCurrentDirectoryA(sizeof(CurDir), CurDir);\r
+ if (g_os_param_reserved[0] == 3)\r
+ {\r
+ Log("Open log for debug ...");\r
+ sprintf_s(LunchFile, sizeof(LunchFile), "%s", "notepad.exe ventoy.log");\r
+ }\r
+ else\r
+ {\r
+ if (CallParam[0])\r
+ {\r
+ strcat_s(LunchFile, sizeof(LunchFile), CallParam);\r
+ }\r
+ else if (NULL == strstr(LunchFile, "setup.exe"))\r
+ {\r
+ Log("Not setup.exe, hide windows.");\r
+ Si.dwFlags |= STARTF_USESHOWWINDOW;\r
+ Si.wShowWindow = SW_HIDE;\r
+ }\r
\r
- strcpy_s(LunchFile, sizeof(LunchFile), argv[0]);\r
- Pos = (char *)GetFileNameInPath(LunchFile);\r
+ Log("Ventoy jump %s ...", rc == 0 ? "success" : "failed");\r
+ }\r
\r
- strcat_s(CurDir, sizeof(CurDir), "\\");\r
- strcat_s(CurDir, sizeof(CurDir), Pos);\r
+ Log("Now launch <%s> ...", LunchFile);\r
\r
- if (_stricmp(argv[0], CurDir) != 0)\r
- {\r
- *Pos = 0;\r
- SetCurrentDirectoryA(LunchFile);\r
- }\r
- }\r
+ if (g_os_param_reserved[0] == 4)\r
+ {\r
+ Log("Open cmd for debug ...");\r
+ sprintf_s(LunchFile, sizeof(LunchFile), "%s", "cmd.exe");\r
+ }\r
\r
-#ifdef VTOY_32\r
- Log("######## VentoyJump 32bit [%d] ##########", id);\r
-#else\r
- Log("######## VentoyJump 64bit [%d] ##########", id);\r
-#endif\r
+ Log("Backup log at this point");\r
+ CopyFileA(LOG_FILE, "X:\\Windows\\ventoy.backup", TRUE);\r
\r
- Log("argc = %d", argc);\r
- for (i = 0; i < argc; i++)\r
- {\r
- Log("argv[%d]=<%s>", i, argv[i]);\r
- if (i > 0)\r
- {\r
- strcat_s(CallParam, sizeof(CallParam), " ");\r
- strcat_s(CallParam, sizeof(CallParam), argv[i]);\r
- }\r
- }\r
+ CreateProcessA(NULL, LunchFile, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);\r
\r
- if (Pos && *Pos == 0)\r
- {\r
- Log("Old current directory = <%s>", CurDir);\r
- Log("New current directory = <%s>", LunchFile);\r
- }\r
- else\r
+ for (i = 0; rc && i < 1800; i++)\r
{\r
- GetCurrentDirectoryA(sizeof(CurDir), CurDir);\r
- Log("Current directory = <%s>", CurDir);\r
+ Log("Ventoy hook failed, now wait and retry ...");\r
+ Sleep(1000);\r
+ rc = VentoyHook(&g_os_param);\r
}\r
\r
- GetStartupInfoA(&Si);\r
+ Log("Wait process...");\r
+ WaitForSingleObject(Pi.hProcess, INFINITE);\r
\r
- memset(LunchFile, 0, sizeof(LunchFile));\r
+ Log("vtoyjump finished");\r
+ return 0;\r
+}\r
\r
- if (strstr(argv[0], "vtoyjump.exe"))\r
- {\r
- rc = VentoyJumpWimboot(argc, argv, LunchFile);\r
- }\r
- else\r
- {\r
- rc = VentoyJump(argc, argv, LunchFile);\r
- }\r
\r
- Log("id=%d LunchFile=<%s> CallParam=<%s>", id, LunchFile, CallParam);\r
+int main(int argc, char **argv)\r
+{\r
+ int i;\r
+ STARTUPINFOA Si;\r
+ PROCESS_INFORMATION Pi;\r
+ CHAR CurDir[MAX_PATH];\r
+ CHAR NewArgv0[MAX_PATH];\r
+ CHAR CallParam[1024] = { 0 };\r
\r
- if (id == 1 && _stricmp(argv[0], "PECMD.EXE") == 0 && _stricmp(LunchFile, "ventoy\\PECMD.EXE") == 0)\r
- {\r
- MUTEX_LOCK(g_vtoyins_mutex);\r
- id = ventoy_get_instance_id(VTOY_PID_FILE);\r
- MUTEX_UNLOCK(g_vtoyins_mutex);\r
+ g_vtoylog_mutex = CreateMutexA(NULL, FALSE, "VTOYLOG_LOCK");\r
+ g_vtoyins_mutex = CreateMutexA(NULL, FALSE, "VTOYINS_LOCK");\r
\r
- Log("Current instance id is: %d", id);\r
+ Log("######## VentoyJump %dbit ##########", g_system_bit);\r
\r
- if (id == 2)\r
- {\r
- #ifdef VTOY_REJUMP_SUPPORTED\r
- if (g_PecmdHasCmdLine)\r
- {\r
- ReJump = TRUE;\r
- CopyFileA("PECMD.EXE", "ventoy\\WinLogon.exe", TRUE);\r
- }\r
- #endif\r
+ GetCurrentDirectoryA(sizeof(CurDir), CurDir);\r
+ Log("Current directory is <%s>", CurDir);\r
+ \r
+ GetModuleFileNameA(NULL, g_prog_full_path, MAX_PATH);\r
+ split_path_name(g_prog_full_path, g_prog_dir, g_prog_name);\r
\r
- MoveFileA("PECMD.EXE", "PECMD_BACK.EXE");\r
- CopyFileA("ventoy\\PECMD.EXE", "PECMD.EXE", TRUE); \r
- sprintf_s(LunchFile, sizeof(LunchFile), "%s", "PECMD.EXE");\r
- Log("Move original PECMD.EXE <%s>", LunchFile);\r
- }\r
- else\r
- {\r
- Log("%d instance started, don't move PECMD.EXE", id);\r
- }\r
- }\r
+ Log("EXE path: <%s> dir:<%s> name:<%s>", g_prog_full_path, g_prog_dir, g_prog_name);\r
\r
- if (g_os_param_reserved[0] == 3)\r
- {\r
- Log("Open log for debug ...");\r
- sprintf_s(LunchFile, sizeof(LunchFile), "%s", "notepad.exe ventoy.log");\r
- }\r
- else\r
- {\r
- if (CallParam[0])\r
- {\r
- strcat_s(LunchFile, sizeof(LunchFile), CallParam);\r
- }\r
- else if (NULL == strstr(LunchFile, "setup.exe"))\r
- {\r
- Log("Not setup.exe, hide windows.");\r
- Si.dwFlags |= STARTF_USESHOWWINDOW;\r
- Si.wShowWindow = SW_HIDE;\r
- } \r
+ if (_stricmp(g_prog_name, "WinLogon.exe") == 0)\r
+ {\r
+ Log("This time is rejump back ...");\r
+ \r
+ strcpy_s(g_prog_full_path, sizeof(g_prog_full_path), argv[1]);\r
+ split_path_name(g_prog_full_path, g_prog_dir, g_prog_name);\r
\r
- Log("Ventoy jump %s ...", rc == 0 ? "success" : "failed");\r
- }\r
- \r
- Log("Now launch <%s> ...", LunchFile);\r
+ return real_main(argc - 1, argv + 1);\r
+ }\r
+ else if (_stricmp(g_prog_name, "PECMD.exe") == 0)\r
+ {\r
+ Log("We need to rejump for pecmd ...");\r
\r
- if (g_os_param_reserved[0] == 4)\r
- {\r
- Log("Open cmd for debug ...");\r
- sprintf_s(LunchFile, sizeof(LunchFile), "%s", "cmd.exe");\r
- }\r
+ ventoy_check_create_directory();\r
+ CopyFileA(g_prog_full_path, "ventoy\\WinLogon.exe", TRUE);\r
\r
-#ifdef VTOY_REJUMP_SUPPORTED\r
- if (ReJump)\r
- {\r
- sprintf_s(CallParam, sizeof(CallParam), "ventoy\\WinLogon.exe%s", LunchFile + strlen("PECMD.EXE"));\r
- Log("Now rejump to pecmd.exe <%s> ...", CallParam);\r
+ sprintf_s(CallParam, sizeof(CallParam), "ventoy\\WinLogon.exe %s", g_prog_full_path);\r
+ for (i = 1; i < argc; i++)\r
+ {\r
+ strcat_s(CallParam, sizeof(CallParam), " ");\r
+ strcat_s(CallParam, sizeof(CallParam), argv[i]);\r
+ }\r
\r
- CreateProcessA(NULL, CallParam, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);\r
+ Log("Now rejump to <%s> ...", CallParam);\r
+ GetStartupInfoA(&Si);\r
+ CreateProcessA(NULL, CallParam, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);\r
\r
- Log("Wait rejump process...");\r
- WaitForSingleObject(Pi.hProcess, INFINITE);\r
- Log("rejump finished");\r
- return 0;\r
- }\r
-#else\r
- (void)ReJump;\r
-#endif\r
+ Log("Wait rejump process...");\r
+ WaitForSingleObject(Pi.hProcess, INFINITE);\r
+ Log("rejump finished");\r
+ return 0;\r
+ }\r
+ else\r
+ {\r
+ Log("We don't need to rejump ...");\r
\r
- CreateProcessA(NULL, LunchFile, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);\r
+ strcpy_s(NewArgv0, sizeof(NewArgv0), g_prog_full_path);\r
+ argv[0] = NewArgv0;\r
\r
- for (i = 0; rc && i < 1800; i++)\r
- {\r
- Log("Ventoy hook failed, now wait and retry ...");\r
- Sleep(1000);\r
- rc = VentoyHook(&g_os_param);\r
- }\r
+ return real_main(argc, argv);\r
+ }\r
+}\r
\r
- Log("Wait process...");\r
- WaitForSingleObject(Pi.hProcess, INFINITE);\r
\r
- Log("vtoyjump finished");\r
- return 0;\r
-}\r