https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2be7af18fe4a5517da843c3e9da52296d7e44f1d

commit 2be7af18fe4a5517da843c3e9da52296d7e44f1d
Author:     Eric Kohl <[email protected]>
AuthorDate: Fri Jun 17 01:37:26 2022 +0200
Commit:     Eric Kohl <[email protected]>
CommitDate: Fri Jun 17 01:37:26 2022 +0200

    [DISKPART] Implement the clean command
---
 base/system/diskpart/clean.c       | 236 ++++++++++++++++++++++++++++++++++++-
 base/system/diskpart/diskpart.h    |  12 +-
 base/system/diskpart/lang/de-DE.rc |   7 ++
 base/system/diskpart/lang/en-US.rc |   7 ++
 base/system/diskpart/lang/pl-PL.rc |   7 ++
 base/system/diskpart/lang/pt-PT.rc |   7 ++
 base/system/diskpart/lang/ro-RO.rc |   7 ++
 base/system/diskpart/lang/ru-RU.rc |   7 ++
 base/system/diskpart/lang/sq-AL.rc |   7 ++
 base/system/diskpart/lang/tr-TR.rc |   7 ++
 base/system/diskpart/lang/zh-CN.rc |   7 ++
 base/system/diskpart/lang/zh-TW.rc |   7 ++
 base/system/diskpart/partlist.c    |  78 ++++++++++--
 base/system/diskpart/resource.h    |   4 +
 14 files changed, 390 insertions(+), 10 deletions(-)

diff --git a/base/system/diskpart/clean.c b/base/system/diskpart/clean.c
index 145e7131b90..cd8014a5d91 100644
--- a/base/system/diskpart/clean.c
+++ b/base/system/diskpart/clean.c
@@ -8,7 +8,241 @@
 
 #include "diskpart.h"
 
