ReactOS  0.4.15-dev-2765-g10e48fa
devaction.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for devaction.c:

Go to the source code of this file.

Classes

struct  _DEVICE_ACTION_REQUEST
 
struct  _ADD_DEV_DRIVERS_LIST
 
struct  _ATTACH_FILTER_DRIVERS_CONTEXT
 

Macros

#define NDEBUG
 
#define MAX_DEVICE_ID_LEN   200
 
#define MAX_SEPARATORS_INSTANCEID   0
 
#define MAX_SEPARATORS_DEVICEID   1
 
#define TAG_PNP_DEVACTION   'aDpP'
 

Typedefs

typedef struct _DEVICE_ACTION_REQUEST DEVICE_ACTION_REQUEST
 
typedef struct _DEVICE_ACTION_REQUESTPDEVICE_ACTION_REQUEST
 
typedef enum _ADD_DEV_DRIVER_TYPE ADD_DEV_DRIVER_TYPE
 
typedef struct _ADD_DEV_DRIVERS_LIST ADD_DEV_DRIVERS_LIST
 
typedef struct _ADD_DEV_DRIVERS_LISTPADD_DEV_DRIVERS_LIST
 
typedef struct _ATTACH_FILTER_DRIVERS_CONTEXT ATTACH_FILTER_DRIVERS_CONTEXT
 
typedef struct _ATTACH_FILTER_DRIVERS_CONTEXTPATTACH_FILTER_DRIVERS_CONTEXT
 

Enumerations

enum  _ADD_DEV_DRIVER_TYPE {
  LowerFilter, LowerClassFilter, DeviceDriver, UpperFilter,
  UpperClassFilter
}
 

Functions

PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance (PUNICODE_STRING DeviceInstance)
 
NTSTATUS IopGetParentIdPrefix (PDEVICE_NODE DeviceNode, PUNICODE_STRING ParentIdPrefix)
 
USHORT NTAPI IopGetBusTypeGuidIndex (LPGUID BusTypeGuid)
 
NTSTATUS IopSetDeviceInstanceData (HANDLE InstanceKey, PDEVICE_NODE DeviceNode)
 
VOID NTAPI IopInstallCriticalDevice (PDEVICE_NODE DeviceNode)
 
static VOID IopCancelPrepareDeviceForRemoval (PDEVICE_OBJECT DeviceObject)
 
static NTSTATUS IopPrepareDeviceForRemoval (PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
 
static NTSTATUS IopSetServiceEnumData (_In_ PDEVICE_NODE DeviceNode, _In_ HANDLE InstanceHandle)
 
static BOOLEAN IopValidateID (_In_ PWCHAR Id, _In_ BUS_QUERY_ID_TYPE QueryType)
 
static NTSTATUS IopCreateDeviceInstancePath (_In_ PDEVICE_NODE DeviceNode, _Out_ PUNICODE_STRING InstancePath)
 
static NTSTATUS NTAPI PiAttachFilterDriversCallback (PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Ctx, PVOID EntryContext)
 Loads and/or returns the driver associated with the registry entry if the driver is enabled. In case of an error, sets up a corresponding Problem to the DeviceNode. More...
 
static NTSTATUS PiAttachFilterDrivers (PLIST_ENTRY DriversListHead, PDEVICE_NODE DeviceNode, HANDLE EnumSubKey, HANDLE ClassKey, BOOLEAN Lower, BOOLEAN LoadDrivers)
 Calls PiAttachFilterDriversCallback for filter drivers (if any) More...
 
static NTSTATUS PiCallDriverAddDevice (_In_ PDEVICE_NODE DeviceNode, _In_ BOOLEAN LoadDrivers)
 Loads all drivers for a device node (actual service and filters) and calls their AddDevice routine. More...
 
NTSTATUS NTAPI IopQueryDeviceCapabilities (PDEVICE_NODE DeviceNode, PDEVICE_CAPABILITIES DeviceCaps)
 
static NTSTATUS IopQueryHardwareIds (PDEVICE_NODE DeviceNode, HANDLE InstanceKey)
 
static NTSTATUS IopQueryCompatibleIds (PDEVICE_NODE DeviceNode, HANDLE InstanceKey)
 
VOID PiSetDevNodeText (_In_ PDEVICE_NODE DeviceNode, _In_ HANDLE InstanceKey)
 Sets the DeviceNode's DeviceDesc and LocationInformation registry values. More...
 
static NTSTATUS PiInitializeDevNode (_In_ PDEVICE_NODE DeviceNode)
 
static NTSTATUS PiStartDeviceFinal (_In_ PDEVICE_NODE DeviceNode)
 
static NTSTATUS PiIrpSendRemoveCheckVpb (_In_ PDEVICE_OBJECT DeviceObject, _In_ UCHAR MinorFunction)
 Sends one of the remove IRPs to the device stack. More...
 
static VOID NTAPI IopSendRemoveDevice (IN PDEVICE_OBJECT DeviceObject)
 
static VOID IopSendRemoveDeviceRelations (PDEVICE_RELATIONS DeviceRelations)
 
static VOID IopSendRemoveChildDevices (PDEVICE_NODE ParentDeviceNode)
 
static VOID NTAPI IopSendSurpriseRemoval (IN PDEVICE_OBJECT DeviceObject)
 
static VOID NTAPI IopCancelRemoveDevice (IN PDEVICE_OBJECT DeviceObject)
 
static VOID IopCancelRemoveChildDevices (PDEVICE_NODE ParentDeviceNode)
 
static VOID IopCancelRemoveDeviceRelations (PDEVICE_RELATIONS DeviceRelations)
 
static NTSTATUS NTAPI IopQueryRemoveDevice (IN PDEVICE_OBJECT DeviceObject)
 
static NTSTATUS IopQueryRemoveChildDevices (PDEVICE_NODE ParentDeviceNode, BOOLEAN Force)
 
static NTSTATUS IopQueryRemoveDeviceRelations (PDEVICE_RELATIONS DeviceRelations, BOOLEAN Force)
 
static NTSTATUS IopPrepareDeviceForRemoval (IN PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
 
static NTSTATUS IopRemoveDevice (PDEVICE_NODE DeviceNode)
 
VOID NTAPI IoInvalidateDeviceState (IN PDEVICE_OBJECT PhysicalDeviceObject)
 
static NTSTATUS PiEnumerateDevice (_In_ PDEVICE_NODE DeviceNode)
 
static NTSTATUS NTAPI IopSendEject (IN PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI IoRequestDeviceEject (IN PDEVICE_OBJECT PhysicalDeviceObject)
 
static VOID PiDevNodeStateMachine (_In_ PDEVICE_NODE RootNode)
 
static VOID NTAPI PipDeviceActionWorker (_In_opt_ PVOID Context)
 
VOID PiQueueDeviceAction (_In_ PDEVICE_OBJECT DeviceObject, _In_ DEVICE_ACTION Action, _In_opt_ PKEVENT CompletionEvent, _Out_opt_ NTSTATUS *CompletionStatus)
 Queue a device operation to a worker thread. More...
 
NTSTATUS PiPerformSyncDeviceAction (_In_ PDEVICE_OBJECT DeviceObject, _In_ DEVICE_ACTION Action)
 Perfom a device operation synchronously via PiQueueDeviceAction. More...
 

Variables

ERESOURCE IopDriverLoadResource
 
BOOLEAN PnpSystemInit
 
PDEVICE_NODE IopRootDeviceNode
 
BOOLEAN PnPBootDriversLoaded
 
BOOLEAN PnPBootDriversInitialized
 
LIST_ENTRY IopDeviceActionRequestList
 
WORK_QUEUE_ITEM IopDeviceActionWorkItem
 
BOOLEAN IopDeviceActionInProgress
 
KSPIN_LOCK IopDeviceActionLock
 
KEVENT PiEnumerationFinished
 
static const WCHAR ServicesKeyName [] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
 

Macro Definition Documentation

◆ MAX_DEVICE_ID_LEN

#define MAX_DEVICE_ID_LEN   200

Definition at line 40 of file devaction.c.

◆ MAX_SEPARATORS_DEVICEID

#define MAX_SEPARATORS_DEVICEID   1

Definition at line 42 of file devaction.c.

◆ MAX_SEPARATORS_INSTANCEID

#define MAX_SEPARATORS_INSTANCEID   0

Definition at line 41 of file devaction.c.

◆ NDEBUG

#define NDEBUG

Definition at line 29 of file devaction.c.

◆ TAG_PNP_DEVACTION

#define TAG_PNP_DEVACTION   'aDpP'

Definition at line 53 of file devaction.c.

Typedef Documentation

◆ ADD_DEV_DRIVER_TYPE

◆ ADD_DEV_DRIVERS_LIST

◆ ATTACH_FILTER_DRIVERS_CONTEXT

◆ DEVICE_ACTION_REQUEST

◆ PADD_DEV_DRIVERS_LIST

◆ PATTACH_FILTER_DRIVERS_CONTEXT

◆ PDEVICE_ACTION_REQUEST

Enumeration Type Documentation

◆ _ADD_DEV_DRIVER_TYPE

Enumerator
LowerFilter 
LowerClassFilter 
DeviceDriver 
UpperFilter 
UpperClassFilter 

Definition at line 66 of file devaction.c.

Function Documentation

◆ IoInvalidateDeviceState()

VOID NTAPI IoInvalidateDeviceState ( IN PDEVICE_OBJECT  PhysicalDeviceObject)

Definition at line 2014 of file devaction.c.

2015 {
2017  PNP_DEVICE_STATE PnPFlags;
2018  NTSTATUS Status;
2019 
2021  if (!NT_SUCCESS(Status))
2022  {
2024  {
2025  DPRINT1("IRP_MN_QUERY_PNP_DEVICE_STATE failed with status 0x%lx\n", Status);
2026  }
2027  return;
2028  }
2029 
2030  if (PnPFlags & PNP_DEVICE_NOT_DISABLEABLE)
2031  DeviceNode->UserFlags |= DNUF_NOT_DISABLEABLE;
2032  else
2033  DeviceNode->UserFlags &= ~DNUF_NOT_DISABLEABLE;
2034 
2035  if (PnPFlags & PNP_DEVICE_DONT_DISPLAY_IN_UI)
2036  DeviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI;
2037  else
2038  DeviceNode->UserFlags &= ~DNUF_DONT_SHOW_IN_UI;
2039 
2040  if ((PnPFlags & PNP_DEVICE_REMOVED) ||
2041  ((PnPFlags & PNP_DEVICE_FAILED) && !(PnPFlags & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED)))
2042  {
2043  /* Flag it if it's failed */
2044  if (PnPFlags & PNP_DEVICE_FAILED)
2045  {
2047  }
2048 
2049  DeviceNode->Flags |= DNF_DEVICE_GONE;
2051  }
2052  // it doesn't work anyway. A real resource rebalancing should be implemented
2053 #if 0
2054  else if ((PnPFlags & PNP_DEVICE_FAILED) && (PnPFlags & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED))
2055  {
2056  /* Stop for resource rebalance */
2057  Status = IopStopDevice(DeviceNode);
2058  if (!NT_SUCCESS(Status))
2059  {
2060  DPRINT1("Failed to stop device for rebalancing\n");
2061 
2062  /* Stop failed so don't rebalance */
2064  }
2065  }
2066 
2067  /* Resource rebalance */
2069  {
2070  DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n");
2071 
2073  &IoStatusBlock,
2075  NULL);
2077  {
2078  DeviceNode->BootResources =
2081  }
2082  else
2083  {
2084  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
2085  DeviceNode->BootResources = NULL;
2086  }
2087 
2088  DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n");
2089 
2091  &IoStatusBlock,
2093  NULL);
2094  if (NT_SUCCESS(Status))
2095  {
2096  DeviceNode->ResourceRequirements =
2098  }
2099  else
2100  {
2101  DPRINT("IopInitiatePnpIrp() failed (Status %08lx)\n", Status);
2102  DeviceNode->ResourceRequirements = NULL;
2103  }
2104 
2105  /* IRP_MN_FILTER_RESOURCE_REQUIREMENTS is called indirectly by IopStartDevice */
2106  if (IopStartDevice(DeviceNode) != STATUS_SUCCESS)
2107  {
2108  DPRINT1("Restart after resource rebalance failed\n");
2109 
2110  DeviceNode->Flags &= ~(DNF_STARTED | DNF_START_REQUEST_PENDING);
2111  DeviceNode->Flags |= DNF_START_FAILED;
2112 
2114  }
2115  }
2116 #endif
2117 }
struct _CM_RESOURCE_LIST * PCM_RESOURCE_LIST
return STATUS_NOT_SUPPORTED
#define IRP_MN_QUERY_RESOURCES
#define PNP_DEVICE_REMOVED
Definition: iotypes.h:1004
PNP_DEVNODE_STATE PiSetDevNodeState(_In_ PDEVICE_NODE DeviceNode, _In_ PNP_DEVNODE_STATE NewState)
Definition: devnode.c:108
#define DNUF_NOT_DISABLEABLE
Definition: iotypes.h:211
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS
LONG NTSTATUS
Definition: precomp.h:26
ULONG PNP_DEVICE_STATE
Definition: iotypes.h:997
#define DNF_HAS_BOOT_CONFIG
Definition: iotypes.h:176
struct _IO_RESOURCE_REQUIREMENTS_LIST * PIO_RESOURCE_REQUIREMENTS_LIST
#define CM_PROB_FAILED_POST_START
Definition: cfg.h:73
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1155
#define PNP_DEVICE_DONT_DISPLAY_IN_UI
Definition: iotypes.h:1002
static NTSTATUS IopRemoveDevice(PDEVICE_NODE DeviceNode)
Definition: devaction.c:1975
#define DNUF_DONT_SHOW_IN_UI
Definition: iotypes.h:209
#define IopDeviceNodeSetFlag(DeviceNode, Flag)
Definition: io.h:142
Status
Definition: gdiplustypes.h:24
VOID PiSetDevNodeProblem(_In_ PDEVICE_NODE DeviceNode, _In_ UINT32 Problem)
Definition: devnode.c:132
#define PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED
Definition: iotypes.h:1005
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define PNP_DEVICE_NOT_DISABLEABLE
Definition: iotypes.h:1006
Definition: Node.h:9
#define DNF_DEVICE_GONE
Definition: iotypes.h:186
#define PNP_DEVICE_FAILED
Definition: iotypes.h:1003
NTSTATUS PiIrpQueryPnPDeviceState(_In_ PDEVICE_NODE DeviceNode, _Out_ PPNP_DEVICE_STATE DeviceState)
Definition: pnpirp.c:232
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack)
PDEVICE_NODE FASTCALL IopGetDeviceNode(IN PDEVICE_OBJECT DeviceObject)

Referenced by HidUsb_ResetWorkerRoutine(), MxDeviceObject::InvalidateDeviceState(), IsaPdoQueryDeviceUsageNotification(), IsaPdoStartReadPort(), and PiStartDeviceFinal().

◆ IopCancelPrepareDeviceForRemoval()

static VOID IopCancelPrepareDeviceForRemoval ( PDEVICE_OBJECT  DeviceObject)
static

Definition at line 1759 of file devaction.c.

1760 {
1763  PDEVICE_RELATIONS DeviceRelations;
1764  NTSTATUS Status;
1765 
1767 
1768  Stack.Parameters.QueryDeviceRelations.Type = RemovalRelations;
1769 
1771  &IoStatusBlock,
1773  &Stack);
1774  if (!NT_SUCCESS(Status))
1775  {
1776  DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
1777  DeviceRelations = NULL;
1778  }
1779  else
1780  {
1781  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
1782  }
1783 
1784  if (DeviceRelations)
1785  IopCancelRemoveDeviceRelations(DeviceRelations);
1786 }
LONG NTSTATUS
Definition: precomp.h:26
static VOID NTAPI IopCancelRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1708
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define IRP_MN_QUERY_DEVICE_RELATIONS
static VOID IopCancelRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations)
Definition: devaction.c:1741
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack)

Referenced by IopCancelRemoveChildDevices(), IopCancelRemoveDeviceRelations(), IopQueryRemoveChildDevices(), and IopQueryRemoveDeviceRelations().

◆ IopCancelRemoveChildDevices()

static VOID IopCancelRemoveChildDevices ( PDEVICE_NODE  ParentDeviceNode)
static

Definition at line 1718 of file devaction.c.

1719 {
1720  PDEVICE_NODE ChildDeviceNode, NextDeviceNode;
1721  KIRQL OldIrql;
1722 
1724  ChildDeviceNode = ParentDeviceNode->Child;
1725  while (ChildDeviceNode != NULL)
1726  {
1727  NextDeviceNode = ChildDeviceNode->Sibling;
1729 
1731 
1732  ChildDeviceNode = NextDeviceNode;
1733 
1735  }
1737 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:850
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _DEVICE_NODE * Child
Definition: iotypes.h:835
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
KSPIN_LOCK IopDeviceTreeLock
Definition: devnode.c:19
static VOID IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1759
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
struct _DEVICE_NODE * Sibling
Definition: iotypes.h:834

Referenced by IoRequestDeviceEject().

◆ IopCancelRemoveDevice()

static VOID NTAPI IopCancelRemoveDevice ( IN PDEVICE_OBJECT  DeviceObject)
static

Definition at line 1708 of file devaction.c.

1709 {
1710  /* Drivers should never fail a IRP_MN_CANCEL_REMOVE_DEVICE request */
1712 
1713  PiNotifyTargetDeviceChange(&GUID_TARGET_DEVICE_REMOVE_CANCELLED, DeviceObject, NULL);
1714 }
#define IRP_MN_CANCEL_REMOVE_DEVICE
static NTSTATUS PiIrpSendRemoveCheckVpb(_In_ PDEVICE_OBJECT DeviceObject, _In_ UCHAR MinorFunction)
Sends one of the remove IRPs to the device stack.
Definition: devaction.c:1574
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define NULL
Definition: types.h:112
VOID PiNotifyTargetDeviceChange(_In_ LPCGUID Event, _In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PTARGET_DEVICE_CUSTOM_NOTIFICATION CustomNotification)
Delivers the event to all drivers subscribed to EventCategoryTargetDeviceChange PnP event.
Definition: pnpnotify.c:258

Referenced by IopCancelPrepareDeviceForRemoval(), and IopPrepareDeviceForRemoval().

◆ IopCancelRemoveDeviceRelations()

static VOID IopCancelRemoveDeviceRelations ( PDEVICE_RELATIONS  DeviceRelations)
static

Definition at line 1741 of file devaction.c.

1742 {
1743  /* This function DOES dereference the device objects in all cases */
1744 
1745  ULONG i;
1746 
1747  for (i = 0; i < DeviceRelations->Count; i++)
1748  {
1749  IopCancelPrepareDeviceForRemoval(DeviceRelations->Objects[i]);
1750  ObDereferenceObject(DeviceRelations->Objects[i]);
1751  DeviceRelations->Objects[i] = NULL;
1752  }
1753 
1754  ExFreePool(DeviceRelations);
1755 }
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
#define ObDereferenceObject
Definition: obfuncs.h:203
static VOID IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1759
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
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by IopCancelPrepareDeviceForRemoval(), IopPrepareDeviceForRemoval(), and IoRequestDeviceEject().

◆ IopCreateDeviceInstancePath()

static NTSTATUS IopCreateDeviceInstancePath ( _In_ PDEVICE_NODE  DeviceNode,
_Out_ PUNICODE_STRING  InstancePath 
)
static

Definition at line 215 of file devaction.c.

218 {
220  UNICODE_STRING DeviceId;
224  UNICODE_STRING ParentIdPrefix = { 0, 0, NULL };
226  BOOLEAN IsValidID;
227 
228  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryDeviceID to device stack\n");
229 
230  Stack.Parameters.QueryId.IdType = BusQueryDeviceID;
231  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
232  &IoStatusBlock,
234  &Stack);
235  if (!NT_SUCCESS(Status))
236  {
237  DPRINT1("IopInitiatePnpIrp(BusQueryDeviceID) failed (Status %x)\n", Status);
238  return Status;
239  }
240 
242 
243  if (!IsValidID)
244  {
245  DPRINT1("Invalid DeviceID. DeviceNode - %p\n", DeviceNode);
246  }
247 
248  /* Save the device id string */
250 
251  DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack (after enumeration)\n");
252 
254  if (!NT_SUCCESS(Status))
255  {
256  DPRINT1("IopQueryDeviceCapabilities() failed (Status 0x%08lx)\n", Status);
257  RtlFreeUnicodeString(&DeviceId);
258  return Status;
259  }
260 
261  /* This bit is only check after enumeration */
262  if (DeviceCapabilities.HardwareDisabled)
263  {
264  /* FIXME: Cleanup device */
265  RtlFreeUnicodeString(&DeviceId);
267  }
268 
269  if (!DeviceCapabilities.UniqueID)
270  {
271  /* Device has not a unique ID. We need to prepend parent bus unique identifier */
272  DPRINT("Instance ID is not unique\n");
273  Status = IopGetParentIdPrefix(DeviceNode, &ParentIdPrefix);
274  if (!NT_SUCCESS(Status))
275  {
276  DPRINT1("IopGetParentIdPrefix() failed (Status 0x%08lx)\n", Status);
277  RtlFreeUnicodeString(&DeviceId);
278  return Status;
279  }
280  }
281 
282  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryInstanceID to device stack\n");
283 
284  Stack.Parameters.QueryId.IdType = BusQueryInstanceID;
285  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
286  &IoStatusBlock,
288  &Stack);
289  if (!NT_SUCCESS(Status))
290  {
291  DPRINT("IopInitiatePnpIrp(BusQueryInstanceID) failed (Status %lx)\n", Status);
293  }
294 
296  {
298 
299  if (!IsValidID)
300  {
301  DPRINT1("Invalid InstanceID. DeviceNode - %p\n", DeviceNode);
302  }
303  }
304 
307 
308  InstancePath->Length = 0;
309  InstancePath->MaximumLength = DeviceId.Length + sizeof(WCHAR) +
310  ParentIdPrefix.Length +
311  InstanceId.Length +
312  sizeof(UNICODE_NULL);
313  if (ParentIdPrefix.Length && InstanceId.Length)
314  {
315  InstancePath->MaximumLength += sizeof(WCHAR);
316  }
317 
318  InstancePath->Buffer = ExAllocatePoolWithTag(PagedPool,
319  InstancePath->MaximumLength,
320  TAG_IO);
321  if (!InstancePath->Buffer)
322  {
324  RtlFreeUnicodeString(&ParentIdPrefix);
325  RtlFreeUnicodeString(&DeviceId);
327  }
328 
329  /* Start with the device id */
330  RtlCopyUnicodeString(InstancePath, &DeviceId);
331  RtlAppendUnicodeToString(InstancePath, L"\\");
332 
333  /* Add information from parent bus device to InstancePath */
334  RtlAppendUnicodeStringToString(InstancePath, &ParentIdPrefix);
335  if (ParentIdPrefix.Length && InstanceId.Length)
336  {
337  RtlAppendUnicodeToString(InstancePath, L"&");
338  }
339 
340  /* Finally, add the id returned by the driver stack */
342 
343  /*
344  * FIXME: Check for valid characters, if there is invalid characters
345  * then bugcheck
346  */
347 
349  RtlFreeUnicodeString(&DeviceId);
350  RtlFreeUnicodeString(&ParentIdPrefix);
351 
352  return STATUS_SUCCESS;
353 }
#define STATUS_PLUGPLAY_NO_DEVICE
Definition: ntstatus.h:731
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IRP_MN_QUERY_ID
#define TAG_IO
Definition: tag.h:69
uint16_t * PWSTR
Definition: typedefs.h:56
LONG NTSTATUS
Definition: precomp.h:26
DEVICE_CAPABILITIES
Definition: iotypes.h:965
uint16_t * PWCHAR
Definition: typedefs.h:56
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
#define UNICODE_NULL
NTSTATUS NTAPI IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode, PDEVICE_CAPABILITIES DeviceCaps)
Definition: devaction.c:853
_Must_inspect_result_ _In_opt_ PVOID _In_opt_ PVOID InstanceId
Definition: fsrtlfuncs.h:907
unsigned char BOOLEAN
#define DeviceCapabilities
Definition: wingdi.h:4448
Status
Definition: gdiplustypes.h:24
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
static BOOLEAN IopValidateID(_In_ PWCHAR Id, _In_ BUS_QUERY_ID_TYPE QueryType)
Definition: devaction.c:124
#define ASSERT(a)
Definition: mode.c:44
NTSTATUS IopGetParentIdPrefix(PDEVICE_NODE DeviceNode, PUNICODE_STRING ParentIdPrefix)
Definition: pnpmgr.c:761
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
Definition: Node.h:9
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack)

Referenced by PiInitializeDevNode().

◆ IopGetBusTypeGuidIndex()

USHORT NTAPI IopGetBusTypeGuidIndex ( LPGUID  BusTypeGuid)

Definition at line 412 of file pnpmgr.c.

413 {
414  USHORT i = 0, FoundIndex = 0xFFFF;
415  ULONG NewSize;
416  PVOID NewList;
417 
418  /* Acquire the lock */
420 
421  /* Loop all entries */
422  while (i < PnpBusTypeGuidList->GuidCount)
423  {
424  /* Try to find a match */
425  if (RtlCompareMemory(BusTypeGuid,
427  sizeof(GUID)) == sizeof(GUID))
428  {
429  /* Found it */
430  FoundIndex = i;
431  goto Quickie;
432  }
433  i++;
434  }
435 
436  /* Check if we have to grow the list */
438  {
439  /* Calculate the new size */
440  NewSize = sizeof(IO_BUS_TYPE_GUID_LIST) +
441  (sizeof(GUID) * PnpBusTypeGuidList->GuidCount);
442 
443  /* Allocate the new copy */
444  NewList = ExAllocatePool(PagedPool, NewSize);
445 
446  if (!NewList)
447  {
448  /* Fail */
450  goto Quickie;
451  }
452 
453  /* Now copy them, decrease the size too */
454  NewSize -= sizeof(GUID);
456 
457  /* Free the old list */
459 
460  /* Use the new buffer */
461  PnpBusTypeGuidList = NewList;
462  }
463 
464  /* Copy the new GUID */
466  BusTypeGuid,
467  sizeof(GUID));
468 
469  /* The new entry is the index */
470  FoundIndex = (USHORT)PnpBusTypeGuidList->GuidCount;
472 
473 Quickie:
475  return FoundIndex;
476 }
GUID Guids[1]
Definition: io.h:428
PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList
Definition: pnpmgr.c:28
FAST_MUTEX Lock
Definition: io.h:427
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
struct _IO_BUS_TYPE_GUID_LIST IO_BUS_TYPE_GUID_LIST
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
struct _GUID GUID
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
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
unsigned short USHORT
Definition: pedump.c:61
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by PiInitializeDevNode().

◆ IopGetDeviceObjectFromDeviceInstance()

PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance ( PUNICODE_STRING  DeviceInstance)

Definition at line 121 of file plugplay.c.

122 {
123  if (IopRootDeviceNode == NULL)
124  return NULL;
125 
126  if (DeviceInstance == NULL ||
127  DeviceInstance->Length == 0)
128  {
130  {
133  }
134  else
135  return NULL;
136  }
137 
139 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:850
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
static PDEVICE_OBJECT IopTraverseDeviceNode(PDEVICE_NODE Node, PUNICODE_STRING DeviceInstance)
Definition: plugplay.c:92
_In_ PNDIS_STRING DeviceInstance
Definition: ndis.h:5202
#define NULL
Definition: types.h:112
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by IopDeviceStatus(), IopGetDeviceDepth(), IopGetDeviceProperty(), IopGetDeviceRelations(), IopGetInterfaceDeviceList(), IopGetRelatedDevice(), PiControlSyncDeviceAction(), and PiInitializeDevNode().

◆ IopGetParentIdPrefix()

NTSTATUS IopGetParentIdPrefix ( PDEVICE_NODE  DeviceNode,
PUNICODE_STRING  ParentIdPrefix 
)

Definition at line 761 of file pnpmgr.c.

763 {
764  const UNICODE_STRING EnumKeyPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
765  ULONG KeyNameBufferLength;
766  PKEY_VALUE_PARTIAL_INFORMATION ParentIdPrefixInformation = NULL;
767  UNICODE_STRING KeyName = {0, 0, NULL};
768  UNICODE_STRING KeyValue;
770  HANDLE hKey = NULL;
771  ULONG crc32;
773 
774  /* HACK: As long as some devices have a NULL device
775  * instance path, the following test is required :(
776  */
777  if (DeviceNode->Parent->InstancePath.Length == 0)
778  {
779  DPRINT1("Parent of %wZ has NULL Instance path, please report!\n",
780  &DeviceNode->InstancePath);
781  return STATUS_UNSUCCESSFUL;
782  }
783 
784  /* 1. Try to retrieve ParentIdPrefix from registry */
785  KeyNameBufferLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + sizeof(L"12345678&12345678");
786  ParentIdPrefixInformation = ExAllocatePoolWithTag(PagedPool,
787  KeyNameBufferLength + sizeof(UNICODE_NULL),
788  TAG_IO);
789  if (!ParentIdPrefixInformation)
790  {
792  }
793 
794  KeyName.Length = 0;
795  KeyName.MaximumLength = EnumKeyPath.Length +
796  DeviceNode->Parent->InstancePath.Length +
797  sizeof(UNICODE_NULL);
799  KeyName.MaximumLength,
800  TAG_IO);
801  if (!KeyName.Buffer)
802  {
804  goto cleanup;
805  }
806 
807  RtlCopyUnicodeString(&KeyName, &EnumKeyPath);
808  RtlAppendUnicodeStringToString(&KeyName, &DeviceNode->Parent->InstancePath);
809 
811  if (!NT_SUCCESS(Status))
812  {
813  goto cleanup;
814  }
815  RtlInitUnicodeString(&ValueName, L"ParentIdPrefix");
816  Status = ZwQueryValueKey(hKey,
817  &ValueName,
819  ParentIdPrefixInformation,
820  KeyNameBufferLength,
821  &KeyNameBufferLength);
822  if (NT_SUCCESS(Status))
823  {
824  if (ParentIdPrefixInformation->Type != REG_SZ)
825  {
827  }
828  else
829  {
830  KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
831  KeyValue.Length = KeyValue.MaximumLength - sizeof(UNICODE_NULL);
832  KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
833  ASSERT(KeyValue.Buffer[KeyValue.Length / sizeof(WCHAR)] == UNICODE_NULL);
834  }
835  goto cleanup;
836  }
838  {
839  /* FIXME how do we get here and why is ParentIdPrefixInformation valid? */
840  KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
841  KeyValue.Length = KeyValue.MaximumLength - sizeof(UNICODE_NULL);
842  KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
843  ASSERT(KeyValue.Buffer[KeyValue.Length / sizeof(WCHAR)] == UNICODE_NULL);
844  goto cleanup;
845  }
846 
847  /* 2. Create the ParentIdPrefix value */
849  (PUCHAR)DeviceNode->Parent->InstancePath.Buffer,
850  DeviceNode->Parent->InstancePath.Length);
851 
852  RtlStringCbPrintfW((PWSTR)ParentIdPrefixInformation,
853  KeyNameBufferLength,
854  L"%lx&%lx",
855  DeviceNode->Parent->Level,
856  crc32);
857  RtlInitUnicodeString(&KeyValue, (PWSTR)ParentIdPrefixInformation);
858 
859  /* 3. Try to write the ParentIdPrefix to registry */
860  Status = ZwSetValueKey(hKey,
861  &ValueName,
862  0,
863  REG_SZ,
864  KeyValue.Buffer,
865  ((ULONG)wcslen(KeyValue.Buffer) + 1) * sizeof(WCHAR));
866 
867 cleanup:
868  if (NT_SUCCESS(Status))
869  {
870  /* Duplicate the string to return it */
872  &KeyValue,
873  ParentIdPrefix);
874  }
875  ExFreePoolWithTag(ParentIdPrefixInformation, TAG_IO);
877  if (hKey != NULL)
878  {
879  ZwClose(hKey);
880  }
881  return Status;
882 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
#define KEY_SET_VALUE
Definition: nt_native.h:1017
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1456
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define UNICODE_NULL
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
Definition: Node.h:9
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
static const WCHAR L[]
Definition: oid.c:1250
#define RtlComputeCrc32
Definition: compat.h:669
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
unsigned short USHORT
Definition: pedump.c:61
FxAutoRegKey hKey
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NULL
Definition: types.h:112
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
#define crc32(crc, buf, len)
Definition: inflate.c:1081
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
char * cleanup(char *str)
Definition: wpickclick.c:99
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22

Referenced by IopCreateDeviceInstancePath().

◆ IopInstallCriticalDevice()

VOID NTAPI IopInstallCriticalDevice ( PDEVICE_NODE  DeviceNode)

Definition at line 46 of file pnpmgr.c.

47 {
49  HANDLE CriticalDeviceKey, InstanceKey;
51  UNICODE_STRING CriticalDeviceKeyU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\CriticalDeviceDatabase");
52  UNICODE_STRING CompatibleIdU = RTL_CONSTANT_STRING(L"CompatibleIDs");
53  UNICODE_STRING HardwareIdU = RTL_CONSTANT_STRING(L"HardwareID");
54  UNICODE_STRING ServiceU = RTL_CONSTANT_STRING(L"Service");
55  UNICODE_STRING ClassGuidU = RTL_CONSTANT_STRING(L"ClassGUID");
57  ULONG HidLength = 0, CidLength = 0, BufferLength;
58  PWCHAR IdBuffer, OriginalIdBuffer;
59 
60  /* Open the device instance key */
61  Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
62  if (Status != STATUS_SUCCESS)
63  return;
64 
65  Status = ZwQueryValueKey(InstanceKey,
66  &HardwareIdU,
68  NULL,
69  0,
70  &HidLength);
72  {
73  ZwClose(InstanceKey);
74  return;
75  }
76 
77  Status = ZwQueryValueKey(InstanceKey,
78  &CompatibleIdU,
80  NULL,
81  0,
82  &CidLength);
84  {
85  CidLength = 0;
86  }
87 
88  BufferLength = HidLength + CidLength;
89  BufferLength -= (((CidLength != 0) ? 2 : 1) * FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data));
90 
91  /* Allocate a buffer to hold data from both */
92  OriginalIdBuffer = IdBuffer = ExAllocatePool(PagedPool, BufferLength);
93  if (!IdBuffer)
94  {
95  ZwClose(InstanceKey);
96  return;
97  }
98 
99  /* Compute the buffer size */
100  if (HidLength > CidLength)
101  BufferLength = HidLength;
102  else
103  BufferLength = CidLength;
104 
105  PartialInfo = ExAllocatePool(PagedPool, BufferLength);
106  if (!PartialInfo)
107  {
108  ZwClose(InstanceKey);
109  ExFreePool(OriginalIdBuffer);
110  return;
111  }
112 
113  Status = ZwQueryValueKey(InstanceKey,
114  &HardwareIdU,
116  PartialInfo,
117  HidLength,
118  &HidLength);
119  if (Status != STATUS_SUCCESS)
120  {
121  ExFreePool(PartialInfo);
122  ExFreePool(OriginalIdBuffer);
123  ZwClose(InstanceKey);
124  return;
125  }
126 
127  /* Copy in HID info first (without 2nd terminating NULL if CID is present) */
128  HidLength = PartialInfo->DataLength - ((CidLength != 0) ? sizeof(WCHAR) : 0);
129  RtlCopyMemory(IdBuffer, PartialInfo->Data, HidLength);
130 
131  if (CidLength != 0)
132  {
133  Status = ZwQueryValueKey(InstanceKey,
134  &CompatibleIdU,
136  PartialInfo,
137  CidLength,
138  &CidLength);
139  if (Status != STATUS_SUCCESS)
140  {
141  ExFreePool(PartialInfo);
142  ExFreePool(OriginalIdBuffer);
143  ZwClose(InstanceKey);
144  return;
145  }
146 
147  /* Copy CID next */
148  CidLength = PartialInfo->DataLength;
149  RtlCopyMemory(((PUCHAR)IdBuffer) + HidLength, PartialInfo->Data, CidLength);
150  }
151 
152  /* Free our temp buffer */
153  ExFreePool(PartialInfo);
154 
156  &CriticalDeviceKeyU,
158  NULL,
159  NULL);
160  Status = ZwOpenKey(&CriticalDeviceKey,
163  if (!NT_SUCCESS(Status))
164  {
165  /* The critical device database doesn't exist because
166  * we're probably in 1st stage setup, but it's ok */
167  ExFreePool(OriginalIdBuffer);
168  ZwClose(InstanceKey);
169  return;
170  }
171 
172  while (*IdBuffer)
173  {
174  USHORT StringLength = (USHORT)wcslen(IdBuffer) + 1, Index;
175 
176  IopFixupDeviceId(IdBuffer);
177 
178  /* Look through all subkeys for a match */
179  for (Index = 0; TRUE; Index++)
180  {
181  ULONG NeededLength;
182  PKEY_BASIC_INFORMATION BasicInfo;
183 
184  Status = ZwEnumerateKey(CriticalDeviceKey,
185  Index,
187  NULL,
188  0,
189  &NeededLength);
191  break;
193  {
194  UNICODE_STRING ChildIdNameU, RegKeyNameU;
195 
196  BasicInfo = ExAllocatePool(PagedPool, NeededLength);
197  if (!BasicInfo)
198  {
199  /* No memory */
200  ExFreePool(OriginalIdBuffer);
201  ZwClose(CriticalDeviceKey);
202  ZwClose(InstanceKey);
203  return;
204  }
205 
206  Status = ZwEnumerateKey(CriticalDeviceKey,
207  Index,
209  BasicInfo,
210  NeededLength,
211  &NeededLength);
212  if (Status != STATUS_SUCCESS)
213  {
214  /* This shouldn't happen */
215  ExFreePool(BasicInfo);
216  continue;
217  }
218 
219  ChildIdNameU.Buffer = IdBuffer;
220  ChildIdNameU.MaximumLength = ChildIdNameU.Length = (StringLength - 1) * sizeof(WCHAR);
221  RegKeyNameU.Buffer = BasicInfo->Name;
222  RegKeyNameU.MaximumLength = RegKeyNameU.Length = (USHORT)BasicInfo->NameLength;
223 
224  if (RtlEqualUnicodeString(&ChildIdNameU, &RegKeyNameU, TRUE))
225  {
226  HANDLE ChildKeyHandle;
227 
229  &ChildIdNameU,
231  CriticalDeviceKey,
232  NULL);
233 
234  Status = ZwOpenKey(&ChildKeyHandle,
237  if (Status != STATUS_SUCCESS)
238  {
239  ExFreePool(BasicInfo);
240  continue;
241  }
242 
243  /* Check if there's already a driver installed */
244  Status = ZwQueryValueKey(InstanceKey,
245  &ClassGuidU,
247  NULL,
248  0,
249  &NeededLength);
251  {
252  ExFreePool(BasicInfo);
253  continue;
254  }
255 
256  Status = ZwQueryValueKey(ChildKeyHandle,
257  &ClassGuidU,
259  NULL,
260  0,
261  &NeededLength);
263  {
264  ExFreePool(BasicInfo);
265  continue;
266  }
267 
268  PartialInfo = ExAllocatePool(PagedPool, NeededLength);
269  if (!PartialInfo)
270  {
271  ExFreePool(OriginalIdBuffer);
272  ExFreePool(BasicInfo);
273  ZwClose(InstanceKey);
274  ZwClose(ChildKeyHandle);
275  ZwClose(CriticalDeviceKey);
276  return;
277  }
278 
279  /* Read ClassGUID entry in the CDDB */
280  Status = ZwQueryValueKey(ChildKeyHandle,
281  &ClassGuidU,
283  PartialInfo,
284  NeededLength,
285  &NeededLength);
286  if (Status != STATUS_SUCCESS)
287  {
288  ExFreePool(BasicInfo);
289  continue;
290  }
291 
292  /* Write it to the ENUM key */
293  Status = ZwSetValueKey(InstanceKey,
294  &ClassGuidU,
295  0,
296  REG_SZ,
297  PartialInfo->Data,
298  PartialInfo->DataLength);
299  if (Status != STATUS_SUCCESS)
300  {
301  ExFreePool(BasicInfo);
302  ExFreePool(PartialInfo);
303  ZwClose(ChildKeyHandle);
304  continue;
305  }
306 
307  Status = ZwQueryValueKey(ChildKeyHandle,
308  &ServiceU,
310  NULL,
311  0,
312  &NeededLength);
314  {
315  ExFreePool(PartialInfo);
316  PartialInfo = ExAllocatePool(PagedPool, NeededLength);
317  if (!PartialInfo)
318  {
319  ExFreePool(OriginalIdBuffer);
320  ExFreePool(BasicInfo);
321  ZwClose(InstanceKey);
322  ZwClose(ChildKeyHandle);
323  ZwClose(CriticalDeviceKey);
324  return;
325  }
326 
327  /* Read the service entry from the CDDB */
328  Status = ZwQueryValueKey(ChildKeyHandle,
329  &ServiceU,
331  PartialInfo,
332  NeededLength,
333  &NeededLength);
334  if (Status != STATUS_SUCCESS)
335  {
336  ExFreePool(BasicInfo);
337  ExFreePool(PartialInfo);
338  ZwClose(ChildKeyHandle);
339  continue;
340  }
341 
342  /* Write it to the ENUM key */
343  Status = ZwSetValueKey(InstanceKey,
344  &ServiceU,
345  0,
346  REG_SZ,
347  PartialInfo->Data,
348  PartialInfo->DataLength);
349  if (Status != STATUS_SUCCESS)
350  {
351  ExFreePool(BasicInfo);
352  ExFreePool(PartialInfo);
353  ZwClose(ChildKeyHandle);
354  continue;
355  }
356 
357  DPRINT("Installed service '%S' for critical device '%wZ'\n", PartialInfo->Data, &ChildIdNameU);
358  }
359  else
360  {
361  DPRINT1("Installed NULL service for critical device '%wZ'\n", &ChildIdNameU);
362  }
363 
364  ExFreePool(OriginalIdBuffer);
365  ExFreePool(PartialInfo);
366  ExFreePool(BasicInfo);
367  ZwClose(InstanceKey);
368  ZwClose(ChildKeyHandle);
369  ZwClose(CriticalDeviceKey);
370 
371  /* That's it */
372  return;
373  }
374 
375  ExFreePool(BasicInfo);
376  }
377  else
378  {
379  /* Umm, not sure what happened here */
380  continue;
381  }
382  }
383 
384  /* Advance to the next ID */
385  IdBuffer += StringLength;
386  }
387 
388  ExFreePool(OriginalIdBuffer);
389  ZwClose(InstanceKey);
390  ZwClose(CriticalDeviceKey);
391 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3767
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
unsigned char * PUCHAR
Definition: retypes.h:3
NTSTATUS NTAPI IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, IN ULONG CreateOptions, OUT PHANDLE Handle)
Definition: pnpmgr.c:523
LONG NTSTATUS
Definition: precomp.h:26
uint16_t * PWCHAR
Definition: typedefs.h:56
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
Status
Definition: gdiplustypes.h:24
#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
_In_ WDFCOLLECTION _In_ ULONG Index
Definition: Node.h:9
static const WCHAR L[]
Definition: oid.c:1250
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
VOID IopFixupDeviceId(PWCHAR String)
Definition: pnpmgr.c:33
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
unsigned short USHORT
Definition: pedump.c:61
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NULL
Definition: types.h:112
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22

Referenced by PiInitializeDevNode().

◆ IopPrepareDeviceForRemoval() [1/2]

static NTSTATUS IopPrepareDeviceForRemoval ( PDEVICE_OBJECT  DeviceObject,
BOOLEAN  Force 
)
static

◆ IopPrepareDeviceForRemoval() [2/2]

static NTSTATUS IopPrepareDeviceForRemoval ( IN PDEVICE_OBJECT  DeviceObject,
BOOLEAN  Force 
)
static

Definition at line 1912 of file devaction.c.

1913 {
1917  PDEVICE_RELATIONS DeviceRelations;
1918  NTSTATUS Status;
1919 
1920  if ((DeviceNode->UserFlags & DNUF_NOT_DISABLEABLE) && !Force)
1921  {
1922  DPRINT1("Removal not allowed for %wZ\n", &DeviceNode->InstancePath);
1923  return STATUS_UNSUCCESSFUL;
1924  }
1925 
1927  {
1928  DPRINT1("Removal vetoed by failing the query remove request\n");
1929 
1931 
1932  return STATUS_UNSUCCESSFUL;
1933  }
1934 
1935  Stack.Parameters.QueryDeviceRelations.Type = RemovalRelations;
1936 
1938  &IoStatusBlock,
1940  &Stack);
1941  if (!NT_SUCCESS(Status))
1942  {
1943  DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
1944  DeviceRelations = NULL;
1945  }
1946  else
1947  {
1948  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
1949  }
1950 
1951  if (DeviceRelations)
1952  {
1953  Status = IopQueryRemoveDeviceRelations(DeviceRelations, Force);
1954  if (!NT_SUCCESS(Status))
1955  return Status;
1956  }
1957 
1959  if (!NT_SUCCESS(Status))
1960  {
1961  if (DeviceRelations)
1962  IopCancelRemoveDeviceRelations(DeviceRelations);
1963  return Status;
1964  }
1965 
1966  if (DeviceRelations)
1967  IopSendRemoveDeviceRelations(DeviceRelations);
1969 
1970  return STATUS_SUCCESS;
1971 }
static NTSTATUS IopQueryRemoveChildDevices(PDEVICE_NODE ParentDeviceNode, BOOLEAN Force)
Definition: devaction.c:1817
static NTSTATUS NTAPI IopQueryRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1791
#define DNUF_NOT_DISABLEABLE
Definition: iotypes.h:211
LONG NTSTATUS
Definition: precomp.h:26
static VOID NTAPI IopCancelRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1708
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static VOID IopSendRemoveChildDevices(PDEVICE_NODE ParentDeviceNode)
Definition: devaction.c:1674
Definition: Node.h:9
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static VOID IopSendRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations)
Definition: devaction.c:1657
static NTSTATUS IopQueryRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations, BOOLEAN Force)
Definition: devaction.c:1871
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define IRP_MN_QUERY_DEVICE_RELATIONS
static VOID IopCancelRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations)
Definition: devaction.c:1741
#define DPRINT1
Definition: precomp.h:8
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack)
PDEVICE_NODE FASTCALL IopGetDeviceNode(IN PDEVICE_OBJECT DeviceObject)
_Inout_ PVCB _In_ BOOLEAN Force
Definition: cdprocs.h:1415

◆ IopQueryCompatibleIds()

static NTSTATUS IopQueryCompatibleIds ( PDEVICE_NODE  DeviceNode,
HANDLE  InstanceKey 
)
static

Definition at line 1021 of file devaction.c.

1023 {
1026  PWSTR Ptr;
1028  NTSTATUS Status;
1030  BOOLEAN IsValidID;
1031 
1032  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryCompatibleIDs to device stack\n");
1033 
1034  RtlZeroMemory(&Stack, sizeof(Stack));
1035  Stack.Parameters.QueryId.IdType = BusQueryCompatibleIDs;
1036  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
1037  &IoStatusBlock,
1039  &Stack);
1041  {
1043 
1044  if (!IsValidID)
1045  {
1046  DPRINT1("Invalid CompatibleIDs. DeviceNode - %p\n", DeviceNode);
1047  }
1048 
1049  TotalLength = 0;
1050 
1052  DPRINT("Compatible IDs:\n");
1053  while (*Ptr)
1054  {
1055  DPRINT(" %S\n", Ptr);
1056  Length = (ULONG)wcslen(Ptr) + 1;
1057 
1058  Ptr += Length;
1059  TotalLength += Length;
1060  }
1061  DPRINT("TotalLength: %hu\n", TotalLength);
1062  DPRINT("\n");
1063 
1064  RtlInitUnicodeString(&ValueName, L"CompatibleIDs");
1065  Status = ZwSetValueKey(InstanceKey,
1066  &ValueName,
1067  0,
1068  REG_MULTI_SZ,
1070  (TotalLength + 1) * sizeof(WCHAR));
1071  if (!NT_SUCCESS(Status))
1072  {
1073  DPRINT1("ZwSetValueKey() failed (Status %lx) or no Compatible ID returned\n", Status);
1074  }
1075  }
1076  else
1077  {
1078  DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
1079  }
1080 
1081  return Status;
1082 }
#define IRP_MN_QUERY_ID
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
uint16_t * PWSTR
Definition: typedefs.h:56
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
LONG NTSTATUS
Definition: precomp.h:26
uint16_t * PWCHAR
Definition: typedefs.h:56
_In_ ULONG TotalLength
Definition: usbdlib.h:158
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
#define REG_MULTI_SZ
Definition: nt_native.h:1501
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24
static BOOLEAN IopValidateID(_In_ PWCHAR Id, _In_ BUS_QUERY_ID_TYPE QueryType)
Definition: devaction.c:124
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: Node.h:9
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
static const WCHAR L[]
Definition: oid.c:1250
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack)

Referenced by PiInitializeDevNode(), and PiStartDeviceFinal().

◆ IopQueryDeviceCapabilities()

NTSTATUS NTAPI IopQueryDeviceCapabilities ( PDEVICE_NODE  DeviceNode,
PDEVICE_CAPABILITIES  DeviceCaps 
)

Definition at line 853 of file devaction.c.

855 {
856  IO_STATUS_BLOCK StatusBlock;
859  HANDLE InstanceKey;
861 
862  /* Set up the Header */
863  RtlZeroMemory(DeviceCaps, sizeof(DEVICE_CAPABILITIES));
864  DeviceCaps->Size = sizeof(DEVICE_CAPABILITIES);
865  DeviceCaps->Version = 1;
866  DeviceCaps->Address = -1;
867  DeviceCaps->UINumber = -1;
868 
869  /* Set up the Stack */
871  Stack.Parameters.DeviceCapabilities.Capabilities = DeviceCaps;
872 
873  /* Send the IRP */
874  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
875  &StatusBlock,
877  &Stack);
878  if (!NT_SUCCESS(Status))
879  {
881  {
882  DPRINT1("IRP_MN_QUERY_CAPABILITIES failed with status 0x%lx\n", Status);
883  }
884  return Status;
885  }
886 
887  /* Map device capabilities to capability flags */
888  DeviceNode->CapabilityFlags = 0;
889  if (DeviceCaps->LockSupported)
890  DeviceNode->CapabilityFlags |= 0x00000001; // CM_DEVCAP_LOCKSUPPORTED
891 
892  if (DeviceCaps->EjectSupported)
893  DeviceNode->CapabilityFlags |= 0x00000002; // CM_DEVCAP_EJECTSUPPORTED
894 
895  if (DeviceCaps->Removable)
896  DeviceNode->CapabilityFlags |= 0x00000004; // CM_DEVCAP_REMOVABLE
897 
898  if (DeviceCaps->DockDevice)
899  DeviceNode->CapabilityFlags |= 0x00000008; // CM_DEVCAP_DOCKDEVICE
900 
901  if (DeviceCaps->UniqueID)
902  DeviceNode->CapabilityFlags |= 0x00000010; // CM_DEVCAP_UNIQUEID
903 
904  if (DeviceCaps->SilentInstall)
905  DeviceNode->CapabilityFlags |= 0x00000020; // CM_DEVCAP_SILENTINSTALL
906 
907  if (DeviceCaps->RawDeviceOK)
908  DeviceNode->CapabilityFlags |= 0x00000040; // CM_DEVCAP_RAWDEVICEOK
909 
910  if (DeviceCaps->SurpriseRemovalOK)
911  DeviceNode->CapabilityFlags |= 0x00000080; // CM_DEVCAP_SURPRISEREMOVALOK
912 
913  if (DeviceCaps->HardwareDisabled)
914  DeviceNode->CapabilityFlags |= 0x00000100; // CM_DEVCAP_HARDWAREDISABLED
915 
916  if (DeviceCaps->NonDynamic)
917  DeviceNode->CapabilityFlags |= 0x00000200; // CM_DEVCAP_NONDYNAMIC
918 
919  if (DeviceCaps->NoDisplayInUI)
920  DeviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI;
921  else
922  DeviceNode->UserFlags &= ~DNUF_DONT_SHOW_IN_UI;
923 
924  Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
925  if (NT_SUCCESS(Status))
926  {
927  /* Set 'Capabilities' value */
928  RtlInitUnicodeString(&ValueName, L"Capabilities");
929  Status = ZwSetValueKey(InstanceKey,
930  &ValueName,
931  0,
932  REG_DWORD,
933  &DeviceNode->CapabilityFlags,
934  sizeof(ULONG));
935 
936  /* Set 'UINumber' value */
937  if (DeviceCaps->UINumber != MAXULONG)
938  {
939  RtlInitUnicodeString(&ValueName, L"UINumber");
940  Status = ZwSetValueKey(InstanceKey,
941  &ValueName,
942  0,
943  REG_DWORD,
944  &DeviceCaps->UINumber,
945  sizeof(ULONG));
946  }
947 
948  ZwClose(InstanceKey);
949  }
950 
951  return Status;
952 }
return STATUS_NOT_SUPPORTED
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTATUS NTAPI IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, IN ULONG CreateOptions, OUT PHANDLE Handle)
Definition: pnpmgr.c:523
LONG NTSTATUS
Definition: precomp.h:26
DEVICE_CAPABILITIES
Definition: iotypes.h:965
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
#define DNUF_DONT_SHOW_IN_UI
Definition: iotypes.h:209
Status
Definition: gdiplustypes.h:24
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: Node.h:9
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
static const WCHAR L[]
Definition: oid.c:1250
#define MAXULONG
Definition: typedefs.h:251
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define REG_DWORD
Definition: sdbapi.c:596
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack)
#define IRP_MN_QUERY_CAPABILITIES

Referenced by IoGetDeviceProperty(), IopCreateDeviceInstancePath(), IoRequestDeviceEject(), and PiStartDeviceFinal().

◆ IopQueryHardwareIds()

static NTSTATUS IopQueryHardwareIds ( PDEVICE_NODE  DeviceNode,
HANDLE  InstanceKey 
)
static

Definition at line 956 of file devaction.c.

958 {
961  PWSTR Ptr;
965  BOOLEAN IsValidID;
966 
967  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryHardwareIDs to device stack\n");
968 
969  RtlZeroMemory(&Stack, sizeof(Stack));
970  Stack.Parameters.QueryId.IdType = BusQueryHardwareIDs;
971  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
972  &IoStatusBlock,
974  &Stack);
975  if (NT_SUCCESS(Status))
976  {
978 
979  if (!IsValidID)
980  {
981  DPRINT1("Invalid HardwareIDs. DeviceNode - %p\n", DeviceNode);
982  }
983 
984  TotalLength = 0;
985 
987  DPRINT("Hardware IDs:\n");
988  while (*Ptr)
989  {
990  DPRINT(" %S\n", Ptr);
991  Length = (ULONG)wcslen(Ptr) + 1;
992 
993  Ptr += Length;
994  TotalLength += Length;
995  }
996  DPRINT("TotalLength: %hu\n", TotalLength);
997  DPRINT("\n");
998 
999  RtlInitUnicodeString(&ValueName, L"HardwareID");
1000  Status = ZwSetValueKey(InstanceKey,
1001  &ValueName,
1002  0,
1003  REG_MULTI_SZ,
1005  (TotalLength + 1) * sizeof(WCHAR));
1006  if (!NT_SUCCESS(Status))
1007  {
1008  DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
1009  }
1010  }
1011  else
1012  {
1013  DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
1014  }
1015 
1016  return Status;
1017 }
#define IRP_MN_QUERY_ID
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
uint16_t * PWSTR
Definition: typedefs.h:56
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
LONG NTSTATUS
Definition: precomp.h:26
uint16_t * PWCHAR
Definition: typedefs.h:56
_In_ ULONG TotalLength
Definition: usbdlib.h:158
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
#define REG_MULTI_SZ
Definition: nt_native.h:1501
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24
static BOOLEAN IopValidateID(_In_ PWCHAR Id, _In_ BUS_QUERY_ID_TYPE QueryType)
Definition: devaction.c:124
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: Node.h:9
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
static const WCHAR L[]
Definition: oid.c:1250
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack)

Referenced by PiInitializeDevNode(), and PiStartDeviceFinal().

◆ IopQueryRemoveChildDevices()

static NTSTATUS IopQueryRemoveChildDevices ( PDEVICE_NODE  ParentDeviceNode,
BOOLEAN  Force 
)
static

Definition at line 1817 of file devaction.c.

1818 {
1819  PDEVICE_NODE ChildDeviceNode, NextDeviceNode, FailedRemoveDevice;
1820  NTSTATUS Status;
1821  KIRQL OldIrql;
1822 
1824  ChildDeviceNode = ParentDeviceNode->Child;
1825  while (ChildDeviceNode != NULL)
1826  {
1827  NextDeviceNode = ChildDeviceNode->Sibling;
1830 
1832  if (!NT_SUCCESS(Status))
1833  {
1834  FailedRemoveDevice = ChildDeviceNode;
1835  goto cleanup;
1836  }
1837 
1839  ChildDeviceNode = NextDeviceNode;
1840  }
1842 
1843  return STATUS_SUCCESS;
1844 
1845 cleanup:
1847  ChildDeviceNode = ParentDeviceNode->Child;
1848  while (ChildDeviceNode != NULL)
1849  {
1850  NextDeviceNode = ChildDeviceNode->Sibling;
1852 
1854 
1855  /* IRP_MN_CANCEL_REMOVE_DEVICE is also sent to the device
1856  * that failed the IRP_MN_QUERY_REMOVE_DEVICE request */
1857  if (ChildDeviceNode == FailedRemoveDevice)
1858  return Status;
1859 
1860  ChildDeviceNode = NextDeviceNode;
1861 
1863  }
1865 
1866  return Status;
1867 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:850
PNP_DEVNODE_STATE PiSetDevNodeState(_In_ PDEVICE_NODE DeviceNode, _In_ PNP_DEVNODE_STATE NewState)
Definition: devnode.c:108
LONG NTSTATUS
Definition: precomp.h:26
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _DEVICE_NODE * Child
Definition: iotypes.h:835
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
static NTSTATUS IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
KSPIN_LOCK IopDeviceTreeLock
Definition: devnode.c:19
static VOID IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1759
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
struct _DEVICE_NODE * Sibling
Definition: iotypes.h:834
char * cleanup(char *str)
Definition: wpickclick.c:99
#define STATUS_SUCCESS
Definition: shellext.h:65
_Inout_ PVCB _In_ BOOLEAN Force
Definition: cdprocs.h:1415

Referenced by IopPrepareDeviceForRemoval(), and IoRequestDeviceEject().

◆ IopQueryRemoveDevice()

static NTSTATUS NTAPI IopQueryRemoveDevice ( IN PDEVICE_OBJECT  DeviceObject)
static

Definition at line 1791 of file devaction.c.

1792 {
1794  NTSTATUS Status;
1795 
1796  ASSERT(DeviceNode);
1797 
1798  IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVE_PENDING,
1799  &DeviceNode->InstancePath);
1800 
1802 
1803  PiNotifyTargetDeviceChange(&GUID_TARGET_DEVICE_QUERY_REMOVE, DeviceObject, NULL);
1804 
1805  if (!NT_SUCCESS(Status))
1806  {
1807  DPRINT1("Removal vetoed by %wZ\n", &DeviceNode->InstancePath);
1808  IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVAL_VETOED,
1809  &DeviceNode->InstancePath);
1810  }
1811 
1812  return Status;
1813 }
LONG NTSTATUS
Definition: precomp.h:26
static NTSTATUS PiIrpSendRemoveCheckVpb(_In_ PDEVICE_OBJECT DeviceObject, _In_ UCHAR MinorFunction)
Sends one of the remove IRPs to the device stack.
Definition: devaction.c:1574
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IRP_MN_QUERY_REMOVE_DEVICE
Status
Definition: gdiplustypes.h:24
NTSTATUS IopQueueTargetDeviceEvent(const GUID *Guid, PUNICODE_STRING DeviceIds)
Definition: plugplay.c:42
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: Node.h:9
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
VOID PiNotifyTargetDeviceChange(_In_ LPCGUID Event, _In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PTARGET_DEVICE_CUSTOM_NOTIFICATION CustomNotification)
Delivers the event to all drivers subscribed to EventCategoryTargetDeviceChange PnP event.
Definition: pnpnotify.c:258
PDEVICE_NODE FASTCALL IopGetDeviceNode(IN PDEVICE_OBJECT DeviceObject)

Referenced by IopPrepareDeviceForRemoval().

◆ IopQueryRemoveDeviceRelations()

static NTSTATUS IopQueryRemoveDeviceRelations ( PDEVICE_RELATIONS  DeviceRelations,
BOOLEAN  Force 
)
static

Definition at line 1871 of file devaction.c.

1872 {
1873  /* This function DOES NOT dereference the device objects on SUCCESS
1874  * but it DOES dereference device objects on FAILURE */
1875 
1876  ULONG i, j;
1877  NTSTATUS Status;
1878 
1879  for (i = 0; i < DeviceRelations->Count; i++)
1880  {
1881  Status = IopPrepareDeviceForRemoval(DeviceRelations->Objects[i], Force);
1882  if (!NT_SUCCESS(Status))
1883  {
1884  j = i;
1885  goto cleanup;
1886  }
1887  }
1888 
1889  return STATUS_SUCCESS;
1890 
1891 cleanup:
1892  /* IRP_MN_CANCEL_REMOVE_DEVICE is also sent to the device
1893  * that failed the IRP_MN_QUERY_REMOVE_DEVICE request */
1894  for (i = 0; i <= j; i++)
1895  {
1896  IopCancelPrepareDeviceForRemoval(DeviceRelations->Objects[i]);
1897  ObDereferenceObject(DeviceRelations->Objects[i]);
1898  DeviceRelations->Objects[i] = NULL;
1899  }
1900  for (; i < DeviceRelations->Count; i++)
1901  {
1902  ObDereferenceObject(DeviceRelations->Objects[i]);
1903  DeviceRelations->Objects[i] = NULL;
1904  }
1905  ExFreePool(DeviceRelations);
1906 
1907  return Status;
1908 }
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
LONG NTSTATUS
Definition: precomp.h:26
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
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
static NTSTATUS IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
static VOID IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1759
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
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
char * cleanup(char *str)
Definition: wpickclick.c:99
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
_Inout_ PVCB _In_ BOOLEAN Force
Definition: cdprocs.h:1415

Referenced by IopPrepareDeviceForRemoval(), and IoRequestDeviceEject().

◆ IopRemoveDevice()

static NTSTATUS IopRemoveDevice ( PDEVICE_NODE  DeviceNode)
static

Definition at line 1975 of file devaction.c.

1976 {
1977  NTSTATUS Status;
1978 
1979  // This function removes the device subtree, with the root in DeviceNode
1980  // atm everyting is in fact done inside this function, which is completely wrong.
1981  // The right implementation should have a separate removal worker thread and
1982  // properly do device node state transitions
1983 
1984  DPRINT("Removing device: %wZ\n", &DeviceNode->InstancePath);
1985 
1986  BOOLEAN surpriseRemoval = (_Bool)(DeviceNode->Flags & DNF_DEVICE_GONE);
1987 
1988  Status = IopPrepareDeviceForRemoval(DeviceNode->PhysicalDeviceObject, surpriseRemoval);
1989 
1990  if (surpriseRemoval)
1991  {
1992  IopSendSurpriseRemoval(DeviceNode->PhysicalDeviceObject);
1993  IopQueueTargetDeviceEvent(&GUID_DEVICE_SURPRISE_REMOVAL, &DeviceNode->InstancePath);
1994  }
1995 
1996  if (NT_SUCCESS(Status))
1997  {
1998  IopSendRemoveDevice(DeviceNode->PhysicalDeviceObject);
1999  if (surpriseRemoval)
2000  {
2001  IopQueueTargetDeviceEvent(&GUID_DEVICE_SAFE_REMOVAL, &DeviceNode->InstancePath);
2002  }
2003  return STATUS_SUCCESS;
2004  }
2005 
2006  return Status;
2007 }
LONG NTSTATUS
Definition: precomp.h:26
unsigned char BOOLEAN
static VOID NTAPI IopSendRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1637
Status
Definition: gdiplustypes.h:24
NTSTATUS IopQueueTargetDeviceEvent(const GUID *Guid, PUNICODE_STRING DeviceIds)
Definition: plugplay.c:42
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: Node.h:9
static VOID NTAPI IopSendSurpriseRemoval(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1698
#define DNF_DEVICE_GONE
Definition: iotypes.h:186
static NTSTATUS IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71

Referenced by IoInvalidateDeviceState(), and PiDevNodeStateMachine().

◆ IopSendEject()

static NTSTATUS NTAPI IopSendEject ( IN PDEVICE_OBJECT  DeviceObject)
static

Definition at line 2211 of file devaction.c.

2212 {
2214  PVOID Dummy;
2215 
2217  Stack.MajorFunction = IRP_MJ_PNP;
2218  Stack.MinorFunction = IRP_MN_EJECT;
2219 
2220  return IopSynchronousCall(DeviceObject, &Stack, &Dummy);
2221 }
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
#define IRP_MN_EJECT
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
NTSTATUS IopSynchronousCall(IN PDEVICE_OBJECT DeviceObject, IN PIO_STACK_LOCATION IoStackLocation, OUT PVOID *Information)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by IoRequestDeviceEject().

◆ IopSendRemoveChildDevices()

static VOID IopSendRemoveChildDevices ( PDEVICE_NODE  ParentDeviceNode)
static

Definition at line 1674 of file devaction.c.

1675 {
1676  PDEVICE_NODE ChildDeviceNode, NextDeviceNode;
1677  KIRQL OldIrql;
1678 
1680  ChildDeviceNode = ParentDeviceNode->Child;
1681  while (ChildDeviceNode != NULL)
1682  {
1683  NextDeviceNode = ChildDeviceNode->Sibling;
1685 
1686  IopSendRemoveDevice(ChildDeviceNode->PhysicalDeviceObject);
1687 
1688  ChildDeviceNode = NextDeviceNode;
1689 
1691  }
1693 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:850
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _DEVICE_NODE * Child
Definition: iotypes.h:835
static VOID NTAPI IopSendRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1637
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
KSPIN_LOCK IopDeviceTreeLock
Definition: devnode.c:19
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
struct _DEVICE_NODE * Sibling
Definition: iotypes.h:834

Referenced by IopPrepareDeviceForRemoval(), and IoRequestDeviceEject().

◆ IopSendRemoveDevice()

static VOID NTAPI IopSendRemoveDevice ( IN PDEVICE_OBJECT  DeviceObject)
static

Definition at line 1637 of file devaction.c.

1638 {
1640 
1642 
1643  /* Drivers should never fail a IRP_MN_REMOVE_DEVICE request */
1645 
1647  PiNotifyTargetDeviceChange(&GUID_TARGET_DEVICE_REMOVE_COMPLETE, DeviceObject, NULL);
1649  if (refCount != 0)
1650  {
1651  DPRINT1("Leaking device %wZ, refCount = %d\n", &DeviceNode->InstancePath, (INT32)refCount);
1652  }
1653 }
#define IRP_MN_REMOVE_DEVICE
PNP_DEVNODE_STATE PiSetDevNodeState(_In_ PDEVICE_NODE DeviceNode, _In_ PNP_DEVNODE_STATE NewState)
Definition: devnode.c:108
static NTSTATUS PiIrpSendRemoveCheckVpb(_In_ PDEVICE_OBJECT DeviceObject, _In_ UCHAR MinorFunction)
Sends one of the remove IRPs to the device stack.
Definition: devaction.c:1574
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define ASSERT(a)
Definition: mode.c:44
#define ObDereferenceObject
Definition: obfuncs.h:203
Definition: Node.h:9
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
VOID PiNotifyTargetDeviceChange(_In_ LPCGUID Event, _In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PTARGET_DEVICE_CUSTOM_NOTIFICATION CustomNotification)
Delivers the event to all drivers subscribed to EventCategoryTargetDeviceChange PnP event.
Definition: pnpnotify.c:258
signed int INT32
PDEVICE_NODE FASTCALL IopGetDeviceNode(IN PDEVICE_OBJECT DeviceObject)

Referenced by IopRemoveDevice(), IopSendRemoveChildDevices(), and IopSendRemoveDeviceRelations().

◆ IopSendRemoveDeviceRelations()

static VOID IopSendRemoveDeviceRelations ( PDEVICE_RELATIONS  DeviceRelations)
static

Definition at line 1657 of file devaction.c.

1658 {
1659  /* This function DOES dereference the device objects in all cases */
1660 
1661  ULONG i;
1662 
1663  for (i = 0; i < DeviceRelations->Count; i++)
1664  {
1665  IopSendRemoveDevice(DeviceRelations->Objects[i]);
1666  DeviceRelations->Objects[i] = NULL;
1667  }
1668 
1669  ExFreePool(DeviceRelations);
1670 }
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
static VOID NTAPI IopSendRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1637
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
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by IopPrepareDeviceForRemoval(), and IoRequestDeviceEject().

◆ IopSendSurpriseRemoval()

static VOID NTAPI IopSendSurpriseRemoval ( IN PDEVICE_OBJECT  DeviceObject)
static

Definition at line 1698 of file devaction.c.

1699 {
1701  /* Drivers should never fail a IRP_MN_SURPRISE_REMOVAL request */
1703 }
static NTSTATUS PiIrpSendRemoveCheckVpb(_In_ PDEVICE_OBJECT DeviceObject, _In_ UCHAR MinorFunction)
Sends one of the remove IRPs to the device stack.
Definition: devaction.c:1574
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define ASSERT(a)
Definition: mode.c:44
PDEVICE_NODE FASTCALL IopGetDeviceNode(IN PDEVICE_OBJECT DeviceObject)

Referenced by IopRemoveDevice().

◆ IopSetDeviceInstanceData()

NTSTATUS IopSetDeviceInstanceData ( HANDLE  InstanceKey,
PDEVICE_NODE  DeviceNode 
)

Definition at line 607 of file pnpmgr.c.

609 {
612  HANDLE LogConfKey, ControlKey, DeviceParamsKey;
613  ULONG ResCount;
616 
617  DPRINT("IopSetDeviceInstanceData() called\n");
618 
619  /* Create the 'LogConf' key */
620  RtlInitUnicodeString(&KeyName, L"LogConf");
622  &KeyName,
624  InstanceKey,
625  NULL);
626  Status = ZwCreateKey(&LogConfKey,
629  0,
630  NULL,
631  // FIXME? In r53694 it was silently turned from non-volatile into this,
632  // without any extra warning. Is this still needed??
634  NULL);
635  if (NT_SUCCESS(Status))
636  {
637  /* Set 'BootConfig' value */
638  if (DeviceNode->BootResources != NULL)
639  {
640  ResCount = DeviceNode->BootResources->Count;
641  if (ResCount != 0)
642  {
643  RtlInitUnicodeString(&KeyName, L"BootConfig");
644  Status = ZwSetValueKey(LogConfKey,
645  &KeyName,
646  0,
648  DeviceNode->BootResources,
649  PnpDetermineResourceListSize(DeviceNode->BootResources));
650  }
651  }
652 
653  /* Set 'BasicConfigVector' value */
654  if (DeviceNode->ResourceRequirements != NULL &&
655  DeviceNode->ResourceRequirements->ListSize != 0)
656  {
657  RtlInitUnicodeString(&KeyName, L"BasicConfigVector");
658  Status = ZwSetValueKey(LogConfKey,
659  &KeyName,
660  0,
662  DeviceNode->ResourceRequirements,
663  DeviceNode->ResourceRequirements->ListSize);
664  }
665 
666  ZwClose(LogConfKey);
667  }
668 
669  /* Set the 'ConfigFlags' value */
670  RtlInitUnicodeString(&KeyName, L"ConfigFlags");
671  Status = ZwQueryValueKey(InstanceKey,
672  &KeyName,
674  NULL,
675  0,
676  &ResultLength);
678  {
679  /* Write the default value */
680  ULONG DefaultConfigFlags = 0;
681  Status = ZwSetValueKey(InstanceKey,
682  &KeyName,
683  0,
684  REG_DWORD,
685  &DefaultConfigFlags,
686  sizeof(DefaultConfigFlags));
687  }
688 
689  /* Create the 'Control' key */
690  RtlInitUnicodeString(&KeyName, L"Control");
692  &KeyName,
694  InstanceKey,
695  NULL);
696  Status = ZwCreateKey(&ControlKey,
697  0,
699  0,
700  NULL,
702  NULL);
703  if (NT_SUCCESS(Status))
704  ZwClose(ControlKey);
705 
706  /* Create the 'Device Parameters' key and set the 'FirmwareIdentified' value for all ACPI-enumerated devices */
707  if (_wcsnicmp(DeviceNode->InstancePath.Buffer, L"ACPI\\", 5) == 0)
708  {
709  RtlInitUnicodeString(&KeyName, L"Device Parameters");
711  &KeyName,
713  InstanceKey,
714  NULL);
715  Status = ZwCreateKey(&DeviceParamsKey,
716  0,
718  0,
719  NULL,
721  NULL);
722  if (NT_SUCCESS(Status))
723  {
724  ULONG FirmwareIdentified = 1;
725  RtlInitUnicodeString(&KeyName, L"FirmwareIdentified");
726  Status = ZwSetValueKey(DeviceParamsKey,
727  &KeyName,
728  0,
729  REG_DWORD,
730  &FirmwareIdentified,
731  sizeof(FirmwareIdentified));
732 
733  ZwClose(DeviceParamsKey);
734  }
735  }
736 
737  DPRINT("IopSetDeviceInstanceData() done\n");
738 
739  return Status;
740 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define REG_RESOURCE_REQUIREMENTS_LIST
Definition: nt_native.h:1504
#define REG_RESOURCE_LIST
Definition: nt_native.h:1502
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
Status
Definition: gdiplustypes.h:24
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: Node.h:9
static const WCHAR L[]
Definition: oid.c:1250
ULONG NTAPI PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList)
Definition: pnpmgr.c:1808
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define NULL
Definition: types.h:112
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
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define DPRINT
Definition: sndvol32.h:71
#define REG_DWORD
Definition: sdbapi.c:596

Referenced by PiInitializeDevNode().

◆ IopSetServiceEnumData()

static NTSTATUS IopSetServiceEnumData ( _In_ PDEVICE_NODE  DeviceNode,
_In_ HANDLE  InstanceHandle 
)
static

Definition at line 1342 of file devaction.c.

1345 {
1346  UNICODE_STRING ServicesKeyPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
1347  UNICODE_STRING ServiceKeyName;
1348  UNICODE_STRING EnumKeyName;
1351  PKEY_VALUE_FULL_INFORMATION KeyValueInformation, kvInfo2;
1352  HANDLE ServiceKey = NULL, ServiceEnumKey = NULL;
1354  ULONG Count = 0, NextInstance = 0;
1355  WCHAR ValueBuffer[6];
1357 
1358  // obtain the device node's ServiceName
1359  Status = IopGetRegistryValue(InstanceHandle, L"Service", &kvInfo2);
1360  if (!NT_SUCCESS(Status))
1361  {
1362  return Status;
1363  }
1364 
1365  if (kvInfo2->Type != REG_SZ || kvInfo2->DataLength <= sizeof(WCHAR))
1366  {
1367  ExFreePool(kvInfo2);
1368  return STATUS_UNSUCCESSFUL;
1369  }
1370 
1371  ServiceName.MaximumLength = kvInfo2->DataLength;
1372  ServiceName.Length = kvInfo2->DataLength - sizeof(UNICODE_NULL);
1373  ServiceName.Buffer = (PVOID)((ULONG_PTR)kvInfo2 + kvInfo2->DataOffset);
1374 
1375  DPRINT("IopSetServiceEnumData(%p)\n", DeviceNode);
1376  DPRINT("Instance: %wZ\n", &DeviceNode->InstancePath);
1377  DPRINT("Service: %wZ\n", &ServiceName);
1378 
1379  ServiceKeyName.MaximumLength = ServicesKeyPath.Length + ServiceName.Length + sizeof(UNICODE_NULL);
1380  ServiceKeyName.Length = 0;
1381  ServiceKeyName.Buffer = ExAllocatePool(PagedPool, ServiceKeyName.MaximumLength);
1382  if (ServiceKeyName.Buffer == NULL)
1383  {
1384  DPRINT1("No ServiceKeyName.Buffer!\n");
1386  }
1387 
1388  RtlAppendUnicodeStringToString(&ServiceKeyName, &ServicesKeyPath);
1389  RtlAppendUnicodeStringToString(&ServiceKeyName, &ServiceName);
1390 
1391  DPRINT("ServiceKeyName: %wZ\n", &ServiceKeyName);
1392 
1393  Status = IopOpenRegistryKeyEx(&ServiceKey, NULL, &ServiceKeyName, KEY_CREATE_SUB_KEY);
1394  if (!NT_SUCCESS(Status))
1395  {
1396  goto done;
1397  }
1398 
1399  RtlInitUnicodeString(&EnumKeyName, L"Enum");
1400  Status = IopCreateRegistryKeyEx(&ServiceEnumKey,
1401  ServiceKey,
1402  &EnumKeyName,
1403  KEY_SET_VALUE,
1405  &Disposition);
1406  if (NT_SUCCESS(Status))
1407  {
1409  {
1410  /* Read the NextInstance value */
1411  Status = IopGetRegistryValue(ServiceEnumKey,
1412  L"Count",
1413  &KeyValueInformation);
1414  if (!NT_SUCCESS(Status))
1415  goto done;
1416 
1417  if ((KeyValueInformation->Type == REG_DWORD) &&
1418  (KeyValueInformation->DataLength))
1419  {
1420  /* Read it */
1421  Count = *(PULONG)((ULONG_PTR)KeyValueInformation +
1422  KeyValueInformation->DataOffset);
1423  }
1424 
1425  ExFreePool(KeyValueInformation);
1426  KeyValueInformation = NULL;
1427 
1428  /* Read the NextInstance value */
1429  Status = IopGetRegistryValue(ServiceEnumKey,
1430  L"NextInstance",
1431  &KeyValueInformation);
1432  if (!NT_SUCCESS(Status))
1433  goto done;
1434 
1435  if ((KeyValueInformation->Type == REG_DWORD) &&
1436  (KeyValueInformation->DataLength))
1437  {
1438  NextInstance = *(PULONG)((ULONG_PTR)KeyValueInformation +
1439  KeyValueInformation->DataOffset);
1440  }
1441 
1442  ExFreePool(KeyValueInformation);
1443  KeyValueInformation = NULL;
1444  }
1445 
1446  /* Set the instance path */
1447  swprintf(ValueBuffer, L"%lu", NextInstance);
1448  RtlInitUnicodeString(&ValueName, ValueBuffer);
1449  Status = ZwSetValueKey(ServiceEnumKey,
1450  &ValueName,
1451  0,
1452  REG_SZ,
1453  DeviceNode->InstancePath.Buffer,
1454  DeviceNode->InstancePath.MaximumLength);
1455  if (!NT_SUCCESS(Status))
1456  goto done;
1457 
1458  /* Increment Count and NextInstance */
1459  Count++;
1460  NextInstance++;
1461 
1462  /* Set the new Count value */
1463  RtlInitUnicodeString(&ValueName, L"Count");
1464  Status = ZwSetValueKey(ServiceEnumKey,
1465  &ValueName,
1466  0,
1467  REG_DWORD,
1468  &Count,
1469  sizeof(Count));
1470  if (!NT_SUCCESS(Status))
1471  goto done;
1472 
1473  /* Set the new NextInstance value */
1474  RtlInitUnicodeString(&ValueName, L"NextInstance");
1475  Status = ZwSetValueKey(ServiceEnumKey,
1476  &ValueName,
1477  0,
1478  REG_DWORD,
1479  &NextInstance,
1480  sizeof(NextInstance));
1481  }
1482 
1484  &ServiceName,
1485  &DeviceNode->ServiceName);
1486 
1487 done:
1488  if (ServiceEnumKey != NULL)
1489  ZwClose(ServiceEnumKey);
1490 
1491  if (ServiceKey != NULL)
1492  ZwClose(ServiceKey);
1493 
1494  ExFreePool(ServiceKeyName.Buffer);
1495  ExFreePool(kvInfo2);
1496 
1497  return Status;
1498 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define KEY_SET_VALUE
Definition: nt_native.h:1017
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING
Definition: green.h:16
LONG NTSTATUS
Definition: precomp.h:26
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1085
#define swprintf
Definition: precomp.h:40
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
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)
#define UNICODE_NULL
void * PVOID
Definition: retypes.h:9
Status
Definition: gdiplustypes.h:24
int Count
Definition: noreturn.cpp:7
LPTSTR ServiceName
Definition: ServiceMain.c:15
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
Definition: Node.h:9
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
static const WCHAR L[]
Definition: oid.c:1250
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1607
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1456
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define DPRINT
Definition: sndvol32.h:71
#define REG_DWORD
Definition: sdbapi.c:596
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22

