- Bless halxbox too.
[reactos.git] / reactos / hal / halx86 / xbox / part_xbox.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: hal/halx86/xbox/part_xbox.c
6 * PURPOSE: Xbox specific handling of partition tables
7 * PROGRAMMER: Ge van Geldorp (gvg@reactos.com)
8 * UPDATE HISTORY:
9 * 2004/12/04: Created
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <halxbox.h>
15
16 #define NDEBUG
17 #include <debug.h>
18
19 #define XBOX_SIGNATURE_SECTOR 3
20 #define XBOX_SIGNATURE ('B' | ('R' << 8) | ('F' << 16) | ('R' << 24))
21 #define PARTITION_SIGNATURE 0xaa55
22
23 /* VARIABLES ***************************************************************/
24
25 static pHalExamineMBR NtoskrnlExamineMBR;
26 static pHalIoReadPartitionTable NtoskrnlIoReadPartitionTable;
27 static pHalIoSetPartitionInformation NtoskrnlIoSetPartitionInformation;
28 static pHalIoWritePartitionTable NtoskrnlIoWritePartitionTable;
29
30 static struct
31 {
32 ULONG SectorStart;
33 ULONG SectorCount;
34 CHAR PartitionType;
35 } XboxPartitions[] =
36 {
37 /* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */
38 { 0x0055F400, 0x0098f800, PARTITION_FAT32 }, /* Store, E: */
39 { 0x00465400, 0x000FA000, PARTITION_FAT_16 }, /* System, C: */
40 { 0x00000400, 0x00177000, PARTITION_FAT_16 }, /* Cache1, X: */
41 { 0x00177400, 0x00177000, PARTITION_FAT_16 }, /* Cache2, Y: */
42 { 0x002EE400, 0x00177000, PARTITION_FAT_16 } /* Cache3, Z: */
43 };
44
45 #define XBOX_PARTITION_COUNT (sizeof(XboxPartitions) / sizeof(XboxPartitions[0]))
46
47 /* FUNCTIONS ***************************************************************/
48
49
50 static NTSTATUS
51 HalpXboxReadSector(IN PDEVICE_OBJECT DeviceObject,
52 IN ULONG SectorSize,
53 IN PLARGE_INTEGER SectorOffset,
54 IN PVOID Sector)
55 {
56 IO_STATUS_BLOCK StatusBlock;
57 KEVENT Event;
58 PIRP Irp;
59 NTSTATUS Status;
60
61 DPRINT("HalpXboxReadSector(%p %lu 0x%08x%08x %p)\n",
62 DeviceObject, SectorSize, SectorOffset->u.HighPart, SectorOffset->u.LowPart, Sector);
63
64 ASSERT(DeviceObject);
65 ASSERT(Sector);
66
67 KeInitializeEvent(&Event,
68 NotificationEvent,
69 FALSE);
70
71 /* Read the sector */
72 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
73 DeviceObject,
74 Sector,
75 SectorSize,
76 SectorOffset,
77 &Event,
78 &StatusBlock);
79
80 Status = IoCallDriver(DeviceObject,
81 Irp);
82 if (Status == STATUS_PENDING)
83 {
84 KeWaitForSingleObject(&Event,
85 Executive,
86 KernelMode,
87 FALSE,
88 NULL);
89 Status = StatusBlock.Status;
90 }
91
92 if (!NT_SUCCESS(Status))
93 {
94 DPRINT("Reading sector failed (Status 0x%08lx)\n",
95 Status);
96 return Status;
97 }
98
99 return Status;
100 }
101
102 static NTSTATUS FASTCALL
103 HalpXboxDeviceHasXboxPartitioning(PDEVICE_OBJECT DeviceObject,
104 ULONG SectorSize,
105 BOOLEAN *HasXboxPartitioning)
106 {
107 PVOID SectorData;
108 LARGE_INTEGER Offset;
109 NTSTATUS Status;
110
111 DPRINT("HalpXboxDeviceHasXboxPartitioning(%p %lu %p)\n",
112 DeviceObject,
113 SectorSize,
114 HasXboxPartitioning);
115
116 SectorData = ExAllocatePool(PagedPool, SectorSize);
117 if (NULL == SectorData)
118 {
119 return STATUS_NO_MEMORY;
120 }
121
122 Offset.QuadPart = XBOX_SIGNATURE_SECTOR * SectorSize;
123 Status = HalpXboxReadSector(DeviceObject, SectorSize, &Offset, SectorData);
124 if (! NT_SUCCESS(Status))
125 {
126 return Status;
127 }
128
129 DPRINT("Signature 0x%02x 0x%02x 0x%02x 0x%02x\n",
130 *((UCHAR *) SectorData), *((UCHAR *) SectorData + 1), *((UCHAR *) SectorData + 2), *((UCHAR *) SectorData + 3));
131 *HasXboxPartitioning = (XBOX_SIGNATURE == *((ULONG *) SectorData));
132 ExFreePool(SectorData);
133 DPRINT("%s partitioning found\n", *HasXboxPartitioning ? "Xbox" : "MBR");
134
135 return STATUS_SUCCESS;
136 }
137
138 static VOID FASTCALL
139 HalpXboxExamineMBR(IN PDEVICE_OBJECT DeviceObject,
140 IN ULONG SectorSize,
141 IN ULONG MBRTypeIdentifier,
142 OUT PVOID *Buffer)
143 {
144 BOOLEAN HasXboxPartitioning;
145 NTSTATUS Status;
146
147 DPRINT("HalpXboxExamineMBR(%p %lu %lx %p)\n",
148 DeviceObject,
149 SectorSize,
150 MBRTypeIdentifier,
151 Buffer);
152
153 *Buffer = NULL;
154
155 Status = HalpXboxDeviceHasXboxPartitioning(DeviceObject, SectorSize, &HasXboxPartitioning);
156 if (! NT_SUCCESS(Status))
157 {
158 return;
159 }
160
161 if (! HasXboxPartitioning)
162 {
163 DPRINT("Delegating to standard MBR code\n");
164 NtoskrnlExamineMBR(DeviceObject, SectorSize, MBRTypeIdentifier, Buffer);
165 return;
166 }
167
168 /* Buffer already set to NULL */
169 return;
170 }
171
172 static NTSTATUS FASTCALL
173 HalpXboxIoReadPartitionTable(PDEVICE_OBJECT DeviceObject,
174 ULONG SectorSize,
175 BOOLEAN ReturnRecognizedPartitions,
176 PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
177 {
178 BOOLEAN HasXboxPartitioning;
179 NTSTATUS Status;
180 unsigned Part;
181 PPARTITION_INFORMATION PartInfo;
182
183 DPRINT("HalpXboxIoReadPartitionTable(%p %lu %x %p)\n",
184 DeviceObject,
185 SectorSize,
186 ReturnRecognizedPartitions,
187 PartitionBuffer);
188
189 Status = HalpXboxDeviceHasXboxPartitioning(DeviceObject, SectorSize, &HasXboxPartitioning);
190 if (! NT_SUCCESS(Status))
191 {
192 return Status;
193 }
194
195 if (! HasXboxPartitioning)
196 {
197 DPRINT("Delegating to standard MBR code\n");
198 return NtoskrnlIoReadPartitionTable(DeviceObject, SectorSize,
199 ReturnRecognizedPartitions, PartitionBuffer);
200 }
201
202 *PartitionBuffer = (PDRIVE_LAYOUT_INFORMATION)
203 ExAllocatePool(PagedPool,
204 sizeof(DRIVE_LAYOUT_INFORMATION) +
205 XBOX_PARTITION_COUNT * sizeof(PARTITION_INFORMATION));
206 if (NULL == *PartitionBuffer)
207 {
208 return STATUS_NO_MEMORY;
209 }
210 (*PartitionBuffer)->PartitionCount = XBOX_PARTITION_COUNT;
211 (*PartitionBuffer)->Signature = PARTITION_SIGNATURE;
212 for (Part = 0; Part < XBOX_PARTITION_COUNT; Part++)
213 {
214 PartInfo = (*PartitionBuffer)->PartitionEntry + Part;
215 PartInfo->StartingOffset.QuadPart = (ULONGLONG) XboxPartitions[Part].SectorStart *
216 (ULONGLONG) SectorSize;
217 PartInfo->PartitionLength.QuadPart = (ULONGLONG) XboxPartitions[Part].SectorCount *
218 (ULONGLONG) SectorSize;
219 PartInfo->HiddenSectors = 0;
220 PartInfo->PartitionNumber = Part + 1;
221 PartInfo->PartitionType = XboxPartitions[Part].PartitionType;
222 PartInfo->BootIndicator = FALSE;
223 PartInfo->RecognizedPartition = TRUE;
224 PartInfo->RewritePartition = FALSE;
225 DPRINT(" %ld: nr: %d boot: %1x type: %x start: 0x%I64x count: 0x%I64x rec: %d\n",
226 Part,
227 PartInfo->PartitionNumber,
228 PartInfo->BootIndicator,
229 PartInfo->PartitionType,
230 PartInfo->StartingOffset.QuadPart,
231 PartInfo->PartitionLength.QuadPart,
232 PartInfo->RecognizedPartition);
233 }
234
235 return STATUS_SUCCESS;
236 }
237
238 static NTSTATUS FASTCALL
239 HalpXboxIoSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject,
240 IN ULONG SectorSize,
241 IN ULONG PartitionNumber,
242 IN ULONG PartitionType)
243 {
244 BOOLEAN HasXboxPartitioning;
245 NTSTATUS Status;
246
247 DPRINT("HalpXboxIoSetPartitionInformation(%p %lu %lu %lu)\n",
248 DeviceObject,
249 SectorSize,
250 PartitionNumber,
251 PartitionType);
252
253 Status = HalpXboxDeviceHasXboxPartitioning(DeviceObject, SectorSize, &HasXboxPartitioning);
254 if (! NT_SUCCESS(Status))
255 {
256 return Status;
257 }
258
259 if (! HasXboxPartitioning)
260 {
261 DPRINT("Delegating to standard MBR code\n");
262 return NtoskrnlIoSetPartitionInformation(DeviceObject, SectorSize,
263 PartitionNumber, PartitionType);
264 }
265
266 /* Can't change the partitioning */
267 DPRINT1("Xbox partitions are fixed, can't change them\n");
268 return STATUS_ACCESS_DENIED;
269 }
270
271 static NTSTATUS FASTCALL
272 HalpXboxIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject,
273 IN ULONG SectorSize,
274 IN ULONG SectorsPerTrack,
275 IN ULONG NumberOfHeads,
276 IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
277 {
278 BOOLEAN HasXboxPartitioning;
279 NTSTATUS Status;
280
281 DPRINT("HalpXboxIoWritePartitionTable(%p %lu %lu %lu %p)\n",
282 DeviceObject,
283 SectorSize,
284 SectorsPerTrack,
285 NumberOfHeads,
286 PartitionBuffer);
287
288 Status = HalpXboxDeviceHasXboxPartitioning(DeviceObject, SectorSize, &HasXboxPartitioning);
289 if (! NT_SUCCESS(Status))
290 {
291 return Status;
292 }
293
294 if (! HasXboxPartitioning)
295 {
296 DPRINT("Delegating to standard MBR code\n");
297 return NtoskrnlIoWritePartitionTable(DeviceObject, SectorSize,
298 SectorsPerTrack, NumberOfHeads,
299 PartitionBuffer);
300 }
301
302 /* Can't change the partitioning */
303 DPRINT1("Xbox partitions are fixed, can't change them\n");
304 return STATUS_ACCESS_DENIED;
305 }
306
307 #define HalExamineMBR HALDISPATCH->HalExamineMBR
308
309 void
310 HalpXboxInitPartIo(void)
311 {
312 NtoskrnlExamineMBR = HalExamineMBR;
313 HalExamineMBR = HalpXboxExamineMBR;
314 NtoskrnlIoReadPartitionTable = HalIoReadPartitionTable;
315 HalIoReadPartitionTable = HalpXboxIoReadPartitionTable;
316 NtoskrnlIoSetPartitionInformation = HalIoSetPartitionInformation;
317 HalIoSetPartitionInformation = HalpXboxIoSetPartitionInformation;
318 NtoskrnlIoWritePartitionTable = HalIoWritePartitionTable;
319 HalIoWritePartitionTable = HalpXboxIoWritePartitionTable;
320 }
321
322 /* EOF */