mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
don't access pagable memory at dispatch level in NtQueryDirectoryObject
svn path=/trunk/; revision=14708
This commit is contained in:
parent
9da5e3306e
commit
6ba7e5d2cd
1 changed files with 48 additions and 42 deletions
|
@ -169,6 +169,7 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
ULONG SkipEntries = 0;
|
ULONG SkipEntries = 0;
|
||||||
ULONG NextEntry = 0;
|
ULONG NextEntry = 0;
|
||||||
|
ULONG CopyBytes = 0;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
@ -318,63 +319,66 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
|
||||||
Status = STATUS_MORE_ENTRIES;
|
Status = STATUS_MORE_ENTRIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status) && nDirectories > 0)
|
||||||
{
|
{
|
||||||
if(nDirectories > 0)
|
PWSTR strbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + nDirectories);
|
||||||
{
|
PWSTR deststrbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)Buffer + nDirectories);
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
POBJECT_DIRECTORY_INFORMATION DestDirInfo = (POBJECT_DIRECTORY_INFORMATION)Buffer;
|
|
||||||
PWSTR strbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)Buffer + nDirectories);
|
|
||||||
|
|
||||||
/* copy all OBJECT_DIRECTORY_INFORMATION structures to the buffer and
|
CopyBytes = nDirectories * sizeof(OBJECT_DIRECTORY_INFORMATION);
|
||||||
just append all strings (whose pointers are stored in the buffer!)
|
|
||||||
and replace the pointers */
|
/* 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;
|
for(DirInfo = (POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer;
|
||||||
nDirectories > 0;
|
nDirectories > 0;
|
||||||
nDirectories--, DirInfo++, DestDirInfo++)
|
nDirectories--, DirInfo++)
|
||||||
{
|
{
|
||||||
|
ULONG NameLength;
|
||||||
|
|
||||||
if(DirInfo->ObjectName.Length > 0)
|
if(DirInfo->ObjectName.Length > 0)
|
||||||
{
|
{
|
||||||
DestDirInfo->ObjectName.Length = DirInfo->ObjectName.Length;
|
|
||||||
DestDirInfo->ObjectName.MaximumLength = DirInfo->ObjectName.MaximumLength;
|
|
||||||
DestDirInfo->ObjectName.Buffer = strbuf;
|
|
||||||
RtlCopyMemory(strbuf,
|
RtlCopyMemory(strbuf,
|
||||||
DirInfo->ObjectName.Buffer,
|
DirInfo->ObjectName.Buffer,
|
||||||
DirInfo->ObjectName.Length);
|
DirInfo->ObjectName.Length);
|
||||||
|
/* change the buffer pointer to the buffer */
|
||||||
|
DirInfo->ObjectName.Buffer = deststrbuf;
|
||||||
|
NameLength = DirInfo->ObjectName.Length / sizeof(WCHAR);
|
||||||
/* NULL-terminate the string */
|
/* NULL-terminate the string */
|
||||||
strbuf[DirInfo->ObjectName.Length / sizeof(WCHAR)] = L'\0';
|
strbuf[NameLength] = L'\0';
|
||||||
strbuf += (DirInfo->ObjectName.Length / sizeof(WCHAR)) + 1;
|
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,
|
RtlCopyMemory(strbuf,
|
||||||
DirInfo->ObjectTypeName.Buffer,
|
DirInfo->ObjectTypeName.Buffer,
|
||||||
DirInfo->ObjectTypeName.Length);
|
DirInfo->ObjectTypeName.Length);
|
||||||
|
/* change the buffer pointer to the buffer */
|
||||||
|
DirInfo->ObjectTypeName.Buffer = deststrbuf;
|
||||||
|
NameLength = DirInfo->ObjectTypeName.Length / sizeof(WCHAR);
|
||||||
/* NULL-terminate the string */
|
/* NULL-terminate the string */
|
||||||
strbuf[DirInfo->ObjectTypeName.Length / sizeof(WCHAR)] = L'\0';
|
strbuf[NameLength] = L'\0';
|
||||||
strbuf += (DirInfo->ObjectTypeName.Length / sizeof(WCHAR)) + 1;
|
strbuf += NameLength + 1;
|
||||||
}
|
deststrbuf += NameLength + 1;
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
CopyBytes += (NameLength + 1) * sizeof(WCHAR);
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeReleaseSpinLock(&Directory->Lock, OldLevel);
|
KeReleaseSpinLock(&Directory->Lock, OldLevel);
|
||||||
ObDereferenceObject(Directory);
|
ObDereferenceObject(Directory);
|
||||||
|
|
||||||
ExFreePool(TemporaryBuffer);
|
|
||||||
|
|
||||||
if(NT_SUCCESS(Status) || ReturnSingleEntry)
|
if(NT_SUCCESS(Status) || ReturnSingleEntry)
|
||||||
{
|
{
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
|
if(CopyBytes != 0)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(Buffer,
|
||||||
|
TemporaryBuffer,
|
||||||
|
CopyBytes);
|
||||||
|
}
|
||||||
*Context = NextEntry;
|
*Context = NextEntry;
|
||||||
if(ReturnLength != NULL)
|
if(ReturnLength != NULL)
|
||||||
{
|
{
|
||||||
|
@ -387,6 +391,8 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
|
||||||
}
|
}
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExFreePool(TemporaryBuffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue