[MOUNTMGR]
authorPierre Schweitzer <pierre@reactos.org>
Sat, 19 Sep 2015 13:03:41 +0000 (13:03 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Sat, 19 Sep 2015 13:03:41 +0000 (13:03 +0000)
Implement the IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATHS:
- Implement MountMgrQueryVolumePaths()
- Implement MountMgrValidateBackPointer()
- Implement MountMgrQueryDosVolumePaths()
- Rename a struct var to reflect its real usage

svn path=/trunk/; revision=69284

reactos/drivers/filters/mountmgr/device.c
reactos/drivers/filters/mountmgr/mntmgr.h
reactos/drivers/filters/mountmgr/mountmgr.c
reactos/drivers/filters/mountmgr/notify.c
reactos/drivers/filters/mountmgr/point.c

index 3f822b4..609849d 100644 (file)
@@ -311,7 +311,7 @@ MountMgrCheckUnprocessedVolumes(IN PDEVICE_EXTENSION DeviceExtension,
 
         ArrivalStatus = MountMgrMountedDeviceArrival(DeviceExtension,
                                                      &(DeviceInformation->SymbolicName),
-                                                     DeviceInformation->Volume);
+                                                     DeviceInformation->ManuallyRegistered);
         /* Then, remove them dead information */
         MountMgrFreeDeadDeviceInfo(DeviceInformation);
 
@@ -829,6 +829,9 @@ MountMgrAssignDriveLetters(IN PDEVICE_EXTENSION DeviceExtension)
     }
 }
 
+/*
+ * @implemented
+ */
 NTSTATUS
 MountMgrQueryDosVolumePath(IN PDEVICE_EXTENSION DeviceExtension,
                            IN PIRP Irp)
@@ -967,7 +970,7 @@ MountMgrQueryDosVolumePath(IN PDEVICE_EXTENSION DeviceExtension,
     }
 
     /* Get the letter */
-    DeviceString[0] = SymlinkInformation->Name.Buffer[12];
+    DeviceString[0] = SymlinkInformation->Name.Buffer[LETTER_POSITION];
     DeviceString[1] = L':';
 
     /* And copy the rest */
@@ -1053,13 +1056,539 @@ TryWithVolumeName:
     return STATUS_NOT_FOUND;
 }
 
+/*
+ * @implemented
+ */
+NTSTATUS
+MountMgrValidateBackPointer(IN PASSOCIATED_DEVICE_ENTRY AssociatedDeviceEntry,
+                            IN PDEVICE_INFORMATION DeviceInformation,
+                            OUT PBOOLEAN Invalid)
+{
+    HANDLE Handle;
+    NTSTATUS Status;
+    PLIST_ENTRY SymlinksEntry;
+    IO_STATUS_BLOCK IoStatusBlock;
+    PREPARSE_DATA_BUFFER ReparseData;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING FullName, SubstituteName;
+    PSYMLINK_INFORMATION SymlinkInformation;
+
+    /* Initialize & allocate a string big enough to contain our complete mount point name */
+    FullName.Length = AssociatedDeviceEntry->String.Length + AssociatedDeviceEntry->DeviceInformation->DeviceName.Length + sizeof(WCHAR);
+    FullName.MaximumLength = FullName.Length + sizeof(UNICODE_NULL);
+    FullName.Buffer = AllocatePool(FullName.MaximumLength);
+    if (!FullName.Buffer)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* Create the path  */
+    RtlCopyMemory(FullName.Buffer, AssociatedDeviceEntry->DeviceInformation->DeviceName.Buffer, AssociatedDeviceEntry->DeviceInformation->DeviceName.Length);
+    FullName.Buffer[AssociatedDeviceEntry->DeviceInformation->DeviceName.Length / sizeof(WCHAR)] = L'\\';
+    RtlCopyMemory(&FullName.Buffer[AssociatedDeviceEntry->DeviceInformation->DeviceName.Length / sizeof(WCHAR) + 1], AssociatedDeviceEntry->String.Buffer, AssociatedDeviceEntry->String.Length);
+    FullName.Buffer[FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+
+    /* Open it to query the reparse point */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &FullName,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               NULL,
+                               NULL);
+    Status = ZwOpenFile(&Handle,
+                        SYNCHRONIZE | FILE_READ_ATTRIBUTES,
+                        &ObjectAttributes, &IoStatusBlock,
+                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                        FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT);
+    FreePool(FullName.Buffer);
+
+    if (!NT_SUCCESS(Status))
+    {
+        *Invalid = TRUE;
+        return STATUS_SUCCESS;
+    }
+
+    /* Allocate a buffer big enough to read reparse data */
+    ReparseData = AllocatePool(0x4000);
+    if (ReparseData == NULL)
+    {
+        ZwClose(Handle);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* Query reparse data */
+    Status = ZwFsControlFile(Handle,
+                             NULL, NULL, NULL,
+                             &IoStatusBlock,
+                             FSCTL_GET_REPARSE_POINT,
+                             NULL, 0,
+                             ReparseData, 0x4000);
+    ZwClose(Handle);
+
+    if (!NT_SUCCESS(Status))
+    {
+        FreePool(ReparseData);
+        *Invalid = TRUE;
+        return STATUS_SUCCESS;
+    }
+
+    /* Create a string with the substitute name */
+    SubstituteName.Length = ReparseData->SymbolicLinkReparseBuffer.SubstituteNameLength;
+    SubstituteName.MaximumLength = SubstituteName.Length;
+    SubstituteName.Buffer = (PWSTR)((ULONG_PTR)ReparseData->SymbolicLinkReparseBuffer.PathBuffer + ReparseData->SymbolicLinkReparseBuffer.SubstituteNameOffset);
+
+    /* If that's a volume name that matches our associated device, that's a success! */
+    if (MOUNTMGR_IS_VOLUME_NAME(&SubstituteName))
+    {
+        if (SubstituteName.Length == 98 && SubstituteName.Buffer[1] == L'?')
+        {
+            for (SymlinksEntry = DeviceInformation->SymbolicLinksListHead.Flink;
+                 SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead);
+                 SymlinksEntry = SymlinksEntry->Flink)
+            {
+                SymlinkInformation = CONTAINING_RECORD(SymlinksEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
+
+                if (RtlEqualUnicodeString(&SubstituteName, &SymlinkInformation->Name, TRUE))
+                {
+                    FreePool(ReparseData);
+                    return STATUS_SUCCESS;
+                }
+            }
+        }
+    }
+
+    FreePool(ReparseData);
+    *Invalid = TRUE;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+MountMgrQueryVolumePaths(IN PDEVICE_EXTENSION DeviceExtension,
+                         IN PDEVICE_INFORMATION DeviceInformation,
+                         IN PLIST_ENTRY DeviceInfoList,
+                         OUT PMOUNTMGR_VOLUME_PATHS * VolumePaths,
+                         OUT PDEVICE_INFORMATION *FailedDevice)
+{
+    ULONG Written;
+    NTSTATUS Status;
+    PLIST_ENTRY Entry;
+    PSYMLINK_INFORMATION SymlinkInformation;
+    PDEVICE_INFORMATION_ENTRY DeviceInfoEntry;
+    PASSOCIATED_DEVICE_ENTRY AssociatedDeviceEntry;
+    PMOUNTMGR_VOLUME_PATHS * Paths = NULL, * CurrentPath;
+    ULONG OutputPathLength, NumberOfPaths, ReturnedPaths;
+
+    /* We return at least null char */
+    OutputPathLength = sizeof(UNICODE_NULL);
+
+    for (Entry = DeviceInformation->SymbolicLinksListHead.Flink;
+         Entry != &(DeviceInformation->SymbolicLinksListHead);
+         Entry = Entry->Flink)
+    {
+        SymlinkInformation = CONTAINING_RECORD(Entry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
+
+        /* Try to find the drive letter (ie, DOS device) */
+        if (MOUNTMGR_IS_DRIVE_LETTER(&SymlinkInformation->Name) && SymlinkInformation->Online)
+        {
+            /* We'll return the letter */
+            OutputPathLength = 4 * sizeof(WCHAR);
+            break;
+        }
+    }
+
+    /* We didn't find any */
+    if (Entry == &(DeviceInformation->SymbolicLinksListHead))
+    {
+        SymlinkInformation = NULL;
+    }
+
+    /* Do we have any device info to return? */
+    for (Entry = DeviceInfoList->Flink; Entry != DeviceInfoList; Entry = Entry->Flink)
+    {
+        DeviceInfoEntry = CONTAINING_RECORD(Entry, DEVICE_INFORMATION_ENTRY, DeviceInformationEntry);
+
+        /* Matching current device */
+        if (DeviceInfoEntry->DeviceInformation == DeviceInformation)
+        {
+            /* Allocate the output buffer */
+            *VolumePaths = AllocatePool(sizeof(ULONG) + OutputPathLength);
+            if (*VolumePaths == NULL)
+            {
+                return STATUS_INSUFFICIENT_RESOURCES;
+            }
+
+            /* Set size */
+            (*VolumePaths)->MultiSzLength = OutputPathLength;
+            /* If we have a drive letter, return it */
+            if (SymlinkInformation != NULL)
+            {
+                (*VolumePaths)->MultiSz[0] = SymlinkInformation->Name.Buffer[LETTER_POSITION];
+                (*VolumePaths)->MultiSz[1] = L':';
+                (*VolumePaths)->MultiSz[2] = UNICODE_NULL;
+                (*VolumePaths)->MultiSz[3] = UNICODE_NULL;
+            }
+            else
+            {
+                (*VolumePaths)->MultiSz[0] = UNICODE_NULL;
+            }
+
+            return STATUS_SUCCESS;
+        }
+    }
+
+    /* Allocate a new device entry */
+    DeviceInfoEntry = AllocatePool(sizeof(DEVICE_INFORMATION_ENTRY));
+    if (DeviceInfoEntry == NULL)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* Add it to the list */
+    DeviceInfoEntry->DeviceInformation = DeviceInformation;
+    InsertTailList(DeviceInfoList, &DeviceInfoEntry->DeviceInformationEntry);
+
+    NumberOfPaths = 0;
+    /* Count the amount of devices we will have to handle */
+    if (!IsListEmpty(&DeviceInformation->AssociatedDevicesHead))
+    {
+        for (Entry = DeviceInformation->AssociatedDevicesHead.Flink;
+                     Entry != &DeviceInformation->AssociatedDevicesHead;
+                     Entry = Entry->Flink)
+        {
+            ++NumberOfPaths;
+        }
+
+        ASSERT(NumberOfPaths != 0);
+        /* And allocate a big enough buffer */
+        Paths = AllocatePool(NumberOfPaths * sizeof(PMOUNTMGR_VOLUME_PATHS));
+        if (Paths == NULL)
+        {
+            RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
+            FreePool(DeviceInfoEntry);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+    }
+
+    /* Start the hot loop to gather all the paths and be able to compute total output length! */
+    ReturnedPaths = 0;
+    CurrentPath = Paths;
+    for (Entry = DeviceInformation->AssociatedDevicesHead.Flink;
+         Entry != &DeviceInformation->AssociatedDevicesHead;
+         Entry = Entry->Flink)
+    {
+        USHORT InnerStrings;
+        BOOLEAN Invalid = FALSE;
+
+        AssociatedDeviceEntry = CONTAINING_RECORD(Entry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
+
+        /* Validate the fact its a mount point by query reparse data */
+        Status = MountMgrValidateBackPointer(AssociatedDeviceEntry, DeviceInformation, &Invalid);
+
+        /* If we found an invalid device, that's a failure */
+        if (Invalid)
+        {
+            *FailedDevice = AssociatedDeviceEntry->DeviceInformation;
+            Status = STATUS_UNSUCCESSFUL;
+        }
+
+        /* Check whether we failed, if so, bail out */
+        if (!NT_SUCCESS(Status))
+        {
+            ULONG i;
+
+            for (i = 0; i < ReturnedPaths; ++i)
+            {
+                FreePool(Paths[i]);
+            }
+
+            if (Paths != NULL)
+            {
+                FreePool(Paths);
+            }
+            RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
+            FreePool(DeviceInfoEntry);
+            return Status;
+        }
+
+        /* Query associated paths (hello ourselves :-)) */
+        Status = MountMgrQueryVolumePaths(DeviceExtension,
+                                          AssociatedDeviceEntry->DeviceInformation,
+                                          DeviceInfoList,
+                                          CurrentPath,
+                                          FailedDevice);
+        if (!NT_SUCCESS(Status))
+        {
+            ULONG i;
+
+            for (i = 0; i < ReturnedPaths; ++i)
+            {
+                FreePool(Paths[i]);
+            }
+
+            if (Paths != NULL)
+            {
+                FreePool(Paths);
+            }
+            RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
+            FreePool(DeviceInfoEntry);
+            return Status;
+        }
+
+        /* Count the number of strings we have in the multi string buffer */
+        InnerStrings = 0;
+        if ((*CurrentPath)->MultiSzLength != sizeof(UNICODE_NULL))
+        {
+            ULONG i;
+            PWSTR MultiSz = (*CurrentPath)->MultiSz;
+
+            for (i = 0; i < (*CurrentPath)->MultiSzLength / sizeof(WCHAR); ++i, ++MultiSz)
+            {
+                if (*MultiSz == UNICODE_NULL)
+                {
+                    ++InnerStrings;
+                }
+            }
+        }
+
+        /* We returned one more path (ie, one more allocated buffer) */
+        ++ReturnedPaths;
+        /* Move the next pointer to use in the array */
+        ++CurrentPath;
+        /* Multiply String.Length by the number of found paths, we always add it after a path */
+        OutputPathLength += (*CurrentPath)->MultiSzLength + InnerStrings * AssociatedDeviceEntry->String.Length - sizeof(UNICODE_NULL);
+    }
+
+    /* Allocate the output buffer */
+    *VolumePaths = AllocatePool(sizeof(ULONG) + OutputPathLength);
+    if (*VolumePaths == NULL)
+    {
+        ULONG i;
+
+        for (i = 0; i < ReturnedPaths; ++i)
+        {
+            FreePool(Paths[i]);
+        }
+
+        if (Paths != NULL)
+        {
+            FreePool(Paths);
+        }
+        RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
+        FreePool(DeviceInfoEntry);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    Written = 0;
+    /* If we had found a DOS letter, that's the first thing we return */
+    (*VolumePaths)->MultiSzLength = OutputPathLength;
+    if (SymlinkInformation != NULL)
+    {
+        (*VolumePaths)->MultiSz[0] = SymlinkInformation->Name.Buffer[LETTER_POSITION];
+        (*VolumePaths)->MultiSz[1] = L':';
+        (*VolumePaths)->MultiSz[2] = UNICODE_NULL;
+        Written = 3;
+    }
+
+    /* Now, browse again all our paths to return them */
+    CurrentPath = Paths;
+    for (Entry = DeviceInformation->AssociatedDevicesHead.Flink;
+         Entry != &DeviceInformation->AssociatedDevicesHead;
+         Entry = Entry->Flink)
+    {
+        AssociatedDeviceEntry = CONTAINING_RECORD(Entry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
+
+        /* If we had a path... */
+        if ((*CurrentPath)->MultiSzLength != sizeof(UNICODE_NULL))
+        {
+            ULONG i, Offset;
+            PWSTR MultiSz;
+
+            /* This offset is used to "jump" into MultiSz, so, start with the string begin (ie, skip MultiSzLength) */
+            Offset = sizeof(ULONG);
+            /* Browse every single letter, and skip last UNICODE_NULL */
+            for (i = 0; i < (*CurrentPath)->MultiSzLength / sizeof(WCHAR) - 1; ++i)
+            {
+                /* Get the letter */
+                MultiSz = (PWSTR)((ULONG_PTR)(*CurrentPath) + Offset);
+                /* If it was part of the path, just return it */
+                if (*MultiSz != UNICODE_NULL)
+                {
+                    (*VolumePaths)->MultiSz[Written] = *MultiSz;
+                }
+                else
+                {
+                    /* Otherwise, as planed, return our whole associated device name */
+                    RtlCopyMemory(&(*VolumePaths)->MultiSz[Written],
+                                  AssociatedDeviceEntry->String.Buffer,
+                                  AssociatedDeviceEntry->String.Length);
+                    Written += AssociatedDeviceEntry->String.Length / sizeof(WCHAR);
+                    /* And don't forget to nullify */
+                    (*VolumePaths)->MultiSz[Written] = UNICODE_NULL;
+                }
+
+                /* We at least return a letter or a null char */
+                ++Written;
+                /* Move to the next letter */
+                Offset += sizeof(WCHAR);
+            }
+        }
+
+        FreePool(*CurrentPath);
+        ++CurrentPath;
+    }
+
+    /* MultiSz: don't forget last null char */
+    (*VolumePaths)->MultiSz[Written] = UNICODE_NULL;
+    /* Cleanup everything and return success! */
+    if (Paths != NULL)
+    {
+        FreePool(Paths);
+    }
+    RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
+    FreePool(DeviceInfoEntry);
+    return STATUS_SUCCESS;
+}
+
 NTSTATUS
 MountMgrQueryDosVolumePaths(IN PDEVICE_EXTENSION DeviceExtension,
                             IN PIRP Irp)
 {
-    UNREFERENCED_PARAMETER(DeviceExtension);
-    UNREFERENCED_PARAMETER(Irp);
-    return STATUS_NOT_IMPLEMENTED;
+    NTSTATUS Status;
+    PLIST_ENTRY Entry;
+    LIST_ENTRY Devices;
+    BOOLEAN NeedNotification;
+    PIO_STACK_LOCATION Stack;
+    UNICODE_STRING SymbolicName;
+    ULONG Attempts, OutputLength;
+    PMOUNTMGR_TARGET_NAME Target;
+    PMOUNTMGR_VOLUME_PATHS Paths, Output;
+    PDEVICE_INFORMATION DeviceInformation, ListDeviceInfo, FailedDevice;
+
+    Stack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* Validate input size */
+    if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_TARGET_NAME))
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Ensure we have received UNICODE_STRING */
+    Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer;
+    if (Target->DeviceNameLength & 1)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Validate the entry structure size */
+    if (Target->DeviceNameLength + FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) > Stack->Parameters.DeviceIoControl.InputBufferLength)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Ensure we can at least return needed size */
+    if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Construct string for query */
+    SymbolicName.Length = Target->DeviceNameLength;
+    SymbolicName.MaximumLength = Target->DeviceNameLength + sizeof(UNICODE_NULL);
+    SymbolicName.Buffer = Target->DeviceName;
+
+    /* Find device with our info */
+    Status = FindDeviceInfo(DeviceExtension, &SymbolicName, FALSE, &DeviceInformation);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    NeedNotification = FALSE;
+    Attempts = 0;
+    for (;;)
+    {
+        FailedDevice = NULL;
+        InitializeListHead(&Devices);
+
+        /* Query paths */
+        Status = MountMgrQueryVolumePaths(DeviceExtension, DeviceInformation, &Devices, &Paths, &FailedDevice);
+        if (NT_SUCCESS(Status))
+        {
+            break;
+        }
+
+        /* If it failed for generic reason (memory, whatever), bail out (ie, FailedDevice not set) */
+        if (FailedDevice == NULL)
+        {
+            return Status;
+        }
+
+        /* If PnP, let's notify in case of success */
+        if (!DeviceInformation->ManuallyRegistered)
+        {
+            NeedNotification = TRUE;
+        }
+
+        /* Reconcile database */
+        KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
+        ReconcileThisDatabaseWithMasterWorker(&DeviceExtension);
+        KeWaitForSingleObject(&DeviceExtension->DeviceLock, Executive, KernelMode, FALSE, NULL);
+
+        /* Look for our device, to check it's online */
+        for (Entry = DeviceExtension->DeviceListHead.Flink;
+             Entry != &DeviceExtension->DeviceListHead;
+             Entry = Entry->Flink)
+        {
+            ListDeviceInfo = CONTAINING_RECORD(Entry, DEVICE_INFORMATION, DeviceListEntry);
+            /* It's online, it's OK! */
+            if (ListDeviceInfo == DeviceInformation)
+            {
+                break;
+            }
+        }
+
+        /* It's not online, it's not good */
+        if (Entry == &DeviceExtension->DeviceListHead)
+        {
+            return STATUS_OBJECT_NAME_NOT_FOUND;
+        }
+
+        /* Increase attempts count */
+        ++Attempts;
+        /* Don't look forever and fail if we get out of attempts */
+        if (Attempts >= 1000)
+        {
+            return Status;
+        }
+    }
+
+    /* We need to notify? Go ahead */
+    if (NeedNotification)
+    {
+        MountMgrNotifyNameChange(DeviceExtension, &SymbolicName, FALSE);
+    }
+
+    /* Get output buffer */
+    Output = (PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer;
+
+    /* Set required size */
+    Output->MultiSzLength = Paths->MultiSzLength;
+
+    /* Compute total length */
+    OutputLength = Output->MultiSzLength + sizeof(ULONG);
+
+    /* If it cannot fit, just return need size and quit */
+    if (OutputLength > Stack->Parameters.DeviceIoControl.OutputBufferLength)
+    {
+        Irp->IoStatus.Information = sizeof(ULONG);
+        FreePool(Paths);
+        return STATUS_BUFFER_OVERFLOW;
+    }
+
+    /* Copy data and quit */
+    Irp->IoStatus.Information = OutputLength;
+    RtlCopyMemory(Output->MultiSz, Paths->MultiSz, Output->MultiSzLength);
+    FreePool(Paths);
+    return STATUS_SUCCESS;
 }
 
 /*
@@ -1930,7 +2459,6 @@ MountMgrVolumeMountPointCreated(IN PDEVICE_EXTENSION DeviceExtension,
 /*
  * @implemented
  */
-
 NTSTATUS
 MountMgrVolumeMountPointDeleted(IN PDEVICE_EXTENSION DeviceExtension,
                                 IN PIRP Irp,
index f909d75..7161c4b 100644 (file)
@@ -67,7 +67,7 @@ typedef struct _DEVICE_INFORMATION
     UNICODE_STRING DeviceName;              // 0x2C
     BOOLEAN KeepLinks;                      // 0x34
     UCHAR SuggestedDriveLetter;             // 0x35
-    BOOLEAN Volume;                         // 0x36
+    BOOLEAN ManuallyRegistered;             // 0x36
     BOOLEAN Removable;                      // 0x37
     BOOLEAN LetterAssigned;                 // 0x38
     BOOLEAN NeedsReconcile;                 // 0x39
@@ -116,6 +116,12 @@ typedef struct _ASSOCIATED_DEVICE_ENTRY
     UNICODE_STRING String;                            // 0x0C
 } ASSOCIATED_DEVICE_ENTRY, *PASSOCIATED_DEVICE_ENTRY; // 0x14
 
+typedef struct _DEVICE_INFORMATION_ENTRY
+{
+    LIST_ENTRY DeviceInformationEntry;                  // 0x00
+    PDEVICE_INFORMATION DeviceInformation;              // 0x08
+} DEVICE_INFORMATION_ENTRY, *PDEVICE_INFORMATION_ENTRY; // 0x0C
+
 typedef struct _ONLINE_NOTIFICATION_WORK_ITEM
 {
     WORK_QUEUE_ITEM;                                              // 0x00
@@ -334,6 +340,12 @@ DeleteRemoteDatabaseEntry(
     IN LONG StartingOffset
 );
 
+VOID
+NTAPI
+ReconcileThisDatabaseWithMasterWorker(
+    IN PVOID Parameter
+);
+
 /* device.c */
 
 DRIVER_DISPATCH MountMgrDeviceControl;
index ec91753..dd2e4f0 100644 (file)
@@ -45,9 +45,6 @@ static const WCHAR Cunc[] = L"\\??\\C:";
 
 /*
  * TODO:
- * - MountMgrQueryDosVolumePaths
- * - MountMgrQueryVolumePaths
- * - MountMgrValidateBackPointer
  * - ReconcileThisDatabaseWithMasterWorker
  */
 
@@ -952,7 +949,7 @@ MountmgrReadNoAutoMount(IN PUNICODE_STRING RegistryPath)
 NTSTATUS
 MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION DeviceExtension,
                              IN PUNICODE_STRING SymbolicName,
-                             IN BOOLEAN FromVolume)
+                             IN BOOLEAN ManuallyRegistered)
 {
     WCHAR Letter;
     GUID StableGuid;
@@ -994,7 +991,7 @@ MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION DeviceExtension,
     /* Copy symbolic name */
     RtlCopyMemory(DeviceInformation->SymbolicName.Buffer, SymbolicName->Buffer, SymbolicName->Length);
     DeviceInformation->SymbolicName.Buffer[DeviceInformation->SymbolicName.Length / sizeof(WCHAR)] = UNICODE_NULL;
-    DeviceInformation->Volume = FromVolume;
+    DeviceInformation->ManuallyRegistered = ManuallyRegistered;
     DeviceInformation->DeviceExtension = DeviceExtension;
 
     /* Query as much data as possible about device */
@@ -1376,8 +1373,8 @@ MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION DeviceExtension,
         }
     }
 
-    /* If required, register for notifications about the device */
-    if (!FromVolume)
+    /* If that's a PnP device, register for notifications */
+    if (!ManuallyRegistered)
     {
         RegisterForTargetDeviceNotification(DeviceExtension, DeviceInformation);
     }
index de1e573..a5e0b25 100644 (file)
@@ -379,8 +379,9 @@ MountMgrNotifyNameChange(IN PDEVICE_EXTENSION DeviceExtension,
             }
         }
 
+        /* No need to notify for a PnP device or if we didn't find the device */
         if (NextEntry == &(DeviceExtension->DeviceListHead) ||
-            !DeviceInformation->Volume)
+            !DeviceInformation->ManuallyRegistered)
         {
             return;
         }
index 730add4..b65c22c 100644 (file)
@@ -221,7 +221,7 @@ MountMgrCreatePointWorker(IN PDEVICE_EXTENSION DeviceExtension,
     FreePool(SymLink.Buffer);
     MountMgrNotify(DeviceExtension);
 
-    if (!DeviceInformation->Volume)
+    if (!DeviceInformation->ManuallyRegistered)
     {
         MountMgrNotifyNameChange(DeviceExtension, DeviceName, FALSE);
     }