ReactOS  0.4.13-dev-257-gfabbd7c
pnpmgr.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for pnpmgr.c:

Go to the source code of this file.

Classes

struct  _DEVICE_ACTION_DATA
 

Macros

#define NDEBUG
 
#define MAX_DEVICE_ID_LEN   200
 
#define MAX_SEPARATORS_INSTANCEID   0
 
#define MAX_SEPARATORS_DEVICEID   1
 
#define PIP_RETURN_DATA(x, y)   {ReturnLength = x; Data = y; Status = STATUS_SUCCESS; break;}
 
#define PIP_REGISTRY_DATA(x, y)   {ValueName = x; ValueType = y; break;}
 
#define PIP_UNIMPLEMENTED()   {UNIMPLEMENTED_DBGBREAK(); break;}
 

Typedefs

typedef struct _DEVICE_ACTION_DATA DEVICE_ACTION_DATA
 
typedef struct _DEVICE_ACTION_DATAPDEVICE_ACTION_DATA
 

Functions

NTSTATUS NTAPI IopCreateDeviceKeyPath (IN PCUNICODE_STRING RegistryPath, IN ULONG CreateOptions, OUT PHANDLE Handle)
 
NTSTATUS IopPrepareDeviceForRemoval (PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
 
PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance (PUNICODE_STRING DeviceInstance)
 
PDEVICE_NODE FASTCALL IopGetDeviceNode (PDEVICE_OBJECT DeviceObject)
 
VOID IopFixupDeviceId (PWCHAR String)
 
VOID NTAPI IopInstallCriticalDevice (PDEVICE_NODE DeviceNode)
 
NTSTATUS FASTCALL IopInitializeDevice (PDEVICE_NODE DeviceNode, PDRIVER_OBJECT DriverObject)
 
static NTSTATUS NTAPI IopSendEject (IN PDEVICE_OBJECT DeviceObject)
 
static VOID NTAPI IopSendSurpriseRemoval (IN PDEVICE_OBJECT DeviceObject)
 
static NTSTATUS NTAPI IopQueryRemoveDevice (IN PDEVICE_OBJECT DeviceObject)
 
static NTSTATUS NTAPI IopQueryStopDevice (IN PDEVICE_OBJECT DeviceObject)
 
static VOID NTAPI IopSendRemoveDevice (IN PDEVICE_OBJECT DeviceObject)
 
static VOID NTAPI IopCancelRemoveDevice (IN PDEVICE_OBJECT DeviceObject)
 
static VOID NTAPI IopSendStopDevice (IN PDEVICE_OBJECT DeviceObject)
 
static NTSTATUS IopSetServiceEnumData (PDEVICE_NODE DeviceNode)
 
VOID NTAPI IopStartDevice2 (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI IopStartAndEnumerateDevice (IN PDEVICE_NODE DeviceNode)
 
NTSTATUS IopStopDevice (PDEVICE_NODE DeviceNode)
 
NTSTATUS IopStartDevice (PDEVICE_NODE DeviceNode)
 
NTSTATUS NTAPI IopQueryDeviceCapabilities (PDEVICE_NODE DeviceNode, PDEVICE_CAPABILITIES DeviceCaps)
 
static VOID NTAPI IopDeviceActionWorker (_In_ PVOID Context)
 
NTSTATUS IopGetSystemPowerDeviceObject (PDEVICE_OBJECT *DeviceObject)
 
USHORT NTAPI IopGetBusTypeGuidIndex (LPGUID BusTypeGuid)
 
NTSTATUS IopCreateDeviceNode (PDEVICE_NODE ParentNode, PDEVICE_OBJECT PhysicalDeviceObject, PUNICODE_STRING ServiceName, PDEVICE_NODE *DeviceNode)
 
NTSTATUS IopFreeDeviceNode (PDEVICE_NODE DeviceNode)
 
NTSTATUS NTAPI IopSynchronousCall (IN PDEVICE_OBJECT DeviceObject, IN PIO_STACK_LOCATION IoStackLocation, OUT PVOID *Information)
 
NTSTATUS NTAPI IopInitiatePnpIrp (IN PDEVICE_OBJECT DeviceObject, IN OUT PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack OPTIONAL)
 
NTSTATUS IopTraverseDeviceTreeNode (PDEVICETREE_TRAVERSE_CONTEXT Context)
 
NTSTATUS IopTraverseDeviceTree (PDEVICETREE_TRAVERSE_CONTEXT Context)
 
NTSTATUS IopSetDeviceInstanceData (HANDLE InstanceKey, PDEVICE_NODE DeviceNode)
 
NTSTATUS IopGetParentIdPrefix (PDEVICE_NODE DeviceNode, PUNICODE_STRING ParentIdPrefix)
 
static BOOLEAN IopValidateID (_In_ PWCHAR Id, _In_ BUS_QUERY_ID_TYPE QueryType)
 
NTSTATUS IopQueryHardwareIds (PDEVICE_NODE DeviceNode, HANDLE InstanceKey)
 
NTSTATUS IopQueryCompatibleIds (PDEVICE_NODE DeviceNode, HANDLE InstanceKey)
 
NTSTATUS IopCreateDeviceInstancePath (_In_ PDEVICE_NODE DeviceNode, _Out_ PUNICODE_STRING InstancePath)
 
NTSTATUS IopActionInterrogateDeviceStack (PDEVICE_NODE DeviceNode, PVOID Context)
 
static VOID IopHandleDeviceRemoval (IN PDEVICE_NODE DeviceNode, IN PDEVICE_RELATIONS DeviceRelations)
 
NTSTATUS IopEnumerateDevice (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS IopActionConfigureChildServices (PDEVICE_NODE DeviceNode, PVOID Context)
 
NTSTATUS IopActionInitChildServices (PDEVICE_NODE DeviceNode, PVOID Context)
 
NTSTATUS IopInitializePnpServices (IN PDEVICE_NODE DeviceNode)
 
static INIT_FUNCTION NTSTATUS IopEnumerateDetectedDevices (IN HANDLE hBaseKey, IN PUNICODE_STRING RelativePath OPTIONAL, IN HANDLE hRootKey, IN BOOLEAN EnumerateSubKeys, IN PCM_FULL_RESOURCE_DESCRIPTOR ParentBootResources, IN ULONG ParentBootResourcesLength)
 
static INIT_FUNCTION BOOLEAN IopIsFirmwareMapperDisabled (VOID)
 
INIT_FUNCTION NTSTATUS NTAPI IopUpdateRootKey (VOID)
 
NTSTATUS NTAPI IopOpenRegistryKeyEx (PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
 
NTSTATUS NTAPI IopCreateRegistryKeyEx (OUT PHANDLE Handle, IN HANDLE RootHandle OPTIONAL, IN PUNICODE_STRING KeyName, IN ACCESS_MASK DesiredAccess, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
 
NTSTATUS NTAPI IopGetRegistryValue (IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
 
RTL_GENERIC_COMPARE_RESULTS NTAPI PiCompareInstancePath (IN PRTL_AVL_TABLE Table, IN PVOID FirstStruct, IN PVOID SecondStruct)
 
PVOID NTAPI PiAllocateGenericTableEntry (IN PRTL_AVL_TABLE Table, IN CLONG ByteSize)
 
VOID NTAPI PiFreeGenericTableEntry (IN PRTL_AVL_TABLE Table, IN PVOID Buffer)
 
VOID NTAPI PpInitializeDeviceReferenceTable (VOID)
 
BOOLEAN NTAPI PiInitPhase0 (VOID)
 
BOOLEAN NTAPI PpInitSystem (VOID)
 
PDEVICE_NODE NTAPI PipAllocateDeviceNode (IN PDEVICE_OBJECT PhysicalDeviceObject)
 
NTSTATUS NTAPI PnpBusTypeGuidGet (IN USHORT Index, IN LPGUID BusTypeGuid)
 
NTSTATUS NTAPI PnpDeviceObjectToDeviceInstance (IN PDEVICE_OBJECT DeviceObject, IN PHANDLE DeviceInstanceHandle, IN ACCESS_MASK DesiredAccess)
 
ULONG NTAPI PnpDetermineResourceListSize (IN PCM_RESOURCE_LIST ResourceList)
 
NTSTATUS NTAPI PiGetDeviceRegistryProperty (IN PDEVICE_OBJECT DeviceObject, IN ULONG ValueType, IN PWSTR ValueName, IN PWSTR KeyName, OUT PVOID Buffer, IN PULONG BufferLength)
 
NTSTATUS NTAPI IoGetDeviceProperty (IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength)
 
VOID NTAPI IoInvalidateDeviceState (IN PDEVICE_OBJECT PhysicalDeviceObject)
 
IoOpenDeviceRegistryKey

Open a registry key unique for a specified driver or device instance.

Parameters
DeviceObjectDevice to get the registry key for.
DevInstKeyTypeType of the key to return.
DesiredAccessAccess mask (eg. KEY_READ | KEY_WRITE).
DevInstRegKeyHandle to the opened registry key on successful return.
Returns
Status.

@implemented

VOID IopCancelPrepareDeviceForRemoval (PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI IoOpenDeviceRegistryKey (IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
 
static NTSTATUS IopQueryRemoveChildDevices (PDEVICE_NODE ParentDeviceNode, BOOLEAN Force)
 
static VOID IopSendRemoveChildDevices (PDEVICE_NODE ParentDeviceNode)
 
static VOID IopCancelRemoveChildDevices (PDEVICE_NODE ParentDeviceNode)
 
static NTSTATUS IopQueryRemoveDeviceRelations (PDEVICE_RELATIONS DeviceRelations, BOOLEAN Force)
 
static VOID IopSendRemoveDeviceRelations (PDEVICE_RELATIONS DeviceRelations)
 
static VOID IopCancelRemoveDeviceRelations (PDEVICE_RELATIONS DeviceRelations)
 
NTSTATUS IopPrepareDeviceForRemoval (IN PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
 
NTSTATUS IopRemoveDevice (PDEVICE_NODE DeviceNode)
 
VOID NTAPI IoRequestDeviceEject (IN PDEVICE_OBJECT PhysicalDeviceObject)
 
VOID NTAPI IoInvalidateDeviceRelations (IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
 
NTSTATUS NTAPI IoSynchronousInvalidateDeviceRelations (IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
 
BOOLEAN NTAPI IoTranslateBusAddress (IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN PHYSICAL_ADDRESS BusAddress, IN OUT PULONG AddressSpace, OUT PPHYSICAL_ADDRESS TranslatedAddress)
 

Variables

PDEVICE_NODE IopRootDeviceNode
 
KSPIN_LOCK IopDeviceTreeLock
 
ERESOURCE PpRegistryDeviceResource
 
KGUARDED_MUTEX PpDeviceReferenceTableLock
 
RTL_AVL_TABLE PpDeviceReferenceTable
 
ERESOURCE IopDriverLoadResource
 
ULONG ExpInitializationPhase
 
BOOLEAN PnpSystemInit
 
PDRIVER_OBJECT IopRootDriverObject
 
PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList = NULL
 
LIST_ENTRY IopDeviceActionRequestList
 
WORK_QUEUE_ITEM IopDeviceActionWorkItem
 
BOOLEAN IopDeviceActionInProgress
 
KSPIN_LOCK IopDeviceActionLock
 
LONG IopNumberDeviceNodes
 

Macro Definition Documentation

◆ MAX_DEVICE_ID_LEN

#define MAX_DEVICE_ID_LEN   200

Definition at line 28 of file pnpmgr.c.

◆ MAX_SEPARATORS_DEVICEID

#define MAX_SEPARATORS_DEVICEID   1

Definition at line 30 of file pnpmgr.c.

◆ MAX_SEPARATORS_INSTANCEID

#define MAX_SEPARATORS_INSTANCEID   0

Definition at line 29 of file pnpmgr.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file pnpmgr.c.

◆ PIP_REGISTRY_DATA

#define PIP_REGISTRY_DATA (   x,
  y 
)    {ValueName = x; ValueType = y; break;}

Definition at line 4202 of file pnpmgr.c.

◆ PIP_RETURN_DATA

#define PIP_RETURN_DATA (   x,
  y 
)    {ReturnLength = x; Data = y; Status = STATUS_SUCCESS; break;}

Definition at line 4201 of file pnpmgr.c.

◆ PIP_UNIMPLEMENTED

#define PIP_UNIMPLEMENTED ( )    {UNIMPLEMENTED_DBGBREAK(); break;}

Definition at line 4203 of file pnpmgr.c.

Typedef Documentation

◆ DEVICE_ACTION_DATA

◆ PDEVICE_ACTION_DATA

Function Documentation

◆ IoGetDeviceProperty()

NTSTATUS NTAPI IoGetDeviceProperty ( IN PDEVICE_OBJECT  DeviceObject,
IN DEVICE_REGISTRY_PROPERTY  DeviceProperty,
IN ULONG  BufferLength,
OUT PVOID  PropertyBuffer,
OUT PULONG  ResultLength 
)

Definition at line 4210 of file pnpmgr.c.

4215 {
4217  DEVICE_CAPABILITIES DeviceCaps;
4218  ULONG ReturnLength = 0, Length = 0, ValueType;
4219  PWCHAR ValueName = NULL, EnumeratorNameEnd, DeviceInstanceName;
4220  PVOID Data = NULL;
4222  GUID BusTypeGuid;
4223  POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
4224  BOOLEAN NullTerminate = FALSE;
4225 
4226  DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty);
4227 
4228  /* Assume failure */
4229  *ResultLength = 0;
4230 
4231  /* Only PDOs can call this */
4233 
4234  /* Handle all properties */
4235  switch (DeviceProperty)
4236  {
4238 
4239  /* Get the GUID from the internal cache */
4240  Status = PnpBusTypeGuidGet(DeviceNode->ChildBusTypeIndex, &BusTypeGuid);
4241  if (!NT_SUCCESS(Status)) return Status;
4242 
4243  /* This is the format of the returned data */
4244  PIP_RETURN_DATA(sizeof(GUID), &BusTypeGuid);
4245 
4247 
4248  /* Validate correct interface type */
4249  if (DeviceNode->ChildInterfaceType == InterfaceTypeUndefined)
4251 
4252  /* This is the format of the returned data */
4253  PIP_RETURN_DATA(sizeof(INTERFACE_TYPE), &DeviceNode->ChildInterfaceType);
4254 
4256 
4257  /* Validate correct bus number */
4258  if ((DeviceNode->ChildBusNumber & 0x80000000) == 0x80000000)
4260 
4261  /* This is the format of the returned data */
4262  PIP_RETURN_DATA(sizeof(ULONG), &DeviceNode->ChildBusNumber);
4263 
4265 
4266  /* Get the instance path */
4267  DeviceInstanceName = DeviceNode->InstancePath.Buffer;
4268 
4269  /* Sanity checks */
4270  ASSERT((BufferLength & 1) == 0);
4271  ASSERT(DeviceInstanceName != NULL);
4272 
4273  /* Get the name from the path */
4274  EnumeratorNameEnd = wcschr(DeviceInstanceName, OBJ_NAME_PATH_SEPARATOR);
4275  ASSERT(EnumeratorNameEnd);
4276 
4277  /* This string needs to be NULL-terminated */
4278  NullTerminate = TRUE;
4279 
4280  /* This is the format of the returned data */
4281  PIP_RETURN_DATA((ULONG)(EnumeratorNameEnd - DeviceInstanceName) * sizeof(WCHAR),
4282  DeviceInstanceName);
4283 
4284  case DevicePropertyAddress:
4285 
4286  /* Query the device caps */
4288  if (!NT_SUCCESS(Status) || (DeviceCaps.Address == MAXULONG))
4290 
4291  /* This is the format of the returned data */
4292  PIP_RETURN_DATA(sizeof(ULONG), &DeviceCaps.Address);
4293 
4295 
4296  /* Validate we have resources */
4297  if (!DeviceNode->BootResources)
4298 // if (!DeviceNode->BootResourcesTranslated) // FIXFIX: Need this field
4299  {
4300  /* No resources will still fake success, but with 0 bytes */
4301  *ResultLength = 0;
4302  return STATUS_SUCCESS;
4303  }
4304 
4305  /* This is the format of the returned data */
4306  PIP_RETURN_DATA(PnpDetermineResourceListSize(DeviceNode->BootResources), // FIXFIX: Should use BootResourcesTranslated
4307  DeviceNode->BootResources); // FIXFIX: Should use BootResourcesTranslated
4308 
4310 
4311  /* Sanity check for Unicode-sized string */
4312  ASSERT((BufferLength & 1) == 0);
4313 
4314  /* Allocate name buffer */
4316  ObjectNameInfo = ExAllocatePool(PagedPool, Length);
4317  if (!ObjectNameInfo) return STATUS_INSUFFICIENT_RESOURCES;
4318 
4319  /* Query the PDO name */
4321  ObjectNameInfo,
4322  Length,
4323  ResultLength);
4325  {
4326  /* It's up to the caller to try again */
4328  }
4329 
4330  /* This string needs to be NULL-terminated */
4331  NullTerminate = TRUE;
4332 
4333  /* Return if successful */
4334  if (NT_SUCCESS(Status)) PIP_RETURN_DATA(ObjectNameInfo->Name.Length,
4335  ObjectNameInfo->Name.Buffer);
4336 
4337  /* Let the caller know how big the name is */
4339  break;
4340 
4342  PIP_RETURN_DATA(sizeof(UCHAR), &DeviceNode->RemovalPolicy);
4343 
4344  /* Handle the registry-based properties */
4368  //PIP_REGISTRY_DATA(REGSTR_VAL_CONTAINERID, REG_SZ); // Win7
4370  break;
4373  break;
4378  default:
4380  }
4381 
4382  /* Having a registry value name implies registry data */
4383  if (ValueName)
4384  {
4385  /* We know up-front how much data to expect */
4387 
4388  /* Go get the data, use the LogConf subkey if necessary */
4390  ValueType,
4391  ValueName,
4392  (DeviceProperty ==
4394  L"LogConf": NULL,
4395  PropertyBuffer,
4396  ResultLength);
4397  }
4398  else if (NT_SUCCESS(Status))
4399  {
4400  /* We know up-front how much data to expect, check the caller's buffer */
4401  *ResultLength = ReturnLength + (NullTerminate ? sizeof(UNICODE_NULL) : 0);
4402  if (*ResultLength <= BufferLength)
4403  {
4404  /* Buffer is all good, copy the data */
4405  RtlCopyMemory(PropertyBuffer, Data, ReturnLength);
4406 
4407  /* Check if we need to NULL-terminate the string */
4408  if (NullTerminate)
4409  {
4410  /* Terminate the string */
4411  ((PWCHAR)PropertyBuffer)[ReturnLength / sizeof(WCHAR)] = UNICODE_NULL;
4412  }
4413 
4414  /* This is the success path */
4416  }
4417  else
4418  {
4419  /* Failure path */
4421  }
4422  }
4423 
4424  /* Free any allocation we may have made, and return the status code */
4425  if (ObjectNameInfo) ExFreePool(ObjectNameInfo);
4426  return Status;
4427 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define REGSTR_VAL_CLASS
Definition: regstr.h:291
#define REGSTR_VAL_DRIVER
Definition: regstr.h:385
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
enum _INTERFACE_TYPE INTERFACE_TYPE
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4000
NTSTATUS NTAPI PnpBusTypeGuidGet(IN USHORT Index, IN LPGUID BusTypeGuid)
Definition: pnpmgr.c:3998
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1156
#define REGSTR_VAL_CONFIGFLAGS
Definition: regstr.h:388
DEVICE_CAPABILITIES
Definition: iotypes.h:927
#define REGSTR_VAL_UI_NUMBER
Definition: regstr.h:426
uint16_t * PWCHAR
Definition: typedefs.h:54
#define REGSTR_VAL_FRIENDLYNAME
Definition: regstr.h:465
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
NTSTATUS NTAPI PiGetDeviceRegistryProperty(IN PDEVICE_OBJECT DeviceObject, IN ULONG ValueType, IN PWSTR ValueName, IN PWSTR KeyName, OUT PVOID Buffer, IN PULONG BufferLength)
Definition: pnpmgr.c:4119
#define REGSTR_VAL_COMPATIBLEIDS
Definition: regstr.h:296
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
#define UNICODE_NULL
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define REG_MULTI_SZ
Definition: nt_native.h:1501
unsigned char BOOLEAN
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:462
void DPRINT(...)
Definition: polytest.cpp:61
#define REG_RESOURCE_LIST
Definition: nt_native.h:1502
#define PIP_UNIMPLEMENTED()
Definition: pnpmgr.c:4203
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define REGSTR_VAL_CLASSGUID
Definition: regstr.h:422
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
Definition: Node.h:9
PDEVICE_NODE FASTCALL IopGetDeviceNode(PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:66
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define PIP_REGISTRY_DATA(x, y)
Definition: pnpmgr.c:4202
ULONG NTAPI PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList)
Definition: pnpmgr.c:4065
#define REGSTR_VAL_HARDWAREID
Definition: regstr.h:485
#define REGSTR_VAL_DEVDESC
Definition: regstr.h:292
Status
Definition: gdiplustypes.h:24
#define MAXULONG
Definition: typedefs.h:250
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define REGSTR_VAL_MFG
Definition: regstr.h:306
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_In_ DEVICE_REGISTRY_PROPERTY DeviceProperty
Definition: iofuncs.h:1003
#define PIP_RETURN_DATA(x, y)
Definition: pnpmgr.c:4201
NTSTATUS NTAPI IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode, PDEVICE_CAPABILITIES DeviceCaps)
Definition: pnpmgr.c:986
unsigned int ULONG
Definition: retypes.h:1
#define REGSTR_VAL_BOOTCONFIG
Definition: regstr.h:293
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define REG_DWORD
Definition: sdbapi.c:596
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define REGSTR_VAL_LOCATION_INFORMATION
Definition: regstr.h:423
#define REG_SZ
Definition: layer.c:22

Referenced by Bus_AddDevice(), ClasspInitializeHotplugInfo(), GetBusInterface(), CHCDController::HandleDeviceControl(), IntVideoPortCreateAdapterDeviceObject(), IoGetDmaAdapter(), IoOpenDeviceRegistryKey(), IopGetDeviceProperty(), IopUpdateResourceMap(), KspStartBusDevice(), NdisIAddDevice(), NdisIPnPStartDevice(), PcGetDeviceProperty(), PciDetermineSlotNumber(), PciGetDeviceProperty(), RamdiskPnp(), StreamClassStartDevice(), USBH_IoctlGetNodeConnectionDriverKeyName(), USBHUB_FdoHandleDeviceControl(), USBPORT_StartDevice(), and USBPORT_UserGetHcName().

◆ IoInvalidateDeviceRelations()

VOID NTAPI IoInvalidateDeviceRelations ( IN PDEVICE_OBJECT  DeviceObject,
IN DEVICE_RELATION_TYPE  Type 
)

Definition at line 5090 of file pnpmgr.c.

5093 {
5095  KIRQL OldIrql;
5096 
5098  sizeof(DEVICE_ACTION_DATA),
5099  TAG_IO);
5100  if (!Data)
5101  return;
5102 
5104  Data->DeviceObject = DeviceObject;
5105  Data->Type = Type;
5106 
5108  InsertTailList(&IopDeviceActionRequestList, &Data->RequestListEntry);
5110  {
5112  return;
5113  }
5116 
5119  NULL);
5122 }
#define TRUE
Definition: types.h:120
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
#define TAG_IO
Definition: tag.h:69
Type
Definition: Type.h:6
KSPIN_LOCK IopDeviceActionLock
Definition: pnpmgr.c:39
#define InsertTailList(ListHead, Entry)
BOOLEAN IopDeviceActionInProgress
Definition: pnpmgr.c:38
UCHAR KIRQL
Definition: env_spec_w32.h:591
smooth NULL
Definition: ftsmooth.c:416
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
LIST_ENTRY IopDeviceActionRequestList
Definition: pnpmgr.c:36
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
static VOID NTAPI IopDeviceActionWorker(_In_ PVOID Context)
Definition: pnpmgr.c:1060
#define ObReferenceObject
Definition: obfuncs.h:204
WORK_QUEUE_ITEM IopDeviceActionWorkItem
Definition: pnpmgr.c:37

Referenced by _Function_class_(), add_volume_device(), ClassDeviceControl(), ClassInvalidateBusRelations(), ClassRemoveDevice(), CreateUsbChildDeviceObject(), DestroyUsbChildDeviceObject(), DiskDeviceControl(), DiskFdoProcessError(), DiskIoctlGetLengthInfo(), DiskIoctlGetPartitionInfo(), DiskIoctlGetPartitionInfoEx(), FDO_StartDevice(), KsCreateBusEnumObject(), KspBusWorkerRoutine(), KspInstallBusEnumInterface(), KsServiceBusEnumCreateRequest(), RamdiskCreateRamdisk(), remove_volume_child(), ReportGreenPdo(), USBH_ProcessPortStateChange(), USBHUB_RootHubCallBack(), and VideoPortEnumerateChildren().

◆ IoInvalidateDeviceState()

VOID NTAPI IoInvalidateDeviceState ( IN PDEVICE_OBJECT  PhysicalDeviceObject)

Definition at line 4434 of file pnpmgr.c.

4435 {
4437  IO_STACK_LOCATION Stack;
4438  ULONG PnPFlags;
4439  NTSTATUS Status;
4441 
4442  RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
4443  Stack.MajorFunction = IRP_MJ_PNP;
4445 
4446  Status = IopSynchronousCall(PhysicalDeviceObject, &Stack, (PVOID*)&PnPFlags);
4447  if (!NT_SUCCESS(Status))
4448  {
4450  {
4451  DPRINT1("IRP_MN_QUERY_PNP_DEVICE_STATE failed with status 0x%lx\n", Status);
4452  }
4453  return;
4454  }
4455 
4456  if (PnPFlags & PNP_DEVICE_NOT_DISABLEABLE)
4457  DeviceNode->UserFlags |= DNUF_NOT_DISABLEABLE;
4458  else
4459  DeviceNode->UserFlags &= ~DNUF_NOT_DISABLEABLE;
4460 
4461  if (PnPFlags & PNP_DEVICE_DONT_DISPLAY_IN_UI)
4462  DeviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI;
4463  else
4464  DeviceNode->UserFlags &= ~DNUF_DONT_SHOW_IN_UI;
4465 
4466  if ((PnPFlags & PNP_DEVICE_REMOVED) ||
4467  ((PnPFlags & PNP_DEVICE_FAILED) && !(PnPFlags & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED)))
4468  {
4469  /* Flag it if it's failed */
4470  if (PnPFlags & PNP_DEVICE_FAILED) DeviceNode->Problem = CM_PROB_FAILED_POST_START;
4471 
4472  /* Send removal IRPs to all of its children */
4474 
4475  /* Send surprise removal */
4477 
4478  /* Tell the user-mode PnP manager that a device was removed */
4479  IopQueueTargetDeviceEvent(&GUID_DEVICE_SURPRISE_REMOVAL,
4480  &DeviceNode->InstancePath);
4481 
4483  }
4484  else if ((PnPFlags & PNP_DEVICE_FAILED) && (PnPFlags & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED))
4485  {
4486  /* Stop for resource rebalance */
4488  if (!NT_SUCCESS(Status))
4489  {
4490  DPRINT1("Failed to stop device for rebalancing\n");
4491 
4492  /* Stop failed so don't rebalance */
4494  }
4495  }
4496 
4497  /* Resource rebalance */
4499  {
4500  DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n");
4501 
4503  &IoStatusBlock,
4505  NULL);
4507  {
4508  DeviceNode->BootResources =
4511  }
4512  else
4513  {
4514  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
4515  DeviceNode->BootResources = NULL;
4516  }
4517 
4518  DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n");
4519 
4521  &IoStatusBlock,
4523  NULL);
4524  if (NT_SUCCESS(Status))
4525  {
4526  DeviceNode->ResourceRequirements =
4528  }
4529  else
4530  {
4531  DPRINT("IopInitiatePnpIrp() failed (Status %08lx)\n", Status);
4532  DeviceNode->ResourceRequirements = NULL;
4533  }
4534 
4535  /* IRP_MN_FILTER_RESOURCE_REQUIREMENTS is called indirectly by IopStartDevice */
4537  {
4538  DPRINT1("Restart after resource rebalance failed\n");
4539 
4541  DeviceNode->Flags |= DNF_START_FAILED;
4542 
4544  }
4545  }
4546 }
struct _CM_RESOURCE_LIST * PCM_RESOURCE_LIST
#define TRUE
Definition: types.h:120
#define IRP_MN_QUERY_RESOURCES
NTSTATUS NTAPI IopSynchronousCall(IN PDEVICE_OBJECT DeviceObject, IN PIO_STACK_LOCATION IoStackLocation, OUT PVOID *Information)
Definition: pnpmgr.c:1420
#define PNP_DEVICE_REMOVED
Definition: iotypes.h:966
#define DNUF_NOT_DISABLEABLE
Definition: iotypes.h:204
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define DNF_HAS_BOOT_CONFIG
Definition: iotypes.h:196
#define CM_PROB_FAILED_POST_START
Definition: cfg.h:73
static VOID NTAPI IopSendSurpriseRemoval(IN PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:519
#define PNP_DEVICE_DONT_DISPLAY_IN_UI
Definition: iotypes.h:964
#define DNF_START_FAILED
Definition: iotypes.h:169
#define DNUF_DONT_SHOW_IN_UI
Definition: iotypes.h:203
#define IopDeviceNodeSetFlag(DeviceNode, Flag)
Definition: io.h:142
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define DNF_STARTED
Definition: iotypes.h:168
NTSTATUS IopQueueTargetDeviceEvent(const GUID *Guid, PUNICODE_STRING DeviceIds)
Definition: plugplay.c:46
#define PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED
Definition: iotypes.h:967
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define PNP_DEVICE_NOT_DISABLEABLE
Definition: iotypes.h:968
Definition: Node.h:9
PDEVICE_NODE FASTCALL IopGetDeviceNode(PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:66
NTSTATUS IopStartDevice(PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:926
NTSTATUS IopRemoveDevice(PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:4979
NTSTATUS IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
#define PNP_DEVICE_FAILED
Definition: iotypes.h:965
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack OPTIONAL)
Definition: pnpmgr.c:1489
Status
Definition: gdiplustypes.h:24
struct _IO_RESOURCE_REQUIREMENTS_LIST * PIO_RESOURCE_REQUIREMENTS_LIST
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSTATUS IopStopDevice(PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:904
static VOID NTAPI IopSendRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:587
#define DPRINT1
Definition: precomp.h:8
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define IRP_MN_QUERY_PNP_DEVICE_STATE
#define DNF_START_REQUEST_PENDING
Definition: iotypes.h:173

Referenced by HidUsb_ResetWorkerRoutine(), and IopStartDevice2().

◆ IoOpenDeviceRegistryKey()

NTSTATUS NTAPI IoOpenDeviceRegistryKey ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  DevInstKeyType,
IN ACCESS_MASK  DesiredAccess,
OUT PHANDLE  DevInstRegKey 
)

Definition at line 4565 of file pnpmgr.c.

4569 {
4570  static WCHAR RootKeyName[] =
4571  L"\\Registry\\Machine\\System\\CurrentControlSet\\";
4572  static WCHAR ProfileKeyName[] =
4573  L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
4574  static WCHAR ClassKeyName[] = L"Control\\Class\\";
4575  static WCHAR EnumKeyName[] = L"Enum\\";
4576  static WCHAR DeviceParametersKeyName[] = L"Device Parameters";
4578  PWSTR KeyNameBuffer;
4580  ULONG DriverKeyLength;
4583  NTSTATUS Status;
4584 
4585  DPRINT("IoOpenDeviceRegistryKey() called\n");
4586 
4588  {
4589  DPRINT1("IoOpenDeviceRegistryKey(): got wrong params, exiting... \n");
4590  return STATUS_INVALID_PARAMETER;
4591  }
4592 
4596 
4597  /*
4598  * Calculate the length of the base key name. This is the full
4599  * name for driver key or the name excluding "Device Parameters"
4600  * subkey for device key.
4601  */
4602 
4603  KeyNameLength = sizeof(RootKeyName);
4605  KeyNameLength += sizeof(ProfileKeyName) - sizeof(UNICODE_NULL);
4607  {
4608  KeyNameLength += sizeof(ClassKeyName) - sizeof(UNICODE_NULL);
4610  0, NULL, &DriverKeyLength);
4612  return Status;
4613  KeyNameLength += DriverKeyLength;
4614  }
4615  else
4616  {
4617  KeyNameLength += sizeof(EnumKeyName) - sizeof(UNICODE_NULL) +
4618  DeviceNode->InstancePath.Length;
4619  }
4620 
4621  /*
4622  * Now allocate the buffer for the key name...
4623  */
4624 
4625  KeyNameBuffer = ExAllocatePool(PagedPool, KeyNameLength);
4626  if (KeyNameBuffer == NULL)
4628 
4629  KeyName.Length = 0;
4630  KeyName.MaximumLength = (USHORT)KeyNameLength;
4631  KeyName.Buffer = KeyNameBuffer;
4632 
4633  /*
4634  * ...and build the key name.
4635  */
4636 
4637  KeyName.Length += sizeof(RootKeyName) - sizeof(UNICODE_NULL);
4638  RtlCopyMemory(KeyNameBuffer, RootKeyName, KeyName.Length);
4639 
4641  RtlAppendUnicodeToString(&KeyName, ProfileKeyName);
4642 
4644  {
4645  RtlAppendUnicodeToString(&KeyName, ClassKeyName);
4647  DriverKeyLength, KeyNameBuffer +
4648  (KeyName.Length / sizeof(WCHAR)),
4649  &DriverKeyLength);
4650  if (!NT_SUCCESS(Status))
4651  {
4652  DPRINT1("Call to IoGetDeviceProperty() failed with Status 0x%08lx\n", Status);
4653  ExFreePool(KeyNameBuffer);
4654  return Status;
4655  }
4656  KeyName.Length += (USHORT)DriverKeyLength - sizeof(UNICODE_NULL);
4657  }
4658  else
4659  {
4660  RtlAppendUnicodeToString(&KeyName, EnumKeyName);
4662  if (DeviceNode->InstancePath.Length == 0)
4663  {
4664  ExFreePool(KeyNameBuffer);
4665  return Status;
4666  }
4667  }
4668 
4669  /*
4670  * Open the base key.
4671  */
4673  if (!NT_SUCCESS(Status))
4674  {
4675  DPRINT1("IoOpenDeviceRegistryKey(%wZ): Base key doesn't exist, exiting... (Status 0x%08lx)\n", &KeyName, Status);
4676  ExFreePool(KeyNameBuffer);
4677  return Status;
4678  }
4679  ExFreePool(KeyNameBuffer);
4680 
4681  /*
4682  * For driver key we're done now.
4683  */
4684 
4686  return Status;
4687 
4688  /*
4689  * Let's go further. For device key we must open "Device Parameters"
4690  * subkey and create it if it doesn't exist yet.
4691  */
4692 
4693  RtlInitUnicodeString(&KeyName, DeviceParametersKeyName);
4695  &KeyName,
4697  *DevInstRegKey,
4698  NULL);
4699  Status = ZwCreateKey(DevInstRegKey,
4700  DesiredAccess,
4702  0,
4703  NULL,
4705  NULL);
4706  ZwClose(ObjectAttributes.RootDirectory);
4707 
4708  return Status;
4709 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define PLUGPLAY_REGKEY_DEVICE
Definition: iofuncs.h:2738
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:3670
uint16_t * PWSTR
Definition: typedefs.h:54
_In_ ULONG DevInstKeyType
Definition: iofuncs.h:1123
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength)
Definition: pnpmgr.c:4210
void DPRINT(...)
Definition: polytest.cpp:61
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
Definition: Node.h:9
PDEVICE_NODE FASTCALL IopGetDeviceNode(PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:66
static const WCHAR L[]
Definition: oid.c:1250
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define PLUGPLAY_REGKEY_DRIVER
Definition: usbd.c:42
_In_ ULONG _In_ ULONG KeyNameLength
Definition: usbdlib.h:195
_In_ ULONG _In_ ACCESS_MASK _Out_ PHANDLE DevInstRegKey
Definition: iofuncs.h:1123
#define IopIsValidPhysicalDeviceObject(PhysicalDeviceObject)
Definition: io.h:238
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
unsigned short USHORT
Definition: pedump.c:61
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PLUGPLAY_REGKEY_CURRENT_HWPROFILE
Definition: iofuncs.h:2740

Referenced by CdRomGetDeviceParameter(), CdRomSetDeviceParameter(), ClassGetDeviceParameter(), ClasspMediaChangeDeviceInstanceOverride(), ClasspScanForSpecialInRegistry(), ClassSetDeviceParameter(), CmBattAddDevice(), CmBattCreateFdo(), DiskAddDevice(), IntCreateNewRegistryPath(), IntSetupDeviceSettingsKey(), KsMapModuleName(), NdisIPnPStartDevice(), PciAddDevice(), PciGetBiosConfig(), PciSaveBiosConfig(), PcNewRegistryKey(), USBD_GetPdoRegistryParameter(), USBH_SetPdoRegistryParameter(), USBH_WriteFailReasonID(), USBPORT_GetRegistryKeyValueFullInfo(), and USBPORT_SetRegistryKeyValue().

◆ IopActionConfigureChildServices()

NTSTATUS IopActionConfigureChildServices ( PDEVICE_NODE  DeviceNode,
PVOID  Context 
)

Definition at line 2814 of file pnpmgr.c.

2816 {
2818  PDEVICE_NODE ParentDeviceNode;
2821  NTSTATUS Status;
2822  DEVICE_CAPABILITIES DeviceCaps;
2823 
2824  DPRINT("IopActionConfigureChildServices(%p, %p)\n", DeviceNode, Context);
2825 
2826  ParentDeviceNode = (PDEVICE_NODE)Context;
2827 
2828  /*
2829  * We are called for the parent too, but we don't need to do special
2830  * handling for this node
2831  */
2832  if (DeviceNode == ParentDeviceNode)
2833  {
2834  DPRINT("Success\n");
2835  return STATUS_SUCCESS;
2836  }
2837 
2838  /*
2839  * Make sure this device node is a direct child of the parent device node
2840  * that is given as an argument
2841  */
2842 
2843  if (DeviceNode->Parent != ParentDeviceNode)
2844  {
2845  DPRINT("Skipping 2+ level child\n");
2846  return STATUS_SUCCESS;
2847  }
2848 
2849  if (!(DeviceNode->Flags & DNF_PROCESSED))
2850  {
2851  DPRINT1("Child not ready to be configured\n");
2852  return STATUS_SUCCESS;
2853  }
2854 
2855  if (!(DeviceNode->Flags & (DNF_DISABLED | DNF_STARTED | DNF_ADDED)))
2856  {
2857  UNICODE_STRING RegKey;
2858 
2859  /* Install the service for this if it's in the CDDB */
2861 
2862  /*
2863  * Retrieve configuration from Enum key
2864  */
2865 
2866  Service = &DeviceNode->ServiceName;
2867 
2871 
2872  QueryTable[0].Name = L"Service";
2875 
2876  QueryTable[1].Name = L"ClassGUID";
2880  QueryTable[1].DefaultData = L"";
2881  QueryTable[1].DefaultLength = 0;
2882 
2883  RegKey.Length = 0;
2884  RegKey.MaximumLength = sizeof(ENUM_ROOT) + sizeof(WCHAR) + DeviceNode->InstancePath.Length;
2886  RegKey.MaximumLength,
2887  TAG_IO);
2888  if (RegKey.Buffer == NULL)
2889  {
2892  }
2893 
2895  RtlAppendUnicodeToString(&RegKey, L"\\");
2896  RtlAppendUnicodeStringToString(&RegKey, &DeviceNode->InstancePath);
2897 
2899  RegKey.Buffer, QueryTable, NULL, NULL);
2900  ExFreePoolWithTag(RegKey.Buffer, TAG_IO);
2901 
2902  if (!NT_SUCCESS(Status))
2903  {
2904  /* FIXME: Log the error */
2905  DPRINT("Could not retrieve configuration for device %wZ (Status 0x%08x)\n",
2906  &DeviceNode->InstancePath, Status);
2908  return STATUS_SUCCESS;
2909  }
2910 
2911  if (Service->Buffer == NULL)
2912  {
2913  if (NT_SUCCESS(IopQueryDeviceCapabilities(DeviceNode, &DeviceCaps)) &&
2914  DeviceCaps.RawDeviceOK)
2915  {
2916  DPRINT("%wZ is using parent bus driver (%wZ)\n", &DeviceNode->InstancePath, &ParentDeviceNode->ServiceName);
2917  RtlInitEmptyUnicodeString(&DeviceNode->ServiceName, NULL, 0);
2918  }
2919  else if (ClassGUID.Length != 0)
2920  {
2921  /* Device has a ClassGUID value, but no Service value.
2922  * Suppose it is using the NULL driver, so state the
2923  * device is started */
2924  DPRINT("%wZ is using NULL driver\n", &DeviceNode->InstancePath);
2926  }
2927  else
2928  {
2931  }
2932  return STATUS_SUCCESS;
2933  }
2934 
2935  DPRINT("Got Service %S\n", Service->Buffer);
2936  }
2937 
2938  return STATUS_SUCCESS;
2939 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:3988
#define DNF_PROCESSED
Definition: iotypes.h:167
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
USHORT MaximumLength
Definition: env_spec_w32.h:370
VOID NTAPI IopInstallCriticalDevice(PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:85
LONG NTSTATUS
Definition: precomp.h:26
DEVICE_CAPABILITIES
Definition: iotypes.h:927
struct _DEVICE_NODE * PDEVICE_NODE
#define IopDeviceNodeSetFlag(DeviceNode, Flag)
Definition: io.h:142
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
static const WCHAR ClassGUID[]
Definition: devclass.c:30
#define DNF_STARTED
Definition: iotypes.h:168
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ENUM_ROOT
Definition: io.h:53
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
Definition: Node.h:9
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
#define DNF_DISABLED
Definition: iotypes.h:188
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
Status
Definition: gdiplustypes.h:24
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
UNICODE_STRING ServiceName
Definition: iotypes.h:843
#define CM_PROB_FAILED_INSTALL
Definition: cfg.h:58
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode, PDEVICE_CAPABILITIES DeviceCaps)
Definition: pnpmgr.c:986
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define DNF_ADDED
Definition: iotypes.h:179
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define REG_SZ
Definition: layer.c:22

Referenced by IopEnumerateDevice().

◆ IopActionInitChildServices()

NTSTATUS IopActionInitChildServices ( PDEVICE_NODE  DeviceNode,
PVOID  Context 
)

Definition at line 2959 of file pnpmgr.c.

2961 {
2962  PDEVICE_NODE ParentDeviceNode;
2963  NTSTATUS Status;
2964  BOOLEAN BootDrivers = !PnpSystemInit;
2965 
2966  DPRINT("IopActionInitChildServices(%p, %p)\n", DeviceNode, Context);
2967 
2968  ParentDeviceNode = Context;
2969 
2970  /*
2971  * We are called for the parent too, but we don't need to do special
2972  * handling for this node
2973  */
2974  if (DeviceNode == ParentDeviceNode)
2975  {
2976  DPRINT("Success\n");
2977  return STATUS_SUCCESS;
2978  }
2979 
2980  /*
2981  * We don't want to check for a direct child because
2982  * this function is called during boot to reinitialize
2983  * devices with drivers that couldn't load yet due to
2984  * stage 0 limitations (ie can't load from disk yet).
2985  */
2986 
2987  if (!(DeviceNode->Flags & DNF_PROCESSED))
2988  {
2989  DPRINT1("Child not ready to be added\n");
2990  return STATUS_SUCCESS;
2991  }
2992 
2996  return STATUS_SUCCESS;
2997 
2998  if (DeviceNode->ServiceName.Buffer == NULL)
2999  {
3000  /* We don't need to worry about loading the driver because we're
3001  * being driven in raw mode so our parent must be loaded to get here */
3003  if (NT_SUCCESS(Status))
3004  {
3006  if (!NT_SUCCESS(Status))
3007  {
3008  DPRINT1("IopStartDevice(%wZ) failed with status 0x%08x\n",
3009  &DeviceNode->InstancePath, Status);
3010  }
3011  }
3012  }
3013  else
3014  {
3015  PLDR_DATA_TABLE_ENTRY ModuleObject;
3017 
3020  /* Get existing DriverObject pointer (in case the driver has
3021  already been loaded and initialized) */
3023  &DriverObject,
3024  &DeviceNode->ServiceName,
3025  FALSE);
3026 
3027  if (!NT_SUCCESS(Status))
3028  {
3029  /* Driver is not initialized, try to load it */
3030  Status = IopLoadServiceModule(&DeviceNode->ServiceName, &ModuleObject);
3031 
3033  {
3034  /* Initialize the driver */
3036  &DeviceNode->ServiceName, FALSE, &DriverObject);
3038  }
3040  {
3041  DPRINT1("Service '%wZ' is disabled\n", &DeviceNode->ServiceName);
3043  }
3044  else
3045  {
3046  DPRINT("IopLoadServiceModule(%wZ) failed with status 0x%08x\n",
3047  &DeviceNode->ServiceName, Status);
3048  if (!BootDrivers) DeviceNode->Problem = CM_PROB_DRIVER_FAILED_LOAD;
3049  }
3050  }
3053 
3054  /* Driver is loaded and initialized at this point */
3055  if (NT_SUCCESS(Status))
3056  {
3057  /* Initialize the device, including all filters */
3059 
3060  /* Remove the extra reference */
3062  }
3063  else
3064  {
3065  /*
3066  * Don't disable when trying to load only boot drivers
3067  */
3068  if (!BootDrivers)
3069  {
3071  }
3072  }
3073  }
3074 
3075  return STATUS_SUCCESS;
3076 }
NTSTATUS NTAPI PipCallDriverAddDevice(IN PDEVICE_NODE DeviceNode, IN BOOLEAN LoadDriver, IN PDRIVER_OBJECT DriverObject)
Definition: pnpinit.c:240
#define TRUE
Definition: types.h:120
#define DNF_PROCESSED
Definition: iotypes.h:167
BOOLEAN PnpSystemInit
Definition: iomgr.c:17
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS FASTCALL IopLoadServiceModule(IN PUNICODE_STRING ServiceName, OUT PLDR_DATA_TABLE_ENTRY *ModuleObject)
Definition: driver.c:314
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define CM_PROB_FAILED_DRIVER_ENTRY
Definition: cfg.h:67
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define STATUS_DRIVER_UNABLE_TO_LOAD
Definition: ntstatus.h:731
NTSTATUS FASTCALL IopInitializeDevice(PDEVICE_NODE DeviceNode, PDRIVER_OBJECT DriverObject)
Definition: pnpmgr.c:434
#define IopDeviceNodeSetFlag(DeviceNode, Flag)
Definition: io.h:142
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
void DPRINT(...)
Definition: polytest.cpp:61
#define DNF_STARTED
Definition: iotypes.h:168
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CM_PROB_DISABLED_SERVICE
Definition: cfg.h:62
NTSTATUS FASTCALL IopGetDriverObject(OUT PDRIVER_OBJECT *DriverObject, IN PUNICODE_STRING ServiceName, IN BOOLEAN FileSystem)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
Definition: Node.h:9
NTSTATUS IopStartDevice(PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:926
#define CM_PROB_DRIVER_FAILED_LOAD
Definition: cfg.h:69
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: btrfs_drv.h:1814
#define DNF_DISABLED
Definition: iotypes.h:188
#define IopDeviceNodeHasFlag(DeviceNode, Flag)
Definition: io.h:160
Status
Definition: gdiplustypes.h:24
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
NTSTATUS FASTCALL IopInitializeDriverModule(IN PDEVICE_NODE DeviceNode, IN PLDR_DATA_TABLE_ENTRY ModuleObject, IN PUNICODE_STRING ServiceName, IN BOOLEAN FileSystemDriver, OUT PDRIVER_OBJECT *DriverObject)
Definition: driver.c:467
#define DPRINT1
Definition: precomp.h:8
struct tagContext Context
Definition: acpixf.h:1012
ERESOURCE IopDriverLoadResource
Definition: driver.c:19
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define DNF_ADDED
Definition: iotypes.h:179
#define STATUS_IMAGE_ALREADY_LOADED
Definition: ntstatus.h:492

Referenced by IopInitializePnpServices().

◆ IopActionInterrogateDeviceStack()

NTSTATUS IopActionInterrogateDeviceStack ( PDEVICE_NODE  DeviceNode,
PVOID  Context 
)

Definition at line 2337 of file pnpmgr.c.

2339 {
2342  PWSTR LocationInformation;
2343  PDEVICE_NODE ParentDeviceNode;
2344  IO_STACK_LOCATION Stack;
2345  NTSTATUS Status;
2347  LCID LocaleId;
2348  HANDLE InstanceKey = NULL;
2350  UNICODE_STRING InstancePathU;
2351  PDEVICE_OBJECT OldDeviceObject;
2352 
2353  DPRINT("IopActionInterrogateDeviceStack(%p, %p)\n", DeviceNode, Context);
2354  DPRINT("PDO 0x%p\n", DeviceNode->PhysicalDeviceObject);
2355 
2356  ParentDeviceNode = (PDEVICE_NODE)Context;
2357 
2358  /*
2359  * We are called for the parent too, but we don't need to do special
2360  * handling for this node
2361  */
2362  if (DeviceNode == ParentDeviceNode)
2363  {
2364  DPRINT("Success\n");
2365  return STATUS_SUCCESS;
2366  }
2367 
2368  /*
2369  * Make sure this device node is a direct child of the parent device node
2370  * that is given as an argument
2371  */
2372  if (DeviceNode->Parent != ParentDeviceNode)
2373  {
2374  DPRINT("Skipping 2+ level child\n");
2375  return STATUS_SUCCESS;
2376  }
2377 
2378  /* Skip processing if it was already completed before */
2379  if (DeviceNode->Flags & DNF_PROCESSED)
2380  {
2381  /* Nothing to do */
2382  return STATUS_SUCCESS;
2383  }
2384 
2385  /* Get Locale ID */
2386  Status = ZwQueryDefaultLocale(FALSE, &LocaleId);
2387  if (!NT_SUCCESS(Status))
2388  {
2389  DPRINT1("ZwQueryDefaultLocale() failed with status 0x%lx\n", Status);
2390  return Status;
2391  }
2392 
2393  /*
2394  * FIXME: For critical errors, cleanup and disable device, but always
2395  * return STATUS_SUCCESS.
2396  */
2397 
2398  Status = IopCreateDeviceInstancePath(DeviceNode, &InstancePathU);
2399  if (!NT_SUCCESS(Status))
2400  {
2402  {
2403  DPRINT1("IopCreateDeviceInstancePath() failed with status 0x%lx\n", Status);
2404  }
2405 
2406  /* We have to return success otherwise we abort the traverse operation */
2407  return STATUS_SUCCESS;
2408  }
2409 
2410  /* Verify that this is not a duplicate */
2411  OldDeviceObject = IopGetDeviceObjectFromDeviceInstance(&InstancePathU);
2412  if (OldDeviceObject != NULL)
2413  {
2414  PDEVICE_NODE OldDeviceNode = IopGetDeviceNode(OldDeviceObject);
2415 
2416  DPRINT1("Duplicate device instance '%wZ'\n", &InstancePathU);
2417  DPRINT1("Current instance parent: '%wZ'\n", &DeviceNode->Parent->InstancePath);
2418  DPRINT1("Old instance parent: '%wZ'\n", &OldDeviceNode->Parent->InstancePath);
2419 
2420  KeBugCheckEx(PNP_DETECTED_FATAL_ERROR,
2421  0x01,
2422  (ULONG_PTR)DeviceNode->PhysicalDeviceObject,
2423  (ULONG_PTR)OldDeviceObject,
2424  0);
2425  }
2426 
2427  DeviceNode->InstancePath = InstancePathU;
2428 
2429  DPRINT("InstancePath is %S\n", DeviceNode->InstancePath.Buffer);
2430 
2431  /*
2432  * Create registry key for the instance id, if it doesn't exist yet
2433  */
2434  Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
2435  if (!NT_SUCCESS(Status))
2436  {
2437  DPRINT1("Failed to create the instance key! (Status %lx)\n", Status);
2438 
2439  /* We have to return success otherwise we abort the traverse operation */
2440  return STATUS_SUCCESS;
2441  }
2442 
2443  IopQueryHardwareIds(DeviceNode, InstanceKey);
2444 
2445  IopQueryCompatibleIds(DeviceNode, InstanceKey);
2446 
2447  DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextDescription to device stack\n");
2448 
2449  Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextDescription;
2450  Stack.Parameters.QueryDeviceText.LocaleId = LocaleId;
2451  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
2452  &IoStatusBlock,
2454  &Stack);
2456  : NULL;
2457  /* This key is mandatory, so even if the Irp fails, we still write it */
2458  RtlInitUnicodeString(&ValueName, L"DeviceDesc");
2459  if (ZwQueryValueKey(InstanceKey, &ValueName, KeyValueBasicInformation, NULL, 0, &RequiredLength) == STATUS_OBJECT_NAME_NOT_FOUND)
2460  {
2461  if (DeviceDescription &&
2463  {
2464  /* This key is overriden when a driver is installed. Don't write the
2465  * new description if another one already exists */
2466  Status = ZwSetValueKey(InstanceKey,
2467  &ValueName,
2468  0,
2469  REG_SZ,
2471  ((ULONG)wcslen(DeviceDescription) + 1) * sizeof(WCHAR));
2472  }
2473  else
2474  {
2475  UNICODE_STRING DeviceDesc = RTL_CONSTANT_STRING(L"Unknown device");
2476  DPRINT("Driver didn't return DeviceDesc (Status 0x%08lx), so place unknown device there\n", Status);
2477 
2478  Status = ZwSetValueKey(InstanceKey,
2479  &ValueName,
2480  0,
2481  REG_SZ,
2482  DeviceDesc.Buffer,
2483  DeviceDesc.MaximumLength);
2484  if (!NT_SUCCESS(Status))
2485  {
2486  DPRINT1("ZwSetValueKey() failed (Status 0x%lx)\n", Status);
2487  }
2488 
2489  }
2490  }
2491 
2492  if (DeviceDescription)
2493  {
2495  }
2496 
2497  DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextLocation to device stack\n");
2498 
2499  Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextLocationInformation;
2500  Stack.Parameters.QueryDeviceText.LocaleId = LocaleId;
2501  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
2502  &IoStatusBlock,
2504  &Stack);
2506  {
2507  LocationInformation = (PWSTR)IoStatusBlock.Information;
2508  DPRINT("LocationInformation: %S\n", LocationInformation);
2509  RtlInitUnicodeString(&ValueName, L"LocationInformation");
2510  Status = ZwSetValueKey(InstanceKey,
2511  &ValueName,
2512  0,
2513  REG_SZ,
2514  LocationInformation,
2515  ((ULONG)wcslen(LocationInformation) + 1) * sizeof(WCHAR));
2516  if (!NT_SUCCESS(Status))
2517  {
2518  DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
2519  }
2520 
2521  ExFreePoolWithTag(LocationInformation, 0);
2522  }
2523  else
2524  {
2525  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
2526  }
2527 
2528  DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n");
2529 
2530  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
2531  &IoStatusBlock,
2533  NULL);
2535  {
2537 
2538  DeviceNode->ChildBusNumber = BusInformation->BusNumber;
2539  DeviceNode->ChildInterfaceType = BusInformation->LegacyBusType;
2540  DeviceNode->ChildBusTypeIndex = IopGetBusTypeGuidIndex(&BusInformation->BusTypeGuid);
2541  ExFreePoolWithTag(BusInformation, 0);
2542  }
2543  else
2544  {
2545  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
2546 
2547  DeviceNode->ChildBusNumber = 0xFFFFFFF0;
2548  DeviceNode->ChildInterfaceType = InterfaceTypeUndefined;
2549  DeviceNode->ChildBusTypeIndex = -1;
2550  }
2551 
2552  DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n");
2553 
2554  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
2555  &IoStatusBlock,
2557  NULL);
2559  {
2562  }
2563  else
2564  {
2565  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
2566  DeviceNode->BootResources = NULL;
2567  }
2568 
2569  DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n");
2570 
2571  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
2572  &IoStatusBlock,
2574  NULL);
2575  if (NT_SUCCESS(Status))
2576  {
2578  }
2579  else
2580  {
2581  DPRINT("IopInitiatePnpIrp() failed (Status %08lx)\n", Status);
2582  DeviceNode->ResourceRequirements = NULL;
2583  }
2584 
2585  if (InstanceKey != NULL)
2586  {
2587  IopSetDeviceInstanceData(InstanceKey, DeviceNode);
2588  }
2589 
2590  ZwClose(InstanceKey);
2591 
2593 
2595  {
2596  /* Report the device to the user-mode pnp manager */
2597  IopQueueTargetDeviceEvent(&GUID_DEVICE_ENUMERATED,
2598  &DeviceNode->InstancePath);
2599  }
2600 
2601  return STATUS_SUCCESS;
2602 }
struct _CM_RESOURCE_LIST * PCM_RESOURCE_LIST
#define STATUS_PLUGPLAY_NO_DEVICE
Definition: ntstatus.h:717
#define IRP_MN_QUERY_RESOURCES
#define DNF_PROCESSED
Definition: iotypes.h:167
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS
NTSTATUS NTAPI IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, IN ULONG CreateOptions, OUT PHANDLE Handle)
Definition: pnpmgr.c:1594
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS NTAPI ZwQueryDefaultLocale(_In_ BOOLEAN UserProfile, _Out_ PLCID DefaultLocaleId)
#define DNF_HAS_BOOT_CONFIG
Definition: iotypes.h:196
PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance)
Definition: plugplay.c:148
DWORD LCID
Definition: nls.h:13
struct _DEVICE_NODE * Parent
Definition: iotypes.h:825
uint32_t ULONG_PTR
Definition: typedefs.h:63
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
struct _DEVICE_NODE * PDEVICE_NODE
#define UNICODE_NULL
NTSTATUS IopCreateDeviceInstancePath(_In_ PDEVICE_NODE DeviceNode, _Out_ PUNICODE_STRING InstancePath)
Definition: pnpmgr.c:2175
#define IopDeviceNodeSetFlag(DeviceNode, Flag)
Definition: io.h:142
smooth NULL
Definition: ftsmooth.c:416
struct _PNP_BUS_INFORMATION * PPNP_BUS_INFORMATION
void DPRINT(...)
Definition: polytest.cpp:61
USHORT NTAPI IopGetBusTypeGuidIndex(LPGUID BusTypeGuid)
Definition: pnpmgr.c:1106
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
_Must_inspect_result_ _In_ PDEVICE_DESCRIPTION DeviceDescription
Definition: iofuncs.h:1015
NTSTATUS IopQueueTargetDeviceEvent(const GUID *Guid, PUNICODE_STRING DeviceIds)
Definition: plugplay.c:46
NTSTATUS IopSetDeviceInstanceData(HANDLE InstanceKey, PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:1678
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IRP_MN_QUERY_DEVICE_TEXT
Definition: Node.h:9
PDEVICE_NODE FASTCALL IopGetDeviceNode(PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:66
#define IRP_MN_QUERY_BUS_INFORMATION
static const WCHAR L[]
Definition: oid.c:1250
#define DNF_LEGACY_DRIVER
Definition: iotypes.h:181
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack OPTIONAL)
Definition: pnpmgr.c:1489
#define IopDeviceNodeHasFlag(DeviceNode, Flag)
Definition: io.h:160
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
struct _IO_RESOURCE_REQUIREMENTS_LIST * PIO_RESOURCE_REQUIREMENTS_LIST
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:29
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSTATUS IopQueryCompatibleIds(PDEVICE_NODE DeviceNode, HANDLE InstanceKey)
Definition: pnpmgr.c:2111
#define DPRINT1
Definition: precomp.h:8
NTSTATUS IopQueryHardwareIds(PDEVICE_NODE DeviceNode, HANDLE InstanceKey)
Definition: pnpmgr.c:2047
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
return STATUS_SUCCESS
Definition: btrfs.c:2745
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
INTERFACE_TYPE LegacyBusType
Definition: cmtypes.h:363
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:107
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22

Referenced by IopEnumerateDevice(), and IoReportDetectedDevice().

◆ IopCancelPrepareDeviceForRemoval()

VOID IopCancelPrepareDeviceForRemoval ( PDEVICE_OBJECT  DeviceObject)

Definition at line 4887 of file pnpmgr.c.

4888 {
4889  IO_STACK_LOCATION Stack;
4891  PDEVICE_RELATIONS DeviceRelations;
4892  NTSTATUS Status;
4893 
4895 
4896  Stack.Parameters.QueryDeviceRelations.Type = RemovalRelations;
4897 
4899  &IoStatusBlock,
4901  &Stack);
4902  if (!NT_SUCCESS(Status))
4903  {
4904  DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
4905  DeviceRelations = NULL;
4906  }
4907  else
4908  {
4909  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
4910  }
4911 
4912  if (DeviceRelations)
4913  IopCancelRemoveDeviceRelations(DeviceRelations);
4914 }
LONG NTSTATUS
Definition: precomp.h:26
static VOID NTAPI IopCancelRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:614
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static VOID IopCancelRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations)
Definition: pnpmgr.c:4870
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack OPTIONAL)
Definition: pnpmgr.c:1489
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define IRP_MN_QUERY_DEVICE_RELATIONS
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771

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

◆ IopCancelRemoveChildDevices()

static VOID IopCancelRemoveChildDevices ( PDEVICE_NODE  ParentDeviceNode)
static

Definition at line 4789 of file pnpmgr.c.

4790 {
4791  PDEVICE_NODE ChildDeviceNode, NextDeviceNode;
4792  KIRQL OldIrql;
4793 
4795  ChildDeviceNode = ParentDeviceNode->Child;
4796  while (ChildDeviceNode != NULL)
4797  {
4798  NextDeviceNode = ChildDeviceNode->Sibling;
4800 
4802 
4803  ChildDeviceNode = NextDeviceNode;
4804 
4806  }
4808 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:839
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _DEVICE_NODE * Child
Definition: iotypes.h:824
smooth NULL
Definition: ftsmooth.c:416
VOID IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:4887
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
struct _DEVICE_NODE * Sibling
Definition: iotypes.h:823
KSPIN_LOCK IopDeviceTreeLock
Definition: pnpmgr.c:19

Referenced by IoRequestDeviceEject().

◆ IopCancelRemoveDevice()

static VOID NTAPI IopCancelRemoveDevice ( IN PDEVICE_OBJECT  DeviceObject)
static

Definition at line 614 of file pnpmgr.c.

615 {
616  IO_STACK_LOCATION Stack;
617  PVOID Dummy;
618 
619  RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
620  Stack.MajorFunction = IRP_MJ_PNP;
622 
623  /* Drivers should never fail a IRP_MN_CANCEL_REMOVE_DEVICE request */
624  IopSynchronousCall(DeviceObject, &Stack, &Dummy);
625 
628  &GUID_TARGET_DEVICE_REMOVE_CANCELLED,
629  NULL,
630  NULL);
631 }
#define IRP_MN_CANCEL_REMOVE_DEVICE
NTSTATUS NTAPI IopSynchronousCall(IN PDEVICE_OBJECT DeviceObject, IN PIO_STACK_LOCATION IoStackLocation, OUT PVOID *Information)
Definition: pnpmgr.c:1420
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
smooth NULL
Definition: ftsmooth.c:416
VOID IopNotifyPlugPlayNotification(IN PDEVICE_OBJECT DeviceObject, IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory, IN LPCGUID Event, IN PVOID EventCategoryData1, IN PVOID EventCategoryData2)
Definition: pnpnotify.c:36
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261

Referenced by IopCancelPrepareDeviceForRemoval(), and IopPrepareDeviceForRemoval().

◆ IopCancelRemoveDeviceRelations()

static VOID IopCancelRemoveDeviceRelations ( PDEVICE_RELATIONS  DeviceRelations)
static

Definition at line 4870 of file pnpmgr.c.

4871 {
4872  /* This function DOES dereference the device objects in all cases */
4873 
4874  ULONG i;
4875 
4876  for (i = 0; i < DeviceRelations->Count; i++)
4877  {
4878  IopCancelPrepareDeviceForRemoval(DeviceRelations->Objects[i]);
4879  ObDereferenceObject(DeviceRelations->Objects[i]);
4880  DeviceRelations->Objects[i] = NULL;
4881  }
4882 
4883  ExFreePool(DeviceRelations);
4884 }
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2054
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
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
smooth NULL
Definition: ftsmooth.c:416
VOID IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:4887
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

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

◆ IopCreateDeviceInstancePath()

NTSTATUS IopCreateDeviceInstancePath ( _In_ PDEVICE_NODE  DeviceNode,
_Out_ PUNICODE_STRING  InstancePath 
)

Definition at line 2175 of file pnpmgr.c.

2178 {
2180  UNICODE_STRING DeviceId;
2182  IO_STACK_LOCATION Stack;
2183  NTSTATUS Status;
2184  UNICODE_STRING ParentIdPrefix = { 0, 0, NULL };
2186  BOOLEAN IsValidID;
2187 
2188  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryDeviceID to device stack\n");
2189 
2190  Stack.Parameters.QueryId.IdType = BusQueryDeviceID;
2191  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
2192  &IoStatusBlock,
2194  &Stack);
2195  if (!NT_SUCCESS(Status))
2196  {
2197  DPRINT1("IopInitiatePnpIrp(BusQueryDeviceID) failed (Status %x)\n", Status);
2198  return Status;
2199  }
2200 
2202 
2203  if (!IsValidID)
2204  {
2205  DPRINT1("Invalid DeviceID. DeviceNode - %p\n", DeviceNode);
2206  }
2207 
2208  /* Save the device id string */
2210 
2211  DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack (after enumeration)\n");
2212 
2214  if (!NT_SUCCESS(Status))
2215  {
2216  DPRINT1("IopQueryDeviceCapabilities() failed (Status 0x%08lx)\n", Status);
2217  RtlFreeUnicodeString(&DeviceId);
2218  return Status;
2219  }
2220 
2221  /* This bit is only check after enumeration */
2222  if (DeviceCapabilities.HardwareDisabled)
2223  {
2224  /* FIXME: Cleanup device */
2225  DeviceNode->Flags |= DNF_DISABLED;
2226  RtlFreeUnicodeString(&DeviceId);
2228  }
2229  else
2230  {
2231  DeviceNode->Flags &= ~DNF_DISABLED;
2232  }
2233 
2234  if (!DeviceCapabilities.UniqueID)
2235  {
2236  /* Device has not a unique ID. We need to prepend parent bus unique identifier */
2237  DPRINT("Instance ID is not unique\n");
2238  Status = IopGetParentIdPrefix(DeviceNode, &ParentIdPrefix);
2239  if (!NT_SUCCESS(Status))
2240  {
2241  DPRINT1("IopGetParentIdPrefix() failed (Status 0x%08lx)\n", Status);
2242  RtlFreeUnicodeString(&DeviceId);
2243  return Status;
2244  }
2245  }
2246 
2247  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryInstanceID to device stack\n");
2248 
2249  Stack.Parameters.QueryId.IdType = BusQueryInstanceID;
2250  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
2251  &IoStatusBlock,
2253  &Stack);
2254  if (!NT_SUCCESS(Status))
2255  {
2256  DPRINT("IopInitiatePnpIrp(BusQueryInstanceID) failed (Status %lx)\n", Status);
2258  }
2259 
2261  {
2263 
2264  if (!IsValidID)
2265  {
2266  DPRINT1("Invalid InstanceID. DeviceNode - %p\n", DeviceNode);
2267  }
2268  }
2269 
2272 
2273  InstancePath->Length = 0;
2274  InstancePath->MaximumLength = DeviceId.Length + sizeof(WCHAR) +
2275  ParentIdPrefix.Length +
2276  InstanceId.Length +
2277  sizeof(UNICODE_NULL);
2278  if (ParentIdPrefix.Length && InstanceId.Length)
2279  {
2280  InstancePath->MaximumLength += sizeof(WCHAR);
2281  }
2282 
2283  InstancePath->Buffer = ExAllocatePoolWithTag(PagedPool,
2284  InstancePath->MaximumLength,
2285  TAG_IO);
2286  if (!InstancePath->Buffer)
2287  {
2289  RtlFreeUnicodeString(&ParentIdPrefix);
2290  RtlFreeUnicodeString(&DeviceId);
2292  }
2293 
2294  /* Start with the device id */
2295  RtlCopyUnicodeString(InstancePath, &DeviceId);
2296  RtlAppendUnicodeToString(InstancePath, L"\\");
2297 
2298  /* Add information from parent bus device to InstancePath */
2299  RtlAppendUnicodeStringToString(InstancePath, &ParentIdPrefix);
2300  if (ParentIdPrefix.Length && InstanceId.Length)
2301  {
2302  RtlAppendUnicodeToString(InstancePath, L"&");
2303  }
2304 
2305  /* Finally, add the id returned by the driver stack */
2307 
2308  /*
2309  * FIXME: Check for valid characters, if there is invalid characters
2310  * then bugcheck
2311  */
2312 
2314  RtlFreeUnicodeString(&DeviceId);
2315  RtlFreeUnicodeString(&ParentIdPrefix);
2316 
2317  return STATUS_SUCCESS;
2318 }
#define STATUS_PLUGPLAY_NO_DEVICE
Definition: ntstatus.h:717
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IRP_MN_QUERY_ID
#define TAG_IO
Definition: tag.h:69
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
DEVICE_CAPABILITIES
Definition: iotypes.h:927
uint16_t * PWCHAR
Definition: typedefs.h:54
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define UNICODE_NULL
_Must_inspect_result_ _In_opt_ PVOID _In_opt_ PVOID InstanceId
Definition: fsrtlfuncs.h:907
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define DeviceCapabilities
Definition: wingdi.h:4427
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS IopGetParentIdPrefix(PDEVICE_NODE DeviceNode, PUNICODE_STRING ParentIdPrefix)
Definition: pnpmgr.c:1832
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
Definition: Node.h:9
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static BOOLEAN IopValidateID(_In_ PWCHAR Id, _In_ BUS_QUERY_ID_TYPE QueryType)
Definition: pnpmgr.c:1957
static const WCHAR L[]
Definition: oid.c:1250
#define DNF_DISABLED
Definition: iotypes.h:188
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack OPTIONAL)
Definition: pnpmgr.c:1489
Status
Definition: gdiplustypes.h:24
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode, PDEVICE_CAPABILITIES DeviceCaps)
Definition: pnpmgr.c:986
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
return STATUS_SUCCESS
Definition: btrfs.c:2745

Referenced by IopActionInterrogateDeviceStack().

◆ IopCreateDeviceKeyPath()

NTSTATUS NTAPI IopCreateDeviceKeyPath ( IN PCUNICODE_STRING  RegistryPath,
IN ULONG  CreateOptions,
OUT PHANDLE  Handle 
)

Definition at line 1594 of file pnpmgr.c.

1597 {
1599  HANDLE hParent = NULL, hKey;
1602  PCWSTR Current, Last;
1603  USHORT Length;
1604  NTSTATUS Status;
1605 
1606  /* Assume failure */
1607  *Handle = NULL;
1608 
1609  /* Open root key for device instances */
1611  if (!NT_SUCCESS(Status))
1612  {
1613  DPRINT1("ZwOpenKey('%wZ') failed with status 0x%08lx\n", &EnumU, Status);
1614  return Status;
1615  }
1616 
1617  Current = KeyName.Buffer = RegistryPath->Buffer;
1618  Last = &RegistryPath->Buffer[RegistryPath->Length / sizeof(WCHAR)];
1619 
1620  /* Go up to the end of the string */
1621  while (Current <= Last)
1622  {
1623  if (Current != Last && *Current != L'\\')
1624  {
1625  /* Not the end of the string and not a separator */
1626  Current++;
1627  continue;
1628  }
1629 
1630  /* Prepare relative key name */
1631  Length = (USHORT)((ULONG_PTR)Current - (ULONG_PTR)KeyName.Buffer);
1632  KeyName.MaximumLength = KeyName.Length = Length;
1633  DPRINT("Create '%wZ'\n", &KeyName);
1634 
1635  /* Open key */
1637  &KeyName,
1639  hParent,
1640  NULL);
1641  Status = ZwCreateKey(&hKey,
1642  Current == Last ? KEY_ALL_ACCESS : KEY_CREATE_SUB_KEY,
1644  0,
1645  NULL,
1646  CreateOptions,
1647  NULL);
1648 
1649  /* Close parent key handle, we don't need it anymore */
1650  if (hParent)
1651  ZwClose(hParent);
1652 
1653  /* Key opening/creating failed? */
1654  if (!NT_SUCCESS(Status))
1655  {
1656  DPRINT1("ZwCreateKey('%wZ') failed with status 0x%08lx\n", &KeyName, Status);
1657  return Status;
1658  }
1659 
1660  /* Check if it is the end of the string */
1661  if (Current == Last)
1662  {
1663  /* Yes, return success */
1664  *Handle = hKey;
1665  return STATUS_SUCCESS;
1666  }
1667 
1668  /* Start with this new parent key */
1669  hParent = hKey;
1670  Current++;
1671  KeyName.Buffer = (PWSTR)Current;
1672  }
1673 
1674  return STATUS_UNSUCCESSFUL;
1675 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
const uint16_t * PCWSTR
Definition: typedefs.h:55
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:3670
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
uint32_t ULONG_PTR
Definition: typedefs.h:63
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
_In_ HANDLE Handle
Definition: extypes.h:390
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ENUM_ROOT
Definition: io.h:53
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG CreateOptions
Definition: fltkernel.h:1230
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static const WCHAR L[]
Definition: oid.c:1250
const DOCKBAR PVOID HWND hParent
Definition: tooldock.h:22
Status
Definition: gdiplustypes.h:24
unsigned short USHORT
Definition: pedump.c:61
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define DPRINT1
Definition: precomp.h:8
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by IopActionInterrogateDeviceStack(), IopCreateDeviceNode(), IopInstallCriticalDevice(), IopQueryDeviceCapabilities(), IopStartDevice(), and IoReportDetectedDevice().

