Reactos
1/*
2 * PROJECT: ReactOS RPC Subsystem Service
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: DCOMLAUNCH service
5 * COPYRIGHT: Copyright 2019 Pierre Schweitzer
6 */
7
8/* INCLUDES *****************************************************************/
9
10#define WIN32_NO_STATUS
11#define _INC_WINDOWS
12#define COM_NO_WINDOWS_H
13#include <stdarg.h>
14#include <windef.h>
15#include <winbase.h>
16#include <winreg.h>
17#include <winsvc.h>
18
19#define NDEBUG
20#include <debug.h>
21
22/* GLOBALS ******************************************************************/
23
24static WCHAR ServiceName[] = L"dcomlaunch";
25
26static SERVICE_STATUS_HANDLE ServiceStatusHandle;
27static SERVICE_STATUS ServiceStatus;
28static HANDLE ShutdownEvent;
29
30/* FUNCTIONS *****************************************************************/
31
32static VOID
33UpdateServiceStatus(DWORD dwState)
34{
35 ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
36 ServiceStatus.dwCurrentState = dwState;
37 ServiceStatus.dwControlsAccepted = 0;
38 ServiceStatus.dwWin32ExitCode = 0;
39 ServiceStatus.dwServiceSpecificExitCode = 0;
40 ServiceStatus.dwCheckPoint = 0;
41
42 if (dwState == SERVICE_START_PENDING ||
43 dwState == SERVICE_STOP_PENDING ||
44 dwState == SERVICE_PAUSE_PENDING ||
45 dwState == SERVICE_CONTINUE_PENDING)
46 ServiceStatus.dwWaitHint = 10000;
47 else
48 ServiceStatus.dwWaitHint = 0;
49
50 SetServiceStatus(ServiceStatusHandle,
51 &ServiceStatus);
52}
53
54static DWORD WINAPI
55ServiceControlHandler(DWORD dwControl,
56 DWORD dwEventType,
57 LPVOID lpEventData,
58 LPVOID lpContext)
59{
60 DPRINT1("ServiceControlHandler() called\n");
61
62 switch (dwControl)
63 {
64 case SERVICE_CONTROL_STOP:
65 DPRINT1(" SERVICE_CONTROL_STOP received\n");
66 SetEvent(ShutdownEvent);
67 UpdateServiceStatus(SERVICE_STOP_PENDING);
68 return ERROR_SUCCESS;
69
70 case SERVICE_CONTROL_PAUSE:
71 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
72 UpdateServiceStatus(SERVICE_PAUSED);
73 return ERROR_SUCCESS;
74
75 case SERVICE_CONTROL_CONTINUE:
76 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
77 UpdateServiceStatus(SERVICE_RUNNING);
78 return ERROR_SUCCESS;
79
80 case SERVICE_CONTROL_INTERROGATE:
81 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
82 SetServiceStatus(ServiceStatusHandle,
83 &ServiceStatus);
84 return ERROR_SUCCESS;
85
86 case SERVICE_CONTROL_SHUTDOWN:
87 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
88 SetEvent(ShutdownEvent);
89 UpdateServiceStatus(SERVICE_STOP_PENDING);
90 return ERROR_SUCCESS;
91
92 default :
93 DPRINT1(" Control %lu received\n", dwControl);
94 return ERROR_CALL_NOT_IMPLEMENTED;
95 }
96}
97
98VOID DealWithDeviceEvent();
99
100VOID WINAPI
101ServiceMain(DWORD argc, LPTSTR *argv)
102{
103 UNREFERENCED_PARAMETER(argc);
104 UNREFERENCED_PARAMETER(argv);
105
106 DPRINT("ServiceMain() called\n");
107
108 ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName,
109 ServiceControlHandler,
110 NULL);
111 if (!ServiceStatusHandle)
112 {
113 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
114 return;
115 }
116
117 ShutdownEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
118
119 DealWithDeviceEvent();
120
121 UpdateServiceStatus(SERVICE_RUNNING);
122
123 WaitForSingleObject(ShutdownEvent, INFINITE);
124 CloseHandle(ShutdownEvent);
125
126 UpdateServiceStatus(SERVICE_STOPPED);
127}
128
129BOOL WINAPI
130DllMain(HINSTANCE hinstDLL,
131 DWORD fdwReason,
132 LPVOID lpvReserved)
133{
134 switch (fdwReason)
135 {
136 case DLL_PROCESS_ATTACH:
137 DisableThreadLibraryCalls(hinstDLL);
138 break;
139
140 case DLL_PROCESS_DETACH:
141 break;
142 }
143
144 return TRUE;
145}