Files
reactos/base/system/diskpart/convert.c
Eric Kohl d2ae286c6b [DISKPART] Command function return EXIT_CODE instead of BOOL
This simplifies the implementation of the NOERR option.
2026-01-01 13:46:34 +01:00

194 lines
5.4 KiB
C

/*
* PROJECT: ReactOS DiskPart
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/system/diskpart/convert.c
* PURPOSE: Manages all the partitions of the OS in an interactive way.
* PROGRAMMERS: Lee Schroeder
*/
#include "diskpart.h"
#define NDEBUG
#include <debug.h>
NTSTATUS
CreateDisk(
_In_ ULONG DiskNumber,
_In_ PCREATE_DISK DiskInfo)
{
WCHAR DstPath[MAX_PATH];
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name;
HANDLE FileHandle = NULL;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
DPRINT("CreateDisk(%lu %p)\n", DiskNumber, DiskInfo);
StringCchPrintfW(DstPath, ARRAYSIZE(DstPath),
L"\\Device\\Harddisk%lu\\Partition0",
CurrentDisk->DiskNumber);
RtlInitUnicodeString(&Name, DstPath);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
&ObjectAttributes,
&Iosb,
0,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
goto done;
}
Status = NtDeviceIoControlFile(FileHandle,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_DISK_CREATE_DISK,
DiskInfo,
sizeof(*DiskInfo),
NULL,
0);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtDeviceIoControlFile() failed (Status %lx)\n", Status);
goto done;
}
/* Free the layout buffer */
if (CurrentDisk->LayoutBuffer)
RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDisk->LayoutBuffer);
CurrentDisk->LayoutBuffer = NULL;
CurrentDisk->ExtendedPartition = NULL;
CurrentDisk->Dirty = FALSE;
CurrentDisk->NewDisk = TRUE;
CurrentDisk->PartitionStyle = DiskInfo->PartitionStyle;
ReadLayoutBuffer(FileHandle, CurrentDisk);
done:
if (FileHandle)
NtClose(FileHandle);
return Status;
}
EXIT_CODE
ConvertGPT(
_In_ INT argc,
_In_ PWSTR *argv)
{
CREATE_DISK DiskInfo;
NTSTATUS Status;
DPRINT("ConvertGPT()\n");
if (CurrentDisk == NULL)
{
ConResPuts(StdOut, IDS_SELECT_NO_DISK);
return EXIT_SUCCESS;
}
if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT)
{
ConResPuts(StdOut, IDS_CONVERT_GPT_ALREADY);
return EXIT_SUCCESS;
}
if (GetPrimaryPartitionCount(CurrentDisk) != 0)
{
ConResPuts(StdOut, IDS_CONVERT_GPT_NOT_EMPTY);
return EXIT_SUCCESS;
}
#if 0
/* Fail if disk size is less than 128MB */
if (CurrentDisk->SectorCount.QuadPart * CurrentDisk->BytesPerSector < 128ULL * 1024ULL * 1024ULL)
{
ConResPuts(StdOut, IDS_CONVERT_GPT_TOO_SMALL);
return EXIT_SUCCESS;
}
#endif
DiskInfo.PartitionStyle = PARTITION_STYLE_GPT;
CreateGUID(&DiskInfo.Gpt.DiskId);
DiskInfo.Gpt.MaxPartitionCount = 128;
Status = CreateDisk(CurrentDisk->DiskNumber, &DiskInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("CreateDisk() failed!\n");
return EXIT_SUCCESS;
}
CurrentDisk->StartSector.QuadPart = AlignDown(CurrentDisk->LayoutBuffer->Gpt.StartingUsableOffset.QuadPart / CurrentDisk->BytesPerSector,
CurrentDisk->SectorAlignment) + (ULONGLONG)CurrentDisk->SectorAlignment;
CurrentDisk->EndSector.QuadPart = AlignDown(CurrentDisk->StartSector.QuadPart + (CurrentDisk->LayoutBuffer->Gpt.UsableLength.QuadPart / CurrentDisk->BytesPerSector) - 1,
CurrentDisk->SectorAlignment);
ScanForUnpartitionedGptDiskSpace(CurrentDisk);
ConResPuts(StdOut, IDS_CONVERT_GPT_SUCCESS);
return EXIT_SUCCESS;
}
EXIT_CODE
ConvertMBR(
_In_ INT argc,
_In_ PWSTR *argv)
{
CREATE_DISK DiskInfo;
NTSTATUS Status;
DPRINT("ConvertMBR()\n");
if (CurrentDisk == NULL)
{
ConResPuts(StdOut, IDS_SELECT_NO_DISK);
return EXIT_SUCCESS;
}
if ((CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR) ||
(CurrentDisk->PartitionStyle == PARTITION_STYLE_RAW))
{
ConResPuts(StdOut, IDS_CONVERT_MBR_ALREADY);
return EXIT_SUCCESS;
}
if (GetPrimaryPartitionCount(CurrentDisk) != 0)
{
ConResPuts(StdOut, IDS_CONVERT_MBR_NOT_EMPTY);
return EXIT_SUCCESS;
}
DiskInfo.PartitionStyle = PARTITION_STYLE_MBR;
CreateSignature(&DiskInfo.Mbr.Signature);
Status = CreateDisk(CurrentDisk->DiskNumber, &DiskInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("CreateDisk() failed!\n");
return EXIT_SUCCESS;
}
CurrentDisk->StartSector.QuadPart = (ULONGLONG)CurrentDisk->SectorAlignment;
CurrentDisk->EndSector.QuadPart = min(CurrentDisk->SectorCount.QuadPart, 0x100000000) - 1;
ScanForUnpartitionedMbrDiskSpace(CurrentDisk);
ConResPuts(StdOut, IDS_CONVERT_MBR_SUCCESS);
return EXIT_SUCCESS;
}