]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - vtoyjump/vtoyjump/vtoyjump.c
Compatibility improvement for some WinPE
[Ventoy.git] / vtoyjump / vtoyjump / vtoyjump.c
1 /******************************************************************************
2 * vtoyjump.c
3 *
4 * Copyright (c) 2020, 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 BOOL g_64bit_system = FALSE;
35 static ventoy_guid g_ventoy_guid = VENTOY_GUID;
36
37 void Log(const char *Fmt, ...)
38 {
39 va_list Arg;
40 int Len = 0;
41 FILE *File = NULL;
42 SYSTEMTIME Sys;
43 char szBuf[1024];
44 DWORD PID = GetCurrentProcessId();
45
46 GetLocalTime(&Sys);
47 Len += sprintf_s(szBuf, sizeof(szBuf),
48 "[%4d/%02d/%02d %02d:%02d:%02d.%03d] [%u] ",
49 Sys.wYear, Sys.wMonth, Sys.wDay,
50 Sys.wHour, Sys.wMinute, Sys.wSecond,
51 Sys.wMilliseconds, PID);
52
53 va_start(Arg, Fmt);
54 Len += vsnprintf_s(szBuf + Len, sizeof(szBuf)-Len, sizeof(szBuf)-Len, Fmt, Arg);
55 va_end(Arg);
56
57 fopen_s(&File, "ventoy.log", "a+");
58 if (File)
59 {
60 fwrite(szBuf, 1, Len, File);
61 fwrite("\n", 1, 1, File);
62 fclose(File);
63 }
64 }
65
66
67 static int LoadNtDriver(const char *DrvBinPath)
68 {
69 int i;
70 int rc = 0;
71 BOOL Ret;
72 DWORD Status;
73 SC_HANDLE hServiceMgr;
74 SC_HANDLE hService;
75 char name[256] = { 0 };
76
77 for (i = (int)strlen(DrvBinPath) - 1; i >= 0; i--)
78 {
79 if (DrvBinPath[i] == '\\' || DrvBinPath[i] == '/')
80 {
81 sprintf_s(name, sizeof(name), "%s", DrvBinPath + i + 1);
82 break;
83 }
84 }
85
86 Log("Load NT driver: %s %s", DrvBinPath, name);
87
88 hServiceMgr = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
89 if (hServiceMgr == NULL)
90 {
91 Log("OpenSCManager failed Error:%u", GetLastError());
92 return 1;
93 }
94
95 Log("OpenSCManager OK");
96
97 hService = CreateServiceA(hServiceMgr,
98 name,
99 name,
100 SERVICE_ALL_ACCESS,
101 SERVICE_KERNEL_DRIVER,
102 SERVICE_DEMAND_START,
103 SERVICE_ERROR_NORMAL,
104 DrvBinPath,
105 NULL, NULL, NULL, NULL, NULL);
106 if (hService == NULL)
107 {
108 Status = GetLastError();
109 if (Status != ERROR_IO_PENDING && Status != ERROR_SERVICE_EXISTS)
110 {
111 Log("CreateService failed v %u", Status);
112 CloseServiceHandle(hServiceMgr);
113 return 1;
114 }
115
116 hService = OpenServiceA(hServiceMgr, name, SERVICE_ALL_ACCESS);
117 if (hService == NULL)
118 {
119 Log("OpenService failed %u", Status);
120 CloseServiceHandle(hServiceMgr);
121 return 1;
122 }
123 }
124
125 Log("CreateService imdisk OK");
126
127 Ret = StartServiceA(hService, 0, NULL);
128 if (Ret)
129 {
130 Log("StartService OK");
131 }
132 else
133 {
134 Status = GetLastError();
135 if (Status == ERROR_SERVICE_ALREADY_RUNNING)
136 {
137 rc = 0;
138 }
139 else
140 {
141 Log("StartService error %u", Status);
142 rc = 1;
143 }
144 }
145
146 CloseServiceHandle(hService);
147 CloseServiceHandle(hServiceMgr);
148
149 Log("Load NT driver %s", rc ? "failed" : "success");
150
151 return rc;
152 }
153
154 static int ReadWholeFile2Buf(const char *Fullpath, void **Data, DWORD *Size)
155 {
156 int rc = 1;
157 DWORD FileSize;
158 DWORD dwSize;
159 HANDLE Handle;
160 BYTE *Buffer = NULL;
161
162 Log("ReadWholeFile2Buf <%s>", Fullpath);
163
164 Handle = CreateFileA(Fullpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
165 if (Handle == INVALID_HANDLE_VALUE)
166 {
167 Log("Could not open the file<%s>, error:%u", Fullpath, GetLastError());
168 goto End;
169 }
170
171 FileSize = SetFilePointer(Handle, 0, NULL, FILE_END);
172
173 Buffer = malloc(FileSize);
174 if (!Buffer)
175 {
176 Log("Failed to alloc memory size:%u", FileSize);
177 goto End;
178 }
179
180 SetFilePointer(Handle, 0, NULL, FILE_BEGIN);
181 if (!ReadFile(Handle, Buffer, FileSize, &dwSize, NULL))
182 {
183 Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError());
184 goto End;
185 }
186
187 *Data = Buffer;
188 *Size = FileSize;
189
190 Log("Success read file size:%u", FileSize);
191
192 rc = 0;
193
194 End:
195 SAFE_CLOSE_HANDLE(Handle);
196
197 return rc;
198 }
199
200 static BOOL CheckPeHead(BYTE *Head)
201 {
202 UINT32 PeOffset;
203
204 if (Head[0] != 'M' || Head[1] != 'Z')
205 {
206 return FALSE;
207 }
208
209 PeOffset = *(UINT32 *)(Head + 60);
210 if (*(UINT32 *)(Head + PeOffset) != 0x00004550)
211 {
212 return FALSE;
213 }
214
215 return TRUE;
216 }
217
218 static BOOL IsPe64(BYTE *buffer)
219 {
220 DWORD pe_off;
221
222 if (!CheckPeHead(buffer))
223 {
224 return FALSE;
225 }
226
227 pe_off = *(UINT32 *)(buffer + 60);
228 if (*(UINT16 *)(buffer + pe_off + 24) == 0x020b)
229 {
230 return TRUE;
231 }
232
233 return FALSE;
234 }
235
236
237 static BOOL CheckOsParam(ventoy_os_param *param)
238 {
239 UINT32 i;
240 BYTE Sum = 0;
241
242 if (memcmp(&param->guid, &g_ventoy_guid, sizeof(ventoy_guid)))
243 {
244 return FALSE;
245 }
246
247 for (i = 0; i < sizeof(ventoy_os_param); i++)
248 {
249 Sum += *((BYTE *)param + i);
250 }
251
252 if (Sum)
253 {
254 return FALSE;
255 }
256
257 if (param->vtoy_img_location_addr % 4096)
258 {
259 return FALSE;
260 }
261
262 return TRUE;
263 }
264
265 static int SaveBuffer2File(const char *Fullpath, void *Buffer, DWORD Length)
266 {
267 int rc = 1;
268 DWORD dwSize;
269 HANDLE Handle;
270
271 Log("SaveBuffer2File <%s> len:%u", Fullpath, Length);
272
273 Handle = CreateFileA(Fullpath, GENERIC_READ | GENERIC_WRITE,
274 FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, 0, 0);
275 if (Handle == INVALID_HANDLE_VALUE)
276 {
277 Log("Could not create new file, error:%u", GetLastError());
278 goto End;
279 }
280
281 WriteFile(Handle, Buffer, Length, &dwSize, NULL);
282
283 rc = 0;
284
285 End:
286 SAFE_CLOSE_HANDLE(Handle);
287
288 return rc;
289 }
290
291 static int IsUTF8Encode(const char *src)
292 {
293 int i;
294 const UCHAR *Byte = (const UCHAR *)src;
295
296 for (i = 0; i < MAX_PATH && Byte[i]; i++)
297 {
298 if (Byte[i] > 127)
299 {
300 return 1;
301 }
302 }
303
304 return 0;
305 }
306
307 static int Utf8ToUtf16(const char* src, WCHAR * dst)
308 {
309 int size = MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, 0);
310 return MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, size + 1);
311 }
312
313 static BOOL IsDirExist(const char *Fmt, ...)
314 {
315 va_list Arg;
316 DWORD Attr;
317 int UTF8 = 0;
318 CHAR FilePathA[MAX_PATH];
319 WCHAR FilePathW[MAX_PATH];
320
321 va_start(Arg, Fmt);
322 vsnprintf_s(FilePathA, sizeof(FilePathA), sizeof(FilePathA), Fmt, Arg);
323 va_end(Arg);
324
325 UTF8 = IsUTF8Encode(FilePathA);
326
327 if (UTF8)
328 {
329 Utf8ToUtf16(FilePathA, FilePathW);
330 Attr = GetFileAttributesW(FilePathW);
331 }
332 else
333 {
334 Attr = GetFileAttributesA(FilePathA);
335 }
336
337 if (Attr != INVALID_FILE_ATTRIBUTES && (Attr & FILE_ATTRIBUTE_DIRECTORY))
338 {
339 return TRUE;
340 }
341
342 return FALSE;
343 }
344
345 static BOOL IsFileExist(const char *Fmt, ...)
346 {
347 va_list Arg;
348 HANDLE hFile;
349 DWORD Attr;
350 BOOL bRet = FALSE;
351 int UTF8 = 0;
352 CHAR FilePathA[MAX_PATH];
353 WCHAR FilePathW[MAX_PATH];
354
355 va_start(Arg, Fmt);
356 vsnprintf_s(FilePathA, sizeof(FilePathA), sizeof(FilePathA), Fmt, Arg);
357 va_end(Arg);
358
359 UTF8 = IsUTF8Encode(FilePathA);
360
361 if (UTF8)
362 {
363 Utf8ToUtf16(FilePathA, FilePathW);
364 hFile = CreateFileW(FilePathW, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
365 }
366 else
367 {
368 hFile = CreateFileA(FilePathA, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
369 }
370 if (INVALID_HANDLE_VALUE == hFile)
371 {
372 goto out;
373 }
374
375 CloseHandle(hFile);
376
377 if (UTF8)
378 {
379 Attr = GetFileAttributesW(FilePathW);
380 }
381 else
382 {
383 Attr = GetFileAttributesA(FilePathA);
384 }
385
386 if (Attr & FILE_ATTRIBUTE_DIRECTORY)
387 {
388 goto out;
389 }
390
391 bRet = TRUE;
392
393 out:
394 Log("File <%s> %s", FilePathA, (bRet ? "exist" : "NOT exist"));
395 return bRet;
396 }
397
398 static int GetPhyDiskUUID(const char LogicalDrive, UINT8 *UUID, DISK_EXTENT *DiskExtent)
399 {
400 BOOL Ret;
401 DWORD dwSize;
402 HANDLE Handle;
403 VOLUME_DISK_EXTENTS DiskExtents;
404 CHAR PhyPath[128];
405 UINT8 SectorBuf[512];
406
407 Log("GetPhyDiskUUID %C", LogicalDrive);
408
409 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", LogicalDrive);
410 Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
411 if (Handle == INVALID_HANDLE_VALUE)
412 {
413 Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
414 return 1;
415 }
416
417 Ret = DeviceIoControl(Handle,
418 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
419 NULL,
420 0,
421 &DiskExtents,
422 (DWORD)(sizeof(DiskExtents)),
423 (LPDWORD)&dwSize,
424 NULL);
425 if (!Ret || DiskExtents.NumberOfDiskExtents == 0)
426 {
427 Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed, error:%u", GetLastError());
428 CloseHandle(Handle);
429 return 1;
430 }
431 CloseHandle(Handle);
432
433 memcpy(DiskExtent, DiskExtents.Extents, sizeof(DiskExtent));
434 Log("%C: is in PhysicalDrive%d ", LogicalDrive, DiskExtents.Extents[0].DiskNumber);
435
436 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", DiskExtents.Extents[0].DiskNumber);
437 Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
438 if (Handle == INVALID_HANDLE_VALUE)
439 {
440 Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
441 return 1;
442 }
443
444 if (!ReadFile(Handle, SectorBuf, sizeof(SectorBuf), &dwSize, NULL))
445 {
446 Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError());
447 CloseHandle(Handle);
448 return 1;
449 }
450
451 memcpy(UUID, SectorBuf + 0x180, 16);
452 CloseHandle(Handle);
453 return 0;
454 }
455
456 static int VentoyMountAnywhere(HANDLE Handle)
457 {
458 DWORD Status;
459 ATTACH_VIRTUAL_DISK_PARAMETERS AttachParameters;
460
461 Log("VentoyMountAnywhere");
462
463 memset(&AttachParameters, 0, sizeof(AttachParameters));
464 AttachParameters.Version = ATTACH_VIRTUAL_DISK_VERSION_1;
465
466 Status = AttachVirtualDisk(Handle, NULL, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY | ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME, 0, &AttachParameters, NULL);
467 if (Status != ERROR_SUCCESS)
468 {
469 Log("Failed to attach virtual disk ErrorCode:%u", Status);
470 return 1;
471 }
472
473 return 0;
474 }
475
476 int VentoyMountY(HANDLE Handle)
477 {
478 int i;
479 BOOL bRet = FALSE;
480 DWORD Status;
481 DWORD physicalDriveNameSize;
482 CHAR *Pos = NULL;
483 WCHAR physicalDriveName[MAX_PATH];
484 CHAR physicalDriveNameA[MAX_PATH];
485 CHAR cdromDriveName[MAX_PATH];
486 ATTACH_VIRTUAL_DISK_PARAMETERS AttachParameters;
487
488 Log("VentoyMountY");
489
490 memset(&AttachParameters, 0, sizeof(AttachParameters));
491 AttachParameters.Version = ATTACH_VIRTUAL_DISK_VERSION_1;
492
493 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);
494 if (Status != ERROR_SUCCESS)
495 {
496 Log("Failed to attach virtual disk ErrorCode:%u", Status);
497 return 1;
498 }
499
500 memset(physicalDriveName, 0, sizeof(physicalDriveName));
501 memset(physicalDriveNameA, 0, sizeof(physicalDriveNameA));
502
503 physicalDriveNameSize = MAX_PATH;
504 Status = GetVirtualDiskPhysicalPath(Handle, &physicalDriveNameSize, physicalDriveName);
505 if (Status != ERROR_SUCCESS)
506 {
507 Log("Failed GetVirtualDiskPhysicalPath ErrorCode:%u", Status);
508 return 1;
509 }
510
511 for (i = 0; physicalDriveName[i]; i++)
512 {
513 physicalDriveNameA[i] = toupper((CHAR)(physicalDriveName[i]));
514 }
515
516 Log("physicalDriveNameA=<%s>", physicalDriveNameA);
517
518 Pos = strstr(physicalDriveNameA, "CDROM");
519 if (!Pos)
520 {
521 Log("Not cdrom phy drive");
522 return 1;
523 }
524
525 sprintf_s(cdromDriveName, sizeof(cdromDriveName), "\\Device\\%s", Pos);
526 Log("cdromDriveName=<%s>", cdromDriveName);
527
528 for (i = 0; i < 3 && (bRet == FALSE); i++)
529 {
530 Sleep(1000);
531 bRet = DefineDosDeviceA(DDD_RAW_TARGET_PATH, "Y:", cdromDriveName);
532 Log("DefineDosDeviceA %s", bRet ? "success" : "failed");
533 }
534
535 return bRet ? 0 : 1;
536 }
537
538 static BOOL VentoyNeedMountY(const char *IsoPath)
539 {
540 /* TBD */
541 return FALSE;
542 }
543
544 static int VentoyAttachVirtualDisk(HANDLE Handle, const char *IsoPath)
545 {
546 int DriveYFree;
547 DWORD Drives;
548
549 Drives = GetLogicalDrives();
550 if ((1 << 24) & Drives)
551 {
552 Log("Y: is occupied");
553 DriveYFree = 0;
554 }
555 else
556 {
557 Log("Y: is free now");
558 DriveYFree = 1;
559 }
560
561 if (DriveYFree && VentoyNeedMountY(IsoPath))
562 {
563 return VentoyMountY(Handle);
564 }
565 else
566 {
567 return VentoyMountAnywhere(Handle);
568 }
569 }
570
571 int VentoyMountISOByAPI(const char *IsoPath)
572 {
573 HANDLE Handle;
574 DWORD Status;
575 WCHAR wFilePath[512] = { 0 };
576 VIRTUAL_STORAGE_TYPE StorageType;
577 OPEN_VIRTUAL_DISK_PARAMETERS OpenParameters;
578
579 Log("VentoyMountISOByAPI <%s>", IsoPath);
580
581 if (IsUTF8Encode(IsoPath))
582 {
583 MultiByteToWideChar(CP_UTF8, 0, IsoPath, (int)strlen(IsoPath), wFilePath, (int)(sizeof(wFilePath) / sizeof(WCHAR)));
584 }
585 else
586 {
587 MultiByteToWideChar(CP_ACP, 0, IsoPath, (int)strlen(IsoPath), wFilePath, (int)(sizeof(wFilePath) / sizeof(WCHAR)));
588 }
589
590 memset(&StorageType, 0, sizeof(StorageType));
591 memset(&OpenParameters, 0, sizeof(OpenParameters));
592
593 OpenParameters.Version = OPEN_VIRTUAL_DISK_VERSION_1;
594
595 Status = OpenVirtualDisk(&StorageType, wFilePath, VIRTUAL_DISK_ACCESS_READ, 0, &OpenParameters, &Handle);
596 if (Status != ERROR_SUCCESS)
597 {
598 if (ERROR_VIRTDISK_PROVIDER_NOT_FOUND == Status)
599 {
600 Log("VirtualDisk for ISO file is not supported in current system");
601 }
602 else
603 {
604 Log("Failed to open virtual disk ErrorCode:%u", Status);
605 }
606 return 1;
607 }
608
609 Log("OpenVirtualDisk success");
610
611 Status = VentoyAttachVirtualDisk(Handle, IsoPath);
612 if (Status != ERROR_SUCCESS)
613 {
614 Log("Failed to attach virtual disk ErrorCode:%u", Status);
615 CloseHandle(Handle);
616 return 1;
617 }
618
619 Log("VentoyAttachVirtualDisk success");
620
621 CloseHandle(Handle);
622 return 0;
623 }
624
625
626 static HANDLE g_FatPhyDrive;
627 static UINT64 g_Part2StartSec;
628
629 static int CopyFileFromFatDisk(const CHAR* SrcFile, const CHAR *DstFile)
630 {
631 int rc = 1;
632 int size = 0;
633 char *buf = NULL;
634 void *flfile = NULL;
635
636 Log("CopyFileFromFatDisk (%s)==>(%s)", SrcFile, DstFile);
637
638 flfile = fl_fopen(SrcFile, "rb");
639 if (flfile)
640 {
641 fl_fseek(flfile, 0, SEEK_END);
642 size = (int)fl_ftell(flfile);
643 fl_fseek(flfile, 0, SEEK_SET);
644
645 buf = (char *)malloc(size);
646 if (buf)
647 {
648 fl_fread(buf, 1, size, flfile);
649
650 rc = 0;
651 SaveBuffer2File(DstFile, buf, size);
652 free(buf);
653 }
654
655 fl_fclose(flfile);
656 }
657
658 return rc;
659 }
660
661 static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount)
662 {
663 DWORD dwSize;
664 BOOL bRet;
665 DWORD ReadSize;
666 LARGE_INTEGER liCurrentPosition;
667
668 liCurrentPosition.QuadPart = Sector + g_Part2StartSec;
669 liCurrentPosition.QuadPart *= 512;
670 SetFilePointerEx(g_FatPhyDrive, liCurrentPosition, &liCurrentPosition, FILE_BEGIN);
671
672 ReadSize = (DWORD)(SectorCount * 512);
673
674 bRet = ReadFile(g_FatPhyDrive, Buffer, ReadSize, &dwSize, NULL);
675 if (bRet == FALSE || dwSize != ReadSize)
676 {
677 Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u\n", bRet, ReadSize, dwSize, GetLastError());
678 }
679
680 return 1;
681 }
682
683 static CHAR GetMountLogicalDrive(void)
684 {
685 CHAR Letter = 'Y';
686 DWORD Drives;
687 DWORD Mask = 0x1000000;
688
689 Drives = GetLogicalDrives();
690 Log("Drives=0x%x", Drives);
691
692 while (Mask)
693 {
694 if ((Drives & Mask) == 0)
695 {
696 break;
697 }
698
699 Letter--;
700 Mask >>= 1;
701 }
702
703 return Letter;
704 }
705
706 UINT64 GetVentoyEfiPartStartSector(HANDLE hDrive)
707 {
708 BOOL bRet;
709 DWORD dwSize;
710 MBR_HEAD MBR;
711 VTOY_GPT_INFO *pGpt = NULL;
712 UINT64 StartSector = 0;
713
714 SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
715
716 bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);
717 Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR);
718
719 if ((!bRet) || (dwSize != sizeof(MBR)))
720 {
721 0;
722 }
723
724 if (MBR.PartTbl[0].FsFlag == 0xEE)
725 {
726 Log("GPT partition style");
727
728 pGpt = malloc(sizeof(VTOY_GPT_INFO));
729 if (!pGpt)
730 {
731 return 0;
732 }
733
734 SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
735 bRet = ReadFile(hDrive, pGpt, sizeof(VTOY_GPT_INFO), &dwSize, NULL);
736 if ((!bRet) || (dwSize != sizeof(VTOY_GPT_INFO)))
737 {
738 Log("Failed to read gpt info %d %u %d", bRet, dwSize, LASTERR);
739 return 0;
740 }
741
742 StartSector = pGpt->PartTbl[1].StartLBA;
743 free(pGpt);
744 }
745 else
746 {
747 Log("MBR partition style");
748 StartSector = MBR.PartTbl[1].StartSectorId;
749 }
750
751 Log("GetVentoyEfiPart StartSector: %llu", StartSector);
752 return StartSector;
753 }
754
755 int VentoyMountISOByImdisk(const char *IsoPath, DWORD PhyDrive)
756 {
757 int rc = 1;
758 BOOL bRet;
759 CHAR Letter;
760 DWORD dwBytes;
761 HANDLE hDrive;
762 CHAR PhyPath[MAX_PATH];
763 WCHAR PhyPathW[MAX_PATH];
764 STARTUPINFOA Si;
765 PROCESS_INFORMATION Pi;
766 GET_LENGTH_INFORMATION LengthInfo;
767
768 Log("VentoyMountISOByImdisk %s", IsoPath);
769
770 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", PhyDrive);
771 if (IsUTF8Encode(PhyPath))
772 {
773 Utf8ToUtf16(PhyPath, PhyPathW);
774 hDrive = CreateFileW(PhyPathW, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
775 }
776 else
777 {
778 hDrive = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
779 }
780
781 if (hDrive == INVALID_HANDLE_VALUE)
782 {
783 Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
784 goto End;
785 }
786
787 bRet = DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &LengthInfo, sizeof(LengthInfo), &dwBytes, NULL);
788 if (!bRet)
789 {
790 Log("Could not get phy disk %s size, error:%u", PhyPath, GetLastError());
791 goto End;
792 }
793
794 g_FatPhyDrive = hDrive;
795 g_Part2StartSec = GetVentoyEfiPartStartSector(hDrive);
796
797 Log("Parse FAT fs...");
798
799 fl_init();
800
801 if (0 == fl_attach_media(VentoyFatDiskRead, NULL))
802 {
803 if (g_64bit_system)
804 {
805 CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.sys", "ventoy\\imdisk.sys");
806 CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.exe", "ventoy\\imdisk.exe");
807 CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.cpl", "ventoy\\imdisk.cpl");
808 }
809 else
810 {
811 CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.sys", "ventoy\\imdisk.sys");
812 CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.exe", "ventoy\\imdisk.exe");
813 CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.cpl", "ventoy\\imdisk.cpl");
814 }
815
816 GetCurrentDirectoryA(sizeof(PhyPath), PhyPath);
817 strcat_s(PhyPath, sizeof(PhyPath), "\\ventoy\\imdisk.sys");
818
819 if (LoadNtDriver(PhyPath) == 0)
820 {
821 rc = 0;
822
823 Letter = GetMountLogicalDrive();
824 sprintf_s(PhyPath, sizeof(PhyPath), "ventoy\\imdisk.exe -a -o ro -f %s -m %C:", IsoPath, Letter);
825
826 Log("mount iso to %C: use imdisk cmd <%s>", Letter, PhyPath);
827
828 GetStartupInfoA(&Si);
829
830 Si.dwFlags |= STARTF_USESHOWWINDOW;
831 Si.wShowWindow = SW_HIDE;
832
833 CreateProcessA(NULL, PhyPath, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
834 WaitForSingleObject(Pi.hProcess, INFINITE);
835 }
836 }
837 fl_shutdown();
838
839 End:
840
841 SAFE_CLOSE_HANDLE(hDrive);
842
843 return rc;
844 }
845
846 static int MountIsoFile(CONST CHAR *IsoPath, DWORD PhyDrive)
847 {
848 if (IsWindows8OrGreater())
849 {
850 Log("This is Windows 8 or latter...");
851 if (VentoyMountISOByAPI(IsoPath) == 0)
852 {
853 Log("Mount iso by API success");
854 return 0;
855 }
856 else
857 {
858 Log("Mount iso by API failed, maybe not supported, try imdisk");
859 return VentoyMountISOByImdisk(IsoPath, PhyDrive);
860 }
861 }
862 else
863 {
864 Log("This is before Windows 8 ...");
865 if (VentoyMountISOByImdisk(IsoPath, PhyDrive) == 0)
866 {
867 Log("Mount iso by imdisk success");
868 return 0;
869 }
870 else
871 {
872 return VentoyMountISOByAPI(IsoPath);
873 }
874 }
875 }
876
877 static int GetPhyDriveByLogicalDrive(int DriveLetter)
878 {
879 BOOL Ret;
880 DWORD dwSize;
881 HANDLE Handle;
882 VOLUME_DISK_EXTENTS DiskExtents;
883 CHAR PhyPath[128];
884
885 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", (CHAR)DriveLetter);
886
887 Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
888 if (Handle == INVALID_HANDLE_VALUE)
889 {
890 Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
891 return -1;
892 }
893
894 Ret = DeviceIoControl(Handle,
895 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
896 NULL,
897 0,
898 &DiskExtents,
899 (DWORD)(sizeof(DiskExtents)),
900 (LPDWORD)&dwSize,
901 NULL);
902
903 if (!Ret || DiskExtents.NumberOfDiskExtents == 0)
904 {
905 Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed %s, error:%u", PhyPath, GetLastError());
906 SAFE_CLOSE_HANDLE(Handle);
907 return -1;
908 }
909 SAFE_CLOSE_HANDLE(Handle);
910
911 Log("LogicalDrive:%s PhyDrive:%d Offset:%llu ExtentLength:%llu",
912 PhyPath,
913 DiskExtents.Extents[0].DiskNumber,
914 DiskExtents.Extents[0].StartingOffset.QuadPart,
915 DiskExtents.Extents[0].ExtentLength.QuadPart
916 );
917
918 return (int)DiskExtents.Extents[0].DiskNumber;
919 }
920
921
922 static int DeleteVentoyPart2MountPoint(DWORD PhyDrive)
923 {
924 CHAR Letter = 'A';
925 DWORD Drives;
926 DWORD PhyDisk;
927 CHAR DriveName[] = "?:\\";
928
929 Log("DeleteVentoyPart2MountPoint Phy%u ...", PhyDrive);
930
931 Drives = GetLogicalDrives();
932 while (Drives)
933 {
934 if ((Drives & 0x01) && IsFileExist("%C:\\ventoy\\ventoy.cpio", Letter))
935 {
936 Log("File %C:\\ventoy\\ventoy.cpio exist", Letter);
937
938 PhyDisk = GetPhyDriveByLogicalDrive(Letter);
939 Log("PhyDisk=%u for %C", PhyDisk, Letter);
940
941 if (PhyDisk == PhyDrive)
942 {
943 DriveName[0] = Letter;
944 DeleteVolumeMountPointA(DriveName);
945 return 0;
946 }
947 }
948
949 Letter++;
950 Drives >>= 1;
951 }
952
953 return 1;
954 }
955
956 static BOOL check_tar_archive(const char *archive, CHAR *tarName)
957 {
958 int len;
959 int nameLen;
960 const char *pos = archive;
961 const char *slash = archive;
962
963 while (*pos)
964 {
965 if (*pos == '\\' || *pos == '/')
966 {
967 slash = pos;
968 }
969 pos++;
970 }
971
972 len = (int)strlen(slash);
973
974 if (len > 7 && (strncmp(slash + len - 7, ".tar.gz", 7) == 0 || strncmp(slash + len - 7, ".tar.xz", 7) == 0))
975 {
976 nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash);
977 tarName[nameLen - 3] = 0;
978 return TRUE;
979 }
980 else if (len > 8 && strncmp(slash + len - 8, ".tar.bz2", 8) == 0)
981 {
982 nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash);
983 tarName[nameLen - 4] = 0;
984 return TRUE;
985 }
986 else if (len > 9 && strncmp(slash + len - 9, ".tar.lzma", 9) == 0)
987 {
988 nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash);
989 tarName[nameLen - 5] = 0;
990 return TRUE;
991 }
992
993 return FALSE;
994 }
995
996 static int DecompressInjectionArchive(const char *archive, DWORD PhyDrive)
997 {
998 int rc = 1;
999 BOOL bRet;
1000 DWORD dwBytes;
1001 HANDLE hDrive;
1002 HANDLE hOut;
1003 DWORD flags = CREATE_NO_WINDOW;
1004 CHAR StrBuf[MAX_PATH];
1005 CHAR tarName[MAX_PATH];
1006 STARTUPINFOA Si;
1007 PROCESS_INFORMATION Pi;
1008 PROCESS_INFORMATION NewPi;
1009 GET_LENGTH_INFORMATION LengthInfo;
1010 SECURITY_ATTRIBUTES Sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
1011
1012 Log("DecompressInjectionArchive %s", archive);
1013
1014 sprintf_s(StrBuf, sizeof(StrBuf), "\\\\.\\PhysicalDrive%d", PhyDrive);
1015 hDrive = CreateFileA(StrBuf, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
1016 if (hDrive == INVALID_HANDLE_VALUE)
1017 {
1018 Log("Could not open the disk<%s>, error:%u", StrBuf, GetLastError());
1019 goto End;
1020 }
1021
1022 bRet = DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &LengthInfo, sizeof(LengthInfo), &dwBytes, NULL);
1023 if (!bRet)
1024 {
1025 Log("Could not get phy disk %s size, error:%u", StrBuf, GetLastError());
1026 goto End;
1027 }
1028
1029 g_FatPhyDrive = hDrive;
1030 g_Part2StartSec = GetVentoyEfiPartStartSector(hDrive);
1031
1032 Log("Parse FAT fs...");
1033
1034 fl_init();
1035
1036 if (0 == fl_attach_media(VentoyFatDiskRead, NULL))
1037 {
1038 if (g_64bit_system)
1039 {
1040 CopyFileFromFatDisk("/ventoy/7z/64/7za.exe", "ventoy\\7za.exe");
1041 }
1042 else
1043 {
1044 CopyFileFromFatDisk("/ventoy/7z/32/7za.exe", "ventoy\\7za.exe");
1045 }
1046
1047 sprintf_s(StrBuf, sizeof(StrBuf), "ventoy\\7za.exe x -y -aoa -oX:\\ %s", archive);
1048
1049 Log("extract inject to X:");
1050 Log("cmdline:<%s>", StrBuf);
1051
1052 GetStartupInfoA(&Si);
1053
1054 hOut = CreateFileA("ventoy\\7z.log",
1055 FILE_APPEND_DATA,
1056 FILE_SHARE_WRITE | FILE_SHARE_READ,
1057 &Sa,
1058 OPEN_ALWAYS,
1059 FILE_ATTRIBUTE_NORMAL,
1060 NULL);
1061
1062 Si.dwFlags |= STARTF_USESTDHANDLES;
1063
1064 if (hOut != INVALID_HANDLE_VALUE)
1065 {
1066 Si.hStdError = hOut;
1067 Si.hStdOutput = hOut;
1068 }
1069
1070 CreateProcessA(NULL, StrBuf, NULL, NULL, TRUE, flags, NULL, NULL, &Si, &Pi);
1071 WaitForSingleObject(Pi.hProcess, INFINITE);
1072
1073 //
1074 // decompress tar archive, for tar.gz/tar.xz/tar.bz2
1075 //
1076 if (check_tar_archive(archive, tarName))
1077 {
1078 Log("Decompress tar archive...<%s>", tarName);
1079
1080 sprintf_s(StrBuf, sizeof(StrBuf), "ventoy\\7za.exe x -y -aoa -oX:\\ %s", tarName);
1081
1082 CreateProcessA(NULL, StrBuf, NULL, NULL, TRUE, flags, NULL, NULL, &Si, &NewPi);
1083 WaitForSingleObject(NewPi.hProcess, INFINITE);
1084
1085 Log("Now delete %s", tarName);
1086 DeleteFileA(tarName);
1087 }
1088
1089 SAFE_CLOSE_HANDLE(hOut);
1090 }
1091 fl_shutdown();
1092
1093 End:
1094
1095 SAFE_CLOSE_HANDLE(hDrive);
1096
1097 return rc;
1098 }
1099
1100 static int ProcessUnattendedInstallation(const char *script)
1101 {
1102 DWORD dw;
1103 HKEY hKey;
1104 LSTATUS Ret;
1105 CHAR Letter;
1106 CHAR CurDir[MAX_PATH];
1107
1108 Log("Copy unattended XML ...");
1109
1110 GetCurrentDirectory(sizeof(CurDir), CurDir);
1111 Letter = CurDir[0];
1112 if ((Letter >= 'A' && Letter <= 'Z') || (Letter >= 'a' && Letter <= 'z'))
1113 {
1114 Log("Current Drive Letter: %C", Letter);
1115 }
1116 else
1117 {
1118 Letter = 'X';
1119 }
1120
1121 sprintf_s(CurDir, sizeof(CurDir), "%C:\\Autounattend.xml", Letter);
1122 Log("Copy file <%s> --> <%s>", script, CurDir);
1123 CopyFile(script, CurDir, FALSE);
1124
1125 Ret = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "System\\Setup", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dw);
1126 if (ERROR_SUCCESS == Ret)
1127 {
1128 Ret = RegSetValueEx(hKey, "UnattendFile", 0, REG_SZ, CurDir, (DWORD)(strlen(CurDir) + 1));
1129 }
1130
1131 return 0;
1132 }
1133
1134 static int VentoyHook(ventoy_os_param *param)
1135 {
1136 int rc;
1137 CHAR Letter = 'A';
1138 DISK_EXTENT DiskExtent;
1139 DWORD Drives = GetLogicalDrives();
1140 UINT8 UUID[16];
1141 CHAR IsoPath[MAX_PATH];
1142
1143 Log("Logical Drives=0x%x Path:<%s>", Drives, param->vtoy_img_path);
1144
1145 if (IsUTF8Encode(param->vtoy_img_path))
1146 {
1147 Log("This file is UTF8 encoding\n");
1148 }
1149
1150 while (Drives)
1151 {
1152 if (Drives & 0x01)
1153 {
1154 sprintf_s(IsoPath, sizeof(IsoPath), "%C:\\%s", Letter, param->vtoy_img_path);
1155 if (IsFileExist("%s", IsoPath))
1156 {
1157 Log("File exist under %C:", Letter);
1158 if (GetPhyDiskUUID(Letter, UUID, &DiskExtent) == 0)
1159 {
1160 if (memcmp(UUID, param->vtoy_disk_guid, 16) == 0)
1161 {
1162 Log("Disk UUID match");
1163 break;
1164 }
1165 }
1166 }
1167 else
1168 {
1169 Log("File NOT exist under %C:", Letter);
1170 }
1171 }
1172
1173 Drives >>= 1;
1174 Letter++;
1175 }
1176
1177 if (Drives == 0)
1178 {
1179 Log("Failed to find ISO file");
1180 return 1;
1181 }
1182
1183 Log("Find ISO file <%s>", IsoPath);
1184
1185 rc = MountIsoFile(IsoPath, DiskExtent.DiskNumber);
1186 Log("Mount ISO FILE: %s", rc == 0 ? "SUCCESS" : "FAILED");
1187
1188 // for protect
1189 rc = DeleteVentoyPart2MountPoint(DiskExtent.DiskNumber);
1190 Log("Delete ventoy mountpoint: %s", rc == 0 ? "SUCCESS" : "NO NEED");
1191
1192 if (g_windows_data.auto_install_script[0])
1193 {
1194 sprintf_s(IsoPath, sizeof(IsoPath), "%C:%s", Letter, g_windows_data.auto_install_script);
1195 if (IsFileExist("%s", IsoPath))
1196 {
1197 Log("use auto install script %s...", IsoPath);
1198 ProcessUnattendedInstallation(IsoPath);
1199 }
1200 else
1201 {
1202 Log("auto install script %s not exist", IsoPath);
1203 }
1204 }
1205 else
1206 {
1207 Log("auto install no need");
1208 }
1209
1210 if (g_windows_data.injection_archive[0])
1211 {
1212 sprintf_s(IsoPath, sizeof(IsoPath), "%C:%s", Letter, g_windows_data.injection_archive);
1213 if (IsFileExist("%s", IsoPath))
1214 {
1215 Log("decompress injection archive %s...", IsoPath);
1216 DecompressInjectionArchive(IsoPath, DiskExtent.DiskNumber);
1217 }
1218 else
1219 {
1220 Log("injection archive %s not exist", IsoPath);
1221 }
1222 }
1223 else
1224 {
1225 Log("no injection archive found");
1226 }
1227
1228 return 0;
1229 }
1230
1231 const char * GetFileNameInPath(const char *fullpath)
1232 {
1233 int i;
1234 const char *pos = NULL;
1235
1236 if (strstr(fullpath, ":"))
1237 {
1238 for (i = (int)strlen(fullpath); i > 0; i--)
1239 {
1240 if (fullpath[i - 1] == '/' || fullpath[i - 1] == '\\')
1241 {
1242 return fullpath + i;
1243 }
1244 }
1245 }
1246
1247 return fullpath;
1248 }
1249
1250 int VentoyJumpWimboot(INT argc, CHAR **argv, CHAR *LunchFile)
1251 {
1252 int rc = 1;
1253 char *buf = NULL;
1254 DWORD size = 0;
1255 DWORD Pos;
1256
1257 #ifdef VTOY_32
1258 g_64bit_system = FALSE;
1259 #else
1260 g_64bit_system = TRUE;
1261 #endif
1262
1263 Log("VentoyJumpWimboot %dbit", g_64bit_system ? 64 : 32);
1264
1265 sprintf_s(LunchFile, MAX_PATH, "X:\\setup.exe");
1266
1267 ReadWholeFile2Buf("wimboot.data", &buf, &size);
1268 Log("wimboot.data size:%d", size);
1269
1270 memcpy(&g_os_param, buf, sizeof(ventoy_os_param));
1271 memcpy(&g_windows_data, buf + sizeof(ventoy_os_param), sizeof(ventoy_windows_data));
1272 memcpy(g_os_param_reserved, g_os_param.vtoy_reserved, sizeof(g_os_param_reserved));
1273
1274 if (g_os_param_reserved[0] == 1)
1275 {
1276 Log("break here for debug .....");
1277 goto End;
1278 }
1279
1280 // convert / to \\
1281 for (Pos = 0; Pos < sizeof(g_os_param.vtoy_img_path) && g_os_param.vtoy_img_path[Pos]; Pos++)
1282 {
1283 if (g_os_param.vtoy_img_path[Pos] == '/')
1284 {
1285 g_os_param.vtoy_img_path[Pos] = '\\';
1286 }
1287 }
1288
1289 if (g_os_param_reserved[0] == 2)
1290 {
1291 Log("skip hook for debug .....");
1292 rc = 0;
1293 goto End;
1294 }
1295
1296 rc = VentoyHook(&g_os_param);
1297
1298 End:
1299
1300 if (buf)
1301 {
1302 free(buf);
1303 }
1304
1305 return rc;
1306 }
1307
1308 int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile)
1309 {
1310 int rc = 1;
1311 DWORD Pos;
1312 DWORD PeStart;
1313 DWORD FileSize;
1314 BYTE *Buffer = NULL;
1315 CHAR ExeFileName[MAX_PATH];
1316
1317 sprintf_s(ExeFileName, sizeof(ExeFileName), "%s", argv[0]);
1318 if (!IsFileExist("%s", ExeFileName))
1319 {
1320 Log("File %s NOT exist, now try %s.exe", ExeFileName, ExeFileName);
1321 sprintf_s(ExeFileName, sizeof(ExeFileName), "%s.exe", argv[0]);
1322
1323 Log("File %s exist ? %s", ExeFileName, IsFileExist("%s", ExeFileName) ? "YES" : "NO");
1324 }
1325
1326 if (ReadWholeFile2Buf(ExeFileName, (void **)&Buffer, &FileSize))
1327 {
1328 goto End;
1329 }
1330
1331 g_64bit_system = IsPe64(Buffer);
1332 Log("VentoyJump %dbit", g_64bit_system ? 64 : 32);
1333
1334 if (IsDirExist("ventoy"))
1335 {
1336 Log("ventoy directory already exist");
1337 }
1338 else
1339 {
1340 Log("ventoy directory not exist, now create it.");
1341 if (!CreateDirectoryA("ventoy", NULL))
1342 {
1343 Log("Failed to create ventoy directory err:%u", GetLastError());
1344 goto End;
1345 }
1346 }
1347
1348 for (PeStart = 0; PeStart < FileSize; PeStart += 16)
1349 {
1350 if (CheckOsParam((ventoy_os_param *)(Buffer + PeStart)) &&
1351 CheckPeHead(Buffer + PeStart + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data)))
1352 {
1353 Log("Find os pararm at %u", PeStart);
1354
1355 memcpy(&g_os_param, Buffer + PeStart, sizeof(ventoy_os_param));
1356 memcpy(&g_windows_data, Buffer + PeStart + sizeof(ventoy_os_param), sizeof(ventoy_windows_data));
1357 memcpy(g_os_param_reserved, g_os_param.vtoy_reserved, sizeof(g_os_param_reserved));
1358
1359 if (g_os_param_reserved[0] == 1)
1360 {
1361 Log("break here for debug .....");
1362 goto End;
1363 }
1364
1365 // convert / to \\
1366 for (Pos = 0; Pos < sizeof(g_os_param.vtoy_img_path) && g_os_param.vtoy_img_path[Pos]; Pos++)
1367 {
1368 if (g_os_param.vtoy_img_path[Pos] == '/')
1369 {
1370 g_os_param.vtoy_img_path[Pos] = '\\';
1371 }
1372 }
1373
1374 PeStart += sizeof(ventoy_os_param) + sizeof(ventoy_windows_data);
1375 sprintf_s(LunchFile, MAX_PATH, "ventoy\\%s", GetFileNameInPath(ExeFileName));
1376
1377 if (IsFileExist("%s", LunchFile))
1378 {
1379 Log("vtoyjump multiple call...");
1380 rc = 0;
1381 goto End;
1382 }
1383
1384 SaveBuffer2File(LunchFile, Buffer + PeStart, FileSize - PeStart);
1385 break;
1386 }
1387 }
1388
1389 if (PeStart >= FileSize)
1390 {
1391 Log("OS param not found");
1392 goto End;
1393 }
1394
1395 if (g_os_param_reserved[0] == 2)
1396 {
1397 Log("skip hook for debug .....");
1398 rc = 0;
1399 goto End;
1400 }
1401
1402 rc = VentoyHook(&g_os_param);
1403
1404 End:
1405
1406 if (Buffer)
1407 {
1408 free(Buffer);
1409 }
1410
1411 return rc;
1412 }
1413
1414 int main(int argc, char **argv)
1415 {
1416 int i = 0;
1417 int rc = 0;
1418 CHAR *Pos = NULL;
1419 CHAR CurDir[MAX_PATH];
1420 CHAR LunchFile[MAX_PATH];
1421 CHAR CallParam[1024] = { 0 };
1422 STARTUPINFOA Si;
1423 PROCESS_INFORMATION Pi;
1424
1425 if (argv[0] && argv[0][0] && argv[0][1] == ':')
1426 {
1427 GetCurrentDirectoryA(sizeof(CurDir), CurDir);
1428
1429 strcpy_s(LunchFile, sizeof(LunchFile), argv[0]);
1430 Pos = (char *)GetFileNameInPath(LunchFile);
1431
1432 strcat_s(CurDir, sizeof(CurDir), "\\");
1433 strcat_s(CurDir, sizeof(CurDir), Pos);
1434
1435 if (_stricmp(argv[0], CurDir) != 0)
1436 {
1437 *Pos = 0;
1438 SetCurrentDirectoryA(LunchFile);
1439 }
1440 }
1441
1442 Log("######## VentoyJump ##########");
1443 Log("argc = %d", argc);
1444 for (i = 0; i < argc; i++)
1445 {
1446 Log("argv[%d]=<%s>", i, argv[i]);
1447 if (i > 0)
1448 {
1449 strcat_s(CallParam, sizeof(CallParam), " ");
1450 strcat_s(CallParam, sizeof(CallParam), argv[i]);
1451 }
1452 }
1453
1454 if (Pos && *Pos == 0)
1455 {
1456 Log("Old current directory = <%s>", CurDir);
1457 Log("New current directory = <%s>", LunchFile);
1458 }
1459 else
1460 {
1461 GetCurrentDirectoryA(sizeof(CurDir), CurDir);
1462 Log("Current directory = <%s>", CurDir);
1463 }
1464
1465 GetStartupInfoA(&Si);
1466
1467 memset(LunchFile, 0, sizeof(LunchFile));
1468
1469 if (strstr(argv[0], "vtoyjump.exe"))
1470 {
1471 rc = VentoyJumpWimboot(argc, argv, LunchFile);
1472 }
1473 else
1474 {
1475 rc = VentoyJump(argc, argv, LunchFile);
1476 }
1477
1478 Log("LunchFile=<%s> CallParam=<%s>", LunchFile, CallParam);
1479
1480 if (_stricmp(argv[0], "PECMD.EXE") == 0 && _stricmp(LunchFile, "ventoy\\PECMD.EXE") == 0)
1481 {
1482 MoveFileA("PECMD.EXE", "PECMD_BACK.EXE");
1483 MoveFileA("ventoy\\PECMD.EXE", "PECMD.EXE");
1484 sprintf_s(LunchFile, sizeof(LunchFile), "%s", "PECMD.EXE");
1485 Log("Move original PECMD.EXE <%s>", LunchFile);
1486 }
1487
1488 if (g_os_param_reserved[0] == 3)
1489 {
1490 Log("Open log for debug ...");
1491 sprintf_s(LunchFile, sizeof(LunchFile), "%s", "notepad.exe ventoy.log");
1492 }
1493 else
1494 {
1495 if (CallParam[0])
1496 {
1497 strcat_s(LunchFile, sizeof(LunchFile), CallParam);
1498 }
1499 else if (NULL == strstr(LunchFile, "setup.exe"))
1500 {
1501 Log("Not setup.exe, hide windows.");
1502 Si.dwFlags |= STARTF_USESHOWWINDOW;
1503 Si.wShowWindow = SW_HIDE;
1504 }
1505
1506 Log("Ventoy jump %s ...", rc == 0 ? "success" : "failed");
1507 }
1508
1509 Log("Now launch <%s> ...", LunchFile);
1510
1511 //sprintf_s(LunchFile, sizeof(LunchFile), "%s", "cmd.exe");
1512 CreateProcessA(NULL, LunchFile, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
1513
1514 for (i = 0; rc && i < 1800; i++)
1515 {
1516 Log("Ventoy hook failed, now wait and retry ...");
1517 Sleep(1000);
1518 rc = VentoyHook(&g_os_param);
1519 }
1520
1521 Log("Wait process...");
1522 WaitForSingleObject(Pi.hProcess, INFINITE);
1523
1524 Log("vtoyjump finished");
1525 return 0;
1526 }