[ros-diffs] [ion] 22903: - Implement IopCheckVpbMounted and use it in IopParseDevice as documented in NT File System Internals. - Add some missing ref/deref calls for DOs and VPBs.

ion at svn.reactos.org ion at svn.reactos.org
Fri Jul 7 19:18:53 CEST 2006


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/io.h?rev=22903&r1=22902&r2=22903&view=diff
==============================================================================
--- 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?rev=22903&r1=22902&r2=22903&view=diff
==============================================================================
--- 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?rev=22903&r1=22902&r2=22903&view=diff
==============================================================================
--- 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




More information about the Ros-diffs mailing list