mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 22:56:00 +00:00
- Implement IopCheckVpbMounted and use it in IopParseDevice as documented in NT File System Internals.
- Add some missing ref/deref calls for DOs and VPBs. svn path=/trunk/; revision=22903
This commit is contained in:
parent
979b777dd5
commit
d6e384ce39
3 changed files with 96 additions and 17 deletions
|
@ -574,6 +574,15 @@ IopStartDevice(
|
||||||
IN PDEVICE_NODE DeviceNode
|
IN PDEVICE_NODE DeviceNode
|
||||||
);
|
);
|
||||||
|
|
||||||
|
PVPB
|
||||||
|
NTAPI
|
||||||
|
IopCheckVpbMounted(
|
||||||
|
IN POPEN_PACKET OpenPacket,
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PUNICODE_STRING RemainingName,
|
||||||
|
OUT PNTSTATUS Status
|
||||||
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IopMountVolume(
|
IopMountVolume(
|
||||||
|
@ -619,6 +628,13 @@ IopReferenceDeviceObject(
|
||||||
IN PDEVICE_OBJECT DeviceObject
|
IN PDEVICE_OBJECT DeviceObject
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
IopDereferenceDeviceObject(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN BOOLEAN ForceUnload
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// IRP Routines
|
// IRP Routines
|
||||||
//
|
//
|
||||||
|
|
|
@ -92,6 +92,9 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
{
|
{
|
||||||
/* Yes, remember it */
|
/* Yes, remember it */
|
||||||
Vpb = OpenPacket->RelatedFileObject->Vpb;
|
Vpb = OpenPacket->RelatedFileObject->Vpb;
|
||||||
|
|
||||||
|
/* Reference it */
|
||||||
|
InterlockedIncrement(&Vpb->ReferenceCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -102,25 +105,15 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
/* Check if it has a VPB */
|
/* Check if it has a VPB */
|
||||||
if ((DeviceObject->Vpb) && !(DirectOpen))
|
if ((DeviceObject->Vpb) && !(DirectOpen))
|
||||||
{
|
{
|
||||||
/* Check if it's not already mounted */
|
/* Check if the VPB is mounted, and mount it */
|
||||||
if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
|
Vpb = IopCheckVpbMounted(OpenPacket,
|
||||||
{
|
DeviceObject,
|
||||||
/* Mount the volume */
|
RemainingName,
|
||||||
Status = IopMountVolume(DeviceObject,
|
&Status);
|
||||||
FALSE,
|
if (!Vpb) return Status;
|
||||||
FALSE,
|
|
||||||
FALSE,
|
|
||||||
&Vpb);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
/* Couldn't mount, fail the lookup */
|
|
||||||
ObDereferenceObject(FileObject);
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the VPB's device object */
|
/* Get the VPB's device object */
|
||||||
DeviceObject = DeviceObject->Vpb->DeviceObject;
|
DeviceObject = Vpb->DeviceObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if there's an attached device */
|
/* Check if there's an attached device */
|
||||||
|
|
|
@ -54,6 +54,76 @@ IoInitFileSystemImplementation(VOID)
|
||||||
KeInitializeGuardedMutex(&FsChangeNotifyListLock);
|
KeInitializeGuardedMutex(&FsChangeNotifyListLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PVPB
|
||||||
|
NTAPI
|
||||||
|
IopCheckVpbMounted(IN POPEN_PACKET OpenPacket,
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PUNICODE_STRING RemainingName,
|
||||||
|
OUT PNTSTATUS Status)
|
||||||
|
{
|
||||||
|
BOOLEAN Alertable, Raw;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
PVPB Vpb = NULL;
|
||||||
|
|
||||||
|
/* Lock the VPBs */
|
||||||
|
IoAcquireVpbSpinLock(&OldIrql);
|
||||||
|
|
||||||
|
/* Set VPB mount settings */
|
||||||
|
Raw = !RemainingName->Length && !OpenPacket->RelatedFileObject;
|
||||||
|
Alertable = (OpenPacket->CreateOptions & FILE_SYNCHRONOUS_IO_ALERT);
|
||||||
|
|
||||||
|
/* Start looping until the VPB is mounted */
|
||||||
|
while (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
|
||||||
|
{
|
||||||
|
/* Release the lock */
|
||||||
|
IoReleaseVpbSpinLock(OldIrql);
|
||||||
|
|
||||||
|
/* Mount the volume */
|
||||||
|
*Status = IopMountVolume(DeviceObject,
|
||||||
|
Raw,
|
||||||
|
FALSE,
|
||||||
|
Alertable,
|
||||||
|
&Vpb);
|
||||||
|
|
||||||
|
/* Check if we failed or if we were alerted */
|
||||||
|
if (!(NT_SUCCESS(*Status)) ||
|
||||||
|
(*Status == STATUS_USER_APC) ||
|
||||||
|
(*Status == STATUS_ALERTED))
|
||||||
|
{
|
||||||
|
/* Dereference the device, since IopParseDevice referenced it */
|
||||||
|
IopDereferenceDeviceObject(DeviceObject, FALSE);
|
||||||
|
|
||||||
|
/* Check if it was a total failure */
|
||||||
|
if (!NT_SUCCESS(Status)) return NULL;
|
||||||
|
|
||||||
|
/* Otherwise we were alerted */
|
||||||
|
*Status = STATUS_WRONG_VOLUME;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Re-acquire the lock */
|
||||||
|
IoAcquireVpbSpinLock(&OldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure the VPB isn't locked */
|
||||||
|
Vpb = DeviceObject->Vpb;
|
||||||
|
if (Vpb->Flags & VPB_LOCKED)
|
||||||
|
{
|
||||||
|
/* We're locked, so fail */
|
||||||
|
*Status = STATUS_ACCESS_DENIED;
|
||||||
|
Vpb = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Success! Reference the VPB */
|
||||||
|
Vpb->ReferenceCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the lock and return the VPB */
|
||||||
|
IoReleaseVpbSpinLock(OldIrql);
|
||||||
|
return Vpb;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IopCreateVpb(IN PDEVICE_OBJECT DeviceObject)
|
IopCreateVpb(IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue