© 2004 Microsoft Corporation. All rights reserved.
Figure 1 Dependency Walker

Figure 1 Dependency Walker
Figure 2 Process Explorer

Figure 2 Process Explorer
Figure 3 DllSpy

Figure 3 DllSpy
Figure 4 ProcessSpy

Figure 4 ProcessSpy
Figure 5 Methods for Enumerating Running Processes

Windows NT, Windows 2000, Windows XP
Gets information about process, driver, module, memory, and working set
Performance counters
Windows NT, Windows 2000, Windows XP
Provides more information than the process list and can be used from a remote computer
Windows 9x, Windows 2000, Windows XP
Gets information about process, thread, module, and heap
Figure 6 Using CProcessList to List Running Processes
// get one process after the other
   CProcess* pProcess = NULL;
   POSITION  Pos = 0;
   for (
         pProcess = ProcessList.GetFirst(Pos); 
         (pProcess != NULL); 
         pProcess = ProcessList.GetNext(Pos)
      if (pProcess != NULL)
      // do what you want with the process information
Figure 7 Refreshing the Processes List
void CProcessList::Refresh()
// don't forget to reset and free the current list

// store the current process list
   DWORD aProcesses[MAX_PROCESS];
   DWORD cbNeeded = 0;

// get a snapshot of the processes
   if (!g_PSAPI.EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
// Calculate how many process IDs were returned
   DWORD cProcesses = cbNeeded / sizeof(DWORD);

// attach a CProcess object to each process ID
   DWORD     dwProcessID;
   CProcess* pProcess;
   for (
         DWORD dwCurrentProcess = 0; 
         dwCurrentProcess < cProcesses; 
      dwProcessID = aProcesses[dwCurrentProcess];

   // add the process definition into the map
      pProcess = new CProcess(TRUE);
      if (pProcess != NULL)
      // fill in the process information for the current process ID
         if (!pProcess->AttachProcess(aProcesses[dwCurrentProcess]))
            delete pProcess;
         // store into the map
            m_ProcessMap[(LPVOID)dwProcessID] = pProcess;

// a second iteration is needed to know the process children
Figure 8 Process Details

Uses GetModuleBaseName with NULL as parameter but without the ".EXE"
Uses GetModuleFileNameEx with NULL as parameter
GetMainWindowHandle GetMainWindowTitle
See the GetMainWindowHandle discussion
Uses NtQueryInformationProcess with ProcessBasicInformation
Uses NtQueryInformationProcess with ProcessHandleCount
Uses GetGuiResources with GR_USEROBJECTS
Uses GetGuiResources with GR_GDIOBJECTS
Uses GetProcessMemoryInfo
See GetProcessCmdLine discussion
See GetProcessOwner details
ProcessIdToSessionId (see Fast User Switching discussion)
CModuleList is a wrapper class around EnumProcessModules and GetModuleFileNameEx
GetChildrenCount and children list
There is no API (even undocumented) to get the list of processes spawned by a process. But since the parent of each process is known, it is easy to add a process to the child list of its parent. (See the implementation of SetChildrenList)
Figure 10 TLIST Detailed Output for a Running Process
C:\>tlist 632
 632 CMD.EXE           C:\WINNT\System32\cmd.exe - tlist 632
   CWD:     C:\
   CmdLine: C:\WINNT\System32\cmd.exe /k cd "C:\"
   VirtualSize:    13408 KB   PeakVirtualSize:    13412 KB
   WorkingSetSize:   948 KB   PeakWorkingSetSize:   952 KB
   NumberOfThreads: 1
    968 Win32StartAddr:0x4ad1a420 LastErr:0x000000cb State:Waiting
  5.0.2195.1600 shp  0x4ad00000  cmd.exe
  5.0.2195.1600 shp  0x77f80000  ntdll.dll
  5.0.2195.1600 shp  0x77e80000  KERNEL32.dll
  5.0.2195.1600 shp  0x77e10000  USER32.dll
  5.0.2195.1340 shp  0x77f40000  GDI32.DLL
  5.0.2195.1600 shp  0x77db0000  ADVAPI32.dll
  5.0.2195.1615 shp  0x77d40000  RPCRT4.DLL
     6.1.8637.0 shp  0x78000000  MSVCRT.dll
Figure 12 ProcessXP Output
3  open sessions
   ID   State             Window Station
   0    (WTSActive)       Console  [Administrator]
   1    (WTSDisconnected)          [standard]
   2    (WTSDisconnected)          [Player]

30 running processes
   0    0                       ?
   0    4       System          \\NT AUTHORITY\SYSTEM
   0    388     smss.exe        \\NT AUTHORITY\SYSTEM
   0    600     csrss.exe       \\NT AUTHORITY\SYSTEM
   0    632     winlogon.exe    \\NT AUTHORITY\SYSTEM
   0    676     services.exe    \\NT AUTHORITY\SYSTEM
   0    688     lsass.exe       \\NT AUTHORITY\SYSTEM
   0    856     svchost.exe     \\NT AUTHORITY\SYSTEM
   0    968     svchost.exe     \\NT AUTHORITY\SYSTEM
   0    1160    svchost.exe     \\NT AUTHORITY\NETWORK SERVICE
   0    1192    svchost.exe     \\NT AUTHORITY\LOCAL SERVICE
   0    1252    spoolsv.exe     \\NT AUTHORITY\SYSTEM
   0    1888    explorer.exe    \\MACHINE\Administrator
   0    2004    msmsgs.exe      \\MACHINE\Administrator
   0    104     svchost.exe     \\NT AUTHORITY\SYSTEM
   1    1496    csrss.exe       \\NT AUTHORITY\SYSTEM
   1    1172    winlogon.exe    \\NT AUTHORITY\SYSTEM
   1    1640    explorer.exe    \\MACHINE\standard
   1    1900    ctfmon.exe      \\MACHINE\standard
   1    352     notepad.exe     \\MACHINE\standard
   1    1896    freecell.exe    \\MACHINE\standard
   2    416     csrss.exe       \\NT AUTHORITY\SYSTEM
   2    268     winlogon.exe    \\NT AUTHORITY\SYSTEM
   2    1784    explorer.exe    \\MACHINE\Player
   0    1820    msiexec.exe     \\NT AUTHORITY\SYSTEM
   2    1544    ctfmon.exe      \\MACHINE\Player
   2    1632    msmsgs.exe      \\MACHINE\Player
   2    1268    wordpad.exe     \\MACHINE\Player
   0    1696    wuauclt.exe     \\MACHINE\Administrator
   0    1996    ProcessXP.exe   \\MACHINE\Administrator 
Figure 13 Module Walking Using TOOLHELP32
// Enumerate the module list for this process.  Start by taking
// another ToolHelp32 snapshot, this time of the process's module list
HANDLE hSnapshotModule;
hSnapshotModule = pfnCreateToolhelp32Snapshot( TH32CS_SNAPMODULE,
                                           procEntry.th32ProcessID );
if ( !hSnapshotModule )

// Iterate through each module in the snapshot
MODULEENTRY32 modEntry = { sizeof(MODULEENTRY32) };
BOOL fModWalkContinue;

for (fModWalkContinue = pfnModule32First(hSnapshotModule,&modEntry);
    fModWalkContinue = pfnModule32Next(hSnapshotModule,&modEntry) )
   // Hack!  Cheezy way to figure out if this is EXE module itself
   // If so, we don't want to add it to the module list
   if ( 0 == stricmp( modEntry.szExePath, procEntry.szExeFile ) )

   // Determine if this is a DLL we've already seen                
   PModuleInstance pModInst = modList.Lookup(modEntry.hModule,
                                             modEntry.szExePath );

   // If we haven't see it, add it to the list
   if ( !pModInst )
       pModInst = modList.Add( modEntry.hModule, modEntry.szExePath );

   // Add this process to the list of processes using the DLL              
   pModInst->AddProcessReference( procEntry.th32ProcessID );       

CloseHandle( hSnapshotModule ); // Done with module list snapshot
Figure 14 Accessor Methods

HMODULE GetModuleHandle
Address where the DLL is mapped
CString& GetFullPathName
From either TOOLHELP32::Module32xxx Or PSAPI::GetModuleFilenameEx
CString& GetModuleName
Same as GetFullPathName
CString& GetPathName
Same as GetFullPathName
Figure 15 Accessor Details

DWORD GetBaseAddress
Uses PE_EXE::GetImageBase to get the preferred loading address
void GetFileTime(FILETIME& ft)
Uses GetFileTime API from KERNEL32.DLL to know when it has been created, modified, and last accessed
CString& GetFileTime
Get the same info as the previous one but in text format using GetFileDateAsString/GetFileTimeAsString helper functions
DWORD GetFileSize
Uses PE_EXE::GetFileSize to get the size of the file in bytes
CString& GetSubSystem
Uses PE_EXE::GetSubSystem to know the module subsystem among the IMAGE_SUBSYSTEM_xxx values from winnt.h; in the last version of this file, IMAGE_SUBSYSTEM_XBOX could be found
void GetLinkTime(FILETIME& ft)
Uses PE_EXE::GetTimeDateStamp to discover when the module has been linked
CString& GetLinkTime
Gets the same info as the previous one but in text format using GetFileDateAsString/GetFileTimeAsString helper functions
WORD GetLinkVersion
Uses PE_EXE::GetLinkerVersion to get the version of linker used to build the module
Figure 16 File Types According to Version Information

Contains debugging information or is compiled with debugging features enabled
Version structure was created dynamically; therefore, some of the members in this structure may be empty or incorrect. This flag should never be set in a file's VS_VERSIONINFO data
Has been modified and is not identical to the original shipping file of the same version number
A development version, not a commercially released product
Not built using standard release procedures. If this flag is set, the StringFileInfo structure should contain a PrivateBuild entry
Built by the original company using standard release procedures but is a variation of the normal file of the same version number. If this flag is set, the StringFileInfo structure should contain a SpecialBuild entry
Figure 17 Flags in the dwFileType Field

Unknown to the system
Contains an application
Contains a DLL
Contains a device driver. If dwFileType is VFT_DRV, dwFileSubtype contains a more specific description of the driver
Contains a font. If dwFileType is VFT_FONT, dwFileSubtype contains a more specific description of the font file
Contains a virtual device
Contains a static-link library
Page view tracker