return Status;\r
}\r
\r
-static int GetLettersBelongPhyDrive(int PhyDrive, char *DriveLetters, size_t Length)\r
+int GetLettersBelongPhyDrive(int PhyDrive, char *DriveLetters, size_t Length)\r
{\r
int n = 0;\r
DWORD DataSize = 0;\r
STORAGE_PROPERTY_QUERY Query;\r
STORAGE_DESCRIPTOR_HEADER DevDescHeader;\r
STORAGE_DEVICE_DESCRIPTOR *pDevDesc;\r
+ STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR diskAlignment;\r
int PhyDriveId[VENTOY_MAX_PHY_DRIVE];\r
\r
Count = GetPhysicalDriveCount();\r
continue;\r
}\r
\r
+\r
+\r
+ memset(&Query, 0, sizeof(STORAGE_PROPERTY_QUERY));\r
+ Query.PropertyId = StorageAccessAlignmentProperty;\r
+ Query.QueryType = PropertyStandardQuery;\r
+ memset(&diskAlignment, 0, sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR));\r
+\r
+ bRet = DeviceIoControl(Handle,\r
+ IOCTL_STORAGE_QUERY_PROPERTY,\r
+ &Query,\r
+ sizeof(STORAGE_PROPERTY_QUERY),\r
+ &diskAlignment,\r
+ sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR),\r
+ &dwBytes,\r
+ NULL);\r
+ if (!bRet)\r
+ {\r
+ Log("DeviceIoControl3 error:%u dwBytes:%u", LASTERR, dwBytes); \r
+ }\r
+\r
CurDrive->PhyDrive = i;\r
CurDrive->SizeInBytes = LengthInfo.Length.QuadPart;\r
CurDrive->DeviceType = pDevDesc->DeviceType;\r
CurDrive->RemovableMedia = pDevDesc->RemovableMedia;\r
CurDrive->BusType = pDevDesc->BusType;\r
\r
+ CurDrive->BytesPerLogicalSector = diskAlignment.BytesPerLogicalSector;\r
+ CurDrive->BytesPerPhysicalSector = diskAlignment.BytesPerPhysicalSector;\r
+\r
if (pDevDesc->VendorIdOffset)\r
{\r
safe_strcpy(CurDrive->VendorId, (char *)pDevDesc + pDevDesc->VendorIdOffset);\r
\r
for (i = 0, CurDrive = pDriveList; i < (int)DriveCount; i++, CurDrive++)\r
{\r
- Log("PhyDrv:%d BusType:%-4s Removable:%u Size:%dGB(%llu) Name:%s %s",\r
+ Log("PhyDrv:%d BusType:%-4s Removable:%u Size:%dGB(%llu) Sector:%u/%u Name:%s %s",\r
CurDrive->PhyDrive, GetBusTypeString(CurDrive->BusType), CurDrive->RemovableMedia,\r
GetHumanReadableGBSize(CurDrive->SizeInBytes), CurDrive->SizeInBytes,\r
+ CurDrive->BytesPerLogicalSector, CurDrive->BytesPerPhysicalSector,\r
CurDrive->VendorId, CurDrive->ProductId);\r
}\r
\r
fl_fclose(file);\r
\r
Log("Now delete all efi files ...");\r
- fl_remove("/EFI/BOOT/BOOTX64.EFI");\r
- fl_remove("/EFI/BOOT/grubx64.efi");\r
+ fl_remove("/EFI/BOOT/BOOTX64.EFI"); \r
+ fl_remove("/EFI/BOOT/grubx64.efi"); \r
fl_remove("/EFI/BOOT/grubx64_real.efi");\r
fl_remove("/EFI/BOOT/MokManager.efi");\r
fl_remove("/EFI/BOOT/mmx64.efi");\r
fl_remove("/ENROLL_THIS_KEY_IN_MOKMANAGER.cer");\r
+ fl_remove("/EFI/BOOT/grub.efi");\r
\r
file = fl_fopen("/EFI/BOOT/BOOTX64.EFI", "wb");\r
Log("Open bootx64 efi file %p ", file);\r
}\r
\r
\r
+static int FormatPart1LargeFAT32(UINT64 DiskSizeBytes, int CluserSize)\r
+{\r
+ MKFS_PARM Option;\r
+ FRESULT Ret;\r
+ FATFS FS;\r
+\r
+ Option.fmt = FM_FAT32;\r
+ Option.n_fat = 1;\r
+ Option.align = 8;\r
+ Option.n_root = 1;\r
+\r
+ if (CluserSize == 0)\r
+ {\r
+ // < 32GB select 32KB as cluster size\r
+ // > 32GB select 128KB as cluster size\r
+ if (DiskSizeBytes / 1024 / 1024 / 1024 <= 32)\r
+ {\r
+ Option.au_size = 32768;\r
+ }\r
+ else\r
+ {\r
+ Option.au_size = 131072;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ Option.au_size = CluserSize;\r
+ }\r
+\r
+ Log("Formatting Part1 large FAT32 ClusterSize:%u(%uKB) ...", CluserSize, CluserSize / 1024);\r
+\r
+ disk_io_reset_write_error();\r
+\r
+ Ret = f_mkfs(TEXT("0:"), &Option, 0, 8 * 1024 * 1024);\r
+ if (FR_OK == Ret)\r
+ {\r
+ if (disk_io_is_write_error())\r
+ {\r
+ Log("Formatting Part1 large FAT32 failed, write error.");\r
+ return 1;\r
+ }\r
+\r
+ Log("Formatting Part1 large FAT32 success, now set label");\r
+ \r
+ Ret = f_mount(&FS, TEXT("0:"), 1);\r
+ if (FR_OK == Ret)\r
+ {\r
+ Log("f_mount SUCCESS");\r
+ Ret = f_setlabel(TEXT("0:Ventoy"));\r
+ if (FR_OK == Ret)\r
+ {\r
+ Log("f_setlabel SUCCESS");\r
+ Ret = f_unmount(TEXT("0:"));\r
+ Log("f_unmount %d %s", Ret, (FR_OK == Ret) ? "SUCCESS" : "FAILED");\r
+ }\r
+ else\r
+ {\r
+ Log("f_setlabel failed %d", Ret);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ Log("f_mount failed %d", Ret);\r
+ }\r
+\r
+ return 0;\r
+ }\r
+ else\r
+ {\r
+ Log("Formatting Part1 large FAT32 failed");\r
+ return 1;\r
+ }\r
+}\r
\r
static int FormatPart1exFAT(UINT64 DiskSizeBytes)\r
{\r
}\r
}\r
\r
+static int ZeroPart1FileSystem(HANDLE hDrive, UINT64 Part2StartSector)\r
+{\r
+ int i;\r
+ DWORD dwSize = 0;\r
+ LARGE_INTEGER liCurPos;\r
+ LARGE_INTEGER liNewPos;\r
+ CHAR TmpBuffer[1024] = { 0 };\r
+\r
+ liCurPos.QuadPart = VENTOY_PART1_START_SECTOR * 512;\r
+ liNewPos.QuadPart = 0;\r
+ if (0 == SetFilePointerEx(hDrive, liCurPos, &liNewPos, FILE_BEGIN) ||\r
+ liNewPos.QuadPart != liCurPos.QuadPart)\r
+ {\r
+ Log("SetFilePointerEx Failed %u %llu %llu", LASTERR, (ULONGLONG)liCurPos.QuadPart, (ULONGLONG)liNewPos.QuadPart);\r
+ return 1;\r
+ }\r
+\r
+ for (i = 0; i < 1024; i++)\r
+ {\r
+ WriteFile(hDrive, TmpBuffer, 1024, &dwSize, NULL);\r
+ }\r
+\r
+ liCurPos.QuadPart = (Part2StartSector * 512) - (1024 * 1024);\r
+ liNewPos.QuadPart = 0;\r
+ if (0 == SetFilePointerEx(hDrive, liCurPos, &liNewPos, FILE_BEGIN) ||\r
+ liNewPos.QuadPart != liCurPos.QuadPart)\r
+ {\r
+ Log("SetFilePointerEx Failed %u %llu %llu", LASTERR, (ULONGLONG)liCurPos.QuadPart, (ULONGLONG)liNewPos.QuadPart);\r
+ return 1;\r
+ }\r
+\r
+ for (i = 0; i < 1024; i++)\r
+ {\r
+ WriteFile(hDrive, TmpBuffer, 1024, &dwSize, NULL);\r
+ }\r
\r
+ Log("Zero Part1 SUCCESS");\r
+ return 0;\r
+}\r
\r
int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLetter)\r
{\r
memset(pData, 0, 512);\r
\r
pMBR = (MBR_HEAD *)pData;\r
- VentoyFillMBR(pPhyDrive->SizeInBytes, pMBR, PartStyle);\r
+ VentoyFillMBR(pPhyDrive->SizeInBytes, pMBR, PartStyle, 0x07);\r
Part1StartSector = pMBR->PartTbl[0].StartSectorId;\r
Part1SectorCount = pMBR->PartTbl[0].SectorCount;\r
Part2StartSector = pMBR->PartTbl[1].StartSectorId;\r
int i;\r
int rc = 0;\r
int state = 0;\r
+ BOOL ReformatOK;\r
HANDLE hDrive;\r
DWORD dwSize;\r
BOOL bRet;\r
UINT64 Part1StartSector = 0;\r
UINT64 Part1SectorCount = 0;\r
UINT64 Part2StartSector = 0;\r
+ BOOL LargeFAT32 = FALSE;\r
+ BOOL DefaultExFAT = FALSE;\r
+ UINT8 FsFlag = 0x07;\r
\r
Log("#####################################################");\r
Log("InstallVentoy2PhyDrive try%d %s PhyDrive%d <<%s %s %dGB>>", TryId,\r
}\r
else\r
{\r
- VentoyFillMBR(pPhyDrive->SizeInBytes, &MBR, PartStyle);\r
+ if (GetVentoyFsType() == VTOY_FS_FAT32)\r
+ {\r
+ FsFlag = 0x0C;\r
+ }\r
+\r
+ VentoyFillMBR(pPhyDrive->SizeInBytes, &MBR, PartStyle, FsFlag);\r
Part1StartSector = MBR.PartTbl[0].StartSectorId;\r
Part1SectorCount = MBR.PartTbl[0].SectorCount;\r
Part2StartSector = MBR.PartTbl[1].StartSectorId;\r
Sleep(1000 * 5);\r
}\r
\r
- Log("Formatting part1 exFAT ...");\r
- if (0 != FormatPart1exFAT(pPhyDrive->SizeInBytes))\r
+ if (GetVentoyFsType() == VTOY_FS_FAT32 && (Part1SectorCount * 512 >= FAT32_MAX_LIMIT))\r
{\r
- Log("FormatPart1exFAT failed.");\r
- rc = 1;\r
- goto End;\r
+ Log("Formatting part1 large FAT32 ...");\r
+ LargeFAT32 = TRUE;\r
+ if (0 != FormatPart1LargeFAT32(pPhyDrive->SizeInBytes, GetClusterSize()))\r
+ {\r
+ Log("FormatPart1LargeFAT32 failed.");\r
+ rc = 1;\r
+ goto End;\r
+ }\r
+ }\r
+ else if (GetVentoyFsType() == VTOY_FS_EXFAT && GetClusterSize() == 0)\r
+ {\r
+ Log("Formatting part1 exFAT ...");\r
+ DefaultExFAT = TRUE;\r
+ if (0 != FormatPart1exFAT(pPhyDrive->SizeInBytes))\r
+ {\r
+ Log("FormatPart1exFAT failed.");\r
+ rc = 1;\r
+ goto End;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ Log("Zero part1 file system ...");\r
+ if (0 != ZeroPart1FileSystem(hDrive, Part2StartSector))\r
+ {\r
+ Log("ZeroPart1FileSystem failed.");\r
+ rc = 1;\r
+ goto End;\r
+ }\r
}\r
\r
PROGRESS_BAR_SET_POS(PT_FORMAT_PART2);\r
}\r
}\r
\r
- if (GetVentoyFsType() > 0)\r
+ // close handle, or it will deny reformat\r
+ Log("Close handle ...");\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
+\r
+ ReformatOK = TRUE;\r
+\r
+ if (state)\r
{\r
- if (state)\r
+ if (LargeFAT32)\r
{\r
- Log("Reformat %C:\\ to %s", MountDrive, GetVentoyFsName());\r
- DISK_FormatVolume(MountDrive, GetVentoyFsType());\r
+ Log("No need to reformat for large FAT32");\r
+ pPhyDrive->VentoyFsClusterSize = GetVolumeClusterSize(MountDrive);\r
+ }\r
+ else if (DefaultExFAT)\r
+ {\r
+ Log("No need to reformat for default exfat");\r
+ pPhyDrive->VentoyFsClusterSize = GetVolumeClusterSize(MountDrive);\r
}\r
else\r
{\r
- Log("Can not reformat %s to %s", DriveName, GetVentoyFsName());\r
+ bRet = DISK_FormatVolume(MountDrive, GetVentoyFsType(), Part1SectorCount * 512);\r
+ for (i = 0; bRet == FALSE && i < 2; i++)\r
+ {\r
+ Log("Wait and retry reformat ...");\r
+ Sleep(1000);\r
+ bRet = DISK_FormatVolume(MountDrive, GetVentoyFsType(), Part1SectorCount * 512);\r
+ }\r
+\r
+ if (bRet)\r
+ {\r
+ Log("Reformat %C:\\ to %s SUCCESS", MountDrive, GetVentoyFsName());\r
+ pPhyDrive->VentoyFsClusterSize = GetVolumeClusterSize(MountDrive);\r
+\r
+ if ((GetVentoyFsType() != VTOY_FS_UDF) && (pPhyDrive->VentoyFsClusterSize < 2048))\r
+ {\r
+ for (i = 0; i < 10; i++)\r
+ {\r
+ Log("### Invalid cluster size %d ###", pPhyDrive->VentoyFsClusterSize);\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ ReformatOK = FALSE;\r
+ Log("Reformat %C:\\ to %s FAILED", MountDrive, GetVentoyFsName());\r
+ }\r
}\r
}\r
else\r
{\r
- Log("No need to reformat ventoy partition");\r
+ Log("Can not reformat %s to %s", DriveName, GetVentoyFsName());\r
+ }\r
+\r
+ if (!ReformatOK)\r
+ {\r
+ Log("Format to exfat with built-in algorithm");\r
+\r
+ hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE);\r
+ if (hDrive == INVALID_HANDLE_VALUE)\r
+ {\r
+ Log("Failed to GetPhysicalHandle for write.");\r
+ }\r
+ else\r
+ {\r
+ if (0 != FormatPart1exFAT(pPhyDrive->SizeInBytes))\r
+ {\r
+ Log("FormatPart1exFAT SUCCESS.");\r
+ }\r
+ else\r
+ {\r
+ Log("FormatPart1exFAT FAILED.");\r
+ }\r
+\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
+ }\r
}\r
\r
Log("OK\n");\r
Log("###### [Error:] Virtual Disk Service (VDS) Unavailable ######");\r
Log("###### [Error:] Virtual Disk Service (VDS) Unavailable ######");\r
}\r
+\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
}\r
\r
if (pGptInfo)\r
{\r
free(pGptInfo);\r
}\r
-\r
- CHECK_CLOSE_HANDLE(hDrive);\r
+ \r
return rc;\r
}\r
\r
\r
Sleep(2000);\r
\r
- //Refresh disk list\r
- PhyDrive = pPhyDrive->PhyDrive;\r
+ if (g_CLI_Mode)\r
+ {\r
+ Log("### Ventoy non-destructive CLI installation successfully finished.");\r
+ }\r
+ else\r
+ {\r
+ //Refresh disk list\r
+ PhyDrive = pPhyDrive->PhyDrive;\r
+\r
+ Log("#### Now Refresh PhyDrive ####");\r
+ Ventoy2DiskDestroy();\r
+ Ventoy2DiskInit();\r
\r
- Log("#### Now Refresh PhyDrive ####");\r
- Ventoy2DiskDestroy();\r
- Ventoy2DiskInit();\r
- \r
- pPhyDrive = GetPhyDriveInfoByPhyDrive(PhyDrive);\r
- if (pPhyDrive)\r
- {\r
- if (pPhyDrive->VentoyVersion[0] == 0)\r
- {\r
- Log("After process the Ventoy version is still invalid");\r
- goto End;\r
- }\r
+ pPhyDrive = GetPhyDriveInfoByPhyDrive(PhyDrive);\r
+ if (pPhyDrive)\r
+ {\r
+ if (pPhyDrive->VentoyVersion[0] == 0)\r
+ {\r
+ Log("After process the Ventoy version is still invalid");\r
+ goto End;\r
+ }\r
\r
- Log("### Ventoy non-destructive installation successfully finished <%s>", pPhyDrive->VentoyVersion);\r
- }\r
- else\r
- {\r
- Log("### Ventoy non-destructive installation successfully finished <not found>");\r
- }\r
+ Log("### Ventoy non-destructive installation successfully finished <%s>", pPhyDrive->VentoyVersion);\r
+ }\r
+ else\r
+ {\r
+ Log("### Ventoy non-destructive installation successfully finished <not found>");\r
+ }\r
\r
- InitComboxCtrl(g_DialogHwnd, PhyDrive);\r
+ InitComboxCtrl(g_DialogHwnd, PhyDrive);\r
+ }\r
\r
rc = 0;\r
\r