https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8c6c5a92e86ecd69d0fd5662645a1696706eb56a
commit 8c6c5a92e86ecd69d0fd5662645a1696706eb56a Author: Pierre Schweitzer <pie...@reactos.org> AuthorDate: Wed Oct 3 13:56:18 2018 +0200 Commit: Pierre Schweitzer <pie...@reactos.org> CommitDate: Wed Oct 3 13:56:18 2018 +0200 [NTOSKRNL] Implement DOS name query in IopQueryNameInternal() --- ntoskrnl/io/iomgr/file.c | 88 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 12 deletions(-) diff --git a/ntoskrnl/io/iomgr/file.c b/ntoskrnl/io/iomgr/file.c index 1112686225..df4e37638e 100644 --- a/ntoskrnl/io/iomgr/file.c +++ b/ntoskrnl/io/iomgr/file.c @@ -1902,6 +1902,9 @@ IopQueryNameInternal(IN PVOID ObjectBody, BOOLEAN LengthMismatch = FALSE; NTSTATUS Status; PWCHAR p; + PDEVICE_OBJECT DeviceObject; + BOOLEAN NoObCall; + IOTRACE(IO_FILE_DEBUG, "ObjectBody: %p\n", ObjectBody); /* Validate length */ @@ -1912,17 +1915,56 @@ IopQueryNameInternal(IN PVOID ObjectBody, return STATUS_INFO_LENGTH_MISMATCH; } - if (QueryDosName) return STATUS_NOT_IMPLEMENTED; - /* Allocate Buffer */ LocalInfo = ExAllocatePoolWithTag(PagedPool, Length, TAG_IO); if (!LocalInfo) return STATUS_INSUFFICIENT_RESOURCES; - /* Query the name */ - Status = ObQueryNameString(FileObject->DeviceObject, - LocalInfo, - Length, - &LocalReturnLength); + /* Query DOS name if the caller asked to */ + NoObCall = FALSE; + if (QueryDosName) + { + DeviceObject = FileObject->DeviceObject; + + /* In case of a network file system, don't call mountmgr */ + if (DeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) + { + /* We'll store separator and terminator */ + LocalReturnLength = sizeof(OBJECT_NAME_INFORMATION) + 2 * sizeof(WCHAR); + if (Length < LocalReturnLength) + { + Status = STATUS_BUFFER_OVERFLOW; + } + else + { + LocalInfo->Name.Length = sizeof(WCHAR); + LocalInfo->Name.MaximumLength = sizeof(WCHAR); + LocalInfo->Name.Buffer = (PVOID)((ULONG_PTR)LocalInfo + sizeof(OBJECT_NAME_INFORMATION)); + LocalInfo->Name.Buffer[0] = OBJ_NAME_PATH_SEPARATOR; + Status = STATUS_SUCCESS; + } + } + /* Otherwise, call mountmgr to get DOS name */ + else + { + Status = IoVolumeDeviceToDosName(DeviceObject, &LocalInfo->Name); + LocalReturnLength = LocalInfo->Name.Length + sizeof(OBJECT_NAME_INFORMATION) + sizeof(WCHAR); + } + } + + /* Fall back if querying DOS name failed or if caller never wanted it ;-) */ + if (!QueryDosName || !NT_SUCCESS(Status)) + { + /* Query the name */ + Status = ObQueryNameString(FileObject->DeviceObject, + LocalInfo, + Length, + &LocalReturnLength); + } + else + { + NoObCall = TRUE; + } + if (!NT_SUCCESS(Status) && (Status != STATUS_INFO_LENGTH_MISMATCH)) { /* Free the buffer and fail */ @@ -1930,14 +1972,36 @@ IopQueryNameInternal(IN PVOID ObjectBody, return Status; } + /* Get buffer pointer */ + p = (PWCHAR)(ObjectNameInfo + 1); + /* Copy the information */ - RtlCopyMemory(ObjectNameInfo, - LocalInfo, - (LocalReturnLength > Length) ? - Length : LocalReturnLength); + if (QueryDosName && NoObCall) + { + ASSERT(PreviousMode == KernelMode); + + /* Copy structure first */ + RtlCopyMemory(ObjectNameInfo, + LocalInfo, + (Length >= LocalReturnLength ? sizeof(OBJECT_NAME_INFORMATION) : Length)); + /* Name then */ + RtlCopyMemory(p, LocalInfo->Name.Buffer, + (Length >= LocalReturnLength ? LocalInfo->Name.Length : Length - sizeof(OBJECT_NAME_INFORMATION))); + + if (FileObject->DeviceObject->DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM) + { + ExFreePool(LocalInfo->Name.Buffer); + } + } + else + { + RtlCopyMemory(ObjectNameInfo, + LocalInfo, + (LocalReturnLength > Length) ? + Length : LocalReturnLength); + } /* Set buffer pointer */ - p = (PWCHAR)(ObjectNameInfo + 1); ObjectNameInfo->Name.Buffer = p; /* Advance in buffer */