Author: ion
Date: Fri Jul 7 21:18:52 2006
New Revision: 22903
URL:
http://svn.reactos.org/svn/reactos?rev=22903&view=rev
Log:
- Implement IopCheckVpbMounted and use it in IopParseDevice as documented in NT File
System Internals.
- Add some missing ref/deref calls for DOs and VPBs.
Modified:
trunk/reactos/ntoskrnl/include/internal/io.h
trunk/reactos/ntoskrnl/io/iomgr/file.c
trunk/reactos/ntoskrnl/io/iomgr/volume.c
Modified: trunk/reactos/ntoskrnl/include/internal/io.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/io.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/io.h Fri Jul 7 21:18:52 2006
@@ -574,6 +574,15 @@
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(
@@ -617,6 +626,13 @@
NTAPI
IopReferenceDeviceObject(
IN PDEVICE_OBJECT DeviceObject
+);
+
+VOID
+NTAPI
+IopDereferenceDeviceObject(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN BOOLEAN ForceUnload
);
//
Modified: trunk/reactos/ntoskrnl/io/iomgr/file.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/file.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/file.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/file.c Fri Jul 7 21:18:52 2006
@@ -92,6 +92,9 @@
{
/* Yes, remember it */
Vpb = OpenPacket->RelatedFileObject->Vpb;
+
+ /* Reference it */
+ InterlockedIncrement(&Vpb->ReferenceCount);
}
}
else
@@ -102,25 +105,15 @@
/* 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 */
Modified: trunk/reactos/ntoskrnl/io/iomgr/volume.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/volume.c…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/volume.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/volume.c Fri Jul 7 21:18:52 2006
@@ -52,6 +52,76 @@
ExInitializeResourceLite(&FileSystemListLock);
InitializeListHead(&FsChangeNotifyListHead);
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