don't access pagable memory at dispatch level in NtQueryDirectoryObject

svn path=/trunk/; revision=14708
This commit is contained in:
Thomas Bluemel 2005-04-19 22:45:48 +00:00
parent 9da5e3306e
commit 6ba7e5d2cd

View file

@ -169,6 +169,7 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
KPROCESSOR_MODE PreviousMode;
ULONG SkipEntries = 0;
ULONG NextEntry = 0;
ULONG CopyBytes = 0;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
@ -318,63 +319,66 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
Status = STATUS_MORE_ENTRIES;
}
if(NT_SUCCESS(Status))
if(NT_SUCCESS(Status) && nDirectories > 0)
{
if(nDirectories > 0)
{
_SEH_TRY
{
POBJECT_DIRECTORY_INFORMATION DestDirInfo = (POBJECT_DIRECTORY_INFORMATION)Buffer;
PWSTR strbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)Buffer + nDirectories);
PWSTR strbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + nDirectories);
PWSTR deststrbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)Buffer + nDirectories);
/* copy all OBJECT_DIRECTORY_INFORMATION structures to the buffer and
just append all strings (whose pointers are stored in the buffer!)
and replace the pointers */
CopyBytes = nDirectories * 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++, DestDirInfo++)
nDirectories--, DirInfo++)
{
ULONG NameLength;
if(DirInfo->ObjectName.Length > 0)
{
DestDirInfo->ObjectName.Length = DirInfo->ObjectName.Length;
DestDirInfo->ObjectName.MaximumLength = DirInfo->ObjectName.MaximumLength;
DestDirInfo->ObjectName.Buffer = strbuf;
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[DirInfo->ObjectName.Length / sizeof(WCHAR)] = L'\0';
strbuf += (DirInfo->ObjectName.Length / sizeof(WCHAR)) + 1;
strbuf[NameLength] = L'\0';
strbuf += NameLength + 1;
deststrbuf += NameLength + 1;
CopyBytes += (NameLength + 1) * sizeof(WCHAR);
}
DestDirInfo->ObjectTypeName.Length = DirInfo->ObjectTypeName.Length;
DestDirInfo->ObjectTypeName.MaximumLength = DirInfo->ObjectTypeName.MaximumLength;
DestDirInfo->ObjectTypeName.Buffer = strbuf;
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[DirInfo->ObjectTypeName.Length / sizeof(WCHAR)] = L'\0';
strbuf += (DirInfo->ObjectTypeName.Length / sizeof(WCHAR)) + 1;
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
strbuf[NameLength] = L'\0';
strbuf += NameLength + 1;
deststrbuf += NameLength + 1;
CopyBytes += (NameLength + 1) * sizeof(WCHAR);
}
}
KeReleaseSpinLock(&Directory->Lock, OldLevel);
ObDereferenceObject(Directory);
ExFreePool(TemporaryBuffer);
if(NT_SUCCESS(Status) || ReturnSingleEntry)
{
_SEH_TRY
{
if(CopyBytes != 0)
{
RtlCopyMemory(Buffer,
TemporaryBuffer,
CopyBytes);
}
*Context = NextEntry;
if(ReturnLength != NULL)
{
@ -387,6 +391,8 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
}
_SEH_END;
}
ExFreePool(TemporaryBuffer);
}
else
{