mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 09:46:21 +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
|
||||
);
|
||||
|
||||
PVPB
|
||||
NTAPI
|
||||
IopCheckVpbMounted(
|
||||
IN POPEN_PACKET OpenPacket,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PUNICODE_STRING RemainingName,
|
||||
OUT PNTSTATUS Status
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IopMountVolume(
|
||||
|
@ -619,6 +628,13 @@ IopReferenceDeviceObject(
|
|||
IN PDEVICE_OBJECT DeviceObject
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
IopDereferenceDeviceObject(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN BOOLEAN ForceUnload
|
||||
);
|
||||
|
||||
//
|
||||
// IRP Routines
|
||||
//
|
||||
|
|
|
@ -92,6 +92,9 @@ IopParseDevice(IN PVOID ParseObject,
|
|||
{
|
||||
/* Yes, remember it */
|
||||
Vpb = OpenPacket->RelatedFileObject->Vpb;
|
||||
|
||||
/* Reference it */
|
||||
InterlockedIncrement(&Vpb->ReferenceCount);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -102,25 +105,15 @@ IopParseDevice(IN PVOID ParseObject,
|
|||
/* Check if it has a VPB */
|
||||
if ((DeviceObject->Vpb) && !(DirectOpen))
|
||||
{
|
||||
/* Check if it's not already mounted */
|
||||
if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
|
||||
{
|
||||
/* Mount the volume */
|
||||
Status = IopMountVolume(DeviceObject,
|
||||
FALSE,
|
||||
FALSE,
|
||||
FALSE,
|
||||
&Vpb);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Couldn't mount, fail the lookup */
|
||||
ObDereferenceObject(FileObject);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
/* Check if the VPB is mounted, and mount it */
|
||||
Vpb = IopCheckVpbMounted(OpenPacket,
|
||||
DeviceObject,
|
||||
RemainingName,
|
||||
&Status);
|
||||
if (!Vpb) return Status;
|
||||
|
||||
/* Get the VPB's device object */
|
||||
DeviceObject = DeviceObject->Vpb->DeviceObject;
|
||||
DeviceObject = Vpb->DeviceObject;
|
||||
}
|
||||
|
||||
/* Check if there's an attached device */
|
||||
|
|
|
@ -54,6 +54,76 @@ IoInitFileSystemImplementation(VOID)
|
|||
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
|
||||
NTAPI
|
||||
IopCreateVpb(IN PDEVICE_OBJECT DeviceObject)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue