Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

query.c File Reference

#include <ntos.h>
#include "ldrp.h"
#include <stktrace.h>
#include <heap.h>
#include <stdio.h>

Go to the source code of this file.

Defines

#define AdjustPointer(t, p, d)   (p); if ((p) != NULL) (p) = (t)((ULONG_PTR)(p) + (d))

Functions

NTSYSAPI NTSTATUS NTAPI RtlpQueryProcessDebugInformationRemote (IN OUT PRTL_DEBUG_INFORMATION Buffer)
NTSTATUS RtlpChangeQueryDebugBufferTarget (IN PRTL_DEBUG_INFORMATION Buffer, IN HANDLE TargetProcessId, OUT PHANDLE ReturnedTargetProcessHandle)
PVOID RtlpCommitQueryDebugInfo (IN PRTL_DEBUG_INFORMATION Buffer, IN ULONG Size)
VOID RtlpDeCommitQueryDebugInfo (IN PRTL_DEBUG_INFORMATION Buffer, IN PVOID p, IN ULONG Size)
NTSYSAPI PRTL_DEBUG_INFORMATION
NTAPI 
RtlCreateQueryDebugBuffer (IN ULONG MaximumCommit OPTIONAL, IN BOOLEAN UseEventPair)
NTSYSAPI NTSTATUS NTAPI RtlDestroyQueryDebugBuffer (IN PRTL_DEBUG_INFORMATION Buffer)
NTSYSAPI NTSTATUS NTAPI RtlQueryProcessDebugInformation (IN HANDLE UniqueProcessId, IN ULONG Flags, IN OUT PRTL_DEBUG_INFORMATION Buffer)
NTSTATUS NTAPI RtlQueryProcessModuleInformation (IN OUT PRTL_DEBUG_INFORMATION Buffer)
NTSTATUS RtlQueryProcessBackTraceInformation (IN OUT PRTL_DEBUG_INFORMATION Buffer)
NTSTATUS RtlpQueryProcessEnumHeapsRoutine (PVOID HeapHandle, PVOID Parameter)
NTSYSAPI NTSTATUS NTAPI RtlQueryProcessHeapInformation (IN OUT PRTL_DEBUG_INFORMATION Buffer)
NTSYSAPI NTSTATUS NTAPI RtlQueryProcessLockInformation (IN OUT PRTL_DEBUG_INFORMATION Buffer)


Define Documentation

#define AdjustPointer t,
p,
 )     (p); if ((p) != NULL) (p) = (t)((ULONG_PTR)(p) + (d))
 

Definition at line 27 of file dll/query.c.

Referenced by RtlpQueryProcessDebugInformationRemote().


Function Documentation

NTSYSAPI PRTL_DEBUG_INFORMATION NTAPI RtlCreateQueryDebugBuffer IN ULONG MaximumCommit  OPTIONAL,
IN BOOLEAN  UseEventPair
 

Definition at line 316 of file dll/query.c.

References Buffer, NT_SUCCESS, NtAllocateVirtualMemory(), NtClose(), NtCreateEventPair(), NtCreateSection(), NtMapViewOfSection(), NTSTATUS(), NtUnmapViewOfSection(), NULL, and Status.

00320 { 00321 NTSTATUS Status; 00322 HANDLE Section; 00323 PRTL_DEBUG_INFORMATION Buffer; 00324 LARGE_INTEGER MaximumSize; 00325 ULONG_PTR ViewSize, CommitSize; 00326 00327 if (!ARGUMENT_PRESENT( (PVOID)(ULONG_PTR)MaximumCommit )) { // Sundown Note: ULONG zero-extended. 00328 MaximumCommit = 4 * 1024 * 1024; 00329 } 00330 MaximumSize.QuadPart = MaximumCommit; 00331 Status = NtCreateSection( &Section, 00332 SECTION_ALL_ACCESS, 00333 NULL, 00334 &MaximumSize, 00335 PAGE_READWRITE, 00336 SEC_RESERVE, 00337 NULL 00338 ); 00339 if (!NT_SUCCESS( Status )) { 00340 return NULL; 00341 } 00342 00343 Buffer = NULL; 00344 ViewSize = MaximumCommit; 00345 Status = NtMapViewOfSection( Section, 00346 NtCurrentProcess(), 00347 &Buffer, 00348 0, 00349 0, 00350 NULL, 00351 &ViewSize, 00352 ViewUnmap, 00353 0, 00354 PAGE_READWRITE 00355 ); 00356 if (!NT_SUCCESS( Status )) { 00357 NtClose( Section ); 00358 return NULL; 00359 } 00360 00361 CommitSize = 1; 00362 Status = NtAllocateVirtualMemory( NtCurrentProcess(), 00363 &Buffer, 00364 0, 00365 &CommitSize, 00366 MEM_COMMIT, 00367 PAGE_READWRITE 00368 ); 00369 if (!NT_SUCCESS( Status )) { 00370 NtUnmapViewOfSection( NtCurrentProcess(), Buffer ); 00371 NtClose( Section ); 00372 return NULL; 00373 } 00374 00375 if (UseEventPair) { 00376 Status = NtCreateEventPair( &Buffer->EventPairClient, 00377 EVENT_PAIR_ALL_ACCESS, 00378 NULL 00379 ); 00380 if (!NT_SUCCESS( Status )) { 00381 NtUnmapViewOfSection( NtCurrentProcess(), Buffer ); 00382 NtClose( Section ); 00383 return NULL; 00384 } 00385 } 00386 00387 Buffer->SectionHandleClient = Section; 00388 Buffer->ViewBaseClient = Buffer; 00389 Buffer->OffsetFree = 0; 00390 Buffer->CommitSize = CommitSize; 00391 Buffer->ViewSize = ViewSize; 00392 return Buffer; 00393 }

NTSYSAPI NTSTATUS NTAPI RtlDestroyQueryDebugBuffer IN PRTL_DEBUG_INFORMATION  Buffer  ) 
 

Definition at line 399 of file dll/query.c.

References Buffer, NT_SUCCESS, NtClose(), NtFreeVirtualMemory(), NtQueryInformationThread(), NtReadVirtualMemory(), NtSetLowEventPair(), NTSTATUS(), NtUnmapViewOfSection(), NtWaitForSingleObject(), NULL, RtlpChangeQueryDebugBufferTarget(), Size, Status, ThreadHandle, and TRUE.

00402 { 00403 NTSTATUS Status; 00404 HANDLE ProcessHandle, ThreadHandle; 00405 THREAD_BASIC_INFORMATION BasicInformation; 00406 PTEB Teb; 00407 PVOID StackDeallocationBase; 00408 ULONG Size; 00409 SIZE_T BigSize; 00410 00411 RtlpChangeQueryDebugBufferTarget( Buffer, NULL, NULL ); 00412 00413 Status = STATUS_SUCCESS; 00414 if (Buffer->TargetThreadHandle != NULL) { 00415 StackDeallocationBase = NULL; 00416 Status = NtQueryInformationThread( Buffer->TargetThreadHandle, 00417 ThreadBasicInformation, 00418 &BasicInformation, 00419 sizeof( BasicInformation ), 00420 NULL 00421 ); 00422 if (NT_SUCCESS( Status )) { 00423 if (Teb = BasicInformation.TebBaseAddress) { 00424 NtReadVirtualMemory( Buffer->TargetProcessHandle, 00425 &Teb->DeallocationStack, 00426 &StackDeallocationBase, 00427 sizeof( StackDeallocationBase ), 00428 &Size 00429 ); 00430 } 00431 } 00432 00433 Buffer->EventPairTarget = NULL; 00434 NtSetLowEventPair( Buffer->EventPairClient ); 00435 NtClose( Buffer->EventPairClient ); 00436 Status = NtWaitForSingleObject( Buffer->TargetThreadHandle, 00437 TRUE, 00438 NULL 00439 ); 00440 if (NT_SUCCESS( Status )) { 00441 Status = NtQueryInformationThread( Buffer->TargetThreadHandle, 00442 ThreadBasicInformation, 00443 &BasicInformation, 00444 sizeof( BasicInformation ), 00445 NULL 00446 ); 00447 if (NT_SUCCESS( Status )) { 00448 Status = BasicInformation.ExitStatus; 00449 } 00450 } 00451 00452 BigSize = 0; 00453 NtFreeVirtualMemory( Buffer->TargetProcessHandle, 00454 &StackDeallocationBase, 00455 &BigSize, 00456 MEM_RELEASE 00457 ); 00458 } 00459 00460 NtClose( Buffer->SectionHandleClient ); 00461 NtUnmapViewOfSection( NtCurrentProcess(), Buffer ); 00462 return Status; 00463 }

NTSTATUS RtlpChangeQueryDebugBufferTarget IN PRTL_DEBUG_INFORMATION  Buffer,
IN HANDLE  TargetProcessId,
OUT PHANDLE  ReturnedTargetProcessHandle
 

Definition at line 99 of file dll/query.c.

References Buffer, NT_SUCCESS, NtClose(), NtDuplicateObject(), NtMapViewOfSection(), NtOpenProcess(), NTSTATUS(), NtUnmapViewOfSection(), NULL, ObjectAttributes, and Status.

Referenced by RtlDestroyQueryDebugBuffer(), and RtlQueryProcessDebugInformation().

00104 { 00105 NTSTATUS Status; 00106 CLIENT_ID OldTargetClientId, NewTargetClientId; 00107 OBJECT_ATTRIBUTES ObjectAttributes; 00108 HANDLE OldTargetProcess, NewTargetProcess, NewHandle; 00109 PHANDLE pOldHandle; 00110 ULONG DuplicateHandleFlags; 00111 00112 if (Buffer->EventPairClient != NULL && 00113 Buffer->TargetProcessId == TargetProcessId 00114 ) { 00115 return STATUS_SUCCESS; 00116 } 00117 00118 InitializeObjectAttributes( &ObjectAttributes, 00119 NULL, 00120 0, 00121 NULL, 00122 NULL 00123 ); 00124 00125 DuplicateHandleFlags = DUPLICATE_CLOSE_SOURCE | 00126 DUPLICATE_SAME_ACCESS | 00127 DUPLICATE_SAME_ATTRIBUTES; 00128 00129 if (Buffer->EventPairClient != NULL) { 00130 pOldHandle = &Buffer->EventPairTarget; 00131 } 00132 else { 00133 pOldHandle = NULL; 00134 } 00135 00136 if (Buffer->TargetProcessId != NULL) { 00137 OldTargetClientId.UniqueProcess = Buffer->TargetProcessId; 00138 OldTargetClientId.UniqueThread = 0; 00139 Status = NtOpenProcess( &OldTargetProcess, 00140 PROCESS_ALL_ACCESS, 00141 &ObjectAttributes, 00142 &OldTargetClientId 00143 ); 00144 if (!NT_SUCCESS( Status )) { 00145 return Status; 00146 } 00147 } 00148 else { 00149 OldTargetProcess = NtCurrentProcess(); 00150 DuplicateHandleFlags &= ~DUPLICATE_CLOSE_SOURCE; 00151 if (pOldHandle != NULL) { 00152 pOldHandle = &Buffer->EventPairClient; 00153 } 00154 } 00155 00156 if (ARGUMENT_PRESENT( TargetProcessId )) { 00157 NewTargetClientId.UniqueProcess = TargetProcessId; 00158 NewTargetClientId.UniqueThread = 0; 00159 Status = NtOpenProcess( &NewTargetProcess, 00160 PROCESS_ALL_ACCESS, 00161 &ObjectAttributes, 00162 &NewTargetClientId 00163 ); 00164 if (!NT_SUCCESS( Status )) { 00165 if (OldTargetProcess != NtCurrentProcess()) { 00166 NtClose( OldTargetProcess ); 00167 } 00168 return Status; 00169 } 00170 } 00171 else { 00172 NewTargetProcess = NULL; 00173 } 00174 00175 NewHandle = NULL; 00176 if (pOldHandle != NULL) { 00177 Status = NtDuplicateObject( OldTargetProcess, 00178 *pOldHandle, 00179 NewTargetProcess, 00180 &NewHandle, 00181 0, 00182 0, 00183 DuplicateHandleFlags 00184 ); 00185 if (!NT_SUCCESS( Status )) { 00186 if (OldTargetProcess != NtCurrentProcess()) { 00187 NtClose( OldTargetProcess ); 00188 } 00189 if (NewTargetProcess != NULL) { 00190 NtClose( NewTargetProcess ); 00191 } 00192 return Status; 00193 } 00194 } 00195 00196 if (OldTargetProcess != NtCurrentProcess()) { 00197 NtUnmapViewOfSection( OldTargetProcess, Buffer->ViewBaseTarget ); 00198 } 00199 else { 00200 Buffer->ViewBaseTarget = Buffer->ViewBaseClient; 00201 } 00202 00203 if (NewTargetProcess != NULL) { 00204 Status = NtMapViewOfSection( Buffer->SectionHandleClient, 00205 NewTargetProcess, 00206 &Buffer->ViewBaseTarget, 00207 0, 00208 0, 00209 NULL, 00210 &Buffer->ViewSize, 00211 ViewUnmap, 00212 0, 00213 PAGE_READWRITE 00214 ); 00215 if (Status == STATUS_CONFLICTING_ADDRESSES) { 00216 Buffer->ViewBaseTarget = NULL; 00217 Status = NtMapViewOfSection( Buffer->SectionHandleClient, 00218 NewTargetProcess, 00219 &Buffer->ViewBaseTarget, 00220 0, 00221 0, 00222 NULL, 00223 &Buffer->ViewSize, 00224 ViewUnmap, 00225 0, 00226 PAGE_READWRITE 00227 ); 00228 } 00229 00230 if (!NT_SUCCESS( Status )) { 00231 if (NewHandle != NULL) { 00232 NtDuplicateObject( NewTargetProcess, 00233 &NewHandle, 00234 NULL, 00235 NULL, 00236 0, 00237 0, 00238 DUPLICATE_CLOSE_SOURCE 00239 ); 00240 } 00241 00242 return Status; 00243 } 00244 00245 if (ARGUMENT_PRESENT( ReturnedTargetProcessHandle )) { 00246 *ReturnedTargetProcessHandle = NewTargetProcess; 00247 } 00248 else { 00249 NtClose( NewTargetProcess ); 00250 } 00251 } 00252 00253 Buffer->EventPairTarget = NewHandle; 00254 Buffer->ViewBaseDelta = (ULONG_PTR)Buffer->ViewBaseClient - (ULONG_PTR)Buffer->ViewBaseTarget; 00255 return STATUS_SUCCESS; 00256 }

PVOID RtlpCommitQueryDebugInfo IN PRTL_DEBUG_INFORMATION  Buffer,
IN ULONG  Size
 

Definition at line 260 of file dll/query.c.

References Buffer, NT_SUCCESS, NtAllocateVirtualMemory(), NTSTATUS(), NULL, Size, and Status.

Referenced by RtlpQueryProcessEnumHeapsRoutine(), RtlQueryProcessBackTraceInformation(), RtlQueryProcessHeapInformation(), RtlQueryProcessLockInformation(), and RtlQueryProcessModuleInformation().

00264 { 00265 NTSTATUS Status; 00266 PVOID Result; 00267 PVOID CommitBase; 00268 SIZE_T CommitSize; 00269 SIZE_T NeededSize; 00270 00271 Size = (Size + 3) & ~3; 00272 NeededSize = Buffer->OffsetFree + Size; 00273 if (NeededSize > Buffer->CommitSize) { 00274 if (NeededSize >= Buffer->ViewSize) { 00275 return NULL; 00276 } 00277 00278 CommitBase = (PCHAR)Buffer + Buffer->CommitSize; 00279 CommitSize = NeededSize - Buffer->CommitSize; 00280 Status = NtAllocateVirtualMemory( NtCurrentProcess(), 00281 &CommitBase, 00282 0, 00283 &CommitSize, 00284 MEM_COMMIT, 00285 PAGE_READWRITE 00286 ); 00287 if (!NT_SUCCESS( Status )) { 00288 return NULL; 00289 } 00290 00291 00292 Buffer->CommitSize += CommitSize; 00293 } 00294 00295 Result = (PCHAR)Buffer + Buffer->OffsetFree; 00296 Buffer->OffsetFree = NeededSize; 00297 return Result; 00298 }

VOID RtlpDeCommitQueryDebugInfo IN PRTL_DEBUG_INFORMATION  Buffer,
IN PVOID  p,
IN ULONG  Size
 

Definition at line 301 of file dll/query.c.

References Buffer, and Size.

Referenced by RtlQueryProcessLockInformation().

00306 { 00307 Size = (Size + 3) & ~3; 00308 if (p == (PVOID)(Buffer->OffsetFree - Size)) { 00309 Buffer->OffsetFree -= Size; 00310 } 00311 }

NTSYSAPI NTSTATUS NTAPI RtlpQueryProcessDebugInformationRemote IN OUT PRTL_DEBUG_INFORMATION  Buffer  ) 
 

