ReactOS  0.4.15-dev-1184-g23e04ae
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 PathPrefix = RTL_CONSTANT_STRING(L"System32\\DRIVERS\\");
67  UNICODE_STRING ServiceU = RTL_CONSTANT_STRING(L"Service");
68  UNICODE_STRING ErrorControlU = RTL_CONSTANT_STRING(L"ErrorControl");
69  UNICODE_STRING ImagePathU = RTL_CONSTANT_STRING(L"ImagePath");
70  UNICODE_STRING StartU = RTL_CONSTANT_STRING(L"Start");
71  UNICODE_STRING TypeU = RTL_CONSTANT_STRING(L"Type");
72  UNICODE_STRING UpperFiltersU = RTL_CONSTANT_STRING(L"UpperFilters");
73  PWSTR keyboardClass = L"kbdclass\0";
74 
75  UNICODE_STRING StringU;
77  HANDLE hService;
79  PCWSTR Driver, ClassGuid, ImagePath;
80  PWSTR FullImagePath;
81  ULONG dwValue;
84  BOOLEAN deviceInstalled = FALSE;
85 
86  /* Check if we know the hardware */
87  if (!SpInfFindFirstLine(hInf, L"HardwareIdsDatabase", HardwareId, &Context))
88  return FALSE;
89  if (!INF_GetDataField(&Context, 1, &Driver))
90  return FALSE;
91 
92  /* Get associated class GUID (if any) */
93  if (!INF_GetDataField(&Context, 2, &ClassGuid))
94  ClassGuid = NULL;
95 
96  /* Find associated driver name */
97  /* FIXME: check in other sections too! */
98  if (!SpInfFindFirstLine(hInf, L"BootBusExtenders.Load", Driver, &Context)
99  && !SpInfFindFirstLine(hInf, L"BusExtenders.Load", Driver, &Context)
100  && !SpInfFindFirstLine(hInf, L"SCSI.Load", Driver, &Context)
101  && !SpInfFindFirstLine(hInf, L"InputDevicesSupport.Load", Driver, &Context)
102  && !SpInfFindFirstLine(hInf, L"Keyboard.Load", Driver, &Context))
103  {
104  INF_FreeData(ClassGuid);
106  return FALSE;
107  }
108 
109  if (!INF_GetDataField(&Context, 1, &ImagePath))
110  {
111  INF_FreeData(ClassGuid);
113  return FALSE;
114  }
115 
116  /* Prepare full driver path */
117  dwValue = PathPrefix.MaximumLength + wcslen(ImagePath) * sizeof(WCHAR);
118  FullImagePath = (PWSTR)RtlAllocateHeap(ProcessHeap, 0, dwValue);
119  if (!FullImagePath)
120  {
121  DPRINT1("RtlAllocateHeap() failed\n");
122  INF_FreeData(ImagePath);
123  INF_FreeData(ClassGuid);
125  return FALSE;
126  }
127  RtlCopyMemory(FullImagePath, PathPrefix.Buffer, PathPrefix.MaximumLength);
128  ConcatPaths(FullImagePath, dwValue / sizeof(WCHAR), 1, ImagePath);
129 
130  DPRINT1("Using driver '%S' for device '%S'\n", ImagePath, DeviceId);
131 
132  /* Create service key */
133  RtlInitUnicodeString(&StringU, Driver);
136  if (!NT_SUCCESS(Status))
137  {
138  DPRINT1("NtCreateKey('%wZ') failed with status 0x%08x\n", &StringU, Status);
139  RtlFreeHeap(ProcessHeap, 0, FullImagePath);
140  INF_FreeData(ImagePath);
141  INF_FreeData(ClassGuid);
143  return FALSE;
144  }
145 
146  /* Fill service key */
148  {
149  dwValue = 0;
150  NtSetValueKey(hService,
151  &ErrorControlU,
152  0,
153  REG_DWORD,
154  &dwValue,
155  sizeof(dwValue));
156 
157  dwValue = 0;
158  NtSetValueKey(hService,
159  &StartU,
160  0,
161  REG_DWORD,
162  &dwValue,
163  sizeof(dwValue));
164 
165  dwValue = SERVICE_KERNEL_DRIVER;
166  NtSetValueKey(hService,
167  &TypeU,
168  0,
169  REG_DWORD,
170  &dwValue,
171  sizeof(dwValue));
172  }
173  /* HACK: don't put any path in registry */
174  NtSetValueKey(hService,
175  &ImagePathU,
176  0,
177  REG_SZ,
178  (PVOID)ImagePath,
179  (wcslen(ImagePath) + 1) * sizeof(WCHAR));
180 
181  INF_FreeData(ImagePath);
182 
183  if (ClassGuid &&_wcsicmp(ClassGuid, L"{4D36E96B-E325-11CE-BFC1-08002BE10318}") == 0)
184  {
185  DPRINT1("Installing keyboard class driver for '%S'\n", DeviceId);
186  NtSetValueKey(hDeviceKey,
187  &UpperFiltersU,
188  0,
189  REG_MULTI_SZ,
190  keyboardClass,
191  (wcslen(keyboardClass) + 2) * sizeof(WCHAR));
192  }
193 
194  INF_FreeData(ClassGuid);
195 
196  /* Associate device with the service we just filled */
197  Status = NtSetValueKey(hDeviceKey,
198  &ServiceU,
199  0,
200  REG_SZ,
201  (PVOID)Driver,
202  (wcslen(Driver) + 1) * sizeof(WCHAR));
203  if (NT_SUCCESS(Status))
204  {
205  /* Restart the device, so it will use the driver we registered */
206  deviceInstalled = ResetDevice(DeviceId);
207  }
208 
210 
211  /* HACK: Update driver path */
212  NtSetValueKey(hService,
213  &ImagePathU,
214  0,
215  REG_SZ,
216  FullImagePath,
217  (wcslen(FullImagePath) + 1) * sizeof(WCHAR));
218  RtlFreeHeap(ProcessHeap, 0, FullImagePath);
219 
220  NtClose(hService);
221 
222  return deviceInstalled;
223 }
224 
225 static VOID
227  IN HINF hInf,
228  IN HANDLE hEnum,
229  IN HANDLE hServices,
230  IN LPCWSTR DeviceId)
231 {
232  UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID");
233  UNICODE_STRING CompatibleIDsU = RTL_CONSTANT_STRING(L"CompatibleIDs");
234 
235  UNICODE_STRING DeviceIdU;
237  LPCWSTR HardwareID;
238  PKEY_VALUE_PARTIAL_INFORMATION pPartialInformation = NULL;
239  HANDLE hDeviceKey;
240  ULONG ulRequired;
241  BOOLEAN bDriverInstalled = FALSE;
243 
244  RtlInitUnicodeString(&DeviceIdU, DeviceId);
247  if (!NT_SUCCESS(Status))
248  {
249  DPRINT("Unable to open subkey '%S'\n", DeviceId);
250  return;
251  }
252 
254  hDeviceKey,
255  &HardwareIDU,
257  NULL,
258  0,
259  &ulRequired);
261  {
262  pPartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)RtlAllocateHeap(ProcessHeap, 0, ulRequired);
263  if (!pPartialInformation)
264  {
265  DPRINT1("RtlAllocateHeap() failed\n");
266  NtClose(hDeviceKey);
267  return;
268  }
270  hDeviceKey,
271  &HardwareIDU,
273  pPartialInformation,
274  ulRequired,
275  &ulRequired);
276  }
278  {
279  /* Nothing to do */
280  }
281  else if (!NT_SUCCESS(Status))
282  {
283  DPRINT1("NtQueryValueKey() failed with status 0x%08x\n", Status);
284  if (pPartialInformation)
285  RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
286  NtClose(hDeviceKey);
287  return;
288  }
289  else if (pPartialInformation)
290  {
291  for (HardwareID = (LPCWSTR)pPartialInformation->Data;
292  (PUCHAR)HardwareID < pPartialInformation->Data + pPartialInformation->DataLength
293  && *HardwareID
294  && !bDriverInstalled;
295  HardwareID += wcslen(HardwareID) + 1)
296  {
297  bDriverInstalled = InstallDriver(hInf, hServices,hDeviceKey, DeviceId, HardwareID);
298  }
299  }
300 
301  if (!bDriverInstalled)
302  {
303  if (pPartialInformation)
304  {
305  RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
306  pPartialInformation = NULL;
307  }
309  hDeviceKey,
310  &CompatibleIDsU,
312  NULL,
313  0,
314  &ulRequired);
316  {
317  pPartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)RtlAllocateHeap(ProcessHeap, 0, ulRequired);
318  if (!pPartialInformation)
319  {
320  DPRINT("RtlAllocateHeap() failed\n");
321  NtClose(hDeviceKey);
322  return;
323  }
325  hDeviceKey,
326  &CompatibleIDsU,
328  pPartialInformation,
329  ulRequired,
330  &ulRequired);
331  }
333  {
334  /* Nothing to do */
335  }
336  else if (!NT_SUCCESS(Status))
337  {
338  if (pPartialInformation)
339  RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
340  NtClose(hDeviceKey);
341  DPRINT1("NtQueryValueKey() failed with status 0x%08x\n", Status);
342  return;
343  }
344  else if (pPartialInformation)
345  {
346  for (HardwareID = (LPCWSTR)pPartialInformation->Data;
347  (PUCHAR)HardwareID < pPartialInformation->Data + pPartialInformation->DataLength
348  && *HardwareID
349  && !bDriverInstalled;
350  HardwareID += wcslen(HardwareID) + 1)
351  {
352  bDriverInstalled = InstallDriver(hInf, hServices,hDeviceKey, DeviceId, HardwareID);
353  }
354  }
355  }
356  if (!bDriverInstalled)
357  DPRINT("No driver available for %S\n", DeviceId);
358 
359  RtlFreeHeap(ProcessHeap, 0, pPartialInformation);
360  NtClose(hDeviceKey);
361 }
362 
363 /* Loop to install all queued devices installations */
364 static ULONG NTAPI
366 {
368  PLIST_ENTRY ListEntry;
369  DeviceInstallParams* Params;
371 
372  for (;;)
373  {
374  /* Dequeue the next oldest device-install event */
376  ListEntry = (IsListEmpty(&DeviceInstallListHead)
379 
380  if (ListEntry == NULL)
381  {
382  /*
383  * The list is now empty, but there may be a new enumerated device
384  * that is going to be added to the list soon. In order to avoid
385  * setting the hNoPendingInstalls event to release it soon after,
386  * we wait for maximum 1 second for no PnP enumeration event being
387  * received before declaring that no pending installations are
388  * taking place and setting the corresponding event.
389  */
390  Timeout.QuadPart = -10000000LL; /* Wait for 1 second */
392  {
393  /* We timed out: set the event and do the actual wait */
396  }
397  }
398  else
399  {
401  Params = CONTAINING_RECORD(ListEntry, DeviceInstallParams, ListEntry);
403  RtlFreeHeap(ProcessHeap, 0, Params);
404  }
405  }
406 
407  return 0;
408 }
409 
410 static ULONG NTAPI
412 {
414  PLUGPLAY_CONTROL_USER_RESPONSE_DATA ResponseData = {0, 0, 0, 0};
415  PPLUGPLAY_EVENT_BLOCK PnpEvent, NewPnpEvent;
416  ULONG PnpEventSize;
417 
419 
420  PnpEventSize = 0x1000;
421  PnpEvent = RtlAllocateHeap(ProcessHeap, 0, PnpEventSize);
422  if (PnpEvent == NULL)
423  {
425  goto Quit;
426  }
427 
428  for (;;)
429  {
430  DPRINT("Calling NtGetPlugPlayEvent()\n");
431 
432  /* Wait for the next PnP event */
433  Status = NtGetPlugPlayEvent(0, 0, PnpEvent, PnpEventSize);
434 
435  /* Resize the buffer for the PnP event if it's too small */
437  {
438  PnpEventSize += 0x400;
439  NewPnpEvent = RtlReAllocateHeap(ProcessHeap, 0, PnpEvent, PnpEventSize);
440  if (NewPnpEvent == NULL)
441  {
443  goto Quit;
444  }
445  PnpEvent = NewPnpEvent;
446  continue;
447  }
448 
449  if (!NT_SUCCESS(Status))
450  {
451  DPRINT1("NtGetPlugPlayEvent() failed (Status 0x%08lx)\n", Status);
452  goto Quit;
453  }
454 
455  /* Process the PnP event */
456  DPRINT("Received PnP Event\n");
457  if (IsEqualGUID(&PnpEvent->EventGuid, &GUID_DEVICE_ENUMERATED))
458  {
459  DeviceInstallParams* Params;
460  ULONG len;
461  ULONG DeviceIdLength;
462 
463  DPRINT("Device enumerated: %S\n", PnpEvent->TargetDevice.DeviceIds);
464 
465  DeviceIdLength = wcslen(PnpEvent->TargetDevice.DeviceIds);
466  if (DeviceIdLength)
467  {
468  /* Allocate a new device-install event */
469  len = FIELD_OFFSET(DeviceInstallParams, DeviceIds) + (DeviceIdLength + 1) * sizeof(WCHAR);
470  Params = RtlAllocateHeap(ProcessHeap, 0, len);
471  if (Params)
472  {
473  wcscpy(Params->DeviceIds, PnpEvent->TargetDevice.DeviceIds);
474 
475  /* Queue the event (will be dequeued by DeviceInstallThread) */
479 
481  }
482  else
483  {
484  DPRINT1("Not enough memory (size %lu)\n", len);
485  }
486  }
487  }
488  else
489  {
490  DPRINT("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
491  PnpEvent->EventGuid.Data1, PnpEvent->EventGuid.Data2, PnpEvent->EventGuid.Data3,
492  PnpEvent->EventGuid.Data4[0], PnpEvent->EventGuid.Data4[1], PnpEvent->EventGuid.Data4[2],
493  PnpEvent->EventGuid.Data4[3], PnpEvent->EventGuid.Data4[4], PnpEvent->EventGuid.Data4[5],
494  PnpEvent->EventGuid.Data4[6], PnpEvent->EventGuid.Data4[7]);
495  }
496 
497  /* Dequeue the current PnP event and signal the next one */
499  &ResponseData,
500  sizeof(ResponseData));
501  if (!NT_SUCCESS(Status))
502  {
503  DPRINT1("NtPlugPlayControl(PlugPlayControlUserResponse) failed (Status 0x%08lx)\n", Status);
504  goto Quit;
505  }
506  }
507 
509 
510 Quit:
511  if (PnpEvent)
512  RtlFreeHeap(ProcessHeap, 0, PnpEvent);
513 
515  return Status;
516 }
517 
518 NTSTATUS
521 {
523 }
524 
525 BOOLEAN
527 {
529 
530  /* Start the PnP thread */
531  if (hPnpThread != NULL)
533 
534  /*
535  * Wait a little bit so that we get a chance to have some events being
536  * queued by the time the device-installation thread becomes resumed.
537  */
538  Timeout.QuadPart = -10000000LL; /* Wait for 1 second */
540 
541  /* Start the device installation thread */
542  if (hDeviceInstallThread != NULL)
544 
545  return TRUE;
546 }
547 
548 BOOLEAN
550 {
551  /* Wait until all pending installations are done, then freeze the threads */
553  DPRINT1("WaitNoPendingInstallEvents() failed to wait!\n");
554 
555  // TODO: use signalling events
556 
559 
560  return TRUE;
561 }
562 
563 NTSTATUS
565  IN HINF* phSetupInf)
566 {
569 
570  UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum");
571  UNICODE_STRING ServicesU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
572 
575  NULL,
577  FALSE);
578  if (!NT_SUCCESS(Status))
579  {
580  DPRINT1("Could not create the Pending-Install Event! (Status 0x%08lx)\n", Status);
581  goto Failure;
582  }
583 
584  /*
585  * Initialize the device-install event list
586  */
587 
590  NULL,
592  FALSE);
593  if (!NT_SUCCESS(Status))
594  {
595  DPRINT1("Could not create the List Event! (Status 0x%08lx)\n", Status);
596  goto Failure;
597  }
598 
601  NULL, FALSE);
602  if (!NT_SUCCESS(Status))
603  {
604  DPRINT1("Could not create the List Mutex! (Status 0x%08lx)\n", Status);
605  goto Failure;
606  }
608 
611  if (!NT_SUCCESS(Status))
612  {
613  DPRINT1("NtOpenKey('%wZ') failed (Status 0x%08lx)\n", &EnumU, Status);
614  goto Failure;
615  }
616 
619  if (!NT_SUCCESS(Status))
620  {
621  DPRINT1("NtCreateKey('%wZ') failed (Status 0x%08lx)\n", &ServicesU, Status);
622  goto Failure;
623  }
624 
625  /* Create the PnP event thread in suspended state */
627  NULL,
628  TRUE,
629  0,
630  0,
631  0,
633  NULL,
634  &hPnpThread,
635  NULL);
636  if (!NT_SUCCESS(Status))
637  {
638  DPRINT1("Failed to create the PnP event thread (Status 0x%08lx)\n", Status);
639  hPnpThread = NULL;
640  goto Failure;
641  }
642 
643  /* Create the device installation thread in suspended state */
645  NULL,
646  TRUE,
647  0,
648  0,
649  0,
651  phSetupInf,
653  NULL);
654  if (!NT_SUCCESS(Status))
655  {
656  DPRINT1("Failed to create the device installation thread (Status 0x%08lx)\n", Status);
658  goto Failure;
659  }
660 
661  return STATUS_SUCCESS;
662 
663 Failure:
664  if (hPnpThread)
665  {
668  }
669  hPnpThread = NULL;
670 
671  if (hServicesKey)
673  hServicesKey = NULL;
674 
675  if (hEnumKey)
676  NtClose(hEnumKey);
677  hEnumKey = NULL;
678 
682 
686 
687  if (hNoPendingInstalls)
690 
691  return Status;
692 }
693 
694 VOID
696 {
698 
699  // TODO: use signalling events
700 
701  /* Kill the PnP thread as it blocks inside the NtGetPlugPlayEvent() call */
702  if (hPnpThread)
703  {
706  }
707  hPnpThread = NULL;
708 
709  /* Kill the device installation thread */
711  {
714  }
716 
717  /* Close the opened handles */
718 
719  if (hServicesKey)
721  hServicesKey = NULL;
722 
723  if (hEnumKey)
724  NtClose(hEnumKey);
725  hEnumKey = NULL;
726 
727  if (hNoPendingInstalls)
730 
734 }
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:40
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#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
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
USHORT MaximumLength
Definition: env_spec_w32.h:370
#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
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: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: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:389
#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:1132
#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:365
smooth NULL
Definition: ftsmooth.c:416
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
NTSTATUS InitializeUserModePnpManager(IN HINF *phSetupInf)
Definition: devinst.c:564
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:59
#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: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:526
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
static ULONG NTAPI PnpEventThread(IN PVOID Parameter)
Definition: devinst.c:411
LIST_ENTRY ListEntry
Definition: precomp.h:38
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:83
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)
Status
Definition: gdiplustypes.h:24
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
WCHAR DeviceIds[ANYSIZE_ARRAY]
Definition: precomp.h:39
NTSTATUS NTAPI NtPlugPlayControl(IN PLUGPLAY_CONTROL_CLASS PlugPlayControlClass, IN OUT PVOID Buffer, IN ULONG BufferLength)
Definition: plugplay.c:1262
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:519
static VOID InstallDevice(IN HINF hInf, IN HANDLE hEnum, IN HANDLE hServices, IN LPCWSTR DeviceId)
Definition: devinst.c:226
struct _PLUGPLAY_EVENT_BLOCK::@2344::@2347 TargetDevice
#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:695
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
#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
BOOLEAN DisableUserModePnpManager(VOID)
Definition: devinst.c:549
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define REG_DWORD
Definition: sdbapi.c:596
NTSTATUS NTAPI NtReleaseMutant(IN HANDLE MutantHandle, IN PLONG PreviousCount OPTIONAL)
Definition: mutant.c:299
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)