3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/rawfs.c
6 * PURPOSE: Raw filesystem driver
8 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 /* TYPES *******************************************************************/
19 typedef struct _RAWFS_GLOBAL_DATA
21 PDRIVER_OBJECT DriverObject
;
22 PDEVICE_OBJECT DeviceObject
;
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
;
30 typedef struct _RAWFS_DEVICE_EXTENSION
32 KSPIN_LOCK FcbListLock
;
33 LIST_ENTRY FcbListHead
;
34 PDEVICE_OBJECT StorageDevice
;
36 struct _RAWFS_FCB
*VolumeFcb
;
37 LIST_ENTRY VolumeListEntry
;
38 } RAWFS_DEVICE_EXTENSION
, *PRAWFS_DEVICE_EXTENSION
;
40 typedef struct _RAWFS_IRP_CONTEXT
43 PDEVICE_OBJECT DeviceObject
;
44 PRAWFS_DEVICE_EXTENSION DeviceExt
;
46 WORK_QUEUE_ITEM WorkQueueItem
;
47 PIO_STACK_LOCATION Stack
;
50 PFILE_OBJECT FileObject
;
51 } RAWFS_IRP_CONTEXT
, *PRAWFS_IRP_CONTEXT
;
53 #define IRPCONTEXT_CANWAIT 0x0001
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
61 typedef struct _RAWFS_FCB
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 */
73 /* List of FCB's for this volume */
74 LIST_ENTRY FcbListEntry
;
76 /* Pointer to the parent fcb */
77 struct _RAWFS_FCB
* ParentFcb
;
79 /* Flags for the FCB */
82 /* Pointer to the file object which has initialized the fcb */
83 PFILE_OBJECT FileObject
;
84 } RAWFS_FCB
, *PRAWFS_FCB
;
86 typedef struct _RAWFS_CCB
88 LARGE_INTEGER CurrentByteOffset
;
89 } RAWFS_CCB
, *PRAWFS_CCB
;
91 /* GLOBALS ******************************************************************/
93 #define TAG_IRP TAG('R', 'I', 'R', 'P')
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;
102 /* FUNCTIONS *****************************************************************/
105 RawFsIsRawFileSystemDeviceObject(IN PDEVICE_OBJECT DeviceObject
)
107 DPRINT("RawFsIsRawFileSystemDeviceObject(DeviceObject %x)\n", DeviceObject
);
109 if (DeviceObject
== DiskDeviceObject
)
111 if (DeviceObject
== CdromDeviceObject
)
113 if (DeviceObject
== TapeDeviceObject
)
119 RawFsDispatchRequest(IN PRAWFS_IRP_CONTEXT IrpContext
);
122 RawFsReadDisk(IN PDEVICE_OBJECT pDeviceObject
,
123 IN PLARGE_INTEGER ReadOffset
,
125 IN OUT PUCHAR Buffer
)
127 IO_STATUS_BLOCK IoStatus
;
132 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
134 DPRINT("RawFsReadDisk(pDeviceObject %x, Offset %I64x, Length %d, Buffer %x)\n",
135 pDeviceObject
, ReadOffset
->QuadPart
, ReadLength
, Buffer
);
137 DPRINT ("Building synchronous FSD Request...\n");
138 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
,
147 DPRINT("IoBuildSynchronousFsdRequest() failed\n");
148 return STATUS_UNSUCCESSFUL
;
151 DPRINT("Calling IO Driver... with irp %x\n", Irp
);
152 Status
= IoCallDriver(pDeviceObject
, Irp
);
154 DPRINT("Waiting for IO Operation for %x\n", Irp
);
155 if (Status
== STATUS_PENDING
)
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
;
163 if (!NT_SUCCESS(Status
))
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
);
170 DPRINT("Block request succeeded for %x\n", Irp
);
171 return STATUS_SUCCESS
;
175 RawFsWriteDisk(IN PDEVICE_OBJECT pDeviceObject
,
176 IN PLARGE_INTEGER WriteOffset
,
177 IN ULONG WriteLength
,
180 IO_STATUS_BLOCK IoStatus
;
185 DPRINT("RawFsWriteDisk(pDeviceObject %x, Offset %I64x, Size %d, Buffer %x)\n",
186 pDeviceObject
, WriteOffset
->QuadPart
, WriteLength
, Buffer
);
188 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
190 DPRINT("Building synchronous FSD Request...\n");
191 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_WRITE
,
200 DPRINT("IoBuildSynchronousFsdRequest()\n");
201 return(STATUS_UNSUCCESSFUL
);
204 DPRINT("Calling IO Driver...\n");
205 Status
= IoCallDriver(pDeviceObject
, Irp
);
207 DPRINT("Waiting for IO Operation...\n");
208 if (Status
== STATUS_PENDING
)
210 KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
211 DPRINT("Getting IO Status...\n");
212 Status
= IoStatus
.Status
;
214 if (!NT_SUCCESS(Status
))
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
);
222 return STATUS_SUCCESS
;
226 RawFsBlockDeviceIoControl(IN PDEVICE_OBJECT DeviceObject
,
228 IN PVOID InputBuffer
,
229 IN ULONG InputBufferSize
,
230 IN OUT PVOID OutputBuffer
,
231 IN OUT PULONG pOutputBufferSize
)
233 ULONG OutputBufferSize
= 0;
236 IO_STATUS_BLOCK IoStatus
;
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);
245 if (pOutputBufferSize
)
247 OutputBufferSize
= *pOutputBufferSize
;
250 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
252 DPRINT("Building device I/O control request ...\n");
253 Irp
= IoBuildDeviceIoControlRequest(CtlCode
,
264 DPRINT("IoBuildDeviceIoControlRequest failed\n");
265 return STATUS_INSUFFICIENT_RESOURCES
;
268 DPRINT("Calling IO Driver... with irp %x\n", Irp
);
269 Status
= IoCallDriver(DeviceObject
, Irp
);
271 DPRINT("Waiting for IO Operation for %x\n", Irp
);
272 if (Status
== STATUS_PENDING
)
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
;
279 if (OutputBufferSize
)
281 *pOutputBufferSize
= OutputBufferSize
;
283 DPRINT("Returning Status %x\n", Status
);
288 RawFsNewFCB(IN PRAWFS_GLOBAL_DATA pGlobalData
)
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);
301 RawFsDestroyFCB(IN PRAWFS_GLOBAL_DATA pGlobalData
, IN PRAWFS_FCB pFcb
)
303 //FsRtlUninitializeFileLock(&pFcb->FileLock);
304 ExDeleteResourceLite(&pFcb
->PagingIoResource
);
305 ExDeleteResourceLite(&pFcb
->MainResource
);
306 ExFreeToNPagedLookasideList(&pGlobalData
->FcbLookasideList
, pFcb
);
310 RawFsNewCCB(PRAWFS_GLOBAL_DATA pGlobalData
)
314 Ccb
= ExAllocateFromNPagedLookasideList(&pGlobalData
->CcbLookasideList
);
315 memset(Ccb
, 0, sizeof(RAWFS_CCB
));
320 RawFsDestroyCCB(PRAWFS_GLOBAL_DATA pGlobalData
, PRAWFS_CCB pCcb
)
322 ExFreeToNPagedLookasideList(&pGlobalData
->CcbLookasideList
, pCcb
);
325 static PRAWFS_IRP_CONTEXT
326 RawFsAllocateIrpContext(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
)
328 PRAWFS_GLOBAL_DATA GlobalData
;
329 PRAWFS_IRP_CONTEXT IrpContext
;
332 DPRINT("RawFsAllocateIrpContext(DeviceObject %x, Irp %x)\n", DeviceObject
, Irp
);
334 ASSERT(DeviceObject
);
337 GlobalData
= (PRAWFS_GLOBAL_DATA
) DeviceObject
->DeviceExtension
;
338 IrpContext
= ExAllocateFromNPagedLookasideList(&IrpContextLookasideList
);
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
)
354 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
356 else if (MajorFunction
!= IRP_MJ_CLEANUP
&&
357 MajorFunction
!= IRP_MJ_CLOSE
&&
358 IoIsOperationSynchronous(Irp
))
360 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
367 RawFsFreeIrpContext(IN PRAWFS_IRP_CONTEXT IrpContext
)
369 DPRINT("RawFsFreeIrpContext(IrpContext %x)\n", IrpContext
);
373 ExFreeToNPagedLookasideList(&IrpContextLookasideList
, IrpContext
);
377 STDCALL
RawFsDoRequest(PVOID IrpContext
)
381 Count
= InterlockedDecrement(&RawFsQueueCount
);
383 DPRINT("RawFsDoRequest(IrpContext %x), MajorFunction %x, %d\n",
384 IrpContext
, ((PRAWFS_IRP_CONTEXT
) IrpContext
)->MajorFunction
, Count
);
386 RawFsDispatchRequest((PRAWFS_IRP_CONTEXT
) IrpContext
);
390 RawFsQueueRequest(PRAWFS_IRP_CONTEXT IrpContext
)
394 ASSERT(IrpContext
!= NULL
);
395 ASSERT(IrpContext
->Irp
!= NULL
);
397 Count
= InterlockedIncrement(&RawFsQueueCount
);
399 DPRINT("RawFsQueueRequest (IrpContext %x), %d\n", IrpContext
, Count
);
401 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
402 IoMarkIrpPending (IrpContext
->Irp
);
403 ExInitializeWorkItem (&IrpContext
->WorkQueueItem
, RawFsDoRequest
, IrpContext
);
404 ExQueueWorkItem(&IrpContext
->WorkQueueItem
, CriticalWorkQueue
);
405 return STATUS_PENDING
;
409 RawFsClose(IN PRAWFS_IRP_CONTEXT IrpContext
)
411 DPRINT("RawFsClose(IrpContext %x)\n", IrpContext
);
413 return STATUS_NOT_IMPLEMENTED
;
417 RawFsCreateFile(IN PRAWFS_IRP_CONTEXT IrpContext
)
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
;
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
;
435 if (FileObject
->FileName
.Length
== 0 &&
436 FileObject
->RelatedFileObject
== NULL
)
438 /* This a open operation for the volume itself */
439 if (RequestedDisposition
== FILE_CREATE
440 || RequestedDisposition
== FILE_OVERWRITE_IF
441 || RequestedDisposition
== FILE_SUPERSEDE
)
443 return STATUS_ACCESS_DENIED
;
445 if (RequestedOptions
& FILE_DIRECTORY_FILE
)
447 return STATUS_NOT_A_DIRECTORY
;
449 pFcb
= DeviceExt
->VolumeFcb
;
450 pCcb
= RawFsNewCCB(GlobalData
);
453 return (STATUS_INSUFFICIENT_RESOURCES
);
456 FileObject
->SectionObjectPointer
= &pFcb
->SectionObjectPointers
;
457 FileObject
->FsContext
= pFcb
;
458 FileObject
->FsContext2
= pCcb
;
461 IrpContext
->Irp
->IoStatus
.Information
= FILE_OPENED
;
462 return(STATUS_SUCCESS
);
465 /* This filesystem driver only supports volume access */
466 return(STATUS_INVALID_PARAMETER
);
470 RawFsCreate(IN PRAWFS_IRP_CONTEXT IrpContext
)
474 DPRINT("RawFsCreate(IrpContext %x)\n", IrpContext
);
478 if (RawFsIsRawFileSystemDeviceObject(IrpContext
->DeviceObject
))
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
;
489 if (!(IrpContext
->Flags
& IRPCONTEXT_CANWAIT
))
491 return RawFsQueueRequest(IrpContext
);
494 IrpContext
->Irp
->IoStatus
.Information
= 0;
496 Status
= RawFsCreateFile(IrpContext
);
498 IrpContext
->Irp
->IoStatus
.Status
= Status
;
499 IoCompleteRequest(IrpContext
->Irp
,
500 (CCHAR
)(NT_SUCCESS(Status
) ? IO_DISK_INCREMENT
: IO_NO_INCREMENT
));
501 RawFsFreeIrpContext(IrpContext
);
507 RawFsRead(IN PRAWFS_IRP_CONTEXT IrpContext
)
509 DPRINT("RawFsRead(IrpContext %x)\n", IrpContext
);
511 return STATUS_NOT_IMPLEMENTED
;
515 RawFsWrite(IN PRAWFS_IRP_CONTEXT IrpContext
)
517 DPRINT("RawFsWrite(IrpContext %x)\n", IrpContext
);
519 return STATUS_NOT_IMPLEMENTED
;
523 RawFsMount(IN PRAWFS_IRP_CONTEXT IrpContext
)
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
;
536 DPRINT("RawFsMount(IrpContext %x)\n", IrpContext
);
540 if (!RawFsIsRawFileSystemDeviceObject(IrpContext
->DeviceObject
))
542 Status
= STATUS_INVALID_DEVICE_REQUEST
;
543 DPRINT("Not for me\n");
547 GlobalData
= (PRAWFS_GLOBAL_DATA
) IrpContext
->DeviceObject
->DeviceExtension
;
549 Status
= IoCreateDevice(GlobalData
->DriverObject
,
550 sizeof(RAWFS_DEVICE_EXTENSION
),
552 FILE_DEVICE_FILE_SYSTEM
,
556 if (!NT_SUCCESS(Status
))
561 DeviceObject
->Flags
|= DO_DIRECT_IO
;
562 DeviceExt
= (PVOID
) DeviceObject
->DeviceExtension
;
563 RtlZeroMemory(DeviceExt
, sizeof(RAWFS_DEVICE_EXTENSION
));
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
;
574 KeInitializeSpinLock(&DeviceExt
->FcbListLock
);
575 InitializeListHead(&DeviceExt
->FcbListHead
);
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
,
586 if (!NT_SUCCESS(Status
))
588 DPRINT("RawFsBlockDeviceIoControl failed with status 0x%.08x\n", Status
);
591 if (DiskGeometry
.MediaType
== FixedMedia
)
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
,
602 if (!NT_SUCCESS(Status
))
604 DPRINT("RawFsBlockDeviceIoControl() failed (%x)\n", Status
);
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
);
618 VolumeSize
.QuadPart
= PartitionInfo
.PartitionLength
.QuadPart
;
620 else if (DiskGeometry
.MediaType
> Unknown
&& DiskGeometry
.MediaType
<= RemovableMedia
)
622 Status
= STATUS_UNRECOGNIZED_VOLUME
;
626 VolumeFcb
= RawFsNewFCB(GlobalData
);
627 if (VolumeFcb
== NULL
)
629 Status
= STATUS_INSUFFICIENT_RESOURCES
;
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
;
639 KeEnterCriticalRegion();
640 ExAcquireResourceExclusiveLite(&GlobalData
->VolumeListLock
, TRUE
);
641 InsertHeadList(&GlobalData
->VolumeListHead
, &DeviceExt
->VolumeListEntry
);
642 ExReleaseResourceLite(&GlobalData
->VolumeListLock
);
643 KeLeaveCriticalRegion();
645 /* No serial number */
646 DeviceObject
->Vpb
->SerialNumber
= 0;
648 /* Set volume label (no label) */
649 *(DeviceObject
->Vpb
->VolumeLabel
) = 0;
650 DeviceObject
->Vpb
->VolumeLabelLength
= 0;
652 Status
= STATUS_SUCCESS
;
655 if (!NT_SUCCESS(Status
))
657 DPRINT("RAWFS: RawFsMount() Status 0x%.08x\n", Status
);
660 RawFsDestroyFCB(GlobalData
, Fcb
);
662 IoDeleteDevice(DeviceObject
);
664 RawFsDestroyFCB(GlobalData
, VolumeFcb
);
670 RawFsFileSystemControl(IN PRAWFS_IRP_CONTEXT IrpContext
)
674 DPRINT("RawFsFileSystemControl(IrpContext %x)\n", IrpContext
);
678 switch (IrpContext
->MinorFunction
)
680 case IRP_MN_USER_FS_REQUEST
:
681 DPRINT("RawFs FSC: IRP_MN_USER_FS_REQUEST\n");
682 Status
= STATUS_INVALID_DEVICE_REQUEST
;
685 case IRP_MN_MOUNT_VOLUME
:
686 DPRINT("RawFs FSC: IRP_MN_MOUNT_VOLUME\n");
687 Status
= RawFsMount(IrpContext
);
690 case IRP_MN_VERIFY_VOLUME
:
691 DPRINT("RawFs FSC: IRP_MN_VERIFY_VOLUME\n");
692 Status
= STATUS_INVALID_DEVICE_REQUEST
;
696 DPRINT("RawFs FSC: MinorFunction %d\n", IrpContext
->MinorFunction
);
697 Status
= STATUS_INVALID_DEVICE_REQUEST
;
701 IrpContext
->Irp
->IoStatus
.Status
= Status
;
702 IrpContext
->Irp
->IoStatus
.Information
= 0;
704 IoCompleteRequest(IrpContext
->Irp
, IO_NO_INCREMENT
);
705 RawFsFreeIrpContext(IrpContext
);
710 RawFsQueryInformation(IN PRAWFS_IRP_CONTEXT IrpContext
)
712 DPRINT("RawFsQueryInformation(IrpContext %x)\n", IrpContext
);
714 return STATUS_NOT_IMPLEMENTED
;
718 RawFsSetInformation(IN PRAWFS_IRP_CONTEXT IrpContext
)
720 DPRINT("RawFsSetInformation(IrpContext %x)\n", IrpContext
);
722 return STATUS_NOT_IMPLEMENTED
;
726 RawFsDirectoryControl(IN PRAWFS_IRP_CONTEXT IrpContext
)
728 DPRINT("RawFsDirectoryControl(IrpContext %x)\n", IrpContext
);
730 return STATUS_NOT_IMPLEMENTED
;
734 RawFsQueryVolumeInformation(IN PRAWFS_IRP_CONTEXT IrpContext
)
736 DPRINT("RawFsQueryVolumeInformation(IrpContext %x)\n", IrpContext
);
738 return STATUS_NOT_IMPLEMENTED
;
742 RawFsSetVolumeInformation(IN PRAWFS_IRP_CONTEXT IrpContext
)
744 DPRINT("RawFsSetVolumeInformation(IrpContext %x)\n", IrpContext
);
746 return STATUS_NOT_IMPLEMENTED
;
750 RawFsLockControl(IN PRAWFS_IRP_CONTEXT IrpContext
)
752 DPRINT("RawFsLockControl(IrpContext %x)\n", IrpContext
);
754 return STATUS_NOT_IMPLEMENTED
;
758 RawFsCleanup(IN PRAWFS_IRP_CONTEXT IrpContext
)
760 DPRINT("RawFsCleanup(IrpContext %x)\n", IrpContext
);
762 return STATUS_NOT_IMPLEMENTED
;
766 RawFsFlush(IN PRAWFS_IRP_CONTEXT IrpContext
)
768 DPRINT("RawFsFlush(IrpContext %x)\n", IrpContext
);
770 return STATUS_NOT_IMPLEMENTED
;
773 static NTSTATUS STDCALL
774 RawFsShutdown(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
)
776 DPRINT("RawFsShutdown(DeviceObject %x, Irp %x)\n", DeviceObject
, Irp
);
779 * Note: Do NOT call UNIMPLEMENTED here!
780 * This function must finish in order to shutdown ReactOS properly!
783 return STATUS_NOT_IMPLEMENTED
;
787 RawFsDispatchRequest(IN PRAWFS_IRP_CONTEXT IrpContext
)
789 DPRINT("RawFsDispatchRequest(IrpContext %x), MajorFunction %x\n",
790 IrpContext
, IrpContext
->MajorFunction
);
794 switch (IrpContext
->MajorFunction
)
797 return RawFsClose(IrpContext
);
799 return RawFsCreate (IrpContext
);
801 return RawFsRead (IrpContext
);
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
);
819 return RawFsCleanup(IrpContext
);
820 case IRP_MJ_FLUSH_BUFFERS
:
821 return RawFsFlush(IrpContext
);
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
;
831 static NTSTATUS STDCALL
832 RawFsBuildRequest(IN PDEVICE_OBJECT DeviceObject
,
835 PRAWFS_IRP_CONTEXT IrpContext
;
838 DPRINT("RawFsBuildRequest(DeviceObject %x, Irp %x)\n", DeviceObject
, Irp
);
840 ASSERT(DeviceObject
);
843 IrpContext
= RawFsAllocateIrpContext(DeviceObject
, Irp
);
844 if (IrpContext
== NULL
)
846 Status
= STATUS_INSUFFICIENT_RESOURCES
;
847 Irp
->IoStatus
.Status
= Status
;
848 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
852 if (KeGetCurrentIrql() <= PASSIVE_LEVEL
)
854 FsRtlEnterFileSystem();
858 DPRINT1("RawFs is entered at irql = %d\n", KeGetCurrentIrql());
860 Status
= RawFsDispatchRequest(IrpContext
);
861 if (KeGetCurrentIrql() <= PASSIVE_LEVEL
)
863 FsRtlExitFileSystem();
870 RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject
,
871 IN PUNICODE_STRING RegistryPath
)
873 PRAWFS_GLOBAL_DATA DeviceData
;
876 RawFsDriverObject
= DriverObject
;
878 Status
= IoCreateDevice(DriverObject
,
879 sizeof(RAWFS_GLOBAL_DATA
),
881 FILE_DEVICE_DISK_FILE_SYSTEM
,
885 if (!NT_SUCCESS(Status
))
887 CPRINT("IoCreateDevice() failed with status 0x%.08x\n", Status
);
888 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
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
;
898 Status
= IoCreateDevice(DriverObject
,
899 sizeof(RAWFS_GLOBAL_DATA
),
901 FILE_DEVICE_CD_ROM_FILE_SYSTEM
,
905 if (!NT_SUCCESS(Status
))
907 CPRINT("IoCreateDevice() failed with status 0x%.08x\n", Status
);
908 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
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
;
918 Status
= IoCreateDevice(DriverObject
,
919 sizeof(RAWFS_GLOBAL_DATA
),
921 FILE_DEVICE_TAPE_FILE_SYSTEM
,
925 if (!NT_SUCCESS(Status
))
927 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
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
;
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
;
953 ExInitializeNPagedLookasideList(&IrpContextLookasideList
,
954 NULL
, NULL
, 0, sizeof(RAWFS_IRP_CONTEXT
), TAG_IRP
, 0);
957 IoRegisterFileSystem(DiskDeviceObject
);
958 IoRegisterFileSystem(CdromDeviceObject
);
959 IoRegisterFileSystem(TapeDeviceObject
);
961 return STATUS_SUCCESS
;