]> 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 557bdfc1b70aa7f0a0c9277568e9e34d79977721..68520a06cecf39274afa23ed07dab5d388f1490f 100644 (file)
 PHY_DRIVE_INFO *g_PhyDriveList = NULL;\r
 DWORD g_PhyDriveCount = 0;\r
 static int g_FilterRemovable = 0;\r
-static int g_FilterUSB = 1;\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,18 +141,78 @@ 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
+        if (pGpt->PartTbl[0].StartLBA != 2048)\r
+        {\r
+            Log("Part1 not match %llu", pGpt->PartTbl[0].StartLBA);\r
+            return FALSE;\r
+        }\r
+\r
+        PartSectorCount = VENTOY_EFI_PART_SIZE / 512;\r
+\r
+        if (pGpt->PartTbl[1].StartLBA != pGpt->PartTbl[0].LastLBA + 1 ||\r
+            (UINT32)(pGpt->PartTbl[1].LastLBA + 1 - pGpt->PartTbl[1].StartLBA) != PartSectorCount)\r
+        {\r
+            Log("Part2 not match [%llu %llu] [%llu %llu]",\r
+                pGpt->PartTbl[0].StartLBA, pGpt->PartTbl[0].LastLBA,\r
+                pGpt->PartTbl[1].StartLBA, pGpt->PartTbl[1].LastLBA);\r
+            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
        }\r
        else\r
        {\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
@@ -180,17 +235,106 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN
                if (MBR.PartTbl[0].Active != 0x80 && MBR.PartTbl[1].Active != 0x80)\r
                {\r
                        Log("Part1 and Part2 are both NOT active 0x%x 0x%x", MBR.PartTbl[0].Active, MBR.PartTbl[1].Active);\r
-                       return FALSE;\r
+            if (MBR.PartTbl[2].Active != 0x80 && MBR.PartTbl[3].Active != 0x80)\r
+            {\r
+                Log("Part3 and Part4 are both NOT active 0x%x 0x%x", MBR.PartTbl[2].Active, MBR.PartTbl[3].Active);\r
+                //return FALSE;\r
+            }\r
                }\r
 \r
                *Part2StartSector = MBR.PartTbl[1].StartSectorId;\r
+\r
+        memcpy(pMBR, &MBR, sizeof(MBR_HEAD));\r
        }\r
 \r
-       memcpy(pMBR, &MBR, sizeof(MBR_HEAD));\r
     Log("PhysicalDrive%d is ventoy disk", PhyDrive);\r
     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
@@ -200,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
@@ -211,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
@@ -222,18 +367,12 @@ 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
         memset(CurDrive->DriveLetters, 0, sizeof(CurDrive->DriveLetters));\r
 \r
-        // Too big for MBR\r
-        if (CurDrive->SizeInBytes > 2199023255552ULL)\r
-        {\r
-            Log("<%s %s> is filtered for too big for MBR.", CurDrive->VendorId, CurDrive->ProductId);\r
-            continue;\r
-        }\r
-\r
         if (g_FilterRemovable && (!CurDrive->RemovableMedia))\r
         {\r
             Log("<%s %s> is filtered for not removable.", CurDrive->VendorId, CurDrive->ProductId);\r
@@ -260,10 +399,21 @@ 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
-                       GetVentoyVerInPhyDrive(CurDrive, Part2StartSector, CurDrive->VentoyVersion, sizeof(CurDrive->VentoyVersion));\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
+                Log("Unknown Ventoy Version");\r
+            }\r
         }\r
     }\r
 \r
@@ -294,24 +444,60 @@ 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
+       BOOL flag;\r
        PHY_DRIVE_INFO TmpDriveInfo;\r
 \r
        for (i = 0; i < DriveCount; i++)\r
        {\r
                for (j = i + 1; j < DriveCount; j++)\r
                {\r
+                       flag = FALSE;\r
+\r
                        if (pDriveList[i].BusType == BusTypeUsb && pDriveList[j].BusType == BusTypeUsb)\r
                        {\r
                                if (pDriveList[i].RemovableMedia == FALSE && pDriveList[j].RemovableMedia == TRUE)\r
                                {\r
-                                       memcpy(&TmpDriveInfo, pDriveList + i, sizeof(PHY_DRIVE_INFO));\r
-                                       memcpy(pDriveList + i, pDriveList + j, sizeof(PHY_DRIVE_INFO));\r
-                                       memcpy(pDriveList + j, &TmpDriveInfo, sizeof(PHY_DRIVE_INFO));\r
+                                       flag = TRUE;\r
+                               }\r
+                       }\r
+                       else if (pDriveList[j].BusType == BusTypeUsb)\r
+                       {\r
+                               flag = TRUE;\r
+                       }\r
+                       else\r
+                       {\r
+                               if (pDriveList[j].PhyDrive < pDriveList[i].PhyDrive)\r
+                               {\r
+                                       flag = TRUE;\r
                                }\r
                        }\r
+\r
+                       if (flag)\r
+                       {\r
+                               memcpy(&TmpDriveInfo, pDriveList + i, sizeof(PHY_DRIVE_INFO));\r
+                               memcpy(pDriveList + i, pDriveList + j, sizeof(PHY_DRIVE_INFO));\r
+                               memcpy(pDriveList + j, &TmpDriveInfo, sizeof(PHY_DRIVE_INFO));\r
+                       }\r
                }\r
        }\r
 \r
@@ -341,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