ReactOS  0.4.14-dev-55-g2da92ac
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 
39 static WCHAR ServiceName[] = L"PlugPlay";
40 
43 
47 
48 /* FUNCTIONS *****************************************************************/
49 
50 static 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 
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  {
98  DeviceInstallParams* Params;
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  /* Queue device install (will be dequeued by DeviceInstallThread) */
108  len = FIELD_OFFSET(DeviceInstallParams, DeviceIds) + (DeviceIdLength + 1) * sizeof(WCHAR);
109  Params = HeapAlloc(GetProcessHeap(), 0, len);
110  if (Params)
111  {
112  wcscpy(Params->DeviceIds, PnpEvent->TargetDevice.DeviceIds);
115  }
116  }
117  }
118  else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus))
119  {
120 // DWORD dwRecipient;
121 
122  DPRINT("Device arrival: %S\n", PnpEvent->TargetDevice.DeviceIds);
123 
124 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
125 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
126 // &dwRecipient,
127 // WM_DEVICECHANGE,
128 // DBT_DEVNODES_CHANGED,
129 // 0);
131  }
132  else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_EJECT_VETOED, &RpcStatus))
133  {
134  DPRINT1("Eject vetoed: %S\n", PnpEvent->TargetDevice.DeviceIds);
135  }
136  else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_KERNEL_INITIATED_EJECT, &RpcStatus))
137  {
138  DPRINT1("Kernel initiated eject: %S\n", PnpEvent->TargetDevice.DeviceIds);
139  }
140  else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_SAFE_REMOVAL, &RpcStatus))
141  {
142 // DWORD dwRecipient;
143 
144  DPRINT1("Safe removal: %S\n", PnpEvent->TargetDevice.DeviceIds);
145 
146 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
147 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
148 // &dwRecipient,
149 // WM_DEVICECHANGE,
150 // DBT_DEVNODES_CHANGED,
151 // 0);
153  }
154  else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_SURPRISE_REMOVAL, &RpcStatus))
155  {
156 // DWORD dwRecipient;
157 
158  DPRINT1("Surprise removal: %S\n", PnpEvent->TargetDevice.DeviceIds);
159 
160 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
161 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
162 // &dwRecipient,
163 // WM_DEVICECHANGE,
164 // DBT_DEVNODES_CHANGED,
165 // 0);
167  }
168  else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_REMOVAL_VETOED, &RpcStatus))
169  {
170  DPRINT1("Removal vetoed: %S\n", PnpEvent->TargetDevice.DeviceIds);
171  }
172  else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_REMOVE_PENDING, &RpcStatus))
173  {
174  DPRINT1("Removal pending: %S\n", PnpEvent->TargetDevice.DeviceIds);
175  }
176  else
177  {
178  DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
179  PnpEvent->EventGuid.Data1, PnpEvent->EventGuid.Data2, PnpEvent->EventGuid.Data3,
180  PnpEvent->EventGuid.Data4[0], PnpEvent->EventGuid.Data4[1], PnpEvent->EventGuid.Data4[2],
181  PnpEvent->EventGuid.Data4[3], PnpEvent->EventGuid.Data4[4], PnpEvent->EventGuid.Data4[5],
182  PnpEvent->EventGuid.Data4[6], PnpEvent->EventGuid.Data4[7]);
183  }
184 
185  /* Dequeue the current PnP event and signal the next one */
187  &ResponseData,
188  sizeof(ResponseData));
189  if (!NT_SUCCESS(Status))
190  {
191  DPRINT1("NtPlugPlayControl(PlugPlayControlUserResponse) failed (Status 0x%08lx)\n", Status);
192  break;
193  }
194  }
195 
196  HeapFree(GetProcessHeap(), 0, PnpEvent);
197 
198  return dwRet;
199 }
200 
201 
202 static VOID
204 {
206  ServiceStatus.dwCurrentState = dwState;
211 
212  if (dwState == SERVICE_START_PENDING ||
213  dwState == SERVICE_STOP_PENDING ||
214  dwState == SERVICE_PAUSE_PENDING ||
215  dwState == SERVICE_CONTINUE_PENDING)
216  ServiceStatus.dwWaitHint = 10000;
217  else
219 
221  &ServiceStatus);
222 }
223 
224 
225 static DWORD WINAPI
227  DWORD dwEventType,
228  LPVOID lpEventData,
229  LPVOID lpContext)
230 {
231  DPRINT1("ServiceControlHandler() called\n");
232 
233  switch (dwControl)
234  {
236  DPRINT1(" SERVICE_CONTROL_STOP received\n");
237  /* Stop listening to RPC Messages */
240  return ERROR_SUCCESS;
241 
243  DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
245  return ERROR_SUCCESS;
246 
248  DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
250  return ERROR_SUCCESS;
251 
253  DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
255  &ServiceStatus);
256  return ERROR_SUCCESS;
257 
259  DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
260  /* Stop listening to RPC Messages */
263  return ERROR_SUCCESS;
264 
265  default :
266  DPRINT1(" Control %lu received\n", dwControl);
268  }
269 }
270 
271 static DWORD
273  IN HKEY hKey,
274  IN PCWSTR lpSubKey,
275  IN PCWSTR lpValue,
276  OUT PBOOL pValue)
277 {
278  DWORD dwError, dwType, dwData;
279  DWORD cbData = sizeof(dwData);
280  HKEY hSubKey = NULL;
281 
282  /* Default value */
283  *pValue = FALSE;
284 
285  dwError = RegOpenKeyExW(hKey,
286  lpSubKey,
287  0,
288  KEY_READ,
289  &hSubKey);
290  if (dwError != ERROR_SUCCESS)
291  {
292  DPRINT("GetBooleanRegValue(): RegOpenKeyExW() has failed to open '%S' key! (Error: %lu)\n",
293  lpSubKey, dwError);
294  return dwError;
295  }
296 
297  dwError = RegQueryValueExW(hSubKey,
298  lpValue,
299  0,
300  &dwType,
301  (PBYTE)&dwData,
302  &cbData);
303  if (dwError != ERROR_SUCCESS)
304  {
305  DPRINT("GetBooleanRegValue(): RegQueryValueExW() has failed to query '%S' value! (Error: %lu)\n",
306  lpValue, dwError);
307  goto Cleanup;
308  }
309  if (dwType != REG_DWORD)
310  {
311  DPRINT("GetBooleanRegValue(): The value is not of REG_DWORD type!\n");
312  goto Cleanup;
313  }
314 
315  /* Return the value */
316  *pValue = (dwData == 1);
317 
318 Cleanup:
319  RegCloseKey(hSubKey);
320 
321  return dwError;
322 }
323 
324 BOOL
326 {
327  BOOL bSuppressNewHWUI = FALSE;
328 
329  /*
330  * Query the SuppressNewHWUI policy registry value. Don't cache it
331  * as we want to update our behaviour in consequence.
332  */
334  L"Software\\Policies\\Microsoft\\Windows\\DeviceInstall\\Settings",
335  L"SuppressNewHWUI",
336  &bSuppressNewHWUI);
337  if (bSuppressNewHWUI)
338  DPRINT("GetSuppressNewUIValue(): newdev.dll's wizard UI won't be shown!\n");
339 
340  return bSuppressNewHWUI;
341 }
342 
343 VOID WINAPI
345 {
346  HANDLE hThread;
348 
351 
352  DPRINT("ServiceMain() called\n");
353 
356  NULL);
357  if (!ServiceStatusHandle)
358  {
359  DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
360  return;
361  }
362 
364 
366  0,
368  NULL,
369  0,
370  &dwThreadId);
371  if (hThread != NULL)
373 
375  0,
377  NULL,
378  0,
379  &dwThreadId);
380  if (hThread != NULL)
382 
384  0,
386  NULL,
387  0,
388  &dwThreadId);
389  if (hThread != NULL)
391 
393 
394  DPRINT("ServiceMain() done\n");
395 }
396 
397 static DWORD
399 {
400  BOOLEAN OldValue;
401  DWORD dwError;
402 
403  DPRINT("UMPNPMGR: InitializePnPManager() started\n");
404 
405  /* We need this privilege for using CreateProcessAsUserW */
407 
409  if (hInstallEvent == NULL)
410  {
411  dwError = GetLastError();
412  DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError);
413  return dwError;
414  }
415 
418  {
419  dwError = GetLastError();
420  DPRINT1("Could not create the Event! (Error %lu)\n", dwError);
421  return dwError;
422  }
423 
425  TRUE,
426  FALSE,
427  L"Global\\PnP_No_Pending_Install_Events");
428  if (hNoPendingInstalls == NULL)
429  {
430  dwError = GetLastError();
431  DPRINT1("Could not create the Event! (Error %lu)\n", dwError);
432  return dwError;
433  }
434 
436 
437  /* Query the SuppressUI registry value and cache it for our whole lifetime */
439  L"System\\CurrentControlSet\\Services\\PlugPlay\\Parameters",
440  L"SuppressUI",
442  if (g_IsUISuppressed)
443  DPRINT("UMPNPMGR: newdev.dll's wizard UI won't be shown!\n");
444 
446  L"System\\CurrentControlSet\\Enum",
447  0,
449  &hEnumKey);
450  if (dwError != ERROR_SUCCESS)
451  {
452  DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError);
453  return dwError;
454  }
455 
457  L"System\\CurrentControlSet\\Control\\Class",
458  0,
460  &hClassKey);
461  if (dwError != ERROR_SUCCESS)
462  {
463  DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError);
464  return dwError;
465  }
466 
467  DPRINT("UMPNPMGR: InitializePnPManager() done\n");
468 
469  return 0;
470 }
471 
472 BOOL WINAPI
474  DWORD fdwReason,
476 {
477  switch (fdwReason)
478  {
479  case DLL_PROCESS_ATTACH:
480  DisableThreadLibraryCalls(hinstDLL);
482  break;
483 
484  case DLL_PROCESS_DETACH:
485  break;
486  }
487 
488  return TRUE;
489 }
490 
491 /* EOF */
static int argc
Definition: ServiceArgs.c:12
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
Definition: umpnpmgr.c:473
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
Definition: umpnpmgr.c:344
#define CloseHandle
Definition: compat.h:398
RPC_STATUS WINAPI RpcMgmtStopServerListening(RPC_BINDING_HANDLE Binding)
Definition: rpc_server.c:1599
static SERVICE_STATUS ServiceStatus
Definition: umpnpmgr.c:42
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL g_IsUISuppressed
Definition: umpnpmgr.c:46
DWORD dwCurrentState
Definition: winsvc.h:100
#define DBT_DEVNODES_CHANGED
Definition: dbt.h:28
#define SERVICE_PAUSE_PENDING
Definition: winsvc.h:26
#define KEY_READ
Definition: nt_native.h:1023
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define SERVICE_PAUSED
Definition: winsvc.h:27
HANDLE hInstallEvent
Definition: install.c:40
LONG NTSTATUS
Definition: precomp.h:26
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
static HANDLE ULONG_PTR dwData
Definition: file.c:35
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
NTSYSAPI NTSTATUS NTAPI RtlAdjustPrivilege(_In_ ULONG Privilege, _In_ BOOLEAN NewValue, _In_ BOOLEAN ForThread, _Out_ PBOOLEAN OldValue)
#define SERVICE_START_PENDING
Definition: winsvc.h:22
DWORD dwServiceSpecificExitCode
Definition: winsvc.h:103
static VOID UpdateServiceStatus(DWORD dwState)
Definition: umpnpmgr.c:203
#define DLL_PROCESS_ATTACH
Definition: compat.h:120
int WINAPI UuidEqual(UUID *Uuid1, UUID *Uuid2, RPC_STATUS *Status)
Definition: rpcrt4_main.c:253
SLIST_HEADER DeviceInstallListHead
Definition: install.c:43
#define argv
Definition: mplay32.c:18
#define lstrlenW
Definition: compat.h:407
CHAR * LPTSTR
Definition: xmlstorage.h:192
static IN DWORD IN LPVOID lpvReserved
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 GetSuppressNewUIValue(VOID)
Definition: umpnpmgr.c:325
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: sctrl.c:995
long RPC_STATUS
Definition: rpc.h:52
DWORD dwCheckPoint
Definition: winsvc.h:104
#define SERVICE_STOPPED
Definition: winsvc.h:21
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned int BOOL
Definition: ntddk_ex.h:94
NTSTATUS NTAPI NtGetPlugPlayEvent(IN ULONG Reserved1, IN ULONG Reserved2, OUT PPLUGPLAY_EVENT_BLOCK Buffer, IN ULONG BufferSize)
Definition: plugplay.c:1169
#define SERVICE_RUNNING
Definition: winsvc.h:24
static SERVICE_STATUS_HANDLE ServiceStatusHandle
Definition: umpnpmgr.c:41
static DWORD WINAPI PnpEventThread(LPVOID lpParameter)
Definition: umpnpmgr.c:51
HKEY hEnumKey
Definition: umpnpmgr.c:44
unsigned char BOOLEAN
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:136
static BOOL SetupIsActive(VOID)
Definition: setup.c:27
smooth NULL
Definition: ftsmooth.c:416
WCHAR DeviceIds[1]
Definition: precomp.h:39
void DPRINT(...)
Definition: polytest.cpp:61
#define SERVICE_CONTROL_INTERROGATE
Definition: winsvc.h:39
static DWORD InitializePnPManager(VOID)
Definition: umpnpmgr.c:398
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:960
BOOL * PBOOL
Definition: windef.h:161
HANDLE hNoPendingInstalls
Definition: install.c:41
struct _PLUGPLAY_EVENT_BLOCK::@2278::@2281 TargetDevice
FORCEINLINE VOID InitializeSListHead(_Out_ PSLIST_HEADER SListHead)
Definition: rtlfuncs.h:3353
#define DLL_PROCESS_DETACH
Definition: compat.h:119
static SERVICE_STATUS_HANDLE(WINAPI *pRegisterServiceCtrlHandlerExA)(LPCSTR
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DWORD dwWaitHint
Definition: winsvc.h:105
#define WINAPI
Definition: msvc.h:8
DWORD dwWin32ExitCode
Definition: winsvc.h:102
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD dwServiceType
Definition: winsvc.h:99
#define SERVICE_CONTROL_PAUSE
Definition: winsvc.h:37
DWORD dwThreadId
Definition: fdebug.c:31
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
static DWORD WINAPI ServiceControlHandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
Definition: umpnpmgr.c:226
LPVOID lpParameter
Definition: kernel32.h:241
static DWORD GetBooleanRegValue(IN HKEY hKey, IN PCWSTR lpSubKey, IN PCWSTR lpValue, OUT PBOOL pValue)
Definition: umpnpmgr.c:272
GLenum GLsizei len
Definition: glext.h:6722
SLIST_ENTRY ListEntry
Definition: precomp.h:38
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExW(LPCWSTR lpServiceName, LPHANDLER_FUNCTION_EX lpHandlerProc, LPVOID lpContext)
Definition: sctrl.c:810
NTKERNELAPI PSLIST_ENTRY FASTCALL InterlockedPushEntrySList(IN PSLIST_HEADER ListHead, IN PSLIST_ENTRY ListEntry)
Definition: interlocked.c:82
static const WCHAR Cleanup[]
Definition: register.c:80
HANDLE hDeviceInstallListNotEmpty
Definition: install.c:44
Status
Definition: gdiplustypes.h:24
DWORD dwControlsAccepted
Definition: winsvc.h:101
NTSTATUS NTAPI NtPlugPlayControl(IN PLUGPLAY_CONTROL_CLASS PlugPlayControlClass, IN OUT PVOID Buffer, IN ULONG BufferLength)
Definition: plugplay.c:1299
#define SERVICE_CONTINUE_PENDING
Definition: winsvc.h:25
DWORD WINAPI RpcServerThread(LPVOID lpParameter)
Definition: rpcserver.c:45
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define SERVICE_CONTROL_CONTINUE
Definition: winsvc.h:38
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define HeapReAlloc
Definition: compat.h:393
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
HANDLE hThread
Definition: wizard.c:27
#define WM_DEVICECHANGE
Definition: winuser.h:1793
#define DPRINT1
Definition: precomp.h:8
#define OUT
Definition: typedefs.h:39
#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
Definition: security.c:657
unsigned int ULONG
Definition: retypes.h:1
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
static WCHAR ServiceName[]
Definition: umpnpmgr.c:39
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define REG_DWORD
Definition: sdbapi.c:596
#define HWND_BROADCAST
Definition: winuser.h:1190
DWORD WINAPI DeviceInstallThread(LPVOID lpParameter)
Definition: install.c:355
BYTE * PBYTE
Definition: pedump.c:66
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
#define HeapFree(x, y, z)
Definition: compat.h:394
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
HKEY hClassKey
Definition: umpnpmgr.c:45
#define SERVICE_CONTROL_SHUTDOWN
Definition: winsvc.h:40
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12