ReactOS  0.4.13-dev-100-gc8611ae
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:72
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
_In_ PVOID Parameter
Definition: ldrtypes.h:240
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: umpnpmgr.c:77
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 530 of file devinst.c.

531 {
532  /* Wait until all pending installations are done, then freeze the threads */
534  DPRINT1("WaitNoPendingInstallEvents() failed to wait!\n");
535 
536  // TODO: use signalling events
537 
540 
541  return TRUE;
542 }
#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:500
#define DPRINT1
Definition: precomp.h:8

Referenced by TerminateUserModePnpManager().

◆ EnableUserModePnpManager()

BOOLEAN EnableUserModePnpManager ( VOID  )

Definition at line 507 of file devinst.c.

508 {
510 
511  /* Start the PnP thread */
512  if (hPnpThread != NULL)
514 
515  /*
516  * Wait a little bit so that we get a chance to have some events being
517  * queued by the time the device-installation thread becomes resumed.
518  */
519  Timeout.QuadPart = -10000000LL; /* Wait for 1 second */
521 
522  /* Start the device installation thread */
523  if (hDeviceInstallThread != NULL)
525 
526  return TRUE;
527 }
#define TRUE
Definition: types.h:120
#define LL
Definition: tui.h:72
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 545 of file devinst.c.

547 {
550 
551  UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum");
552  UNICODE_STRING ServicesU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
553 
556  NULL,
558  FALSE);
559  if (!NT_SUCCESS(Status))
560  {
561  DPRINT1("Could not create the event! (Status 0x%08lx)\n", Status);
562  goto Failure;
563  }
564 
567  NULL,
569  FALSE);
570  if (!NT_SUCCESS(Status))
571  {
572  DPRINT1("Could not create the event! (Status 0x%08lx)\n", Status);
573  goto Failure;
574  }
575 
577 
580  if (!NT_SUCCESS(Status))
581  {
582  DPRINT1("NtOpenKey('%wZ') failed (Status 0x%08lx)\n", &EnumU, Status);
583  goto Failure;
584  }
585 
588  if (!NT_SUCCESS(Status))
589  {
590  DPRINT1("NtCreateKey('%wZ') failed (Status 0x%08lx)\n", &ServicesU, Status);
591  goto Failure;
592  }
593 
594  /* Create the PnP event thread in suspended state */
596  NULL,
597  TRUE,
598  0,
599  0,
600  0,
602  NULL,
603  &hPnpThread,
604  NULL);
605  if (!NT_SUCCESS(Status))
606  {
607  DPRINT1("Failed to create the PnP event thread (Status 0x%08lx)\n", Status);
608  hPnpThread = NULL;
609  goto Failure;
610  }
611 
612  /* Create the device installation thread in suspended state */
614  NULL,
615  TRUE,
616  0,
617  0,
618  0,
620  phSetupInf,
622  NULL);
623  if (!NT_SUCCESS(Status))
624  {
625  DPRINT1("Failed to create the device installation thread (Status 0x%08lx)\n", Status);
627  goto Failure;
628  }
629 
630  return STATUS_SUCCESS;
631 
632 Failure:
633  if (hPnpThread)
634  {
637  }
638  hPnpThread = NULL;
639 
640  if (hServicesKey)
642  hServicesKey = NULL;
643 
644  if (hEnumKey)
645  NtClose(hEnumKey);
646  hEnumKey = NULL;
647 
648  if (hNoPendingInstalls)
651 
655 
656  return Status;
657 }
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:2725
#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:603
#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:585
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:603
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:585
#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: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
#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  PPLUGPLAY_EVENT_BLOCK PnpEvent, NewPnpEvent;
409  ULONG PnpEventSize;
410 
412 
413  PnpEventSize = 0x1000;
414  PnpEvent = RtlAllocateHeap(ProcessHeap, 0, PnpEventSize);
415  if (PnpEvent == NULL)
416  {
418  goto Quit;
419  }
420 
421  for (;;)
422  {
423  DPRINT("Calling NtGetPlugPlayEvent()\n");
424 
425  /* Wait for the next PnP event */
426  Status = NtGetPlugPlayEvent(0, 0, PnpEvent, PnpEventSize);
427 
428  /* Resize the buffer for the PnP event if it's too small */
430  {
431  PnpEventSize += 0x400;
432  NewPnpEvent = RtlReAllocateHeap(ProcessHeap, 0, PnpEvent, PnpEventSize);
433  if (NewPnpEvent == NULL)
434  {
436  goto Quit;
437  }
438  PnpEvent = NewPnpEvent;
439  continue;
440  }
441 
442  if (!NT_SUCCESS(Status))
443  {
444  DPRINT1("NtGetPlugPlayEvent() failed (Status 0x%08lx)\n", Status);
445  goto Quit;
446  }
447 
448  /* Process the PnP event */
449  DPRINT("Received PnP Event\n");
450  if (IsEqualGUID(&PnpEvent->EventGuid, &GUID_DEVICE_ENUMERATED))
451  {
452  DeviceInstallParams* Params;
453  ULONG len;
454  ULONG DeviceIdLength;
455 
456  DPRINT("Device enumerated event: %S\n", PnpEvent->TargetDevice.DeviceIds);
457 
458  DeviceIdLength = wcslen(PnpEvent->TargetDevice.DeviceIds);
459  if (DeviceIdLength)
460  {
461  /* Queue device install (will be dequeued by DeviceInstallThread) */
462  len = FIELD_OFFSET(DeviceInstallParams, DeviceIds) + (DeviceIdLength + 1) * sizeof(WCHAR);
463  Params = RtlAllocateHeap(ProcessHeap, 0, len);
464  if (Params)
465  {
466  wcscpy(Params->DeviceIds, PnpEvent->TargetDevice.DeviceIds);
469  }
470  else
471  {
472  DPRINT1("Not enough memory (size %lu)\n", len);
473  }
474  }
475  }
476  else
477  {
478  DPRINT("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
479  PnpEvent->EventGuid.Data1, PnpEvent->EventGuid.Data2, PnpEvent->EventGuid.Data3,
480  PnpEvent->EventGuid.Data4[0], PnpEvent->EventGuid.Data4[1], PnpEvent->EventGuid.Data4[2],
481  PnpEvent->EventGuid.Data4[3], PnpEvent->EventGuid.Data4[4], PnpEvent->EventGuid.Data4[5],
482  PnpEvent->EventGuid.Data4[6], PnpEvent->EventGuid.Data4[7]);
483  }
484 
485  /* Dequeue the current PnP event and signal the next one */
487  }
488 
490 
491 Quit:
492  if (PnpEvent)
493  RtlFreeHeap(ProcessHeap, 0, PnpEvent);
494 
496  return Status;
497 }
#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:603
#define NtCurrentThread()
_In_ PVOID Parameter
Definition: ldrtypes.h:240
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:1136
smooth NULL
Definition: ftsmooth.c:416
WCHAR DeviceIds[1]
Definition: umpnpmgr.c:77
void DPRINT(...)
Definition: polytest.cpp:61
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
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: umpnpmgr.c:76
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:1266
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:2725
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
struct _PLUGPLAY_EVENT_BLOCK::@2269::@2272 TargetDevice

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:1266
#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 660 of file devinst.c.

661 {
663 
664  // TODO: use signalling events
665 
666  /* Kill the PnP thread as it blocks inside the NtGetPlugPlayEvent() call */
667  if (hPnpThread)
668  {
671  }
672  hPnpThread = NULL;
673 
674  /* Kill the device installation thread */
676  {
679  }
681 
682  /* Close the opened handles */
683 
684  if (hServicesKey)
686  hServicesKey = NULL;
687 
688  if (hEnumKey)
689  NtClose(hEnumKey);
690  hEnumKey = NULL;
691 
692  if (hNoPendingInstalls)
695 
699 }
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:530
return STATUS_SUCCESS
Definition: btrfs.c:2725

Referenced by RunUSetup().

◆ WaitNoPendingInstallEvents()

NTSTATUS WaitNoPendingInstallEvents ( IN PLARGE_INTEGER Timeout  OPTIONAL)

Definition at line 500 of file devinst.c.

502 {
504 }
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