u can implement this....it is wonderful

On Mon, Sep 14, 2015 at 8:54 AM, Alex Ionescu <ionucu@videotron.ca> wrote:
Lol, make sure not to implement the huge vulnerability Microsoft patched two months ago (win2k->xp-style database migration).

Best regards,
Alex Ionescu

On Sun, Sep 13, 2015 at 6:52 PM, <pschweitzer@svn.reactos.org> wrote:
Author: pschweitzer
Date: Sun Sep 13 22:52:07 2015
New Revision: 69221

URL: http://svn.reactos.org/svn/reactos?rev=69221&view=rev
Log:
[MOUNTMGR]
Implement the IOCTL IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED:
- Implement WriteRemoteDatabaseEntry()
- Implement MountMgrVolumeMountPointCreated()

Modified:
    trunk/reactos/drivers/filters/mountmgr/database.c
    trunk/reactos/drivers/filters/mountmgr/device.c
    trunk/reactos/drivers/filters/mountmgr/mntmgr.h
    trunk/reactos/drivers/filters/mountmgr/mountmgr.c

Modified: trunk/reactos/drivers/filters/mountmgr/database.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filters/mountmgr/database.c?rev=69221&r1=69220&r2=69221&view=diff
==============================================================================
--- trunk/reactos/drivers/filters/mountmgr/database.c   [iso-8859-1] (original)
+++ trunk/reactos/drivers/filters/mountmgr/database.c   [iso-8859-1] Sun Sep 13 22:52:07 2015
@@ -192,6 +192,39 @@
     }

     return Entry;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+WriteRemoteDatabaseEntry(IN HANDLE Database,
+                         IN LONG Offset,
+                         IN PDATABASE_ENTRY Entry)
+{
+    NTSTATUS Status;
+    LARGE_INTEGER ByteOffset;
+    IO_STATUS_BLOCK IoStatusBlock;
+
+    ByteOffset.QuadPart = Offset;
+    Status = ZwWriteFile(Database,
+                         NULL,
+                         NULL,
+                         NULL,
+                         &IoStatusBlock,
+                         Entry,
+                         Entry->EntrySize,
+                         &ByteOffset,
+                         NULL);
+    if (NT_SUCCESS(Status))
+    {
+        if (IoStatusBlock.Information < Entry->EntrySize)
+        {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+        }
+    }
+
+    return Status;
 }

 /*

Modified: trunk/reactos/drivers/filters/mountmgr/device.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filters/mountmgr/device.c?rev=69221&r1=69220&r2=69221&view=diff
==============================================================================
--- trunk/reactos/drivers/filters/mountmgr/device.c     [iso-8859-1] (original)
+++ trunk/reactos/drivers/filters/mountmgr/device.c     [iso-8859-1] Sun Sep 13 22:52:07 2015
@@ -1688,15 +1688,242 @@
     return Status;
 }

+/*
+ * @implemented
+ */
 NTSTATUS
 MountMgrVolumeMountPointCreated(IN PDEVICE_EXTENSION DeviceExtension,
                                 IN PIRP Irp,
                                 IN NTSTATUS LockStatus)
 {
-    UNREFERENCED_PARAMETER(DeviceExtension);
-    UNREFERENCED_PARAMETER(Irp);
-    UNREFERENCED_PARAMETER(LockStatus);
-    return STATUS_NOT_IMPLEMENTED;
+    LONG Offset;
+    BOOLEAN Found;
+    NTSTATUS Status;
+    HANDLE RemoteDatabase;
+    PMOUNTDEV_UNIQUE_ID UniqueId;
+    PDATABASE_ENTRY DatabaseEntry;
+    PASSOCIATED_DEVICE_ENTRY AssociatedEntry;
+    PDEVICE_INFORMATION DeviceInformation, TargetDeviceInformation;
+    UNICODE_STRING LinkTarget, SourceDeviceName, SourceSymbolicName, TargetVolumeName, VolumeName, DbName;
+
+    /* Initialize string */
+    LinkTarget.Length = 0;
+    LinkTarget.MaximumLength = 0xC8;
+    LinkTarget.Buffer = AllocatePool(LinkTarget.MaximumLength);
+    if (LinkTarget.Buffer == NULL)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* If the mount point was created, then, it changed!
+     * Also use it to query some information
+     */
+    Status = MountMgrVolumeMountPointChanged(DeviceExtension, Irp, LockStatus, &SourceDeviceName, &SourceSymbolicName, &TargetVolumeName);
+    /* Pending means DB are under synchronization, bail out */
+    if (Status == STATUS_PENDING)
+    {
+        FreePool(LinkTarget.Buffer);
+        FreePool(SourceDeviceName.Buffer);
+        FreePool(SourceSymbolicName.Buffer);
+        return STATUS_PENDING;
+    }
+    else if (!NT_SUCCESS(Status))
+    {
+        FreePool(LinkTarget.Buffer);
+        return Status;
+    }
+
+    /* Query the device information */
+    Status = FindDeviceInfo(DeviceExtension, &SourceDeviceName, FALSE, &DeviceInformation);
+    if (!NT_SUCCESS(Status))
+    {
+        /* If it failed, first try to get volume name */
+        Status = QueryVolumeName(0, NULL, &SourceDeviceName, &LinkTarget, &VolumeName);
+        if (!NT_SUCCESS(Status))
+        {
+            /* Then, try to read the symlink */
+            Status = MountMgrQuerySymbolicLink(&SourceDeviceName, &LinkTarget);
+            if (!NT_SUCCESS(Status))
+            {
+                FreePool(LinkTarget.Buffer);
+                FreePool(SourceDeviceName.Buffer);
+                FreePool(SourceSymbolicName.Buffer);
+                return Status;
+            }
+        }
+        else
+        {
+            FreePool(VolumeName.Buffer);
+        }
+
+        FreePool(SourceDeviceName.Buffer);
+
+        SourceDeviceName.Length = LinkTarget.Length;
+        SourceDeviceName.MaximumLength = LinkTarget.MaximumLength;
+        SourceDeviceName.Buffer = LinkTarget.Buffer;
+
+        /* Now that we have the correct source, reattempt to query information */
+        Status = FindDeviceInfo(DeviceExtension, &SourceDeviceName, FALSE, &DeviceInformation);
+        if (!NT_SUCCESS(Status))
+        {
+            FreePool(SourceDeviceName.Buffer);
+            FreePool(SourceSymbolicName.Buffer);
+            return Status;
+        }
+    }
+
+    FreePool(SourceDeviceName.Buffer);
+
+    /* Get information about target device */
+    Status = FindDeviceInfo(DeviceExtension, &TargetVolumeName, FALSE, &TargetDeviceInformation);
+    if (!NT_SUCCESS(Status))
+    {
+        FreePool(SourceSymbolicName.Buffer);
+        return Status;
+    }
+
+    /* Notify if not disabled */
+    if (!TargetDeviceInformation->SkipNotifications)
+    {
+        PostOnlineNotification(DeviceExtension, &TargetDeviceInformation->SymbolicName);
+    }
+
+    /* Open the remote database */
+    RemoteDatabase = OpenRemoteDatabase(DeviceInformation, TRUE);
+    if (RemoteDatabase == 0)
+    {
+        FreePool(SourceSymbolicName.Buffer);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* Browse all the entries */
+    Offset = 0;
+    Found = FALSE;
+    for (;;)
+    {
+        DatabaseEntry = GetRemoteDatabaseEntry(RemoteDatabase, Offset);
+        if (DatabaseEntry == NULL)
+        {
+            break;
+        }
+
+        /* Try to find ourselves */
+        DbName.MaximumLength = DatabaseEntry->SymbolicNameLength;
+        DbName.Length = DbName.MaximumLength;
+        DbName.Buffer = (PWSTR)((ULONG_PTR)DatabaseEntry + DatabaseEntry->SymbolicNameOffset);
+        if (RtlEqualUnicodeString(&TargetVolumeName, &DbName, TRUE))
+        {
+            ++DatabaseEntry->DatabaseOffset;
+            Status = WriteRemoteDatabaseEntry(RemoteDatabase, Offset, DatabaseEntry);
+            FreePool(DatabaseEntry);
+            Found = TRUE;
+            break;
+        }
+
+        Offset += DatabaseEntry->EntrySize;
+        FreePool(DatabaseEntry);
+    }
+
+    /* We couldn't find ourselves, we'll have to add ourselves */
+    if (!Found)
+    {
+        ULONG EntrySize;
+        PUNIQUE_ID_REPLICATE UniqueIdReplicate;
+
+        /* Query the device unique ID */
+        Status = QueryDeviceInformation(&TargetVolumeName, NULL, &UniqueId, NULL, NULL, NULL, NULL, NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            FreePool(SourceSymbolicName.Buffer);
+            CloseRemoteDatabase(RemoteDatabase);
+            return Status;
+        }
+
+        /* Allocate a database entry */
+        EntrySize = UniqueId->UniqueIdLength + TargetVolumeName.Length + sizeof(DATABASE_ENTRY);
+        DatabaseEntry = AllocatePool(EntrySize);
+        if (DatabaseEntry == NULL)
+        {
+            FreePool(UniqueId);
+            FreePool(SourceSymbolicName.Buffer);
+            CloseRemoteDatabase(RemoteDatabase);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        /* Fill it in */
+        DatabaseEntry->EntrySize = EntrySize;
+        DatabaseEntry->DatabaseOffset = 1;
+        DatabaseEntry->SymbolicNameOffset = sizeof(DATABASE_ENTRY);
+        DatabaseEntry->SymbolicNameLength = TargetVolumeName.Length;
+        DatabaseEntry->UniqueIdOffset = TargetVolumeName.Length + sizeof(DATABASE_ENTRY);
+        DatabaseEntry->UniqueIdLength = UniqueId->UniqueIdLength;
+        RtlCopyMemory((PVOID)((ULONG_PTR)DatabaseEntry + sizeof(DATABASE_ENTRY)), TargetVolumeName.Buffer, DatabaseEntry->SymbolicNameLength);
+        RtlCopyMemory((PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->UniqueIdOffset), UniqueId->UniqueId, UniqueId->UniqueIdLength);
+
+        /* And write it down */
+        Status = AddRemoteDatabaseEntry(RemoteDatabase, DatabaseEntry);
+        FreePool(DatabaseEntry);
+        if (!NT_SUCCESS(Status))
+        {
+            FreePool(UniqueId);
+            FreePool(SourceSymbolicName.Buffer);
+            CloseRemoteDatabase(RemoteDatabase);
+            return Status;
+        }
+
+        /* And now, allocate an Unique ID item */
+        UniqueIdReplicate = AllocatePool(sizeof(UNIQUE_ID_REPLICATE));
+        if (UniqueIdReplicate == NULL)
+        {
+            FreePool(UniqueId);
+            FreePool(SourceSymbolicName.Buffer);
+            CloseRemoteDatabase(RemoteDatabase);
+            return Status;
+        }
+
+        /* To associate it with the device */
+        UniqueIdReplicate->UniqueId = UniqueId;
+        InsertTailList(&DeviceInformation->ReplicatedUniqueIdsListHead, &UniqueIdReplicate->ReplicatedUniqueIdsListEntry);
+    }
+
+    /* We're done with the remote database */
+    CloseRemoteDatabase(RemoteDatabase);
+
+    /* Check we were find writing the entry */
+    if (!NT_SUCCESS(Status))
+    {
+        FreePool(SourceSymbolicName.Buffer);
+        return Status;
+    }
+
+    /* This is the end, allocate an associated entry */
+    AssociatedEntry = AllocatePool(sizeof(ASSOCIATED_DEVICE_ENTRY));
+    if (AssociatedEntry == NULL)
+    {
+        FreePool(SourceSymbolicName.Buffer);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* Initialize its source name string */
+    AssociatedEntry->String.Length = SourceSymbolicName.Length;
+    AssociatedEntry->String.MaximumLength = AssociatedEntry->String.Length + sizeof(UNICODE_NULL);
+    AssociatedEntry->String.Buffer = AllocatePool(AssociatedEntry->String.MaximumLength);
+    if (AssociatedEntry->String.Buffer == NULL)
+    {
+        FreePool(AssociatedEntry);
+        FreePool(SourceSymbolicName.Buffer);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* Copy data & insert in list */
+    RtlCopyMemory(AssociatedEntry->String.Buffer, SourceSymbolicName.Buffer, SourceSymbolicName.Length);
+    AssociatedEntry->String.Buffer[SourceSymbolicName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+    AssociatedEntry->DeviceInformation = DeviceInformation;
+    InsertTailList(&TargetDeviceInformation->AssociatedDevicesHead, &AssociatedEntry->AssociatedDevicesEntry);
+
+    /* We're done! */
+    FreePool(SourceSymbolicName.Buffer);
+    return STATUS_SUCCESS;
 }

 NTSTATUS

Modified: trunk/reactos/drivers/filters/mountmgr/mntmgr.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filters/mountmgr/mntmgr.h?rev=69221&r1=69220&r2=69221&view=diff
==============================================================================
--- trunk/reactos/drivers/filters/mountmgr/mntmgr.h     [iso-8859-1] (original)
+++ trunk/reactos/drivers/filters/mountmgr/mntmgr.h     [iso-8859-1] Sun Sep 13 22:52:07 2015
@@ -298,6 +298,36 @@
     OUT PUNICODE_STRING VolumeName
 );

+HANDLE
+OpenRemoteDatabase(
+    IN PDEVICE_INFORMATION DeviceInformation,
+    IN BOOLEAN MigrateDatabase
+);
+
+PDATABASE_ENTRY
+GetRemoteDatabaseEntry(
+    IN HANDLE Database,
+    IN LONG StartingOffset
+);
+
+NTSTATUS
+WriteRemoteDatabaseEntry(
+    IN HANDLE Database,
+    IN LONG Offset,
+    IN PDATABASE_ENTRY Entry
+);
+
+NTSTATUS
+CloseRemoteDatabase(
+    IN HANDLE Database
+);
+
+NTSTATUS
+AddRemoteDatabaseEntry(
+    IN HANDLE Database,
+    IN PDATABASE_ENTRY Entry
+);
+
 /* device.c */

 DRIVER_DISPATCH MountMgrDeviceControl;
@@ -458,4 +488,10 @@
     IN BOOLEAN MarkOffline
 );

+NTSTATUS
+MountMgrQuerySymbolicLink(
+    IN PUNICODE_STRING SymbolicName,
+    IN OUT PUNICODE_STRING LinkTarget
+);
+
 #endif /* _MNTMGR_H_ */

Modified: trunk/reactos/drivers/filters/mountmgr/mountmgr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filters/mountmgr/mountmgr.c?rev=69221&r1=69220&r2=69221&view=diff
==============================================================================
--- trunk/reactos/drivers/filters/mountmgr/mountmgr.c   [iso-8859-1] (original)
+++ trunk/reactos/drivers/filters/mountmgr/mountmgr.c   [iso-8859-1] Sun Sep 13 22:52:07 2015
@@ -48,7 +48,6 @@
  * - MountMgrQueryDosVolumePaths
  * - MountMgrQueryVolumePaths
  * - MountMgrValidateBackPointer
- * - MountMgrVolumeMountPointCreated
  * - MountMgrVolumeMountPointDeleted
  * - ReconcileThisDatabaseWithMasterWorker
  */




_______________________________________________
Ros-dev mailing list
Ros-dev@reactos.org
http://www.reactos.org/mailman/listinfo/ros-dev