https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9504a38f52fe2ac4fc2d0…
commit 9504a38f52fe2ac4fc2d0581b4049699d79691f8
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Fri Nov 16 03:02:28 2018 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Nov 25 15:03:47 2018 +0100
[SETUPLIB] Dismount a disk partition before deleting it.
---
base/setup/lib/utils/partlist.c | 117 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 116 insertions(+), 1 deletion(-)
diff --git a/base/setup/lib/utils/partlist.c b/base/setup/lib/utils/partlist.c
index 10ec9d6db6..89178ae014 100644
--- a/base/setup/lib/utils/partlist.c
+++ b/base/setup/lib/utils/partlist.c
@@ -2706,6 +2706,111 @@ CreateLogicalPartition(
return TRUE;
}
+static
+NTSTATUS
+DismountVolume(
+ IN PPARTENTRY PartEntry)
+{
+ NTSTATUS Status;
+ NTSTATUS LockStatus;
+ UNICODE_STRING Name;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE PartitionHandle;
+ WCHAR Buffer[MAX_PATH];
+
+ /* Check whether the partition is valid and may have been mounted in the system */
+ if (!PartEntry->IsPartitioned ||
+ PartEntry->PartitionType == PARTITION_ENTRY_UNUSED ||
+ IsContainerPartition(PartEntry->PartitionType) ||
+ !IsRecognizedPartition(PartEntry->PartitionType) ||
+ PartEntry->FormatState == Unformatted /* || PartEntry->FormatState ==
UnknownFormat */ ||
+ PartEntry->FileSystem == NULL ||
+ PartEntry->PartitionNumber == 0)
+ {
+ /* The partition is not mounted, so just return success */
+ return STATUS_SUCCESS;
+ }
+
+ /* Open the volume */
+ RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
+ L"\\Device\\Harddisk%lu\\Partition%lu",
+ PartEntry->DiskEntry->DiskNumber,
+ PartEntry->PartitionNumber);
+ RtlInitUnicodeString(&Name, Buffer);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtOpenFile(&PartitionHandle,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status
0x%lx)\n", &Name, Status);
+ return Status;
+ }
+
+ /* Lock the volume */
+ LockStatus = NtFsControlFile(PartitionHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_LOCK_VOLUME,
+ NULL,
+ 0,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(LockStatus))
+ {
+ DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status
0x%lx)\n", LockStatus);
+ }
+
+ /* Dismount the volume */
+ Status = NtFsControlFile(PartitionHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_DISMOUNT_VOLUME,
+ NULL,
+ 0,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
+ }
+
+ /* Unlock the volume */
+ LockStatus = NtFsControlFile(PartitionHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_UNLOCK_VOLUME,
+ NULL,
+ 0,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(LockStatus))
+ {
+ DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
+ }
+
+ /* Close the volume */
+ NtClose(PartitionHandle);
+
+ return Status;
+}
+
VOID
DeleteCurrentPartition(
IN PPARTLIST List)
@@ -2734,19 +2839,29 @@ DeleteCurrentPartition(
DiskEntry = List->CurrentDisk;
PartEntry = List->CurrentPartition;
- /* Delete all logical partition entries if an extended partition will be deleted */
+ /* Check which type of partition (primary/logical or extended) is being deleted */
if (DiskEntry->ExtendedPartition == PartEntry)
{
+ /* An extended partition is being deleted: delete all logical partition entries
*/
while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
{
Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+ /* Dismount the logical partition */
+ DismountVolume(LogicalPartEntry);
+
+ /* Delete it */
RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry);
}
DiskEntry->ExtendedPartition = NULL;
}
+ else
+ {
+ /* A primary partition is being deleted: dismount it */
+ DismountVolume(PartEntry);
+ }
/* Adjust unpartitioned disk space entries */