-BOOL clean_main(INT argc, LPWSTR *argv)
+#define NDEBUG
+#include <debug.h>
+
+
+BOOL
+clean_main(
+    _In_ INT argc,
+    _In_ PWSTR *argv)
 {
+    PLIST_ENTRY Entry;
+    PPARTENTRY PartEntry;
+    PVOLENTRY VolumeEntry;
+    BOOL bAll = FALSE;
+    PUCHAR SectorsBuffer = NULL;
+    ULONG LayoutBufferSize, Size;
+    INT i;
+    WCHAR Buffer[MAX_PATH];
+    UNICODE_STRING Name;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK IoStatusBlock;
+    HANDLE FileHandle = NULL;
+    LARGE_INTEGER Offset, Count, MaxCount;
+    NTSTATUS Status;
+
+    DPRINT("Clean()\n");
+
+    if (CurrentDisk == NULL)
+    {
+        ConResPuts(StdOut, IDS_SELECT_NO_DISK);
+        return TRUE;
+    }
+
+    /* Do not allow to clean the boot disk */
+    if ((CurrentDisk->BiosFound == TRUE) &&
+        (CurrentDisk->BiosDiskNumber == 0))
+    {
+        ConResPuts(StdOut, IDS_CLEAN_SYSTEM);
+        return TRUE;
+    }
+
+    for (i = 1; i < argc; i++)
+    {
+        if (_wcsicmp(argv[1], L"all") == 0)
+        {
+            bAll = TRUE;
+        }
+    }
+
+    /* Dismount and remove all logical partitions */
+    while (!IsListEmpty(&CurrentDisk->LogicalPartListHead))
+    {
+        Entry = RemoveHeadList(&CurrentDisk->LogicalPartListHead);
+        PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+
+        /* Dismount the logical partition */
+        if (PartEntry->PartitionType != 0)
+        {
+            DismountVolume(PartEntry);
+            VolumeEntry = GetVolumeFromPartition(PartEntry);
+            if (VolumeEntry)
+                RemoveVolume(VolumeEntry);
+        }
+
+        /* Delete it */
+        RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
+    }
+
+    /* Dismount and remove all primary partitions */
+    while (!IsListEmpty(&CurrentDisk->PrimaryPartListHead))
+    {
+        Entry = RemoveHeadList(&CurrentDisk->PrimaryPartListHead);
+        PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+
+        /* Dismount the primary partition */
+        if ((PartEntry->PartitionType != 0) &&
+            (IsContainerPartition(PartEntry->PartitionType) == FALSE))
+        {
+            DismountVolume(PartEntry);
+            VolumeEntry = GetVolumeFromPartition(PartEntry);
+            if (VolumeEntry)
+                RemoveVolume(VolumeEntry);
+        }
+
+        /* Delete it */
+        RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
+    }
+
+    /* Initialize the disk entry */
+    CurrentDisk->ExtendedPartition = NULL;
+    CurrentDisk->Dirty = FALSE;
+    CurrentDisk->NewDisk = TRUE;
+    CurrentDisk->NoMbr = TRUE;
+
+    /* Wipe the layout buffer */
+    RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDisk->LayoutBuffer);
+
+    LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
+                       ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
+    CurrentDisk->LayoutBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                                HEAP_ZERO_MEMORY,
+                                                LayoutBufferSize);
+    if (CurrentDisk->LayoutBuffer == NULL)
+    {
+        DPRINT1("Failed to allocate the disk layout buffer!\n");
+        return TRUE;
+    }
+
+    /* Allocate a 1MB sectors buffer */
+    SectorsBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                    HEAP_ZERO_MEMORY,
+                                    1024 * 1024);
+    if (SectorsBuffer == NULL)
+    {
+        DPRINT1("Failed to allocate the sectors buffer!\n");
+        goto done;
+    }
+
+    /* Open the disk for writing */
+    StringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
+                     L"\\Device\\Harddisk%d\\Partition0",
+                     CurrentDisk->DiskNumber);
+
+    RtlInitUnicodeString(&Name, Buffer);
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &Name,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+
+    Status = NtOpenFile(&FileHandle,
+                        GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
+                        &ObjectAttributes,
+                        &IoStatusBlock,
+                        0,
+                        FILE_SYNCHRONOUS_IO_NONALERT);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to open the disk! (Status 0x%08lx)\n", Status);
+        ConResPuts(StdOut, IDS_CLEAN_FAIL);
+        goto done;
+    }
+
+    /* Clean sectors */
+    if (bAll)
+    {
+        MaxCount.QuadPart = (CurrentDisk->SectorCount.QuadPart * 
CurrentDisk->BytesPerSector) / (1024 * 1024);
+        for (Count.QuadPart = 0; Count.QuadPart < MaxCount.QuadPart; 
Count.QuadPart++)
+        {
+            Offset.QuadPart = Count.QuadPart * (1024 * 1024);
+            Status = NtWriteFile(FileHandle,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 &IoStatusBlock,
+                                 SectorsBuffer,
+                                 1024 * 1024,
+                                 &Offset,
+                                 NULL);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("Failed to write MB! (Status 0x%08lx)\n", Status);
+                ConResPuts(StdOut, IDS_CLEAN_FAIL);
+                goto done;
+            }
+        }
+
+        Size = (ULONG)(CurrentDisk->SectorCount.QuadPart * 
CurrentDisk->BytesPerSector) % (1024 * 1024);
+        if (Size != 0)
+        {
+            Offset.QuadPart += (1024 * 1024);
+            Status = NtWriteFile(FileHandle,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 &IoStatusBlock,
+                                 SectorsBuffer,
+                                 Size,
+                                 &Offset,
+                                 NULL);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("Failed to write the last part! (Status 0x%08lx)\n", 
Status);
+                ConResPuts(StdOut, IDS_CLEAN_FAIL);
+                goto done;
+            }
+        }
+    }
+    else
+    {
+        /* Clean the first MB */
+        Offset.QuadPart = 0;
+        Status = NtWriteFile(FileHandle,
+                             NULL,
+                             NULL,
+                             NULL,
+                             &IoStatusBlock,
+                             SectorsBuffer,
+                             1024 * 1024,
+                             &Offset,
+                             NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to write the first MB! (Status 0x%08lx)\n", 
Status);
+            ConResPuts(StdOut, IDS_CLEAN_FAIL);
+            goto done;
+        }
+
+        /* Clean the last MB */
+        Offset.QuadPart = (CurrentDisk->SectorCount.QuadPart * 
CurrentDisk->BytesPerSector) - (1024 * 1024);
+        Status = NtWriteFile(FileHandle,
+                             NULL,
+                             NULL,
+                             NULL,
+                             &IoStatusBlock,
+                             SectorsBuffer,
+                             1024 * 1024,
+                             &Offset,
+                             NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to write the last MB! (Status 0x%08lx)\n", Status);
+            ConResPuts(StdOut, IDS_CLEAN_FAIL);
+            goto done;
+        }
+    }
+
+    ConResPuts(StdOut, IDS_CLEAN_SUCCESS);
+
+done:
+    if (FileHandle != NULL)
+        NtClose(FileHandle);
+
+    if (SectorsBuffer != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, SectorsBuffer);
+
     return TRUE;
 }
diff --git a/base/system/diskpart/diskpart.h b/base/system/diskpart/diskpart.h
index fbf63bc7dc4..99f468f9916 100644
--- a/base/system/diskpart/diskpart.h
+++ b/base/system/diskpart/diskpart.h
@@ -22,6 +22,7 @@
 #include <winioctl.h>
 
 #include <errno.h>
+#include <strsafe.h>
 
 #include <conutils.h>
 
@@ -439,7 +440,16 @@ GetPrimaryPartitionCount(
 
 NTSTATUS
 DismountVolume(
-    IN PPARTENTRY PartEntry);
+    _In_ PPARTENTRY PartEntry);
+
+PVOLENTRY
+GetVolumeFromPartition(
+    _In_ PPARTENTRY PartEntry);
+
+VOID
+RemoveVolume(
+    _In_ PVOLENTRY VolumeEntry);
+
 
 /* recover.c */
 BOOL recover_main(INT argc, LPWSTR *argv);
diff --git a/base/system/diskpart/lang/de-DE.rc 
b/base/system/diskpart/lang/de-DE.rc
index 6de5a7687ba..bf8345d9b6f 100644
--- a/base/system/diskpart/lang/de-DE.rc
+++ b/base/system/diskpart/lang/de-DE.rc
@@ -22,6 +22,13 @@ BEGIN
     IDS_ACTIVE_ALREADY "\nDie aktuelle Partition wurde bereits als aktiv 
markiert.\n"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_CLEAN_FAIL "\nDer Datenträger konnte nicht bereinigt 
werden.\nMöglicherweise können die Daten auf diesem Datenträger nicht 
wiederhergestellt werden.\n"
+    IDS_CLEAN_SUCCESS "\nDer Datenträger wurde bereinigt.\n"
+    IDS_CLEAN_SYSTEM "\nDer gewählte Datenträger ist zum Ausführen des 
Computers erforderlich und kann nicht bereinigt werden.\n"
+END
+
 STRINGTABLE
 BEGIN
     IDS_CREATE_PARTITION_FAIL "\nDie angegebene Partition konnte nicht 
erstellt werden.\n"
diff --git a/base/system/diskpart/lang/en-US.rc 
b/base/system/diskpart/lang/en-US.rc
index e0e23003df4..af0d2185b11 100644
--- a/base/system/diskpart/lang/en-US.rc
+++ b/base/system/diskpart/lang/en-US.rc
@@ -22,6 +22,13 @@ BEGIN
     IDS_ACTIVE_ALREADY "\nThe current partition is already marked as active.\n"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_CLEAN_FAIL "\nDiskPart was unable to clean the disk.\nThe data on this 
disk may be unrecoverable.\n"
+    IDS_CLEAN_SUCCESS "\nDiskPart succeeded in cleaning the disk.\n"
+    IDS_CLEAN_SYSTEM "\nThe selected disk is neccessary to the operation of 
your computer, and may not be cleaned.\n"
+END
+
 STRINGTABLE
 BEGIN
     IDS_CREATE_PARTITION_FAIL "\nDiskPart was unable to create the specified 
partition.\n"
diff --git a/base/system/diskpart/lang/pl-PL.rc 
b/base/system/diskpart/lang/pl-PL.rc
index d15721a8809..f71ad8e1173 100644
--- a/base/system/diskpart/lang/pl-PL.rc
+++ b/base/system/diskpart/lang/pl-PL.rc
@@ -22,6 +22,13 @@ BEGIN
     IDS_ACTIVE_ALREADY "\nThe current partition is already marked as active.\n"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_CLEAN_FAIL "\nDiskPart was unable to clean the disk.\nThe data on this 
disk may be unrecoverable.\n"
+    IDS_CLEAN_SUCCESS "\nDiskPart succeeded in cleaning the disk.\n"
+    IDS_CLEAN_SYSTEM "\nThe selected disk is neccessary to the operation of 
your computer, and may not be cleaned.\n"
+END
+
 STRINGTABLE
 BEGIN
     IDS_CREATE_PARTITION_FAIL "\nDiskPart was unable to create the specified 
partition.\n"
diff --git a/base/system/diskpart/lang/pt-PT.rc 
b/base/system/diskpart/lang/pt-PT.rc
index 1187c52bad2..a9d210aee03 100644
--- a/base/system/diskpart/lang/pt-PT.rc
+++ b/base/system/diskpart/lang/pt-PT.rc
@@ -24,6 +24,13 @@ BEGIN
     IDS_ACTIVE_ALREADY "\nThe current partition is already marked as active.\n"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_CLEAN_FAIL "\nDiskPart was unable to clean the disk.\nThe data on this 
disk may be unrecoverable.\n"
+    IDS_CLEAN_SUCCESS "\nDiskPart succeeded in cleaning the disk.\n"
+    IDS_CLEAN_SYSTEM "\nThe selected disk is neccessary to the operation of 
your computer, and may not be cleaned.\n"
+END
+
 STRINGTABLE
 BEGIN
     IDS_CREATE_PARTITION_FAIL "\nDiskPart was unable to create the specified 
partition.\n"
diff --git a/base/system/diskpart/lang/ro-RO.rc 
b/base/system/diskpart/lang/ro-RO.rc
index 8ff6e4805f0..7bfd771a786 100644
--- a/base/system/diskpart/lang/ro-RO.rc
+++ b/base/system/diskpart/lang/ro-RO.rc
@@ -24,6 +24,13 @@ BEGIN
     IDS_ACTIVE_ALREADY "\nThe current partition is already marked as active.\n"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_CLEAN_FAIL "\nDiskPart was unable to clean the disk.\nThe data on this 
disk may be unrecoverable.\n"
+    IDS_CLEAN_SUCCESS "\nDiskPart succeeded in cleaning the disk.\n"
+    IDS_CLEAN_SYSTEM "\nThe selected disk is neccessary to the operation of 
your computer, and may not be cleaned.\n"
+END
+
 STRINGTABLE
 BEGIN
     IDS_CREATE_PARTITION_FAIL "\nDiskPart was unable to create the specified 
partition.\n"
diff --git a/base/system/diskpart/lang/ru-RU.rc 
b/base/system/diskpart/lang/ru-RU.rc
index 52a5058d27b..0dcb1fb3377 100644
--- a/base/system/diskpart/lang/ru-RU.rc
+++ b/base/system/diskpart/lang/ru-RU.rc
@@ -24,6 +24,13 @@ BEGIN
     IDS_ACTIVE_ALREADY "\nThe current partition is already marked as active.\n"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_CLEAN_FAIL "\nDiskPart was unable to clean the disk.\nThe data on this 
disk may be unrecoverable.\n"
+    IDS_CLEAN_SUCCESS "\nDiskPart succeeded in cleaning the disk.\n"
+    IDS_CLEAN_SYSTEM "\nThe selected disk is neccessary to the operation of 
your computer, and may not be cleaned.\n"
+END
+
 STRINGTABLE
 BEGIN
     IDS_CREATE_PARTITION_FAIL "\nDiskPart was unable to create the specified 
partition.\n"
diff --git a/base/system/diskpart/lang/sq-AL.rc 
b/base/system/diskpart/lang/sq-AL.rc
index 04943b671bf..26ca5044578 100644
--- a/base/system/diskpart/lang/sq-AL.rc
+++ b/base/system/diskpart/lang/sq-AL.rc
@@ -26,6 +26,13 @@ BEGIN
     IDS_ACTIVE_ALREADY "\nThe current partition is already marked as active.\n"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_CLEAN_FAIL "\nDiskPart was unable to clean the disk.\nThe data on this 
disk may be unrecoverable.\n"
+    IDS_CLEAN_SUCCESS "\nDiskPart succeeded in cleaning the disk.\n"
+    IDS_CLEAN_SYSTEM "\nThe selected disk is neccessary to the operation of 
your computer, and may not be cleaned.\n"
+END
+
 STRINGTABLE
 BEGIN
     IDS_CREATE_PARTITION_FAIL "\nDiskPart was unable to create the specified 
partition.\n"
diff --git a/base/system/diskpart/lang/tr-TR.rc 
b/base/system/diskpart/lang/tr-TR.rc
index 683a4bd5617..f13e48ef803 100644
--- a/base/system/diskpart/lang/tr-TR.rc
+++ b/base/system/diskpart/lang/tr-TR.rc
@@ -24,6 +24,13 @@ BEGIN
     IDS_ACTIVE_ALREADY "\nThe current partition is already marked as active.\n"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_CLEAN_FAIL "\nDiskPart was unable to clean the disk.\nThe data on this 
disk may be unrecoverable.\n"
+    IDS_CLEAN_SUCCESS "\nDiskPart succeeded in cleaning the disk.\n"
+    IDS_CLEAN_SYSTEM "\nThe selected disk is neccessary to the operation of 
your computer, and may not be cleaned.\n"
+END
+
 STRINGTABLE
 BEGIN
     IDS_CREATE_PARTITION_FAIL "\nDiskPart was unable to create the specified 
partition.\n"
diff --git a/base/system/diskpart/lang/zh-CN.rc 
b/base/system/diskpart/lang/zh-CN.rc
index ec002a4ac88..4f48fd8c7f2 100644
--- a/base/system/diskpart/lang/zh-CN.rc
+++ b/base/system/diskpart/lang/zh-CN.rc
@@ -31,6 +31,13 @@ BEGIN
     IDS_ACTIVE_ALREADY "\nThe current partition is already marked as active.\n"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_CLEAN_FAIL "\nDiskPart was unable to clean the disk.\nThe data on this 
disk may be unrecoverable.\n"
+    IDS_CLEAN_SUCCESS "\nDiskPart succeeded in cleaning the disk.\n"
+    IDS_CLEAN_SYSTEM "\nThe selected disk is neccessary to the operation of 
your computer, and may not be cleaned.\n"
+END
+
 STRINGTABLE
 BEGIN
     IDS_CREATE_PARTITION_FAIL "\nDiskPart was unable to create the specified 
partition.\n"
diff --git a/base/system/diskpart/lang/zh-TW.rc 
b/base/system/diskpart/lang/zh-TW.rc
index cb5751ed667..814cda7e40b 100644
--- a/base/system/diskpart/lang/zh-TW.rc
+++ b/base/system/diskpart/lang/zh-TW.rc
@@ -25,6 +25,13 @@ BEGIN
     IDS_ACTIVE_ALREADY "\nThe current partition is already marked as active.\n"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_CLEAN_FAIL "\nDiskPart was unable to clean the disk.\nThe data on this 
disk may be unrecoverable.\n"
+    IDS_CLEAN_SUCCESS "\nDiskPart succeeded in cleaning the disk.\n"
+    IDS_CLEAN_SYSTEM "\nThe selected disk is neccessary to the operation of 
your computer, and may not be cleaned.\n"
+END
+
 STRINGTABLE
 BEGIN
     IDS_CREATE_PARTITION_FAIL "\nDiskPart was unable to create the specified 
partition.\n"
diff --git a/base/system/diskpart/partlist.c b/base/system/diskpart/partlist.c
index 8d27b585ecc..713e54ca645 100644
--- a/base/system/diskpart/partlist.c
+++ b/base/system/diskpart/partlist.c
@@ -10,7 +10,6 @@
 
 #include "diskpart.h"
 #include <ntddscsi.h>
