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/da...
============================================================================== --- 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/de...
============================================================================== --- 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 queryinformation */
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/mn...
============================================================================== --- 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/mo...
============================================================================== --- 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