◆ IopCreateDeviceNode()

NTSTATUS IopCreateDeviceNode ( PDEVICE_NODE  ParentNode,
PDEVICE_OBJECT  PhysicalDeviceObject,
PUNICODE_STRING  ServiceName,
PDEVICE_NODE DeviceNode 
)

Definition at line 1187 of file pnpmgr.c.

1191 {
1193  NTSTATUS Status;
1194  KIRQL OldIrql;
1195  UNICODE_STRING FullServiceName;
1196  UNICODE_STRING LegacyPrefix = RTL_CONSTANT_STRING(L"LEGACY_");
1197  UNICODE_STRING UnknownDeviceName = RTL_CONSTANT_STRING(L"UNKNOWN");
1198  UNICODE_STRING KeyName, ClassName;
1199  PUNICODE_STRING ServiceName1;
1200  ULONG LegacyValue;
1202  HANDLE InstanceHandle;
1203 
1204  DPRINT("ParentNode 0x%p PhysicalDeviceObject 0x%p ServiceName %wZ\n",
1205  ParentNode, PhysicalDeviceObject, ServiceName);
1206 
1208  if (!Node)
1209  {
1211  }
1212 
1213  RtlZeroMemory(Node, sizeof(DEVICE_NODE));
1214 
1215  if (!ServiceName)
1216  ServiceName1 = &UnknownDeviceName;
1217  else
1218  ServiceName1 = ServiceName;
1219 
1220  if (!PhysicalDeviceObject)
1221  {
1222  FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName1->Length + sizeof(UNICODE_NULL);
1223  FullServiceName.Length = 0;
1224  FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength);
1225  if (!FullServiceName.Buffer)
1226  {
1229  }
1230 
1231  RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix);
1232  RtlAppendUnicodeStringToString(&FullServiceName, ServiceName1);
1233  RtlUpcaseUnicodeString(&FullServiceName, &FullServiceName, FALSE);
1234 
1235  Status = PnpRootCreateDevice(&FullServiceName, NULL, &PhysicalDeviceObject, &Node->InstancePath);
1236  if (!NT_SUCCESS(Status))
1237  {
1238  DPRINT1("PnpRootCreateDevice() failed with status 0x%08X\n", Status);
1239  ExFreePool(FullServiceName.Buffer);
1241  return Status;
1242  }
1243 
1244  /* Create the device key for legacy drivers */
1245  Status = IopCreateDeviceKeyPath(&Node->InstancePath, REG_OPTION_VOLATILE, &InstanceHandle);
1246  if (!NT_SUCCESS(Status))
1247  {
1248  ExFreePool(FullServiceName.Buffer);
1250  return Status;
1251  }
1252 
1253  Node->ServiceName.MaximumLength = ServiceName1->Length + sizeof(UNICODE_NULL);
1254  Node->ServiceName.Length = 0;
1255  Node->ServiceName.Buffer = ExAllocatePool(PagedPool, Node->ServiceName.MaximumLength);
1256  if (!Node->ServiceName.Buffer)
1257  {
1258  ZwClose(InstanceHandle);
1259  ExFreePool(FullServiceName.Buffer);
1261  return Status;
1262  }
1263 
1264  RtlCopyUnicodeString(&Node->ServiceName, ServiceName1);
1265 
1266  if (ServiceName)
1267  {
1268  RtlInitUnicodeString(&KeyName, L"Service");
1269  Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName->Buffer, ServiceName->Length + sizeof(UNICODE_NULL));
1270  }
1271 
1272  if (NT_SUCCESS(Status))
1273  {
1274  RtlInitUnicodeString(&KeyName, L"Legacy");
1275  LegacyValue = 1;
1276  Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue));
1277 
1278  RtlInitUnicodeString(&KeyName, L"ConfigFlags");
1279  LegacyValue = 0;
1280  ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue));
1281 
1282  if (NT_SUCCESS(Status))
1283  {
1284  RtlInitUnicodeString(&KeyName, L"Class");
1285  RtlInitUnicodeString(&ClassName, L"LegacyDriver");
1286  Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassName.Buffer, ClassName.Length + sizeof(UNICODE_NULL));
1287  if (NT_SUCCESS(Status))
1288  {
1289  RtlInitUnicodeString(&KeyName, L"ClassGUID");
1290  RtlInitUnicodeString(&ClassGUID, L"{8ECC055D-047F-11D1-A537-0000F8753ED1}");
1291  Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassGUID.Buffer, ClassGUID.Length + sizeof(UNICODE_NULL));
1292  if (NT_SUCCESS(Status))
1293  {
1294  // FIXME: Retrieve the real "description" by looking at the "DisplayName" string
1295  // of the corresponding CurrentControlSet\Services\xxx entry for this driver.
1296  RtlInitUnicodeString(&KeyName, L"DeviceDesc");
1297  Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName1->Buffer, ServiceName1->Length + sizeof(UNICODE_NULL));
1298  }
1299  }
1300  }
1301  }
1302 
1303  ZwClose(InstanceHandle);
1304  ExFreePool(FullServiceName.Buffer);
1305 
1306  if (!NT_SUCCESS(Status))
1307  {
1308  ExFreePool(Node->ServiceName.Buffer);
1310  return Status;
1311  }
1312 
1317  }
1318 
1319  Node->PhysicalDeviceObject = PhysicalDeviceObject;
1320 
1321  ((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = Node;
1322 
1323  if (ParentNode)
1324  {
1326  Node->Parent = ParentNode;
1327  Node->Sibling = NULL;
1328  if (ParentNode->LastChild == NULL)
1329  {
1330  ParentNode->Child = Node;
1331  ParentNode->LastChild = Node;
1332  }
1333  else
1334  {
1335  ParentNode->LastChild->Sibling = Node;
1336  ParentNode->LastChild = Node;
1337  }
1339  Node->Level = ParentNode->Level + 1;
1340  }
1341 
1343 
1344  *DeviceNode = Node;
1345 
1346  return STATUS_SUCCESS;
1347 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
#define DNF_PROCESSED
Definition: iotypes.h:167
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define TAG_IO_DEVNODE
Definition: tag.h:89
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTATUS NTAPI IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, IN ULONG CreateOptions, OUT PHANDLE Handle)
Definition: pnpmgr.c:1594
LONG NTSTATUS
Definition: precomp.h:26
struct _EXTENDED_DEVOBJ_EXTENSION * PEXTENDED_DEVOBJ_EXTENSION
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _DEVICE_NODE * Child
Definition: iotypes.h:824
#define UNICODE_NULL
union node Node
Definition: types.h:1255
#define IopDeviceNodeSetFlag(DeviceNode, Flag)
Definition: io.h:142
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
static const WCHAR ClassGUID[]
Definition: devclass.c:30
#define DNF_STARTED
Definition: iotypes.h:168
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
Definition: Node.h:9
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
struct _DEVICE_NODE * LastChild
Definition: iotypes.h:826
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define DNF_LEGACY_DRIVER
Definition: iotypes.h:181
Status
Definition: gdiplustypes.h:24
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define DPRINT1
Definition: precomp.h:8
ULONG Level
Definition: iotypes.h:827
KSPIN_LOCK IopDeviceTreeLock
Definition: pnpmgr.c:19
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define DNF_ADDED
Definition: iotypes.h:179
#define REG_DWORD
Definition: sdbapi.c:596
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS PnpRootCreateDevice(IN PUNICODE_STRING ServiceName, IN OPTIONAL PDRIVER_OBJECT DriverObject, OUT PDEVICE_OBJECT *PhysicalDeviceObject, OUT OPTIONAL PUNICODE_STRING FullInstancePath)
Definition: pnproot.c:186
Definition: dlist.c:348
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22

Referenced by IopEnumerateDevice().

◆ IopCreateRegistryKeyEx()

NTSTATUS NTAPI IopCreateRegistryKeyEx ( OUT PHANDLE  Handle,
IN HANDLE RootHandle  OPTIONAL,
IN PUNICODE_STRING  KeyName,
IN ACCESS_MASK  DesiredAccess,
IN ULONG  CreateOptions,
OUT PULONG Disposition  OPTIONAL 
)

Definition at line 3695 of file pnpmgr.c.

3701 {
3703  ULONG KeyDisposition, RootHandleIndex = 0, i = 1, NestedCloseLevel = 0;
3704  USHORT Length;
3705  HANDLE HandleArray[2];
3706  BOOLEAN Recursing = TRUE;
3707  PWCHAR pp, p, p1;
3708  UNICODE_STRING KeyString;
3710  PAGED_CODE();
3711 
3712  /* P1 is start, pp is end */
3713  p1 = KeyName->Buffer;
3714  pp = (PVOID)((ULONG_PTR)p1 + KeyName->Length);
3715 
3716  /* Create the target key */
3718  KeyName,
3720  RootHandle,
3721  NULL);
3722  Status = ZwCreateKey(&HandleArray[i],
3723  DesiredAccess,
3725  0,
3726  NULL,
3727  CreateOptions,
3728  &KeyDisposition);
3729 
3730  /* Now we check if this failed */
3731  if ((Status == STATUS_OBJECT_NAME_NOT_FOUND) && (RootHandle))
3732  {
3733  /* Target key failed, so we'll need to create its parent. Setup array */
3734  HandleArray[0] = NULL;
3735  HandleArray[1] = RootHandle;
3736 
3737  /* Keep recursing for each missing parent */
3738  while (Recursing)
3739  {
3740  /* And if we're deep enough, close the last handle */
3741  if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]);
3742 
3743  /* We're setup to ping-pong between the two handle array entries */
3744  RootHandleIndex = i;
3745  i = (i + 1) & 1;
3746 
3747  /* Clear the one we're attempting to open now */
3748  HandleArray[i] = NULL;
3749 
3750  /* Process the parent key name */
3751  for (p = p1; ((p < pp) && (*p != OBJ_NAME_PATH_SEPARATOR)); p++);
3752  Length = (USHORT)(p - p1) * sizeof(WCHAR);
3753 
3754  /* Is there a parent name? */
3755  if (Length)
3756  {
3757  /* Build the unicode string for it */
3758  KeyString.Buffer = p1;
3759  KeyString.Length = KeyString.MaximumLength = Length;
3760 
3761  /* Now try opening the parent */
3763  &KeyString,
3765  HandleArray[RootHandleIndex],
3766  NULL);
3767  Status = ZwCreateKey(&HandleArray[i],
3768  DesiredAccess,
3770  0,
3771  NULL,
3772  CreateOptions,
3773  &KeyDisposition);
3774  if (NT_SUCCESS(Status))
3775  {
3776  /* It worked, we have one more handle */
3777  NestedCloseLevel++;
3778  }
3779  else
3780  {
3781  /* Parent key creation failed, abandon loop */
3782  Recursing = FALSE;
3783  continue;
3784  }
3785  }
3786  else
3787  {
3788  /* We don't have a parent name, probably corrupted key name */
3790  Recursing = FALSE;
3791  continue;
3792  }
3793 
3794  /* Now see if there's more parents to create */
3795  p1 = p + 1;
3796  if ((p == pp) || (p1 == pp))
3797  {
3798  /* We're done, hopefully successfully, so stop */
3799  Recursing = FALSE;
3800  }
3801  }
3802 
3803  /* Outer loop check for handle nesting that requires closing the top handle */
3804  if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]);
3805  }
3806 
3807  /* Check if we broke out of the loop due to success */
3808  if (NT_SUCCESS(Status))
3809  {
3810  /* Return the target handle (we closed all the parent ones) and disposition */
3811  *Handle = HandleArray[i];
3812  if (Disposition) *Disposition = KeyDisposition;
3813  }
3814 
3815  /* Return the success state */
3816  return Status;
3817 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
#define TRUE
Definition: types.h:120
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
uint16_t * PWCHAR
Definition: typedefs.h:54
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
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 OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define pp
Definition: hlsl.yy.c:978
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
_In_ HANDLE Handle
Definition: extypes.h:390
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG CreateOptions
Definition: fltkernel.h:1230
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
unsigned short USHORT
Definition: pedump.c:61
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
GLfloat GLfloat p
Definition: glext.h:8902
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231

Referenced by IopSetServiceEnumData().

◆ IopDeviceActionWorker()

static VOID NTAPI IopDeviceActionWorker ( _In_ PVOID  Context)
static

Definition at line 1060 of file pnpmgr.c.

1062 {
1063  PLIST_ENTRY ListEntry;
1065  KIRQL OldIrql;
1066 
1069  {
1072  Data = CONTAINING_RECORD(ListEntry,
1074  RequestListEntry);
1075 
1077  Data->Type);
1078 
1079  ObDereferenceObject(Data->DeviceObject);
1082  }
1085 }
NTSTATUS NTAPI IoSynchronousInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:5129
#define TAG_IO
Definition: tag.h:69
KSPIN_LOCK IopDeviceActionLock
Definition: pnpmgr.c:39
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
BOOLEAN IopDeviceActionInProgress
Definition: pnpmgr.c:38
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: typedefs.h:117
LIST_ENTRY IopDeviceActionRequestList
Definition: pnpmgr.c:36
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by IoInvalidateDeviceRelations().

◆ IopEnumerateDetectedDevices()

static INIT_FUNCTION NTSTATUS IopEnumerateDetectedDevices ( IN HANDLE  hBaseKey,
IN PUNICODE_STRING RelativePath  OPTIONAL,
IN HANDLE  hRootKey,
IN BOOLEAN  EnumerateSubKeys,
IN PCM_FULL_RESOURCE_DESCRIPTOR  ParentBootResources,
IN ULONG  ParentBootResourcesLength 
)
static

Definition at line 3109 of file pnpmgr.c.

3116 {
3117  UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier");
3118  UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID");
3119  UNICODE_STRING ConfigurationDataU = RTL_CONSTANT_STRING(L"Configuration Data");
3120  UNICODE_STRING BootConfigU = RTL_CONSTANT_STRING(L"BootConfig");
3121  UNICODE_STRING LogConfU = RTL_CONSTANT_STRING(L"LogConf");
3123  HANDLE hDevicesKey = NULL;
3124  HANDLE hDeviceKey = NULL;
3125  HANDLE hLevel1Key, hLevel2Key = NULL, hLogConf;
3126  UNICODE_STRING Level2NameU;
3127  WCHAR Level2Name[5];
3128  ULONG IndexDevice = 0;
3129  ULONG IndexSubKey;
3130  PKEY_BASIC_INFORMATION pDeviceInformation = NULL;
3131  ULONG DeviceInfoLength = sizeof(KEY_BASIC_INFORMATION) + 50 * sizeof(WCHAR);
3132  PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL;
3133  ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR);
3136  PCM_FULL_RESOURCE_DESCRIPTOR BootResources = NULL;
3137  ULONG BootResourcesLength;
3138  NTSTATUS Status;
3139 
3140  const UNICODE_STRING IdentifierSerial = RTL_CONSTANT_STRING(L"SerialController");
3141  UNICODE_STRING HardwareIdSerial = RTL_CONSTANT_STRING(L"*PNP0501\0");
3142  static ULONG DeviceIndexSerial = 0;
3143  const UNICODE_STRING IdentifierKeyboard = RTL_CONSTANT_STRING(L"KeyboardController");
3144  UNICODE_STRING HardwareIdKeyboard = RTL_CONSTANT_STRING(L"*PNP0303\0");
3145  static ULONG DeviceIndexKeyboard = 0;
3146  const UNICODE_STRING IdentifierMouse = RTL_CONSTANT_STRING(L"PointerController");
3147  UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*PNP0F13\0");
3148  static ULONG DeviceIndexMouse = 0;
3149  const UNICODE_STRING IdentifierParallel = RTL_CONSTANT_STRING(L"ParallelController");
3150  UNICODE_STRING HardwareIdParallel = RTL_CONSTANT_STRING(L"*PNP0400\0");
3151  static ULONG DeviceIndexParallel = 0;
3152  const UNICODE_STRING IdentifierFloppy = RTL_CONSTANT_STRING(L"FloppyDiskPeripheral");
3153  UNICODE_STRING HardwareIdFloppy = RTL_CONSTANT_STRING(L"*PNP0700\0");
3154  static ULONG DeviceIndexFloppy = 0;
3155  UNICODE_STRING HardwareIdKey;
3156  PUNICODE_STRING pHardwareId;
3157  ULONG DeviceIndex = 0;
3158  PUCHAR CmResourceList;
3159  ULONG ListCount;
3160 
3161  if (RelativePath)
3162  {
3163  Status = IopOpenRegistryKeyEx(&hDevicesKey, hBaseKey, RelativePath, KEY_ENUMERATE_SUB_KEYS);
3164  if (!NT_SUCCESS(Status))
3165  {
3166  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
3167  goto cleanup;
3168  }
3169  }
3170  else
3171  hDevicesKey = hBaseKey;
3172 
3173  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
3174  if (!pDeviceInformation)
3175  {
3176  DPRINT("ExAllocatePool() failed\n");
3178  goto cleanup;
3179  }
3180 
3181  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
3182  if (!pValueInformation)
3183  {
3184  DPRINT("ExAllocatePool() failed\n");
3186  goto cleanup;
3187  }
3188 
3189  while (TRUE)
3190  {
3191  Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
3193  break;
3195  {
3196  ExFreePool(pDeviceInformation);
3197  DeviceInfoLength = RequiredSize;
3198  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
3199  if (!pDeviceInformation)
3200  {
3201  DPRINT("ExAllocatePool() failed\n");
3203  goto cleanup;
3204  }
3205  Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
3206  }
3207  if (!NT_SUCCESS(Status))
3208  {
3209  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
3210  goto cleanup;
3211  }
3212  IndexDevice++;
3213 
3214  /* Open device key */
3215  DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength;
3216  DeviceName.Buffer = pDeviceInformation->Name;
3217 
3218  Status = IopOpenRegistryKeyEx(&hDeviceKey, hDevicesKey, &DeviceName,
3219  KEY_QUERY_VALUE + (EnumerateSubKeys ? KEY_ENUMERATE_SUB_KEYS : 0));
3220  if (!NT_SUCCESS(Status))
3221  {
3222  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
3223  goto cleanup;
3224  }
3225 
3226  /* Read boot resources, and add then to parent ones */
3227  Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
3229  {
3230  ExFreePool(pValueInformation);
3231  ValueInfoLength = RequiredSize;
3232  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
3233  if (!pValueInformation)
3234  {
3235  DPRINT("ExAllocatePool() failed\n");
3236  ZwDeleteKey(hLevel2Key);
3238  goto cleanup;
3239  }
3240  Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
3241  }
3243  {
3244  BootResources = ParentBootResources;
3245  BootResourcesLength = ParentBootResourcesLength;
3246  }
3247  else if (!NT_SUCCESS(Status))
3248  {
3249  DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
3250  goto nextdevice;
3251  }
3252  else if (pValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR)
3253  {
3254  DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_FULL_RESOURCE_DESCRIPTOR);
3255  goto nextdevice;
3256  }
3257  else
3258  {
3259  static const ULONG Header = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors);
3260 
3261  /* Concatenate current resources and parent ones */
3262  if (ParentBootResourcesLength == 0)
3263  BootResourcesLength = pValueInformation->DataLength;
3264  else
3265  BootResourcesLength = ParentBootResourcesLength
3266  + pValueInformation->DataLength
3267  - Header;
3268  BootResources = ExAllocatePool(PagedPool, BootResourcesLength);
3269  if (!BootResources)
3270  {
3271  DPRINT("ExAllocatePool() failed\n");
3272  goto nextdevice;
3273  }
3274  if (ParentBootResourcesLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
3275  {
3276  RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength);
3277  }
3278  else if (ParentBootResources->PartialResourceList.PartialDescriptors[ParentBootResources->PartialResourceList.Count - 1].Type == CmResourceTypeDeviceSpecific)
3279  {
3280  RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength);
3281  RtlCopyMemory(
3282  (PVOID)((ULONG_PTR)BootResources + pValueInformation->DataLength),
3283  (PVOID)((ULONG_PTR)ParentBootResources + Header),
3284  ParentBootResourcesLength - Header);
3285  BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count;
3286  }
3287  else
3288  {
3289  RtlCopyMemory(BootResources, pValueInformation->Data, Header);
3290  RtlCopyMemory(
3291  (PVOID)((ULONG_PTR)BootResources + Header),
3292  (PVOID)((ULONG_PTR)ParentBootResources + Header),
3293  ParentBootResourcesLength - Header);
3294  RtlCopyMemory(
3295  (PVOID)((ULONG_PTR)BootResources + ParentBootResourcesLength),
3296  pValueInformation->Data + Header,
3297  pValueInformation->DataLength - Header);
3298  BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count;
3299  }
3300  }
3301 
3302  if (EnumerateSubKeys)
3303  {
3304  IndexSubKey = 0;
3305  while (TRUE)
3306  {
3307  Status = ZwEnumerateKey(hDeviceKey, IndexSubKey, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
3309  break;
3311  {
3312  ExFreePool(pDeviceInformation);
3313  DeviceInfoLength = RequiredSize;
3314  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
3315  if (!pDeviceInformation)
3316  {
3317  DPRINT("ExAllocatePool() failed\n");
3319  goto cleanup;
3320  }
3321  Status = ZwEnumerateKey(hDeviceKey, IndexSubKey, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
3322  }
3323  if (!NT_SUCCESS(Status))
3324  {
3325  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
3326  goto cleanup;
3327  }
3328  IndexSubKey++;
3329  DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength;
3330  DeviceName.Buffer = pDeviceInformation->Name;
3331 
3333  hDeviceKey,
3334  &DeviceName,
3335  hRootKey,
3336  TRUE,
3337  BootResources,
3338  BootResourcesLength);
3339  if (!NT_SUCCESS(Status))
3340  goto cleanup;
3341  }
3342  }
3343 
3344  /* Read identifier */
3345  Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
3347  {
3348  ExFreePool(pValueInformation);
3349  ValueInfoLength = RequiredSize;
3350  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
3351  if (!pValueInformation)
3352  {
3353  DPRINT("ExAllocatePool() failed\n");
3355  goto cleanup;
3356  }
3357  Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
3358  }
3359  if (!NT_SUCCESS(Status))
3360  {
3362  {
3363  DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
3364  goto nextdevice;
3365  }
3367  }
3368  else if (pValueInformation->Type != REG_SZ)
3369  {
3370  DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ);
3371  goto nextdevice;
3372  }
3373  else
3374  {
3375  /* Assign hardware id to this device */
3376  ValueName.Length = ValueName.MaximumLength = (USHORT)pValueInformation->DataLength;
3377  ValueName.Buffer = (PWCHAR)pValueInformation->Data;
3378  if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL)
3379  ValueName.Length -= sizeof(WCHAR);
3380  }
3381 
3382  if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0)
3383  {
3384  pHardwareId = &HardwareIdSerial;
3385  DeviceIndex = DeviceIndexSerial++;
3386  }
3387  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierKeyboard, FALSE) == 0)
3388  {
3389  pHardwareId = &HardwareIdKeyboard;
3390  DeviceIndex = DeviceIndexKeyboard++;
3391  }
3392  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierMouse, FALSE) == 0)
3393  {
3394  pHardwareId = &HardwareIdMouse;
3395  DeviceIndex = DeviceIndexMouse++;
3396  }
3397  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierParallel, FALSE) == 0)
3398  {
3399  pHardwareId = &HardwareIdParallel;
3400  DeviceIndex = DeviceIndexParallel++;
3401  }
3402  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierFloppy, FALSE) == 0)
3403  {
3404  pHardwareId = &HardwareIdFloppy;
3405  DeviceIndex = DeviceIndexFloppy++;
3406  }
3407  else
3408  {
3409  /* Unknown key path */
3410  DPRINT("Unknown key path '%wZ'\n", RelativePath);
3411  goto nextdevice;
3412  }
3413 
3414  /* Prepare hardware id key (hardware id value without final \0) */
3415  HardwareIdKey = *pHardwareId;
3416  HardwareIdKey.Length -= sizeof(UNICODE_NULL);
3417 
3418  /* Add the detected device to Root key */
3419  InitializeObjectAttributes(&ObjectAttributes, &HardwareIdKey, OBJ_KERNEL_HANDLE, hRootKey, NULL);
3420  Status = ZwCreateKey(
3421  &hLevel1Key,
3424  0,
3425  NULL,
3427  NULL);
3428  if (!NT_SUCCESS(Status))
3429  {
3430  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
3431  goto nextdevice;
3432  }
3433  swprintf(Level2Name, L"%04lu", DeviceIndex);
3434  RtlInitUnicodeString(&Level2NameU, Level2Name);
3435  InitializeObjectAttributes(&ObjectAttributes, &Level2NameU, OBJ_KERNEL_HANDLE, hLevel1Key, NULL);
3436  Status = ZwCreateKey(
3437  &hLevel2Key,
3440  0,
3441  NULL,
3443  NULL);
3444  ZwClose(hLevel1Key);
3445  if (!NT_SUCCESS(Status))
3446  {
3447  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
3448  goto nextdevice;
3449  }
3450  DPRINT("Found %wZ #%lu (%wZ)\n", &ValueName, DeviceIndex, &HardwareIdKey);
3451  Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength);
3452  if (!NT_SUCCESS(Status))
3453  {
3454  DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
3455  ZwDeleteKey(hLevel2Key);
3456  goto nextdevice;
3457  }
3458  /* Create 'LogConf' subkey */
3460  Status = ZwCreateKey(
3461  &hLogConf,
3462  KEY_SET_VALUE,
3464  0,
3465  NULL,
3467  NULL);
3468  if (!NT_SUCCESS(Status))
3469  {
3470  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
3471  ZwDeleteKey(hLevel2Key);
3472  goto nextdevice;
3473  }
3474  if (BootResourcesLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
3475  {
3476  CmResourceList = ExAllocatePool(PagedPool, BootResourcesLength + sizeof(ULONG));
3477  if (!CmResourceList)
3478  {
3479  ZwClose(hLogConf);
3480  ZwDeleteKey(hLevel2Key);
3481  goto nextdevice;
3482  }
3483 
3484  /* Add the list count (1st member of CM_RESOURCE_LIST) */
3485  ListCount = 1;
3486  RtlCopyMemory(CmResourceList,
3487  &ListCount,
3488  sizeof(ULONG));
3489 
3490  /* Now add the actual list (2nd member of CM_RESOURCE_LIST) */
3491  RtlCopyMemory(CmResourceList + sizeof(ULONG),
3492  BootResources,
3493  BootResourcesLength);
3494 
3495  /* Save boot resources to 'LogConf\BootConfig' */
3496  Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, REG_RESOURCE_LIST, CmResourceList, BootResourcesLength + sizeof(ULONG));
3497  if (!NT_SUCCESS(Status))
3498  {
3499  DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
3500  ZwClose(hLogConf);
3501  ZwDeleteKey(hLevel2Key);
3502  goto nextdevice;
3503  }
3504  }
3505  ZwClose(hLogConf);
3506 
3507 nextdevice:
3508  if (BootResources && BootResources != ParentBootResources)
3509  {
3510  ExFreePool(BootResources);
3511  BootResources = NULL;
3512  }
3513  if (hLevel2Key)
3514  {
3515  ZwClose(hLevel2Key);
3516  hLevel2Key = NULL;
3517  }
3518  if (hDeviceKey)
3519  {
3520  ZwClose(hDeviceKey);
3521  hDeviceKey = NULL;
3522  }
3523  }
3524 
3526 
3527 cleanup:
3528  if (hDevicesKey && hDevicesKey != hBaseKey)
3529  ZwClose(hDevicesKey);
3530  if (hDeviceKey)
3531  ZwClose(hDeviceKey);
3532  if (pDeviceInformation)
3533  ExFreePool(pDeviceInformation);
3534  if (pValueInformation)
3535  ExFreePool(pValueInformation);
3536  return Status;
3537 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
#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:3670
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
struct _KEY_BASIC_INFORMATION KEY_BASIC_INFORMATION
uint16_t * PWCHAR
Definition: typedefs.h:54
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
uint32_t ULONG_PTR
Definition: typedefs.h:63
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
#define UNICODE_NULL
Definition: Header.h:8
#define REG_MULTI_SZ
Definition: nt_native.h:1501
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define REG_RESOURCE_LIST
Definition: nt_native.h:1502
#define REG_FULL_RESOURCE_DESCRIPTOR
Definition: nt_native.h:1503
_Inout_ PRTL_BUFFER _In_ SIZE_T RequiredSize
#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
#define swprintf(buf, format,...)
Definition: sprintf.c:56
static const WCHAR L[]
Definition: oid.c:1250
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
unsigned short USHORT
Definition: pedump.c:61
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
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
char * cleanup(char *str)
Definition: wpickclick.c:99
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
static INIT_FUNCTION NTSTATUS IopEnumerateDetectedDevices(IN HANDLE hBaseKey, IN PUNICODE_STRING RelativePath OPTIONAL, IN HANDLE hRootKey, IN BOOLEAN EnumerateSubKeys, IN PCM_FULL_RESOURCE_DESCRIPTOR ParentBootResources, IN ULONG ParentBootResourcesLength)
Definition: pnpmgr.c:3109
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#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 IopUpdateRootKey().

◆ IopEnumerateDevice()

NTSTATUS IopEnumerateDevice ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 2652 of file pnpmgr.c.

2654 {
2657  PDEVICE_RELATIONS DeviceRelations;
2658  PDEVICE_OBJECT ChildDeviceObject;
2660  PDEVICE_NODE ChildDeviceNode;
2661  IO_STACK_LOCATION Stack;
2662  NTSTATUS Status;
2663  ULONG i;
2664 
2665  DPRINT("DeviceObject 0x%p\n", DeviceObject);
2666 
2668  {
2670 
2671  DPRINT("Sending GUID_DEVICE_ARRIVAL\n");
2672  IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL,
2673  &DeviceNode->InstancePath);
2674  }
2675 
2676  DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
2677 
2678  Stack.Parameters.QueryDeviceRelations.Type = BusRelations;
2679 
2681  DeviceObject,
2682  &IoStatusBlock,
2684  &Stack);
2685  if (!NT_SUCCESS(Status) || Status == STATUS_PENDING)
2686  {
2687  DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
2688  return Status;
2689  }
2690 
2691  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
2692 
2693  /*
2694  * Send removal IRPs for devices that have disappeared
2695  * NOTE: This code handles the case where no relations are specified
2696  */
2697  IopHandleDeviceRemoval(DeviceNode, DeviceRelations);
2698 
2699  /* Now we bail if nothing was returned */
2700  if (!DeviceRelations)
2701  {
2702  /* We're all done */
2703  DPRINT("No PDOs\n");
2704  return STATUS_SUCCESS;
2705  }
2706 
2707  DPRINT("Got %u PDOs\n", DeviceRelations->Count);
2708 
2709  /*
2710  * Create device nodes for all discovered devices
2711  */
2712  for (i = 0; i < DeviceRelations->Count; i++)
2713  {
2714  ChildDeviceObject = DeviceRelations->Objects[i];
2715  ASSERT((ChildDeviceObject->Flags & DO_DEVICE_INITIALIZING) == 0);
2716 
2717  ChildDeviceNode = IopGetDeviceNode(ChildDeviceObject);
2718  if (!ChildDeviceNode)
2719  {
2720  /* One doesn't exist, create it */
2722  DeviceNode,
2723  ChildDeviceObject,
2724  NULL,
2725  &ChildDeviceNode);
2726  if (NT_SUCCESS(Status))
2727  {
2728  /* Mark the node as enumerated */
2729  ChildDeviceNode->Flags |= DNF_ENUMERATED;
2730 
2731  /* Mark the DO as bus enumerated */
2732  ChildDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
2733  }
2734  else
2735  {
2736  /* Ignore this DO */
2737  DPRINT1("IopCreateDeviceNode() failed with status 0x%08x. Skipping PDO %u\n", Status, i);
2738  ObDereferenceObject(ChildDeviceObject);
2739  }
2740  }
2741  else
2742  {
2743  /* Mark it as enumerated */
2744  ChildDeviceNode->Flags |= DNF_ENUMERATED;
2745  ObDereferenceObject(ChildDeviceObject);
2746  }
2747  }
2748  ExFreePool(DeviceRelations);
2749 
2750  /*
2751  * Retrieve information about all discovered children from the bus driver
2752  */
2754  &Context,
2755  DeviceNode,
2757  DeviceNode);
2758 
2760  if (!NT_SUCCESS(Status))
2761  {
2762  DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status);
2763  return Status;
2764  }
2765 
2766  /*
2767  * Retrieve configuration from the registry for discovered children
2768  */
2770  &Context,
2771  DeviceNode,
2773  DeviceNode);
2774 
2776  if (!NT_SUCCESS(Status))
2777  {
2778  DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status);
2779  return Status;
2780  }
2781 
2782  /*
2783  * Initialize services for discovered children.
2784  */
2786  if (!NT_SUCCESS(Status))
2787  {
2788  DPRINT("IopInitializePnpServices() failed with status 0x%08lx\n", Status);
2789  return Status;
2790  }
2791 
2792  DPRINT("IopEnumerateDevice() finished\n");
2793  return STATUS_SUCCESS;
2794 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
ULONG Flags
Definition: iotypes.h:836
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2054
LONG NTSTATUS
Definition: precomp.h:26
static VOID IopHandleDeviceRemoval(IN PDEVICE_NODE DeviceNode, IN PDEVICE_RELATIONS DeviceRelations)
Definition: pnpmgr.c:2606
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
NTSTATUS IopCreateDeviceNode(PDEVICE_NODE ParentNode, PDEVICE_OBJECT PhysicalDeviceObject, PUNICODE_STRING ServiceName, PDEVICE_NODE *DeviceNode)
Definition: pnpmgr.c:1187
NTSTATUS IopActionConfigureChildServices(PDEVICE_NODE DeviceNode, PVOID Context)
Definition: pnpmgr.c:2814
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode, PVOID Context)
Definition: pnpmgr.c:2337
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
smooth NULL
Definition: ftsmooth.c:416
#define DO_BUS_ENUMERATED_DEVICE
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS IopQueueTargetDeviceEvent(const GUID *Guid, PUNICODE_STRING DeviceIds)
Definition: plugplay.c:46
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define DNF_NEED_ENUMERATION_ONLY
Definition: iotypes.h:194
Definition: Node.h:9
PDEVICE_NODE FASTCALL IopGetDeviceNode(PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:66
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack OPTIONAL)
Definition: pnpmgr.c:1489
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define DPRINT1
Definition: precomp.h:8
#define IopInitDeviceTreeTraverseContext( _DeviceTreeTraverseContext, _DeviceNode, _Action, _Context)
Definition: io.h:225
struct tagContext Context
Definition: acpixf.h:1012
unsigned int ULONG
Definition: retypes.h:1
#define DNF_ENUMERATED
Definition: iotypes.h:170
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
return STATUS_SUCCESS
Definition: btrfs.c:2745
NTSTATUS IopInitializePnpServices(IN PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:3091
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS IopTraverseDeviceTree(PDEVICETREE_TRAVERSE_CONTEXT Context)
Definition: pnpmgr.c:1552

Referenced by IoInitSystem(), and IoSynchronousInvalidateDeviceRelations().

◆ IopFixupDeviceId()

VOID IopFixupDeviceId ( PWCHAR  String)

Definition at line 72 of file pnpmgr.c.

73 {
75 
76  for (i = 0; i < Length; i++)
77  {
78  if (String[i] == L'\\')
79  String[i] = L'#';
80  }
81 }
static WCHAR String[]
Definition: stringtable.c:55
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
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
static const WCHAR L[]
Definition: oid.c:1250
ULONG_PTR SIZE_T
Definition: typedefs.h:78
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)

