ReactOS  0.4.14-dev-1296-g56aa513
pnpmgr.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for pnpmgr.c:

Go to the source code of this file.

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;}
 

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)
 
VOID IopQueueDeviceAction (_In_ PDEVICE_ACTION_DATA ActionData)
 
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 4292 of file pnpmgr.c.

◆ PIP_RETURN_DATA

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

Definition at line 4291 of file pnpmgr.c.

◆ PIP_UNIMPLEMENTED

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

Definition at line 4293 of file pnpmgr.c.

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 4300 of file pnpmgr.c.

4305 {
4307  DEVICE_CAPABILITIES DeviceCaps;
4308  ULONG ReturnLength = 0, Length = 0, ValueType;
4309  PWCHAR ValueName = NULL, EnumeratorNameEnd, DeviceInstanceName;
4310  PVOID Data = NULL;
4312  GUID BusTypeGuid;
4313  POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
4314  BOOLEAN NullTerminate = FALSE;
4315  DEVICE_REMOVAL_POLICY Policy;
4316 
4317  DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty);
4318 
4319  /* Assume failure */
4320  *ResultLength = 0;
4321 
4322  /* Only PDOs can call this */
4324 
4325  /* Handle all properties */
4326  switch (DeviceProperty)
4327  {
4329 
4330  /* Get the GUID from the internal cache */
4331  Status = PnpBusTypeGuidGet(DeviceNode->ChildBusTypeIndex, &BusTypeGuid);
4332  if (!NT_SUCCESS(Status)) return Status;
4333 
4334  /* This is the format of the returned data */
4335  PIP_RETURN_DATA(sizeof(GUID), &BusTypeGuid);
4336 
4338 
4339  /* Validate correct interface type */
4340  if (DeviceNode->ChildInterfaceType == InterfaceTypeUndefined)
4342 
4343  /* This is the format of the returned data */
4344  PIP_RETURN_DATA(sizeof(INTERFACE_TYPE), &DeviceNode->ChildInterfaceType);
4345 
4347 
4348  /* Validate correct bus number */
4349  if ((DeviceNode->ChildBusNumber & 0x80000000) == 0x80000000)
4351 
4352  /* This is the format of the returned data */
4353  PIP_RETURN_DATA(sizeof(ULONG), &DeviceNode->ChildBusNumber);
4354 
4356 
4357  /* Get the instance path */
4358  DeviceInstanceName = DeviceNode->InstancePath.Buffer;
4359 
4360  /* Sanity checks */
4361  ASSERT((BufferLength & 1) == 0);
4362  ASSERT(DeviceInstanceName != NULL);
4363 
4364  /* Get the name from the path */
4365  EnumeratorNameEnd = wcschr(DeviceInstanceName, OBJ_NAME_PATH_SEPARATOR);
4366  ASSERT(EnumeratorNameEnd);
4367 
4368  /* This string needs to be NULL-terminated */
4369  NullTerminate = TRUE;
4370 
4371  /* This is the format of the returned data */
4372  PIP_RETURN_DATA((ULONG)(EnumeratorNameEnd - DeviceInstanceName) * sizeof(WCHAR),
4373  DeviceInstanceName);
4374 
4375  case DevicePropertyAddress:
4376 
4377  /* Query the device caps */
4379  if (!NT_SUCCESS(Status) || (DeviceCaps.Address == MAXULONG))
4381 
4382  /* This is the format of the returned data */
4383  PIP_RETURN_DATA(sizeof(ULONG), &DeviceCaps.Address);
4384 
4386 
4387  /* Validate we have resources */
4388  if (!DeviceNode->BootResources)
4389 // if (!DeviceNode->BootResourcesTranslated) // FIXFIX: Need this field
4390  {
4391  /* No resources will still fake success, but with 0 bytes */
4392  *ResultLength = 0;
4393  return STATUS_SUCCESS;
4394  }
4395 
4396  /* This is the format of the returned data */
4397  PIP_RETURN_DATA(PnpDetermineResourceListSize(DeviceNode->BootResources), // FIXFIX: Should use BootResourcesTranslated
4398  DeviceNode->BootResources); // FIXFIX: Should use BootResourcesTranslated
4399 
4401 
4402  /* Sanity check for Unicode-sized string */
4403  ASSERT((BufferLength & 1) == 0);
4404 
4405  /* Allocate name buffer */
4407  ObjectNameInfo = ExAllocatePool(PagedPool, Length);
4408  if (!ObjectNameInfo) return STATUS_INSUFFICIENT_RESOURCES;
4409 
4410  /* Query the PDO name */
4412  ObjectNameInfo,
4413  Length,
4414  ResultLength);
4416  {
4417  /* It's up to the caller to try again */
4419  }
4420 
4421  /* This string needs to be NULL-terminated */
4422  NullTerminate = TRUE;
4423 
4424  /* Return if successful */
4425  if (NT_SUCCESS(Status)) PIP_RETURN_DATA(ObjectNameInfo->Name.Length,
4426  ObjectNameInfo->Name.Buffer);
4427 
4428  /* Let the caller know how big the name is */
4430  break;
4431 
4433 
4434  Policy = DeviceNode->RemovalPolicy;
4435  PIP_RETURN_DATA(sizeof(Policy), &Policy);
4436 
4437  /* Handle the registry-based properties */
4461  //PIP_REGISTRY_DATA(REGSTR_VAL_CONTAINERID, REG_SZ); // Win7
4463  break;
4466  break;
4471  default:
4473  }
4474 
4475  /* Having a registry value name implies registry data */
4476  if (ValueName)
4477  {
4478  /* We know up-front how much data to expect */
4480 
4481  /* Go get the data, use the LogConf subkey if necessary */
4483  ValueType,
4484  ValueName,
4485  (DeviceProperty ==
4487  L"LogConf": NULL,
4488  PropertyBuffer,
4489  ResultLength);
4490  }
4491  else if (NT_SUCCESS(Status))
4492  {
4493  /* We know up-front how much data to expect, check the caller's buffer */
4494  *ResultLength = ReturnLength + (NullTerminate ? sizeof(UNICODE_NULL) : 0);
4495  if (*ResultLength <= BufferLength)
4496  {
4497  /* Buffer is all good, copy the data */
4498  RtlCopyMemory(PropertyBuffer, Data, ReturnLength);
4499 
4500  /* Check if we need to NULL-terminate the string */
4501  if (NullTerminate)
4502  {
4503  /* Terminate the string */
4504  ((PWCHAR)PropertyBuffer)[ReturnLength / sizeof(WCHAR)] = UNICODE_NULL;
4505  }
4506 
4507  /* This is the success path */
4509  }
4510  else
4511  {
4512  /* Failure path */
4514  }
4515  }
4516 
4517  /* Free any allocation we may have made, and return the status code */
4518  if (ObjectNameInfo) ExFreePool(ObjectNameInfo);
4519  return Status;
4520 }
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:4063
NTSTATUS NTAPI PnpBusTypeGuidGet(IN USHORT Index, IN LPGUID BusTypeGuid)
Definition: pnpmgr.c:4088
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:1209
#define REGSTR_VAL_CONFIGFLAGS
Definition: regstr.h:388
DEVICE_CAPABILITIES
Definition: iotypes.h:928
#define REGSTR_VAL_UI_NUMBER
Definition: regstr.h:426
uint16_t * PWCHAR
Definition: typedefs.h:55
#define REGSTR_VAL_FRIENDLYNAME
Definition: regstr.h:465
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
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:4209
#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:4293
_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:60
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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:4292
ULONG NTAPI PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList)
Definition: pnpmgr.c:4155
#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
enum _DEVICE_REMOVAL_POLICY DEVICE_REMOVAL_POLICY
#define PIP_RETURN_DATA(x, y)
Definition: pnpmgr.c:4291
NTSTATUS NTAPI IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode, PDEVICE_CAPABILITIES DeviceCaps)
Definition: pnpmgr.c:980
unsigned int ULONG
Definition: retypes.h:1
#define REGSTR_VAL_BOOTCONFIG
Definition: regstr.h:293
return STATUS_SUCCESS
Definition: btrfs.c:2938
#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(), IntVideoPortCreateAdapterDeviceObject(), IoGetDmaAdapter(), IoOpenDeviceRegistryKey(), IopGetDeviceProperty(), IopUpdateResourceMap(), KspStartBusDevice(), NdisIAddDevice(), NdisIPnPStartDevice(), PcGetDeviceProperty(), PciDetermineSlotNumber(), PciGetDeviceProperty(), RamdiskPnp(), StreamClassStartDevice(), USBH_IoctlGetNodeConnectionDriverKeyName(), USBPORT_StartDevice(), and USBPORT_UserGetHcName().

◆ IoInvalidateDeviceRelations()

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

◆ IoInvalidateDeviceState()

VOID NTAPI IoInvalidateDeviceState ( IN PDEVICE_OBJECT  PhysicalDeviceObject)

Definition at line 4527 of file pnpmgr.c.

4528 {
4530  IO_STACK_LOCATION Stack;
4531  ULONG_PTR PnPFlags;
4532  NTSTATUS Status;
4534 
4535  RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
4536  Stack.MajorFunction = IRP_MJ_PNP;
4538 
4539  Status = IopSynchronousCall(PhysicalDeviceObject, &Stack, (PVOID*)&PnPFlags);
4540  if (!NT_SUCCESS(Status))
4541  {
4543  {
4544  DPRINT1("IRP_MN_QUERY_PNP_DEVICE_STATE failed with status 0x%lx\n", Status);
4545  }
4546  return;
4547  }
4548 
4549  if (PnPFlags & PNP_DEVICE_NOT_DISABLEABLE)
4550  DeviceNode->UserFlags |= DNUF_NOT_DISABLEABLE;
4551  else
4552  DeviceNode->UserFlags &= ~DNUF_NOT_DISABLEABLE;
4553 
4554  if (PnPFlags & PNP_DEVICE_DONT_DISPLAY_IN_UI)
4555  DeviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI;
4556  else
4557  DeviceNode->UserFlags &= ~DNUF_DONT_SHOW_IN_UI;
4558 
4559  if ((PnPFlags & PNP_DEVICE_REMOVED) ||
4560  ((PnPFlags & PNP_DEVICE_FAILED) && !(PnPFlags & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED)))
4561  {
4562  /* Flag it if it's failed */
4563  if (PnPFlags & PNP_DEVICE_FAILED) DeviceNode->Problem = CM_PROB_FAILED_POST_START;
4564 
4565  /* Send removal IRPs to all of its children */
4567 
4568  /* Send surprise removal */
4570 
4571  /* Tell the user-mode PnP manager that a device was removed */
4572  IopQueueTargetDeviceEvent(&GUID_DEVICE_SURPRISE_REMOVAL,
4573  &DeviceNode->InstancePath);
4574 
4576  }
4577  else if ((PnPFlags & PNP_DEVICE_FAILED) && (PnPFlags & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED))
4578  {
4579  /* Stop for resource rebalance */
4581  if (!NT_SUCCESS(Status))
4582  {
4583  DPRINT1("Failed to stop device for rebalancing\n");
4584 
4585  /* Stop failed so don't rebalance */
4587  }
4588  }
4589 
4590  /* Resource rebalance */
4592  {
4593  DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n");
4594 
4596  &IoStatusBlock,
4598  NULL);
4600  {
4601  DeviceNode->BootResources =
4604  }
4605  else
4606  {
4607  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
4608  DeviceNode->BootResources = NULL;
4609  }
4610 
4611  DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n");
4612 
4614  &IoStatusBlock,
4616  NULL);
4617  if (NT_SUCCESS(Status))
4618  {
4619  DeviceNode->ResourceRequirements =
4621  }
4622  else
4623  {
4624  DPRINT("IopInitiatePnpIrp() failed (Status %08lx)\n", Status);
4625  DeviceNode->ResourceRequirements = NULL;
4626  }
4627 
4628  /* IRP_MN_FILTER_RESOURCE_REQUIREMENTS is called indirectly by IopStartDevice */
4630  {
4631  DPRINT1("Restart after resource rebalance failed\n");
4632 
4634  DeviceNode->Flags |= DNF_START_FAILED;
4635 
4637  }
4638  }
4639 }
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:1490
#define PNP_DEVICE_REMOVED
Definition: iotypes.h:967
#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
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1122
static VOID NTAPI IopSendSurpriseRemoval(IN PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:513
#define PNP_DEVICE_DONT_DISPLAY_IN_UI
Definition: iotypes.h:965
uint32_t ULONG_PTR
Definition: typedefs.h:64
#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:968
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define PNP_DEVICE_NOT_DISABLEABLE
Definition: iotypes.h:969
Definition: Node.h:9
PDEVICE_NODE FASTCALL IopGetDeviceNode(PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:60
NTSTATUS IopStartDevice(PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:920
NTSTATUS IopRemoveDevice(PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:5072
NTSTATUS IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
#define PNP_DEVICE_FAILED
Definition: iotypes.h:966
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:1560
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:898
static VOID NTAPI IopSendRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:581
#define DPRINT1
Definition: precomp.h:8
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
return STATUS_SUCCESS
Definition: btrfs.c:2938
#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 4658 of file pnpmgr.c.

4662 {
4663  static WCHAR RootKeyName[] =
4664  L"\\Registry\\Machine\\System\\CurrentControlSet\\";
4665  static WCHAR ProfileKeyName[] =
4666  L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
4667  static WCHAR ClassKeyName[] = L"Control\\Class\\";
4668  static WCHAR EnumKeyName[] = L"Enum\\";
4669  static WCHAR DeviceParametersKeyName[] = L"Device Parameters";
4671  PWSTR KeyNameBuffer;
4673  ULONG DriverKeyLength;
4676  NTSTATUS Status;
4677 
4678  DPRINT("IoOpenDeviceRegistryKey() called\n");
4679 
4681  {
4682  DPRINT1("IoOpenDeviceRegistryKey(): got wrong params, exiting... \n");
4683  return STATUS_INVALID_PARAMETER;
4684  }
4685 
4689 
4690  /*
4691  * Calculate the length of the base key name. This is the full
4692  * name for driver key or the name excluding "Device Parameters"
4693  * subkey for device key.
4694  */
4695 
4696  KeyNameLength = sizeof(RootKeyName);
4698  KeyNameLength += sizeof(ProfileKeyName) - sizeof(UNICODE_NULL);
4700  {
4701  KeyNameLength += sizeof(ClassKeyName) - sizeof(UNICODE_NULL);
4703  0, NULL, &DriverKeyLength);
4705  return Status;
4706  KeyNameLength += DriverKeyLength;
4707  }
4708  else
4709  {
4710  KeyNameLength += sizeof(EnumKeyName) - sizeof(UNICODE_NULL) +
4711  DeviceNode->InstancePath.Length;
4712  }
4713 
4714  /*
4715  * Now allocate the buffer for the key name...
4716  */
4717 
4718  KeyNameBuffer = ExAllocatePool(PagedPool, KeyNameLength);
4719  if (KeyNameBuffer == NULL)
4721 
4722  KeyName.Length = 0;
4723  KeyName.MaximumLength = (USHORT)KeyNameLength;
4724  KeyName.Buffer = KeyNameBuffer;
4725 
4726  /*
4727  * ...and build the key name.
4728  */
4729 
4730  KeyName.Length += sizeof(RootKeyName) - sizeof(UNICODE_NULL);
4731  RtlCopyMemory(KeyNameBuffer, RootKeyName, KeyName.Length);
4732 
4734  RtlAppendUnicodeToString(&KeyName, ProfileKeyName);
4735 
4737  {
4738  RtlAppendUnicodeToString(&KeyName, ClassKeyName);
4740  DriverKeyLength, KeyNameBuffer +
4741  (KeyName.Length / sizeof(WCHAR)),
4742  &DriverKeyLength);
4743  if (!NT_SUCCESS(Status))
4744  {
4745  DPRINT1("Call to IoGetDeviceProperty() failed with Status 0x%08lx\n", Status);
4746  ExFreePool(KeyNameBuffer);
4747  return Status;
4748  }
4749  KeyName.Length += (USHORT)DriverKeyLength - sizeof(UNICODE_NULL);
4750  }
4751  else
4752  {
4753  RtlAppendUnicodeToString(&KeyName, EnumKeyName);
4755  if (DeviceNode->InstancePath.Length == 0)
4756  {
4757  ExFreePool(KeyNameBuffer);
4758  return Status;
4759  }
4760  }
4761 
4762  /*
4763  * Open the base key.
4764  */
4766  if (!NT_SUCCESS(Status))
4767  {
4768  DPRINT1("IoOpenDeviceRegistryKey(%wZ): Base key doesn't exist, exiting... (Status 0x%08lx)\n", &KeyName, Status);
4769  ExFreePool(KeyNameBuffer);
4770  return Status;
4771  }
4772  ExFreePool(KeyNameBuffer);
4773 
4774  /*
4775  * For driver key we're done now.
4776  */
4777 
4779  return Status;
4780 
4781  /*
4782  * Let's go further. For device key we must open "Device Parameters"
4783  * subkey and create it if it doesn't exist yet.
4784  */
4785 
4786  RtlInitUnicodeString(&KeyName, DeviceParametersKeyName);
4788  &KeyName,
4790  *DevInstRegKey,
4791  NULL);
4792  Status = ZwCreateKey(DevInstRegKey,
4793  DesiredAccess,
4795  0,
4796  NULL,
4798  NULL);
4799  ZwClose(ObjectAttributes.RootDirectory);
4800 
4801  return Status;
4802 }
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 OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#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:3760
uint16_t * PWSTR
Definition: typedefs.h:55
_In_ ULONG DevInstKeyType
Definition: iofuncs.h:1123
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#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:4300
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
Definition: Node.h:9
PDEVICE_NODE FASTCALL IopGetDeviceNode(PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:60
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 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 2902 of file pnpmgr.c.

2904 {
2906  PDEVICE_NODE ParentDeviceNode;
2909  NTSTATUS Status;
2910  DEVICE_CAPABILITIES DeviceCaps;
2911 
2912  DPRINT("IopActionConfigureChildServices(%p, %p)\n", DeviceNode, Context);
2913 
2914  ParentDeviceNode = (PDEVICE_NODE)Context;
2915 
2916  /*
2917  * We are called for the parent too, but we don't need to do special
2918  * handling for this node
2919  */
2920  if (DeviceNode == ParentDeviceNode)
2921  {
2922  DPRINT("Success\n");
2923  return STATUS_SUCCESS;
2924  }
2925 
2926  /*
2927  * Make sure this device node is a direct child of the parent device node
2928  * that is given as an argument
2929  */
2930 
2931  if (DeviceNode->Parent != ParentDeviceNode)
2932  {
2933  DPRINT("Skipping 2+ level child\n");
2934  return STATUS_SUCCESS;
2935  }
2936 
2937  if (!(DeviceNode->Flags & DNF_PROCESSED))
2938  {
2939  DPRINT1("Child not ready to be configured\n");
2940  return STATUS_SUCCESS;
2941  }
2942 
2943  if (!(DeviceNode->Flags & (DNF_DISABLED | DNF_STARTED | DNF_ADDED)))
2944  {
2945  UNICODE_STRING RegKey;
2946 
2947  /* Install the service for this if it's in the CDDB */
2949 
2950  /*
2951  * Retrieve configuration from Enum key
2952  */
2953 
2954  Service = &DeviceNode->ServiceName;
2955 
2959 
2960  QueryTable[0].Name = L"Service";
2963 
2964  QueryTable[1].Name = L"ClassGUID";
2968  QueryTable[1].DefaultData = L"";
2969  QueryTable[1].DefaultLength = 0;
2970 
2971  RegKey.Length = 0;
2972  RegKey.MaximumLength = sizeof(ENUM_ROOT) + sizeof(WCHAR) + DeviceNode->InstancePath.Length;
2974  RegKey.MaximumLength,
2975  TAG_IO);
2976  if (RegKey.Buffer == NULL)
2977  {
2980  }
2981 
2983  RtlAppendUnicodeToString(&RegKey, L"\\");
2984  RtlAppendUnicodeStringToString(&RegKey, &DeviceNode->InstancePath);
2985 
2987  RegKey.Buffer, QueryTable, NULL, NULL);
2988  ExFreePoolWithTag(RegKey.Buffer, TAG_IO);
2989 
2990  if (!NT_SUCCESS(Status))
2991  {
2992  /* FIXME: Log the error */
2993  DPRINT("Could not retrieve configuration for device %wZ (Status 0x%08x)\n",
2994  &DeviceNode->InstancePath, Status);
2996  return STATUS_SUCCESS;
2997  }
2998 
2999  if (Service->Buffer == NULL)
3000  {
3001  if (NT_SUCCESS(IopQueryDeviceCapabilities(DeviceNode, &DeviceCaps)) &&
3002  DeviceCaps.RawDeviceOK)
3003  {
3004  DPRINT("%wZ is using parent bus driver (%wZ)\n", &DeviceNode->InstancePath, &ParentDeviceNode->ServiceName);
3005  RtlInitEmptyUnicodeString(&DeviceNode->ServiceName, NULL, 0);
3006  }
3007  else if (ClassGUID.Length != 0)
3008  {
3009  /* Device has a ClassGUID value, but no Service value.
3010  * Suppose it is using the NULL driver, so state the
3011  * device is started */
3012  DPRINT("%wZ is using NULL driver\n", &DeviceNode->InstancePath);
3014  }
3015  else
3016  {
3019  }
3020  return STATUS_SUCCESS;
3021  }
3022 
3023  DPRINT("Got Service %S\n", Service->Buffer);
3024  }
3025 
3026  return STATUS_SUCCESS;
3027 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4051
#define DNF_PROCESSED
Definition: iotypes.h:167
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
USHORT MaximumLength
Definition: env_spec_w32.h:370
VOID NTAPI IopInstallCriticalDevice(PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:79
LONG NTSTATUS
Definition: precomp.h:26
DEVICE_CAPABILITIES
Definition: iotypes.h:928
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
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:980
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:2938
#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 3047 of file pnpmgr.c.

3049 {
3050  PDEVICE_NODE ParentDeviceNode;
3051  NTSTATUS Status;
3052  BOOLEAN BootDrivers = !PnpSystemInit;
3053 
3054  DPRINT("IopActionInitChildServices(%p, %p)\n", DeviceNode, Context);
3055 
3056  ParentDeviceNode = Context;
3057 
3058  /*
3059  * We are called for the parent too, but we don't need to do special
3060  * handling for this node
3061  */
3062  if (DeviceNode == ParentDeviceNode)
3063  {
3064  DPRINT("Success\n");
3065  return STATUS_SUCCESS;
3066  }
3067 
3068  /*
3069  * We don't want to check for a direct child because
3070  * this function is called during boot to reinitialize
3071  * devices with drivers that couldn't load yet due to
3072  * stage 0 limitations (ie can't load from disk yet).
3073  */
3074 
3075  if (!(DeviceNode->Flags & DNF_PROCESSED))
3076  {
3077  DPRINT1("Child not ready to be added\n");
3078  return STATUS_SUCCESS;
3079  }
3080 
3084  return STATUS_SUCCESS;
3085 
3086  if (DeviceNode->ServiceName.Buffer == NULL)
3087  {
3088  /* We don't need to worry about loading the driver because we're
3089  * being driven in raw mode so our parent must be loaded to get here */
3091  if (NT_SUCCESS(Status))
3092  {
3094  if (!NT_SUCCESS(Status))
3095  {
3096  DPRINT1("IopStartDevice(%wZ) failed with status 0x%08x\n",
3097  &DeviceNode->InstancePath, Status);
3098  }
3099  }
3100  }
3101  else
3102  {
3103  PLDR_DATA_TABLE_ENTRY ModuleObject;
3105 
3108  /* Get existing DriverObject pointer (in case the driver has
3109  already been loaded and initialized) */
3111  &DriverObject,
3112  &DeviceNode->ServiceName,
3113  FALSE);
3114 
3115  if (!NT_SUCCESS(Status))
3116  {
3117  /* Driver is not initialized, try to load it */
3118  Status = IopLoadServiceModule(&DeviceNode->ServiceName, &ModuleObject);
3119 
3121  {
3122  /* Initialize the driver */
3124  &DeviceNode->ServiceName, FALSE, &DriverObject);
3125  if (!NT_SUCCESS(Status))
3127  }
3129  {
3130  DPRINT1("Service '%wZ' is disabled\n", &DeviceNode->ServiceName);
3132  }
3133  else
3134  {
3135  DPRINT("IopLoadServiceModule(%wZ) failed with status 0x%08x\n",
3136  &DeviceNode->ServiceName, Status);
3137  if (!BootDrivers)
3139  }
3140  }
3143 
3144  /* Driver is loaded and initialized at this point */
3145  if (NT_SUCCESS(Status))
3146  {
3147  /* Initialize the device, including all filters */
3149 
3150  /* Remove the extra reference */
3152  }
3153  else
3154  {
3155  /*
3156  * Don't disable when trying to load only boot drivers
3157  */
3158  if (!BootDrivers)
3159  {
3161  }
3162  }
3163  }
3164 
3165  return STATUS_SUCCESS;
3166 }
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:428
#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:920
#define CM_PROB_DRIVER_FAILED_LOAD
Definition: cfg.h:69
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: btrfs_drv.h:1853
#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:1034
ERESOURCE IopDriverLoadResource
Definition: driver.c:19
return STATUS_SUCCESS
Definition: btrfs.c:2938
#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 2425 of file pnpmgr.c.