-#include <strsafe.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -1635,7 +1634,7 @@ IsSamePrimaryLayoutEntry(
 
 ULONG
 GetPrimaryPartitionCount(
-    IN PDISKENTRY DiskEntry)
+    _In_ PDISKENTRY DiskEntry)
 {
     PLIST_ENTRY Entry;
     PPARTENTRY PartEntry;
@@ -1657,7 +1656,7 @@ GetPrimaryPartitionCount(
 static
 ULONG
 GetLogicalPartitionCount(
-    IN PDISKENTRY DiskEntry)
+    _In_ PDISKENTRY DiskEntry)
 {
     PLIST_ENTRY ListEntry;
     PPARTENTRY PartEntry;
@@ -1679,7 +1678,7 @@ GetLogicalPartitionCount(
 static
 BOOLEAN
 ReAllocateLayoutBuffer(
-    IN PDISKENTRY DiskEntry)
+    _In_ PDISKENTRY DiskEntry)
 {
     PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
     ULONG NewPartitionCount;
@@ -1731,7 +1730,7 @@ ReAllocateLayoutBuffer(
 
 VOID
 UpdateDiskLayout(
-    IN PDISKENTRY DiskEntry)
+    _In_ PDISKENTRY DiskEntry)
 {
     PPARTITION_INFORMATION PartitionInfo;
     PPARTITION_INFORMATION LinkInfo = NULL;
@@ -1901,7 +1900,7 @@ UpdateDiskLayout(
 
 PPARTENTRY
 GetPrevUnpartitionedEntry(
-    IN PPARTENTRY PartEntry)
+    _In_ PPARTENTRY PartEntry)
 {
     PDISKENTRY DiskEntry = PartEntry->DiskEntry;
     PPARTENTRY PrevPartEntry;
@@ -1930,7 +1929,7 @@ GetPrevUnpartitionedEntry(
 
 PPARTENTRY
 GetNextUnpartitionedEntry(
-    IN PPARTENTRY PartEntry)
+    _In_ PPARTENTRY PartEntry)
 {
     PDISKENTRY DiskEntry = PartEntry->DiskEntry;
     PPARTENTRY NextPartEntry;
@@ -1958,7 +1957,7 @@ GetNextUnpartitionedEntry(
 
 NTSTATUS
 DismountVolume(
-    IN PPARTENTRY PartEntry)
+    _In_ PPARTENTRY PartEntry)
 {
     NTSTATUS Status;
     NTSTATUS LockStatus;
@@ -2063,4 +2062,67 @@ DismountVolume(
     return Status;
 }
 
+
+PVOLENTRY
+GetVolumeFromPartition(
+    _In_ PPARTENTRY PartEntry)
+{
+    PLIST_ENTRY Entry;
+    PVOLENTRY VolumeEntry;
+    ULONG i;
+
+    if ((PartEntry == NULL) ||
+        (PartEntry->DiskEntry == NULL))
+        return NULL;
+
+    Entry = VolumeListHead.Flink;
+    while (Entry != &VolumeListHead)
+    {
+        VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
+
+        if (VolumeEntry->pExtents == NULL)
+            return NULL;
+
+        for (i = 0; i < VolumeEntry->pExtents->NumberOfDiskExtents; i++)
+        {
+            if (VolumeEntry->pExtents->Extents[i].DiskNumber == 
PartEntry->DiskEntry->DiskNumber)
+            {
+                if ((VolumeEntry->pExtents->Extents[i].StartingOffset.QuadPart 
== PartEntry->StartSector.QuadPart * PartEntry->DiskEntry->BytesPerSector) &&
+                    (VolumeEntry->pExtents->Extents[i].ExtentLength.QuadPart 
== PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector))
+                    return VolumeEntry;
+            }
+        }
+
+        Entry = Entry->Flink;
+    }
+
+    return NULL;
+}
+
+
+VOID
+RemoveVolume(
+    _In_ PVOLENTRY VolumeEntry)
+{
+    if (VolumeEntry == NULL)
+        return;
+
+    if (VolumeEntry == CurrentVolume)
+        CurrentVolume = NULL;
+
+    RemoveEntryList(&VolumeEntry->ListEntry);
+
+    if (VolumeEntry->pszLabel)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszLabel);
+
+    if (VolumeEntry->pszFilesystem)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszFilesystem);
+
+    if (VolumeEntry->pExtents)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pExtents);
+
+    /* Release disk entry */
+    RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
+}
+
 /* EOF */
diff --git a/base/system/diskpart/resource.h b/base/system/diskpart/resource.h
index 5afab820c6f..ca9d401d3ff 100644
--- a/base/system/diskpart/resource.h
+++ b/base/system/diskpart/resource.h
@@ -22,6 +22,10 @@
 #define IDS_ACTIVE_SUCCESS             1001
 #define IDS_ACTIVE_ALREADY             1002
 
+#define IDS_CLEAN_FAIL                 1020
+#define IDS_CLEAN_SUCCESS              1021
+#define IDS_CLEAN_SYSTEM               1022
+
 #define IDS_CREATE_PARTITION_FAIL      1050
 #define IDS_CREATE_PARTITION_SUCCESS   1051
 

Reply via email to