ReactOS  0.4.15-dev-1618-g9c8ed68
devinst.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS text-mode setup
4  * PURPOSE: Device installation
5  * PROGRAMMER: Hervé Poussineau (hpoussin@reactos.org)
6  * Hermes Belusca-Maito
7  */
8 
9 #include <usetup.h>
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 #define INITGUID
15 #include <guiddef.h>
16 #include <libs/umpnpmgr/sysguid.h>
17 
18 /* LOCALS *******************************************************************/
19 
20 static HANDLE hEnumKey = NULL;
22 
24 
27 
28 /* Device-install event list */
32 
33 typedef struct
34 {
35  LIST_ENTRY ListEntry;
36  WCHAR DeviceIds[ANYSIZE_ARRAY];
38 
39 /* FUNCTIONS ****************************************************************/
40 
41 static BOOLEAN
43  IN LPCWSTR DeviceId)
44 {
45  PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData;
47 
48  RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, DeviceId);
50  if (!NT_SUCCESS(Status))
51  {
52  DPRINT1("NtPlugPlayControl() failed with status 0x%08x\n", Status);
53  return FALSE;
54  }
55  return TRUE;
56 }
57 
58 static BOOLEAN
60  IN HINF hInf,
61  IN HANDLE hServices,
62  IN HANDLE hDeviceKey,
63  IN LPCWSTR DeviceId,
64  IN LPCWSTR HardwareId)
65 {
66  UNICODE_STRING ServiceU = RTL_CONSTANT_STRING(L"Service");
67  UNICODE_STRING ErrorControlU = RTL_CONSTANT_STRING(L"ErrorControl");
68  UNICODE_STRING StartU = RTL_CONSTANT_STRING(L"Start");
69  UNICODE_STRING TypeU = RTL_CONSTANT_STRING(L"Type");
70  UNICODE_STRING UpperFiltersU = RTL_CONSTANT_STRING(L"UpperFilters");
71  PWSTR keyboardClass = L"kbdclass\0";
72  PWSTR partMgr = L"partmgr\0";
73 
74  UNICODE_STRING StringU;
76  HANDLE hService;
78  PCWSTR Driver, ClassGuid, ImagePath;
79  ULONG dwValue;
82  BOOLEAN deviceInstalled = FALSE;
83 
84  /* Check if we know the hardware */
85  if (!SpInfFindFirstLine(hInf, L"HardwareIdsDatabase", HardwareId, &Context))
86  return FALSE;
87  if (!INF_GetDataField(&Context, 1, &Driver))
88  return FALSE;
89 
90  /* Get associated class GUID (if any) */
91  if (!INF_GetDataField(&Context, 2, &ClassGuid))
92  ClassGuid = NULL;
93 
94  /* Find associated driver name */
95  /* FIXME: check in other sections too! */
96  if (!SpInfFindFirstLine(hInf, L"BootBusExtenders.Load", Driver, &Context)
97  && !SpInfFindFirstLine(hInf, L"BusExtenders.Load", Driver, &Context)
98  && !SpInfFindFirstLine(hInf, L"SCSI.Load", Driver, &Context)
99  && !SpInfFindFirstLine(hInf, L"InputDevicesSupport.Load", Driver, &Context)
100  && !SpInfFindFirstLine(hInf, L"Keyboard.Load", Driver, &Context))
101  {
102  INF_FreeData(ClassGuid);
104  return FALSE;
105  }
106 
107  if (!INF_GetDataField(&Context, 1, &ImagePath))
108  {
109  INF_FreeData(ClassGuid);
111  return FALSE;
112  }
113 
114  DPRINT1("Using driver '%S' for device '%S'\n", ImagePath, DeviceId);
115 
116  /* Create service key */
117  RtlInitUnicodeString(&StringU, Driver);
120  if (!NT_SUCCESS(Status))
121  {
122  DPRINT1("NtCreateKey('%wZ') failed with status 0x%08x\n", &StringU, Status);
123  INF_FreeData(ImagePath);
124  INF_FreeData(ClassGuid);
126  return FALSE;
127  }
128 
129  /* Fill service key */
131  {
132  dwValue = 0;
133  NtSetValueKey(hService,
134  &ErrorControlU,
135  0,
136  REG_DWORD,
137  &dwValue,
138  sizeof(dwValue));
139 
140  dwValue = 0;
141  NtSetValueKey(hService,
142  &StartU,
143  0,
144  REG_DWORD,
145  &dwValue,
146  sizeof(dwValue));
147 
148  dwValue = SERVICE_KERNEL_DRIVER;
149  NtSetValueKey(hService,
150  &TypeU,
151  0,
152  REG_DWORD,
153  &dwValue,
154  sizeof(dwValue));
155  }
156 
157  INF_FreeData(ImagePath);
158  NtClose(hService);
159 
160  /* Add kbdclass and partmgr upper filters */
161  if (ClassGuid &&_wcsicmp(ClassGuid, L"{4D36E96B-E325-11CE-BFC1-08002BE10318}") == 0)
162  {
163  DPRINT1("Installing keyboard class driver for '%S'\n", DeviceId);
164  NtSetValueKey(hDeviceKey,
165  &UpperFiltersU,
166  0,
167  REG_MULTI_SZ,
168  keyboardClass,
169  (wcslen(keyboardClass) + 2) * sizeof(WCHAR));
170  }
171  else if (ClassGuid && _wcsicmp(ClassGuid, L"{4D36E967-E325-11CE-BFC1-08002BE10318}") == 0)
172  {
173  DPRINT1("Installing partition manager driver for '%S'\n", DeviceId);
174  NtSetValueKey(hDeviceKey,
175  &UpperFiltersU,
176  0,
177  REG_MULTI_SZ,
178  partMgr,
179  (wcslen(partMgr) + 2) * sizeof(WCHAR));
180  }
181 
182  INF_FreeData(ClassGuid);
183 
184  /* Associate device with the service we just filled */
185  Status = NtSetValueKey(hDeviceKey,
186  &ServiceU,
187  0,
188  REG_SZ,
189  (PVOID)Driver,
190  (wcslen(Driver) + 1) * sizeof(WCHAR));
191  if (NT_SUCCESS(Status))
192  {
193  /* Restart the device, so it will use the driver we registered */
194  deviceInstalled = ResetDevice(DeviceId);
195  }
196 
198 
199  return deviceInstalled;
200 }
201 
202 static VOID
204  IN HINF hInf,
205  IN HANDLE hEnum,
206  IN HANDLE hServices,
207  IN LPCWSTR DeviceId)
208 {
209  UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID");
210  UNICODE_STRING CompatibleIDsU = RTL_CONSTANT_STRING(L"CompatibleIDs");
211 
212  UNICODE_STRING DeviceIdU;
215  PKEY_VALUE_PARTIAL_INFORMATION pPartialInformation = NULL;
216  HANDLE hDeviceKey;
217  ULONG ulRequired;
218  BOOLEAN bDriverInstalled = FALSE;
220 
221  RtlInitUnicodeString(&DeviceIdU, DeviceId);
224  if (!NT_SUCCESS(Status))
225  {
226  DPRINT("Unable to open subkey '%S'\n", DeviceId);
227  return;
228  }
229 
231  hDeviceKey,
232  &HardwareIDU,
234  NULL,
235  0,
236  &ulRequired);
238  {
239  pPartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)RtlAllocateHeap(ProcessHeap, 0, ulRequired);
240  if (!pPartialInformation)
241  {
242  DPRINT1("RtlAllocateHeap() failed\n");
243  NtClose(hDeviceKey);
244  return;
245  }
247  hDeviceKey,
248  &HardwareIDU,
250  pPartialInformation,
251  ulRequired,
252  &ulRequired);
253  }
255  {
256  /* Nothing to do */
257  }
258  else if (!NT_SUCCESS(Status))
259  {
260  DPRINT1("NtQueryValueKey() failed with status 0x%08x\n", Status);
261  if (pPartialInformation)
262  RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
263  NtClose(hDeviceKey);
264  return;
265  }
266  else if (pPartialInformation)
267  {
268  for (HardwareID = (LPCWSTR)pPartialInformation->Data;
270  && *HardwareID
271  && !bDriverInstalled;
272  HardwareID += wcslen(HardwareID) + 1)
273  {
274  bDriverInstalled = InstallDriver(hInf, hServices,hDeviceKey, DeviceId, HardwareID);
275  }
276  }
277 
278  if (!bDriverInstalled)
279  {
280  if (pPartialInformation)
281  {
282  RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
283  pPartialInformation = NULL;
284  }
286  hDeviceKey,
287  &CompatibleIDsU,
289  NULL,
290  0,
291  &ulRequired);
293  {
294  pPartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)RtlAllocateHeap(ProcessHeap, 0, ulRequired);
295  if (!pPartialInformation)
296  {
297  DPRINT("RtlAllocateHeap() failed\n");
298  NtClose(hDeviceKey);
299  return;
300  }
302  hDeviceKey,
303  &CompatibleIDsU,
305  pPartialInformation,
306  ulRequired,
307  &ulRequired);
308  }
310  {
311  /* Nothing to do */
312  }
313  else if (!NT_SUCCESS(Status))
314  {
315  if (pPartialInformation)
316  RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
317  NtClose(hDeviceKey);
318  DPRINT1("NtQueryValueKey() failed with status 0x%08x\n", Status);
319  return;
320  }
321  else if (pPartialInformation)
322  {
323  for (HardwareID = (LPCWSTR)pPartialInformation->Data;
325  && *HardwareID
326  && !bDriverInstalled;
327  HardwareID += wcslen(HardwareID) + 1)
328  {
329  bDriverInstalled = InstallDriver(hInf, hServices,hDeviceKey, DeviceId, HardwareID);
330  }
331  }
332  }
333  if (!bDriverInstalled)
334  DPRINT("No driver available for %S\n", DeviceId);
335 
336  RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
337  NtClose(hDeviceKey);
338 }
339 
340 /* Loop to install all queued devices installations */
341 static ULONG NTAPI
343 {
345  PLIST_ENTRY ListEntry;
348 
349  for (;;)
350  {
351  /* Dequeue the next oldest device-install event */
353  ListEntry = (IsListEmpty(&DeviceInstallListHead)
356 
357  if (ListEntry == NULL)
358  {
359  /*
360  * The list is now empty, but there may be a new enumerated device
361  * that is going to be added to the list soon. In order to avoid
362  * setting the hNoPendingInstalls event to release it soon after,
363  * we wait for maximum 1 second for no PnP enumeration event being
364  * received before declaring that no pending installations are
365  * taking place and setting the corresponding event.
366  */
367  Timeout.QuadPart = -10000000LL; /* Wait for 1 second */
369  {
370  /* We timed out: set the event and do the actual wait */
373  }
374  }
375  else
376  {
378  Params = CONTAINING_RECORD(ListEntry, DeviceInstallParams, ListEntry);
381  }
382  }
383 
384  return 0;
385 }
386 
387 static ULONG NTAPI
389 {
391  PLUGPLAY_CONTROL_USER_RESPONSE_DATA ResponseData = {0, 0, 0, 0};
392  PPLUGPLAY_EVENT_BLOCK PnpEvent, NewPnpEvent;
393  ULONG PnpEventSize;
394 
396 
397  PnpEventSize = 0x1000;
398  PnpEvent = RtlAllocateHeap(ProcessHeap, 0, PnpEventSize);
399  if (PnpEvent == NULL)
400  {
402  goto Quit;
403  }
404 
405  for (;;)
406  {
407  DPRINT("Calling NtGetPlugPlayEvent()\n");
408 
409  /* Wait for the next PnP event */
410  Status = NtGetPlugPlayEvent(0, 0, PnpEvent, PnpEventSize);
411 
412  /* Resize the buffer for the PnP event if it's too small */
414  {
415  PnpEventSize += 0x400;
416  NewPnpEvent = RtlReAllocateHeap(ProcessHeap, 0, PnpEvent, PnpEventSize);
417  if (NewPnpEvent == NULL)
418  {
420  goto Quit;
421  }
422  PnpEvent = NewPnpEvent;
423  continue;
424  }
425 
426  if (!NT_SUCCESS(Status))
427  {
428  DPRINT1("NtGetPlugPlayEvent() failed (Status 0x%08lx)\n", Status);
429  goto Quit;
430  }
431 
432  /* Process the PnP event */
433  DPRINT("Received PnP Event\n");
434  if (IsEqualGUID(&PnpEvent->EventGuid, &GUID_DEVICE_ENUMERATED))
435  {
437  ULONG len;
438  ULONG DeviceIdLength;
439 
440  DPRINT("Device enumerated: %S\n", PnpEvent->TargetDevice.DeviceIds);
441 
442  DeviceIdLength = wcslen(PnpEvent->TargetDevice.DeviceIds);
443  if (DeviceIdLength)
444  {
445  /* Allocate a new device-install event */
446  len = FIELD_OFFSET(DeviceInstallParams, DeviceIds) + (DeviceIdLength + 1) * sizeof(WCHAR);
448  if (Params)
449  {
450  wcscpy(Params->DeviceIds, PnpEvent->TargetDevice.DeviceIds);
451 
452  /* Queue the event (will be dequeued by DeviceInstallThread) */
456 
458  }
459  else
460  {
461  DPRINT1("Not enough memory (size %lu)\n", len);
462  }
463  }
464  }
465  else
466  {
467  DPRINT("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
468  PnpEvent->EventGuid.Data1, PnpEvent->EventGuid.Data2, PnpEvent->EventGuid.Data3,
469  PnpEvent->EventGuid.Data4[0], PnpEvent->EventGuid.Data4[1], PnpEvent->EventGuid.Data4[2],
470  PnpEvent->EventGuid.Data4[3], PnpEvent->EventGuid.Data4[4], PnpEvent->EventGuid.Data4[5],
471  PnpEvent->EventGuid.Data4[6], PnpEvent->EventGuid.Data4[7]);
472  }
473 
474  /* Dequeue the current PnP event and signal the next one */
476  &ResponseData,
477  sizeof(ResponseData));
478  if (!NT_SUCCESS(Status))
479  {
480  DPRINT1("NtPlugPlayControl(PlugPlayControlUserResponse) failed (Status 0x%08lx)\n", Status);
481  goto Quit;
482  }
483  }
484 
486 
487 Quit:
488  if (PnpEvent)
489  RtlFreeHeap(ProcessHeap, 0, PnpEvent);
490 
492  return Status;
493 }
494 
495 NTSTATUS
498 {
500 }
501 
502 BOOLEAN
504 {
506 
507  /* Start the PnP thread */
508  if (hPnpThread != NULL)
510 
511  /*
512  * Wait a little bit so that we get a chance to have some events being
513  * queued by the time the device-installation thread becomes resumed.
514  */
515  Timeout.QuadPart = -10000000LL; /* Wait for 1 second */
517 
518  /* Start the device installation thread */
519  if (hDeviceInstallThread != NULL)
521 
522  return TRUE;
523 }
524 
525 BOOLEAN
527 {
528  /* Wait until all pending installations are done, then freeze the threads */
530  DPRINT1("WaitNoPendingInstallEvents() failed to wait!\n");
531 
532  // TODO: use signalling events
533 
536 
537  return TRUE;
538 }
539 
540 NTSTATUS
542  IN HINF* phSetupInf)
543 {
546 
547  UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum");
548  UNICODE_STRING ServicesU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
549 
552  NULL,
554  FALSE);
555  if (!NT_SUCCESS(Status))
556  {
557  DPRINT1("Could not create the Pending-Install Event! (Status 0x%08lx)\n", Status);
558  goto Failure;
559  }
560 
561  /*
562  * Initialize the device-install event list
563  */
564 
567  NULL,
569  FALSE);
570  if (!NT_SUCCESS(Status))
571  {
572  DPRINT1("Could not create the List Event! (Status 0x%08lx)\n", Status);
573  goto Failure;
574  }
575 
578  NULL, FALSE);
579  if (!NT_SUCCESS(Status))
580  {
581  DPRINT1("Could not create the List Mutex! (Status 0x%08lx)\n", Status);
582  goto Failure;
583  }
585 
588  if (!NT_SUCCESS(Status))
589  {
590  DPRINT1("NtOpenKey('%wZ') failed (Status 0x%08lx)\n", &EnumU, Status);
591  goto Failure;
592  }
593 
596  if (!NT_SUCCESS(Status))
597  {
598  DPRINT1("NtCreateKey('%wZ') failed (Status 0x%08lx)\n", &ServicesU, Status);
599  goto Failure;
600  }
601 
602  /* Create the PnP event thread in suspended state */
604  NULL,
605  TRUE,
606  0,
607  0,
608  0,
610  NULL,
611  &hPnpThread,
612  NULL);
613  if (!NT_SUCCESS(Status))
614  {
615  DPRINT1("Failed to create the PnP event thread (Status 0x%08lx)\n", Status);
616  hPnpThread = NULL;
617  goto Failure;
618  }
619 
620  /* Create the device installation thread in suspended state */
622  NULL,
623  TRUE,
624  0,
625  0,
626  0,
628  phSetupInf,
630  NULL);
631  if (!NT_SUCCESS(Status))
632  {
633  DPRINT1("Failed to create the device installation thread (Status 0x%08lx)\n", Status);
635  goto Failure;
636  }
637 
638  return STATUS_SUCCESS;
639 
640 Failure:
641  if (hPnpThread)
642  {
645  }
646  hPnpThread = NULL;
647 
648  if (hServicesKey)
650  hServicesKey = NULL;
651 
652  if (hEnumKey)
653  NtClose(hEnumKey);
654  hEnumKey = NULL;
655 
659 
663 
664  if (hNoPendingInstalls)
667 
668  return Status;
669 }
670 
671 VOID
673 {
675 
676  // TODO: use signalling events
677 
678  /* Kill the PnP thread as it blocks inside the NtGetPlugPlayEvent() call */
679  if (hPnpThread)
680  {
683  }
684  hPnpThread = NULL;
685 
686  /* Kill the device installation thread */
688  {
691  }
693 
694  /* Close the opened handles */
695 
696  if (hServicesKey)
698  hServicesKey = NULL;
699 
700  if (hEnumKey)
701  NtClose(hEnumKey);
702  hEnumKey = NULL;
703 
704  if (hNoPendingInstalls)
707 
711 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define IN
Definition: typedefs.h:39
HINF hSetupInf
Definition: intl.c:39
#define LL
Definition: tui.h:84
NTSTATUS NTAPI NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: ntapi.c:240
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:306
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define ANYSIZE_ARRAY
Definition: typedefs.h:46
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
struct _PLUGPLAY_EVENT_BLOCK::@2361::@2364 TargetDevice
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define NtCurrentThread()
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:96
pSpInfFindFirstLine SpInfFindFirstLine
Definition: infsupp.c:87
_In_ PVOID Parameter
Definition: ldrtypes.h:241
#define InsertTailList(ListHead, Entry)
NTSTATUS NTAPI NtSuspendThread(IN HANDLE ThreadHandle, OUT PULONG PreviousSuspendCount OPTIONAL)
Definition: state.c:352
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
static HANDLE hEnumKey
Definition: devinst.c:20
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
NTSTATUS NTAPI NtResetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:385
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
#define STATUS_WAIT_0
Definition: ntstatus.h:237
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
static HANDLE hPnpThread
Definition: devinst.c:25
#define FALSE
Definition: types.h:117
#define MUTANT_ALL_ACCESS
Definition: extypes.h:110
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
NTSTATUS NTAPI NtGetPlugPlayEvent(IN ULONG Reserved1, IN ULONG Reserved2, OUT PPLUGPLAY_EVENT_BLOCK Buffer, IN ULONG BufferSize)
Definition: plugplay.c:1129
#define REG_MULTI_SZ
Definition: nt_native.h:1501
static HANDLE hDeviceInstallThread
Definition: devinst.c:26
unsigned char BOOLEAN
BOOLEAN INF_GetDataField(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT PCWSTR *Data)
Definition: infsupp.c:42
static ULONG NTAPI DeviceInstallThread(IN PVOID Parameter)
Definition: devinst.c:342
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
NTSTATUS InitializeUserModePnpManager(IN HINF *phSetupInf)
Definition: devinst.c:541
void DPRINT(...)
Definition: polytest.cpp:61
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define NtCurrentProcess()
Definition: nt_native.h:1657
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
static BOOLEAN InstallDriver(IN HINF hInf, IN HANDLE hServices, IN HANDLE hDeviceKey, IN LPCWSTR DeviceId, IN LPCWSTR HardwareId)
Definition: devinst.c:59
Status
Definition: gdiplustypes.h:24
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
static HANDLE hServicesKey
Definition: devinst.c:21
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1278
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:454
static HANDLE hNoPendingInstalls
Definition: devinst.c:23
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN EnableUserModePnpManager(VOID)
Definition: devinst.c:503
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
static ULONG NTAPI PnpEventThread(IN PVOID Parameter)
Definition: devinst.c:388
FORCEINLINE VOID INF_FreeData(IN PCWSTR InfData)
Definition: infsupp.h:157
NTSTATUS NTAPI NtCreateMutant(OUT PHANDLE MutantHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN BOOLEAN InitialOwner)
Definition: mutant.c:79
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
_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
GLenum GLsizei len
Definition: glext.h:6722
Definition: typedefs.h:119
NTSYSAPI NTSTATUS NTAPI RtlCreateUserThread(_In_ PVOID ThreadContext, _Out_ HANDLE *OutThreadHandle, _Reserved_ PVOID Reserved1, _Reserved_ PVOID Reserved2, _Reserved_ PVOID Reserved3, _Reserved_ PVOID Reserved4, _Reserved_ PVOID Reserved5, _Reserved_ PVOID Reserved6, _Reserved_ PVOID Reserved7, _Reserved_ PVOID Reserved8)
static BOOLEAN ResetDevice(IN LPCWSTR DeviceId)
Definition: devinst.c:42
HANDLE ProcessHeap
Definition: servman.c:15
static HANDLE hDeviceInstallListNotEmpty
Definition: devinst.c:31
static LIST_ENTRY DeviceInstallListHead
Definition: devinst.c:30
NTSTATUS NTAPI NtPlugPlayControl(IN PLUGPLAY_CONTROL_CLASS PlugPlayControlClass, IN OUT PVOID Buffer, IN ULONG BufferLength)
Definition: plugplay.c:1259
static ULONG Timeout
Definition: ping.c:61
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
NTSTATUS WaitNoPendingInstallEvents(IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: devinst.c:496
static VOID InstallDevice(IN HINF hInf, IN HANDLE hEnum, IN HANDLE hServices, IN LPCWSTR DeviceId)
Definition: devinst.c:203
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
VOID TerminateUserModePnpManager(VOID)
Definition: devinst.c:672
#define NULL
Definition: types.h:112
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING HardwareID
Definition: wdfpdo.h:337
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
struct tagContext Context
Definition: acpixf.h:1034
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2622
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define STATUS_SUCCESS
Definition: shellext.h:65
BOOLEAN DisableUserModePnpManager(VOID)
Definition: devinst.c:526
#define REG_DWORD
Definition: sdbapi.c:596
_Must_inspect_result_ _In_ WDFDRIVER Driver
Definition: wdfcontrol.h:83
NTSTATUS NTAPI NtReleaseMutant(IN HANDLE MutantHandle, IN PLONG PreviousCount OPTIONAL)
Definition: mutant.c:295
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static HANDLE hDeviceInstallListMutex
Definition: devinst.c:29
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define SERVICE_KERNEL_DRIVER
Definition: cmtypes.h:953
#define REG_SZ
Definition: layer.c:22
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)