]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - vtoyjump/vtoyjump/vtoyjump.c
7c3d80377ce2012ad466ff0fce8aa160f1ea0c3f
[Ventoy.git] / vtoyjump / vtoyjump / vtoyjump.c
1 /******************************************************************************
2 * vtoyjump.c
3 *
4 * Copyright (c) 2021, longpanda <admin@ventoy.net>
5 *
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.
10 *
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.
15 *
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/>.
18 *
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <Windows.h>
25 #include <virtdisk.h>
26 #include <winioctl.h>
27 #include <VersionHelpers.h>
28 #include "vtoyjump.h"
29 #include "fat_filelib.h"
30
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 INT g_system_bit = VTOY_BIT;
35 static ventoy_guid g_ventoy_guid = VENTOY_GUID;
36 static HANDLE g_vtoylog_mutex = NULL;
37 static HANDLE g_vtoyins_mutex = NULL;
38
39 static CHAR g_prog_full_path[MAX_PATH];
40 static CHAR g_prog_dir[MAX_PATH];
41 static CHAR g_prog_name[MAX_PATH];
42
43 #define VTOY_PECMD_PATH "X:\\Windows\\system32\\ventoy\\PECMD.EXE"
44 #define ORG_PECMD_PATH "X:\\Windows\\system32\\PECMD.EXE"
45 #define ORG_PECMD_BK_PATH "X:\\Windows\\system32\\PECMD.EXE_BACK.EXE"
46
47 #define AUTO_RUN_BAT "X:\\VentoyAutoRun.bat"
48 #define AUTO_RUN_LOG "X:\\VentoyAutoRun.log"
49
50 #define LOG_FILE "X:\\Windows\\system32\\ventoy.log"
51 #define MUTEX_LOCK(hmutex) if (hmutex != NULL) LockStatus = WaitForSingleObject(hmutex, INFINITE)
52 #define MUTEX_UNLOCK(hmutex) if (hmutex != NULL && WAIT_OBJECT_0 == LockStatus) ReleaseMutex(hmutex)
53
54 static const char * GetFileNameInPath(const char *fullpath)
55 {
56 int i;
57
58 if (strstr(fullpath, ":"))
59 {
60 for (i = (int)strlen(fullpath); i > 0; i--)
61 {
62 if (fullpath[i - 1] == '/' || fullpath[i - 1] == '\\')
63 {
64 return fullpath + i;
65 }
66 }
67 }
68
69 return fullpath;
70 }
71
72 static int split_path_name(char *fullpath, char *dir, char *name)
73 {
74 CHAR ch;
75 CHAR *Pos = NULL;
76
77 Pos = (CHAR *)GetFileNameInPath(fullpath);
78
79 strcpy_s(name, MAX_PATH, Pos);
80
81 ch = *(Pos - 1);
82 *(Pos - 1) = 0;
83 strcpy_s(dir, MAX_PATH, fullpath);
84 *(Pos - 1) = ch;
85
86 return 0;
87 }
88
89
90 void Log(const char *Fmt, ...)
91 {
92 va_list Arg;
93 int Len = 0;
94 FILE *File = NULL;
95 SYSTEMTIME Sys;
96 char szBuf[1024];
97 DWORD LockStatus = 0;
98 DWORD PID = GetCurrentProcessId();
99
100 GetLocalTime(&Sys);
101 Len += sprintf_s(szBuf, sizeof(szBuf),
102 "[%4d/%02d/%02d %02d:%02d:%02d.%03d] [%u] ",
103 Sys.wYear, Sys.wMonth, Sys.wDay,
104 Sys.wHour, Sys.wMinute, Sys.wSecond,
105 Sys.wMilliseconds, PID);
106
107 va_start(Arg, Fmt);
108 Len += vsnprintf_s(szBuf + Len, sizeof(szBuf)-Len, sizeof(szBuf)-Len, Fmt, Arg);
109 va_end(Arg);
110
111 MUTEX_LOCK(g_vtoylog_mutex);
112
113 fopen_s(&File, LOG_FILE, "a+");
114 if (File)
115 {
116 fwrite(szBuf, 1, Len, File);
117 fwrite("\n", 1, 1, File);
118 fclose(File);
119 }
120
121 MUTEX_UNLOCK(g_vtoylog_mutex);
122 }
123
124
125 static int LoadNtDriver(const char *DrvBinPath)
126 {
127 int i;
128 int rc = 0;
129 BOOL Ret;
130 DWORD Status;
131 SC_HANDLE hServiceMgr;
132 SC_HANDLE hService;
133 char name[256] = { 0 };
134
135 for (i = (int)strlen(DrvBinPath) - 1; i >= 0; i--)
136 {
137 if (DrvBinPath[i] == '\\' || DrvBinPath[i] == '/')
138 {
139 sprintf_s(name, sizeof(name), "%s", DrvBinPath + i + 1);
140 break;
141 }
142 }
143
144 Log("Load NT driver: %s %s", DrvBinPath, name);
145
146 hServiceMgr = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
147 if (hServiceMgr == NULL)
148 {
149 Log("OpenSCManager failed Error:%u", GetLastError());
150 return 1;
151 }
152
153 Log("OpenSCManager OK");
154
155 hService = CreateServiceA(hServiceMgr,
156 name,
157 name,
158 SERVICE_ALL_ACCESS,
159 SERVICE_KERNEL_DRIVER,
160 SERVICE_DEMAND_START,
161 SERVICE_ERROR_NORMAL,
162 DrvBinPath,
163 NULL, NULL, NULL, NULL, NULL);
164 if (hService == NULL)
165 {
166 Status = GetLastError();
167 if (Status != ERROR_IO_PENDING && Status != ERROR_SERVICE_EXISTS)
168 {
169 Log("CreateService failed v %u", Status);
170 CloseServiceHandle(hServiceMgr);
171 return 1;
172 }
173
174 hService = OpenServiceA(hServiceMgr, name, SERVICE_ALL_ACCESS);
175 if (hService == NULL)
176 {
177 Log("OpenService failed %u", Status);
178 CloseServiceHandle(hServiceMgr);
179 return 1;
180 }
181 }
182
183 Log("CreateService imdisk OK");
184
185 Ret = StartServiceA(hService, 0, NULL);
186 if (Ret)
187 {
188 Log("StartService OK");
189 }
190 else
191 {
192 Status = GetLastError();
193 if (Status == ERROR_SERVICE_ALREADY_RUNNING)
194 {
195 rc = 0;
196 }
197 else
198 {
199 Log("StartService error %u", Status);
200 rc = 1;
201 }
202 }
203
204 CloseServiceHandle(hService);
205 CloseServiceHandle(hServiceMgr);
206
207 Log("Load NT driver %s", rc ? "failed" : "success");
208
209 return rc;
210 }
211
212 static int ReadWholeFile2Buf(const char *Fullpath, void **Data, DWORD *Size)
213 {
214 int rc = 1;
215 DWORD FileSize;
216 DWORD dwSize;
217 HANDLE Handle;
218 BYTE *Buffer = NULL;
219
220 Log("ReadWholeFile2Buf <%s>", Fullpath);
221
222 Handle = CreateFileA(Fullpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
223 if (Handle == INVALID_HANDLE_VALUE)
224 {
225 Log("Could not open the file<%s>, error:%u", Fullpath, GetLastError());
226 goto End;
227 }
228
229 FileSize = SetFilePointer(Handle, 0, NULL, FILE_END);
230
231 Buffer = malloc(FileSize);
232 if (!Buffer)
233 {
234 Log("Failed to alloc memory size:%u", FileSize);
235 goto End;
236 }
237
238 SetFilePointer(Handle, 0, NULL, FILE_BEGIN);
239 if (!ReadFile(Handle, Buffer, FileSize, &dwSize, NULL))
240 {
241 Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError());
242 goto End;
243 }
244
245 *Data = Buffer;
246 *Size = FileSize;
247
248 Log("Success read file size:%u", FileSize);
249
250 rc = 0;
251
252 End:
253 SAFE_CLOSE_HANDLE(Handle);
254
255 return rc;
256 }
257
258 static BOOL CheckPeHead(BYTE *Head)
259 {
260 UINT32 PeOffset;
261
262 if (Head[0] != 'M' || Head[1] != 'Z')
263 {
264 return FALSE;
265 }
266
267 PeOffset = *(UINT32 *)(Head + 60);
268 if (*(UINT32 *)(Head + PeOffset) != 0x00004550)
269 {
270 return FALSE;
271 }
272
273 return TRUE;
274 }
275
276
277 static BOOL CheckOsParam(ventoy_os_param *param)
278 {
279 UINT32 i;
280 BYTE Sum = 0;
281
282 if (memcmp(&param->guid, &g_ventoy_guid, sizeof(ventoy_guid)))
283 {
284 return FALSE;
285 }
286
287 for (i = 0; i < sizeof(ventoy_os_param); i++)
288 {
289 Sum += *((BYTE *)param + i);
290 }
291
292 if (Sum)
293 {
294 return FALSE;
295 }
296
297 if (param->vtoy_img_location_addr % 4096)
298 {
299 return FALSE;
300 }
301
302 return TRUE;
303 }
304
305 static int SaveBuffer2File(const char *Fullpath, void *Buffer, DWORD Length)
306 {
307 int rc = 1;
308 DWORD dwSize;
309 HANDLE Handle;
310
311 Log("SaveBuffer2File <%s> len:%u", Fullpath, Length);
312
313 Handle = CreateFileA(Fullpath, GENERIC_READ | GENERIC_WRITE,
314 FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, 0, 0);
315 if (Handle == INVALID_HANDLE_VALUE)
316 {
317 Log("Could not create new file, error:%u", GetLastError());
318 goto End;
319 }
320
321 WriteFile(Handle, Buffer, Length, &dwSize, NULL);
322
323 rc = 0;
324
325 End:
326 SAFE_CLOSE_HANDLE(Handle);
327
328 return rc;
329 }
330
331 static int IsUTF8Encode(const char *src)
332 {
333 int i;
334 const UCHAR *Byte = (const UCHAR *)src;
335
336 for (i = 0; i < MAX_PATH && Byte[i]; i++)
337 {
338 if (Byte[i] > 127)
339 {
340 return 1;
341 }
342 }
343
344 return 0;
345 }
346
347 static int Utf8ToUtf16(const char* src, WCHAR * dst)
348 {
349 int size = MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, 0);
350 return MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, size + 1);
351 }
352
353 static BOOL IsDirExist(const char *Fmt, ...)
354 {
355 va_list Arg;
356 DWORD Attr;
357 int UTF8 = 0;
358 CHAR FilePathA[MAX_PATH];
359 WCHAR FilePathW[MAX_PATH];
360
361 va_start(Arg, Fmt);
362 vsnprintf_s(FilePathA, sizeof(FilePathA), sizeof(FilePathA), Fmt, Arg);
363 va_end(Arg);
364
365 UTF8 = IsUTF8Encode(FilePathA);
366
367 if (UTF8)
368 {
369 Utf8ToUtf16(FilePathA, FilePathW);
370 Attr = GetFileAttributesW(FilePathW);
371 }
372 else
373 {
374 Attr = GetFileAttributesA(FilePathA);
375 }
376
377 if (Attr != INVALID_FILE_ATTRIBUTES && (Attr & FILE_ATTRIBUTE_DIRECTORY))
378 {
379 return TRUE;
380 }
381
382 return FALSE;
383 }
384
385 static BOOL IsFileExist(const char *Fmt, ...)
386 {
387 va_list Arg;
388 HANDLE hFile;
389 DWORD Attr;
390 BOOL bRet = FALSE;
391 int UTF8 = 0;
392 CHAR FilePathA[MAX_PATH];
393 WCHAR FilePathW[MAX_PATH];
394
395 va_start(Arg, Fmt);
396 vsnprintf_s(FilePathA, sizeof(FilePathA), sizeof(FilePathA), Fmt, Arg);
397 va_end(Arg);
398
399 UTF8 = IsUTF8Encode(FilePathA);
400
401 if (UTF8)
402 {
403 Utf8ToUtf16(FilePathA, FilePathW);
404 hFile = CreateFileW(FilePathW, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
405 }
406 else
407 {
408 hFile = CreateFileA(FilePathA, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
409 }
410 if (INVALID_HANDLE_VALUE == hFile)
411 {
412 goto out;
413 }
414
415 CloseHandle(hFile);
416
417 if (UTF8)
418 {
419 Attr = GetFileAttributesW(FilePathW);
420 }
421 else
422 {
423 Attr = GetFileAttributesA(FilePathA);
424 }
425
426 if (Attr & FILE_ATTRIBUTE_DIRECTORY)
427 {
428 goto out;
429 }
430
431 bRet = TRUE;
432
433 out:
434 Log("File <%s> %s", FilePathA, (bRet ? "exist" : "NOT exist"));
435 return bRet;
436 }
437
438 static int GetPhyDiskUUID(const char LogicalDrive, UINT8 *UUID, UINT32 *DiskSig, DISK_EXTENT *DiskExtent)
439 {
440 BOOL Ret;
441 DWORD dwSize;
442 HANDLE Handle;
443 VOLUME_DISK_EXTENTS DiskExtents;
444 CHAR PhyPath[128];
445 UINT8 SectorBuf[512];
446
447 Log("GetPhyDiskUUID %C", LogicalDrive);
448
449 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", LogicalDrive);
450 Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
451 if (Handle == INVALID_HANDLE_VALUE)
452 {
453 Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
454 return 1;
455 }
456
457 Ret = DeviceIoControl(Handle,
458 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
459 NULL,
460 0,
461 &DiskExtents,
462 (DWORD)(sizeof(DiskExtents)),
463 (LPDWORD)&dwSize,
464 NULL);
465 if (!Ret || DiskExtents.NumberOfDiskExtents == 0)
466 {
467 Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed, error:%u", GetLastError());
468 CloseHandle(Handle);
469 return 1;
470 }
471 CloseHandle(Handle);
472
473 memcpy(DiskExtent, DiskExtents.Extents, sizeof(DISK_EXTENT));
474 Log("%C: is in PhysicalDrive%d Offset:%llu", LogicalDrive, DiskExtents.Extents[0].DiskNumber,
475 (ULONGLONG)(DiskExtents.Extents[0].StartingOffset.QuadPart));
476
477 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", DiskExtents.Extents[0].DiskNumber);
478 Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
479 if (Handle == INVALID_HANDLE_VALUE)
480 {
481 Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
482 return 1;
483 }
484
485 if (!ReadFile(Handle, SectorBuf, sizeof(SectorBuf), &dwSize, NULL))
486 {
487 Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError());
488 CloseHandle(Handle);
489 return 1;
490 }
491
492 memcpy(UUID, SectorBuf + 0x180, 16);
493 if (DiskSig)
494 {
495 memcpy(DiskSig, SectorBuf + 0x1B8, 4);
496 }
497
498 CloseHandle(Handle);
499 return 0;
500 }
501
502 static int VentoyMountAnywhere(HANDLE Handle)
503 {
504 DWORD Status;
505 ATTACH_VIRTUAL_DISK_PARAMETERS AttachParameters;
506
507 Log("VentoyMountAnywhere");
508
509 memset(&AttachParameters, 0, sizeof(AttachParameters));
510 AttachParameters.Version = ATTACH_VIRTUAL_DISK_VERSION_1;
511
512 Status = AttachVirtualDisk(Handle, NULL, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY | ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME, 0, &AttachParameters, NULL);
513 if (Status != ERROR_SUCCESS)
514 {
515 Log("Failed to attach virtual disk ErrorCode:%u", Status);
516 return 1;
517 }
518
519 return 0;
520 }
521
522 int VentoyMountY(HANDLE Handle)
523 {
524 int i;
525 BOOL bRet = FALSE;
526 DWORD Status;
527 DWORD physicalDriveNameSize;
528 CHAR *Pos = NULL;
529 WCHAR physicalDriveName[MAX_PATH];
530 CHAR physicalDriveNameA[MAX_PATH];
531 CHAR cdromDriveName[MAX_PATH];
532 ATTACH_VIRTUAL_DISK_PARAMETERS AttachParameters;
533
534 Log("VentoyMountY");
535
536 memset(&AttachParameters, 0, sizeof(AttachParameters));
537 AttachParameters.Version = ATTACH_VIRTUAL_DISK_VERSION_1;
538
539 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);
540 if (Status != ERROR_SUCCESS)
541 {
542 Log("Failed to attach virtual disk ErrorCode:%u", Status);
543 return 1;
544 }
545
546 memset(physicalDriveName, 0, sizeof(physicalDriveName));
547 memset(physicalDriveNameA, 0, sizeof(physicalDriveNameA));
548
549 physicalDriveNameSize = MAX_PATH;
550 Status = GetVirtualDiskPhysicalPath(Handle, &physicalDriveNameSize, physicalDriveName);
551 if (Status != ERROR_SUCCESS)
552 {
553 Log("Failed GetVirtualDiskPhysicalPath ErrorCode:%u", Status);
554 return 1;
555 }
556
557 for (i = 0; physicalDriveName[i]; i++)
558 {
559 physicalDriveNameA[i] = (CHAR)toupper((CHAR)(physicalDriveName[i]));
560 }
561
562 Log("physicalDriveNameA=<%s>", physicalDriveNameA);
563
564 Pos = strstr(physicalDriveNameA, "CDROM");
565 if (!Pos)
566 {
567 Log("Not cdrom phy drive");
568 return 1;
569 }
570
571 sprintf_s(cdromDriveName, sizeof(cdromDriveName), "\\Device\\%s", Pos);
572 Log("cdromDriveName=<%s>", cdromDriveName);
573
574 for (i = 0; i < 3 && (bRet == FALSE); i++)
575 {
576 Sleep(1000);
577 bRet = DefineDosDeviceA(DDD_RAW_TARGET_PATH, "Y:", cdromDriveName);
578 Log("DefineDosDeviceA %s", bRet ? "success" : "failed");
579 }
580
581 return bRet ? 0 : 1;
582 }
583
584 static BOOL VentoyAPINeedMountY(const char *IsoPath)
585 {
586 (void)IsoPath;
587
588 /* TBD */
589 return FALSE;
590 }
591
592 static int VentoyAttachVirtualDisk(HANDLE Handle, const char *IsoPath)
593 {
594 int DriveYFree;
595 DWORD Drives;
596
597 Drives = GetLogicalDrives();
598 if ((1 << 24) & Drives)
599 {
600 Log("Y: is occupied");
601 DriveYFree = 0;
602 }
603 else
604 {
605 Log("Y: is free now");
606 DriveYFree = 1;
607 }
608
609 if (DriveYFree && VentoyAPINeedMountY(IsoPath))
610 {
611 return VentoyMountY(Handle);
612 }
613 else
614 {
615 return VentoyMountAnywhere(Handle);
616 }
617 }
618
619 int VentoyMountISOByAPI(const char *IsoPath)
620 {
621 int i;
622 HANDLE Handle;
623 DWORD Status;
624 WCHAR wFilePath[512] = { 0 };
625 VIRTUAL_STORAGE_TYPE StorageType;
626 OPEN_VIRTUAL_DISK_PARAMETERS OpenParameters;
627
628 Log("VentoyMountISOByAPI <%s>", IsoPath);
629
630 if (IsUTF8Encode(IsoPath))
631 {
632 Log("This is UTF8 encoding");
633 MultiByteToWideChar(CP_UTF8, 0, IsoPath, (int)strlen(IsoPath), wFilePath, (int)(sizeof(wFilePath) / sizeof(WCHAR)));
634 }
635 else
636 {
637 Log("This is ANSI encoding");
638 MultiByteToWideChar(CP_ACP, 0, IsoPath, (int)strlen(IsoPath), wFilePath, (int)(sizeof(wFilePath) / sizeof(WCHAR)));
639 }
640
641 memset(&StorageType, 0, sizeof(StorageType));
642 memset(&OpenParameters, 0, sizeof(OpenParameters));
643
644 OpenParameters.Version = OPEN_VIRTUAL_DISK_VERSION_1;
645
646 for (i = 0; i < 10; i++)
647 {
648 Status = OpenVirtualDisk(&StorageType, wFilePath, VIRTUAL_DISK_ACCESS_READ, 0, &OpenParameters, &Handle);
649 if (ERROR_FILE_NOT_FOUND == Status || ERROR_PATH_NOT_FOUND == Status)
650 {
651 Log("OpenVirtualDisk ErrorCode:%u, now wait and retry...", Status);
652 Sleep(1000);
653 }
654 else
655 {
656 if (ERROR_SUCCESS == Status)
657 {
658 Log("OpenVirtualDisk success");
659 }
660 else if (ERROR_VIRTDISK_PROVIDER_NOT_FOUND == Status)
661 {
662 Log("VirtualDisk for ISO file is not supported in current system");
663 }
664 else
665 {
666 Log("Failed to open virtual disk ErrorCode:%u", Status);
667 }
668 break;
669 }
670 }
671
672 if (Status != ERROR_SUCCESS)
673 {
674 return 1;
675 }
676
677 Log("OpenVirtualDisk success");
678
679 Status = VentoyAttachVirtualDisk(Handle, IsoPath);
680 if (Status != ERROR_SUCCESS)
681 {
682 Log("Failed to attach virtual disk ErrorCode:%u", Status);
683 CloseHandle(Handle);
684 return 1;
685 }
686
687 Log("VentoyAttachVirtualDisk success");
688
689 CloseHandle(Handle);
690 return 0;
691 }
692
693
694 static HANDLE g_FatPhyDrive;
695 static UINT64 g_Part2StartSec;
696
697 static int CopyFileFromFatDisk(const CHAR* SrcFile, const CHAR *DstFile)
698 {
699 int rc = 1;
700 int size = 0;
701 char *buf = NULL;
702 void *flfile = NULL;
703
704 Log("CopyFileFromFatDisk (%s)==>(%s)", SrcFile, DstFile);
705
706 flfile = fl_fopen(SrcFile, "rb");
707 if (flfile)
708 {
709 fl_fseek(flfile, 0, SEEK_END);
710 size = (int)fl_ftell(flfile);
711 fl_fseek(flfile, 0, SEEK_SET);
712
713 buf = (char *)malloc(size);
714 if (buf)
715 {
716 fl_fread(buf, 1, size, flfile);
717
718 rc = 0;
719 SaveBuffer2File(DstFile, buf, size);
720 free(buf);
721 }
722
723 fl_fclose(flfile);
724 }
725
726 return rc;
727 }
728
729 static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount)
730 {
731 DWORD dwSize;
732 BOOL bRet;
733 DWORD ReadSize;
734 LARGE_INTEGER liCurrentPosition;
735
736 liCurrentPosition.QuadPart = Sector + g_Part2StartSec;
737 liCurrentPosition.QuadPart *= 512;
738 SetFilePointerEx(g_FatPhyDrive, liCurrentPosition, &liCurrentPosition, FILE_BEGIN);
739
740 ReadSize = (DWORD)(SectorCount * 512);
741
742 bRet = ReadFile(g_FatPhyDrive, Buffer, ReadSize, &dwSize, NULL);
743 if (bRet == FALSE || dwSize != ReadSize)
744 {
745 Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u\n", bRet, ReadSize, dwSize, GetLastError());
746 }
747
748 return 1;
749 }
750
751 static BOOL Is2K10PE(void)
752 {
753 BOOL bRet = FALSE;
754 FILE *fp = NULL;
755 CHAR szLine[1024];
756
757 fopen_s(&fp, "X:\\Windows\\System32\\PECMD.INI", "r");
758 if (!fp)
759 {
760 return FALSE;
761 }
762
763 memset(szLine, 0, sizeof(szLine));
764 while (fgets(szLine, sizeof(szLine) - 1, fp))
765 {
766 if (strstr(szLine, "2k10\\"))
767 {
768 bRet = TRUE;
769 break;
770 }
771 }
772
773 fclose(fp);
774 return bRet;
775 }
776
777 static CHAR GetIMDiskMountLogicalDrive(void)
778 {
779 CHAR Letter = 'Y';
780 DWORD Drives;
781 DWORD Mask = 0x1000000;
782
783 // fixed use M as mountpoint for 2K10 PE
784 if (Is2K10PE())
785 {
786 Log("Use M: for 2K10 PE");
787 return 'M';
788 }
789
790 Drives = GetLogicalDrives();
791 Log("Drives=0x%x", Drives);
792
793 while (Mask)
794 {
795 if ((Drives & Mask) == 0)
796 {
797 break;
798 }
799
800 Letter--;
801 Mask >>= 1;
802 }
803
804 return Letter;
805 }
806
807 UINT64 GetVentoyEfiPartStartSector(HANDLE hDrive)
808 {
809 BOOL bRet;
810 DWORD dwSize;
811 MBR_HEAD MBR;
812 VTOY_GPT_INFO *pGpt = NULL;
813 UINT64 StartSector = 0;
814
815 SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
816
817 bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);
818 Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR);
819
820 if ((!bRet) || (dwSize != sizeof(MBR)))
821 {
822 0;
823 }
824
825 if (MBR.PartTbl[0].FsFlag == 0xEE)
826 {
827 Log("GPT partition style");
828
829 pGpt = malloc(sizeof(VTOY_GPT_INFO));
830 if (!pGpt)
831 {
832 return 0;
833 }
834
835 SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
836 bRet = ReadFile(hDrive, pGpt, sizeof(VTOY_GPT_INFO), &dwSize, NULL);
837 if ((!bRet) || (dwSize != sizeof(VTOY_GPT_INFO)))
838 {
839 Log("Failed to read gpt info %d %u %d", bRet, dwSize, LASTERR);
840 return 0;
841 }
842
843 StartSector = pGpt->PartTbl[1].StartLBA;
844 free(pGpt);
845 }
846 else
847 {
848 Log("MBR partition style");
849 StartSector = MBR.PartTbl[1].StartSectorId;
850 }
851
852 Log("GetVentoyEfiPart StartSector: %llu", StartSector);
853 return StartSector;
854 }
855
856 static int VentoyRunImdisk(const char *IsoPath, const char *imdiskexe)
857 {
858 CHAR Letter;
859 CHAR Cmdline[512];
860 WCHAR CmdlineW[512];
861 PROCESS_INFORMATION Pi;
862
863 Log("VentoyRunImdisk <%s> <%s>", IsoPath, imdiskexe);
864
865 Letter = GetIMDiskMountLogicalDrive();
866 sprintf_s(Cmdline, sizeof(Cmdline), "%s -a -o ro -f \"%s\" -m %C:", imdiskexe, IsoPath, Letter);
867 Log("mount iso to %C: use imdisk cmd <%s>", Letter, Cmdline);
868
869 if (IsUTF8Encode(IsoPath))
870 {
871 STARTUPINFOW Si;
872 GetStartupInfoW(&Si);
873 Si.dwFlags |= STARTF_USESHOWWINDOW;
874 Si.wShowWindow = SW_HIDE;
875
876 Utf8ToUtf16(Cmdline, CmdlineW);
877 CreateProcessW(NULL, CmdlineW, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
878
879 Log("This is UTF8 encoding");
880 }
881 else
882 {
883 STARTUPINFOA Si;
884 GetStartupInfoA(&Si);
885 Si.dwFlags |= STARTF_USESHOWWINDOW;
886 Si.wShowWindow = SW_HIDE;
887
888 CreateProcessA(NULL, Cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
889
890 Log("This is ANSI encoding");
891 }
892
893 Log("Wait for imdisk process ...");
894 WaitForSingleObject(Pi.hProcess, INFINITE);
895 Log("imdisk process finished");
896
897 return 0;
898 }
899
900 int VentoyMountISOByImdisk(const char *IsoPath, DWORD PhyDrive)
901 {
902 int rc = 1;
903 BOOL bRet;
904 DWORD dwBytes;
905 HANDLE hDrive;
906 CHAR PhyPath[MAX_PATH];
907 GET_LENGTH_INFORMATION LengthInfo;
908
909 Log("VentoyMountISOByImdisk %s", IsoPath);
910
911 if (IsFileExist("X:\\Windows\\System32\\imdisk.exe"))
912 {
913 Log("imdisk.exe exist, use it directly...");
914 VentoyRunImdisk(IsoPath, "imdisk.exe");
915 return 0;
916 }
917
918 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", PhyDrive);
919 hDrive = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
920 if (hDrive == INVALID_HANDLE_VALUE)
921 {
922 Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
923 goto End;
924 }
925
926 bRet = DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &LengthInfo, sizeof(LengthInfo), &dwBytes, NULL);
927 if (!bRet)
928 {
929 Log("Could not get phy disk %s size, error:%u", PhyPath, GetLastError());
930 goto End;
931 }
932
933 g_FatPhyDrive = hDrive;
934 g_Part2StartSec = GetVentoyEfiPartStartSector(hDrive);
935
936 Log("Parse FAT fs...");
937
938 fl_init();
939
940 if (0 == fl_attach_media(VentoyFatDiskRead, NULL))
941 {
942 if (g_system_bit == 64)
943 {
944 CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.sys", "ventoy\\imdisk.sys");
945 CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.exe", "ventoy\\imdisk.exe");
946 CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.cpl", "ventoy\\imdisk.cpl");
947 }
948 else
949 {
950 CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.sys", "ventoy\\imdisk.sys");
951 CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.exe", "ventoy\\imdisk.exe");
952 CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.cpl", "ventoy\\imdisk.cpl");
953 }
954
955 GetCurrentDirectoryA(sizeof(PhyPath), PhyPath);
956 strcat_s(PhyPath, sizeof(PhyPath), "\\ventoy\\imdisk.sys");
957
958 if (LoadNtDriver(PhyPath) == 0)
959 {
960 VentoyRunImdisk(IsoPath, "ventoy\\imdisk.exe");
961 rc = 0;
962 }
963 }
964 fl_shutdown();
965
966 End:
967
968 SAFE_CLOSE_HANDLE(hDrive);
969
970 return rc;
971 }
972
973 static int MountIsoFile(CONST CHAR *IsoPath, DWORD PhyDrive)
974 {
975 if (IsWindows8OrGreater())
976 {
977 Log("This is Windows 8 or latter...");
978 if (VentoyMountISOByAPI(IsoPath) == 0)
979 {
980 Log("Mount iso by API success");
981 return 0;
982 }
983 else
984 {
985 Log("Mount iso by API failed, maybe not supported, try imdisk");
986 return VentoyMountISOByImdisk(IsoPath, PhyDrive);
987 }
988 }
989 else
990 {
991 Log("This is before Windows 8 ...");
992 if (VentoyMountISOByImdisk(IsoPath, PhyDrive) == 0)
993 {
994 Log("Mount iso by imdisk success");
995 return 0;
996 }
997 else
998 {
999 return VentoyMountISOByAPI(IsoPath);
1000 }
1001 }
1002 }
1003
1004 static int GetPhyDriveByLogicalDrive(int DriveLetter)
1005 {
1006 BOOL Ret;
1007 DWORD dwSize;
1008 HANDLE Handle;
1009 VOLUME_DISK_EXTENTS DiskExtents;
1010 CHAR PhyPath[128];
1011
1012 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", (CHAR)DriveLetter);
1013
1014 Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
1015 if (Handle == INVALID_HANDLE_VALUE)
1016 {
1017 Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
1018 return -1;
1019 }
1020
1021 Ret = DeviceIoControl(Handle,
1022 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
1023 NULL,
1024 0,
1025 &DiskExtents,
1026 (DWORD)(sizeof(DiskExtents)),
1027 (LPDWORD)&dwSize,
1028 NULL);
1029
1030 if (!Ret || DiskExtents.NumberOfDiskExtents == 0)
1031 {
1032 Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed %s, error:%u", PhyPath, GetLastError());
1033 SAFE_CLOSE_HANDLE(Handle);
1034 return -1;
1035 }
1036 SAFE_CLOSE_HANDLE(Handle);
1037
1038 Log("LogicalDrive:%s PhyDrive:%d Offset:%llu ExtentLength:%llu",
1039 PhyPath,
1040 DiskExtents.Extents[0].DiskNumber,
1041 DiskExtents.Extents[0].StartingOffset.QuadPart,
1042 DiskExtents.Extents[0].ExtentLength.QuadPart
1043 );
1044
1045 return (int)DiskExtents.Extents[0].DiskNumber;
1046 }
1047
1048
1049 static int DeleteVentoyPart2MountPoint(DWORD PhyDrive)
1050 {
1051 CHAR Letter = 'A';
1052 DWORD Drives;
1053 DWORD PhyDisk;
1054 CHAR DriveName[] = "?:\\";
1055
1056 Log("DeleteVentoyPart2MountPoint Phy%u ...", PhyDrive);
1057
1058 Drives = GetLogicalDrives();
1059 while (Drives)
1060 {
1061 if ((Drives & 0x01) && IsFileExist("%C:\\ventoy\\ventoy.cpio", Letter))
1062 {
1063 Log("File %C:\\ventoy\\ventoy.cpio exist", Letter);
1064
1065 PhyDisk = GetPhyDriveByLogicalDrive(Letter);
1066 Log("PhyDisk=%u for %C", PhyDisk, Letter);
1067
1068 if (PhyDisk == PhyDrive)
1069 {
1070 DriveName[0] = Letter;
1071 DeleteVolumeMountPointA(DriveName);
1072 return 0;
1073 }
1074 }
1075
1076 Letter++;
1077 Drives >>= 1;
1078 }
1079
1080 return 1;
1081 }
1082
1083 static BOOL check_tar_archive(const char *archive, CHAR *tarName)
1084 {
1085 int len;
1086 int nameLen;
1087 const char *pos = archive;
1088 const char *slash = archive;
1089
1090 while (*pos)
1091 {
1092 if (*pos == '\\' || *pos == '/')
1093 {
1094 slash = pos;
1095 }
1096 pos++;
1097 }
1098
1099 len = (int)strlen(slash);
1100
1101 if (len > 7 && (strncmp(slash + len - 7, ".tar.gz", 7) == 0 || strncmp(slash + len - 7, ".tar.xz", 7) == 0))
1102 {
1103 nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash);
1104 tarName[nameLen - 3] = 0;
1105 return TRUE;
1106 }
1107 else if (len > 8 && strncmp(slash + len - 8, ".tar.bz2", 8) == 0)
1108 {
1109 nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash);
1110 tarName[nameLen - 4] = 0;
1111 return TRUE;
1112 }
1113 else if (len > 9 && strncmp(slash + len - 9, ".tar.lzma", 9) == 0)
1114 {
1115 nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash);
1116 tarName[nameLen - 5] = 0;
1117 return TRUE;
1118 }
1119
1120 return FALSE;
1121 }
1122
1123 static UCHAR *g_unxz_buffer = NULL;
1124 static int g_unxz_len = 0;
1125
1126 static void unxz_error(char *x)
1127 {
1128 Log("%s", x);
1129 }
1130
1131 static int unxz_flush(void *src, unsigned int size)
1132 {
1133 memcpy(g_unxz_buffer + g_unxz_len, src, size);
1134 g_unxz_len += (int)size;
1135
1136 return (int)size;
1137 }
1138
1139 static int DecompressInjectionArchive(const char *archive, DWORD PhyDrive)
1140 {
1141 int rc = 1;
1142 int writelen = 0;
1143 UCHAR *Buffer = NULL;
1144 UCHAR *RawBuffer = NULL;
1145 BOOL bRet;
1146 DWORD dwBytes;
1147 DWORD dwSize;
1148 HANDLE hDrive;
1149 HANDLE hOut;
1150 DWORD flags = CREATE_NO_WINDOW;
1151 CHAR StrBuf[MAX_PATH];
1152 CHAR tarName[MAX_PATH];
1153 STARTUPINFOA Si;
1154 PROCESS_INFORMATION Pi;
1155 PROCESS_INFORMATION NewPi;
1156 GET_LENGTH_INFORMATION LengthInfo;
1157 SECURITY_ATTRIBUTES Sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
1158
1159 Log("DecompressInjectionArchive %s", archive);
1160
1161 sprintf_s(StrBuf, sizeof(StrBuf), "\\\\.\\PhysicalDrive%d", PhyDrive);
1162 hDrive = CreateFileA(StrBuf, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
1163 if (hDrive == INVALID_HANDLE_VALUE)
1164 {
1165 Log("Could not open the disk<%s>, error:%u", StrBuf, GetLastError());
1166 goto End;
1167 }
1168
1169 bRet = DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &LengthInfo, sizeof(LengthInfo), &dwBytes, NULL);
1170 if (!bRet)
1171 {
1172 Log("Could not get phy disk %s size, error:%u", StrBuf, GetLastError());
1173 goto End;
1174 }
1175
1176 g_FatPhyDrive = hDrive;
1177 g_Part2StartSec = GetVentoyEfiPartStartSector(hDrive);
1178
1179 Log("Parse FAT fs...");
1180
1181 fl_init();
1182
1183 if (0 == fl_attach_media(VentoyFatDiskRead, NULL))
1184 {
1185 if (g_system_bit == 64)
1186 {
1187 CopyFileFromFatDisk("/ventoy/7z/64/7za.xz", "ventoy\\7za.xz");
1188 }
1189 else
1190 {
1191 CopyFileFromFatDisk("/ventoy/7z/32/7za.xz", "ventoy\\7za.xz");
1192 }
1193
1194 ReadWholeFile2Buf("ventoy\\7za.xz", &Buffer, &dwSize);
1195 Log("7za.xz file size:%u", dwSize);
1196
1197 RawBuffer = malloc(SIZE_1MB * 4);
1198 if (RawBuffer)
1199 {
1200 g_unxz_buffer = RawBuffer;
1201 g_unxz_len = 0;
1202 unxz(Buffer, (int)dwSize, NULL, unxz_flush, NULL, &writelen, unxz_error);
1203 if (writelen == (int)dwSize)
1204 {
1205 Log("Decompress success 7za.xz(%u) ---> 7za.exe(%d)", dwSize, g_unxz_len);
1206 }
1207 else
1208 {
1209 Log("Decompress failed 7za.xz(%u) ---> 7za.exe(%u)", dwSize, dwSize);
1210 }
1211
1212 SaveBuffer2File("ventoy\\7za.exe", RawBuffer, (DWORD)g_unxz_len);
1213
1214 g_unxz_buffer = NULL;
1215 g_unxz_len = 0;
1216 free(RawBuffer);
1217 }
1218 else
1219 {
1220 Log("Failed to alloc 4MB memory");
1221 }
1222
1223 sprintf_s(StrBuf, sizeof(StrBuf), "ventoy\\7za.exe x -y -aoa -oX:\\ %s", archive);
1224
1225 Log("extract inject to X:");
1226 Log("cmdline:<%s>", StrBuf);
1227
1228 GetStartupInfoA(&Si);
1229
1230 hOut = CreateFileA("ventoy\\7z.log",
1231 FILE_APPEND_DATA,
1232 FILE_SHARE_WRITE | FILE_SHARE_READ,
1233 &Sa,
1234 OPEN_ALWAYS,
1235 FILE_ATTRIBUTE_NORMAL,
1236 NULL);
1237
1238 Si.dwFlags |= STARTF_USESTDHANDLES;
1239
1240 if (hOut != INVALID_HANDLE_VALUE)
1241 {
1242 Si.hStdError = hOut;
1243 Si.hStdOutput = hOut;
1244 }
1245
1246 CreateProcessA(NULL, StrBuf, NULL, NULL, TRUE, flags, NULL, NULL, &Si, &Pi);
1247 WaitForSingleObject(Pi.hProcess, INFINITE);
1248
1249 //
1250 // decompress tar archive, for tar.gz/tar.xz/tar.bz2
1251 //
1252 if (check_tar_archive(archive, tarName))
1253 {
1254 Log("Decompress tar archive...<%s>", tarName);
1255
1256 sprintf_s(StrBuf, sizeof(StrBuf), "ventoy\\7za.exe x -y -aoa -oX:\\ %s", tarName);
1257
1258 CreateProcessA(NULL, StrBuf, NULL, NULL, TRUE, flags, NULL, NULL, &Si, &NewPi);
1259 WaitForSingleObject(NewPi.hProcess, INFINITE);
1260
1261 Log("Now delete %s", tarName);
1262 DeleteFileA(tarName);
1263 }
1264
1265 SAFE_CLOSE_HANDLE(hOut);
1266 }
1267 fl_shutdown();
1268
1269 End:
1270
1271 SAFE_CLOSE_HANDLE(hDrive);
1272
1273 return rc;
1274 }
1275
1276 static int ProcessUnattendedInstallation(const char *script)
1277 {
1278 DWORD dw;
1279 HKEY hKey;
1280 LSTATUS Ret;
1281 CHAR Letter;
1282 CHAR CurDir[MAX_PATH];
1283
1284 Log("Copy unattended XML ...");
1285
1286 GetCurrentDirectory(sizeof(CurDir), CurDir);
1287 Letter = CurDir[0];
1288 if ((Letter >= 'A' && Letter <= 'Z') || (Letter >= 'a' && Letter <= 'z'))
1289 {
1290 Log("Current Drive Letter: %C", Letter);
1291 }
1292 else
1293 {
1294 Letter = 'X';
1295 }
1296
1297 sprintf_s(CurDir, sizeof(CurDir), "%C:\\Autounattend.xml", Letter);
1298 Log("Copy file <%s> --> <%s>", script, CurDir);
1299 CopyFile(script, CurDir, FALSE);
1300
1301 Ret = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "System\\Setup", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dw);
1302 if (ERROR_SUCCESS == Ret)
1303 {
1304 Ret = RegSetValueEx(hKey, "UnattendFile", 0, REG_SZ, CurDir, (DWORD)(strlen(CurDir) + 1));
1305 }
1306
1307 return 0;
1308 }
1309
1310 static int Windows11BypassCheck(const char *isofile, const char MntLetter)
1311 {
1312 int Ret = 1;
1313 DWORD dwHandle;
1314 DWORD dwSize;
1315 DWORD dwValue = 1;
1316 UINT VerLen = 0;
1317 CHAR *Buffer = NULL;
1318 VS_FIXEDFILEINFO* VerInfo = NULL;
1319 CHAR CheckFile[MAX_PATH];
1320 UINT16 Major, Minor, Build, Revision;
1321
1322 Log("Windows11BypassCheck for <%s> %C:", isofile, MntLetter);
1323
1324 if (FALSE == IsFileExist("%C:\\sources\\boot.wim", MntLetter) ||
1325 FALSE == IsFileExist("%C:\\sources\\compatresources.dll", MntLetter))
1326 {
1327 Log("boot.wim/compatresources.dll not exist, this is not a windows install media.");
1328 goto End;
1329 }
1330
1331 if (FALSE == IsFileExist("%C:\\sources\\install.wim", MntLetter) &&
1332 FALSE == IsFileExist("%C:\\sources\\install.esd", MntLetter))
1333 {
1334 Log("install.wim/install.esd not exist, this is not a windows install media.");
1335 goto End;
1336 }
1337
1338 sprintf_s(CheckFile, sizeof(CheckFile), "%C:\\sources\\compatresources.dll", MntLetter);
1339 dwSize = GetFileVersionInfoSizeA(CheckFile, &dwHandle);
1340 if (0 == dwSize)
1341 {
1342 Log("Failed to get file version info size: %u", LASTERR);
1343 goto End;
1344 }
1345
1346 Buffer = malloc(dwSize);
1347 if (!Buffer)
1348 {
1349 goto End;
1350 }
1351
1352 if (FALSE == GetFileVersionInfoA(CheckFile, dwHandle, dwSize, Buffer))
1353 {
1354 Log("Failed to get file version info : %u", LASTERR);
1355 goto End;
1356 }
1357
1358 if (VerQueryValueA(Buffer, "\\", (LPVOID)&VerInfo, &VerLen) && VerLen != 0)
1359 {
1360 if (VerInfo->dwSignature == VS_FFI_SIGNATURE)
1361 {
1362 Major = HIWORD(VerInfo->dwFileVersionMS);
1363 Minor = LOWORD(VerInfo->dwFileVersionMS);
1364 Build = HIWORD(VerInfo->dwFileVersionLS);
1365 Revision = LOWORD(VerInfo->dwFileVersionLS);
1366
1367 Log("FileVersionze: <%u %u %u %u>", Major, Minor, Build, Revision);
1368
1369 if (Major == 10 && Build > 20000)
1370 {
1371 Major = 11;
1372 }
1373
1374 if (Major != 11)
1375 {
1376 Log("This is not Windows 11, not need to bypass.", Major);
1377 goto End;
1378 }
1379 }
1380 }
1381
1382 //Now we really need to bypass windows 11 check. create registry
1383 HKEY hKey = NULL;
1384 HKEY hSubKey = NULL;
1385 LSTATUS Status;
1386
1387 Status = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "System\\Setup", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwSize);
1388 if (ERROR_SUCCESS != Status)
1389 {
1390 Log("Failed to create reg key System\\Setup %u %u", LASTERR, Status);
1391 goto End;
1392 }
1393
1394 Status = RegCreateKeyExA(hKey, "LabConfig", 0, NULL, 0, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_CREATE_SUB_KEY, NULL, &hSubKey, &dwSize);
1395 if (ERROR_SUCCESS != Status)
1396 {
1397 Log("Failed to create LabConfig reg %u %u", LASTERR, Status);
1398 goto End;
1399 }
1400
1401 //set reg value
1402 Status += RegSetValueExA(hSubKey, "BypassRAMCheck", 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
1403 Status += RegSetValueExA(hSubKey, "BypassTPMCheck", 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
1404 Status += RegSetValueExA(hSubKey, "BypassSecureBootCheck", 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
1405 Status += RegSetValueExA(hSubKey, "BypassStorageCheck", 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
1406 Status += RegSetValueExA(hSubKey, "BypassCPUCheck", 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
1407
1408 Log("Create bypass registry %s %u", (Status == ERROR_SUCCESS) ? "SUCCESS" : "FAILED", Status);
1409
1410 Ret = 0;
1411
1412 End:
1413 if (Buffer)
1414 {
1415 free(Buffer);
1416 }
1417
1418 return Ret;
1419 }
1420
1421 static BOOL CheckVentoyDisk(DWORD DiskNum)
1422 {
1423 DWORD dwSize = 0;
1424 CHAR PhyPath[128];
1425 UINT8 SectorBuf[512];
1426 HANDLE Handle;
1427 UINT8 check[8] = { 0x56, 0x54, 0x00, 0x47, 0x65, 0x00, 0x48, 0x44 };
1428
1429 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", DiskNum);
1430 Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
1431 if (Handle == INVALID_HANDLE_VALUE)
1432 {
1433 Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
1434 return FALSE;
1435 }
1436
1437 if (!ReadFile(Handle, SectorBuf, sizeof(SectorBuf), &dwSize, NULL))
1438 {
1439 Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError());
1440 CloseHandle(Handle);
1441 return FALSE;
1442 }
1443
1444 CloseHandle(Handle);
1445
1446 if (memcmp(SectorBuf + 0x190, check, 8) == 0)
1447 {
1448 return TRUE;
1449 }
1450
1451 return FALSE;
1452 }
1453
1454
1455 static int VentoyHook(ventoy_os_param *param)
1456 {
1457 int i;
1458 int rc;
1459 BOOL find = FALSE;
1460 BOOL vtoyfind = FALSE;
1461 CHAR Letter;
1462 CHAR MntLetter;
1463 CHAR VtoyLetter;
1464 DWORD Drives;
1465 DWORD NewDrives;
1466 DWORD VtoyDiskNum;
1467 UINT32 DiskSig;
1468 UINT32 VtoySig;
1469 DISK_EXTENT DiskExtent;
1470 DISK_EXTENT VtoyDiskExtent;
1471 UINT8 UUID[16];
1472 CHAR IsoPath[MAX_PATH];
1473
1474 Log("VentoyHook Path:<%s>", param->vtoy_img_path);
1475
1476 if (IsUTF8Encode(param->vtoy_img_path))
1477 {
1478 Log("This file is UTF8 encoding\n");
1479 }
1480
1481 for (i = 0; i < 5; i++)
1482 {
1483 Letter = 'A';
1484 Drives = GetLogicalDrives();
1485 Log("Logic Drives: 0x%x", Drives);
1486
1487 while (Drives)
1488 {
1489 if (Drives & 0x01)
1490 {
1491 sprintf_s(IsoPath, sizeof(IsoPath), "%C:\\%s", Letter, param->vtoy_img_path);
1492 if (IsFileExist("%s", IsoPath))
1493 {
1494 Log("File exist under %C:", Letter);
1495 memset(UUID, 0, sizeof(UUID));
1496 memset(&DiskExtent, 0, sizeof(DiskExtent));
1497 if (GetPhyDiskUUID(Letter, UUID, NULL, &DiskExtent) == 0)
1498 {
1499 if (memcmp(UUID, param->vtoy_disk_guid, 16) == 0)
1500 {
1501 Log("Disk UUID match");
1502 find = TRUE;
1503 break;
1504 }
1505 }
1506 }
1507 else
1508 {
1509 Log("File NOT exist under %C:", Letter);
1510 }
1511 }
1512
1513 Drives >>= 1;
1514 Letter++;
1515 }
1516
1517 if (find)
1518 {
1519 break;
1520 }
1521 else
1522 {
1523 Log("Now wait and retry ...");
1524 Sleep(1000);
1525 }
1526 }
1527
1528 if (find == FALSE)
1529 {
1530 Log("Failed to find ISO file");
1531 return 1;
1532 }
1533
1534 Log("Find ISO file <%s>", IsoPath);
1535
1536 //Find VtoyLetter in Vlnk Mode
1537 if (g_os_param_reserved[6] == 1)
1538 {
1539 memcpy(&VtoySig, g_os_param_reserved + 7, 4);
1540 for (i = 0; i < 5; i++)
1541 {
1542 VtoyLetter = 'A';
1543 Drives = GetLogicalDrives();
1544 Log("Logic Drives: 0x%x VentoySig:%08X", Drives, VtoySig);
1545
1546 while (Drives)
1547 {
1548 if (Drives & 0x01)
1549 {
1550 memset(UUID, 0, sizeof(UUID));
1551 memset(&VtoyDiskExtent, 0, sizeof(VtoyDiskExtent));
1552 DiskSig = 0;
1553 if (GetPhyDiskUUID(VtoyLetter, UUID, &DiskSig, &VtoyDiskExtent) == 0)
1554 {
1555 Log("DiskSig=%08X PartStart=%lld", DiskSig, VtoyDiskExtent.StartingOffset.QuadPart);
1556 if (DiskSig == VtoySig && VtoyDiskExtent.StartingOffset.QuadPart == SIZE_1MB)
1557 {
1558 Log("Ventoy Disk Sig match");
1559 vtoyfind = TRUE;
1560 break;
1561 }
1562 }
1563 }
1564
1565 Drives >>= 1;
1566 VtoyLetter++;
1567 }
1568
1569 if (vtoyfind)
1570 {
1571 Log("Find Ventoy Letter: %C", VtoyLetter);
1572 break;
1573 }
1574 else
1575 {
1576 Log("Now wait and retry ...");
1577 Sleep(1000);
1578 }
1579 }
1580
1581 if (vtoyfind == FALSE)
1582 {
1583 Log("Failed to find ventoy disk");
1584 return 1;
1585 }
1586
1587 VtoyDiskNum = VtoyDiskExtent.DiskNumber;
1588 }
1589 else
1590 {
1591 VtoyLetter = Letter;
1592 Log("No vlnk mode %C", Letter);
1593
1594 VtoyDiskNum = DiskExtent.DiskNumber;
1595 }
1596
1597 if (CheckVentoyDisk(VtoyDiskNum))
1598 {
1599 Log("Disk check OK %C: %u", VtoyLetter, VtoyDiskNum);
1600 }
1601 else
1602 {
1603 Log("Failed to check ventoy disk %u", VtoyDiskNum);
1604 return 1;
1605 }
1606
1607 Drives = GetLogicalDrives();
1608 Log("Drives before mount: 0x%x", Drives);
1609
1610 rc = MountIsoFile(IsoPath, VtoyDiskNum);
1611
1612 NewDrives = GetLogicalDrives();
1613 Log("Drives after mount: 0x%x (0x%x)", NewDrives, (NewDrives ^ Drives));
1614
1615 MntLetter = 'A';
1616 NewDrives = (NewDrives ^ Drives);
1617 while (NewDrives)
1618 {
1619 if (NewDrives & 0x01)
1620 {
1621 if ((NewDrives >> 1) == 0)
1622 {
1623 Log("The ISO file is mounted at %C:", MntLetter);
1624 }
1625 else
1626 {
1627 Log("Maybe the ISO file is mounted at %C:", MntLetter);
1628 }
1629 break;
1630 }
1631
1632 NewDrives >>= 1;
1633 MntLetter++;
1634 }
1635
1636 Log("Mount ISO FILE: %s", rc == 0 ? "SUCCESS" : "FAILED");
1637
1638 //Windows 11 bypass check
1639 if (g_windows_data.windows11_bypass_check == 1)
1640 {
1641 Windows11BypassCheck(IsoPath, MntLetter);
1642 }
1643
1644 // for protect
1645 rc = DeleteVentoyPart2MountPoint(VtoyDiskNum);
1646 Log("Delete ventoy mountpoint: %s", rc == 0 ? "SUCCESS" : "NO NEED");
1647
1648 if (g_windows_data.auto_install_script[0])
1649 {
1650 sprintf_s(IsoPath, sizeof(IsoPath), "%C:%s", VtoyLetter, g_windows_data.auto_install_script);
1651 if (IsFileExist("%s", IsoPath))
1652 {
1653 Log("use auto install script %s...", IsoPath);
1654 ProcessUnattendedInstallation(IsoPath);
1655 }
1656 else
1657 {
1658 Log("auto install script %s not exist", IsoPath);
1659 }
1660 }
1661 else
1662 {
1663 Log("auto install no need");
1664 }
1665
1666 if (g_windows_data.injection_archive[0])
1667 {
1668 sprintf_s(IsoPath, sizeof(IsoPath), "%C:%s", VtoyLetter, g_windows_data.injection_archive);
1669 if (IsFileExist("%s", IsoPath))
1670 {
1671 Log("decompress injection archive %s...", IsoPath);
1672 DecompressInjectionArchive(IsoPath, VtoyDiskNum);
1673
1674 if (IsFileExist("%s", AUTO_RUN_BAT))
1675 {
1676 HANDLE hOut;
1677 DWORD flags = CREATE_NO_WINDOW;
1678 CHAR StrBuf[1024];
1679 STARTUPINFOA Si;
1680 PROCESS_INFORMATION Pi;
1681 SECURITY_ATTRIBUTES Sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
1682
1683 Log("%s exist, now run it...", AUTO_RUN_BAT);
1684
1685 GetStartupInfoA(&Si);
1686
1687 hOut = CreateFileA(AUTO_RUN_LOG,
1688 FILE_APPEND_DATA,
1689 FILE_SHARE_WRITE | FILE_SHARE_READ,
1690 &Sa,
1691 OPEN_ALWAYS,
1692 FILE_ATTRIBUTE_NORMAL,
1693 NULL);
1694
1695 Si.dwFlags |= STARTF_USESTDHANDLES;
1696 if (hOut != INVALID_HANDLE_VALUE)
1697 {
1698 Si.hStdError = hOut;
1699 Si.hStdOutput = hOut;
1700 }
1701
1702 sprintf_s(IsoPath, sizeof(IsoPath), "%C:\\%s", Letter, param->vtoy_img_path);
1703 sprintf_s(StrBuf, sizeof(StrBuf), "cmd.exe /c %s \"%s\" %C", AUTO_RUN_BAT, IsoPath, MntLetter);
1704 CreateProcessA(NULL, StrBuf, NULL, NULL, TRUE, flags, NULL, NULL, &Si, &Pi);
1705 WaitForSingleObject(Pi.hProcess, INFINITE);
1706
1707 SAFE_CLOSE_HANDLE(hOut);
1708 }
1709 else
1710 {
1711 Log("%s not exist...", AUTO_RUN_BAT);
1712 }
1713 }
1714 else
1715 {
1716 Log("injection archive %s not exist", IsoPath);
1717 }
1718 }
1719 else
1720 {
1721 Log("no injection archive found");
1722 }
1723
1724 return 0;
1725 }
1726
1727
1728 int VentoyJumpWimboot(INT argc, CHAR **argv, CHAR *LunchFile)
1729 {
1730 int rc = 1;
1731 char *buf = NULL;
1732 DWORD size = 0;
1733 DWORD Pos;
1734
1735 Log("VentoyJumpWimboot %dbit", g_system_bit);
1736
1737 sprintf_s(LunchFile, MAX_PATH, "X:\\setup.exe");
1738
1739 ReadWholeFile2Buf("wimboot.data", &buf, &size);
1740 Log("wimboot.data size:%d", size);
1741
1742 memcpy(&g_os_param, buf, sizeof(ventoy_os_param));
1743 memcpy(&g_windows_data, buf + sizeof(ventoy_os_param), sizeof(ventoy_windows_data));
1744 memcpy(g_os_param_reserved, g_os_param.vtoy_reserved, sizeof(g_os_param_reserved));
1745
1746 if (g_os_param_reserved[0] == 1)
1747 {
1748 Log("break here for debug .....");
1749 goto End;
1750 }
1751
1752 // convert / to \\
1753 for (Pos = 0; Pos < sizeof(g_os_param.vtoy_img_path) && g_os_param.vtoy_img_path[Pos]; Pos++)
1754 {
1755 if (g_os_param.vtoy_img_path[Pos] == '/')
1756 {
1757 g_os_param.vtoy_img_path[Pos] = '\\';
1758 }
1759 }
1760
1761 if (g_os_param_reserved[0] == 2)
1762 {
1763 Log("skip hook for debug .....");
1764 rc = 0;
1765 goto End;
1766 }
1767
1768 rc = VentoyHook(&g_os_param);
1769
1770 End:
1771
1772 if (buf)
1773 {
1774 free(buf);
1775 }
1776
1777 return rc;
1778 }
1779
1780 static int ventoy_check_create_directory(void)
1781 {
1782 if (IsDirExist("ventoy"))
1783 {
1784 Log("ventoy directory already exist");
1785 }
1786 else
1787 {
1788 Log("ventoy directory not exist, now create it.");
1789 if (!CreateDirectoryA("ventoy", NULL))
1790 {
1791 Log("Failed to create ventoy directory err:%u", GetLastError());
1792 return 1;
1793 }
1794 }
1795
1796 return 0;
1797 }
1798
1799 int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile)
1800 {
1801 int rc = 1;
1802 int stat = 0;
1803 DWORD Pos;
1804 DWORD PeStart;
1805 DWORD FileSize;
1806 DWORD LockStatus = 0;
1807 BYTE *Buffer = NULL;
1808 CHAR ExeFileName[MAX_PATH];
1809
1810 sprintf_s(ExeFileName, sizeof(ExeFileName), "%s", argv[0]);
1811 if (!IsFileExist("%s", ExeFileName))
1812 {
1813 Log("File %s NOT exist, now try %s.exe", ExeFileName, ExeFileName);
1814 sprintf_s(ExeFileName, sizeof(ExeFileName), "%s.exe", argv[0]);
1815
1816 Log("File %s exist ? %s", ExeFileName, IsFileExist("%s", ExeFileName) ? "YES" : "NO");
1817 }
1818
1819 if (ReadWholeFile2Buf(ExeFileName, (void **)&Buffer, &FileSize))
1820 {
1821 goto End;
1822 }
1823
1824 Log("VentoyJump %dbit", g_system_bit);
1825
1826 MUTEX_LOCK(g_vtoyins_mutex);
1827 stat = ventoy_check_create_directory();
1828 MUTEX_UNLOCK(g_vtoyins_mutex);
1829
1830 if (stat != 0)
1831 {
1832 goto End;
1833 }
1834
1835 for (PeStart = 0; PeStart < FileSize; PeStart += 16)
1836 {
1837 if (CheckOsParam((ventoy_os_param *)(Buffer + PeStart)) &&
1838 CheckPeHead(Buffer + PeStart + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data)))
1839 {
1840 Log("Find os pararm at %u", PeStart);
1841
1842 memcpy(&g_os_param, Buffer + PeStart, sizeof(ventoy_os_param));
1843 memcpy(&g_windows_data, Buffer + PeStart + sizeof(ventoy_os_param), sizeof(ventoy_windows_data));
1844 memcpy(g_os_param_reserved, g_os_param.vtoy_reserved, sizeof(g_os_param_reserved));
1845
1846 if (g_os_param_reserved[0] == 1)
1847 {
1848 Log("break here for debug .....");
1849 goto End;
1850 }
1851
1852 // convert / to \\
1853 for (Pos = 0; Pos < sizeof(g_os_param.vtoy_img_path) && g_os_param.vtoy_img_path[Pos]; Pos++)
1854 {
1855 if (g_os_param.vtoy_img_path[Pos] == '/')
1856 {
1857 g_os_param.vtoy_img_path[Pos] = '\\';
1858 }
1859 }
1860
1861 PeStart += sizeof(ventoy_os_param) + sizeof(ventoy_windows_data);
1862 sprintf_s(LunchFile, MAX_PATH, "ventoy\\%s", GetFileNameInPath(ExeFileName));
1863
1864 MUTEX_LOCK(g_vtoyins_mutex);
1865 if (IsFileExist("%s", LunchFile))
1866 {
1867 Log("vtoyjump multiple call ...");
1868 rc = 0;
1869 MUTEX_UNLOCK(g_vtoyins_mutex);
1870 goto End;
1871 }
1872
1873 SaveBuffer2File(LunchFile, Buffer + PeStart, FileSize - PeStart);
1874 MUTEX_UNLOCK(g_vtoyins_mutex);
1875
1876 break;
1877 }
1878 }
1879
1880 if (PeStart >= FileSize)
1881 {
1882 Log("OS param not found");
1883 goto End;
1884 }
1885
1886 if (g_os_param_reserved[0] == 2)
1887 {
1888 Log("skip hook for debug .....");
1889 rc = 0;
1890 goto End;
1891 }
1892
1893 rc = VentoyHook(&g_os_param);
1894
1895 End:
1896
1897 if (Buffer)
1898 {
1899 free(Buffer);
1900 }
1901
1902 return rc;
1903 }
1904
1905
1906 int real_main(int argc, char **argv)
1907 {
1908 int i = 0;
1909 int rc = 0;
1910 CHAR NewFile[MAX_PATH];
1911 CHAR LunchFile[MAX_PATH];
1912 CHAR CallParam[1024] = { 0 };
1913 STARTUPINFOA Si;
1914 PROCESS_INFORMATION Pi;
1915
1916 Log("#### real_main #### argc = %d", argc);
1917 Log("program full path: <%s>", g_prog_full_path);
1918 Log("program dir: <%s>", g_prog_dir);
1919 Log("program name:: <%s>", g_prog_name);
1920
1921 Log("argc = %d", argc);
1922 for (i = 0; i < argc; i++)
1923 {
1924 Log("argv[%d]=<%s>", i, argv[i]);
1925 if (i > 0)
1926 {
1927 strcat_s(CallParam, sizeof(CallParam), " ");
1928 strcat_s(CallParam, sizeof(CallParam), argv[i]);
1929 }
1930 }
1931
1932 GetStartupInfoA(&Si);
1933 memset(LunchFile, 0, sizeof(LunchFile));
1934
1935 if (strstr(argv[0], "vtoyjump.exe"))
1936 {
1937 rc = VentoyJumpWimboot(argc, argv, LunchFile);
1938 }
1939 else
1940 {
1941 rc = VentoyJump(argc, argv, LunchFile);
1942 }
1943
1944 Log("LunchFile=<%s> CallParam=<%s>", LunchFile, CallParam);
1945
1946 if (_stricmp(g_prog_name, "winpeshl.exe") != 0 && IsFileExist("ventoy\\%s", g_prog_name))
1947 {
1948 sprintf_s(NewFile, sizeof(NewFile), "%s_BACK.EXE", g_prog_full_path);
1949 MoveFileA(g_prog_full_path, NewFile);
1950 Log("Move <%s> to <%s>", g_prog_full_path, NewFile);
1951
1952 sprintf_s(NewFile, sizeof(NewFile), "ventoy\\%s", g_prog_name);
1953 CopyFileA(NewFile, g_prog_full_path, TRUE);
1954 Log("Copy <%s> to <%s>", NewFile, g_prog_full_path);
1955
1956 sprintf_s(LunchFile, sizeof(LunchFile), "%s", g_prog_full_path);
1957 Log("Final lunchFile is <%s>", LunchFile);
1958 }
1959 else
1960 {
1961 Log("We don't need to recover original <%s>", g_prog_name);
1962 }
1963
1964 if (g_os_param_reserved[0] == 3)
1965 {
1966 Log("Open log for debug ...");
1967 sprintf_s(LunchFile, sizeof(LunchFile), "%s", "notepad.exe ventoy.log");
1968 }
1969 else
1970 {
1971 if (CallParam[0])
1972 {
1973 strcat_s(LunchFile, sizeof(LunchFile), CallParam);
1974 }
1975 else if (NULL == strstr(LunchFile, "setup.exe"))
1976 {
1977 Log("Not setup.exe, hide windows.");
1978 Si.dwFlags |= STARTF_USESHOWWINDOW;
1979 Si.wShowWindow = SW_HIDE;
1980 }
1981
1982 Log("Ventoy jump %s ...", rc == 0 ? "success" : "failed");
1983 }
1984
1985 Log("Now launch <%s> ...", LunchFile);
1986
1987 if (g_os_param_reserved[0] == 4)
1988 {
1989 Log("Open cmd for debug ...");
1990 sprintf_s(LunchFile, sizeof(LunchFile), "%s", "cmd.exe");
1991 }
1992
1993 Log("Backup log at this point");
1994 CopyFileA(LOG_FILE, "X:\\Windows\\ventoy.backup", TRUE);
1995
1996 CreateProcessA(NULL, LunchFile, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
1997
1998 for (i = 0; rc && i < 1800; i++)
1999 {
2000 Log("Ventoy hook failed, now wait and retry ...");
2001 Sleep(1000);
2002 rc = VentoyHook(&g_os_param);
2003 }
2004
2005 Log("Wait process...");
2006 WaitForSingleObject(Pi.hProcess, INFINITE);
2007
2008 Log("vtoyjump finished");
2009 return 0;
2010 }
2011
2012 static void VentoyToUpper(CHAR *str)
2013 {
2014 int i;
2015 for (i = 0; str[i]; i++)
2016 {
2017 str[i] = (CHAR)toupper(str[i]);
2018 }
2019 }
2020
2021 int main(int argc, char **argv)
2022 {
2023 int i;
2024 STARTUPINFOA Si;
2025 PROCESS_INFORMATION Pi;
2026 CHAR CurDir[MAX_PATH];
2027 CHAR NewArgv0[MAX_PATH];
2028 CHAR CallParam[1024] = { 0 };
2029
2030 g_vtoylog_mutex = CreateMutexA(NULL, FALSE, "VTOYLOG_LOCK");
2031 g_vtoyins_mutex = CreateMutexA(NULL, FALSE, "VTOYINS_LOCK");
2032
2033 Log("######## VentoyJump %dbit ##########", g_system_bit);
2034
2035 GetCurrentDirectoryA(sizeof(CurDir), CurDir);
2036 Log("Current directory is <%s>", CurDir);
2037
2038 GetModuleFileNameA(NULL, g_prog_full_path, MAX_PATH);
2039 split_path_name(g_prog_full_path, g_prog_dir, g_prog_name);
2040
2041 Log("EXE path: <%s> dir:<%s> name:<%s>", g_prog_full_path, g_prog_dir, g_prog_name);
2042
2043 if (_stricmp(g_prog_name, "WinLogon.exe") == 0)
2044 {
2045 Log("This time is rejump back ...");
2046
2047 strcpy_s(g_prog_full_path, sizeof(g_prog_full_path), argv[1]);
2048 split_path_name(g_prog_full_path, g_prog_dir, g_prog_name);
2049
2050 return real_main(argc - 1, argv + 1);
2051 }
2052 else if (_stricmp(g_prog_name, "PECMD.exe") == 0)
2053 {
2054 strcpy_s(NewArgv0, sizeof(NewArgv0), g_prog_dir);
2055 VentoyToUpper(NewArgv0);
2056
2057 if (NULL == strstr(NewArgv0, "SYSTEM32") && IsFileExist(ORG_PECMD_BK_PATH))
2058 {
2059 Log("Just call original pecmd.exe");
2060 strcpy_s(CallParam, sizeof(CallParam), ORG_PECMD_PATH);
2061 }
2062 else
2063 {
2064 Log("We need to rejump for pecmd ...");
2065
2066 ventoy_check_create_directory();
2067 CopyFileA(g_prog_full_path, "ventoy\\WinLogon.exe", TRUE);
2068
2069 sprintf_s(CallParam, sizeof(CallParam), "ventoy\\WinLogon.exe %s", g_prog_full_path);
2070 }
2071
2072 for (i = 1; i < argc; i++)
2073 {
2074 strcat_s(CallParam, sizeof(CallParam), " ");
2075 strcat_s(CallParam, sizeof(CallParam), argv[i]);
2076 }
2077
2078 Log("Now rejump to <%s> ...", CallParam);
2079 GetStartupInfoA(&Si);
2080 CreateProcessA(NULL, CallParam, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
2081
2082 Log("Wait rejump process...");
2083 WaitForSingleObject(Pi.hProcess, INFINITE);
2084 Log("rejump finished");
2085 return 0;
2086 }
2087 else
2088 {
2089 Log("We don't need to rejump ...");
2090
2091 strcpy_s(NewArgv0, sizeof(NewArgv0), g_prog_full_path);
2092 argv[0] = NewArgv0;
2093
2094 return real_main(argc, argv);
2095 }
2096 }
2097
2098