1 /******************************************************************************
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
5 * Copyright (c) 2011-2020, Pete Batard <pete@akeo.ie>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
29 #include "Ventoy2Disk.h"
30 #include "fat_filelib.h"
32 #include "DiskService.h"
34 static DWORD
GetVentoyVolumeName(int PhyDrive
, UINT64 StartSectorId
, CHAR
*NameBuf
, UINT32 BufLen
, BOOL DelSlash
)
42 DWORD Status
= ERROR_NOT_FOUND
;
43 DISK_EXTENT
*pExtents
= NULL
;
44 CHAR VolumeName
[MAX_PATH
] = { 0 };
45 VOLUME_DISK_EXTENTS DiskExtents
;
47 PartOffset
= 512ULL * StartSectorId
;
49 Log("GetVentoyVolumeName PhyDrive %d SectorStart:%llu PartOffset:%llu", PhyDrive
, (ULONGLONG
)StartSectorId
, (ULONGLONG
)PartOffset
);
51 hVolume
= FindFirstVolumeA(VolumeName
, sizeof(VolumeName
));
52 if (hVolume
== INVALID_HANDLE_VALUE
)
59 len
= strlen(VolumeName
);
60 Log("Find volume:%s", VolumeName
);
62 VolumeName
[len
- 1] = 0;
64 hDrive
= CreateFileA(VolumeName
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
65 if (hDrive
== INVALID_HANDLE_VALUE
)
70 bRet
= DeviceIoControl(hDrive
,
71 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
,
75 (DWORD
)(sizeof(DiskExtents
)),
79 Log("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS bRet:%u code:%u", bRet
, LASTERR
);
80 Log("NumberOfDiskExtents:%u DiskNumber:%u", DiskExtents
.NumberOfDiskExtents
, DiskExtents
.Extents
[0].DiskNumber
);
82 if (bRet
&& DiskExtents
.NumberOfDiskExtents
== 1)
84 pExtents
= DiskExtents
.Extents
;
86 Log("This volume DiskNumber:%u offset:%llu", pExtents
->DiskNumber
, (ULONGLONG
)pExtents
->StartingOffset
.QuadPart
);
87 if ((int)pExtents
->DiskNumber
== PhyDrive
&& pExtents
->StartingOffset
.QuadPart
== PartOffset
)
89 Log("This volume match");
93 VolumeName
[len
- 1] = '\\';
96 sprintf_s(NameBuf
, BufLen
, "%s", VolumeName
);
97 Status
= ERROR_SUCCESS
;
104 } while (FindNextVolumeA(hVolume
, VolumeName
, sizeof(VolumeName
)));
106 FindVolumeClose(hVolume
);
108 Log("GetVentoyVolumeName return %u", Status
);
112 static int GetLettersBelongPhyDrive(int PhyDrive
, char *DriveLetters
, size_t Length
)
117 CHAR
*StringBuf
= NULL
;
119 DataSize
= GetLogicalDriveStringsA(0, NULL
);
120 StringBuf
= (CHAR
*)malloc(DataSize
+ 1);
121 if (StringBuf
== NULL
)
126 GetLogicalDriveStringsA(DataSize
, StringBuf
);
128 for (Pos
= StringBuf
; *Pos
; Pos
+= strlen(Pos
) + 1)
130 if (n
< (int)Length
&& PhyDrive
== GetPhyDriveByLogicalDrive(Pos
[0]))
132 Log("%C: is belong to phydrive%d", Pos
[0], PhyDrive
);
133 DriveLetters
[n
++] = Pos
[0];
141 static HANDLE
GetPhysicalHandle(int Drive
, BOOLEAN bLockDrive
, BOOLEAN bWriteAccess
, BOOLEAN bWriteShare
)
147 HANDLE hDrive
= INVALID_HANDLE_VALUE
;
149 CHAR DevPath
[MAX_PATH
] = { 0 };
151 safe_sprintf(PhyDrive
, "\\\\.\\PhysicalDrive%d", Drive
);
153 if (0 == QueryDosDeviceA(PhyDrive
+ 4, DevPath
, sizeof(DevPath
)))
155 Log("QueryDosDeviceA failed error:%u", GetLastError());
156 strcpy_s(DevPath
, sizeof(DevPath
), "???");
160 Log("QueryDosDeviceA success %s", DevPath
);
163 for (i
= 0; i
< DRIVE_ACCESS_RETRIES
; i
++)
165 // Try without FILE_SHARE_WRITE (unless specifically requested) so that
166 // we won't be bothered by the OS or other apps when we set up our data.
167 // However this means we might have to wait for an access gap...
168 // We keep FILE_SHARE_READ though, as this shouldn't hurt us any, and is
169 // required for enumeration.
170 hDrive
= CreateFileA(PhyDrive
,
171 GENERIC_READ
| (bWriteAccess
? GENERIC_WRITE
: 0),
172 FILE_SHARE_READ
| (bWriteShare
? FILE_SHARE_WRITE
: 0),
175 FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_NO_BUFFERING
| FILE_FLAG_WRITE_THROUGH
,
178 LastError
= GetLastError();
179 Log("[%d] CreateFileA %s code:%u %p", i
, PhyDrive
, LastError
, hDrive
);
181 if (hDrive
!= INVALID_HANDLE_VALUE
)
186 if ((LastError
!= ERROR_SHARING_VIOLATION
) && (LastError
!= ERROR_ACCESS_DENIED
))
193 Log("Waiting for access on %s [%s]...", PhyDrive
, DevPath
);
195 else if (!bWriteShare
&& (i
> DRIVE_ACCESS_RETRIES
/ 3))
197 // If we can't seem to get a hold of the drive for some time, try to enable FILE_SHARE_WRITE...
198 Log("Warning: Could not obtain exclusive rights. Retrying with write sharing enabled...");
201 // Try to report the process that is locking the drive
202 // We also use bit 6 as a flag to indicate that SearchProcess was called.
203 //access_mask = SearchProcess(DevPath, SEARCH_PROCESS_TIMEOUT, TRUE, TRUE, FALSE) | 0x40;
206 Sleep(DRIVE_ACCESS_TIMEOUT
/ DRIVE_ACCESS_RETRIES
);
209 if (hDrive
== INVALID_HANDLE_VALUE
)
211 Log("Could not open %s %u", PhyDrive
, LASTERR
);
217 Log("Opened %s for %s write access", PhyDrive
, bWriteShare
? "shared" : "exclusive");
222 if (DeviceIoControl(hDrive
, FSCTL_ALLOW_EXTENDED_DASD_IO
, NULL
, 0, NULL
, 0, &dwSize
, NULL
))
224 Log("I/O boundary checks disabled");
227 EndTime
= GetTickCount64() + DRIVE_ACCESS_TIMEOUT
;
230 if (DeviceIoControl(hDrive
, FSCTL_LOCK_VOLUME
, NULL
, 0, NULL
, 0, &dwSize
, NULL
))
232 Log("FSCTL_LOCK_VOLUME success");
235 Sleep(DRIVE_ACCESS_TIMEOUT
/ DRIVE_ACCESS_RETRIES
);
236 } while (GetTickCount64() < EndTime
);
238 // If we reached this section, either we didn't manage to get a lock or the user cancelled
239 Log("Could not lock access to %s %u", PhyDrive
, LASTERR
);
241 // See if we can report the processes are accessing the drive
242 //if (!IS_ERROR(FormatStatus) && (access_mask == 0))
243 // access_mask = SearchProcess(DevPath, SEARCH_PROCESS_TIMEOUT, TRUE, TRUE, FALSE);
244 // Try to continue if the only access rights we saw were for read-only
245 //if ((access_mask & 0x07) != 0x01)
246 // safe_closehandle(hDrive);
248 CHECK_CLOSE_HANDLE(hDrive
);
253 if (hDrive
== INVALID_HANDLE_VALUE
)
255 Log("Can get handle of %s, maybe some process control it.", DevPath
);
261 int GetPhyDriveByLogicalDrive(int DriveLetter
)
266 VOLUME_DISK_EXTENTS DiskExtents
;
269 safe_sprintf(PhyPath
, "\\\\.\\%C:", (CHAR
)DriveLetter
);
271 Handle
= CreateFileA(PhyPath
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, 0, OPEN_EXISTING
, 0, 0);
272 if (Handle
== INVALID_HANDLE_VALUE
)
274 Log("Could not open the disk<%s>, error:%u", PhyPath
, LASTERR
);
278 Ret
= DeviceIoControl(Handle
,
279 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
,
283 (DWORD
)(sizeof(DiskExtents
)),
287 if (!Ret
|| DiskExtents
.NumberOfDiskExtents
== 0)
289 Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed %s, error:%u", PhyPath
, LASTERR
);
290 CHECK_CLOSE_HANDLE(Handle
);
293 CHECK_CLOSE_HANDLE(Handle
);
295 Log("LogicalDrive:%s PhyDrive:%d Offset:%llu ExtentLength:%llu",
297 DiskExtents
.Extents
[0].DiskNumber
,
298 DiskExtents
.Extents
[0].StartingOffset
.QuadPart
,
299 DiskExtents
.Extents
[0].ExtentLength
.QuadPart
302 return (int)DiskExtents
.Extents
[0].DiskNumber
;
305 int GetAllPhysicalDriveInfo(PHY_DRIVE_INFO
*pDriveList
, DWORD
*pDriveCount
)
313 DWORD DriveCount
= 0;
314 HANDLE Handle
= INVALID_HANDLE_VALUE
;
316 PHY_DRIVE_INFO
*CurDrive
= pDriveList
;
317 GET_LENGTH_INFORMATION LengthInfo
;
318 STORAGE_PROPERTY_QUERY Query
;
319 STORAGE_DESCRIPTOR_HEADER DevDescHeader
;
320 STORAGE_DEVICE_DESCRIPTOR
*pDevDesc
;
321 int PhyDriveId
[VENTOY_MAX_PHY_DRIVE
];
323 Count
= GetPhysicalDriveCount();
325 for (i
= 0; i
< Count
&& i
< VENTOY_MAX_PHY_DRIVE
; i
++)
330 dwBytes
= GetLogicalDrives();
331 Log("Logical Drives: 0x%x", dwBytes
);
336 id
= GetPhyDriveByLogicalDrive(Letter
);
337 Log("%C --> %d", Letter
, id
);
340 for (i
= 0; i
< Count
; i
++)
342 if (PhyDriveId
[i
] == id
)
350 Log("Add phy%d to list", i
);
351 PhyDriveId
[Count
] = id
;
361 for (i
= 0; i
< Count
&& DriveCount
< VENTOY_MAX_PHY_DRIVE
; i
++)
363 CHECK_CLOSE_HANDLE(Handle
);
365 safe_sprintf(PhyDrive
, "\\\\.\\PhysicalDrive%d", PhyDriveId
[i
]);
366 Handle
= CreateFileA(PhyDrive
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
367 Log("Create file Handle:%p %s status:%u", Handle
, PhyDrive
, LASTERR
);
369 if (Handle
== INVALID_HANDLE_VALUE
)
374 bRet
= DeviceIoControl(Handle
,
375 IOCTL_DISK_GET_LENGTH_INFO
, NULL
,
383 Log("DeviceIoControl IOCTL_DISK_GET_LENGTH_INFO failed error:%u", LASTERR
);
387 Log("PHYSICALDRIVE%d size %llu bytes", i
, (ULONGLONG
)LengthInfo
.Length
.QuadPart
);
389 Query
.PropertyId
= StorageDeviceProperty
;
390 Query
.QueryType
= PropertyStandardQuery
;
392 bRet
= DeviceIoControl(Handle
,
393 IOCTL_STORAGE_QUERY_PROPERTY
,
397 sizeof(STORAGE_DESCRIPTOR_HEADER
),
402 Log("DeviceIoControl1 error:%u dwBytes:%u", LASTERR
, dwBytes
);
406 if (DevDescHeader
.Size
< sizeof(STORAGE_DEVICE_DESCRIPTOR
))
408 Log("Invalid DevDescHeader.Size:%u", DevDescHeader
.Size
);
412 pDevDesc
= (STORAGE_DEVICE_DESCRIPTOR
*)malloc(DevDescHeader
.Size
);
415 Log("failed to malloc error:%u len:%u", LASTERR
, DevDescHeader
.Size
);
419 bRet
= DeviceIoControl(Handle
,
420 IOCTL_STORAGE_QUERY_PROPERTY
,
429 Log("DeviceIoControl2 error:%u dwBytes:%u", LASTERR
, dwBytes
);
434 CurDrive
->PhyDrive
= i
;
435 CurDrive
->SizeInBytes
= LengthInfo
.Length
.QuadPart
;
436 CurDrive
->DeviceType
= pDevDesc
->DeviceType
;
437 CurDrive
->RemovableMedia
= pDevDesc
->RemovableMedia
;
438 CurDrive
->BusType
= pDevDesc
->BusType
;
440 if (pDevDesc
->VendorIdOffset
)
442 safe_strcpy(CurDrive
->VendorId
, (char *)pDevDesc
+ pDevDesc
->VendorIdOffset
);
443 TrimString(CurDrive
->VendorId
);
446 if (pDevDesc
->ProductIdOffset
)
448 safe_strcpy(CurDrive
->ProductId
, (char *)pDevDesc
+ pDevDesc
->ProductIdOffset
);
449 TrimString(CurDrive
->ProductId
);
452 if (pDevDesc
->ProductRevisionOffset
)
454 safe_strcpy(CurDrive
->ProductRev
, (char *)pDevDesc
+ pDevDesc
->ProductRevisionOffset
);
455 TrimString(CurDrive
->ProductRev
);
458 if (pDevDesc
->SerialNumberOffset
)
460 safe_strcpy(CurDrive
->SerialNumber
, (char *)pDevDesc
+ pDevDesc
->SerialNumberOffset
);
461 TrimString(CurDrive
->SerialNumber
);
469 CHECK_CLOSE_HANDLE(Handle
);
472 for (i
= 0, CurDrive
= pDriveList
; i
< (int)DriveCount
; i
++, CurDrive
++)
474 Log("PhyDrv:%d BusType:%-4s Removable:%u Size:%dGB(%llu) Name:%s %s",
475 CurDrive
->PhyDrive
, GetBusTypeString(CurDrive
->BusType
), CurDrive
->RemovableMedia
,
476 GetHumanReadableGBSize(CurDrive
->SizeInBytes
), CurDrive
->SizeInBytes
,
477 CurDrive
->VendorId
, CurDrive
->ProductId
);
480 *pDriveCount
= DriveCount
;
486 static HANDLE g_FatPhyDrive
;
487 static UINT64 g_Part2StartSec
;
488 static int GetVentoyVersionFromFatFile(CHAR
*VerBuf
, size_t BufLen
)
495 flfile
= fl_fopen("/grub/grub.cfg", "rb");
498 fl_fseek(flfile
, 0, SEEK_END
);
499 size
= (int)fl_ftell(flfile
);
501 fl_fseek(flfile
, 0, SEEK_SET
);
503 buf
= (char *)malloc(size
+ 1);
506 fl_fread(buf
, 1, size
, flfile
);
510 sprintf_s(VerBuf
, BufLen
, "%s", ParseVentoyVersionFromString(buf
));
520 static int VentoyFatDiskRead(uint32 Sector
, uint8
*Buffer
, uint32 SectorCount
)
525 LARGE_INTEGER liCurrentPosition
;
527 liCurrentPosition
.QuadPart
= Sector
+ g_Part2StartSec
;
528 liCurrentPosition
.QuadPart
*= 512;
529 SetFilePointerEx(g_FatPhyDrive
, liCurrentPosition
, &liCurrentPosition
, FILE_BEGIN
);
531 ReadSize
= (DWORD
)(SectorCount
* 512);
533 bRet
= ReadFile(g_FatPhyDrive
, Buffer
, ReadSize
, &dwSize
, NULL
);
534 if (bRet
== FALSE
|| dwSize
!= ReadSize
)
536 Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u\n", bRet
, ReadSize
, dwSize
, LASTERR
);
543 int GetVentoyVerInPhyDrive(const PHY_DRIVE_INFO
*pDriveInfo
, UINT64 Part2StartSector
, CHAR
*VerBuf
, size_t BufLen
, BOOL
*pSecureBoot
)
549 hDrive
= GetPhysicalHandle(pDriveInfo
->PhyDrive
, FALSE
, FALSE
, FALSE
);
550 if (hDrive
== INVALID_HANDLE_VALUE
)
555 g_FatPhyDrive
= hDrive
;
556 g_Part2StartSec
= Part2StartSector
;
558 Log("Parse FAT fs...");
562 if (0 == fl_attach_media(VentoyFatDiskRead
, NULL
))
564 Log("attach media success...");
565 rc
= GetVentoyVersionFromFatFile(VerBuf
, BufLen
);
569 Log("attach media failed...");
573 Log("GetVentoyVerInPhyDrive rc=%d...", rc
);
576 Log("VentoyVerInPhyDrive %d is <%s>...", pDriveInfo
->PhyDrive
, VerBuf
);
578 flfile
= fl_fopen("/EFI/BOOT/grubx64_real.efi", "rb");
588 CHECK_CLOSE_HANDLE(hDrive
);
597 static unsigned int g_disk_unxz_len
= 0;
598 static BYTE
*g_part_img_pos
= NULL
;
599 static BYTE
*g_part_img_buf
[VENTOY_EFI_PART_SIZE
/ SIZE_1MB
];
602 static int VentoyFatMemRead(uint32 Sector
, uint8
*Buffer
, uint32 SectorCount
)
608 for (i
= 0; i
< SectorCount
; i
++)
610 offset
= (Sector
+ i
) * 512;
612 if (g_part_img_buf
[1] == NULL
)
614 MbBuf
= g_part_img_buf
[0] + offset
;
615 memcpy(Buffer
+ i
* 512, MbBuf
, 512);
619 MbBuf
= g_part_img_buf
[offset
/ SIZE_1MB
];
620 memcpy(Buffer
+ i
* 512, MbBuf
+ (offset
% SIZE_1MB
), 512);
628 static int VentoyFatMemWrite(uint32 Sector
, uint8
*Buffer
, uint32 SectorCount
)
634 for (i
= 0; i
< SectorCount
; i
++)
636 offset
= (Sector
+ i
) * 512;
638 if (g_part_img_buf
[1] == NULL
)
640 MbBuf
= g_part_img_buf
[0] + offset
;
641 memcpy(MbBuf
, Buffer
+ i
* 512, 512);
645 MbBuf
= g_part_img_buf
[offset
/ SIZE_1MB
];
646 memcpy(MbBuf
+ (offset
% SIZE_1MB
), Buffer
+ i
* 512, 512);
653 int VentoyProcSecureBoot(BOOL SecureBoot
)
657 char *filebuf
= NULL
;
660 Log("VentoyProcSecureBoot %d ...", SecureBoot
);
664 Log("Secure boot is enabled ...");
670 if (0 == fl_attach_media(VentoyFatMemRead
, VentoyFatMemWrite
))
672 file
= fl_fopen("/EFI/BOOT/grubx64_real.efi", "rb");
673 Log("Open ventoy efi file %p ", file
);
676 fl_fseek(file
, 0, SEEK_END
);
677 size
= (int)fl_ftell(file
);
678 fl_fseek(file
, 0, SEEK_SET
);
680 Log("ventoy efi file size %d ...", size
);
682 filebuf
= (char *)malloc(size
);
685 fl_fread(filebuf
, 1, size
, file
);
690 Log("Now delete all efi files ...");
691 fl_remove("/EFI/BOOT/BOOTX64.EFI");
692 fl_remove("/EFI/BOOT/grubx64.efi");
693 fl_remove("/EFI/BOOT/grubx64_real.efi");
694 fl_remove("/EFI/BOOT/MokManager.efi");
695 fl_remove("/ENROLL_THIS_KEY_IN_MOKMANAGER.cer");
697 file
= fl_fopen("/EFI/BOOT/BOOTX64.EFI", "wb");
698 Log("Open bootx64 efi file %p ", file
);
703 fl_fwrite(filebuf
, 1, size
, file
);
716 file
= fl_fopen("/EFI/BOOT/grubia32_real.efi", "rb");
717 Log("Open ventoy efi file %p ", file
);
720 fl_fseek(file
, 0, SEEK_END
);
721 size
= (int)fl_ftell(file
);
722 fl_fseek(file
, 0, SEEK_SET
);
724 Log("ventoy efi file size %d ...", size
);
726 filebuf
= (char *)malloc(size
);
729 fl_fread(filebuf
, 1, size
, file
);
734 Log("Now delete all efi files ...");
735 fl_remove("/EFI/BOOT/BOOTIA32.EFI");
736 fl_remove("/EFI/BOOT/grubia32.efi");
737 fl_remove("/EFI/BOOT/grubia32_real.efi");
738 fl_remove("/EFI/BOOT/mmia32.efi");
740 file
= fl_fopen("/EFI/BOOT/BOOTIA32.EFI", "wb");
741 Log("Open bootia32 efi file %p ", file
);
746 fl_fwrite(filebuf
, 1, size
, file
);
772 static int disk_xz_flush(void *src
, unsigned int size
)
775 BYTE
*buf
= (BYTE
*)src
;
777 for (i
= 0; i
< size
; i
++)
779 *g_part_img_pos
= *buf
++;
782 if ((g_disk_unxz_len
% SIZE_1MB
) == 0)
784 g_part_img_pos
= g_part_img_buf
[g_disk_unxz_len
/ SIZE_1MB
];
795 static void unxz_error(char *x
)
800 static BOOL
TryWritePart2(HANDLE hDrive
, UINT64 StartSectorId
)
803 DWORD TrySize
= 16 * 1024;
806 unsigned char *data
= NULL
;
807 LARGE_INTEGER liCurrentPosition
;
809 liCurrentPosition
.QuadPart
= StartSectorId
* 512;
810 SetFilePointerEx(hDrive
, liCurrentPosition
, &liCurrentPosition
, FILE_BEGIN
);
812 Buffer
= malloc(TrySize
);
814 bRet
= WriteFile(hDrive
, Buffer
, TrySize
, &dwSize
, NULL
);
818 Log("Try write part2 bRet:%u dwSize:%u code:%u", bRet
, dwSize
, LASTERR
);
820 if (bRet
&& dwSize
== TrySize
)
828 static int FormatPart2Fat(HANDLE hDrive
, UINT64 StartSectorId
)
835 int Pos
= PT_WRITE_VENTOY_START
;
838 unsigned char *data
= NULL
;
839 LARGE_INTEGER liCurrentPosition
;
840 LARGE_INTEGER liNewPosition
;
841 BYTE
*CheckBuf
= NULL
;
843 Log("FormatPart2Fat %llu...", StartSectorId
);
845 CheckBuf
= malloc(SIZE_1MB
);
848 Log("Failed to malloc check buf");
852 rc
= ReadWholeFileToBuf(VENTOY_FILE_DISK_IMG
, 0, (void **)&data
, &len
);
855 Log("Failed to read img file %p %u", data
, len
);
860 liCurrentPosition
.QuadPart
= StartSectorId
* 512;
861 SetFilePointerEx(hDrive
, liCurrentPosition
, &liNewPosition
, FILE_BEGIN
);
863 memset(g_part_img_buf
, 0, sizeof(g_part_img_buf
));
865 g_part_img_buf
[0] = (BYTE
*)malloc(VENTOY_EFI_PART_SIZE
);
866 if (g_part_img_buf
[0])
868 Log("Malloc whole img buffer success, now decompress ...");
869 unxz(data
, len
, NULL
, NULL
, g_part_img_buf
[0], &writelen
, unxz_error
);
873 Log("decompress finished success");
875 VentoyProcSecureBoot(g_SecureBoot
);
877 for (i
= 0; i
< VENTOY_EFI_PART_SIZE
/ SIZE_1MB
; i
++)
880 bRet
= WriteFile(hDrive
, g_part_img_buf
[0] + i
* SIZE_1MB
, SIZE_1MB
, &dwSize
, NULL
);
881 Log("Write part data bRet:%u dwSize:%u code:%u", bRet
, dwSize
, LASTERR
);
889 PROGRESS_BAR_SET_POS(Pos
);
896 //Read and check the data
897 liCurrentPosition
.QuadPart
= StartSectorId
* 512;
898 SetFilePointerEx(hDrive
, liCurrentPosition
, &liNewPosition
, FILE_BEGIN
);
900 for (i
= 0; i
< VENTOY_EFI_PART_SIZE
/ SIZE_1MB
; i
++)
902 bRet
= ReadFile(hDrive
, CheckBuf
, SIZE_1MB
, &dwSize
, NULL
);
903 Log("Read part data bRet:%u dwSize:%u code:%u", bRet
, dwSize
, LASTERR
);
905 if (!bRet
|| memcmp(CheckBuf
, g_part_img_buf
[0] + i
* SIZE_1MB
, SIZE_1MB
))
907 Log("### [Check Fail] The data write and read does not match");
912 PROGRESS_BAR_SET_POS(Pos
);
922 Log("decompress finished failed");
928 Log("Failed to malloc whole img size %u, now split it", VENTOY_EFI_PART_SIZE
);
931 for (i
= 0; i
< VENTOY_EFI_PART_SIZE
/ SIZE_1MB
; i
++)
933 g_part_img_buf
[i
] = (BYTE
*)malloc(SIZE_1MB
);
934 if (g_part_img_buf
[i
] == NULL
)
941 Log("Malloc part img buffer success, now decompress ...");
943 g_part_img_pos
= g_part_img_buf
[0];
945 unxz(data
, len
, NULL
, disk_xz_flush
, NULL
, NULL
, unxz_error
);
947 if (g_disk_unxz_len
== VENTOY_EFI_PART_SIZE
)
949 Log("decompress finished success");
951 VentoyProcSecureBoot(g_SecureBoot
);
953 for (i
= 0; i
< VENTOY_EFI_PART_SIZE
/ SIZE_1MB
; i
++)
956 bRet
= WriteFile(hDrive
, g_part_img_buf
[i
], SIZE_1MB
, &dwSize
, NULL
);
957 Log("Write part data bRet:%u dwSize:%u code:%u", bRet
, dwSize
, LASTERR
);
965 PROGRESS_BAR_SET_POS(Pos
);
972 //Read and check the data
973 liCurrentPosition
.QuadPart
= StartSectorId
* 512;
974 SetFilePointerEx(hDrive
, liCurrentPosition
, &liNewPosition
, FILE_BEGIN
);
976 for (i
= 0; i
< VENTOY_EFI_PART_SIZE
/ SIZE_1MB
; i
++)
978 bRet
= ReadFile(hDrive
, CheckBuf
, SIZE_1MB
, &dwSize
, NULL
);
979 Log("Read part data bRet:%u dwSize:%u code:%u", bRet
, dwSize
, LASTERR
);
981 if (!bRet
|| memcmp(CheckBuf
, g_part_img_buf
[i
], SIZE_1MB
))
983 Log("### [Check Fail] The data write and read does not match");
988 PROGRESS_BAR_SET_POS(Pos
);
998 Log("decompress finished failed");
1005 if (data
) free(data
);
1006 if (CheckBuf
)free(CheckBuf
);
1010 for (i
= 0; i
< VENTOY_EFI_PART_SIZE
/ SIZE_1MB
; i
++)
1012 if (g_part_img_buf
[i
]) free(g_part_img_buf
[i
]);
1017 if (g_part_img_buf
[0]) free(g_part_img_buf
[0]);
1023 static int WriteGrubStage1ToPhyDrive(HANDLE hDrive
, int PartStyle
)
1029 BYTE
*ImgBuf
= NULL
;
1030 BYTE
*RawBuf
= NULL
;
1032 Log("WriteGrubStage1ToPhyDrive ...");
1034 RawBuf
= (BYTE
*)malloc(SIZE_1MB
);
1040 if (ReadWholeFileToBuf(VENTOY_FILE_STG1_IMG
, 0, (void **)&ImgBuf
, &Len
))
1042 Log("Failed to read stage1 img");
1047 unxz(ImgBuf
, Len
, NULL
, NULL
, RawBuf
, &readLen
, unxz_error
);
1051 Log("Write GPT stage1 ...");
1052 RawBuf
[500] = 35;//update blocklist
1053 SetFilePointer(hDrive
, 512 * 34, NULL
, FILE_BEGIN
);
1054 bRet
= WriteFile(hDrive
, RawBuf
, SIZE_1MB
- 512 * 34, &dwSize
, NULL
);
1058 Log("Write MBR stage1 ...");
1059 SetFilePointer(hDrive
, 512, NULL
, FILE_BEGIN
);
1060 bRet
= WriteFile(hDrive
, RawBuf
, SIZE_1MB
- 512, &dwSize
, NULL
);
1063 Log("WriteFile Ret:%u dwSize:%u ErrCode:%u", bRet
, dwSize
, GetLastError());
1072 static int FormatPart1exFAT(UINT64 DiskSizeBytes
)
1077 Option
.fmt
= FM_EXFAT
;
1082 // < 32GB select 32KB as cluster size
1083 // > 32GB select 128KB as cluster size
1084 if (DiskSizeBytes
/ 1024 / 1024 / 1024 <= 32)
1086 Option
.au_size
= 32768;
1090 Option
.au_size
= 131072;
1093 Log("Formatting Part1 exFAT ...");
1095 Ret
= f_mkfs(TEXT("0:"), &Option
, 0, 8 * 1024 * 1024);
1098 Log("Formatting Part1 exFAT success");
1103 Log("Formatting Part1 exFAT failed");
1110 int ClearVentoyFromPhyDrive(HWND hWnd
, PHY_DRIVE_INFO
*pPhyDrive
, char *pDrvLetter
)
1119 CHAR DriveName
[] = "?:\\";
1120 CHAR DriveLetters
[MAX_PATH
] = { 0 };
1121 LARGE_INTEGER liCurrentPosition
;
1122 char *pTmpBuf
= NULL
;
1127 Log("ClearVentoyFromPhyDrive PhyDrive%d <<%s %s %dGB>>",
1128 pPhyDrive
->PhyDrive
, pPhyDrive
->VendorId
, pPhyDrive
->ProductId
,
1129 GetHumanReadableGBSize(pPhyDrive
->SizeInBytes
));
1131 PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN
);
1133 Log("Lock disk for clean ............................. ");
1135 hDrive
= GetPhysicalHandle(pPhyDrive
->PhyDrive
, TRUE
, FALSE
, FALSE
);
1136 if (hDrive
== INVALID_HANDLE_VALUE
)
1138 Log("Failed to open physical disk");
1142 GetLettersBelongPhyDrive(pPhyDrive
->PhyDrive
, DriveLetters
, sizeof(DriveLetters
));
1144 if (DriveLetters
[0] == 0)
1146 Log("No drive letter was assigned...");
1147 DriveName
[0] = GetFirstUnusedDriveLetter();
1148 Log("GetFirstUnusedDriveLetter %C: ...", DriveName
[0]);
1152 // Unmount all mounted volumes that belong to this drive
1153 // Do it in reverse so that we always end on the first volume letter
1154 for (i
= (int)strlen(DriveLetters
); i
> 0; i
--)
1156 DriveName
[0] = DriveLetters
[i
- 1];
1157 bRet
= DeleteVolumeMountPointA(DriveName
);
1158 Log("Delete mountpoint %s ret:%u code:%u", DriveName
, bRet
, GetLastError());
1162 MountDrive
= DriveName
[0];
1163 Log("Will use '%C:' as volume mountpoint", DriveName
[0]);
1165 // It kind of blows, but we have to relinquish access to the physical drive
1166 // for VDS to be able to delete the partitions that reside on it...
1167 DeviceIoControl(hDrive
, FSCTL_UNLOCK_VOLUME
, NULL
, 0, NULL
, 0, &dwSize
, NULL
);
1168 CHECK_CLOSE_HANDLE(hDrive
);
1170 PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART
);
1172 if (!VDS_DeleteAllPartitions(pPhyDrive
->PhyDrive
))
1174 Log("Notice: Could not delete partitions: %u", GetLastError());
1177 Log("Deleting all partitions ......................... OK");
1179 PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE
);
1181 Log("Lock disk for write ............................. ");
1182 hDrive
= GetPhysicalHandle(pPhyDrive
->PhyDrive
, TRUE
, TRUE
, FALSE
);
1183 if (hDrive
== INVALID_HANDLE_VALUE
)
1185 Log("Failed to GetPhysicalHandle for write.");
1190 // clear first and last 2MB space
1191 pTmpBuf
= malloc(SIZE_2MB
);
1194 Log("Failed to alloc memory.");
1198 memset(pTmpBuf
, 0, SIZE_2MB
);
1201 bRet
= WriteFile(hDrive
, pTmpBuf
, SIZE_2MB
- 512, &dwSize
, NULL
);
1202 Log("Write fisrt 1MB ret:%d size:%u err:%d", bRet
, dwSize
, LASTERR
);
1209 SET_FILE_POS(pPhyDrive
->SizeInBytes
- SIZE_2MB
);
1210 bRet
= WriteFile(hDrive
, pTmpBuf
, SIZE_2MB
, &dwSize
, NULL
);
1211 Log("Write 2nd 1MB ret:%d size:%u err:%d", bRet
, dwSize
, LASTERR
);
1220 if (pPhyDrive
->SizeInBytes
> 2199023255552ULL)
1222 VTOY_GPT_INFO
*pGptInfo
;
1223 VTOY_GPT_HDR BackupHead
;
1224 LARGE_INTEGER liCurrentPosition
;
1226 pGptInfo
= (VTOY_GPT_INFO
*)pTmpBuf
;
1228 VentoyFillWholeGpt(pPhyDrive
->SizeInBytes
, pGptInfo
);
1230 SET_FILE_POS(pPhyDrive
->SizeInBytes
- 512);
1231 VentoyFillBackupGptHead(pGptInfo
, &BackupHead
);
1232 if (!WriteFile(hDrive
, &BackupHead
, sizeof(VTOY_GPT_HDR
), &dwSize
, NULL
))
1235 Log("Write GPT Backup Head Failed, dwSize:%u (%u) ErrCode:%u", dwSize
, sizeof(VTOY_GPT_INFO
), GetLastError());
1239 SET_FILE_POS(pPhyDrive
->SizeInBytes
- 512 * 33);
1240 if (!WriteFile(hDrive
, pGptInfo
->PartTbl
, sizeof(pGptInfo
->PartTbl
), &dwSize
, NULL
))
1243 Log("Write GPT Backup Part Table Failed, dwSize:%u (%u) ErrCode:%u", dwSize
, sizeof(VTOY_GPT_INFO
), GetLastError());
1248 if (!WriteFile(hDrive
, pGptInfo
, sizeof(VTOY_GPT_INFO
), &dwSize
, NULL
))
1251 Log("Write GPT Info Failed, dwSize:%u (%u) ErrCode:%u", dwSize
, sizeof(VTOY_GPT_INFO
), GetLastError());
1255 Log("Write GPT Info OK ...");
1259 bRet
= ReadFile(hDrive
, &MBR
, sizeof(MBR
), &dwSize
, NULL
);
1260 Log("Read MBR ret:%d size:%u err:%d", bRet
, dwSize
, LASTERR
);
1267 //clear boot code and partition table (reserved disk signature)
1268 memset(MBR
.BootCode
, 0, 440);
1269 memset(MBR
.PartTbl
, 0, sizeof(MBR
.PartTbl
));
1271 VentoyFillMBRLocation(pPhyDrive
->SizeInBytes
, 2048, (UINT32
)(pPhyDrive
->SizeInBytes
/ 512 - 2048), MBR
.PartTbl
);
1273 MBR
.PartTbl
[0].Active
= 0x00; // bootable
1274 MBR
.PartTbl
[0].FsFlag
= 0x07; // exFAT/NTFS/HPFS
1277 bRet
= WriteFile(hDrive
, &MBR
, 512, &dwSize
, NULL
);
1278 Log("Write MBR ret:%d size:%u err:%d", bRet
, dwSize
, LASTERR
);
1286 Log("Clear Ventoy successfully finished");
1288 //Refresh Drive Layout
1289 DeviceIoControl(hDrive
, IOCTL_DISK_UPDATE_PROPERTIES
, NULL
, 0, NULL
, 0, &dwSize
, NULL
);
1293 PROGRESS_BAR_SET_POS(PT_MOUNT_VOLUME
);
1302 Log("Mounting Ventoy Partition ....................... ");
1306 memset(DriveLetters
, 0, sizeof(DriveLetters
));
1307 GetLettersBelongPhyDrive(pPhyDrive
->PhyDrive
, DriveLetters
, sizeof(DriveLetters
));
1308 Log("Logical drive letter after write ventoy: <%s>", DriveLetters
);
1310 for (i
= 0; i
< sizeof(DriveLetters
) && DriveLetters
[i
]; i
++)
1312 DriveName
[0] = DriveLetters
[i
];
1313 Log("%s is ventoy part1, already mounted", DriveName
);
1319 Log("need to mount ventoy part1...");
1320 if (0 == GetVentoyVolumeName(pPhyDrive
->PhyDrive
, 2048, DriveLetters
, sizeof(DriveLetters
), FALSE
))
1322 DriveName
[0] = MountDrive
;
1323 bRet
= SetVolumeMountPointA(DriveName
, DriveLetters
);
1324 Log("SetVolumeMountPoint <%s> <%s> bRet:%u code:%u", DriveName
, DriveLetters
, bRet
, GetLastError());
1326 *pDrvLetter
= MountDrive
;
1330 Log("Failed to find ventoy volume");
1338 FindProcessOccupyDisk(hDrive
, pPhyDrive
);
1341 CHECK_CLOSE_HANDLE(hDrive
);
1345 int InstallVentoy2FileImage(PHY_DRIVE_INFO
*pPhyDrive
, int PartStyle
)
1354 UINT64 data_offset
= 0;
1355 UINT64 Part2StartSector
= 0;
1356 UINT64 Part1StartSector
= 0;
1357 UINT64 Part1SectorCount
= 0;
1358 UINT8
*pData
= NULL
;
1359 UINT8
*pBkGptPartTbl
= NULL
;
1360 BYTE
*ImgBuf
= NULL
;
1361 MBR_HEAD
*pMBR
= NULL
;
1362 VTSI_FOOTER
*pImgFooter
= NULL
;
1363 VTSI_SEGMENT
*pSegment
= NULL
;
1364 VTOY_GPT_INFO
*pGptInfo
= NULL
;
1365 VTOY_GPT_HDR
*pBkGptHdr
= NULL
;
1368 Log("InstallVentoy2FileImage %s PhyDrive%d <<%s %s %dGB>>",
1369 PartStyle
? "GPT" : "MBR", pPhyDrive
->PhyDrive
, pPhyDrive
->VendorId
, pPhyDrive
->ProductId
,
1370 GetHumanReadableGBSize(pPhyDrive
->SizeInBytes
));
1372 PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN
);
1374 size
= SIZE_1MB
+ VENTOY_EFI_PART_SIZE
+ 33 * 512 + VTSI_IMG_MAX_SEG
* sizeof(VTSI_SEGMENT
) + sizeof(VTSI_FOOTER
);
1376 pData
= (UINT8
*)malloc(size
);
1379 Log("malloc image buffer failed %d.", size
);
1383 pImgFooter
= (VTSI_FOOTER
*)(pData
+ size
- sizeof(VTSI_FOOTER
));
1384 pSegment
= (VTSI_SEGMENT
*)((UINT8
*)pImgFooter
- VTSI_IMG_MAX_SEG
* sizeof(VTSI_SEGMENT
));
1385 memset(pImgFooter
, 0, sizeof(VTSI_FOOTER
));
1386 memset(pSegment
, 0, VTSI_IMG_MAX_SEG
* sizeof(VTSI_SEGMENT
));
1388 PROGRESS_BAR_SET_POS(PT_WRITE_VENTOY_START
);
1390 Log("Writing Boot Image ............................. ");
1391 if (ReadWholeFileToBuf(VENTOY_FILE_STG1_IMG
, 0, (void **)&ImgBuf
, &Len
))
1393 Log("Failed to read stage1 img");
1397 unxz(ImgBuf
, Len
, NULL
, NULL
, pData
, &dataLen
, unxz_error
);
1400 Log("decompress %s len:%d", VENTOY_FILE_STG1_IMG
, dataLen
);
1404 pData
[500] = 35;//update blocklist
1405 memmove(pData
+ 34 * 512, pData
, SIZE_1MB
- 512 * 34);
1406 memset(pData
, 0, 34 * 512);
1408 pGptInfo
= (VTOY_GPT_INFO
*)pData
;
1409 memset(pGptInfo
, 0, sizeof(VTOY_GPT_INFO
));
1410 VentoyFillGpt(pPhyDrive
->SizeInBytes
, pGptInfo
);
1412 pBkGptPartTbl
= pData
+ SIZE_1MB
+ VENTOY_EFI_PART_SIZE
;
1413 memset(pBkGptPartTbl
, 0, 33 * 512);
1415 memcpy(pBkGptPartTbl
, pGptInfo
->PartTbl
, 32 * 512);
1416 pBkGptHdr
= (VTOY_GPT_HDR
*)(pBkGptPartTbl
+ 32 * 512);
1417 VentoyFillBackupGptHead(pGptInfo
, pBkGptHdr
);
1419 Part1StartSector
= pGptInfo
->PartTbl
[0].StartLBA
;
1420 Part1SectorCount
= pGptInfo
->PartTbl
[0].LastLBA
- Part1StartSector
+ 1;
1421 Part2StartSector
= pGptInfo
->PartTbl
[1].StartLBA
;
1423 Log("Write GPT Info OK ...");
1427 memmove(pData
+ 512, pData
, SIZE_1MB
- 512);
1428 memset(pData
, 0, 512);
1430 pMBR
= (MBR_HEAD
*)pData
;
1431 VentoyFillMBR(pPhyDrive
->SizeInBytes
, pMBR
, PartStyle
);
1432 Part1StartSector
= pMBR
->PartTbl
[0].StartSectorId
;
1433 Part1SectorCount
= pMBR
->PartTbl
[0].SectorCount
;
1434 Part2StartSector
= pMBR
->PartTbl
[1].StartSectorId
;
1436 Log("Write MBR OK ...");
1439 Log("Writing EFI part Image ............................. ");
1440 rc
= ReadWholeFileToBuf(VENTOY_FILE_DISK_IMG
, 0, (void **)&ImgBuf
, &Len
);
1443 Log("Failed to read img file %p %u", ImgBuf
, Len
);
1447 PROGRESS_BAR_SET_POS(PT_WRITE_VENTOY_START
+ 28);
1448 memset(g_part_img_buf
, 0, sizeof(g_part_img_buf
));
1449 unxz(ImgBuf
, Len
, NULL
, NULL
, pData
+ SIZE_1MB
, &dataLen
, unxz_error
);
1452 Log("decompress finished success");
1453 g_part_img_buf
[0] = pData
+ SIZE_1MB
;
1455 VentoyProcSecureBoot(g_SecureBoot
);
1459 Log("decompress finished failed");
1463 fopen_s(&fp
, "VentoySparseImg.vtsi", "wb+");
1466 Log("Failed to create Ventoy img file");
1470 Log("Writing stage1 data ............................. ");
1472 fwrite(pData
, 1, SIZE_1MB
, fp
);
1474 pSegment
[0].disk_start_sector
= 0;
1475 pSegment
[0].sector_num
= SIZE_1MB
/ 512;
1476 pSegment
[0].data_offset
= data_offset
;
1477 data_offset
+= pSegment
[0].sector_num
* 512;
1479 disk_io_set_param(INVALID_HANDLE_VALUE
, Part1StartSector
+ Part1SectorCount
);// include the 2048 sector gap
1480 disk_io_set_imghook(fp
, pSegment
+ 1, VTSI_IMG_MAX_SEG
- 1, data_offset
);
1482 Log("Formatting part1 exFAT ...");
1483 if (0 != FormatPart1exFAT(pPhyDrive
->SizeInBytes
))
1485 Log("FormatPart1exFAT failed.");
1486 disk_io_reset_imghook(&segnum
, &data_offset
);
1490 disk_io_reset_imghook(&segnum
, &data_offset
);
1493 Log("current segment number:%d dataoff:%ld", segnum
, (long)data_offset
);
1496 Log("Writing part2 data ............................. ");
1497 fwrite(pData
+ SIZE_1MB
, 1, VENTOY_EFI_PART_SIZE
, fp
);
1498 pSegment
[segnum
].disk_start_sector
= Part2StartSector
;
1499 pSegment
[segnum
].sector_num
= VENTOY_EFI_PART_SIZE
/ 512;
1500 pSegment
[segnum
].data_offset
= data_offset
;
1501 data_offset
+= pSegment
[segnum
].sector_num
* 512;
1506 Log("Writing backup gpt table ............................. ");
1507 fwrite(pBkGptPartTbl
, 1, 33 * 512, fp
);
1508 pSegment
[segnum
].disk_start_sector
= pPhyDrive
->SizeInBytes
/ 512 - 33;
1509 pSegment
[segnum
].sector_num
= 33;
1510 pSegment
[segnum
].data_offset
= data_offset
;
1511 data_offset
+= pSegment
[segnum
].sector_num
* 512;
1515 Log("Writing segment metadata ............................. ");
1517 for (i
= 0; i
< (int)segnum
; i
++)
1519 Log("SEG[%d]: PhySector:%llu SectorNum:%llu DataOffset:%llu(sector:%llu)", i
, pSegment
[i
].disk_start_sector
, pSegment
[i
].sector_num
,
1520 pSegment
[i
].data_offset
, pSegment
[i
].data_offset
/ 512);
1523 dataLen
= segnum
* sizeof(VTSI_SEGMENT
);
1524 fwrite(pSegment
, 1, dataLen
, fp
);
1528 //pData + SIZE_1MB - 8192 is a temp data buffer with zero
1529 fwrite(pData
+ SIZE_1MB
- 8192, 1, 512 - (dataLen
% 512), fp
);
1533 pImgFooter
->magic
= VTSI_IMG_MAGIC
;
1534 pImgFooter
->version
= 1;
1535 pImgFooter
->disk_size
= pPhyDrive
->SizeInBytes
;
1536 memcpy(&pImgFooter
->disk_signature
, pPhyDrive
->MBR
.BootCode
+ 0x1b8, 4);
1537 pImgFooter
->segment_num
= segnum
;
1538 pImgFooter
->segment_offset
= data_offset
;
1540 for (i
= 0, chksum
= 0; i
< (int)(segnum
* sizeof(VTSI_SEGMENT
)); i
++)
1542 chksum
+= *((UINT8
*)pSegment
+ i
);
1544 pImgFooter
->segment_chksum
= ~chksum
;
1546 for (i
= 0, chksum
= 0; i
< sizeof(VTSI_FOOTER
); i
++)
1548 chksum
+= *((UINT8
*)pImgFooter
+ i
);
1550 pImgFooter
->foot_chksum
= ~chksum
;
1552 Log("Writing footer segnum(%u) segoffset(%llu) ......................", segnum
, data_offset
);
1553 Log("disk_size=%llu disk_signature=%lx segment_offset=%llu", pImgFooter
->disk_size
, pImgFooter
->disk_signature
, pImgFooter
->segment_offset
);
1555 fwrite(pImgFooter
, 1, sizeof(VTSI_FOOTER
), fp
);
1558 Log("Writing Ventoy image file finished, the file size should be %llu .", data_offset
+ 512 + ((dataLen
+ 511) / 512 * 512));
1564 PROGRESS_BAR_SET_POS(PT_MOUNT_VOLUME
);
1566 Log("retcode:%d\n", rc
);
1575 int InstallVentoy2PhyDrive(PHY_DRIVE_INFO
*pPhyDrive
, int PartStyle
, int TryId
)
1584 CHAR DriveName
[] = "?:\\";
1585 CHAR DriveLetters
[MAX_PATH
] = { 0 };
1587 VTOY_GPT_INFO
*pGptInfo
= NULL
;
1588 UINT64 Part1StartSector
= 0;
1589 UINT64 Part1SectorCount
= 0;
1590 UINT64 Part2StartSector
= 0;
1592 Log("InstallVentoy2PhyDrive try%d %s PhyDrive%d <<%s %s %dGB>>", TryId
,
1593 PartStyle
? "GPT" : "MBR", pPhyDrive
->PhyDrive
, pPhyDrive
->VendorId
, pPhyDrive
->ProductId
,
1594 GetHumanReadableGBSize(pPhyDrive
->SizeInBytes
));
1598 pGptInfo
= malloc(sizeof(VTOY_GPT_INFO
));
1599 memset(pGptInfo
, 0, sizeof(VTOY_GPT_INFO
));
1602 PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN
);
1606 VentoyFillGpt(pPhyDrive
->SizeInBytes
, pGptInfo
);
1607 Part1StartSector
= pGptInfo
->PartTbl
[0].StartLBA
;
1608 Part1SectorCount
= pGptInfo
->PartTbl
[0].LastLBA
- Part1StartSector
+ 1;
1609 Part2StartSector
= pGptInfo
->PartTbl
[1].StartLBA
;
1613 VentoyFillMBR(pPhyDrive
->SizeInBytes
, &MBR
, PartStyle
);
1614 Part1StartSector
= MBR
.PartTbl
[0].StartSectorId
;
1615 Part1SectorCount
= MBR
.PartTbl
[0].SectorCount
;
1616 Part2StartSector
= MBR
.PartTbl
[1].StartSectorId
;
1619 Log("Lock disk for clean ............................. ");
1621 hDrive
= GetPhysicalHandle(pPhyDrive
->PhyDrive
, TRUE
, FALSE
, FALSE
);
1622 if (hDrive
== INVALID_HANDLE_VALUE
)
1624 Log("Failed to open physical disk");
1629 GetLettersBelongPhyDrive(pPhyDrive
->PhyDrive
, DriveLetters
, sizeof(DriveLetters
));
1631 if (DriveLetters
[0] == 0)
1633 Log("No drive letter was assigned...");
1634 DriveName
[0] = GetFirstUnusedDriveLetter();
1635 Log("GetFirstUnusedDriveLetter %C: ...", DriveName
[0]);
1639 // Unmount all mounted volumes that belong to this drive
1640 // Do it in reverse so that we always end on the first volume letter
1641 for (i
= (int)strlen(DriveLetters
); i
> 0; i
--)
1643 DriveName
[0] = DriveLetters
[i
- 1];
1644 bRet
= DeleteVolumeMountPointA(DriveName
);
1645 Log("Delete mountpoint %s ret:%u code:%u", DriveName
, bRet
, GetLastError());
1649 MountDrive
= DriveName
[0];
1650 Log("Will use '%C:' as volume mountpoint", DriveName
[0]);
1652 // It kind of blows, but we have to relinquish access to the physical drive
1653 // for VDS to be able to delete the partitions that reside on it...
1654 DeviceIoControl(hDrive
, FSCTL_UNLOCK_VOLUME
, NULL
, 0, NULL
, 0, &dwSize
, NULL
);
1655 CHECK_CLOSE_HANDLE(hDrive
);
1657 PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART
);
1659 if (!VDS_DeleteAllPartitions(pPhyDrive
->PhyDrive
))
1661 Log("Notice: Could not delete partitions: 0x%x", GetLastError());
1666 Log("Deleting all partitions ......................... OK");
1668 PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE
);
1670 Log("Lock disk for write ............................. ");
1671 hDrive
= GetPhysicalHandle(pPhyDrive
->PhyDrive
, TRUE
, TRUE
, FALSE
);
1672 if (hDrive
== INVALID_HANDLE_VALUE
)
1674 Log("Failed to GetPhysicalHandle for write.");
1679 //Refresh Drive Layout
1680 DeviceIoControl(hDrive
, IOCTL_DISK_UPDATE_PROPERTIES
, NULL
, 0, NULL
, 0, &dwSize
, NULL
);
1682 disk_io_set_param(hDrive
, Part1StartSector
+ Part1SectorCount
);// include the 2048 sector gap
1684 PROGRESS_BAR_SET_POS(PT_FORMAT_PART1
);
1686 if (PartStyle
== 1 && pPhyDrive
->PartStyle
== 0)
1688 Log("Wait for format part1 ...");
1692 Log("Formatting part1 exFAT ...");
1693 if (0 != FormatPart1exFAT(pPhyDrive
->SizeInBytes
))
1695 Log("FormatPart1exFAT failed.");
1700 PROGRESS_BAR_SET_POS(PT_FORMAT_PART2
);
1701 Log("Writing part2 FAT img ...");
1703 if (0 != FormatPart2Fat(hDrive
, Part2StartSector
))
1705 Log("FormatPart2Fat failed.");
1710 PROGRESS_BAR_SET_POS(PT_WRITE_STG1_IMG
);
1711 Log("Writing Boot Image ............................. ");
1712 if (WriteGrubStage1ToPhyDrive(hDrive
, PartStyle
) != 0)
1714 Log("WriteGrubStage1ToPhyDrive failed.");
1719 PROGRESS_BAR_SET_POS(PT_WRITE_PART_TABLE
);
1720 Log("Writing Partition Table ........................ ");
1721 SetFilePointer(hDrive
, 0, NULL
, FILE_BEGIN
);
1725 VTOY_GPT_HDR BackupHead
;
1726 LARGE_INTEGER liCurrentPosition
;
1728 SET_FILE_POS(pPhyDrive
->SizeInBytes
- 512);
1729 VentoyFillBackupGptHead(pGptInfo
, &BackupHead
);
1730 if (!WriteFile(hDrive
, &BackupHead
, sizeof(VTOY_GPT_HDR
), &dwSize
, NULL
))
1733 Log("Write GPT Backup Head Failed, dwSize:%u (%u) ErrCode:%u", dwSize
, sizeof(VTOY_GPT_INFO
), GetLastError());
1737 SET_FILE_POS(pPhyDrive
->SizeInBytes
- 512 * 33);
1738 if (!WriteFile(hDrive
, pGptInfo
->PartTbl
, sizeof(pGptInfo
->PartTbl
), &dwSize
, NULL
))
1741 Log("Write GPT Backup Part Table Failed, dwSize:%u (%u) ErrCode:%u", dwSize
, sizeof(VTOY_GPT_INFO
), GetLastError());
1746 if (!WriteFile(hDrive
, pGptInfo
, sizeof(VTOY_GPT_INFO
), &dwSize
, NULL
))
1749 Log("Write GPT Info Failed, dwSize:%u (%u) ErrCode:%u", dwSize
, sizeof(VTOY_GPT_INFO
), GetLastError());
1753 Log("Write GPT Info OK ...");
1754 memcpy(&(pPhyDrive
->MBR
), &(pGptInfo
->MBR
), 512);
1758 if (!WriteFile(hDrive
, &MBR
, sizeof(MBR
), &dwSize
, NULL
))
1761 Log("Write MBR Failed, dwSize:%u ErrCode:%u", dwSize
, GetLastError());
1764 Log("Write MBR OK ...");
1765 memcpy(&(pPhyDrive
->MBR
), &MBR
, 512);
1768 //Refresh Drive Layout
1769 DeviceIoControl(hDrive
, IOCTL_DISK_UPDATE_PROPERTIES
, NULL
, 0, NULL
, 0, &dwSize
, NULL
);
1773 PROGRESS_BAR_SET_POS(PT_MOUNT_VOLUME
);
1777 Log("Mounting Ventoy Partition ....................... ");
1781 memset(DriveLetters
, 0, sizeof(DriveLetters
));
1782 GetLettersBelongPhyDrive(pPhyDrive
->PhyDrive
, DriveLetters
, sizeof(DriveLetters
));
1783 Log("Logical drive letter after write ventoy: <%s>", DriveLetters
);
1785 for (i
= 0; i
< sizeof(DriveLetters
) && DriveLetters
[i
]; i
++)
1787 DriveName
[0] = DriveLetters
[i
];
1788 if (IsVentoyLogicalDrive(DriveName
[0]))
1790 Log("%s is ventoy part2, delete mountpoint", DriveName
);
1791 DeleteVolumeMountPointA(DriveName
);
1795 Log("%s is ventoy part1, already mounted", DriveName
);
1802 Log("need to mount ventoy part1...");
1804 if (0 == GetVentoyVolumeName(pPhyDrive
->PhyDrive
, Part1StartSector
, DriveLetters
, sizeof(DriveLetters
), FALSE
))
1806 DriveName
[0] = MountDrive
;
1807 bRet
= SetVolumeMountPointA(DriveName
, DriveLetters
);
1808 Log("SetVolumeMountPoint <%s> <%s> bRet:%u code:%u", DriveName
, DriveLetters
, bRet
, GetLastError());
1812 Log("Failed to find ventoy volume");
1819 FindProcessOccupyDisk(hDrive
, pPhyDrive
);
1827 CHECK_CLOSE_HANDLE(hDrive
);
1831 static BOOL
BackupDataBeforeCleanDisk(int PhyDrive
, UINT64 DiskSize
, BYTE
**pBackup
)
1835 BOOL Return
= FALSE
;
1837 BYTE
*backup
= NULL
;
1838 HANDLE hDrive
= INVALID_HANDLE_VALUE
;
1839 LARGE_INTEGER liCurPosition
;
1840 LARGE_INTEGER liNewPosition
;
1842 Log("BackupDataBeforeCleanDisk %d", PhyDrive
);
1844 backup
= malloc(SIZE_1MB
* 3);
1850 hDrive
= GetPhysicalHandle(PhyDrive
, FALSE
, FALSE
, FALSE
);
1851 if (hDrive
== INVALID_HANDLE_VALUE
)
1857 dwStatus
= SetFilePointer(hDrive
, 0, NULL
, FILE_BEGIN
);
1864 ret
= ReadFile(hDrive
, backup
, SIZE_1MB
, &dwSize
, NULL
);
1865 if ((!ret
) || (dwSize
!= SIZE_1MB
))
1867 Log("Failed to read %d %u 0x%x", ret
, dwSize
, LASTERR
);
1871 liCurPosition
.QuadPart
= DiskSize
- (SIZE_1MB
* 2);
1872 liNewPosition
.QuadPart
= 0;
1873 if (0 == SetFilePointerEx(hDrive
, liCurPosition
, &liNewPosition
, FILE_BEGIN
) ||
1874 liNewPosition
.QuadPart
!= liCurPosition
.QuadPart
)
1880 ret
= ReadFile(hDrive
, backup
+ SIZE_1MB
, 2 * SIZE_1MB
, &dwSize
, NULL
);
1881 if ((!ret
) || (dwSize
!= 2 * SIZE_1MB
))
1883 Log("Failed to read %d %u 0x%x", ret
, dwSize
, LASTERR
);
1888 backup
= NULL
; //For don't free later
1892 CHECK_CLOSE_HANDLE(hDrive
);
1900 static BOOL
WriteBackupDataToDisk(HANDLE hDrive
, UINT64 Offset
, BYTE
*Data
, DWORD Length
)
1904 LARGE_INTEGER liCurPosition
;
1905 LARGE_INTEGER liNewPosition
;
1907 Log("WriteBackupDataToDisk %llu %p %u", Offset
, Data
, Length
);
1909 liCurPosition
.QuadPart
= Offset
;
1910 liNewPosition
.QuadPart
= 0;
1911 if (0 == SetFilePointerEx(hDrive
, liCurPosition
, &liNewPosition
, FILE_BEGIN
) ||
1912 liNewPosition
.QuadPart
!= liCurPosition
.QuadPart
)
1917 ret
= WriteFile(hDrive
, Data
, Length
, &dwSize
, NULL
);
1918 if ((!ret
) || dwSize
!= Length
)
1920 Log("Failed to write %d %u %u", ret
, dwSize
, LASTERR
);
1924 Log("WriteBackupDataToDisk %llu %p %u success", Offset
, Data
, Length
);
1929 int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO
*pPhyDrive
, int TryId
)
1934 BOOL ForceMBR
= FALSE
;
1935 BOOL Esp2Basic
= FALSE
;
1936 BOOL ChangeAttr
= FALSE
;
1937 BOOL CleanDisk
= FALSE
;
1943 CHAR DriveName
[] = "?:\\";
1944 CHAR DriveLetters
[MAX_PATH
] = { 0 };
1946 UINT64 ReservedMB
= 0;
1949 BYTE
*pBackup
= NULL
;
1950 VTOY_GPT_INFO
*pGptInfo
= NULL
;
1951 UINT8 ReservedData
[4096];
1953 Log("UpdateVentoy2PhyDrive try%d %s PhyDrive%d <<%s %s %dGB>>", TryId
,
1954 pPhyDrive
->PartStyle
? "GPT" : "MBR", pPhyDrive
->PhyDrive
, pPhyDrive
->VendorId
, pPhyDrive
->ProductId
,
1955 GetHumanReadableGBSize(pPhyDrive
->SizeInBytes
));
1957 PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN
);
1959 Log("Lock disk for umount ............................ ");
1961 hDrive
= GetPhysicalHandle(pPhyDrive
->PhyDrive
, TRUE
, FALSE
, FALSE
);
1962 if (hDrive
== INVALID_HANDLE_VALUE
)
1964 Log("Failed to open physical disk");
1968 if (pPhyDrive
->PartStyle
)
1970 pGptInfo
= malloc(sizeof(VTOY_GPT_INFO
));
1976 memset(pGptInfo
, 0, sizeof(VTOY_GPT_INFO
));
1979 SetFilePointer(hDrive
, 0, NULL
, FILE_BEGIN
);
1980 ReadFile(hDrive
, pGptInfo
, sizeof(VTOY_GPT_INFO
), &dwSize
, NULL
);
1982 //MBR will be used to compare with local boot image
1983 memcpy(&MBR
, &pGptInfo
->MBR
, sizeof(MBR_HEAD
));
1985 StartSector
= pGptInfo
->PartTbl
[1].StartLBA
;
1986 Log("GPT StartSector in PartTbl:%llu", (ULONGLONG
)StartSector
);
1988 ReservedMB
= (pPhyDrive
->SizeInBytes
/ 512 - (StartSector
+ VENTOY_EFI_PART_SIZE
/ 512) - 33) / 2048;
1989 Log("GPT Reserved Disk Space:%llu MB", (ULONGLONG
)ReservedMB
);
1994 SetFilePointer(hDrive
, 0, NULL
, FILE_BEGIN
);
1995 ReadFile(hDrive
, &MBR
, sizeof(MBR
), &dwSize
, NULL
);
1997 StartSector
= MBR
.PartTbl
[1].StartSectorId
;
1998 Log("MBR StartSector in PartTbl:%llu", (ULONGLONG
)StartSector
);
2000 ReservedMB
= (pPhyDrive
->SizeInBytes
/ 512 - (StartSector
+ VENTOY_EFI_PART_SIZE
/ 512)) / 2048;
2001 Log("MBR Reserved Disk Space:%llu MB", (ULONGLONG
)ReservedMB
);
2004 //Read Reserved Data
2005 SetFilePointer(hDrive
, 512 * 2040, NULL
, FILE_BEGIN
);
2006 ReadFile(hDrive
, ReservedData
, sizeof(ReservedData
), &dwSize
, NULL
);
2008 GetLettersBelongPhyDrive(pPhyDrive
->PhyDrive
, DriveLetters
, sizeof(DriveLetters
));
2010 if (DriveLetters
[0] == 0)
2012 Log("No drive letter was assigned...");
2016 // Unmount all mounted volumes that belong to this drive
2017 // Do it in reverse so that we always end on the first volume letter
2018 for (i
= (int)strlen(DriveLetters
); i
> 0; i
--)
2020 DriveName
[0] = DriveLetters
[i
- 1];
2021 if (IsVentoyLogicalDrive(DriveName
[0]))
2023 Log("%s is ventoy logical drive", DriveName
);
2024 bRet
= DeleteVolumeMountPointA(DriveName
);
2025 Log("Delete mountpoint %s ret:%u code:%u", DriveName
, bRet
, LASTERR
);
2031 // It kind of blows, but we have to relinquish access to the physical drive
2032 // for VDS to be able to delete the partitions that reside on it...
2033 DeviceIoControl(hDrive
, FSCTL_UNLOCK_VOLUME
, NULL
, 0, NULL
, 0, &dwSize
, NULL
);
2034 CHECK_CLOSE_HANDLE(hDrive
);
2036 if (pPhyDrive
->PartStyle
== 1)
2038 Log("TryId=%d EFI GPT partition type is 0x%llx", TryId
, pPhyDrive
->Part2GPTAttr
);
2039 PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART
);
2043 Log("Change GPT partition type to ESP");
2044 if (VDS_ChangeVtoyEFI2ESP(pPhyDrive
->PhyDrive
, StartSector
* 512))
2050 else if (TryId
== 2)
2052 Log("Change GPT partition attribute");
2053 if (VDS_ChangeVtoyEFIAttr(pPhyDrive
->PhyDrive
, 0x8000000000000001))
2059 else if (TryId
== 3)
2061 Log("Clean disk GPT partition table");
2062 if (BackupDataBeforeCleanDisk(pPhyDrive
->PhyDrive
, pPhyDrive
->SizeInBytes
, &pBackup
))
2064 Log("Success to backup data before clean");
2066 VDS_CleanDisk(pPhyDrive
->PhyDrive
);
2071 Log("Failed to backup data before clean");
2076 PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE
);
2078 Log("Lock disk for update ............................ ");
2079 hDrive
= GetPhysicalHandle(pPhyDrive
->PhyDrive
, TRUE
, TRUE
, FALSE
);
2080 if (hDrive
== INVALID_HANDLE_VALUE
)
2082 Log("Failed to GetPhysicalHandle for write.");
2087 PROGRESS_BAR_SET_POS(PT_LOCK_VOLUME
);
2089 Log("Lock volume for update .......................... ");
2090 hVolume
= INVALID_HANDLE_VALUE
;
2092 //If we change VTOYEFI to ESP, it can not have s volume name, so don't try to get it.
2095 WriteBackupDataToDisk(hDrive
, pPhyDrive
->SizeInBytes
- (2 * SIZE_1MB
), pBackup
+ SIZE_1MB
, 2 * SIZE_1MB
);
2096 Status
= ERROR_NOT_FOUND
;
2100 Status
= ERROR_NOT_FOUND
;
2104 for (i
= 0; i
< MaxRetry
; i
++)
2106 Status
= GetVentoyVolumeName(pPhyDrive
->PhyDrive
, StartSector
, DriveLetters
, sizeof(DriveLetters
), TRUE
);
2107 if (ERROR_SUCCESS
== Status
)
2113 Log("==== Volume not found, wait and retry %d... ====", i
);
2119 if (ERROR_SUCCESS
== Status
)
2121 Log("Now lock and dismount volume <%s>", DriveLetters
);
2123 for (i
= 0; i
< MaxRetry
; i
++)
2125 hVolume
= CreateFileA(DriveLetters
,
2126 GENERIC_READ
| GENERIC_WRITE
,
2130 FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_NO_BUFFERING
| FILE_FLAG_WRITE_THROUGH
,
2133 if (hVolume
== INVALID_HANDLE_VALUE
)
2135 Log("Failed to create file volume, errcode:%u, wait and retry ...", LASTERR
);
2144 if (hVolume
== INVALID_HANDLE_VALUE
)
2146 Log("Failed to create file volume, errcode:%u", LASTERR
);
2150 bRet
= DeviceIoControl(hVolume
, FSCTL_LOCK_VOLUME
, NULL
, 0, NULL
, 0, &dwSize
, NULL
);
2151 Log("FSCTL_LOCK_VOLUME bRet:%u code:%u", bRet
, LASTERR
);
2153 bRet
= DeviceIoControl(hVolume
, FSCTL_DISMOUNT_VOLUME
, NULL
, 0, NULL
, 0, &dwSize
, NULL
);
2154 Log("FSCTL_DISMOUNT_VOLUME bRet:%u code:%u", bRet
, LASTERR
);
2157 else if (ERROR_NOT_FOUND
== Status
)
2159 Log("Volume not found, maybe not supported");
2167 if (!TryWritePart2(hDrive
, StartSector
))
2169 if (pPhyDrive
->PartStyle
== 0)
2173 Log("Try write failed, now delete partition 2 for MBR...");
2174 CHECK_CLOSE_HANDLE(hDrive
);
2176 Log("Now delete partition 2...");
2177 VDS_DeleteVtoyEFIPartition(pPhyDrive
->PhyDrive
);
2179 hDrive
= GetPhysicalHandle(pPhyDrive
->PhyDrive
, TRUE
, TRUE
, FALSE
);
2180 if (hDrive
== INVALID_HANDLE_VALUE
)
2182 Log("Failed to GetPhysicalHandle for write.");
2189 Log("TryWritePart2 failed ....");
2195 PROGRESS_BAR_SET_POS(PT_FORMAT_PART2
);
2197 Log("Write Ventoy to disk ............................ ");
2198 if (0 != FormatPart2Fat(hDrive
, StartSector
))
2204 if (hVolume
!= INVALID_HANDLE_VALUE
)
2206 bRet
= DeviceIoControl(hVolume
, FSCTL_UNLOCK_VOLUME
, NULL
, 0, NULL
, 0, &dwSize
, NULL
);
2207 Log("FSCTL_UNLOCK_VOLUME bRet:%u code:%u", bRet
, LASTERR
);
2208 CHECK_CLOSE_HANDLE(hVolume
);
2211 Log("Updating Boot Image ............................. ");
2212 if (WriteGrubStage1ToPhyDrive(hDrive
, pPhyDrive
->PartStyle
) != 0)
2218 //write reserved data
2219 SetFilePointer(hDrive
, 512 * 2040, NULL
, FILE_BEGIN
);
2220 bRet
= WriteFile(hDrive
, ReservedData
, sizeof(ReservedData
), &dwSize
, NULL
);
2221 Log("Write resv data ret:%u dwSize:%u Error:%u", bRet
, dwSize
, LASTERR
);
2224 VentoyGetLocalBootImg(&BootImg
);
2227 memcpy(BootImg
.BootCode
+ 0x180, MBR
.BootCode
+ 0x180, 16);
2228 if (pPhyDrive
->PartStyle
)
2230 BootImg
.BootCode
[92] = 0x22;
2233 if (ForceMBR
== FALSE
&& memcmp(BootImg
.BootCode
, MBR
.BootCode
, 440) == 0)
2235 Log("Boot image has no difference, no need to write.");
2239 Log("Boot image need to write %u.", ForceMBR
);
2241 SetFilePointer(hDrive
, 0, NULL
, FILE_BEGIN
);
2243 memcpy(MBR
.BootCode
, BootImg
.BootCode
, 440);
2244 bRet
= WriteFile(hDrive
, &MBR
, 512, &dwSize
, NULL
);
2245 Log("Write Boot Image ret:%u dwSize:%u Error:%u", bRet
, dwSize
, LASTERR
);
2248 if (pPhyDrive
->PartStyle
== 0)
2250 if (0x00 == MBR
.PartTbl
[0].Active
&& 0x80 == MBR
.PartTbl
[1].Active
)
2252 Log("Need to chage 1st partition active and 2nd partition inactive.");
2254 MBR
.PartTbl
[0].Active
= 0x80;
2255 MBR
.PartTbl
[1].Active
= 0x00;
2257 SetFilePointer(hDrive
, 0, NULL
, FILE_BEGIN
);
2258 bRet
= WriteFile(hDrive
, &MBR
, 512, &dwSize
, NULL
);
2259 Log("Write NEW MBR ret:%u dwSize:%u Error:%u", bRet
, dwSize
, LASTERR
);
2265 WriteBackupDataToDisk(hDrive
, 4 * 512, pBackup
+ 4 * 512, SIZE_1MB
- 4 * 512);
2266 WriteBackupDataToDisk(hDrive
, 0, pBackup
, 4 * 512);
2270 //Refresh Drive Layout
2271 DeviceIoControl(hDrive
, IOCTL_DISK_UPDATE_PROPERTIES
, NULL
, 0, NULL
, 0, &dwSize
, NULL
);
2281 FindProcessOccupyDisk(hDrive
, pPhyDrive
);
2284 CHECK_CLOSE_HANDLE(hDrive
);
2288 Log("Recover GPT partition type to basic");
2289 VDS_ChangeVtoyEFI2Basic(pPhyDrive
->PhyDrive
, StartSector
* 512);
2292 if (ChangeAttr
|| ((pPhyDrive
->Part2GPTAttr
>> 56) != 0xC0))
2294 Log("Change EFI partition attr %u <0x%llx> to <0x%llx>", ChangeAttr
, pPhyDrive
->Part2GPTAttr
, 0xC000000000000001ULL
);
2295 if (VDS_ChangeVtoyEFIAttr(pPhyDrive
->PhyDrive
, 0xC000000000000001ULL
))
2297 Log("Change EFI partition attr success");
2298 pPhyDrive
->Part2GPTAttr
= 0xC000000000000001ULL
;
2302 Log("Change EFI partition attr failed");