]> glassweightruler.freedombox.rocks Git - Ventoy.git/blobdiff - Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c
Optimization for Ventoy2Disk.exe
[Ventoy.git] / Ventoy2Disk / Ventoy2Disk / Ventoy2Disk.c
index f6f77342aed421585f2036abe653dac2e929afeb..5ba9e71ae7f1adbb0fe1d8f72bc942462e4aa29b 100644 (file)
-/******************************************************************************
- * Ventoy2Disk.c
- *
- * Copyright (c) 2020, longpanda <admin@ventoy.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 3 of the
- * License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <Windows.h>
-#include "resource.h"
-#include "Language.h"
-#include "Ventoy2Disk.h"
-
-PHY_DRIVE_INFO *g_PhyDriveList = NULL;
-DWORD g_PhyDriveCount = 0;
-static int g_FilterRemovable = 1;
-static int g_FilterUSB = 1;
-int g_ForceOperation = 1;
-
-int ParseCmdLineOption(LPSTR lpCmdLine)
-{
-    int i;
-    char cfgfile[MAX_PATH];
-
-    if (lpCmdLine && lpCmdLine[0])
-    {
-        Log("CmdLine:<%s>", lpCmdLine);
-    }
-
-    for (i = 0; i < __argc; i++)
-    {
-        if (strncmp(__argv[i], "-R", 2) == 0)
-        {
-            g_FilterRemovable = 0;
-        }
-        else if (strncmp(__argv[i], "-U", 2) == 0)
-        {
-            g_FilterUSB = 0;
-        }
-        else if (strncmp(__argv[i], "-F", 2) == 0)
-        {
-            g_ForceOperation = 1;
-        }
-    }
-
-    GetCurrentDirectoryA(sizeof(cfgfile), cfgfile);
-    strcat_s(cfgfile, sizeof(cfgfile), "\\Ventoy2Disk.ini");
-
-    if (0 == GetPrivateProfileIntA("Filter", "Removable", 1, cfgfile))
-    {
-        g_FilterRemovable = 0;
-    }
-
-    if (0 == GetPrivateProfileIntA("Filter", "USB", 1, cfgfile))
-    {
-        g_FilterUSB = 0;
-    }
-
-    if (1 == GetPrivateProfileIntA("Operation", "Force", 0, cfgfile))
-    {
-        g_ForceOperation = 1;
-    }
-
-    Log("Control Flag: %d %d %d", g_FilterRemovable, g_FilterUSB, g_ForceOperation);
-
-    return 0;
-}
-
-static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes)
-{
-    int i;
-    BOOL bRet;
-    DWORD dwSize;
-    HANDLE hDrive;
-    MBR_HEAD MBR;
-    UINT32 PartStartSector;
-    UINT32 PartSectorCount;
-    CHAR PhyDrivePath[128];
-
-    safe_sprintf(PhyDrivePath, "\\\\.\\PhysicalDrive%d", PhyDrive);
-    hDrive = CreateFileA(PhyDrivePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
-    Log("Create file Handle:%p %s status:%u", hDrive, PhyDrivePath, LASTERR);
-
-    if (hDrive == INVALID_HANDLE_VALUE)
-    {
-        return FALSE;
-    }
-
-    bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);
-    CHECK_CLOSE_HANDLE(hDrive);
-
-    Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR);
-
-    if ((!bRet) || (dwSize != sizeof(MBR)))
-    {
-        return FALSE;
-    }
-
-    if (MBR.Byte55 != 0x55 || MBR.ByteAA != 0xAA)
-    {
-        Log("Byte55 ByteAA not match 0x%x 0x%x", MBR.Byte55, MBR.ByteAA);
-        return FALSE;
-    }
-
-    for (i = 0; i < 4; i++)
-    {
-        Log("=========== Partition Table %d ============", i + 1);
-        Log("PartTbl.Active = 0x%x", MBR.PartTbl[i].Active);
-        Log("PartTbl.FsFlag = 0x%x", MBR.PartTbl[i].FsFlag);
-        Log("PartTbl.StartSectorId = %u", MBR.PartTbl[i].StartSectorId);
-        Log("PartTbl.SectorCount = %u", MBR.PartTbl[i].SectorCount);
-        Log("PartTbl.StartHead = %u", MBR.PartTbl[i].StartHead);
-        Log("PartTbl.StartSector = %u", MBR.PartTbl[i].StartSector);
-        Log("PartTbl.StartCylinder = %u", MBR.PartTbl[i].StartCylinder);
-        Log("PartTbl.EndHead = %u", MBR.PartTbl[i].EndHead);
-        Log("PartTbl.EndSector = %u", MBR.PartTbl[i].EndSector);
-        Log("PartTbl.EndCylinder = %u", MBR.PartTbl[i].EndCylinder);
-    }
-
-    if (MBR.PartTbl[2].SectorCount > 0 || MBR.PartTbl[3].SectorCount > 0)
-    {
-        Log("Part3 Part4 are not empty");
-        return FALSE;
-    }
-
-    PartStartSector = 2048;
-    PartSectorCount = (UINT32)((SizeBytes - VENTOY_EFI_PART_SIZE - SIZE_1MB) / 512);
-
-    if (MBR.PartTbl[0].FsFlag != 0x07 ||
-        MBR.PartTbl[0].StartSectorId != PartStartSector ||
-        MBR.PartTbl[0].SectorCount != PartSectorCount)
-    {
-        Log("Part1 not match %u %u", PartStartSector, PartSectorCount);
-        return FALSE;
-    }
-
-    PartStartSector = (UINT32)((SizeBytes - VENTOY_EFI_PART_SIZE) / 512);
-    PartSectorCount = VENTOY_EFI_PART_SIZE / 512;
-
-    if (MBR.PartTbl[1].Active != 0x80 ||
-        MBR.PartTbl[1].FsFlag != 0xEF ||
-        MBR.PartTbl[1].StartSectorId != PartStartSector ||
-        MBR.PartTbl[1].SectorCount != PartSectorCount)
-    {
-        Log("Part2 not match %u %u", PartStartSector, PartSectorCount);
-        return FALSE;
-    }
-
-    Log("PhysicalDrive%d is ventoy disk", PhyDrive);
-    return TRUE;
-}
-
-
-static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)
-{
-    DWORD i; 
-    DWORD LogDrive;
-    int Letter = 'A';
-    int Id = 0;
-    int LetterCount = 0;
-    PHY_DRIVE_INFO *CurDrive;
-    int LogLetter[VENTOY_MAX_PHY_DRIVE];
-    int PhyDriveId[VENTOY_MAX_PHY_DRIVE];
-
-    for (LogDrive = GetLogicalDrives(); LogDrive > 0; LogDrive >>= 1)
-    {
-        if (LogDrive & 0x01)
-        {
-            LogLetter[LetterCount] = Letter;
-            PhyDriveId[LetterCount] = GetPhyDriveByLogicalDrive(Letter);
-
-            Log("Logical Drive:%C  ===> PhyDrive:%d", LogLetter[LetterCount], PhyDriveId[LetterCount]);
-            LetterCount++;
-        }
-        
-        Letter++;
-    }    
-
-    for (i = 0; i < DriveCount; i++)
-    {
-        CurDrive = pDriveList + i;
-
-        CurDrive->Id = -1;
-        CurDrive->FirstDriveLetter = -1;
-
-        // Too big for MBR
-        if (CurDrive->SizeInBytes > 2199023255552ULL)
-        {
-            Log("<%s %s> is filtered for too big for MBR.", CurDrive->VendorId, CurDrive->ProductId);
-            continue;
-        }
-
-        if (g_FilterRemovable && (!CurDrive->RemovableMedia))
-        {
-            Log("<%s %s> is filtered for not removable.", CurDrive->VendorId, CurDrive->ProductId);
-            continue;
-        }
-
-        if (g_FilterUSB && CurDrive->BusType != BusTypeUsb)
-        {
-            Log("<%s %s> is filtered for not USB type.", CurDrive->VendorId, CurDrive->ProductId);
-            continue;
-        }
-        
-        CurDrive->Id = Id++;
-
-        for (Letter = 0; Letter < LetterCount; Letter++)
-        {
-            if (PhyDriveId[Letter] == CurDrive->PhyDrive)
-            {
-                CurDrive->FirstDriveLetter = LogLetter[Letter];
-                break;
-            }
-        }
-
-        if (IsVentoyPhyDrive(CurDrive->PhyDrive, CurDrive->SizeInBytes))
-        {
-            GetVentoyVerInPhyDrive(CurDrive, CurDrive->VentoyVersion, sizeof(CurDrive->VentoyVersion));
-        }
-    }
-
-    // for safe
-    for (i = 0; i < DriveCount; i++)
-    {
-        CurDrive = pDriveList + i;
-        if (CurDrive->Id < 0)
-        {
-            CurDrive->PhyDrive = 0x00FFFFFF;
-        }
-    }
-
-    return Id;
-}
-
-PHY_DRIVE_INFO * GetPhyDriveInfoById(int Id)
-{
-    DWORD i;
-    for (i = 0; i < g_PhyDriveCount; i++)
-    {
-        if (g_PhyDriveList[i].Id >= 0 && g_PhyDriveList[i].Id == Id)
-        {
-            return g_PhyDriveList + i;
-        }
-    }
-
-    return NULL;
-}
-
-int Ventoy2DiskInit(void)
-{
-    g_PhyDriveList = (PHY_DRIVE_INFO *)malloc(sizeof(PHY_DRIVE_INFO)* VENTOY_MAX_PHY_DRIVE);
-    if (NULL == g_PhyDriveList)
-    {
-        Log("Failed to alloc phy drive memory");
-        return FALSE;
-    }
-    memset(g_PhyDriveList, 0, sizeof(PHY_DRIVE_INFO)* VENTOY_MAX_PHY_DRIVE);
-
-    GetAllPhysicalDriveInfo(g_PhyDriveList, &g_PhyDriveCount);
-    FilterPhysicalDrive(g_PhyDriveList, g_PhyDriveCount);
-
-    return 0;
-}
-
-int Ventoy2DiskDestroy(void)
-{
-    free(g_PhyDriveList);
-    return 0;
-}
+/******************************************************************************\r
+ * Ventoy2Disk.c\r
+ *\r
+ * Copyright (c) 2020, longpanda <admin@ventoy.net>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License as\r
+ * published by the Free Software Foundation; either version 3 of the\r
+ * License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+#include <Windows.h>\r
+#include "resource.h"\r
+#include "Language.h"\r
+#include "Ventoy2Disk.h"\r
+\r
+PHY_DRIVE_INFO *g_PhyDriveList = NULL;\r
+DWORD g_PhyDriveCount = 0;\r
+static int g_FilterRemovable = 0;\r
+int g_FilterUSB = 1;\r
+int g_ForceOperation = 1;\r
+int g_WriteImage = 0;\r
+\r
+int ParseCmdLineOption(LPSTR lpCmdLine)\r
+{\r
+    int i;\r
+    char cfgfile[MAX_PATH];\r
+\r
+    if (lpCmdLine && lpCmdLine[0])\r
+    {\r
+        Log("CmdLine:<%s>", lpCmdLine);\r
+    }\r
+\r
+    for (i = 0; i < __argc; i++)\r
+    {\r
+        if (strncmp(__argv[i], "-U", 2) == 0 ||\r
+                       strncmp(__argv[i], "-u", 2) == 0)\r
+        {\r
+            g_FilterUSB = 0;\r
+        }\r
+        else if (strncmp(__argv[i], "-F", 2) == 0)\r
+        {\r
+            g_ForceOperation = 1;\r
+        }\r
+    }\r
+\r
+    GetCurrentDirectoryA(sizeof(cfgfile), cfgfile);\r
+    strcat_s(cfgfile, sizeof(cfgfile), "\\Ventoy2Disk.ini");\r
+\r
+    if (0 == GetPrivateProfileIntA("Filter", "USB", 1, cfgfile))\r
+    {\r
+        g_FilterUSB = 0;\r
+    }\r
+\r
+    if (1 == GetPrivateProfileIntA("Operation", "Force", 0, cfgfile))\r
+    {\r
+        g_ForceOperation = 1;\r
+    }\r
+\r
+    Log("Control Flag: %d %d %d", g_FilterRemovable, g_FilterUSB, g_ForceOperation);\r
+\r
+    return 0;\r
+}\r
+\r
+static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UINT64 *Part2StartSector, UINT64 *GptPart2Attr)\r
+{\r
+    int i;\r
+    BOOL bRet;\r
+    DWORD dwSize;\r
+    HANDLE hDrive;\r
+    MBR_HEAD MBR;\r
+    UINT32 PartStartSector;\r
+    UINT32 PartSectorCount;\r
+    CHAR PhyDrivePath[128];\r
+       VTOY_GPT_INFO *pGpt = NULL;\r
+\r
+    safe_sprintf(PhyDrivePath, "\\\\.\\PhysicalDrive%d", PhyDrive);\r
+    hDrive = CreateFileA(PhyDrivePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);\r
+    Log("Create file Handle:%p %s status:%u", hDrive, PhyDrivePath, LASTERR);\r
+\r
+    if (hDrive == INVALID_HANDLE_VALUE)\r
+    {\r
+        return FALSE;\r
+    }\r
+\r
+       bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);\r
+       Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR);\r
+\r
+    if ((!bRet) || (dwSize != sizeof(MBR)))\r
+    {\r
+               CHECK_CLOSE_HANDLE(hDrive);\r
+        return FALSE;\r
+    }\r
+\r
+    if (MBR.Byte55 != 0x55 || MBR.ByteAA != 0xAA)\r
+    {\r
+        Log("Byte55 ByteAA not match 0x%x 0x%x", MBR.Byte55, MBR.ByteAA);\r
+               CHECK_CLOSE_HANDLE(hDrive);\r
+        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
+       if (MBR.PartTbl[0].FsFlag == 0xEE)\r
+       {\r
+               pGpt = malloc(sizeof(VTOY_GPT_INFO));\r
+               if (!pGpt)\r
+               {\r
+                       CHECK_CLOSE_HANDLE(hDrive);\r
+                       return FALSE;\r
+               }\r
+\r
+               SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);\r
+               bRet = ReadFile(hDrive, pGpt, sizeof(VTOY_GPT_INFO), &dwSize, NULL);\r
+               CHECK_CLOSE_HANDLE(hDrive);\r
+               if ((!bRet) || (dwSize != sizeof(VTOY_GPT_INFO)))\r
+               {\r
+                       Log("Failed to read gpt info %d %u %d", bRet, dwSize, LASTERR);\r
+                       return FALSE;\r
+               }\r
+\r
+               if (memcmp(pGpt->Head.Signature, "EFI PART", 8))\r
+               {\r
+                       Log("Invalid GPT signature");\r
+                       return FALSE;\r
+               }\r
+\r
+               if (memcmp(pGpt->PartTbl[1].Name, L"VTOYEFI", 7 * 2))\r
+               {\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
+               if (MBR.PartTbl[0].StartSectorId != 2048)\r
+               {\r
+                       Log("Part1 not match %u", MBR.PartTbl[0].StartSectorId);\r
+                       return FALSE;\r
+               }\r
+\r
+               PartStartSector = MBR.PartTbl[0].StartSectorId + MBR.PartTbl[0].SectorCount;\r
+               PartSectorCount = VENTOY_EFI_PART_SIZE / 512;\r
+\r
+               if (MBR.PartTbl[1].StartSectorId != PartStartSector ||\r
+                       MBR.PartTbl[1].SectorCount != PartSectorCount)\r
+               {\r
+                       Log("Part2 not match [0x%x 0x%x] [%u %u] [%u %u]",\r
+                               MBR.PartTbl[1].FsFlag, 0xEF,\r
+                               MBR.PartTbl[1].StartSectorId, PartStartSector,\r
+                               MBR.PartTbl[1].SectorCount, PartSectorCount);\r
+                       return FALSE;\r
+               }\r
+\r
+               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
+            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
+    Log("PhysicalDrive%d is ventoy disk", PhyDrive);\r
+    return TRUE;\r
+}\r
+\r
+\r
+static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)\r
+{\r
+    DWORD i; \r
+    DWORD LogDrive;\r
+    int Count = 0;\r
+    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
+    int LogLetter[VENTOY_MAX_PHY_DRIVE];\r
+    int PhyDriveId[VENTOY_MAX_PHY_DRIVE];\r
+\r
+    for (LogDrive = GetLogicalDrives(); LogDrive > 0; LogDrive >>= 1)\r
+    {\r
+        if (LogDrive & 0x01)\r
+        {\r
+            LogLetter[LetterCount] = Letter;\r
+            PhyDriveId[LetterCount] = GetPhyDriveByLogicalDrive(Letter);\r
+\r
+            Log("Logical Drive:%C  ===> PhyDrive:%d", LogLetter[LetterCount], PhyDriveId[LetterCount]);\r
+            LetterCount++;\r
+        }\r
+        \r
+        Letter++;\r
+    }    \r
+\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
+        if (g_FilterRemovable && (!CurDrive->RemovableMedia))\r
+        {\r
+            Log("<%s %s> is filtered for not removable.", CurDrive->VendorId, CurDrive->ProductId);\r
+            continue;\r
+        }\r
+\r
+        if (g_FilterUSB && CurDrive->BusType != BusTypeUsb)\r
+        {\r
+            Log("<%s %s> is filtered for not USB type.", CurDrive->VendorId, CurDrive->ProductId);\r
+            continue;\r
+        }\r
+        \r
+        CurDrive->Id = Id++;\r
+\r
+        for (Count = 0, Letter = 0; Letter < LetterCount; Letter++)\r
+        {\r
+            if (PhyDriveId[Letter] == CurDrive->PhyDrive)\r
+            {\r
+                if (Count + 1 < sizeof(CurDrive->DriveLetters) / sizeof(CHAR))\r
+                {\r
+                    CurDrive->DriveLetters[Count] = LogLetter[Letter];\r
+                }\r
+                Count++;\r
+            }\r
+        }\r
+\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
+            if (CurDrive->VentoyVersion[0] == 0)\r
+            {\r
+                CurDrive->VentoyVersion[0] = '?';\r
+                Log("Unknown Ventoy Version");\r
+            }\r
+        }\r
+    }\r
+\r
+    // for safe\r
+    for (i = 0; i < DriveCount; i++)\r
+    {\r
+        CurDrive = pDriveList + i;\r
+        if (CurDrive->Id < 0)\r
+        {\r
+            CurDrive->PhyDrive = 0x00FFFFFF;\r
+        }\r
+    }\r
+\r
+    return Id;\r
+}\r
+\r
+PHY_DRIVE_INFO * GetPhyDriveInfoById(int Id)\r
+{\r
+    DWORD i;\r
+    for (i = 0; i < g_PhyDriveCount; i++)\r
+    {\r
+        if (g_PhyDriveList[i].Id >= 0 && g_PhyDriveList[i].Id == Id)\r
+        {\r
+            return g_PhyDriveList + i;\r
+        }\r
+    }\r
+\r
+    return NULL;\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
+                                       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
+       return 0;\r
+}\r
+\r
+int Ventoy2DiskInit(void)\r
+{\r
+    Log("\n===================== Enum All PhyDrives =====================");\r
+    g_PhyDriveList = (PHY_DRIVE_INFO *)malloc(sizeof(PHY_DRIVE_INFO)* VENTOY_MAX_PHY_DRIVE);\r
+    if (NULL == g_PhyDriveList)\r
+    {\r
+        Log("Failed to alloc phy drive memory");\r
+        return FALSE;\r
+    }\r
+    memset(g_PhyDriveList, 0, sizeof(PHY_DRIVE_INFO)* VENTOY_MAX_PHY_DRIVE);\r
+\r
+    GetAllPhysicalDriveInfo(g_PhyDriveList, &g_PhyDriveCount);\r
+\r
+       SortPhysicalDrive(g_PhyDriveList, g_PhyDriveCount);\r
+\r
+    FilterPhysicalDrive(g_PhyDriveList, g_PhyDriveCount);\r
+\r
+    return 0;\r
+}\r
+\r
+int Ventoy2DiskDestroy(void)\r
+{\r
+    free(g_PhyDriveList);\r
+    return 0;\r
+}\r