Referenced by PiInitializeDevNode().

◆ IopValidateID()

static BOOLEAN IopValidateID ( _In_ PWCHAR  Id,
_In_ BUS_QUERY_ID_TYPE  QueryType 
)
static

Definition at line 124 of file devaction.c.

127 {
128  PWCHAR PtrChar;
129  PWCHAR StringEnd;
130  WCHAR Char;
131  ULONG SeparatorsCount = 0;
132  PWCHAR PtrPrevChar = NULL;
133  ULONG MaxSeparators;
134  BOOLEAN IsMultiSz;
135 
136  PAGED_CODE();
137 
138  switch (QueryType)
139  {
140  case BusQueryDeviceID:
141  MaxSeparators = MAX_SEPARATORS_DEVICEID;
142  IsMultiSz = FALSE;
143  break;
144  case BusQueryInstanceID:
145  MaxSeparators = MAX_SEPARATORS_INSTANCEID;
146  IsMultiSz = FALSE;
147  break;
148 
149  case BusQueryHardwareIDs:
151  MaxSeparators = MAX_SEPARATORS_DEVICEID;
152  IsMultiSz = TRUE;
153  break;
154 
155  default:
156  DPRINT1("IopValidateID: Not handled QueryType - %x\n", QueryType);
157  return FALSE;
158  }
159 
160  StringEnd = Id + MAX_DEVICE_ID_LEN;
161 
162  for (PtrChar = Id; PtrChar < StringEnd; PtrChar++)
163  {
164  Char = *PtrChar;
165 
166  if (Char == UNICODE_NULL)
167  {
168  if (!IsMultiSz || (PtrPrevChar && PtrChar == PtrPrevChar + 1))
169  {
170  if (MaxSeparators == SeparatorsCount || IsMultiSz)
171  {
172  return TRUE;
173  }
174 
175  DPRINT1("IopValidateID: SeparatorsCount - %lu, MaxSeparators - %lu\n",
176  SeparatorsCount, MaxSeparators);
177  goto ErrorExit;
178  }
179 
180  StringEnd = PtrChar + MAX_DEVICE_ID_LEN + 1;
181  PtrPrevChar = PtrChar;
182  SeparatorsCount = 0;
183  }
184  else if (Char < ' ' || Char > 0x7F || Char == ',')
185  {
186  DPRINT1("IopValidateID: Invalid character - %04X\n", Char);
187  goto ErrorExit;
188  }
189  else if (Char == ' ')
190  {
191  *PtrChar = '_';
192  }
193  else if (Char == '\\')
194  {
195  SeparatorsCount++;
196 
197  if (SeparatorsCount > MaxSeparators)
198  {
199  DPRINT1("IopValidateID: SeparatorsCount - %lu, MaxSeparators - %lu\n",
200  SeparatorsCount, MaxSeparators);
201  goto ErrorExit;
202  }
203  }
204  }
205 
206  DPRINT1("IopValidateID: Not terminated ID\n");
207 
208 ErrorExit:
209  // FIXME logging
210  return FALSE;
211 }
#define TRUE
Definition: types.h:120
uint16_t * PWCHAR
Definition: typedefs.h:56
DWORD Id
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
unsigned char BOOLEAN
__wchar_t WCHAR
Definition: xmlstorage.h:180
_Must_inspect_result_ _In_ KTMOBJECT_TYPE QueryType
Definition: nttmapi.h:404
#define MAX_DEVICE_ID_LEN
Definition: devaction.c:40
#define MAX_SEPARATORS_INSTANCEID
Definition: devaction.c:41
static VOID ErrorExit(LPTSTR lpszMessage)
Definition: telnetd.c:647
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define MAX_SEPARATORS_DEVICEID
Definition: devaction.c:42
#define PAGED_CODE()

Referenced by IopCreateDeviceInstancePath(), IopQueryCompatibleIds(), and IopQueryHardwareIds().

◆ IoRequestDeviceEject()

VOID NTAPI IoRequestDeviceEject ( IN PDEVICE_OBJECT  PhysicalDeviceObject)

Definition at line 2228 of file devaction.c.

2229 {
2231  PDEVICE_RELATIONS DeviceRelations;
2235  NTSTATUS Status;
2236 
2237  IopQueueTargetDeviceEvent(&GUID_DEVICE_KERNEL_INITIATED_EJECT,
2238  &DeviceNode->InstancePath);
2239 
2241  {
2242  goto cleanup;
2243  }
2244 
2245  Stack.Parameters.QueryDeviceRelations.Type = EjectionRelations;
2246 
2248  &IoStatusBlock,
2250  &Stack);
2251  if (!NT_SUCCESS(Status))
2252  {
2253  DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
2254  DeviceRelations = NULL;
2255  }
2256  else
2257  {
2258  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
2259  }
2260 
2261  if (DeviceRelations)
2262  {
2263  Status = IopQueryRemoveDeviceRelations(DeviceRelations, FALSE);
2264  if (!NT_SUCCESS(Status))
2265  goto cleanup;
2266  }
2267 
2269  if (!NT_SUCCESS(Status))
2270  {
2271  if (DeviceRelations)
2272  IopCancelRemoveDeviceRelations(DeviceRelations);
2273  goto cleanup;
2274  }
2275 
2277  {
2278  if (DeviceRelations)
2279  IopCancelRemoveDeviceRelations(DeviceRelations);
2281  goto cleanup;
2282  }
2283 
2284  if (DeviceRelations)
2285  IopSendRemoveDeviceRelations(DeviceRelations);
2287 
2289  if (Capabilities.EjectSupported)
2290  {
2292  {
2293  goto cleanup;
2294  }
2295  }
2296  else
2297  {
2298  // DeviceNode->Flags |= DNF_DISABLED;
2299  }
2300 
2301  IopQueueTargetDeviceEvent(&GUID_DEVICE_EJECT,
2302  &DeviceNode->InstancePath);
2303 
2304  return;
2305 
2306 cleanup:
2307  IopQueueTargetDeviceEvent(&GUID_DEVICE_EJECT_VETOED,
2308  &DeviceNode->InstancePath);
2309 }
static NTSTATUS IopQueryRemoveChildDevices(PDEVICE_NODE ParentDeviceNode, BOOLEAN Force)
Definition: devaction.c:1817
static VOID IopCancelRemoveChildDevices(PDEVICE_NODE ParentDeviceNode)
Definition: devaction.c:1718
#define CM_PROB_HELD_FOR_EJECT
Definition: cfg.h:77
LONG NTSTATUS
Definition: precomp.h:26
DEVICE_CAPABILITIES
Definition: iotypes.h:965
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1155
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
#define FALSE
Definition: types.h:117
_Must_inspect_result_ typedef _Out_ PHIDP_CAPS Capabilities
Definition: hidclass.h:103
NTSTATUS NTAPI IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode, PDEVICE_CAPABILITIES DeviceCaps)
Definition: devaction.c:853
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
Status
Definition: gdiplustypes.h:24
NTSTATUS IopQueueTargetDeviceEvent(const GUID *Guid, PUNICODE_STRING DeviceIds)
Definition: plugplay.c:42
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static VOID IopSendRemoveChildDevices(PDEVICE_NODE ParentDeviceNode)
Definition: devaction.c:1674
Definition: Node.h:9
static NTSTATUS IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
static VOID IopSendRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations)
Definition: devaction.c:1657
static NTSTATUS NTAPI IopSendEject(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:2211
static NTSTATUS IopQueryRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations, BOOLEAN Force)
Definition: devaction.c:1871
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define IRP_MN_QUERY_DEVICE_RELATIONS
static VOID IopCancelRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations)
Definition: devaction.c:1741
char * cleanup(char *str)
Definition: wpickclick.c:99
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack)
PDEVICE_NODE FASTCALL IopGetDeviceNode(IN PDEVICE_OBJECT DeviceObject)

◆ PiAttachFilterDrivers()

static NTSTATUS PiAttachFilterDrivers ( PLIST_ENTRY  DriversListHead,
PDEVICE_NODE  DeviceNode,
HANDLE  EnumSubKey,
HANDLE  ClassKey,
BOOLEAN  Lower,
BOOLEAN  LoadDrivers 
)
static

Calls PiAttachFilterDriversCallback for filter drivers (if any)

Definition at line 531 of file devaction.c.

538 {
539  RTL_QUERY_REGISTRY_TABLE QueryTable[2] = { { NULL, 0, NULL, NULL, 0, NULL, 0 }, };
540  ATTACH_FILTER_DRIVERS_CONTEXT routineContext;
542 
543  PAGED_CODE();
544 
545  routineContext.DriversListHead = DriversListHead;
546  routineContext.DeviceNode = DeviceNode;
547 
548  // First add device filters
549  routineContext.DriverType = Lower ? LowerFilter : UpperFilter;
552  .Name = Lower ? L"LowerFilters" : L"UpperFilters",
553  .DefaultType = REG_NONE,
554  .EntryContext = (PVOID)(ULONG_PTR)LoadDrivers
555  };
556 
558  (PWSTR)EnumSubKey,
559  QueryTable,
560  &routineContext,
561  NULL);
562  if (ClassKey == NULL)
563  {
564  return Status;
565  }
566 
567  // Then add device class filters
568  routineContext.DriverType = Lower ? LowerClassFilter : UpperClassFilter;
571  .Name = Lower ? L"LowerFilters" : L"UpperFilters",
572  .DefaultType = REG_NONE,
573  .EntryContext = (PVOID)(ULONG_PTR)LoadDrivers
574  };
575 
577  (PWSTR)ClassKey,
578  QueryTable,
579  &routineContext,
580  NULL);
581  return Status;
582 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
uint16_t * PWSTR
Definition: typedefs.h:56
LONG NTSTATUS
Definition: precomp.h:26
uint32_t ULONG_PTR
Definition: typedefs.h:65
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
void * PVOID
Definition: retypes.h:9
Status
Definition: gdiplustypes.h:24
static NTSTATUS NTAPI PiAttachFilterDriversCallback(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Ctx, PVOID EntryContext)
Loads and/or returns the driver associated with the registry entry if the driver is enabled....
Definition: devaction.c:362
struct _RTL_QUERY_REGISTRY_TABLE RTL_QUERY_REGISTRY_TABLE
Definition: Node.h:9
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
#define NULL
Definition: types.h:112
#define REG_NONE
Definition: nt_native.h:1492
ADD_DEV_DRIVER_TYPE DriverType
Definition: devaction.c:84
#define PAGED_CODE()

Referenced by PiCallDriverAddDevice().

◆ PiAttachFilterDriversCallback()

static NTSTATUS NTAPI PiAttachFilterDriversCallback ( PWSTR  ValueName,
ULONG  ValueType,
PVOID  ValueData,
ULONG  ValueLength,
PVOID  Ctx,
PVOID  EntryContext 
)
static

Loads and/or returns the driver associated with the registry entry if the driver is enabled. In case of an error, sets up a corresponding Problem to the DeviceNode.

Definition at line 362 of file devaction.c.

369 {
373  BOOLEAN loadDrivers = (BOOLEAN)(ULONG_PTR)EntryContext;
374 
375  PAGED_CODE();
376 
377  // No filter value present
378  if (ValueType != REG_SZ)
379  return STATUS_SUCCESS;
380 
381  if (ValueLength <= sizeof(WCHAR))
383 
384  // open the service registry key
385  UNICODE_STRING serviceName = { .Length = 0 }, servicesKeyName;
387  RtlInitUnicodeString(&servicesKeyName, ServicesKeyName);
388 
389  HANDLE ccsServicesHandle, serviceHandle = NULL;
390 
391  Status = IopOpenRegistryKeyEx(&ccsServicesHandle, NULL, &servicesKeyName, KEY_READ);
392  if (!NT_SUCCESS(Status))
393  {
394  DPRINT1("Failed to open a registry key for \"%wZ\" (status %x)\n", &serviceName, Status);
395  return Status;
396  }
397 
398  Status = IopOpenRegistryKeyEx(&serviceHandle, ccsServicesHandle, &serviceName, KEY_READ);
399  ZwClose(ccsServicesHandle);
400  if (!NT_SUCCESS(Status))
401  {
402  DPRINT1("Failed to open a registry key for \"%wZ\" (status %x)\n", &serviceName, Status);
403  return Status;
404  }
405 
407  sizeof(*driverEntry),
409 
410  if (!driverEntry)
411  {
412  DPRINT1("Failed to allocate driverEntry for \"%wZ\"\n", &serviceName);
413  ZwClose(serviceHandle);
415  }
416 
417  // check if the driver is disabled
419  SERVICE_LOAD_TYPE startType = DisableLoad;
420 
421  Status = IopGetRegistryValue(serviceHandle, L"Start", &kvInfo);
422  if (NT_SUCCESS(Status))
423  {
424  if (kvInfo->Type == REG_DWORD)
425  {
426  RtlMoveMemory(&startType,
427  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
428  sizeof(startType));
429  }
430 
431  ExFreePool(kvInfo);
432  }
433 
434  // TODO: take into account other start types (like SERVICE_DEMAND_START)
435  if (startType >= DisableLoad)
436  {
437  if (!(context->DeviceNode->Flags & DNF_HAS_PROBLEM))
438  {
440  }
441 
442  DPRINT("Service \"%wZ\" is disabled (start type %u)\n", &serviceName, startType);
444  goto Cleanup;
445  }
446 
447  // check if the driver is already loaded
448  UNICODE_STRING driverName;
449  Status = IopGetDriverNames(serviceHandle, &driverName, NULL);
450  if (!NT_SUCCESS(Status))
451  {
452  DPRINT1("Unable to obtain the driver name for \"%wZ\"\n", &serviceName);
453  goto Cleanup;
454  }
455 
456  // try to open it
457  Status = ObReferenceObjectByName(&driverName,
459  NULL, /* PassedAccessState */
460  0, /* DesiredAccess */
462  KernelMode,
463  NULL, /* ParseContext */
464  (PVOID*)&DriverObject);
465  RtlFreeUnicodeString(&driverName);
466 
467  // the driver was not probably loaded, try to load
468  if (!NT_SUCCESS(Status))
469  {
470  if (loadDrivers)
471  {
472  Status = IopLoadDriver(serviceHandle, &DriverObject);
473  }
474  else
475  {
476  DPRINT("Service \"%wZ\" will not be loaded now\n", &serviceName);
477  // return failure, the driver will be loaded later (in a subsequent call)
479  goto Cleanup;
480  }
481  }
482 
483  if (NT_SUCCESS(Status))
484  {
485  driverEntry->DriverObject = DriverObject;
486  driverEntry->DriverType = context->DriverType;
487  InsertTailList(context->DriversListHead, &driverEntry->ListEntry);
488  ZwClose(serviceHandle);
489  return STATUS_SUCCESS;
490  }
491  else
492  {
493  if (!(context->DeviceNode->Flags & DNF_HAS_PROBLEM))
494  {
495  switch (Status)
496  {
499  break;
502  break;
505  break;
506  default:
508  break;
509  }
510  }
511 
512  DPRINT1("Failed to load driver \"%wZ\" for %wZ (status %x)\n",
513  &serviceName, &context->DeviceNode->InstancePath, Status);
514  }
515 
516 Cleanup:
517  ExFreePoolWithTag(driverEntry, TAG_PNP_DEVACTION);
518  if (serviceHandle)
519  {
520  ZwClose(serviceHandle);
521  }
522  return Status;
523 }
NTSTATUS IopGetDriverNames(_In_ HANDLE ServiceHandle, _Out_ PUNICODE_STRING DriverName, _Out_opt_ PUNICODE_STRING ServiceName)
Definition: driver.c:125
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define DNF_HAS_PROBLEM
Definition: iotypes.h:183
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
Definition: http.c:7251
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define CM_PROB_OUT_OF_MEMORY
Definition: cfg.h:33
enum _CM_SERVICE_LOAD_TYPE SERVICE_LOAD_TYPE
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_FAILED_DRIVER_ENTRY
Definition: ntstatus.h:911
POBJECT_TYPE IoDriverObjectType
Definition: driver.c:33
#define CM_PROB_FAILED_DRIVER_ENTRY
Definition: cfg.h:67
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:279
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_OPENIF
Definition: winternl.h:229
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTATUS IopLoadDriver(_In_ HANDLE ServiceHandle, _Out_ PDRIVER_OBJECT *DriverObject)
Definition: driver.c:1896
LIST_ENTRY ListEntry
Definition: devaction.c:77
unsigned char BOOLEAN
#define TAG_PNP_DEVACTION
Definition: devaction.c:53
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4155
ADD_DEV_DRIVER_TYPE DriverType
Definition: devaction.c:79
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define STATUS_ILL_FORMED_SERVICE_ENTRY
Definition: ntstatus.h:588
Status
Definition: gdiplustypes.h:24
char serviceName[]
Definition: tftpd.cpp:34
VOID PiSetDevNodeProblem(_In_ PDEVICE_NODE DeviceNode, _In_ UINT32 Problem)
Definition: devnode.c:132
PDRIVER_OBJECT DriverObject
Definition: devaction.c:78
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CM_PROB_DISABLED_SERVICE
Definition: cfg.h:62
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
#define CM_PROB_DRIVER_FAILED_LOAD
Definition: cfg.h:69
static const WCHAR Cleanup[]
Definition: register.c:80
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1607
#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:1456
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define BOOLEAN
Definition: pedump.c:73
#define CM_PROB_DRIVER_SERVICE_KEY_INVALID
Definition: cfg.h:70
static const WCHAR ServicesKeyName[]
Definition: devaction.c:51
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define DPRINT
Definition: sndvol32.h:71
#define REG_DWORD
Definition: sdbapi.c:596
NTSTATUS NTAPI ObReferenceObjectByName(IN PUNICODE_STRING ObjectPath, IN ULONG Attributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext, OUT PVOID *ObjectPtr)
Definition: obref.c:409
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PAGED_CODE()
#define REG_SZ
Definition: layer.c:22
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:271

Referenced by PiAttachFilterDrivers(), and PiCallDriverAddDevice().

◆ PiCallDriverAddDevice()

static NTSTATUS PiCallDriverAddDevice ( _In_ PDEVICE_NODE  DeviceNode,
_In_ BOOLEAN  LoadDrivers 
)
static

Loads all drivers for a device node (actual service and filters) and calls their AddDevice routine.

Parameters
[in]DeviceNodeThe device node
[in]LoadDriversWhether to load drivers if they are not loaded yet (used when storage subsystem is not yet initialized)

Definition at line 594 of file devaction.c.

597 {
599  HANDLE EnumRootKey, SubKey;
600  HANDLE ClassKey = NULL;
602  static UNICODE_STRING ccsControlClass =
603  RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class");
605 
606  PAGED_CODE();
607 
608  // open the enumeration root key
609  Status = IopOpenRegistryKeyEx(&EnumRootKey, NULL, &EnumRoot, KEY_READ);
610  if (!NT_SUCCESS(Status))
611  {
612  DPRINT1("IopOpenRegistryKeyEx() failed for \"%wZ\" (status %x)\n", &EnumRoot, Status);
613  return Status;
614  }
615 
616  // open an instance subkey
617  Status = IopOpenRegistryKeyEx(&SubKey, EnumRootKey, &DeviceNode->InstancePath, KEY_READ);
618  ZwClose(EnumRootKey);
619  if (!NT_SUCCESS(Status))
620  {
621  DPRINT1("Failed to open a devnode instance key for \"%wZ\" (status %x)\n",
622  &DeviceNode->InstancePath, Status);
623  return Status;
624  }
625 
626  // try to get the class GUID of an instance and its registry key
627  Status = IopGetRegistryValue(SubKey, REGSTR_VAL_CLASSGUID, &kvInfo);
628  if (NT_SUCCESS(Status))
629  {
630  if (kvInfo->Type == REG_SZ && kvInfo->DataLength > sizeof(WCHAR))
631  {
632  UNICODE_STRING classGUID = {
633  .MaximumLength = kvInfo->DataLength,
634  .Length = kvInfo->DataLength - sizeof(UNICODE_NULL),
635  .Buffer = (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset)
636  };
637  HANDLE ccsControlHandle;
638 
639  Status = IopOpenRegistryKeyEx(&ccsControlHandle, NULL, &ccsControlClass, KEY_READ);
640  if (!NT_SUCCESS(Status))
641  {
642  DPRINT1("IopOpenRegistryKeyEx() failed for \"%wZ\" (status %x)\n",
643  &ccsControlClass, Status);
644  }
645  else
646  {
647  // open the CCS\Control\Class<ClassGUID> key
648  Status = IopOpenRegistryKeyEx(&ClassKey, ccsControlHandle, &classGUID, KEY_READ);
649  ZwClose(ccsControlHandle);
650  if (!NT_SUCCESS(Status))
651  {
652  DPRINT1("Failed to open class key \"%wZ\" (status %x)\n", &classGUID, Status);
653  }
654  }
655 
656  if (ClassKey)
657  {
658  // Check the Properties key of a class too
659  // Windows fills some device properties from this key (which is protected)
660  // TODO: add the device properties from this key
661 
663  HANDLE propertiesHandle;
664 
665  Status = IopOpenRegistryKeyEx(&propertiesHandle, ClassKey, &properties, KEY_READ);
666  if (!NT_SUCCESS(Status))
667  {
668  DPRINT("Properties key failed to open for \"%wZ\" (status %x)\n",
669  &classGUID, Status);
670  }
671  else
672  {
673  ZwClose(propertiesHandle);
674  }
675  }
676  }
677 
678  ExFreePool(kvInfo);
679  }
680 
681  // the driver loading order:
682  // 1. LowerFilters
683  // 2. LowerClassFilters
684  // 3. Device driver (only one service!)
685  // 4. UpperFilters
686  // 5. UpperClassFilters
687 
688  LIST_ENTRY drvListHead;
689  InitializeListHead(&drvListHead);
690 
691  // lower (class) filters
692  Status = PiAttachFilterDrivers(&drvListHead, DeviceNode, SubKey, ClassKey, TRUE, LoadDrivers);
693  if (!NT_SUCCESS(Status))
694  {
695  goto Cleanup;
696  }
697 
698  ATTACH_FILTER_DRIVERS_CONTEXT routineContext = {
699  .DriversListHead = &drvListHead,
700  .DriverType = DeviceDriver,
701  .DeviceNode = DeviceNode
702  };
703 
704  RTL_QUERY_REGISTRY_TABLE queryTable[2] = {{
706  .Name = L"Service",
708  .DefaultType = REG_SZ, // REG_MULTI_SZ is not allowed here
709  .DefaultData = L"",
710  .EntryContext = (PVOID)(ULONG_PTR)LoadDrivers
711  },};
712 
713  // device driver
715  (PWSTR)SubKey,
716  queryTable,
717  &routineContext,
718  NULL);
719  if (NT_SUCCESS(Status))
720  {
721  // do nothing
722  }
723  // if a driver is not found, but a device allows raw access -> proceed
724  else if (Status == STATUS_OBJECT_NAME_NOT_FOUND &&
725  (DeviceNode->CapabilityFlags & 0x00000040)) // CM_DEVCAP_RAWDEVICEOK
726  {
727  // add a dummy entry to the drivers list (need for later processing)
728  PADD_DEV_DRIVERS_LIST driverEntry = ExAllocatePoolZero(PagedPool,
729  sizeof(*driverEntry),
731  driverEntry->DriverType = DeviceDriver;
732  InsertTailList(&drvListHead, &driverEntry->ListEntry);
733  DPRINT("No service for \"%wZ\" (RawDeviceOK)\n", &DeviceNode->InstancePath);
734  }
735  else
736  {
738  {
740  }
741  DPRINT("No service for \"%wZ\" (loadDrv: %u)\n", &DeviceNode->InstancePath, LoadDrivers);
742  goto Cleanup;
743  }
744 
745  // upper (class) filters
746  Status = PiAttachFilterDrivers(&drvListHead, DeviceNode, SubKey, ClassKey, FALSE, LoadDrivers);
747  if (!NT_SUCCESS(Status))
748  {
749  goto Cleanup;
750  }
751 
752  // finally loop through the stack and call AddDevice for every driver
753  for (PLIST_ENTRY listEntry = drvListHead.Flink;
754  listEntry != &drvListHead;
755  listEntry = listEntry->Flink)
756  {
757  PADD_DEV_DRIVERS_LIST driverEntry;
758  driverEntry = CONTAINING_RECORD(listEntry, ADD_DEV_DRIVERS_LIST, ListEntry);
759  PDRIVER_OBJECT driverObject = driverEntry->DriverObject;
760 
761  // FIXME: ReactOS is not quite ready for this assert
762  // (legacy drivers should not have AddDevice routine)
763  // ASSERT(!(DriverObject->Flags & DRVO_LEGACY_DRIVER));
764 
765  if (driverObject && driverObject->DriverExtension->AddDevice)
766  {
767  Status = driverObject->DriverExtension->AddDevice(driverEntry->DriverObject,
768  DeviceNode->PhysicalDeviceObject);
769  }
770  else if (driverObject == NULL)
771  {
772  // valid only for DeviceDriver
773  ASSERT(driverEntry->DriverType == DeviceDriver);
774  ASSERT(DeviceNode->CapabilityFlags & 0x00000040); // CM_DEVCAP_RAWDEVICEOK
776  }
777  else
778  {
779  // HACK: the driver doesn't have a AddDevice routine. We shouldn't be here,
780  // but ReactOS' PnP stack is not that correct yet
781  DeviceNode->Flags |= DNF_LEGACY_DRIVER;
783  }
784 
785  // for filter drivers we don't care about the AddDevice result
786  if (driverEntry->DriverType == DeviceDriver)
787  {
788  if (NT_SUCCESS(Status))
789  {
790  PDEVICE_OBJECT fdo = IoGetAttachedDeviceReference(DeviceNode->PhysicalDeviceObject);
791 
792  // HACK: Check if we have a ACPI device (needed for power management)
793  if (fdo->DeviceType == FILE_DEVICE_ACPI)
794  {
795  static BOOLEAN SystemPowerDeviceNodeCreated = FALSE;
796 
797  // There can be only one system power device
798  if (!SystemPowerDeviceNodeCreated)
799  {
802  SystemPowerDeviceNodeCreated = TRUE;
803  }
804  }
805 
806  ObDereferenceObject(fdo);
808  }
809  else
810  {
811  // lower filters (if already started) will be removed upon this request
814  break;
815  }
816  }
817 
818 #if DBG
819  PDEVICE_OBJECT attachedDO = IoGetAttachedDevice(DeviceNode->PhysicalDeviceObject);
820  if (attachedDO->Flags & DO_DEVICE_INITIALIZING)
821  {
822  DPRINT1("DO_DEVICE_INITIALIZING is not cleared on a device 0x%p!\n", attachedDO);
823  }
824 #endif
825  }
826 
827 Cleanup:
828  while (!IsListEmpty(&drvListHead))
829  {
830  PLIST_ENTRY listEntry = RemoveHeadList(&drvListHead);
831  PADD_DEV_DRIVERS_LIST driverEntry;
832  driverEntry = CONTAINING_RECORD(listEntry, ADD_DEV_DRIVERS_LIST, ListEntry);
833 
834  // drivers which don't have any devices (in case of failure) will be cleaned up
835  if (driverEntry->DriverObject)
836  {
837  ObDereferenceObject(driverEntry->DriverObject);
838  }
839  ExFreePoolWithTag(driverEntry, TAG_PNP_DEVACTION);
840  }
841 
842  ZwClose(SubKey);
843  if (ClassKey != NULL)
844  {
845  ZwClose(ClassKey);
846  }
847 
848  return Status;
849 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:850
#define DNF_HAS_PROBLEM
Definition: iotypes.h:183
PNP_DEVNODE_STATE PiSetDevNodeState(_In_ PDEVICE_NODE DeviceNode, _In_ PNP_DEVNODE_STATE NewState)
Definition: devnode.c:108
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:56
LONG NTSTATUS
Definition: precomp.h:26
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:65
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
LIST_ENTRY ListEntry
Definition: devaction.c:77
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2282
unsigned char BOOLEAN
#define TAG_PNP_DEVACTION
Definition: devaction.c:53
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
ADD_DEV_DRIVER_TYPE DriverType
Definition: devaction.c:79
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
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
Status
Definition: gdiplustypes.h:24
VOID PiSetDevNodeProblem(_In_ PDEVICE_NODE DeviceNode, _In_ UINT32 Problem)
Definition: devnode.c:132
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
PDRIVER_OBJECT DriverObject
Definition: devaction.c:78
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ENUM_ROOT
Definition: io.h:53
#define ObDereferenceObject
Definition: obfuncs.h:203
static NTSTATUS PiAttachFilterDrivers(PLIST_ENTRY DriversListHead, PDEVICE_NODE DeviceNode, HANDLE EnumSubKey, HANDLE ClassKey, BOOLEAN Lower, BOOLEAN LoadDrivers)
Calls PiAttachFilterDriversCallback for filter drivers (if any)
Definition: devaction.c:531
#define REGSTR_VAL_CLASSGUID
Definition: regstr.h:422
static NTSTATUS NTAPI PiAttachFilterDriversCallback(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Ctx, PVOID EntryContext)
Loads and/or returns the driver associated with the registry entry if the driver is enabled....
Definition: devaction.c:362
PDEVICE_NODE PopSystemPowerDeviceNode
Definition: power.c:25
Definition: Node.h:9
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
#define DNF_LEGACY_DRIVER
Definition: iotypes.h:182
Definition: typedefs.h:119
static const WCHAR Cleanup[]
Definition: register.c:80
#define REGSTR_KEY_DEVICE_PROPERTIES
Definition: regstr.h:752
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2220
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1607
#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:1456
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
PDEVICE_OBJECT NTAPI IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1385
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define ObReferenceObject
Definition: obfuncs.h:204
#define FILE_DEVICE_ACPI
Definition: winioctl.h:156
#define ULONG_PTR
Definition: config.h:101
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define CM_PROB_FAILED_ADD
Definition: cfg.h:61
#define DPRINT
Definition: sndvol32.h:71
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
#define CM_PROB_REGISTRY
Definition: cfg.h:49
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PAGED_CODE()
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22

Referenced by PiDevNodeStateMachine(), and PipDeviceActionWorker().

◆ PiDevNodeStateMachine()

static VOID PiDevNodeStateMachine ( _In_ PDEVICE_NODE  RootNode)
static

Definition at line 2313 of file devaction.c.

2315 {
2316  NTSTATUS status;
2317  BOOLEAN doProcessAgain;
2318  PDEVICE_NODE currentNode = RootNode;
2319  PDEVICE_OBJECT referencedObject;
2320 
2321  do
2322  {
2323  doProcessAgain = FALSE;
2324 
2325  // The device can be removed during processing, but we still need its Parent and Sibling
2326  // links to continue the tree traversal. So keep the link till the and of a cycle
2327  referencedObject = currentNode->PhysicalDeviceObject;
2328  ObReferenceObject(referencedObject);
2329 
2330  // Devices with problems are skipped (unless they are not being removed)
2331  if (currentNode->Flags & DNF_HAS_PROBLEM &&
2332  currentNode->State != DeviceNodeAwaitingQueuedRemoval)
2333  {
2334  goto skipEnum;
2335  }
2336 
2337  switch (currentNode->State)
2338  {
2339  case DeviceNodeUnspecified: // this state is not used
2340  break;
2342  DPRINT("DeviceNodeUninitialized %wZ\n", &currentNode->InstancePath);
2343  status = PiInitializeDevNode(currentNode);
2344  doProcessAgain = NT_SUCCESS(status);
2345  break;
2346  case DeviceNodeInitialized:
2347  DPRINT("DeviceNodeInitialized %wZ\n", &currentNode->InstancePath);
2349  doProcessAgain = NT_SUCCESS(status);
2350  break;
2352  DPRINT("DeviceNodeDriversAdded %wZ\n", &currentNode->InstancePath);
2353  status = IopAssignDeviceResources(currentNode);
2354  doProcessAgain = NT_SUCCESS(status);
2355  break;
2357  DPRINT("DeviceNodeResourcesAssigned %wZ\n", &currentNode->InstancePath);
2358  // send IRP_MN_START_DEVICE
2359  PiIrpStartDevice(currentNode);
2360 
2361  // skip DeviceNodeStartPending, it is probably used for an async IRP_MN_START_DEVICE
2363  doProcessAgain = TRUE;
2364  break;
2365  case DeviceNodeStartPending: // skipped on XP/2003
2366  break;
2368  DPRINT("DeviceNodeStartCompletion %wZ\n", &currentNode->InstancePath);
2369  status = currentNode->CompletionStatus;
2370  doProcessAgain = TRUE;
2371  if (!NT_SUCCESS(status))
2372  {
2376 
2377  PiSetDevNodeProblem(currentNode, problem);
2379  }
2380  else
2381  {
2382  // TODO: IopDoDeferredSetInterfaceState and IopAllocateLegacyBootResources
2383  // are called here too
2384 
2386  }
2387  break;
2389  DPRINT("DeviceNodeStartPostWork %wZ\n", &currentNode->InstancePath);
2390  status = PiStartDeviceFinal(currentNode);
2391  doProcessAgain = TRUE;
2392  break;
2393  case DeviceNodeStarted:
2394  if (currentNode->Flags & DNF_REENUMERATE)
2395  {
2396  DPRINT("DeviceNodeStarted REENUMERATE %wZ\n", &currentNode->InstancePath);
2397  currentNode->Flags &= ~DNF_REENUMERATE;
2399 
2400  // again, skip DeviceNodeEnumeratePending as with the starting sequence
2402  doProcessAgain = TRUE;
2403  }
2404  break;
2406  // we're here after sending IRP_MN_QUERY_STOP_DEVICE
2407  status = currentNode->CompletionStatus;
2408  if (NT_SUCCESS(status))
2409  {
2410  PiSetDevNodeState(currentNode, DeviceNodeStopped);
2411  }
2412  else
2413  {
2414  PiIrpCancelStopDevice(currentNode);
2415  PiSetDevNodeState(currentNode, DeviceNodeStarted);
2416  }
2417  break;
2418  case DeviceNodeStopped:
2419  // TODO: do resource rebalance (not implemented)
2420  ASSERT(FALSE);
2421  break;
2423  break;
2424  case DeviceNodeEnumeratePending: // skipped on XP/2003
2425  break;
2427  DPRINT("DeviceNodeEnumerateCompletion %wZ\n", &currentNode->InstancePath);
2428  status = PiEnumerateDevice(currentNode);
2429  doProcessAgain = TRUE;
2430  break;
2432  break;
2434  DPRINT("DeviceNodeAwaitingQueuedRemoval %wZ\n", &currentNode->InstancePath);
2435  status = IopRemoveDevice(currentNode);
2436  break;
2438  break;
2440  break;
2441  case DeviceNodeRemoved:
2442  break;
2444  break;
2445  case DeviceNodeDeleted:
2446  break;
2447  default:
2448  break;
2449  }
2450 
2451 skipEnum:
2452  if (!doProcessAgain)
2453  {
2454  KIRQL OldIrql;
2456  /* If we have a child, simply go down the tree */
2457  if (currentNode->State != DeviceNodeRemoved && currentNode->Child != NULL)
2458  {
2459  ASSERT(currentNode->Child->Parent == currentNode);
2460  currentNode = currentNode->Child;
2461  }
2462  else
2463  {
2464  while (currentNode != RootNode)
2465  {
2466  /* All children processed -- go sideways */
2467  if (currentNode->Sibling != NULL)
2468  {
2469  ASSERT(currentNode->Sibling->Parent == currentNode->Parent);
2470  currentNode = currentNode->Sibling;
2471  break;
2472  }
2473  else
2474  {
2475  /* We're the last sibling -- go back up */
2476  ASSERT(currentNode->Parent->LastChild == currentNode);
2477  currentNode = currentNode->Parent;
2478  }
2479  /* We already visited the parent and all its children, so keep looking */
2480  }
2481  }
2483  }
2484  ObDereferenceObject(referencedObject);
2485  } while (doProcessAgain || currentNode != RootNode);
2486 }
ULONG Flags
Definition: iotypes.h:847
static NTSTATUS PiInitializeDevNode(_In_ PDEVICE_NODE DeviceNode)
Definition: devaction.c:1189
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:850
static NTSTATUS PiEnumerateDevice(_In_ PDEVICE_NODE DeviceNode)
Definition: devaction.c:2121
#define DNF_HAS_PROBLEM
Definition: iotypes.h:183
PNP_DEVNODE_STATE PiSetDevNodeState(_In_ PDEVICE_NODE DeviceNode, _In_ PNP_DEVNODE_STATE NewState)
Definition: devnode.c:108
NTSTATUS PiIrpCancelStopDevice(_In_ PDEVICE_NODE DeviceNode)
Definition: pnpirp.c:154
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define CM_PROB_FAILED_START
Definition: cfg.h:40
NTSTATUS PiIrpStartDevice(_In_ PDEVICE_NODE DeviceNode)
Definition: pnpirp.c:87
struct _DEVICE_NODE * Parent
Definition: iotypes.h:836
static NTSTATUS IopRemoveDevice(PDEVICE_NODE DeviceNode)
Definition: devaction.c:1975
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _DEVICE_NODE * Child
Definition: iotypes.h:835
#define FALSE
Definition: types.h:117
unsigned int UINT32
unsigned char BOOLEAN
PNP_DEVNODE_STATE State
Definition: iotypes.h:841
VOID PiSetDevNodeProblem(_In_ PDEVICE_NODE DeviceNode, _In_ UINT32 Problem)
Definition: devnode.c:132
#define ASSERT(a)
Definition: mode.c:44
NTSTATUS CompletionStatus
Definition: iotypes.h:845
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DNF_REENUMERATE
Definition: iotypes.h:173
static NTSTATUS PiCallDriverAddDevice(_In_ PDEVICE_NODE DeviceNode, _In_ BOOLEAN LoadDrivers)
Loads all drivers for a device node (actual service and filters) and calls their AddDevice routine.
Definition: devaction.c:594
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define ObDereferenceObject
Definition: obfuncs.h:203
BOOLEAN PnPBootDriversInitialized
Definition: pnpinit.c:27
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define CM_PROB_NEED_RESTART
Definition: cfg.h:44
UNICODE_STRING InstancePath
Definition: iotypes.h:853
KSPIN_LOCK IopDeviceTreeLock
Definition: devnode.c:19
#define STATUS_PNP_REBOOT_REQUIRED
Definition: ntstatus.h:830
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
struct _DEVICE_NODE * Sibling
Definition: iotypes.h:834
#define ObReferenceObject
Definition: obfuncs.h:204
static NTSTATUS PiStartDeviceFinal(_In_ PDEVICE_NODE DeviceNode)
Definition: devaction.c:1502
NTSTATUS NTAPI IopAssignDeviceResources(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:1106
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS PiIrpQueryDeviceRelations(_In_ PDEVICE_NODE DeviceNode, _In_ DEVICE_RELATION_TYPE Type)
Definition: pnpirp.c:176
static SERVICE_STATUS status
Definition: service.c:31
PCONFIGURATION_COMPONENT_DATA RootNode
Definition: macharm.c:19
Definition: ps.c:97

Referenced by PipDeviceActionWorker().

◆ PiEnumerateDevice()

static NTSTATUS PiEnumerateDevice ( _In_ PDEVICE_NODE  DeviceNode)
static

Definition at line 2121 of file devaction.c.

2123 {
2124  PDEVICE_OBJECT ChildDeviceObject;
2125  PDEVICE_NODE ChildDeviceNode;
2126  ULONG i;
2127 
2128  // bus relations are already obtained for this device node
2129 
2130  if (!NT_SUCCESS(DeviceNode->CompletionStatus))
2131  {
2132  DPRINT("QDR request failed for %wZ, status %x\n",
2133  &DeviceNode->InstancePath, DeviceNode->CompletionStatus);
2134  // treat as if there are no child objects
2135  }
2136 
2137  PDEVICE_RELATIONS DeviceRelations = DeviceNode->OverUsed1.PendingDeviceRelations;
2138  DeviceNode->OverUsed1.PendingDeviceRelations = NULL;
2139 
2140  // it's acceptable not to have PDOs
2141  if (!DeviceRelations)
2142  {
2144  DPRINT("No PDOs\n");
2145  return STATUS_SUCCESS;
2146  }
2147 
2148  // mark children nodes as non-present (those not returned in DR request will be removed)
2149  for (PDEVICE_NODE child = DeviceNode->Child; child != NULL; child = child->Sibling)
2150  {
2151  child->Flags &= ~DNF_ENUMERATED;
2152  }
2153 
2154  DPRINT("PiEnumerateDevice: enumerating %u children\n", DeviceRelations->Count);
2155 
2156  // create device nodes for all new children and set DNF_ENUMERATED back for old ones
2157  for (i = 0; i < DeviceRelations->Count; i++)
2158  {
2159  ChildDeviceObject = DeviceRelations->Objects[i];
2160  ASSERT((ChildDeviceObject->Flags & DO_DEVICE_INITIALIZING) == 0);
2161 
2162  ChildDeviceNode = IopGetDeviceNode(ChildDeviceObject);
2163  if (!ChildDeviceNode)
2164  {
2165  /* One doesn't exist, create it */
2166  ChildDeviceNode = PipAllocateDeviceNode(ChildDeviceObject);
2167  if (ChildDeviceNode)
2168  {
2169  PiInsertDevNode(ChildDeviceNode, DeviceNode);
2170 
2171  /* Mark the node as enumerated */
2172  ChildDeviceNode->Flags |= DNF_ENUMERATED;
2173 
2174  /* Mark the DO as bus enumerated */
2175  ChildDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
2176  }
2177  else
2178  {
2179  /* Ignore this DO */
2180  DPRINT1("PipAllocateDeviceNode() failed. Skipping PDO %u\n", i);
2181  ObDereferenceObject(ChildDeviceObject);
2182  }
2183  }
2184  else
2185  {
2186  /* Mark it as enumerated */
2187  ChildDeviceNode->Flags |= DNF_ENUMERATED;
2188  ObDereferenceObject(ChildDeviceObject);
2189  }
2190  }
2191  ExFreePool(DeviceRelations);
2192 
2193  // time to remove non-reported devices
2194  for (PDEVICE_NODE child = DeviceNode->Child; child != NULL; child = child->Sibling)
2195  {
2196  if (!(child->Flags & (DNF_ENUMERATED|DNF_DEVICE_GONE)))
2197  {
2198  // this flag indicates that this is a surprise removal
2199  child->Flags |= DNF_DEVICE_GONE;
2201  }
2202  }
2203 
2205  return STATUS_SUCCESS;
2206 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
ULONG Flags
Definition: iotypes.h:847
PNP_DEVNODE_STATE PiSetDevNodeState(_In_ PDEVICE_NODE DeviceNode, _In_ PNP_DEVNODE_STATE NewState)
Definition: devnode.c:108
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
static HWND child
Definition: cursoricon.c:298
PDEVICE_NODE PipAllocateDeviceNode(IN PDEVICE_OBJECT PhysicalDeviceObject)
#define DO_BUS_ENUMERATED_DEVICE
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
Definition: Node.h:9
#define DNF_DEVICE_GONE
Definition: iotypes.h:186
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
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
VOID PiInsertDevNode(_In_ PDEVICE_NODE DeviceNode, _In_ PDEVICE_NODE ParentNode)
Definition: devnode.c:80
unsigned int ULONG
Definition: retypes.h:1
#define DNF_ENUMERATED
Definition: iotypes.h:174
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
PDEVICE_NODE FASTCALL IopGetDeviceNode(IN PDEVICE_OBJECT DeviceObject)

Referenced by PiDevNodeStateMachine().

◆ PiInitializeDevNode()

static NTSTATUS PiInitializeDevNode ( _In_ PDEVICE_NODE  DeviceNode)
static

Definition at line 1189 of file devaction.c.

1191 {
1193  NTSTATUS Status;
1194  HANDLE InstanceKey = NULL;
1195  UNICODE_STRING InstancePathU;
1196  PDEVICE_OBJECT OldDeviceObject;
1197 
1198  DPRINT("PiProcessNewDevNode(%p)\n", DeviceNode);
1199  DPRINT("PDO 0x%p\n", DeviceNode->PhysicalDeviceObject);
1200 
1201  /*
1202  * FIXME: For critical errors, cleanup and disable device, but always
1203  * return STATUS_SUCCESS.
1204  */
1205 
1206  Status = IopCreateDeviceInstancePath(DeviceNode, &InstancePathU);
1207  if (!NT_SUCCESS(Status))
1208  {
1210  {
1211  DPRINT1("IopCreateDeviceInstancePath() failed with status 0x%lx\n", Status);
1212  }
1213  return Status;
1214  }
1215 
1216  /* Verify that this is not a duplicate */
1217  OldDeviceObject = IopGetDeviceObjectFromDeviceInstance(&InstancePathU);
1218  if (OldDeviceObject != NULL)
1219  {
1220  PDEVICE_NODE OldDeviceNode = IopGetDeviceNode(OldDeviceObject);
1221 
1222  DPRINT1("Duplicate device instance '%wZ'\n", &InstancePathU);
1223  DPRINT1("Current instance parent: '%wZ'\n", &DeviceNode->Parent->InstancePath);
1224  DPRINT1("Old instance parent: '%wZ'\n", &OldDeviceNode->Parent->InstancePath);
1225 
1226  KeBugCheckEx(PNP_DETECTED_FATAL_ERROR,
1227  0x01,
1228  (ULONG_PTR)DeviceNode->PhysicalDeviceObject,
1229  (ULONG_PTR)OldDeviceObject,
1230  0);
1231  }
1232 
1233  DeviceNode->InstancePath = InstancePathU;
1234 
1235  DPRINT("InstancePath is %S\n", DeviceNode->InstancePath.Buffer);
1236 
1237  /*
1238  * Create registry key for the instance id, if it doesn't exist yet
1239  */
1240  Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
1241  if (!NT_SUCCESS(Status))
1242  {
1243  DPRINT1("Failed to create the instance key! (Status %lx)\n", Status);
1244 
1245  /* We have to return success otherwise we abort the traverse operation */
1246  return STATUS_SUCCESS;
1247  }
1248 
1249  IopQueryHardwareIds(DeviceNode, InstanceKey);
1250 
1251  IopQueryCompatibleIds(DeviceNode, InstanceKey);
1252 
1253  DeviceNode->Flags |= DNF_IDS_QUERIED;
1254 
1255  // Set the device's DeviceDesc and LocationInformation fields
1256  PiSetDevNodeText(DeviceNode, InstanceKey);
1257 
1258  DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n");
1259 
1260