]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - vtoyjump/vtoyjump/vtoyjump.c
d4aebce5bab109d79a13cbc14d051c7e3a3892cb
[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 UINT8 g_os_param_reserved[32];
32 static BOOL g_64bit_system = FALSE;
33 static ventoy_guid g_ventoy_guid = VENTOY_GUID;
34
35 void Log(const char *Fmt, ...)
36 {
37 va_list Arg;
38 int Len = 0;
39 FILE *File = NULL;
40 SYSTEMTIME Sys;
41 char szBuf[1024];
42
43 GetLocalTime(&Sys);
44 Len += sprintf_s(szBuf, sizeof(szBuf),
45 "[%4d/%02d/%02d %02d:%02d:%02d.%03d] ",
46 Sys.wYear, Sys.wMonth, Sys.wDay,
47 Sys.wHour, Sys.wMinute, Sys.wSecond,
48 Sys.wMilliseconds);
49
50 va_start(Arg, Fmt);
51 Len += vsnprintf_s(szBuf + Len, sizeof(szBuf)-Len, sizeof(szBuf)-Len, Fmt, Arg);
52 va_end(Arg);
53
54 fopen_s(&File, "ventoy.log", "a+");
55 if (File)
56 {
57 fwrite(szBuf, 1, Len, File);
58 fwrite("\n", 1, 1, File);
59 fclose(File);
60 }
61 }
62
63
64 static int LoadNtDriver(const char *DrvBinPath)
65 {
66 int i;
67 int rc = 0;
68 BOOL Ret;
69 DWORD Status;
70 SC_HANDLE hServiceMgr;
71 SC_HANDLE hService;
72 char name[256] = { 0 };
73
74 for (i = (int)strlen(DrvBinPath) - 1; i >= 0; i--)
75 {
76 if (DrvBinPath[i] == '\\' || DrvBinPath[i] == '/')
77 {
78 sprintf_s(name, sizeof(name), "%s", DrvBinPath + i + 1);
79 break;
80 }
81 }
82
83 Log("Load NT driver: %s %s", DrvBinPath, name);
84
85 hServiceMgr = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
86 if (hServiceMgr == NULL)
87 {
88 Log("OpenSCManager failed Error:%u", GetLastError());
89 return 1;
90 }
91
92 Log("OpenSCManager OK");
93
94 hService = CreateServiceA(hServiceMgr,
95 name,
96 name,
97 SERVICE_ALL_ACCESS,
98 SERVICE_KERNEL_DRIVER,
99 SERVICE_DEMAND_START,
100 SERVICE_ERROR_NORMAL,
101 DrvBinPath,
102 NULL, NULL, NULL, NULL, NULL);
103 if (hService == NULL)
104 {
105 Status = GetLastError();
106 if (Status != ERROR_IO_PENDING && Status != ERROR_SERVICE_EXISTS)
107 {
108 Log("CreateService failed v %u", Status);
109 CloseServiceHandle(hServiceMgr);
110 return 1;
111 }
112
113 hService = OpenServiceA(hServiceMgr, name, SERVICE_ALL_ACCESS);
114 if (hService == NULL)
115 {
116 Log("OpenService failed %u", Status);
117 CloseServiceHandle(hServiceMgr);
118 return 1;
119 }
120 }
121
122 Log("CreateService imdisk OK");
123
124 Ret = StartServiceA(hService, 0, NULL);
125 if (Ret)
126 {
127 Log("StartService OK");
128 }
129 else
130 {
131 Status = GetLastError();
132 if (Status == ERROR_SERVICE_ALREADY_RUNNING)
133 {
134 rc = 0;
135 }
136 else
137 {
138 Log("StartService error %u", Status);
139 rc = 1;
140 }
141 }
142
143 CloseServiceHandle(hService);
144 CloseServiceHandle(hServiceMgr);
145
146 Log("Load NT driver %s", rc ? "failed" : "success");
147
148 return rc;
149 }
150
151 static int ReadWholeFile2Buf(const char *Fullpath, void **Data, DWORD *Size)
152 {
153 int rc = 1;
154 DWORD FileSize;
155 DWORD dwSize;
156 HANDLE Handle;
157 BYTE *Buffer = NULL;
158
159 Log("ReadWholeFile2Buf <%s>", Fullpath);
160
161 Handle = CreateFileA(Fullpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
162 if (Handle == INVALID_HANDLE_VALUE)
163 {
164 Log("Could not open the file<%s>, error:%u", Fullpath, GetLastError());
165 goto End;
166 }
167
168 FileSize = SetFilePointer(Handle, 0, NULL, FILE_END);
169
170 Buffer = malloc(FileSize);
171 if (!Buffer)
172 {
173 Log("Failed to alloc memory size:%u", FileSize);
174 goto End;
175 }
176
177 SetFilePointer(Handle, 0, NULL, FILE_BEGIN);
178 if (!ReadFile(Handle, Buffer, FileSize, &dwSize, NULL))
179 {
180 Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError());
181 goto End;
182 }
183
184 *Data = Buffer;
185 *Size = FileSize;
186
187 Log("Success read file size:%u", FileSize);
188
189 rc = 0;
190
191 End:
192 SAFE_CLOSE_HANDLE(Handle);
193
194 return rc;
195 }
196
197 static BOOL CheckPeHead(BYTE *Head)
198 {
199 UINT32 PeOffset;
200
201 if (Head[0] != 'M' || Head[1] != 'Z')
202 {
203 return FALSE;
204 }
205
206 PeOffset = *(UINT32 *)(Head + 60);
207 if (*(UINT32 *)(Head + PeOffset) != 0x00004550)
208 {
209 return FALSE;
210 }
211
212 return TRUE;
213 }
214
215 static BOOL IsPe64(BYTE *buffer)
216 {
217 DWORD pe_off;
218
219 if (!CheckPeHead(buffer))
220 {
221 return FALSE;
222 }
223
224 pe_off = *(UINT32 *)(buffer + 60);
225 if (*(UINT16 *)(buffer + pe_off + 24) == 0x020b)
226 {
227 return TRUE;
228 }
229
230 return FALSE;
231 }
232
233
234 static BOOL CheckOsParam(ventoy_os_param *param)
235 {
236 UINT32 i;
237 BYTE Sum = 0;
238
239 if (memcmp(&param->guid, &g_ventoy_guid, sizeof(ventoy_guid)))
240 {
241 return FALSE;
242 }
243
244 for (i = 0; i < sizeof(ventoy_os_param); i++)
245 {
246 Sum += *((BYTE *)param + i);
247 }
248
249 if (Sum)
250 {
251 return FALSE;
252 }
253
254 if (param->vtoy_img_location_addr % 4096)
255 {
256 return FALSE;
257 }
258
259 return TRUE;
260 }
261
262 static int SaveBuffer2File(const char *Fullpath, void *Buffer, DWORD Length)
263 {
264 int rc = 1;
265 DWORD dwSize;
266 HANDLE Handle;
267
268 Log("SaveBuffer2File <%s> len:%u", Fullpath, Length);
269
270 Handle = CreateFileA(Fullpath, GENERIC_READ | GENERIC_WRITE,
271 FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, 0, 0);
272 if (Handle == INVALID_HANDLE_VALUE)
273 {
274 Log("Could not create new file, error:%u", GetLastError());
275 goto End;
276 }
277
278 WriteFile(Handle, Buffer, Length, &dwSize, NULL);
279
280 rc = 0;
281
282 End:
283 SAFE_CLOSE_HANDLE(Handle);
284
285 return rc;
286 }
287
288 static BOOL IsPathExist(BOOL Dir, const char *Fmt, ...)
289 {
290 va_list Arg;
291 HANDLE hFile;
292 DWORD Attr;
293 CHAR FilePath[MAX_PATH];
294
295 va_start(Arg, Fmt);
296 vsnprintf_s(FilePath, sizeof(FilePath), sizeof(FilePath), Fmt, Arg);
297 va_end(Arg);
298
299 hFile = CreateFileA(FilePath, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
300 if (INVALID_HANDLE_VALUE == hFile)
301 {
302 return FALSE;
303 }
304
305 CloseHandle(hFile);
306
307 Attr = GetFileAttributesA(FilePath);
308
309 if (Dir)
310 {
311 if ((Attr & FILE_ATTRIBUTE_DIRECTORY) == 0)
312 {
313 return FALSE;
314 }
315 }
316 else
317 {
318 if (Attr & FILE_ATTRIBUTE_DIRECTORY)
319 {
320 return FALSE;
321 }
322 }
323
324 return TRUE;
325 }
326
327 static int GetPhyDiskUUID(const char LogicalDrive, UINT8 *UUID, DISK_EXTENT *DiskExtent)
328 {
329 BOOL Ret;
330 DWORD dwSize;
331 HANDLE Handle;
332 VOLUME_DISK_EXTENTS DiskExtents;
333 CHAR PhyPath[128];
334 UINT8 SectorBuf[512];
335
336 Log("GetPhyDiskUUID %C", LogicalDrive);
337
338 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", LogicalDrive);
339 Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
340 if (Handle == INVALID_HANDLE_VALUE)
341 {
342 Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
343 return 1;
344 }
345
346 Ret = DeviceIoControl(Handle,
347 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
348 NULL,
349 0,
350 &DiskExtents,
351 (DWORD)(sizeof(DiskExtents)),
352 (LPDWORD)&dwSize,
353 NULL);
354 if (!Ret || DiskExtents.NumberOfDiskExtents == 0)
355 {
356 Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed, error:%u", GetLastError());
357 CloseHandle(Handle);
358 return 1;
359 }
360 CloseHandle(Handle);
361
362 memcpy(DiskExtent, DiskExtents.Extents, sizeof(DiskExtent));
363 Log("%C: is in PhysicalDrive%d ", LogicalDrive, DiskExtents.Extents[0].DiskNumber);
364
365 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", DiskExtents.Extents[0].DiskNumber);
366 Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
367 if (Handle == INVALID_HANDLE_VALUE)
368 {
369 Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
370 return 1;
371 }
372
373 if (!ReadFile(Handle, SectorBuf, sizeof(SectorBuf), &dwSize, NULL))
374 {
375 Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError());
376 CloseHandle(Handle);
377 return 1;
378 }
379
380 memcpy(UUID, SectorBuf + 0x180, 16);
381 CloseHandle(Handle);
382 return 0;
383 }
384
385 int VentoyMountISOByAPI(const char *IsoPath)
386 {
387 HANDLE Handle;
388 DWORD Status;
389 WCHAR wFilePath[512] = { 0 };
390 VIRTUAL_STORAGE_TYPE StorageType;
391 OPEN_VIRTUAL_DISK_PARAMETERS OpenParameters;
392 ATTACH_VIRTUAL_DISK_PARAMETERS AttachParameters;
393
394 Log("VentoyMountISOByAPI <%s>", IsoPath);
395
396 MultiByteToWideChar(CP_ACP, 0, IsoPath, (int)strlen(IsoPath), wFilePath, (int)(sizeof(wFilePath) / sizeof(WCHAR)));
397
398 memset(&StorageType, 0, sizeof(StorageType));
399 memset(&OpenParameters, 0, sizeof(OpenParameters));
400 memset(&AttachParameters, 0, sizeof(AttachParameters));
401
402 OpenParameters.Version = OPEN_VIRTUAL_DISK_VERSION_1;
403 AttachParameters.Version = ATTACH_VIRTUAL_DISK_VERSION_1;
404
405 Status = OpenVirtualDisk(&StorageType, wFilePath, VIRTUAL_DISK_ACCESS_READ, 0, &OpenParameters, &Handle);
406 if (Status != ERROR_SUCCESS)
407 {
408 if (ERROR_VIRTDISK_PROVIDER_NOT_FOUND == Status)
409 {
410 Log("VirtualDisk for ISO file is not supported in current system");
411 }
412 else
413 {
414 Log("Failed to open virtual disk ErrorCode:%u", Status);
415 }
416 return 1;
417 }
418
419 Log("OpenVirtualDisk success");
420
421 Status = AttachVirtualDisk(Handle, NULL, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY | ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME, 0, &AttachParameters, NULL);
422 if (Status != ERROR_SUCCESS)
423 {
424 Log("Failed to attach virtual disk ErrorCode:%u", Status);
425 CloseHandle(Handle);
426 return 1;
427 }
428
429 CloseHandle(Handle);
430 return 0;
431 }
432
433
434 static HANDLE g_FatPhyDrive;
435 static UINT64 g_Part2StartSec;
436
437 static int CopyFileFromFatDisk(const CHAR* SrcFile, const CHAR *DstFile)
438 {
439 int rc = 1;
440 int size = 0;
441 char *buf = NULL;
442 void *flfile = NULL;
443
444 Log("CopyFileFromFatDisk (%s)==>(%s)", SrcFile, DstFile);
445
446 flfile = fl_fopen(SrcFile, "rb");
447 if (flfile)
448 {
449 fl_fseek(flfile, 0, SEEK_END);
450 size = (int)fl_ftell(flfile);
451 fl_fseek(flfile, 0, SEEK_SET);
452
453 buf = (char *)malloc(size);
454 if (buf)
455 {
456 fl_fread(buf, 1, size, flfile);
457
458 rc = 0;
459 SaveBuffer2File(DstFile, buf, size);
460 free(buf);
461 }
462
463 fl_fclose(flfile);
464 }
465
466 return rc;
467 }
468
469 static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount)
470 {
471 DWORD dwSize;
472 BOOL bRet;
473 DWORD ReadSize;
474 LARGE_INTEGER liCurrentPosition;
475
476 liCurrentPosition.QuadPart = Sector + g_Part2StartSec;
477 liCurrentPosition.QuadPart *= 512;
478 SetFilePointerEx(g_FatPhyDrive, liCurrentPosition, &liCurrentPosition, FILE_BEGIN);
479
480 ReadSize = (DWORD)(SectorCount * 512);
481
482 bRet = ReadFile(g_FatPhyDrive, Buffer, ReadSize, &dwSize, NULL);
483 if (bRet == FALSE || dwSize != ReadSize)
484 {
485 Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u\n", bRet, ReadSize, dwSize, GetLastError());
486 }
487
488 return 1;
489 }
490
491 static CHAR GetMountLogicalDrive(void)
492 {
493 CHAR Letter = 'Z';
494 DWORD Drives;
495 DWORD Mask = 0x2000000;
496
497 Drives = GetLogicalDrives();
498 Log("Drives=0x%x", Drives);
499
500 while (Mask)
501 {
502 if ((Drives & Mask) == 0)
503 {
504 break;
505 }
506
507 Letter--;
508 Mask >>= 1;
509 }
510
511 return Letter;
512 }
513
514 int VentoyMountISOByImdisk(const char *IsoPath, DWORD PhyDrive)
515 {
516 int rc = 1;
517 BOOL bRet;
518 CHAR Letter;
519 DWORD dwBytes;
520 HANDLE hDrive;
521 CHAR PhyPath[MAX_PATH];
522 STARTUPINFOA Si;
523 PROCESS_INFORMATION Pi;
524 GET_LENGTH_INFORMATION LengthInfo;
525
526 Log("VentoyMountISOByImdisk %s", IsoPath);
527
528 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", PhyDrive);
529 hDrive = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
530 if (hDrive == INVALID_HANDLE_VALUE)
531 {
532 Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
533 goto End;
534 }
535
536 bRet = DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &LengthInfo, sizeof(LengthInfo), &dwBytes, NULL);
537 if (!bRet)
538 {
539 Log("Could not get phy disk %s size, error:%u", PhyPath, GetLastError());
540 goto End;
541 }
542
543 g_FatPhyDrive = hDrive;
544 g_Part2StartSec = (LengthInfo.Length.QuadPart - VENTOY_EFI_PART_SIZE) / 512;
545
546 Log("Parse FAT fs...");
547
548 fl_init();
549
550 if (0 == fl_attach_media(VentoyFatDiskRead, NULL))
551 {
552 if (g_64bit_system)
553 {
554 CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.sys", "ventoy\\imdisk.sys");
555 CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.exe", "ventoy\\imdisk.exe");
556 CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.cpl", "ventoy\\imdisk.cpl");
557 }
558 else
559 {
560 CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.sys", "ventoy\\imdisk.sys");
561 CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.exe", "ventoy\\imdisk.exe");
562 CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.cpl", "ventoy\\imdisk.cpl");
563 }
564
565 GetCurrentDirectoryA(sizeof(PhyPath), PhyPath);
566 strcat_s(PhyPath, sizeof(PhyPath), "\\ventoy\\imdisk.sys");
567
568 if (LoadNtDriver(PhyPath) == 0)
569 {
570 rc = 0;
571
572 Letter = GetMountLogicalDrive();
573 sprintf_s(PhyPath, sizeof(PhyPath), "ventoy\\imdisk.exe -a -o ro -f %s -m %C:", IsoPath, Letter);
574
575 Log("mount iso to %C: use imdisk cmd <%s>", Letter, PhyPath);
576
577 GetStartupInfoA(&Si);
578
579 Si.dwFlags |= STARTF_USESHOWWINDOW;
580 Si.wShowWindow = SW_HIDE;
581
582 CreateProcessA(NULL, PhyPath, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
583 WaitForSingleObject(Pi.hProcess, INFINITE);
584 }
585 }
586 fl_shutdown();
587
588 End:
589
590 SAFE_CLOSE_HANDLE(hDrive);
591
592 return rc;
593 }
594
595 static int MountIsoFile(CONST CHAR *IsoPath, DWORD PhyDrive)
596 {
597 if (IsWindows8OrGreater())
598 {
599 Log("This is Windows 8 or latter...");
600 if (VentoyMountISOByAPI(IsoPath) == 0)
601 {
602 Log("Mount iso by API success");
603 return 0;
604 }
605 else
606 {
607 Log("Mount iso by API failed, maybe not supported, try imdisk");
608 return VentoyMountISOByImdisk(IsoPath, PhyDrive);
609 }
610 }
611 else
612 {
613 Log("This is before Windows 8 ...");
614 if (VentoyMountISOByImdisk(IsoPath, PhyDrive) == 0)
615 {
616 Log("Mount iso by imdisk success");
617 return 0;
618 }
619 else
620 {
621 return VentoyMountISOByAPI(IsoPath);
622 }
623 }
624 }
625
626 static int GetPhyDriveByLogicalDrive(int DriveLetter)
627 {
628 BOOL Ret;
629 DWORD dwSize;
630 HANDLE Handle;
631 VOLUME_DISK_EXTENTS DiskExtents;
632 CHAR PhyPath[128];
633
634 sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", (CHAR)DriveLetter);
635
636 Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
637 if (Handle == INVALID_HANDLE_VALUE)
638 {
639 Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
640 return -1;
641 }
642
643 Ret = DeviceIoControl(Handle,
644 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
645 NULL,
646 0,
647 &DiskExtents,
648 (DWORD)(sizeof(DiskExtents)),
649 (LPDWORD)&dwSize,
650 NULL);
651
652 if (!Ret || DiskExtents.NumberOfDiskExtents == 0)
653 {
654 Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed %s, error:%u", PhyPath, GetLastError());
655 SAFE_CLOSE_HANDLE(Handle);
656 return -1;
657 }
658 SAFE_CLOSE_HANDLE(Handle);
659
660 Log("LogicalDrive:%s PhyDrive:%d Offset:%llu ExtentLength:%llu",
661 PhyPath,
662 DiskExtents.Extents[0].DiskNumber,
663 DiskExtents.Extents[0].StartingOffset.QuadPart,
664 DiskExtents.Extents[0].ExtentLength.QuadPart
665 );
666
667 return (int)DiskExtents.Extents[0].DiskNumber;
668 }
669
670
671 static int DeleteVentoyPart2MountPoint(DWORD PhyDrive)
672 {
673 CHAR Letter = 'A';
674 DWORD Drives;
675 DWORD PhyDisk;
676 CHAR DriveName[] = "?:\\";
677
678 Log("DeleteVentoyPart2MountPoint Phy%u ...", PhyDrive);
679
680 Drives = GetLogicalDrives();
681 while (Drives)
682 {
683 if ((Drives & 0x01) && IsPathExist(FALSE, "%C:\\ventoy\\ventoy.cpio", Letter))
684 {
685 Log("File %C:\\ventoy\\ventoy.cpio exist", Letter);
686
687 PhyDisk = GetPhyDriveByLogicalDrive(Letter);
688 Log("PhyDisk=%u for %C", PhyDisk, Letter);
689
690 if (PhyDisk == PhyDrive)
691 {
692 DriveName[0] = Letter;
693 DeleteVolumeMountPointA(DriveName);
694 return 0;
695 }
696 }
697
698 Letter++;
699 Drives >>= 1;
700 }
701
702 return 1;
703 }
704
705 static int VentoyHook(ventoy_os_param *param)
706 {
707 int rc;
708 CHAR Letter = 'A';
709 DISK_EXTENT DiskExtent;
710 DWORD Drives = GetLogicalDrives();
711 UINT8 UUID[16];
712 CHAR IsoPath[MAX_PATH];
713
714 Log("Logical Drives=0x%x Path:<%s>", Drives, param->vtoy_img_path);
715
716 while (Drives)
717 {
718 if (Drives & 0x01)
719 {
720 sprintf_s(IsoPath, sizeof(IsoPath), "%C:\\%s", Letter, param->vtoy_img_path);
721 if (IsPathExist(FALSE, "%s", IsoPath))
722 {
723 Log("File exist under %C:", Letter);
724 if (GetPhyDiskUUID(Letter, UUID, &DiskExtent) == 0)
725 {
726 if (memcmp(UUID, param->vtoy_disk_guid, 16) == 0)
727 {
728 Log("Disk UUID match");
729 break;
730 }
731 }
732 }
733 else
734 {
735 Log("File NOT exist under %C:", Letter);
736 }
737 }
738
739 Drives >>= 1;
740 Letter++;
741 }
742
743 if (Drives == 0)
744 {
745 Log("Failed to find ISO file");
746 return 1;
747 }
748
749 Log("Find ISO file <%s>", IsoPath);
750
751 rc = MountIsoFile(IsoPath, DiskExtent.DiskNumber);
752 Log("Mount ISO FILE: %s", rc == 0 ? "SUCCESS" : "FAILED");
753
754 // for protect
755 rc = DeleteVentoyPart2MountPoint(DiskExtent.DiskNumber);
756 Log("Delete ventoy mountpoint: %s", rc == 0 ? "SUCCESS" : "NO NEED");
757
758 return 0;
759 }
760
761 const char * GetFileNameInPath(const char *fullpath)
762 {
763 int i;
764 const char *pos = NULL;
765
766 if (strstr(fullpath, ":"))
767 {
768 for (i = (int)strlen(fullpath); i > 0; i--)
769 {
770 if (fullpath[i - 1] == '/' || fullpath[i - 1] == '\\')
771 {
772 return fullpath + i;
773 }
774 }
775 }
776
777 return fullpath;
778 }
779
780 int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile)
781 {
782 int rc = 1;
783 DWORD Pos;
784 DWORD PeStart;
785 DWORD FileSize;
786 BYTE *Buffer = NULL;
787 ventoy_os_param os_param;
788 CHAR ExeFileName[MAX_PATH];
789
790 sprintf_s(ExeFileName, sizeof(ExeFileName), "%s", argv[0]);
791 if (!IsPathExist(FALSE, "%s", ExeFileName))
792 {
793 Log("File %s NOT exist, now try %s.exe", ExeFileName, ExeFileName);
794 sprintf_s(ExeFileName, sizeof(ExeFileName), "%s.exe", argv[0]);
795
796 Log("File %s exist ? %s", ExeFileName, IsPathExist(FALSE, "%s", ExeFileName) ? "YES" : "NO");
797 }
798
799 if (ReadWholeFile2Buf(ExeFileName, (void **)&Buffer, &FileSize))
800 {
801 goto End;
802 }
803
804 g_64bit_system = IsPe64(Buffer);
805
806 if (!IsPathExist(TRUE, "ventoy"))
807 {
808 if (!CreateDirectoryA("ventoy", NULL))
809 {
810 Log("Failed to create ventoy directory err:%u", GetLastError());
811 goto End;
812 }
813 }
814
815 for (PeStart = 0; PeStart < FileSize; PeStart += 16)
816 {
817 if (CheckOsParam((ventoy_os_param *)(Buffer + PeStart)) &&
818 CheckPeHead(Buffer + PeStart + sizeof(ventoy_os_param)))
819 {
820 Log("Find os pararm at %u", PeStart);
821 memcpy(&os_param, Buffer + PeStart, sizeof(ventoy_os_param));
822
823 memcpy(g_os_param_reserved, os_param.vtoy_reserved, sizeof(g_os_param_reserved));
824
825 if (g_os_param_reserved[0] == 1)
826 {
827 Log("break here for debug .....");
828 goto End;
829 }
830
831 // convert / to \\
832 for (Pos = 0; Pos < sizeof(os_param.vtoy_img_path) && os_param.vtoy_img_path[Pos]; Pos++)
833 {
834 if (os_param.vtoy_img_path[Pos] == '/')
835 {
836 os_param.vtoy_img_path[Pos] = '\\';
837 }
838 }
839
840 PeStart += sizeof(ventoy_os_param);
841 sprintf_s(LunchFile, MAX_PATH, "ventoy\\%s", GetFileNameInPath(ExeFileName));
842 SaveBuffer2File(LunchFile, Buffer + PeStart, FileSize - PeStart);
843 break;
844 }
845 }
846
847 if (PeStart >= FileSize)
848 {
849 Log("OS param not found");
850 goto End;
851 }
852
853 if (g_os_param_reserved[0] == 2)
854 {
855 Log("skip hook for debug .....");
856 rc = 0;
857 goto End;
858 }
859
860 rc = VentoyHook(&os_param);
861
862 End:
863
864 if (Buffer)
865 {
866 free(Buffer);
867 }
868
869 return rc;
870 }
871
872 int main(int argc, char **argv)
873 {
874 int i = 0;
875 int rc = 0;
876 CHAR *Pos = NULL;
877 CHAR CurDir[MAX_PATH];
878 CHAR LunchFile[MAX_PATH];
879 STARTUPINFOA Si;
880 PROCESS_INFORMATION Pi;
881
882 if (argv[0] && argv[0][0] && argv[0][1] == ':')
883 {
884 GetCurrentDirectoryA(sizeof(CurDir), CurDir);
885
886 strcpy_s(LunchFile, sizeof(LunchFile), argv[0]);
887 Pos = (char *)GetFileNameInPath(LunchFile);
888
889 strcat_s(CurDir, sizeof(CurDir), "\\");
890 strcat_s(CurDir, sizeof(CurDir), Pos);
891
892 if (_stricmp(argv[0], CurDir) != 0)
893 {
894 *Pos = 0;
895 SetCurrentDirectoryA(LunchFile);
896 }
897 }
898
899 Log("######## VentoyJump ##########");
900 Log("argc = %d argv[0] = <%s>", argc, argv[0]);
901
902 if (Pos && *Pos == 0)
903 {
904 Log("Old current directory = <%s>", CurDir);
905 Log("New current directory = <%s>", LunchFile);
906 }
907 else
908 {
909 GetCurrentDirectoryA(sizeof(CurDir), CurDir);
910 Log("Current directory = <%s>", CurDir);
911 }
912
913 GetStartupInfoA(&Si);
914
915 for (i = 0; i < 10; i++)
916 {
917 Log("VentoyJump loop %d", i + 1);
918
919 memset(LunchFile, 0, sizeof(LunchFile));
920 rc = VentoyJump(argc, argv, LunchFile);
921
922 if (g_os_param_reserved[0] == 3)
923 {
924 Log("Open log for debug ...");
925 sprintf_s(LunchFile, sizeof(LunchFile), "%s", "notepad.exe ventoy.log");
926 break;
927 }
928 else if (rc == 0)
929 {
930 Log("Ventoy jump success ...");
931 Si.dwFlags |= STARTF_USESHOWWINDOW;
932 Si.wShowWindow = SW_HIDE;
933 break;
934 }
935 else
936 {
937 Log("Ventoy jump fail, now wait ...");
938 sprintf_s(LunchFile, sizeof(LunchFile), "%s", "cmd.exe");
939 Sleep(3000);
940 }
941 }
942
943 CreateProcessA(NULL, LunchFile, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
944 WaitForSingleObject(Pi.hProcess, INFINITE);
945
946 return 0;
947 }