7fe84a57d26c2c95725fe8a748ea64b98c02901b
[reactos.git] / reactos / base / services / rpcss / service_main.c
1 /*
2 * PROJECT: ReactOS Remote Procedure Call service
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: /base/services/rpcss/service_main.c
5 * PURPOSE: Service control code
6 * COPYRIGHT: Copyright 2008 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9
10 #include "rpcss.h"
11
12 BOOL RPCSS_Initialize(void);
13 BOOL RPCSS_Shutdown(void);
14
15 static WCHAR ServiceName[] = L"RpcSs";
16
17 typedef struct _ServiceInfo
18 {
19 SERVICE_STATUS servStatus;
20 SERVICE_STATUS_HANDLE hStatus;
21 } SERVICEINFO, *PSERVICEINFO;
22
23
24 static VOID
25 UpdateStatus(PSERVICEINFO pServInfo,
26 DWORD NewStatus,
27 DWORD Check)
28 {
29 if (Check > 0)
30 {
31 pServInfo->servStatus.dwCheckPoint += Check;
32 }
33 else
34 {
35 pServInfo->servStatus.dwCheckPoint = Check;
36 }
37
38 if (NewStatus > 0)
39 {
40 pServInfo->servStatus.dwCurrentState = NewStatus;
41 }
42
43 SetServiceStatus(pServInfo->hStatus, &pServInfo->servStatus);
44 }
45
46
47 static BOOL
48 RunService(PSERVICEINFO pServInfo)
49 {
50 return RPCSS_Initialize();
51 }
52
53 VOID WINAPI
54 ServerCtrlHandler(DWORD dwControl,
55 DWORD dwEventType,
56 LPVOID lpEventData,
57 LPVOID lpContext)
58 {
59 PSERVICEINFO pServInfo = (PSERVICEINFO)lpContext;
60
61 switch (dwControl)
62 {
63 case SERVICE_CONTROL_SHUTDOWN:
64 case SERVICE_CONTROL_STOP:
65 RPCSS_Shutdown();
66 pServInfo->servStatus.dwWin32ExitCode = 0;
67 pServInfo->servStatus.dwWaitHint = 0;
68 UpdateStatus(pServInfo, SERVICE_STOP_PENDING, 1);
69 break;
70
71 default:
72 break;
73 }
74 }
75
76 VOID WINAPI
77 ServiceMain(DWORD argc, LPWSTR argv[])
78 {
79 SERVICEINFO servInfo;
80 HANDLE hThread;
81 DWORD dwThreadId;
82
83 servInfo.servStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
84 servInfo.servStatus.dwCurrentState = SERVICE_STOPPED;
85 servInfo.servStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
86 servInfo.servStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
87 servInfo.servStatus.dwServiceSpecificExitCode = 0;
88 servInfo.servStatus.dwCheckPoint = 0;
89 servInfo.servStatus.dwWaitHint = 1000;
90
91 servInfo.hStatus = RegisterServiceCtrlHandlerExW(ServiceName,
92 (LPHANDLER_FUNCTION_EX)ServerCtrlHandler,
93 &servInfo);
94 if (!servInfo.hStatus) return;
95
96 UpdateStatus(&servInfo, SERVICE_START_PENDING, 1);
97
98 /* Create worker thread */
99 hThread = CreateThread(NULL,
100 0,
101 (LPTHREAD_START_ROUTINE)RunService,
102 &servInfo,
103 0,
104 &dwThreadId);
105 if (!hThread) return;
106
107 /* Set service status to running */
108 UpdateStatus(&servInfo, SERVICE_RUNNING, 0);
109
110 /* Wait until thread has terminated */
111 WaitForSingleObject(hThread, INFINITE);
112
113 CloseHandle(hThread);
114
115 UpdateStatus(&servInfo, SERVICE_STOPPED, 0);
116 }
117
118
119 int wmain(int argc, LPWSTR argv [])
120 {
121 SERVICE_TABLE_ENTRYW ServiceTable[] =
122 {
123 {ServiceName, ServiceMain},
124 {NULL, NULL }
125 };
126
127 return (int)(StartServiceCtrlDispatcherW(ServiceTable) != TRUE);
128 }