xref: /reactos/base/services/wmisvc/wmisvc.c (revision 019f21ee)
1 /*
2  *  ReactOS Services
3  *  Copyright (C) 2015 ReactOS Team
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License along
16  *  with this program; if not, write to the Free Software Foundation, Inc.,
17  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 /*
20  * COPYRIGHT:        See COPYING in the top level directory
21  * PROJECT:          ReactOS Services
22  * FILE:             base/services/wmisvc/wmisvc.c
23  * PURPOSE:          WMI service
24  * PROGRAMMER:       Pierre Schweitzer
25  */
26 
27 /* INCLUDES *****************************************************************/
28 
29 #define WIN32_NO_STATUS
30 #define _INC_WINDOWS
31 #define COM_NO_WINDOWS_H
32 #include <stdarg.h>
33 #include <windef.h>
34 #include <winbase.h>
35 #include <winreg.h>
36 #include <winsvc.h>
37 
38 #define NDEBUG
39 #include <debug.h>
40 
41 /* GLOBALS ******************************************************************/
42 
43 static WCHAR ServiceName[] = L"winmgmt";
44 
45 static SERVICE_STATUS_HANDLE ServiceStatusHandle;
46 static SERVICE_STATUS ServiceStatus;
47 static HANDLE hStopEvent = NULL;
48 
49 /* FUNCTIONS *****************************************************************/
50 
51 static VOID
52 UpdateServiceStatus(DWORD dwState)
53 {
54     ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
55     ServiceStatus.dwCurrentState = dwState;
56     ServiceStatus.dwControlsAccepted = 0;
57     ServiceStatus.dwWin32ExitCode = 0;
58     ServiceStatus.dwServiceSpecificExitCode = 0;
59     ServiceStatus.dwCheckPoint = 0;
60 
61     if (dwState == SERVICE_START_PENDING ||
62         dwState == SERVICE_STOP_PENDING ||
63         dwState == SERVICE_PAUSE_PENDING ||
64         dwState == SERVICE_CONTINUE_PENDING)
65         ServiceStatus.dwWaitHint = 10000;
66     else
67         ServiceStatus.dwWaitHint = 0;
68 
69     if (dwState == SERVICE_RUNNING)
70         ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
71 
72     SetServiceStatus(ServiceStatusHandle,
73                      &ServiceStatus);
74 }
75 
76 static DWORD WINAPI
77 ServiceControlHandler(DWORD dwControl,
78                       DWORD dwEventType,
79                       LPVOID lpEventData,
80                       LPVOID lpContext)
81 {
82     DPRINT1("ServiceControlHandler() called\n");
83 
84     switch (dwControl)
85     {
86         case SERVICE_CONTROL_STOP:
87             DPRINT1("  SERVICE_CONTROL_STOP received\n");
88             SetEvent(hStopEvent);
89             UpdateServiceStatus(SERVICE_STOP_PENDING);
90             return ERROR_SUCCESS;
91 
92         case SERVICE_CONTROL_PAUSE:
93             DPRINT1("  SERVICE_CONTROL_PAUSE received\n");
94             UpdateServiceStatus(SERVICE_PAUSED);
95             return ERROR_SUCCESS;
96 
97         case SERVICE_CONTROL_CONTINUE:
98             DPRINT1("  SERVICE_CONTROL_CONTINUE received\n");
99             UpdateServiceStatus(SERVICE_RUNNING);
100             return ERROR_SUCCESS;
101 
102         case SERVICE_CONTROL_INTERROGATE:
103             DPRINT1("  SERVICE_CONTROL_INTERROGATE received\n");
104             SetServiceStatus(ServiceStatusHandle,
105                              &ServiceStatus);
106             return ERROR_SUCCESS;
107 
108         case SERVICE_CONTROL_SHUTDOWN:
109             DPRINT1("  SERVICE_CONTROL_SHUTDOWN received\n");
110             SetEvent(hStopEvent);
111             UpdateServiceStatus(SERVICE_STOP_PENDING);
112             return ERROR_SUCCESS;
113 
114         default :
115             DPRINT1("  Control %lu received\n");
116             return ERROR_CALL_NOT_IMPLEMENTED;
117     }
118 }
119 
120 VOID WINAPI
121 ServiceMain(DWORD argc, LPTSTR *argv)
122 {
123     UNREFERENCED_PARAMETER(argc);
124     UNREFERENCED_PARAMETER(argv);
125 
126     DPRINT("ServiceMain() called\n");
127 
128     ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName,
129                                                         ServiceControlHandler,
130                                                         NULL);
131     if (!ServiceStatusHandle)
132     {
133         DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
134         return;
135     }
136 
137     hStopEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
138     if (hStopEvent == NULL)
139     {
140         DPRINT1("CreateEvent() failed! (Error %lu)\n", GetLastError());
141         goto done;
142     }
143 
144     UpdateServiceStatus(SERVICE_RUNNING);
145 
146     WaitForSingleObject(hStopEvent, INFINITE);
147     CloseHandle(hStopEvent);
148 
149 done:
150     UpdateServiceStatus(SERVICE_STOPPED);
151 }
152 
153 BOOL WINAPI
154 DllMain(HINSTANCE hinstDLL,
155         DWORD fdwReason,
156         LPVOID lpvReserved)
157 {
158     switch (fdwReason)
159     {
160         case DLL_PROCESS_ATTACH:
161             DisableThreadLibraryCalls(hinstDLL);
162             break;
163 
164         case DLL_PROCESS_DETACH:
165             break;
166     }
167 
168     return TRUE;
169 }
170