ReactOS  0.4.13-dev-563-g0561610
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 
30 
31 typedef struct
32 {
34  WCHAR DeviceIds[ANYSIZE_ARRAY];
36 
37 /* FUNCTIONS ****************************************************************/
38 
39 static BOOLEAN
41  IN LPCWSTR DeviceId)
42 {
43  PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData;
45 
46  RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, DeviceId);
48  if (!NT_SUCCESS(Status))
49  {
50  DPRINT1("NtPlugPlayControl() failed with status 0x%08x\n", Status);
51  return FALSE;
52  }
53  return TRUE;
54 }
55 
56 static BOOLEAN
58  IN HINF hInf,
59  IN HANDLE hServices,
60  IN HANDLE hDeviceKey,
61  IN LPCWSTR DeviceId,
62  IN LPCWSTR HardwareId)
63 {
64  UNICODE_STRING PathPrefix = RTL_CONSTANT_STRING(L"System32\\DRIVERS\\");
65  UNICODE_STRING ServiceU = RTL_CONSTANT_STRING(L"Service");
66  UNICODE_STRING ErrorControlU = RTL_CONSTANT_STRING(L"ErrorControl");
67  UNICODE_STRING ImagePathU = RTL_CONSTANT_STRING(L"ImagePath");
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 
73  UNICODE_STRING StringU;
75  HANDLE hService;
77  PCWSTR Driver, ClassGuid, ImagePath;
78  PWSTR FullImagePath;
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  /* Prepare full driver path */
115  dwValue = PathPrefix.MaximumLength + wcslen(ImagePath) * sizeof(WCHAR);
116  FullImagePath = (PWSTR)RtlAllocateHeap(ProcessHeap, 0, dwValue);
117  if (!FullImagePath)
118  {
119  DPRINT1("RtlAllocateHeap() failed\n");
120  INF_FreeData(ImagePath);
121  INF_FreeData(ClassGuid);
123  return FALSE;
124  }
125  RtlCopyMemory(FullImagePath, PathPrefix.Buffer, PathPrefix.MaximumLength);
126  ConcatPaths(FullImagePath, dwValue / sizeof(WCHAR), 1, ImagePath);
127 
128  DPRINT1("Using driver '%S' for device '%S'\n", ImagePath, DeviceId);
129 
130  /* Create service key */
131  RtlInitUnicodeString(&StringU, Driver);
134  if (!NT_SUCCESS(Status))
135  {
136  DPRINT1("NtCreateKey('%wZ') failed with status 0x%08x\n", &StringU, Status);
137  RtlFreeHeap(ProcessHeap, 0, FullImagePath);
138  INF_FreeData(ImagePath);
139  INF_FreeData(ClassGuid);
141  return FALSE;
142  }
143 
144  /* Fill service key */
146  {
147  dwValue = 0;
148  NtSetValueKey(hService,
149  &ErrorControlU,
150  0,
151  REG_DWORD,
152  &dwValue,
153  sizeof(dwValue));
154 
155  dwValue = 0;
156  NtSetValueKey(hService,
157  &StartU,
158  0,
159  REG_DWORD,
160  &dwValue,
161  sizeof(dwValue));
162 
163  dwValue = SERVICE_KERNEL_DRIVER;
164  NtSetValueKey(hService,
165  &TypeU,
166  0,
167  REG_DWORD,
168  &dwValue,
169  sizeof(dwValue));
170  }
171  /* HACK: don't put any path in registry */
172  NtSetValueKey(hService,
173  &ImagePathU,
174  0,
175  REG_SZ,
176  (PVOID)ImagePath,
177  (wcslen(ImagePath) + 1) * sizeof(WCHAR));
178 
179  INF_FreeData(ImagePath);
180 
181  if (ClassGuid &&_wcsicmp(ClassGuid, L"{4D36E96B-E325-11CE-BFC1-08002BE10318}") == 0)
182  {
183  DPRINT1("Installing keyboard class driver for '%S'\n", DeviceId);
184  NtSetValueKey(hDeviceKey,
185  &UpperFiltersU,
186  0,
187  REG_MULTI_SZ,
188  keyboardClass,
189  (wcslen(keyboardClass) + 2) * sizeof(WCHAR));
190  }
191 
192  INF_FreeData(ClassGuid);
193 
194  /* Associate device with the service we just filled */
195  Status = NtSetValueKey(hDeviceKey,
196  &ServiceU,
197  0,
198  REG_SZ,
199  (PVOID)Driver,
200  (wcslen(Driver) + 1) * sizeof(WCHAR));
201  if (NT_SUCCESS(Status))
202  {
203  /* Restart the device, so it will use the driver we registered */
204  deviceInstalled = ResetDevice(DeviceId);
205  }
206 
208 
209  /* HACK: Update driver path */
210  NtSetValueKey(hService,
211  &ImagePathU,
212  0,
213  REG_SZ,
214  FullImagePath,
215  (wcslen(FullImagePath) + 1) * sizeof(WCHAR));
216  RtlFreeHeap(ProcessHeap, 0, FullImagePath);
217 
218  NtClose(hService);
219 
220  return deviceInstalled;
221 }
222 
223 static VOID
225  IN HINF hInf,
226  IN HANDLE hEnum,
227  IN HANDLE hServices,
228  IN LPCWSTR DeviceId)
229 {
230  UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID");
231  UNICODE_STRING CompatibleIDsU = RTL_CONSTANT_STRING(L"CompatibleIDs");
232 
233  UNICODE_STRING DeviceIdU;
235  LPCWSTR HardwareID;
236  PKEY_VALUE_PARTIAL_INFORMATION pPartialInformation = NULL;
237  HANDLE hDeviceKey;
238  ULONG ulRequired;
239  BOOLEAN bDriverInstalled = FALSE;
241 
242  RtlInitUnicodeString(&DeviceIdU, DeviceId);
245  if (!NT_SUCCESS(Status))
246  {
247  DPRINT("Unable to open subkey '%S'\n", DeviceId);
248  return;
249  }
250 
252  hDeviceKey,
253  &HardwareIDU,
255  NULL,
256  0,
257  &ulRequired);
259  {
260  pPartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)RtlAllocateHeap(ProcessHeap, 0, ulRequired);
261  if (!pPartialInformation)
262  {
263  DPRINT1("RtlAllocateHeap() failed\n");
264  NtClose(hDeviceKey);
265  return;
266  }
268  hDeviceKey,
269  &HardwareIDU,
271  pPartialInformation,
272  ulRequired,
273  &ulRequired);
274  }
276  {
277  /* Nothing to do */
278  }
279  else if (!NT_SUCCESS(Status))
280  {
281  DPRINT1("NtQueryValueKey() failed with status 0x%08x\n", Status);
282  if (pPartialInformation)
283  RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
284  NtClose(hDeviceKey);
285  return;
286  }
287  else if (pPartialInformation)
288  {
289  for (HardwareID = (LPCWSTR)pPartialInformation->Data;
290  (PUCHAR)HardwareID < pPartialInformation->Data + pPartialInformation->DataLength
291  && *HardwareID
292  && !bDriverInstalled;
293  HardwareID += wcslen(HardwareID) + 1)
294  {
295  bDriverInstalled = InstallDriver(hInf, hServices,hDeviceKey, DeviceId, HardwareID);
296  }
297  }
298 
299  if (!bDriverInstalled)
300  {
301  if (pPartialInformation)
302  {
303  RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
304  pPartialInformation = NULL;
305  }
307  hDeviceKey,
308  &CompatibleIDsU,
310  NULL,
311  0,
312  &ulRequired);
314  {
315  pPartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)RtlAllocateHeap(ProcessHeap, 0, ulRequired);
316  if (!pPartialInformation)
317  {
318  DPRINT("RtlAllocateHeap() failed\n");
319  NtClose(hDeviceKey);
320  return;
321  }
323  hDeviceKey,
324  &CompatibleIDsU,
326  pPartialInformation,
327  ulRequired,
328  &ulRequired);
329  }
331  {
332  /* Nothing to do */
333  }
334  else if (!NT_SUCCESS(Status))
335  {
336  if (pPartialInformation)
337  RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
338  NtClose(hDeviceKey);
339  DPRINT1("NtQueryValueKey() failed with status 0x%08x\n", Status);
340  return;
341  }
342  else if (pPartialInformation)
343  {
344  for (HardwareID = (LPCWSTR)pPartialInformation->Data;
345  (PUCHAR)HardwareID < pPartialInformation->Data + pPartialInformation->DataLength
346  && *HardwareID
347  && !bDriverInstalled;
348  HardwareID += wcslen(HardwareID) + 1)
349  {
350  bDriverInstalled = InstallDriver(hInf, hServices,hDeviceKey, DeviceId, HardwareID);
351  }
352  }
353  }
354  if (!bDriverInstalled)
355  DPRINT("No driver available for %S\n", DeviceId);
356 
357  RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
358  NtClose(hDeviceKey);
359 }
360 
361 /* Loop to install all queued devices installations */
362 static ULONG NTAPI
364 {
367  DeviceInstallParams* Params;
369 
370  for (;;)
371  {
373 
374  if (ListEntry == NULL)
375  {
376  /*
377  * The list is now empty, but there may be a new enumerated device
378  * that is going to be added to the list soon. In order to avoid
379  * setting the hNoPendingInstalls event to release it soon after,
380  * we wait for maximum 1 second for no PnP enumeration event being
381  * received before declaring that no pending installations are
382  * taking place and setting the corresponding event.
383  */
384  Timeout.QuadPart = -10000000LL; /* Wait for 1 second */
386  {
387  /* We timed out: set the event and do the actual wait */
390  }
391  }
392  else
393  {
397  RtlFreeHeap(ProcessHeap, 0, Params);
398  }
399  }
400 
401  return 0;
402 }
403 
404 static ULONG NTAPI
406 {
408  PLUGPLAY_CONTROL_USER_RESPONSE_DATA ResponseData = {0, 0, 0, 0};
409  PPLUGPLAY_EVENT_BLOCK PnpEvent, NewPnpEvent;
410  ULONG PnpEventSize;
411 
413 
414  PnpEventSize = 0x1000;
415  PnpEvent = RtlAllocateHeap(ProcessHeap, 0, PnpEventSize);
416  if (PnpEvent == NULL)
417  {
419  goto Quit;
420  }
421 
422  for (;;)
423  {
424  DPRINT("Calling NtGetPlugPlayEvent()\n");
425 
426  /* Wait for the next PnP event */
427  Status = NtGetPlugPlayEvent(0, 0, PnpEvent, PnpEventSize);
428 
429  /* Resize the buffer for the PnP event if it's too small */
431  {
432  PnpEventSize += 0x400;
433  NewPnpEvent = RtlReAllocateHeap(ProcessHeap, 0, PnpEvent, PnpEventSize);
434  if (NewPnpEvent == NULL)
435  {
437  goto Quit;
438  }
439  PnpEvent = NewPnpEvent;
440  continue;
441  }
442 
443  if (!NT_SUCCESS(Status))
444  {
445  DPRINT1("NtGetPlugPlayEvent() failed (Status 0x%08lx)\n", Status);
446  goto Quit;
447  }
448 
449  /* Process the PnP event */
450  DPRINT("Received PnP Event\n");
451  if (IsEqualGUID(&PnpEvent->EventGuid, &GUID_DEVICE_ENUMERATED))
452  {
453  DeviceInstallParams* Params;
454  ULONG len;
455  ULONG DeviceIdLength;
456 
457  DPRINT("Device enumerated event: %S\n", PnpEvent->TargetDevice.DeviceIds);
458 
459  DeviceIdLength = wcslen(PnpEvent->TargetDevice.DeviceIds);
460  if (DeviceIdLength)
461  {
462  /* Queue device install (will be dequeued by DeviceInstallThread) */
463  len = FIELD_OFFSET(DeviceInstallParams, DeviceIds) + (DeviceIdLength + 1) * sizeof(WCHAR);
464  Params = RtlAllocateHeap(ProcessHeap, 0, len);
465  if (Params)
466  {
467  wcscpy(Params->DeviceIds, PnpEvent->TargetDevice.DeviceIds);
470  }
471  else
472  {
473  DPRINT1("Not enough memory (size %lu)\n", len);
474  }
475  }
476  }
477  else
478  {
479  DPRINT("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
480  PnpEvent->EventGuid.Data1, PnpEvent->EventGuid.Data2, PnpEvent->EventGuid.Data3,
481  PnpEvent->EventGuid.Data4[0], PnpEvent->EventGuid.Data4[1], PnpEvent->EventGuid.Data4[2],
482  PnpEvent->EventGuid.Data4[3], PnpEvent->EventGuid.Data4[4], PnpEvent->EventGuid.Data4[5],
483  PnpEvent->EventGuid.Data4[6], PnpEvent->EventGuid.Data4[7]);
484  }
485 
486  /* Dequeue the current PnP event and signal the next one */
488  &ResponseData,
489  sizeof(ResponseData));
490  if (!NT_SUCCESS(Status))
491  {
492  DPRINT1("NtPlugPlayControl(PlugPlayControlUserResponse) failed (Status 0x%08lx)\n", Status);
493  goto Quit;
494  }
495  }
496 
498 
499 Quit:
500  if (PnpEvent)
501  RtlFreeHeap(ProcessHeap, 0, PnpEvent);
502 
504  return Status;
505 }
506 
507 NTSTATUS
510 {
512 }
513 
514 BOOLEAN
516 {
518 
519  /* Start the PnP thread */
520  if (hPnpThread != NULL)
522 
523  /*
524  * Wait a little bit so that we get a chance to have some events being
525  * queued by the time the device-installation thread becomes resumed.
526  */
527  Timeout.QuadPart = -10000000LL; /* Wait for 1 second */
529 
530  /* Start the device installation thread */
531  if (hDeviceInstallThread != NULL)
533 
534  return TRUE;
535 }
536 
537 BOOLEAN
539 {
540  /* Wait until all pending installations are done, then freeze the threads */
542  DPRINT1("WaitNoPendingInstallEvents() failed to wait!\n");
543 
544  // TODO: use signalling events
545 
548 
549  return TRUE;
550 }
551 
552 NTSTATUS
554  IN HINF* phSetupInf)
555 {
558 
559  UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum");
560  UNICODE_STRING ServicesU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
561 
564  NULL,
566  FALSE);
567  if (!NT_SUCCESS(Status))
568  {
569  DPRINT1("Could not create the event! (Status 0x%08lx)\n", Status);
570  goto Failure;
571  }
572 
575  NULL,
577  FALSE);
578  if (!NT_SUCCESS(Status))
579  {
580  DPRINT1("Could not create the event! (Status 0x%08lx)\n", Status);
581  goto Failure;
582  }
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 
656  if (hNoPendingInstalls)
659 
663 
664  return Status;
665 }
666 
667 VOID
669 {
671 
672  // TODO: use signalling events
673 
674  /* Kill the PnP thread as it blocks inside the NtGetPlugPlayEvent() call */
675  if (hPnpThread)
676  {
679  }
680  hPnpThread = NULL;
681 
682  /* Kill the device installation thread */
684  {
687  }
689 
690  /* Close the opened handles */
691 
692  if (hServicesKey)
694  hServicesKey = NULL;
695 
696  if (hEnumKey)
697  NtClose(hEnumKey);
698  hEnumKey = NULL;
699 
700  if (hNoPendingInstalls)
703 
707 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
HINF hSetupInf
Definition: intl.c:40
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define LL
Definition: tui.h:72
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
#define KEY_SET_VALUE
Definition: nt_native.h:1017
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define ANYSIZE_ARRAY
Definition: typedefs.h:45
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
uint16_t * PWSTR
Definition: typedefs.h:54
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define NtCurrentThread()
struct _PLUGPLAY_EVENT_BLOCK::@2276::@2279 TargetDevice
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:100
NTSTATUS ConcatPaths(IN OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:659
pSpInfFindFirstLine SpInfFindFirstLine
Definition: infsupp.c:87
_In_ PVOID Parameter
Definition: ldrtypes.h:240
NTSTATUS NTAPI NtSuspendThread(IN HANDLE ThreadHandle, OUT PULONG PreviousSuspendCount OPTIONAL)
Definition: state.c:352
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2561
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:389
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
#define STATUS_WAIT_0
Definition: ntstatus.h:223
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 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:1169
#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:363
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS InitializeUserModePnpManager(IN HINF *phSetupInf)
Definition: devinst.c:553
WCHAR DeviceIds[1]
Definition: precomp.h:39
void DPRINT(...)
Definition: polytest.cpp:61
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
_In_ PCUNICODE_STRING _In_ PVOID Driver
Definition: cmfuncs.h:32
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:57
#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
NTSYSAPI PSLIST_ENTRY NTAPI RtlInterlockedPushEntrySList(_Inout_ PSLIST_HEADER ListHead, _Inout_ __drv_aliasesMem PSLIST_ENTRY ListEntry)
Definition: slist.c:157
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:458
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:515
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
static ULONG NTAPI PnpEventThread(IN PVOID Parameter)
Definition: devinst.c:405
#define PSLIST_ENTRY
Definition: rtltypes.h:130
NTSYSAPI PSLIST_ENTRY NTAPI RtlInterlockedPopEntrySList(_Inout_ PSLIST_HEADER ListHead)
Definition: slist.c:192
FORCEINLINE VOID INF_FreeData(IN PCWSTR InfData)
Definition: infsupp.h:157
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_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
SLIST_ENTRY ListEntry
Definition: precomp.h:38
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:40
HANDLE ProcessHeap
Definition: servman.c:15
Status
Definition: gdiplustypes.h:24
static HANDLE hDeviceInstallListNotEmpty
Definition: devinst.c:29
NTSYSAPI VOID NTAPI RtlInitializeSListHead(_Out_ PSLIST_HEADER ListHead)
Definition: slist.c:25
NTSTATUS NTAPI NtPlugPlayControl(IN PLUGPLAY_CONTROL_CLASS PlugPlayControlClass, IN OUT PVOID Buffer, IN ULONG BufferLength)
Definition: plugplay.c:1299
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:508
static VOID InstallDevice(IN HINF hInf, IN HANDLE hEnum, IN HANDLE hServices, IN LPCWSTR DeviceId)
Definition: devinst.c:224
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
static SLIST_HEADER DeviceInstallListHead
Definition: devinst.c:28
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
VOID TerminateUserModePnpManager(VOID)
Definition: devinst.c:668
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
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
#define DPRINT1
Definition: precomp.h:8
#define SLIST_ENTRY(type)
Definition: queue.h:102
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:1012
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
BOOLEAN DisableUserModePnpManager(VOID)
Definition: devinst.c:538
return STATUS_SUCCESS
Definition: btrfs.c:2777
#define REG_DWORD
Definition: sdbapi.c:596
LIST_ENTRY ListEntry
Definition: conio.h:329
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)
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define SERVICE_KERNEL_DRIVER
Definition: cmtypes.h:951
#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)