1 /* $Id: rawfs.c,v 1.13 2004/10/22 20:25:54 ekohl Exp $
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 *****************************************************************/
16 #include <internal/debug.h>
18 /* TYPES *******************************************************************/
20 typedef struct _RAWFS_GLOBAL_DATA
22 PDRIVER_OBJECT DriverObject
;
23 PDEVICE_OBJECT DeviceObject
;
25 ERESOURCE VolumeListLock
;
26 LIST_ENTRY VolumeListHead
;
27 NPAGED_LOOKASIDE_LIST FcbLookasideList
;
28 NPAGED_LOOKASIDE_LIST CcbLookasideList
;
29 } RAWFS_GLOBAL_DATA
, *PRAWFS_GLOBAL_DATA
, VCB
, *PVCB
;
31 typedef struct _RAWFS_DEVICE_EXTENSION
33 KSPIN_LOCK FcbListLock
;
34 LIST_ENTRY FcbListHead
;
35 PDEVICE_OBJECT StorageDevice
;
37 struct _RAWFS_FCB
*VolumeFcb
;
38 LIST_ENTRY VolumeListEntry
;
39 } RAWFS_DEVICE_EXTENSION
, *PRAWFS_DEVICE_EXTENSION
;
41 typedef struct _RAWFS_IRP_CONTEXT
44 PDEVICE_OBJECT DeviceObject
;
45 PRAWFS_DEVICE_EXTENSION DeviceExt
;
47 WORK_QUEUE_ITEM WorkQueueItem
;
48 PIO_STACK_LOCATION Stack
;
51 PFILE_OBJECT FileObject
;
52 } RAWFS_IRP_CONTEXT
, *PRAWFS_IRP_CONTEXT
;
54 #define IRPCONTEXT_CANWAIT 0x0001
56 #define FCB_CACHE_INITIALIZED 0x0001
57 #define FCB_DELETE_PENDING 0x0002
58 #define FCB_IS_FAT 0x0004
59 #define FCB_IS_PAGE_FILE 0x0008
60 #define FCB_IS_VOLUME 0x0010
62 typedef struct _RAWFS_FCB
64 /* Start FCB header required by ReactOS/Windows NT */
65 FSRTL_COMMON_FCB_HEADER RFCB
;
66 SECTION_OBJECT_POINTERS SectionObjectPointers
;
67 ERESOURCE MainResource
;
68 ERESOURCE PagingIoResource
;
69 /* End FCB header required by ReactOS/Windows NT */
74 /* List of FCB's for this volume */
75 LIST_ENTRY FcbListEntry
;
77 /* Pointer to the parent fcb */
78 struct _RAWFS_FCB
* ParentFcb
;
80 /* Flags for the FCB */
83 /* Pointer to the file object which has initialized the fcb */
84 PFILE_OBJECT FileObject
;
85 } RAWFS_FCB
, *PRAWFS_FCB
;
87 typedef struct _RAWFS_CCB
89 LARGE_INTEGER CurrentByteOffset
;
90 } RAWFS_CCB
, *PRAWFS_CCB
;
92 /* GLOBALS ******************************************************************/
94 #define TAG_IRP TAG('R', 'I', 'R', 'P')
96 static PDRIVER_OBJECT RawFsDriverObject
;
97 static PDEVICE_OBJECT DiskDeviceObject
;
98 static PDEVICE_OBJECT CdromDeviceObject
;
99 static PDEVICE_OBJECT TapeDeviceObject
;
100 static NPAGED_LOOKASIDE_LIST IrpContextLookasideList
;
101 static LONG RawFsQueueCount
= 0;
103 /* FUNCTIONS *****************************************************************/
106 RawFsIsRawFileSystemDeviceObject(IN PDEVICE_OBJECT DeviceObject
)
108 DPRINT("RawFsIsRawFileSystemDeviceObject(DeviceObject %x)\n", DeviceObject
);
110 if (DeviceObject
== DiskDeviceObject
)
112 if (DeviceObject
== CdromDeviceObject
)
114 if (DeviceObject
== TapeDeviceObject
)
120 RawFsDispatchRequest(IN PRAWFS_IRP_CONTEXT IrpContext
);
123 RawFsReadDisk(IN PDEVICE_OBJECT pDeviceObject
,
124 IN PLARGE_INTEGER ReadOffset
,
126 IN OUT PUCHAR Buffer
)
128 IO_STATUS_BLOCK IoStatus
;
133 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
135 DPRINT("RawFsReadDisk(pDeviceObject %x, Offset %I64x, Length %d, Buffer %x)\n",
136 pDeviceObject
, ReadOffset
->QuadPart
, ReadLength
, Buffer
);
138 DPRINT ("Building synchronous FSD Request...\n");
139 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
,
148 DPRINT("IoBuildSynchronousFsdRequest() failed\n");
149 return STATUS_UNSUCCESSFUL
;
152 DPRINT("Calling IO Driver... with irp %x\n", Irp
);
153 Status
= IoCallDriver(pDeviceObject
, Irp
);
155 DPRINT("Waiting for IO Operation for %x\n", Irp
);
156 if (Status
== STATUS_PENDING
)
158 DPRINT("Operation pending\n");
159 KeWaitForSingleObject (&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
160 DPRINT("Getting IO Status... for %x\n", Irp
);
161 Status
= IoStatus
.Status
;
164 if (!NT_SUCCESS(Status
))
166 DPRINT("RawFsReadDisk() failed. Status %x\n", Status
);
167 DPRINT("(pDeviceObject %x, Offset %I64x, Size %d, Buffer %x\n",
168 pDeviceObject
, ReadOffset
->QuadPart
, ReadLength
, Buffer
);
171 DPRINT("Block request succeeded for %x\n", Irp
);
172 return STATUS_SUCCESS
;
176 RawFsWriteDisk(IN PDEVICE_OBJECT pDeviceObject
,
177 IN PLARGE_INTEGER WriteOffset
,
178 IN ULONG WriteLength
,
181 IO_STATUS_BLOCK IoStatus
;
186 DPRINT("RawFsWriteDisk(pDeviceObject %x, Offset %I64x, Size %d, Buffer %x)\n",
187 pDeviceObject
, WriteOffset
->QuadPart
, WriteLength
, Buffer
);
189 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
191 DPRINT("Building synchronous FSD Request...\n");
192 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_WRITE
,
201 DPRINT("IoBuildSynchronousFsdRequest()\n");
202 return(STATUS_UNSUCCESSFUL
);
205 DPRINT("Calling IO Driver...\n");
206 Status
= IoCallDriver(pDeviceObject
, Irp
);
208 DPRINT("Waiting for IO Operation...\n");
209 if (Status
== STATUS_PENDING
)
211 KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
212 DPRINT("Getting IO Status...\n");
213 Status
= IoStatus
.Status
;
215 if (!NT_SUCCESS(Status
))
217 DPRINT("RawFsWriteDisk() failed. Status %x\n", Status
);
218 DPRINT("(pDeviceObject %x, Offset %I64x, Size %d, Buffer %x\n",
219 pDeviceObject
, WriteOffset
->QuadPart
, WriteLength
, Buffer
);
223 return STATUS_SUCCESS
;
227 RawFsBlockDeviceIoControl(IN PDEVICE_OBJECT DeviceObject
,
229 IN PVOID InputBuffer
,
230 IN ULONG InputBufferSize
,
231 IN OUT PVOID OutputBuffer
,
232 IN OUT PULONG pOutputBufferSize
)
234 ULONG OutputBufferSize
= 0;
237 IO_STATUS_BLOCK IoStatus
;
240 DPRINT("RawFsBlockDeviceIoControl(DeviceObject %x, CtlCode %x, "
241 "InputBuffer %x, InputBufferSize %x, OutputBuffer %x, "
242 "POutputBufferSize %x (%x)\n", DeviceObject
, CtlCode
,
243 InputBuffer
, InputBufferSize
, OutputBuffer
, pOutputBufferSize
,
244 pOutputBufferSize
? *pOutputBufferSize
: 0);
246 if (pOutputBufferSize
)
248 OutputBufferSize
= *pOutputBufferSize
;
251 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
253 DPRINT("Building device I/O control request ...\n");
254 Irp
= IoBuildDeviceIoControlRequest(CtlCode
,
265 DPRINT("IoBuildDeviceIoControlRequest failed\n");
266 return STATUS_INSUFFICIENT_RESOURCES
;
269 DPRINT("Calling IO Driver... with irp %x\n", Irp
);
270 Status
= IoCallDriver(DeviceObject
, Irp
);
272 DPRINT("Waiting for IO Operation for %x\n", Irp
);
273 if (Status
== STATUS_PENDING
)
275 DPRINT("Operation pending\n");
276 KeWaitForSingleObject (&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
277 DPRINT("Getting IO Status... for %x\n", Irp
);
278 Status
= IoStatus
.Status
;
280 if (OutputBufferSize
)
282 *pOutputBufferSize
= OutputBufferSize
;
284 DPRINT("Returning Status %x\n", Status
);
289 RawFsNewFCB(IN PRAWFS_GLOBAL_DATA pGlobalData
)
293 Fcb
= ExAllocateFromNPagedLookasideList(&pGlobalData
->FcbLookasideList
);
294 memset(Fcb
, 0, sizeof(RAWFS_FCB
));
295 ExInitializeResourceLite(&Fcb
->PagingIoResource
);
296 ExInitializeResourceLite(&Fcb
->MainResource
);
297 // FsRtlInitializeFileLock(&Fcb->FileLock, NULL, NULL);
302 RawFsDestroyFCB(IN PRAWFS_GLOBAL_DATA pGlobalData
, IN PRAWFS_FCB pFcb
)
304 //FsRtlUninitializeFileLock(&pFcb->FileLock);
305 ExDeleteResourceLite(&pFcb
->PagingIoResource
);
306 ExDeleteResourceLite(&pFcb
->MainResource
);
307 ExFreeToNPagedLookasideList(&pGlobalData
->FcbLookasideList
, pFcb
);
311 RawFsNewCCB(PRAWFS_GLOBAL_DATA pGlobalData
)
315 Ccb
= ExAllocateFromNPagedLookasideList(&pGlobalData
->CcbLookasideList
);
316 memset(Ccb
, 0, sizeof(RAWFS_CCB
));
321 RawFsDestroyCCB(PRAWFS_GLOBAL_DATA pGlobalData
, PRAWFS_CCB pCcb
)
323 ExFreeToNPagedLookasideList(&pGlobalData
->CcbLookasideList
, pCcb
);
326 static PRAWFS_IRP_CONTEXT
327 RawFsAllocateIrpContext(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
)
329 PRAWFS_GLOBAL_DATA GlobalData
;
330 PRAWFS_IRP_CONTEXT IrpContext
;
333 DPRINT("RawFsAllocateIrpContext(DeviceObject %x, Irp %x)\n", DeviceObject
, Irp
);
335 ASSERT(DeviceObject
);
338 GlobalData
= (PRAWFS_GLOBAL_DATA
) DeviceObject
->DeviceExtension
;
339 IrpContext
= ExAllocateFromNPagedLookasideList(&IrpContextLookasideList
);
342 RtlZeroMemory(IrpContext
, sizeof(IrpContext
));
343 IrpContext
->Irp
= Irp
;
344 IrpContext
->DeviceObject
= DeviceObject
;
345 IrpContext
->DeviceExt
= DeviceObject
->DeviceExtension
;
346 IrpContext
->Stack
= IoGetCurrentIrpStackLocation(Irp
);
347 ASSERT(IrpContext
->Stack
);
348 MajorFunction
= IrpContext
->MajorFunction
= IrpContext
->Stack
->MajorFunction
;
349 IrpContext
->MinorFunction
= IrpContext
->Stack
->MinorFunction
;
350 IrpContext
->FileObject
= IrpContext
->Stack
->FileObject
;
351 if (MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
||
352 MajorFunction
== IRP_MJ_DEVICE_CONTROL
||
353 MajorFunction
== IRP_MJ_SHUTDOWN
)
355 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
357 else if (MajorFunction
!= IRP_MJ_CLEANUP
&&
358 MajorFunction
!= IRP_MJ_CLOSE
&&
359 IoIsOperationSynchronous(Irp
))
361 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
368 RawFsFreeIrpContext(IN PRAWFS_IRP_CONTEXT IrpContext
)
370 DPRINT("RawFsFreeIrpContext(IrpContext %x)\n", IrpContext
);
374 ExFreeToNPagedLookasideList(&IrpContextLookasideList
, IrpContext
);
378 STDCALL
RawFsDoRequest(PVOID IrpContext
)
382 Count
= InterlockedDecrement(&RawFsQueueCount
);
384 DPRINT("RawFsDoRequest(IrpContext %x), MajorFunction %x, %d\n",
385 IrpContext
, ((PRAWFS_IRP_CONTEXT
) IrpContext
)->MajorFunction
, Count
);
387 RawFsDispatchRequest((PRAWFS_IRP_CONTEXT
) IrpContext
);
391 RawFsQueueRequest(PRAWFS_IRP_CONTEXT IrpContext
)
395 ASSERT(IrpContext
!= NULL
);
396 ASSERT(IrpContext
->Irp
!= NULL
);
398 Count
= InterlockedIncrement(&RawFsQueueCount
);
400 DPRINT("RawFsQueueRequest (IrpContext %x), %d\n", IrpContext
, Count
);
402 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
403 IoMarkIrpPending (IrpContext
->Irp
);
404 ExInitializeWorkItem (&IrpContext
->WorkQueueItem
, RawFsDoRequest
, IrpContext
);
405 ExQueueWorkItem(&IrpContext
->WorkQueueItem
, CriticalWorkQueue
);
406 return STATUS_PENDING
;
410 RawFsClose(IN PRAWFS_IRP_CONTEXT IrpContext
)
412 DPRINT("RawFsClose(IrpContext %x)\n", IrpContext
);
414 return STATUS_NOT_IMPLEMENTED
;
418 RawFsCreateFile(IN PRAWFS_IRP_CONTEXT IrpContext
)
420 PRAWFS_DEVICE_EXTENSION DeviceExt
;
421 PRAWFS_GLOBAL_DATA GlobalData
;
422 PIO_STACK_LOCATION IoSp
;
423 PFILE_OBJECT FileObject
;
424 ULONG RequestedDisposition
;
425 ULONG RequestedOptions
;
429 GlobalData
= (PRAWFS_GLOBAL_DATA
) IrpContext
->DeviceObject
->DeviceExtension
;
430 IoSp
= IoGetCurrentIrpStackLocation(IrpContext
->Irp
);
431 RequestedDisposition
= ((IoSp
->Parameters
.Create
.Options
>> 24) & 0xff);
432 RequestedOptions
= IoSp
->Parameters
.Create
.Options
& FILE_VALID_OPTION_FLAGS
;
433 FileObject
= IoSp
->FileObject
;
434 DeviceExt
= IrpContext
->DeviceObject
->DeviceExtension
;
436 if (FileObject
->FileName
.Length
== 0 &&
437 FileObject
->RelatedFileObject
== NULL
)
439 /* This a open operation for the volume itself */
440 if (RequestedDisposition
== FILE_CREATE
441 || RequestedDisposition
== FILE_OVERWRITE_IF
442 || RequestedDisposition
== FILE_SUPERSEDE
)
444 return STATUS_ACCESS_DENIED
;
446 if (RequestedOptions
& FILE_DIRECTORY_FILE
)
448 return STATUS_NOT_A_DIRECTORY
;
450 pFcb
= DeviceExt
->VolumeFcb
;
451 pCcb
= RawFsNewCCB(GlobalData
);
454 return (STATUS_INSUFFICIENT_RESOURCES
);
457 FileObject
->Flags
|= FO_FCB_IS_VALID
;
458 FileObject
->SectionObjectPointer
= &pFcb
->SectionObjectPointers
;
459 FileObject
->FsContext
= pFcb
;
460 FileObject
->FsContext2
= pCcb
;
463 IrpContext
->Irp
->IoStatus
.Information
= FILE_OPENED
;
464 return(STATUS_SUCCESS
);
467 /* This filesystem driver only supports volume access */
468 return(STATUS_INVALID_PARAMETER
);
472 RawFsCreate(IN PRAWFS_IRP_CONTEXT IrpContext
)
476 DPRINT("RawFsCreate(IrpContext %x)\n", IrpContext
);
480 if (RawFsIsRawFileSystemDeviceObject(IrpContext
->DeviceObject
))
482 /* DeviceObject represents FileSystem instead of logical volume */
483 DPRINT("RawFsCreate() called with file system\n");
484 IrpContext
->Irp
->IoStatus
.Information
= FILE_OPENED
;
485 IrpContext
->Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
486 IoCompleteRequest(IrpContext
->Irp
, IO_DISK_INCREMENT
);
487 RawFsFreeIrpContext(IrpContext
);
488 return STATUS_SUCCESS
;
491 if (!(IrpContext
->Flags
& IRPCONTEXT_CANWAIT
))
493 return RawFsQueueRequest(IrpContext
);
496 IrpContext
->Irp
->IoStatus
.Information
= 0;
498 Status
= RawFsCreateFile(IrpContext
);
500 IrpContext
->Irp
->IoStatus
.Status
= Status
;
501 IoCompleteRequest(IrpContext
->Irp
,
502 (CCHAR
)(NT_SUCCESS(Status
) ? IO_DISK_INCREMENT
: IO_NO_INCREMENT
));
503 RawFsFreeIrpContext(IrpContext
);
509 RawFsRead(IN PRAWFS_IRP_CONTEXT IrpContext
)
511 DPRINT("RawFsRead(IrpContext %x)\n", IrpContext
);
513 return STATUS_NOT_IMPLEMENTED
;
517 RawFsWrite(IN PRAWFS_IRP_CONTEXT IrpContext
)
519 DPRINT("RawFsWrite(IrpContext %x)\n", IrpContext
);
521 return STATUS_NOT_IMPLEMENTED
;
525 RawFsMount(IN PRAWFS_IRP_CONTEXT IrpContext
)
527 PRAWFS_GLOBAL_DATA GlobalData
= NULL
;
528 PDEVICE_OBJECT DeviceObject
= NULL
;
529 PRAWFS_DEVICE_EXTENSION DeviceExt
= NULL
;
530 PRAWFS_FCB VolumeFcb
= NULL
;
531 PRAWFS_FCB Fcb
= NULL
;
532 PARTITION_INFORMATION PartitionInfo
;
533 DISK_GEOMETRY DiskGeometry
;
534 LARGE_INTEGER VolumeSize
;
538 DPRINT("RawFsMount(IrpContext %x)\n", IrpContext
);
542 if (!RawFsIsRawFileSystemDeviceObject(IrpContext
->DeviceObject
))
544 Status
= STATUS_INVALID_DEVICE_REQUEST
;
545 DPRINT("Not for me\n");
549 GlobalData
= (PRAWFS_GLOBAL_DATA
) IrpContext
->DeviceObject
->DeviceExtension
;
551 Status
= IoCreateDevice(GlobalData
->DriverObject
,
552 sizeof(RAWFS_DEVICE_EXTENSION
),
554 FILE_DEVICE_FILE_SYSTEM
,
558 if (!NT_SUCCESS(Status
))
563 DeviceObject
->Flags
|= DO_DIRECT_IO
;
564 DeviceExt
= (PVOID
) DeviceObject
->DeviceExtension
;
565 RtlZeroMemory(DeviceExt
, sizeof(RAWFS_DEVICE_EXTENSION
));
567 /* Use same vpb as device disk */
568 DeviceObject
->Vpb
= IrpContext
->Stack
->Parameters
.MountVolume
.DeviceObject
->Vpb
;
569 DeviceExt
->StorageDevice
= IrpContext
->Stack
->Parameters
.MountVolume
.DeviceObject
;
570 DeviceExt
->StorageDevice
->Vpb
->DeviceObject
= DeviceObject
;
571 DeviceExt
->StorageDevice
->Vpb
->RealDevice
= DeviceExt
->StorageDevice
;
572 DeviceExt
->StorageDevice
->Vpb
->Flags
|= VPB_MOUNTED
;
573 DeviceObject
->StackSize
= DeviceExt
->StorageDevice
->StackSize
+ 1;
574 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
576 KeInitializeSpinLock(&DeviceExt
->FcbListLock
);
577 InitializeListHead(&DeviceExt
->FcbListHead
);
579 /* First try getting harddisk geometry then try getting CD-ROM geometry */
580 Size
= sizeof(DISK_GEOMETRY
);
581 Status
= RawFsBlockDeviceIoControl(
582 IrpContext
->Stack
->Parameters
.MountVolume
.DeviceObject
,
583 IOCTL_DISK_GET_DRIVE_GEOMETRY
,
588 if (!NT_SUCCESS(Status
))
590 DPRINT("RawFsBlockDeviceIoControl failed with status 0x%.08x\n", Status
);
593 if (DiskGeometry
.MediaType
== FixedMedia
)
595 // We have found a hard disk
596 Size
= sizeof(PARTITION_INFORMATION
);
597 Status
= RawFsBlockDeviceIoControl(
598 IrpContext
->Stack
->Parameters
.MountVolume
.DeviceObject
,
599 IOCTL_DISK_GET_PARTITION_INFO
,
604 if (!NT_SUCCESS(Status
))
606 DPRINT("RawFsBlockDeviceIoControl() failed (%x)\n", Status
);
610 DbgPrint("Partition Information:\n");
611 DbgPrint("StartingOffset %u\n", PartitionInfo
.StartingOffset
.QuadPart
);
612 DbgPrint("PartitionLength %u\n", PartitionInfo
.PartitionLength
.QuadPart
);
613 DbgPrint("HiddenSectors %u\n", PartitionInfo
.HiddenSectors
);
614 DbgPrint("PartitionNumber %u\n", PartitionInfo
.PartitionNumber
);
615 DbgPrint("PartitionType %u\n", PartitionInfo
.PartitionType
);
616 DbgPrint("BootIndicator %u\n", PartitionInfo
.BootIndicator
);
617 DbgPrint("RecognizedPartition %u\n", PartitionInfo
.RecognizedPartition
);
618 DbgPrint("RewritePartition %u\n", PartitionInfo
.RewritePartition
);
620 VolumeSize
.QuadPart
= PartitionInfo
.PartitionLength
.QuadPart
;
622 else if (DiskGeometry
.MediaType
> Unknown
&& DiskGeometry
.MediaType
<= RemovableMedia
)
624 Status
= STATUS_UNRECOGNIZED_VOLUME
;
628 VolumeFcb
= RawFsNewFCB(GlobalData
);
629 if (VolumeFcb
== NULL
)
631 Status
= STATUS_INSUFFICIENT_RESOURCES
;
635 VolumeFcb
->Flags
= FCB_IS_VOLUME
;
636 VolumeFcb
->RFCB
.FileSize
.QuadPart
= VolumeSize
.QuadPart
;
637 VolumeFcb
->RFCB
.ValidDataLength
.QuadPart
= VolumeFcb
->RFCB
.FileSize
.QuadPart
;
638 VolumeFcb
->RFCB
.AllocationSize
.QuadPart
= VolumeFcb
->RFCB
.FileSize
.QuadPart
;
639 DeviceExt
->VolumeFcb
= VolumeFcb
;
641 KeEnterCriticalRegion();
642 ExAcquireResourceExclusiveLite(&GlobalData
->VolumeListLock
, TRUE
);
643 InsertHeadList(&GlobalData
->VolumeListHead
, &DeviceExt
->VolumeListEntry
);
644 ExReleaseResourceLite(&GlobalData
->VolumeListLock
);
645 KeLeaveCriticalRegion();
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 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
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 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
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 KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED
, Status
, 0, 0, 0);
932 DeviceData
= TapeDeviceObject
->DeviceExtension
;
933 RtlZeroMemory (DeviceData
, sizeof(RAWFS_GLOBAL_DATA
));
934 DeviceData
->DriverObject
= DriverObject
;
935 DeviceData
->DeviceObject
= TapeDeviceObject
;
936 TapeDeviceObject
->Flags
|= DO_DIRECT_IO
;
939 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
940 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
941 DriverObject
->MajorFunction
[IRP_MJ_READ
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
942 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
943 DriverObject
->MajorFunction
[IRP_MJ_FILE_SYSTEM_CONTROL
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
944 DriverObject
->MajorFunction
[IRP_MJ_QUERY_INFORMATION
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
945 DriverObject
->MajorFunction
[IRP_MJ_SET_INFORMATION
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
946 DriverObject
->MajorFunction
[IRP_MJ_DIRECTORY_CONTROL
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
947 DriverObject
->MajorFunction
[IRP_MJ_QUERY_VOLUME_INFORMATION
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
948 DriverObject
->MajorFunction
[IRP_MJ_SET_VOLUME_INFORMATION
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
949 DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = (PDRIVER_DISPATCH
) RawFsShutdown
;
950 DriverObject
->MajorFunction
[IRP_MJ_LOCK_CONTROL
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
951 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
952 DriverObject
->MajorFunction
[IRP_MJ_FLUSH_BUFFERS
] = (PDRIVER_DISPATCH
) RawFsBuildRequest
;
953 DriverObject
->DriverUnload
= NULL
;
955 ExInitializeNPagedLookasideList(&IrpContextLookasideList
,
956 NULL
, NULL
, 0, sizeof(RAWFS_IRP_CONTEXT
), TAG_IRP
, 0);
959 IoRegisterFileSystem(DiskDeviceObject
);
960 IoRegisterFileSystem(CdromDeviceObject
);
961 IoRegisterFileSystem(TapeDeviceObject
);
963 return STATUS_SUCCESS
;