home *** CD-ROM | disk | FTP | other *** search
/ Exame Informatica 139 / Exame Informatica 139.iso / Revista / Flash / Uniform Server / diskw / docs / SRC / pskill.c next >
Encoding:
C/C++ Source or Header  |  2005-07-06  |  8.3 KB  |  295 lines

  1. /*
  2.  * pskill.c
  3.  *
  4.  * Version 3.3
  5.  *
  6.  * Copyright (C) 2004-2005 Anatoliy & Taras Slobodskyy
  7.  */
  8.  
  9.  
  10. #include <windows.h>
  11. #include <tchar.h>
  12. #include <stdio.h>
  13. #include <stddef.h>
  14. #include <tlhelp32.h>
  15.  
  16.  
  17. enum tagErrorCodes
  18.     {
  19.     ERROR_SYSTEM = 2,
  20.     ERROR_PLATFORM,
  21.     ERROR_USAGE
  22.     };
  23.  
  24.  
  25. /*
  26.  * type definition for application-defined callback function
  27.  */
  28. typedef BOOL (CALLBACK *LPCALLBACK)(DWORD, LPTSTR, LPTSTR, LPARAM);
  29.  
  30.  
  31. /*
  32.  * callback function for application-defined logic
  33.  * return: TRUE  - to continue enumeration
  34.  *         FALSE - to stop enumeration
  35.  */
  36. BOOL CALLBACK
  37. EnumCallback(DWORD dwProcessID, LPTSTR lpProcessName,
  38.              LPTSTR lpTargetName, LPARAM lParam)
  39. {
  40.     if ( _tcsicmp(lpProcessName, lpTargetName) == 0 )
  41.         if ( (BOOL)lParam )                             // query only
  42.             {
  43.             _tprintf(_T("%s is running.\n"), lpProcessName);
  44.             return FALSE;
  45.             }
  46.         else                                            // kill if matched
  47.             {
  48.             HANDLE hProcess = OpenProcess(PROCESS_TERMINATE,
  49.                                           FALSE, dwProcessID);
  50.             if ( hProcess )
  51.                 {
  52.                 TerminateProcess(hProcess, (DWORD) -1);
  53.                 CloseHandle(hProcess);
  54.                 }
  55.             }
  56.  
  57.     return TRUE;
  58. }
  59.  
  60.  
  61. /*
  62.  * exit the current process after printing an optional error message
  63.  */
  64. static void
  65. ErrorExit(LPTSTR lpErrMsg, UINT uExitCode)
  66. {
  67.     if ( lpErrMsg )
  68.         switch ( uExitCode )
  69.             {
  70.             case ERROR_SYSTEM:
  71.                 _tprintf(_T("System error: %s\n"), lpErrMsg);
  72.                 break;
  73.  
  74.             case ERROR_USAGE:
  75.                 _tprintf(_T("%s\n\n"), lpErrMsg);   // print an extra blank line
  76.                 break;                              // above the usage message
  77.  
  78.             default:
  79.                 _tprintf(_T("%s\n"), lpErrMsg);
  80.                 break;
  81.             }
  82.  
  83.     // print usage on usage error regardless of lpErrMsg
  84.     if ( uExitCode == ERROR_USAGE )
  85.         _tprintf(_T("%s\n\n%s\n%s\n"),
  86.                  _T("Usage: pskill <ProcessName> [c]"),
  87.                  _T("      with c - kill the process"),
  88.                  _T("   without c - query only"));
  89.  
  90.     ExitProcess(uExitCode);
  91. }
  92.  
  93.  
  94. /*
  95.  * enumerate processes using PSAPI
  96.  */
  97. static int
  98. EnumPSAPI(LPCALLBACK lpCallback, LPTSTR lpTargetName, LPARAM lParam)
  99. {
  100.     typedef BOOL  (WINAPI *LPEP)(DWORD *, DWORD, DWORD *);
  101.     typedef BOOL  (WINAPI *LPEPM)(HANDLE, HMODULE *, DWORD, LPDWORD);
  102.     typedef DWORD (WINAPI *LPGMBN)(HANDLE, HMODULE, LPTSTR, DWORD);
  103.  
  104.     LPEP   lpEnumProcesses;
  105.     LPEPM  lpEnumProcessModules;
  106.     LPGMBN lpGetModuleBaseName;
  107.  
  108.     DWORD aProcesses[1024], cbNeeded, cProcesses, i;
  109.     BOOL  bContinue;
  110.  
  111.     HINSTANCE hDLL = LoadLibrary("psapi.dll");
  112.  
  113.     if ( !hDLL )
  114.         ErrorExit(_T("LoadLibrary"), ERROR_SYSTEM);
  115.  
  116.     lpEnumProcesses = (LPEP)GetProcAddress(hDLL, "EnumProcesses");
  117.     lpEnumProcessModules = (LPEPM)GetProcAddress(hDLL, "EnumProcessModules");
  118.     lpGetModuleBaseName = (LPGMBN)GetProcAddress(hDLL, "GetModuleBaseNameA");
  119.  
  120.     if ( lpEnumProcesses && lpEnumProcessModules && lpGetModuleBaseName )
  121.         bContinue = lpEnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded);
  122.     else
  123.         {
  124.         FreeLibrary(hDLL);
  125.         ErrorExit(_T("GetProcAddress"), ERROR_SYSTEM);
  126.         }
  127.  
  128.     if ( !bContinue )
  129.         {
  130.         FreeLibrary(hDLL);
  131.         ErrorExit(_T("EnumProcesses"), ERROR_SYSTEM);
  132.         }
  133.  
  134.     for ( i = 0, cProcesses = cbNeeded / sizeof(DWORD);
  135.           i < cProcesses && bContinue;
  136.           i++ )
  137.         {
  138.         TCHAR szProcessName[MAX_PATH] = "";
  139.         HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
  140.                                       FALSE, aProcesses[i]);
  141.         if ( hProcess )
  142.             {
  143.             HMODULE hMod;
  144.             DWORD cbModules;
  145.  
  146.             // get the process name, which is in the 1st module
  147.             if ( lpEnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbModules) )
  148.                 lpGetModuleBaseName(hProcess, hMod, szProcessName, MAX_PATH);
  149.  
  150.             CloseHandle(hProcess);
  151.             }
  152.  
  153.         // let the callback function do the application-defined logic
  154.         // regardless of the outcome of OpenProcess
  155.         bContinue = lpCallback(aProcesses[i], szProcessName, lpTargetName, lParam);
  156.         }
  157.  
  158.     FreeLibrary(hDLL);
  159.     return ( bContinue ) ? 1 : 0;
  160. }
  161.  
  162.  
  163. /*
  164.  * enumerate processes using Tool Help
  165.  */
  166. static int
  167. EnumToolHelp(LPCALLBACK lpCallback, LPTSTR lpTargetName, LPARAM lParam)
  168. {
  169.     typedef HANDLE (WINAPI *LPCT32S)(DWORD, DWORD);
  170.     typedef BOOL   (WINAPI *LPP32F)(HANDLE, PROCESSENTRY32 *);
  171.     typedef BOOL   (WINAPI *LPP32N)(HANDLE, PROCESSENTRY32 *);
  172.  
  173.     LPCT32S lpCreateToolhelp32Snapshot;
  174.     LPP32F  lpProcess32First;
  175.     LPP32N  lpProcess32Next;
  176.  
  177.     HANDLE hSnapshot;
  178.     PROCESSENTRY32 pe32;
  179.     BOOL bContinue;
  180.  
  181.     HINSTANCE hDLL = GetModuleHandle("Kernel32.dll");
  182.  
  183.     if ( !hDLL )
  184.         ErrorExit(_T("GetModuleHandle"), ERROR_SYSTEM);
  185.  
  186.     lpCreateToolhelp32Snapshot =
  187.         (LPCT32S)GetProcAddress(hDLL, "CreateToolhelp32Snapshot");
  188.     lpProcess32First = (LPP32F)GetProcAddress(hDLL, "Process32First");
  189.     lpProcess32Next  = (LPP32N)GetProcAddress(hDLL, "Process32Next");
  190.  
  191.     if (lpCreateToolhelp32Snapshot && lpProcess32First && lpProcess32Next )
  192.         hSnapshot = lpCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  193.     else
  194.         ErrorExit(_T("GetProcAddress"), ERROR_SYSTEM);
  195.  
  196.     if ( hSnapshot == INVALID_HANDLE_VALUE )
  197.         ErrorExit(_T("CreateToolhelp32Snapshot"), ERROR_SYSTEM);
  198.  
  199.     pe32.dwSize = sizeof(PROCESSENTRY32);
  200.  
  201.     if ( !lpProcess32First(hSnapshot, &pe32) )
  202.         {
  203.         CloseHandle(hSnapshot);
  204.         ErrorExit(_T("Process32First"), ERROR_SYSTEM);
  205.         }
  206.  
  207.     do
  208.         {
  209.         LPTSTR lpProcessName;
  210.  
  211.         // check if the value of szExeFile has been written to the structure
  212.         if ( pe32.dwSize > offsetof(PROCESSENTRY32, szExeFile) )
  213.             {
  214.             lpProcessName = _tcsrchr(pe32.szExeFile, _T('\\'));
  215.  
  216.             // strip path, if any
  217.             if ( lpProcessName )
  218.                 lpProcessName++;
  219.             else
  220.                 lpProcessName = pe32.szExeFile;
  221.             }
  222.         else
  223.             lpProcessName = "";
  224.  
  225.         // let the callback function do the application-defined logic
  226.         // regardless of whether szExeFile can be retrieved or not
  227.         bContinue = lpCallback(pe32.th32ProcessID, lpProcessName,
  228.                                lpTargetName, lParam);
  229.  
  230.         // reset dwSize as it might have been changed by Process32First/Next
  231.         if ( bContinue )
  232.             pe32.dwSize = sizeof(PROCESSENTRY32);
  233.         else
  234.             break;
  235.         }
  236.     while ( lpProcess32Next(hSnapshot, &pe32) );
  237.  
  238.     CloseHandle(hSnapshot);
  239.     return ( bContinue ) ? 1 : 0;
  240. }
  241.  
  242.  
  243. int
  244. main(int argc, LPTSTR argv[])
  245. {
  246.     BOOL bQueryOnly;
  247.     OSVERSIONINFO osvi;
  248.     int nExitCode;
  249.  
  250.     switch ( argc )
  251.         {
  252.         case 1:
  253.             ErrorExit(_T("Missing argument(s)."), ERROR_USAGE);
  254.  
  255.         case 2:
  256.             bQueryOnly = TRUE;
  257.             break;
  258.  
  259.         case 3:
  260.             if ( _tcsicmp(argv[2], _T("c")) != 0 )
  261.                 ErrorExit(_T("Unrecognized option."), ERROR_USAGE);
  262.  
  263.             bQueryOnly = FALSE;
  264.             break;
  265.  
  266.         default:
  267.             ErrorExit(_T("Invalid number of arguments."), ERROR_USAGE);
  268.         }
  269.  
  270.     ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
  271.     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  272.  
  273.     if ( !GetVersionEx(&osvi) )
  274.         ErrorExit(_T("GetVersionEx"), ERROR_SYSTEM);
  275.  
  276.     switch ( osvi.dwPlatformId )
  277.         {
  278.         case VER_PLATFORM_WIN32_NT:
  279.             nExitCode = EnumPSAPI((LPCALLBACK)EnumCallback, argv[1], bQueryOnly);
  280.             break;
  281.  
  282.         case VER_PLATFORM_WIN32_WINDOWS:
  283.             nExitCode = EnumToolHelp((LPCALLBACK)EnumCallback, argv[1], bQueryOnly);
  284.             break;
  285.  
  286.         case VER_PLATFORM_WIN32s:
  287.             ErrorExit(_T("Win32s is not supported."), ERROR_PLATFORM);
  288.  
  289.         default:
  290.             ErrorExit(_T("Unknown platform."), ERROR_PLATFORM);
  291.         }
  292.  
  293.     return nExitCode;
  294. }
  295.