mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 13:13:00 +00:00
[DISKPART] Implement the clean command
This commit is contained in:
parent
74870c1ae1
commit
2be7af18fe
14 changed files with 390 additions and 10 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue