ReactOS 0.4.15-dev-5672-gf73ac17
umpnpmgr.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2005 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 kernel
22 * FILE: base/services/umpnpmgr/umpnpmgr.c
23 * PURPOSE: User-mode Plug and Play manager
24 * PROGRAMMER: Eric Kohl (eric.kohl@reactos.org)
25 * Hervé Poussineau (hpoussin@reactos.org)
26 * Colin Finck (colin@reactos.org)
27 */
28
29/* INCLUDES *****************************************************************/
30
31#include "precomp.h"
32
33#define NDEBUG
34#include <debug.h>
35
36
37/* GLOBALS ******************************************************************/
38
39static WCHAR ServiceName[] = L"PlugPlay";
40
43
47
48/* FUNCTIONS *****************************************************************/
49
50static DWORD WINAPI
52{
53 PLUGPLAY_CONTROL_USER_RESPONSE_DATA ResponseData = {0, 0, 0, 0};
54 DWORD dwRet = ERROR_SUCCESS;
56 RPC_STATUS RpcStatus;
57 PPLUGPLAY_EVENT_BLOCK PnpEvent, NewPnpEvent;
58 ULONG PnpEventSize;
59
60 UNREFERENCED_PARAMETER(lpParameter);
61
62 PnpEventSize = 0x1000;
63 PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize);
64 if (PnpEvent == NULL)
65 return ERROR_OUTOFMEMORY;
66
67 for (;;)
68 {
69 DPRINT("Calling NtGetPlugPlayEvent()\n");
70
71 /* Wait for the next PnP event */
72 Status = NtGetPlugPlayEvent(0, 0, PnpEvent, PnpEventSize);
73
74 /* Resize the buffer for the PnP event if it's too small */
76 {
77 PnpEventSize += 0x400;
78 NewPnpEvent = HeapReAlloc(GetProcessHeap(), 0, PnpEvent, PnpEventSize);
79 if (NewPnpEvent == NULL)
80 {
81 dwRet = ERROR_OUTOFMEMORY;
82 break;
83 }
84 PnpEvent = NewPnpEvent;
85 continue;
86 }
87
88 if (!NT_SUCCESS(Status))
89 {
90 DPRINT1("NtGetPlugPlayEvent() failed (Status 0x%08lx)\n", Status);
91 break;
92 }
93
94 /* Process the PnP event */
95 DPRINT("Received PnP Event\n");
96 if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ENUMERATED, &RpcStatus))
97 {
99 DWORD len;
100 DWORD DeviceIdLength;
101
102 DPRINT("Device enumerated: %S\n", PnpEvent->TargetDevice.DeviceIds);
103
104 DeviceIdLength = lstrlenW(PnpEvent->TargetDevice.DeviceIds);
105 if (DeviceIdLength)
106 {
107 /* Allocate a new device-install event */
108 len = FIELD_OFFSET(DeviceInstallParams, DeviceIds) + (DeviceIdLength + 1) * sizeof(WCHAR);
110 if (Params)
111 {
112 wcscpy(Params->DeviceIds, PnpEvent->TargetDevice.DeviceIds);
113
114 /* Queue the event (will be dequeued by DeviceInstallThread) */
118
120 }
121 }
122 }
123 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus))
124 {
125// DWORD dwRecipient;
126
127 DPRINT("Device arrival: %S\n", PnpEvent->TargetDevice.DeviceIds);
128
129// dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
130// BroadcastSystemMessageW(BSF_POSTMESSAGE,
131// &dwRecipient,
132// WM_DEVICECHANGE,
133// DBT_DEVNODES_CHANGED,
134// 0);
136 }
137 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_EJECT_VETOED, &RpcStatus))
138 {
139 DPRINT1("Eject vetoed: %S\n", PnpEvent->TargetDevice.DeviceIds);
140 }
141 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_KERNEL_INITIATED_EJECT, &RpcStatus))
142 {
143 DPRINT1("Kernel initiated eject: %S\n", PnpEvent->TargetDevice.DeviceIds);
144 }
145 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_SAFE_REMOVAL, &RpcStatus))
146 {
147// DWORD dwRecipient;
148
149 DPRINT1("Safe removal: %S\n", PnpEvent->TargetDevice.DeviceIds);
150
151// dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
152// BroadcastSystemMessageW(BSF_POSTMESSAGE,
153// &dwRecipient,
154// WM_DEVICECHANGE,
155// DBT_DEVNODES_CHANGED,
156// 0);
158 }
159 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_SURPRISE_REMOVAL, &RpcStatus))
160 {
161// DWORD dwRecipient;
162
163 DPRINT1("Surprise removal: %S\n", PnpEvent->TargetDevice.DeviceIds);
164
165// dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
166// BroadcastSystemMessageW(BSF_POSTMESSAGE,
167// &dwRecipient,
168// WM_DEVICECHANGE,
169// DBT_DEVNODES_CHANGED,
170// 0);
172 }
173 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_REMOVAL_VETOED, &RpcStatus))
174 {
175 DPRINT1("Removal vetoed: %S\n", PnpEvent->TargetDevice.DeviceIds);
176 }
177 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_REMOVE_PENDING, &RpcStatus))
178 {
179 DPRINT1("Removal pending: %S\n", PnpEvent->TargetDevice.DeviceIds);
180 }
181 else
182 {
183 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
184 PnpEvent->EventGuid.Data1, PnpEvent->EventGuid.Data2, PnpEvent->EventGuid.Data3,
185 PnpEvent->EventGuid.Data4[0], PnpEvent->EventGuid.Data4[1], PnpEvent->EventGuid.Data4[2],
186 PnpEvent->EventGuid.Data4[3], PnpEvent->EventGuid.Data4[4], PnpEvent->EventGuid.Data4[5],
187 PnpEvent->EventGuid.Data4[6], PnpEvent->EventGuid.Data4[7]);
188 }
189
190 /* Dequeue the current PnP event and signal the next one */
192 &ResponseData,
193 sizeof(ResponseData));
194 if (!NT_SUCCESS(Status))
195 {
196 DPRINT1("NtPlugPlayControl(PlugPlayControlUserResponse) failed (Status 0x%08lx)\n", Status);
197 break;
198 }
199 }
200
201 HeapFree(GetProcessHeap(), 0, PnpEvent);
202
203 return dwRet;
204}
205
206
207static VOID
209 _In_ DWORD dwState,
210 _In_ DWORD dwCheckPoint)
211{
216 ServiceStatus.dwCheckPoint = dwCheckPoint;
217
218 if (dwState == SERVICE_RUNNING)
220 else
222
223 if (dwState == SERVICE_START_PENDING ||
224 dwState == SERVICE_STOP_PENDING ||
225 dwState == SERVICE_PAUSE_PENDING ||
226 dwState == SERVICE_CONTINUE_PENDING)
228 else
230
233}
234
235
236static DWORD WINAPI
238 DWORD dwEventType,
239 LPVOID lpEventData,
240 LPVOID lpContext)
241{
242 DPRINT1("ServiceControlHandler() called\n");
243
244 switch (dwControl)
245 {
247 DPRINT1(" SERVICE_CONTROL_STOP received\n");
249 /* Stop listening to RPC Messages */
252 return ERROR_SUCCESS;
253
255 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
257 return ERROR_SUCCESS;
258
260 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
262 return ERROR_SUCCESS;
263
265 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
268 return ERROR_SUCCESS;
269
271 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
273 /* Stop listening to RPC Messages */
276 return ERROR_SUCCESS;
277
278 default :
279 DPRINT1(" Control %lu received\n", dwControl);
281 }
282}
283
284static DWORD
286 IN HKEY hKey,
287 IN PCWSTR lpSubKey,
288 IN PCWSTR lpValue,
290{
291 DWORD dwError, dwType, dwData;
292 DWORD cbData = sizeof(dwData);
293 HKEY hSubKey = NULL;
294
295 /* Default value */
296 *pValue = FALSE;
297
298 dwError = RegOpenKeyExW(hKey,
299 lpSubKey,
300 0,
301 KEY_READ,
302 &hSubKey);
303 if (dwError != ERROR_SUCCESS)
304 {
305 DPRINT("GetBooleanRegValue(): RegOpenKeyExW() has failed to open '%S' key! (Error: %lu)\n",
306 lpSubKey, dwError);
307 return dwError;
308 }
309
310 dwError = RegQueryValueExW(hSubKey,
311 lpValue,
312 0,
313 &dwType,
314 (PBYTE)&dwData,
315 &cbData);
316 if (dwError != ERROR_SUCCESS)
317 {
318 DPRINT("GetBooleanRegValue(): RegQueryValueExW() has failed to query '%S' value! (Error: %lu)\n",
319 lpValue, dwError);
320 goto Cleanup;
321 }
322 if (dwType != REG_DWORD)
323 {
324 DPRINT("GetBooleanRegValue(): The value is not of REG_DWORD type!\n");
325 goto Cleanup;
326 }
327
328 /* Return the value */
329 *pValue = (dwData == 1);
330
331Cleanup:
332 RegCloseKey(hSubKey);
333
334 return dwError;
335}
336
337BOOL
339{
340 BOOL bSuppressNewHWUI = FALSE;
341
342 /*
343 * Query the SuppressNewHWUI policy registry value. Don't cache it
344 * as we want to update our behaviour in consequence.
345 */
347 L"Software\\Policies\\Microsoft\\Windows\\DeviceInstall\\Settings",
348 L"SuppressNewHWUI",
349 &bSuppressNewHWUI);
350 if (bSuppressNewHWUI)
351 DPRINT("GetSuppressNewUIValue(): newdev.dll's wizard UI won't be shown!\n");
352
353 return bSuppressNewHWUI;
354}
355
358{
361
364
365 DPRINT("ServiceMain() called\n");
366
369 NULL);
371 {
372 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
373 return;
374 }
375
377
379 0,
381 NULL,
382 0,
383 &dwThreadId);
384 if (hThread != NULL)
386
388
390 0,
392 NULL,
393 0,
394 &dwThreadId);
395 if (hThread != NULL)
397
399
401 0,
403 NULL,
404 0,
405 &dwThreadId);
406 if (hThread != NULL)
408
410
411 DPRINT("ServiceMain() done\n");
412}
413
414static DWORD
416{
417 BOOLEAN OldValue;
418 DWORD dwError;
419
420 DPRINT("UMPNPMGR: InitializePnPManager() started\n");
421
422 /* We need this privilege for using CreateProcessAsUserW */
424
426 if (hInstallEvent == NULL)
427 {
428 dwError = GetLastError();
429 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError);
430 return dwError;
431 }
432
434 TRUE,
435 FALSE,
436 L"Global\\PnP_No_Pending_Install_Events");
438 {
439 dwError = GetLastError();
440 DPRINT1("Could not create the Pending-Install Event! (Error %lu)\n", dwError);
441 return dwError;
442 }
443
444 /*
445 * Initialize the device-install event list
446 */
447
450 {
451 dwError = GetLastError();
452 DPRINT1("Could not create the List Event! (Error %lu)\n", dwError);
453 return dwError;
454 }
455
458 {
459 dwError = GetLastError();
460 DPRINT1("Could not create the List Mutex! (Error %lu)\n", dwError);
461 return dwError;
462 }
464
465 /* Query the SuppressUI registry value and cache it for our whole lifetime */
467 L"System\\CurrentControlSet\\Services\\PlugPlay\\Parameters",
468 L"SuppressUI",
471 DPRINT("UMPNPMGR: newdev.dll's wizard UI won't be shown!\n");
472
474 L"System\\CurrentControlSet\\Enum",
475 0,
477 &hEnumKey);
478 if (dwError != ERROR_SUCCESS)
479 {
480 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError);
481 return dwError;
482 }
483
485 L"System\\CurrentControlSet\\Control\\Class",
486 0,
488 &hClassKey);
489 if (dwError != ERROR_SUCCESS)
490 {
491 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError);
492 return dwError;
493 }
494
495 DPRINT("UMPNPMGR: InitializePnPManager() done\n");
496
497 return 0;
498}
499
502 DWORD fdwReason,
504{
505 switch (fdwReason)
506 {
510 break;
511
513 break;
514 }
515
516 return TRUE;
517}
518
519/* EOF */
static SERVICE_STATUS_HANDLE(WINAPI *pRegisterServiceCtrlHandlerExA)(LPCSTR
unsigned char BOOLEAN
static int argc
Definition: ServiceArgs.c:12
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
static BOOL SetupIsActive(VOID)
Definition: setup.c:27
HANDLE hDeviceInstallListNotEmpty
Definition: install.c:46
DWORD WINAPI DeviceInstallThread(LPVOID lpParameter)
Definition: install.c:534
HANDLE hInstallEvent
Definition: install.c:40
HANDLE hDeviceInstallListMutex
Definition: install.c:44
HANDLE hNoPendingInstalls
Definition: install.c:41
LIST_ENTRY DeviceInstallListHead
Definition: install.c:45
DWORD WINAPI RpcServerThread(LPVOID lpParameter)
Definition: rpcserver.c:46
#define RegCloseKey(hKey)
Definition: registry.h:47
#define DBT_DEVNODES_CHANGED
Definition: dbt.h:28
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4121
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define DLL_PROCESS_DETACH
Definition: compat.h:130
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
static const WCHAR Cleanup[]
Definition: register.c:80
#define INFINITE
Definition: serial.h:102
#define InsertTailList(ListHead, Entry)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DWORD dwThreadId
Definition: fdebug.c:31
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
PWCHAR pValue
Status
Definition: gdiplustypes.h:25
GLenum GLsizei len
Definition: glext.h:6722
static IN DWORD IN LPVOID lpvReserved
#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
Definition: security.c:657
static HANDLE ULONG_PTR dwData
Definition: file.c:35
#define argv
Definition: mplay32.c:18
#define _In_
Definition: ms_sal.h:308
@ PlugPlayControlUserResponse
Definition: cmtypes.h:216
NTSYSAPI NTSTATUS NTAPI RtlAdjustPrivilege(_In_ ULONG Privilege, _In_ BOOLEAN NewValue, _In_ BOOLEAN ForThread, _Out_ PBOOLEAN OldValue)
HANDLE hThread
Definition: wizard.c:28
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_READ
Definition: nt_native.h:1023
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define L(x)
Definition: ntvdm.h:50
BYTE * PBYTE
Definition: pedump.c:66
NTSTATUS NTAPI NtGetPlugPlayEvent(IN ULONG Reserved1, IN ULONG Reserved2, OUT PPLUGPLAY_EVENT_BLOCK Buffer, IN ULONG BufferSize)
Definition: plugplay.c:1255
NTSTATUS NTAPI NtPlugPlayControl(IN PLUGPLAY_CONTROL_CLASS PlugPlayControlClass, IN OUT PVOID Buffer, IN ULONG BufferLength)
Definition: plugplay.c:1385
RPC_STATUS WINAPI RpcMgmtStopServerListening(RPC_BINDING_HANDLE Binding)
Definition: rpc_server.c:1596
int WINAPI UuidEqual(UUID *Uuid1, UUID *Uuid2, RPC_STATUS *Status)
Definition: rpcrt4_main.c:252
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExW(LPCWSTR lpServiceName, LPHANDLER_FUNCTION_EX lpHandlerProc, LPVOID lpContext)
Definition: sctrl.c:812
BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: sctrl.c:997
#define REG_DWORD
Definition: sdbapi.c:596
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
long RPC_STATUS
Definition: rpc.h:52
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define DPRINT
Definition: sndvol32.h:71
struct _PLUGPLAY_EVENT_BLOCK::@2366::@2369 TargetDevice
DWORD dwServiceType
Definition: winsvc.h:99
DWORD dwWin32ExitCode
Definition: winsvc.h:102
DWORD dwControlsAccepted
Definition: winsvc.h:101
DWORD dwWaitHint
Definition: winsvc.h:105
DWORD dwCurrentState
Definition: winsvc.h:100
DWORD dwCheckPoint
Definition: winsvc.h:104
DWORD dwServiceSpecificExitCode
Definition: winsvc.h:103
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexW(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, IN BOOL bInitialOwner, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:576
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:618
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
static WCHAR ServiceName[]
Definition: umpnpmgr.c:39
static VOID UpdateServiceStatus(_In_ DWORD dwState, _In_ DWORD dwCheckPoint)
Definition: umpnpmgr.c:208
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
Definition: umpnpmgr.c:501
BOOL GetSuppressNewUIValue(VOID)
Definition: umpnpmgr.c:338
static DWORD WINAPI ServiceControlHandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
Definition: umpnpmgr.c:237
static SERVICE_STATUS_HANDLE ServiceStatusHandle
Definition: umpnpmgr.c:41
HKEY hEnumKey
Definition: umpnpmgr.c:44
BOOL g_IsUISuppressed
Definition: umpnpmgr.c:46
static DWORD InitializePnPManager(VOID)
Definition: umpnpmgr.c:415
VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
Definition: umpnpmgr.c:357
static DWORD WINAPI PnpEventThread(LPVOID lpParameter)
Definition: umpnpmgr.c:51
static DWORD GetBooleanRegValue(IN HKEY hKey, IN PCWSTR lpSubKey, IN PCWSTR lpValue, OUT PBOOL pValue)
Definition: umpnpmgr.c:285
static SERVICE_STATUS ServiceStatus
Definition: umpnpmgr.c:42
HKEY hClassKey
Definition: umpnpmgr.c:45
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308
DWORD WINAPI GetLastError(void)
Definition: except.c:1040
BOOL * PBOOL
Definition: windef.h:161
#define WINAPI
Definition: msvc.h:6
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
#define SERVICE_CONTROL_SHUTDOWN
Definition: winsvc.h:40
#define SERVICE_PAUSED
Definition: winsvc.h:27
#define SERVICE_START_PENDING
Definition: winsvc.h:22
#define SERVICE_RUNNING
Definition: winsvc.h:24
#define SERVICE_CONTROL_CONTINUE
Definition: winsvc.h:38
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define SERVICE_ACCEPT_SHUTDOWN
Definition: winsvc.h:30
#define SERVICE_PAUSE_PENDING
Definition: winsvc.h:26
#define SERVICE_CONTROL_PAUSE
Definition: winsvc.h:37
#define SERVICE_CONTROL_INTERROGATE
Definition: winsvc.h:39
#define SERVICE_CONTINUE_PENDING
Definition: winsvc.h:25
#define HWND_BROADCAST
Definition: winuser.h:1194
#define WM_DEVICECHANGE
Definition: winuser.h:1801
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:962
__wchar_t WCHAR
Definition: xmlstorage.h:180
CHAR * LPTSTR
Definition: xmlstorage.h:192