Author: ion Date: Mon Jul 17 07:16:15 2006 New Revision: 23112
URL: http://svn.reactos.org/svn/reactos?rev=23112&view=rev Log: - Fix definition of OBJECT_DIRECTORY_INFORMATION - Implement most of NtQueryDirectoryObject. It lacks the last step of converting the absolute buffer to a relative one. I have no idea why the old code was re-implemented in a recent commit when I clearly said I would fix this tonight.
Modified: trunk/reactos/base/applications/utils/objdir/objdir.c trunk/reactos/base/system/services/database.c trunk/reactos/base/system/services/driver.c trunk/reactos/dll/win32/kernel32/file/dosdev.c trunk/reactos/include/ndk/obtypes.h trunk/reactos/ntoskrnl/io/iomgr/disk.c trunk/reactos/ntoskrnl/ob/obdir.c trunk/reactos/subsystems/csr/csrsrv/init.c trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c
Modified: trunk/reactos/base/applications/utils/objdir/objdir.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/utils/obj... ============================================================================== --- trunk/reactos/base/applications/utils/objdir/objdir.c (original) +++ trunk/reactos/base/applications/utils/objdir/objdir.c Mon Jul 17 07:16:15 2006 @@ -257,11 +257,11 @@ CHAR TypeNameA [MAX_PATH]; CHAR TargetNameA [MAX_PATH];
- if (0 == wcscmp (L"SymbolicLink", pDirectoryEntry->ObjectTypeName.Buffer)) + if (0 == wcscmp (L"SymbolicLink", pDirectoryEntry->TypeName.Buffer)) { if (TRUE == ExpandSymbolicLink ( DirectoryNameW, - & pDirectoryEntry->ObjectName, + & pDirectoryEntry->Name, & TargetObjectName ) ) @@ -269,8 +269,8 @@
printf ( "%-16s %s -> %s\n", - RawUszAsz (pDirectoryEntry->ObjectTypeName.Buffer, TypeNameA), - RawUszAsz (pDirectoryEntry->ObjectName.Buffer, ObjectNameA), + RawUszAsz (pDirectoryEntry->TypeName.Buffer, TypeNameA), + RawUszAsz (pDirectoryEntry->Name.Buffer, ObjectNameA), RawUszAsz (TargetObjectName.Buffer, TargetNameA) ); } @@ -278,8 +278,8 @@ { printf ( "%-16s %s -> (error!)\n", - RawUszAsz (pDirectoryEntry->ObjectTypeName.Buffer, TypeNameA), - RawUszAsz (pDirectoryEntry->ObjectName.Buffer, ObjectNameA) + RawUszAsz (pDirectoryEntry->TypeName.Buffer, TypeNameA), + RawUszAsz (pDirectoryEntry->Name.Buffer, ObjectNameA) ); } } @@ -287,8 +287,8 @@ { printf ( "%-16s %s\n", - RawUszAsz (pDirectoryEntry->ObjectTypeName.Buffer, TypeNameA), - RawUszAsz (pDirectoryEntry->ObjectName.Buffer, ObjectNameA) + RawUszAsz (pDirectoryEntry->TypeName.Buffer, TypeNameA), + RawUszAsz (pDirectoryEntry->Name.Buffer, ObjectNameA) ); } ++ pDirectoryEntry; @@ -306,9 +306,9 @@ if (FALSE != Recurse) { pDirectoryEntry = (POBJECT_DIRECTORY_INFORMATION) DirectoryEntry; - while (0 != pDirectoryEntry->ObjectTypeName.Length) + while (0 != pDirectoryEntry->TypeName.Length) { - if (0 == wcscmp (L"Directory", pDirectoryEntry->ObjectTypeName.Buffer)) + if (0 == wcscmp (L"Directory", pDirectoryEntry->TypeName.Buffer)) { WCHAR CurrentName [MAX_PATH]; UNICODE_STRING CurrentDirectory; @@ -319,7 +319,7 @@ { wcscat (CurrentName, L"\"); } - wcscat (CurrentName, pDirectoryEntry->ObjectName.Buffer); + wcscat (CurrentName, pDirectoryEntry->Name.Buffer); RtlInitUnicodeString (& CurrentDirectory, CurrentName); ListDirectory (& CurrentDirectory, Recurse); }
Modified: trunk/reactos/base/system/services/database.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/databa... ============================================================================== --- trunk/reactos/base/system/services/database.c (original) +++ trunk/reactos/base/system/services/database.c Mon Jul 17 07:16:15 2006 @@ -470,12 +470,12 @@ if (!NT_SUCCESS(Status)) break;
- DPRINT("Comparing: '%S' '%wZ'\n", Service->lpServiceName, &DirInfo->ObjectName); - - if (_wcsicmp(Service->lpServiceName, DirInfo->ObjectName.Buffer) == 0) + DPRINT("Comparing: '%S' '%wZ'\n", Service->lpServiceName, &DirInfo->Name); + + if (_wcsicmp(Service->lpServiceName, DirInfo->Name.Buffer) == 0) { DPRINT("Found: '%S' '%wZ'\n", - Service->lpServiceName, &DirInfo->ObjectName); + Service->lpServiceName, &DirInfo->Name);
/* Mark service as 'running' */ Service->Status.dwCurrentState = SERVICE_RUNNING;
Modified: trunk/reactos/base/system/services/driver.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/driver... ============================================================================== --- trunk/reactos/base/system/services/driver.c (original) +++ trunk/reactos/base/system/services/driver.c Mon Jul 17 07:16:15 2006 @@ -140,12 +140,12 @@ if (!NT_SUCCESS(Status)) break;
- DPRINT("Comparing: '%S' '%wZ'\n", lpService->lpServiceName, &DirInfo->ObjectName); - - if (_wcsicmp(lpService->lpServiceName, DirInfo->ObjectName.Buffer) == 0) + DPRINT("Comparing: '%S' '%wZ'\n", lpService->lpServiceName, &DirInfo->Name); + + if (_wcsicmp(lpService->lpServiceName, DirInfo->Name.Buffer) == 0) { DPRINT1("Found: '%S' '%wZ'\n", - lpService->lpServiceName, &DirInfo->ObjectName); + lpService->lpServiceName, &DirInfo->Name); bFound = TRUE;
break;
Modified: trunk/reactos/dll/win32/kernel32/file/dosdev.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/file/dos... ============================================================================== --- trunk/reactos/dll/win32/kernel32/file/dosdev.c (original) +++ trunk/reactos/dll/win32/kernel32/file/dosdev.c Mon Jul 17 07:16:15 2006 @@ -298,11 +298,11 @@ break; }
- if (!wcscmp (DirInfo->ObjectTypeName.Buffer, L"SymbolicLink")) + if (!wcscmp (DirInfo->TypeName.Buffer, L"SymbolicLink")) { - DPRINT ("Name: '%wZ'\n", &DirInfo->ObjectName); - - NameLength = DirInfo->ObjectName.Length / sizeof(WCHAR); + DPRINT ("Name: '%wZ'\n", &DirInfo->Name); + + NameLength = DirInfo->Name.Length / sizeof(WCHAR); if (Length + NameLength + 1 >= ucchMax) { Length = 0; @@ -311,8 +311,8 @@ }
memcpy (Ptr, - DirInfo->ObjectName.Buffer, - DirInfo->ObjectName.Length); + DirInfo->Name.Buffer, + DirInfo->Name.Length); Ptr += NameLength; Length += NameLength; *Ptr = UNICODE_NULL;
Modified: trunk/reactos/include/ndk/obtypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/obtypes.h?rev=2... ============================================================================== --- trunk/reactos/include/ndk/obtypes.h (original) +++ trunk/reactos/include/ndk/obtypes.h Mon Jul 17 07:16:15 2006 @@ -261,8 +261,8 @@
typedef struct _OBJECT_DIRECTORY_INFORMATION { - UNICODE_STRING ObjectName; - UNICODE_STRING ObjectTypeName; + UNICODE_STRING Name; + UNICODE_STRING TypeName; } OBJECT_DIRECTORY_INFORMATION, *POBJECT_DIRECTORY_INFORMATION;
#ifndef NTOS_MODE_USER
Modified: trunk/reactos/ntoskrnl/io/iomgr/disk.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/disk.c?re... ============================================================================== --- trunk/reactos/ntoskrnl/io/iomgr/disk.c (original) +++ trunk/reactos/ntoskrnl/io/iomgr/disk.c Mon Jul 17 07:16:15 2006 @@ -513,12 +513,12 @@ if (NT_SUCCESS(Status)) { Count = 0; - while (DirectoryInfo[Count].ObjectName.Buffer) + while (DirectoryInfo[Count].Name.Buffer) { DPRINT("Count %x\n", Count); - DirectoryInfo[Count].ObjectName.Buffer[DirectoryInfo[Count].ObjectName.Length / sizeof(WCHAR)] = 0; - ArcNameBuffer = DirectoryInfo[Count].ObjectName.Buffer; - if (DirectoryInfo[Count].ObjectName.Length >= sizeof(L"multi(0)disk(0)rdisk(0)") - sizeof(WCHAR) && + DirectoryInfo[Count].Name.Buffer[DirectoryInfo[Count].Name.Length / sizeof(WCHAR)] = 0; + ArcNameBuffer = DirectoryInfo[Count].Name.Buffer; + if (DirectoryInfo[Count].Name.Length >= sizeof(L"multi(0)disk(0)rdisk(0)") - sizeof(WCHAR) && !_wcsnicmp(ArcNameBuffer, L"multi(0)disk(0)rdisk(", (sizeof(L"multi(0)disk(0)rdisk(") - sizeof(WCHAR)) / sizeof(WCHAR))) { DPRINT("%S\n", ArcNameBuffer);
Modified: trunk/reactos/ntoskrnl/ob/obdir.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obdir.c?rev=231... ============================================================================== --- trunk/reactos/ntoskrnl/ob/obdir.c (original) +++ trunk/reactos/ntoskrnl/ob/obdir.c Mon Jul 17 07:16:15 2006 @@ -414,6 +414,15 @@ ULONG NextEntry = 0; ULONG CopyBytes = 0; NTSTATUS Status = STATUS_SUCCESS; + PVOID LocalBuffer; + POBJECT_DIRECTORY_INFORMATION DirectoryInfo; + ULONG Length, TotalLength; + ULONG Count, CurrentEntry; + ULONG Hash; + POBJECT_DIRECTORY_ENTRY Entry; + POBJECT_HEADER ObjectHeader; + POBJECT_HEADER_NAME_INFO ObjectNameInfo; + UNICODE_STRING Name; PAGED_CODE();
/* Check if we need to do any probing */ @@ -446,6 +455,14 @@ /* This is kernel mode, save the context without probing, if needed */ SkipEntries = *Context; } + + /* Allocate a buffer */ + LocalBuffer = ExAllocatePoolWithTag(PagedPool, + sizeof(OBJECT_DIRECTORY_INFORMATION) + + BufferLength, + OB_NAME_TAG); + if (!LocalBuffer) return STATUS_INSUFFICIENT_RESOURCES; + RtlZeroMemory(LocalBuffer, BufferLength);
/* Get a reference to directory */ Status = ObReferenceObjectByHandle(DirectoryHandle, @@ -454,199 +471,125 @@ PreviousMode, (PVOID*)&Directory, NULL); - if (NT_SUCCESS(Status)) - { - PVOID TemporaryBuffer = ExAllocatePool(NonPagedPool, - BufferLength); - if(TemporaryBuffer != NULL) - { - POBJECT_HEADER EntryHeader; - ULONG RequiredSize = sizeof(OBJECT_DIRECTORY_INFORMATION); - ULONG nDirectories = 0; - POBJECT_DIRECTORY_INFORMATION DirInfo = (POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer; - POBJECT_DIRECTORY_ENTRY DirectoryEntry; - ULONG i; - BOOLEAN StopIt = FALSE; - - Status = STATUS_NO_MORE_ENTRIES; - - KeEnterCriticalRegion(); - ExAcquireResourceSharedLite(&Directory->Lock, TRUE); - - for (i = 0; i < NUMBER_HASH_BUCKETS && !StopIt; i++) + if (!NT_SUCCESS(Status)) + { + /* Free the buffer and fail */ + ExFreePool(LocalBuffer); + return Status; + } + + /* Start at position 0 */ + DirectoryInfo = (POBJECT_DIRECTORY_INFORMATION)LocalBuffer; + TotalLength = sizeof(OBJECT_DIRECTORY_INFORMATION); + + /* Start with 0 entries */ + Count = 0; + CurrentEntry = 0; + + /* Set default status and start looping */ + Status = STATUS_NO_MORE_ENTRIES; + for (Hash = 0; Hash < 37; Hash++) + { + /* Get this entry and loop all of them */ + Entry = Directory->HashBuckets[Hash]; + while (Entry) + { + /* Check if we should process this entry */ + if (SkipEntries == CurrentEntry++) { - DirectoryEntry = Directory->HashBuckets[i]; - while (DirectoryEntry) + /* Get the header data */ + ObjectHeader = OBJECT_TO_OBJECT_HEADER(Entry->Object); + ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader); + + /* Get the object name */ + if (ObjectNameInfo) { - NextEntry++; - if (SkipEntries == 0) + /* Use the one we have */ + Name = ObjectNameInfo->Name; + } + else + { + /* Otherwise, use an empty one */ + RtlInitEmptyUnicodeString(&Name, NULL, 0); + } + + /* Calculate the length for this entry */ + Length = sizeof(OBJECT_DIRECTORY_INFORMATION) + + Name.Length + sizeof(UNICODE_NULL) + + ObjectHeader->Type->Name.Length + sizeof(UNICODE_NULL); + + /* Make sure this entry won't overflow */ + if ((TotalLength + Length) > BufferLength) + { + /* Check if the caller wanted only an entry */ + if (ReturnSingleEntry) { - PUNICODE_STRING Name, Type; - ULONG EntrySize; - - EntryHeader = OBJECT_TO_OBJECT_HEADER(DirectoryEntry->Object); - - /* Calculate the size of the required buffer space for this entry */ - Name = (OBJECT_HEADER_TO_NAME_INFO(EntryHeader)->Name.Length != 0 ? &OBJECT_HEADER_TO_NAME_INFO(EntryHeader)->Name : NULL); - Type = &EntryHeader->Type->Name; - EntrySize = sizeof(OBJECT_DIRECTORY_INFORMATION) + - ((Name != NULL) ? ((ULONG)Name->Length + sizeof(WCHAR)) : 0) + - (ULONG)EntryHeader->Type->Name.Length + sizeof(WCHAR); - - if (RequiredSize + EntrySize <= BufferLength) - { - /* The buffer is large enough to receive this entry. It would've - been much easier if the strings were directly appended to the - OBJECT_DIRECTORY_INFORMATION structured written into the buffer */ - if (Name != NULL && Name->Length > 0) - DirInfo->ObjectName = *Name; - else - { - DirInfo->ObjectName.Length = DirInfo->ObjectName.MaximumLength = 0; - DirInfo->ObjectName.Buffer = NULL; - } - DirInfo->ObjectTypeName = *Type; - - nDirectories++; - RequiredSize += EntrySize; - - Status = STATUS_SUCCESS; - - if (ReturnSingleEntry) - { - /* We're only supposed to query one entry, so bail and copy the - strings to the buffer */ - StopIt = TRUE; - break; - } - DirInfo++; - } - else - { - if (ReturnSingleEntry) - { - /* The buffer is too small, so return the number of bytes that - would've been required for this query */ - RequiredSize += EntrySize; - Status = STATUS_BUFFER_TOO_SMALL; - } - - /* We couldn't query this entry, so leave the index that will be stored - in Context to this entry so the caller can query it the next time - he queries (hopefully with a buffer that is large enough then...) */ - NextEntry--; - - /* Just copy the entries that fit into the buffer */ - StopIt = TRUE; - break; - } + /* Then we'll fail and ask for more buffer */ + TotalLength += Length; + Status = STATUS_BUFFER_TOO_SMALL; } else { - /* Skip the entry */ - SkipEntries--; + /* Otherwise, we'll say we're done for now */ + Status = STATUS_MORE_ENTRIES; } - DirectoryEntry = DirectoryEntry->ChainLink; + + /* Decrease the entry since we didn't process */ + CurrentEntry--; + goto Quickie; } + + /* Now fill in the buffer */ + DirectoryInfo->Name.Length = Name.Length; + DirectoryInfo->Name.MaximumLength = Name.Length + + sizeof(UNICODE_NULL); + DirectoryInfo->Name.Buffer = Name.Buffer; + DirectoryInfo->TypeName.Length = ObjectHeader-> + Type->Name.Length; + DirectoryInfo->TypeName.MaximumLength = ObjectHeader-> + Type->Name.Length + + sizeof(UNICODE_NULL); + DirectoryInfo->TypeName.Buffer = ObjectHeader-> + Type->Name.Buffer; + + /* Increase statistics */ + TotalLength += Length; + DirectoryInfo++; + Count++; + + /* If the caller only wanted an entry, bail out */ + if (ReturnSingleEntry) goto Quickie; + + /* Increase the key by one */ + SkipEntries++; } - - if (!ReturnSingleEntry) - { - /* Check if there are more entries to enumerate but the buffer is already - full. Only tell this to the user if he queries multiple entries */ - if (DirectoryEntry) - Status = STATUS_MORE_ENTRIES; - else - for (; i < NUMBER_HASH_BUCKETS; i++) - if (Directory->HashBuckets[i]) - { - Status = STATUS_MORE_ENTRIES; - break; - } - } - - if (NT_SUCCESS(Status) && nDirectories > 0) - { - PWSTR strbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + nDirectories + 1); - PWSTR deststrbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)Buffer + nDirectories + 1); - memset((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + nDirectories, 0, sizeof(OBJECT_DIRECTORY_INFORMATION)); - - CopyBytes = (nDirectories + 1) * sizeof(OBJECT_DIRECTORY_INFORMATION); - - /* Copy the names from the objects and append them to the list of the - objects. copy to the temporary buffer only because the directory - lock can't be released and the buffer might be pagable memory! */ - for (DirInfo = (POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer; - nDirectories > 0; - nDirectories--, DirInfo++) - { - ULONG NameLength; - - if (DirInfo->ObjectName.Length > 0) - { - RtlCopyMemory(strbuf, - DirInfo->ObjectName.Buffer, - DirInfo->ObjectName.Length); - /* Change the buffer pointer to the buffer */ - DirInfo->ObjectName.Buffer = deststrbuf; - NameLength = DirInfo->ObjectName.Length / sizeof(WCHAR); - /* NULL-terminate the string */ - strbuf[NameLength] = L'\0'; - strbuf += NameLength + 1; - deststrbuf += NameLength + 1; - - CopyBytes += (NameLength + 1) * sizeof(WCHAR); - } - - RtlCopyMemory(strbuf, - DirInfo->ObjectTypeName.Buffer, - DirInfo->ObjectTypeName.Length); - /* Change the buffer pointer to the buffer */ - DirInfo->ObjectTypeName.Buffer = deststrbuf; - NameLength = DirInfo->ObjectTypeName.Length / sizeof(WCHAR); - /* NULL-terminate the string */ - strbuf[NameLength] = L'\0'; - strbuf += NameLength + 1; - deststrbuf += NameLength + 1; - - CopyBytes += (NameLength + 1) * sizeof(WCHAR); - } - } - - ExReleaseResourceLite(&Directory->Lock); - KeLeaveCriticalRegion(); - ObDereferenceObject(Directory); - - if (NT_SUCCESS(Status) || ReturnSingleEntry) - { - _SEH_TRY - { - if (CopyBytes != 0) - { - RtlCopyMemory(Buffer, - TemporaryBuffer, - CopyBytes); - } - *Context = NextEntry; - if(ReturnLength != NULL) - { - *ReturnLength = RequiredSize; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - } - - ExFreePool(TemporaryBuffer); - } - else - { - Status = STATUS_INSUFFICIENT_RESOURCES; - } - } + } + + /* Move to the next directory */ + Entry = Entry->ChainLink; + } + +Quickie: + /* Make sure we got success */ + if (NT_SUCCESS(Status)) + { + /* We need to parse all the entries and convert absolute to relative */ + DPRINT1("NOT FULLY IMPLEMENTED\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + + /* Copy the buffer */ + RtlMoveMemory(Buffer, + LocalBuffer, + (TotalLength <= BufferLength) ? + TotalLength : BufferLength); + + /* Check if the caller requested the return length and return it*/ + if (ReturnLength) *ReturnLength = TotalLength; + } + + /* Dereference the directory and free our buffer */ + ObDereferenceObject(Directory); + ExFreePool(LocalBuffer);
/* Return status to caller */ return Status;
Modified: trunk/reactos/subsystems/csr/csrsrv/init.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/csr/csrsrv/init.... ============================================================================== --- trunk/reactos/subsystems/csr/csrsrv/init.c (original) +++ trunk/reactos/subsystems/csr/csrsrv/init.c Mon Jul 17 07:16:15 2006 @@ -94,14 +94,14 @@ if (NT_SUCCESS(Status)) { /* Make sure it has a name */ - if (!QueryBuffer->ObjectName.Buffer[0]) continue; + if (!QueryBuffer->Name.Buffer[0]) continue;
/* Check if it's actually a symbolic link */ - if (wcscmp(QueryBuffer->ObjectTypeName.Buffer, SYMLINK_NAME)) + if (wcscmp(QueryBuffer->TypeName.Buffer, SYMLINK_NAME)) { /* It is, open it */ InitializeObjectAttributes(&ObjectAttributes, - &QueryBuffer->ObjectName, + &QueryBuffer->Name, OBJ_CASE_INSENSITIVE, NULL, hDirectory);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c Mon Jul 17 07:16:15 2006 @@ -1235,10 +1235,10 @@ */ ReturnLength = sizeof(DWORD); EntryCount = 0; - for (DirEntry = (POBJECT_DIRECTORY_INFORMATION) Buffer; 0 != DirEntry->ObjectName.Length; + for (DirEntry = (POBJECT_DIRECTORY_INFORMATION) Buffer; 0 != DirEntry->Name.Length; DirEntry++) { - ReturnLength += DirEntry->ObjectName.Length + sizeof(WCHAR); + ReturnLength += DirEntry->Name.Length + sizeof(WCHAR); EntryCount++; } DPRINT("Required size: %d Entry count: %d\n", ReturnLength, EntryCount); @@ -1282,10 +1282,10 @@ lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
NullWchar = L'\0'; - for (DirEntry = (POBJECT_DIRECTORY_INFORMATION) Buffer; 0 != DirEntry->ObjectName.Length; + for (DirEntry = (POBJECT_DIRECTORY_INFORMATION) Buffer; 0 != DirEntry->Name.Length; DirEntry++) { - Status = MmCopyToCaller(lpBuffer, DirEntry->ObjectName.Buffer, DirEntry->ObjectName.Length); + Status = MmCopyToCaller(lpBuffer, DirEntry->Name.Buffer, DirEntry->Name.Length); if (! NT_SUCCESS(Status)) { if (Buffer != InitialBuffer) @@ -1294,7 +1294,7 @@ } return Status; } - lpBuffer = (PVOID) ((PCHAR) lpBuffer + DirEntry->ObjectName.Length); + lpBuffer = (PVOID) ((PCHAR) lpBuffer + DirEntry->Name.Length); Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR)); if (! NT_SUCCESS(Status)) {