]> glassweightruler.freedombox.rocks Git - Ventoy.git/blobdiff - Ventoy2Disk/Ventoy2Disk/DiskService.c
Support TrueNAS Scale (Linux) distro. (#3069 #3137)
[Ventoy.git] / Ventoy2Disk / Ventoy2Disk / DiskService.c
index cbc27b8d2509879e6563ef7c1e7ee23b1b69c4fc..2eebde0d0e0d63b255682b7138cc627f4e31ef9c 100644 (file)
@@ -2,6 +2,7 @@
 * DiskService.c\r
 *\r
 * Copyright (c) 2021, longpanda <admin@ventoy.net>\r
+* Copyright (c) 2011-2021 Pete Batard <pete@akeo.ie>\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
 #include "Ventoy2Disk.h"\r
 #include "DiskService.h"\r
 \r
+static CHAR g_WindowsDir[MAX_PATH] = {0};\r
+\r
+const CHAR* DISK_GetWindowsDir(void)\r
+{\r
+       if (g_WindowsDir[0] == 0)\r
+       {\r
+               GetEnvironmentVariableA("SystemRoot", g_WindowsDir, MAX_PATH);\r
+               if (g_WindowsDir[0] == 0)\r
+               {\r
+                       sprintf_s(g_WindowsDir, MAX_PATH, "C:\\Windows");\r
+               }\r
+       }\r
+\r
+       return g_WindowsDir;\r
+}\r
+\r
 BOOL DISK_CleanDisk(int DriveIndex)\r
 {\r
        BOOL ret;\r
@@ -85,7 +102,7 @@ BOOL DISK_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Offset, UINT64 Attr)
        BOOL ret;\r
 \r
        ret = VDS_ChangeVtoyEFIAttr(DriveIndex, Offset, Attr);\r
-       \r
+\r
        return ret;\r
 }\r
 \r
@@ -118,29 +135,51 @@ typedef struct
        PCHAR Output;\r
 } TEXTOUTPUT, * PTEXTOUTPUT;\r
 \r
-// Callback command types\r
-typedef enum\r
-{\r
-       PROGRESS,\r
-       DONEWITHSTRUCTURE,\r
-       UNKNOWN2,\r
-       UNKNOWN3,\r
-       UNKNOWN4,\r
-       UNKNOWN5,\r
-       INSUFFICIENTRIGHTS,\r
-       UNKNOWN7,\r
-       UNKNOWN8,\r
-       UNKNOWN9,\r
-       UNKNOWNA,\r
-       DONE,\r
-       UNKNOWNC,\r
-       UNKNOWND,\r
-       OUTPUT,\r
-       STRUCTUREPROGRESS\r
-} CALLBACKCOMMAND;\r
+/* Callback command types (some errorcode were filled from HPUSBFW V2.2.3 and their\r
+   designation from docs.microsoft.com/windows/win32/api/vds/nf-vds-ivdsvolumemf2-formatex */\r
+typedef enum {\r
+       FCC_PROGRESS,\r
+       FCC_DONE_WITH_STRUCTURE,\r
+       FCC_UNKNOWN2,\r
+       FCC_INCOMPATIBLE_FILE_SYSTEM,\r
+       FCC_UNKNOWN4,\r
+       FCC_UNKNOWN5,\r
+       FCC_ACCESS_DENIED,\r
+       FCC_MEDIA_WRITE_PROTECTED,\r
+       FCC_VOLUME_IN_USE,\r
+       FCC_CANT_QUICK_FORMAT,\r
+       FCC_UNKNOWNA,\r
+       FCC_DONE,\r
+       FCC_BAD_LABEL,\r
+       FCC_UNKNOWND,\r
+       FCC_OUTPUT,\r
+       FCC_STRUCTURE_PROGRESS,\r
+       FCC_CLUSTER_SIZE_TOO_SMALL,\r
+       FCC_CLUSTER_SIZE_TOO_BIG,\r
+       FCC_VOLUME_TOO_SMALL,\r
+       FCC_VOLUME_TOO_BIG,\r
+       FCC_NO_MEDIA_IN_DRIVE,\r
+       FCC_UNKNOWN15,\r
+       FCC_UNKNOWN16,\r
+       FCC_UNKNOWN17,\r
+       FCC_DEVICE_NOT_READY,\r
+       FCC_CHECKDISK_PROGRESS,\r
+       FCC_UNKNOWN1A,\r
+       FCC_UNKNOWN1B,\r
+       FCC_UNKNOWN1C,\r
+       FCC_UNKNOWN1D,\r
+       FCC_UNKNOWN1E,\r
+       FCC_UNKNOWN1F,\r
+       FCC_READ_ONLY_MODE,\r
+       FCC_UNKNOWN21,\r
+       FCC_UNKNOWN22,\r
+       FCC_UNKNOWN23,\r
+       FCC_UNKNOWN24,\r
+       FCC_ALIGNMENT_VIOLATION,\r
+} FILE_SYSTEM_CALLBACK_COMMAND;\r
 \r
 // FMIFS callback definition\r
