1 /* COPYRIGHT: See COPYING in the top level directory
2 * PROJECT: ReactOS system libraries
3 * FILE: lib/rtl/dbgbuffer.c
4 * PROGRAMER: James Tabor
7 /* INCLUDES *****************************************************************/
14 /* FUNCTIONS *****************************************************************/
19 PRTL_DEBUG_INFORMATION NTAPI
20 RtlCreateQueryDebugBuffer(IN ULONG Size
,
24 PRTL_DEBUG_INFORMATION Buf
= NULL
;
25 SIZE_T ViewSize
= 100 * PAGE_SIZE
;
27 Status
= NtAllocateVirtualMemory( NtCurrentProcess(),
33 if (!NT_SUCCESS(Status
))
38 Buf
->ViewBaseClient
= Buf
;
39 Buf
->ViewSize
= ViewSize
;
41 DPRINT("RtlCQDB: BA: %p BS: 0x%lx\n", Buf
->ViewBaseClient
, Buf
->ViewSize
);
50 RtlDestroyQueryDebugBuffer(IN PRTL_DEBUG_INFORMATION Buf
)
52 NTSTATUS Status
= STATUS_SUCCESS
;
56 Status
= NtFreeVirtualMemory( NtCurrentProcess(),
58 (PSIZE_T
)&Buf
->ViewSize
, /* FIXME: not portable! */
61 if (!NT_SUCCESS(Status
))
63 DPRINT1("RtlDQDB: Failed to free VM!\n");
69 * Based on lib/epsapi/enum/modules.c by KJK::Hyperion.
73 RtlpQueryRemoteProcessModules(HANDLE ProcessHandle
,
74 IN PRTL_PROCESS_MODULES Modules OPTIONAL
,
75 IN ULONG Size OPTIONAL
,
76 OUT PULONG ReturnedSize
)
78 PROCESS_BASIC_INFORMATION pbiInfo
;
79 PPEB_LDR_DATA ppldLdrData
;
80 LDR_DATA_TABLE_ENTRY lmModule
;
81 PLIST_ENTRY pleListHead
;
82 PLIST_ENTRY pleCurEntry
;
84 PRTL_PROCESS_MODULE_INFORMATION ModulePtr
= NULL
;
85 NTSTATUS Status
= STATUS_SUCCESS
;
86 ULONG UsedSize
= sizeof(ULONG
);
87 ANSI_STRING AnsiString
;
90 DPRINT("RtlpQueryRemoteProcessModules Start\n");
92 /* query the process basic information (includes the PEB address) */
93 Status
= NtQueryInformationProcess ( ProcessHandle
,
94 ProcessBasicInformation
,
96 sizeof(PROCESS_BASIC_INFORMATION
),
99 if (!NT_SUCCESS(Status
))
102 DPRINT("NtQueryInformationProcess 1 0x%lx \n", Status
);
106 if (Modules
== NULL
|| Size
== 0)
108 Status
= STATUS_INFO_LENGTH_MISMATCH
;
112 Modules
->NumberOfModules
= 0;
113 ModulePtr
= &Modules
->Modules
[0];
114 Status
= STATUS_SUCCESS
;
117 /* get the address of the PE Loader data */
118 Status
= NtReadVirtualMemory ( ProcessHandle
,
119 &(pbiInfo
.PebBaseAddress
->Ldr
),
124 if (!NT_SUCCESS(Status
))
127 DPRINT("NtReadVirtualMemory 1 0x%lx \n", Status
);
132 /* head of the module list: the last element in the list will point to this */
133 pleListHead
= &ppldLdrData
->InLoadOrderModuleList
;
135 /* get the address of the first element in the list */
136 Status
= NtReadVirtualMemory ( ProcessHandle
,
137 &(ppldLdrData
->InLoadOrderModuleList
.Flink
),
142 if (!NT_SUCCESS(Status
))
145 DPRINT("NtReadVirtualMemory 2 0x%lx \n", Status
);
149 while(pleCurEntry
!= pleListHead
)
152 UNICODE_STRING Unicode
;
153 WCHAR Buffer
[256 * sizeof(WCHAR
)];
155 /* read the current module */
156 Status
= NtReadVirtualMemory ( ProcessHandle
,
157 CONTAINING_RECORD(pleCurEntry
, LDR_DATA_TABLE_ENTRY
, InLoadOrderLinks
),
159 sizeof(LDR_DATA_TABLE_ENTRY
),
162 /* Import module name from remote Process user space. */
163 Unicode
.Length
= lmModule
.FullDllName
.Length
;
164 Unicode
.MaximumLength
= lmModule
.FullDllName
.MaximumLength
;
165 Unicode
.Buffer
= Buffer
;
167 Status
= NtReadVirtualMemory ( ProcessHandle
,
168 lmModule
.FullDllName
.Buffer
,
173 if (!NT_SUCCESS(Status
))
176 DPRINT( "NtReadVirtualMemory 3 0x%lx \n", Status
);
180 DPRINT(" Module %wZ\n", &Unicode
);
184 Status
= STATUS_INFO_LENGTH_MISMATCH
;
186 else if (Modules
!= NULL
)
188 ModulePtr
->Section
= 0;
189 ModulePtr
->MappedBase
= NULL
; // FIXME: ??
190 ModulePtr
->ImageBase
= lmModule
.DllBase
;
191 ModulePtr
->ImageSize
= lmModule
.SizeOfImage
;
192 ModulePtr
->Flags
= lmModule
.Flags
;
193 ModulePtr
->LoadOrderIndex
= 0; // FIXME: ??
194 ModulePtr
->InitOrderIndex
= 0; // FIXME: ??
195 ModulePtr
->LoadCount
= lmModule
.LoadCount
;
197 AnsiString
.Length
= 0;
198 AnsiString
.MaximumLength
= 256;
199 AnsiString
.Buffer
= ModulePtr
->FullPathName
;
200 RtlUnicodeStringToAnsiString(&AnsiString
,
204 p
= strrchr(ModulePtr
->FullPathName
, '\\');
206 ModulePtr
->OffsetToFileName
= p
- ModulePtr
->FullPathName
+ 1;
208 ModulePtr
->OffsetToFileName
= 0;
211 Modules
->NumberOfModules
++;
213 UsedSize
+= sizeof(RTL_PROCESS_MODULE_INFORMATION
);
215 /* address of the next module in the list */
216 pleCurEntry
= lmModule
.InLoadOrderLinks
.Flink
;
219 if (ReturnedSize
!= 0)
220 *ReturnedSize
= UsedSize
;
222 DPRINT("RtlpQueryRemoteProcessModules End\n");
225 return (STATUS_SUCCESS
);
232 RtlQueryProcessDebugInformation(IN ULONG ProcessId
,
233 IN ULONG DebugInfoMask
,
234 IN OUT PRTL_DEBUG_INFORMATION Buf
)
236 NTSTATUS Status
= STATUS_SUCCESS
;
237 ULONG Pid
= (ULONG_PTR
) NtCurrentTeb()->ClientId
.UniqueProcess
;
239 Buf
->Flags
= DebugInfoMask
;
240 Buf
->OffsetFree
= sizeof(RTL_DEBUG_INFORMATION
);
242 DPRINT("QueryProcessDebugInformation Start\n");
245 Currently ROS can not read-only from kenrel space, and doesn't
246 check for boundaries inside kernel space that are page protected
247 from every one but the kernel. aka page 0 - 2
251 Status
= STATUS_ACCESS_VIOLATION
;
254 if (Pid
== ProcessId
)
256 if (DebugInfoMask
& RTL_DEBUG_QUERY_MODULES
)
258 PRTL_PROCESS_MODULES Mp
;
259 ULONG ReturnSize
= 0;
262 Mp
= (PRTL_PROCESS_MODULES
)(Buf
+ Buf
->OffsetFree
);
264 /* I like this better than the do & while loop. */
265 Status
= LdrQueryProcessModuleInformation( NULL
,
268 Status
= LdrQueryProcessModuleInformation( Mp
,
271 if (!NT_SUCCESS(Status
))
276 MSize
= Mp
->NumberOfModules
* (sizeof(RTL_PROCESS_MODULES
) + 8);
278 Buf
->OffsetFree
= Buf
->OffsetFree
+ MSize
;
281 if (DebugInfoMask
& RTL_DEBUG_QUERY_HEAPS
)
283 PRTL_PROCESS_HEAPS Hp
;
286 Hp
= (PRTL_PROCESS_HEAPS
)(Buf
+ Buf
->OffsetFree
);
287 HSize
= sizeof(RTL_PROCESS_HEAPS
);
288 if (DebugInfoMask
& RTL_DEBUG_QUERY_HEAP_TAGS
)
291 if (DebugInfoMask
& RTL_DEBUG_QUERY_HEAP_BLOCKS
)
295 Buf
->OffsetFree
= Buf
->OffsetFree
+ HSize
;
299 if (DebugInfoMask
& RTL_DEBUG_QUERY_LOCKS
)
301 PRTL_PROCESS_LOCKS Lp
;
304 Lp
= (PRTL_PROCESS_LOCKS
)(Buf
+ Buf
->OffsetFree
);
305 LSize
= sizeof(RTL_PROCESS_LOCKS
);
307 Buf
->OffsetFree
= Buf
->OffsetFree
+ LSize
;
310 DPRINT("QueryProcessDebugInformation end \n");
311 DPRINT("QueryDebugInfo : 0x%lx\n", Buf
->OffsetFree
);
317 OBJECT_ATTRIBUTES ObjectAttributes
;
319 Buf
->TargetProcessHandle
= NtCurrentProcess();
321 ClientId
.UniqueThread
= 0;
322 ClientId
.UniqueProcess
= (HANDLE
)(ULONG_PTR
)ProcessId
;
323 InitializeObjectAttributes(&ObjectAttributes
,
329 Status
= NtOpenProcess( &hProcess
,
330 (PROCESS_ALL_ACCESS
),
333 if (!NT_SUCCESS(Status
))
338 if (DebugInfoMask
& RTL_DEBUG_QUERY_MODULES
)
340 PRTL_PROCESS_MODULES Mp
;
341 ULONG ReturnSize
= 0;
344 Mp
= (PRTL_PROCESS_MODULES
)(Buf
+ Buf
->OffsetFree
);
346 Status
= RtlpQueryRemoteProcessModules( hProcess
,
351 Status
= RtlpQueryRemoteProcessModules( hProcess
,
355 if (!NT_SUCCESS(Status
))
360 MSize
= Mp
->NumberOfModules
* (sizeof(RTL_PROCESS_MODULES
) + 8);
362 Buf
->OffsetFree
= Buf
->OffsetFree
+ MSize
;
365 if (DebugInfoMask
& RTL_DEBUG_QUERY_HEAPS
)
367 PRTL_PROCESS_HEAPS Hp
;
370 Hp
= (PRTL_PROCESS_HEAPS
)(Buf
+ Buf
->OffsetFree
);
371 HSize
= sizeof(RTL_PROCESS_HEAPS
);
372 if (DebugInfoMask
& RTL_DEBUG_QUERY_HEAP_TAGS
)
375 if (DebugInfoMask
& RTL_DEBUG_QUERY_HEAP_BLOCKS
)
379 Buf
->OffsetFree
= Buf
->OffsetFree
+ HSize
;
383 if (DebugInfoMask
& RTL_DEBUG_QUERY_LOCKS
)
385 PRTL_PROCESS_LOCKS Lp
;
388 Lp
= (PRTL_PROCESS_LOCKS
)(Buf
+ Buf
->OffsetFree
);
389 LSize
= sizeof(RTL_PROCESS_LOCKS
);
391 Buf
->OffsetFree
= Buf
->OffsetFree
+ LSize
;
394 DPRINT("QueryProcessDebugInformation end \n");
395 DPRINT("QueryDebugInfo : 0x%lx\n", Buf
->OffsetFree
);