2427 {
2430  PWSTR LocationInformation;
2431  PDEVICE_NODE ParentDeviceNode;
2432  IO_STACK_LOCATION Stack;
2433  NTSTATUS Status;
2435  LCID LocaleId;
2436  HANDLE InstanceKey = NULL;
2438  UNICODE_STRING InstancePathU;
2439  PDEVICE_OBJECT OldDeviceObject;
2440 
2441  DPRINT("IopActionInterrogateDeviceStack(%p, %p)\n", DeviceNode, Context);
2442  DPRINT("PDO 0x%p\n", DeviceNode->PhysicalDeviceObject);
2443 
2444  ParentDeviceNode = (PDEVICE_NODE)Context;
2445 
2446  /*
2447  * We are called for the parent too, but we don't need to do special
2448  * handling for this node
2449  */
2450  if (DeviceNode == ParentDeviceNode)
2451  {
2452  DPRINT("Success\n");
2453  return STATUS_SUCCESS;
2454  }
2455 
2456  /*
2457  * Make sure this device node is a direct child of the parent device node
2458  * that is given as an argument
2459  */
2460  if (DeviceNode->Parent != ParentDeviceNode)
2461  {
2462  DPRINT("Skipping 2+ level child\n");
2463  return STATUS_SUCCESS;
2464  }
2465 
2466  /* Skip processing if it was already completed before */
2467  if (DeviceNode->Flags & DNF_PROCESSED)
2468  {
2469  /* Nothing to do */
2470  return STATUS_SUCCESS;
2471  }
2472 
2473  /* Get Locale ID */
2474  Status = ZwQueryDefaultLocale(FALSE, &LocaleId);
2475  if (!NT_SUCCESS(Status))
2476  {
2477  DPRINT1("ZwQueryDefaultLocale() failed with status 0x%lx\n", Status);
2478  return Status;
2479  }
2480 
2481  /*
2482  * FIXME: For critical errors, cleanup and disable device, but always
2483  * return STATUS_SUCCESS.
2484  */
2485 
2486  Status = IopCreateDeviceInstancePath(DeviceNode, &InstancePathU);
2487  if (!NT_SUCCESS(Status))
2488  {
2490  {
2491  DPRINT1("IopCreateDeviceInstancePath() failed with status 0x%lx\n", Status);
2492  }
2493 
2494  /* We have to return success otherwise we abort the traverse operation */
2495  return STATUS_SUCCESS;
2496  }
2497 
2498  /* Verify that this is not a duplicate */
2499  OldDeviceObject = IopGetDeviceObjectFromDeviceInstance(&InstancePathU);
2500  if (OldDeviceObject != NULL)
2501  {
2502  PDEVICE_NODE OldDeviceNode = IopGetDeviceNode(OldDeviceObject);
2503 
2504  DPRINT1("Duplicate device instance '%wZ'\n", &InstancePathU);
2505  DPRINT1("Current instance parent: '%wZ'\n", &DeviceNode->Parent->InstancePath);
2506  DPRINT1("Old instance parent: '%wZ'\n", &OldDeviceNode->Parent->InstancePath);
2507 
2508  KeBugCheckEx(PNP_DETECTED_FATAL_ERROR,
2509  0x01,
2510  (ULONG_PTR)DeviceNode->PhysicalDeviceObject,
2511  (ULONG_PTR)OldDeviceObject,
2512  0);
2513  }
2514 
2515  DeviceNode->InstancePath = InstancePathU;
2516 
2517  DPRINT("InstancePath is %S\n", DeviceNode->InstancePath.Buffer);
2518 
2519  /*
2520  * Create registry key for the instance id, if it doesn't exist yet
2521  */
2522  Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, REG_OPTION_NON_VOLATILE, &InstanceKey);
2523  if (!NT_SUCCESS(Status))
2524  {
2525  DPRINT1("Failed to create the instance key! (Status %lx)\n", Status);
2526 
2527  /* We have to return success otherwise we abort the traverse operation */
2528  return STATUS_SUCCESS;
2529  }
2530 
2531  IopQueryHardwareIds(DeviceNode, InstanceKey);
2532 
2533  IopQueryCompatibleIds(DeviceNode, InstanceKey);
2534 
2535  DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextDescription to device stack\n");
2536 
2537  Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextDescription;
2538  Stack.Parameters.QueryDeviceText.LocaleId = LocaleId;
2539  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
2540  &IoStatusBlock,
2542  &Stack);
2544  : NULL;
2545  /* This key is mandatory, so even if the Irp fails, we still write it */
2546  RtlInitUnicodeString(&ValueName, L"DeviceDesc");
2547  if (ZwQueryValueKey(InstanceKey, &ValueName, KeyValueBasicInformation, NULL, 0, &RequiredLength) == STATUS_OBJECT_NAME_NOT_FOUND)
2548  {
2549  if (DeviceDescription &&
2551  {
2552  /* This key is overriden when a driver is installed. Don't write the
2553  * new description if another one already exists */
2554  Status = ZwSetValueKey(InstanceKey,
2555  &ValueName,
2556  0,
2557  REG_SZ,
2559  ((ULONG)wcslen(DeviceDescription) + 1) * sizeof(WCHAR));
2560  }
2561  else
2562  {
2563  UNICODE_STRING DeviceDesc = RTL_CONSTANT_STRING(L"Unknown device");
2564  DPRINT("Driver didn't return DeviceDesc (Status 0x%08lx), so place unknown device there\n", Status);
2565 
2566  Status = ZwSetValueKey(InstanceKey,
2567  &ValueName,
2568  0,
2569  REG_SZ,
2570  DeviceDesc.Buffer,
2571  DeviceDesc.MaximumLength);
2572  if (!NT_SUCCESS(Status))
2573  {
2574  DPRINT1("ZwSetValueKey() failed (Status 0x%lx)\n", Status);
2575  }
2576 
2577  }
2578  }
2579 
2580  if (DeviceDescription)
2581  {
2583  }
2584 
2585  DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextLocation to device stack\n");
2586 
2587  Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextLocationInformation;
2588  Stack.Parameters.QueryDeviceText.LocaleId = LocaleId;
2589  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
2590  &IoStatusBlock,
2592  &Stack);
2594  {
2595  LocationInformation = (PWSTR)IoStatusBlock.Information;
2596  DPRINT("LocationInformation: %S\n", LocationInformation);
2597  RtlInitUnicodeString(&ValueName, L"LocationInformation");
2598  Status = ZwSetValueKey(InstanceKey,
2599  &ValueName,
2600  0,
2601  REG_SZ,
2602  LocationInformation,
2603  ((ULONG)wcslen(LocationInformation) + 1) * sizeof(WCHAR));
2604  if (!NT_SUCCESS(Status))
2605  {
2606  DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
2607  }
2608 
2609  ExFreePoolWithTag(LocationInformation, 0);
2610  }
2611  else
2612  {
2613  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
2614  }
2615 
2616  DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n");
2617 
2618  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
2619  &IoStatusBlock,
2621  NULL);
2623  {
2625 
2626  DeviceNode->ChildBusNumber = BusInformation->BusNumber;
2627  DeviceNode->ChildInterfaceType = BusInformation->LegacyBusType;
2628  DeviceNode->ChildBusTypeIndex = IopGetBusTypeGuidIndex(&BusInformation->BusTypeGuid);
2629  ExFreePoolWithTag(BusInformation, 0);
2630  }
2631  else
2632  {
2633  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
2634 
2635  DeviceNode->ChildBusNumber = 0xFFFFFFF0;
2636  DeviceNode->ChildInterfaceType = InterfaceTypeUndefined;
2637  DeviceNode->ChildBusTypeIndex = -1;
2638  }
2639 
2640  DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n");
2641 
2642  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
2643  &IoStatusBlock,
2645  NULL);
2647  {
2650  }
2651  else
2652  {
2653  DPRINT("IopInitiatePnpIrp() failed (Status %x) or IoStatusBlock.Information=NULL\n", Status);
2654  DeviceNode->BootResources = NULL;
2655  }
2656 
2657  DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n");
2658 
2659  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
2660  &IoStatusBlock,
2662  NULL);
2663  if (NT_SUCCESS(Status))
2664  {
2666  }
2667  else
2668  {
2669  DPRINT("IopInitiatePnpIrp() failed (Status %08lx)\n", Status);
2670  DeviceNode->ResourceRequirements = NULL;
2671  }
2672 
2673  if (InstanceKey != NULL)
2674  {
2675  IopSetDeviceInstanceData(InstanceKey, DeviceNode);
2676  }
2677 
2678  ZwClose(InstanceKey);
2679 
2681 
2683  {
2684  /* Report the device to the user-mode pnp manager */
2685  IopQueueTargetDeviceEvent(&GUID_DEVICE_ENUMERATED,
2686  &DeviceNode->InstancePath);
2687  }
2688 
2689  return STATUS_SUCCESS;
2690 }
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:55
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS
NTSTATUS NTAPI IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, IN ULONG CreateOptions, OUT PHANDLE Handle)
Definition: pnpmgr.c:1682
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:124
DWORD LCID
Definition: nls.h:13
struct _DEVICE_NODE * Parent
Definition: iotypes.h:825
uint32_t ULONG_PTR
Definition: typedefs.h:64
_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:2263
#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:1176
#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:1766
__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:60
#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:1560
#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:2199
#define DPRINT1
Definition: precomp.h:8
NTSTATUS IopQueryHardwareIds(PDEVICE_NODE DeviceNode, HANDLE InstanceKey)
Definition: pnpmgr.c:2135
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:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
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 4980 of file pnpmgr.c.

