Figures
© 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

Method
Platform
Note
PSAPI
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
TOOLHELP32
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
   DefaultReset();

// 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))
      return;
    
// 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; 
         dwCurrentProcess++
       )
   {
      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;
         else
         // store into the map
            m_ProcessMap[(LPVOID)dwProcessID] = pProcess;
      }
   }

// a second iteration is needed to know the process children
   SetChildrenList();
}
Figure 8 Process Details

Method
Description
GetName
Uses GetModuleBaseName with NULL as parameter but without the ".EXE"
GetFileName
Uses GetModuleFileNameEx with NULL as parameter
GetMainWindowHandle GetMainWindowTitle
See the GetMainWindowHandle discussion
GetParentProcessID
Uses NtQueryInformationProcess with ProcessBasicInformation
GetKERNELHandleCount
Uses NtQueryInformationProcess with ProcessHandleCount
GetUSERHandleCount
Uses GetGuiResources with GR_USEROBJECTS
GetGDIHandleCount
Uses GetGuiResources with GR_GDIOBJECTS
GetWorkingSet
Uses GetProcessMemoryInfo
GetCmdLine
See GetProcessCmdLine discussion
GetOwner
See GetProcessOwner details
GetSessionID
ProcessIdToSessionId (see Fast User Switching discussion)
GetModuleList
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 )
   continue;

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

for (fModWalkContinue = pfnModule32First(hSnapshotModule,&modEntry);
    fModWalkContinue;
    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 ) )
       continue;

   // 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

Accessor
Notes
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

Accessor
Notes
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

Flag
Description
VS_FF_DEBUG
Contains debugging information or is compiled with debugging features enabled
VS_FF_INFOINFERRED
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
VS_FF_PATCHED
Has been modified and is not identical to the original shipping file of the same version number
VS_FF_PRERELEASE
A development version, not a commercially released product
VS_FF_PRIVATEBUILD
Not built using standard release procedures. If this flag is set, the StringFileInfo structure should contain a PrivateBuild entry
VS_FF_SPECIALBUILD
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

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