ReactOS  0.4.15-dev-489-g75a0787
devaction.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: PnP manager device manipulation functions
5  * COPYRIGHT: Casper S. Hornstrup (chorns@users.sourceforge.net)
6  * 2007 HervĂ© Poussineau (hpoussin@reactos.org)
7  * 2014-2017 Thomas Faber (thomas.faber@reactos.org)
8  */
9 
10 /* INCLUDES ******************************************************************/
11 
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* GLOBALS *******************************************************************/
17 
19 extern BOOLEAN PnpSystemInit;
21 
22 #define MAX_DEVICE_ID_LEN 200
23 #define MAX_SEPARATORS_INSTANCEID 0
24 #define MAX_SEPARATORS_DEVICEID 1
25 
26 /* DATA **********************************************************************/
27 
32 
33 /* FUNCTIONS *****************************************************************/
34 
37 
40 
41 USHORT
42 NTAPI
43 IopGetBusTypeGuidIndex(LPGUID BusTypeGuid);
44 
47 
48 VOID
49 NTAPI
51 
52 static
53 VOID
55 
56 static
59 
60 static
61 BOOLEAN
63  _In_ PWCHAR Id,
65 {
66  PWCHAR PtrChar;
67  PWCHAR StringEnd;
68  WCHAR Char;
69  ULONG SeparatorsCount = 0;
70  PWCHAR PtrPrevChar = NULL;
71  ULONG MaxSeparators;
72  BOOLEAN IsMultiSz;
73 
74  PAGED_CODE();
75 
76  switch (QueryType)
77  {
78  case BusQueryDeviceID:
79  MaxSeparators = MAX_SEPARATORS_DEVICEID;
80  IsMultiSz = FALSE;
81  break;
82  case BusQueryInstanceID:
83  MaxSeparators = MAX_SEPARATORS_INSTANCEID;
84  IsMultiSz = FALSE;
85  break;
86 
89  MaxSeparators = MAX_SEPARATORS_DEVICEID;
90  IsMultiSz = TRUE;
91  break;
92 
93  default:
94  DPRINT1("IopValidateID: Not handled QueryType - %x\n", QueryType);
95  return FALSE;
96  }
97 
98  StringEnd = Id + MAX_DEVICE_ID_LEN;
99 
100  for (PtrChar = Id; PtrChar < StringEnd; PtrChar++)
101  {
102  Char = *PtrChar;
103 
104  if (Char == UNICODE_NULL)
105  {
106  if (!IsMultiSz || (PtrPrevChar && PtrChar == PtrPrevChar + 1))
107  {
108  if (MaxSeparators == SeparatorsCount || IsMultiSz)
109  {
110  return TRUE;
111  }
112 
113  DPRINT1("IopValidateID: SeparatorsCount - %lu, MaxSeparators - %lu\n",
114  SeparatorsCount, MaxSeparators);
115  goto ErrorExit;
116  }
117 
118  StringEnd = PtrChar + MAX_DEVICE_ID_LEN + 1;
119  PtrPrevChar = PtrChar;
120  SeparatorsCount = 0;
121  }
122  else if (Char < ' ' || Char > 0x7F || Char == ',')
123  {
124  DPRINT1("IopValidateID: Invalid character - %04X\n", Char);
125  goto ErrorExit;
126  }
127  else if (Char == ' ')
128  {
129  *PtrChar = '_';
130  }
131  else if (Char == '\\')
132  {
133  SeparatorsCount++;
134 
135  if (SeparatorsCount > MaxSeparators)
136  {
137  DPRINT1("IopValidateID: SeparatorsCount - %lu, MaxSeparators - %lu\n",
138  SeparatorsCount, MaxSeparators);
139  goto ErrorExit;
140  }
141  }
142  }
143 
144  DPRINT1("IopValidateID: Not terminated ID\n");
145 
146 ErrorExit:
147  // FIXME logging
148  return FALSE;
149 }
150 
151 static
152 NTSTATUS
155  _Out_ PUNICODE_STRING InstancePath)
156 {
158  UNICODE_STRING DeviceId;
160  IO_STACK_LOCATION Stack;
162  UNICODE_STRING ParentIdPrefix = { 0, 0, NULL };
164  BOOLEAN IsValidID;
165 
166  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryDeviceID to device stack\n");
167 
168  Stack.Parameters.QueryId.IdType = BusQueryDeviceID;
169  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
170  &IoStatusBlock,
172  &Stack);
173  if (!NT_SUCCESS(Status))
174  {
175  DPRINT1("IopInitiatePnpIrp(BusQueryDeviceID) failed (Status %x)\n", Status);
176  return Status;
177  }
178 
180 
181  if (!IsValidID)
182  {
183  DPRINT1("Invalid DeviceID. DeviceNode - %p\n", DeviceNode);
184  }
185 
186  /* Save the device id string */
188 
189  DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack (after enumeration)\n");
190 
192  if (!NT_SUCCESS(Status))
193  {
194  DPRINT1("IopQueryDeviceCapabilities() failed (Status 0x%08lx)\n", Status);
195  RtlFreeUnicodeString(&DeviceId);
196  return Status;
197  }
198 
199  /* This bit is only check after enumeration */
200  if (DeviceCapabilities.HardwareDisabled)
201  {
202  /* FIXME: Cleanup device */
203  DeviceNode->Flags |= DNF_DISABLED;
204  RtlFreeUnicodeString(&DeviceId);
206  }
207  else
208  {
209  DeviceNode->Flags &= ~DNF_DISABLED;
210  }
211 
212  if (!DeviceCapabilities.UniqueID)
213  {
214  /* Device has not a unique ID. We need to prepend parent bus unique identifier */
215  DPRINT("Instance ID is not unique\n");
216  Status = IopGetParentIdPrefix(DeviceNode, &ParentIdPrefix);
217  if (!NT_SUCCESS(Status))
218  {
219  DPRINT1("IopGetParentIdPrefix() failed (Status 0x%08lx)\n", Status);
220  RtlFreeUnicodeString(&DeviceId);
221  return Status;
222  }
223  }
224 
225  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryInstanceID to device stack\n");
226 
227  Stack.Parameters.QueryId.IdType = BusQueryInstanceID;
228  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
229  &IoStatusBlock,
231  &Stack);
232  if (!NT_SUCCESS(Status))
233  {
234  DPRINT("IopInitiatePnpIrp(BusQueryInstanceID) failed (Status %lx)\n", Status);
236  }
237 
239  {
241 
242  if (!IsValidID)
243  {
244  DPRINT1("Invalid InstanceID. DeviceNode - %p\n", DeviceNode);
245  }
246  }
247 
250 
251  InstancePath->Length = 0;
252  InstancePath->MaximumLength = DeviceId.Length + sizeof(WCHAR) +
253  ParentIdPrefix.Length +
254  InstanceId.Length +
255  sizeof(UNICODE_NULL);
256  if (ParentIdPrefix.Length && InstanceId.Length)
257  {
258  InstancePath->MaximumLength += sizeof(WCHAR);
259  }
260 
261  InstancePath->Buffer = ExAllocatePoolWithTag(PagedPool,
262  InstancePath->MaximumLength,
263  TAG_IO);
264  if (!InstancePath->Buffer)
265  {
267  RtlFreeUnicodeString(&ParentIdPrefix);
268  RtlFreeUnicodeString(&DeviceId);
270  }
271 
272  /* Start with the device id */
273  RtlCopyUnicodeString(InstancePath, &DeviceId);
274  RtlAppendUnicodeToString(InstancePath, L"\\");
275 
276  /* Add information from parent bus device to InstancePath */
277  RtlAppendUnicodeStringToString(InstancePath, &ParentIdPrefix);
278  if (ParentIdPrefix.Length && InstanceId.Length)
279  {
280  RtlAppendUnicodeToString(InstancePath, L"&");
281  }
282 
283  /* Finally, add the id returned by the driver stack */
285 
286  /*
287  * FIXME: Check for valid characters, if there is invalid characters
288  * then bugcheck
289  */
290 
292  RtlFreeUnicodeString(&DeviceId);
293  RtlFreeUnicodeString(&ParentIdPrefix);
294 
295  return STATUS_SUCCESS;
296 }
297 
298 NTSTATUS
299 NTAPI
301  PDEVICE_CAPABILITIES DeviceCaps)
302 {
303  IO_STATUS_BLOCK StatusBlock;
304  IO_STACK_LOCATION Stack;
306  HANDLE InstanceKey;
308 
309  /* Set up the Header */
310  RtlZeroMemory(DeviceCaps, sizeof(DEVICE_CAPABILITIES));
311  DeviceCaps->Size = sizeof(DEVICE_CAPABILITIES);
312  DeviceCaps->Version = 1;
313  DeviceCaps->Address = -1;
314  DeviceCaps->UINumber = -1;
315 
316  /* Set up the Stack */
317  RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
318  Stack.Parameters.DeviceCapabilities.Capabilities = DeviceCaps;
319 
320  /* Send the IRP */
321  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
322  &StatusBlock,
324  &Stack);
325  if (!NT_SUCCESS(Status))
326  {
328  {
329  DPRINT1("IRP_MN_QUERY_CAPABILITIES failed with status 0x%lx\n", Status);
330  }
331  return Status;
332  }
333 
334  /* Map device capabilities to capability flags */
335  DeviceNode->CapabilityFlags = 0;
336  if (DeviceCaps->LockSupported)
337  DeviceNode->CapabilityFlags |= 0x00000001; // CM_DEVCAP_LOCKSUPPORTED
338 
339  if (DeviceCaps->EjectSupported)
340  DeviceNode->CapabilityFlags |= 0x00000002; // CM_DEVCAP_EJECTSUPPORTED
341 
342  if (DeviceCaps->Removable)
343  DeviceNode->CapabilityFlags |= 0x00000004; // CM_DEVCAP_REMOVABLE
344 
345  if (DeviceCaps->DockDevice)
346  DeviceNode->CapabilityFlags |= 0x00000008; // CM_DEVCAP_DOCKDEVICE
347 
348  if (DeviceCaps->UniqueID)
349  DeviceNode->CapabilityFlags |= 0x00000010; // CM_DEVCAP_UNIQUEID
350 
351  if (DeviceCaps->SilentInstall)
352  DeviceNode->CapabilityFlags |= 0x00000020; // CM_DEVCAP_SILENTINSTALL
353 
354  if (DeviceCaps->RawDeviceOK)
355  DeviceNode->CapabilityFlags |= 0x00000040; // CM_DEVCAP_RAWDEVICEOK
356 
357  if (DeviceCaps->SurpriseRemovalOK)
358  DeviceNode->CapabilityFlags |= 0x00000080; // CM_DEVCAP_SURPRISEREMOVALOK
359 
360  if (DeviceCaps->HardwareDisabled)
361  DeviceNode->CapabilityFlags |= 0x00000100; // CM_DEVCAP_HARDWAREDISABLED
362 
363  if (DeviceCaps->NonDynamic)
364  DeviceNode->CapabilityFlags |= 0x00000200; // CM_DEVCAP_NONDYNAMIC
365 
366  if (DeviceCaps->NoDisplayInUI)
367  DeviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI;
368  else
369  DeviceNode->UserFlags &= ~DNUF_DONT_SHOW_IN_UI;
370 
371  Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
372  if (NT_SUCCESS(Status))
373  {
374  /* Set 'Capabilities' value */
375  RtlInitUnicodeString(&ValueName, L"Capabilities");
376  Status = ZwSetValueKey(InstanceKey,
377  &ValueName,
378  0,
379  REG_DWORD,
380  &DeviceNode->CapabilityFlags,
381  sizeof(ULONG));
382 
383  /* Set 'UINumber' value */
384  if (DeviceCaps->UINumber != MAXULONG)
385  {
386  RtlInitUnicodeString(&ValueName, L"UINumber");
387  Status = ZwSetValueKey(InstanceKey,
388  &ValueName,
389  0,
390  REG_DWORD,
391  &DeviceCaps->UINumber,
392  sizeof(ULONG));
393  }
394 
395  ZwClose(InstanceKey);
396  }
397 
398  return Status;
399 }
400 
401 static
402 NTSTATUS
404  HANDLE InstanceKey)
405 {
406  IO_STACK_LOCATION Stack;
408  PWSTR Ptr;
412  BOOLEAN IsValidID;
413 
414  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryHardwareIDs to device stack\n");
415 
416  RtlZeroMemory(&Stack, sizeof(Stack));
417  Stack.Parameters.QueryId.IdType = BusQueryHardwareIDs;
418  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
419  &IoStatusBlock,
421  &Stack);
422  if (NT_SUCCESS(Status))
423  {
425 
426  if (!IsValidID)
427  {
428  DPRINT1("Invalid HardwareIDs. DeviceNode - %p\n", DeviceNode);
429  }
430 
431  TotalLength = 0;
432 
434  DPRINT("Hardware IDs:\n");
435  while (*Ptr)
436  {
437  DPRINT(" %S\n", Ptr);
438  Length = (ULONG)wcslen(Ptr) + 1;
439 
440  Ptr += Length;
441  TotalLength += Length;
442  }
443  DPRINT("TotalLength: %hu\n", TotalLength);
444  DPRINT("\n");
445 
446  RtlInitUnicodeString(&ValueName, L"HardwareID");
447  Status = ZwSetValueKey(InstanceKey,
448  &ValueName,
449  0,
450  REG_MULTI_SZ,
452  (TotalLength + 1) * sizeof(WCHAR));
453  if (!NT_SUCCESS(Status))
454  {
455  DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
456  }
457  }
458  else
459  {
460  DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
461  }
462 
463  return Status;
464 }
465 
466 static
467 NTSTATUS
469  HANDLE InstanceKey)
470 {
471  IO_STACK_LOCATION Stack;
473  PWSTR Ptr;
477  BOOLEAN IsValidID;
478 
479  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryCompatibleIDs to device stack\n");
480 
481  RtlZeroMemory(&Stack, sizeof(Stack));
482  Stack.Parameters.QueryId.IdType = BusQueryCompatibleIDs;
483  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
484  &IoStatusBlock,
486  &Stack);
488  {
490 
491  if (!IsValidID)
492  {
493  DPRINT1("Invalid CompatibleIDs. DeviceNode - %p\n", DeviceNode);
494  }
495 
496  TotalLength = 0;
497 
499  DPRINT("Compatible IDs:\n");
500  while (*Ptr)
501  {
502  DPRINT(" %S\n", Ptr);
503  Length = (ULONG)wcslen(Ptr) + 1;
504 
505  Ptr += Length;
506  TotalLength += Length;
507  }
508  DPRINT("TotalLength: %hu\n", TotalLength);
509  DPRINT("\n");
510 
511  RtlInitUnicodeString(&ValueName, L"CompatibleIDs");
512  Status = ZwSetValueKey(InstanceKey,
513  &ValueName,
514  0,
515  REG_MULTI_SZ,
517  (TotalLength + 1) * sizeof(WCHAR));
518  if (!NT_SUCCESS(Status))
519  {
520  DPRINT1("ZwSetValueKey() failed (Status %lx) or no Compatible ID returned\n", Status);
521  }
522  }
523  else
524  {
525  DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
526  }
527 
528  return Status;
529 }
530 
531 /*
532  * IopActionInterrogateDeviceStack
533  *
534  * Retrieve information for all (direct) child nodes of a parent node.
535  *
536  * Parameters
537  * DeviceNode
538  * Pointer to device node.
539  * Context
540  * Pointer to parent node to retrieve child node information for.
541  *
542  * Remarks
543  * Any errors that occur are logged instead so that all child services have a chance
544  * of being interrogated.
545  */
546 
547 NTSTATUS
549  PVOID Context)
550 {
553  PWSTR LocationInformation;
554  PDEVICE_NODE ParentDeviceNode;
555  IO_STACK_LOCATION Stack;
558  LCID LocaleId;
559  HANDLE InstanceKey = NULL;
561  UNICODE_STRING InstancePathU;
562  PDEVICE_OBJECT OldDeviceObject;
563 
564  DPRINT("IopActionInterrogateDeviceStack(%p, %p)\n", DeviceNode, Context);
565  DPRINT("PDO 0x%p\n", DeviceNode->PhysicalDeviceObject);
566 
567  ParentDeviceNode = (PDEVICE_NODE)Context;
568 
569  /*
570  * We are called for the parent too, but we don't need to do special
571  * handling for this node
572  */
573  if (DeviceNode == ParentDeviceNode)
574  {
575  DPRINT("Success\n");
576  return STATUS_SUCCESS;
577  }
578 
579  /*
580  * Make sure this device node is a direct child of the parent device node
581  * that is given as an argument
582  */
583  if (DeviceNode->Parent != ParentDeviceNode)
584  {
585  DPRINT("Skipping 2+ level child\n");
586  return STATUS_SUCCESS;
587  }
588 
589  /* Skip processing if it was already completed before */
590  if (DeviceNode->Flags & DNF_PROCESSED)
591  {
592  /* Nothing to do */
593  return STATUS_SUCCESS;
594  }
595 
596  /* Get Locale ID */
597  Status = ZwQueryDefaultLocale(FALSE, &LocaleId);
598  if (!NT_SUCCESS(Status))
599  {
600  DPRINT1("ZwQueryDefaultLocale() failed with status 0x%lx\n", Status);
601  return Status;
602  }
603 
604  /*
605  * FIXME: For critical errors, cleanup and disable device, but always
606  * return STATUS_SUCCESS.
607  */
608 
609  Status = IopCreateDeviceInstancePath(DeviceNode, &InstancePathU);
610  if (!NT_SUCCESS(Status))
611  {
613  {
614  DPRINT1("IopCreateDeviceInstancePath() failed with status 0x%lx\n", Status);
615  }
616 
617  /* We have to return success otherwise we abort the traverse operation */
618  return STATUS_SUCCESS;
619  }
620 
621  /* Verify that this is not a duplicate */
622  OldDeviceObject = IopGetDeviceObjectFromDeviceInstance(&InstancePathU);
623  if (OldDeviceObject != NULL)
624  {
625  PDEVICE_NODE OldDeviceNode = IopGetDeviceNode(OldDeviceObject);
626 
627  DPRINT1("Duplicate device instance '%wZ'\n", &InstancePathU);
628  DPRINT1("Current instance parent: '%wZ'\n", &DeviceNode->Parent->InstancePath);
629  DPRINT1("Old instance parent: '%wZ'\n", &OldDeviceNode->Parent->InstancePath);
630 
631  KeBugCheckEx(PNP_DETECTED_FATAL_ERROR,
632  0x01,
633  (ULONG_PTR)DeviceNode->PhysicalDeviceObject,
634  (ULONG_PTR)OldDeviceObject,
635  0);
636  }
637 
638  DeviceNode->InstancePath = InstancePathU;
639 
640  DPRINT("InstancePath is %S\n", DeviceNode->InstancePath.Buffer);
641 
642  /*
643  * Create registry key for the instance id, if it doesn't exist yet
644  */
645  Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
646  if (!NT_SUCCESS(Status))
647  {
648  DPRINT1("Failed to create the instance key! (Status %lx)\n", Status);
649 
650  /* We have to return success otherwise we abort the traverse operation */
651  return STATUS_SUCCESS;
652  }
653 
654  IopQueryHardwareIds(DeviceNode, InstanceKey);
655 
656  IopQueryCompatibleIds(DeviceNode, InstanceKey);
657 
658  DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextDescription to device stack\n");
659 
660  Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextDescription;
661  Stack.Parameters.QueryDeviceText.LocaleId = LocaleId;
662  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
663  &IoStatusBlock,
665  &Stack);
667  : NULL;
668  /* This key is mandatory, so even if the Irp fails, we still write it */
669  RtlInitUnicodeString(&ValueName, L"DeviceDesc");
670  if (ZwQueryValueKey(InstanceKey, &ValueName, KeyValueBasicInformation, NULL, 0, &RequiredLength) == STATUS_OBJECT_NAME_NOT_FOUND)
671  {
672  if (DeviceDescription &&
674  {
675  /* This key is overriden when a driver is installed. Don't write the
676  * new description if another one already exists */
677  Status = ZwSetValueKey(InstanceKey,
678  &ValueName,
679  0,
680  REG_SZ,
682  ((ULONG)wcslen(DeviceDescription) + 1) * sizeof(WCHAR));
683  }
684  else
685  {
686  UNICODE_STRING DeviceDesc = RTL_CONSTANT_STRING(L"Unknown device");
687  DPRINT("Driver didn't return DeviceDesc (Status 0x%08lx), so place unknown device there\n", Status);
688 
689  Status = ZwSetValueKey(InstanceKey,
690  &ValueName,
691  0,
692  REG_SZ,
693  DeviceDesc.Buffer,
694  DeviceDesc.MaximumLength);
695  if (!NT_SUCCESS(Status))
696  {
697  DPRINT1("ZwSetValueKey() failed (Status 0x%lx)\n", Status);
698  }
699 
700  }
701  }
702 
703  if (DeviceDescription)
704  {
706  }
707 
708  DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextLocation to device stack\n");
709 
710  Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextLocationInformation;
711  Stack.Parameters.QueryDeviceText.LocaleId = LocaleId;
712  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
713  &IoStatusBlock,
715  &Stack);
717  {
718  LocationInformation = (PWSTR)IoStatusBlock.Information;
719  DPRINT("LocationInformation: %S\n", LocationInformation);
720  RtlInitUnicodeString(&ValueName, L"LocationInformation");
721  Status = ZwSetValueKey(InstanceKey,
722  &ValueName,
723  0,
724  REG_SZ,
725  LocationInformation,
726  ((ULONG)wcslen(LocationInformation) + 1) * sizeof(WCHAR));
727  if (!NT_SUCCESS(Status))
728  {
729  DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
730  }
731 
732  ExFreePoolWithTag(LocationInformation, 0);
733  }
734  else
735  {
736  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
737  }
738 
739  DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n");
740 
741  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
742  &IoStatusBlock,
744  NULL);
746  {
748 
749  DeviceNode->ChildBusNumber = BusInformation->BusNumber;
750  DeviceNode->ChildInterfaceType = BusInformation->LegacyBusType;
751  DeviceNode->ChildBusTypeIndex = IopGetBusTypeGuidIndex(&BusInformation->BusTypeGuid);
752  ExFreePoolWithTag(BusInformation, 0);
753  }
754  else
755  {
756  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
757 
758  DeviceNode->ChildBusNumber = 0xFFFFFFF0;
759  DeviceNode->ChildInterfaceType = InterfaceTypeUndefined;
760  DeviceNode->ChildBusTypeIndex = -1;
761  }
762 
763  DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n");
764 
765  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
766  &IoStatusBlock,
768  NULL);
770  {
773  }
774  else
775  {
776  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
777  DeviceNode->BootResources = NULL;
778  }
779 
780  DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n");
781 
782  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
783  &IoStatusBlock,
785  NULL);
786  if (NT_SUCCESS(Status))
787  {
789  }
790  else
791  {
792  DPRINT("IopInitiatePnpIrp() failed (Status %08lx)\n", Status);
793  DeviceNode->ResourceRequirements = NULL;
794  }
795 
796  if (InstanceKey != NULL)
797  {
798  IopSetDeviceInstanceData(InstanceKey, DeviceNode);
799  }
800 
801  ZwClose(InstanceKey);
802 
804 
806  {
807  /* Report the device to the user-mode pnp manager */
808  IopQueueTargetDeviceEvent(&GUID_DEVICE_ENUMERATED,
809  &DeviceNode->InstancePath);
810  }
811 
812  return STATUS_SUCCESS;
813 }
814 
815 /*
816  * IopActionConfigureChildServices
817  *
818  * Retrieve configuration for all (direct) child nodes of a parent node.
819  *
820  * Parameters
821  * DeviceNode
822  * Pointer to device node.
823  * Context
824  * Pointer to parent node to retrieve child node configuration for.
825  *
826  * Remarks
827  * Any errors that occur are logged instead so that all child services have a chance of beeing
828  * configured.
829  */
830 
831 NTSTATUS
833  PVOID Context)
834 {
836  PDEVICE_NODE ParentDeviceNode;
840  DEVICE_CAPABILITIES DeviceCaps;
841 
842  DPRINT("IopActionConfigureChildServices(%p, %p)\n", DeviceNode, Context);
843 
844  ParentDeviceNode = (PDEVICE_NODE)Context;
845 
846  /*
847  * We are called for the parent too, but we don't need to do special
848  * handling for this node
849  */
850  if (DeviceNode == ParentDeviceNode)
851  {
852  DPRINT("Success\n");
853  return STATUS_SUCCESS;
854  }
855 
856  /*
857  * Make sure this device node is a direct child of the parent device node
858  * that is given as an argument
859  */
860 
861  if (DeviceNode->Parent != ParentDeviceNode)
862  {
863  DPRINT("Skipping 2+ level child\n");
864  return STATUS_SUCCESS;
865  }
866 
867  if (!(DeviceNode->Flags & DNF_PROCESSED))
868  {
869  DPRINT1("Child not ready to be configured\n");
870  return STATUS_SUCCESS;
871  }
872 
873  if (!(DeviceNode->Flags & (DNF_DISABLED | DNF_STARTED | DNF_ADDED)))
874  {
875  UNICODE_STRING RegKey;
876 
877  /* Install the service for this if it's in the CDDB */
879 
880  /*
881  * Retrieve configuration from Enum key
882  */
883 
884  Service = &DeviceNode->ServiceName;
885 
889 
890  QueryTable[0].Name = L"Service";
893 
894  QueryTable[1].Name = L"ClassGUID";
898  QueryTable[1].DefaultData = L"";
899  QueryTable[1].DefaultLength = 0;
900 
901  RegKey.Length = 0;
902  RegKey.MaximumLength = sizeof(ENUM_ROOT) + sizeof(WCHAR) + DeviceNode->InstancePath.Length;
904  RegKey.MaximumLength,
905  TAG_IO);
906  if (RegKey.Buffer == NULL)
907  {
910  }
911 
913  RtlAppendUnicodeToString(&RegKey, L"\\");
914  RtlAppendUnicodeStringToString(&RegKey, &DeviceNode->InstancePath);
915 
917  RegKey.Buffer, QueryTable, NULL, NULL);
919 
920  if (!NT_SUCCESS(Status))
921  {
922  /* FIXME: Log the error */
923  DPRINT("Could not retrieve configuration for device %wZ (Status 0x%08x)\n",
924  &DeviceNode->InstancePath, Status);
926  return STATUS_SUCCESS;
927  }
928 
929  if (Service->Buffer == NULL)
930  {
931  if (NT_SUCCESS(IopQueryDeviceCapabilities(DeviceNode, &DeviceCaps)) &&
932  DeviceCaps.RawDeviceOK)
933  {
934  DPRINT("%wZ is using parent bus driver (%wZ)\n", &DeviceNode->InstancePath, &ParentDeviceNode->ServiceName);
935  RtlInitEmptyUnicodeString(&DeviceNode->ServiceName, NULL, 0);
936  }
937  else if (ClassGUID.Length != 0)
938  {
939  /* Device has a ClassGUID value, but no Service value.
940  * Suppose it is using the NULL driver, so state the
941  * device is started */
942  DPRINT("%wZ is using NULL driver\n", &DeviceNode->InstancePath);
944  }
945  else
946  {
949  }
950  return STATUS_SUCCESS;
951  }
952 
953  DPRINT("Got Service %S\n", Service->Buffer);
954  }
955 
956  return STATUS_SUCCESS;
957 }
958 
959 /*
960  * IopActionInitChildServices
961  *
962  * Initialize the service for all (direct) child nodes of a parent node
963  *
964  * Parameters
965  * DeviceNode
966  * Pointer to device node.
967  * Context
968  * Pointer to parent node to initialize child node services for.
969  *
970  * Remarks
971  * If the driver image for a service is not loaded and initialized
972  * it is done here too. Any errors that occur are logged instead so
973  * that all child services have a chance of being initialized.
974  */
975 
976 NTSTATUS
978  PVOID Context)
979 {
980  PDEVICE_NODE ParentDeviceNode;
982  BOOLEAN BootDrivers = !PnpSystemInit;
983 
984  DPRINT("IopActionInitChildServices(%p, %p)\n", DeviceNode, Context);
985 
986  ParentDeviceNode = Context;
987 
988  /*
989  * We are called for the parent too, but we don't need to do special
990  * handling for this node
991  */
992  if (DeviceNode == ParentDeviceNode)
993  {
994  DPRINT("Success\n");
995  return STATUS_SUCCESS;
996  }
997 
998  /*
999  * We don't want to check for a direct child because
1000  * this function is called during boot to reinitialize
1001  * devices with drivers that couldn't load yet due to
1002  * stage 0 limitations (ie can't load from disk yet).
1003  */
1004 
1005  if (!(DeviceNode->Flags & DNF_PROCESSED))
1006  {
1007  DPRINT1("Child not ready to be added\n");
1008  return STATUS_SUCCESS;
1009  }
1010 
1014  return STATUS_SUCCESS;
1015 
1016  if (DeviceNode->ServiceName.Buffer == NULL)
1017  {
1018  /* We don't need to worry about loading the driver because we're
1019  * being driven in raw mode so our parent must be loaded to get here */
1021  if (NT_SUCCESS(Status))
1022  {
1024  if (!NT_SUCCESS(Status))
1025  {
1026  DPRINT1("IopStartDevice(%wZ) failed with status 0x%08x\n",
1027  &DeviceNode->InstancePath, Status);
1028  }
1029  }
1030  }
1031  else
1032  {
1033  PLDR_DATA_TABLE_ENTRY ModuleObject;
1035 
1038  /* Get existing DriverObject pointer (in case the driver has
1039  already been loaded and initialized) */
1041  &DriverObject,
1042  &DeviceNode->ServiceName,
1043  FALSE);
1044 
1045  if (!NT_SUCCESS(Status))
1046  {
1047  /* Driver is not initialized, try to load it */
1048  Status = IopLoadServiceModule(&DeviceNode->ServiceName, &ModuleObject);
1049 
1051  {
1052  /* Initialize the driver */
1054  &DeviceNode->ServiceName, FALSE, &DriverObject);
1055  if (!NT_SUCCESS(Status))
1057  }
1059  {
1060  DPRINT1("Service '%wZ' is disabled\n", &DeviceNode->ServiceName);
1062  }
1063  else
1064  {
1065  DPRINT("IopLoadServiceModule(%wZ) failed with status 0x%08x\n",
1066  &DeviceNode->ServiceName, Status);
1067  if (!BootDrivers)
1069  }
1070  }
1073 
1074  /* Driver is loaded and initialized at this point */
1075  if (NT_SUCCESS(Status))
1076  {
1077  /* Initialize the device, including all filters */
1079 
1080  /* Remove the extra reference */
1082  }
1083  else
1084  {
1085  /*
1086  * Don't disable when trying to load only boot drivers
1087  */
1088  if (!BootDrivers)
1089  {
1091  }
1092  }
1093  }
1094 
1095  return STATUS_SUCCESS;
1096 }
1097 
1098 static
1099 NTSTATUS
1101 {
1102  UNICODE_STRING ServicesKeyPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
1103  UNICODE_STRING ServiceKeyName;
1104  UNICODE_STRING EnumKeyName;
1106  PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
1107  HANDLE ServiceKey = NULL, ServiceEnumKey = NULL;
1109  ULONG Count = 0, NextInstance = 0;
1110  WCHAR ValueBuffer[6];
1112 
1113  DPRINT("IopSetServiceEnumData(%p)\n", DeviceNode);
1114  DPRINT("Instance: %wZ\n", &DeviceNode->InstancePath);
1115  DPRINT("Service: %wZ\n", &DeviceNode->ServiceName);
1116 
1117  if (DeviceNode->ServiceName.Buffer == NULL)
1118  {
1119  DPRINT1("No service!\n");
1120  return STATUS_SUCCESS;
1121  }
1122 
1123  ServiceKeyName.MaximumLength = ServicesKeyPath.Length + DeviceNode->ServiceName.Length + sizeof(UNICODE_NULL);
1124  ServiceKeyName.Length = 0;
1125  ServiceKeyName.Buffer = ExAllocatePool(PagedPool, ServiceKeyName.MaximumLength);
1126  if (ServiceKeyName.Buffer == NULL)
1127  {
1128  DPRINT1("No ServiceKeyName.Buffer!\n");
1130  }
1131 
1132  RtlAppendUnicodeStringToString(&ServiceKeyName, &ServicesKeyPath);
1133  RtlAppendUnicodeStringToString(&ServiceKeyName, &DeviceNode->ServiceName);
1134 
1135  DPRINT("ServiceKeyName: %wZ\n", &ServiceKeyName);
1136 
1137  Status = IopOpenRegistryKeyEx(&ServiceKey, NULL, &ServiceKeyName, KEY_CREATE_SUB_KEY);
1138  if (!NT_SUCCESS(Status))
1139  {
1140  goto done;
1141  }
1142 
1143  RtlInitUnicodeString(&EnumKeyName, L"Enum");
1144  Status = IopCreateRegistryKeyEx(&ServiceEnumKey,
1145  ServiceKey,
1146  &EnumKeyName,
1147  KEY_SET_VALUE,
1149  &Disposition);
1150  if (NT_SUCCESS(Status))
1151  {
1153  {
1154  /* Read the NextInstance value */
1155  Status = IopGetRegistryValue(ServiceEnumKey,
1156  L"Count",
1157  &KeyValueInformation);
1158  if (!NT_SUCCESS(Status))
1159  goto done;
1160 
1161  if ((KeyValueInformation->Type == REG_DWORD) &&
1162  (KeyValueInformation->DataLength))
1163  {
1164  /* Read it */
1165  Count = *(PULONG)((ULONG_PTR)KeyValueInformation +
1166  KeyValueInformation->DataOffset);
1167  }
1168 
1169  ExFreePool(KeyValueInformation);
1170  KeyValueInformation = NULL;
1171 
1172  /* Read the NextInstance value */
1173  Status = IopGetRegistryValue(ServiceEnumKey,
1174  L"NextInstance",
1175  &KeyValueInformation);
1176  if (!NT_SUCCESS(Status))
1177  goto done;
1178 
1179  if ((KeyValueInformation->Type == REG_DWORD) &&
1180  (KeyValueInformation->DataLength))
1181  {
1182  NextInstance = *(PULONG)((ULONG_PTR)KeyValueInformation +
1183  KeyValueInformation->DataOffset);
1184  }
1185 
1186  ExFreePool(KeyValueInformation);
1187  KeyValueInformation = NULL;
1188  }
1189 
1190  /* Set the instance path */
1191  swprintf(ValueBuffer, L"%lu", NextInstance);
1192  RtlInitUnicodeString(&ValueName, ValueBuffer);
1193  Status = ZwSetValueKey(ServiceEnumKey,
1194  &ValueName,
1195  0,
1196  REG_SZ,
1197  DeviceNode->InstancePath.Buffer,
1198  DeviceNode->InstancePath.MaximumLength);
1199  if (!NT_SUCCESS(Status))
1200  goto done;
1201 
1202  /* Increment Count and NextInstance */
1203  Count++;
1204  NextInstance++;
1205 
1206  /* Set the new Count value */
1207  RtlInitUnicodeString(&ValueName, L"Count");
1208  Status = ZwSetValueKey(ServiceEnumKey,
1209  &ValueName,
1210  0,
1211  REG_DWORD,
1212  &Count,
1213  sizeof(Count));
1214  if (!NT_SUCCESS(Status))
1215  goto done;
1216 
1217  /* Set the new NextInstance value */
1218  RtlInitUnicodeString(&ValueName, L"NextInstance");
1219  Status = ZwSetValueKey(ServiceEnumKey,
1220  &ValueName,
1221  0,
1222  REG_DWORD,
1223  &NextInstance,
1224  sizeof(NextInstance));
1225  }
1226 
1227 done:
1228  if (ServiceEnumKey != NULL)
1229  ZwClose(ServiceEnumKey);
1230 
1231  if (ServiceKey != NULL)
1232  ZwClose(ServiceKey);
1233 
1234  ExFreePool(ServiceKeyName.Buffer);
1235 
1236  return Status;
1237 }
1238 
1239 static
1240 VOID
1241 NTAPI
1243 {
1244  IO_STACK_LOCATION Stack;
1246  NTSTATUS Status;
1247  PVOID Dummy;
1249 
1250  /* Get the device node */
1252 
1253  ASSERT(!(DeviceNode->Flags & DNF_DISABLED));
1254 
1255  /* Build the I/O stack location */
1256  RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
1257  Stack.MajorFunction = IRP_MJ_PNP;
1259 
1260  Stack.Parameters.StartDevice.AllocatedResources =
1261  DeviceNode->ResourceList;
1262  Stack.Parameters.StartDevice.AllocatedResourcesTranslated =
1263  DeviceNode->ResourceListTranslated;
1264 
1265  /* Do the call */
1266  Status = IopSynchronousCall(DeviceObject, &Stack, &Dummy);
1267  if (!NT_SUCCESS(Status))
1268  {
1269  /* Send an IRP_MN_REMOVE_DEVICE request */
1271 
1272  /* Set the appropriate flag */
1273  DeviceNode->Flags |= DNF_START_FAILED;
1274  DeviceNode->Problem = CM_PROB_FAILED_START;
1275 
1276  DPRINT1("Warning: PnP Start failed (%wZ) [Status: 0x%x]\n", &DeviceNode->InstancePath, Status);
1277  return;
1278  }
1279 
1280  DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack (after start)\n");
1281 
1283  if (!NT_SUCCESS(Status))
1284  {
1285  DPRINT("IopInitiatePnpIrp() failed (Status 0x%08lx)\n", Status);
1286  }
1287 
1288  /* Invalidate device state so IRP_MN_QUERY_PNP_DEVICE_STATE is sent */
1290 
1291  /* Otherwise, mark us as started */
1292  DeviceNode->Flags |= DNF_STARTED;
1293  DeviceNode->Flags &= ~DNF_STOPPED;
1294 
1295  /* We now need enumeration */
1297 }
1298 
1299 static
1300 NTSTATUS
1301 NTAPI
1303 {
1305  NTSTATUS Status;
1306  PAGED_CODE();
1307 
1308  /* Sanity check */
1309  ASSERT((DeviceNode->Flags & DNF_ADDED));
1313 
1314  /* Get the device object */
1315  DeviceObject = DeviceNode->PhysicalDeviceObject;
1316 
1317  /* Check if we're not started yet */
1318  if (!(DeviceNode->Flags & DNF_STARTED))
1319  {
1320  /* Start us */
1322  }
1323 
1324  /* Do we need to query IDs? This happens in the case of manual reporting */
1325 #if 0
1326  if (DeviceNode->Flags & DNF_NEED_QUERY_IDS)
1327  {
1328  DPRINT1("Warning: Device node has DNF_NEED_QUERY_IDS\n");
1329  /* And that case shouldn't happen yet */
1330  ASSERT(FALSE);
1331  }
1332 #endif
1333 
1335 
1336  /* Make sure we're started, and check if we need enumeration */
1337  if ((DeviceNode->Flags & DNF_STARTED) &&
1339  {
1340  /* Enumerate us */
1343  }
1344  else
1345  {
1346  /* Nothing to do */
1348  }
1349 
1350  /* Return */
1351  return Status;
1352 }
1353 
1354 NTSTATUS
1357 {
1358  NTSTATUS Status;
1359  HANDLE InstanceHandle = NULL, ControlHandle = NULL;
1360  UNICODE_STRING KeyName, ValueString;
1362 
1363  if (DeviceNode->Flags & DNF_DISABLED)
1364  return STATUS_SUCCESS;
1365 
1367  if (!NT_SUCCESS(Status))
1368  goto ByeBye;
1369 
1370  /* New PnP ABI */
1372 
1373  /* FIX: Should be done in new device instance code */
1374  Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceHandle);
1375  if (!NT_SUCCESS(Status))
1376  goto ByeBye;
1377 
1378  /* FIX: Should be done in IoXxxPrepareDriverLoading */
1379  // {
1380  RtlInitUnicodeString(&KeyName, L"Control");
1382  &KeyName,
1384  InstanceHandle,
1385  NULL);
1386  Status = ZwCreateKey(&ControlHandle,
1387  KEY_SET_VALUE,
1389  0,
1390  NULL,
1392  NULL);
1393  if (!NT_SUCCESS(Status))
1394  goto ByeBye;
1395 
1396  RtlInitUnicodeString(&KeyName, L"ActiveService");
1397  ValueString = DeviceNode->ServiceName;
1398  if (!ValueString.Buffer)
1399  RtlInitUnicodeString(&ValueString, L"");
1400  Status = ZwSetValueKey(ControlHandle, &KeyName, 0, REG_SZ, ValueString.Buffer, ValueString.Length + sizeof(UNICODE_NULL));
1401  // }
1402 
1403 ByeBye:
1404  if (ControlHandle != NULL)
1405  ZwClose(ControlHandle);
1406 
1407  if (InstanceHandle != NULL)
1408  ZwClose(InstanceHandle);
1409 
1410  return Status;
1411 }
1412 
1413 static
1414 NTSTATUS
1415 NTAPI
1417 {
1418  IO_STACK_LOCATION Stack;
1419  PVOID Dummy;
1420 
1421  RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
1422  Stack.MajorFunction = IRP_MJ_PNP;
1424 
1425  return IopSynchronousCall(DeviceObject, &Stack, &Dummy);
1426 }
1427 
1428 static
1429 VOID
1430 NTAPI
1432 {
1433  IO_STACK_LOCATION Stack;
1434  PVOID Dummy;
1435 
1436  RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
1437  Stack.MajorFunction = IRP_MJ_PNP;
1439 
1440  /* Drivers should never fail a IRP_MN_STOP_DEVICE request */
1441  IopSynchronousCall(DeviceObject, &Stack, &Dummy);
1442 }
1443 
1444 NTSTATUS
1447 {
1448  NTSTATUS Status;
1449 
1450  DPRINT("Stopping device: %wZ\n", &DeviceNode->InstancePath);
1451 
1452  Status = IopQueryStopDevice(DeviceNode->PhysicalDeviceObject);
1453  if (NT_SUCCESS(Status))
1454  {
1455  IopSendStopDevice(DeviceNode->PhysicalDeviceObject);
1456 
1458  DeviceNode->Flags |= DNF_STOPPED;
1459 
1460  return STATUS_SUCCESS;
1461  }
1462 
1463  return Status;
1464 }
1465 
1466 /* PUBLIC FUNCTIONS **********************************************************/
1467 
1468 static
1469 VOID
1470 NTAPI
1472 {
1473  IO_STACK_LOCATION Stack;
1474  PVOID Dummy;
1476 
1477  /* Drop all our state for this device in case it isn't really going away */
1479 
1480  RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
1481  Stack.MajorFunction = IRP_MJ_PNP;
1483 
1484  /* Drivers should never fail a IRP_MN_REMOVE_DEVICE request */
1485  IopSynchronousCall(DeviceObject, &Stack, &Dummy);
1486 
1489  &GUID_TARGET_DEVICE_REMOVE_COMPLETE,
1490  NULL,
1491  NULL);
1493 }
1494 
1495 static
1496 VOID
1498 {
1499  /* This function DOES dereference the device objects in all cases */
1500 
1501  ULONG i;
1502 
1503  for (i = 0; i < DeviceRelations->Count; i++)
1504  {
1505  IopSendRemoveDevice(DeviceRelations->Objects[i]);
1506  DeviceRelations->Objects[i] = NULL;
1507  }
1508 
1509  ExFreePool(DeviceRelations);
1510 }
1511 
1512 static
1513 VOID
1515 {
1516  PDEVICE_NODE ChildDeviceNode, NextDeviceNode;
1517  KIRQL OldIrql;
1518 
1520  ChildDeviceNode = ParentDeviceNode->Child;
1521  while (ChildDeviceNode != NULL)
1522  {
1523  NextDeviceNode = ChildDeviceNode->Sibling;
1525 
1526  IopSendRemoveDevice(ChildDeviceNode->PhysicalDeviceObject);
1527 
1528  ChildDeviceNode = NextDeviceNode;
1529 
1531  }
1533 }
1534 
1535 static
1536 VOID
1537 NTAPI
1539 {
1540  IO_STACK_LOCATION Stack;
1541  PVOID Dummy;
1542 
1543  RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
1544  Stack.MajorFunction = IRP_MJ_PNP;
1546 
1547  /* Drivers should never fail a IRP_MN_SURPRISE_REMOVAL request */
1548  IopSynchronousCall(DeviceObject, &Stack, &Dummy);
1549 }
1550 
1551 static
1552 VOID
1553 NTAPI
1555 {
1556  IO_STACK_LOCATION Stack;
1557  PVOID Dummy;
1558 
1559  RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
1560  Stack.MajorFunction = IRP_MJ_PNP;
1562 
1563  /* Drivers should never fail a IRP_MN_CANCEL_REMOVE_DEVICE request */
1564  IopSynchronousCall(DeviceObject, &Stack, &Dummy);
1565 
1568  &GUID_TARGET_DEVICE_REMOVE_CANCELLED,
1569  NULL,
1570  NULL);
1571 }
1572 
1573 static
1574 VOID
1576 {
1577  PDEVICE_NODE ChildDeviceNode, NextDeviceNode;
1578  KIRQL OldIrql;
1579 
1581  ChildDeviceNode = ParentDeviceNode->Child;
1582  while (ChildDeviceNode != NULL)
1583  {
1584  NextDeviceNode = ChildDeviceNode->Sibling;
1586 
1588 
1589  ChildDeviceNode = NextDeviceNode;
1590 
1592  }
1594 }
1595 
1596 static
1597 VOID
1599 {
1600  /* This function DOES dereference the device objects in all cases */
1601 
1602  ULONG i;
1603 
1604  for (i = 0; i < DeviceRelations->Count; i++)
1605  {
1606  IopCancelPrepareDeviceForRemoval(DeviceRelations->Objects[i]);
1607  ObDereferenceObject(DeviceRelations->Objects[i]);
1608  DeviceRelations->Objects[i] = NULL;
1609  }
1610 
1611  ExFreePool(DeviceRelations);
1612 }
1613 
1614 static
1615 VOID
1617 {
1618  IO_STACK_LOCATION Stack;
1620  PDEVICE_RELATIONS DeviceRelations;
1621  NTSTATUS Status;
1622 
1624 
1625  Stack.Parameters.QueryDeviceRelations.Type = RemovalRelations;
1626 
1628  &IoStatusBlock,
1630  &Stack);
1631  if (!NT_SUCCESS(Status))
1632  {
1633  DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
1634  DeviceRelations = NULL;
1635  }
1636  else
1637  {
1638  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
1639  }
1640 
1641  if (DeviceRelations)
1642  IopCancelRemoveDeviceRelations(DeviceRelations);
1643 }
1644 
1645 static
1646 NTSTATUS
1647 NTAPI
1649 {
1651  IO_STACK_LOCATION Stack;
1652  PVOID Dummy;
1653  NTSTATUS Status;
1654 
1655  ASSERT(DeviceNode);
1656 
1657  IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVE_PENDING,
1658  &DeviceNode->InstancePath);
1659 
1660  RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
1661  Stack.MajorFunction = IRP_MJ_PNP;
1663 
1664  Status = IopSynchronousCall(DeviceObject, &Stack, &Dummy);
1665 
1668  &GUID_TARGET_DEVICE_QUERY_REMOVE,
1669  NULL,
1670  NULL);
1671 
1672  if (!NT_SUCCESS(Status))
1673  {
1674  DPRINT1("Removal vetoed by %wZ\n", &DeviceNode->InstancePath);
1675  IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVAL_VETOED,
1676  &DeviceNode->InstancePath);
1677  }
1678 
1679  return Status;
1680 }
1681 
1682 static
1683 NTSTATUS
1685 {
1686  PDEVICE_NODE ChildDeviceNode, NextDeviceNode, FailedRemoveDevice;
1687  NTSTATUS Status;
1688  KIRQL OldIrql;
1689 
1691  ChildDeviceNode = ParentDeviceNode->Child;
1692  while (ChildDeviceNode != NULL)
1693  {
1694  NextDeviceNode = ChildDeviceNode->Sibling;
1696 
1698  if (!NT_SUCCESS(Status))
1699  {
1700  FailedRemoveDevice = ChildDeviceNode;
1701  goto cleanup;
1702  }
1703 
1705  ChildDeviceNode = NextDeviceNode;
1706  }
1708 
1709  return STATUS_SUCCESS;
1710 
1711 cleanup:
1713  ChildDeviceNode = ParentDeviceNode->Child;
1714  while (ChildDeviceNode != NULL)
1715  {
1716  NextDeviceNode = ChildDeviceNode->Sibling;
1718 
1720 
1721  /* IRP_MN_CANCEL_REMOVE_DEVICE is also sent to the device
1722  * that failed the IRP_MN_QUERY_REMOVE_DEVICE request */
1723  if (ChildDeviceNode == FailedRemoveDevice)
1724  return Status;
1725 
1726  ChildDeviceNode = NextDeviceNode;
1727 
1729  }
1731 
1732  return Status;
1733 }
1734 
1735 static
1736 NTSTATUS
1738 {
1739  /* This function DOES NOT dereference the device objects on SUCCESS
1740  * but it DOES dereference device objects on FAILURE */
1741 
1742  ULONG i, j;
1743  NTSTATUS Status;
1744 
1745  for (i = 0; i < DeviceRelations->Count; i++)
1746  {
1747  Status = IopPrepareDeviceForRemoval(DeviceRelations->Objects[i], Force);
1748  if (!NT_SUCCESS(Status))
1749  {
1750  j = i;
1751  goto cleanup;
1752  }
1753  }
1754 
1755  return STATUS_SUCCESS;
1756 
1757 cleanup:
1758  /* IRP_MN_CANCEL_REMOVE_DEVICE is also sent to the device
1759  * that failed the IRP_MN_QUERY_REMOVE_DEVICE request */
1760  for (i = 0; i <= j; i++)
1761  {
1762  IopCancelPrepareDeviceForRemoval(DeviceRelations->Objects[i]);
1763  ObDereferenceObject(DeviceRelations->Objects[i]);
1764  DeviceRelations->Objects[i] = NULL;
1765  }
1766  for (; i < DeviceRelations->Count; i++)
1767  {
1768  ObDereferenceObject(DeviceRelations->Objects[i]);
1769  DeviceRelations->Objects[i] = NULL;
1770  }
1771  ExFreePool(DeviceRelations);
1772 
1773  return Status;
1774 }
1775 
1776 static
1777 NTSTATUS
1779 {
1781  IO_STACK_LOCATION Stack;
1783  PDEVICE_RELATIONS DeviceRelations;
1784  NTSTATUS Status;
1785 
1786  if ((DeviceNode->UserFlags & DNUF_NOT_DISABLEABLE) && !Force)
1787  {
1788  DPRINT1("Removal not allowed for %wZ\n", &DeviceNode->InstancePath);
1789  return STATUS_UNSUCCESSFUL;
1790  }
1791 
1793  {
1794  DPRINT1("Removal vetoed by failing the query remove request\n");
1795 
1797 
1798  return STATUS_UNSUCCESSFUL;
1799  }
1800 
1801  Stack.Parameters.QueryDeviceRelations.Type = RemovalRelations;
1802 
1804  &IoStatusBlock,
1806  &Stack);
1807  if (!NT_SUCCESS(Status))
1808  {
1809  DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
1810  DeviceRelations = NULL;
1811  }
1812  else
1813  {
1814  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
1815  }
1816 
1817  if (DeviceRelations)
1818  {
1819  Status = IopQueryRemoveDeviceRelations(DeviceRelations, Force);
1820  if (!NT_SUCCESS(Status))
1821  return Status;
1822  }
1823 
1825  if (!NT_SUCCESS(Status))
1826  {
1827  if (DeviceRelations)
1828  IopCancelRemoveDeviceRelations(DeviceRelations);
1829  return Status;
1830  }
1831 
1832  if (DeviceRelations)
1833  IopSendRemoveDeviceRelations(DeviceRelations);
1835 
1836  return STATUS_SUCCESS;
1837 }
1838 
1839 static
1840 VOID
1843  IN PDEVICE_RELATIONS DeviceRelations)
1844 {
1845  PDEVICE_NODE Child = DeviceNode->Child, NextChild;
1846  ULONG i;
1847  BOOLEAN Found;
1848 
1850  return;
1851 
1852  while (Child != NULL)
1853  {
1854  NextChild = Child->Sibling;
1855  Found = FALSE;
1856 
1857  for (i = 0; DeviceRelations && i < DeviceRelations->Count; i++)
1858  {
1859  if (IopGetDeviceNode(DeviceRelations->Objects[i]) == Child)
1860  {
1861  Found = TRUE;
1862  break;
1863  }
1864  }
1865 
1866  if (!Found && !(Child->Flags & DNF_WILL_BE_REMOVED))
1867  {
1868  /* Send removal IRPs to all of its children */
1869  IopPrepareDeviceForRemoval(Child->PhysicalDeviceObject, TRUE);
1870 
1871  /* Send the surprise removal IRP */
1872  IopSendSurpriseRemoval(Child->PhysicalDeviceObject);
1873 
1874  /* Tell the user-mode PnP manager that a device was removed */
1875  IopQueueTargetDeviceEvent(&GUID_DEVICE_SURPRISE_REMOVAL,
1876  &Child->InstancePath);
1877 
1878  /* Send the remove device IRP */
1879  IopSendRemoveDevice(Child->PhysicalDeviceObject);
1880  }
1881 
1882  Child = NextChild;
1883  }
1884 }
1885 
1886 NTSTATUS
1888 {
1889  NTSTATUS Status;
1890 
1891  DPRINT("Removing device: %wZ\n", &DeviceNode->InstancePath);
1892 
1893  Status = IopPrepareDeviceForRemoval(DeviceNode->PhysicalDeviceObject, FALSE);
1894  if (NT_SUCCESS(Status))
1895  {
1896  IopSendRemoveDevice(DeviceNode->PhysicalDeviceObject);
1897  IopQueueTargetDeviceEvent(&GUID_DEVICE_SAFE_REMOVAL,
1898  &DeviceNode->InstancePath);
1899  return STATUS_SUCCESS;
1900  }
1901 
1902  return Status;
1903 }
1904 
1905 /*
1906  * @implemented
1907  */
1908 VOID
1909 NTAPI
1911 {
1913  IO_STACK_LOCATION Stack;
1914  ULONG_PTR PnPFlags;
1915  NTSTATUS Status;
1917 
1918  RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
1919  Stack.MajorFunction = IRP_MJ_PNP;
1921 
1922  Status = IopSynchronousCall(PhysicalDeviceObject, &Stack, (PVOID*)&PnPFlags);
1923  if (!NT_SUCCESS(Status))
1924  {
1926  {
1927  DPRINT1("IRP_MN_QUERY_PNP_DEVICE_STATE failed with status 0x%lx\n", Status);
1928  }
1929  return;
1930  }
1931 
1932  if (PnPFlags & PNP_DEVICE_NOT_DISABLEABLE)
1933  DeviceNode->UserFlags |= DNUF_NOT_DISABLEABLE;
1934  else
1935  DeviceNode->UserFlags &= ~DNUF_NOT_DISABLEABLE;
1936 
1937  if (PnPFlags & PNP_DEVICE_DONT_DISPLAY_IN_UI)
1938  DeviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI;
1939  else
1940  DeviceNode->UserFlags &= ~DNUF_DONT_SHOW_IN_UI;
1941 
1942  if ((PnPFlags & PNP_DEVICE_REMOVED) ||
1943  ((PnPFlags & PNP_DEVICE_FAILED) && !(PnPFlags & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED)))
1944  {
1945  /* Flag it if it's failed */
1946  if (PnPFlags & PNP_DEVICE_FAILED) DeviceNode->Problem = CM_PROB_FAILED_POST_START;
1947 
1948  /* Send removal IRPs to all of its children */
1950 
1951  /* Send surprise removal */
1953 
1954  /* Tell the user-mode PnP manager that a device was removed */
1955  IopQueueTargetDeviceEvent(&GUID_DEVICE_SURPRISE_REMOVAL,
1956  &DeviceNode->InstancePath);
1957 
1959  }
1960  else if ((PnPFlags & PNP_DEVICE_FAILED) && (PnPFlags & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED))
1961  {
1962  /* Stop for resource rebalance */
1964  if (!NT_SUCCESS(Status))
1965  {
1966  DPRINT1("Failed to stop device for rebalancing\n");
1967 
1968  /* Stop failed so don't rebalance */
1970  }
1971  }
1972 
1973  /* Resource rebalance */
1975  {
1976  DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n");
1977 
1979  &IoStatusBlock,
1981  NULL);
1983  {
1984  DeviceNode->BootResources =
1987  }
1988  else
1989  {
1990  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
1991  DeviceNode->BootResources = NULL;
1992  }
1993 
1994  DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n");
1995 
1997  &IoStatusBlock,
1999  NULL);
2000  if (NT_SUCCESS(Status))
2001  {
2002  DeviceNode->ResourceRequirements =
2004  }
2005  else
2006  {
2007  DPRINT("IopInitiatePnpIrp() failed (Status %08lx)\n", Status);
2008  DeviceNode->ResourceRequirements = NULL;
2009  }
2010 
2011  /* IRP_MN_FILTER_RESOURCE_REQUIREMENTS is called indirectly by IopStartDevice */
2013  {
2014  DPRINT1("Restart after resource rebalance failed\n");
2015 
2017  DeviceNode->Flags |= DNF_START_FAILED;
2018 
2020  }
2021  }
2022 }
2023 
2024 /*
2025  * IopInitializePnpServices
2026  *
2027  * Initialize services for discovered children
2028  *
2029  * Parameters
2030  * DeviceNode
2031  * Top device node to start initializing services.
2032  *
2033  * Return Value
2034  * Status
2035  */
2036 NTSTATUS
2038 {
2040 
2041  DPRINT("IopInitializePnpServices(%p)\n", DeviceNode);
2042 
2044  &Context,
2045  DeviceNode,
2047  DeviceNode);
2048 
2049  return IopTraverseDeviceTree(&Context);
2050 }
2051 
2052 
2053 NTSTATUS
2056 {
2059  PDEVICE_RELATIONS DeviceRelations;
2060  PDEVICE_OBJECT ChildDeviceObject;
2062  PDEVICE_NODE ChildDeviceNode;
2063  IO_STACK_LOCATION Stack;
2064  NTSTATUS Status;
2065  ULONG i;
2066 
2067  DPRINT("DeviceObject 0x%p\n", DeviceObject);
2068 
2070  {
2072 
2073  DPRINT("Sending GUID_DEVICE_ARRIVAL\n");
2074  IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL,
2075  &DeviceNode->InstancePath);
2076  }
2077 
2078  DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
2079 
2080  Stack.Parameters.QueryDeviceRelations.Type = BusRelations;
2081 
2083  DeviceObject,
2084  &IoStatusBlock,
2086  &Stack);
2087  if (!NT_SUCCESS(Status) || Status == STATUS_PENDING)
2088  {
2089  DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
2090  return Status;
2091  }
2092 
2093  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
2094 
2095  /*
2096  * Send removal IRPs for devices that have disappeared
2097  * NOTE: This code handles the case where no relations are specified
2098  */
2099  IopHandleDeviceRemoval(DeviceNode, DeviceRelations);
2100 
2101  /* Now we bail if nothing was returned */
2102  if (!DeviceRelations)
2103  {
2104  /* We're all done */
2105  DPRINT("No PDOs\n");
2106  return STATUS_SUCCESS;
2107  }
2108 
2109  DPRINT("Got %u PDOs\n", DeviceRelations->Count);
2110 
2111  /*
2112  * Create device nodes for all discovered devices
2113  */
2114  for (i = 0; i < DeviceRelations->Count; i++)
2115  {
2116  ChildDeviceObject = DeviceRelations->Objects[i];
2117  ASSERT((ChildDeviceObject->Flags & DO_DEVICE_INITIALIZING) == 0);
2118 
2119  ChildDeviceNode = IopGetDeviceNode(ChildDeviceObject);
2120  if (!ChildDeviceNode)
2121  {
2122  /* One doesn't exist, create it */
2124  DeviceNode,
2125  ChildDeviceObject,
2126  NULL,
2127  &ChildDeviceNode);
2128  if (NT_SUCCESS(Status))
2129  {
2130  /* Mark the node as enumerated */
2131  ChildDeviceNode->Flags |= DNF_ENUMERATED;
2132 
2133  /* Mark the DO as bus enumerated */
2134  ChildDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
2135  }
2136  else
2137  {
2138  /* Ignore this DO */
2139  DPRINT1("IopCreateDeviceNode() failed with status 0x%08x. Skipping PDO %u\n", Status, i);
2140  ObDereferenceObject(ChildDeviceObject);
2141  }
2142  }
2143  else
2144  {
2145  /* Mark it as enumerated */
2146  ChildDeviceNode->Flags |= DNF_ENUMERATED;
2147  ObDereferenceObject(ChildDeviceObject);
2148  }
2149  }
2150  ExFreePool(DeviceRelations);
2151 
2152  /*
2153  * Retrieve information about all discovered children from the bus driver
2154  */
2156  &Context,
2157  DeviceNode,
2159  DeviceNode);
2160 
2162  if (!NT_SUCCESS(Status))
2163  {
2164  DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status);
2165  return Status;
2166  }
2167 
2168  /*
2169  * Retrieve configuration from the registry for discovered children
2170  */
2172  &Context,
2173  DeviceNode,
2175  DeviceNode);
2176 
2178  if (!NT_SUCCESS(Status))
2179  {
2180  DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status);
2181  return Status;
2182  }
2183 
2184  /*
2185  * Initialize services for discovered children.
2186  */
2188  if (!NT_SUCCESS(Status))
2189  {
2190  DPRINT("IopInitializePnpServices() failed with status 0x%08lx\n", Status);
2191  return Status;
2192  }
2193 
2194  DPRINT("IopEnumerateDevice() finished\n");
2195  return STATUS_SUCCESS;
2196 }
2197 
2198 static
2199 NTSTATUS
2200 NTAPI
2202 {
2203  IO_STACK_LOCATION Stack;
2204  PVOID Dummy;
2205 
2206  RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
2207  Stack.MajorFunction = IRP_MJ_PNP;
2208  Stack.MinorFunction = IRP_MN_EJECT;
2209 
2210  return IopSynchronousCall(DeviceObject, &Stack, &Dummy);
2211 }
2212 
2213 /*
2214  * @implemented
2215  */
2216 VOID
2217 NTAPI
2219 {
2221  PDEVICE_RELATIONS DeviceRelations;
2223  IO_STACK_LOCATION Stack;
2225  NTSTATUS Status;
2226 
2227  IopQueueTargetDeviceEvent(&GUID_DEVICE_KERNEL_INITIATED_EJECT,
2228  &DeviceNode->InstancePath);
2229 
2231  {
2232  goto cleanup;
2233  }
2234 
2235  Stack.Parameters.QueryDeviceRelations.Type = EjectionRelations;
2236 
2238  &IoStatusBlock,
2240  &Stack);
2241  if (!NT_SUCCESS(Status))
2242  {
2243  DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
2244  DeviceRelations = NULL;
2245  }
2246  else
2247  {
2248  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
2249  }
2250 
2251  if (DeviceRelations)
2252  {
2253  Status = IopQueryRemoveDeviceRelations(DeviceRelations, FALSE);
2254  if (!NT_SUCCESS(Status))
2255  goto cleanup;
2256  }
2257 
2259  if (!NT_SUCCESS(Status))
2260  {
2261  if (DeviceRelations)
2262  IopCancelRemoveDeviceRelations(DeviceRelations);
2263  goto cleanup;
2264  }
2265 
2267  {
2268  if (DeviceRelations)
2269  IopCancelRemoveDeviceRelations(DeviceRelations);
2271  goto cleanup;
2272  }
2273 
2274  if (DeviceRelations)
2275  IopSendRemoveDeviceRelations(DeviceRelations);
2277 
2279  if (Capabilities.EjectSupported)
2280  {
2282  {
2283  goto cleanup;
2284  }
2285  }
2286  else
2287  {
2288  DeviceNode->Flags |= DNF_DISABLED;
2289  }
2290 
2291  IopQueueTargetDeviceEvent(&GUID_DEVICE_EJECT,
2292  &DeviceNode->InstancePath);
2293 
2294  return;
2295 
2296 cleanup:
2297  IopQueueTargetDeviceEvent(&GUID_DEVICE_EJECT_VETOED,
2298  &DeviceNode->InstancePath);
2299 }
2300 
2301 static
2302 VOID
2303 NTAPI
2305  _In_ PVOID Context)
2306 {
2307  PLIST_ENTRY ListEntry;
2309  KIRQL OldIrql;
2310 
2313  {
2316  Data = CONTAINING_RECORD(ListEntry,
2318  RequestListEntry);
2319 
2320  switch (Data->Action)
2321  {
2324  Data->InvalidateDeviceRelations.Type);
2325  break;
2326 
2327  default:
2328  DPRINT1("Unimplemented device action %u\n", Data->Action);
2329  break;
2330  }
2331 
2332  ObDereferenceObject(Data->DeviceObject);
2335  }
2338 }
2339 
2340 VOID
2342  _In_ PDEVICE_ACTION_DATA ActionData)
2343 {
2345  KIRQL OldIrql;
2346 
2347  DPRINT("IopQueueDeviceAction(%p)\n", ActionData);
2348 
2350  sizeof(DEVICE_ACTION_DATA),
2351  TAG_IO);
2352  if (!Data)
2353  return;
2354 
2355  ObReferenceObject(ActionData->DeviceObject);
2356  RtlCopyMemory(Data, ActionData, sizeof(DEVICE_ACTION_DATA));
2357 
2358  DPRINT("Action %u\n", Data->Action);
2359 
2361  InsertTailList(&IopDeviceActionRequestList, &Data->RequestListEntry);
2363  {
2365  return;
2366  }
2369 
2372  NULL);
2375 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
NTSTATUS NTAPI PipCallDriverAddDevice(IN PDEVICE_NODE DeviceNode, IN BOOLEAN LoadDriver, IN PDRIVER_OBJECT DriverObject)
Definition: pnpinit.c:288
NTSTATUS NTAPI IoSynchronousInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2491
#define IRP_MN_CANCEL_REMOVE_DEVICE
struct _CM_RESOURCE_LIST * PCM_RESOURCE_LIST
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
LIST_ENTRY IopDeviceActionRequestList
Definition: devaction.c:28
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4050
#define IN
Definition: typedefs.h:39
ULONG Flags
Definition: iotypes.h:836
#define STATUS_PLUGPLAY_NO_DEVICE
Definition: ntstatus.h:717
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:839
NTSTATUS NTAPI IopSynchronousCall(IN PDEVICE_OBJECT DeviceObject, IN PIO_STACK_LOCATION IoStackLocation, OUT PVOID *Information)
Definition: pnpmgr.c:548
static NTSTATUS IopQueryRemoveChildDevices(PDEVICE_NODE ParentDeviceNode, BOOLEAN Force)
Definition: devaction.c:1684
#define IRP_MN_QUERY_RESOURCES
enum _BUS_QUERY_ID_TYPE BUS_QUERY_ID_TYPE
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
static VOID IopCancelRemoveChildDevices(PDEVICE_NODE ParentDeviceNode)
Definition: devaction.c:1575
#define DNF_PROCESSED
Definition: iotypes.h:167
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IRP_MN_QUERY_ID
#define TAG_IO
Definition: tag.h:69
#define PNP_DEVICE_REMOVED
Definition: iotypes.h:969
static NTSTATUS NTAPI IopQueryRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1648
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSTATUS IopTraverseDeviceTree(PDEVICETREE_TRAVERSE_CONTEXT Context)
#define DNUF_NOT_DISABLEABLE
Definition: iotypes.h:204
#define CM_PROB_HELD_FOR_EJECT
Definition: cfg.h:77
NTSTATUS IopInitializePnpServices(IN PDEVICE_NODE DeviceNode)
Definition: devaction.c:2037
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:55
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2057
NTSTATUS IopActionInitChildServices(PDEVICE_NODE DeviceNode, PVOID Context)
Definition: devaction.c:977
NTSTATUS NTAPI IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, IN ULONG CreateOptions, OUT PHANDLE Handle)
Definition: pnpmgr.c:661
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS IopCreateDeviceNode(IN PDEVICE_NODE ParentNode, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PUNICODE_STRING ServiceName, OUT PDEVICE_NODE *DeviceNode)
#define DNF_STOPPED
Definition: iotypes.h:182
static VOID NTAPI IopCancelRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1554
#define DNF_NO_RESOURCE_REQUIRED
Definition: iotypes.h:174
NTSYSAPI NTSTATUS NTAPI ZwQueryDefaultLocale(_In_ BOOLEAN UserProfile, _Out_ PLCID DefaultLocaleId)
NTSTATUS FASTCALL IopLoadServiceModule(IN PUNICODE_STRING ServiceName, OUT PLDR_DATA_TABLE_ENTRY *ModuleObject)
Definition: driver.c:314
#define DNF_HAS_BOOT_CONFIG
Definition: iotypes.h:196
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1173
struct _IO_RESOURCE_REQUIREMENTS_LIST * PIO_RESOURCE_REQUIREMENTS_LIST
#define CM_PROB_FAILED_START
Definition: cfg.h:40
DEVICE_CAPABILITIES
Definition: iotypes.h:930
#define CM_PROB_FAILED_POST_START
Definition: cfg.h:73
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
DWORD LCID
Definition: nls.h:13
#define IRP_MN_EJECT
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1085
static NTSTATUS IopSetServiceEnumData(PDEVICE_NODE DeviceNode)
Definition: devaction.c:1100
#define CM_PROB_FAILED_DRIVER_ENTRY
Definition: cfg.h:67
uint16_t * PWCHAR
Definition: typedefs.h:55
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1155
#define InsertTailList(ListHead, Entry)
_In_ ULONG TotalLength
Definition: usbdlib.h:145
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
struct _DEVICE_NODE * Parent
Definition: iotypes.h:825
NTSTATUS IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode, PVOID Context)
Definition: devaction.c:548
#define PNP_DEVICE_DONT_DISPLAY_IN_UI
Definition: iotypes.h:967
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
#define DNF_RESOURCE_ASSIGNED
Definition: iotypes.h:176
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
static NTSTATUS IopQueryHardwareIds(PDEVICE_NODE DeviceNode, HANDLE InstanceKey)
Definition: devaction.c:403
DWORD Id
uint32_t ULONG_PTR
Definition: typedefs.h:64
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define DNF_START_FAILED
Definition: iotypes.h:169
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
static NTSTATUS IopQueryCompatibleIds(PDEVICE_NODE DeviceNode, HANDLE InstanceKey)
Definition: devaction.c:468
NTSTATUS NTAPI IopCreateRegistryKeyEx(OUT PHANDLE Handle, IN HANDLE BaseHandle OPTIONAL, IN PUNICODE_STRING KeyName, IN ACCESS_MASK DesiredAccess, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define STATUS_DRIVER_UNABLE_TO_LOAD
Definition: ntstatus.h:731
struct _DEVICE_NODE * PDEVICE_NODE
struct _DEVICE_NODE * Child
Definition: iotypes.h:824
KSPIN_LOCK IopDeviceActionLock
Definition: devaction.c:31
#define UNICODE_NULL
#define IRP_MN_QUERY_REMOVE_DEVICE
_Must_inspect_result_ typedef _Out_ PHIDP_CAPS Capabilities
Definition: hidclass.h:103
#define DNUF_DONT_SHOW_IN_UI
Definition: iotypes.h:203
VOID IopQueueDeviceAction(_In_ PDEVICE_ACTION_DATA ActionData)
Definition: devaction.c:2341
VOID NTAPI IoInvalidateDeviceState(IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: devaction.c:1910
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define DNF_WILL_BE_REMOVED
Definition: iotypes.h:183
NTSTATUS NTAPI IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode, PDEVICE_CAPABILITIES DeviceCaps)
Definition: devaction.c:300
_Must_inspect_result_ _In_opt_ PVOID _In_opt_ PVOID InstanceId
Definition: fsrtlfuncs.h:907
static NTSTATUS IopCreateDeviceInstancePath(_In_ PDEVICE_NODE DeviceNode, _Out_ PUNICODE_STRING InstancePath)
Definition: devaction.c:153
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
#define IopDeviceNodeSetFlag(DeviceNode, Flag)
Definition: io.h:142
VOID NTAPI IopInstallCriticalDevice(PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:45
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define DO_BUS_ENUMERATED_DEVICE
static NTSTATUS NTAPI IopQueryStopDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1416
struct _PNP_BUS_INFORMATION * PPNP_BUS_INFORMATION
#define _Out_
Definition: no_sal2.h:323
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
#define DeviceCapabilities
Definition: wingdi.h:4448
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS FASTCALL IopInitializeDevice(IN PDEVICE_NODE DeviceNode, IN PDRIVER_OBJECT DriverObject)
return Found
Definition: dirsup.c:1270
static const WCHAR ClassGUID[]
Definition: devclass.c:30
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 DNF_STARTED
Definition: iotypes.h:168
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define IRP_MN_QUERY_STOP_DEVICE
static VOID NTAPI IopSendRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1471
BOOLEAN PnpSystemInit
Definition: iomgr.c:17
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
_Must_inspect_result_ _In_ PDEVICE_DESCRIPTION DeviceDescription
Definition: iofuncs.h:1015
NTSTATUS IopQueueTargetDeviceEvent(const GUID *Guid, PUNICODE_STRING DeviceIds)
Definition: plugplay.c:46
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
static BOOLEAN IopValidateID(_In_ PWCHAR Id, _In_ BUS_QUERY_ID_TYPE QueryType)
Definition: devaction.c:62
#define PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED
Definition: iotypes.h:970
#define IRP_MN_STOP_DEVICE
USHORT NTAPI IopGetBusTypeGuidIndex(LPGUID BusTypeGuid)
Definition: pnpmgr.c:480
NTSTATUS IopGetParentIdPrefix(PDEVICE_NODE DeviceNode, PUNICODE_STRING ParentIdPrefix)
Definition: pnpmgr.c:899
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance)
Definition: plugplay.c:125
#define STATUS_PENDING
Definition: ntstatus.h:82
#define CM_PROB_DISABLED_SERVICE
Definition: cfg.h:62
static VOID NTAPI IopSendStopDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1431
#define ENUM_ROOT
Definition: io.h:53
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define IRP_MN_START_DEVICE
#define PNP_DEVICE_NOT_DISABLEABLE
Definition: iotypes.h:971
#define DNF_NEED_ENUMERATION_ONLY
Definition: iotypes.h:194
NTSTATUS FASTCALL IopGetDriverObject(OUT PDRIVER_OBJECT *DriverObject, IN PUNICODE_STRING ServiceName, IN BOOLEAN FileSystem)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define IRP_MN_QUERY_DEVICE_TEXT
static VOID IopSendRemoveChildDevices(PDEVICE_NODE ParentDeviceNode)
Definition: devaction.c:1514
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
_Must_inspect_result_ _In_ KTMOBJECT_TYPE QueryType
Definition: nttmapi.h:404
Definition: Node.h:9
static VOID NTAPI IopStartDevice2(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1242
static VOID NTAPI IopSendSurpriseRemoval(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1538
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
WORK_QUEUE_ITEM IopDeviceActionWorkItem
Definition: devaction.c:29
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IRP_MN_QUERY_BUS_INFORMATION
#define MAX_DEVICE_ID_LEN
Definition: devaction.c:22
VOID IopNotifyPlugPlayNotification(IN PDEVICE_OBJECT DeviceObject, IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory, IN LPCGUID Event, IN PVOID EventCategoryData1, IN PVOID EventCategoryData2)
Definition: pnpnotify.c:36
static const WCHAR L[]
Definition: oid.c:1250
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define CM_PROB_DRIVER_FAILED_LOAD
Definition: cfg.h:69
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define DNF_LEGACY_DRIVER
Definition: iotypes.h:181
Definition: btrfs_drv.h:1922
static NTSTATUS IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
_In_ PNDIS_STRING DeviceInstance
Definition: ndis.h:5202
#define DNF_DISABLED
Definition: iotypes.h:188
Definition: typedefs.h:118
#define PNP_DEVICE_FAILED
Definition: iotypes.h:968
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
VOID NTAPI IoRequestDeviceEject(IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: devaction.c:2218
#define IopDeviceNodeHasFlag(DeviceNode, Flag)
Definition: io.h:160
#define MAX_SEPARATORS_INSTANCEID
Definition: devaction.c:23
* PDEVICE_CAPABILITIES
Definition: iotypes.h:930
Status
Definition: gdiplustypes.h:24
#define MAXULONG
Definition: typedefs.h:250
static NTSTATUS NTAPI IopStartAndEnumerateDevice(IN PDEVICE_NODE DeviceNode)
Definition: devaction.c:1302
#define _In_
Definition: no_sal2.h:204
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
static VOID IopSendRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations)
Definition: devaction.c:1497
KSPIN_LOCK IopDeviceTreeLock
Definition: devnode.c:19
static NTSTATUS NTAPI IopSendEject(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:2201
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1737
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1586
static VOID IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1616
static NTSTATUS IopQueryRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations, BOOLEAN Force)
Definition: devaction.c:1737
unsigned short USHORT
Definition: pedump.c:61
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:29
static VOID ErrorExit(LPTSTR lpszMessage)
Definition: telnetd.c:647
NTSTATUS FASTCALL IopInitializeDriverModule(IN PDEVICE_NODE DeviceNode, IN PLDR_DATA_TABLE_ENTRY ModuleObject, IN PUNICODE_STRING ServiceName, IN BOOLEAN FileSystemDriver, OUT PDRIVER_OBJECT *DriverObject)
Definition: driver.c:467
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
UNICODE_STRING ServiceName
Definition: iotypes.h:843
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define IRP_MN_QUERY_DEVICE_RELATIONS
struct _DEVICE_NODE * Sibling
Definition: iotypes.h:823
NTSTATUS IopStartDevice(PDEVICE_NODE DeviceNode)
Definition: devaction.c:1355
static VOID IopCancelRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations)
Definition: devaction.c:1598
NTSTATUS IopStopDevice(PDEVICE_NODE DeviceNode)
Definition: devaction.c:1445
#define CM_PROB_FAILED_INSTALL
Definition: cfg.h:58
#define DPRINT1
Definition: precomp.h:8
NTSTATUS IopActionConfigureChildServices(PDEVICE_NODE DeviceNode, PVOID Context)
Definition: devaction.c:832
NTSTATUS IopRemoveDevice(PDEVICE_NODE DeviceNode)
Definition: devaction.c:1887
NTSTATUS IopEnumerateDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:2054
ERESOURCE IopDriverLoadResource
Definition: driver.c:19
#define ObReferenceObject
Definition: obfuncs.h:204
NTSTATUS NTAPI IopAssignDeviceResources(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:1105
#define IopInitDeviceTreeTraverseContext( _DeviceTreeTraverseContext, _DeviceNode, _Action, _Context)
Definition: io.h:225
BOOLEAN IopDeviceActionInProgress
Definition: devaction.c:30
struct tagContext Context
Definition: acpixf.h:1034
ULONG ERESOURCE
Definition: env_spec_w32.h:594
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE ACPI_HANDLE Child
Definition: acpixf.h:728
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
char * cleanup(char *str)
Definition: wpickclick.c:99
#define DNF_ENUMERATED
Definition: iotypes.h:170
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2774
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
static VOID IopHandleDeviceRemoval(IN PDEVICE_NODE DeviceNode, IN PDEVICE_RELATIONS DeviceRelations)
Definition: devaction.c:1841
static VOID NTAPI IopDeviceActionWorker(_In_ PVOID Context)
Definition: devaction.c:2304
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define DNF_ADDED
Definition: iotypes.h:179
#define DNF_RESOURCE_REPORTED
Definition: iotypes.h:177
#define REG_DWORD
Definition: sdbapi.c:596
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack)
#define MAX_SEPARATORS_DEVICEID
Definition: devaction.c:24
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
INTERFACE_TYPE LegacyBusType
Definition: cmtypes.h:365
#define IRP_MN_QUERY_PNP_DEVICE_STATE
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define DNF_START_REQUEST_PENDING
Definition: iotypes.h:173
PDEVICE_NODE FASTCALL IopGetDeviceNode(IN PDEVICE_OBJECT DeviceObject)
NTSTATUS IopSetDeviceInstanceData(HANDLE InstanceKey, PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:745
#define IRP_MN_QUERY_CAPABILITIES
#define STATUS_IMAGE_ALREADY_LOADED
Definition: ntstatus.h:492
_Inout_ PVCB _In_ BOOLEAN Force
Definition: cdprocs.h:1415
#define PAGED_CODE()
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22