2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/io/iomgr/rawfs.c
5 * PURPOSE: Raw File System Driver
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES *****************************************************************/
15 /* TYPES *******************************************************************/
21 PDEVICE_OBJECT TargetDeviceObject
;
26 SHARE_ACCESS ShareAccess
;
28 LARGE_INTEGER SectorsOnDisk
;
31 typedef struct _VOLUME_DEVICE_OBJECT
33 DEVICE_OBJECT DeviceObject
;
35 } VOLUME_DEVICE_OBJECT
, *PVOLUME_DEVICE_OBJECT
;
37 /* GLOBALS *******************************************************************/
39 PDEVICE_OBJECT RawDiskDeviceObject
, RawCdromDeviceObject
, RawTapeDeviceObject
;
41 /* FUNCTIONS *****************************************************************/
45 RawInitializeVcb(IN OUT PVCB Vcb
,
46 IN PDEVICE_OBJECT TargetDeviceObject
,
52 RtlZeroMemory(Vcb
, sizeof(VCB
));
54 /* Associate to system objects */
55 Vcb
->TargetDeviceObject
= TargetDeviceObject
;
58 /* Initialize the lock */
59 KeInitializeMutex(&Vcb
->Mutex
, 0);
64 RawCheckForDismount(IN PVCB Vcb
,
65 IN BOOLEAN CreateOperation
)
72 IoAcquireVpbSpinLock(&OldIrql
);
74 /* Reference it and check if a create is being done */
76 if (Vcb
->Vpb
->ReferenceCount
!= CreateOperation
)
78 /* Don't do anything */
83 /* Otherwise, delete the volume */
86 /* Check if it has a VPB and unmount it */
87 if (Vpb
->RealDevice
->Vpb
== Vpb
)
89 Vpb
->DeviceObject
= NULL
;
90 Vpb
->Flags
&= ~VPB_MOUNTED
;
94 /* Release lock and return status */
95 IoReleaseVpbSpinLock(OldIrql
);
101 RawCompletionRoutine(IN PDEVICE_OBJECT DeviceObject
,
105 PIO_STACK_LOCATION IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
107 /* Check if this was a valid sync R/W request */
108 if (((IoStackLocation
->MajorFunction
== IRP_MJ_READ
) ||
109 (IoStackLocation
->MajorFunction
== IRP_MJ_WRITE
)) &&
110 ((IoStackLocation
->FileObject
)) &&
111 (FlagOn(IoStackLocation
->FileObject
->Flags
, FO_SYNCHRONOUS_IO
)) &&
112 (NT_SUCCESS(Irp
->IoStatus
.Status
)))
114 /* Update byte offset */
115 IoStackLocation
->FileObject
->CurrentByteOffset
.QuadPart
+=
116 Irp
->IoStatus
.Information
;
119 /* Mark the IRP Pending if it was */
120 if (Irp
->PendingReturned
) IoMarkIrpPending(Irp
);
121 return STATUS_SUCCESS
;
126 RawClose(IN PVCB Vcb
,
128 IN PIO_STACK_LOCATION IoStackLocation
)
131 BOOLEAN Deleted
= FALSE
;
134 /* Make sure we can clean up */
135 Status
= KeWaitForSingleObject(&Vcb
->Mutex
,
140 ASSERT(NT_SUCCESS(Status
));
142 /* Decrease the open count and check if this is a dismount */
144 if (!Vcb
->OpenCount
) Deleted
= RawCheckForDismount(Vcb
, FALSE
);
146 /* Check if we should delete the device */
147 KeReleaseMutex(&Vcb
->Mutex
, FALSE
);
151 IoDeleteDevice((PDEVICE_OBJECT
)CONTAINING_RECORD(Vcb
,
152 VOLUME_DEVICE_OBJECT
,
156 /* Complete the request */
157 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
158 IoCompleteRequest(Irp
, IO_DISK_INCREMENT
);
159 return STATUS_SUCCESS
;
164 RawCreate(IN PVCB Vcb
,
166 IN PIO_STACK_LOCATION IoStackLocation
)
169 BOOLEAN Deleted
= FALSE
;
171 ACCESS_MASK DesiredAccess
;
174 /* Make sure we can clean up */
175 Status
= KeWaitForSingleObject(&Vcb
->Mutex
,
180 ASSERT(NT_SUCCESS(Status
));
182 /* Check if this is a valid non-directory file open */
183 if ((!(IoStackLocation
->FileObject
) ||
184 !(IoStackLocation
->FileObject
->FileName
.Length
)) &&
185 ((IoStackLocation
->Parameters
.Create
.Options
>> 24) == FILE_OPEN
) &&
186 (!(IoStackLocation
->Parameters
.Create
.Options
& FILE_DIRECTORY_FILE
)))
188 /* Make sure the VCB isn't locked */
189 if (Vcb
->VcbState
& 1)
191 /* Refuse the operation */
192 Status
= STATUS_ACCESS_DENIED
;
193 Irp
->IoStatus
.Information
= 0;
197 /* Setup share access */
198 ShareAccess
= IoStackLocation
->Parameters
.Create
.ShareAccess
;
199 DesiredAccess
= IoStackLocation
->Parameters
.Create
.
200 SecurityContext
->DesiredAccess
;
202 /* Check if this VCB was already opened */
203 if (Vcb
->OpenCount
> 0)
205 /* Try to see if we have access to it */
206 Status
= IoCheckShareAccess(DesiredAccess
,
208 IoStackLocation
->FileObject
,
211 if (!NT_SUCCESS(Status
)) Irp
->IoStatus
.Information
= 0;
214 /* Make sure we have access */
215 if (NT_SUCCESS(Status
))
217 /* Check if this is the first open */
220 /* Set the share access */
221 IoSetShareAccess(DesiredAccess
,
223 IoStackLocation
->FileObject
,
227 /* Increase the open count and set the VPB */
229 IoStackLocation
->FileObject
->Vpb
= Vcb
->Vpb
;
231 /* Set IRP status and disable intermediate buffering */
232 Status
= STATUS_SUCCESS
;
233 Irp
->IoStatus
.Information
= FILE_OPENED
;
234 IoStackLocation
->FileObject
->Flags
|=
235 FO_NO_INTERMEDIATE_BUFFERING
;
241 /* Invalid create request */
242 Status
= STATUS_INVALID_PARAMETER
;
243 Irp
->IoStatus
.Information
= 0;
246 /* Check if the request failed */
247 if (!(NT_SUCCESS(Status
)) && !(Vcb
->OpenCount
))
249 /* Check if we can dismount the device */
250 Deleted
= RawCheckForDismount(Vcb
, FALSE
);
253 /* Check if we should delete the device */
254 KeReleaseMutex(&Vcb
->Mutex
, FALSE
);
258 IoDeleteDevice((PDEVICE_OBJECT
)CONTAINING_RECORD(Vcb
,
259 VOLUME_DEVICE_OBJECT
,
263 /* Complete the request */
264 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
265 IoCompleteRequest(Irp
, IO_DISK_INCREMENT
);
266 return STATUS_SUCCESS
;
271 RawReadWriteDeviceControl(IN PVCB Vcb
,
273 IN PIO_STACK_LOCATION IoStackLocation
)
278 /* Don't do anything if the request was 0 bytes */
279 if (((IoStackLocation
->MajorFunction
== IRP_MJ_READ
) ||
280 (IoStackLocation
->MajorFunction
== IRP_MJ_WRITE
)) &&
281 !(IoStackLocation
->Parameters
.Read
.Length
))
284 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
285 IoCompleteRequest(Irp
, IO_DISK_INCREMENT
);
286 return STATUS_SUCCESS
;
289 /* Copy the IRP stack location */
290 IoCopyCurrentIrpStackLocationToNext(Irp
);
292 /* Disable verifies */
293 IoGetNextIrpStackLocation(Irp
)->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
295 /* Setup a completion routine */
296 IoSetCompletionRoutine(Irp
,
297 RawCompletionRoutine
,
303 /* Call the next driver and exit */
304 Status
= IoCallDriver(Vcb
->TargetDeviceObject
, Irp
);
310 RawMountVolume(IN PIO_STACK_LOCATION IoStackLocation
)
313 PDEVICE_OBJECT DeviceObject
;
314 PVOLUME_DEVICE_OBJECT Volume
;
317 /* Remember our owner */
318 DeviceObject
= IoStackLocation
->Parameters
.MountVolume
.DeviceObject
;
320 /* Create the volume */
321 Status
= IoCreateDevice(RawDiskDeviceObject
->DriverObject
,
322 sizeof(VOLUME_DEVICE_OBJECT
) -
323 sizeof(DEVICE_OBJECT
),
325 FILE_DEVICE_DISK_FILE_SYSTEM
,
328 (PDEVICE_OBJECT
*)&Volume
);
329 if (!NT_SUCCESS(Status
)) return Status
;
331 /* Use highest alignment requirement */
332 Volume
->DeviceObject
.AlignmentRequirement
= max(DeviceObject
->
333 AlignmentRequirement
,
334 Volume
->DeviceObject
.
335 AlignmentRequirement
);
338 RawInitializeVcb(&Volume
->Vcb
,
339 IoStackLocation
->Parameters
.MountVolume
.DeviceObject
,
340 IoStackLocation
->Parameters
.MountVolume
.Vpb
);
342 /* Set dummy label and serial number */
343 Volume
->Vcb
.Vpb
->SerialNumber
= 0xFFFFFFFF;
344 Volume
->Vcb
.Vpb
->VolumeLabelLength
= 0;
347 Volume
->Vcb
.Vpb
->DeviceObject
= &Volume
->DeviceObject
;
348 Volume
->DeviceObject
.StackSize
= DeviceObject
->StackSize
+ 1;
349 Volume
->DeviceObject
.SectorSize
= DeviceObject
->SectorSize
;
350 Volume
->DeviceObject
.Flags
|= DO_DIRECT_IO
;
351 Volume
->DeviceObject
.Flags
&= ~DO_DEVICE_INITIALIZING
;
357 RawUserFsCtrl(IN PIO_STACK_LOCATION IoStackLocation
,
363 /* Lock the device */
364 Status
= KeWaitForSingleObject(&Vcb
->Mutex
,
369 ASSERT(NT_SUCCESS(Status
));
371 /* Check what kind of request this is */
372 switch (IoStackLocation
->Parameters
.FileSystemControl
.FsControlCode
)
374 /* Oplock requests */
375 case FSCTL_REQUEST_OPLOCK_LEVEL_1
:
376 case FSCTL_REQUEST_OPLOCK_LEVEL_2
:
377 case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE
:
378 case FSCTL_OPLOCK_BREAK_NOTIFY
:
380 /* We don't handle them */
381 Status
= STATUS_NOT_IMPLEMENTED
;
385 case FSCTL_LOCK_VOLUME
:
387 /* Make sure we're not locked, and that we're alone */
388 if (!(Vcb
->VcbState
& 1) && (Vcb
->OpenCount
== 1))
392 Status
= STATUS_SUCCESS
;
396 /* Otherwise, we can't do this */
397 Status
= STATUS_ACCESS_DENIED
;
402 case FSCTL_UNLOCK_VOLUME
:
404 /* Make sure we're locked */
405 if (!(Vcb
->VcbState
& 1))
407 /* Let caller know we're not */
408 Status
= STATUS_NOT_LOCKED
;
414 Status
= STATUS_SUCCESS
;
418 /* Dismount request */
419 case FSCTL_DISMOUNT_VOLUME
:
421 /* Make sure we're locked */
422 if (Vcb
->VcbState
& 1)
424 /* Do nothing, just return success */
425 Status
= STATUS_SUCCESS
;
429 /* We can't dismount, device not locked */
430 Status
= STATUS_ACCESS_DENIED
;
434 /* Unknown request */
438 Status
= STATUS_INVALID_PARAMETER
;
442 /* Unlock device and return */
443 KeReleaseMutex(&Vcb
->Mutex
, FALSE
);
449 RawFileSystemControl(IN PVCB Vcb
,
451 IN PIO_STACK_LOCATION IoStackLocation
)
456 /* Check the kinds of FSCTLs that we support */
457 switch (IoStackLocation
->MinorFunction
)
459 /* User-mode request */
460 case IRP_MN_USER_FS_REQUEST
:
463 Status
= RawUserFsCtrl(IoStackLocation
, Vcb
);
467 case IRP_MN_MOUNT_VOLUME
:
469 /* Mount the volume */
470 Status
= RawMountVolume(IoStackLocation
);
473 case IRP_MN_VERIFY_VOLUME
:
475 /* We don't do verifies */
476 Status
= STATUS_WRONG_VOLUME
;
477 Vcb
->Vpb
->RealDevice
->Flags
&= ~DO_VERIFY_VOLUME
;
479 /* Check if we should delete the device */
480 if (RawCheckForDismount(Vcb
, FALSE
))
483 IoDeleteDevice((PDEVICE_OBJECT
)
484 CONTAINING_RECORD(Vcb
,
485 VOLUME_DEVICE_OBJECT
,
492 /* Invalid request */
496 Status
= STATUS_INVALID_DEVICE_REQUEST
;
500 /* Complete the request */
501 Irp
->IoStatus
.Status
= Status
;
502 IoCompleteRequest(Irp
, IO_DISK_INCREMENT
);
508 RawQueryInformation(IN PVCB Vcb
,
510 IN PIO_STACK_LOCATION IoStackLocation
)
512 NTSTATUS Status
= STATUS_INVALID_DEVICE_REQUEST
;
514 PFILE_POSITION_INFORMATION Buffer
;
517 /* Get information from the IRP */
518 Length
= &IoStackLocation
->Parameters
.QueryFile
.Length
;
519 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
521 /* We only handle this request */
522 if (IoStackLocation
->Parameters
.QueryFile
.FileInformationClass
==
523 FilePositionInformation
)
525 /* Validate buffer size */
526 if (*Length
< sizeof(FILE_POSITION_INFORMATION
))
529 Irp
->IoStatus
.Information
= 0;
530 Status
= STATUS_BUFFER_OVERFLOW
;
534 /* Get offset and update length */
535 Buffer
->CurrentByteOffset
= IoStackLocation
->FileObject
->
537 *Length
-= sizeof(FILE_POSITION_INFORMATION
);
539 /* Set IRP Status information */
540 Irp
->IoStatus
.Information
= sizeof(FILE_POSITION_INFORMATION
);
541 Status
= STATUS_SUCCESS
;
546 Irp
->IoStatus
.Status
= Status
;
547 IoCompleteRequest(Irp
, IO_DISK_INCREMENT
);
553 RawSetInformation(IN PVCB Vcb
,
555 IN PIO_STACK_LOCATION IoStackLocation
)
557 NTSTATUS Status
= STATUS_INVALID_DEVICE_REQUEST
;
559 PFILE_POSITION_INFORMATION Buffer
;
560 PDEVICE_OBJECT DeviceObject
;
563 /* Get information from the IRP */
564 Length
= &IoStackLocation
->Parameters
.QueryFile
.Length
;
565 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
567 /* We only handle this request */
568 if (IoStackLocation
->Parameters
.QueryFile
.FileInformationClass
==
569 FilePositionInformation
)
572 DeviceObject
= IoGetRelatedDeviceObject(IoStackLocation
->FileObject
);
574 /* Make sure the offset is aligned */
575 if ((Buffer
->CurrentByteOffset
.LowPart
&
576 DeviceObject
->AlignmentRequirement
))
579 Status
= STATUS_INVALID_PARAMETER
;
583 /* Otherwise, set offset */
584 IoStackLocation
->FileObject
->CurrentByteOffset
= Buffer
->
587 /* Set IRP Status information */
588 Status
= STATUS_SUCCESS
;
593 Irp
->IoStatus
.Status
= Status
;
594 IoCompleteRequest(Irp
, IO_DISK_INCREMENT
);
600 RawQueryFsVolumeInfo(IN PVCB Vcb
,
601 IN PFILE_FS_VOLUME_INFORMATION Buffer
,
602 IN OUT PULONG Length
)
606 /* Clear the buffer and stub it out */
607 RtlZeroMemory( Buffer
, sizeof(FILE_FS_VOLUME_INFORMATION
));
608 Buffer
->VolumeSerialNumber
= Vcb
->Vpb
->SerialNumber
;
609 Buffer
->SupportsObjects
= FALSE
;
610 Buffer
->VolumeLabelLength
= 0;
612 /* Return length and success */
613 *Length
-= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION
, VolumeLabel
[0]);
614 return STATUS_SUCCESS
;
619 RawQueryFsSizeInfo(IN PVCB Vcb
,
620 IN PFILE_FS_SIZE_INFORMATION Buffer
,
621 IN OUT PULONG Length
)
626 IO_STATUS_BLOCK IoStatusBlock
;
627 PDEVICE_OBJECT RealDevice
;
628 DISK_GEOMETRY DiskGeometry
;
629 PARTITION_INFORMATION PartitionInformation
;
630 BOOLEAN DiskHasPartitions
;
633 /* Validate the buffer */
634 if (*Length
< sizeof(FILE_FS_SIZE_INFORMATION
))
637 return STATUS_BUFFER_OVERFLOW
;
640 /* Clear the buffer, initialize the event and set the DO */
641 RtlZeroMemory(Buffer
, sizeof(FILE_FS_SIZE_INFORMATION
));
642 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
643 RealDevice
= Vcb
->Vpb
->RealDevice
;
645 /* Build query IRP */
646 Irp
= IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY
,
651 sizeof(DISK_GEOMETRY
),
655 if (!Irp
) return STATUS_INSUFFICIENT_RESOURCES
;
657 /* Call driver and check if we're pending */
658 Status
= IoCallDriver(RealDevice
, Irp
);
659 if (Status
== STATUS_PENDING
)
661 /* Wait on driver to finish */
662 KeWaitForSingleObject(&Event
,
667 Status
= IoStatusBlock
.Status
;
670 /* Fail if we couldn't get CHS data */
671 if (!NT_SUCCESS(Status
))
677 /* Check if this is a floppy */
678 if (FlagOn(RealDevice
->Characteristics
, FILE_FLOPPY_DISKETTE
))
680 /* Floppies don't have partitions */
681 DiskHasPartitions
= FALSE
;
685 /* Setup query IRP */
686 KeResetEvent(&Event
);
687 Irp
= IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO
,
691 &PartitionInformation
,
692 sizeof(PARTITION_INFORMATION
),
696 if (!Irp
) return STATUS_INSUFFICIENT_RESOURCES
;
698 /* Call driver and check if we're pending */
699 Status
= IoCallDriver(RealDevice
, Irp
);
700 if (Status
== STATUS_PENDING
)
702 /* Wait on driver to finish */
703 KeWaitForSingleObject(&Event
,
708 Status
= IoStatusBlock
.Status
;
711 /* If this was an invalid request, then the disk is not partitioned */
712 if (Status
== STATUS_INVALID_DEVICE_REQUEST
)
714 DiskHasPartitions
= FALSE
;
718 /* Otherwise, it must be */
719 ASSERT(NT_SUCCESS(Status
));
720 DiskHasPartitions
= TRUE
;
724 /* Set sector data */
725 Buffer
->BytesPerSector
= DiskGeometry
.BytesPerSector
;
726 Buffer
->SectorsPerAllocationUnit
= 1;
728 /* Calculate allocation units */
729 if (DiskHasPartitions
)
731 /* Use partition data */
732 Buffer
->TotalAllocationUnits
=
733 RtlExtendedLargeIntegerDivide(PartitionInformation
.PartitionLength
,
734 DiskGeometry
.BytesPerSector
,
740 Buffer
->TotalAllocationUnits
=
741 RtlExtendedIntegerMultiply(DiskGeometry
.Cylinders
,
742 DiskGeometry
.TracksPerCylinder
*
743 DiskGeometry
.SectorsPerTrack
);
746 /* Set available units */
747 Buffer
->AvailableAllocationUnits
= Buffer
->TotalAllocationUnits
;
749 /* Return length and success */
750 *Length
-= sizeof(FILE_FS_SIZE_INFORMATION
);
751 return STATUS_SUCCESS
;
756 RawQueryFsDeviceInfo(IN PVCB Vcb
,
757 IN PFILE_FS_DEVICE_INFORMATION Buffer
,
758 IN OUT PULONG Length
)
762 /* Validate buffer */
763 if (*Length
< sizeof(FILE_FS_DEVICE_INFORMATION
))
766 return STATUS_BUFFER_OVERFLOW
;
769 /* Clear buffer and write information */
770 RtlZeroMemory(Buffer
, sizeof(FILE_FS_DEVICE_INFORMATION
));
771 Buffer
->DeviceType
= FILE_DEVICE_DISK
;
772 Buffer
->Characteristics
= Vcb
->TargetDeviceObject
->Characteristics
;
774 /* Return length and success */
775 *Length
-= sizeof(FILE_FS_DEVICE_INFORMATION
);
776 return STATUS_SUCCESS
;
781 RawQueryFsAttributeInfo(IN PVCB Vcb
,
782 IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer
,
783 IN OUT PULONG Length
)
785 const WCHAR szRawFSName
[] = L
"RAW";
789 /* Check if the buffer is large enough for our name ("RAW") */
790 ReturnLength
= FIELD_OFFSET(FILE_FS_ATTRIBUTE_INFORMATION
,
791 FileSystemName
[sizeof(szRawFSName
) / sizeof(szRawFSName
[0])]);
792 if (*Length
< ReturnLength
) return STATUS_BUFFER_OVERFLOW
;
794 /* Output the data */
795 Buffer
->FileSystemAttributes
= 0;
796 Buffer
->MaximumComponentNameLength
= 0;
797 Buffer
->FileSystemNameLength
= 6;
798 RtlCopyMemory(&Buffer
->FileSystemName
[0], szRawFSName
, sizeof(szRawFSName
));
800 /* Return length and success */
801 *Length
-= ReturnLength
;
802 return STATUS_SUCCESS
;
807 RawQueryVolumeInformation(IN PVCB Vcb
,
809 IN PIO_STACK_LOCATION IoStackLocation
)
817 Length
= IoStackLocation
->Parameters
.QueryVolume
.Length
;
818 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
820 /* Check the kind of request */
821 switch (IoStackLocation
->Parameters
.QueryVolume
.FsInformationClass
)
823 /* Volume information request */
824 case FileFsVolumeInformation
:
826 Status
= RawQueryFsVolumeInfo(Vcb
, Buffer
, &Length
);
829 /* File system size invormation */
830 case FileFsSizeInformation
:
832 Status
= RawQueryFsSizeInfo(Vcb
, Buffer
, &Length
);
835 /* Device information */
836 case FileFsDeviceInformation
:
838 Status
= RawQueryFsDeviceInfo(Vcb
, Buffer
, &Length
);
841 /* Attribute information */
842 case FileFsAttributeInformation
:
844 Status
= RawQueryFsAttributeInfo(Vcb
, Buffer
, &Length
);
847 /* Invalid request */
851 Status
= STATUS_INVALID_PARAMETER
;
855 /* Set status and complete the request */
856 Irp
->IoStatus
.Information
= IoStackLocation
->
857 Parameters
.QueryVolume
.Length
- Length
;
858 Irp
->IoStatus
.Status
= Status
;
859 IoCompleteRequest(Irp
, IO_DISK_INCREMENT
);
865 RawCleanup(IN PVCB Vcb
,
867 IN PIO_STACK_LOCATION IoStackLocation
)
872 /* Make sure we can clean up */
873 Status
= KeWaitForSingleObject(&Vcb
->Mutex
,
878 ASSERT(NT_SUCCESS(Status
));
880 /* Remove shared access and complete the request */
881 IoRemoveShareAccess(IoStackLocation
->FileObject
, &Vcb
->ShareAccess
);
882 KeReleaseMutex(&Vcb
->Mutex
, FALSE
);
883 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
884 IoCompleteRequest(Irp
, IO_DISK_INCREMENT
);
885 return STATUS_SUCCESS
;
890 RawDispatch(IN PVOLUME_DEVICE_OBJECT DeviceObject
,
893 NTSTATUS Status
= STATUS_INVALID_DEVICE_REQUEST
;
894 PIO_STACK_LOCATION IoStackLocation
;
898 /* Get the stack location */
899 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
901 /* Differentiate between Volume DO and FS DO */
902 if ((((PDEVICE_OBJECT
)DeviceObject
)->Size
== sizeof(DEVICE_OBJECT
)) &&
903 !((IoStackLocation
->MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
) &&
904 (IoStackLocation
->MinorFunction
== IRP_MN_MOUNT_VOLUME
)))
906 /* This is an FS DO. Stub out the common calls */
907 if ((IoStackLocation
->MajorFunction
== IRP_MJ_CREATE
) ||
908 (IoStackLocation
->MajorFunction
== IRP_MJ_CLEANUP
) ||
909 (IoStackLocation
->MajorFunction
== IRP_MJ_CLOSE
))
911 /* Return success for them */
912 Status
= STATUS_SUCCESS
;
916 /* Anything else, we don't support */
917 Status
= STATUS_INVALID_DEVICE_REQUEST
;
920 /* Complete the request */
921 Irp
->IoStatus
.Status
= Status
;
922 IoCompleteRequest(Irp
, IO_DISK_INCREMENT
);
926 /* Otherwise, get our VCB and start handling the IRP */
927 FsRtlEnterFileSystem();
928 Vcb
= &DeviceObject
->Vcb
;
930 /* Check what kind of IRP this is */
931 switch (IoStackLocation
->MajorFunction
)
933 /* Cleanup request */
936 Status
= RawCleanup(Vcb
, Irp
, IoStackLocation
);
942 Status
= RawClose(Vcb
, Irp
, IoStackLocation
);
948 Status
= RawCreate(Vcb
, Irp
, IoStackLocation
);
952 case IRP_MJ_FILE_SYSTEM_CONTROL
:
954 Status
= RawFileSystemControl(Vcb
, Irp
, IoStackLocation
);
957 /* R/W or IOCTL request */
960 case IRP_MJ_DEVICE_CONTROL
:
962 Status
= RawReadWriteDeviceControl(Vcb
, Irp
, IoStackLocation
);
965 /* Information query request */
966 case IRP_MJ_QUERY_INFORMATION
:
968 Status
= RawQueryInformation(Vcb
, Irp
, IoStackLocation
);
971 /* Information set request */
972 case IRP_MJ_SET_INFORMATION
:
974 Status
= RawSetInformation(Vcb
, Irp
, IoStackLocation
);
977 /* Volume information request */
978 case IRP_MJ_QUERY_VOLUME_INFORMATION
:
980 Status
= RawQueryVolumeInformation(Vcb
, Irp
, IoStackLocation
);
983 /* Unexpected request */
986 /* Anything else is pretty bad */
987 KeBugCheck(FILE_SYSTEM
);
990 /* Return the status */
991 FsRtlExitFileSystem();
997 RawShutdown(IN PDEVICE_OBJECT DeviceObject
,
1000 /* Unregister file systems */
1001 #if 0 // FIXME: This freezes ROS at shutdown. PnP Problem?
1002 IoUnregisterFileSystem(RawDiskDeviceObject
);
1003 IoUnregisterFileSystem(RawCdromDeviceObject
);
1004 IoUnregisterFileSystem(RawTapeDeviceObject
);
1006 /* Delete the devices */
1007 IoDeleteDevice(RawDiskDeviceObject
);
1008 IoDeleteDevice(RawCdromDeviceObject
);
1009 IoDeleteDevice(RawTapeDeviceObject
);
1012 /* Complete the request */
1013 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1014 IoCompleteRequest(Irp
, IO_DISK_INCREMENT
);
1015 return STATUS_SUCCESS
;
1020 RawUnload(IN PDRIVER_OBJECT DriverObject
)
1022 #if 0 // FIXME: DriverUnload is never called
1023 /* Dereference device objects */
1024 ObDereferenceObject(RawDiskDeviceObject
);
1025 ObDereferenceObject(RawCdromDeviceObject
);
1026 ObDereferenceObject(RawTapeDeviceObject
);
1032 RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject
,
1033 IN PUNICODE_STRING RegistryPath
)
1035 UNICODE_STRING DeviceName
;
1038 /* Create the raw disk device */
1039 RtlInitUnicodeString(&DeviceName
, L
"\\Device\\RawDisk");
1040 Status
= IoCreateDevice(DriverObject
,
1043 FILE_DEVICE_DISK_FILE_SYSTEM
,
1046 &RawDiskDeviceObject
);
1047 if (!NT_SUCCESS(Status
)) return Status
;
1049 /* Create the raw CDROM device */
1050 RtlInitUnicodeString(&DeviceName
, L
"\\Device\\RawCdRom");
1051 Status
= IoCreateDevice(DriverObject
,
1054 FILE_DEVICE_CD_ROM_FILE_SYSTEM
,
1057 &RawCdromDeviceObject
);
1058 if (!NT_SUCCESS(Status
)) return Status
;
1060 /* Create the raw tape device */
1061 RtlInitUnicodeString(&DeviceName
, L
"\\Device\\RawTape");
1062 Status
= IoCreateDevice(DriverObject
,
1065 FILE_DEVICE_TAPE_FILE_SYSTEM
,
1068 &RawTapeDeviceObject
);
1069 if (!NT_SUCCESS(Status
)) return Status
;
1071 /* Set Direct I/O for all devices */
1072 RawDiskDeviceObject
->Flags
|= DO_DIRECT_IO
;
1073 RawCdromDeviceObject
->Flags
|= DO_DIRECT_IO
;
1074 RawTapeDeviceObject
->Flags
|= DO_DIRECT_IO
;
1076 /* Set generic stubs */
1077 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] =
1078 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] =
1079 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] =
1080 DriverObject
->MajorFunction
[IRP_MJ_READ
] =
1081 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] =
1082 DriverObject
->MajorFunction
[IRP_MJ_QUERY_INFORMATION
] =
1083 DriverObject
->MajorFunction
[IRP_MJ_SET_INFORMATION
] =
1084 DriverObject
->MajorFunction
[IRP_MJ_QUERY_VOLUME_INFORMATION
] =
1085 DriverObject
->MajorFunction
[IRP_MJ_FILE_SYSTEM_CONTROL
] =
1086 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = (PDRIVER_DISPATCH
)RawDispatch
;
1088 /* Shutdown and unload */
1089 DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = RawShutdown
;
1090 DriverObject
->DriverUnload
= RawUnload
;
1092 /* Register the file systems */
1093 IoRegisterFileSystem(RawDiskDeviceObject
);
1094 IoRegisterFileSystem(RawCdromDeviceObject
);
1095 IoRegisterFileSystem(RawTapeDeviceObject
);
1097 #if 0 // FIXME: DriverUnload is never called
1098 /* Reference device objects */
1099 ObReferenceObject(RawDiskDeviceObject
);
1100 ObReferenceObject(RawCdromDeviceObject
);
1101 ObReferenceObject(RawTapeDeviceObject
);
1103 return STATUS_SUCCESS
;