4981 {
4982  IO_STACK_LOCATION Stack;
4984  PDEVICE_RELATIONS DeviceRelations;
4985  NTSTATUS Status;
4986 
4988 
4989  Stack.Parameters.QueryDeviceRelations.Type = RemovalRelations;
4990 
4992  &IoStatusBlock,
4994  &Stack);
4995  if (!NT_SUCCESS(Status))
4996  {
4997  DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
4998  DeviceRelations = NULL;
4999  }
5000  else
5001  {
5002  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
5003  }
5004 
5005  if (DeviceRelations)
5006  IopCancelRemoveDeviceRelations(DeviceRelations);
5007 }
LONG NTSTATUS
Definition: precomp.h:26
static VOID NTAPI IopCancelRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: pnpmgr.c:608
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:4963
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:1560
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:2772

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

◆ IopCancelRemoveChildDevices()

static VOID IopCancelRemoveChildDevices ( PDEVICE_NODE  ParentDeviceNode)
static

Definition at line 4882 of file pnpmgr.c.

4883 {
4884  PDEVICE_NODE ChildDeviceNode, NextDeviceNode;
4885  KIRQL OldIrql;
4886 
4888  ChildDeviceNode = ParentDeviceNode->Child;
4889  while (ChildDeviceNode != NULL)
4890  {
4891  NextDeviceNode = ChildDeviceNode->Sibling;
4893 
4895 
4896  ChildDeviceNode = NextDeviceNode;
4897 
4899  }
4901 }
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:4980
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#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 608 of file pnpmgr.c.

609 {
610  IO_STACK_LOCATION Stack;
611  PVOID Dummy;
612 
613  RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
614  Stack.MajorFunction = IRP_MJ_PNP;
616 
617  /* Drivers should never fail a IRP_MN_CANCEL_REMOVE_DEVICE request */
618  IopSynchronousCall(DeviceObject, &Stack, &Dummy);
619 
622  &GUID_TARGET_DEVICE_REMOVE_CANCELLED,
623  NULL,
624  NULL);
625 }
#define IRP_MN_CANCEL_REMOVE_DEVICE
NTSTATUS NTAPI IopSynchronousCall(IN PDEVICE_OBJECT DeviceObject, IN PIO_STACK_LOCATION IoStackLocation, OUT PVOID *Information)
Definition: pnpmgr.c:1490
#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 4963 of file pnpmgr.c.

4964 {
4965  /* This function DOES dereference the device objects in all cases */
4966 
4967  ULONG i;
4968 
4969  for (i = 0; i < DeviceRelations->Count; i++)
4970  {
4971  IopCancelPrepareDeviceForRemoval(DeviceRelations->Objects[i]);
4972  ObDereferenceObject(DeviceRelations->Objects[i]);
4973  DeviceRelations->Objects[i] = NULL;
4974  }
4975 
4976  ExFreePool(DeviceRelations);
4977 }
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2055
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:4980
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 2263 of file pnpmgr.c.

2266 {
2268  UNICODE_STRING DeviceId;
2270  IO_STACK_LOCATION Stack;
2271  NTSTATUS Status;
2272  UNICODE_STRING ParentIdPrefix = { 0, 0, NULL };
2274  BOOLEAN IsValidID;
2275 
2276  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryDeviceID to device stack\n");
2277 
2278  Stack.Parameters.QueryId.IdType = BusQueryDeviceID;
2279  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
2280  &IoStatusBlock,
2282  &Stack);
2283  if (!NT_SUCCESS(Status))
2284  {
2285  DPRINT1("IopInitiatePnpIrp(BusQueryDeviceID) failed (Status %x)\n", Status);
2286  return Status;
2287  }
2288 
2290 
2291  if (!IsValidID)
2292  {
2293  DPRINT1("Invalid DeviceID. DeviceNode - %p\n", DeviceNode);
2294  }
2295 
2296  /* Save the device id string */
2298 
2299  DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack (after enumeration)\n");
2300 
2302  if (!NT_SUCCESS(Status))
2303  {
2304  DPRINT1("IopQueryDeviceCapabilities() failed (Status 0x%08lx)\n", Status);
2305  RtlFreeUnicodeString(&DeviceId);
2306  return Status;
2307  }
2308 
2309  /* This bit is only check after enumeration */
2310  if (DeviceCapabilities.HardwareDisabled)
2311  {
2312  /* FIXME: Cleanup device */
2313  DeviceNode->Flags |= DNF_DISABLED;
2314  RtlFreeUnicodeString(&DeviceId);
2316  }
2317  else
2318  {
2319  DeviceNode->Flags &= ~DNF_DISABLED;
2320  }
2321 
2322  if (!DeviceCapabilities.UniqueID)
2323  {
2324  /* Device has not a unique ID. We need to prepend parent bus unique identifier */
2325  DPRINT("Instance ID is not unique\n");
2326  Status = IopGetParentIdPrefix(DeviceNode, &ParentIdPrefix);
2327  if (!NT_SUCCESS(Status))
2328  {
2329  DPRINT1("IopGetParentIdPrefix() failed (Status 0x%08lx)\n", Status);
2330  RtlFreeUnicodeString(&DeviceId);
2331  return Status;
2332  }
2333  }
2334 
2335  DPRINT("Sending IRP_MN_QUERY_ID.BusQueryInstanceID to device stack\n");
2336 
2337  Stack.Parameters.QueryId.IdType = BusQueryInstanceID;
2338  Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
2339  &IoStatusBlock,
2341  &Stack);
2342  if (!NT_SUCCESS(Status))
2343  {
2344  DPRINT("IopInitiatePnpIrp(BusQueryInstanceID) failed (Status %lx)\n", Status);
2346  }
2347 
2349  {
2351 
2352  if (!IsValidID)
2353  {
2354  DPRINT1("Invalid InstanceID. DeviceNode - %p\n", DeviceNode);
2355  }
2356  }
2357 
2360 
2361  InstancePath->Length = 0;
2362  InstancePath->MaximumLength = DeviceId.Length + sizeof(WCHAR) +
2363  ParentIdPrefix.Length +
2364  InstanceId.Length +
2365  sizeof(UNICODE_NULL);
2366  if (ParentIdPrefix.Length && InstanceId.Length)
2367  {
2368  InstancePath->MaximumLength += sizeof(WCHAR);
2369  }
2370 
2371  InstancePath->Buffer = ExAllocatePoolWithTag(PagedPool,
2372  InstancePath->MaximumLength,
2373  TAG_IO);
2374  if (!InstancePath->Buffer)
2375  {
2377  RtlFreeUnicodeString(&ParentIdPrefix);
2378  RtlFreeUnicodeString(&DeviceId);
2380  }
2381 
2382  /* Start with the device id */
2383  RtlCopyUnicodeString(InstancePath, &DeviceId);
2384  RtlAppendUnicodeToString(InstancePath, L"\\");
2385 
2386  /* Add information from parent bus device to InstancePath */
2387  RtlAppendUnicodeStringToString(InstancePath, &ParentIdPrefix);
2388  if (ParentIdPrefix.Length && InstanceId.Length)
2389  {
2390  RtlAppendUnicodeToString(InstancePath, L"&");
2391  }
2392 
2393  /* Finally, add the id returned by the driver stack */
2395 
2396  /*
2397  * FIXME: Check for valid characters, if there is invalid characters
2398  * then bugcheck
2399  */
2400 
2402  RtlFreeUnicodeString(&DeviceId);
2403  RtlFreeUnicodeString(&ParentIdPrefix);
2404 
2405  return STATUS_SUCCESS;
2406 }
#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:55
LONG NTSTATUS
Definition: precomp.h:26
DEVICE_CAPABILITIES
Definition: iotypes.h:928
uint16_t * PWCHAR
Definition: typedefs.h:55
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:4448
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:1920
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:2045
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:1560
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:980
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by IopActionInterrogateDeviceStack().

◆ IopCreateDeviceKeyPath()

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

Definition at line 1682 of file pnpmgr.c.

