mirror of
https://github.com/reactos/reactos.git
synced 2024-07-27 22:58:42 +00:00
[MOUNTMGR]
Implement the IOCTL IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED: - Implement MountMgrVolumeMountPointDeleteed() - Rename a struct var to reflect its real usage svn path=/trunk/; revision=69232
This commit is contained in:
parent
7e81961504
commit
8c0d5e2546
|
@ -1464,7 +1464,7 @@ ChangeRemoteDatabaseUniqueId(IN PDEVICE_INFORMATION DeviceInformation,
|
||||||
|
|
||||||
/* Recreate the entry from the previous one */
|
/* Recreate the entry from the previous one */
|
||||||
NewEntry->EntrySize = Entry->EntrySize + NewUniqueId->UniqueIdLength - OldUniqueId->UniqueIdLength;
|
NewEntry->EntrySize = Entry->EntrySize + NewUniqueId->UniqueIdLength - OldUniqueId->UniqueIdLength;
|
||||||
NewEntry->DatabaseOffset = Entry->DatabaseOffset;
|
NewEntry->EntryReferences = Entry->EntryReferences;
|
||||||
NewEntry->SymbolicNameOffset = sizeof(DATABASE_ENTRY);
|
NewEntry->SymbolicNameOffset = sizeof(DATABASE_ENTRY);
|
||||||
NewEntry->SymbolicNameLength = Entry->SymbolicNameLength;
|
NewEntry->SymbolicNameLength = Entry->SymbolicNameLength;
|
||||||
NewEntry->UniqueIdOffset = Entry->SymbolicNameLength + sizeof(DATABASE_ENTRY);
|
NewEntry->UniqueIdOffset = Entry->SymbolicNameLength + sizeof(DATABASE_ENTRY);
|
||||||
|
|
|
@ -1813,7 +1813,8 @@ MountMgrVolumeMountPointCreated(IN PDEVICE_EXTENSION DeviceExtension,
|
||||||
DbName.Buffer = (PWSTR)((ULONG_PTR)DatabaseEntry + DatabaseEntry->SymbolicNameOffset);
|
DbName.Buffer = (PWSTR)((ULONG_PTR)DatabaseEntry + DatabaseEntry->SymbolicNameOffset);
|
||||||
if (RtlEqualUnicodeString(&TargetVolumeName, &DbName, TRUE))
|
if (RtlEqualUnicodeString(&TargetVolumeName, &DbName, TRUE))
|
||||||
{
|
{
|
||||||
++DatabaseEntry->DatabaseOffset;
|
/* Reference ourselves and update the entry */
|
||||||
|
++DatabaseEntry->EntryReferences;
|
||||||
Status = WriteRemoteDatabaseEntry(RemoteDatabase, Offset, DatabaseEntry);
|
Status = WriteRemoteDatabaseEntry(RemoteDatabase, Offset, DatabaseEntry);
|
||||||
FreePool(DatabaseEntry);
|
FreePool(DatabaseEntry);
|
||||||
Found = TRUE;
|
Found = TRUE;
|
||||||
|
@ -1852,7 +1853,7 @@ MountMgrVolumeMountPointCreated(IN PDEVICE_EXTENSION DeviceExtension,
|
||||||
|
|
||||||
/* Fill it in */
|
/* Fill it in */
|
||||||
DatabaseEntry->EntrySize = EntrySize;
|
DatabaseEntry->EntrySize = EntrySize;
|
||||||
DatabaseEntry->DatabaseOffset = 1;
|
DatabaseEntry->EntryReferences = 1;
|
||||||
DatabaseEntry->SymbolicNameOffset = sizeof(DATABASE_ENTRY);
|
DatabaseEntry->SymbolicNameOffset = sizeof(DATABASE_ENTRY);
|
||||||
DatabaseEntry->SymbolicNameLength = TargetVolumeName.Length;
|
DatabaseEntry->SymbolicNameLength = TargetVolumeName.Length;
|
||||||
DatabaseEntry->UniqueIdOffset = TargetVolumeName.Length + sizeof(DATABASE_ENTRY);
|
DatabaseEntry->UniqueIdOffset = TargetVolumeName.Length + sizeof(DATABASE_ENTRY);
|
||||||
|
@ -1926,15 +1927,217 @@ MountMgrVolumeMountPointCreated(IN PDEVICE_EXTENSION DeviceExtension,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MountMgrVolumeMountPointDeleted(IN PDEVICE_EXTENSION DeviceExtension,
|
MountMgrVolumeMountPointDeleted(IN PDEVICE_EXTENSION DeviceExtension,
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN NTSTATUS LockStatus)
|
IN NTSTATUS LockStatus)
|
||||||
{
|
{
|
||||||
UNREFERENCED_PARAMETER(DeviceExtension);
|
LONG Offset;
|
||||||
UNREFERENCED_PARAMETER(Irp);
|
NTSTATUS Status;
|
||||||
UNREFERENCED_PARAMETER(LockStatus);
|
PLIST_ENTRY Entry;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
HANDLE RemoteDatabase;
|
||||||
|
PDATABASE_ENTRY DatabaseEntry;
|
||||||
|
PUNIQUE_ID_REPLICATE UniqueIdReplicate;
|
||||||
|
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 deleted, 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_SUCCESS;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open the remote database */
|
||||||
|
RemoteDatabase = OpenRemoteDatabase(DeviceInformation, TRUE);
|
||||||
|
if (RemoteDatabase == 0)
|
||||||
|
{
|
||||||
|
FreePool(SourceSymbolicName.Buffer);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Browse all the entries */
|
||||||
|
Offset = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
DatabaseEntry = GetRemoteDatabaseEntry(RemoteDatabase, Offset);
|
||||||
|
if (DatabaseEntry == NULL)
|
||||||
|
{
|
||||||
|
/* We didn't find ourselves, that's infortunate! */
|
||||||
|
FreePool(SourceSymbolicName.Buffer);
|
||||||
|
CloseRemoteDatabase(RemoteDatabase);
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Offset += DatabaseEntry->EntrySize;
|
||||||
|
FreePool(DatabaseEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dereference ourselves */
|
||||||
|
DatabaseEntry->EntryReferences--;
|
||||||
|
if (DatabaseEntry->EntryReferences == 0)
|
||||||
|
{
|
||||||
|
/* If we're still referenced, just update the entry */
|
||||||
|
Status = WriteRemoteDatabaseEntry(RemoteDatabase, Offset, DatabaseEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Otherwise, delete the entry */
|
||||||
|
Status = DeleteRemoteDatabaseEntry(RemoteDatabase, Offset);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
FreePool(DatabaseEntry);
|
||||||
|
FreePool(SourceSymbolicName.Buffer);
|
||||||
|
CloseRemoteDatabase(RemoteDatabase);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Also, delete our unique ID replicated record */
|
||||||
|
for (Entry = DeviceInformation->ReplicatedUniqueIdsListHead.Flink;
|
||||||
|
Entry != &DeviceInformation->ReplicatedUniqueIdsListHead;
|
||||||
|
Entry = Entry->Flink)
|
||||||
|
{
|
||||||
|
UniqueIdReplicate = CONTAINING_RECORD(Entry, UNIQUE_ID_REPLICATE, ReplicatedUniqueIdsListEntry);
|
||||||
|
|
||||||
|
if (UniqueIdReplicate->UniqueId->UniqueIdLength == DatabaseEntry->UniqueIdLength &&
|
||||||
|
RtlCompareMemory(UniqueIdReplicate->UniqueId->UniqueId,
|
||||||
|
(PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->UniqueIdOffset),
|
||||||
|
DatabaseEntry->UniqueIdLength) == DatabaseEntry->UniqueIdLength)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* It has to exist! */
|
||||||
|
if (Entry == &DeviceInformation->ReplicatedUniqueIdsListHead)
|
||||||
|
{
|
||||||
|
FreePool(DatabaseEntry);
|
||||||
|
FreePool(SourceSymbolicName.Buffer);
|
||||||
|
CloseRemoteDatabase(RemoteDatabase);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove it and free it */
|
||||||
|
RemoveEntryList(&UniqueIdReplicate->ReplicatedUniqueIdsListEntry);
|
||||||
|
FreePool(UniqueIdReplicate->UniqueId);
|
||||||
|
FreePool(UniqueIdReplicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're done with the remote database */
|
||||||
|
FreePool(DatabaseEntry);
|
||||||
|
CloseRemoteDatabase(RemoteDatabase);
|
||||||
|
|
||||||
|
/* Check write operation succeed */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
FreePool(SourceSymbolicName.Buffer);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to find our associated device entry */
|
||||||
|
for (Entry = TargetDeviceInformation->AssociatedDevicesHead.Flink;
|
||||||
|
Entry != &TargetDeviceInformation->AssociatedDevicesHead;
|
||||||
|
Entry = Entry->Flink)
|
||||||
|
{
|
||||||
|
AssociatedEntry = CONTAINING_RECORD(Entry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
|
||||||
|
|
||||||
|
/* If found, delete it */
|
||||||
|
if (AssociatedEntry->DeviceInformation == DeviceInformation &&
|
||||||
|
RtlEqualUnicodeString(&AssociatedEntry->String, &SourceSymbolicName, TRUE))
|
||||||
|
{
|
||||||
|
RemoveEntryList(&AssociatedEntry->AssociatedDevicesEntry);
|
||||||
|
FreePool(AssociatedEntry->String.Buffer);
|
||||||
|
FreePool(AssociatedEntry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're done! */
|
||||||
|
FreePool(SourceSymbolicName.Buffer);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -102,7 +102,7 @@ typedef struct _UNIQUE_ID_REPLICATE
|
||||||
typedef struct _DATABASE_ENTRY
|
typedef struct _DATABASE_ENTRY
|
||||||
{
|
{
|
||||||
ULONG EntrySize; // 0x00
|
ULONG EntrySize; // 0x00
|
||||||
ULONG DatabaseOffset; // 0x04
|
ULONG EntryReferences; // 0x04
|
||||||
USHORT SymbolicNameOffset; // 0x08
|
USHORT SymbolicNameOffset; // 0x08
|
||||||
USHORT SymbolicNameLength; // 0x0A
|
USHORT SymbolicNameLength; // 0x0A
|
||||||
USHORT UniqueIdOffset; // 0x0C
|
USHORT UniqueIdOffset; // 0x0C
|
||||||
|
@ -328,6 +328,12 @@ AddRemoteDatabaseEntry(
|
||||||
IN PDATABASE_ENTRY Entry
|
IN PDATABASE_ENTRY Entry
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
DeleteRemoteDatabaseEntry(
|
||||||
|
IN HANDLE Database,
|
||||||
|
IN LONG StartingOffset
|
||||||
|
);
|
||||||
|
|
||||||
/* device.c */
|
/* device.c */
|
||||||
|
|
||||||
DRIVER_DISPATCH MountMgrDeviceControl;
|
DRIVER_DISPATCH MountMgrDeviceControl;
|
||||||
|
|
|
@ -48,7 +48,6 @@ static const WCHAR Cunc[] = L"\\??\\C:";
|
||||||
* - MountMgrQueryDosVolumePaths
|
* - MountMgrQueryDosVolumePaths
|
||||||
* - MountMgrQueryVolumePaths
|
* - MountMgrQueryVolumePaths
|
||||||
* - MountMgrValidateBackPointer
|
* - MountMgrValidateBackPointer
|
||||||
* - MountMgrVolumeMountPointDeleted
|
|
||||||
* - ReconcileThisDatabaseWithMasterWorker
|
* - ReconcileThisDatabaseWithMasterWorker
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue