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