process.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 8k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////
  2. //                     Microsoft Windows                          //
  3. //              Copyright(c) Microsoft Corp., 1998                   //
  4. ///////////////////////////////////////////////////////////////////////
  5. //
  6. // processs ID related routines 
  7. //
  8. #include "inetcplp.h"
  9. #include <tchar.h>
  10. #include "psapi.h"
  11. #include "tlhelp32.h"
  12. #include "process.h"
  13. CProcessInfo::CProcessInfo()
  14. {
  15.     _fNT = (IsOS(OS_NT5)|| IsOS(OS_NT4));
  16.     // init w95 func pointers
  17.     _lpfnCreateToolhelp32Snapshot = NULL;
  18.     _lpfnProcess32First = NULL;
  19.     _lpfnProcess32Next  = NULL;
  20.     
  21.     // init NT func pointers
  22.     _hPsapiDLL = NULL;
  23.     _lpfnEnumProcesses = NULL;
  24.     _lpfnGetModuleBaseName = NULL;
  25.     // process info array
  26.     _pProcInfoArray  = NULL;
  27.     _nAlloced        = 0;
  28.     _iProcInfoCount  = 0;
  29. }
  30. CProcessInfo::~CProcessInfo()
  31. {
  32.     if(_pProcInfoArray)
  33.         LocalFree(_pProcInfoArray);
  34.     if(_hPsapiDLL)
  35.     FreeLibrary (_hPsapiDLL);
  36. }
  37. #define ALLOC_STEP 50
  38. HRESULT CProcessInfo::MakeRoomForInfoArray(int n)
  39. {
  40.     HRESULT hr = S_OK;
  41.     if (n > _nAlloced)
  42.     {
  43.         PROCESSINFO *p;
  44.         int nSaved = _nAlloced;
  45.         while(n > _nAlloced)
  46.             _nAlloced += ALLOC_STEP;
  47.         if (!_pProcInfoArray)
  48.         {
  49.             p = (PROCESSINFO *)LocalAlloc(LPTR, sizeof(PROCESSINFO)*_nAlloced);
  50.         }
  51.         else
  52.         {
  53.             p = (PROCESSINFO *)LocalReAlloc(_pProcInfoArray, 
  54.                                             sizeof(PROCESSINFO)*_nAlloced, 
  55.                                             LMEM_MOVEABLE|LMEM_ZEROINIT);
  56.         }
  57.         if (p)
  58.             _pProcInfoArray = p;
  59.         else
  60.         {
  61.             hr        = E_FAIL;
  62.             _nAlloced = nSaved; 
  63.         }
  64.     }
  65.     return hr;
  66. }
  67. HRESULT CProcessInfo::EnsureProcessInfo()
  68. {
  69.     HRESULT hr = S_OK;
  70.     if (!_pProcInfoArray)
  71.     {
  72.         if (_fNT)
  73.         {
  74.             NTCreateProcessList();
  75.         }
  76.         else
  77.         {
  78.             W95CreateProcessList();
  79.         }
  80.     }
  81.     return hr;
  82. }
  83. HRESULT CProcessInfo::GetExeNameFromPID(DWORD dwPID, LPTSTR szFile, int cchFile)
  84. {
  85.     HRESULT hr;
  86.     hr = EnsureProcessInfo();
  87.     if (hr == S_OK)
  88.     {
  89.         for (int i = 0; i < _iProcInfoCount; i++)
  90.         {
  91.             if (_pProcInfoArray[i].dwPID == dwPID)
  92.             {
  93.                 _tcsncpy(szFile, _pProcInfoArray[i].szExeName, cchFile);
  94.                 break;
  95.             }
  96.         }
  97.     }
  98.     return hr;
  99. }
  100. HRESULT CProcessInfo::NTCreateProcessList()
  101. // Testing routine to see if we can get Process IDs.
  102. {
  103. HRESULT hr = E_FAIL;
  104.     hr = NTInitPsapi();
  105.     if (hr == S_OK)
  106.     {
  107.         UINT iIndex;
  108.         DWORD aProcesses[100], cbNeeded;
  109.         if (_lpfnEnumProcesses((DWORD * )aProcesses, sizeof(aProcesses), (DWORD *)&cbNeeded))
  110.         {
  111.             // Calculate how many process IDs were returned
  112.             DWORD cProcesses = cbNeeded / sizeof(DWORD);
  113.             
  114.             hr = MakeRoomForInfoArray(cProcesses);
  115.             if (S_OK == hr)
  116.             {
  117.                 // Spit out the information for each ID
  118.                 for ( iIndex = 0; iIndex < cProcesses; iIndex++ )
  119.                 {
  120.                     hr = NTFillProcessList(aProcesses[iIndex], iIndex);
  121.                 }
  122.                 if (hr == S_OK)
  123.                     _iProcInfoCount = iIndex;
  124.             }
  125.         }
  126.     }
  127.     return hr;
  128. }
  129. HRESULT CProcessInfo::NTInitPsapi()
  130. {
  131.     HRESULT hr;
  132.     // First, load the NT specific library, PSAPI.DLL.
  133.     if (!_hPsapiDLL)
  134.         _hPsapiDLL = LoadLibrary(TEXT("PSAPI.DLL"));
  135.     if (_hPsapiDLL)
  136.     {
  137.         _lpfnEnumProcesses 
  138.         = (LPFNENUMPROCESSES)GetProcAddress(_hPsapiDLL, "EnumProcesses");
  139.         _lpfnGetModuleBaseName 
  140.         = (LPFNGETMODULEBASENAMEW)GetProcAddress(_hPsapiDLL, "GetModuleBaseNameW");
  141.     }
  142.     Assert(_lpfnEnumProcesses && _lpfnGetModuleBaseName);
  143.     hr = (_lpfnEnumProcesses 
  144.         && _lpfnGetModuleBaseName) ? S_OK : E_FAIL;
  145.     return hr;
  146. }
  147. HRESULT CProcessInfo::NTFillProcessList(DWORD dwProcessID, int iIndex)
  148. {
  149. HRESULT hr = E_FAIL;
  150.     TCHAR szProcessName[MAX_PATH] = TEXT("unknown");
  151. int i = -1;
  152.     HANDLE hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessID );
  153.     if ( hProcess )
  154.     {
  155.         DWORD dw = _lpfnGetModuleBaseName( hProcess, NULL, szProcessName, sizeof(szProcessName) );
  156.         if (dw > 0)
  157.                 hr = S_OK;
  158.         CloseHandle (hProcess);
  159.     }
  160.     if (hr == S_OK)
  161.     {
  162.         // Add PID and associated .EXE file info to list...
  163.         _pProcInfoArray[iIndex].dwPID = dwProcessID;
  164.         
  165.         _tcsncpy (_pProcInfoArray[iIndex].szExeName, szProcessName, 
  166.                   ARRAYSIZE(_pProcInfoArray[iIndex].szExeName));
  167.     }
  168.     return hr;
  169. }
  170. HRESULT CProcessInfo::W95CreateProcessList()
  171. {
  172. HRESULT hr = E_FAIL;
  173. if (S_OK == W95InitToolhelp32())
  174. {
  175. hr = W95FillProcessList();
  176. }
  177. return (hr);
  178. }
  179. HRESULT CProcessInfo::W95InitToolhelp32()
  180. // Win95 specific, sets up the things we need to get the process IDs.
  181. {
  182.     HRESULT hr      = E_FAIL;
  183.     HMODULE hKernel = NULL;
  184.     // Obtain a module handle to KERNEL so that we can get the addresses of
  185.     // the 32-bit Toolhelp functions we need.
  186.     hKernel = GetModuleHandle(TEXT("KERNEL32.DLL"));
  187.     if (hKernel)
  188.     {
  189.         _lpfnCreateToolhelp32Snapshot =
  190.           (CREATESNAPSHOT)GetProcAddress(hKernel, "CreateToolhelp32Snapshot");
  191.         _lpfnProcess32First = (PROCESSWALK)GetProcAddress(hKernel, "Process32First");
  192.         _lpfnProcess32Next  = (PROCESSWALK)GetProcAddress(hKernel, "Process32Next");
  193.         // All of our addresses must be non-NULL in order for us to be
  194.         // successful.  If even one of these addresses is NULL, then we
  195.         // must fail because we won't be able to walk one of the lists
  196.         // we need to.
  197.         if (_lpfnProcess32First && _lpfnProcess32Next && _lpfnCreateToolhelp32Snapshot)
  198.             hr = S_OK;
  199.     }
  200.     return (hr);
  201. }
  202. #ifdef UNICODE
  203. #undef PROCESSENTRY32
  204. #endif  // !UNICODE
  205. HRESULT CProcessInfo::W95FillProcessList()
  206. // Fills in the array of process info, and also set the count of the items
  207. {
  208.     HRESULT hr = E_FAIL;
  209.     HANDLE         hProcessSnap = NULL;
  210.     PROCESSENTRY32 pe32         = {0};
  211.     // Take a snapshot of all processes currently in the system.
  212.     hProcessSnap = _lpfnCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  213.     if (hProcessSnap == (HANDLE)-1)
  214.         return hr;
  215.     // Size of the PROCESSENTRY32 structure must be filled out before use.
  216.     pe32.dwSize = sizeof(PROCESSENTRY32);
  217.     // Walk the snapshot of processes and for each process, get information
  218.     // to display.
  219.     if (_lpfnProcess32First(hProcessSnap, &pe32))
  220.     {
  221.         int iIndex = 0;
  222.         do // Add PID and associated .EXE file info to list...
  223.         {
  224.             hr = MakeRoomForInfoArray(iIndex+1);
  225.             if (hr != S_OK)
  226.                 break;
  227.             _pProcInfoArray[iIndex].dwPID = pe32.th32ProcessID;
  228.             LPSTR pszFile = PathFindFileNameA(pe32.szExeFile);
  229.             if (pszFile)
  230.             {
  231.                 SHAnsiToUnicode( pszFile, _pProcInfoArray[iIndex].szExeName, 
  232.                                  ARRAYSIZE(_pProcInfoArray[iIndex].szExeName)); 
  233.             }
  234.             iIndex++;
  235.         }
  236.         while (_lpfnProcess32Next(hProcessSnap, &pe32));
  237.         _iProcInfoCount = iIndex; // takes care of the last failure
  238.         hr = S_OK;
  239.     }
  240.     CloseHandle (hProcessSnap);
  241.     return hr;
  242. }