1685 {
1687  HANDLE hParent = NULL, hKey;
1690  PCWSTR Current, Last;
1691  USHORT Length;
1692  NTSTATUS Status;
1693 
1694  /* Assume failure */
1695  *Handle = NULL;
1696 
1697  /* Open root key for device instances */
1699  if (!NT_SUCCESS(Status))
1700  {
1701  DPRINT1("ZwOpenKey('%wZ') failed with status 0x%08lx\n", &EnumU, Status);
1702  return Status;
1703  }
1704 
1705  Current = KeyName.Buffer = RegistryPath->Buffer;
1706  Last = &RegistryPath->Buffer[RegistryPath->Length / sizeof(WCHAR)];
1707 
1708  /* Go up to the end of the string */
1709  while (Current <= Last)
1710  {
1711  if (Current != Last && *Current != L'\\')
1712  {
1713  /* Not the end of the string and not a separator */
1714  Current++;
1715  continue;
1716  }
1717 
1718  /* Prepare relative key name */
1719  Length = (USHORT)((ULONG_PTR)Current - (ULONG_PTR)KeyName.Buffer);
1720  KeyName.MaximumLength = KeyName.Length = Length;
1721  DPRINT("Create '%wZ'\n", &KeyName);
1722 
1723  /* Open key */
1725  &KeyName,
1727  hParent,
1728  NULL);
1729  Status = ZwCreateKey(&hKey,
1730  Current == Last ? KEY_ALL_ACCESS : KEY_CREATE_SUB_KEY,
1732  0,
1733  NULL,
1734  CreateOptions,
1735  NULL);
1736 
1737  /* Close parent key handle, we don't need it anymore */
1738  if (hParent)
1739  ZwClose(hParent);
1740 
1741  /* Key opening/creating failed? */
1742  if (!NT_SUCCESS(Status))
1743  {
1744  DPRINT1("ZwCreateKey('%wZ') failed with status 0x%08lx\n", &KeyName, Status);
1745  return Status;
1746  }
1747 
1748  /* Check if it is the end of the string */
1749  if (Current == Last)
1750  {
1751  /* Yes, return success */
1752  *Handle = hKey;
1753  return STATUS_SUCCESS;
1754  }
1755 
1756  /* Start with this new parent key */
1757  hParent = hKey;
1758  Current++;
1759  KeyName.Buffer = (PWSTR)Current;
1760  }
1761 
1762  return STATUS_UNSUCCESSFUL;
1763 }
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:56
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:3760
uint16_t * PWSTR
Definition: typedefs.h:55
LONG NTSTATUS
Definition: precomp.h:26
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
uint32_t ULONG_PTR
Definition: typedefs.h:64
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 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:28
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
#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 1257 of file pnpmgr.c.

1261 {
1263  NTSTATUS Status;
1264  KIRQL OldIrql;
1265  UNICODE_STRING FullServiceName;
1266  UNICODE_STRING LegacyPrefix = RTL_CONSTANT_STRING(L"LEGACY_");
1267  UNICODE_STRING UnknownDeviceName = RTL_CONSTANT_STRING(L"UNKNOWN");
1268  UNICODE_STRING KeyName, ClassName;
1269  PUNICODE_STRING ServiceName1;
1270  ULONG LegacyValue;
1272  HANDLE InstanceHandle;
1273 
1274  DPRINT("ParentNode 0x%p PhysicalDeviceObject 0x%p ServiceName %wZ\n",
1275  ParentNode, PhysicalDeviceObject, ServiceName);
1276 
1278  if (!Node)
1279  {
1281  }
1282 
1283  RtlZeroMemory(Node, sizeof(DEVICE_NODE));
1284 
1285  if (!ServiceName)
1286  ServiceName1 = &UnknownDeviceName;
1287  else
1288  ServiceName1 = ServiceName;
1289 
1290  if (!PhysicalDeviceObject)
1291  {
1292  FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName1->Length + sizeof(UNICODE_NULL);
1293  FullServiceName.Length = 0;
1294  FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength);
1295  if (!FullServiceName.Buffer)
1296  {
1299  }
1300 
1301  RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix);
1302  RtlAppendUnicodeStringToString(&FullServiceName, ServiceName1);
1303  RtlUpcaseUnicodeString(&FullServiceName, &FullServiceName, FALSE);
1304 
1305  Status = PnpRootCreateDevice(&FullServiceName, NULL, &PhysicalDeviceObject, &Node->InstancePath);
1306  if (!NT_SUCCESS(Status))
1307  {
1308  DPRINT1("PnpRootCreateDevice() failed with status 0x%08X\n", Status);
1309  ExFreePool(FullServiceName.Buffer);
1311  return Status;
1312  }
1313 
1314  /* Create the device key for legacy drivers */
1315  Status = IopCreateDeviceKeyPath(&Node->InstancePath, REG_OPTION_VOLATILE, &InstanceHandle);
1316  if (!NT_SUCCESS(Status))
1317  {
1318  ExFreePool(FullServiceName.Buffer);
1320  return Status;
1321  }
1322 
1323  Node->ServiceName.MaximumLength = ServiceName1->Length + sizeof(UNICODE_NULL);
1324  Node->ServiceName.Length = 0;
1325  Node->ServiceName.Buffer = ExAllocatePool(PagedPool, Node->ServiceName.MaximumLength);
1326  if (!Node->ServiceName.Buffer)
1327  {
1328  ZwClose(InstanceHandle);
1329  ExFreePool(FullServiceName.Buffer);
1331  return Status;
1332  }
1333 
1334  RtlCopyUnicodeString(&Node->ServiceName, ServiceName1);
1335 
1336  if (ServiceName)
1337  {
1338  RtlInitUnicodeString(&KeyName, L"Service");
1339  Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName->Buffer, ServiceName->Length + sizeof(UNICODE_NULL));
1340  }
1341 
1342  if (NT_SUCCESS(Status))
1343  {
1344  RtlInitUnicodeString(&KeyName, L"Legacy");
1345  LegacyValue = 1;
1346  Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue));
1347 
1348  RtlInitUnicodeString(&KeyName, L"ConfigFlags");
1349  LegacyValue = 0;
1350  ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue));
1351 
1352  if (NT_SUCCESS(Status))
1353  {
1354  RtlInitUnicodeString(&KeyName, L"Class");
1355  RtlInitUnicodeString(&ClassName, L"LegacyDriver");
1356  Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassName.Buffer, ClassName.Length + sizeof(UNICODE_NULL));
1357  if (NT_SUCCESS(Status))
1358  {
1359  RtlInitUnicodeString(&KeyName, L"ClassGUID");
1360  RtlInitUnicodeString(&ClassGUID, L"{8ECC055D-047F-11D1-A537-0000F8753ED1}");
1361  Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassGUID.Buffer, ClassGUID.Length + sizeof(UNICODE_NULL));
1362  if (NT_SUCCESS(Status))
1363  {
1364  // FIXME: Retrieve the real "description" by looking at the "DisplayName" string
1365  // of the corresponding CurrentControlSet\Services\xxx entry for this driver.
1366  RtlInitUnicodeString(&KeyName, L"DeviceDesc");
1367  Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName1->Buffer, ServiceName1->Length + sizeof(UNICODE_NULL));
1368  }
1369  }
1370  }
1371  }
1372 
1373  ZwClose(InstanceHandle);
1374  ExFreePool(FullServiceName.Buffer);
1375 
1376  if (!NT_SUCCESS(Status))
1377  {
1378  ExFreePool(Node->ServiceName.Buffer);
1380  return Status;
1381  }
1382 
1387  }
1388 
1389  Node->PhysicalDeviceObject = PhysicalDeviceObject;
1390 
1391  ((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = Node;
1392 
1393  if (ParentNode)
1394  {
1396  Node->Parent = ParentNode;
1397  Node->Sibling = NULL;
1398  if (ParentNode->LastChild == NULL)
1399  {
1400  ParentNode->Child = Node;
1401  ParentNode->LastChild = Node;
1402  }
1403  else
1404  {
1405  ParentNode->LastChild->Sibling = Node;
1406  ParentNode->LastChild = Node;
1407  }
1409  Node->Level = ParentNode->Level + 1;
1410  }
1411 
1413 
1414  *DeviceNode = Node;
1415 
1416  return STATUS_SUCCESS;
1417 }
#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:1682
LONG NTSTATUS
Definition: precomp.h:26
struct _EXTENDED_DEVOBJ_EXTENSION * PEXTENDED_DEVOBJ_EXTENSION
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1122
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:790
#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:2938
#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 3785 of file pnpmgr.c.

3791 {
3793  ULONG KeyDisposition, RootHandleIndex = 0, i = 1, NestedCloseLevel = 0;
3794  USHORT Length;
3795  HANDLE HandleArray[2];
3796  BOOLEAN Recursing = TRUE;
3797  PWCHAR pp, p, p1;
3798  UNICODE_STRING KeyString;
3800  PAGED_CODE();
3801 
3802  /* P1 is start, pp is end */
3803  p1 = KeyName->Buffer;
3804  pp = (PVOID)((ULONG_PTR)p1 + KeyName->Length);
3805 
3806  /* Create the target key */
3808  KeyName,
3810  RootHandle,
3811  NULL);
3812  Status = ZwCreateKey(&HandleArray[i],
3813  DesiredAccess,
3815  0,
3816  NULL,
3817  CreateOptions,
3818  &KeyDisposition);
3819 
3820  /* Now we check if this failed */
3821  if ((Status == STATUS_OBJECT_NAME_NOT_FOUND) && (RootHandle))
3822  {
3823  /* Target key failed, so we'll need to create its parent. Setup array */
3824  HandleArray[0] = NULL;
3825  HandleArray[1] = RootHandle;
3826 
3827  /* Keep recursing for each missing parent */
3828  while (Recursing)
3829  {
3830  /* And if we're deep enough, close the last handle */
3831  if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]);
3832 
3833  /* We're setup to ping-pong between the two handle array entries */
3834  RootHandleIndex = i;
3835  i = (i + 1) & 1;
3836 
3837  /* Clear the one we're attempting to open now */
3838  HandleArray[i] = NULL;
3839 
3840  /* Process the parent key name */
3841  for (p = p1; ((p < pp) && (*p != OBJ_NAME_PATH_SEPARATOR)); p++);
3842  Length = (USHORT)(p - p1) * sizeof(WCHAR);
3843 
3844  /* Is there a parent name? */
3845  if (Length)
3846  {
3847  /* Build the unicode string for it */
3848  KeyString.Buffer = p1;
3849  KeyString.Length = KeyString.MaximumLength = Length;
3850 
3851  /* Now try opening the parent */
3853  &KeyString,
3855  HandleArray[RootHandleIndex],
3856  NULL);
3857  Status = ZwCreateKey(&HandleArray[i],
3858  DesiredAccess,
3860  0,
3861  NULL,
3862  CreateOptions,
3863  &KeyDisposition);
3864  if (NT_SUCCESS(Status))
3865  {
3866  /* It worked, we have one more handle */
3867  NestedCloseLevel++;
3868  }
3869  else
3870  {
3871  /* Parent key creation failed, abandon loop */
3872  Recursing = FALSE;
3873  continue;
3874  }
3875  }
3876  else
3877  {
3878  /* We don't have a parent name, probably corrupted key name */
3880  Recursing = FALSE;
3881  continue;
3882  }
3883 
3884  /* Now see if there's more parents to create */
3885  p1 = p + 1;
3886  if ((p == pp) || (p1 == pp))
3887  {
3888  /* We're done, hopefully successfully, so stop */
3889  Recursing = FALSE;
3890  }
3891  }
3892 
3893  /* Outer loop check for handle nesting that requires closing the top handle */
3894  if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]);
3895  }
3896 
3897  /* Check if we broke out of the loop due to success */
3898  if (NT_SUCCESS(Status))
3899  {
3900  /* Return the target handle (we closed all the parent ones) and disposition */
3901  *Handle = HandleArray[i];
3902  if (Disposition) *Disposition = KeyDisposition;
3903  }
3904 
3905  /* Return the success state */
3906  return Status;
3907 }
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
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
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:55
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_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:64
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:1208
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
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:2938

