]> glassweightruler.freedombox.rocks Git - Ventoy.git/blobdiff - Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c
Fix the "Unsupported vtoy type unknown" error when boot a VDI file created by Virtual...
[Ventoy.git] / Ventoy2Disk / Ventoy2Disk / Ventoy2Disk.c
index 4c9fdf4d1a32f7e7d3b663b377dff55a609497e4..68520a06cecf39274afa23ed07dab5d388f1490f 100644 (file)
@@ -28,6 +28,8 @@ DWORD g_PhyDriveCount = 0;
 static int g_FilterRemovable = 0;\r
 int g_FilterUSB = 1;\r
 int g_ForceOperation = 1;\r
+int g_NoNeedInputYes = 0;\r
+int g_WriteImage = 0;\r
 \r
 int ParseCmdLineOption(LPSTR lpCmdLine)\r
 {\r
@@ -50,6 +52,10 @@ int ParseCmdLineOption(LPSTR lpCmdLine)
         {\r
             g_ForceOperation = 1;\r
         }\r
+        else if (strncmp(__argv[i], "-Y", 2) == 0 || strncmp(__argv[i], "-y", 2) == 0)\r
+        {\r
+            g_NoNeedInputYes = 1;\r
+        }\r
     }\r
 \r
     GetCurrentDirectoryA(sizeof(cfgfile), cfgfile);\r
@@ -70,7 +76,7 @@ int ParseCmdLineOption(LPSTR lpCmdLine)
     return 0;\r
 }\r
 \r
-static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UINT64 *Part2StartSector)\r
+BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UINT64 *Part2StartSector, UINT64 *GptPart2Attr)\r
 {\r
     int i;\r
     BOOL bRet;\r
@@ -80,6 +86,8 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN
     UINT32 PartStartSector;\r
     UINT32 PartSectorCount;\r
     CHAR PhyDrivePath[128];\r
+    CHAR GUIDStr[128];\r
+    GUID ZeroGuid = { 0 };\r
        VTOY_GPT_INFO *pGpt = NULL;\r
 \r
     safe_sprintf(PhyDrivePath, "\\\\.\\PhysicalDrive%d", PhyDrive);\r
@@ -107,20 +115,7 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN
         return FALSE;\r
     }\r
 \r
-       for (i = 0; i < 4; i++)\r
-       {\r
-               Log("=========== Partition Table %d ============", i + 1);\r
-               Log("PartTbl.Active = 0x%x", MBR.PartTbl[i].Active);\r
-               Log("PartTbl.FsFlag = 0x%x", MBR.PartTbl[i].FsFlag);\r
-               Log("PartTbl.StartSectorId = %u", MBR.PartTbl[i].StartSectorId);\r
-               Log("PartTbl.SectorCount = %u", MBR.PartTbl[i].SectorCount);\r
-               Log("PartTbl.StartHead = %u", MBR.PartTbl[i].StartHead);\r
-               Log("PartTbl.StartSector = %u", MBR.PartTbl[i].StartSector);\r
-               Log("PartTbl.StartCylinder = %u", MBR.PartTbl[i].StartCylinder);\r
-               Log("PartTbl.EndHead = %u", MBR.PartTbl[i].EndHead);\r
-               Log("PartTbl.EndSector = %u", MBR.PartTbl[i].EndSector);\r
-               Log("PartTbl.EndCylinder = %u", MBR.PartTbl[i].EndCylinder);\r
-       }\r
+    \r
 \r
        if (MBR.PartTbl[0].FsFlag == 0xEE)\r
        {\r
@@ -146,9 +141,34 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN
                        return FALSE;\r
                }\r
 \r
+        for (i = 0; i < 128; i++)\r
+        {\r
+            if (memcmp(&(pGpt->PartTbl[i].PartGuid), &ZeroGuid, sizeof(GUID)) == 0)\r
+            {\r
+                continue;\r
+            }\r
+\r
+            Log("=========== Disk%d GPT Partition %d ============", PhyDrive, i + 1);\r
+            \r
+            Log("PartTbl.PartType = %s", GUID2String(&pGpt->PartTbl[i].PartType, GUIDStr, sizeof(GUIDStr)));\r
+            Log("PartTbl.PartGuid = %s", GUID2String(&pGpt->PartTbl[i].PartGuid, GUIDStr, sizeof(GUIDStr)));\r
+            Log("PartTbl.StartLBA = %llu", (ULONGLONG)pGpt->PartTbl[i].StartLBA);\r
+            Log("PartTbl.LastLBA = %llu", (ULONGLONG)pGpt->PartTbl[i].LastLBA);\r
+            Log("PartTbl.Attribute = 0x%llx", pGpt->PartTbl[i].Attr);\r
+            Log("PartTbl.Name = %S", pGpt->PartTbl[i].Name);\r
+        }\r
+\r
                if (memcmp(pGpt->PartTbl[1].Name, L"VTOYEFI", 7 * 2))\r
                {\r
-                       Log("Invalid ventoy efi part name");\r
+                       if (pGpt->PartTbl[1].Name[0])\r
+                       {\r
+                               Log("Invalid ventoy efi part name <%S>", pGpt->PartTbl[1].Name);\r
+                       }\r
+                       else\r
+                       {\r
+                               Log("Invalid ventoy efi part name <null>");\r
+                       }\r
+                       \r
                        return FALSE;\r
                }\r
 \r
