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 static PDRIVER_OBJECT RawFsDriverObject
;
94 static PDEVICE_OBJECT DiskDeviceObject
;
95 static PDEVICE_OBJECT CdromDeviceObject
;
96 static PDEVICE_OBJECT TapeDeviceObject
;
97 static NPAGED_LOOKASIDE_LIST IrpContextLookasideList
;
98 static LONG RawFsQueueCount
= 0;
100 /* FUNCTIONS *****************************************************************/
103 RawFsIsRawFileSystemDeviceObject(IN PDEVICE_OBJECT DeviceObject
)
105 DPRINT("RawFsIsRawFileSystemDeviceObject(DeviceObject 0x%p)\n", DeviceObject
);
107 if (DeviceObject
== DiskDeviceObject
)
109 if (DeviceObject
== CdromDeviceObject
)
111 if (DeviceObject
== TapeDeviceObject
)
117 RawFsDispatchRequest(IN PRAWFS_IRP_CONTEXT IrpContext
);
120 RawFsReadDisk(IN PDEVICE_OBJECT pDeviceObject
,
121 IN PLARGE_INTEGER ReadOffset
,
123 IN OUT PUCHAR Buffer
)
125 IO_STATUS_BLOCK IoStatus
;
130 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
132 DPRINT("RawFsReadDisk(pDeviceObject 0x%p, Offset %I64x, Length %d, Buffer 0x%p)\n",
133 pDeviceObject
, ReadOffset
->QuadPart
, ReadLength
, Buffer
);
135 DPRINT ("Building synchronous FSD Request...\n");
136 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
,
145 DPRINT("IoBuildSynchronousFsdRequest() failed\n");
146 return STATUS_UNSUCCESSFUL
;
149 DPRINT("Calling IO Driver... with irp 0x%p\n", Irp
);
150 Status
= IoCallDriver(pDeviceObject
, Irp
);
152 DPRINT("Waiting for IO Operation for 0x%p\n", Irp
);
153 if (Status
== STATUS_PENDING
)
155 DPRINT("Operation pending\n");
156 KeWaitForSingleObject (&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
157 DPRINT("Getting IO Status... for 0x%p\n", Irp
);
158 Status
= IoStatus
.Status
;
161 if (!NT_SUCCESS(Status
))
163 DPRINT("RawFsReadDisk() failed. Status %x\n", Status
);
164 DPRINT("(pDeviceObject 0x%p, Offset %I64x, Size %d, Buffer 0x%p\n",
165 pDeviceObject
, ReadOffset
->QuadPart
, ReadLength
, Buffer
);
168 DPRINT("Block request succeeded for 0x%p\n", Irp
);
169 return STATUS_SUCCESS
;
173 RawFsWriteDisk(IN PDEVICE_OBJECT pDeviceObject
,
174 IN PLARGE_INTEGER WriteOffset
,
175 IN ULONG WriteLength
,
178 IO_STATUS_BLOCK IoStatus
;
183 DPRINT("RawFsWriteDisk(pDeviceObject 0x%p, Offset %I64x, Size %d, Buffer 0x%p)\n",
184 pDeviceObject
, WriteOffset
->QuadPart
, WriteLength
, Buffer
);
186 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
188 DPRINT("Building synchronous FSD Request...\n");
189 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_WRITE
,
198 DPRINT("IoBuildSynchronousFsdRequest()\n");
199 return(STATUS_UNSUCCESSFUL
);
202 DPRINT("Calling IO Driver...\n");
203 Status
= IoCallDriver(pDeviceObject
, Irp
);
205 DPRINT("Waiting for IO Operation...\n");
206 if (Status
== STATUS_PENDING
)
208 KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
209 DPRINT("Getting IO Status...\n");
210 Status
= IoStatus
.Status
;
212 if (!NT_SUCCESS(Status
))
214 DPRINT("RawFsWriteDisk() failed. Status %x\n", Status
);
215 DPRINT("(pDeviceObject 0x%p, Offset %I64x, Size %d, Buffer 0x%p\n",
216 pDeviceObject
, WriteOffset
->QuadPart
, WriteLength
, Buffer
);
220 return STATUS_SUCCESS
;
224 RawFsBlockDeviceIoControl(IN PDEVICE_OBJECT DeviceObject
,
226 IN PVOID InputBuffer
,
227 IN ULONG InputBufferSize
,
228 IN OUT PVOID OutputBuffer
,
229 IN OUT PULONG pOutputBufferSize
)
231 ULONG OutputBufferSize
= 0;
234 IO_STATUS_BLOCK IoStatus
;
237 DPRINT("RawFsBlockDeviceIoControl(DeviceObject 0x%p, CtlCode %x, "
238 "InputBuffer 0x%p, InputBufferSize %x, OutputBuffer 0x%p, "
239 "POutputBufferSize 0x%p (%x)\n", DeviceObject
, CtlCode
,
240 InputBuffer
, InputBufferSize
, OutputBuffer
, pOutputBufferSize
,
241 pOutputBufferSize
? *pOutputBufferSize
: 0);
243 if (pOutputBufferSize
)
245 OutputBufferSize
= *pOutputBufferSize
;
248 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
250 DPRINT("Building device I/O control request ...\n");
251 Irp
= IoBuildDeviceIoControlRequest(CtlCode
,
262 DPRINT("IoBuildDeviceIoControlRequest failed\n");
263 return STATUS_INSUFFICIENT_RESOURCES
;
266 DPRINT("Calling IO Driver... with irp 0x%p\n", Irp
);
267 Status
= IoCallDriver(DeviceObject
, Irp
);
269 DPRINT("Waiting for IO Operation for 0x%p\n", Irp
);
270 if (Status
== STATUS_PENDING
)
272 DPRINT("Operation pending\n");
273 KeWaitForSingleObject (&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
274 DPRINT("Getting IO Status... for 0x%p\n", Irp
);
275 Status
= IoStatus
.Status
;
277 if (OutputBufferSize
)
279 *pOutputBufferSize
= OutputBufferSize
;
281 DPRINT("Returning Status %x\n", Status
);
286 RawFsNewFCB(IN PRAWFS_GLOBAL_DATA pGlobalData
)
290 Fcb
= ExAllocateFromNPagedLookasideList(&pGlobalData
->FcbLookasideList
);
291 memset(Fcb
, 0, sizeof(RAWFS_FCB
));
292 ExInitializeResourceLite(&Fcb
->PagingIoResource
);
293 ExInitializeResourceLite(&Fcb
->MainResource
);
294 // FsRtlInitializeFileLock(&Fcb->FileLock, NULL, NULL);
299 RawFsDestroyFCB(IN PRAWFS_GLOBAL_DATA pGlobalData
, IN PRAWFS_FCB pFcb
)
301 //FsRtlUninitializeFileLock(&pFcb->FileLock);
302 ExDeleteResourceLite(&pFcb
->PagingIoResource
);
303 ExDeleteResourceLite(&pFcb
->MainResource
);
304 ExFreeToNPagedLookasideList(&pGlobalData
->FcbLookasideList
, pFcb
);
308 RawFsNewCCB(PRAWFS_GLOBAL_DATA pGlobalData
)
312 Ccb
= ExAllocateFromNPagedLookasideList(&pGlobalData
->CcbLookasideList
);
313 memset(Ccb
, 0, sizeof(RAWFS_CCB
));
318 RawFsDestroyCCB(PRAWFS_GLOBAL_DATA pGlobalData
, PRAWFS_CCB pCcb
)
320 ExFreeToNPagedLookasideList(&pGlobalData
->CcbLookasideList
, pCcb
);
323 static PRAWFS_IRP_CONTEXT
324 RawFsAllocateIrpContext(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
)
326 PRAWFS_GLOBAL_DATA GlobalData
;
327 PRAWFS_IRP_CONTEXT IrpContext
;
330 DPRINT("RawFsAllocateIrpContext(DeviceObject 0x%p, Irp 0x%p)\n", DeviceObject
, Irp
);
332 ASSERT(DeviceObject
);
335 GlobalData
= (PRAWFS_GLOBAL_DATA
) DeviceObject
->DeviceExtension
;
336 IrpContext
= ExAllocateFromNPagedLookasideList(&IrpContextLookasideList
);
339 RtlZeroMemory(IrpContext
, sizeof(IrpContext
));
340 IrpContext
->Irp
= Irp
;
341 IrpContext
->DeviceObject
= DeviceObject
;
342 IrpContext
->DeviceExt
= DeviceObject
->DeviceExtension
;
343 IrpContext
->Stack
= IoGetCurrentIrpStackLocation(Irp
);
344 ASSERT(IrpContext
->Stack
);
345 MajorFunction
= IrpContext
->MajorFunction
= IrpContext
->Stack
->MajorFunction
;
346 IrpContext
->MinorFunction
= IrpContext
->Stack
->MinorFunction
;
347 IrpContext
->FileObject
= IrpContext
->Stack
->FileObject
;
348 if (MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
||
349 MajorFunction
== IRP_MJ_DEVICE_CONTROL
||
350 MajorFunction
== IRP_MJ_SHUTDOWN
)
352 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
354 else if (MajorFunction
!= IRP_MJ_CLEANUP
&&
355 MajorFunction
!= IRP_MJ_CLOSE
&&
356 IoIsOperationSynchronous(Irp
))
358 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
365 RawFsFreeIrpContext(IN PRAWFS_IRP_CONTEXT IrpContext
)
367 DPRINT("RawFsFreeIrpContext(IrpContext 0x%p)\n", IrpContext
);
371 ExFreeToNPagedLookasideList(&IrpContextLookasideList
, IrpContext
);
375 STDCALL
RawFsDoRequest(PVOID IrpContext
)
379 Count
= InterlockedDecrement(&RawFsQueueCount
);
381 DPRINT("RawFsDoRequest(IrpContext 0x%p), MajorFunction %x, %d\n",
382 IrpContext
, ((PRAWFS_IRP_CONTEXT
) IrpContext
)->MajorFunction
, Count
);
384 RawFsDispatchRequest((PRAWFS_IRP_CONTEXT
) IrpContext
);
388 RawFsQueueRequest(PRAWFS_IRP_CONTEXT IrpContext
)
392 ASSERT(IrpContext
!= NULL
);
393 ASSERT(IrpContext
->Irp
!= NULL
);
395 Count
= InterlockedIncrement(&RawFsQueueCount
);
397 DPRINT("RawFsQueueRequest (IrpContext 0x%p), %d\n", IrpContext
, Count
);
399 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
400 IoMarkIrpPending (IrpContext
->Irp
);
401 ExInitializeWorkItem (&IrpContext
->WorkQueueItem
, RawFsDoRequest
, IrpContext
);
402 ExQueueWorkItem(&IrpContext
->WorkQueueItem
, CriticalWorkQueue
);
403 return STATUS_PENDING
;
407 RawFsClose(IN PRAWFS_IRP_CONTEXT IrpContext
)
409 DPRINT("RawFsClose(IrpContext 0x%p)\n", IrpContext
);
411 return STATUS_NOT_IMPLEMENTED
;
415 RawFsCreateFile(IN PRAWFS_IRP_CONTEXT IrpContext
)
417 PRAWFS_DEVICE_EXTENSION DeviceExt
;
418 PRAWFS_GLOBAL_DATA GlobalData
;
419 PIO_STACK_LOCATION IoSp
;
420 PFILE_OBJECT FileObject
;
421 ULONG RequestedDisposition
;
422 ULONG RequestedOptions
;
426 GlobalData
= (PRAWFS_GLOBAL_DATA
) IrpContext
->DeviceObject
->DeviceExtension
;
427 IoSp
= IoGetCurrentIrpStackLocation(IrpContext
->Irp
);
428 RequestedDisposition
= ((IoSp
->Parameters
.Create
.Options
>> 24) & 0xff);
429 RequestedOptions
= IoSp
->Parameters
.Create
.Options
& FILE_VALID_OPTION_FLAGS
;
430 FileObject
= IoSp
->FileObject
;
431 DeviceExt
= IrpContext
->DeviceObject
->DeviceExtension
;
433 if (FileObject
->FileName
.Length
== 0 &&
434 FileObject
->RelatedFileObject
== NULL
)
436 /* This a open operation for the volume itself */
437 if (RequestedDisposition
== FILE_CREATE
438 || RequestedDisposition
== FILE_OVERWRITE_IF
439 || RequestedDisposition
== FILE_SUPERSEDE
)
441 return STATUS_ACCESS_DENIED
;
443 if (RequestedOptions
& FILE_DIRECTORY_FILE
)
445 return STATUS_NOT_A_DIRECTORY
;
447 pFcb
= DeviceExt
->VolumeFcb
;
448 pCcb
= RawFsNewCCB(GlobalData
);
451 return (STATUS_INSUFFICIENT_RESOURCES
);
454 FileObject
->SectionObjectPointer
= &pFcb
->SectionObjectPointers
;
455 FileObject
->FsContext
= pFcb
;
456 FileObject
->FsContext2
= pCcb
;
459 IrpContext
->Irp
->IoStatus
.Information
= FILE_OPENED
;
460 return(STATUS_SUCCESS
);
463 /* This filesystem driver only supports volume access */
464 return(STATUS_INVALID_PARAMETER
);
468 RawFsCreate(IN PRAWFS_IRP_CONTEXT IrpContext
)
472 DPRINT("RawFsCreate(IrpContext 0x%p)\n", IrpContext
);
476 if (RawFsIsRawFileSystemDeviceObject(IrpContext
->DeviceObject
))
478 /* DeviceObject represents FileSystem instead of logical volume */
479 DPRINT("RawFsCreate() called with file system\n");
480 IrpContext
->Irp
->IoStatus
.Information
= FILE_OPENED
;
481 IrpContext
->Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
482 IoCompleteRequest(IrpContext
->Irp
, IO_DISK_INCREMENT
);
483 RawFsFreeIrpContext(IrpContext
);
484 return STATUS_SUCCESS
;
487 if (!(IrpContext
->Flags
& IRPCONTEXT_CANWAIT
))
489 return RawFsQueueRequest(IrpContext
);
492 IrpContext
->Irp
->IoStatus
.Information
= 0;
494 Status
= RawFsCreateFile(IrpContext
);
496 IrpContext
->Irp
->IoStatus
.Status
= Status
;
497 IoCompleteRequest(IrpContext
->Irp
,
498 (CCHAR
)(NT_SUCCESS(Status
) ? IO_DISK_INCREMENT
: IO_NO_INCREMENT
));
499 RawFsFreeIrpContext(IrpContext
);
505 RawFsRead(IN PRAWFS_IRP_CONTEXT IrpContext
)
507 DPRINT("RawFsRead(IrpContext 0x%p)\n", IrpContext
);
509 return STATUS_NOT_IMPLEMENTED
;
513 RawFsWrite(IN PRAWFS_IRP_CONTEXT IrpContext
)
515 DPRINT("RawFsWrite(IrpContext 0x%p)\n", IrpContext
);
517 return STATUS_NOT_IMPLEMENTED
;
521 RawFsMount(IN PRAWFS_IRP_CONTEXT IrpContext
)
523 PRAWFS_GLOBAL_DATA GlobalData
= NULL
;
524 PDEVICE_OBJECT DeviceObject
= NULL
;
525 PRAWFS_DEVICE_EXTENSION DeviceExt
= NULL
;
526 PRAWFS_FCB VolumeFcb
= NULL
;
527 PRAWFS_FCB Fcb
= NULL
;
528 PARTITION_INFORMATION PartitionInfo
;
529 DISK_GEOMETRY DiskGeometry
;
530 LARGE_INTEGER VolumeSize
;
534 DPRINT("RawFsMount(IrpContext 0x%p)\n", IrpContext
);
538 if (!RawFsIsRawFileSystemDeviceObject(IrpContext
->DeviceObject
))
540 Status
= STATUS_INVALID_DEVICE_REQUEST
;
541 DPRINT("Not for me\n");
545 GlobalData
= (PRAWFS_GLOBAL_DATA
) IrpContext
->DeviceObject
->DeviceExtension
;
547 Status
= IoCreateDevice(GlobalData
->DriverObject
,
548 sizeof(RAWFS_DEVICE_EXTENSION
),
550 FILE_DEVICE_FILE_SYSTEM
,
554 if (!NT_SUCCESS(Status
))
559 DeviceObject
->Flags
|= DO_DIRECT_IO
;
560 DeviceExt
= (PVOID
) DeviceObject
->DeviceExtension
;
561 RtlZeroMemory(DeviceExt
, sizeof(RAWFS_DEVICE_EXTENSION
));
563 /* Use same vpb as device disk */
564 DeviceObject
->Vpb
= IrpContext
->Stack
->Parameters
.MountVolume
.DeviceObject
->Vpb
;
565 DeviceExt
->StorageDevice
= IrpContext
->Stack
->Parameters
.MountVolume
.DeviceObject
;
566 DeviceExt
->StorageDevice
->Vpb
->DeviceObject
= DeviceObject
;
567 DeviceExt
->StorageDevice
->Vpb
->RealDevice
= DeviceExt
->StorageDevice
;
568 DeviceExt
->StorageDevice
->Vpb
->Flags
|= VPB_MOUNTED
;
569 DeviceObject
->StackSize
= DeviceExt
->StorageDevice
->StackSize
+ 1;
570 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
572 KeInitializeSpinLock(&DeviceExt
->FcbListLock
);
573 InitializeListHead(&DeviceExt
->FcbListHead
);
575 /* First try getting harddisk geometry then try getting CD-ROM geometry */
576 Size
= sizeof(DISK_GEOMETRY
);
577 Status
= RawFsBlockDeviceIoControl(
578 IrpContext
->Stack
->Parameters
.MountVolume
.DeviceObject
,
579 IOCTL_DISK_GET_DRIVE_GEOMETRY
,
584 if (!NT_SUCCESS(Status
))
586 DPRINT("RawFsBlockDeviceIoControl failed with status 0x%.08x\n", Status
);
589 if (DiskGeometry
.MediaType
== FixedMedia
)
591 // We have found a hard disk
592 Size
= sizeof(PARTITION_INFORMATION
);
593 Status
= RawFsBlockDeviceIoControl(
594 IrpContext
->Stack
->Parameters
.MountVolume
.DeviceObject
,
595 IOCTL_DISK_GET_PARTITION_INFO
,
600 if (!NT_SUCCESS(Status
))
602 DPRINT("RawFsBlockDeviceIoControl() failed (%x)\n", Status
);
606 DbgPrint("Partition Information:\n");
607 DbgPrint("StartingOffset %u\n", PartitionInfo
.StartingOffset
.QuadPart
);
608 DbgPrint("PartitionLength %u\n", PartitionInfo
.PartitionLength
.QuadPart
);
609 DbgPrint("HiddenSectors %u\n", PartitionInfo
.HiddenSectors
);
610 DbgPrint("PartitionNumber %u\n", PartitionInfo
.PartitionNumber
);
611 DbgPrint("PartitionType %u\n", PartitionInfo
.PartitionType
);
612 DbgPrint("BootIndicator %u\n", PartitionInfo
.BootIndicator
);
613 DbgPrint("RecognizedPartition %u\n", PartitionInfo
.RecognizedPartition
);
614 DbgPrint("RewritePartition %u\n", PartitionInfo
.RewritePartition
);
616 VolumeSize
.QuadPart
= PartitionInfo
.PartitionLength
.QuadPart
;
618 else if (DiskGeometry
.MediaType
> Unknown
&& DiskGeometry
.MediaType
<= RemovableMedia
)
620 Status
= STATUS_UNRECOGNIZED_VOLUME
;
624 VolumeFcb
= RawFsNewFCB(GlobalData
);
625 if (VolumeFcb
== NULL
)
627 Status
= STATUS_INSUFFICIENT_RESOURCES
;
631 VolumeFcb
->Flags
= FCB_IS_VOLUME
;
632 VolumeFcb
->RFCB
.FileSize
.QuadPart
= VolumeSize
.QuadPart
;
633 VolumeFcb
->RFCB
.ValidDataLength
.QuadPart
= VolumeFcb
->RFCB
.FileSize
.QuadPart
;
634 VolumeFcb
->RFCB
.AllocationSize
.QuadPart
= VolumeFcb
->RFCB
.FileSize
.QuadPart
;
635 DeviceExt
->VolumeFcb
= VolumeFcb
;
637 KeEnterCriticalRegion();
638 ExAcquireResourceExclusiveLite(&GlobalData
->VolumeListLock
, TRUE
);
639 InsertHeadList(&GlobalData
->VolumeListHead
, &DeviceExt
->VolumeListEntry
);
640 ExReleaseResourceLite(&GlobalData
->VolumeListLock
);
641 KeLeaveCriticalRegion();
643 /* No serial number */
644 DeviceObject
->Vpb
->SerialNumber
= 0;
646 /* Set volume label (no label) */
647 *(DeviceObject
->Vpb
->VolumeLabel
) = 0;
648 DeviceObject
->Vpb
->VolumeLabelLength
= 0;
650 Status
= STATUS_SUCCESS
;
653 if (!NT_SUCCESS(Status
))
655 DPRINT("RAWFS: RawFsMount() Status 0x%.08x\n", Status
);
658 RawFsDestroyFCB(GlobalData
, Fcb
);
660 IoDeleteDevice(DeviceObject
);
662 RawFsDestroyFCB(GlobalData
, VolumeFcb
);
668 RawFsFileSystemControl(IN PRAWFS_IRP_CONTEXT IrpContext
)
672 DPRINT("RawFsFileSystemControl(IrpContext 0x%p)\n", IrpContext
);
676 switch (IrpContext
->MinorFunction
)
678 case IRP_MN_USER_FS_REQUEST
:
679 DPRINT("RawFs FSC: IRP_MN_USER_FS_REQUEST\n");
680 Status
= STATUS_INVALID_DEVICE_REQUEST
;
683 case IRP_MN_MOUNT_VOLUME
:
684 DPRINT("RawFs FSC: IRP_MN_MOUNT_VOLUME\n");
685 Status
= RawFsMount(IrpContext
);
688 case IRP_MN_VERIFY_VOLUME
:
689 DPRINT("RawFs FSC: IRP_MN_VERIFY_VOLUME\n");
690 Status
= STATUS_INVALID_DEVICE_REQUEST
;
694 DPRINT("RawFs FSC: MinorFunction %d\n", IrpContext
->MinorFunction
);
695 Status
= STATUS_INVALID_DEVICE_REQUEST
;
699 IrpContext
->Irp
->IoStatus
.Status
= Status
;
700 IrpContext
->Irp
->IoStatus
.Information
= 0;
702 IoCompleteRequest(IrpContext
->Irp
, IO_NO_INCREMENT
);
703 RawFsFreeIrpContext(IrpContext
);
708 RawFsQueryInformation(IN PRAWFS_IRP_CONTEXT IrpContext
)
710 DPRINT("RawFsQueryInformation(IrpContext 0x%p)\n", IrpContext
);
712 return STATUS_NOT_IMPLEMENTED
;
716 RawFsSetInformation(IN PRAWFS_IRP_CONTEXT IrpContext
)
718 DPRINT("RawFsSetInformation(IrpContext 0x%p)\n", IrpContext
);
720 return STATUS_NOT_IMPLEMENTED
;
724 RawFsDirectoryControl(IN PRAWFS_IRP_CONTEXT IrpContext
)
726 DPRINT("RawFsDirectoryControl(IrpContext 0x%p)\n", IrpContext
);
728 return STATUS_NOT_IMPLEMENTED
;
732 RawFsQueryVolumeInformation(IN PRAWFS_IRP_CONTEXT IrpContext
)
734 DPRINT("RawFsQueryVolumeInformation(IrpContext 0x%p)\n", IrpContext
);
736 return STATUS_NOT_IMPLEMENTED
;
740 RawFsSetVolumeInformation(IN PRAWFS_IRP_CONTEXT IrpContext
)
742 DPRINT("RawFsSetVolumeInformation(IrpContext 0x%p)\n", IrpContext
);
744 return STATUS_NOT_IMPLEMENTED
;
748 RawFsLockControl(IN PRAWFS_IRP_CONTEXT IrpContext
)
750 DPRINT("RawFsLockControl(IrpContext 0x%p)\n", IrpContext
);
752 return STATUS_NOT_IMPLEMENTED
;
756 RawFsCleanup(IN PRAWFS_IRP_CONTEXT IrpContext
)
758 DPRINT("RawFsCleanup(IrpContext 0x%p)\n", IrpContext
);
760 return STATUS_NOT_IMPLEMENTED
;
764 RawFsFlush(IN PRAWFS_IRP_CONTEXT IrpContext
)
766 DPRINT("RawFsFlush(IrpContext 0x%p)\n", IrpContext
);
768 return STATUS_NOT_IMPLEMENTED
;
771 static NTSTATUS STDCALL
772 RawFsShutdown(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
)
774 DPRINT("RawFsShutdown(DeviceObject 0x%p, Irp 0x%p)\n", DeviceObject
, Irp
);
777 * Note: Do NOT call UNIMPLEMENTED here!
778 * This function must finish in order to shutdown ReactOS properly!
781 return STATUS_NOT_IMPLEMENTED
;
785 RawFsDispatchRequest(IN PRAWFS_IRP_CONTEXT IrpContext
)
787 DPRINT("RawFsDispatchRequest(IrpContext 0x%p), MajorFunction %x\n",
788 IrpContext
, IrpContext
->MajorFunction
);
792 switch (IrpContext
->MajorFunction
)
795 return RawFsClose(IrpContext
);
797 return RawFsCreate (IrpContext
);
799 return RawFsRead (IrpContext
);
801 return RawFsWrite (IrpContext
);
802 case IRP_MJ_FILE_SYSTEM_CONTROL
:
803 return RawFsFileSystemControl(IrpContext
);
804 case IRP_MJ_QUERY_INFORMATION
:
805 return RawFsQueryInformation (IrpContext
);
806 case IRP_MJ_SET_INFORMATION
:
807 return RawFsSetInformation (IrpContext
);
808 case IRP_MJ_DIRECTORY_CONTROL
:
809 return RawFsDirectoryControl(IrpContext
);
810 case IRP_MJ_QUERY_VOLUME_INFORMATION
:
811 return RawFsQueryVolumeInformation(IrpContext
);
812 case IRP_MJ_SET_VOLUME_INFORMATION
:
813 return RawFsSetVolumeInformation(IrpContext
);
814 case IRP_MJ_LOCK_CONTROL
:
815 return RawFsLockControl(IrpContext
);
817 return RawFsCleanup(IrpContext
);
818 case IRP_MJ_FLUSH_BUFFERS
:
819 return RawFsFlush(IrpContext
);
821 DPRINT1("Unexpected major function %x\n", IrpContext
->MajorFunction
);
822 IrpContext
->Irp
->IoStatus
.Status
= STATUS_DRIVER_INTERNAL_ERROR
;
823 IoCompleteRequest(IrpContext
->Irp
, IO_NO_INCREMENT
);
824 RawFsFreeIrpContext(IrpContext
);
825 return STATUS_DRIVER_INTERNAL_ERROR
;
829 static NTSTATUS STDCALL
830 RawFsBuildRequest(IN PDEVICE_OBJECT DeviceObject
,
833 PRAWFS_IRP_CONTEXT IrpContext
;
836 DPRINT("RawFsBuildRequest(DeviceObject 0x%p, Irp 0x%p)\n", DeviceObject
, Irp
);
838 ASSERT(DeviceObject
);
841 IrpContext
= RawFsAllocateIrpContext(DeviceObject
, Irp
);
842 if (IrpContext
== NULL
)
844 Status
= STATUS_INSUFFICIENT_RESOURCES
;
845 Irp
->IoStatus
.Status
= Status
;
846 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
850 if (KeGetCurrentIrql() <= PASSIVE_LEVEL
)
852 FsRtlEnterFileSystem();
856 DPRINT1("RawFs is entered at irql = %d\n", KeGetCurrentIrql());
858 Status
= RawFsDispatchRequest(IrpContext
);
859 if (KeGetCurrentIrql() <= PASSIVE_LEVEL
)
861 FsRtlExitFileSystem();
868 RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject
,
869 IN PUNICODE_STRING RegistryPath
)
871 PRAWFS_GLOBAL_DATA DeviceData
;
874 RawFsDriverObject
= DriverObject
;
876 Status
= IoCreateDevice(DriverObject
,
877 sizeof(RAWFS_GLOBAL_DATA
),
879 FILE_DEVICE_DISK_FILE_SYSTEM
,
883 if (!NT_SUCCESS(Status
))
885 CPRINT("IoCreateDevice() failed with status 0x%.08x\n", Status
);
886 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
889 DeviceData
= DiskDeviceObject
->DeviceExtension
;
890 RtlZeroMemory(DeviceData
, sizeof(RAWFS_GLOBAL_DATA
));
891 DeviceData
->DriverObject
= DriverObject
;
892 DeviceData
->DeviceObject
= DiskDeviceObject
;
893 DiskDeviceObject
->Flags
|= DO_DIRECT_IO
;
896 Status
= IoCreateDevice(DriverObject
,
897 sizeof(RAWFS_GLOBAL_DATA
),
899 FILE_DEVICE_CD_ROM_FILE_SYSTEM
,
903 if (!NT_SUCCESS(Status
))
905 CPRINT("IoCreateDevice() failed with status 0x%.08x\n", Status
);
906 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
909 DeviceData
= CdromDeviceObject
->DeviceExtension
;
910 RtlZeroMemory (DeviceData
, sizeof(RAWFS_GLOBAL_DATA
));
911 DeviceData
->DriverObject
= DriverObject
;
912 DeviceData
->DeviceObject
= CdromDeviceObject
;
913 CdromDeviceObject
->Flags
|= DO_DIRECT_IO
;
916 Status
= IoCreateDevice(DriverObject
,
917 sizeof(RAWFS_GLOBAL_DATA
),
919 FILE_DEVICE_TAPE_FILE_SYSTEM
,
923 if (!NT_SUCCESS(Status
))
925 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
928 DeviceData
= TapeDeviceObject
->DeviceExtension
;
929 RtlZeroMemory (DeviceData
, sizeof(RAWFS_GLOBAL_DATA
));
930 DeviceData
->DriverObject
= DriverObject
;
931 DeviceData
->DeviceObject
= TapeDeviceObject
;
932 TapeDeviceObject
->Flags
|= DO_DIRECT_IO
;
935 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
936 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
937 DriverObject
->MajorFunction
[IRP_MJ_READ
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
938 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
939 DriverObject
->MajorFunction
[IRP_MJ_FILE_SYSTEM_CONTROL
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
940 DriverObject
->MajorFunction
[IRP_MJ_QUERY_INFORMATION
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
941 DriverObject
->MajorFunction
[IRP_MJ_SET_INFORMATION
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
942 DriverObject
->MajorFunction
[IRP_MJ_DIRECTORY_CONTROL
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
943 DriverObject
->MajorFunction
[IRP_MJ_QUERY_VOLUME_INFORMATION
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
944 DriverObject
->MajorFunction
[IRP_MJ_SET_VOLUME_INFORMATION
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
945 DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = (PDRIVER_DISPATCH
) RawFsShutdown
;
946 DriverObject
->MajorFunction
[IRP_MJ_LOCK_CONTROL
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
947 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
948 DriverObject
->MajorFunction
[IRP_MJ_FLUSH_BUFFERS
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
949 DriverObject
->DriverUnload
= NULL
;
951 ExInitializeNPagedLookasideList(&IrpContextLookasideList
,
952 NULL
, NULL
, 0, sizeof(RAWFS_IRP_CONTEXT
), TAG_IRP
, 0);
955 IoRegisterFileSystem(DiskDeviceObject
);
956 IoRegisterFileSystem(CdromDeviceObject
);
957 IoRegisterFileSystem(TapeDeviceObject
);
959 return STATUS_SUCCESS
;