mirror of
https://github.com/reactos/reactos.git
synced 2024-07-31 00:28:56 +00:00
- Implement some functions to handle VPB Referencing/Dereferencing.
- IoVerifyVolume: - Send the IRP to the base FSD, in case the current FSD is an attachee - Set correct flags in the IRP to notify that this is a mount operation using PAGING I/O semantics. - Don't ignore AllowRawMount parameter. - We want to mount the File System on *FAILURE*, not on SUCCESS! - Add reference/dereferencing to the VPB. svn path=/trunk/; revision=22756
This commit is contained in:
parent
042e74885b
commit
fe8b3cfda1
|
@ -85,6 +85,60 @@ IopCreateVpb(IN PDEVICE_OBJECT DeviceObject)
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
IopDereferenceVpb(IN PVPB Vpb)
|
||||||
|
{
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
/* Lock the VPBs and decrease references */
|
||||||
|
IoAcquireVpbSpinLock(&OldIrql);
|
||||||
|
Vpb->ReferenceCount--;
|
||||||
|
|
||||||
|
/* Check if we're out of references */
|
||||||
|
if (!Vpb->ReferenceCount)
|
||||||
|
{
|
||||||
|
/* FIXME: IMPLEMENT CLEANUP! */
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release VPB lock */
|
||||||
|
IoReleaseVpbSpinLock(OldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
IopReferenceVpbForVerify(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
OUT PDEVICE_OBJECT *FileSystemObject,
|
||||||
|
OUT PVPB *Vpb)
|
||||||
|
{
|
||||||
|
KIRQL OldIrql;
|
||||||
|
PVPB LocalVpb;
|
||||||
|
BOOLEAN Result = FALSE;
|
||||||
|
|
||||||
|
/* Lock the VPBs and assume failure */
|
||||||
|
IoAcquireVpbSpinLock(&OldIrql);
|
||||||
|
*Vpb = NULL;
|
||||||
|
*FileSystemObject = NULL;
|
||||||
|
|
||||||
|
/* Get the VPB and make sure it's mounted */
|
||||||
|
LocalVpb = DeviceObject->Vpb;
|
||||||
|
if ((LocalVpb) && (LocalVpb->Flags & VPB_MOUNTED))
|
||||||
|
{
|
||||||
|
/* Return it */
|
||||||
|
*Vpb = LocalVpb;
|
||||||
|
*FileSystemObject = LocalVpb->DeviceObject;
|
||||||
|
|
||||||
|
/* Reference it */
|
||||||
|
LocalVpb->ReferenceCount++;
|
||||||
|
Result = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the VPB lock and return status */
|
||||||
|
IoReleaseVpbSpinLock(OldIrql);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
IopNotifyFileSystemChange(IN PDEVICE_OBJECT DeviceObject,
|
IopNotifyFileSystemChange(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
@ -335,73 +389,88 @@ IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
PIO_STACK_LOCATION StackPtr;
|
PIO_STACK_LOCATION StackPtr;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS, VpbStatus;
|
||||||
PDEVICE_OBJECT DevObject;
|
PDEVICE_OBJECT FileSystemDeviceObject;
|
||||||
PVPB NewVpb;
|
PVPB Vpb, NewVpb;
|
||||||
|
BOOLEAN WasNotMounted = TRUE;
|
||||||
|
|
||||||
|
/* Wait on the device lock */
|
||||||
KeWaitForSingleObject(&DeviceObject->DeviceLock,
|
KeWaitForSingleObject(&DeviceObject->DeviceLock,
|
||||||
Executive,
|
Executive,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (DeviceObject->Vpb->Flags & VPB_MOUNTED)
|
/* Reference the VPB */
|
||||||
|
if (IopReferenceVpbForVerify(DeviceObject, &FileSystemDeviceObject, &Vpb))
|
||||||
{
|
{
|
||||||
/* Issue verify request to the FSD */
|
/* Initialize the event */
|
||||||
DevObject = DeviceObject->Vpb->DeviceObject;
|
|
||||||
|
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
Irp = IoAllocateIrp(DevObject->StackSize, TRUE);
|
/* Find the actual File System DO */
|
||||||
if (Irp==NULL)
|
WasNotMounted = FALSE;
|
||||||
|
FileSystemDeviceObject = DeviceObject->Vpb->DeviceObject;
|
||||||
|
while (FileSystemDeviceObject->AttachedDevice)
|
||||||
{
|
{
|
||||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
/* Go to the next one */
|
||||||
|
FileSystemDeviceObject = FileSystemDeviceObject->AttachedDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate the IRP */
|
||||||
|
Irp = IoAllocateIrp(FileSystemDeviceObject->StackSize, FALSE);
|
||||||
|
if (!Irp) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* Set it up */
|
||||||
Irp->UserIosb = &IoStatusBlock;
|
Irp->UserIosb = &IoStatusBlock;
|
||||||
Irp->UserEvent = &Event;
|
Irp->UserEvent = &Event;
|
||||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||||
|
Irp->Flags = IRP_MOUNT_COMPLETION | IRP_SYNCHRONOUS_PAGING_IO;
|
||||||
|
Irp->RequestorMode = KernelMode;
|
||||||
|
|
||||||
|
/* Get the I/O Stack location and set it */
|
||||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||||
StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
|
StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
|
||||||
StackPtr->MinorFunction = IRP_MN_VERIFY_VOLUME;
|
StackPtr->MinorFunction = IRP_MN_VERIFY_VOLUME;
|
||||||
StackPtr->Flags = 0;
|
StackPtr->Flags = AllowRawMount ? SL_ALLOW_RAW_MOUNT : 0;
|
||||||
StackPtr->Control = 0;
|
StackPtr->Parameters.VerifyVolume.Vpb = Vpb;
|
||||||
StackPtr->DeviceObject = DevObject;
|
StackPtr->Parameters.VerifyVolume.DeviceObject =
|
||||||
StackPtr->FileObject = NULL;
|
DeviceObject->Vpb->DeviceObject;
|
||||||
StackPtr->CompletionRoutine = NULL;
|
|
||||||
|
|
||||||
StackPtr->Parameters.VerifyVolume.Vpb = DeviceObject->Vpb;
|
/* Call the driver */
|
||||||
StackPtr->Parameters.VerifyVolume.DeviceObject = DeviceObject;
|
Status = IoCallDriver(FileSystemDeviceObject, Irp);
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
Status = IoCallDriver(DevObject, Irp);
|
|
||||||
if (Status==STATUS_PENDING)
|
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
|
/* Wait on it */
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
Status = IoStatusBlock.Status;
|
Status = IoStatusBlock.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
/* Dereference the VPB */
|
||||||
{
|
IopDereferenceVpb(Vpb);
|
||||||
KeSetEvent(&DeviceObject->DeviceLock, IO_NO_INCREMENT, FALSE);
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Status == STATUS_WRONG_VOLUME)
|
/* Check if we had the wrong volume or didn't mount at all */
|
||||||
|
if ((Status == STATUS_WRONG_VOLUME) || (WasNotMounted))
|
||||||
{
|
{
|
||||||
/* Clean existing VPB. This unmounts the filesystem. */
|
/* Create a VPB */
|
||||||
DPRINT("Wrong volume!\n");
|
VpbStatus = IopCreateVpb(DeviceObject);
|
||||||
|
if (NT_SUCCESS(VpbStatus))
|
||||||
|
{
|
||||||
|
/* Mount it */
|
||||||
|
VpbStatus = IopMountVolume(DeviceObject,
|
||||||
|
AllowRawMount,
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
&NewVpb);
|
||||||
|
}
|
||||||
|
|
||||||
DeviceObject->Vpb->DeviceObject = NULL;
|
/* If we failed, remove the verify flag */
|
||||||
DeviceObject->Vpb->Flags &= ~VPB_MOUNTED;
|
if (!NT_SUCCESS(VpbStatus)) DeviceObject->Flags &= ~DO_VERIFY_VOLUME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start mount sequence */
|
/* Signal the device lock and return */
|
||||||
Status = IopMountVolume(DeviceObject, AllowRawMount, TRUE, FALSE, &NewVpb);
|
|
||||||
|
|
||||||
KeSetEvent(&DeviceObject->DeviceLock, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&DeviceObject->DeviceLock, IO_NO_INCREMENT, FALSE);
|
||||||
return(Status);
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue