Ars Longa, Vita Brevis

Маленькая программа для отображения полного списка установленных сервисных процессов

Не секрет, что список сервисных процессов (служб), отображаемый Windows (например, при помощи консоли services.msc), является далеко не полным. Когда-то давно меня заинтересовало, как же можно посмотреть, какие службы/драйвера/системные процессы живут в системе.

Самое простое решение — открыть Редактор реестра (regedit) и посмотреть. Список сервисов и не только находится в HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services. Однако по тем данным, которые представлены в реестре, трудно определить, какая из служб работает в данный момент времени, чем она является (напрмер, драйвером ядра или драйвером файловой системы) и т.п.

В Microsoft Windows Recovery Console есть команда, listsvc, позволяющая получить полный список сервисных процессов. Мне стало интересно написать что-то подобное, и вот результат:

[-]
View Code C
  1. /*-------------------------------------------------------------------------*/
  2. #include <windows.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. /*-------------------------------------------------------------------------*/
  7. const char* unknown_error = "<Unknown error!>";
  8. const char* get_error_code(DWORD dwCode)
  9. {
  10.     const char* msgbuf;
  11.     return (!FormatMessage(
  12.                 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
  13.                 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwCode,
  14.                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msgbuf,
  15.                 0, NULL
  16.              )
  17.            ) ? unknown_error : msgbuf;
  18. }
  19. /*-------------------------------------------------------------------------*/
  20. const char* servicetypes[] = {
  21.     "File System Driver",
  22.     "Kernel Driver",
  23.     "Own Process",
  24.     "Share Process",
  25.     "Unknown"
  26. };
  27. /*-------------------------------------------------------------------------*/
  28. const char* get_service_type(DWORD dwType)
  29. {
  30.     size_t i = 4;
  31.     if (SERVICE_FILE_SYSTEM_DRIVER == (dwType & SERVICE_FILE_SYSTEM_DRIVER)) {
  32.         i = 0;
  33.     }
  34.     else if (SERVICE_KERNEL_DRIVER == (dwType & SERVICE_KERNEL_DRIVER)) {
  35.         i = 1;
  36.     }
  37.     else if (SERVICE_WIN32_OWN_PROCESS == (dwType & SERVICE_WIN32_OWN_PROCESS)) {
  38.         i = 2;
  39.     }
  40.     else if (SERVICE_WIN32_SHARE_PROCESS == (dwType & SERVICE_WIN32_SHARE_PROCESS)) {
  41.         i = 3;
  42.     }
  43.  
  44.     return servicetypes[i];
  45. }
  46. /*-------------------------------------------------------------------------*/
  47. const char* states[] = {
  48.     "stopped",
  49.     "start pending",
  50.     "stop pending",
  51.     "running",
  52.     "continue pending",
  53.     "pause pending",
  54.     "paused",
  55.     "unknown"
  56. };
  57. /*-------------------------------------------------------------------------*/
  58. const char* get_state(DWORD dwState)
  59. {
  60.     --dwState;
  61.     if ((unsigned int)dwState > 6) {
  62.         dwState = 7;
  63.     }
  64.  
  65.     return states[dwState];
  66. }
  67. /*-------------------------------------------------------------------------*/
  68. int main(int argc, char* argv[])
  69. {
  70.     SC_HANDLE Handle;
  71.     BOOL Status;
  72.     LPENUM_SERVICE_STATUS Buffer = NULL;
  73.     DWORD BytesNeeded;
  74.     DWORD ServicesReturned;
  75.     DWORD ResumeHandle;
  76.     DWORD Error;
  77.     DWORD i;
  78.     const char* ErrCode;
  79.  
  80.     Handle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
  81.     if (NULL == Handle) {
  82.         ErrCode = get_error_code(GetLastError());
  83.         printf("Call to OpenSCManager failed: %s\n", ErrCode);
  84.         LocalFree((HLOCAL)ErrCode);
  85.         return EXIT_FAILURE;
  86.     }
  87.  
  88.     ResumeHandle = 0;
  89.     Status = EnumServicesStatus(
  90.         Handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
  91.         Buffer, 0, &BytesNeeded, &ServicesReturned, &ResumeHandle
  92.     );
  93.  
  94.     Error = GetLastError();
  95.     if (FALSE == Status && ERROR_MORE_DATA == Error) {
  96.         Buffer = (LPENUM_SERVICE_STATUS)calloc(BytesNeeded, 1);
  97.         if (NULL == Buffer) {
  98.             printf("Failed to allocate %ld bytes of memory!\n", BytesNeeded);
  99.             CloseServiceHandle(Handle);
  100.             return EXIT_FAILURE;
  101.         }
  102.  
  103.         Status = EnumServicesStatus(
  104.             Handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
  105.             Buffer, BytesNeeded, &BytesNeeded, &ServicesReturned, &ResumeHandle
  106.         );
  107.  
  108.         if (FALSE == Status) {
  109.             ErrCode = get_error_code(GetLastError());
  110.             printf("Call to EnumServicesStatus failed: %s\n", ErrCode);
  111.             LocalFree((HLOCAL)ErrCode);
  112.             free(Buffer);
  113.             CloseServiceHandle (Handle);
  114.             return EXIT_FAILURE;
  115.         }
  116.     }
  117.     else {
  118.         ErrCode = get_error_code(GetLastError());
  119.         printf("Call to EnumServicesStatus failed: %s\n", ErrCode);
  120.         LocalFree((HLOCAL)ErrCode);
  121.         CloseServiceHandle(Handle);
  122.         return EXIT_FAILURE;
  123.     }
  124.  
  125.     printf ("Service\tDisplay Name\tType\tState\n");
  126.  
  127.     for (i=0; i<ServicesReturned; ++i) {
  128.         printf ("%s\t%s\t%s\t%s\n",
  129.                 Buffer[i].lpServiceName, Buffer[i].lpDisplayName,
  130.         get_service_type(Buffer[i].ServiceStatus.dwServiceType),
  131.         get_state(Buffer[i].ServiceStatus.dwCurrentState));
  132.     }
  133.  
  134.     free(Buffer);
  135.     CloseServiceHandle(Handle);
  136.     return EXIT_SUCCESS;
  137. }
  138. /*-------------------------------------------------------------------------*/

Хотя это код трёхгодичной давности, работает до сих пор :-)

Скачать исходный код listsvc.
Скачать EXE-файл (7168 байт).

Сумма MD5 listsvc.exe: a04735a4ea104d96af78d234ae4e35b6
Сумма SHA1 listsvc.exe: 6d24bf22e48fc8f8e2b8a49f9fce51e973ff0a00

Комментарии к статье "Кто живёт у нас в системе, или, как просмотреть полный список сервисных процессов в Windows" »

К статье "Кто живёт у нас в системе, или, как просмотреть полный список сервисных процессов в Windows" комментариев нет. Может быть, Вы хотите прокомментировать статью?

RSS лента комментариев к этой записи. TrackBack URL

Оставить комментарий к записи "Кто живёт у нас в системе, или, как просмотреть полный список сервисных процессов в Windows"

Изображения должны быть включены!

XHTML: Вы можете использовать эти теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, Вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя