strip whitespace from end of lines
[reactos.git] / reactos / ntoskrnl / io / rawfs.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/rawfs.c
6 * PURPOSE: Raw filesystem driver
7 *
8 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 /* TYPES *******************************************************************/
18
19 typedef struct _RAWFS_GLOBAL_DATA
20 {
21 PDRIVER_OBJECT DriverObject;
22 PDEVICE_OBJECT DeviceObject;
23 ULONG Flags;
24 ERESOURCE VolumeListLock;
25 LIST_ENTRY VolumeListHead;
26 NPAGED_LOOKASIDE_LIST FcbLookasideList;
27 NPAGED_LOOKASIDE_LIST CcbLookasideList;
28 } RAWFS_GLOBAL_DATA, *PRAWFS_GLOBAL_DATA, VCB, *PVCB;
29
30 typedef struct _RAWFS_DEVICE_EXTENSION
31 {
32 KSPIN_LOCK FcbListLock;
33 LIST_ENTRY FcbListHead;
34 PDEVICE_OBJECT StorageDevice;
35 ULONG Flags;
36 struct _RAWFS_FCB *VolumeFcb;
37 LIST_ENTRY VolumeListEntry;
38 } RAWFS_DEVICE_EXTENSION, *PRAWFS_DEVICE_EXTENSION;
39
40 typedef struct _RAWFS_IRP_CONTEXT
41 {
42 PIRP Irp;
43 PDEVICE_OBJECT DeviceObject;
44 PRAWFS_DEVICE_EXTENSION DeviceExt;
45 ULONG Flags;
46 WORK_QUEUE_ITEM WorkQueueItem;
47 PIO_STACK_LOCATION Stack;
48 UCHAR MajorFunction;
49 UCHAR MinorFunction;
50 PFILE_OBJECT FileObject;
51 } RAWFS_IRP_CONTEXT, *PRAWFS_IRP_CONTEXT;
52
53 #define IRPCONTEXT_CANWAIT 0x0001
54
55 #define FCB_CACHE_INITIALIZED 0x0001
56 #define FCB_DELETE_PENDING 0x0002
57 #define FCB_IS_FAT 0x0004
58 #define FCB_IS_PAGE_FILE 0x0008
59 #define FCB_IS_VOLUME 0x0010
60
61 typedef struct _RAWFS_FCB
62 {
63 /* Start FCB header required by ReactOS/Windows NT */
64 FSRTL_COMMON_FCB_HEADER RFCB;
65 SECTION_OBJECT_POINTERS SectionObjectPointers;
66 ERESOURCE MainResource;
67 ERESOURCE PagingIoResource;
68 /* End FCB header required by ReactOS/Windows NT */
69
70 /* Reference count */
71 LONG RefCount;
72
73 /* List of FCB's for this volume */
74 LIST_ENTRY FcbListEntry;
75
76 /* Pointer to the parent fcb */
77 struct _RAWFS_FCB* ParentFcb;
78
79 /* Flags for the FCB */
80 ULONG Flags;
81
82 /* Pointer to the file object which has initialized the fcb */
83 PFILE_OBJECT FileObject;
84 } RAWFS_FCB, *PRAWFS_FCB;
85
86 typedef struct _RAWFS_CCB
87 {
88 LARGE_INTEGER CurrentByteOffset;
89 } RAWFS_CCB, *PRAWFS_CCB;
90
91 /* GLOBALS ******************************************************************/
92
93 #define TAG_IRP TAG('R', 'I', 'R', 'P')
94
95 static PDRIVER_OBJECT RawFsDriverObject;
96 static PDEVICE_OBJECT DiskDeviceObject;
97 static PDEVICE_OBJECT CdromDeviceObject;
98 static PDEVICE_OBJECT TapeDeviceObject;
99 static NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
100 static LONG RawFsQueueCount = 0;
101
102 /* FUNCTIONS *****************************************************************/
103
104 BOOLEAN
105 RawFsIsRawFileSystemDeviceObject(IN PDEVICE_OBJECT DeviceObject)
106 {
107 DPRINT("RawFsIsRawFileSystemDeviceObject(DeviceObject %x)\n", DeviceObject);
108
109 if (DeviceObject == DiskDeviceObject)
110 return TRUE;
111 if (DeviceObject == CdromDeviceObject)
112 return TRUE;
113 if (DeviceObject == TapeDeviceObject)
114 return TRUE;
115 return FALSE;
116 }
117
118 static NTSTATUS
119 RawFsDispatchRequest(IN PRAWFS_IRP_CONTEXT IrpContext);
120
121 /*static */NTSTATUS
122 RawFsReadDisk(IN PDEVICE_OBJECT pDeviceObject,
123 IN PLARGE_INTEGER ReadOffset,
124 IN ULONG ReadLength,
125 IN OUT PUCHAR Buffer)
126 {
127 IO_STATUS_BLOCK IoStatus;
128 NTSTATUS Status;
129 KEVENT Event;
130 PIRP Irp;
131
132 KeInitializeEvent(&Event, NotificationEvent, FALSE);
133
134 DPRINT("RawFsReadDisk(pDeviceObject %x, Offset %I64x, Length %d, Buffer %x)\n",
135 pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
136
137 DPRINT ("Building synchronous FSD Request...\n");
138 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
139 pDeviceObject,
140 Buffer,
141 ReadLength,
142 ReadOffset,
143 &Event,
144 &IoStatus);
145 if (Irp == NULL)
146 {
147 DPRINT("IoBuildSynchronousFsdRequest() failed\n");
148 return STATUS_UNSUCCESSFUL;
149 }
150
151 DPRINT("Calling IO Driver... with irp %x\n", Irp);
152 Status = IoCallDriver(pDeviceObject, Irp);
153
154 DPRINT("Waiting for IO Operation for %x\n", Irp);
155 if (Status == STATUS_PENDING)
156 {
157 DPRINT("Operation pending\n");
158 KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
159 DPRINT("Getting IO Status... for %x\n", Irp);
160 Status = IoStatus.Status;
161 }
162
163 if (!NT_SUCCESS(Status))
164 {
165 DPRINT("RawFsReadDisk() failed. Status %x\n", Status);
166 DPRINT("(pDeviceObject %x, Offset %I64x, Size %d, Buffer %x\n",
167 pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
168 return Status;
169 }
170 DPRINT("Block request succeeded for %x\n", Irp);
171 return STATUS_SUCCESS;
172 }
173
174 /*static */NTSTATUS
175 RawFsWriteDisk(IN PDEVICE_OBJECT pDeviceObject,
176 IN PLARGE_INTEGER WriteOffset,
177 IN ULONG WriteLength,
178 IN PUCHAR Buffer)
179 {
180 IO_STATUS_BLOCK IoStatus;
181 NTSTATUS Status;
182 KEVENT Event;
183 PIRP Irp;
184
185 DPRINT("RawFsWriteDisk(pDeviceObject %x, Offset %I64x, Size %d, Buffer %x)\n",
186 pDeviceObject, WriteOffset->QuadPart, WriteLength, Buffer);
187
188 KeInitializeEvent(&Event, NotificationEvent, FALSE);
189
190 DPRINT("Building synchronous FSD Request...\n");
191 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
192 pDeviceObject,
193 Buffer,
194 WriteLength,
195 WriteOffset,
196 &Event,
197 &IoStatus);
198 if (!Irp)
199 {
200 DPRINT("IoBuildSynchronousFsdRequest()\n");
201 return(STATUS_UNSUCCESSFUL);
202 }
203
204 DPRINT("Calling IO Driver...\n");
205 Status = IoCallDriver(pDeviceObject, Irp);
206
207 DPRINT("Waiting for IO Operation...\n");
208 if (Status == STATUS_PENDING)
209 {
210 KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
211 DPRINT("Getting IO Status...\n");
212 Status = IoStatus.Status;
213 }
214 if (!NT_SUCCESS(Status))
215 {
216 DPRINT("RawFsWriteDisk() failed. Status %x\n", Status);
217 DPRINT("(pDeviceObject %x, Offset %I64x, Size %d, Buffer %x\n",
218 pDeviceObject, WriteOffset->QuadPart, WriteLength, Buffer);
219 return Status;
220 }
221
222 return STATUS_SUCCESS;
223 }
224
225 static NTSTATUS
226 RawFsBlockDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
227 IN ULONG CtlCode,
228 IN PVOID InputBuffer,
229 IN ULONG InputBufferSize,
230 IN OUT PVOID OutputBuffer,
231 IN OUT PULONG pOutputBufferSize)
232 {
233 ULONG OutputBufferSize = 0;
234 KEVENT Event;
235 PIRP Irp;
236 IO_STATUS_BLOCK IoStatus;
237 NTSTATUS Status;
238
239 DPRINT("RawFsBlockDeviceIoControl(DeviceObject %x, CtlCode %x, "
240 "InputBuffer %x, InputBufferSize %x, OutputBuffer %x, "
241 "POutputBufferSize %x (%x)\n", DeviceObject, CtlCode,
242 InputBuffer, InputBufferSize, OutputBuffer, pOutputBufferSize,
243 pOutputBufferSize ? *pOutputBufferSize : 0);
244
245 if (pOutputBufferSize)
246 {
247 OutputBufferSize = *pOutputBufferSize;
248 }
249
250 KeInitializeEvent(&Event, NotificationEvent, FALSE);
251
252 DPRINT("Building device I/O control request ...\n");
253 Irp = IoBuildDeviceIoControlRequest(CtlCode,
254 DeviceObject,
255 InputBuffer,
256 InputBufferSize,
257 OutputBuffer,
258 OutputBufferSize,
259 FALSE,
260 &Event,
261 &IoStatus);
262 if (Irp == NULL)
263 {
264 DPRINT("IoBuildDeviceIoControlRequest failed\n");
265 return STATUS_INSUFFICIENT_RESOURCES;
266 }
267
268 DPRINT("Calling IO Driver... with irp %x\n", Irp);
269 Status = IoCallDriver(DeviceObject, Irp);
270
271 DPRINT("Waiting for IO Operation for %x\n", Irp);
272 if (Status == STATUS_PENDING)
273 {
274 DPRINT("Operation pending\n");
275 KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
276 DPRINT("Getting IO Status... for %x\n", Irp);
277 Status = IoStatus.Status;
278 }
279 if (OutputBufferSize)
280 {
281 *pOutputBufferSize = OutputBufferSize;
282 }
283 DPRINT("Returning Status %x\n", Status);
284 return Status;
285 }
286
287 static PRAWFS_FCB
288 RawFsNewFCB(IN PRAWFS_GLOBAL_DATA pGlobalData)
289 {
290 PRAWFS_FCB Fcb;
291
292 Fcb = ExAllocateFromNPagedLookasideList(&pGlobalData->FcbLookasideList);
293 memset(Fcb, 0, sizeof(RAWFS_FCB));
294 ExInitializeResourceLite(&Fcb->PagingIoResource);
295 ExInitializeResourceLite(&Fcb->MainResource);
296 // FsRtlInitializeFileLock(&Fcb->FileLock, NULL, NULL);
297 return Fcb;
298 }
299
300 static VOID
301 RawFsDestroyFCB(IN PRAWFS_GLOBAL_DATA pGlobalData, IN PRAWFS_FCB pFcb)
302 {
303 //FsRtlUninitializeFileLock(&pFcb->FileLock);
304 ExDeleteResourceLite(&pFcb->PagingIoResource);
305 ExDeleteResourceLite(&pFcb->MainResource);
306 ExFreeToNPagedLookasideList(&pGlobalData->FcbLookasideList, pFcb);
307 }
308
309 static PRAWFS_CCB
310 RawFsNewCCB(PRAWFS_GLOBAL_DATA pGlobalData)
311 {
312 PRAWFS_CCB Ccb;
313
314 Ccb = ExAllocateFromNPagedLookasideList(&pGlobalData->CcbLookasideList);
315 memset(Ccb, 0, sizeof(RAWFS_CCB));
316 return Ccb;
317 }
318
319 /*static */VOID
320 RawFsDestroyCCB(PRAWFS_GLOBAL_DATA pGlobalData, PRAWFS_CCB pCcb)
321 {
322 ExFreeToNPagedLookasideList(&pGlobalData->CcbLookasideList, pCcb);
323 }
324
325 static PRAWFS_IRP_CONTEXT
326 RawFsAllocateIrpContext(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
327 {
328 PRAWFS_GLOBAL_DATA GlobalData;
329 PRAWFS_IRP_CONTEXT IrpContext;
330 UCHAR MajorFunction;
331
332 DPRINT("RawFsAllocateIrpContext(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
333
334 ASSERT(DeviceObject);
335 ASSERT(Irp);
336
337 GlobalData = (PRAWFS_GLOBAL_DATA) DeviceObject->DeviceExtension;
338 IrpContext = ExAllocateFromNPagedLookasideList(&IrpContextLookasideList);
339 if (IrpContext)
340 {
341 RtlZeroMemory(IrpContext, sizeof(IrpContext));
342 IrpContext->Irp = Irp;
343 IrpContext->DeviceObject = DeviceObject;
344 IrpContext->DeviceExt = DeviceObject->DeviceExtension;
345 IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp);
346 ASSERT(IrpContext->Stack);
347 MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction;
348 IrpContext->MinorFunction = IrpContext->Stack->MinorFunction;
349 IrpContext->FileObject = IrpContext->Stack->FileObject;
350 if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
351 MajorFunction == IRP_MJ_DEVICE_CONTROL ||
352 MajorFunction == IRP_MJ_SHUTDOWN)
353 {
354 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
355 }
356 else if (MajorFunction != IRP_MJ_CLEANUP &&
357 MajorFunction != IRP_MJ_CLOSE &&
358 IoIsOperationSynchronous(Irp))
359 {
360 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
361 }
362 }
363 return IrpContext;
364 }
365
366 static VOID
367 RawFsFreeIrpContext(IN PRAWFS_IRP_CONTEXT IrpContext)
368 {
369 DPRINT("RawFsFreeIrpContext(IrpContext %x)\n", IrpContext);
370
371 ASSERT(IrpContext);
372
373 ExFreeToNPagedLookasideList(&IrpContextLookasideList, IrpContext);
374 }
375
376 static VOID
377 STDCALL RawFsDoRequest(PVOID IrpContext)
378 {
379 ULONG Count;
380
381 Count = InterlockedDecrement(&RawFsQueueCount);
382
383 DPRINT("RawFsDoRequest(IrpContext %x), MajorFunction %x, %d\n",
384 IrpContext, ((PRAWFS_IRP_CONTEXT) IrpContext)->MajorFunction, Count);
385
386 RawFsDispatchRequest((PRAWFS_IRP_CONTEXT) IrpContext);
387 }
388
389 static NTSTATUS
390 RawFsQueueRequest(PRAWFS_IRP_CONTEXT IrpContext)
391 {
392 ULONG Count;
393
394 ASSERT(IrpContext != NULL);
395 ASSERT(IrpContext->Irp != NULL);
396
397 Count = InterlockedIncrement(&RawFsQueueCount);
398
399 DPRINT("RawFsQueueRequest (IrpContext %x), %d\n", IrpContext, Count);
400
401 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
402 IoMarkIrpPending (IrpContext->Irp);
403 ExInitializeWorkItem (&IrpContext->WorkQueueItem, RawFsDoRequest, IrpContext);
404 ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
405 return STATUS_PENDING;
406 }
407
408 static NTSTATUS
409 RawFsClose(IN PRAWFS_IRP_CONTEXT IrpContext)
410 {
411 DPRINT("RawFsClose(IrpContext %x)\n", IrpContext);
412 UNIMPLEMENTED;
413 return STATUS_NOT_IMPLEMENTED;
414 }
415
416 static NTSTATUS
417 RawFsCreateFile(IN PRAWFS_IRP_CONTEXT IrpContext)
418 {
419 PRAWFS_DEVICE_EXTENSION DeviceExt;
420 PRAWFS_GLOBAL_DATA GlobalData;
421 PIO_STACK_LOCATION IoSp;
422 PFILE_OBJECT FileObject;
423 ULONG RequestedDisposition;
424 ULONG RequestedOptions;
425 PRAWFS_FCB pFcb;
426 PRAWFS_CCB pCcb;
427
428 GlobalData = (PRAWFS_GLOBAL_DATA) IrpContext->DeviceObject->DeviceExtension;
429 IoSp = IoGetCurrentIrpStackLocation(IrpContext->Irp);
430 RequestedDisposition = ((IoSp->Parameters.Create.Options >> 24) & 0xff);
431 RequestedOptions = IoSp->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
432 FileObject = IoSp->FileObject;
433 DeviceExt = IrpContext->DeviceObject->DeviceExtension;
434
435 if (FileObject->FileName.Length == 0 &&
436 FileObject->RelatedFileObject == NULL)
437 {
438 /* This a open operation for the volume itself */
439 if (RequestedDisposition == FILE_CREATE
440 || RequestedDisposition == FILE_OVERWRITE_IF
441 || RequestedDisposition == FILE_SUPERSEDE)
442 {
443 return STATUS_ACCESS_DENIED;
444 }
445 if (RequestedOptions & FILE_DIRECTORY_FILE)
446 {
447 return STATUS_NOT_A_DIRECTORY;
448 }
449 pFcb = DeviceExt->VolumeFcb;
450 pCcb = RawFsNewCCB(GlobalData);
451 if (pCcb == NULL)
452 {
453 return (STATUS_INSUFFICIENT_RESOURCES);
454 }
455
456 FileObject->SectionObjectPointer = &pFcb->SectionObjectPointers;
457 FileObject->FsContext = pFcb;
458 FileObject->FsContext2 = pCcb;
459 pFcb->RefCount++;
460
461 IrpContext->Irp->IoStatus.Information = FILE_OPENED;
462 return(STATUS_SUCCESS);
463 }
464
465 /* This filesystem driver only supports volume access */
466 return(STATUS_INVALID_PARAMETER);
467 }
468
469 static NTSTATUS
470 RawFsCreate(IN PRAWFS_IRP_CONTEXT IrpContext)
471 {
472 NTSTATUS Status;
473
474 DPRINT("RawFsCreate(IrpContext %x)\n", IrpContext);
475
476 ASSERT(IrpContext);
477
478 if (RawFsIsRawFileSystemDeviceObject(IrpContext->DeviceObject))
479 {
480 /* DeviceObject represents FileSystem instead of logical volume */
481 DPRINT("RawFsCreate() called with file system\n");
482 IrpContext->Irp->IoStatus.Information = FILE_OPENED;
483 IrpContext->Irp->IoStatus.Status = STATUS_SUCCESS;
484 IoCompleteRequest(IrpContext->Irp, IO_DISK_INCREMENT);
485 RawFsFreeIrpContext(IrpContext);
486 return STATUS_SUCCESS;
487 }
488
489 if (!(IrpContext->Flags & IRPCONTEXT_CANWAIT))
490 {
491 return RawFsQueueRequest(IrpContext);
492 }
493
494 IrpContext->Irp->IoStatus.Information = 0;
495
496 Status = RawFsCreateFile(IrpContext);
497
498 IrpContext->Irp->IoStatus.Status = Status;
499 IoCompleteRequest(IrpContext->Irp,
500 (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
501 RawFsFreeIrpContext(IrpContext);
502
503 return Status;
504 }
505
506 static NTSTATUS
507 RawFsRead(IN PRAWFS_IRP_CONTEXT IrpContext)
508 {
509 DPRINT("RawFsRead(IrpContext %x)\n", IrpContext);
510 UNIMPLEMENTED;
511 return STATUS_NOT_IMPLEMENTED;
512 }
513
514 static NTSTATUS
515 RawFsWrite(IN PRAWFS_IRP_CONTEXT IrpContext)
516 {
517 DPRINT("RawFsWrite(IrpContext %x)\n", IrpContext);
518 UNIMPLEMENTED;
519 return STATUS_NOT_IMPLEMENTED;
520 }
521
522 static NTSTATUS
523 RawFsMount(IN PRAWFS_IRP_CONTEXT IrpContext)
524 {
525 PRAWFS_GLOBAL_DATA GlobalData = NULL;
526 PDEVICE_OBJECT DeviceObject = NULL;
527 PRAWFS_DEVICE_EXTENSION DeviceExt = NULL;
528 PRAWFS_FCB VolumeFcb = NULL;
529 PRAWFS_FCB Fcb = NULL;
530 PARTITION_INFORMATION PartitionInfo;
531 DISK_GEOMETRY DiskGeometry;
532 LARGE_INTEGER VolumeSize;
533 NTSTATUS Status;
534 ULONG Size;
535
536 DPRINT("RawFsMount(IrpContext %x)\n", IrpContext);
537
538 ASSERT(IrpContext);
539
540 if (!RawFsIsRawFileSystemDeviceObject(IrpContext->DeviceObject))
541 {
542 Status = STATUS_INVALID_DEVICE_REQUEST;
543 DPRINT("Not for me\n");
544 goto ByeBye;
545 }
546
547 GlobalData = (PRAWFS_GLOBAL_DATA) IrpContext->DeviceObject->DeviceExtension;
548
549 Status = IoCreateDevice(GlobalData->DriverObject,
550 sizeof(RAWFS_DEVICE_EXTENSION),
551 NULL,
552 FILE_DEVICE_FILE_SYSTEM,
553 0,
554 FALSE,
555 &DeviceObject);
556 if (!NT_SUCCESS(Status))
557 {
558 goto ByeBye;
559 }
560
561 DeviceObject->Flags |= DO_DIRECT_IO;
562 DeviceExt = (PVOID) DeviceObject->DeviceExtension;
563 RtlZeroMemory(DeviceExt, sizeof(RAWFS_DEVICE_EXTENSION));
564
565 /* Use same vpb as device disk */
566 DeviceObject->Vpb = IrpContext->Stack->Parameters.MountVolume.DeviceObject->Vpb;
567 DeviceExt->StorageDevice = IrpContext->Stack->Parameters.MountVolume.DeviceObject;
568 DeviceExt->StorageDevice->Vpb->DeviceObject = DeviceObject;
569 DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
570 DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
571 DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
572 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
573
574 KeInitializeSpinLock(&DeviceExt->FcbListLock);
575 InitializeListHead(&DeviceExt->FcbListHead);
576
577 /* First try getting harddisk geometry then try getting CD-ROM geometry */
578 Size = sizeof(DISK_GEOMETRY);
579 Status = RawFsBlockDeviceIoControl(
580 IrpContext->Stack->Parameters.MountVolume.DeviceObject,
581 IOCTL_DISK_GET_DRIVE_GEOMETRY,
582 NULL,
583 0,
584 &DiskGeometry,
585 &Size);
586 if (!NT_SUCCESS(Status))
587 {
588 DPRINT("RawFsBlockDeviceIoControl failed with status 0x%.08x\n", Status);
589 goto ByeBye;
590 }
591 if (DiskGeometry.MediaType == FixedMedia)
592 {
593 // We have found a hard disk
594 Size = sizeof(PARTITION_INFORMATION);
595 Status = RawFsBlockDeviceIoControl(
596 IrpContext->Stack->Parameters.MountVolume.DeviceObject,
597 IOCTL_DISK_GET_PARTITION_INFO,
598 NULL,
599 0,
600 &PartitionInfo,
601 &Size);
602 if (!NT_SUCCESS(Status))
603 {
604 DPRINT("RawFsBlockDeviceIoControl() failed (%x)\n", Status);
605 goto ByeBye;
606 }
607 #ifndef NDEBUG
608 DbgPrint("Partition Information:\n");
609 DbgPrint("StartingOffset %u\n", PartitionInfo.StartingOffset.QuadPart);
610 DbgPrint("PartitionLength %u\n", PartitionInfo.PartitionLength.QuadPart);
611 DbgPrint("HiddenSectors %u\n", PartitionInfo.HiddenSectors);
612 DbgPrint("PartitionNumber %u\n", PartitionInfo.PartitionNumber);
613 DbgPrint("PartitionType %u\n", PartitionInfo.PartitionType);
614 DbgPrint("BootIndicator %u\n", PartitionInfo.BootIndicator);
615 DbgPrint("RecognizedPartition %u\n", PartitionInfo.RecognizedPartition);
616 DbgPrint("RewritePartition %u\n", PartitionInfo.RewritePartition);
617 #endif
618 VolumeSize.QuadPart = PartitionInfo.PartitionLength.QuadPart;
619 }
620 else if (DiskGeometry.MediaType > Unknown && DiskGeometry.MediaType <= RemovableMedia)
621 {
622 Status = STATUS_UNRECOGNIZED_VOLUME;
623 goto ByeBye;
624 }
625
626 VolumeFcb = RawFsNewFCB(GlobalData);
627 if (VolumeFcb == NULL)
628 {
629 Status = STATUS_INSUFFICIENT_RESOURCES;
630 goto ByeBye;
631 }
632
633 VolumeFcb->Flags = FCB_IS_VOLUME;
634 VolumeFcb->RFCB.FileSize.QuadPart = VolumeSize.QuadPart;
635 VolumeFcb->RFCB.ValidDataLength.QuadPart = VolumeFcb->RFCB.FileSize.QuadPart;
636 VolumeFcb->RFCB.AllocationSize.QuadPart = VolumeFcb->RFCB.FileSize.QuadPart;
637 DeviceExt->VolumeFcb = VolumeFcb;
638
639 KeEnterCriticalRegion();
640 ExAcquireResourceExclusiveLite(&GlobalData->VolumeListLock, TRUE);
641 InsertHeadList(&GlobalData->VolumeListHead, &DeviceExt->VolumeListEntry);
642 ExReleaseResourceLite(&GlobalData->VolumeListLock);
643 KeLeaveCriticalRegion();
644
645 /* No serial number */
646 DeviceObject->Vpb->SerialNumber = 0;
647
648 /* Set volume label (no label) */
649 *(DeviceObject->Vpb->VolumeLabel) = 0;
650 DeviceObject->Vpb->VolumeLabelLength = 0;
651
652 Status = STATUS_SUCCESS;
653
654 ByeBye:
655 if (!NT_SUCCESS(Status))
656 {
657 DPRINT("RAWFS: RawFsMount() Status 0x%.08x\n", Status);
658
659 if (Fcb)
660 RawFsDestroyFCB(GlobalData, Fcb);
661 if (DeviceObject)
662 IoDeleteDevice(DeviceObject);
663 if (VolumeFcb)
664 RawFsDestroyFCB(GlobalData, VolumeFcb);
665 }
666 return Status;
667 }
668
669 static NTSTATUS
670 RawFsFileSystemControl(IN PRAWFS_IRP_CONTEXT IrpContext)
671 {
672 NTSTATUS Status;
673
674 DPRINT("RawFsFileSystemControl(IrpContext %x)\n", IrpContext);
675
676 ASSERT(IrpContext);
677
678 switch (IrpContext->MinorFunction)
679 {
680 case IRP_MN_USER_FS_REQUEST:
681 DPRINT("RawFs FSC: IRP_MN_USER_FS_REQUEST\n");
682 Status = STATUS_INVALID_DEVICE_REQUEST;
683 break;
684
685 case IRP_MN_MOUNT_VOLUME:
686 DPRINT("RawFs FSC: IRP_MN_MOUNT_VOLUME\n");
687 Status = RawFsMount(IrpContext);
688 break;
689
690 case IRP_MN_VERIFY_VOLUME:
691 DPRINT("RawFs FSC: IRP_MN_VERIFY_VOLUME\n");
692 Status = STATUS_INVALID_DEVICE_REQUEST;
693 break;
694
695 default:
696 DPRINT("RawFs FSC: MinorFunction %d\n", IrpContext->MinorFunction);
697 Status = STATUS_INVALID_DEVICE_REQUEST;
698 break;
699 }
700
701 IrpContext->Irp->IoStatus.Status = Status;
702 IrpContext->Irp->IoStatus.Information = 0;
703
704 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
705 RawFsFreeIrpContext(IrpContext);
706 return Status;
707 }
708
709 static NTSTATUS
710 RawFsQueryInformation(IN PRAWFS_IRP_CONTEXT IrpContext)
711 {
712 DPRINT("RawFsQueryInformation(IrpContext %x)\n", IrpContext);
713 UNIMPLEMENTED;
714 return STATUS_NOT_IMPLEMENTED;
715 }
716
717 static NTSTATUS
718 RawFsSetInformation(IN PRAWFS_IRP_CONTEXT IrpContext)
719 {
720 DPRINT("RawFsSetInformation(IrpContext %x)\n", IrpContext);
721 UNIMPLEMENTED;
722 return STATUS_NOT_IMPLEMENTED;
723 }
724
725 static NTSTATUS
726 RawFsDirectoryControl(IN PRAWFS_IRP_CONTEXT IrpContext)
727 {
728 DPRINT("RawFsDirectoryControl(IrpContext %x)\n", IrpContext);
729 UNIMPLEMENTED;
730 return STATUS_NOT_IMPLEMENTED;
731 }
732
733 static NTSTATUS
734 RawFsQueryVolumeInformation(IN PRAWFS_IRP_CONTEXT IrpContext)
735 {
736 DPRINT("RawFsQueryVolumeInformation(IrpContext %x)\n", IrpContext);
737 UNIMPLEMENTED;
738 return STATUS_NOT_IMPLEMENTED;
739 }
740
741 static NTSTATUS
742 RawFsSetVolumeInformation(IN PRAWFS_IRP_CONTEXT IrpContext)
743 {
744 DPRINT("RawFsSetVolumeInformation(IrpContext %x)\n", IrpContext);
745 UNIMPLEMENTED;
746 return STATUS_NOT_IMPLEMENTED;
747 }
748
749 static NTSTATUS
750 RawFsLockControl(IN PRAWFS_IRP_CONTEXT IrpContext)
751 {
752 DPRINT("RawFsLockControl(IrpContext %x)\n", IrpContext);
753 UNIMPLEMENTED;
754 return STATUS_NOT_IMPLEMENTED;
755 }
756
757 static NTSTATUS
758 RawFsCleanup(IN PRAWFS_IRP_CONTEXT IrpContext)
759 {
760 DPRINT("RawFsCleanup(IrpContext %x)\n", IrpContext);
761 UNIMPLEMENTED;
762 return STATUS_NOT_IMPLEMENTED;
763 }
764
765 static NTSTATUS
766 RawFsFlush(IN PRAWFS_IRP_CONTEXT IrpContext)
767 {
768 DPRINT("RawFsFlush(IrpContext %x)\n", IrpContext);
769 UNIMPLEMENTED;
770 return STATUS_NOT_IMPLEMENTED;
771 }
772
773 static NTSTATUS STDCALL
774 RawFsShutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
775 {
776 DPRINT("RawFsShutdown(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
777
778 /*
779 * Note: Do NOT call UNIMPLEMENTED here!
780 * This function must finish in order to shutdown ReactOS properly!
781 */
782
783 return STATUS_NOT_IMPLEMENTED;
784 }
785
786 static NTSTATUS
787 RawFsDispatchRequest(IN PRAWFS_IRP_CONTEXT IrpContext)
788 {
789 DPRINT("RawFsDispatchRequest(IrpContext %x), MajorFunction %x\n",
790 IrpContext, IrpContext->MajorFunction);
791
792 ASSERT(IrpContext);
793
794 switch (IrpContext->MajorFunction)
795 {
796 case IRP_MJ_CLOSE:
797 return RawFsClose(IrpContext);
798 case IRP_MJ_CREATE:
799 return RawFsCreate (IrpContext);
800 case IRP_MJ_READ:
801 return RawFsRead (IrpContext);
802 case IRP_MJ_WRITE:
803 return RawFsWrite (IrpContext);
804 case IRP_MJ_FILE_SYSTEM_CONTROL:
805 return RawFsFileSystemControl(IrpContext);
806 case IRP_MJ_QUERY_INFORMATION:
807 return RawFsQueryInformation (IrpContext);
808 case IRP_MJ_SET_INFORMATION:
809 return RawFsSetInformation (IrpContext);
810 case IRP_MJ_DIRECTORY_CONTROL:
811 return RawFsDirectoryControl(IrpContext);
812 case IRP_MJ_QUERY_VOLUME_INFORMATION:
813 return RawFsQueryVolumeInformation(IrpContext);
814 case IRP_MJ_SET_VOLUME_INFORMATION:
815 return RawFsSetVolumeInformation(IrpContext);
816 case IRP_MJ_LOCK_CONTROL:
817 return RawFsLockControl(IrpContext);
818 case IRP_MJ_CLEANUP:
819 return RawFsCleanup(IrpContext);
820 case IRP_MJ_FLUSH_BUFFERS:
821 return RawFsFlush(IrpContext);
822 default:
823 DPRINT1("Unexpected major function %x\n", IrpContext->MajorFunction);
824 IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
825 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
826 RawFsFreeIrpContext(IrpContext);
827 return STATUS_DRIVER_INTERNAL_ERROR;
828 }
829 }
830
831 static NTSTATUS STDCALL
832 RawFsBuildRequest(IN PDEVICE_OBJECT DeviceObject,
833 IN PIRP Irp)
834 {
835 PRAWFS_IRP_CONTEXT IrpContext;
836 NTSTATUS Status;
837
838 DPRINT("RawFsBuildRequest(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
839
840 ASSERT(DeviceObject);
841 ASSERT(Irp);
842
843 IrpContext = RawFsAllocateIrpContext(DeviceObject, Irp);
844 if (IrpContext == NULL)
845 {
846 Status = STATUS_INSUFFICIENT_RESOURCES;
847 Irp->IoStatus.Status = Status;
848 IoCompleteRequest(Irp, IO_NO_INCREMENT);
849 }
850 else
851 {
852 if (KeGetCurrentIrql() <= PASSIVE_LEVEL)
853 {
854 FsRtlEnterFileSystem();
855 }
856 else
857 {
858 DPRINT1("RawFs is entered at irql = %d\n", KeGetCurrentIrql());
859 }
860 Status = RawFsDispatchRequest(IrpContext);
861 if (KeGetCurrentIrql() <= PASSIVE_LEVEL)
862 {
863 FsRtlExitFileSystem();
864 }
865 }
866 return Status;
867 }
868
869 NTSTATUS STDCALL
870 RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject,
871 IN PUNICODE_STRING RegistryPath)
872 {
873 PRAWFS_GLOBAL_DATA DeviceData;
874 NTSTATUS Status;
875
876 RawFsDriverObject = DriverObject;
877
878 Status = IoCreateDevice(DriverObject,
879 sizeof(RAWFS_GLOBAL_DATA),
880 NULL,
881 FILE_DEVICE_DISK_FILE_SYSTEM,
882 0,
883 FALSE,
884 &DiskDeviceObject);
885 if (!NT_SUCCESS(Status))
886 {
887 CPRINT("IoCreateDevice() failed with status 0x%.08x\n", Status);
888 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
889 return(Status);
890 }
891 DeviceData = DiskDeviceObject->DeviceExtension;
892 RtlZeroMemory(DeviceData, sizeof(RAWFS_GLOBAL_DATA));
893 DeviceData->DriverObject = DriverObject;
894 DeviceData->DeviceObject = DiskDeviceObject;
895 DiskDeviceObject->Flags |= DO_DIRECT_IO;
896
897
898 Status = IoCreateDevice(DriverObject,
899 sizeof(RAWFS_GLOBAL_DATA),
900 NULL,
901 FILE_DEVICE_CD_ROM_FILE_SYSTEM,
902 0,
903 FALSE,
904 &CdromDeviceObject);
905 if (!NT_SUCCESS(Status))
906 {
907 CPRINT("IoCreateDevice() failed with status 0x%.08x\n", Status);
908 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
909 return(Status);
910 }
911 DeviceData = CdromDeviceObject->DeviceExtension;
912 RtlZeroMemory (DeviceData, sizeof(RAWFS_GLOBAL_DATA));
913 DeviceData->DriverObject = DriverObject;
914 DeviceData->DeviceObject = CdromDeviceObject;
915 CdromDeviceObject->Flags |= DO_DIRECT_IO;
916
917
918 Status = IoCreateDevice(DriverObject,
919 sizeof(RAWFS_GLOBAL_DATA),
920 NULL,
921 FILE_DEVICE_TAPE_FILE_SYSTEM,
922 0,
923 FALSE,
924 &TapeDeviceObject);
925 if (!NT_SUCCESS(Status))
926 {
927 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
928 return(Status);
929 }
930 DeviceData = TapeDeviceObject->DeviceExtension;
931 RtlZeroMemory (DeviceData, sizeof(RAWFS_GLOBAL_DATA));
932 DeviceData->DriverObject = DriverObject;
933 DeviceData->DeviceObject = TapeDeviceObject;
934 TapeDeviceObject->Flags |= DO_DIRECT_IO;
935
936
937 DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH) RawFsBuildRequest;
938 DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH) RawFsBuildRequest;
939 DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH) RawFsBuildRequest;
940 DriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH) RawFsBuildRequest;
941 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = (PDRIVER_DISPATCH) RawFsBuildRequest;
942 DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = (PDRIVER_DISPATCH) RawFsBuildRequest;
943 DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = (PDRIVER_DISPATCH) RawFsBuildRequest;
944 DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = (PDRIVER_DISPATCH) RawFsBuildRequest;
945 DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = (PDRIVER_DISPATCH) RawFsBuildRequest;
946 DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = (PDRIVER_DISPATCH) RawFsBuildRequest;
947 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = (PDRIVER_DISPATCH) RawFsShutdown;
948 DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = (PDRIVER_DISPATCH) RawFsBuildRequest;
949 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = (PDRIVER_DISPATCH) RawFsBuildRequest;
950 DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = (PDRIVER_DISPATCH) RawFsBuildRequest;
951 DriverObject->DriverUnload = NULL;
952
953 ExInitializeNPagedLookasideList(&IrpContextLookasideList,
954 NULL, NULL, 0, sizeof(RAWFS_IRP_CONTEXT), TAG_IRP, 0);
955
956
957 IoRegisterFileSystem(DiskDeviceObject);
958 IoRegisterFileSystem(CdromDeviceObject);
959 IoRegisterFileSystem(TapeDeviceObject);
960
961 return STATUS_SUCCESS;
962 }
963
964 /* EOF */