Referenced by IopSetServiceEnumData().

◆ IopDeviceActionWorker()

static VOID NTAPI IopDeviceActionWorker ( _In_ PVOID  Context)
static

Definition at line 1084 of file pnpmgr.c.

1086 {
1087  PLIST_ENTRY ListEntry;
1089  KIRQL OldIrql;
1090 
1093  {
1096  Data = CONTAINING_RECORD(ListEntry,
1098  RequestListEntry);
1099 
1100  switch (Data->Action)
1101  {
1104  Data->InvalidateDeviceRelations.Type);
1105  break;
1106 
1107  default:
1108  DPRINT1("Unimplemented device action %u\n", Data->Action);
1109  break;
1110  }
1111 
1112  ObDereferenceObject(Data->DeviceObject);
1115  }
1118 }
NTSTATUS NTAPI IoSynchronousInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:5201
#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:790
Definition: typedefs.h:118
LIST_ENTRY IopDeviceActionRequestList
Definition: pnpmgr.c:36
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define DPRINT1
Definition: precomp.h:8
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by IopQueueDeviceAction().

◆ 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 3199 of file pnpmgr.c.

3206 {
3207  UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier");
3208  UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID");
3209  UNICODE_STRING ConfigurationDataU = RTL_CONSTANT_STRING(L"Configuration Data");
3210  UNICODE_STRING BootConfigU = RTL_CONSTANT_STRING(L"BootConfig");
3211  UNICODE_STRING LogConfU = RTL_CONSTANT_STRING(L"LogConf");
3213  HANDLE hDevicesKey = NULL;
3214  HANDLE hDeviceKey = NULL;
3215  HANDLE hLevel1Key, hLevel2Key = NULL, hLogConf;
3216  UNICODE_STRING Level2NameU;
3217  WCHAR Level2Name[5];
3218  ULONG IndexDevice = 0;
3219  ULONG IndexSubKey;
3220  PKEY_BASIC_INFORMATION pDeviceInformation = NULL;
3221  ULONG DeviceInfoLength = sizeof(KEY_BASIC_INFORMATION) + 50 * sizeof(WCHAR);
3222  PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL;
3223  ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR);
3226  PCM_FULL_RESOURCE_DESCRIPTOR BootResources = NULL;
3227  ULONG BootResourcesLength;
3228  NTSTATUS Status;
3229 
3230  const UNICODE_STRING IdentifierSerial = RTL_CONSTANT_STRING(L"SerialController");
3231  UNICODE_STRING HardwareIdSerial = RTL_CONSTANT_STRING(L"*PNP0501\0");
3232  static ULONG DeviceIndexSerial = 0;
3233  const UNICODE_STRING IdentifierKeyboard = RTL_CONSTANT_STRING(L"KeyboardController");
3234  UNICODE_STRING HardwareIdKeyboard = RTL_CONSTANT_STRING(L"*PNP0303\0");
3235  static ULONG DeviceIndexKeyboard = 0;
3236  const UNICODE_STRING IdentifierMouse = RTL_CONSTANT_STRING(L"PointerController");
3237  UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*PNP0F13\0");
3238  static ULONG DeviceIndexMouse = 0;
3239  const UNICODE_STRING IdentifierParallel = RTL_CONSTANT_STRING(L"ParallelController");
3240  UNICODE_STRING HardwareIdParallel = RTL_CONSTANT_STRING(L"*PNP0400\0");
3241  static ULONG DeviceIndexParallel = 0;
3242  const UNICODE_STRING IdentifierFloppy = RTL_CONSTANT_STRING(L"FloppyDiskPeripheral");
3243  UNICODE_STRING HardwareIdFloppy = RTL_CONSTANT_STRING(L"*PNP0700\0");
3244  static ULONG DeviceIndexFloppy = 0;
3245  UNICODE_STRING HardwareIdKey;
3246  PUNICODE_STRING pHardwareId;
3247  ULONG DeviceIndex = 0;
3248  PUCHAR CmResourceList;
3249  ULONG ListCount;
3250 
3251  if (RelativePath)
3252  {
3253  Status = IopOpenRegistryKeyEx(&hDevicesKey, hBaseKey, RelativePath, KEY_ENUMERATE_SUB_KEYS);
3254  if (!NT_SUCCESS(Status))
3255  {
3256  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
3257  goto cleanup;
3258  }
3259  }
3260  else
3261  hDevicesKey = hBaseKey;
3262 
3263  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
3264  if (!pDeviceInformation)
3265  {
3266  DPRINT("ExAllocatePool() failed\n");
3268  goto cleanup;
3269  }
3270 
3271  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
3272  if (!pValueInformation)
3273  {
3274  DPRINT("ExAllocatePool() failed\n");
3276  goto cleanup;
3277  }
3278 
3279  while (TRUE)
3280  {
3281  Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
3283  break;
3285  {
3286  ExFreePool(pDeviceInformation);
3287  DeviceInfoLength = RequiredSize;
3288  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
3289  if (!pDeviceInformation)
3290  {
3291  DPRINT("ExAllocatePool() failed\n");
3293  goto cleanup;
3294  }
3295  Status = ZwEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
3296  }
3297  if (!NT_SUCCESS(Status))
3298  {
3299  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
3300  goto cleanup;
3301  }
3302  IndexDevice++;
3303 
3304  /* Open device key */
3305  DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength;
3306  DeviceName.Buffer = pDeviceInformation->Name;
3307 
3308  Status = IopOpenRegistryKeyEx(&hDeviceKey, hDevicesKey, &DeviceName,
3309  KEY_QUERY_VALUE + (EnumerateSubKeys ? KEY_ENUMERATE_SUB_KEYS : 0));
3310  if (!NT_SUCCESS(Status))
3311  {
3312  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
3313  goto cleanup;
3314  }
3315 
3316  /* Read boot resources, and add then to parent ones */
3317  Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
3319  {
3320  ExFreePool(pValueInformation);
3321  ValueInfoLength = RequiredSize;
3322  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
3323  if (!pValueInformation)
3324  {
3325  DPRINT("ExAllocatePool() failed\n");
3326  ZwDeleteKey(hLevel2Key);
3328  goto cleanup;
3329  }
3330  Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
3331  }
3333  {
3334  BootResources = ParentBootResources;
3335  BootResourcesLength = ParentBootResourcesLength;
3336  }
3337  else if (!NT_SUCCESS(Status))
3338  {
3339  DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
3340  goto nextdevice;
3341  }
3342  else if (pValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR)
3343  {
3344  DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_FULL_RESOURCE_DESCRIPTOR);
3345  goto nextdevice;
3346  }
3347  else
3348  {
3349  static const ULONG Header = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors);
3350 
3351  /* Concatenate current resources and parent ones */
3352  if (ParentBootResourcesLength == 0)
3353  BootResourcesLength = pValueInformation->DataLength;
3354  else
3355  BootResourcesLength = ParentBootResourcesLength
3356  + pValueInformation->DataLength
3357  - Header;
3358  BootResources = ExAllocatePool(PagedPool, BootResourcesLength);
3359  if (!BootResources)
3360  {
3361  DPRINT("ExAllocatePool() failed\n");
3362  goto nextdevice;
3363  }
3364  if (ParentBootResourcesLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
3365  {
3366  RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength);
3367  }
3368  else if (ParentBootResources->PartialResourceList.PartialDescriptors[ParentBootResources->PartialResourceList.Count - 1].Type == CmResourceTypeDeviceSpecific)
3369  {
3370  RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength);
3371  RtlCopyMemory(
3372  (PVOID)((ULONG_PTR)BootResources + pValueInformation->DataLength),
3373  (PVOID)((ULONG_PTR)ParentBootResources + Header),
3374  ParentBootResourcesLength - Header);
3375  BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count;
3376  }
3377  else
3378  {
3379  RtlCopyMemory(BootResources, pValueInformation->Data, Header);
3380  RtlCopyMemory(
3381  (PVOID)((ULONG_PTR)BootResources + Header),
3382  (PVOID)((ULONG_PTR)ParentBootResources + Header),
3383  ParentBootResourcesLength - Header);
3384  RtlCopyMemory(
3385  (PVOID)((ULONG_PTR)BootResources + ParentBootResourcesLength),
3386  pValueInformation->Data + Header,
3387  pValueInformation->DataLength - Header);
3388  BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count;
3389  }
3390  }
3391 
3392  if (EnumerateSubKeys)
3393  {
3394  IndexSubKey = 0;
3395  while (TRUE)
3396  {
3397  Status = ZwEnumerateKey(hDeviceKey, IndexSubKey, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
3399  break;
3401  {
3402  ExFreePool(pDeviceInformation);
3403  DeviceInfoLength = RequiredSize;
3404  pDeviceInformation = ExAllocatePool(PagedPool, DeviceInfoLength);
3405  if (!pDeviceInformation)
3406  {
3407  DPRINT("ExAllocatePool() failed\n");
3409  goto cleanup;
3410  }
3411  Status = ZwEnumerateKey(hDeviceKey, IndexSubKey, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
3412  }
3413  if (!NT_SUCCESS(Status))
3414  {
3415  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
3416  goto cleanup;
3417  }
3418  IndexSubKey++;
3419  DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength;
3420  DeviceName.Buffer = pDeviceInformation->Name;
3421 
3423  hDeviceKey,
3424  &DeviceName,
3425  hRootKey,
3426  TRUE,
3427  BootResources,
3428  BootResourcesLength);
3429  if (!NT_SUCCESS(Status))
3430  goto cleanup;
3431  }
3432  }
3433 
3434  /* Read identifier */
3435  Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
3437  {
3438  ExFreePool(pValueInformation);
3439  ValueInfoLength = RequiredSize;
3440  pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
3441  if (!pValueInformation)
3442  {
3443  DPRINT("ExAllocatePool() failed\n");
3445  goto cleanup;
3446  }
3447  Status = ZwQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
3448  }
3449  if (!NT_SUCCESS(Status))
3450  {
3452  {
3453  DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
3454  goto nextdevice;
3455  }
3457  }
3458  else if (pValueInformation->Type != REG_SZ)
3459  {
3460  DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ);
3461  goto nextdevice;
3462  }
3463  else
3464  {
3465  /* Assign hardware id to this device */
3466  ValueName.Length = ValueName.MaximumLength = (USHORT)pValueInformation->DataLength;
3467  ValueName.Buffer = (PWCHAR)pValueInformation->Data;
3468  if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL)
3469  ValueName.Length -= sizeof(WCHAR);
3470  }
3471 
3472  if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0)
3473  {
3474  pHardwareId = &HardwareIdSerial;
3475  DeviceIndex = DeviceIndexSerial++;
3476  }
3477  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierKeyboard, FALSE) == 0)
3478  {
3479  pHardwareId = &HardwareIdKeyboard;
3480  DeviceIndex = DeviceIndexKeyboard++;
3481  }
3482  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierMouse, FALSE) == 0)
3483  {
3484  pHardwareId = &HardwareIdMouse;
3485  DeviceIndex = DeviceIndexMouse++;
3486  }
3487  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierParallel, FALSE) == 0)
3488  {
3489  pHardwareId = &HardwareIdParallel;
3490  DeviceIndex = DeviceIndexParallel++;
3491  }
3492  else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierFloppy, FALSE) == 0)
3493  {
3494  pHardwareId = &HardwareIdFloppy;
3495  DeviceIndex = DeviceIndexFloppy++;
3496  }
3497  else
3498  {
3499  /* Unknown key path */
3500  DPRINT("Unknown key path '%wZ'\n", RelativePath);
3501  goto nextdevice;
3502  }
3503 
3504  /* Prepare hardware id key (hardware id value without final \0) */
3505  HardwareIdKey = *pHardwareId;
3506  HardwareIdKey.Length -= sizeof(UNICODE_NULL);
3507 
3508  /* Add the detected device to Root key */
3509  InitializeObjectAttributes(&ObjectAttributes, &HardwareIdKey, OBJ_KERNEL_HANDLE, hRootKey, NULL);
3510  Status = ZwCreateKey(
3511  &hLevel1Key,
3514  0,
3515  NULL,
3517  NULL);
3518  if (!NT_SUCCESS(Status))
3519  {
3520  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
3521  goto nextdevice;
3522  }
3523  swprintf(Level2Name, L"%04lu", DeviceIndex);
3524  RtlInitUnicodeString(&Level2NameU, Level2Name);
3525  InitializeObjectAttributes(&ObjectAttributes, &Level2NameU, OBJ_KERNEL_HANDLE, hLevel1Key, NULL);
3526  Status = ZwCreateKey(
3527  &hLevel2Key,
3530  0,
3531  NULL,
3533  NULL);
3534  ZwClose(hLevel1Key);
3535  if (!NT_SUCCESS(Status))
3536  {
3537  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
3538  goto nextdevice;
3539  }
3540  DPRINT("Found %wZ #%lu (%wZ)\n", &ValueName, DeviceIndex, &HardwareIdKey);
3541  Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength);
3542  if (!NT_SUCCESS(Status))
3543  {
3544  DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
3545  ZwDeleteKey(hLevel2Key);
3546  goto nextdevice;
3547  }
3548  /* Create 'LogConf' subkey */
3550  Status = ZwCreateKey(
3551  &hLogConf,
3552  KEY_SET_VALUE,
3554  0,
3555  NULL,
3557  NULL);
3558  if (!NT_SUCCESS(Status))
3559  {
3560  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
3561  ZwDeleteKey(hLevel2Key);
3562  goto nextdevice;
3563  }
3564  if (BootResourcesLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
3565  {
3566  CmResourceList = ExAllocatePool(PagedPool, BootResourcesLength + sizeof(ULONG));
3567  if (!CmResourceList)
3568  {
3569  ZwClose(hLogConf);
3570  ZwDeleteKey(hLevel2Key);
3571  goto nextdevice;
3572  }
3573 
3574  /* Add the list count (1st member of CM_RESOURCE_LIST) */
3575  ListCount = 1;
3576  RtlCopyMemory(CmResourceList,
3577  &ListCount,
3578  sizeof(ULONG));
3579 
3580  /* Now add the actual list (2nd member of CM_RESOURCE_LIST) */
3581  RtlCopyMemory(CmResourceList + sizeof(ULONG),
3582  BootResources,
3583  BootResourcesLength);
3584 
3585  /* Save boot resources to 'LogConf\BootConfig' */
3586  Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, REG_RESOURCE_LIST, CmResourceList, BootResourcesLength + sizeof(ULONG));
3587  if (!NT_SUCCESS(Status))
3588  {
3589  DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
3590  ZwClose(hLogConf);
3591  ZwDeleteKey(hLevel2Key);
3592  goto nextdevice;
3593  }
3594  }
3595  ZwClose(hLogConf);
3596 
3597 nextdevice:
3598  if (BootResources && BootResources != ParentBootResources)
3599  {
3600  ExFreePool(BootResources);
3601  BootResources = NULL;
3602  }
3603  if (hLevel2Key)
3604  {
3605  ZwClose(hLevel2Key);
3606  hLevel2Key = NULL;
3607  }
3608  if (hDeviceKey)
3609  {
3610  ZwClose(hDeviceKey);
3611  hDeviceKey = NULL;
3612  }
3613  }
3614 
3616 
3617 cleanup:
3618  if (hDevicesKey && hDevicesKey != hBaseKey)
3619  ZwClose(hDevicesKey);
3620  if (hDeviceKey)
3621  ZwClose(hDeviceKey);
3622  if (pDeviceInformation)
3623  ExFreePool(pDeviceInformation);
3624  if (pValueInformation)
3625  ExFreePool(pValueInformation);
3626  return Status;
3627 }
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:3760
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:55
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:64
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:66
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:3199
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
#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 2740 of file pnpmgr.c.

2742 {
2745  PDEVICE_RELATIONS DeviceRelations;
2746  PDEVICE_OBJECT ChildDeviceObject;
2748  PDEVICE_NODE ChildDeviceNode;
2749  IO_STACK_LOCATION Stack;
2750  NTSTATUS Status;
2751  ULONG i;
2752 
2753  DPRINT("DeviceObject 0x%p\n", DeviceObject);
2754 
2756  {
2758 
2759  DPRINT("Sending GUID_DEVICE_ARRIVAL\n");
2760  IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL,
2761  &DeviceNode->InstancePath);
2762  }
2763 
2764  DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
2765 
2766  Stack.Parameters.QueryDeviceRelations.Type = BusRelations;
2767 
2769  DeviceObject,
2770  &IoStatusBlock,
2772  &Stack);
2773  if (!NT_SUCCESS(Status) || Status == STATUS_PENDING)
2774  {
2775  DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
2776  return Status;
2777  }
2778 
2779  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
2780 
2781  /*
2782  * Send removal IRPs for devices that have disappeared
2783  * NOTE: This code handles the case where no relations are specified
2784  */
2785  IopHandleDeviceRemoval(DeviceNode, DeviceRelations);
2786 
2787  /* Now we bail if nothing was returned */
2788  if (!DeviceRelations)
2789  {
2790  /* We're all done */
2791  DPRINT("No PDOs\n");
2792  return STATUS_SUCCESS;
2793  }
2794 
2795  DPRINT("Got %u PDOs\n", DeviceRelations->Count);
2796 
2797  /*
2798  * Create device nodes for all discovered devices
2799  */
2800  for (i = 0; i < DeviceRelations->Count; i++)
2801  {
2802  ChildDeviceObject = DeviceRelations->Objects[i];
2803  ASSERT((ChildDeviceObject->Flags & DO_DEVICE_INITIALIZING) == 0);
2804 
2805  ChildDeviceNode = IopGetDeviceNode(ChildDeviceObject);
2806  if (!ChildDeviceNode)
2807  {
2808  /* One doesn't exist, create it */
2810  DeviceNode,
2811  ChildDeviceObject,
2812  NULL,
2813  &ChildDeviceNode);
2814  if (NT_SUCCESS(Status))
2815  {
2816  /* Mark the node as enumerated */
2817  ChildDeviceNode->Flags |= DNF_ENUMERATED;
2818 
2819  /* Mark the DO as bus enumerated */
2820  ChildDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
2821  }
2822  else
2823  {
2824  /* Ignore this DO */
2825  DPRINT1("IopCreateDeviceNode() failed with status 0x%08x. Skipping PDO %u\n", Status, i);
2826  ObDereferenceObject(ChildDeviceObject);
2827  }
2828  }
2829  else
2830  {
2831  /* Mark it as enumerated */
2832  ChildDeviceNode->Flags |= DNF_ENUMERATED;
2833  ObDereferenceObject(ChildDeviceObject);
2834  }
2835  }
2836  ExFreePool(DeviceRelations);
2837 
2838  /*
2839  * Retrieve information about all discovered children from the bus driver
2840  */
2842  &Context,
2843  DeviceNode,
2845  DeviceNode);
2846 
2848  if (!NT_SUCCESS(Status))
2849  {
2850  DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status);
2851  return Status;
2852  }
2853 
2854  /*
2855  * Retrieve configuration from the registry for discovered children
2856  */
2858  &Context,
2859  DeviceNode,
2861  DeviceNode);
2862 
2864  if (!NT_SUCCESS(Status))
2865  {
2866  DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status);
2867  return Status;
2868  }
2869 
2870  /*
2871  * Initialize services for discovered children.
2872  */
2874  if (!NT_SUCCESS(Status))
2875  {
2876  DPRINT("IopInitializePnpServices() failed with status 0x%08lx\n", Status);
2877  return Status;
2878  }
2879 
2880  DPRINT("IopEnumerateDevice() finished\n");
2881  return STATUS_SUCCESS;
2882 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
ULONG Flags
Definition: iotypes.h:836
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2055
LONG NTSTATUS
Definition: precomp.h:26
static VOID IopHandleDeviceRemoval(IN PDEVICE_NODE DeviceNode, IN PDEVICE_RELATIONS DeviceRelations)
Definition: pnpmgr.c:2694
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:1257
NTSTATUS IopActionConfigureChildServices(PDEVICE_NODE DeviceNode, PVOID Context)
Definition: pnpmgr.c:2902
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:2425
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:60
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:1560
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:1034
unsigned int ULONG
Definition: retypes.h:1
#define DNF_ENUMERATED
Definition: iotypes.h:170
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
NTSTATUS IopInitializePnpServices(IN PDEVICE_NODE DeviceNode)
Definition: pnpmgr.c:3181
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS IopTraverseDeviceTree(PDEVICETREE_TRAVERSE_CONTEXT Context)
Definition: pnpmgr.c:1640

Referenced by IoInitSystem(), IopPnpEnumerateDevice(), and IoSynchronousInvalidateDeviceRelations().

◆ IopFixupDeviceId()

VOID IopFixupDeviceId ( PWCHAR  String)

Definition at line 66 of file pnpmgr.c.

67 {
69 
70  for (i = 0; i < Length; i++)
71  {
72  if (String[i] == L'\\')
73  String[i] = L'#';
74  }
75 }
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:79
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)

Referenced by IopInstallCriticalDevice().

◆ IopFreeDeviceNode()

NTSTATUS IopFreeDeviceNode ( PDEVICE_NODE  DeviceNode)

