VOID PhShowProcessHeapsDialog( __in HWND ParentWindowHandle, __in PPH_PROCESS_ITEM ProcessItem ) { NTSTATUS status; PROCESS_HEAPS_CONTEXT context; PRTL_DEBUG_INFORMATION debugBuffer; HANDLE processHandle; context.ProcessItem = ProcessItem; context.ProcessHeap = NULL; debugBuffer = RtlCreateQueryDebugBuffer(0, FALSE); if (!debugBuffer) return; status = RtlQueryProcessDebugInformation( ProcessItem->ProcessId, RTL_QUERY_PROCESS_HEAP_SUMMARY | RTL_QUERY_PROCESS_HEAP_ENTRIES, debugBuffer ); if (NT_SUCCESS(status)) { context.ProcessHeaps = debugBuffer->Heaps; if (NT_SUCCESS(PhOpenProcess( &processHandle, ProcessQueryAccess | PROCESS_VM_READ, ProcessItem->ProcessId ))) { PhGetProcessDefaultHeap(processHandle, &context.ProcessHeap); NtClose(processHandle); } DialogBoxParam( PhInstanceHandle, MAKEINTRESOURCE(IDD_HEAPS), ParentWindowHandle, PhpProcessHeapsDlgProc, (LPARAM)&context ); } else { PhShowStatus(ParentWindowHandle, L"Unable to query heap information", status, 0); } RtlDestroyQueryDebugBuffer(debugBuffer); }
/* * @implemented */ BOOL WINAPI Heap32Next(LPHEAPENTRY32 lphe) { PRTL_DEBUG_INFORMATION DebugInfo; PRTL_HEAP_INFORMATION Heap; PRTLP_HEAP_ENTRY Block, LastBlock; BOOLEAN FoundUncommitted = FALSE; ULONG i; NTSTATUS Status; CHECK_PARAM_SIZE(lphe, sizeof(HEAPENTRY32)); DebugInfo = RtlCreateQueryDebugBuffer(0, FALSE); if (DebugInfo == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } Status = RtlQueryProcessDebugInformation(lphe->th32ProcessID, RTL_DEBUG_QUERY_HEAPS | RTL_DEBUG_QUERY_HEAP_BLOCKS, DebugInfo); if (NT_SUCCESS(Status)) { Status = STATUS_NO_MORE_FILES; for (i = 0; i != DebugInfo->Heaps->NumberOfHeaps; i++) { Heap = &DebugInfo->Heaps->Heaps[i]; if ((ULONG_PTR)Heap->BaseAddress == lphe->th32HeapID) { if (++lphe->dwResvd < Heap->NumberOfEntries) { lphe->dwFlags = 0; Block = (PRTLP_HEAP_ENTRY)Heap->Entries + lphe->dwResvd; LastBlock = (PRTLP_HEAP_ENTRY)Heap->Entries + Heap->NumberOfEntries; while (Block < LastBlock && (Block->Flags & PROCESS_HEAP_UNCOMMITTED_RANGE)) { lphe->dwResvd++; lphe->dwAddress = (ULONG_PTR)((ULONG_PTR)Block->Address + Heap->EntryOverhead); FoundUncommitted = TRUE; Block++; } if (Block < LastBlock) { if (!FoundUncommitted) lphe->dwAddress += lphe->dwBlockSize; lphe->dwBlockSize = Block->Size; if (Block->Flags & 0x2F1) /* FIXME */ lphe->dwFlags = LF32_FIXED; else if (Block->Flags & 0x20) /* FIXME */ lphe->dwFlags = LF32_MOVEABLE; else if (Block->Flags & 0x100) /* FIXME */ lphe->dwFlags = LF32_FREE; Status = STATUS_SUCCESS; } } break; } } } RtlDestroyQueryDebugBuffer(DebugInfo); if (!NT_SUCCESS(Status)) { BaseSetLastNTError(Status); return FALSE; } return TRUE; }
static NTSTATUS TH32CreateSnapshot(DWORD dwFlags, DWORD th32ProcessID, PRTL_DEBUG_INFORMATION *HeapDebug, PRTL_DEBUG_INFORMATION *ModuleDebug, PVOID *ProcThrdInfo, SIZE_T *ProcThrdInfoSize) { NTSTATUS Status = STATUS_SUCCESS; *HeapDebug = NULL; *ModuleDebug = NULL; *ProcThrdInfo = NULL; *ProcThrdInfoSize = 0; /* * Allocate the debug information for a heap snapshot */ if(dwFlags & TH32CS_SNAPHEAPLIST) { *HeapDebug = RtlCreateQueryDebugBuffer(0, FALSE); if(*HeapDebug != NULL) { Status = RtlQueryProcessDebugInformation(th32ProcessID, RTL_DEBUG_QUERY_HEAPS, *HeapDebug); } else Status = STATUS_UNSUCCESSFUL; } /* * Allocate the debug information for a module snapshot */ if(dwFlags & TH32CS_SNAPMODULE && NT_SUCCESS(Status)) { *ModuleDebug = RtlCreateQueryDebugBuffer(0, FALSE); if(*ModuleDebug != NULL) { Status = RtlQueryProcessDebugInformation(th32ProcessID, RTL_DEBUG_QUERY_MODULES, *ModuleDebug); } else Status = STATUS_UNSUCCESSFUL; } /* * Allocate enough memory for the system's process list */ if(dwFlags & (TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD) && NT_SUCCESS(Status)) { for(;;) { (*ProcThrdInfoSize) += 0x10000; Status = NtAllocateVirtualMemory(NtCurrentProcess(), ProcThrdInfo, 0, ProcThrdInfoSize, MEM_COMMIT, PAGE_READWRITE); if(!NT_SUCCESS(Status)) { break; } Status = NtQuerySystemInformation(SystemProcessInformation, *ProcThrdInfo, *ProcThrdInfoSize, NULL); if(Status == STATUS_INFO_LENGTH_MISMATCH) { NtFreeVirtualMemory(NtCurrentProcess(), ProcThrdInfo, ProcThrdInfoSize, MEM_RELEASE); *ProcThrdInfo = NULL; } else { break; } } } /* * Free resources in case of failure! */ if(!NT_SUCCESS(Status)) { TH32FreeAllocatedResources(*HeapDebug, *ModuleDebug, *ProcThrdInfo, *ProcThrdInfoSize); } return Status; }