ReactOS  0.4.14-dev-98-gb0d4763
devinst.c File Reference
#include <usetup.h>
#include <debug.h>
#include <guiddef.h>
#include <libs/umpnpmgr/sysguid.h>
Include dependency graph for devinst.c:

Go to the source code of this file.

Classes

struct  DeviceInstallParams
 

Macros

#define NDEBUG
 
#define INITGUID
 

Functions

static BOOLEAN ResetDevice (IN LPCWSTR DeviceId)
 
static BOOLEAN InstallDriver (IN HINF hInf, IN HANDLE hServices, IN HANDLE hDeviceKey, IN LPCWSTR DeviceId, IN LPCWSTR HardwareId)
 
static VOID InstallDevice (IN HINF hInf, IN HANDLE hEnum, IN HANDLE hServices, IN LPCWSTR DeviceId)
 
static ULONG NTAPI DeviceInstallThread (IN PVOID Parameter)
 
static ULONG NTAPI PnpEventThread (IN PVOID Parameter)
 
NTSTATUS WaitNoPendingInstallEvents (IN PLARGE_INTEGER Timeout OPTIONAL)
 
BOOLEAN EnableUserModePnpManager (VOID)
 
BOOLEAN DisableUserModePnpManager (VOID)
 
NTSTATUS InitializeUserModePnpManager (IN HINF *phSetupInf)
 
VOID TerminateUserModePnpManager (VOID)
 

Variables

static HANDLE hEnumKey = NULL
 
static HANDLE hServicesKey = NULL
 
static HANDLE hNoPendingInstalls = NULL
 
static HANDLE hPnpThread = NULL
 
static HANDLE hDeviceInstallThread = NULL
 
static SLIST_HEADER DeviceInstallListHead
 
static HANDLE hDeviceInstallListNotEmpty = NULL
 

Macro Definition Documentation

◆ INITGUID

#define INITGUID

Definition at line 14 of file devinst.c.

◆ NDEBUG

#define NDEBUG

Definition at line 11 of file devinst.c.

Function Documentation

◆ DeviceInstallThread()

static ULONG NTAPI DeviceInstallThread ( IN PVOID  Parameter)
static

Definition at line 363 of file devinst.c.

364 {
366  PSLIST_ENTRY ListEntry;
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  {
395  Params = CONTAINING_RECORD(ListEntry, DeviceInstallParams, ListEntry);
397  RtlFreeHeap(ProcessHeap, 0, Params);
398  }
399  }
400 
401  return 0;
402 }
HINF hSetupInf
Definition: intl.c:40
#define LL
Definition: tui.h:85
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
_In_ PVOID Parameter
Definition: ldrtypes.h:241
static HANDLE hEnumKey
Definition: devinst.c:20
NTSTATUS NTAPI NtResetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:389
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
smooth NULL
Definition: ftsmooth.c:416
WCHAR DeviceIds[1]
Definition: precomp.h:39
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
static HANDLE hServicesKey
Definition: devinst.c:21
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:458
static HANDLE hNoPendingInstalls
Definition: devinst.c:23
#define PSLIST_ENTRY
Definition: rtltypes.h:130
NTSYSAPI PSLIST_ENTRY NTAPI RtlInterlockedPopEntrySList(_Inout_ PSLIST_HEADER ListHead)
Definition: slist.c:192
HANDLE ProcessHeap
Definition: servman.c:15
static HANDLE hDeviceInstallListNotEmpty
Definition: devinst.c:29
static ULONG Timeout
Definition: ping.c:61
static VOID InstallDevice(IN HINF hInf, IN HANDLE hEnum, IN HANDLE hServices, IN LPCWSTR DeviceId)
Definition: devinst.c:224
static SLIST_HEADER DeviceInstallListHead
Definition: devinst.c:28
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)

Referenced by InitializeUserModePnpManager().

◆ DisableUserModePnpManager()

BOOLEAN DisableUserModePnpManager ( VOID  )

Definition at line 538 of file devinst.c.

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 }
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI NtSuspendThread(IN HANDLE ThreadHandle, OUT PULONG PreviousSuspendCount OPTIONAL)
Definition: state.c:352
#define STATUS_WAIT_0
Definition: ntstatus.h:223
static HANDLE hPnpThread
Definition: devinst.c:25
static HANDLE hDeviceInstallThread
Definition: devinst.c:26
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS WaitNoPendingInstallEvents(IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: devinst.c:508
#define DPRINT1
Definition: precomp.h:8

Referenced by TerminateUserModePnpManager().

◆ EnableUserModePnpManager()

BOOLEAN EnableUserModePnpManager ( VOID  )

Definition at line 515 of file devinst.c.

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 }
#define TRUE
Definition: types.h:120
#define LL
Definition: tui.h:85
static HANDLE hPnpThread
Definition: devinst.c:25
static HANDLE hDeviceInstallThread
Definition: devinst.c:26
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
static HANDLE hDeviceInstallListNotEmpty
Definition: devinst.c:29
static ULONG Timeout
Definition: ping.c:61
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)

Referenced by SetupStartPage().

◆ InitializeUserModePnpManager()

NTSTATUS InitializeUserModePnpManager ( IN HINF phSetupInf)

Definition at line 553 of file devinst.c.

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 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define TRUE
Definition: types.h:120
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
LONG NTSTATUS
Definition: precomp.h:26
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
static HANDLE hEnumKey
Definition: devinst.c:20
static HANDLE hPnpThread
Definition: devinst.c:25
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
static HANDLE hDeviceInstallThread
Definition: devinst.c:26
static ULONG NTAPI DeviceInstallThread(IN PVOID Parameter)
Definition: devinst.c:363
smooth NULL
Definition: ftsmooth.c:416
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
static HANDLE hServicesKey
Definition: devinst.c:21
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1278
static HANDLE hNoPendingInstalls
Definition: devinst.c:23
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static ULONG NTAPI PnpEventThread(IN PVOID Parameter)
Definition: devinst.c:405
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const WCHAR L[]
Definition: oid.c:1250
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)
Status
Definition: gdiplustypes.h:24
static HANDLE hDeviceInstallListNotEmpty
Definition: devinst.c:29
NTSYSAPI VOID NTAPI RtlInitializeSListHead(_Out_ PSLIST_HEADER ListHead)
Definition: slist.c:25
#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 DPRINT1
Definition: precomp.h:8
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by RunUSetup().

◆ InstallDevice()

static VOID InstallDevice ( IN HINF  hInf,
IN HANDLE  hEnum,
IN HANDLE  hServices,
IN LPCWSTR  DeviceId 
)
static

Definition at line 224 of file devinst.c.

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 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define KEY_SET_VALUE
Definition: nt_native.h:1017
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
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 STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
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
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)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const WCHAR L[]
Definition: oid.c:1250
HANDLE ProcessHeap
Definition: servman.c:15
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#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
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
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by DeviceInstallThread().

◆ InstallDriver()

static BOOLEAN InstallDriver ( IN HINF  hInf,
IN HANDLE  hServices,
IN HANDLE  hDeviceKey,
IN LPCWSTR  DeviceId,
IN LPCWSTR  HardwareId 
)
static

Definition at line 57 of file devinst.c.

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 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
const uint16_t * PCWSTR
Definition: typedefs.h:55
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
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
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
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_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
#define REG_MULTI_SZ
Definition: nt_native.h:1501
unsigned char BOOLEAN
BOOLEAN INF_GetDataField(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT PCWSTR *Data)
Definition: infsupp.c:42
smooth NULL
Definition: ftsmooth.c:416
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
_In_ PCUNICODE_STRING _In_ PVOID Driver
Definition: cmfuncs.h:32
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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
static const WCHAR L[]
Definition: oid.c:1250
static BOOLEAN ResetDevice(IN LPCWSTR DeviceId)
Definition: devinst.c:40
HANDLE ProcessHeap
Definition: servman.c:15
Status
Definition: gdiplustypes.h:24
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
struct tagContext Context
Definition: acpixf.h:1024
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
#define REG_DWORD
Definition: sdbapi.c:596
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

Referenced by InstallDevice().

◆ PnpEventThread()

static ULONG NTAPI PnpEventThread ( IN PVOID  Parameter)
static

Definition at line 405 of file devinst.c.

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 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define NtCurrentThread()
_In_ PVOID Parameter
Definition: ldrtypes.h:241
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2561
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
NTSTATUS NTAPI NtGetPlugPlayEvent(IN ULONG Reserved1, IN ULONG Reserved2, OUT PPLUGPLAY_EVENT_BLOCK Buffer, IN ULONG BufferSize)
Definition: plugplay.c:1169
smooth NULL
Definition: ftsmooth.c:416
WCHAR DeviceIds[1]
Definition: precomp.h:39
void DPRINT(...)
Definition: polytest.cpp:61
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
struct _PLUGPLAY_EVENT_BLOCK::@2282::@2285 TargetDevice
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 NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:458
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
GLenum GLsizei len
Definition: glext.h:6722
SLIST_ENTRY ListEntry
Definition: precomp.h:38
HANDLE ProcessHeap
Definition: servman.c:15
Status
Definition: gdiplustypes.h:24
static HANDLE hDeviceInstallListNotEmpty
Definition: devinst.c:29
NTSTATUS NTAPI NtPlugPlayControl(IN PLUGPLAY_CONTROL_CLASS PlugPlayControlClass, IN OUT PVOID Buffer, IN ULONG BufferLength)
Definition: plugplay.c:1299
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
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2966
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)

Referenced by InitializeUserModePnpManager().

◆ ResetDevice()

static BOOLEAN ResetDevice ( IN LPCWSTR  DeviceId)
static

Definition at line 40 of file devinst.c.

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 }
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI NtPlugPlayControl(IN PLUGPLAY_CONTROL_CLASS PlugPlayControlClass, IN OUT PVOID Buffer, IN ULONG BufferLength)
Definition: plugplay.c:1299
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)

Referenced by InstallDriver().

◆ TerminateUserModePnpManager()

VOID TerminateUserModePnpManager ( VOID  )

Definition at line 668 of file devinst.c.

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 }
static HANDLE hEnumKey
Definition: devinst.c:20
static HANDLE hPnpThread
Definition: devinst.c:25
static HANDLE hDeviceInstallThread
Definition: devinst.c:26
smooth NULL
Definition: ftsmooth.c:416
static HANDLE hServicesKey
Definition: devinst.c:21
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1278
static HANDLE hNoPendingInstalls
Definition: devinst.c:23
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
static HANDLE hDeviceInstallListNotEmpty
Definition: devinst.c:29
BOOLEAN DisableUserModePnpManager(VOID)
Definition: devinst.c:538
return STATUS_SUCCESS
Definition: btrfs.c:2966

Referenced by RunUSetup().

◆ WaitNoPendingInstallEvents()

NTSTATUS WaitNoPendingInstallEvents ( IN PLARGE_INTEGER Timeout  OPTIONAL)

Definition at line 508 of file devinst.c.

510 {
512 }
static HANDLE hNoPendingInstalls
Definition: devinst.c:23
static ULONG Timeout
Definition: ping.c:61
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)

Referenced by DisableUserModePnpManager(), and SetupStartPage().

Variable Documentation

◆ DeviceInstallListHead

SLIST_HEADER DeviceInstallListHead
static

Definition at line 28 of file devinst.c.

Referenced by DeviceInstallThread(), InitializeUserModePnpManager(), and PnpEventThread().

◆ hDeviceInstallListNotEmpty

HANDLE hDeviceInstallListNotEmpty = NULL
static

◆ hDeviceInstallThread

HANDLE hDeviceInstallThread = NULL
static

◆ hEnumKey

◆ hNoPendingInstalls

HANDLE hNoPendingInstalls = NULL
static

◆ hPnpThread

◆ hServicesKey