-typedef BOOLEAN(__stdcall* PFMIFSCALLBACK)(CALLBACKCOMMAND Command, DWORD SubAction, PVOID ActionInfo);\r
+typedef BOOLEAN(__stdcall* PFMIFSCALLBACK)(FILE_SYSTEM_CALLBACK_COMMAND Command, DWORD SubAction, PVOID ActionInfo);\r
 \r
 \r
 // Chkdsk command in FMIFS\r
@@ -167,36 +206,87 @@ typedef VOID(__stdcall* PFORMATEX)(PWCHAR DriveRoot,
        DWORD ClusterSize,\r
        PFMIFSCALLBACK Callback);\r
 \r
+#define FP_FORCE                            0x00000001\r
+#define FP_QUICK                            0x00000002\r
+#define FP_COMPRESSION                      0x00000004\r
+#define FP_DUPLICATE_METADATA               0x00000008\r
+#define FP_LARGE_FAT32                      0x00010000\r
+#define FP_NO_BOOT                          0x00020000\r
+#define FP_CREATE_PERSISTENCE_CONF          0x00040000\r
 \r
 // FormatExCallback\r
 static int g_dll_format_error = 0;\r
-BOOLEAN __stdcall FormatExCallback(CALLBACKCOMMAND Command, DWORD Modifier, PVOID Argument)\r
+BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, DWORD Modifier, PVOID Argument)\r
 {\r
        PDWORD percent;\r
        PBOOLEAN status;\r
 \r
-       switch (Command)\r
-       {\r
-       case PROGRESS:\r
+       switch (Command) {\r
+       case FCC_PROGRESS:\r
                percent = (PDWORD)Argument;\r
-               Log("Format percent: %d \n", *percent);\r
+               Log("Format percent: %u%%", *percent);\r
                break;\r
-\r
-       case OUTPUT:\r
+       case FCC_STRUCTURE_PROGRESS:    // No progress on quick format\r
+               Log("Creating file system...");\r
                break;\r
-\r
-       case DONE:\r
+       case FCC_DONE:\r
                status = (PBOOLEAN)Argument;\r
                if (*status == FALSE)\r
                {\r
+                       Log("Format error: %u ERROR_NOT_SUPPORTED=%u", LASTERR, ERROR_NOT_SUPPORTED);\r
                        g_dll_format_error = 1;\r
                }\r
                else\r
                {\r
+                       Log("Format Done");\r
                }\r
-\r
+               break;\r
+       case FCC_DONE_WITH_STRUCTURE:\r
+               Log("Format FCC_DONE_WITH_STRUCTURE");\r
+               break;\r
+       case FCC_INCOMPATIBLE_FILE_SYSTEM:\r
+               Log("Incompatible File System");\r
+               break;\r
+       case FCC_ACCESS_DENIED:\r
+               Log("Access denied");\r
+               break;\r
+       case FCC_MEDIA_WRITE_PROTECTED:\r
+               Log("Media is write protected");\r
+               break;\r
+       case FCC_VOLUME_IN_USE:\r
+               Log("Volume is in use");\r
+               break;\r
+       case FCC_DEVICE_NOT_READY:\r
+               Log("The device is not ready");\r
+               break;\r
+       case FCC_CANT_QUICK_FORMAT:\r
+               Log("Cannot quick format this volume");\r
+               break;\r
+       case FCC_BAD_LABEL:\r
+               Log("Bad label");\r
+               break;\r
+       case FCC_OUTPUT:\r
+               Log("%s", ((PTEXTOUTPUT)Argument)->Output);\r
+               break;\r
+       case FCC_CLUSTER_SIZE_TOO_BIG:\r
+       case FCC_CLUSTER_SIZE_TOO_SMALL:\r
+               Log("Unsupported cluster size");\r
+               break;\r
+       case FCC_VOLUME_TOO_BIG:\r
+       case FCC_VOLUME_TOO_SMALL:\r
+               Log("Volume is too %s", (Command == FCC_VOLUME_TOO_BIG) ? "big" : "small");\r
+               break;\r
+       case FCC_NO_MEDIA_IN_DRIVE:\r
+               Log("No media in drive");\r
+               break;\r
+       case FCC_ALIGNMENT_VIOLATION:\r
+               Log("Partition start offset is not aligned to the cluster size");\r
+               break;\r
+       default:\r
+               Log("FormatExCallback: Received unhandled command 0x%02X - aborting", Command);\r
                break;\r
        }\r
+\r
        return TRUE;\r
 }\r
 \r
@@ -244,7 +334,7 @@ BOOL DLL_FormatVolume(char DriveLetter, int fs, DWORD ClusterSize)
        g_dll_format_error = 0;\r
 \r
        Log("Call FormatEx Function for %C: %s ClusterSize=%u(%uKB)", DriveLetter, GetVentoyFsFmtNameByTypeA(fs), ClusterSize, ClusterSize / 1024);\r
-       FormatEx(RootDirectory, media, Format, Label, TRUE, ClusterSize, FormatExCallback);\r
+       FormatEx(RootDirectory, media, Format, Label, FP_FORCE | FP_QUICK, ClusterSize, FormatExCallback);\r
        FreeLibrary(ifsModule);\r
 \r
        if (g_dll_format_error)\r
@@ -260,24 +350,30 @@ BOOL DLL_FormatVolume(char DriveLetter, int fs, DWORD ClusterSize)
 \r
 BOOL DISK_FormatVolume(char DriveLetter, int fs, UINT64 VolumeSize)\r
 {\r
+       int i;\r
        DWORD ClusterSize = 0;\r
        BOOL ret = FALSE;\r
+       FmtFunc astFmtFunc[] =\r
+       {\r
+               FMT_DEF(VDS_FormatVolume),\r
+               FMT_DEF(DLL_FormatVolume),\r
+               FMT_DEF(PSHELL_FormatVolume),\r
+               FMT_DEF(DSPT_FormatVolume),\r
+               FMT_DEF(CMD_FormatVolume),\r
+               { NULL, NULL }\r
+       };\r
 \r
        ClusterSize = (DWORD)GetClusterSize();\r
        Log("DISK_FormatVolume %C:\\ %s VolumeSize=%llu ClusterSize=%u(%uKB)",\r
-               DriveLetter, GetVentoyFsNameByType(fs), (ULONGLONG)VolumeSize, ClusterSize, ClusterSize/1024);\r
+               DriveLetter, GetVentoyFsNameByType(fs), (ULONGLONG)VolumeSize, ClusterSize, ClusterSize / 1024);\r
 \r
-       ret = DLL_FormatVolume(DriveLetter, fs, ClusterSize);\r
-       if (!ret)\r
+       for (i = 0; astFmtFunc[i].formatFunc; i++)\r
        {\r
-               ret = VDS_FormatVolume(DriveLetter, fs, ClusterSize);\r
-               if (!ret)\r
+               Log("%s ...", astFmtFunc[i].name);\r
+               ret = astFmtFunc[i].formatFunc(DriveLetter, fs, ClusterSize);\r
+               if (ret)\r
                {\r
-                       ret = DSPT_FormatVolume(DriveLetter, fs, ClusterSize);\r
-                       if (!ret)\r
-                       {\r
-                               ret = PSHELL_FormatVolume(DriveLetter, fs, ClusterSize);\r
-                       }\r
+                       break;\r
                }\r
        }\r
 \r