Кто живёт у нас в системе, или, как просмотреть полный список сервисных процессов в Windows
Маленькая программа для отображения полного списка установленных сервисных процессов
Не секрет, что список сервисных процессов (служб), отображаемый Windows (например, при помощи консоли services.msc), является далеко не полным. Когда-то давно меня заинтересовало, как же можно посмотреть, какие службы/драйвера/системные процессы живут в системе.
Самое простое решение — открыть Редактор реестра (regedit) и посмотреть. Список сервисов и не только находится в HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services. Однако по тем данным, которые представлены в реестре, трудно определить, какая из служб работает в данный момент времени, чем она является (напрмер, драйвером ядра или драйвером файловой системы) и т.п.
В Microsoft Windows Recovery Console есть команда, listsvc, позволяющая получить полный список сервисных процессов. Мне стало интересно написать что-то подобное, и вот результат:
- /*-------------------------------------------------------------------------*/
- #include <windows.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- /*-------------------------------------------------------------------------*/
- const char* unknown_error = "<Unknown error!>";
- const char* get_error_code(DWORD dwCode)
- {
- const char* msgbuf;
- return (!FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwCode,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msgbuf,
- 0, NULL
- )
- ) ? unknown_error : msgbuf;
- }
- /*-------------------------------------------------------------------------*/
- const char* servicetypes[] = {
- "File System Driver",
- "Kernel Driver",
- "Own Process",
- "Share Process",
- "Unknown"
- };
- /*-------------------------------------------------------------------------*/
- const char* get_service_type(DWORD dwType)
- {
- size_t i = 4;
- if (SERVICE_FILE_SYSTEM_DRIVER == (dwType & SERVICE_FILE_SYSTEM_DRIVER)) {
- i = 0;
- }
- else if (SERVICE_KERNEL_DRIVER == (dwType & SERVICE_KERNEL_DRIVER)) {
- i = 1;
- }
- else if (SERVICE_WIN32_OWN_PROCESS == (dwType & SERVICE_WIN32_OWN_PROCESS)) {
- i = 2;
- }
- else if (SERVICE_WIN32_SHARE_PROCESS == (dwType & SERVICE_WIN32_SHARE_PROCESS)) {
- i = 3;
- }
- return servicetypes[i];
- }
- /*-------------------------------------------------------------------------*/
- const char* states[] = {
- "stopped",
- "start pending",
- "stop pending",
- "running",
- "continue pending",
- "pause pending",
- "paused",
- "unknown"
- };
- /*-------------------------------------------------------------------------*/
- const char* get_state(DWORD dwState)
- {
- --dwState;
- if ((unsigned int)dwState > 6) {
- dwState = 7;
- }
- return states[dwState];
- }
- /*-------------------------------------------------------------------------*/
- int main(int argc, char* argv[])
- {
- SC_HANDLE Handle;
- BOOL Status;
- LPENUM_SERVICE_STATUS Buffer = NULL;
- DWORD BytesNeeded;
- DWORD ServicesReturned;
- DWORD ResumeHandle;
- DWORD Error;
- DWORD i;
- const char* ErrCode;
- Handle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
- if (NULL == Handle) {
- ErrCode = get_error_code(GetLastError());
- printf("Call to OpenSCManager failed: %s\n", ErrCode);
- LocalFree((HLOCAL)ErrCode);
- return EXIT_FAILURE;
- }
- ResumeHandle = 0;
- Status = EnumServicesStatus(
- Handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
- Buffer, 0, &BytesNeeded, &ServicesReturned, &ResumeHandle
- );
- Error = GetLastError();
- if (FALSE == Status && ERROR_MORE_DATA == Error) {
- Buffer = (LPENUM_SERVICE_STATUS)calloc(BytesNeeded, 1);
- if (NULL == Buffer) {
- printf("Failed to allocate %ld bytes of memory!\n", BytesNeeded);
- CloseServiceHandle(Handle);
- return EXIT_FAILURE;
- }
- Status = EnumServicesStatus(
- Handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
- Buffer, BytesNeeded, &BytesNeeded, &ServicesReturned, &ResumeHandle
- );
- if (FALSE == Status) {
- ErrCode = get_error_code(GetLastError());
- printf("Call to EnumServicesStatus failed: %s\n", ErrCode);
- LocalFree((HLOCAL)ErrCode);
- free(Buffer);
- CloseServiceHandle (Handle);
- return EXIT_FAILURE;
- }
- }
- else {
- ErrCode = get_error_code(GetLastError());
- printf("Call to EnumServicesStatus failed: %s\n", ErrCode);
- LocalFree((HLOCAL)ErrCode);
- CloseServiceHandle(Handle);
- return EXIT_FAILURE;
- }
- printf ("Service\tDisplay Name\tType\tState\n");
- for (i=0; i<ServicesReturned; ++i) {
- printf ("%s\t%s\t%s\t%s\n",
- Buffer[i].lpServiceName, Buffer[i].lpDisplayName,
- get_service_type(Buffer[i].ServiceStatus.dwServiceType),
- get_state(Buffer[i].ServiceStatus.dwCurrentState));
- }
- free(Buffer);
- CloseServiceHandle(Handle);
- return EXIT_SUCCESS;
- }
- /*-------------------------------------------------------------------------*/
Хотя это код трёхгодичной давности, работает до сих пор
Скачать исходный код listsvc.
Скачать EXE-файл (7168 байт).
Сумма MD5 listsvc.exe: a04735a4ea104d96af78d234ae4e35b6
Сумма SHA1 listsvc.exe: 6d24bf22e48fc8f8e2b8a49f9fce51e973ff0a00

