Snapshots of the System
Snapshots are at the core of the tool help functions. A snapshot is a read-only copy of the current state of one or more of the following lists that reside in system memory:
Processes that use tool help functions access these lists from snapshots instead of directly from the operating system. The lists in system memory change when processes are started and ended, threads are created and destroyed, executable modules are loaded and unloaded from system memory, and heaps are created and destroyed. The use of information from a snapshot prevents inconsistencies. Otherwise, changes to a list could possibly cause a thread to incorrectly traverse the list or cause an access violation (a GP fault). For example, if an application traverses the thread list while other threads are created or terminated, information that the application is using to traverse the thread list might become outdated and could cause an error for the application traversing the list. To take a snapshot of the system memory, use the CreateToolhelp32Snapshot() function. You can control the content of a snapshot by specifying one or more of the following values when calling this function:
The TH32CS_SNAPHEAPLIST and TH32CS_SNAPMODULE values are process specific. When these values are specified, the heap and module lists of the specified process are included in the snapshot. If you specify zero as the process identifier, the current process is used. The TH32CS_SNAPTHREAD value always creates a system-wide snapshot even if a process identifier is passed to CreateToolhelp32Snapshot().
To enumerate the heap or module state for all processes, specify the TH32CS_SNAPALL value and the process identifier of the current process. Then, for each additional process in the snapshot, call CreateToolhelp32Snapshot() again, specifying its process identifier and the TH32CS_SNAPHEAPLIST or TH32CS_SNAPMODULE value.
You can retrieve an extended error status code for CreateToolhelp32Snapshot() by using the GetLastError() function. When your process finishes using a snapshot, destroy it using the CloseHandle() function. If you do not destroy a snapshot, the process will leak memory until it exits, at which time the system reclaims the memory. The snapshot handle acts like a file handle and is subject to the same rules regarding the processes and threads in which it can be used. To specify that the handle is inheritable, create the snapshot using the TH32CS_INHERIT value.
Process Walking
A snapshot that includes the process list contains information about each currently executing process. You can retrieve information for the first process in the list by using the Process32First() function. After retrieving the first process in the list, you can traverse the process list for subsequent entries by using the Process32Next() function. Process32First() and Process32Next() fill a PROCESSENTRY32 structure with information about a process in the snapshot. You can retrieve an extended error status code for Process32First() and Process32Next() by using the GetLastError() function. You can read the memory in a specific process into a buffer by using the Toolhelp32ReadProcessMemory() function (or the VirtualQueryEx() function). The contents of the th32ProcessID() and th32ParentProcessID() members of PROCESSENTRY32 are process identifiers and can be used by any functions that require a process identifier.
Thread Walking
A snapshot that includes the thread list contains information about each thread of each currently executing process. You can retrieve information for the first thread in the list by using the Thread32First() function. After retrieving the first thread in the list, you can retrieve information for subsequent threads by using the Thread32Next() function. Thread32First() and Thread32Next() fill a THREADENTRY32 structure with information about individual threads in the snapshot. You can enumerate the threads of a specific process by taking a snapshot that includes the threads and then by traversing the thread list, keeping information about the threads that have the same process identifier as the specified process. You can retrieve an extended error status code for Thread32First() and Thread32Next() by using the GetLastError() function. The contents of the th32ThreadID member of THREADENTRY32 is a thread identifier and can be used by any functions that require a thread identifier.
Module Walking
A snapshot that includes the module list for a specified process contains information about each module, executable file, or dynamic-link library (DLL), used by the specified process. You can retrieve information for the first module in the list by using the Module32First() function. After retrieving the first module in the list, you can retrieve information for subsequent modules in the list by using the Module32Next() function. Module32First() and Module32Next() fill a MODULEENTRY32 structure with information about the module.
You can retrieve an extended error status code for Module32First() and Module32Next() by using the GetLastError() function. The module identifier, which is specified in the th32ModuleID member of MODULEENTRY32, only has meaning in 16-bit Windows.
Heap Lists and Heap Walking
A snapshot that includes the heap list for a specified process contains identification information for each heap associated with the specified process and detailed information about each heap. You can retrieve an identifier for the first heap of the heap list by using the Heap32ListFirst() function. After retrieving the first heap in the list, you can traverse the heap list for subsequent heaps associated with the process by using the Heap32ListNext() function. Heap32ListFirst() and Heap32ListNext() fill a HEAPLIST32 structure with the process identifier, the heap identifier, and flags describing the heap.
You can retrieve information about the first block of a heap by using the Heap32First() function. After retrieving the first block of a heap, you can retrieve information about subsequent blocks of the same heap by using the Heap32Next() function. Heap32First() and Heap32Next() fill a HEAPENTRY32 structure with information for the appropriate block of a heap. You can retrieve an extended error status code for Heap32ListFirst(), Heap32ListNext(), Heap32First(), and Heap32Next() by using the GetLastError() function. The heap identifier, which is specified in the th32HeapID member of the HEAPENTRY32 structure, has meaning only to the tool help functions. It is not a handle, nor is it usable by other functions.