Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: dll/win32/kernel32/client/toolhelp.c * PURPOSE: Toolhelp functions * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com> * Robert Dickenson (robd@mok.lvcm.com) * * NOTES: Do NOT use the heap functions in here because they * adulterate the heap statistics! * * UPDATE HISTORY: * 10/30/2004 Implemented some parts (w3) * Inspired by the book "Windows NT Native API" * Created 05 January 2003 (robd) */
#include <k32.h>
#define NDEBUG#include <debug.h>
/* INTERNAL DEFINITIONS *******************************************************/
typedef struct _RTLP_HEAP_ENTRY{ ULONG Size; USHORT Flags; USHORT Unknown1; /* FIXME */ ULONG Unknown2; /* FIXME */ PVOID Address;} RTLP_HEAP_ENTRY, *PRTLP_HEAP_ENTRY;
#define CHECK_PARAM_SIZE(ptr, siz) \ if((ptr) == NULL || (ptr)->dwSize != (siz)) \ { \ SetLastError(ERROR_INVALID_PARAMETER); \ return FALSE; \ }
/* * Tests in win showed that the dwSize field can be greater than the actual size * of the structure for the ansi functions. I found this out by accidently * forgetting to set the dwSize field in a test application and it just didn't * work in ros but in win. */
#define CHECK_PARAM_SIZEA(ptr, siz) \ if((ptr) == NULL || (ptr)->dwSize < (siz)) \ { \ SetLastError(ERROR_INVALID_PARAMETER); \ return FALSE; \ }
#define OffsetToPtr(Snapshot, Offset) \ ((ULONG_PTR)((Snapshot) + 1) + (ULONG_PTR)(Offset))
typedef struct _TH32SNAPSHOT{ /* Heap list */ ULONG HeapListCount; ULONG HeapListIndex; ULONG_PTR HeapListOffset; /* Module list */ ULONG ModuleListCount; ULONG ModuleListIndex; ULONG_PTR ModuleListOffset; /* Process list */ ULONG ProcessListCount; ULONG ProcessListIndex; ULONG_PTR ProcessListOffset; /* Thread list */ ULONG ThreadListCount; ULONG ThreadListIndex; ULONG_PTR ThreadListOffset;} TH32SNAPSHOT, *PTH32SNAPSHOT;
/* INTERNAL FUNCTIONS *********************************************************/
static VOIDTH32FreeAllocatedResources(PRTL_DEBUG_INFORMATION HeapDebug, PRTL_DEBUG_INFORMATION ModuleDebug, PVOID ProcThrdInfo, SIZE_T ProcThrdInfoSize){ if(HeapDebug != NULL) { RtlDestroyQueryDebugBuffer(HeapDebug); } if(ModuleDebug != NULL) { RtlDestroyQueryDebugBuffer(ModuleDebug); }
if(ProcThrdInfo != NULL) { NtFreeVirtualMemory(NtCurrentProcess(), &ProcThrdInfo, &ProcThrdInfoSize, MEM_RELEASE); }}
static NTSTATUSTH32CreateSnapshot(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;}
static NTSTATUSTH32CreateSnapshotSectionInitialize(DWORD dwFlags, DWORD th32ProcessID, PRTL_DEBUG_INFORMATION HeapDebug, PRTL_DEBUG_INFORMATION ModuleDebug, PVOID ProcThrdInfo, HANDLE *SectionHandle){ PSYSTEM_PROCESS_INFORMATION ProcessInfo; LPHEAPLIST32 HeapListEntry; LPMODULEENTRY32W ModuleListEntry; LPPROCESSENTRY32W ProcessListEntry; LPTHREADENTRY32 ThreadListEntry; OBJECT_ATTRIBUTES ObjectAttributes; LARGE_INTEGER SSize, SOffset; HANDLE hSection; PTH32SNAPSHOT Snapshot; ULONG_PTR DataOffset; SIZE_T ViewSize; ULONG i, nProcesses = 0, nThreads = 0, nHeaps = 0, nModules = 0; ULONG RequiredSnapshotSize = sizeof(TH32SNAPSHOT); PRTL_PROCESS_HEAPS hi = NULL; PRTL_PROCESS_MODULES mi = NULL; NTSTATUS Status = STATUS_SUCCESS;
/* * Determine the required size for the heap snapshot */ if(dwFlags & TH32CS_SNAPHEAPLIST) { hi = (PRTL_PROCESS_HEAPS)HeapDebug->Heaps; nHeaps = hi->NumberOfHeaps; RequiredSnapshotSize += nHeaps * sizeof(HEAPLIST32); }
/* * Determine the required size for the module snapshot */ if(dwFlags & TH32CS_SNAPMODULE) { mi = (PRTL_PROCESS_MODULES)ModuleDebug->Modules; nModules = mi->NumberOfModules; RequiredSnapshotSize += nModules * sizeof(MODULEENTRY32W); }
/* * Determine the required size for the processes and threads snapshot */ if(dwFlags & (TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD)) { ULONG ProcOffset = 0;
ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)ProcThrdInfo; do { ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset); nProcesses++; nThreads += ProcessInfo->NumberOfThreads; ProcOffset = ProcessInfo->NextEntryOffset; } while(ProcOffset != 0);
if(dwFlags & TH32CS_SNAPPROCESS) { RequiredSnapshotSize += nProcesses * sizeof(PROCESSENTRY32W); } if(dwFlags & TH32CS_SNAPTHREAD) { RequiredSnapshotSize += nThreads * sizeof(THREADENTRY32); } }
/* * Create and map the section */
SSize.QuadPart = RequiredSnapshotSize;
InitializeObjectAttributes(&ObjectAttributes, NULL, ((dwFlags & TH32CS_INHERIT) ? OBJ_INHERIT : 0), NULL, NULL);
Status = NtCreateSection(&hSection, SECTION_ALL_ACCESS, &ObjectAttributes, &SSize, PAGE_READWRITE, SEC_COMMIT, NULL); if(!NT_SUCCESS(Status)) { return Status; }
SOffset.QuadPart = 0; ViewSize = 0; Snapshot = NULL;
Status = NtMapViewOfSection(hSection, NtCurrentProcess(), (PVOID*)&Snapshot, 0, 0, &SOffset, &ViewSize, ViewShare, 0, PAGE_READWRITE); if(!NT_SUCCESS(Status)) { NtClose(hSection); return Status; }
RtlZeroMemory(Snapshot, sizeof(TH32SNAPSHOT)); DataOffset = 0;
/* * Initialize the section data and fill it with all the data we collected */
/* initialize the heap list */ if(dwFlags & TH32CS_SNAPHEAPLIST) { Snapshot->HeapListCount = nHeaps; Snapshot->HeapListOffset = DataOffset; HeapListEntry = (LPHEAPLIST32)OffsetToPtr(Snapshot, DataOffset); for(i = 0; i < nHeaps; i++) { HeapListEntry->dwSize = sizeof(HEAPLIST32); HeapListEntry->th32ProcessID = th32ProcessID; HeapListEntry->th32HeapID = (ULONG_PTR)hi->Heaps[i].BaseAddress; HeapListEntry->dwFlags = hi->Heaps[i].Flags;
HeapListEntry++; }
DataOffset += hi->NumberOfHeaps * sizeof(HEAPLIST32); }
/* initialize the module list */ if(dwFlags & TH32CS_SNAPMODULE) { Snapshot->ModuleListCount = nModules; Snapshot->ModuleListOffset = DataOffset; ModuleListEntry = (LPMODULEENTRY32W)OffsetToPtr(Snapshot, DataOffset); for(i = 0; i < nModules; i++) { ModuleListEntry->dwSize = sizeof(MODULEENTRY32W); ModuleListEntry->th32ModuleID = 1; /* no longer used, always set to one! */ ModuleListEntry->th32ProcessID = th32ProcessID; ModuleListEntry->GlblcntUsage = mi->Modules[i].LoadCount; ModuleListEntry->ProccntUsage = mi->Modules[i].LoadCount; ModuleListEntry->modBaseAddr = (BYTE*)mi->Modules[i].ImageBase; ModuleListEntry->modBaseSize = mi->Modules[i].ImageSize; ModuleListEntry->hModule = (HMODULE)mi->Modules[i].ImageBase;
MultiByteToWideChar(CP_ACP, 0, &mi->Modules[i].FullPathName[mi->Modules[i].OffsetToFileName], -1, ModuleListEntry->szModule, sizeof(ModuleListEntry->szModule) / sizeof(ModuleListEntry->szModule[0]));
MultiByteToWideChar(CP_ACP, 0, mi->Modules[i].FullPathName, -1, ModuleListEntry->szExePath, sizeof(ModuleListEntry->szExePath) / sizeof(ModuleListEntry->szExePath[0]));
ModuleListEntry++; }
DataOffset += mi->NumberOfModules * sizeof(MODULEENTRY32W); }
/* initialize the process list */ if(dwFlags & TH32CS_SNAPPROCESS) { ULONG ProcOffset = 0;
Snapshot->ProcessListCount = nProcesses; Snapshot->ProcessListOffset = DataOffset; ProcessListEntry = (LPPROCESSENTRY32W)OffsetToPtr(Snapshot, DataOffset); ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)ProcThrdInfo; do { ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset);
ProcessListEntry->dwSize = sizeof(PROCESSENTRY32W); ProcessListEntry->cntUsage = 0; /* no longer used */ ProcessListEntry->th32ProcessID = (ULONG_PTR)ProcessInfo->UniqueProcessId; ProcessListEntry->th32DefaultHeapID = 0; /* no longer used */ ProcessListEntry->th32ModuleID = 0; /* no longer used */ ProcessListEntry->cntThreads = ProcessInfo->NumberOfThreads; ProcessListEntry->th32ParentProcessID = (ULONG_PTR)ProcessInfo->InheritedFromUniqueProcessId; ProcessListEntry->pcPriClassBase = ProcessInfo->BasePriority; ProcessListEntry->dwFlags = 0; /* no longer used */ if(ProcessInfo->ImageName.Buffer != NULL) { ULONG ExeFileLength = min(ProcessInfo->ImageName.Length, sizeof(ProcessListEntry->szExeFile) - sizeof(WCHAR)); RtlCopyMemory(ProcessListEntry->szExeFile, ProcessInfo->ImageName.Buffer, ExeFileLength); ProcessListEntry->szExeFile[ExeFileLength / sizeof(WCHAR)] = UNICODE_NULL; } else { lstrcpyW(ProcessListEntry->szExeFile, L"[System Process]"); }
ProcessListEntry++;
ProcOffset = ProcessInfo->NextEntryOffset; } while(ProcOffset != 0);
DataOffset += nProcesses * sizeof(PROCESSENTRY32W); }
/* initialize the thread list */ if(dwFlags & TH32CS_SNAPTHREAD) { ULONG ProcOffset = 0;
Snapshot->ThreadListCount = nThreads; Snapshot->ThreadListOffset = DataOffset; ThreadListEntry = (LPTHREADENTRY32)OffsetToPtr(Snapshot, DataOffset); ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)ProcThrdInfo; do { PSYSTEM_THREAD_INFORMATION ThreadInfo; ULONG n;
ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset); ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(ProcessInfo + 1);
for(n = 0; n < ProcessInfo->NumberOfThreads; n++) { ThreadListEntry->dwSize = sizeof(THREADENTRY32); ThreadListEntry->cntUsage = 0; /* no longer used */ ThreadListEntry->th32ThreadID = (ULONG_PTR)ThreadInfo->ClientId.UniqueThread; ThreadListEntry->th32OwnerProcessID = (ULONG_PTR)ThreadInfo->ClientId.UniqueProcess; ThreadListEntry->tpBasePri = ThreadInfo->BasePriority; ThreadListEntry->tpDeltaPri = 0; /* no longer used */ ThreadListEntry->dwFlags = 0; /* no longer used */
ThreadInfo++; ThreadListEntry++; }
ProcOffset = ProcessInfo->NextEntryOffset; } while(ProcOffset != 0); }
/* * We're done, unmap the view and return the section handle */
Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot);
if(NT_SUCCESS(Status)) { *SectionHandle = hSection; } else { NtClose(hSection); }
return Status;}
/* PUBLIC FUNCTIONS ***********************************************************/
/* * @implemented */BOOLWINAPIHeap32First(LPHEAPENTRY32 lphe, DWORD th32ProcessID, DWORD th32HeapID){ PRTL_DEBUG_INFORMATION DebugInfo; PRTL_HEAP_INFORMATION Heap; PRTLP_HEAP_ENTRY Block, LastBlock; 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(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 == th32HeapID) { lphe->hHandle = (HANDLE)Heap->BaseAddress; lphe->dwAddress = 0; lphe->dwBlockSize = 0; lphe->dwFlags = 0; lphe->dwLockCount = 0; lphe->dwResvd = 0; lphe->th32ProcessID = th32ProcessID; lphe->th32HeapID = (ULONG_PTR)Heap->BaseAddress;
Block = (PRTLP_HEAP_ENTRY)Heap->Entries; LastBlock = Block + Heap->NumberOfEntries;
while (Block != LastBlock && (Block->Flags & PROCESS_HEAP_UNCOMMITTED_RANGE)) { lphe->dwResvd++; lphe->dwAddress = (ULONG_PTR)((ULONG_PTR)Block->Address + Heap->EntryOverhead); Block++; }
if (Block != LastBlock && lphe->dwResvd != 0) { 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;}
/* * @implemented */BOOLWINAPIHeap32Next(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;
}
/* * @implemented */BOOLWINAPIHeap32ListFirst(HANDLE hSnapshot, LPHEAPLIST32 lphl){ PTH32SNAPSHOT Snapshot; LARGE_INTEGER SOffset; SIZE_T ViewSize; NTSTATUS Status;
CHECK_PARAM_SIZE(lphl, sizeof(HEAPLIST32));
SOffset.QuadPart = 0; ViewSize = 0; Snapshot = NULL;
Status = NtMapViewOfSection(hSnapshot, NtCurrentProcess(), (PVOID*)&Snapshot, 0, 0, &SOffset, &ViewSize, ViewShare, 0, PAGE_READWRITE); if(NT_SUCCESS(Status)) { BOOL Ret;
if(Snapshot->HeapListCount > 0) { LPHEAPLIST32 Entries = (LPHEAPLIST32)OffsetToPtr(Snapshot, Snapshot->HeapListOffset); Snapshot->HeapListIndex = 1; RtlCopyMemory(lphl, &Entries[0], sizeof(HEAPLIST32)); Ret = TRUE; } else { SetLastError(ERROR_NO_MORE_FILES); Ret = FALSE; }
NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot); return Ret; }
BaseSetLastNTError(Status); return FALSE;}
/* * @implemented */BOOLWINAPIHeap32ListNext(HANDLE hSnapshot, LPHEAPLIST32 lphl){ PTH32SNAPSHOT Snapshot; LARGE_INTEGER SOffset; SIZE_T ViewSize; NTSTATUS Status;
CHECK_PARAM_SIZE(lphl, sizeof(HEAPLIST32));
SOffset.QuadPart = 0; ViewSize = 0; Snapshot = NULL;
Status = NtMapViewOfSection(hSnapshot, NtCurrentProcess(), (PVOID*)&Snapshot, 0, 0, &SOffset, &ViewSize, ViewShare, 0, PAGE_READWRITE); if(NT_SUCCESS(Status)) { BOOL Ret;
if(Snapshot->HeapListCount > 0 && Snapshot->HeapListIndex < Snapshot->HeapListCount) { LPHEAPLIST32 Entries = (LPHEAPLIST32)OffsetToPtr(Snapshot, Snapshot->HeapListOffset); RtlCopyMemory(lphl, &Entries[Snapshot->HeapListIndex++], sizeof(HEAPLIST32)); Ret = TRUE; } else { SetLastError(ERROR_NO_MORE_FILES); Ret = FALSE; }
NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot); return Ret; }
BaseSetLastNTError(Status); return FALSE;}
/* * @implemented */BOOLWINAPIModule32First(HANDLE hSnapshot, LPMODULEENTRY32 lpme){ MODULEENTRY32W me; BOOL Ret;
CHECK_PARAM_SIZEA(lpme, sizeof(MODULEENTRY32));
me.dwSize = sizeof(MODULEENTRY32W);
Ret = Module32FirstW(hSnapshot, &me); if(Ret) { lpme->th32ModuleID = me.th32ModuleID; lpme->th32ProcessID = me.th32ProcessID; lpme->GlblcntUsage = me.GlblcntUsage; lpme->ProccntUsage = me.ProccntUsage; lpme->modBaseAddr = me.modBaseAddr; lpme->modBaseSize = me.modBaseSize; lpme->hModule = me.hModule;
WideCharToMultiByte(CP_ACP, 0, me.szModule, -1, lpme->szModule, sizeof(lpme->szModule), 0, 0); WideCharToMultiByte(CP_ACP, 0, me.szExePath, -1, lpme->szExePath, sizeof(lpme->szExePath), 0, 0); }
return Ret;}
/* * @implemented */BOOLWINAPIModule32FirstW(HANDLE hSnapshot, LPMODULEENTRY32W lpme){ PTH32SNAPSHOT Snapshot; LARGE_INTEGER SOffset; SIZE_T ViewSize; NTSTATUS Status;
CHECK_PARAM_SIZE(lpme, sizeof(MODULEENTRY32W));
SOffset.QuadPart = 0; ViewSize = 0; Snapshot = NULL;
Status = NtMapViewOfSection(hSnapshot, NtCurrentProcess(), (PVOID*)&Snapshot, 0, 0, &SOffset, &ViewSize, ViewShare, 0, PAGE_READWRITE); if(NT_SUCCESS(Status)) { BOOL Ret;
if(Snapshot->ModuleListCount > 0) { LPMODULEENTRY32W Entries = (LPMODULEENTRY32W)OffsetToPtr(Snapshot, Snapshot->ModuleListOffset); Snapshot->ModuleListIndex = 1; RtlCopyMemory(lpme, &Entries[0], sizeof(MODULEENTRY32W)); Ret = TRUE; } else { SetLastError(ERROR_NO_MORE_FILES); Ret = FALSE; }
NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot); return Ret; }
BaseSetLastNTError(Status); return FALSE;}
/* * @implemented */BOOLWINAPIModule32Next(HANDLE hSnapshot, LPMODULEENTRY32 lpme){ MODULEENTRY32W me; BOOL Ret;
CHECK_PARAM_SIZEA(lpme, sizeof(MODULEENTRY32));
me.dwSize = sizeof(MODULEENTRY32W);
Ret = Module32NextW(hSnapshot, &me); if(Ret) { lpme->th32ModuleID = me.th32ModuleID; lpme->th32ProcessID = me.th32ProcessID; lpme->GlblcntUsage = me.GlblcntUsage; lpme->ProccntUsage = me.ProccntUsage; lpme->modBaseAddr = me.modBaseAddr; lpme->modBaseSize = me.modBaseSize; lpme->hModule = me.hModule;
WideCharToMultiByte(CP_ACP, 0, me.szModule, -1, lpme->szModule, sizeof(lpme->szModule), 0, 0); WideCharToMultiByte(CP_ACP, 0, me.szExePath, -1, lpme->szExePath, sizeof(lpme->szExePath), 0, 0); }
return Ret;}
/* * @implemented */BOOLWINAPIModule32NextW(HANDLE hSnapshot, LPMODULEENTRY32W lpme){ PTH32SNAPSHOT Snapshot; LARGE_INTEGER SOffset; SIZE_T ViewSize; NTSTATUS Status;
CHECK_PARAM_SIZE(lpme, sizeof(MODULEENTRY32W));
SOffset.QuadPart = 0; ViewSize = 0; Snapshot = NULL;
Status = NtMapViewOfSection(hSnapshot, NtCurrentProcess(), (PVOID*)&Snapshot, 0, 0, &SOffset, &ViewSize, ViewShare, 0, PAGE_READWRITE); if(NT_SUCCESS(Status)) { BOOL Ret;
if((Snapshot->ModuleListCount > 0) && (Snapshot->ModuleListIndex < Snapshot->ModuleListCount)) { LPMODULEENTRY32W Entries = (LPMODULEENTRY32W)OffsetToPtr(Snapshot, Snapshot->ModuleListOffset); RtlCopyMemory(lpme, &Entries[Snapshot->ModuleListIndex++], sizeof(MODULEENTRY32W)); Ret = TRUE; } else { SetLastError(ERROR_NO_MORE_FILES); Ret = FALSE; }
NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot); return Ret; }
BaseSetLastNTError(Status); return FALSE;}
/* * @implemented */BOOLWINAPIProcess32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe){ PROCESSENTRY32W pe; BOOL Ret;
CHECK_PARAM_SIZEA(lppe, sizeof(PROCESSENTRY32));
pe.dwSize = sizeof(PROCESSENTRY32W);
Ret = Process32FirstW(hSnapshot, &pe); if(Ret) { lppe->cntUsage = pe.cntUsage; lppe->th32ProcessID = pe.th32ProcessID; lppe->th32DefaultHeapID = pe.th32DefaultHeapID; lppe->th32ModuleID = pe.th32ModuleID; lppe->cntThreads = pe.cntThreads; lppe->th32ParentProcessID = pe.th32ParentProcessID; lppe->pcPriClassBase = pe.pcPriClassBase; lppe->dwFlags = pe.dwFlags;
WideCharToMultiByte(CP_ACP, 0, pe.szExeFile, -1, lppe->szExeFile, sizeof(lppe->szExeFile), 0, 0); }
return Ret;}
/* * @implemented */BOOLWINAPIProcess32FirstW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe){ PTH32SNAPSHOT Snapshot; LARGE_INTEGER SOffset; SIZE_T ViewSize; NTSTATUS Status;
CHECK_PARAM_SIZE(lppe, sizeof(PROCESSENTRY32W));
SOffset.QuadPart = 0; ViewSize = 0; Snapshot = NULL;
Status = NtMapViewOfSection(hSnapshot, NtCurrentProcess(), (PVOID*)&Snapshot, 0, 0, &SOffset, &ViewSize, ViewShare, 0, PAGE_READWRITE); if(NT_SUCCESS(Status)) { BOOL Ret;
if(Snapshot->ProcessListCount > 0) { LPPROCESSENTRY32W Entries = (LPPROCESSENTRY32W)OffsetToPtr(Snapshot, Snapshot->ProcessListOffset);
Snapshot->ProcessListIndex = 1; RtlCopyMemory(lppe, &Entries[0], sizeof(PROCESSENTRY32W)); Ret = TRUE; } else {
SetLastError(ERROR_NO_MORE_FILES); Ret = FALSE; }
NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot); return Ret; }
BaseSetLastNTError(Status); return FALSE;}
/* * @implemented */BOOLWINAPIProcess32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe){ PROCESSENTRY32W pe; BOOL Ret;
CHECK_PARAM_SIZEA(lppe, sizeof(PROCESSENTRY32));
pe.dwSize = sizeof(PROCESSENTRY32W);
Ret = Process32NextW(hSnapshot, &pe); if(Ret) { lppe->cntUsage = pe.cntUsage; lppe->th32ProcessID = pe.th32ProcessID; lppe->th32DefaultHeapID = pe.th32DefaultHeapID; lppe->th32ModuleID = pe.th32ModuleID; lppe->cntThreads = pe.cntThreads; lppe->th32ParentProcessID = pe.th32ParentProcessID; lppe->pcPriClassBase = pe.pcPriClassBase; lppe->dwFlags = pe.dwFlags;
WideCharToMultiByte(CP_ACP, 0, pe.szExeFile, -1, lppe->szExeFile, sizeof(lppe->szExeFile), 0, 0); }
return Ret;}
/* * @implemented */BOOLWINAPIProcess32NextW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe){ PTH32SNAPSHOT Snapshot; LARGE_INTEGER SOffset; SIZE_T ViewSize; NTSTATUS Status;
CHECK_PARAM_SIZE(lppe, sizeof(PROCESSENTRY32W));
SOffset.QuadPart = 0; ViewSize = 0; Snapshot = NULL;
Status = NtMapViewOfSection(hSnapshot, NtCurrentProcess(), (PVOID*)&Snapshot, 0, 0, &SOffset, &ViewSize, ViewShare, 0, PAGE_READWRITE); if(NT_SUCCESS(Status)) { BOOL Ret;
if(Snapshot->ProcessListCount > 0 && Snapshot->ProcessListIndex < Snapshot->ProcessListCount) { LPPROCESSENTRY32W Entries = (LPPROCESSENTRY32W)OffsetToPtr(Snapshot, Snapshot->ProcessListOffset); RtlCopyMemory(lppe, &Entries[Snapshot->ProcessListIndex++], sizeof(PROCESSENTRY32W)); Ret = TRUE; } else { SetLastError(ERROR_NO_MORE_FILES); Ret = FALSE; }
NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot); return Ret; }
BaseSetLastNTError(Status); return FALSE;}
/* * @implemented */BOOLWINAPIThread32First(HANDLE hSnapshot, LPTHREADENTRY32 lpte){ PTH32SNAPSHOT Snapshot; LARGE_INTEGER SOffset; SIZE_T ViewSize; NTSTATUS Status;
CHECK_PARAM_SIZE(lpte, sizeof(THREADENTRY32));
SOffset.QuadPart = 0; ViewSize = 0; Snapshot = NULL;
Status = NtMapViewOfSection(hSnapshot, NtCurrentProcess(), (PVOID*)&Snapshot, 0, 0, &SOffset, &ViewSize, ViewShare, 0, PAGE_READWRITE); if(NT_SUCCESS(Status)) { BOOL Ret;
if(Snapshot->ThreadListCount > 0) { LPTHREADENTRY32 Entries = (LPTHREADENTRY32)OffsetToPtr(Snapshot, Snapshot->ThreadListOffset); Snapshot->ThreadListIndex = 1; RtlCopyMemory(lpte, &Entries[0], sizeof(THREADENTRY32)); Ret = TRUE; } else { SetLastError(ERROR_NO_MORE_FILES); Ret = FALSE; }
NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot); return Ret; }
BaseSetLastNTError(Status); return FALSE;}
/* * @implemented */BOOLWINAPIThread32Next(HANDLE hSnapshot, LPTHREADENTRY32 lpte){ PTH32SNAPSHOT Snapshot; LARGE_INTEGER SOffset; SIZE_T ViewSize; NTSTATUS Status;
CHECK_PARAM_SIZE(lpte, sizeof(THREADENTRY32));
SOffset.QuadPart = 0; ViewSize = 0; Snapshot = NULL;
Status = NtMapViewOfSection(hSnapshot, NtCurrentProcess(), (PVOID*)&Snapshot, 0, 0, &SOffset, &ViewSize, ViewShare, 0, PAGE_READWRITE); if(NT_SUCCESS(Status)) { BOOL Ret;
if(Snapshot->ThreadListCount > 0 && Snapshot->ThreadListIndex < Snapshot->ThreadListCount) { LPTHREADENTRY32 Entries = (LPTHREADENTRY32)OffsetToPtr(Snapshot, Snapshot->ThreadListOffset); RtlCopyMemory(lpte, &Entries[Snapshot->ThreadListIndex++], sizeof(THREADENTRY32)); Ret = TRUE; } else { SetLastError(ERROR_NO_MORE_FILES); Ret = FALSE; }
NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot); return Ret; }
BaseSetLastNTError(Status); return FALSE;}
/* * @implemented */BOOLWINAPIToolhelp32ReadProcessMemory(DWORD th32ProcessID, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T cbRead, SIZE_T* lpNumberOfBytesRead){ HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, th32ProcessID); if(hProcess != NULL) { BOOL Ret = ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, cbRead, lpNumberOfBytesRead); CloseHandle(hProcess); return Ret; }
return FALSE;}
/* * @implemented */HANDLEWINAPICreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID){ PRTL_DEBUG_INFORMATION HeapDebug, ModuleDebug; PVOID ProcThrdInfo; SIZE_T ProcThrdInfoSize; NTSTATUS Status; HANDLE hSnapShotSection = NULL;
if(th32ProcessID == 0) { th32ProcessID = GetCurrentProcessId(); }
/* * Get all information required for the snapshot */ Status = TH32CreateSnapshot(dwFlags, th32ProcessID, &HeapDebug, &ModuleDebug, &ProcThrdInfo, &ProcThrdInfoSize); if(!NT_SUCCESS(Status)) { BaseSetLastNTError(Status); return NULL; }
/* * Create a section handle and initialize the collected information */ Status = TH32CreateSnapshotSectionInitialize(dwFlags, th32ProcessID, HeapDebug, ModuleDebug, ProcThrdInfo, &hSnapShotSection);
/* * Free the temporarily allocated memory which is no longer needed */ TH32FreeAllocatedResources(HeapDebug, ModuleDebug, ProcThrdInfo, ProcThrdInfoSize);
if(!NT_SUCCESS(Status)) { BaseSetLastNTError(Status); return NULL; }
return hSnapShotSection;}
/* EOF */