Reactos
1/*
2 * PROJECT: ReactOS DiskPart
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/diskpart/convert.c
5 * PURPOSE: Manages all the partitions of the OS in an interactive way.
6 * PROGRAMMERS: Lee Schroeder
7 */
8
9#include "diskpart.h"
10
11#define NDEBUG
12#include <debug.h>
13
14NTSTATUS
15CreateDisk(
16 _In_ ULONG DiskNumber,
17 _In_ PCREATE_DISK DiskInfo)
18{
19 WCHAR DstPath[MAX_PATH];
20 OBJECT_ATTRIBUTES ObjectAttributes;
21 UNICODE_STRING Name;
22 HANDLE FileHandle = NULL;
23 IO_STATUS_BLOCK Iosb;
24 NTSTATUS Status;
25
26 DPRINT("CreateDisk(%lu %p)\n", DiskNumber, DiskInfo);
27
28 StringCchPrintfW(DstPath, ARRAYSIZE(DstPath),
29 L"\\Device\\Harddisk%lu\\Partition0",
30 CurrentDisk->DiskNumber);
31 RtlInitUnicodeString(&Name, DstPath);
32
33 InitializeObjectAttributes(&ObjectAttributes,
34 &Name,
35 OBJ_CASE_INSENSITIVE,
36 NULL,
37 NULL);
38
39 Status = NtOpenFile(&FileHandle,
40 GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
41 &ObjectAttributes,
42 &Iosb,
43 0,
44 FILE_SYNCHRONOUS_IO_NONALERT);
45 if (!NT_SUCCESS(Status))
46 {
47 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
48 goto done;
49 }
50
51 Status = NtDeviceIoControlFile(FileHandle,
52 NULL,
53 NULL,
54 NULL,
55 &Iosb,
56 IOCTL_DISK_CREATE_DISK,
57 DiskInfo,
58 sizeof(*DiskInfo),
59 NULL,
60 0);
61 if (!NT_SUCCESS(Status))
62 {
63 DPRINT1("NtDeviceIoControlFile() failed (Status %lx)\n", Status);
64 goto done;
65 }
66
67 /* Free the layout buffer */
68 if (CurrentDisk->LayoutBuffer)
69 RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDisk->LayoutBuffer);
70
71 CurrentDisk->LayoutBuffer = NULL;
72 CurrentDisk->ExtendedPartition = NULL;
73 CurrentDisk->Dirty = FALSE;
74 CurrentDisk->NewDisk = TRUE;
75 CurrentDisk->PartitionStyle = DiskInfo->PartitionStyle;
76
77 ReadLayoutBuffer(FileHandle, CurrentDisk);
78
79done:
80 if (FileHandle)
81 NtClose(FileHandle);
82
83 return Status;
84}
85
86
87EXIT_CODE
88ConvertGPT(
89 _In_ INT argc,
90 _In_ PWSTR *argv)
91{
92 CREATE_DISK DiskInfo;
93 NTSTATUS Status;
94
95 DPRINT("ConvertGPT()\n");
96
97 if (CurrentDisk == NULL)
98 {
99 ConResPuts(StdOut, IDS_SELECT_NO_DISK);
100 return EXIT_SUCCESS;
101 }
102
103 if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT)
104 {
105 ConResPuts(StdOut, IDS_CONVERT_GPT_ALREADY);
106 return EXIT_SUCCESS;
107 }
108
109 if (GetPrimaryPartitionCount(CurrentDisk) != 0)
110 {
111 ConResPuts(StdOut, IDS_CONVERT_GPT_NOT_EMPTY);
112 return EXIT_SUCCESS;
113 }
114
115#if 0
116 /* Fail if disk size is less than 128MB */
117 if (CurrentDisk->SectorCount.QuadPart * CurrentDisk->BytesPerSector < 128ULL * 1024ULL * 1024ULL)
118 {
119 ConResPuts(StdOut, IDS_CONVERT_GPT_TOO_SMALL);
120 return EXIT_SUCCESS;
121 }
122#endif
123
124 DiskInfo.PartitionStyle = PARTITION_STYLE_GPT;
125 CreateGUID(&DiskInfo.Gpt.DiskId);
126 DiskInfo.Gpt.MaxPartitionCount = 128;
127
128 Status = CreateDisk(CurrentDisk->DiskNumber, &DiskInfo);
129 if (!NT_SUCCESS(Status))
130 {
131 DPRINT1("CreateDisk() failed!\n");
132 return EXIT_SUCCESS;
133 }
134
135 CurrentDisk->StartSector.QuadPart = AlignDown(CurrentDisk->LayoutBuffer->Gpt.StartingUsableOffset.QuadPart / CurrentDisk->BytesPerSector,
136 CurrentDisk->SectorAlignment) + (ULONGLONG)CurrentDisk->SectorAlignment;
137 CurrentDisk->EndSector.QuadPart = AlignDown(CurrentDisk->StartSector.QuadPart + (CurrentDisk->LayoutBuffer->Gpt.UsableLength.QuadPart / CurrentDisk->BytesPerSector) - 1,
138 CurrentDisk->SectorAlignment);
139
140 ScanForUnpartitionedGptDiskSpace(CurrentDisk);
141 ConResPuts(StdOut, IDS_CONVERT_GPT_SUCCESS);
142
143 return EXIT_SUCCESS;
144}
145
146
147EXIT_CODE
148ConvertMBR(
149 _In_ INT argc,
150 _In_ PWSTR *argv)
151{
152 CREATE_DISK DiskInfo;
153 NTSTATUS Status;
154
155 DPRINT("ConvertMBR()\n");
156
157 if (CurrentDisk == NULL)
158 {
159 ConResPuts(StdOut, IDS_SELECT_NO_DISK);
160 return EXIT_SUCCESS;
161 }
162
163 if ((CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR) ||
164 (CurrentDisk->PartitionStyle == PARTITION_STYLE_RAW))
165 {
166 ConResPuts(StdOut, IDS_CONVERT_MBR_ALREADY);
167 return EXIT_SUCCESS;
168 }
169
170 if (GetPrimaryPartitionCount(CurrentDisk) != 0)
171 {
172 ConResPuts(StdOut, IDS_CONVERT_MBR_NOT_EMPTY);
173 return EXIT_SUCCESS;
174 }
175
176 DiskInfo.PartitionStyle = PARTITION_STYLE_MBR;
177 CreateSignature(&DiskInfo.Mbr.Signature);
178
179 Status = CreateDisk(CurrentDisk->DiskNumber, &DiskInfo);
180 if (!NT_SUCCESS(Status))
181 {
182 DPRINT1("CreateDisk() failed!\n");
183 return EXIT_SUCCESS;
184 }
185
186 CurrentDisk->StartSector.QuadPart = (ULONGLONG)CurrentDisk->SectorAlignment;
187 CurrentDisk->EndSector.QuadPart = min(CurrentDisk->SectorCount.QuadPart, 0x100000000) - 1;
188
189 ScanForUnpartitionedMbrDiskSpace(CurrentDisk);
190 ConResPuts(StdOut, IDS_CONVERT_MBR_SUCCESS);
191
192 return EXIT_SUCCESS;
193}