@@ -169,6 +189,7 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN
             return FALSE;\r
         }\r
 \r
+        *GptPart2Attr = pGpt->PartTbl[1].Attr;\r
                *Part2StartSector = pGpt->PartTbl[1].StartLBA;\r
 \r
         memcpy(pMBR, &(pGpt->MBR), sizeof(MBR_HEAD));\r
@@ -177,6 +198,21 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN
        {\r
                CHECK_CLOSE_HANDLE(hDrive);\r
 \r
+        for (i = 0; i < 4; i++)\r
+        {\r
+            Log("=========== Disk%d MBR Partition %d ============", PhyDrive, i + 1);\r
+            Log("PartTbl.Active = 0x%x", MBR.PartTbl[i].Active);\r
+            Log("PartTbl.FsFlag = 0x%x", MBR.PartTbl[i].FsFlag);\r
+            Log("PartTbl.StartSectorId = %u", MBR.PartTbl[i].StartSectorId);\r
+            Log("PartTbl.SectorCount = %u", MBR.PartTbl[i].SectorCount);\r
+            Log("PartTbl.StartHead = %u", MBR.PartTbl[i].StartHead);\r
+            Log("PartTbl.StartSector = %u", MBR.PartTbl[i].StartSector);\r
+            Log("PartTbl.StartCylinder = %u", MBR.PartTbl[i].StartCylinder);\r
+            Log("PartTbl.EndHead = %u", MBR.PartTbl[i].EndHead);\r
+            Log("PartTbl.EndSector = %u", MBR.PartTbl[i].EndSector);\r
+            Log("PartTbl.EndCylinder = %u", MBR.PartTbl[i].EndCylinder);\r
+        }\r
+\r
                if (MBR.PartTbl[0].StartSectorId != 2048)\r
                {\r
                        Log("Part1 not match %u", MBR.PartTbl[0].StartSectorId);\r
@@ -215,6 +251,90 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN
     return TRUE;\r
 }\r
 \r
+int GetVolumeClusterSize(char Drive)\r
+{\r
+    CHAR Volume[32] = { 0 };\r
+    DWORD SectorsPerCluster = 0;\r
+    DWORD BytesPerSector = 0;\r
+    DWORD NumberOfFreeClusters = 0;\r
+    DWORD TotalNumberOfClusters = 0;\r
+\r
+    sprintf_s(Volume, sizeof(Volume), "%C:\\", Drive);\r
+\r
+    if (GetDiskFreeSpaceA(Volume, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters))\r
+    {\r
+        Log("GetVolumeClusterSize %s SUCCESS %u %u %u", Volume, SectorsPerCluster, BytesPerSector, SectorsPerCluster * BytesPerSector);\r
+        return (int)(SectorsPerCluster * BytesPerSector);        \r
+    }\r
+    else\r
+    {\r
+        Log("GetVolumeClusterSize %s failed err:%u", Volume, LASTERR);\r
+    }\r
+\r
+    return 0;\r
+}\r
+\r
+int GetVentoyFsNameInPhyDrive(PHY_DRIVE_INFO* CurDrive)\r
+{\r
+    int i = 0;\r
+    UINT64 Offset;\r
+\r
+    CHAR Volume[128] = { 0 };\r
+    CHAR FsName[MAX_PATH] = { 0 };\r
+\r
+    while (CurDrive->DriveLetters[i])\r
+    {\r
+        if (GetPhyDriveByLogicalDrive(CurDrive->DriveLetters[i], &Offset) >= 0)\r
+        {\r
+            if (Offset == SIZE_1MB)\r
+            {\r
+                sprintf_s(Volume, sizeof(Volume), "%C:\\", CurDrive->DriveLetters[i]);\r
+                Log("Find the partition 1 logical drive is %s", Volume);\r
+                break;\r
+            }\r
+        }\r
+        i++;\r
+    }\r
+\r
+    sprintf_s(CurDrive->VentoyFsType, sizeof(CurDrive->VentoyFsType), "??");\r
+\r
+    if (Volume[0])\r
+    {\r
+        CurDrive->VentoyFsClusterSize = GetVolumeClusterSize(Volume[0]);\r
+\r
+        if (GetVolumeInformationA(Volume, NULL, 0, NULL, NULL, NULL, FsName, MAX_PATH))\r
+        {\r
+            if (_stricmp(FsName, "exFAT") == 0)\r
+            {\r
+                sprintf_s(CurDrive->VentoyFsType, sizeof(CurDrive->VentoyFsType), "exFAT");\r
+            }\r
+            else if (_stricmp(FsName, "NTFS") == 0)\r
+            {\r
+                sprintf_s(CurDrive->VentoyFsType, sizeof(CurDrive->VentoyFsType), "NTFS");\r
+            }\r
+            else if (_stricmp(FsName, "FAT") == 0 || _stricmp(FsName, "FAT32") == 0)\r
+            {\r
+                sprintf_s(CurDrive->VentoyFsType, sizeof(CurDrive->VentoyFsType), "FAT32");\r
+            }\r
+            else\r
+            {\r
+                sprintf_s(CurDrive->VentoyFsType, sizeof(CurDrive->VentoyFsType), "%s", FsName);\r
+            }\r
+\r
+            Log("GetVentoyFsNameInPhyDrive %d %s <%s> <%s>", CurDrive->PhyDrive, Volume, FsName, CurDrive->VentoyFsType);\r
+        }\r
+        else\r
+        {\r
+            Log("GetVolumeInformationA %s failed %u", Volume, LASTERR);\r
+        }\r
+    }\r
+    else\r
+    {\r
+        Log("GetVentoyFsNameInPhyDrive %s not found", Volume);\r
+    }\r
+\r
+    return 0;\r
+}\r
 \r
 static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)\r
 {\r
@@ -224,6 +344,7 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)
     int Letter = 'A';\r
     int Id = 0;\r
     int LetterCount = 0;\r
+    UINT64 Part2GPTAttr = 0;\r
        UINT64 Part2StartSector = 0;\r
     PHY_DRIVE_INFO *CurDrive;\r
        MBR_HEAD MBR;\r
@@ -235,7 +356,7 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)
         if (LogDrive & 0x01)\r
         {\r
             LogLetter[LetterCount] = Letter;\r
-            PhyDriveId[LetterCount] = GetPhyDriveByLogicalDrive(Letter);\r
+                       PhyDriveId[LetterCount] = GetPhyDriveByLogicalDrive(Letter, NULL);\r
 \r
             Log("Logical Drive:%C  ===> PhyDrive:%d", LogLetter[LetterCount], PhyDriveId[LetterCount]);\r
             LetterCount++;\r
@@ -246,6 +367,7 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)
 \r
     for (i = 0; i < DriveCount; i++)\r
     {\r
+        Part2GPTAttr = 0;\r
         CurDrive = pDriveList + i;\r
 \r
         CurDrive->Id = -1;\r
@@ -277,13 +399,16 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)
             }\r
         }\r
 \r
-               if (IsVentoyPhyDrive(CurDrive->PhyDrive, CurDrive->SizeInBytes, &MBR, &Part2StartSector))\r
+        if (IsVentoyPhyDrive(CurDrive->PhyDrive, CurDrive->SizeInBytes, &MBR, &Part2StartSector, &Part2GPTAttr))\r
         {\r
             memcpy(&(CurDrive->MBR), &MBR, sizeof(MBR));\r
             CurDrive->PartStyle = (MBR.PartTbl[0].FsFlag == 0xEE) ? 1 : 0;\r
+            CurDrive->Part2GPTAttr = Part2GPTAttr;\r
             GetVentoyVerInPhyDrive(CurDrive, Part2StartSector, CurDrive->VentoyVersion, sizeof(CurDrive->VentoyVersion), &(CurDrive->SecureBootSupport));\r
             Log("PhyDrive %d is Ventoy Disk ver:%s SecureBoot:%u", CurDrive->PhyDrive, CurDrive->VentoyVersion, CurDrive->SecureBootSupport);\r
 \r
+            GetVentoyFsNameInPhyDrive(CurDrive);\r
+\r
             if (CurDrive->VentoyVersion[0] == 0)\r
             {\r
                 CurDrive->VentoyVersion[0] = '?';\r
@@ -319,6 +444,23 @@ PHY_DRIVE_INFO * GetPhyDriveInfoById(int Id)
     return NULL;\r
 }\r
 \r
+\r
+PHY_DRIVE_INFO * GetPhyDriveInfoByPhyDrive(int PhyDrive)\r
+{\r
+       DWORD i;\r
+       for (i = 0; i < g_PhyDriveCount; i++)\r
+       {\r
+               if (g_PhyDriveList[i].PhyDrive == PhyDrive)\r
+               {\r
+                       return g_PhyDriveList + i;\r
+               }\r
+       }\r
+\r
+       return NULL;\r
+}\r
+\r
+\r
+\r
 int SortPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)\r
 {\r
        DWORD i, j;\r
@@ -385,5 +527,8 @@ int Ventoy2DiskInit(void)
 int Ventoy2DiskDestroy(void)\r
 {\r
     free(g_PhyDriveList);\r
+       g_PhyDriveList = NULL;\r
+       g_PhyDriveCount = 0;\r
+\r
     return 0;\r
 }\r