Definition at line 1420 of file pnpmgr.c.

1421 {
1422  KIRQL OldIrql;
1423  PDEVICE_NODE PrevSibling = NULL;
1424 
1425  /* All children must be deleted before a parent is deleted */
1426  ASSERT(!DeviceNode->Child);
1427  ASSERT(DeviceNode->PhysicalDeviceObject);
1428 
1430 
1431  /* Get previous sibling */
1432  if (DeviceNode->Parent && DeviceNode->Parent->Child != DeviceNode)
1433  {
1434  PrevSibling = DeviceNode->Parent->Child;
1435  while (PrevSibling->Sibling != DeviceNode)
1436  PrevSibling = PrevSibling->Sibling;
1437  }
1438 
1439  /* Unlink from parent if it exists */
1440  if (DeviceNode->Parent)
1441  {
1442  if (DeviceNode->Parent->LastChild == DeviceNode)
1443  {
1444  DeviceNode->Parent->LastChild = PrevSibling;
1445  if (PrevSibling)
1446  PrevSibling->Sibling = NULL;
1447  }
1448  if (DeviceNode->Parent->Child == DeviceNode)
1449  DeviceNode->Parent->Child = DeviceNode->Sibling;
1450  }
1451 
1452  /* Unlink from sibling list */
1453  if (PrevSibling)
1454  PrevSibling->Sibling = DeviceNode->Sibling;
1455 
1457 
1458  RtlFreeUnicodeString(&DeviceNode->InstancePath);
1459 
1460  RtlFreeUnicodeString(&DeviceNode->ServiceName);
1461 
1462  if (DeviceNode->ResourceList)
1463  {
1464  ExFreePool(DeviceNode->ResourceList);
1465  }
1466 
1467  if (DeviceNode->ResourceListTranslated)
1468  {
1469  ExFreePool(DeviceNode->ResourceListTranslated);
1470  }
1471 
1472  if (DeviceNode->ResourceRequirements)
1473  {
1474  ExFreePool(DeviceNode->ResourceRequirements);
1475  }
1476 
1477  if (DeviceNode->BootResources)
1478  {
1479  ExFreePool(DeviceNode->BootResources);
1480  }
1481 
1482  ((PEXTENDED_DEVOBJ_EXTENSION)DeviceNode->PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = NULL;
1484 
1485  return STATUS_SUCCESS;
1486 }
#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:790
#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:2938
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

◆ IopGetBusTypeGuidIndex()

USHORT NTAPI IopGetBusTypeGuidIndex ( LPGUID  BusTypeGuid)

Definition at line 1176 of file pnpmgr.c.

1177 {
1178  USHORT i = 0, FoundIndex = 0xFFFF;
1179  ULONG NewSize;
1180  PVOID NewList;
1181 
1182  /* Acquire the lock */
1184 
1185  /* Loop all entries */
1186  while (i < PnpBusTypeGuidList->GuidCount)
1187  {
1188  /* Try to find a match */
1189  if (RtlCompareMemory(BusTypeGuid,
1191  sizeof(GUID)) == sizeof(GUID))
1192  {
1193  /* Found it */
1194  FoundIndex = i;
1195  goto Quickie;
1196  }
1197  i++;
1198  }
1199 
1200  /* Check if we have to grow the list */
1202  {
1203  /* Calculate the new size */
1204  NewSize = sizeof(IO_BUS_TYPE_GUID_LIST) +
1205  (sizeof(GUID) * PnpBusTypeGuidList->GuidCount);
1206 
1207  /* Allocate the new copy */
1208  NewList = ExAllocatePool(PagedPool, NewSize);
1209 
1210  if (!NewList)
1211  {
1212  /* Fail */
1214  goto Quickie;
1215  }
1216 
1217  /* Now copy them, decrease the size too */
1218  NewSize -= sizeof(GUID);
1220 
1221  /* Free the old list */
1223 
1224  /* Use the new buffer */
1225  PnpBusTypeGuidList = NewList;
1226  }
1227 
1228  /* Copy the new GUID */
1230  BusTypeGuid,
1231  sizeof(GUID));
1232 
1233  /* The new entry is the index */
1234  FoundIndex = (USHORT)PnpBusTypeGuidList->GuidCount;
1236 
1237 Quickie:
1239  return FoundIndex;
1240 }
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 124 of file plugplay.c.

125 {
126  if (IopRootDeviceNode == NULL)
127  return NULL;
128 
129  if (DeviceInstance == NULL ||
130  DeviceInstance->Length == 0)
131  {
133  {
136  }
137  else
138  return NULL;
139  }
140 
142 }
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:95
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(), IopPnpEnumerateDevice(), and IopResetDevice().

◆ IopGetParentIdPrefix()

NTSTATUS IopGetParentIdPrefix ( PDEVICE_NODE  DeviceNode,
PUNICODE_STRING  ParentIdPrefix 
)

Definition at line 1920 of file pnpmgr.c.

1922 {
1923  const UNICODE_STRING EnumKeyPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
1924  ULONG KeyNameBufferLength;
1925  PKEY_VALUE_PARTIAL_INFORMATION ParentIdPrefixInformation = NULL;
1926  UNICODE_STRING KeyName = {0, 0, NULL};
1927  UNICODE_STRING KeyValue;
1929  HANDLE hKey = NULL;
1930  ULONG crc32;
1931  NTSTATUS Status;
1932 
1933  /* HACK: As long as some devices have a NULL device
1934  * instance path, the following test is required :(
1935  */
1936  if (DeviceNode->Parent->InstancePath.Length == 0)
1937  {
1938  DPRINT1("Parent of %wZ has NULL Instance path, please report!\n",
1939  &DeviceNode->InstancePath);
1940  return STATUS_UNSUCCESSFUL;
1941  }
1942 
1943  /* 1. Try to retrieve ParentIdPrefix from registry */
1944  KeyNameBufferLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + sizeof(L"12345678&12345678");
1945  ParentIdPrefixInformation = ExAllocatePoolWithTag(PagedPool,
1946  KeyNameBufferLength + sizeof(UNICODE_NULL),
1947  TAG_IO);
1948  if (!ParentIdPrefixInformation)
1949  {
1951  }
1952 
1953  KeyName.Length = 0;
1954  KeyName.MaximumLength = EnumKeyPath.Length +
1955  DeviceNode->Parent->InstancePath.Length +
1956  sizeof(UNICODE_NULL);
1958  KeyName.MaximumLength,
1959  TAG_IO);
1960  if (!KeyName.Buffer)
1961  {
1963  goto cleanup;
1964  }
1965 
1966  RtlCopyUnicodeString(&KeyName, &EnumKeyPath);
1967  RtlAppendUnicodeStringToString(&KeyName, &DeviceNode->Parent->InstancePath);
1968 
1970  if (!NT_SUCCESS(Status))
1971  {
1972  goto cleanup;
1973  }
1974  RtlInitUnicodeString(&ValueName, L"ParentIdPrefix");
1975  Status = ZwQueryValueKey(hKey,
1976  &ValueName,
1978  ParentIdPrefixInformation,
1979  KeyNameBufferLength,
1980  &KeyNameBufferLength);
1981  if (NT_SUCCESS(Status))
1982  {
1983  if (ParentIdPrefixInformation->Type != REG_SZ)
1984  {
1986  }
1987  else
1988  {
1989  KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
1990  KeyValue.Length = KeyValue.MaximumLength - sizeof(UNICODE_NULL);
1991  KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
1992  ASSERT(KeyValue.Buffer[KeyValue.Length / sizeof(WCHAR)] == UNICODE_NULL);
1993  }
1994  goto cleanup;
1995  }
1997  {
1998  /* FIXME how do we get here and why is ParentIdPrefixInformation valid? */
1999  KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
2000  KeyValue.Length = KeyValue.MaximumLength - sizeof(UNICODE_NULL);
2001  KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
2002  ASSERT(KeyValue.Buffer[KeyValue.Length / sizeof(WCHAR)] == UNICODE_NULL);
2003  goto cleanup;
2004  }
2005 
2006  /* 2. Create the ParentIdPrefix value */
2007  crc32 = RtlComputeCrc32(0,
2008  (PUCHAR)DeviceNode->Parent->InstancePath.Buffer,
2009  DeviceNode->Parent->InstancePath.Length);
2010 
2011  RtlStringCbPrintfW((PWSTR)ParentIdPrefixInformation,
2012  KeyNameBufferLength,
2013  L"%lx&%lx",
2014  DeviceNode->Parent->Level,
2015  crc32);
2016  RtlInitUnicodeString(&KeyValue, (PWSTR)ParentIdPrefixInformation);
2017 
2018  /* 3. Try to write the ParentIdPrefix to registry */
2019  Status = ZwSetValueKey(hKey,
2020  &ValueName,
2021  0,
2022  REG_SZ,
2023  KeyValue.Buffer,
2024  ((ULONG)wcslen(KeyValue.Buffer) + 1) * sizeof(WCHAR));
2025 
2026 cleanup:
2027  if (NT_SUCCESS(Status))
2028  {
2029  /* Duplicate the string to return it */
2031  &KeyValue,
2032  ParentIdPrefix);
2033  }
2034  ExFreePoolWithTag(ParentIdPrefixInformation, TAG_IO);
2036  if (hKey != NULL)
2037  {
2038  ZwClose(hKey);
2039  }
2040  return Status;
2041 }
_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:3760
uint16_t * PWSTR
Definition: typedefs.h:55
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
uint32_t crc32
Definition: btrfs.c:4138
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
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: isapnp.h:82
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
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
static const WCHAR L[]
Definition: oid.c:1250
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 3911 of file pnpmgr.c.

3914 {
3915  UNICODE_STRING ValueString;
3916  NTSTATUS Status;
3917  PKEY_VALUE_FULL_INFORMATION FullInformation;
3918  ULONG Size;
3919  PAGED_CODE();
3920 
3921  RtlInitUnicodeString(&ValueString, ValueName);
3922 
3923  Status = ZwQueryValueKey(Handle,
3924  &ValueString,
3926  NULL,
3927  0,
3928  &Size);
3929  if ((Status != STATUS_BUFFER_OVERFLOW) &&
3931  {
3932  return Status;
3933  }
3934 
3935  FullInformation = ExAllocatePool(NonPagedPool, Size);
3936  if (!FullInformation) return STATUS_INSUFFICIENT_RESOURCES;
3937 
3938  Status = ZwQueryValueKey(Handle,
3939  &ValueString,
3941  FullInformation,
3942  Size,
3943  &Size);
3944  if (!NT_SUCCESS(Status))
3945  {
3946  ExFreePool(FullInformation);
3947  return Status;
3948  }
3949 
3950  *Information = FullInformation;
3951  return STATUS_SUCCESS;
3952 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
#define PAGED_CODE()
Definition: video.h:57
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
smooth NULL
Definition: ftsmooth.c:416
_In_ HANDLE Handle
Definition: extypes.h:390
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)