📄 rawfs.c
字号:
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/io/iomgr/rawfs.c
* PURPOSE: Raw File System Driver
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
/* TYPES *******************************************************************/
typedef struct _VCB
{
USHORT NodeTypeCode;
USHORT NodeByteSize;
PDEVICE_OBJECT TargetDeviceObject;
PVPB Vpb;
ULONG VcbState;
KMUTEX Mutex;
CLONG OpenCount;
SHARE_ACCESS ShareAccess;
ULONG BytesPerSector;
LARGE_INTEGER SectorsOnDisk;
} VCB, *PVCB;
typedef struct _VOLUME_DEVICE_OBJECT
{
DEVICE_OBJECT DeviceObject;
VCB Vcb;
} VOLUME_DEVICE_OBJECT, *PVOLUME_DEVICE_OBJECT;
/* GLOBALS *******************************************************************/
PDEVICE_OBJECT RawDiskDeviceObject, RawCdromDeviceObject, RawTapeDeviceObject;
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
RawInitializeVcb(IN OUT PVCB Vcb,
IN PDEVICE_OBJECT TargetDeviceObject,
IN PVPB Vpb)
{
PAGED_CODE();
/* Clear it */
RtlZeroMemory(Vcb, sizeof(VCB));
/* Associate to system objects */
Vcb->TargetDeviceObject = TargetDeviceObject;
Vcb->Vpb = Vpb;
/* Initialize the lock */
KeInitializeMutex(&Vcb->Mutex, 0);
}
BOOLEAN
NTAPI
RawCheckForDismount(IN PVCB Vcb,
IN BOOLEAN CreateOperation)
{
KIRQL OldIrql;
PVPB Vpb;
BOOLEAN Delete;
/* Lock VPB */
IoAcquireVpbSpinLock(&OldIrql);
/* Reference it and check if a create is being done */
Vpb = Vcb->Vpb;
if (Vcb->Vpb->ReferenceCount != CreateOperation)
{
/* Don't do anything */
Delete = FALSE;
}
else
{
/* Otherwise, delete the volume */
Delete = TRUE;
/* Check if it has a VPB and unmount it */
if (Vpb->RealDevice->Vpb == Vpb)
{
Vpb->DeviceObject = NULL;
Vpb->Flags &= ~VPB_MOUNTED;
}
}
/* Release lock and return status */
IoReleaseVpbSpinLock(OldIrql);
return Delete;
}
NTSTATUS
NTAPI
RawCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
/* Check if this was a valid sync R/W request */
if (((IoStackLocation->MajorFunction == IRP_MJ_READ) ||
(IoStackLocation->MajorFunction == IRP_MJ_WRITE)) &&
((IoStackLocation->FileObject)) &&
(FlagOn(IoStackLocation->FileObject->Flags, FO_SYNCHRONOUS_IO)) &&
(NT_SUCCESS(Irp->IoStatus.Status)))
{
/* Update byte offset */
IoStackLocation->FileObject->CurrentByteOffset.QuadPart +=
Irp->IoStatus.Information;
}
/* Mark the IRP Pending if it was */
if (Irp->PendingReturned) IoMarkIrpPending(Irp);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
RawClose(IN PVCB Vcb,
IN PIRP Irp,
IN PIO_STACK_LOCATION IoStackLocation)
{
NTSTATUS Status;
BOOLEAN Deleted = FALSE;
PAGED_CODE();
/* Make sure we can clean up */
Status = KeWaitForSingleObject(&Vcb->Mutex,
Executive,
KernelMode,
FALSE,
NULL);
ASSERT(NT_SUCCESS(Status));
/* Decrease the open count and check if this is a dismount */
Vcb->OpenCount--;
if (!Vcb->OpenCount) Deleted = RawCheckForDismount(Vcb, FALSE);
/* Check if we should delete the device */
KeReleaseMutex(&Vcb->Mutex, FALSE);
if (Deleted)
{
/* Delete it */
IoDeleteDevice((PDEVICE_OBJECT)CONTAINING_RECORD(Vcb,
VOLUME_DEVICE_OBJECT,
Vcb));
}
/* Complete the request */
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
RawCreate(IN PVCB Vcb,
IN PIRP Irp,
IN PIO_STACK_LOCATION IoStackLocation)
{
NTSTATUS Status;
BOOLEAN Deleted = FALSE;
USHORT ShareAccess;
ACCESS_MASK DesiredAccess;
PAGED_CODE();
/* Make sure we can clean up */
Status = KeWaitForSingleObject(&Vcb->Mutex,
Executive,
KernelMode,
FALSE,
NULL);
ASSERT(NT_SUCCESS(Status));
/* Check if this is a valid non-directory file open */
if ((!(IoStackLocation->FileObject) ||
!(IoStackLocation->FileObject->FileName.Length)) &&
((IoStackLocation->Parameters.Create.Options >> 24) == FILE_OPEN) &&
(!(IoStackLocation->Parameters.Create.Options & FILE_DIRECTORY_FILE)))
{
/* Make sure the VCB isn't locked */
if (Vcb->VcbState & 1)
{
/* Refuse the operation */
Status = STATUS_ACCESS_DENIED;
Irp->IoStatus.Information = 0;
}
else
{
/* Setup share access */
ShareAccess = IoStackLocation->Parameters.Create.ShareAccess;
DesiredAccess = IoStackLocation->Parameters.Create.
SecurityContext->DesiredAccess;
/* Check if this VCB was already opened */
if (Vcb->OpenCount > 0)
{
/* Try to see if we have access to it */
Status = IoCheckShareAccess(DesiredAccess,
ShareAccess,
IoStackLocation->FileObject,
&Vcb->ShareAccess,
TRUE);
if (!NT_SUCCESS(Status)) Irp->IoStatus.Information = 0;
}
/* Make sure we have access */
if (NT_SUCCESS(Status))
{
/* Check if this is the first open */
if (!Vcb->OpenCount)
{
/* Set the share access */
IoSetShareAccess(DesiredAccess,
ShareAccess,
IoStackLocation->FileObject,
&Vcb->ShareAccess);
}
/* Increase the open count and set the VPB */
Vcb->OpenCount += 1;
IoStackLocation->FileObject->Vpb = Vcb->Vpb;
/* Set IRP status and disable intermediate buffering */
Status = STATUS_SUCCESS;
Irp->IoStatus.Information = FILE_OPENED;
IoStackLocation->FileObject->Flags |=
FO_NO_INTERMEDIATE_BUFFERING;
}
}
}
else
{
/* Invalid create request */
Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
}
/* Check if the request failed */
if (!(NT_SUCCESS(Status)) && !(Vcb->OpenCount))
{
/* Check if we can dismount the device */
Deleted = RawCheckForDismount(Vcb, FALSE);
}
/* Check if we should delete the device */
KeReleaseMutex(&Vcb->Mutex, FALSE);
if (Deleted)
{
/* Delete it */
IoDeleteDevice((PDEVICE_OBJECT)CONTAINING_RECORD(Vcb,
VOLUME_DEVICE_OBJECT,
Vcb));
}
/* Complete the request */
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
RawReadWriteDeviceControl(IN PVCB Vcb,
IN PIRP Irp,
IN PIO_STACK_LOCATION IoStackLocation)
{
NTSTATUS Status;
PAGED_CODE();
/* Don't do anything if the request was 0 bytes */
if (((IoStackLocation->MajorFunction == IRP_MJ_READ) ||
(IoStackLocation->MajorFunction == IRP_MJ_WRITE)) &&
!(IoStackLocation->Parameters.Read.Length))
{
/* Complete it */
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
return STATUS_SUCCESS;
}
/* Copy the IRP stack location */
IoCopyCurrentIrpStackLocationToNext(Irp);
/* Disable verifies */
IoGetNextIrpStackLocation(Irp)->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
/* Setup a completion routine */
IoSetCompletionRoutine(Irp,
RawCompletionRoutine,
NULL,
TRUE,
TRUE,
TRUE);
/* Call the next driver and exit */
Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
return Status;
}
NTSTATUS
NTAPI
RawMountVolume(IN PIO_STACK_LOCATION IoStackLocation)
{
NTSTATUS Status;
PDEVICE_OBJECT DeviceObject;
PVOLUME_DEVICE_OBJECT Volume;
PAGED_CODE();
/* Remember our owner */
DeviceObject = IoStackLocation->Parameters.MountVolume.DeviceObject;
/* Create the volume */
Status = IoCreateDevice(RawDiskDeviceObject->DriverObject,
sizeof(VOLUME_DEVICE_OBJECT) -
sizeof(DEVICE_OBJECT),
NULL,
FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
(PDEVICE_OBJECT*)&Volume);
if (!NT_SUCCESS(Status)) return Status;
/* Use highest alignment requirement */
Volume->DeviceObject.AlignmentRequirement = max(DeviceObject->
AlignmentRequirement,
Volume->DeviceObject.
AlignmentRequirement);
/* Setup the VCB */
RawInitializeVcb(&Volume->Vcb,
IoStackLocation->Parameters.MountVolume.DeviceObject,
IoStackLocation->Parameters.MountVolume.Vpb);
/* Set dummy label and serial number */
Volume->Vcb.Vpb->SerialNumber = 0xFFFFFFFF;
Volume->Vcb.Vpb->VolumeLabelLength = 0;
/* Setup the DO */
Volume->Vcb.Vpb->DeviceObject = &Volume->DeviceObject;
Volume->DeviceObject.StackSize = DeviceObject->StackSize + 1;
Volume->DeviceObject.SectorSize = DeviceObject->SectorSize;
Volume->DeviceObject.Flags |= DO_DIRECT_IO;
Volume->DeviceObject.Flags &= ~DO_DEVICE_INITIALIZING;
return Status;
}
NTSTATUS
NTAPI
RawUserFsCtrl(IN PIO_STACK_LOCATION IoStackLocation,
IN PVCB Vcb)
{
NTSTATUS Status;
PAGED_CODE();
/* Lock the device */
Status = KeWaitForSingleObject(&Vcb->Mutex,
Executive,
KernelMode,
FALSE,
NULL);
ASSERT(NT_SUCCESS(Status));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -