ReactOS  0.4.15-dev-4572-gde972e2
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
 

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...
 
NTSTATUS IopUpdateResourceMapForPnPDevice (IN PDEVICE_NODE DeviceNode)
 
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)
 
static NTSTATUS PiUpdateDeviceState (_In_ PDEVICE_NODE DeviceNode)
 Processes the IoInvalidateDeviceState request. More...
 
static NTSTATUS PiEnumerateDevice (_In_ PDEVICE_NODE DeviceNode)
 
static NTSTATUS NTAPI IopSendEject (IN PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI IoRequestDeviceEject (IN PDEVICE_OBJECT PhysicalDeviceObject)
 
static VOID PiFakeResourceRebalance (_In_ PDEVICE_NODE DeviceNode)
 
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.

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 64 of file devaction.c.

Function Documentation

◆ IopCancelPrepareDeviceForRemoval()

static VOID IopCancelPrepareDeviceForRemoval ( PDEVICE_OBJECT  DeviceObject)
static

Definition at line 1778 of file devaction.c.

1779 {
1782  PDEVICE_RELATIONS DeviceRelations;
1783  NTSTATUS Status;
1784 
1786 
1787  Stack.Parameters.QueryDeviceRelations.Type = RemovalRelations;
1788 
1790  &IoStatusBlock,
1792  &Stack);
1793  if (!NT_SUCCESS(Status))
1794  {
1795  DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
1796  DeviceRelations = NULL;
1797  }
1798  else
1799  {
1800  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
1801  }
1802 
1803  if (DeviceRelations)
1804  IopCancelRemoveDeviceRelations(DeviceRelations);
1805 }
LONG NTSTATUS
Definition: precomp.h:26
static VOID NTAPI IopCancelRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1727
_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:1760
#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 1737 of file devaction.c.

1738 {
1739  PDEVICE_NODE ChildDeviceNode, NextDeviceNode;
1740  KIRQL OldIrql;
1741 
1743  ChildDeviceNode = ParentDeviceNode->Child;
1744  while (ChildDeviceNode != NULL)
1745  {
1746  NextDeviceNode = ChildDeviceNode->Sibling;
1748 
1750 
1751  ChildDeviceNode = NextDeviceNode;
1752 
1754  }
1756 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:855
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _DEVICE_NODE * Child
Definition: iotypes.h:840
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
KSPIN_LOCK IopDeviceTreeLock
Definition: devnode.c:19
static VOID IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1778
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
struct _DEVICE_NODE * Sibling
Definition: iotypes.h:839

Referenced by IoRequestDeviceEject().

◆ IopCancelRemoveDevice()

static VOID NTAPI IopCancelRemoveDevice ( IN PDEVICE_OBJECT  DeviceObject)
static

Definition at line 1727 of file devaction.c.

1728 {
1729  /* Drivers should never fail a IRP_MN_CANCEL_REMOVE_DEVICE request */
1731 
1732  PiNotifyTargetDeviceChange(&GUID_TARGET_DEVICE_REMOVE_CANCELLED, DeviceObject, NULL);
1733 }
#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:1579
_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 1760 of file devaction.c.

1761 {
1762  /* This function DOES dereference the device objects in all cases */
1763 
1764  ULONG i;
1765 
1766  for (i = 0; i < DeviceRelations->Count; i++)
1767  {
1768  IopCancelPrepareDeviceForRemoval(DeviceRelations->Objects[i]);
1769  ObDereferenceObject(DeviceRelations->Objects[i]);
1770  DeviceRelations->Objects[i] = NULL;
1771  }
1772 
1773  ExFreePool(DeviceRelations);
1774 }
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
#define ObDereferenceObject
Definition: obfuncs.h:203
static VOID IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1778
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 213 of file devaction.c.

216 {
218  UNICODE_STRING DeviceId;
222  UNICODE_STRING ParentIdPrefix = { 0, 0, NULL };
224  BOOLEAN IsValidID;
225 
226  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryDeviceID to device stack\n");
227 
228  Stack.Parameters.QueryId.IdType = BusQueryDeviceID;
229  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
230  &IoStatusBlock,
232  &Stack);
233  if (!NT_SUCCESS(Status))
234  {
235  DPRINT1("IopInitiatePnpIrp(BusQueryDeviceID) failed (Status %x)\n", Status);
236  return Status;
237  }
238 
240 
241  if (!IsValidID)
242  {
243  DPRINT1("Invalid DeviceID. DeviceNode - %p\n", DeviceNode);
244  }
245 
246  /* Save the device id string */
248 
249  DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack (after enumeration)\n");
250 
252  if (!NT_SUCCESS(Status))
253  {
255  {
256  DPRINT1("IopQueryDeviceCapabilities() failed (Status 0x%08lx)\n", Status);
257  }
258  RtlFreeUnicodeString(&DeviceId);
259  return Status;
260  }
261 
262  /* This bit is only check after enumeration */
263  if (DeviceCapabilities.HardwareDisabled)
264  {
265  /* FIXME: Cleanup device */
266  RtlFreeUnicodeString(&DeviceId);
268  }
269 
270  if (!DeviceCapabilities.UniqueID)
271  {
272  /* Device has not a unique ID. We need to prepend parent bus unique identifier */
273  DPRINT("Instance ID is not unique\n");
274  Status = IopGetParentIdPrefix(DeviceNode, &ParentIdPrefix);
275  if (!NT_SUCCESS(Status))
276  {
277  DPRINT1("IopGetParentIdPrefix() failed (Status 0x%08lx)\n", Status);
278  RtlFreeUnicodeString(&DeviceId);
279  return Status;
280  }
281  }
282 
283  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryInstanceID to device stack\n");
284 
285  Stack.Parameters.QueryId.IdType = BusQueryInstanceID;
286  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
287  &IoStatusBlock,
289  &Stack);
290  if (!NT_SUCCESS(Status))
291  {
292  DPRINT("IopInitiatePnpIrp(BusQueryInstanceID) failed (Status %lx)\n", Status);
294  }
295 
297  {
299 
300  if (!IsValidID)
301  {
302  DPRINT1("Invalid InstanceID. DeviceNode - %p\n", DeviceNode);
303  }
304  }
305 
308 
309  InstancePath->Length = 0;
310  InstancePath->MaximumLength = DeviceId.Length + sizeof(WCHAR) +
311  ParentIdPrefix.Length +
312  InstanceId.Length +
313  sizeof(UNICODE_NULL);
314  if (ParentIdPrefix.Length && InstanceId.Length)
315  {
316  InstancePath->MaximumLength += sizeof(WCHAR);
317  }
318 
319  InstancePath->Buffer = ExAllocatePoolWithTag(PagedPool,
320  InstancePath->MaximumLength,
321  TAG_IO);
322  if (!InstancePath->Buffer)
323  {
325  RtlFreeUnicodeString(&ParentIdPrefix);
326  RtlFreeUnicodeString(&DeviceId);
328  }
329 
330  /* Start with the device id */
331  RtlCopyUnicodeString(InstancePath, &DeviceId);
332  RtlAppendUnicodeToString(InstancePath, L"\\");
333 
334  /* Add information from parent bus device to InstancePath */
335  RtlAppendUnicodeStringToString(InstancePath, &ParentIdPrefix);
336  if (ParentIdPrefix.Length && InstanceId.Length)
337  {
338  RtlAppendUnicodeToString(InstancePath, L"&");
339  }
340 
341  /* Finally, add the id returned by the driver stack */
343 
344  /*
345  * FIXME: Check for valid characters, if there is invalid characters
346  * then bugcheck
347  */
348 
350  RtlFreeUnicodeString(&DeviceId);
351  RtlFreeUnicodeString(&ParentIdPrefix);
352 
353  return STATUS_SUCCESS;
354 }
return STATUS_NOT_SUPPORTED
#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:75
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 L(x)
Definition: ntvdm.h:50
#define UNICODE_NULL
NTSTATUS NTAPI IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode, PDEVICE_CAPABILITIES DeviceCaps)
Definition: devaction.c:854
_Must_inspect_result_ _In_opt_ PVOID _In_opt_ PVOID InstanceId
Definition: fsrtlfuncs.h:907
unsigned char BOOLEAN
#define DeviceCapabilities
Definition: wingdi.h:4449
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:122
#define ASSERT(a)
Definition: mode.c:44
NTSTATUS IopGetParentIdPrefix(PDEVICE_NODE DeviceNode, PUNICODE_STRING ParentIdPrefix)
Definition: pnpmgr.c:760
__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
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 411 of file pnpmgr.c.

412 {
413  USHORT i = 0, FoundIndex = 0xFFFF;
414  ULONG NewSize;
415  PVOID NewList;
416 
417  /* Acquire the lock */
419 
420  /* Loop all entries */
421  while (i < PnpBusTypeGuidList->GuidCount)
422  {
423  /* Try to find a match */
424  if (RtlCompareMemory(BusTypeGuid,
426  sizeof(GUID)) == sizeof(GUID))
427  {
428  /* Found it */
429  FoundIndex = i;
430  goto Quickie;
431  }
432  i++;
433  }
434 
435  /* Check if we have to grow the list */
437  {
438  /* Calculate the new size */
439  NewSize = sizeof(IO_BUS_TYPE_GUID_LIST) +
440  (sizeof(GUID) * PnpBusTypeGuidList->GuidCount);
441 
442  /* Allocate the new copy */
443  NewList = ExAllocatePool(PagedPool, NewSize);
444 
445  if (!NewList)
446  {
447  /* Fail */
449  goto Quickie;
450  }
451 
452  /* Now copy them, decrease the size too */
453  NewSize -= sizeof(GUID);
455 
456  /* Free the old list */
458 
459  /* Use the new buffer */
460  PnpBusTypeGuidList = NewList;
461  }
462 
463  /* Copy the new GUID */
465  BusTypeGuid,
466  sizeof(GUID));
467 
468  /* The new entry is the index */
469  FoundIndex = (USHORT)PnpBusTypeGuidList->GuidCount;
471 
472 Quickie:
474  return FoundIndex;
475 }
GUID Guids[1]
Definition: io.h:420
PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList
Definition: pnpmgr.c:27
FAST_MUTEX Lock
Definition: io.h:419
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 122 of file plugplay.c.

123 {
124  if (IopRootDeviceNode == NULL)
125  return NULL;
126 
127  if (DeviceInstance == NULL ||
128  DeviceInstance->Length == 0)
129  {
131  {
134  }
135  else
136  return NULL;
137  }
138 
140 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:855
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
static PDEVICE_OBJECT IopTraverseDeviceNode(PDEVICE_NODE Node, PUNICODE_STRING DeviceInstance)
Definition: plugplay.c:93
_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(), IopInitializeDevice(), PiControlSyncDeviceAction(), and PiInitializeDevNode().

◆ IopGetParentIdPrefix()

NTSTATUS IopGetParentIdPrefix ( PDEVICE_NODE  DeviceNode,
PUNICODE_STRING  ParentIdPrefix 
)

Definition at line 760 of file pnpmgr.c.

762 {
763  const UNICODE_STRING EnumKeyPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
764  ULONG KeyNameBufferLength;
765  PKEY_VALUE_PARTIAL_INFORMATION ParentIdPrefixInformation = NULL;
766  UNICODE_STRING KeyName = {0, 0, NULL};
767  UNICODE_STRING KeyValue;
769  HANDLE hKey = NULL;
770  ULONG crc32;
772 
773  /* HACK: As long as some devices have a NULL device
774  * instance path, the following test is required :(
775  */
776  if (DeviceNode->Parent->InstancePath.Length == 0)
777  {
778  DPRINT1("Parent of %wZ has NULL Instance path, please report!\n",
779  &DeviceNode->InstancePath);
780  return STATUS_UNSUCCESSFUL;
781  }
782 
783  /* 1. Try to retrieve ParentIdPrefix from registry */
784  KeyNameBufferLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + sizeof(L"12345678&12345678");
785  ParentIdPrefixInformation = ExAllocatePoolWithTag(PagedPool,
786  KeyNameBufferLength + sizeof(UNICODE_NULL),
787  TAG_IO);
788  if (!ParentIdPrefixInformation)
789  {
791  }
792 
793  KeyName.Length = 0;
794  KeyName.MaximumLength = EnumKeyPath.Length +
795  DeviceNode->Parent->InstancePath.Length +
796  sizeof(UNICODE_NULL);
798  KeyName.MaximumLength,
799  TAG_IO);
800  if (!KeyName.Buffer)
801  {
803  goto cleanup;
804  }
805 
806  RtlCopyUnicodeString(&KeyName, &EnumKeyPath);
807  RtlAppendUnicodeStringToString(&KeyName, &DeviceNode->Parent->InstancePath);
808 
810  if (!NT_SUCCESS(Status))
811  {
812  goto cleanup;
813  }
814  RtlInitUnicodeString(&ValueName, L"ParentIdPrefix");
815  Status = ZwQueryValueKey(hKey,
816  &ValueName,
818  ParentIdPrefixInformation,
819  KeyNameBufferLength,
820  &KeyNameBufferLength);
821  if (NT_SUCCESS(Status))
822  {
823  if (ParentIdPrefixInformation->Type != REG_SZ)
824  {
826  }
827  else
828  {
829  KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
830  KeyValue.Length = KeyValue.MaximumLength - sizeof(UNICODE_NULL);
831  KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
832  ASSERT(KeyValue.Buffer[KeyValue.Length / sizeof(WCHAR)] == UNICODE_NULL);
833  }
834  goto cleanup;
835  }
837  {
838  /* FIXME how do we get here and why is ParentIdPrefixInformation valid? */
839  KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
840  KeyValue.Length = KeyValue.MaximumLength - sizeof(UNICODE_NULL);
841  KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
842  ASSERT(KeyValue.Buffer[KeyValue.Length / sizeof(WCHAR)] == UNICODE_NULL);
843  goto cleanup;
844  }
845 
846  /* 2. Create the ParentIdPrefix value */
848  (PUCHAR)DeviceNode->Parent->InstancePath.Buffer,
849  DeviceNode->Parent->InstancePath.Length);
850 
851  RtlStringCbPrintfW((PWSTR)ParentIdPrefixInformation,
852  KeyNameBufferLength,
853  L"%lx&%lx",
854  DeviceNode->Parent->Level,
855  crc32);
856  RtlInitUnicodeString(&KeyValue, (PWSTR)ParentIdPrefixInformation);
857 
858  /* 3. Try to write the ParentIdPrefix to registry */
859  Status = ZwSetValueKey(hKey,
860  &ValueName,
861  0,
862  REG_SZ,
863  KeyValue.Buffer,
864  ((ULONG)wcslen(KeyValue.Buffer) + 1) * sizeof(WCHAR));
865 
866 cleanup:
867  if (NT_SUCCESS(Status))
868  {
869  /* Duplicate the string to return it */
871  &KeyValue,
872  ParentIdPrefix);
873  }
874  ExFreePoolWithTag(ParentIdPrefixInformation, TAG_IO);
876  if (hKey != NULL)
877  {
878  ZwClose(hKey);
879  }
880  return Status;
881 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:75
#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:1455
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 L(x)
Definition: ntvdm.h:50
#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
#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 45 of file pnpmgr.c.

46 {
48  HANDLE CriticalDeviceKey, InstanceKey;
50  UNICODE_STRING CriticalDeviceKeyU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\CriticalDeviceDatabase");
51  UNICODE_STRING CompatibleIdU = RTL_CONSTANT_STRING(L"CompatibleIDs");
52  UNICODE_STRING HardwareIdU = RTL_CONSTANT_STRING(L"HardwareID");
53  UNICODE_STRING ServiceU = RTL_CONSTANT_STRING(L"Service");
54  UNICODE_STRING ClassGuidU = RTL_CONSTANT_STRING(L"ClassGUID");
56  ULONG HidLength = 0, CidLength = 0, BufferLength;
57  PWCHAR IdBuffer, OriginalIdBuffer;
58 
59  /* Open the device instance key */
60  Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
61  if (Status != STATUS_SUCCESS)
62  return;
63 
64  Status = ZwQueryValueKey(InstanceKey,
65  &HardwareIdU,
67  NULL,
68  0,
69  &HidLength);
71  {
72  ZwClose(InstanceKey);
73  return;
74  }
75 
76  Status = ZwQueryValueKey(InstanceKey,
77  &CompatibleIdU,
79  NULL,
80  0,
81  &CidLength);
83  {
84  CidLength = 0;
85  }
86 
87  BufferLength = HidLength + CidLength;
88  BufferLength -= (((CidLength != 0) ? 2 : 1) * FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data));
89 
90  /* Allocate a buffer to hold data from both */
91  OriginalIdBuffer = IdBuffer = ExAllocatePool(PagedPool, BufferLength);
92  if (!IdBuffer)
93  {
94  ZwClose(InstanceKey);
95  return;
96  }
97 
98  /* Compute the buffer size */
99  if (HidLength > CidLength)
100  BufferLength = HidLength;
101  else
102  BufferLength = CidLength;
103 
104  PartialInfo = ExAllocatePool(PagedPool, BufferLength);
105  if (!PartialInfo)
106  {
107  ZwClose(InstanceKey);
108  ExFreePool(OriginalIdBuffer);
109  return;
110  }
111 
112  Status = ZwQueryValueKey(InstanceKey,
113  &HardwareIdU,
115  PartialInfo,
116  HidLength,
117  &HidLength);
118  if (Status != STATUS_SUCCESS)
119  {
120  ExFreePool(PartialInfo);
121  ExFreePool(OriginalIdBuffer);
122  ZwClose(InstanceKey);
123  return;
124  }
125 
126  /* Copy in HID info first (without 2nd terminating NULL if CID is present) */
127  HidLength = PartialInfo->DataLength - ((CidLength != 0) ? sizeof(WCHAR) : 0);
128  RtlCopyMemory(IdBuffer, PartialInfo->Data, HidLength);
129 
130  if (CidLength != 0)
131  {
132  Status = ZwQueryValueKey(InstanceKey,
133  &CompatibleIdU,
135  PartialInfo,
136  CidLength,
137  &CidLength);
138  if (Status != STATUS_SUCCESS)
139  {
140  ExFreePool(PartialInfo);
141  ExFreePool(OriginalIdBuffer);
142  ZwClose(InstanceKey);
143  return;
144  }
145 
146  /* Copy CID next */
147  CidLength = PartialInfo->DataLength;
148  RtlCopyMemory(((PUCHAR)IdBuffer) + HidLength, PartialInfo->Data, CidLength);
149  }
150 
151  /* Free our temp buffer */
152  ExFreePool(PartialInfo);
153 
155  &CriticalDeviceKeyU,
157  NULL,
158  NULL);
159  Status = ZwOpenKey(&CriticalDeviceKey,
162  if (!NT_SUCCESS(Status))
163  {
164  /* The critical device database doesn't exist because
165  * we're probably in 1st stage setup, but it's ok */
166  ExFreePool(OriginalIdBuffer);
167  ZwClose(InstanceKey);
168  return;
169  }
170 
171  while (*IdBuffer)
172  {
173  USHORT StringLength = (USHORT)wcslen(IdBuffer) + 1, Index;
174 
175  IopFixupDeviceId(IdBuffer);
176 
177  /* Look through all subkeys for a match */
178  for (Index = 0; TRUE; Index++)
179  {
180  ULONG NeededLength;
181  PKEY_BASIC_INFORMATION BasicInfo;
182 
183  Status = ZwEnumerateKey(CriticalDeviceKey,
184  Index,
186  NULL,
187  0,
188  &NeededLength);
190  break;
192  {
193  UNICODE_STRING ChildIdNameU, RegKeyNameU;
194 
195  BasicInfo = ExAllocatePool(PagedPool, NeededLength);
196  if (!BasicInfo)
197  {
198  /* No memory */
199  ExFreePool(OriginalIdBuffer);
200  ZwClose(CriticalDeviceKey);
201  ZwClose(InstanceKey);
202  return;
203  }
204 
205  Status = ZwEnumerateKey(CriticalDeviceKey,
206  Index,
208  BasicInfo,
209  NeededLength,
210  &NeededLength);
211  if (Status != STATUS_SUCCESS)
212  {
213  /* This shouldn't happen */
214  ExFreePool(BasicInfo);
215  continue;
216  }
217 
218  ChildIdNameU.Buffer = IdBuffer;
219  ChildIdNameU.MaximumLength = ChildIdNameU.Length = (StringLength - 1) * sizeof(WCHAR);
220  RegKeyNameU.Buffer = BasicInfo->Name;
221  RegKeyNameU.MaximumLength = RegKeyNameU.Length = (USHORT)BasicInfo->NameLength;
222 
223  if (RtlEqualUnicodeString(&ChildIdNameU, &RegKeyNameU, TRUE))
224  {
225  HANDLE ChildKeyHandle;
226 
228  &ChildIdNameU,
230  CriticalDeviceKey,
231  NULL);
232 
233  Status = ZwOpenKey(&ChildKeyHandle,
236  if (Status != STATUS_SUCCESS)
237  {
238  ExFreePool(BasicInfo);
239  continue;
240  }
241 
242  /* Check if there's already a driver installed */
243  Status = ZwQueryValueKey(InstanceKey,
244  &ClassGuidU,
246  NULL,
247  0,
248  &NeededLength);
250  {
251  ExFreePool(BasicInfo);
252  continue;
253  }
254 
255  Status = ZwQueryValueKey(ChildKeyHandle,
256  &ClassGuidU,
258  NULL,
259  0,
260  &NeededLength);
262  {
263  ExFreePool(BasicInfo);
264  continue;
265  }
266 
267  PartialInfo = ExAllocatePool(PagedPool, NeededLength);
268  if (!PartialInfo)
269  {
270  ExFreePool(OriginalIdBuffer);
271  ExFreePool(BasicInfo);
272  ZwClose(InstanceKey);
273  ZwClose(ChildKeyHandle);
274  ZwClose(CriticalDeviceKey);
275  return;
276  }
277 
278  /* Read ClassGUID entry in the CDDB */
279  Status = ZwQueryValueKey(ChildKeyHandle,
280  &ClassGuidU,
282  PartialInfo,
283  NeededLength,
284  &NeededLength);
285  if (Status != STATUS_SUCCESS)
286  {
287  ExFreePool(BasicInfo);
288  continue;
289  }
290 
291  /* Write it to the ENUM key */
292  Status = ZwSetValueKey(InstanceKey,
293  &ClassGuidU,
294  0,
295  REG_SZ,
296  PartialInfo->Data,
297  PartialInfo->DataLength);
298  if (Status != STATUS_SUCCESS)
299  {
300  ExFreePool(BasicInfo);
301  ExFreePool(PartialInfo);
302  ZwClose(ChildKeyHandle);
303  continue;
304  }
305 
306  Status = ZwQueryValueKey(ChildKeyHandle,
307  &ServiceU,
309  NULL,
310  0,
311  &NeededLength);
313  {
314  ExFreePool(PartialInfo);
315  PartialInfo = ExAllocatePool(PagedPool, NeededLength);
316  if (!PartialInfo)
317  {
318  ExFreePool(OriginalIdBuffer);
319  ExFreePool(BasicInfo);
320  ZwClose(InstanceKey);
321  ZwClose(ChildKeyHandle);
322  ZwClose(CriticalDeviceKey);
323  return;
324  }
325 
326  /* Read the service entry from the CDDB */
327  Status = ZwQueryValueKey(ChildKeyHandle,
328  &ServiceU,
330  PartialInfo,
331  NeededLength,
332  &NeededLength);
333  if (Status != STATUS_SUCCESS)
334  {
335  ExFreePool(BasicInfo);
336  ExFreePool(PartialInfo);
337  ZwClose(ChildKeyHandle);
338  continue;
339  }
340 
341  /* Write it to the ENUM key */
342  Status = ZwSetValueKey(InstanceKey,
343  &ServiceU,
344  0,
345  REG_SZ,
346  PartialInfo->Data,
347  PartialInfo->DataLength);
348  if (Status != STATUS_SUCCESS)
349  {
350  ExFreePool(BasicInfo);
351  ExFreePool(PartialInfo);
352  ZwClose(ChildKeyHandle);
353  continue;
354  }
355 
356  DPRINT("Installed service '%S' for critical device '%wZ'\n", PartialInfo->Data, &ChildIdNameU);
357  }
358  else
359  {
360  DPRINT1("Installed NULL service for critical device '%wZ'\n", &ChildIdNameU);
361  }
362 
363  ExFreePool(OriginalIdBuffer);
364  ExFreePool(PartialInfo);
365  ExFreePool(BasicInfo);
366  ZwClose(InstanceKey);
367  ZwClose(ChildKeyHandle);
368  ZwClose(CriticalDeviceKey);
369 
370  /* That's it */
371  return;
372  }
373 
374  ExFreePool(BasicInfo);
375  }
376  else
377  {
378  /* Umm, not sure what happened here */
379  continue;
380  }
381  }
382 
383  /* Advance to the next ID */
384  IdBuffer += StringLength;
385  }
386 
387  ExFreePool(OriginalIdBuffer);
388  ZwClose(InstanceKey);
389  ZwClose(CriticalDeviceKey);
390 }
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:522
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
#define L(x)
Definition: ntvdm.h:50
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
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
VOID IopFixupDeviceId(PWCHAR String)
Definition: pnpmgr.c:32
#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 1931 of file devaction.c.

1932 {
1936  PDEVICE_RELATIONS DeviceRelations;
1937  NTSTATUS Status;
1938 
1939  if ((DeviceNode->UserFlags & DNUF_NOT_DISABLEABLE) && !Force)
1940  {
1941  DPRINT1("Removal not allowed for %wZ\n", &DeviceNode->InstancePath);
1942  return STATUS_UNSUCCESSFUL;
1943  }
1944 
1946  {
1947  DPRINT1("Removal vetoed by failing the query remove request\n");
1948 
1950 
1951  return STATUS_UNSUCCESSFUL;
1952  }
1953 
1954  Stack.Parameters.QueryDeviceRelations.Type = RemovalRelations;
1955 
1957  &IoStatusBlock,
1959  &Stack);
1960  if (!NT_SUCCESS(Status))
1961  {
1962  DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
1963  DeviceRelations = NULL;
1964  }
1965  else
1966  {
1967  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
1968  }
1969 
1970  if (DeviceRelations)
1971  {
1972  Status = IopQueryRemoveDeviceRelations(DeviceRelations, Force);
1973  if (!NT_SUCCESS(Status))
1974  return Status;
1975  }
1976 
1978  if (!NT_SUCCESS(Status))
1979  {
1980  if (DeviceRelations)
1981  IopCancelRemoveDeviceRelations(DeviceRelations);
1982  return Status;
1983  }
1984 
1985  if (DeviceRelations)
1986  IopSendRemoveDeviceRelations(DeviceRelations);
1988 
1989  return STATUS_SUCCESS;
1990 }
static NTSTATUS IopQueryRemoveChildDevices(PDEVICE_NODE ParentDeviceNode, BOOLEAN Force)
Definition: devaction.c:1836
static NTSTATUS NTAPI IopQueryRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1810
#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:1727
_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:1693
Definition: Node.h:9
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static VOID IopSendRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations)
Definition: devaction.c:1676
static NTSTATUS IopQueryRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations, BOOLEAN Force)
Definition: devaction.c:1890
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:1760
#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 1022 of file devaction.c.

1024 {
1027  PWSTR Ptr;
1029  NTSTATUS Status;
1031  BOOLEAN IsValidID;
1032 
1033  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryCompatibleIDs to device stack\n");
1034 
1035  RtlZeroMemory(&Stack, sizeof(Stack));
1036  Stack.Parameters.QueryId.IdType = BusQueryCompatibleIDs;
1037  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
1038  &IoStatusBlock,
1040  &Stack);
1042  {
1044 
1045  if (!IsValidID)
1046  {
1047  DPRINT1("Invalid CompatibleIDs. DeviceNode - %p\n", DeviceNode);
1048  }
1049 
1050  TotalLength = 0;
1051 
1053  DPRINT("Compatible IDs:\n");
1054  while (*Ptr)
1055  {
1056  DPRINT(" %S\n", Ptr);
1057  Length = (ULONG)wcslen(Ptr) + 1;
1058 
1059  Ptr += Length;
1060  TotalLength += Length;
1061  }
1062  DPRINT("TotalLength: %hu\n", TotalLength);
1063  DPRINT("\n");
1064 
1065  RtlInitUnicodeString(&ValueName, L"CompatibleIDs");
1066  Status = ZwSetValueKey(InstanceKey,
1067  &ValueName,
1068  0,
1069  REG_MULTI_SZ,
1071  (TotalLength + 1) * sizeof(WCHAR));
1072  if (!NT_SUCCESS(Status))
1073  {
1074  DPRINT1("ZwSetValueKey() failed (Status %lx) or no Compatible ID returned\n", Status);
1075  }
1076  }
1077  else
1078  {
1079  DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
1080  }
1081 
1082  return Status;
1083 }
#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 L(x)
Definition: ntvdm.h:50
#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:122
__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 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 854 of file devaction.c.

856 {
857  IO_STATUS_BLOCK StatusBlock;
860  HANDLE InstanceKey;
862 
863  /* Set up the Header */
864  RtlZeroMemory(DeviceCaps, sizeof(DEVICE_CAPABILITIES));
865  DeviceCaps->Size = sizeof(DEVICE_CAPABILITIES);
866  DeviceCaps->Version = 1;
867  DeviceCaps->Address = -1;
868  DeviceCaps->UINumber = -1;
869 
870  /* Set up the Stack */
872  Stack.Parameters.DeviceCapabilities.Capabilities = DeviceCaps;
873 
874  /* Send the IRP */
875  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
876  &StatusBlock,
878  &Stack);
879  if (!NT_SUCCESS(Status))
880  {
882  {
883  DPRINT1("IRP_MN_QUERY_CAPABILITIES failed with status 0x%lx\n", Status);
884  }
885  return Status;
886  }
887 
888  /* Map device capabilities to capability flags */
889  DeviceNode->CapabilityFlags = 0;
890  if (DeviceCaps->LockSupported)
891  DeviceNode->CapabilityFlags |= 0x00000001; // CM_DEVCAP_LOCKSUPPORTED
892 
893  if (DeviceCaps->EjectSupported)
894  DeviceNode->CapabilityFlags |= 0x00000002; // CM_DEVCAP_EJECTSUPPORTED
895 
896  if (DeviceCaps->Removable)
897  DeviceNode->CapabilityFlags |= 0x00000004; // CM_DEVCAP_REMOVABLE
898 
899  if (DeviceCaps->DockDevice)
900  DeviceNode->CapabilityFlags |= 0x00000008; // CM_DEVCAP_DOCKDEVICE
901 
902  if (DeviceCaps->UniqueID)
903  DeviceNode->CapabilityFlags |= 0x00000010; // CM_DEVCAP_UNIQUEID
904 
905  if (DeviceCaps->SilentInstall)
906  DeviceNode->CapabilityFlags |= 0x00000020; // CM_DEVCAP_SILENTINSTALL
907 
908  if (DeviceCaps->RawDeviceOK)
909  DeviceNode->CapabilityFlags |= 0x00000040; // CM_DEVCAP_RAWDEVICEOK
910 
911  if (DeviceCaps->SurpriseRemovalOK)
912  DeviceNode->CapabilityFlags |= 0x00000080; // CM_DEVCAP_SURPRISEREMOVALOK
913 
914  if (DeviceCaps->HardwareDisabled)
915  DeviceNode->CapabilityFlags |= 0x00000100; // CM_DEVCAP_HARDWAREDISABLED
916 
917  if (DeviceCaps->NonDynamic)
918  DeviceNode->CapabilityFlags |= 0x00000200; // CM_DEVCAP_NONDYNAMIC
919 
920  if (DeviceCaps->NoDisplayInUI)
921  DeviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI;
922  else
923  DeviceNode->UserFlags &= ~DNUF_DONT_SHOW_IN_UI;
924 
925  Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
926  if (NT_SUCCESS(Status))
927  {
928  /* Set 'Capabilities' value */
929  RtlInitUnicodeString(&ValueName, L"Capabilities");
930  Status = ZwSetValueKey(InstanceKey,
931  &ValueName,
932  0,
933  REG_DWORD,
934  &DeviceNode->CapabilityFlags,
935  sizeof(ULONG));
936 
937  /* Set 'UINumber' value */
938  if (DeviceCaps->UINumber != MAXULONG)
939  {
940  RtlInitUnicodeString(&ValueName, L"UINumber");
941  Status = ZwSetValueKey(InstanceKey,
942  &ValueName,
943  0,
944  REG_DWORD,
945  &DeviceCaps->UINumber,
946  sizeof(ULONG));
947  }
948 
949  ZwClose(InstanceKey);
950  }
951 
952  return Status;
953 }
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:522
LONG NTSTATUS
Definition: precomp.h:26
DEVICE_CAPABILITIES
Definition: iotypes.h:965
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
#define L(x)
Definition: ntvdm.h:50
#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
#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 957 of file devaction.c.

959 {
962  PWSTR Ptr;
966  BOOLEAN IsValidID;
967 
968  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryHardwareIDs to device stack\n");
969 
970  RtlZeroMemory(&Stack, sizeof(Stack));
971  Stack.Parameters.QueryId.IdType = BusQueryHardwareIDs;
972  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
973  &IoStatusBlock,
975  &Stack);
976  if (NT_SUCCESS(Status))
977  {
979 
980  if (!IsValidID)
981  {
982  DPRINT1("Invalid HardwareIDs. DeviceNode - %p\n", DeviceNode);
983  }
984 
985  TotalLength = 0;
986 
988  DPRINT("Hardware IDs:\n");
989  while (*Ptr)
990  {
991  DPRINT(" %S\n", Ptr);
992  Length = (ULONG)wcslen(Ptr) + 1;
993 
994  Ptr += Length;
995  TotalLength += Length;
996  }
997  DPRINT("TotalLength: %hu\n", TotalLength);
998  DPRINT("\n");
999 
1000  RtlInitUnicodeString(&ValueName, L"HardwareID");
1001  Status = ZwSetValueKey(InstanceKey,
1002  &ValueName,
1003  0,
1004  REG_MULTI_SZ,
1006  (TotalLength + 1) * sizeof(WCHAR));
1007  if (!NT_SUCCESS(Status))
1008  {
1009  DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
1010  }
1011  }
1012  else
1013  {
1014  DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
1015  }
1016 
1017  return Status;
1018 }
#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 L(x)
Definition: ntvdm.h:50
#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:122
__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 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 1836 of file devaction.c.

1837 {
1838  PDEVICE_NODE ChildDeviceNode, NextDeviceNode, FailedRemoveDevice;
1839  NTSTATUS Status;
1840  KIRQL OldIrql;
1841 
1843  ChildDeviceNode = ParentDeviceNode->Child;
1844  while (ChildDeviceNode != NULL)
1845  {
1846  NextDeviceNode = ChildDeviceNode->Sibling;
1849 
1851  if (!NT_SUCCESS(Status))
1852  {
1853  FailedRemoveDevice = ChildDeviceNode;
1854  goto cleanup;
1855  }
1856 
1858  ChildDeviceNode = NextDeviceNode;
1859  }
1861 
1862  return STATUS_SUCCESS;
1863 
1864 cleanup:
1866  ChildDeviceNode = ParentDeviceNode->Child;
1867  while (ChildDeviceNode != NULL)
1868  {
1869  NextDeviceNode = ChildDeviceNode->Sibling;
1871 
1873 
1874  /* IRP_MN_CANCEL_REMOVE_DEVICE is also sent to the device
1875  * that failed the IRP_MN_QUERY_REMOVE_DEVICE request */
1876  if (ChildDeviceNode == FailedRemoveDevice)
1877  return Status;
1878 
1879  ChildDeviceNode = NextDeviceNode;
1880 
1882  }
1884 
1885  return Status;
1886 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:855
PNP_DEVNODE_STATE PiSetDevNodeState(_In_ PDEVICE_NODE DeviceNode, _In_ PNP_DEVNODE_STATE NewState)
Definition: devnode.c:108
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _DEVICE_NODE * Child
Definition: iotypes.h:840
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
static NTSTATUS IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
KSPIN_LOCK IopDeviceTreeLock
Definition: devnode.c:19
static VOID IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1778
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
struct _DEVICE_NODE * Sibling
Definition: iotypes.h:839
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 1810 of file devaction.c.

1811 {
1813  NTSTATUS Status;
1814 
1815  ASSERT(DeviceNode);
1816 
1817  IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVE_PENDING,
1818  &DeviceNode->InstancePath);
1819 
1821 
1822  PiNotifyTargetDeviceChange(&GUID_TARGET_DEVICE_QUERY_REMOVE, DeviceObject, NULL);
1823 
1824  if (!NT_SUCCESS(Status))
1825  {
1826  DPRINT1("Removal vetoed by %wZ\n", &DeviceNode->InstancePath);
1827  IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVAL_VETOED,
1828  &DeviceNode->InstancePath);
1829  }
1830 
1831  return Status;
1832 }
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:1579
_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:43
#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 1890 of file devaction.c.

1891 {
1892  /* This function DOES NOT dereference the device objects on SUCCESS
1893  * but it DOES dereference device objects on FAILURE */
1894 
1895  ULONG i, j;
1896  NTSTATUS Status;
1897 
1898  for (i = 0; i < DeviceRelations->Count; i++)
1899  {
1900  Status = IopPrepareDeviceForRemoval(DeviceRelations->Objects[i], Force);
1901  if (!NT_SUCCESS(Status))
1902  {
1903  j = i;
1904  goto cleanup;
1905  }
1906  }
1907 
1908  return STATUS_SUCCESS;
1909 
1910 cleanup:
1911  /* IRP_MN_CANCEL_REMOVE_DEVICE is also sent to the device
1912  * that failed the IRP_MN_QUERY_REMOVE_DEVICE request */
1913  for (i = 0; i <= j; i++)
1914  {
1915  IopCancelPrepareDeviceForRemoval(DeviceRelations->Objects[i]);
1916  ObDereferenceObject(DeviceRelations->Objects[i]);
1917  DeviceRelations->Objects[i] = NULL;
1918  }
1919  for (; i < DeviceRelations->Count; i++)
1920  {
1921  ObDereferenceObject(DeviceRelations->Objects[i]);
1922  DeviceRelations->Objects[i] = NULL;
1923  }
1924  ExFreePool(DeviceRelations);
1925 
1926  return Status;
1927 }
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:1778
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 1994 of file devaction.c.

1995 {
1996  NTSTATUS Status;
1997 
1998  // This function removes the device subtree, with the root in DeviceNode
1999  // atm everyting is in fact done inside this function, which is completely wrong.
2000  // The right implementation should have a separate removal worker thread and
2001  // properly do device node state transitions
2002 
2003  DPRINT("Removing device: %wZ\n", &DeviceNode->InstancePath);
2004 
2005  BOOLEAN surpriseRemoval = (_Bool)(DeviceNode->Flags & DNF_DEVICE_GONE);
2006 
2007  Status = IopPrepareDeviceForRemoval(DeviceNode->PhysicalDeviceObject, surpriseRemoval);
2008 
2009  if (surpriseRemoval)
2010  {
2011  IopSendSurpriseRemoval(DeviceNode->PhysicalDeviceObject);
2012  IopQueueTargetDeviceEvent(&GUID_DEVICE_SURPRISE_REMOVAL, &DeviceNode->InstancePath);
2013  }
2014 
2015  if (NT_SUCCESS(Status))
2016  {
2017  IopSendRemoveDevice(DeviceNode->PhysicalDeviceObject);
2018  if (surpriseRemoval)
2019  {
2020  IopQueueTargetDeviceEvent(&GUID_DEVICE_SAFE_REMOVAL, &DeviceNode->InstancePath);
2021  }
2022  return STATUS_SUCCESS;
2023  }
2024 
2025  return Status;
2026 }
LONG NTSTATUS
Definition: precomp.h:26
unsigned char BOOLEAN
static VOID NTAPI IopSendRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1646
Status
Definition: gdiplustypes.h:24
NTSTATUS IopQueueTargetDeviceEvent(const GUID *Guid, PUNICODE_STRING DeviceIds)
Definition: plugplay.c:43
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: Node.h:9
static VOID NTAPI IopSendSurpriseRemoval(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1717
#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 PiDevNodeStateMachine().

◆ IopSendEject()

static NTSTATUS NTAPI IopSendEject ( IN PDEVICE_OBJECT  DeviceObject)
static

Definition at line 2186 of file devaction.c.

2187 {
2189  PVOID Dummy;
2190 
2192  Stack.MajorFunction = IRP_MJ_PNP;
2193  Stack.MinorFunction = IRP_MN_EJECT;
2194 
2195  return IopSynchronousCall(DeviceObject, &Stack, &Dummy);
2196 }
#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 1693 of file devaction.c.

1694 {
1695  PDEVICE_NODE ChildDeviceNode, NextDeviceNode;
1696  KIRQL OldIrql;
1697 
1699  ChildDeviceNode = ParentDeviceNode->Child;
1700  while (ChildDeviceNode != NULL)
1701  {
1702  NextDeviceNode = ChildDeviceNode->Sibling;
1704 
1705  IopSendRemoveDevice(ChildDeviceNode->PhysicalDeviceObject);
1706 
1707  ChildDeviceNode = NextDeviceNode;
1708 
1710  }
1712 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:855
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _DEVICE_NODE * Child
Definition: iotypes.h:840
static VOID NTAPI IopSendRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1646
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
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:839

Referenced by IopPrepareDeviceForRemoval(), and IoRequestDeviceEject().

◆ IopSendRemoveDevice()

static VOID NTAPI IopSendRemoveDevice ( IN PDEVICE_OBJECT  DeviceObject)
static

Definition at line 1646 of file devaction.c.

1647 {
1649 
1651 
1652  /* Drivers should never fail a IRP_MN_REMOVE_DEVICE request */
1654 
1655  /* Start of HACK: update resources stored in registry, so IopDetectResourceConflict works */
1656  if (DeviceNode->ResourceList)
1657  {
1658  ASSERT(DeviceNode->ResourceListTranslated);
1659  DeviceNode->ResourceList->Count = 0;
1660  DeviceNode->ResourceListTranslated->Count = 0;
1662  }
1663  /* End of HACK */
1664 
1666  PiNotifyTargetDeviceChange(&GUID_TARGET_DEVICE_REMOVE_COMPLETE, DeviceObject, NULL);
1668  if (refCount != 0)
1669  {
1670  DPRINT1("Leaking device %wZ, refCount = %d\n", &DeviceNode->InstancePath, (INT32)refCount);
1671  }
1672 }
#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:1579
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
NTSTATUS IopUpdateResourceMapForPnPDevice(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:961
#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 1676 of file devaction.c.

1677 {
1678  /* This function DOES dereference the device objects in all cases */
1679 
1680  ULONG i;
1681 
1682  for (i = 0; i < DeviceRelations->Count; i++)
1683  {
1684  IopSendRemoveDevice(DeviceRelations->Objects[i]);
1685  DeviceRelations->Objects[i] = NULL;
1686  }
1687 
1688  ExFreePool(DeviceRelations);
1689 }
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
static VOID NTAPI IopSendRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:1646
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 1717 of file devaction.c.

1718 {
1720  /* Drivers should never fail a IRP_MN_SURPRISE_REMOVAL request */
1722 }
static NTSTATUS PiIrpSendRemoveCheckVpb(_In_ PDEVICE_OBJECT DeviceObject, _In_ UCHAR MinorFunction)
Sends one of the remove IRPs to the device stack.
Definition: devaction.c:1579
_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 606 of file pnpmgr.c.

608 {
611  HANDLE LogConfKey, ControlKey, DeviceParamsKey;
612  ULONG ResCount;
615 
616  DPRINT("IopSetDeviceInstanceData() called\n");
617 
618  /* Create the 'LogConf' key */
619  RtlInitUnicodeString(&KeyName, L"LogConf");
621  &KeyName,
623  InstanceKey,
624  NULL);
625  Status = ZwCreateKey(&LogConfKey,
628  0,
629  NULL,
630  // FIXME? In r53694 it was silently turned from non-volatile into this,
631  // without any extra warning. Is this still needed??
633  NULL);
634  if (NT_SUCCESS(Status))
635  {
636  /* Set 'BootConfig' value */
637  if (DeviceNode->BootResources != NULL)
638  {
639  ResCount = DeviceNode->BootResources->Count;
640  if (ResCount != 0)
641  {
642  RtlInitUnicodeString(&KeyName, L"BootConfig");
643  Status = ZwSetValueKey(LogConfKey,
644  &KeyName,
645  0,
647  DeviceNode->BootResources,
648  PnpDetermineResourceListSize(DeviceNode->BootResources));
649  }
650  }
651 
652  /* Set 'BasicConfigVector' value */
653  if (DeviceNode->ResourceRequirements != NULL &&
654  DeviceNode->ResourceRequirements->ListSize != 0)
655  {
656  RtlInitUnicodeString(&KeyName, L"BasicConfigVector");
657  Status = ZwSetValueKey(LogConfKey,
658  &KeyName,
659  0,
661  DeviceNode->ResourceRequirements,
662  DeviceNode->ResourceRequirements->ListSize);
663  }
664 
665  ZwClose(LogConfKey);
666  }
667 
668  /* Set the 'ConfigFlags' value */
669  RtlInitUnicodeString(&KeyName, L"ConfigFlags");
670  Status = ZwQueryValueKey(InstanceKey,
671  &KeyName,
673  NULL,
674  0,
675  &ResultLength);
677  {
678  /* Write the default value */
679  ULONG DefaultConfigFlags = 0;
680  Status = ZwSetValueKey(InstanceKey,
681  &KeyName,
682  0,
683  REG_DWORD,
684  &DefaultConfigFlags,
685  sizeof(DefaultConfigFlags));
686  }
687 
688  /* Create the 'Control' key */
689  RtlInitUnicodeString(&KeyName, L"Control");
691  &KeyName,
693  InstanceKey,
694  NULL);
695  Status = ZwCreateKey(&ControlKey,
696  0,
698  0,
699  NULL,
701  NULL);
702  if (NT_SUCCESS(Status))
703  ZwClose(ControlKey);
704 
705  /* Create the 'Device Parameters' key and set the 'FirmwareIdentified' value for all ACPI-enumerated devices */
706  if (_wcsnicmp(DeviceNode->InstancePath.Buffer, L"ACPI\\", 5) == 0)
707  {
708  RtlInitUnicodeString(&KeyName, L"Device Parameters");
710  &KeyName,
712  InstanceKey,
713  NULL);
714  Status = ZwCreateKey(&DeviceParamsKey,
715  0,
717  0,
718  NULL,
720  NULL);
721  if (NT_SUCCESS(Status))
722  {
723  ULONG FirmwareIdentified = 1;
724  RtlInitUnicodeString(&KeyName, L"FirmwareIdentified");
725  Status = ZwSetValueKey(DeviceParamsKey,
726  &KeyName,
727  0,
728  REG_DWORD,
729  &FirmwareIdentified,
730  sizeof(FirmwareIdentified));
731 
732  ZwClose(DeviceParamsKey);
733  }
734  }
735 
736  DPRINT("IopSetDeviceInstanceData() done\n");
737 
738  return Status;
739 }
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 L(x)
Definition: ntvdm.h:50
#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
ULONG NTAPI PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList)
Definition: pnpmgr.c:1807
#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 1343 of file devaction.c.

1346 {
1347  UNICODE_STRING ServicesKeyPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
1348  UNICODE_STRING ServiceKeyName;
1349  UNICODE_STRING EnumKeyName;
1352  PKEY_VALUE_FULL_INFORMATION KeyValueInformation, kvInfo2;
1353  HANDLE ServiceKey = NULL, ServiceEnumKey = NULL;
1355  ULONG Count = 0, NextInstance = 0;
1356  WCHAR ValueBuffer[6];
1358 
1359  // obtain the device node's ServiceName
1360  Status = IopGetRegistryValue(InstanceHandle, L"Service", &kvInfo2);
1361  if (!NT_SUCCESS(Status))
1362  {
1363  return Status;
1364  }
1365 
1366  if (kvInfo2->Type != REG_SZ || kvInfo2->DataLength <= sizeof(WCHAR))
1367  {
1368  ExFreePool(kvInfo2);
1369  return STATUS_UNSUCCESSFUL;
1370  }
1371 
1372  ServiceName.MaximumLength = kvInfo2->DataLength;
1373  ServiceName.Length = kvInfo2->DataLength - sizeof(UNICODE_NULL);
1374  ServiceName.Buffer = (PVOID)((ULONG_PTR)kvInfo2 + kvInfo2->DataOffset);
1375 
1376  DPRINT("IopSetServiceEnumData(%p)\n", DeviceNode);
1377  DPRINT("Instance: %wZ\n", &DeviceNode->InstancePath);
1378  DPRINT("Service: %wZ\n", &ServiceName);
1379 
1380  ServiceKeyName.MaximumLength = ServicesKeyPath.Length + ServiceName.Length + sizeof(UNICODE_NULL);
1381  ServiceKeyName.Length = 0;
1382  ServiceKeyName.Buffer = ExAllocatePool(PagedPool, ServiceKeyName.MaximumLength);
1383  if (ServiceKeyName.Buffer == NULL)
1384  {
1385  DPRINT1("No ServiceKeyName.Buffer!\n");
1387  }
1388 
1389  RtlAppendUnicodeStringToString(&ServiceKeyName, &ServicesKeyPath);
1390  RtlAppendUnicodeStringToString(&ServiceKeyName, &ServiceName);
1391 
1392  DPRINT("ServiceKeyName: %wZ\n", &ServiceKeyName);
1393 
1394  Status = IopOpenRegistryKeyEx(&ServiceKey, NULL, &ServiceKeyName, KEY_CREATE_SUB_KEY);
1395  if (!NT_SUCCESS(Status))
1396  {
1397  goto done;
1398  }
1399 
1401  &ServiceName,
1402  &DeviceNode->ServiceName);
1403  if (!NT_SUCCESS(Status))
1404  {
1405  goto done;
1406  }
1407 
1408  RtlInitUnicodeString(&EnumKeyName, L"Enum");
1409  Status = IopCreateRegistryKeyEx(&ServiceEnumKey,
1410  ServiceKey,
1411  &EnumKeyName,
1412  KEY_SET_VALUE,
1414  &Disposition);
1415  if (NT_SUCCESS(Status))
1416  {
1418  {
1419  /* Read the NextInstance value */
1420  Status = IopGetRegistryValue(ServiceEnumKey,
1421  L"Count",
1422  &KeyValueInformation);
1423  if (!NT_SUCCESS(Status))
1424  goto done;
1425 
1426  if ((KeyValueInformation->Type == REG_DWORD) &&
1427  (KeyValueInformation->DataLength))
1428  {
1429  /* Read it */
1430  Count = *(PULONG)((ULONG_PTR)KeyValueInformation +
1431  KeyValueInformation->DataOffset);
1432  }
1433 
1434  ExFreePool(KeyValueInformation);
1435  KeyValueInformation = NULL;
1436 
1437  /* Read the NextInstance value */
1438  Status = IopGetRegistryValue(ServiceEnumKey,
1439  L"NextInstance",
1440  &KeyValueInformation);
1441  if (!NT_SUCCESS(Status))
1442  goto done;
1443 
1444  if ((KeyValueInformation->Type == REG_DWORD) &&
1445  (KeyValueInformation->DataLength))
1446  {
1447  NextInstance = *(PULONG)((ULONG_PTR)KeyValueInformation +
1448  KeyValueInformation->DataOffset);
1449  }
1450 
1451  ExFreePool(KeyValueInformation);
1452  KeyValueInformation = NULL;
1453  }
1454 
1455  /* Set the instance path */
1456  swprintf(ValueBuffer, L"%lu", NextInstance);
1457  RtlInitUnicodeString(&ValueName, ValueBuffer);
1458  Status = ZwSetValueKey(ServiceEnumKey,
1459  &ValueName,
1460  0,
1461  REG_SZ,
1462  DeviceNode->InstancePath.Buffer,
1463  DeviceNode->InstancePath.MaximumLength);
1464  if (!NT_SUCCESS(Status))
1465  goto done;
1466 
1467  /* Increment Count and NextInstance */
1468  Count++;
1469  NextInstance++;
1470 
1471  /* Set the new Count value */
1472  RtlInitUnicodeString(&ValueName, L"Count");
1473  Status = ZwSetValueKey(ServiceEnumKey,
1474  &ValueName,
1475  0,
1476  REG_DWORD,
1477  &Count,
1478  sizeof(Count));
1479  if (!NT_SUCCESS(Status))
1480  goto done;
1481 
1482  /* Set the new NextInstance value */
1483  RtlInitUnicodeString(&ValueName, L"NextInstance");
1484  Status = ZwSetValueKey(ServiceEnumKey,
1485  &ValueName,
1486  0,
1487  REG_DWORD,
1488  &NextInstance,
1489  sizeof(NextInstance));
1490  }
1491 
1492 done:
1493  if (ServiceEnumKey != NULL)
1494  ZwClose(ServiceEnumKey);
1495 
1496  if (ServiceKey != NULL)
1497  ZwClose(ServiceKey);
1498 
1499  ExFreePool(ServiceKeyName.Buffer);
1500  ExFreePool(kvInfo2);
1501 
1502  return Status;
1503 }
#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
_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 L(x)
Definition: ntvdm.h:50
#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
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
int _cdecl swprintf(const WCHAR *,...)
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1606
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1455
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().

◆ IopUpdateResourceMapForPnPDevice()

NTSTATUS IopUpdateResourceMapForPnPDevice ( IN PDEVICE_NODE  DeviceNode)

Definition at line 961 of file pnpres.c.

963 {
964  return IopUpdateResourceMap(DeviceNode, L"PnP Manager", L"PnpManager");
965 }
#define L(x)
Definition: ntvdm.h:50
NTSTATUS IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2Key)
Definition: pnpres.c:802
Definition: Node.h:9

Referenced by IopAssignDeviceResources(), and IopSendRemoveDevice().

◆ IopValidateID()

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

Definition at line 122 of file devaction.c.

125 {
126  PWCHAR PtrChar;
127  PWCHAR StringEnd;
128  WCHAR Char;
129  ULONG SeparatorsCount = 0;
130  PWCHAR PtrPrevChar = NULL;
131  ULONG MaxSeparators;
132  BOOLEAN IsMultiSz;
133 
134  PAGED_CODE();
135 
136  switch (QueryType)
137  {
138  case BusQueryDeviceID:
139  MaxSeparators = MAX_SEPARATORS_DEVICEID;
140  IsMultiSz = FALSE;
141  break;
142  case BusQueryInstanceID:
143  MaxSeparators = MAX_SEPARATORS_INSTANCEID;
144  IsMultiSz = FALSE;
145  break;
146 
147  case BusQueryHardwareIDs:
149  MaxSeparators = MAX_SEPARATORS_DEVICEID;
150  IsMultiSz = TRUE;
151  break;
152 
153  default:
154  DPRINT1("IopValidateID: Not handled QueryType - %x\n", QueryType);
155  return FALSE;
156  }
157 
158  StringEnd = Id + MAX_DEVICE_ID_LEN;
159 
160  for (PtrChar = Id; PtrChar < StringEnd; PtrChar++)
161  {
162  Char = *PtrChar;
163 
164  if (Char == UNICODE_NULL)
165  {
166  if (!IsMultiSz || (PtrPrevChar && PtrChar == PtrPrevChar + 1))
167  {
168  if (MaxSeparators == SeparatorsCount || IsMultiSz)
169  {
170  return TRUE;
171  }
172 
173  DPRINT1("IopValidateID: SeparatorsCount - %lu, MaxSeparators - %lu\n",
174  SeparatorsCount, MaxSeparators);
175  goto ErrorExit;
176  }
177 
178  StringEnd = PtrChar + MAX_DEVICE_ID_LEN + 1;
179  PtrPrevChar = PtrChar;
180  SeparatorsCount = 0;
181  }
182  else if (Char < ' ' || Char > 0x7F || Char == ',')
183  {
184  DPRINT1("IopValidateID: Invalid character - %04X\n", Char);
185  goto ErrorExit;
186  }
187  else if (Char == ' ')
188  {
189  *PtrChar = '_';
190  }
191  else if (Char == '\\')
192  {
193  SeparatorsCount++;
194 
195  if (SeparatorsCount > MaxSeparators)
196  {
197  DPRINT1("IopValidateID: SeparatorsCount - %lu, MaxSeparators - %lu\n",
198  SeparatorsCount, MaxSeparators);
199  goto ErrorExit;
200  }
201  }
202  }
203 
204  DPRINT1("IopValidateID: Not terminated ID\n");
205 
206 ErrorExit:
207  // FIXME logging
208  return FALSE;
209 }
#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 2203 of file devaction.c.

2204 {
2206  PDEVICE_RELATIONS DeviceRelations;
2210  NTSTATUS Status;
2211 
2212  IopQueueTargetDeviceEvent(&GUID_DEVICE_KERNEL_INITIATED_EJECT,
2213  &DeviceNode->InstancePath);
2214 
2216  {
2217  goto cleanup;
2218  }
2219 
2220  Stack.Parameters.QueryDeviceRelations.Type = EjectionRelations;
2221 
2223  &IoStatusBlock,
2225  &Stack);
2226  if (!NT_SUCCESS(Status))
2227  {
2228  DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
2229  DeviceRelations = NULL;
2230  }
2231  else
2232  {
2233  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
2234  }
2235 
2236  if (DeviceRelations)
2237  {
2238  Status = IopQueryRemoveDeviceRelations(DeviceRelations, FALSE);
2239  if (!NT_SUCCESS(Status))
2240  goto cleanup;
2241  }
2242 
2244  if (!NT_SUCCESS(Status))
2245  {
2246  if (DeviceRelations)
2247  IopCancelRemoveDeviceRelations(DeviceRelations);
2248  goto cleanup;
2249  }
2250 
2252  {
2253  if (DeviceRelations)
2254  IopCancelRemoveDeviceRelations(DeviceRelations);
2256  goto cleanup;
2257  }
2258 
2259  if (DeviceRelations)
2260  IopSendRemoveDeviceRelations(DeviceRelations);
2262 
2264  if (Capabilities.EjectSupported)
2265  {
2267  {
2268  goto cleanup;
2269  }
2270  }
2271  else
2272  {
2273  // DeviceNode->Flags |= DNF_DISABLED;
2274  }
2275 
2276  IopQueueTargetDeviceEvent(&GUID_DEVICE_EJECT,
2277  &DeviceNode->InstancePath);
2278 
2279  return;
2280 
2281 cleanup:
2282  IopQueueTargetDeviceEvent(&GUID_DEVICE_EJECT_VETOED,
2283  &DeviceNode->InstancePath);
2284 }
static NTSTATUS IopQueryRemoveChildDevices(PDEVICE_NODE ParentDeviceNode, BOOLEAN Force)
Definition: devaction.c:1836
static VOID IopCancelRemoveChildDevices(PDEVICE_NODE ParentDeviceNode)
Definition: devaction.c:1737
#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:1149
_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:854
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
Status
Definition: gdiplustypes.h:24
NTSTATUS IopQueueTargetDeviceEvent(const GUID *Guid, PUNICODE_STRING DeviceIds)
Definition: plugplay.c:43
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static VOID IopSendRemoveChildDevices(PDEVICE_NODE ParentDeviceNode)
Definition: devaction.c:1693
Definition: Node.h:9
static NTSTATUS IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
static VOID IopSendRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations)
Definition: devaction.c:1676
static NTSTATUS NTAPI IopSendEject(IN PDEVICE_OBJECT DeviceObject)
Definition: devaction.c:2186
static NTSTATUS IopQueryRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations, BOOLEAN Force)
Definition: devaction.c:1890
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:1760
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 532 of file devaction.c.

539 {
540  RTL_QUERY_REGISTRY_TABLE QueryTable[2] = { { NULL, 0, NULL, NULL, 0, NULL, 0 }, };
541  ATTACH_FILTER_DRIVERS_CONTEXT routineContext;
543 
544  PAGED_CODE();
545 
546  routineContext.DriversListHead = DriversListHead;
547  routineContext.DeviceNode = DeviceNode;
548 
549  // First add device filters
550  routineContext.DriverType = Lower ? LowerFilter : UpperFilter;
553  .Name = Lower ? L"LowerFilters" : L"UpperFilters",
554  .DefaultType = REG_NONE,
555  .EntryContext = (PVOID)(ULONG_PTR)LoadDrivers
556  };
557 
559  (PWSTR)EnumSubKey,
560  QueryTable,
561  &routineContext,
562  NULL);
563  if (ClassKey == NULL)
564  {
565  return Status;
566  }
567 
568  // Then add device class filters
569  routineContext.DriverType = Lower ? LowerClassFilter : UpperClassFilter;
572  .Name = Lower ? L"LowerFilters" : L"UpperFilters",
573  .DefaultType = REG_NONE,
574  .EntryContext = (PVOID)(ULONG_PTR)LoadDrivers
575  };
576 
578  (PWSTR)ClassKey,
579  QueryTable,
580  &routineContext,
581  NULL);
582  return Status;
583 }
_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
#define L(x)
Definition: ntvdm.h:50
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:363
struct _RTL_QUERY_REGISTRY_TABLE RTL_QUERY_REGISTRY_TABLE
Definition: Node.h:9
#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:82
#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 363 of file devaction.c.

370 {
374  BOOLEAN loadDrivers = (BOOLEAN)(ULONG_PTR)EntryContext;
375 
376  PAGED_CODE();
377 
378  // No filter value present
379  if (ValueType != REG_SZ)
380  return STATUS_SUCCESS;
381 
382  if (ValueLength <= sizeof(WCHAR))
384 
385  // open the service registry key
386  UNICODE_STRING serviceName = { .Length = 0 }, servicesKeyName;
388  RtlInitUnicodeString(&servicesKeyName, ServicesKeyName);
389 
390  HANDLE ccsServicesHandle, serviceHandle = NULL;
391 
392  Status = IopOpenRegistryKeyEx(&ccsServicesHandle, NULL, &servicesKeyName, KEY_READ);
393  if (!NT_SUCCESS(Status))
394  {
395  DPRINT1("Failed to open a registry key for \"%wZ\" (status %x)\n", &serviceName, Status);
396  return Status;
397  }
398 
399  Status = IopOpenRegistryKeyEx(&serviceHandle, ccsServicesHandle, &serviceName, KEY_READ);
400  ZwClose(ccsServicesHandle);
401  if (!NT_SUCCESS(Status))
402  {
403  DPRINT1("Failed to open a registry key for \"%wZ\" (status %x)\n", &serviceName, Status);
404  return Status;
405  }
406 
408  sizeof(*driverEntry),
410 
411  if (!driverEntry)
412  {
413  DPRINT1("Failed to allocate driverEntry for \"%wZ\"\n", &serviceName);
414  ZwClose(serviceHandle);
416  }
417 
418  // check if the driver is disabled
420  SERVICE_LOAD_TYPE startType = DisableLoad;
421 
422  Status = IopGetRegistryValue(serviceHandle, L"Start", &kvInfo);
423  if (NT_SUCCESS(Status))
424  {
425  if (kvInfo->Type == REG_DWORD)
426  {
427  RtlMoveMemory(&startType,
428  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
429  sizeof(startType));
430  }
431 
432  ExFreePool(kvInfo);
433  }
434 
435  // TODO: take into account other start types (like SERVICE_DEMAND_START)
436  if (startType >= DisableLoad)
437  {
438  if (!(context->DeviceNode->Flags & DNF_HAS_PROBLEM))
439  {
441  }
442 
443  DPRINT("Service \"%wZ\" is disabled (start type %u)\n", &serviceName, startType);
445  goto Cleanup;
446  }
447 
448  // check if the driver is already loaded
449  UNICODE_STRING driverName;
450  Status = IopGetDriverNames(serviceHandle, &driverName, NULL);
451  if (!NT_SUCCESS(Status))
452  {
453  DPRINT1("Unable to obtain the driver name for \"%wZ\"\n", &serviceName);
454  goto Cleanup;
455  }
456 
457  // try to open it
458  Status = ObReferenceObjectByName(&driverName,
460  NULL, /* PassedAccessState */
461  0, /* DesiredAccess */
463  KernelMode,
464  NULL, /* ParseContext */
465  (PVOID*)&DriverObject);
466  RtlFreeUnicodeString(&driverName);
467 
468  // the driver was not probably loaded, try to load
469  if (!NT_SUCCESS(Status))
470  {
471  if (loadDrivers)
472  {
473  Status = IopLoadDriver(serviceHandle, &DriverObject);
474  }
475  else
476  {
477  DPRINT("Service \"%wZ\" will not be loaded now\n", &serviceName);
478  // return failure, the driver will be loaded later (in a subsequent call)
480  goto Cleanup;
481  }
482  }
483 
484  if (NT_SUCCESS(Status))
485  {
486  driverEntry->DriverObject = DriverObject;
487  driverEntry->DriverType = context->DriverType;
488  InsertTailList(context->DriversListHead, &driverEntry->ListEntry);
489  ZwClose(serviceHandle);
490  return STATUS_SUCCESS;
491  }
492  else
493  {
494  if (!(context->DeviceNode->Flags & DNF_HAS_PROBLEM))
495  {
496  switch (Status)
497  {
500  break;
503  break;
506  break;
507  default:
509  break;
510  }
511  }
512 
513  DPRINT1("Failed to load driver \"%wZ\" for %wZ (status %x)\n",
514  &serviceName, &context->DeviceNode->InstancePath, Status);
515  }
516 
517 Cleanup:
518  ExFreePoolWithTag(driverEntry, TAG_PNP_DEVACTION);
519  if (serviceHandle)
520  {
521  ZwClose(serviceHandle);
522  }
523  return Status;
524 }
NTSTATUS IopGetDriverNames(_In_ HANDLE ServiceHandle, _Out_ PUNICODE_STRING DriverName, _Out_opt_ PUNICODE_STRING ServiceName)
Definition: driver.c:123
#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:1909
#define L(x)
Definition: ntvdm.h:50
LIST_ENTRY ListEntry
Definition: devaction.c:75
unsigned char BOOLEAN
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4155
ADD_DEV_DRIVER_TYPE DriverType
Definition: devaction.c:77
_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:76
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define TAG_PNP_DEVACTION
Definition: tag.h:93
#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
#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:1606
#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:1455
#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 DPRINT
Definition: sndvol32.h:71
#define REG_DWORD
Definition: sdbapi.c:596
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
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 595 of file devaction.c.

598 {
600  HANDLE EnumRootKey, SubKey;
601  HANDLE ClassKey = NULL;
603  static UNICODE_STRING ccsControlClass =
604  RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class");
606 
607  PAGED_CODE();
608 
609  // open the enumeration root key
610  Status = IopOpenRegistryKeyEx(&EnumRootKey, NULL, &EnumRoot, KEY_READ);
611  if (!NT_SUCCESS(Status))
612  {
613  DPRINT1("IopOpenRegistryKeyEx() failed for \"%wZ\" (status %x)\n", &EnumRoot, Status);
614  return Status;
615  }
616 
617  // open an instance subkey
618  Status = IopOpenRegistryKeyEx(&SubKey, EnumRootKey, &DeviceNode->InstancePath, KEY_READ);
619  ZwClose(EnumRootKey);
620  if (!NT_SUCCESS(Status))
621  {
622  DPRINT1("Failed to open a devnode instance key for \"%wZ\" (status %x)\n",
623  &DeviceNode->InstancePath, Status);
624  return Status;
625  }
626 
627  // try to get the class GUID of an instance and its registry key
628  Status = IopGetRegistryValue(SubKey, REGSTR_VAL_CLASSGUID, &kvInfo);
629  if (NT_SUCCESS(Status))
630  {
631  if (kvInfo->Type == REG_SZ && kvInfo->DataLength > sizeof(WCHAR))
632  {
633  UNICODE_STRING classGUID = {
634  .MaximumLength = kvInfo->DataLength,
635  .Length = kvInfo->DataLength - sizeof(UNICODE_NULL),
636  .Buffer = (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset)
637  };
638  HANDLE ccsControlHandle;
639 
640  Status = IopOpenRegistryKeyEx(&ccsControlHandle, NULL, &ccsControlClass, KEY_READ);
641  if (!NT_SUCCESS(Status))
642  {
643  DPRINT1("IopOpenRegistryKeyEx() failed for \"%wZ\" (status %x)\n",
644  &ccsControlClass, Status);
645  }
646  else
647  {
648  // open the CCS\Control\Class<ClassGUID> key
649  Status = IopOpenRegistryKeyEx(&ClassKey, ccsControlHandle, &classGUID, KEY_READ);
650  ZwClose(ccsControlHandle);
651  if (!NT_SUCCESS(Status))
652  {
653  DPRINT1("Failed to open class key \"%wZ\" (status %x)\n", &classGUID, Status);
654  }
655  }
656 
657  if (ClassKey)
658  {
659  // Check the Properties key of a class too
660  // Windows fills some device properties from this key (which is protected)
661  // TODO: add the device properties from this key
662 
664  HANDLE propertiesHandle;
665 
666  Status = IopOpenRegistryKeyEx(&propertiesHandle, ClassKey, &properties, KEY_READ);
667  if (!NT_SUCCESS(Status))
668  {
669  DPRINT("Properties key failed to open for \"%wZ\" (status %x)\n",
670  &classGUID, Status);
671  }
672  else
673  {
674  ZwClose(propertiesHandle);
675  }
676  }
677  }
678 
679  ExFreePool(kvInfo);
680  }
681 
682  // the driver loading order:
683  // 1. LowerFilters
684  // 2. LowerClassFilters
685  // 3. Device driver (only one service!)
686  // 4. UpperFilters
687  // 5. UpperClassFilters
688 
689  LIST_ENTRY drvListHead;
690  InitializeListHead(&drvListHead);
691 
692  // lower (class) filters
693  Status = PiAttachFilterDrivers(&drvListHead, DeviceNode, SubKey, ClassKey, TRUE, LoadDrivers);
694  if (!NT_SUCCESS(Status))
695  {
696  goto Cleanup;
697  }
698 
699  ATTACH_FILTER_DRIVERS_CONTEXT routineContext = {
700  .DriversListHead = &drvListHead,
701  .DriverType = DeviceDriver,
702  .DeviceNode = DeviceNode
703  };
704 
705  RTL_QUERY_REGISTRY_TABLE queryTable[2] = {{
707  .Name = L"Service",
709  .DefaultType = REG_SZ, // REG_MULTI_SZ is not allowed here
710  .DefaultData = L"",
711  .EntryContext = (PVOID)(ULONG_PTR)LoadDrivers
712  },};
713 
714  // device driver
716  (PWSTR)SubKey,
717  queryTable,
718  &routineContext,
719  NULL);
720  if (NT_SUCCESS(Status))
721  {
722  // do nothing
723  }
724  // if a driver is not found, but a device allows raw access -> proceed
725  else if (Status == STATUS_OBJECT_NAME_NOT_FOUND &&
726  (DeviceNode->CapabilityFlags & 0x00000040)) // CM_DEVCAP_RAWDEVICEOK
727  {
728  // add a dummy entry to the drivers list (need for later processing)
729  PADD_DEV_DRIVERS_LIST driverEntry = ExAllocatePoolZero(PagedPool,
730  sizeof(*driverEntry),
732  driverEntry->DriverType = DeviceDriver;
733  InsertTailList(&drvListHead, &driverEntry->ListEntry);
734  DPRINT("No service for \"%wZ\" (RawDeviceOK)\n", &DeviceNode->InstancePath);
735  }
736  else
737  {
739  {
741  }
742  DPRINT("No service for \"%wZ\" (loadDrv: %u)\n", &DeviceNode->InstancePath, LoadDrivers);
743  goto Cleanup;
744  }
745 
746  // upper (class) filters
747  Status = PiAttachFilterDrivers(&drvListHead, DeviceNode, SubKey, ClassKey, FALSE, LoadDrivers);
748  if (!NT_SUCCESS(Status))
749  {
750  goto Cleanup;
751  }
752 
753  // finally loop through the stack and call AddDevice for every driver
754  for (PLIST_ENTRY listEntry = drvListHead.Flink;
755  listEntry != &drvListHead;
756  listEntry = listEntry->Flink)
757  {
758  PADD_DEV_DRIVERS_LIST driverEntry;
759  driverEntry = CONTAINING_RECORD(listEntry, ADD_DEV_DRIVERS_LIST, ListEntry);
760  PDRIVER_OBJECT driverObject = driverEntry->DriverObject;
761 
762  // FIXME: ReactOS is not quite ready for this assert
763  // (legacy drivers should not have AddDevice routine)
764  // ASSERT(!(DriverObject->Flags & DRVO_LEGACY_DRIVER));
765 
766  if (driverObject && driverObject->DriverExtension->AddDevice)
767  {
768  Status = driverObject->DriverExtension->AddDevice(driverEntry->DriverObject,
769  DeviceNode->PhysicalDeviceObject);
770  }
771  else if (driverObject == NULL)
772  {
773  // valid only for DeviceDriver
774  ASSERT(driverEntry->DriverType == DeviceDriver);
775  ASSERT(DeviceNode->CapabilityFlags & 0x00000040); // CM_DEVCAP_RAWDEVICEOK
777  }
778  else
779  {
780  // HACK: the driver doesn't have a AddDevice routine. We shouldn't be here,
781  // but ReactOS' PnP stack is not that correct yet
782  DeviceNode->Flags |= DNF_LEGACY_DRIVER;
784  }
785 
786  // for filter drivers we don't care about the AddDevice result
787  if (driverEntry->DriverType == DeviceDriver)
788  {
789  if (NT_SUCCESS(Status))
790  {
791  PDEVICE_OBJECT fdo = IoGetAttachedDeviceReference(DeviceNode->PhysicalDeviceObject);
792 
793  // HACK: Check if we have a ACPI device (needed for power management)
794  if (fdo->DeviceType == FILE_DEVICE_ACPI)
795  {
796  static BOOLEAN SystemPowerDeviceNodeCreated = FALSE;
797 
798  // There can be only one system power device
799  if (!SystemPowerDeviceNodeCreated)
800  {
803  SystemPowerDeviceNodeCreated = TRUE;
804  }
805  }
806 
807  ObDereferenceObject(fdo);
809  }
810  else
811  {
812  // lower filters (if already started) will be removed upon this request
815  break;
816  }
817  }
818 
819 #if DBG
820  PDEVICE_OBJECT attachedDO = IoGetAttachedDevice(DeviceNode->PhysicalDeviceObject);
821  if (attachedDO->Flags & DO_DEVICE_INITIALIZING)
822  {
823  DPRINT1("DO_DEVICE_INITIALIZING is not cleared on a device 0x%p!\n", attachedDO);
824  }
825 #endif
826  }
827 
828 Cleanup:
829  while (!IsListEmpty(&drvListHead))
830  {
831  PLIST_ENTRY listEntry = RemoveHeadList(&drvListHead);
832  PADD_DEV_DRIVERS_LIST driverEntry;
833  driverEntry = CONTAINING_RECORD(listEntry, ADD_DEV_DRIVERS_LIST, ListEntry);
834 
835  // drivers which don't have any devices (in case of failure) will be cleaned up
836  if (driverEntry->DriverObject)
837  {
838  ObDereferenceObject(driverEntry->DriverObject);
839  }
840  ExFreePoolWithTag(driverEntry, TAG_PNP_DEVACTION);
841  }
842 
843  ZwClose(SubKey);
844  if (ClassKey != NULL)
845  {
846  ZwClose(ClassKey);
847  }
848 
849  return Status;
850 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:855
#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
#define L(x)
Definition: ntvdm.h:50
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:75
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2282
unsigned char BOOLEAN
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:77
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
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:76
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define TAG_PNP_DEVACTION
Definition: tag.h:93
#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:532
#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:363
PDEVICE_NODE PopSystemPowerDeviceNode
Definition: power.c:25
Definition: Node.h:9
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#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:1606
#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:1455
#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 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 ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#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 2312 of file devaction.c.

2314 {
2315  NTSTATUS status;
2316  BOOLEAN doProcessAgain;
2317  PDEVICE_NODE currentNode = RootNode;
2318  PDEVICE_OBJECT referencedObject;
2319 
2320  do
2321  {
2322  doProcessAgain = FALSE;
2323 
2324  // The device can be removed during processing, but we still need its Parent and Sibling
2325  // links to continue the tree traversal. So keep the link till the and of a cycle
2326  referencedObject = currentNode->PhysicalDeviceObject;
2327  ObReferenceObject(referencedObject);
2328 
2329  // Devices with problems are skipped (unless they are not being removed)
2330  if (currentNode->Flags & DNF_HAS_PROBLEM &&
2331  currentNode->State != DeviceNodeAwaitingQueuedRemoval)
2332  {
2333  goto skipEnum;
2334  }
2335 
2336  switch (currentNode->State)
2337  {
2338  case DeviceNodeUnspecified: // this state is not used
2339  break;
2341  DPRINT("DeviceNodeUninitialized %wZ\n", &currentNode->InstancePath);
2342  status = PiInitializeDevNode(currentNode);
2343  doProcessAgain = NT_SUCCESS(status);
2344  break;
2345  case DeviceNodeInitialized:
2346  DPRINT("DeviceNodeInitialized %wZ\n", &currentNode->InstancePath);
2348  doProcessAgain = NT_SUCCESS(status);
2349  break;
2351  DPRINT("DeviceNodeDriversAdded %wZ\n", &currentNode->InstancePath);
2352  status = IopAssignDeviceResources(currentNode);
2353  doProcessAgain = NT_SUCCESS(status);
2354  break;
2356  DPRINT("DeviceNodeResourcesAssigned %wZ\n", &currentNode->InstancePath);
2357  // send IRP_MN_START_DEVICE
2358  PiIrpStartDevice(currentNode);
2359 
2360  // skip DeviceNodeStartPending, it is probably used for an async IRP_MN_START_DEVICE
2362  doProcessAgain = TRUE;
2363  break;
2364  case DeviceNodeStartPending: // skipped on XP/2003
2365  break;
2367  DPRINT("DeviceNodeStartCompletion %wZ\n", &currentNode->InstancePath);
2368  status = currentNode->CompletionStatus;
2369  doProcessAgain = TRUE;
2370  if (!NT_SUCCESS(status))
2371  {
2375 
2376  PiSetDevNodeProblem(currentNode, problem);
2378  }
2379  else
2380  {
2381  // TODO: IopDoDeferredSetInterfaceState and IopAllocateLegacyBootResources
2382  // are called here too
2383 
2385  }
2386  break;
2388  DPRINT("DeviceNodeStartPostWork %wZ\n", &currentNode->InstancePath);
2389  status = PiStartDeviceFinal(currentNode);
2390  doProcessAgain = TRUE;
2391  break;
2392  case DeviceNodeStarted:
2393  if (currentNode->Flags & DNF_REENUMERATE)
2394  {
2395  DPRINT("DeviceNodeStarted REENUMERATE %wZ\n", &currentNode->InstancePath);
2396  currentNode->Flags &= ~DNF_REENUMERATE;
2398 
2399  // again, skip DeviceNodeEnumeratePending as with the starting sequence
2401  doProcessAgain = TRUE;
2402  }
2403  else if (currentNode->Flags & DNF_RESOURCE_REQUIREMENTS_CHANGED)
2404  {
2405  if (currentNode->Flags & DNF_NON_STOPPED_REBALANCE)
2406  {
2407  PiFakeResourceRebalance(currentNode);
2408  currentNode->Flags &= ~DNF_NON_STOPPED_REBALANCE;
2409  }
2410  else
2411  {
2412  PiIrpQueryStopDevice(currentNode);
2414  }
2415 
2416  doProcessAgain = TRUE;
2417  }
2418  break;
2420  // we're here after sending IRP_MN_QUERY_STOP_DEVICE
2421  status = currentNode->CompletionStatus;
2422  if (NT_SUCCESS(status))
2423  {
2424  PiIrpStopDevice(currentNode);
2425  PiSetDevNodeState(currentNode, DeviceNodeStopped);
2426  }
2427  else
2428  {
2429  PiIrpCancelStopDevice(currentNode);
2430  PiSetDevNodeState(currentNode, DeviceNodeStarted);
2431  }
2432  doProcessAgain = TRUE;
2433  break;
2434  case DeviceNodeStopped:
2435  // TODO: do resource rebalance (not implemented)
2436  PiFakeResourceRebalance(currentNode);
2437 
2439  doProcessAgain = TRUE;
2440  break;
2442  break;
2443  case DeviceNodeEnumeratePending: // skipped on XP/2003
2444  break;
2446  DPRINT("DeviceNodeEnumerateCompletion %wZ\n", &currentNode->InstancePath);
2447  status = PiEnumerateDevice(currentNode);
2448  doProcessAgain = TRUE;
2449  break;
2451  break;
2453  DPRINT("DeviceNodeAwaitingQueuedRemoval %wZ\n", &currentNode->InstancePath);
2454  status = IopRemoveDevice(currentNode);
2455  break;
2457  break;
2459  break;
2460  case DeviceNodeRemoved:
2461  break;
2463  break;
2464  case DeviceNodeDeleted:
2465  break;
2466  default:
2467  break;
2468  }
2469 
2470 skipEnum:
2471  if (!doProcessAgain)
2472  {
2473  KIRQL OldIrql;
2475  /* If we have a child, simply go down the tree */
2476  if (currentNode->State != DeviceNodeRemoved && currentNode->Child != NULL)
2477  {
2478  ASSERT(currentNode->Child->Parent == currentNode);
2479  currentNode = currentNode->Child;
2480  }
2481  else
2482  {
2483  while (currentNode != RootNode)
2484  {
2485  /* All children processed -- go sideways */
2486  if (currentNode->Sibling != NULL)
2487  {
2488  ASSERT(currentNode->Sibling->Parent == currentNode->Parent);
2489  currentNode = currentNode->Sibling;
2490  break;
2491  }
2492  else
2493  {
2494  /* We're the last sibling -- go back up */
2495  ASSERT(currentNode->Parent->LastChild == currentNode);
2496  currentNode = currentNode->Parent;
2497  }
2498  /* We already visited the parent and all its children, so keep looking */
2499  }
2500  }
2502  }
2503  ObDereferenceObject(referencedObject);
2504  } while (doProcessAgain || currentNode != RootNode);
2505 }
ULONG Flags
Definition: iotypes.h:852
static NTSTATUS PiInitializeDevNode(_In_ PDEVICE_NODE DeviceNode)
Definition: devaction.c:1190
#define DNF_NON_STOPPED_REBALANCE
Definition: iotypes.h:181
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:855
static NTSTATUS PiEnumerateDevice(_In_ PDEVICE_NODE DeviceNode)
Definition: devaction.c:2096
#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
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
NTSTATUS PiIrpQueryStopDevice(_In_ PDEVICE_NODE DeviceNode)
Definition: pnpirp.c:133
#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:841
static NTSTATUS IopRemoveDevice(PDEVICE_NODE DeviceNode)
Definition: devaction.c:1994
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _DEVICE_NODE * Child
Definition: iotypes.h:840
#define FALSE
Definition: types.h:117
unsigned int UINT32
unsigned char BOOLEAN
PNP_DEVNODE_STATE State
Definition: iotypes.h:846
NTSTATUS PiIrpStopDevice(_In_ PDEVICE_NODE DeviceNode)
Definition: pnpirp.c:111
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:850
#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:595
#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:792
#define CM_PROB_NEED_RESTART
Definition: cfg.h:44
UNICODE_STRING InstancePath
Definition: iotypes.h:858
KSPIN_LOCK IopDeviceTreeLock
Definition: devnode.c:19
#define DNF_RESOURCE_REQUIREMENTS_CHANGED
Definition: iotypes.h:180
#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:839
static VOID PiFakeResourceRebalance(_In_ PDEVICE_NODE DeviceNode)
Definition: devaction.c:2288
#define ObReferenceObject
Definition: obfuncs.h:204
static NTSTATUS PiStartDeviceFinal(_In_ PDEVICE_NODE DeviceNode)
Definition: devaction.c:1507
NTSTATUS NTAPI IopAssignDeviceResources(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:1116
#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 2096 of file devaction.c.

2098 {
2099  PDEVICE_OBJECT ChildDeviceObject;
2100  PDEVICE_NODE ChildDeviceNode;
2101  ULONG i;
2102 
2103  // bus relations are already obtained for this device node
2104 
2105  if (!NT_SUCCESS(DeviceNode->CompletionStatus))
2106  {
2107  DPRINT("QDR request failed for %wZ, status %x\n",
2108  &DeviceNode->InstancePath, DeviceNode->CompletionStatus);
2109  // treat as if there are no child objects
2110  }
2111 
2112  PDEVICE_RELATIONS DeviceRelations = DeviceNode->OverUsed1.PendingDeviceRelations;
2113  DeviceNode->OverUsed1.PendingDeviceRelations = NULL;
2114 
2115  // it's acceptable not to have PDOs
2116  if (!DeviceRelations)
2117  {
2119  DPRINT("No PDOs\n");
2120  return STATUS_SUCCESS;
2121  }
2122 
2123  // mark children nodes as non-present (those not returned in DR request will be removed)
2124  for (PDEVICE_NODE child = DeviceNode->Child; child != NULL; child = child->Sibling)
2125  {
2126  child->Flags &= ~DNF_ENUMERATED;
2127  }
2128 
2129  DPRINT("PiEnumerateDevice: enumerating %u children\n", DeviceRelations->Count);
2130 
2131  // create device nodes for all new children and set DNF_ENUMERATED back for old ones
2132  for (i = 0; i < DeviceRelations->Count; i++)
2133  {
2134  ChildDeviceObject = DeviceRelations->Objects[i];
2135  ASSERT((ChildDeviceObject->Flags & DO_DEVICE_INITIALIZING) == 0);
2136 
2137  ChildDeviceNode = IopGetDeviceNode(ChildDeviceObject);
2138  if (!ChildDeviceNode)
2139  {
2140  /* One doesn't exist, create it */
2141  ChildDeviceNode = PipAllocateDeviceNode(ChildDeviceObject);
2142  if (ChildDeviceNode)
2143  {
2144  PiInsertDevNode(ChildDeviceNode, DeviceNode);
2145 
2146  /* Mark the node as enumerated */
2147  ChildDeviceNode->Flags |= DNF_ENUMERATED;
2148 
2149  /* Mark the DO as bus enumerated */
2150  ChildDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
2151  }
2152  else
2153  {
2154  /* Ignore this DO */
2155  DPRINT1("PipAllocateDeviceNode() failed. Skipping PDO %u\n", i);
2156  ObDereferenceObject(ChildDeviceObject);
2157  }
2158  }
2159  else
2160  {
2161  /* Mark it as enumerated */
2162  ChildDeviceNode->Flags |= DNF_ENUMERATED;
2163  ObDereferenceObject(ChildDeviceObject);
2164  }
2165  }
2166  ExFreePool(DeviceRelations);
2167 
2168  // time to remove non-reported devices
2169  for (PDEVICE_NODE child = DeviceNode->Child; child != NULL; child = child->Sibling)
2170  {
2171  if (!(child->Flags & (DNF_ENUMERATED|DNF_DEVICE_GONE)))
2172  {
2173  // this flag indicates that this is a surprise removal
2174  child->Flags |= DNF_DEVICE_GONE;
2176  }
2177  }
2178 
2180  return STATUS_SUCCESS;
2181 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
ULONG Flags
Definition: iotypes.h:852
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().

◆ PiFakeResourceRebalance()

static VOID PiFakeResourceRebalance ( _In_ PDEVICE_NODE  DeviceNode)
static

Definition at line 2288 of file devaction.c.

2290 {
2292 
2293  PCM_RESOURCE_LIST bootConfig = NULL;
2294  PIO_RESOURCE_REQUIREMENTS_LIST resourceRequirements = NULL;
2295 
2296  PiIrpQueryResources(DeviceNode, &bootConfig);
2297  PiIrpQueryResourceRequirements(DeviceNode, &resourceRequirements);
2298 
2299  DeviceNode->BootResources = bootConfig;
2300  DeviceNode->ResourceRequirements = resourceRequirements;
2301 
2302  if (bootConfig)
2303  {
2304  DeviceNode->Flags |= DNF_HAS_BOOT_CONFIG;
2305  }
2306 
2308 }
NTSTATUS PiIrpQueryResourceRequirements(_In_ PDEVICE_NODE DeviceNode, _Out_ PIO_RESOURCE_REQUIREMENTS_LIST *Resources)
Definition: pnpirp.c:227
#define DNF_HAS_BOOT_CONFIG
Definition: iotypes.h:176
#define ASSERT(a)
Definition: mode.c:44
Definition: Node.h:9
NTSTATUS PiIrpQueryResources(_In_ PDEVICE_NODE DeviceNode, _Out_ PCM_RESOURCE_LIST *Resources)
Definition: pnpirp.c:201
#define DNF_RESOURCE_REQUIREMENTS_CHANGED
Definition: iotypes.h:180
#define NULL
Definition: types.h:112

Referenced by PiDevNodeStateMachine().

◆ PiInitializeDevNode()

static NTSTATUS PiInitializeDevNode ( _In_ PDEVICE_NODE  DeviceNode)
static

Definition at line 1190 of file devaction.c.

1192 {
1194  NTSTATUS Status;
1195  HANDLE InstanceKey = NULL;
1196  UNICODE_STRING InstancePathU;
1197  PDEVICE_OBJECT OldDeviceObject;
1198 
1199  DPRINT("PiProcessNewDevNode(%p)\n", DeviceNode);
1200  DPRINT("PDO 0x%p\n", DeviceNode->PhysicalDeviceObject);
1201 
1202  /*
1203  * FIXME: For critical errors, cleanup and disable device, but always
1204  * return STATUS_SUCCESS.
1205  */
1206 
1207  Status = IopCreateDeviceInstancePath(DeviceNode, &InstancePathU);
1208  if (!NT_SUCCESS(Status))
1209  {
1211  {
1212  DPRINT1("IopCreateDeviceInstancePath() failed with status 0x%lx\n", Status);
1213  }
1214  return Status;
1215  }
1216 
1217  /* Verify that this is not a duplicate */
1218  OldDeviceObject = IopGetDeviceObjectFromDeviceInstance(&InstancePathU);
1219  if (OldDeviceObject != NULL)
1220  {
1221  PDEVICE_NODE OldDeviceNode = IopGetDeviceNode(OldDeviceObject);
1222 
1223  DPRINT1("Duplicate device instance '%wZ'\n", &InstancePathU);
1224  DPRINT1("Current instance parent: '%wZ'\n", &DeviceNode->Parent->InstancePath);
1225  DPRINT1("Old instance parent: '%wZ'\n", &OldDeviceNode->Parent->InstancePath);
1226 
1227  KeBugCheckEx(PNP_DETECTED_FATAL_ERROR,
1228  0x01,
1229  (ULONG_PTR)DeviceNode->PhysicalDeviceObject,
1230  (ULONG_PTR)OldDeviceObject,
1231  0);
1232  }
1233 
1234  DeviceNode->InstancePath = InstancePathU;
1235 
1236  DPRINT("InstancePath is %S\n", DeviceNode->InstancePath.Buffer);
1237 
1238  /*
1239  * Create registry key for the instance id, if it doesn't exist yet
1240  */
1241  Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
1242  if (!NT_SUCCESS(Status))
1243  {
1244  DPRINT1("Failed to create the instance key! (Status %lx)\n", Status);
1245 
1246  /* We have to return success otherwise we abort the traverse operation */
1247  return STATUS_SUCCESS;
1248  }
1249 
1250  IopQueryHardwareIds(DeviceNode, InstanceKey);
1251 
1252  IopQueryCompatibleIds(DeviceNode, InstanceKey);
1253 
1254  DeviceNode->Flags |= DNF_IDS_QUERIED;
1255 
1256  // Set the device's DeviceDesc and LocationInformation fields
1257  PiSetDevNodeText(DeviceNode, InstanceKey);
1258 
1259  DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n");
1260 
1261  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
1262  &IoStatusBlock,
1264  NULL);
1266  {
1268 
1269  DeviceNode->ChildBusNumber = BusInformation->BusNumber;
1270  DeviceNode->ChildInterfaceType = BusInformation->LegacyBusType;
1271  DeviceNode->ChildBusTypeIndex = IopGetBusTypeGuidIndex(&BusInformation->BusTypeGuid);
1273  }
1274  else
1275  {
1276  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
1277 
1278  DeviceNode->ChildBusNumber = 0xFFFFFFF0;
1279  DeviceNode->ChildInterfaceType = InterfaceTypeUndefined;
1280  DeviceNode->ChildBusTypeIndex = -1;
1281  }
1282 
1283  DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n");
1284 
1285  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
1286  &IoStatusBlock,
1288  NULL);
1290  {
1293  }
1294  else
1295  {
1296  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
1297  DeviceNode->BootResources = NULL;
1298  }
1299 
1300  DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n");
1301 
1302  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
1303  &IoStatusBlock,
1305  NULL);
1306  if (NT_SUCCESS(Status))
1307  {
1309  }
1310  else
1311  {
1312  DPRINT("IopInitiatePnpIrp() failed (Status %08lx)\n", Status);
1313  DeviceNode->ResourceRequirements = NULL;
1314  }
1315 
1316  if (InstanceKey != NULL)
1317  {
1318  IopSetDeviceInstanceData(InstanceKey, DeviceNode);
1319  }
1320 
1321  // Try installing a critical device, so its Service key is populated
1322  // then call IopSetServiceEnumData to populate service's Enum key.
1323  // That allows us to start devices during an early boot
1325  IopSetServiceEnumData(DeviceNode, InstanceKey);
1326