[MOUNTMGR] Don't kill Mm when a device has several symlinks
authorPierre Schweitzer <pierre@reactos.org>
Sat, 19 Oct 2019 16:04:30 +0000 (18:04 +0200)
committerPierre Schweitzer <pierre@reactos.org>
Sat, 19 Oct 2019 16:04:30 +0000 (18:04 +0200)
On preflight to compute output size, device name & unique ID were
counted only once per device.
Then, on copy, these two were copied on every MOUNTMGR_MOUNT_POINT
structure. This is counter efficient (data duplication) but also,
it was overruning the output buffer, since the preflight was not
expecting these extra copies.

drivers/filters/mountmgr/point.c

index a2469b0..38260a5 100644 (file)
@@ -241,11 +241,12 @@ QueryPointsFromMemory(IN PDEVICE_EXTENSION DeviceExtension,
     NTSTATUS Status;
     PIO_STACK_LOCATION Stack;
     UNICODE_STRING DeviceName;
-    ULONG TotalSize, TotalSymLinks;
     PMOUNTMGR_MOUNT_POINTS MountPoints;
     PDEVICE_INFORMATION DeviceInformation;
     PLIST_ENTRY DeviceEntry, SymlinksEntry;
     PSYMLINK_INFORMATION SymlinkInformation;
+    USHORT UniqueIdLength, DeviceNameLength;
+    ULONG TotalSize, TotalSymLinks, UniqueIdOffset, DeviceNameOffset;
 
     /* If we got a symbolic link, query device */
     if (SymbolicName)
@@ -384,6 +385,26 @@ QueryPointsFromMemory(IN PDEVICE_EXTENSION DeviceExtension,
             }
         }
 
+        /* Save our information about shared data */
+        UniqueIdOffset = TotalSize;
+        UniqueIdLength = DeviceInformation->UniqueId->UniqueIdLength;
+        DeviceNameOffset = TotalSize + UniqueIdLength;
+        DeviceNameLength = DeviceInformation->DeviceName.Length;
+
+        /* Initialize first symlink */
+        MountPoints->MountPoints[TotalSymLinks].UniqueIdOffset = UniqueIdOffset;
+        MountPoints->MountPoints[TotalSymLinks].UniqueIdLength = UniqueIdLength;
+        MountPoints->MountPoints[TotalSymLinks].DeviceNameOffset = DeviceNameOffset;
+        MountPoints->MountPoints[TotalSymLinks].DeviceNameLength = DeviceNameLength;
+
+        /* And copy data */
+        RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + UniqueIdOffset),
+                      DeviceInformation->UniqueId->UniqueId, UniqueIdLength);
+        RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + DeviceNameOffset),
+                      DeviceInformation->DeviceName.Buffer, DeviceNameLength);
+
+        TotalSize += DeviceInformation->UniqueId->UniqueIdLength + DeviceInformation->DeviceName.Length;
+
         /* Now we've got it, but all the data */
         for (SymlinksEntry = DeviceInformation->SymbolicLinksListHead.Flink;
              SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead);
@@ -391,27 +412,33 @@ QueryPointsFromMemory(IN PDEVICE_EXTENSION DeviceExtension,
         {
             SymlinkInformation = CONTAINING_RECORD(SymlinksEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
 
+            /* First, set shared data */
+
+            /* Only put UniqueID if online */
+            if (SymlinkInformation->Online)
+            {
+                MountPoints->MountPoints[TotalSymLinks].UniqueIdOffset = UniqueIdOffset;
+                MountPoints->MountPoints[TotalSymLinks].UniqueIdLength = UniqueIdLength;
+            }
+            else
+            {
+                MountPoints->MountPoints[TotalSymLinks].UniqueIdOffset = 0;
+                MountPoints->MountPoints[TotalSymLinks].UniqueIdLength = 0;
+            }
+
+            MountPoints->MountPoints[TotalSymLinks].DeviceNameOffset = DeviceNameOffset;
+            MountPoints->MountPoints[TotalSymLinks].DeviceNameLength = DeviceNameLength;
+
+            /* And now, copy specific symlink info */
             MountPoints->MountPoints[TotalSymLinks].SymbolicLinkNameOffset = TotalSize;
             MountPoints->MountPoints[TotalSymLinks].SymbolicLinkNameLength = SymlinkInformation->Name.Length;
-            MountPoints->MountPoints[TotalSymLinks].UniqueIdOffset = SymlinkInformation->Name.Length +
-                                                                     TotalSize;
-            MountPoints->MountPoints[TotalSymLinks].UniqueIdLength = DeviceInformation->UniqueId->UniqueIdLength;
-            MountPoints->MountPoints[TotalSymLinks].DeviceNameOffset = SymlinkInformation->Name.Length +
-                                                                       DeviceInformation->UniqueId->UniqueIdLength +
-                                                                       TotalSize;
-            MountPoints->MountPoints[TotalSymLinks].DeviceNameLength = DeviceInformation->DeviceName.Length;
 
             RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[TotalSymLinks].SymbolicLinkNameOffset),
                           SymlinkInformation->Name.Buffer, SymlinkInformation->Name.Length);
-            RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[TotalSymLinks].UniqueIdOffset),
-                          DeviceInformation->UniqueId->UniqueId, DeviceInformation->UniqueId->UniqueIdLength);
-            RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[TotalSymLinks].DeviceNameOffset),
-                  DeviceInformation->DeviceName.Buffer, DeviceInformation->DeviceName.Length);
 
             /* Update counters */
             TotalSymLinks++;
-            TotalSize += SymlinkInformation->Name.Length + DeviceInformation->UniqueId->UniqueIdLength +
-                         DeviceInformation->DeviceName.Length;
+            TotalSize += SymlinkInformation->Name.Length;
         }
 
         if (UniqueId || SymbolicName)