Definition at line 32 of file dll/query.c.

References AdjustPointer, Buffer, NT_SUCCESS, NtSetHighWaitLowEventPair(), NTSTATUS(), NtTerminateThread(), NtUnmapViewOfSection(), NtWaitLowEventPair(), NULL, RtlQueryProcessDebugInformation(), and Status.

Referenced by RtlQueryProcessDebugInformation().

00035 { 00036 NTSTATUS Status; 00037 ULONG i; 00038 ULONG_PTR Delta; 00039 PRTL_PROCESS_HEAPS Heaps; 00040 PRTL_HEAP_INFORMATION HeapInfo; 00041 00042 if (Buffer->EventPairTarget != NULL) { 00043 Status = NtWaitLowEventPair( Buffer->EventPairTarget ); 00044 } 00045 else { 00046 Status = STATUS_SUCCESS; 00047 } 00048 00049 while (NT_SUCCESS( Status )) { 00050 Status = RtlQueryProcessDebugInformation( NtCurrentTeb()->ClientId.UniqueProcess, 00051 Buffer->Flags, 00052 Buffer 00053 ); 00054 if (NT_SUCCESS( Status )) { 00055 if (Delta = Buffer->ViewBaseDelta) { 00056 // 00057 // Need to relocate buffer pointers back to client addresses 00058 // 00059 AdjustPointer( PRTL_PROCESS_MODULES, Buffer->Modules, Delta ); 00060 AdjustPointer( PRTL_PROCESS_BACKTRACES, Buffer->BackTraces, Delta ); 00061 Heaps = AdjustPointer( PRTL_PROCESS_HEAPS, Buffer->Heaps, Delta ); 00062 if (Heaps != NULL) { 00063 for (i=0; i<Heaps->NumberOfHeaps; i++) { 00064 HeapInfo = &Heaps->Heaps[ i ]; 00065 AdjustPointer( PRTL_HEAP_TAG, HeapInfo->Tags, Delta ); 00066 AdjustPointer( PRTL_HEAP_ENTRY, HeapInfo->Entries, Delta ); 00067 } 00068 } 00069 00070 AdjustPointer( PRTL_PROCESS_LOCKS, Buffer->Locks, Delta ); 00071 } 00072 } 00073 00074 if (Buffer->EventPairTarget == NULL) { 00075 // 00076 // If no event pair handle, then exit loop and terminate 00077 // 00078 break; 00079 } 00080 00081 Status = NtSetHighWaitLowEventPair( Buffer->EventPairTarget ); 00082 if (Buffer->EventPairTarget == NULL) { 00083 break; 00084 } 00085 } 00086 00087 // 00088 // All done with buffer, remove from our address space 00089 // then terminate ourselves so client wakes up. 00090 // 00091 00092 NtUnmapViewOfSection( NtCurrentProcess(), Buffer ); 00093 NtTerminateThread( NtCurrentThread(), Status ); 00094 return Status; 00095 }

NTSTATUS RtlpQueryProcessEnumHeapsRoutine PVOID  HeapHandle,
PVOID  Parameter
 

Definition at line 729 of file dll/query.c.

References _HEAP::AllocatorBackTraceIndex, Buffer, _HEAP::Flags, HEAP_ENTRY, HEAP_GRANULARITY_SHIFT, HEAP_MAXIMUM_SEGMENTS, HeapHandle, NULL, _HEAP_SEGMENT::NumberOfPages, _HEAP_SEGMENT::NumberOfUnCommittedPages, PAGE_SIZE, PHEAP, PHEAP_SEGMENT, RtlpCommitQueryDebugInfo(), _HEAP::Segments, and _HEAP::TotalFreeSize.

Referenced by RtlQueryProcessHeapInformation().

00733 { 00734 PRTL_DEBUG_INFORMATION Buffer = (PRTL_DEBUG_INFORMATION)Parameter; 00735 PRTL_PROCESS_HEAPS Heaps = Buffer->Heaps; 00736 PHEAP Heap = (PHEAP)HeapHandle; 00737 PRTL_HEAP_INFORMATION HeapInfo; 00738 PHEAP_SEGMENT Segment; 00739 UCHAR SegmentIndex; 00740 00741 HeapInfo = RtlpCommitQueryDebugInfo( Buffer, sizeof( *HeapInfo ) ); 00742 if (HeapInfo == NULL) { 00743 return STATUS_NO_MEMORY; 00744 } 00745 00746 HeapInfo->BaseAddress = Heap; 00747 HeapInfo->Flags = Heap->Flags; 00748 HeapInfo->EntryOverhead = sizeof( HEAP_ENTRY ); 00749 HeapInfo->CreatorBackTraceIndex = Heap->AllocatorBackTraceIndex; 00750 SegmentIndex = HEAP_MAXIMUM_SEGMENTS; 00751 while (SegmentIndex--) { 00752 Segment = Heap->Segments[ SegmentIndex ]; 00753 if (Segment) { 00754 HeapInfo->BytesCommitted += (Segment->NumberOfPages - 00755 Segment->NumberOfUnCommittedPages 00756 ) * PAGE_SIZE; 00757 00758 } 00759 } 00760 HeapInfo->BytesAllocated = HeapInfo->BytesCommitted - 00761 (Heap->TotalFreeSize << HEAP_GRANULARITY_SHIFT); 00762 Heaps->NumberOfHeaps += 1; 00763 return STATUS_SUCCESS; 00764 }

NTSTATUS RtlQueryProcessBackTraceInformation IN OUT PRTL_DEBUG_INFORMATION  Buffer  ) 
 

Definition at line 660 of file dll/query.c.

References _RTL_STACK_TRACE_ENTRY::BackTrace, Buffer, _STACK_TRACE_DATABASE::CommitBase, _STACK_TRACE_DATABASE::CurrentUpperCommitLimit, _RTL_STACK_TRACE_ENTRY::Depth, _STACK_TRACE_DATABASE::DumpInProgress, _STACK_TRACE_DATABASE::EntryIndexArray, FALSE, _RTL_STACK_TRACE_ENTRY::Index, n, NT_SUCCESS, NTSTATUS(), NULL, _STACK_TRACE_DATABASE::NumberOfEntriesAdded, _STACK_TRACE_DATABASE::NumberOfEntriesLookedUp, PRTL_STACK_TRACE_ENTRY, PSTACK_TRACE_DATABASE, RtlpAcquireStackTraceDataBase, RtlpCommitQueryDebugInfo(), RtlpReleaseStackTraceDataBase(), Status, _RTL_STACK_TRACE_ENTRY::TraceCount, and TRUE.

Referenced by RtlQueryProcessDebugInformation().

00663 { 00664 #if i386 00665 NTSTATUS Status; 00666 OUT PRTL_PROCESS_BACKTRACES BackTraces; 00667 PRTL_PROCESS_BACKTRACE_INFORMATION BackTraceInfo; 00668 PSTACK_TRACE_DATABASE DataBase; 00669 PRTL_STACK_TRACE_ENTRY p, *pp; 00670 ULONG n; 00671 00672 DataBase = RtlpAcquireStackTraceDataBase(); 00673 if (DataBase == NULL) { 00674 return STATUS_SUCCESS; 00675 } 00676 00677 BackTraces = RtlpCommitQueryDebugInfo( Buffer, FIELD_OFFSET( RTL_PROCESS_BACKTRACES, BackTraces ) ); 00678 if (BackTraces == NULL) { 00679 return STATUS_NO_MEMORY; 00680 } 00681 00682 DataBase->DumpInProgress = TRUE; 00683 RtlpReleaseStackTraceDataBase(); 00684 try { 00685 BackTraces->CommittedMemory = (ULONG)DataBase->CurrentUpperCommitLimit - 00686 (ULONG)DataBase->CommitBase; 00687 BackTraces->ReservedMemory = (ULONG)DataBase->EntryIndexArray - 00688 (ULONG)DataBase->CommitBase; 00689 BackTraces->NumberOfBackTraceLookups = DataBase->NumberOfEntriesLookedUp; 00690 BackTraces->NumberOfBackTraces = DataBase->NumberOfEntriesAdded; 00691 BackTraceInfo = RtlpCommitQueryDebugInfo( Buffer, (sizeof( *BackTraceInfo ) * BackTraces->NumberOfBackTraces) ); 00692 if (BackTraceInfo == NULL) { 00693 Status = STATUS_NO_MEMORY; 00694 } 00695 else { 00696 Status = STATUS_SUCCESS; 00697 n = DataBase->NumberOfEntriesAdded; 00698 pp = DataBase->EntryIndexArray; 00699 while (n--) { 00700 p = *--pp; 00701 BackTraceInfo->SymbolicBackTrace = NULL; 00702 BackTraceInfo->TraceCount = p->TraceCount; 00703 BackTraceInfo->Index = p->Index; 00704 BackTraceInfo->Depth = p->Depth; 00705 RtlMoveMemory( BackTraceInfo->BackTrace, 00706 p->BackTrace, 00707 p->Depth * sizeof( PVOID ) 00708 ); 00709 BackTraceInfo++; 00710 } 00711 } 00712 } 00713 finally { 00714 DataBase->DumpInProgress = FALSE; 00715 } 00716 00717 if (NT_SUCCESS( Status )) { 00718 Buffer->BackTraces = BackTraces; 00719 } 00720 00721 return Status; 00722 #else 00723 return STATUS_SUCCESS; 00724 #endif // i386 00725 }

NTSYSAPI NTSTATUS NTAPI RtlQueryProcessDebugInformation IN HANDLE  UniqueProcessId,
IN ULONG  Flags,
IN OUT PRTL_DEBUG_INFORMATION  Buffer
 

Definition at line 469 of file dll/query.c.

References Buffer, NT_SUCCESS, NtClose(), NtFreeVirtualMemory(), NtQueryInformationThread(), NtReadVirtualMemory(), NtResumeThread(), NtSetInformationThread(), NtSetLowWaitHighEventPair(), NTSTATUS(), NtTerminateThread(), NtWaitForSingleObject(), NULL, RtlCreateUserThread(), RtlpChangeQueryDebugBufferTarget(), RtlpQueryProcessDebugInformationRemote(), RtlQueryProcessBackTraceInformation(), RtlQueryProcessHeapInformation(), RtlQueryProcessLockInformation(), RtlQueryProcessModuleInformation(), Size, Status, ThreadHandle, and TRUE.

Referenced by RtlpQueryProcessDebugInformationRemote().

00474 { 00475 NTSTATUS Status; 00476 HANDLE ProcessHandle, ThreadHandle; 00477 THREAD_BASIC_INFORMATION BasicInformation; 00478 PTEB Teb; 00479 PVOID StackDeallocationBase; 00480 ULONG Size; 00481 SIZE_T BigSize; 00482 00483 Buffer->Flags = Flags; 00484 if (Buffer->OffsetFree != 0) { 00485 RtlZeroMemory( (Buffer+1), Buffer->OffsetFree - (SIZE_T)sizeof(*Buffer) ); 00486 } 00487 Buffer->OffsetFree = sizeof( *Buffer ); 00488 00489 if (NtCurrentTeb()->ClientId.UniqueProcess != UniqueProcessId) { 00490 // 00491 // Not querying current process, so do it remotely 00492 // 00493 ProcessHandle = NULL; 00494 Status = RtlpChangeQueryDebugBufferTarget( Buffer, UniqueProcessId, &ProcessHandle ); 00495 if (!NT_SUCCESS( Status )) { 00496 return Status; 00497 } 00498 00499 if (ProcessHandle == NULL) { 00500 waitForDump: 00501 Status = NtSetLowWaitHighEventPair( Buffer->EventPairClient ); 00502 } 00503 else { 00504 // 00505 // don't let the debugger see this remote thread ! 00506 // This is a very ugly but effective way to prevent 00507 // the debugger deadlocking with the target process when calling 00508 // this function. 00509 // 00510 00511 Status = RtlCreateUserThread( ProcessHandle, 00512 NULL, 00513 TRUE, 00514 0, 00515 0, 00516 0, 00517 RtlpQueryProcessDebugInformationRemote, 00518 Buffer->ViewBaseTarget, 00519 &ThreadHandle, 00520 NULL 00521 ); 00522 if (NT_SUCCESS( Status )) { 00523 00524 Status = NtSetInformationThread( ThreadHandle, 00525 ThreadHideFromDebugger, 00526 NULL, 00527 0 00528 ); 00529 00530 if ( !NT_SUCCESS(Status) ) { 00531 NtTerminateThread(ThreadHandle,Status); 00532 NtClose(ThreadHandle); 00533 NtClose(ProcessHandle); 00534 return Status; 00535 } 00536 00537 NtResumeThread(ThreadHandle,NULL); 00538 00539 if (Buffer->EventPairClient != NULL) { 00540 Buffer->TargetThreadHandle = ThreadHandle; 00541 Buffer->TargetProcessHandle = ProcessHandle; 00542 goto waitForDump; 00543 } 00544 00545 StackDeallocationBase = NULL; 00546 Status = NtQueryInformationThread( ThreadHandle, 00547 ThreadBasicInformation, 00548 &BasicInformation, 00549 sizeof( BasicInformation ), 00550 NULL 00551 ); 00552 if (NT_SUCCESS( Status )) { 00553 if (Teb = BasicInformation.TebBaseAddress) { 00554 NtReadVirtualMemory( ProcessHandle, 00555 &Teb->DeallocationStack, 00556 &StackDeallocationBase, 00557 sizeof( StackDeallocationBase ), 00558 &Size 00559 ); 00560 } 00561 } 00562 00563 Status = NtWaitForSingleObject( ThreadHandle, 00564 TRUE, 00565 NULL 00566 ); 00567 00568 if (NT_SUCCESS( Status )) { 00569 Status = NtQueryInformationThread( ThreadHandle, 00570 ThreadBasicInformation, 00571 &BasicInformation, 00572 sizeof( BasicInformation ), 00573 NULL 00574 ); 00575 if (NT_SUCCESS( Status )) { 00576 Status = BasicInformation.ExitStatus; 00577 } 00578 } 00579 00580 BigSize = 0; 00581 NtFreeVirtualMemory( ProcessHandle, &StackDeallocationBase, &BigSize, MEM_RELEASE ); 00582 NtClose( ThreadHandle ); 00583 00584 } 00585 00586 00587 NtClose( ProcessHandle ); 00588 } 00589 } 00590 else { 00591 if (Flags & RTL_QUERY_PROCESS_MODULES) { 00592 Status = RtlQueryProcessModuleInformation( Buffer ); 00593 if (Status != STATUS_SUCCESS) { 00594 return Status; 00595 } 00596 } 00597 00598 if (Flags & RTL_QUERY_PROCESS_BACKTRACES) { 00599 Status = RtlQueryProcessBackTraceInformation( Buffer ); 00600 if (Status != STATUS_SUCCESS) { 00601 return Status; 00602 } 00603 } 00604 00605 if (Flags & RTL_QUERY_PROCESS_LOCKS) { 00606 Status = RtlQueryProcessLockInformation( Buffer ); 00607 if (Status != STATUS_SUCCESS) { 00608 return Status; 00609 } 00610 } 00611 00612 if (Flags & (RTL_QUERY_PROCESS_HEAP_SUMMARY | 00613 RTL_QUERY_PROCESS_HEAP_TAGS | 00614 RTL_QUERY_PROCESS_HEAP_ENTRIES 00615 ) 00616 ) { 00617 Status = RtlQueryProcessHeapInformation( Buffer ); 00618 if (Status != STATUS_SUCCESS) { 00619 return Status; 00620 } 00621 } 00622 } 00623 00624 return Status; 00625 }

NTSYSAPI NTSTATUS NTAPI RtlQueryProcessHeapInformation IN OUT PRTL_DEBUG_INFORMATION  Buffer  ) 
 

Definition at line 769 of file dll/query.c.

References _HEAP_UNCOMMMTTED_RANGE::Address, _HEAP_ENTRY_EXTRA::AllocatorBackTraceIndex, _HEAP_SEGMENT::AllocatorBackTraceIndex, _HEAP_PSEUDO_TAG_ENTRY::Allocs, Buffer, _HEAP_VIRTUAL_ALLOC_ENTRY::BusyBlock, _HEAP_VIRTUAL_ALLOC_ENTRY::CommitSize, _HEAP_VIRTUAL_ALLOC_ENTRY::ExtraStuff, FALSE, _HEAP_SEGMENT::FirstEntry, _HEAP_ENTRY::Flags, _HEAP::Flags, _HEAP_FREE_ENTRY_EXTRA::FreeBackTraceIndex, _HEAP_PSEUDO_TAG_ENTRY::Frees, HEAP_ENTRY_BUSY, HEAP_ENTRY_EXTRA_PRESENT, HEAP_ENTRY_LAST_ENTRY, HEAP_ENTRY_SETTABLE_FLAGS, HEAP_GRANULARITY, HEAP_GRANULARITY_SHIFT, HEAP_MAXIMUM_FREELISTS, HEAP_MAXIMUM_SEGMENTS, HEAP_NUMBER_OF_PSEUDO_TAG, HEAP_VIRTUAL_ALLOC_ENTRY, L, _HEAP_SEGMENT::LastValidEntry, _HEAP::LockVariable, n, _HEAP_UNCOMMMTTED_RANGE::Next, _HEAP::NextAvailableTagIndex, NT_SUCCESS, NTSTATUS(), NULL, _HEAP_SEGMENT::NumberOfPages, _HEAP_SEGMENT::NumberOfUnCommittedPages, PAGE_SIZE, PHEAP_ENTRY, PHEAP_ENTRY_EXTRA, PHEAP_FREE_ENTRY_EXTRA, PHEAP_PSEUDO_TAG_ENTRY, PHEAP_UNCOMMMTTED_RANGE, PHEAP_VIRTUAL_ALLOC_ENTRY, _HEAP::PseudoTagEntries, _HEAP_VIRTUAL_ALLOC_ENTRY::ReserveSize, RtlEnumProcessHeaps(), RtlpCommitQueryDebugInfo(), RtlpGlobalTagHeap, RtlpQueryProcessEnumHeapsRoutine(), _HEAP::Segments, _HEAP_ENTRY_EXTRA::Settable, _HEAP_UNCOMMMTTED_RANGE::Size, _HEAP_ENTRY::Size, _HEAP_PSEUDO_TAG_ENTRY::Size, Size, _HEAP_ENTRY::SmallTagIndex, Status, _HEAP::TagEntries, _HEAP_FREE_ENTRY_EXTRA::TagIndex, _HEAP_ENTRY_EXTRA::TagIndex, TRUE, _HEAP_SEGMENT::UnCommittedRanges, USHORT, and _HEAP::VirtualAllocdBlocks.

Referenced by RtlQueryProcessDebugInformation().

00772 { 00773 NTSTATUS Status; 00774 PHEAP Heap; 00775 BOOLEAN LockAcquired; 00776 PRTL_PROCESS_HEAPS Heaps; 00777 PRTL_HEAP_INFORMATION HeapInfo; 00778 ULONG NumberOfHeaps; 00779 PVOID *ProcessHeaps; 00780 UCHAR SegmentIndex; 00781 ULONG i, n, TagIndex; 00782 PHEAP_SEGMENT Segment; 00783 PRTL_HEAP_TAG Tags; 00784 PHEAP_PSEUDO_TAG_ENTRY PseudoTags; 00785 PRTL_HEAP_ENTRY Entries; 00786 PHEAP_ENTRY CurrentBlock; 00787 PHEAP_ENTRY_EXTRA ExtraStuff; 00788 PRTL_HEAP_ENTRY p; 00789 PLIST_ENTRY Head, Next; 00790 PHEAP_VIRTUAL_ALLOC_ENTRY VirtualAllocBlock; 00791 ULONG Size; 00792 PHEAP_UNCOMMMTTED_RANGE UnCommittedRange; 00793 00794 Heaps = RtlpCommitQueryDebugInfo( Buffer, FIELD_OFFSET( RTL_PROCESS_HEAPS, Heaps ) ); 00795 if (Heaps == NULL) { 00796 return STATUS_NO_MEMORY; 00797 } 00798 00799 Buffer->Heaps = Heaps; 00800 Status = RtlEnumProcessHeaps( RtlpQueryProcessEnumHeapsRoutine, Buffer ); 00801 if (NT_SUCCESS( Status )) { 00802 if (Buffer->Flags & RTL_QUERY_PROCESS_HEAP_TAGS) { 00803 Heap = RtlpGlobalTagHeap; 00804 if (Heap->TagEntries != NULL) { 00805 HeapInfo = RtlpCommitQueryDebugInfo( Buffer, sizeof( *HeapInfo ) ); 00806 if (HeapInfo == NULL) { 00807 return STATUS_NO_MEMORY; 00808 } 00809 00810 HeapInfo->BaseAddress = Heap; 00811 HeapInfo->Flags = Heap->Flags; 00812 HeapInfo->EntryOverhead = sizeof( HEAP_ENTRY ); 00813 Heaps->NumberOfHeaps += 1; 00814 } 00815 00816 for (i=0; i<Heaps->NumberOfHeaps; i++) { 00817 HeapInfo = &Heaps->Heaps[ i ]; 00818 if (Buffer->SpecificHeap == NULL || 00819 Buffer->SpecificHeap == HeapInfo->BaseAddress 00820 ) { 00821 Heap = HeapInfo->BaseAddress; 00822 HeapInfo->NumberOfTags = Heap->NextAvailableTagIndex; 00823 n = HeapInfo->NumberOfTags * sizeof( RTL_HEAP_TAG ); 00824 if (Heap->PseudoTagEntries != NULL) { 00825 HeapInfo->NumberOfTags += HEAP_MAXIMUM_FREELISTS + 1; 00826 n += (HEAP_MAXIMUM_FREELISTS + 1) * sizeof( RTL_HEAP_TAG ); 00827 } 00828 Tags = RtlpCommitQueryDebugInfo( Buffer, n ); 00829 if (Tags == NULL) { 00830 Status = STATUS_NO_MEMORY; 00831 break; 00832 } 00833 HeapInfo->Tags = Tags; 00834 if ((PseudoTags = Heap->PseudoTagEntries) != NULL) { 00835 HeapInfo->NumberOfPseudoTags = HEAP_NUMBER_OF_PSEUDO_TAG; 00836 HeapInfo->PseudoTagGranularity = HEAP_GRANULARITY; 00837 for (TagIndex=0; TagIndex<=HEAP_MAXIMUM_FREELISTS; TagIndex++) { 00838 Tags->NumberOfAllocations = PseudoTags->Allocs; 00839 Tags->NumberOfFrees = PseudoTags->Frees; 00840 Tags->BytesAllocated = PseudoTags->Size << HEAP_GRANULARITY_SHIFT; 00841 Tags->TagIndex = (USHORT)(TagIndex | HEAP_PSEUDO_TAG_FLAG); 00842 if (TagIndex == 0) { 00843 swprintf( Tags->TagName, L"Objects>%4u", 00844 HEAP_MAXIMUM_FREELISTS << HEAP_GRANULARITY_SHIFT 00845 ); 00846 } 00847 else 00848 if (TagIndex < HEAP_MAXIMUM_FREELISTS) { 00849 swprintf( Tags->TagName, L"Objects=%4u", 00850 TagIndex << HEAP_GRANULARITY_SHIFT 00851 ); 00852 } 00853 else { 00854 swprintf( Tags->TagName, L"VirtualAlloc", 00855 TagIndex << HEAP_GRANULARITY_SHIFT 00856 ); 00857 } 00858 00859 Tags += 1; 00860 PseudoTags += 1; 00861 } 00862 } 00863 00864 RtlMoveMemory( Tags, 00865 Heap->TagEntries, 00866 Heap->NextAvailableTagIndex * sizeof( RTL_HEAP_TAG ) 00867 ); 00868 for (TagIndex=0; TagIndex<Heap->NextAvailableTagIndex; TagIndex++) { 00869 Tags->BytesAllocated <<= HEAP_GRANULARITY_SHIFT; 00870 Tags += 1; 00871 } 00872 } 00873 } 00874 } 00875 } 00876 else { 00877 Buffer->Heaps = NULL; 00878 } 00879 if (NT_SUCCESS( Status )) { 00880 if (Buffer->Flags & RTL_QUERY_PROCESS_HEAP_ENTRIES) { 00881 for (i=0; i<Heaps->NumberOfHeaps; i++) { 00882 HeapInfo = &Heaps->Heaps[ i ]; 00883 Heap = HeapInfo->BaseAddress; 00884 if (Buffer->SpecificHeap == NULL || 00885 Buffer->SpecificHeap == Heap 00886 ) { 00887 if (!(Heap->Flags & HEAP_NO_SERIALIZE)) { 00888 RtlEnterCriticalSection( (PRTL_CRITICAL_SECTION)Heap->LockVariable ); 00889 LockAcquired = TRUE; 00890 } 00891 else { 00892 LockAcquired = FALSE; 00893 } 00894 00895 try { 00896 for (SegmentIndex=0; SegmentIndex<HEAP_MAXIMUM_SEGMENTS; SegmentIndex++) { 00897 Segment = Heap->Segments[ SegmentIndex ]; 00898 if (!Segment) { 00899 continue; 00900 } 00901 00902 Entries = RtlpCommitQueryDebugInfo( Buffer, sizeof( *Entries ) ); 00903 if (Entries == NULL) { 00904 Status = STATUS_NO_MEMORY; 00905 break; 00906 } 00907 else 00908 if (HeapInfo->Entries == NULL) { 00909 HeapInfo->Entries = Entries; 00910 } 00911 00912 Entries->Flags = RTL_HEAP_SEGMENT; 00913 Entries->AllocatorBackTraceIndex = Segment->AllocatorBackTraceIndex; 00914 Entries->Size = Segment->NumberOfPages * PAGE_SIZE; 00915 Entries->u.s2.CommittedSize = (Segment->NumberOfPages - 00916 Segment->NumberOfUnCommittedPages 00917 ) * PAGE_SIZE; 00918 Entries->u.s2.FirstBlock = Segment->FirstEntry; 00919 HeapInfo->NumberOfEntries++; 00920 00921 UnCommittedRange = Segment->UnCommittedRanges; 00922 CurrentBlock = Segment->FirstEntry; 00923 while (CurrentBlock < Segment->LastValidEntry) { 00924 Entries = RtlpCommitQueryDebugInfo( Buffer, sizeof( *Entries ) ); 00925 if (Entries == NULL) { 00926 Status = STATUS_NO_MEMORY; 00927 break; 00928 } 00929 00930 Size = CurrentBlock->Size << HEAP_GRANULARITY_SHIFT; 00931 Entries->Size = Size; 00932 HeapInfo->NumberOfEntries++; 00933 if (CurrentBlock->Flags & HEAP_ENTRY_BUSY) { 00934 if (CurrentBlock->Flags & HEAP_ENTRY_EXTRA_PRESENT) { 00935 ExtraStuff = (PHEAP_ENTRY_EXTRA)(CurrentBlock + CurrentBlock->Size - 1); 00936 #if i386 00937 Entries->AllocatorBackTraceIndex = ExtraStuff->AllocatorBackTraceIndex; 00938 #endif // i386 00939 Entries->Flags |= RTL_HEAP_SETTABLE_VALUE; 00940 Entries->u.s1.Settable = ExtraStuff->Settable; 00941 Entries->u.s1.Tag = ExtraStuff->TagIndex; 00942 } 00943 else { 00944 Entries->u.s1.Tag = CurrentBlock->SmallTagIndex; 00945 } 00946 00947 Entries->Flags |= RTL_HEAP_BUSY | (CurrentBlock->Flags & HEAP_ENTRY_SETTABLE_FLAGS); 00948 } 00949 else 00950 if (CurrentBlock->Flags & HEAP_ENTRY_EXTRA_PRESENT) { 00951 PHEAP_FREE_ENTRY_EXTRA FreeExtra; 00952 00953 FreeExtra = (PHEAP_FREE_ENTRY_EXTRA)(CurrentBlock + CurrentBlock->Size) - 1; 00954 Entries->u.s1.Tag = FreeExtra->TagIndex; 00955 Entries->AllocatorBackTraceIndex = FreeExtra->FreeBackTraceIndex; 00956 } 00957 00958 if (CurrentBlock->Flags & HEAP_ENTRY_LAST_ENTRY) { 00959 CurrentBlock += CurrentBlock->Size; 00960 if (UnCommittedRange == NULL) { 00961 CurrentBlock = Segment->LastValidEntry; 00962 } 00963 else { 00964 Entries = RtlpCommitQueryDebugInfo( Buffer, sizeof( *Entries ) ); 00965 if (Entries == NULL) { 00966 Status = STATUS_NO_MEMORY; 00967 break; 00968 } 00969 00970 Entries->Flags = RTL_HEAP_UNCOMMITTED_RANGE; 00971 Entries->Size = UnCommittedRange->Size; 00972 HeapInfo->NumberOfEntries++; 00973 00974 CurrentBlock = (PHEAP_ENTRY) 00975 ((PCHAR)UnCommittedRange->Address + UnCommittedRange->Size); 00976 UnCommittedRange = UnCommittedRange->Next; 00977 } 00978 } 00979 else { 00980 CurrentBlock += CurrentBlock->Size; 00981 } 00982 } 00983 } 00984 00985 Head = &Heap->VirtualAllocdBlocks; 00986 Next = Head->Flink; 00987 while (Head != Next) { 00988 VirtualAllocBlock = CONTAINING_RECORD( Next, HEAP_VIRTUAL_ALLOC_ENTRY, Entry ); 00989 CurrentBlock = &VirtualAllocBlock->BusyBlock; 00990 Entries = RtlpCommitQueryDebugInfo( Buffer, sizeof( *Entries ) ); 00991 if (Entries == NULL) { 00992 Status = STATUS_NO_MEMORY; 00993 break; 00994 } 00995 else 00996 if (HeapInfo->Entries == NULL) { 00997 HeapInfo->Entries = Entries; 00998 } 00999 01000 Entries->Flags = RTL_HEAP_SEGMENT; 01001 Entries->Size = VirtualAllocBlock->ReserveSize; 01002 Entries->u.s2.CommittedSize = VirtualAllocBlock->CommitSize; 01003 Entries->u.s2.FirstBlock = CurrentBlock; 01004 HeapInfo->NumberOfEntries++; 01005 Entries = RtlpCommitQueryDebugInfo( Buffer, sizeof( *Entries ) ); 01006 if (Entries == NULL) { 01007 Status = STATUS_NO_MEMORY; 01008 break; 01009 } 01010 01011 Entries->Size = VirtualAllocBlock->CommitSize; 01012 Entries->Flags = RTL_HEAP_BUSY | (CurrentBlock->Flags & HEAP_ENTRY_SETTABLE_FLAGS); 01013 #if i386 01014 Entries->AllocatorBackTraceIndex = VirtualAllocBlock->ExtraStuff.AllocatorBackTraceIndex; 01015 #endif // i386 01016 Entries->Flags |= RTL_HEAP_SETTABLE_VALUE; 01017 Entries->u.s1.Settable = VirtualAllocBlock->ExtraStuff.Settable; 01018 Entries->u.s1.Tag = VirtualAllocBlock->ExtraStuff.TagIndex; 01019 HeapInfo->NumberOfEntries++; 01020 01021 Next = Next->Flink; 01022 } 01023 } 01024 finally { 01025 // 01026 // Unlock the heap 01027 // 01028 01029 if (LockAcquired) { 01030 RtlLeaveCriticalSection( (PRTL_CRITICAL_SECTION)Heap->LockVariable ); 01031 } 01032 } 01033 } 01034 01035 if (!NT_SUCCESS( Status )) { 01036 break; 01037 } 01038 } 01039 } 01040 } 01041 01042 return Status; 01043 }

NTSYSAPI NTSTATUS NTAPI RtlQueryProcessLockInformation IN OUT PRTL_DEBUG_INFORMATION  Buffer  ) 
 

Definition at line 1049 of file dll/query.c.

References Buffer, _ERESOURCE::ContentionCount, DbgPrint, EXCEPTION_EXECUTE_HANDLER, NT_SUCCESS, NTSTATUS(), NULL, Resource, RtlCriticalSectionList, RtlCriticalSectionLock, RtlpCommitQueryDebugInfo(), RtlpDeCommitQueryDebugInfo(), and Status.

Referenced by RtlQueryProcessDebugInformation().

01052 { 01053 NTSTATUS Status; 01054 PLIST_ENTRY Head, Next; 01055 PRTL_PROCESS_LOCKS Locks; 01056 PRTL_PROCESS_LOCK_INFORMATION LockInfo; 01057 PRTL_CRITICAL_SECTION CriticalSection; 01058 PRTL_CRITICAL_SECTION_DEBUG DebugInfo; 01059 PRTL_RESOURCE Resource; 01060 PRTL_RESOURCE_DEBUG ResourceDebugInfo; 01061 01062 Locks = RtlpCommitQueryDebugInfo( Buffer, FIELD_OFFSET( RTL_PROCESS_LOCKS, Locks ) ); 01063 if (Locks == NULL) { 01064 return STATUS_NO_MEMORY; 01065 } 01066 01067 RtlEnterCriticalSection( &RtlCriticalSectionLock ); 01068 Head = &RtlCriticalSectionList; 01069 Next = Head->Flink; 01070 Status = STATUS_SUCCESS; 01071 while (Next != Head) { 01072 DebugInfo = CONTAINING_RECORD( Next, 01073 RTL_CRITICAL_SECTION_DEBUG, 01074 ProcessLocksList 01075 ); 01076 LockInfo = RtlpCommitQueryDebugInfo( Buffer, sizeof( RTL_PROCESS_LOCK_INFORMATION ) ); 01077 if (LockInfo == NULL) { 01078 Status = STATUS_NO_MEMORY; 01079 break; 01080 } 01081 01082 CriticalSection = DebugInfo->CriticalSection; 01083 try { 01084 LockInfo->Address = CriticalSection; 01085 LockInfo->Type = DebugInfo->Type; 01086 LockInfo->CreatorBackTraceIndex = DebugInfo->CreatorBackTraceIndex; 01087 if (LockInfo->Type == RTL_CRITSECT_TYPE) { 01088 LockInfo->OwningThread = CriticalSection->OwningThread; 01089 LockInfo->LockCount = CriticalSection->LockCount; 01090 LockInfo->RecursionCount = CriticalSection->RecursionCount; 01091 LockInfo->ContentionCount = DebugInfo->ContentionCount; 01092 LockInfo->EntryCount = DebugInfo->EntryCount; 01093 } 01094 else { 01095 Resource = (PRTL_RESOURCE)CriticalSection; 01096 ResourceDebugInfo = Resource->DebugInfo; 01097 LockInfo->ContentionCount = ResourceDebugInfo->ContentionCount; 01098 LockInfo->OwningThread = Resource->ExclusiveOwnerThread; 01099 LockInfo->LockCount = Resource->NumberOfActive; 01100 LockInfo->NumberOfWaitingShared = Resource->NumberOfWaitingShared; 01101 LockInfo->NumberOfWaitingExclusive = Resource->NumberOfWaitingExclusive; 01102 } 01103 01104 Locks->NumberOfLocks++; 01105 } 01106 except (EXCEPTION_EXECUTE_HANDLER) { 01107 DbgPrint("NTDLL: Lost critical section %08lX\n", CriticalSection); 01108 RtlpDeCommitQueryDebugInfo( Buffer, LockInfo, sizeof( RTL_PROCESS_LOCK_INFORMATION ) ); 01109 } 01110 01111 if (Next == Next->Flink) { 01112 // 01113 // Bail if list is circular 01114 // 01115 break; 01116 } 01117 else { 01118 Next = Next->Flink; 01119 } 01120 } 01121 01122 RtlLeaveCriticalSection( &RtlCriticalSectionLock ); 01123 01124 if (NT_SUCCESS( Status )) { 01125 Buffer->Locks = Locks; 01126 } 01127 01128 return Status; 01129 }

NTSTATUS NTAPI RtlQueryProcessModuleInformation IN OUT PRTL_DEBUG_INFORMATION  Buffer  ) 
 

Definition at line 630 of file dll/query.c.

References Buffer, LdrQueryProcessModuleInformation(), NT_SUCCESS, NTSTATUS(), NULL, RtlpCommitQueryDebugInfo(), and Status.

Referenced by RtlQueryProcessDebugInformation().

00633 { 00634 NTSTATUS Status; 00635 ULONG RequiredLength; 00636 PRTL_PROCESS_MODULES Modules; 00637 00638 Status = LdrQueryProcessModuleInformation( NULL, 00639 0, 00640 &RequiredLength 00641 ); 00642 if (Status == STATUS_INFO_LENGTH_MISMATCH) { 00643 Modules = RtlpCommitQueryDebugInfo( Buffer, RequiredLength ); 00644 if (Modules != NULL) { 00645 Status = LdrQueryProcessModuleInformation( Modules, 00646 RequiredLength, 00647 &RequiredLength 00648 ); 00649 if (NT_SUCCESS( Status )) { 00650 Buffer->Modules = Modules; 00651 return STATUS_SUCCESS; 00652 } 00653 } 00654 } 00655 00656 return STATUS_NO_MEMORY; 00657 }


Generated on Sat May 15 19:45:25 2004 for test by doxygen 1.3.7