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