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 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <ddk/ntifs.h>
16 #include <reactos/bugcodes.h>
19 #include <internal/debug.h>
21 /* TYPES *******************************************************************/
23 typedef struct _RAWFS_GLOBAL_DATA
25 PDRIVER_OBJECT DriverObject;
26 PDEVICE_OBJECT DeviceObject;
28 ERESOURCE VolumeListLock;
29 LIST_ENTRY VolumeListHead;
30 NPAGED_LOOKASIDE_LIST FcbLookasideList;
31 NPAGED_LOOKASIDE_LIST CcbLookasideList;
32 } RAWFS_GLOBAL_DATA, *PRAWFS_GLOBAL_DATA, VCB, *PVCB;
34 typedef struct _RAWFS_DEVICE_EXTENSION
36 KSPIN_LOCK FcbListLock;
37 LIST_ENTRY FcbListHead;
38 PDEVICE_OBJECT StorageDevice;
40 struct _RAWFS_FCB *VolumeFcb;
41 LIST_ENTRY VolumeListEntry;
42 } RAWFS_DEVICE_EXTENSION, *PRAWFS_DEVICE_EXTENSION;
44 typedef struct _RAWFS_IRP_CONTEXT
47 PDEVICE_OBJECT DeviceObject;
48 PRAWFS_DEVICE_EXTENSION DeviceExt;
50 WORK_QUEUE_ITEM WorkQueueItem;
51 PIO_STACK_LOCATION Stack;
54 PFILE_OBJECT FileObject;
55 } RAWFS_IRP_CONTEXT, *PRAWFS_IRP_CONTEXT;
57 #define IRPCONTEXT_CANWAIT 0x0001
59 #define FCB_CACHE_INITIALIZED 0x0001
60 #define FCB_DELETE_PENDING 0x0002
61 #define FCB_IS_FAT 0x0004
62 #define FCB_IS_PAGE_FILE 0x0008
63 #define FCB_IS_VOLUME 0x0010
65 typedef struct _RAWFS_FCB
67 /* Start FCB header required by ReactOS/Windows NT */
68 FSRTL_COMMON_FCB_HEADER RFCB;
69 SECTION_OBJECT_POINTERS SectionObjectPointers;
70 ERESOURCE MainResource;
71 ERESOURCE PagingIoResource;
72 /* End FCB header required by ReactOS/Windows NT */
77 /* List of FCB's for this volume */
78 LIST_ENTRY FcbListEntry;
80 /* Pointer to the parent fcb */
81 struct _RAWFS_FCB* ParentFcb;
83 /* Flags for the FCB */
86 /* Pointer to the file object which has initialized the fcb */
87 PFILE_OBJECT FileObject;
88 } RAWFS_FCB, *PRAWFS_FCB;
90 typedef struct _RAWFS_CCB
92 LARGE_INTEGER CurrentByteOffset;
93 } RAWFS_CCB, *PRAWFS_CCB;
95 /* GLOBALS ******************************************************************/
97 #define TAG_IRP TAG('R', 'I', 'R', 'P')
99 static PDRIVER_OBJECT RawFsDriverObject;
100 static PDEVICE_OBJECT DiskDeviceObject;
101 static PDEVICE_OBJECT CdromDeviceObject;
102 static PDEVICE_OBJECT TapeDeviceObject;
103 static NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
104 static LONG RawFsQueueCount = 0;
106 /* FUNCTIONS *****************************************************************/
109 RawFsIsRawFileSystemDeviceObject(IN PDEVICE_OBJECT DeviceObject)
111 DPRINT("RawFsIsRawFileSystemDeviceObject(DeviceObject %x)\n", DeviceObject);
113 if (DeviceObject == DiskDeviceObject)
115 if (DeviceObject == CdromDeviceObject)
117 if (DeviceObject == TapeDeviceObject)
123 RawFsDispatchRequest(IN PRAWFS_IRP_CONTEXT IrpContext);
126 RawFsReadDisk(IN PDEVICE_OBJECT pDeviceObject,
127 IN PLARGE_INTEGER ReadOffset,
129 IN OUT PUCHAR Buffer)
131 IO_STATUS_BLOCK IoStatus;
136 KeInitializeEvent(&Event, NotificationEvent, FALSE);
138 DPRINT("RawFsReadDisk(pDeviceObject %x, Offset %I64x, Length %d, Buffer %x)\n",
139 pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
141 DPRINT ("Building synchronous FSD Request...\n");
142 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
151 DPRINT("IoBuildSynchronousFsdRequest() failed\n");
152 return STATUS_UNSUCCESSFUL;
155 DPRINT("Calling IO Driver... with irp %x\n", Irp);
156 Status = IoCallDriver(pDeviceObject, Irp);
158 DPRINT("Waiting for IO Operation for %x\n", Irp);
159 if (Status == STATUS_PENDING)
161 DPRINT("Operation pending\n");
162 KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
163 DPRINT("Getting IO Status... for %x\n", Irp);
164 Status = IoStatus.Status;
167 if (!NT_SUCCESS(Status))
169 DPRINT("RawFsReadDisk() failed. Status %x\n", Status);
170 DPRINT("(pDeviceObject %x, Offset %I64x, Size %d, Buffer %x\n",
171 pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
174 DPRINT("Block request succeeded for %x\n", Irp);
175 return STATUS_SUCCESS;
179 RawFsWriteDisk(IN PDEVICE_OBJECT pDeviceObject,
180 IN PLARGE_INTEGER WriteOffset,
181 IN ULONG WriteLength,
184 IO_STATUS_BLOCK IoStatus;
189 DPRINT("RawFsWriteDisk(pDeviceObject %x, Offset %I64x, Size %d, Buffer %x)\n",
190 pDeviceObject, WriteOffset->QuadPart, WriteLength, Buffer);
192 KeInitializeEvent(&Event, NotificationEvent, FALSE);
194 DPRINT("Building synchronous FSD Request...\n");
195 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
204 DPRINT("IoBuildSynchronousFsdRequest()\n");
205 return(STATUS_UNSUCCESSFUL);
208 DPRINT("Calling IO Driver...\n");
209 Status = IoCallDriver(pDeviceObject, Irp);
211 DPRINT("Waiting for IO Operation...\n");
212 if (Status == STATUS_PENDING)
214 KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
215 DPRINT("Getting IO Status...\n");
216 Status = IoStatus.Status;
218 if (!NT_SUCCESS(Status))
220 DPRINT("RawFsWriteDisk() failed. Status %x\n", Status);
221 DPRINT("(pDeviceObject %x, Offset %I64x, Size %d, Buffer %x\n",
222 pDeviceObject, WriteOffset->QuadPart, WriteLength, Buffer);
226 return STATUS_SUCCESS;
230 RawFsBlockDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
232 IN PVOID InputBuffer,
233 IN ULONG InputBufferSize,
234 IN OUT PVOID OutputBuffer,
235 IN OUT PULONG pOutputBufferSize)
237 ULONG OutputBufferSize = 0;
240 IO_STATUS_BLOCK IoStatus;
243 DPRINT("RawFsBlockDeviceIoControl(DeviceObject %x, CtlCode %x, "
244 "InputBuffer %x, InputBufferSize %x, OutputBuffer %x, "
245 "POutputBufferSize %x (%x)\n", DeviceObject, CtlCode,
246 InputBuffer, InputBufferSize, OutputBuffer, pOutputBufferSize,
247 pOutputBufferSize ? *pOutputBufferSize : 0);
249 if (pOutputBufferSize)
251 OutputBufferSize = *pOutputBufferSize;
254 KeInitializeEvent(&Event, NotificationEvent, FALSE);
256 DPRINT("Building device I/O control request ...\n");
257 Irp = IoBuildDeviceIoControlRequest(CtlCode,
268 DPRINT("IoBuildDeviceIoControlRequest failed\n");
269 return STATUS_INSUFFICIENT_RESOURCES;
272 DPRINT("Calling IO Driver... with irp %x\n", Irp);
273 Status = IoCallDriver(DeviceObject, Irp);
275 DPRINT("Waiting for IO Operation for %x\n", Irp);
276 if (Status == STATUS_PENDING)
278 DPRINT("Operation pending\n");
279 KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
280 DPRINT("Getting IO Status... for %x\n", Irp);
281 Status = IoStatus.Status;
283 if (OutputBufferSize)
285 *pOutputBufferSize = OutputBufferSize;
287 DPRINT("Returning Status %x\n", Status);
292 RawFsNewFCB(IN PRAWFS_GLOBAL_DATA pGlobalData)
296 Fcb = ExAllocateFromNPagedLookasideList(&pGlobalData->FcbLookasideList);
297 memset(Fcb, 0, sizeof(RAWFS_FCB));
298 ExInitializeResourceLite(&Fcb->PagingIoResource);
299 ExInitializeResourceLite(&Fcb->MainResource);
300 // FsRtlInitializeFileLock(&Fcb->FileLock, NULL, NULL);
305 RawFsDestroyFCB(IN PRAWFS_GLOBAL_DATA pGlobalData, IN PRAWFS_FCB pFcb)
307 //FsRtlUninitializeFileLock(&pFcb->FileLock);
308 ExDeleteResourceLite(&pFcb->PagingIoResource);
309 ExDeleteResourceLite(&pFcb->MainResource);
310 ExFreeToNPagedLookasideList(&pGlobalData->FcbLookasideList, pFcb);
314 RawFsNewCCB(PRAWFS_GLOBAL_DATA pGlobalData)
318 Ccb = ExAllocateFromNPagedLookasideList(&pGlobalData->CcbLookasideList);
319 memset(Ccb, 0, sizeof(RAWFS_CCB));
324 RawFsDestroyCCB(PRAWFS_GLOBAL_DATA pGlobalData, PRAWFS_CCB pCcb)
326 ExFreeToNPagedLookasideList(&pGlobalData->CcbLookasideList, pCcb);
329 static PRAWFS_IRP_CONTEXT
330 RawFsAllocateIrpContext(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
332 PRAWFS_GLOBAL_DATA GlobalData;
333 PRAWFS_IRP_CONTEXT IrpContext;
336 DPRINT("RawFsAllocateIrpContext(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
338 assert(DeviceObject);
341 GlobalData = (PRAWFS_GLOBAL_DATA) DeviceObject->DeviceExtension;
342 IrpContext = ExAllocateFromNPagedLookasideList(&IrpContextLookasideList);
345 RtlZeroMemory(IrpContext, sizeof(IrpContext));
346 IrpContext->Irp = Irp;
347 IrpContext->DeviceObject = DeviceObject;
348 IrpContext->DeviceExt = DeviceObject->DeviceExtension;
349 IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp);
350 assert(IrpContext->Stack);
351 MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction;
352 IrpContext->MinorFunction = IrpContext->Stack->MinorFunction;
353 IrpContext->FileObject = IrpContext->Stack->FileObject;
354 if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
355 MajorFunction == IRP_MJ_DEVICE_CONTROL ||
356 MajorFunction == IRP_MJ_SHUTDOWN)
358 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
360 else if (MajorFunction != IRP_MJ_CLEANUP &&
361 MajorFunction != IRP_MJ_CLOSE &&
362 IoIsOperationSynchronous(Irp))
364 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
371 RawFsFreeIrpContext(IN PRAWFS_IRP_CONTEXT IrpContext)
373 DPRINT("RawFsFreeIrpContext(IrpContext %x)\n", IrpContext);
377 ExFreeToNPagedLookasideList(&IrpContextLookasideList, IrpContext);
381 STDCALL RawFsDoRequest(PVOID IrpContext)
385 DPRINT("RawFsDoRequest(IrpContext %x), MajorFunction %x, %d\n",
386 IrpContext, ((PRAWFS_IRP_CONTEXT) IrpContext)->MajorFunction, Count);
388 Count = InterlockedDecrement(&RawFsQueueCount);
389 RawFsDispatchRequest((PRAWFS_IRP_CONTEXT) IrpContext);
393 RawFsQueueRequest(PRAWFS_IRP_CONTEXT IrpContext)
397 DPRINT("RawFsQueueRequest (IrpContext %x), %d\n", IrpContext, Count);
399 assert(IrpContext != NULL);
400 assert(IrpContext->Irp != NULL);
402 Count = InterlockedIncrement(&RawFsQueueCount);
404 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
405 IoMarkIrpPending (IrpContext->Irp);
406 ExInitializeWorkItem (&IrpContext->WorkQueueItem, RawFsDoRequest, IrpContext);
407 ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
408 return STATUS_PENDING;
412 RawFsClose(IN PRAWFS_IRP_CONTEXT IrpContext)
414 DPRINT("RawFsClose(IrpContext %x)\n", IrpContext);
416 return STATUS_NOT_IMPLEMENTED;
420 RawFsCreateFile(IN PRAWFS_IRP_CONTEXT IrpContext)
422 PRAWFS_DEVICE_EXTENSION DeviceExt;
423 PRAWFS_GLOBAL_DATA GlobalData;
424 PIO_STACK_LOCATION IoSp;
425 PFILE_OBJECT FileObject;
426 ULONG RequestedDisposition;
427 ULONG RequestedOptions;
431 GlobalData = (PRAWFS_GLOBAL_DATA) IrpContext->DeviceObject->DeviceExtension;
432 IoSp = IoGetCurrentIrpStackLocation(IrpContext->Irp);
433 RequestedDisposition = ((IoSp->Parameters.Create.Options >> 24) & 0xff);
434 RequestedOptions = IoSp->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
435 FileObject = IoSp->FileObject;
436 DeviceExt = IrpContext->DeviceObject->DeviceExtension;
438 if (FileObject->FileName.Length == 0 &&
439 FileObject->RelatedFileObject == NULL)
441 /* This a open operation for the volume itself */
442 if (RequestedDisposition == FILE_CREATE
443 || RequestedDisposition == FILE_OVERWRITE_IF
444 || RequestedDisposition == FILE_SUPERSEDE)
446 return STATUS_ACCESS_DENIED;
448 if (RequestedOptions & FILE_DIRECTORY_FILE)
450 return STATUS_NOT_A_DIRECTORY;
452 pFcb = DeviceExt->VolumeFcb;
453 pCcb = RawFsNewCCB(GlobalData);
456 return (STATUS_INSUFFICIENT_RESOURCES);
459 FileObject->Flags |= FO_FCB_IS_VALID;
460 FileObject->SectionObjectPointer = &pFcb->SectionObjectPointers;
461 FileObject->FsContext = pFcb;
462 FileObject->FsContext2 = pCcb;
465 IrpContext->Irp->IoStatus.Information = FILE_OPENED;
466 return(STATUS_SUCCESS);
469 /* This filesystem driver only supports volume access */
470 return(STATUS_INVALID_PARAMETER);
474 RawFsCreate(IN PRAWFS_IRP_CONTEXT IrpContext)
478 DPRINT("RawFsCreate(IrpContext %x)\n", IrpContext);
482 if (RawFsIsRawFileSystemDeviceObject(IrpContext->DeviceObject))
484 /* DeviceObject represents FileSystem instead of logical volume */
485 DPRINT("RawFsCreate() called with file system\n");
486 IrpContext->Irp->IoStatus.Information = FILE_OPENED;
487 IrpContext->Irp->IoStatus.Status = STATUS_SUCCESS;
488 IoCompleteRequest(IrpContext->Irp, IO_DISK_INCREMENT);
489 RawFsFreeIrpContext(IrpContext);
490 return STATUS_SUCCESS;
493 if (!(IrpContext->Flags & IRPCONTEXT_CANWAIT))
495 return RawFsQueueRequest(IrpContext);
498 IrpContext->Irp->IoStatus.Information = 0;
500 Status = RawFsCreateFile(IrpContext);
502 IrpContext->Irp->IoStatus.Status = Status;
503 IoCompleteRequest(IrpContext->Irp,
504 NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
505 RawFsFreeIrpContext(IrpContext);
511 RawFsRead(IN PRAWFS_IRP_CONTEXT IrpContext)
513 DPRINT("RawFsRead(IrpContext %x)\n", IrpContext);
515 return STATUS_NOT_IMPLEMENTED;
519 RawFsWrite(IN PRAWFS_IRP_CONTEXT IrpContext)
521 DPRINT("RawFsWrite(IrpContext %x)\n", IrpContext);
523 return STATUS_NOT_IMPLEMENTED;
527 RawFsMount(IN PRAWFS_IRP_CONTEXT IrpContext)
529 PRAWFS_GLOBAL_DATA GlobalData;
530 PDEVICE_OBJECT DeviceObject = NULL;
531 PRAWFS_DEVICE_EXTENSION DeviceExt = NULL;
532 PRAWFS_FCB VolumeFcb = NULL;
533 PRAWFS_FCB Fcb = NULL;
534 PARTITION_INFORMATION PartitionInfo;
535 DISK_GEOMETRY DiskGeometry;
536 LARGE_INTEGER VolumeSize;
540 DPRINT("RawFsMount(IrpContext %x)\n", IrpContext);
544 if (!RawFsIsRawFileSystemDeviceObject(IrpContext->DeviceObject))
546 Status = STATUS_INVALID_DEVICE_REQUEST;
547 DPRINT("Not for me\n");
551 GlobalData = (PRAWFS_GLOBAL_DATA) IrpContext->DeviceObject->DeviceExtension;
553 Status = IoCreateDevice(GlobalData->DriverObject,
554 sizeof(RAWFS_DEVICE_EXTENSION),
556 FILE_DEVICE_FILE_SYSTEM,
560 if (!NT_SUCCESS(Status))
565 DeviceObject->Flags |= DO_DIRECT_IO;
566 DeviceExt = (PVOID) DeviceObject->DeviceExtension;
567 RtlZeroMemory(DeviceExt, sizeof(RAWFS_DEVICE_EXTENSION));
569 /* Use same vpb as device disk */
570 DeviceObject->Vpb = IrpContext->Stack->Parameters.MountVolume.DeviceObject->Vpb;
571 DeviceExt->StorageDevice = IrpContext->Stack->Parameters.MountVolume.DeviceObject;
572 DeviceExt->StorageDevice->Vpb->DeviceObject = DeviceObject;
573 DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
574 DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
575 DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
576 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
578 KeInitializeSpinLock(&DeviceExt->FcbListLock);
579 InitializeListHead(&DeviceExt->FcbListHead);
581 /* First try getting harddisk geometry then try getting CD-ROM geometry */
582 Size = sizeof(DISK_GEOMETRY);
583 Status = RawFsBlockDeviceIoControl(
584 IrpContext->Stack->Parameters.MountVolume.DeviceObject,
585 IOCTL_DISK_GET_DRIVE_GEOMETRY,
590 if (!NT_SUCCESS(Status))
592 DPRINT("RawFsBlockDeviceIoControl failed with status 0x%.08x\n", Status);
595 if (DiskGeometry.MediaType == FixedMedia)
597 // We have found a hard disk
598 Size = sizeof(PARTITION_INFORMATION);
599 Status = RawFsBlockDeviceIoControl(
600 IrpContext->Stack->Parameters.MountVolume.DeviceObject,
601 IOCTL_DISK_GET_PARTITION_INFO,
606 if (!NT_SUCCESS(Status))
608 DPRINT("RawFsBlockDeviceIoControl() failed (%x)\n", Status);
612 DbgPrint("Partition Information:\n");
613 DbgPrint("StartingOffset %u\n", PartitionInfo.StartingOffset.QuadPart);
614 DbgPrint("PartitionLength %u\n", PartitionInfo.PartitionLength.QuadPart);
615 DbgPrint("HiddenSectors %u\n", PartitionInfo.HiddenSectors);
616 DbgPrint("PartitionNumber %u\n", PartitionInfo.PartitionNumber);
617 DbgPrint("PartitionType %u\n", PartitionInfo.PartitionType);
618 DbgPrint("BootIndicator %u\n", PartitionInfo.BootIndicator);
619 DbgPrint("RecognizedPartition %u\n", PartitionInfo.RecognizedPartition);
620 DbgPrint("RewritePartition %u\n", PartitionInfo.RewritePartition);
622 VolumeSize.QuadPart = PartitionInfo.PartitionLength.QuadPart;
624 else if (DiskGeometry.MediaType > Unknown && DiskGeometry.MediaType <= RemovableMedia)
626 Status = STATUS_UNRECOGNIZED_VOLUME;
630 VolumeFcb = RawFsNewFCB(GlobalData);
631 if (VolumeFcb == NULL)
633 Status = STATUS_INSUFFICIENT_RESOURCES;
637 VolumeFcb->Flags = FCB_IS_VOLUME;
638 VolumeFcb->RFCB.FileSize.QuadPart = VolumeSize.QuadPart;
639 VolumeFcb->RFCB.ValidDataLength.QuadPart = VolumeFcb->RFCB.FileSize.QuadPart;
640 VolumeFcb->RFCB.AllocationSize.QuadPart = VolumeFcb->RFCB.FileSize.QuadPart;
641 DeviceExt->VolumeFcb = VolumeFcb;
643 ExAcquireResourceExclusiveLite(&GlobalData->VolumeListLock, TRUE);
644 InsertHeadList(&GlobalData->VolumeListHead, &DeviceExt->VolumeListEntry);
645 ExReleaseResourceLite(&GlobalData->VolumeListLock);
647 /* No serial number */
648 DeviceObject->Vpb->SerialNumber = 0;
650 /* Set volume label (no label) */
651 *(DeviceObject->Vpb->VolumeLabel) = 0;
652 DeviceObject->Vpb->VolumeLabelLength = 0;
654 Status = STATUS_SUCCESS;
657 if (!NT_SUCCESS(Status))
659 DPRINT("RAWFS: RawFsMount() Status 0x%.08x\n", Status);
662 RawFsDestroyFCB(GlobalData, Fcb);
664 IoDeleteDevice(DeviceObject);
666 RawFsDestroyFCB(GlobalData, VolumeFcb);
672 RawFsFileSystemControl(IN PRAWFS_IRP_CONTEXT IrpContext)
676 DPRINT("RawFsFileSystemControl(IrpContext %x)\n", IrpContext);
680 switch (IrpContext->MinorFunction)
682 case IRP_MN_USER_FS_REQUEST:
683 DPRINT("RawFs FSC: IRP_MN_USER_FS_REQUEST\n");
684 Status = STATUS_INVALID_DEVICE_REQUEST;
687 case IRP_MN_MOUNT_VOLUME:
688 DPRINT("RawFs FSC: IRP_MN_MOUNT_VOLUME\n");
689 Status = RawFsMount(IrpContext);
692 case IRP_MN_VERIFY_VOLUME:
693 DPRINT("RawFs FSC: IRP_MN_VERIFY_VOLUME\n");
694 Status = STATUS_INVALID_DEVICE_REQUEST;
698 DPRINT("RawFs FSC: MinorFunction %d\n", IrpContext->MinorFunction);
699 Status = STATUS_INVALID_DEVICE_REQUEST;
703 IrpContext->Irp->IoStatus.Status = Status;
704 IrpContext->Irp->IoStatus.Information = 0;
706 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
707 RawFsFreeIrpContext(IrpContext);
712 RawFsQueryInformation(IN PRAWFS_IRP_CONTEXT IrpContext)
714 DPRINT("RawFsQueryInformation(IrpContext %x)\n", IrpContext);
716 return STATUS_NOT_IMPLEMENTED;
720 RawFsSetInformation(IN PRAWFS_IRP_CONTEXT IrpContext)
722 DPRINT("RawFsSetInformation(IrpContext %x)\n", IrpContext);
724 return STATUS_NOT_IMPLEMENTED;
728 RawFsDirectoryControl(IN PRAWFS_IRP_CONTEXT IrpContext)
730 DPRINT("RawFsDirectoryControl(IrpContext %x)\n", IrpContext);
732 return STATUS_NOT_IMPLEMENTED;
736 RawFsQueryVolumeInformation(IN PRAWFS_IRP_CONTEXT IrpContext)
738 DPRINT("RawFsQueryVolumeInformation(IrpContext %x)\n", IrpContext);
740 return STATUS_NOT_IMPLEMENTED;
744 RawFsSetVolumeInformation(IN PRAWFS_IRP_CONTEXT IrpContext)
746 DPRINT("RawFsSetVolumeInformation(IrpContext %x)\n", IrpContext);
748 return STATUS_NOT_IMPLEMENTED;
752 RawFsLockControl(IN PRAWFS_IRP_CONTEXT IrpContext)
754 DPRINT("RawFsLockControl(IrpContext %x)\n", IrpContext);
756 return STATUS_NOT_IMPLEMENTED;
760 RawFsCleanup(IN PRAWFS_IRP_CONTEXT IrpContext)
762 DPRINT("RawFsCleanup(IrpContext %x)\n", IrpContext);
764 return STATUS_NOT_IMPLEMENTED;
768 RawFsFlush(IN PRAWFS_IRP_CONTEXT IrpContext)
770 DPRINT("RawFsFlush(IrpContext %x)\n", IrpContext);
772 return STATUS_NOT_IMPLEMENTED;
775 static NTSTATUS STDCALL
776 RawFsShutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
778 DPRINT("RawFsShutdown(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
781 * Note: Do NOT call UNIMPLEMENTED here!
782 * This function must finish in order to shutdown ReactOS properly!
785 return STATUS_NOT_IMPLEMENTED;
789 RawFsDispatchRequest(IN PRAWFS_IRP_CONTEXT IrpContext)
791 DPRINT("RawFsDispatchRequest(IrpContext %x), MajorFunction %x\n",
792 IrpContext, IrpContext->MajorFunction);
796 switch (IrpContext->MajorFunction)
799 return RawFsClose(IrpContext);
801 return RawFsCreate (IrpContext);
803 return RawFsRead (IrpContext);
805 return RawFsWrite (IrpContext);
806 case IRP_MJ_FILE_SYSTEM_CONTROL:
807 return RawFsFileSystemControl(IrpContext);
808 case IRP_MJ_QUERY_INFORMATION:
809 return RawFsQueryInformation (IrpContext);
810 case IRP_MJ_SET_INFORMATION:
811 return RawFsSetInformation (IrpContext);
812 case IRP_MJ_DIRECTORY_CONTROL:
813 return RawFsDirectoryControl(IrpContext);
814 case IRP_MJ_QUERY_VOLUME_INFORMATION:
815 return RawFsQueryVolumeInformation(IrpContext);
816 case IRP_MJ_SET_VOLUME_INFORMATION:
817 return RawFsSetVolumeInformation(IrpContext);
818 case IRP_MJ_LOCK_CONTROL:
819 return RawFsLockControl(IrpContext);
821 return RawFsCleanup(IrpContext);
822 case IRP_MJ_FLUSH_BUFFERS:
823 return RawFsFlush(IrpContext);
825 DPRINT1("Unexpected major function %x\n", IrpContext->MajorFunction);
826 IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
827 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
828 RawFsFreeIrpContext(IrpContext);
829 return STATUS_DRIVER_INTERNAL_ERROR;
833 static NTSTATUS STDCALL
834 RawFsBuildRequest(IN PDEVICE_OBJECT DeviceObject,
837 PRAWFS_IRP_CONTEXT IrpContext;
840 DPRINT("RawFsBuildRequest(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
842 assert(DeviceObject);
845 IrpContext = RawFsAllocateIrpContext(DeviceObject, Irp);
846 if (IrpContext == NULL)
848 Status = STATUS_INSUFFICIENT_RESOURCES;
849 Irp->IoStatus.Status = Status;
850 IoCompleteRequest(Irp, IO_NO_INCREMENT);
854 if (KeGetCurrentIrql() <= PASSIVE_LEVEL)
856 FsRtlEnterFileSystem();
860 DPRINT1("RawFs is entered at irql = %d\n", KeGetCurrentIrql());
862 Status = RawFsDispatchRequest(IrpContext);
863 if (KeGetCurrentIrql() <= PASSIVE_LEVEL)
865 FsRtlExitFileSystem();
872 RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject,
873 IN PUNICODE_STRING RegistryPath)
875 PRAWFS_GLOBAL_DATA DeviceData;
878 RawFsDriverObject = DriverObject;
880 Status = IoCreateDevice(DriverObject,
881 sizeof(RAWFS_GLOBAL_DATA),
883 FILE_DEVICE_DISK_FILE_SYSTEM,
887 if (!NT_SUCCESS(Status))
889 CPRINT("IoCreateDevice() failed with status 0x%.08x\n", Status);
890 KEBUGCHECK(PHASE1_INITIALIZATION_FAILED);
893 DeviceData = DiskDeviceObject->DeviceExtension;
894 RtlZeroMemory(DeviceData, sizeof(RAWFS_GLOBAL_DATA));
895 DeviceData->DriverObject = DriverObject;
896 DeviceData->DeviceObject = DiskDeviceObject;
897 DiskDeviceObject->Flags |= DO_DIRECT_IO;
900 Status = IoCreateDevice(DriverObject,
901 sizeof(RAWFS_GLOBAL_DATA),
903 FILE_DEVICE_CD_ROM_FILE_SYSTEM,
907 if (!NT_SUCCESS(Status))
909 CPRINT("IoCreateDevice() failed with status 0x%.08x\n", Status);
910 KEBUGCHECK(PHASE1_INITIALIZATION_FAILED);
913 DeviceData = CdromDeviceObject->DeviceExtension;
914 RtlZeroMemory (DeviceData, sizeof(RAWFS_GLOBAL_DATA));
915 DeviceData->DriverObject = DriverObject;
916 DeviceData->DeviceObject = CdromDeviceObject;
917 CdromDeviceObject->Flags |= DO_DIRECT_IO;
920 Status = IoCreateDevice(DriverObject,
921 sizeof(RAWFS_GLOBAL_DATA),
923 FILE_DEVICE_TAPE_FILE_SYSTEM,
927 if (!NT_SUCCESS(Status))
929 CPRINT("IoCreateDevice() failed with status 0x%.08x\n", Status);
930 KEBUGCHECK(PHASE1_INITIALIZATION_FAILED);
933 DeviceData = TapeDeviceObject->DeviceExtension;
934 RtlZeroMemory (DeviceData, sizeof(RAWFS_GLOBAL_DATA));
935 DeviceData->DriverObject = DriverObject;
936 DeviceData->DeviceObject = TapeDeviceObject;
937 TapeDeviceObject->Flags |= DO_DIRECT_IO;
940 DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH) RawFsBuildRequest;
941 DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH) RawFsBuildRequest;
942 DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH) RawFsBuildRequest;
943 DriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH) RawFsBuildRequest;
944 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = (PDRIVER_DISPATCH) RawFsBuildRequest;
945 DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = (PDRIVER_DISPATCH) RawFsBuildRequest;
946 DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = (PDRIVER_DISPATCH) RawFsBuildRequest;
947 DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = (PDRIVER_DISPATCH) RawFsBuildRequest;
948 DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = (PDRIVER_DISPATCH) RawFsBuildRequest;
949 DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = (PDRIVER_DISPATCH) RawFsBuildRequest;
950 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = (PDRIVER_DISPATCH) RawFsShutdown;
951 DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = (PDRIVER_DISPATCH) RawFsBuildRequest;
952 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = (PDRIVER_DISPATCH) RawFsBuildRequest;
953 DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = (PDRIVER_DISPATCH) RawFsBuildRequest;
954 DriverObject->DriverUnload = NULL;
956 ExInitializeNPagedLookasideList(&IrpContextLookasideList,
957 NULL, NULL, 0, sizeof(RAWFS_IRP_CONTEXT), TAG_IRP, 0);
960 IoRegisterFileSystem(DiskDeviceObject);
961 IoRegisterFileSystem(CdromDeviceObject);
962 IoRegisterFileSystem(TapeDeviceObject);
964 return STATUS_SUCCESS;