본문 바로가기
dev/windows

[windows] 윈도우즈 서비스: 실제 등록된 서비스명 가지고 오기

by 최연탄 2017. 5. 30.
728x90
반응형

HKLM\SYSTEM\CurrentControlSet\Services에 등록된 서비스의 이름 가져오는 방법

본인 서비스의 이름을 가져오고 싶은 경우 MSDN에서는 GetServiceKeyName을 소개하고있다. 이 api는 서비스의 display name을 가지고 key name을 가져오는 기능을 하지만 특정 경우 이름 값을 못하는 상황이 발생한다. 만약 위 레지스트리 경로 밑에 ServiceA, ServiceB 라는 이름의 키가 있고 ImagePath, DisplayName 값의 데이터가 동일하다면 GetServiceKeyName 으로는 ServiceA 뿐만 얻을 수 있다. ServiceB를 얻으려면(ServiceB에 의해 트리거된 프로세스에서) 시스템의 서비스를 나열한 후 프로세스 ID를 비교하는 방법을 사용할 수 있다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
BOOL GetCurrentServiceKeyName(_Out_ TCHAR* szServiceName)
{
	DWORD dwBufferSize = 0;
	DWORD dwBytesNeeded = 0;
	DWORD dwServicesCount = 0;
	DWORD dwCurrentProcessId = GetCurrentProcessId();
	SC_HANDLE hScManager = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);

	EnumServicesStatusEx(hScManager, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, nullptr, dwBufferSize, &dwBytesNeeded, &dwServicesCount, nullptr, nullptr);
	std::vector<BYTE> buffer(dwBytesNeeded);
	EnumServicesStatusEx(hScManager, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, buffer.data(), buffer.size(), &dwBytesNeeded, &dwServicesCount, nullptr, nullptr);

	LPENUM_SERVICE_STATUS_PROCESS pServices = reinterpret_cast<LPENUM_SERVICE_STATUS_PROCESS>(buffer.data());

	for (DWORD i = 0; i < dwServicesCount; i++)
	{
		ENUM_SERVICE_STATUS_PROCESS service = pServices[i];

		if (service.ServiceStatusProcess.dwProcessId == dwCurrentProcessId)
		{
			_stprintf(szServiceName, TEXT("%s"), service.lpServiceName);
		}
	}

	return TRUE;
}

예외처리는 각자 알아서

반응형

댓글