1 /******************************************************************************
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
27 #include <VersionHelpers.h>
29 #include "fat_filelib.h"
31 static ventoy_os_param g_os_param
;
32 static ventoy_windows_data g_windows_data
;
33 static UINT8 g_os_param_reserved
[32];
34 static BOOL g_64bit_system
= FALSE
;
35 static ventoy_guid g_ventoy_guid
= VENTOY_GUID
;
36 static HANDLE g_vtoylog_mutex
= NULL
;
37 static HANDLE g_vtoyins_mutex
= NULL
;
40 static BOOL g_PecmdHasCmdLine
= FALSE
;
41 static UCHAR g_aucCmdLineHex
[] =
43 0x43, 0x00, 0x6D, 0x00, 0x64, 0x00, 0x4C, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x65, 0x00
46 #define VTOY_PID_FILE "X:\\Windows\\System32\\pidventoy"
47 #define MUTEX_LOCK(hmutex) if (hmutex != NULL) LockStatus = WaitForSingleObject(hmutex, INFINITE)
48 #define MUTEX_UNLOCK(hmutex) if (hmutex != NULL && WAIT_OBJECT_0 == LockStatus) ReleaseMutex(hmutex)
50 void Log(const char *Fmt
, ...)
58 DWORD PID
= GetCurrentProcessId();
61 Len
+= sprintf_s(szBuf
, sizeof(szBuf
),
62 "[%4d/%02d/%02d %02d:%02d:%02d.%03d] [%u] ",
63 Sys
.wYear
, Sys
.wMonth
, Sys
.wDay
,
64 Sys
.wHour
, Sys
.wMinute
, Sys
.wSecond
,
65 Sys
.wMilliseconds
, PID
);
68 Len
+= vsnprintf_s(szBuf
+ Len
, sizeof(szBuf
)-Len
, sizeof(szBuf
)-Len
, Fmt
, Arg
);
71 MUTEX_LOCK(g_vtoylog_mutex
);
73 fopen_s(&File
, "ventoy.log", "a+");
76 fwrite(szBuf
, 1, Len
, File
);
77 fwrite("\n", 1, 1, File
);
81 MUTEX_UNLOCK(g_vtoylog_mutex
);
85 static int LoadNtDriver(const char *DrvBinPath
)
91 SC_HANDLE hServiceMgr
;
93 char name
[256] = { 0 };
95 for (i
= (int)strlen(DrvBinPath
) - 1; i
>= 0; i
--)
97 if (DrvBinPath
[i
] == '\\' || DrvBinPath
[i
] == '/')
99 sprintf_s(name
, sizeof(name
), "%s", DrvBinPath
+ i
+ 1);
104 Log("Load NT driver: %s %s", DrvBinPath
, name
);
106 hServiceMgr
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_ALL_ACCESS
);
107 if (hServiceMgr
== NULL
)
109 Log("OpenSCManager failed Error:%u", GetLastError());
113 Log("OpenSCManager OK");
115 hService
= CreateServiceA(hServiceMgr
,
119 SERVICE_KERNEL_DRIVER
,
120 SERVICE_DEMAND_START
,
121 SERVICE_ERROR_NORMAL
,
123 NULL
, NULL
, NULL
, NULL
, NULL
);
124 if (hService
== NULL
)
126 Status
= GetLastError();
127 if (Status
!= ERROR_IO_PENDING
&& Status
!= ERROR_SERVICE_EXISTS
)
129 Log("CreateService failed v %u", Status
);
130 CloseServiceHandle(hServiceMgr
);
134 hService
= OpenServiceA(hServiceMgr
, name
, SERVICE_ALL_ACCESS
);
135 if (hService
== NULL
)
137 Log("OpenService failed %u", Status
);
138 CloseServiceHandle(hServiceMgr
);
143 Log("CreateService imdisk OK");
145 Ret
= StartServiceA(hService
, 0, NULL
);
148 Log("StartService OK");
152 Status
= GetLastError();
153 if (Status
== ERROR_SERVICE_ALREADY_RUNNING
)
159 Log("StartService error %u", Status
);
164 CloseServiceHandle(hService
);
165 CloseServiceHandle(hServiceMgr
);
167 Log("Load NT driver %s", rc
? "failed" : "success");
172 static int ReadWholeFile2Buf(const char *Fullpath
, void **Data
, DWORD
*Size
)
180 Log("ReadWholeFile2Buf <%s>", Fullpath
);
182 Handle
= CreateFileA(Fullpath
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, 0, OPEN_EXISTING
, 0, 0);
183 if (Handle
== INVALID_HANDLE_VALUE
)
185 Log("Could not open the file<%s>, error:%u", Fullpath
, GetLastError());
189 FileSize
= SetFilePointer(Handle
, 0, NULL
, FILE_END
);
191 Buffer
= malloc(FileSize
);
194 Log("Failed to alloc memory size:%u", FileSize
);
198 SetFilePointer(Handle
, 0, NULL
, FILE_BEGIN
);
199 if (!ReadFile(Handle
, Buffer
, FileSize
, &dwSize
, NULL
))
201 Log("ReadFile failed, dwSize:%u error:%u", dwSize
, GetLastError());
208 Log("Success read file size:%u", FileSize
);
213 SAFE_CLOSE_HANDLE(Handle
);
218 static BOOL
CheckPeHead(BYTE
*Head
)
222 if (Head
[0] != 'M' || Head
[1] != 'Z')
227 PeOffset
= *(UINT32
*)(Head
+ 60);
228 if (*(UINT32
*)(Head
+ PeOffset
) != 0x00004550)
236 static BOOL
IsPe64(BYTE
*buffer
)
240 if (!CheckPeHead(buffer
))
245 pe_off
= *(UINT32
*)(buffer
+ 60);
246 if (*(UINT16
*)(buffer
+ pe_off
+ 24) == 0x020b)
255 static BOOL
CheckOsParam(ventoy_os_param
*param
)
260 if (memcmp(¶m
->guid
, &g_ventoy_guid
, sizeof(ventoy_guid
)))
265 for (i
= 0; i
< sizeof(ventoy_os_param
); i
++)
267 Sum
+= *((BYTE
*)param
+ i
);
275 if (param
->vtoy_img_location_addr
% 4096)
283 static int SaveBuffer2File(const char *Fullpath
, void *Buffer
, DWORD Length
)
289 Log("SaveBuffer2File <%s> len:%u", Fullpath
, Length
);
291 Handle
= CreateFileA(Fullpath
, GENERIC_READ
| GENERIC_WRITE
,
292 FILE_SHARE_READ
| FILE_SHARE_WRITE
, 0, CREATE_NEW
, 0, 0);
293 if (Handle
== INVALID_HANDLE_VALUE
)
295 Log("Could not create new file, error:%u", GetLastError());
299 WriteFile(Handle
, Buffer
, Length
, &dwSize
, NULL
);
304 SAFE_CLOSE_HANDLE(Handle
);
309 static int IsUTF8Encode(const char *src
)
312 const UCHAR
*Byte
= (const UCHAR
*)src
;
314 for (i
= 0; i
< MAX_PATH
&& Byte
[i
]; i
++)
325 static int Utf8ToUtf16(const char* src
, WCHAR
* dst
)
327 int size
= MultiByteToWideChar(CP_UTF8
, 0, src
, -1, dst
, 0);
328 return MultiByteToWideChar(CP_UTF8
, 0, src
, -1, dst
, size
+ 1);
331 static BOOL
IsDirExist(const char *Fmt
, ...)
336 CHAR FilePathA
[MAX_PATH
];
337 WCHAR FilePathW
[MAX_PATH
];
340 vsnprintf_s(FilePathA
, sizeof(FilePathA
), sizeof(FilePathA
), Fmt
, Arg
);
343 UTF8
= IsUTF8Encode(FilePathA
);
347 Utf8ToUtf16(FilePathA
, FilePathW
);
348 Attr
= GetFileAttributesW(FilePathW
);
352 Attr
= GetFileAttributesA(FilePathA
);
355 if (Attr
!= INVALID_FILE_ATTRIBUTES
&& (Attr
& FILE_ATTRIBUTE_DIRECTORY
))
363 static BOOL
IsFileExist(const char *Fmt
, ...)
370 CHAR FilePathA
[MAX_PATH
];
371 WCHAR FilePathW
[MAX_PATH
];
374 vsnprintf_s(FilePathA
, sizeof(FilePathA
), sizeof(FilePathA
), Fmt
, Arg
);
377 UTF8
= IsUTF8Encode(FilePathA
);
381 Utf8ToUtf16(FilePathA
, FilePathW
);
382 hFile
= CreateFileW(FilePathW
, FILE_READ_EA
, FILE_SHARE_READ
, 0, OPEN_EXISTING
, 0, 0);
386 hFile
= CreateFileA(FilePathA
, FILE_READ_EA
, FILE_SHARE_READ
, 0, OPEN_EXISTING
, 0, 0);
388 if (INVALID_HANDLE_VALUE
== hFile
)
397 Attr
= GetFileAttributesW(FilePathW
);
401 Attr
= GetFileAttributesA(FilePathA
);
404 if (Attr
& FILE_ATTRIBUTE_DIRECTORY
)
412 Log("File <%s> %s", FilePathA
, (bRet
? "exist" : "NOT exist"));
416 static int GetPhyDiskUUID(const char LogicalDrive
, UINT8
*UUID
, DISK_EXTENT
*DiskExtent
)
421 VOLUME_DISK_EXTENTS DiskExtents
;
423 UINT8 SectorBuf
[512];
425 Log("GetPhyDiskUUID %C", LogicalDrive
);
427 sprintf_s(PhyPath
, sizeof(PhyPath
), "\\\\.\\%C:", LogicalDrive
);
428 Handle
= CreateFileA(PhyPath
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, 0, OPEN_EXISTING
, 0, 0);
429 if (Handle
== INVALID_HANDLE_VALUE
)
431 Log("Could not open the disk<%s>, error:%u", PhyPath
, GetLastError());
435 Ret
= DeviceIoControl(Handle
,
436 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
,
440 (DWORD
)(sizeof(DiskExtents
)),
443 if (!Ret
|| DiskExtents
.NumberOfDiskExtents
== 0)
445 Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed, error:%u", GetLastError());
451 memcpy(DiskExtent
, DiskExtents
.Extents
, sizeof(DiskExtent
));
452 Log("%C: is in PhysicalDrive%d ", LogicalDrive
, DiskExtents
.Extents
[0].DiskNumber
);
454 sprintf_s(PhyPath
, sizeof(PhyPath
), "\\\\.\\PhysicalDrive%d", DiskExtents
.Extents
[0].DiskNumber
);
455 Handle
= CreateFileA(PhyPath
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, 0, OPEN_EXISTING
, 0, 0);
456 if (Handle
== INVALID_HANDLE_VALUE
)
458 Log("Could not open the disk<%s>, error:%u", PhyPath
, GetLastError());
462 if (!ReadFile(Handle
, SectorBuf
, sizeof(SectorBuf
), &dwSize
, NULL
))
464 Log("ReadFile failed, dwSize:%u error:%u", dwSize
, GetLastError());
469 memcpy(UUID
, SectorBuf
+ 0x180, 16);
474 static int VentoyMountAnywhere(HANDLE Handle
)
477 ATTACH_VIRTUAL_DISK_PARAMETERS AttachParameters
;
479 Log("VentoyMountAnywhere");
481 memset(&AttachParameters
, 0, sizeof(AttachParameters
));
482 AttachParameters
.Version
= ATTACH_VIRTUAL_DISK_VERSION_1
;
484 Status
= AttachVirtualDisk(Handle
, NULL
, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY
| ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME
, 0, &AttachParameters
, NULL
);
485 if (Status
!= ERROR_SUCCESS
)
487 Log("Failed to attach virtual disk ErrorCode:%u", Status
);
494 int VentoyMountY(HANDLE Handle
)
499 DWORD physicalDriveNameSize
;
501 WCHAR physicalDriveName
[MAX_PATH
];
502 CHAR physicalDriveNameA
[MAX_PATH
];
503 CHAR cdromDriveName
[MAX_PATH
];
504 ATTACH_VIRTUAL_DISK_PARAMETERS AttachParameters
;
508 memset(&AttachParameters
, 0, sizeof(AttachParameters
));
509 AttachParameters
.Version
= ATTACH_VIRTUAL_DISK_VERSION_1
;
511 Status
= AttachVirtualDisk(Handle
, NULL
, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY
| ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER
| ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME
, 0, &AttachParameters
, NULL
);
512 if (Status
!= ERROR_SUCCESS
)
514 Log("Failed to attach virtual disk ErrorCode:%u", Status
);
518 memset(physicalDriveName
, 0, sizeof(physicalDriveName
));
519 memset(physicalDriveNameA
, 0, sizeof(physicalDriveNameA
));
521 physicalDriveNameSize
= MAX_PATH
;
522 Status
= GetVirtualDiskPhysicalPath(Handle
, &physicalDriveNameSize
, physicalDriveName
);
523 if (Status
!= ERROR_SUCCESS
)
525 Log("Failed GetVirtualDiskPhysicalPath ErrorCode:%u", Status
);
529 for (i
= 0; physicalDriveName
[i
]; i
++)
531 physicalDriveNameA
[i
] = toupper((CHAR
)(physicalDriveName
[i
]));
534 Log("physicalDriveNameA=<%s>", physicalDriveNameA
);
536 Pos
= strstr(physicalDriveNameA
, "CDROM");
539 Log("Not cdrom phy drive");
543 sprintf_s(cdromDriveName
, sizeof(cdromDriveName
), "\\Device\\%s", Pos
);
544 Log("cdromDriveName=<%s>", cdromDriveName
);
546 for (i
= 0; i
< 3 && (bRet
== FALSE
); i
++)
549 bRet
= DefineDosDeviceA(DDD_RAW_TARGET_PATH
, "Y:", cdromDriveName
);
550 Log("DefineDosDeviceA %s", bRet
? "success" : "failed");
556 static BOOL
VentoyNeedMountY(const char *IsoPath
)
562 static int VentoyAttachVirtualDisk(HANDLE Handle
, const char *IsoPath
)
567 Drives
= GetLogicalDrives();
568 if ((1 << 24) & Drives
)
570 Log("Y: is occupied");
575 Log("Y: is free now");
579 if (DriveYFree
&& VentoyNeedMountY(IsoPath
))
581 return VentoyMountY(Handle
);
585 return VentoyMountAnywhere(Handle
);
589 int VentoyMountISOByAPI(const char *IsoPath
)
594 WCHAR wFilePath
[512] = { 0 };
595 VIRTUAL_STORAGE_TYPE StorageType
;
596 OPEN_VIRTUAL_DISK_PARAMETERS OpenParameters
;
598 Log("VentoyMountISOByAPI <%s>", IsoPath
);
600 if (IsUTF8Encode(IsoPath
))
602 Log("This is UTF8 encoding");
603 MultiByteToWideChar(CP_UTF8
, 0, IsoPath
, (int)strlen(IsoPath
), wFilePath
, (int)(sizeof(wFilePath
) / sizeof(WCHAR
)));
607 Log("This is ANSI encoding");
608 MultiByteToWideChar(CP_ACP
, 0, IsoPath
, (int)strlen(IsoPath
), wFilePath
, (int)(sizeof(wFilePath
) / sizeof(WCHAR
)));
611 memset(&StorageType
, 0, sizeof(StorageType
));
612 memset(&OpenParameters
, 0, sizeof(OpenParameters
));
614 OpenParameters
.Version
= OPEN_VIRTUAL_DISK_VERSION_1
;
616 for (i
= 0; i
< 10; i
++)
618 Status
= OpenVirtualDisk(&StorageType
, wFilePath
, VIRTUAL_DISK_ACCESS_READ
, 0, &OpenParameters
, &Handle
);
619 if (ERROR_FILE_NOT_FOUND
== Status
|| ERROR_PATH_NOT_FOUND
== Status
)
621 Log("OpenVirtualDisk ErrorCode:%u, now wait and retry...", Status
);
626 if (ERROR_SUCCESS
== Status
)
628 Log("OpenVirtualDisk success");
630 else if (ERROR_VIRTDISK_PROVIDER_NOT_FOUND
== Status
)
632 Log("VirtualDisk for ISO file is not supported in current system");
636 Log("Failed to open virtual disk ErrorCode:%u", Status
);
642 if (Status
!= ERROR_SUCCESS
)
647 Log("OpenVirtualDisk success");
649 Status
= VentoyAttachVirtualDisk(Handle
, IsoPath
);
650 if (Status
!= ERROR_SUCCESS
)
652 Log("Failed to attach virtual disk ErrorCode:%u", Status
);
657 Log("VentoyAttachVirtualDisk success");
664 static HANDLE g_FatPhyDrive
;
665 static UINT64 g_Part2StartSec
;
667 static int CopyFileFromFatDisk(const CHAR
* SrcFile
, const CHAR
*DstFile
)
674 Log("CopyFileFromFatDisk (%s)==>(%s)", SrcFile
, DstFile
);
676 flfile
= fl_fopen(SrcFile
, "rb");
679 fl_fseek(flfile
, 0, SEEK_END
);
680 size
= (int)fl_ftell(flfile
);
681 fl_fseek(flfile
, 0, SEEK_SET
);
683 buf
= (char *)malloc(size
);
686 fl_fread(buf
, 1, size
, flfile
);
689 SaveBuffer2File(DstFile
, buf
, size
);
699 static int VentoyFatDiskRead(uint32 Sector
, uint8
*Buffer
, uint32 SectorCount
)
704 LARGE_INTEGER liCurrentPosition
;
706 liCurrentPosition
.QuadPart
= Sector
+ g_Part2StartSec
;
707 liCurrentPosition
.QuadPart
*= 512;
708 SetFilePointerEx(g_FatPhyDrive
, liCurrentPosition
, &liCurrentPosition
, FILE_BEGIN
);
710 ReadSize
= (DWORD
)(SectorCount
* 512);
712 bRet
= ReadFile(g_FatPhyDrive
, Buffer
, ReadSize
, &dwSize
, NULL
);
713 if (bRet
== FALSE
|| dwSize
!= ReadSize
)
715 Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u\n", bRet
, ReadSize
, dwSize
, GetLastError());
721 static BOOL
Is2K10PE(void)
727 fopen_s(&fp
, "X:\\Windows\\System32\\PECMD.INI", "r");
733 memset(szLine
, 0, sizeof(szLine
));
734 while (fgets(szLine
, sizeof(szLine
) - 1, fp
))
736 if (strstr(szLine
, "2k10\\"))
747 static CHAR
GetMountLogicalDrive(void)
751 DWORD Mask
= 0x1000000;
753 // fixed use M as mountpoint for 2K10 PE
756 Log("Use M: for 2K10 PE");
760 Drives
= GetLogicalDrives();
761 Log("Drives=0x%x", Drives
);
765 if ((Drives
& Mask
) == 0)
777 UINT64
GetVentoyEfiPartStartSector(HANDLE hDrive
)
782 VTOY_GPT_INFO
*pGpt
= NULL
;
783 UINT64 StartSector
= 0;
785 SetFilePointer(hDrive
, 0, NULL
, FILE_BEGIN
);
787 bRet
= ReadFile(hDrive
, &MBR
, sizeof(MBR
), &dwSize
, NULL
);
788 Log("Read MBR Ret:%u Size:%u code:%u", bRet
, dwSize
, LASTERR
);
790 if ((!bRet
) || (dwSize
!= sizeof(MBR
)))
795 if (MBR
.PartTbl
[0].FsFlag
== 0xEE)
797 Log("GPT partition style");
799 pGpt
= malloc(sizeof(VTOY_GPT_INFO
));
805 SetFilePointer(hDrive
, 0, NULL
, FILE_BEGIN
);
806 bRet
= ReadFile(hDrive
, pGpt
, sizeof(VTOY_GPT_INFO
), &dwSize
, NULL
);
807 if ((!bRet
) || (dwSize
!= sizeof(VTOY_GPT_INFO
)))
809 Log("Failed to read gpt info %d %u %d", bRet
, dwSize
, LASTERR
);
813 StartSector
= pGpt
->PartTbl
[1].StartLBA
;
818 Log("MBR partition style");
819 StartSector
= MBR
.PartTbl
[1].StartSectorId
;
822 Log("GetVentoyEfiPart StartSector: %llu", StartSector
);
826 static int VentoyRunImdisk(const char *IsoPath
, const char *imdiskexe
)
831 PROCESS_INFORMATION Pi
;
833 Log("VentoyRunImdisk <%s> <%s>", IsoPath
, imdiskexe
);
835 Letter
= GetMountLogicalDrive();
836 sprintf_s(Cmdline
, sizeof(Cmdline
), "%s -a -o ro -f \"%s\" -m %C:", imdiskexe
, IsoPath
, Letter
);
837 Log("mount iso to %C: use imdisk cmd <%s>", Letter
, Cmdline
);
839 if (IsUTF8Encode(IsoPath
))
842 GetStartupInfoW(&Si
);
843 Si
.dwFlags
|= STARTF_USESHOWWINDOW
;
844 Si
.wShowWindow
= SW_HIDE
;
846 Utf8ToUtf16(Cmdline
, CmdlineW
);
847 CreateProcessW(NULL
, CmdlineW
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &Si
, &Pi
);
849 Log("This is UTF8 encoding");
854 GetStartupInfoA(&Si
);
855 Si
.dwFlags
|= STARTF_USESHOWWINDOW
;
856 Si
.wShowWindow
= SW_HIDE
;
858 CreateProcessA(NULL
, Cmdline
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &Si
, &Pi
);
860 Log("This is ANSI encoding");
863 Log("Wait for imdisk process ...");
864 WaitForSingleObject(Pi
.hProcess
, INFINITE
);
865 Log("imdisk process finished");
870 int VentoyMountISOByImdisk(const char *IsoPath
, DWORD PhyDrive
)
876 CHAR PhyPath
[MAX_PATH
];
877 GET_LENGTH_INFORMATION LengthInfo
;
879 Log("VentoyMountISOByImdisk %s", IsoPath
);
881 if (IsFileExist("X:\\Windows\\System32\\imdisk.exe"))
883 Log("imdisk.exe exist, use it directly...");
884 VentoyRunImdisk(IsoPath
, "imdisk.exe");
888 sprintf_s(PhyPath
, sizeof(PhyPath
), "\\\\.\\PhysicalDrive%d", PhyDrive
);
889 hDrive
= CreateFileA(PhyPath
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, 0, OPEN_EXISTING
, 0, 0);
890 if (hDrive
== INVALID_HANDLE_VALUE
)
892 Log("Could not open the disk<%s>, error:%u", PhyPath
, GetLastError());
896 bRet
= DeviceIoControl(hDrive
, IOCTL_DISK_GET_LENGTH_INFO
, NULL
, 0, &LengthInfo
, sizeof(LengthInfo
), &dwBytes
, NULL
);
899 Log("Could not get phy disk %s size, error:%u", PhyPath
, GetLastError());
903 g_FatPhyDrive
= hDrive
;
904 g_Part2StartSec
= GetVentoyEfiPartStartSector(hDrive
);
906 Log("Parse FAT fs...");
910 if (0 == fl_attach_media(VentoyFatDiskRead
, NULL
))
914 CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.sys", "ventoy\\imdisk.sys");
915 CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.exe", "ventoy\\imdisk.exe");
916 CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.cpl", "ventoy\\imdisk.cpl");
920 CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.sys", "ventoy\\imdisk.sys");
921 CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.exe", "ventoy\\imdisk.exe");
922 CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.cpl", "ventoy\\imdisk.cpl");
925 GetCurrentDirectoryA(sizeof(PhyPath
), PhyPath
);
926 strcat_s(PhyPath
, sizeof(PhyPath
), "\\ventoy\\imdisk.sys");
928 if (LoadNtDriver(PhyPath
) == 0)
930 VentoyRunImdisk(IsoPath
, "ventoy\\imdisk.exe");
938 SAFE_CLOSE_HANDLE(hDrive
);
943 static int MountIsoFile(CONST CHAR
*IsoPath
, DWORD PhyDrive
)
945 if (IsWindows8OrGreater())
947 Log("This is Windows 8 or latter...");
948 if (VentoyMountISOByAPI(IsoPath
) == 0)
950 Log("Mount iso by API success");
955 Log("Mount iso by API failed, maybe not supported, try imdisk");
956 return VentoyMountISOByImdisk(IsoPath
, PhyDrive
);
961 Log("This is before Windows 8 ...");
962 if (VentoyMountISOByImdisk(IsoPath
, PhyDrive
) == 0)
964 Log("Mount iso by imdisk success");
969 return VentoyMountISOByAPI(IsoPath
);
974 static int GetPhyDriveByLogicalDrive(int DriveLetter
)
979 VOLUME_DISK_EXTENTS DiskExtents
;
982 sprintf_s(PhyPath
, sizeof(PhyPath
), "\\\\.\\%C:", (CHAR
)DriveLetter
);
984 Handle
= CreateFileA(PhyPath
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, 0, OPEN_EXISTING
, 0, 0);
985 if (Handle
== INVALID_HANDLE_VALUE
)
987 Log("Could not open the disk<%s>, error:%u", PhyPath
, GetLastError());
991 Ret
= DeviceIoControl(Handle
,
992 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
,
996 (DWORD
)(sizeof(DiskExtents
)),
1000 if (!Ret
|| DiskExtents
.NumberOfDiskExtents
== 0)
1002 Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed %s, error:%u", PhyPath
, GetLastError());
1003 SAFE_CLOSE_HANDLE(Handle
);
1006 SAFE_CLOSE_HANDLE(Handle
);
1008 Log("LogicalDrive:%s PhyDrive:%d Offset:%llu ExtentLength:%llu",
1010 DiskExtents
.Extents
[0].DiskNumber
,
1011 DiskExtents
.Extents
[0].StartingOffset
.QuadPart
,
1012 DiskExtents
.Extents
[0].ExtentLength
.QuadPart
1015 return (int)DiskExtents
.Extents
[0].DiskNumber
;
1019 static int DeleteVentoyPart2MountPoint(DWORD PhyDrive
)
1024 CHAR DriveName
[] = "?:\\";
1026 Log("DeleteVentoyPart2MountPoint Phy%u ...", PhyDrive
);
1028 Drives
= GetLogicalDrives();
1031 if ((Drives
& 0x01) && IsFileExist("%C:\\ventoy\\ventoy.cpio", Letter
))
1033 Log("File %C:\\ventoy\\ventoy.cpio exist", Letter
);
1035 PhyDisk
= GetPhyDriveByLogicalDrive(Letter
);
1036 Log("PhyDisk=%u for %C", PhyDisk
, Letter
);
1038 if (PhyDisk
== PhyDrive
)
1040 DriveName
[0] = Letter
;
1041 DeleteVolumeMountPointA(DriveName
);
1053 static BOOL
check_tar_archive(const char *archive
, CHAR
*tarName
)
1057 const char *pos
= archive
;
1058 const char *slash
= archive
;
1062 if (*pos
== '\\' || *pos
== '/')
1069 len
= (int)strlen(slash
);
1071 if (len
> 7 && (strncmp(slash
+ len
- 7, ".tar.gz", 7) == 0 || strncmp(slash
+ len
- 7, ".tar.xz", 7) == 0))
1073 nameLen
= (int)sprintf_s(tarName
, MAX_PATH
, "X:%s", slash
);
1074 tarName
[nameLen
- 3] = 0;
1077 else if (len
> 8 && strncmp(slash
+ len
- 8, ".tar.bz2", 8) == 0)
1079 nameLen
= (int)sprintf_s(tarName
, MAX_PATH
, "X:%s", slash
);
1080 tarName
[nameLen
- 4] = 0;
1083 else if (len
> 9 && strncmp(slash
+ len
- 9, ".tar.lzma", 9) == 0)
1085 nameLen
= (int)sprintf_s(tarName
, MAX_PATH
, "X:%s", slash
);
1086 tarName
[nameLen
- 5] = 0;
1093 static int DecompressInjectionArchive(const char *archive
, DWORD PhyDrive
)
1100 DWORD flags
= CREATE_NO_WINDOW
;
1101 CHAR StrBuf
[MAX_PATH
];
1102 CHAR tarName
[MAX_PATH
];
1104 PROCESS_INFORMATION Pi
;
1105 PROCESS_INFORMATION NewPi
;
1106 GET_LENGTH_INFORMATION LengthInfo
;
1107 SECURITY_ATTRIBUTES Sa
= { sizeof(SECURITY_ATTRIBUTES
), NULL
, TRUE
};
1109 Log("DecompressInjectionArchive %s", archive
);
1111 sprintf_s(StrBuf
, sizeof(StrBuf
), "\\\\.\\PhysicalDrive%d", PhyDrive
);
1112 hDrive
= CreateFileA(StrBuf
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, 0, OPEN_EXISTING
, 0, 0);
1113 if (hDrive
== INVALID_HANDLE_VALUE
)
1115 Log("Could not open the disk<%s>, error:%u", StrBuf
, GetLastError());
1119 bRet
= DeviceIoControl(hDrive
, IOCTL_DISK_GET_LENGTH_INFO
, NULL
, 0, &LengthInfo
, sizeof(LengthInfo
), &dwBytes
, NULL
);
1122 Log("Could not get phy disk %s size, error:%u", StrBuf
, GetLastError());
1126 g_FatPhyDrive
= hDrive
;
1127 g_Part2StartSec
= GetVentoyEfiPartStartSector(hDrive
);
1129 Log("Parse FAT fs...");
1133 if (0 == fl_attach_media(VentoyFatDiskRead
, NULL
))
1137 CopyFileFromFatDisk("/ventoy/7z/64/7za.exe", "ventoy\\7za.exe");
1141 CopyFileFromFatDisk("/ventoy/7z/32/7za.exe", "ventoy\\7za.exe");
1144 sprintf_s(StrBuf
, sizeof(StrBuf
), "ventoy\\7za.exe x -y -aoa -oX:\\ %s", archive
);
1146 Log("extract inject to X:");
1147 Log("cmdline:<%s>", StrBuf
);
1149 GetStartupInfoA(&Si
);
1151 hOut
= CreateFileA("ventoy\\7z.log",
1153 FILE_SHARE_WRITE
| FILE_SHARE_READ
,
1156 FILE_ATTRIBUTE_NORMAL
,
1159 Si
.dwFlags
|= STARTF_USESTDHANDLES
;
1161 if (hOut
!= INVALID_HANDLE_VALUE
)
1163 Si
.hStdError
= hOut
;
1164 Si
.hStdOutput
= hOut
;
1167 CreateProcessA(NULL
, StrBuf
, NULL
, NULL
, TRUE
, flags
, NULL
, NULL
, &Si
, &Pi
);
1168 WaitForSingleObject(Pi
.hProcess
, INFINITE
);
1171 // decompress tar archive, for tar.gz/tar.xz/tar.bz2
1173 if (check_tar_archive(archive
, tarName
))
1175 Log("Decompress tar archive...<%s>", tarName
);
1177 sprintf_s(StrBuf
, sizeof(StrBuf
), "ventoy\\7za.exe x -y -aoa -oX:\\ %s", tarName
);
1179 CreateProcessA(NULL
, StrBuf
, NULL
, NULL
, TRUE
, flags
, NULL
, NULL
, &Si
, &NewPi
);
1180 WaitForSingleObject(NewPi
.hProcess
, INFINITE
);
1182 Log("Now delete %s", tarName
);
1183 DeleteFileA(tarName
);
1186 SAFE_CLOSE_HANDLE(hOut
);
1192 SAFE_CLOSE_HANDLE(hDrive
);
1197 static int ProcessUnattendedInstallation(const char *script
)
1203 CHAR CurDir
[MAX_PATH
];
1205 Log("Copy unattended XML ...");
1207 GetCurrentDirectory(sizeof(CurDir
), CurDir
);
1209 if ((Letter
>= 'A' && Letter
<= 'Z') || (Letter
>= 'a' && Letter
<= 'z'))
1211 Log("Current Drive Letter: %C", Letter
);
1218 sprintf_s(CurDir
, sizeof(CurDir
), "%C:\\Autounattend.xml", Letter
);
1219 Log("Copy file <%s> --> <%s>", script
, CurDir
);
1220 CopyFile(script
, CurDir
, FALSE
);
1222 Ret
= RegCreateKeyEx(HKEY_LOCAL_MACHINE
, "System\\Setup", 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hKey
, &dw
);
1223 if (ERROR_SUCCESS
== Ret
)
1225 Ret
= RegSetValueEx(hKey
, "UnattendFile", 0, REG_SZ
, CurDir
, (DWORD
)(strlen(CurDir
) + 1));
1231 static int VentoyHook(ventoy_os_param
*param
)
1238 DISK_EXTENT DiskExtent
;
1240 CHAR IsoPath
[MAX_PATH
];
1242 Log("VentoyHook Path:<%s>", param
->vtoy_img_path
);
1244 if (IsUTF8Encode(param
->vtoy_img_path
))
1246 Log("This file is UTF8 encoding\n");
1249 for (i
= 0; i
< 5; i
++)
1252 Drives
= GetLogicalDrives();
1253 Log("Logic Drives: 0x%x", Drives
);
1259 sprintf_s(IsoPath
, sizeof(IsoPath
), "%C:\\%s", Letter
, param
->vtoy_img_path
);
1260 if (IsFileExist("%s", IsoPath
))
1262 Log("File exist under %C:", Letter
);
1263 if (GetPhyDiskUUID(Letter
, UUID
, &DiskExtent
) == 0)
1265 if (memcmp(UUID
, param
->vtoy_disk_guid
, 16) == 0)
1267 Log("Disk UUID match");
1275 Log("File NOT exist under %C:", Letter
);
1289 Log("Now wait and retry ...");
1296 Log("Failed to find ISO file");
1300 Log("Find ISO file <%s>", IsoPath
);
1302 rc
= MountIsoFile(IsoPath
, DiskExtent
.DiskNumber
);
1303 Log("Mount ISO FILE: %s", rc
== 0 ? "SUCCESS" : "FAILED");
1306 rc
= DeleteVentoyPart2MountPoint(DiskExtent
.DiskNumber
);
1307 Log("Delete ventoy mountpoint: %s", rc
== 0 ? "SUCCESS" : "NO NEED");
1309 if (g_windows_data
.auto_install_script
[0])
1311 sprintf_s(IsoPath
, sizeof(IsoPath
), "%C:%s", Letter
, g_windows_data
.auto_install_script
);
1312 if (IsFileExist("%s", IsoPath
))
1314 Log("use auto install script %s...", IsoPath
);
1315 ProcessUnattendedInstallation(IsoPath
);
1319 Log("auto install script %s not exist", IsoPath
);
1324 Log("auto install no need");
1327 if (g_windows_data
.injection_archive
[0])
1329 sprintf_s(IsoPath
, sizeof(IsoPath
), "%C:%s", Letter
, g_windows_data
.injection_archive
);
1330 if (IsFileExist("%s", IsoPath
))
1332 Log("decompress injection archive %s...", IsoPath
);
1333 DecompressInjectionArchive(IsoPath
, DiskExtent
.DiskNumber
);
1337 Log("injection archive %s not exist", IsoPath
);
1342 Log("no injection archive found");
1348 const char * GetFileNameInPath(const char *fullpath
)
1351 const char *pos
= NULL
;
1353 if (strstr(fullpath
, ":"))
1355 for (i
= (int)strlen(fullpath
); i
> 0; i
--)
1357 if (fullpath
[i
- 1] == '/' || fullpath
[i
- 1] == '\\')
1359 return fullpath
+ i
;
1367 int VentoyJumpWimboot(INT argc
, CHAR
**argv
, CHAR
*LunchFile
)
1375 g_64bit_system
= FALSE
;
1377 g_64bit_system
= TRUE
;
1380 Log("VentoyJumpWimboot %dbit", g_64bit_system
? 64 : 32);
1382 sprintf_s(LunchFile
, MAX_PATH
, "X:\\setup.exe");
1384 ReadWholeFile2Buf("wimboot.data", &buf
, &size
);
1385 Log("wimboot.data size:%d", size
);
1387 memcpy(&g_os_param
, buf
, sizeof(ventoy_os_param
));
1388 memcpy(&g_windows_data
, buf
+ sizeof(ventoy_os_param
), sizeof(ventoy_windows_data
));
1389 memcpy(g_os_param_reserved
, g_os_param
.vtoy_reserved
, sizeof(g_os_param_reserved
));
1391 if (g_os_param_reserved
[0] == 1)
1393 Log("break here for debug .....");
1398 for (Pos
= 0; Pos
< sizeof(g_os_param
.vtoy_img_path
) && g_os_param
.vtoy_img_path
[Pos
]; Pos
++)
1400 if (g_os_param
.vtoy_img_path
[Pos
] == '/')
1402 g_os_param
.vtoy_img_path
[Pos
] = '\\';
1406 if (g_os_param_reserved
[0] == 2)
1408 Log("skip hook for debug .....");
1413 rc
= VentoyHook(&g_os_param
);
1425 static int ventoy_check_create_directory(void)
1427 if (IsDirExist("ventoy"))
1429 Log("ventoy directory already exist");
1433 Log("ventoy directory not exist, now create it.");
1434 if (!CreateDirectoryA("ventoy", NULL
))
1436 Log("Failed to create ventoy directory err:%u", GetLastError());
1444 static BOOL
VentoyFindCmdLineStr(BYTE
*buf
, DWORD size
)
1448 UINT32 uiDataHex
= *(UINT32
*)(g_aucCmdLineHex
);
1450 for (i
= 0; i
< size
- sizeof(g_aucCmdLineHex
); i
+= 16)
1452 uiDataChk
= *(UINT32
*)(buf
+ i
);
1453 if (uiDataChk
== uiDataHex
&& memcmp(buf
+ i
, g_aucCmdLineHex
, sizeof(g_aucCmdLineHex
)) == 0)
1462 int VentoyJump(INT argc
, CHAR
**argv
, CHAR
*LunchFile
)
1469 DWORD LockStatus
= 0;
1470 BYTE
*Buffer
= NULL
;
1471 CHAR ExeFileName
[MAX_PATH
];
1473 sprintf_s(ExeFileName
, sizeof(ExeFileName
), "%s", argv
[0]);
1474 if (!IsFileExist("%s", ExeFileName
))
1476 Log("File %s NOT exist, now try %s.exe", ExeFileName
, ExeFileName
);
1477 sprintf_s(ExeFileName
, sizeof(ExeFileName
), "%s.exe", argv
[0]);
1479 Log("File %s exist ? %s", ExeFileName
, IsFileExist("%s", ExeFileName
) ? "YES" : "NO");
1482 if (ReadWholeFile2Buf(ExeFileName
, (void **)&Buffer
, &FileSize
))
1487 g_64bit_system
= IsPe64(Buffer
);
1488 Log("VentoyJump %dbit", g_64bit_system
? 64 : 32);
1490 MUTEX_LOCK(g_vtoyins_mutex
);
1491 stat
= ventoy_check_create_directory();
1492 MUTEX_UNLOCK(g_vtoyins_mutex
);
1499 for (PeStart
= 0; PeStart
< FileSize
; PeStart
+= 16)
1501 if (CheckOsParam((ventoy_os_param
*)(Buffer
+ PeStart
)) &&
1502 CheckPeHead(Buffer
+ PeStart
+ sizeof(ventoy_os_param
) + sizeof(ventoy_windows_data
)))
1504 Log("Find os pararm at %u", PeStart
);
1506 memcpy(&g_os_param
, Buffer
+ PeStart
, sizeof(ventoy_os_param
));
1507 memcpy(&g_windows_data
, Buffer
+ PeStart
+ sizeof(ventoy_os_param
), sizeof(ventoy_windows_data
));
1508 memcpy(g_os_param_reserved
, g_os_param
.vtoy_reserved
, sizeof(g_os_param_reserved
));
1510 if (g_os_param_reserved
[0] == 1)
1512 Log("break here for debug .....");
1517 for (Pos
= 0; Pos
< sizeof(g_os_param
.vtoy_img_path
) && g_os_param
.vtoy_img_path
[Pos
]; Pos
++)
1519 if (g_os_param
.vtoy_img_path
[Pos
] == '/')
1521 g_os_param
.vtoy_img_path
[Pos
] = '\\';
1525 PeStart
+= sizeof(ventoy_os_param
) + sizeof(ventoy_windows_data
);
1526 sprintf_s(LunchFile
, MAX_PATH
, "ventoy\\%s", GetFileNameInPath(ExeFileName
));
1528 MUTEX_LOCK(g_vtoyins_mutex
);
1529 if (IsFileExist("%s", LunchFile
))
1531 Log("vtoyjump multiple call ...");
1533 MUTEX_UNLOCK(g_vtoyins_mutex
);
1537 SaveBuffer2File(LunchFile
, Buffer
+ PeStart
, FileSize
- PeStart
);
1538 MUTEX_UNLOCK(g_vtoyins_mutex
);
1540 #ifdef VTOY_REJUMP_SUPPORTED
1541 if (_stricmp(LunchFile
, "ventoy\\PECMD.EXE") == 0)
1543 g_PecmdHasCmdLine
= VentoyFindCmdLineStr(Buffer
+ PeStart
, FileSize
- PeStart
);
1551 if (PeStart
>= FileSize
)
1553 Log("OS param not found");
1557 if (g_os_param_reserved
[0] == 2)
1559 Log("skip hook for debug .....");
1564 rc
= VentoyHook(&g_os_param
);
1578 static int ventoy_append_process_id(const char *pidfile
)
1583 PID
= GetCurrentProcessId();
1585 fopen_s(&fp
, pidfile
, "a+");
1591 fprintf_s(fp
, "%u\n", PID
);
1597 static int ventoy_get_instance_id(const char *pidfile
)
1603 fopen_s(&fp
, pidfile
, "r");
1609 while (fgets(line
, sizeof(line
), fp
))
1615 return instance
+ 1;
1618 int main(int argc
, char **argv
)
1623 BOOL ReJump
= FALSE
;
1625 CHAR CurDir
[MAX_PATH
];
1626 CHAR LunchFile
[MAX_PATH
];
1627 CHAR CallParam
[1024] = { 0 };
1628 DWORD LockStatus
= 0;
1630 PROCESS_INFORMATION Pi
;
1632 #ifdef VTOY_REJUMP_SUPPORTED
1633 if (argv
[0] && strcmp(argv
[0], "ventoy\\WinLogon.exe") == 0)
1635 GetStartupInfoA(&Si
);
1636 Si
.dwFlags
|= STARTF_USESHOWWINDOW
;
1637 Si
.wShowWindow
= SW_HIDE
;
1639 sprintf_s(LunchFile
, sizeof(LunchFile
), "PECMD.EXE");
1640 for (i
= 1; i
< argc
; i
++)
1642 strcat_s(LunchFile
, sizeof(LunchFile
), " ");
1643 strcat_s(LunchFile
, sizeof(LunchFile
), argv
[i
]);
1646 CreateProcessA(NULL
, LunchFile
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &Si
, &Pi
);
1647 WaitForSingleObject(Pi
.hProcess
, INFINITE
);
1652 g_PecmdHasCmdLine
= 0;
1653 g_vtoylog_mutex
= CreateMutexA(NULL
, FALSE
, "VTOYLOG_LOCK");
1654 g_vtoyins_mutex
= CreateMutexA(NULL
, FALSE
, "VTOYINS_LOCK");
1656 MUTEX_LOCK(g_vtoyins_mutex
);
1657 if (IsFileExist(VTOY_PID_FILE
))
1659 id
= ventoy_get_instance_id(VTOY_PID_FILE
);
1665 ventoy_append_process_id(VTOY_PID_FILE
);
1666 MUTEX_UNLOCK(g_vtoyins_mutex
);
1668 if (argv
[0] && argv
[0][0] && argv
[0][1] == ':')
1670 GetCurrentDirectoryA(sizeof(CurDir
), CurDir
);
1672 strcpy_s(LunchFile
, sizeof(LunchFile
), argv
[0]);
1673 Pos
= (char *)GetFileNameInPath(LunchFile
);
1675 strcat_s(CurDir
, sizeof(CurDir
), "\\");
1676 strcat_s(CurDir
, sizeof(CurDir
), Pos
);
1678 if (_stricmp(argv
[0], CurDir
) != 0)
1681 SetCurrentDirectoryA(LunchFile
);
1686 Log("######## VentoyJump 32bit [%d] ##########", id
);
1688 Log("######## VentoyJump 64bit [%d] ##########", id
);
1691 Log("argc = %d", argc
);
1692 for (i
= 0; i
< argc
; i
++)
1694 Log("argv[%d]=<%s>", i
, argv
[i
]);
1697 strcat_s(CallParam
, sizeof(CallParam
), " ");
1698 strcat_s(CallParam
, sizeof(CallParam
), argv
[i
]);
1702 if (Pos
&& *Pos
== 0)
1704 Log("Old current directory = <%s>", CurDir
);
1705 Log("New current directory = <%s>", LunchFile
);
1709 GetCurrentDirectoryA(sizeof(CurDir
), CurDir
);
1710 Log("Current directory = <%s>", CurDir
);
1713 GetStartupInfoA(&Si
);
1715 memset(LunchFile
, 0, sizeof(LunchFile
));
1717 if (strstr(argv
[0], "vtoyjump.exe"))
1719 rc
= VentoyJumpWimboot(argc
, argv
, LunchFile
);
1723 rc
= VentoyJump(argc
, argv
, LunchFile
);
1726 Log("id=%d LunchFile=<%s> CallParam=<%s>", id
, LunchFile
, CallParam
);
1728 if (id
== 1 && _stricmp(argv
[0], "PECMD.EXE") == 0 && _stricmp(LunchFile
, "ventoy\\PECMD.EXE") == 0)
1730 MUTEX_LOCK(g_vtoyins_mutex
);
1731 id
= ventoy_get_instance_id(VTOY_PID_FILE
);
1732 MUTEX_UNLOCK(g_vtoyins_mutex
);
1734 Log("Current instance id is: %d", id
);
1738 #ifdef VTOY_REJUMP_SUPPORTED
1739 if (g_PecmdHasCmdLine
)
1742 CopyFileA("PECMD.EXE", "ventoy\\WinLogon.exe", TRUE
);
1746 MoveFileA("PECMD.EXE", "PECMD_BACK.EXE");
1747 CopyFileA("ventoy\\PECMD.EXE", "PECMD.EXE", TRUE
);
1748 sprintf_s(LunchFile
, sizeof(LunchFile
), "%s", "PECMD.EXE");
1749 Log("Move original PECMD.EXE <%s>", LunchFile
);
1753 Log("%d instance started, don't move PECMD.EXE", id
);
1757 if (g_os_param_reserved
[0] == 3)
1759 Log("Open log for debug ...");
1760 sprintf_s(LunchFile
, sizeof(LunchFile
), "%s", "notepad.exe ventoy.log");
1766 strcat_s(LunchFile
, sizeof(LunchFile
), CallParam
);
1768 else if (NULL
== strstr(LunchFile
, "setup.exe"))
1770 Log("Not setup.exe, hide windows.");
1771 Si
.dwFlags
|= STARTF_USESHOWWINDOW
;
1772 Si
.wShowWindow
= SW_HIDE
;
1775 Log("Ventoy jump %s ...", rc
== 0 ? "success" : "failed");
1778 Log("Now launch <%s> ...", LunchFile
);
1780 if (g_os_param_reserved
[0] == 4)
1782 Log("Open cmd for debug ...");
1783 sprintf_s(LunchFile
, sizeof(LunchFile
), "%s", "cmd.exe");
1786 #ifdef VTOY_REJUMP_SUPPORTED
1789 sprintf_s(CallParam
, sizeof(CallParam
), "ventoy\\WinLogon.exe%s", LunchFile
+ strlen("PECMD.EXE"));
1790 Log("Now rejump to pecmd.exe <%s> ...", CallParam
);
1792 CreateProcessA(NULL
, CallParam
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &Si
, &Pi
);
1794 Log("Wait rejump process...");
1795 WaitForSingleObject(Pi
.hProcess
, INFINITE
);
1796 Log("rejump finished");
1803 CreateProcessA(NULL
, LunchFile
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &Si
, &Pi
);
1805 for (i
= 0; rc
&& i
< 1800; i
++)
1807 Log("Ventoy hook failed, now wait and retry ...");
1809 rc
= VentoyHook(&g_os_param
);
1812 Log("Wait process...");
1813 WaitForSingleObject(Pi
.hProcess
, INFINITE
);
1815 Log("vtoyjump finished");