Referenced by IopInstallCriticalDevice().

◆ IopFreeDeviceNode()

NTSTATUS IopFreeDeviceNode ( PDEVICE_NODE  DeviceNode)

Definition at line 1350 of file pnpmgr.c.

1351 {
1352  KIRQL OldIrql;
1353  PDEVICE_NODE PrevSibling = NULL;
1354 
1355  /* All children must be deleted before a parent is deleted */
1356  ASSERT(!DeviceNode->Child);
1357  ASSERT(DeviceNode->PhysicalDeviceObject);
1358 
1360 
1361  /* Get previous sibling */
1362  if (DeviceNode->Parent && DeviceNode->Parent->Child != DeviceNode)
1363  {
1364  PrevSibling = DeviceNode->Parent->Child;
1365  while (PrevSibling->Sibling != DeviceNode)
1366  PrevSibling = PrevSibling->Sibling;
1367  }
1368 
1369  /* Unlink from parent if it exists */
1370  if (DeviceNode->Parent)
1371  {
1372  if (DeviceNode->Parent->LastChild == DeviceNode)
1373  {
1374  DeviceNode->Parent->LastChild = PrevSibling;
1375  if (PrevSibling)
1376  PrevSibling->Sibling = NULL;
1377  }
1378  if (DeviceNode->Parent->Child == DeviceNode)
1379  DeviceNode->Parent->Child = DeviceNode->Sibling;
1380  }
1381 
1382  /* Unlink from sibling list */
1383  if (PrevSibling)
1384  PrevSibling->Sibling = DeviceNode->Sibling;
1385 
1387 
1388  RtlFreeUnicodeString(&DeviceNode->InstancePath);
1389 
1390  RtlFreeUnicodeString(&DeviceNode->ServiceName);
1391 
1392  if (DeviceNode->ResourceList)
1393  {
1394  ExFreePool(DeviceNode->ResourceList);
1395  }
1396 
1397  if (DeviceNode->ResourceListTranslated)
1398  {
1399  ExFreePool(DeviceNode->ResourceListTranslated);
1400  }
1401 
1402  if (DeviceNode->ResourceRequirements)
1403  {
1404  ExFreePool(DeviceNode->ResourceRequirements);
1405  }
1406 
1407  if (DeviceNode->BootResources)
1408  {
1409  ExFreePool(DeviceNode->BootResources);
1410  }
1411 
1412  ((PEXTENDED_DEVOBJ_EXTENSION)DeviceNode->PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = NULL;
1414 
1415  return STATUS_SUCCESS;
1416 }
#define TAG_IO_DEVNODE
Definition: tag.h:89
struct _EXTENDED_DEVOBJ_EXTENSION * PEXTENDED_DEVOBJ_EXTENSION
UCHAR KIRQL
Definition: env_spec_w32.h:591
smooth NULL
Definition: ftsmooth.c:416
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
Definition: Node.h:9
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
struct _DEVICE_NODE * Sibling
Definition: iotypes.h:823
KSPIN_LOCK IopDeviceTreeLock
Definition: pnpmgr.c:19
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

◆ IopGetBusTypeGuidIndex()

USHORT NTAPI IopGetBusTypeGuidIndex ( LPGUID  BusTypeGuid)

Definition at line 1106 of file pnpmgr.c.

1107 {
1108  USHORT i = 0, FoundIndex = 0xFFFF;
1109  ULONG NewSize;
1110  PVOID NewList;
1111 
1112  /* Acquire the lock */
1114 
1115  /* Loop all entries */
1116  while (i < PnpBusTypeGuidList->GuidCount)
1117  {
1118  /* Try to find a match */
1119  if (RtlCompareMemory(BusTypeGuid,
1121  sizeof(GUID)) == sizeof(GUID))
1122  {
1123  /* Found it */
1124  FoundIndex = i;
1125  goto Quickie;
1126  }
1127  i++;
1128  }
1129 
1130  /* Check if we have to grow the list */
1132  {
1133  /* Calculate the new size */
1134  NewSize = sizeof(IO_BUS_TYPE_GUID_LIST) +
1135  (sizeof(GUID) * PnpBusTypeGuidList->GuidCount);
1136 
1137  /* Allocate the new copy */
1138  NewList = ExAllocatePool(PagedPool, NewSize);
1139 
1140  if (!NewList)
1141  {
1142  /* Fail */
1144  goto Quickie;
1145  }
1146 
1147  /* Now copy them, decrease the size too */
1148  NewSize -= sizeof(GUID);
1150 
1151  /* Free the old list */
1153 
1154  /* Use the new buffer */
1155  PnpBusTypeGuidList = NewList;
1156  }
1157 
1158  /* Copy the new GUID */
1160  BusTypeGuid,
1161  sizeof(GUID));
1162 
1163  /* The new entry is the index */
1164  FoundIndex = (USHORT)PnpBusTypeGuidList->GuidCount;
1166 
1167 Quickie:
1169  return FoundIndex;
1170 }
GUID Guids[1]
Definition: io.h:440
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList
Definition: pnpmgr.c:35
FAST_MUTEX Lock
Definition: io.h:439
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
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
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
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 ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by IopActionInterrogateDeviceStack().

◆ IopGetDeviceNode()

◆ IopGetDeviceObjectFromDeviceInstance()

PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance ( PUNICODE_STRING  DeviceInstance)

Definition at line 148 of file plugplay.c.

149 {
150  if (IopRootDeviceNode == NULL)
151  return NULL;
152 
153  if (DeviceInstance == NULL ||
154  DeviceInstance->Length == 0)
155  {
157  {
160  }
161  else
162  return NULL;
163  }
164 
166 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:839
PDEVICE_NODE IopRootDeviceNode
Definition: pnpmgr.c:18
static PDEVICE_OBJECT IopTraverseDeviceNode(PDEVICE_NODE Node, PUNICODE_STRING DeviceInstance)
Definition: plugplay.c:119
smooth NULL
Definition: ftsmooth.c:416
_In_ PNDIS_STRING DeviceInstance
Definition: ndis.h:5202
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by IopActionInterrogateDeviceStack(), IopDeviceStatus(), IopGetDeviceDepth(), IopGetDeviceProperty(), IopGetDeviceRelations(), IopGetInterfaceDeviceList(), IopGetRelatedDevice(), and IopResetDevice().

◆ IopGetParentIdPrefix()

NTSTATUS IopGetParentIdPrefix ( PDEVICE_NODE  DeviceNode,
PUNICODE_STRING  ParentIdPrefix 
)

Definition at line 1832 of file pnpmgr.c.

1834 {
1835  const UNICODE_STRING EnumKeyPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
1836  ULONG KeyNameBufferLength;
1837  PKEY_VALUE_PARTIAL_INFORMATION ParentIdPrefixInformation = NULL;
1838  UNICODE_STRING KeyName = {0, 0, NULL};
1839  UNICODE_STRING KeyValue;
1841  HANDLE hKey = NULL;
1842  ULONG crc32;
1843  NTSTATUS Status;
1844 
1845  /* HACK: As long as some devices have a NULL device
1846  * instance path, the following test is required :(
1847  */
1848  if (DeviceNode->Parent->InstancePath.Length == 0)
1849  {
1850  DPRINT1("Parent of %wZ has NULL Instance path, please report!\n",
1851  &DeviceNode->InstancePath);
1852  return STATUS_UNSUCCESSFUL;
1853  }
1854 
1855  /* 1. Try to retrieve ParentIdPrefix from registry */
1856  KeyNameBufferLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + sizeof(L"12345678&12345678");
1857  ParentIdPrefixInformation = ExAllocatePoolWithTag(PagedPool,
1858  KeyNameBufferLength + sizeof(UNICODE_NULL),
1859  TAG_IO);
1860  if (!ParentIdPrefixInformation)
1861  {
1863  }
1864 
1865  KeyName.Length = 0;
1866  KeyName.MaximumLength = EnumKeyPath.Length +
1867  DeviceNode->Parent->InstancePath.Length +
1868  sizeof(UNICODE_NULL);
1870  KeyName.MaximumLength,
1871  TAG_IO);
1872  if (!KeyName.Buffer)
1873  {
1875  goto cleanup;
1876  }
1877 
1878  RtlCopyUnicodeString(&KeyName, &EnumKeyPath);
1879  RtlAppendUnicodeStringToString(&KeyName, &DeviceNode->Parent->InstancePath);
1880 
1882  if (!NT_SUCCESS(Status))
1883  {
1884  goto cleanup;
1885  }
1886  RtlInitUnicodeString(&ValueName, L"ParentIdPrefix");
1887  Status = ZwQueryValueKey(hKey,
1888  &ValueName,
1890  ParentIdPrefixInformation,
1891  KeyNameBufferLength,
1892  &KeyNameBufferLength);
1893  if (NT_SUCCESS(Status))
1894  {
1895  if (ParentIdPrefixInformation->Type != REG_SZ)
1896  {
1898  }
1899  else
1900  {
1901  KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
1902  KeyValue.Length = KeyValue.MaximumLength - sizeof(UNICODE_NULL);
1903  KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
1904  ASSERT(KeyValue.Buffer[KeyValue.Length / sizeof(WCHAR)] == UNICODE_NULL);
1905  }
1906  goto cleanup;
1907  }
1909  {
1910  /* FIXME how do we get here and why is ParentIdPrefixInformation valid? */
1911  KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
1912  KeyValue.Length = KeyValue.MaximumLength - sizeof(UNICODE_NULL);
1913  KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
1914  ASSERT(KeyValue.Buffer[KeyValue.Length / sizeof(WCHAR)] == UNICODE_NULL);
1915  goto cleanup;
1916  }
1917 
1918  /* 2. Create the ParentIdPrefix value */
1919  crc32 = RtlComputeCrc32(0,
1920  (PUCHAR)DeviceNode->Parent->InstancePath.Buffer,
1921  DeviceNode->Parent->InstancePath.Length);
1922 
1923  RtlStringCbPrintfW((PWSTR)ParentIdPrefixInformation,
1924  KeyNameBufferLength,
1925  L"%lx&%lx",
1926  DeviceNode->Parent->Level,
1927  crc32);
1928  RtlInitUnicodeString(&KeyValue, (PWSTR)ParentIdPrefixInformation);
1929 
1930  /* 3. Try to write the ParentIdPrefix to registry */
1931  Status = ZwSetValueKey(hKey,
1932  &ValueName,
1933  0,
1934  REG_SZ,
1935  KeyValue.Buffer,
1936  ((ULONG)wcslen(KeyValue.Buffer) + 1) * sizeof(WCHAR));
1937 
1938 cleanup:
1939  if (NT_SUCCESS(Status))
1940  {
1941  /* Duplicate the string to return it */
1943  &KeyValue,
1944  ParentIdPrefix);
1945  }
1946  ExFreePoolWithTag(ParentIdPrefixInformation, TAG_IO);
1948  if (hKey != NULL)
1949  {
1950  ZwClose(hKey);
1951  }
1952  return Status;
1953 }
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
#define KEY_SET_VALUE
Definition: nt_native.h:1017
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:3670
uint16_t * PWSTR
Definition: typedefs.h:54
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
UINT32 crc32
Definition: btrfs.c:3897
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
Definition: Node.h:9
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
static const WCHAR L[]
Definition: oid.c:1250
static __inline NTSTATUS 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:1120
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
NTSYSAPI ULONG NTAPI RtlComputeCrc32(_In_ ULONG InitialCrc, _In_ PUCHAR Buffer, _In_ ULONG Length)
unsigned short USHORT
Definition: pedump.c:61
#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:254
#define DPRINT1
Definition: precomp.h:8
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
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22

Referenced by IopCreateDeviceInstancePath().

◆ IopGetRegistryValue()

NTSTATUS NTAPI IopGetRegistryValue ( IN HANDLE  Handle,
IN PWSTR  ValueName,
OUT PKEY_VALUE_FULL_INFORMATION Information 
)

Definition at line 3821 of file pnpmgr.c.

3824 {
3825  UNICODE_STRING ValueString;
3826  NTSTATUS Status;
3827  PKEY_VALUE_FULL_INFORMATION FullInformation;
3828  ULONG Size;
3829  PAGED_CODE();
3830 
3831  RtlInitUnicodeString(&ValueString, ValueName);
3832 
3833  Status = ZwQueryValueKey(Handle,
3834  &ValueString,
3836  NULL,
3837  0,
3838  &Size);
3839  if ((Status != STATUS_BUFFER_OVERFLOW) &&
3841  {
3842  return Status;
3843  }
3844 
3845  FullInformation = ExAllocatePool(NonPagedPool, Size);
3846  if (!FullInformation) return STATUS_INSUFFICIENT_RESOURCES;
3847 
3848  Status = ZwQueryValueKey(