[DISKPART] Implement CREATE PARTITION EXTENDED and warn about unimplemented options
authorEric Kohl <eric.kohl@reactos.org>
Sat, 28 May 2022 11:17:45 +0000 (13:17 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 28 May 2022 11:17:45 +0000 (13:17 +0200)
base/system/diskpart/create.c

index 095bf4e..9fa6b18 100644 (file)
 
 BOOL
 CreateExtendedPartition(
-    INT argc,
-    PWSTR *argv)
+    _In_ INT argc,
+    _In_ PWSTR *argv)
 {
+    PPARTENTRY PartEntry, NewPartEntry;
+    PLIST_ENTRY ListEntry;
+    ULONGLONG ullSize = 0ULL;
+    ULONGLONG ullSectorCount;
+#if 0
+    ULONGLONG ullOffset = 0ULL;
+    BOOL bNoErr = FALSE;
+#endif
+    INT i;
+    PWSTR pszSuffix = NULL;
+
     if (CurrentDisk == NULL)
     {
         ConResPuts(StdOut, IDS_SELECT_NO_DISK);
         return TRUE;
     }
 
-    ConPrintf(StdOut, L"Not implemented yet!\n");
+    for (i = 3; i < argc; i++)
+    {
+        if (HasPrefix(argv[i], L"size=", &pszSuffix))
+        {
+            /* size=<N> (MB) */
+            DPRINT("Size : %s\n", pszSuffix);
+
+            ullSize = _wcstoui64(pszSuffix, NULL, 10);
+            if ((ullSize == 0) && (errno == ERANGE))
+            {
+                ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
+                return TRUE;
+            }
+        }
+        else if (HasPrefix(argv[i], L"offset=", &pszSuffix))
+        {
+            /* offset=<N> (KB) */
+            DPRINT("Offset : %s\n", pszSuffix);
+            ConPuts(StdOut, L"The OFFSET option is not supported yet!\n");
+#if 0
+            ullOffset = _wcstoui64(pszSuffix, NULL, 10);
+            if ((ullOffset == 0) && (errno == ERANGE))
+            {
+                ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
+                return TRUE;
+            }
+#endif
+        }
+        else if (HasPrefix(argv[i], L"align=", &pszSuffix))
+        {
+            /* align=<N> */
+            DPRINT("Align : %s\n", pszSuffix);
+            ConPuts(StdOut, L"The ALIGN option is not supported yet!\n");
+#if 0
+            bAlign = TRUE;
+#endif
+        }
+        else if (_wcsicmp(argv[i], L"noerr") == 0)
+        {
+            /* noerr */
+            DPRINT("NoErr\n", pszSuffix);
+            ConPuts(StdOut, L"The NOERR option is not supported yet!\n");
+#if 0
+            bNoErr = TRUE;
+#endif
+        }
+        else
+        {
+            ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
+            return TRUE;
+        }
+    }
+
+    DPRINT1("Size: %I64u\n", ullSize);
+#if 0
+    DPRINT1("Offset: %I64u\n", ullOffset);
+#endif
+
+    if (GetPrimaryPartitionCount(CurrentDisk) >= 4)
+    {
+        ConPuts(StdOut, L"No space left for an extended partition!\n");
+        return TRUE;
+    }
+
+    if (CurrentDisk->ExtendedPartition != NULL)
+    {
+        ConPuts(StdOut, L"We already have an extended partition on this disk!\n");
+        return TRUE;
+    }
+
+    if (ullSize != 0)
+        ullSectorCount = (ullSize * 1024 * 1024) / CurrentDisk->BytesPerSector;
+    else
+        ullSectorCount = 0;
+
+    DPRINT1("SectorCount: %I64u\n", ullSectorCount);
+
+    ListEntry = CurrentDisk->PrimaryPartListHead.Blink;
+
+    PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
+    if (PartEntry->IsPartitioned)
+    {
+        ConPuts(StdOut, L"No disk space left for an extended partition!\n");
+        return TRUE;
+    }
+
+    if (ullSectorCount == 0)
+    {
+        PartEntry->IsPartitioned = TRUE;
+        PartEntry->New = TRUE;
+        PartEntry->PartitionType = PARTITION_EXTENDED;
+        PartEntry->FormatState = Unformatted;
+        PartEntry->FileSystemName[0] = L'\0';
+
+        CurrentDisk->Dirty = TRUE;
+    }
+    else
+    {
+        if (PartEntry->SectorCount.QuadPart == ullSectorCount)
+        {
+            PartEntry->IsPartitioned = TRUE;
+            PartEntry->New = TRUE;
+            PartEntry->PartitionType = PARTITION_EXTENDED;
+            PartEntry->FormatState = Unformatted;
+            PartEntry->FileSystemName[0] = L'\0';
+
+            CurrentDisk->Dirty = TRUE;
+        }
+        else if (PartEntry->SectorCount.QuadPart > ullSectorCount)
+        {
+            NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PPARTENTRY));
+            if (NewPartEntry == NULL)
+            {
+                ConPuts(StdOut, L"Memory allocation failed!\n");
+                return TRUE;
+            }
+
+            NewPartEntry->DiskEntry = PartEntry->DiskEntry;
+
+            NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
+            NewPartEntry->SectorCount.QuadPart = ullSectorCount;
+
+            NewPartEntry->LogicalPartition = FALSE;
+            NewPartEntry->IsPartitioned = TRUE;
+            NewPartEntry->New = TRUE;
+            NewPartEntry->PartitionType = PARTITION_EXTENDED;
+            NewPartEntry->FormatState = Unformatted;
+            NewPartEntry->FileSystemName[0] = L'\0';
+
+            PartEntry->StartSector.QuadPart += ullSectorCount;
+            PartEntry->SectorCount.QuadPart -= ullSectorCount;
+
+            InsertTailList(ListEntry, &NewPartEntry->ListEntry);
+
+            CurrentDisk->Dirty = TRUE;
+        }
+    }
+
+    UpdateDiskLayout(CurrentDisk);
+    WritePartitions(CurrentDisk);
 
     return TRUE;
 }
@@ -31,8 +181,8 @@ CreateExtendedPartition(
 
 BOOL
 CreateLogicalPartition(
-    INT argc,
-    PWSTR *argv)
+    _In_ INT argc,
+    _In_ PWSTR *argv)
 {
     if (CurrentDisk == NULL)
     {
@@ -48,16 +198,19 @@ CreateLogicalPartition(
 
 BOOL
 CreatePrimaryPartition(
-    INT argc,
-    PWSTR *argv)
+    _In_ INT argc,
+    _In_ PWSTR *argv)
 {
     PPARTENTRY PartEntry, NewPartEntry;
     PLIST_ENTRY ListEntry;
-    ULONGLONG ullSize = 0ULL, ullOffset = 0ULL;
+    ULONGLONG ullSize = 0ULL;
     ULONGLONG ullSectorCount;
+#if 0
+    ULONGLONG ullOffset = 0ULL;
+    BOOL bNoErr = FALSE;
+#endif
     UCHAR PartitionType = 6;
     INT i, length;
-//    BOOL bNoErr = FALSE;
     PWSTR pszSuffix = NULL;
 
     if (CurrentDisk == NULL)
@@ -84,13 +237,15 @@ CreatePrimaryPartition(
         {
             /* offset=<N> (KB) */
             DPRINT("Offset : %s\n", pszSuffix);
-
+            ConPuts(StdOut, L"The OFFSET option is not supported yet!\n");
+#if 0
             ullOffset = _wcstoui64(pszSuffix, NULL, 10);
             if ((ullOffset == 0) && (errno == ERANGE))
             {
                 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
                 return TRUE;
             }
+#endif
         }
         else if (HasPrefix(argv[i], L"id=", &pszSuffix))
         {
@@ -124,13 +279,19 @@ CreatePrimaryPartition(
         {
             /* align=<N> */
             DPRINT("Align : %s\n", pszSuffix);
-//            bAlign = TRUE;
+            ConPuts(StdOut, L"The ALIGN option is not supported yet!\n");
+#if 0
+            bAlign = TRUE;
+#endif
         }
         else if (_wcsicmp(argv[i], L"noerr") == 0)
         {
             /* noerr */
             DPRINT("NoErr\n", pszSuffix);
-//            bNoErr = TRUE;
+            ConPuts(StdOut, L"The NOERR option is not supported yet!\n");
+#if 0
+            bNoErr = TRUE;
+#endif
         }
         else
         {
@@ -140,7 +301,9 @@ CreatePrimaryPartition(
     }
 
     DPRINT1("Size: %I64u\n", ullSize);
+#if 0
     DPRINT1("Offset: %I64u\n", ullOffset);
+#endif
     DPRINT1("Partition Type: %hx\n", PartitionType);
 
     if (GetPrimaryPartitionCount(CurrentDisk) >= 4)