[RTL] Partially implement RtlCreateQueryDebugBuffer and RtlDestroyQueryDebugBuffer

This commit is contained in:
Mark Jansen 2020-04-16 19:59:53 +02:00
parent 808aea9b72
commit f26b670b38
No known key found for this signature in database
GPG key ID: B39240EE84BEAE8B
2 changed files with 88 additions and 29 deletions

View file

@ -1,8 +1,9 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries
* PROJECT: ReactOS system libraries * LICENSE: GPL-2.0 (https://spdx.org/licenses/GPL-2.0)
* FILE: lib/rtl/dbgbuffer.c * PURPOSE: RTL_DEBUG_INFORMATION implementation
* PROGRAMER: James Tabor * COPYRIGHT: Copyright James Tabor
* Copyright 2020 Mark Jansen (mark.jansen@reactos.org)
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
@ -14,30 +15,80 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
PVOID
NTAPI
RtlpDebugBufferCommit(_Inout_ PRTL_DEBUG_INFORMATION Buffer,
_In_ SIZE_T Size)
{
ULONG Remaining = Buffer->CommitSize - Buffer->OffsetFree;
PVOID Result;
NTSTATUS Status;
if (Size > MAXLONG)
return NULL;
if (Remaining < Size)
{
PVOID Buf;
SIZE_T CommitSize;
Buf = (PVOID)((ULONG_PTR)Buffer->ViewBaseClient + Buffer->CommitSize);
CommitSize = Size - Remaining;
/* this is not going to end well.. */
if (CommitSize > MAXLONG)
return NULL;
Status = NtAllocateVirtualMemory(NtCurrentProcess(), (PVOID*)&Buf, 0, &CommitSize, MEM_COMMIT, PAGE_READWRITE);
if (!NT_SUCCESS(Status))
return NULL;
Buffer->CommitSize += CommitSize;
Remaining = Buffer->CommitSize - Buffer->OffsetFree;
/* Sanity check */
ASSERT(Remaining >= Size);
if (Remaining < Size)
return NULL;
}
Result = (PBYTE)Buffer->ViewBaseClient + Buffer->OffsetFree;
Buffer->OffsetFree += Size;
return Result;
}
/* /*
* @unimplemented * @unimplemented
*/ */
PRTL_DEBUG_INFORMATION PRTL_DEBUG_INFORMATION
NTAPI NTAPI
RtlCreateQueryDebugBuffer(IN ULONG Size, RtlCreateQueryDebugBuffer(_In_ ULONG Size,
IN BOOLEAN EventPair) _In_ BOOLEAN EventPair)
{ {
NTSTATUS Status; NTSTATUS Status;
PRTL_DEBUG_INFORMATION Buf = NULL; PRTL_DEBUG_INFORMATION Buf = NULL;
SIZE_T ViewSize = 100 * PAGE_SIZE; SIZE_T AllocationSize = Size ? Size : 0x400 * PAGE_SIZE;
SIZE_T CommitSize = sizeof(*Buf);
Status = NtAllocateVirtualMemory(NtCurrentProcess(), /* Reserve the memory */
(PVOID*)&Buf, Status = NtAllocateVirtualMemory(NtCurrentProcess(), (PVOID*)&Buf, 0, &AllocationSize, MEM_RESERVE, PAGE_READWRITE);
0, if (!NT_SUCCESS(Status))
&ViewSize, return NULL;
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status)) return NULL;
/* Commit the first data, CommitSize is updated with the actual committed data */
Status = NtAllocateVirtualMemory(NtCurrentProcess(), (PVOID*)&Buf, 0, &CommitSize, MEM_COMMIT, PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
RtlDestroyQueryDebugBuffer(Buf);
return NULL;
}
/* Fill out the minimum data required */
Buf->ViewBaseClient = Buf; Buf->ViewBaseClient = Buf;
Buf->ViewSize = (ULONG)ViewSize; Buf->ViewSize = (ULONG)AllocationSize;
Buf->CommitSize = CommitSize;
DPRINT("RtlCQDB: BA: %p BS: 0x%lx\n", Buf->ViewBaseClient, Buf->ViewSize); Buf->OffsetFree = sizeof(*Buf);
return Buf; return Buf;
} }
@ -47,7 +98,7 @@ RtlCreateQueryDebugBuffer(IN ULONG Size,
*/ */
NTSTATUS NTSTATUS
NTAPI NTAPI
RtlDestroyQueryDebugBuffer(IN PRTL_DEBUG_INFORMATION Buf) RtlDestroyQueryDebugBuffer(_In_ PRTL_DEBUG_INFORMATION Buf)
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
SIZE_T ViewSize = 0; SIZE_T ViewSize = 0;
@ -265,25 +316,27 @@ RtlQueryProcessDebugInformation(IN ULONG ProcessId,
{ {
PRTL_PROCESS_MODULES Mp; PRTL_PROCESS_MODULES Mp;
ULONG ReturnSize = 0; ULONG ReturnSize = 0;
ULONG MSize;
Mp = (PRTL_PROCESS_MODULES)((PUCHAR)Buf + Buf->OffsetFree);
/* I like this better than the do & while loop. */ /* I like this better than the do & while loop. */
Status = LdrQueryProcessModuleInformation(NULL, Status = LdrQueryProcessModuleInformation(NULL,
0, 0,
&ReturnSize); &ReturnSize);
Mp = RtlpDebugBufferCommit(Buf, ReturnSize);
if (!Mp)
{
DPRINT1("RtlQueryProcessDebugInformation: Unable to commit %u\n", ReturnSize);
}
Status = LdrQueryProcessModuleInformation(Mp, Status = LdrQueryProcessModuleInformation(Mp,
ReturnSize , ReturnSize,
&ReturnSize); &ReturnSize);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return Status; return Status;
} }
MSize = Mp->NumberOfModules * (sizeof(RTL_PROCESS_MODULES) + 8);
Buf->Modules = Mp; Buf->Modules = Mp;
Buf->OffsetFree = Buf->OffsetFree + MSize;
} }
if (DebugInfoMask & RTL_DEBUG_QUERY_HEAPS) if (DebugInfoMask & RTL_DEBUG_QUERY_HEAPS)
@ -349,15 +402,18 @@ RtlQueryProcessDebugInformation(IN ULONG ProcessId,
{ {
PRTL_PROCESS_MODULES Mp; PRTL_PROCESS_MODULES Mp;
ULONG ReturnSize = 0; ULONG ReturnSize = 0;
ULONG MSize;
Mp = (PRTL_PROCESS_MODULES)((PUCHAR)Buf + Buf->OffsetFree);
Status = RtlpQueryRemoteProcessModules(hProcess, Status = RtlpQueryRemoteProcessModules(hProcess,
NULL, NULL,
0, 0,
&ReturnSize); &ReturnSize);
Mp = RtlpDebugBufferCommit(Buf, ReturnSize);
if (!Mp)
{
DPRINT1("RtlQueryProcessDebugInformation: Unable to commit %u\n", ReturnSize);
}
Status = RtlpQueryRemoteProcessModules(hProcess, Status = RtlpQueryRemoteProcessModules(hProcess,
Mp, Mp,
ReturnSize , ReturnSize ,
@ -367,9 +423,7 @@ RtlQueryProcessDebugInformation(IN ULONG ProcessId,
return Status; return Status;
} }
MSize = Mp->NumberOfModules * (sizeof(RTL_PROCESS_MODULES) + 8);
Buf->Modules = Mp; Buf->Modules = Mp;
Buf->OffsetFree = Buf->OffsetFree + MSize;
} }
if (DebugInfoMask & RTL_DEBUG_QUERY_HEAPS) if (DebugInfoMask & RTL_DEBUG_QUERY_HEAPS)

View file

@ -248,5 +248,10 @@ VOID
NTAPI NTAPI
LdrpInitializeProcessCompat(PVOID pProcessActctx, PVOID* pOldShimData); LdrpInitializeProcessCompat(PVOID pProcessActctx, PVOID* pOldShimData);
PVOID
NTAPI
RtlpDebugBufferCommit(_Inout_ PRTL_DEBUG_INFORMATION Buffer,
_In_ SIZE_T Size);
/* EOF */ /* EOF */