Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251/* * PROJECT: ReactOS DiskPart * LICENSE: GPL - See COPYING in the top level directory * FILE: base/system/diskpart/clean.c * PURPOSE: Manages all the partitions of the OS in an interactive way. * PROGRAMMERS: Lee Schroeder */
#include "diskpart.h"
#define NDEBUG#include <debug.h>
EXIT_CODEclean_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 EXIT_SUCCESS; }
/* Do not allow to clean the boot disk */ if ((CurrentDisk->BiosFound == TRUE) && (CurrentDisk->BiosDiskNumber == 0)) { ConResPuts(StdOut, IDS_CLEAN_SYSTEM); return EXIT_SUCCESS; }
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->Mbr.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->Mbr.PartitionType != 0) && (IsContainerPartition(PartEntry->Mbr.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->PartitionStyle = PARTITION_STYLE_RAW;
/* Wipe the layout buffer */ RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDisk->LayoutBuffer);
LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) + ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION_EX)); CurrentDisk->LayoutBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, LayoutBufferSize); if (CurrentDisk->LayoutBuffer == NULL) { DPRINT1("Failed to allocate the disk layout buffer!\n"); return EXIT_SUCCESS; }
CurrentDisk->LayoutBuffer->PartitionStyle = PARTITION_STYLE_RAW;
/* 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 EXIT_SUCCESS;}