test: pnpiop.h File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# pnpiop.h File Reference

`#include "..\pnp\pnpi.h"`
`#include "arbiter.h"`
`#include "dockintf.h"`
`#include "pnprlist.h"`

Go to the source code of this file.

## Classes

struct | _PENDING_SET_INTERFACE_STATE
struct | _DEVICE_NODE
struct | _NEW_DEVICE_WORK_ITEM
struct | _ADD_CONTEXT
struct | _START_CONTEXT
struct | _PI_RESOURCE_ARBITER_ENTRY
struct | _PI_RESOURCE_TRANSLATOR_ENTRY
struct | _IOP_RESOURCE_REQUEST
struct | _PI_DEVICE_REQUEST
struct | _IOPNP_DEVICE_EXTENSION
struct | _IOP_RESERVED_RESOURCES_RECORD
struct | _NOTIFY_ENTRY_HEADER
struct | _TARGET_DEVICE_NOTIFY_ENTRY
struct | _DEVICE_CLASS_NOTIFY_ENTRY
struct | _SETUP_NOTIFY_DATA
struct | _HWPROFILE_NOTIFY_ENTRY
struct | _BUFFER_INFO
struct | _BUS_TYPE_GUID_LIST

## Defines

#define | IOP_DNOD_TAG 'donD'
#define | IOP_DNDT_TAG 'tdnD'
#define | IOP_DPWR_TAG 'rwPD'
#define | DBG_SCOPE 1
#define | ASSERT_PDO(d)
#define | DNF_MADEUP 0x00000001
#define | DNF_DUPLICATE 0x00000002
#define | DNF_HAL_NODE 0x00000004
#define | DNF_PROCESSED 0x00000008
#define | DNF_ENUMERATED 0x00000010
#define | DNF_NEED_QUERY_IDS 0x00000020
#define | DNF_ADDED 0x00000040
#define | DNF_HAS_BOOT_CONFIG 0x00000080
#define | DNF_BOOT_CONFIG_RESERVED 0x00000100
#define | DNF_START_REQUEST_PENDING 0x00000200
#define | DNF_NO_RESOURCE_REQUIRED 0x00000400
#define | DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED 0x00000800
#define | DNF_ASSIGNING_RESOURCES 0x00001000
#define | DNF_RESOURCE_ASSIGNED 0x00002000
#define | DNF_RESOURCE_REPORTED 0x00004000
#define | DNF_RESOURCE_REQUIREMENTS_CHANGED 0x00008000
#define | DNF_NON_STOPPED_REBALANCE 0x00010000
#define | DNF_STOPPED 0x00020000
#define | DNF_STARTED 0x00040000
#define | DNF_LEGACY_DRIVER 0x00080000
#define | DNF_NEED_ENUMERATION_ONLY 0x00100000
#define | DNF_IO_INVALIDATE_DEVICE_RELATIONS_PENDING 0x00200000
#define | DNF_BEING_ENUMERATED 0x00400000
#define | DNF_ENUMERATION_REQUEST_QUEUED 0x00800000
#define | DNF_ENUMERATION_REQUEST_PENDING 0x01000000
#define | DNF_HAS_PROBLEM 0x02000000
#define | DNF_HAS_PRIVATE_PROBLEM 0x04000000
#define | DNF_REMOVE_PENDING_CLOSES 0x08000000
#define | DNF_DEVICE_GONE 0x10000000
#define | DNF_LEGACY_RESOURCE_DEVICENODE 0x20000000
#define | DNF_NEEDS_REBALANCE 0x40000000
#define | DNF_LOCKED_FOR_EJECT 0x80000000
#define | DNUF_WILL_BE_REMOVED 0x00000001
#define | DNUF_DONT_SHOW_IN_UI 0x00000002
#define | DNUF_NEED_RESTART 0x00000004
#define | DNUF_NOT_DISABLEABLE 0x00000008
#define | DNF_ADD_PHASE (DNF_HAS_PROBLEM | DNF_HAS_PRIVATE_PROBLEM | DNF_DEVICE_GONE | DNF_REMOVE_PENDING_CLOSES | DNF_ADDED)
#define | OK_TO_ADD_DEVICE(_devnode_)
#define | DNF_START_PHASE (DNF_HAS_PROBLEM | DNF_HAS_PRIVATE_PROBLEM | DNF_DEVICE_GONE | DNF_REMOVE_PENDING_CLOSES | DNF_STARTED | DNF_START_REQUEST_PENDING)
#define | DNF_ASYNC_REQUEST_PENDING (DNF_START_REQUEST_PENDING | DNF_ENUMERATION_REQUEST_PENDING)
#define | DNF_ASSIGN_RESOURCE_PHASE
#define | DNF_HAS_RESOURCE
#define | PNP_ERR_DUPLICATE_PDO 1
#define | PNP_ERR_INVALID_PDO 2
#define | PNP_ERR_BOGUS_ID 3
#define | PNP_ERR_PDO_ENUMERATED_AFTER_DELETION 4
#define | PNP_ERR_ACTIVE_PDO_FREED 5
#define | PNP_ERR_DEVICE_MISSING_FROM_EJECT_LIST 6
#define | PNP_ERR_UNEXPECTED_ADD_RELATION_ERR 7
#define | NO_MORE_GROUP ((USHORT) -1)
#define | SETUP_RESERVED_GROUP 0
#define | BUS_DRIVER_GROUP 1
#define | PI_MAXIMUM_RESOURCE_TYPE_TRACKED 15
#define | PI_ARBITER_HAS_SOMETHING 1
#define | PI_ARBITER_TEST_FAILED 2
#define | QUERY_RESOURCE_LIST 0
#define | QUERY_RESOURCE_REQUIREMENTS 1
#define | REGISTRY_ALLOC_CONFIG 1
#define | REGISTRY_FORCED_CONFIG 2
#define | REGISTRY_BOOT_CONFIG 4
#define | REGISTRY_OVERRIDE_CONFIGVECTOR 1
#define | REGISTRY_BASIC_CONFIGVECTOR 2
#define | IOP_ASSIGN_RETRY 0x00000008
#define | IOP_ASSIGN_EXCLUDE 0x00000010
#define | IOP_ASSIGN_IGNORE 0x00000020
#define | IOP_ASSIGN_NO_REBALANCE 0x00000080
#define | IOP_ASSIGN_RESOURCES_RELEASED 0x00000100
#define | IOP_ASSIGN_KEEP_CURRENT_CONFIG 0x00000200
#define | IOP_ASSIGN_CLEAR_RESOURCE_REQUIREMENTS_CHANGE_FLAG 0x00000400
#define | CmResourceTypeReserved 0xf0
#define | KEY_VALUE_DATA(k) ((PCHAR)(k) + (k)->DataOffset)
#define | SAVE_FAILURE_INFO(DeviceNode, Status) (DeviceNode)->FailureStatus = (Status)
#define | IopDoesDevNodeHaveProblem(devnode) ((devnode)->Flags & (DNF_HAS_PROBLEM | DNF_HAS_PRIVATE_PROBLEM))
#define | IopIsDevNodeProblem(devnode, problem) (((devnode)->Flags & DNF_HAS_PROBLEM) && (devnode)->Problem == (problem))
#define | IopClearDevNodeProblem(devnode)
#define | IopSetDevNodeProblem(devnode, problem)
#define | IopIsProblemReadonly(problem)
#define | IopRegistryDataToUnicodeString(u, p, l)
#define | TITLE_INDEX_VALUE 0
#define | PNP_ASSERT(condition, message)
#define | PNP_DETECTION_ENABLED_DEFAULT TRUE
#define | PNP_SCRATCH_BUFFER_SIZE 512
#define | PNP_LARGE_SCRATCH_BUFFER_SIZE (PNP_SCRATCH_BUFFER_SIZE * 8)
#define | DEVINSTANCE_FLAG_HWPROFILE_DISABLED 0x1
#define | DEVINSTANCE_FLAG_PNP_ENUMERATED 0x2
#define | FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS 0x1
#define | FUNCTIONSUBKEY_FLAG_DELETE_SUBKEYS 0x2
#define | PLUGPLAY_REGKEY_DEVICE 1
#define | PLUGPLAY_REGKEY_DRIVER 2
#define | PLUGPLAY_REGKEY_CURRENT_HWPROFILE 4
#define | IopAcquireEnumerationLock(_devnode_)
#define | IopReleaseEnumerationLock(_devnode_)
#define | IopReleaseEnumerationLockForThread(_devnode_, _thread_)
#define | IopAcquireDeviceTreeLock() ExAcquireResourceExclusive(&IopDeviceTreeLock, TRUE)
#define | IopReleaseDeviceTreeLock() ExReleaseResource(&IopDeviceTreeLock)
#define | FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
#define | IopDeviceNodeFlagsToCapabilities(DeviceNode)
#define | IopConstStringSize(String) ( sizeof(String) - sizeof(UNICODE_NULL) )
#define | IopConstStringLength(String) ( ( sizeof(String) - sizeof(UNICODE_NULL) ) / sizeof(WCHAR) )
#define | IopKMToUMSymbolicLinkName(String)
#define | IopUMToKMSymbolicLinkName(String)
#define | IopHashGuid(_Guid)
#define | IopAcquireNotifyLock(Lock) ExAcquireFastMutex(Lock);
#define | IopReleaseNotifyLock(Lock) ExReleaseFastMutex(Lock);
#define | IopCompareGuid(g1, g2)
#define | PNP_NOTIFICATION_VERSION 1
#define | NOTIFY_DEVICE_CLASS_HASH_BUCKETS 13

## Typedefs

typedef _PENDING_SET_INTERFACE_STATE | PENDING_SET_INTERFACE_STATE
typedef _PENDING_SET_INTERFACE_STATE * | PPENDING_SET_INTERFACE_STATE
typedef enum _UNLOCK_UNLINK_ACTION | UNLOCK_UNLINK_ACTION
typedef enum _UNLOCK_UNLINK_ACTION * | PUNLOCK_UNLINK_ACTION
typedef _DEVICE_NODE * | PDEVICE_NODE
typedef _DEVICE_NODE | DEVICE_NODE
typedef NTSTATUS(* | PENUM_CALLBACK )(IN PDEVICE_NODE DeviceNode, IN PVOID Context)
typedef _NEW_DEVICE_WORK_ITEM | NEW_DEVICE_WORK_ITEM
typedef _NEW_DEVICE_WORK_ITEM * | PNEW_DEVICE_WORK_ITEM
typedef BOOLEAN(* | PIOP_SUBKEY_CALLBACK_ROUTINE )(IN HANDLE, IN PUNICODE_STRING, IN OUT PVOID)
typedef _ADD_CONTEXT | ADD_CONTEXT
typedef _ADD_CONTEXT * | PADD_CONTEXT
typedef _START_CONTEXT | START_CONTEXT
typedef _START_CONTEXT * | PSTART_CONTEXT
typedef enum _RESOURCE_HANDLER_TYPE | RESOURCE_HANDLER_TYPE
typedef _PI_RESOURCE_ARBITER_ENTRY | PI_RESOURCE_ARBITER_ENTRY
typedef _PI_RESOURCE_ARBITER_ENTRY * | PPI_RESOURCE_ARBITER_ENTRY
typedef _PI_RESOURCE_TRANSLATOR_ENTRY | PI_RESOURCE_TRANSLATOR_ENTRY
typedef _PI_RESOURCE_TRANSLATOR_ENTRY * | PPI_RESOURCE_TRANSLATOR_ENTRY
typedef _IOP_RESOURCE_REQUEST | IOP_RESOURCE_REQUEST
typedef _IOP_RESOURCE_REQUEST * | PIOP_RESOURCE_REQUEST
typedef enum _DEVICE_REQUEST_TYPE | DEVICE_REQUEST_TYPE
typedef _PI_DEVICE_REQUEST | PI_DEVICE_REQUEST
typedef _PI_DEVICE_REQUEST * | PPI_DEVICE_REQUEST
typedef _IOPNP_DEVICE_EXTENSION | IOPNP_DEVICE_EXTENSION
typedef _IOPNP_DEVICE_EXTENSION * | PIOPNP_DEVICE_EXTENSION
typedef _IOP_RESERVED_RESOURCES_RECORD IOP_RESERVED_RESOURCES_RECORD * | PIOP_RESERVED_RESOURCES_RECORD
typedef NTSTATUS(* | PIO_RESERVE_RESOURCES_ROUTINE )(IN ARBITER_REQUEST_SOURCE ArbiterRequestSource, IN PDEVICE_OBJECT DeviceObject, IN PCM_RESOURCE_LIST BootResources)
typedef _NOTIFY_ENTRY_HEADER | NOTIFY_ENTRY_HEADER
typedef _NOTIFY_ENTRY_HEADER * | PNOTIFY_ENTRY_HEADER
typedef _TARGET_DEVICE_NOTIFY_ENTRY | TARGET_DEVICE_NOTIFY_ENTRY
typedef _TARGET_DEVICE_NOTIFY_ENTRY * | PTARGET_DEVICE_NOTIFY_ENTRY
typedef _DEVICE_CLASS_NOTIFY_ENTRY | DEVICE_CLASS_NOTIFY_ENTRY
typedef _DEVICE_CLASS_NOTIFY_ENTRY * | PDEVICE_CLASS_NOTIFY_ENTRY
typedef _SETUP_NOTIFY_DATA | SETUP_NOTIFY_DATA
typedef _SETUP_NOTIFY_DATA * | PSETUP_NOTIFY_DATA
typedef _HWPROFILE_NOTIFY_ENTRY | HWPROFILE_NOTIFY_ENTRY
typedef _HWPROFILE_NOTIFY_ENTRY * | PHWPROFILE_NOTIFY_ENTRY
typedef _BUFFER_INFO | BUFFER_INFO
typedef _BUFFER_INFO * | PBUFFER_INFO
typedef _BUS_TYPE_GUID_LIST | BUS_TYPE_GUID_LIST
typedef _BUS_TYPE_GUID_LIST * | PBUS_TYPE_GUID_LIST
typedef enum _HARDWARE_PROFILE_BUS_TYPE | HARDWARE_PROFILE_BUS_TYPE
typedef enum _HARDWARE_PROFILE_BUS_TYPE * | PHARDWARE_PROFILE_BUS_TYPE

## Enumerations

enum | PROFILE_STATUS { DOCK_NOTDOCKDEVICE, DOCK_QUIESCENT, DOCK_ARRIVING, DOCK_DEPARTING, DOCK_EJECTIRP_COMPLETED }
enum | PROFILE_NOTIFICATION_TIME { PROFILE_IN_PNPEVENT, PROFILE_NOT_IN_PNPEVENT, PROFILE_PERHAPS_IN_PNPEVENT }
enum | _UNLOCK_UNLINK_ACTION { UnlinkRemovedDeviceNodes, UnlinkAllDeviceNodesPendingClose, UnlinkOnlyChildDeviceNodesPendingClose }
enum | _RESOURCE_HANDLER_TYPE { ResourceHandlerNull, ResourceTranslator, ResourceArbiter, ResourceLegacyDeviceDetection }
enum | _DEVICE_REQUEST_TYPE { ReenumerateDeviceTree, ReenumerateDeviceOnly, ReenumerateBootDevices, RestartEnumeration, AssignResources, ResourceRequirementsChanged, StartDevice, ReenumerateRootDevices }
enum | _HARDWARE_PROFILE_BUS_TYPE { HardwareProfileBusTypeACPI }

## Functions

NTSTATUS | IopAppendStringToValueKey (IN HANDLE Handle, IN PWSTR ValueName, IN PUNICODE_STRING String, IN BOOLEAN Create)
NTSTATUS | IopPrepareDriverLoading (IN PUNICODE_STRING KeyName, IN HANDLE KeyHandle, IN PIMAGE_NT_HEADERS Header)
NTSTATUS | IopRemoveStringFromValueKey (IN HANDLE Handle, IN PWSTR ValueName, IN PUNICODE_STRING String)
BOOLEAN | IopIsDuplicatedDevices (IN PCM_RESOURCE_LIST Configuration1, IN PCM_RESOURCE_LIST Configuration2, IN PHAL_BUS_INFORMATION BusInfo1 OPTIONAL, IN PHAL_BUS_INFORMATION BusInfo2 OPTIONAL)
NTSTATUS | IopMarkDuplicateDevice (IN PUNICODE_STRING TargetKeyName, IN ULONG TargetInstance, IN PUNICODE_STRING SourceKeyName, IN ULONG SourceInstance)
BOOLEAN | IopConcatenateUnicodeStrings (OUT PUNICODE_STRING Destination, IN PUNICODE_STRING String1, IN PUNICODE_STRING String2 OPTIONAL)
NTSTATUS | IopServiceInstanceToDeviceInstance (IN HANDLE ServiceKeyHandle OPTIONAL, IN PUNICODE_STRING ServiceKeyName OPTIONAL, IN ULONG ServiceInstanceOrdinal, OUT PUNICODE_STRING DeviceInstanceRegistryPath OPTIONAL, OUT PHANDLE DeviceInstanceHandle OPTIONAL, IN ACCESS_MASK DesiredAccess)
NTSTATUS | IopCreateRegistryKeyEx (OUT PHANDLE Handle, IN HANDLE BaseHandle OPTIONAL, IN PUNICODE_STRING KeyName, IN ACCESS_MASK DesiredAccess, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
NTSTATUS | IopOpenRegistryKeyEx (OUT PHANDLE Handle, IN HANDLE BaseHandle OPTIONAL, IN PUNICODE_STRING KeyName, IN ACCESS_MASK DesiredAccess)
NTSTATUS | IopCreateMadeupNode (IN PUNICODE_STRING ServiceKeyName, OUT PHANDLE ReturnedHandle, OUT PUNICODE_STRING KeyName, OUT PULONG InstanceOrdinal, IN BOOLEAN ResourceOwned)
NTSTATUS | IopInitializePlugPlayServices (IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN ULONG Phase)
NTSTATUS | IopOpenServiceEnumKeys (IN PUNICODE_STRING ServiceKeyName, IN ACCESS_MASK DesiredAccess, OUT PHANDLE ServiceHandle OPTIONAL, OUT PHANDLE ServiceEnumHandle OPTIONAL, IN BOOLEAN CreateEnum)
NTSTATUS | IopOpenCurrentHwProfileDeviceInstanceKey (OUT PHANDLE Handle, IN PUNICODE_STRING ServiceKeyName, IN ULONG Instance, IN ACCESS_MASK DesiredAccess, IN BOOLEAN Create)
NTSTATUS | IopGetDeviceInstanceCsConfigFlags (IN PUNICODE_STRING DeviceInstance, OUT PULONG CsConfigFlags)
NTSTATUS | IopGetServiceInstanceCsConfigFlags (IN PUNICODE_STRING ServiceKeyName, IN ULONG Instance, OUT PULONG CsConfigFlags)
NTSTATUS | IopSetServiceInstanceCsConfigFlags (IN PUNICODE_STRING ServiceKeyName, IN ULONG Instance, IN ULONG CsConfigFlags)
NTSTATUS | IopApplyFunctionToSubKeys (IN HANDLE BaseHandle OPTIONAL, IN PUNICODE_STRING KeyName, IN ACCESS_MASK DesiredAccess, IN ULONG Flags, IN PIOP_SUBKEY_CALLBACK_ROUTINE SubKeyCallbackRoutine, IN OUT PVOID Context)
NTSTATUS | IopRegMultiSzToUnicodeStrings (IN PKEY_VALUE_FULL_INFORMATION KeyValueInformation, IN PUNICODE_STRING *UnicodeStringList, OUT PULONG UnicodeStringCount)
NTSTATUS | IopApplyFunctionToServiceInstances (IN HANDLE ServiceKeyHandle OPTIONAL, IN PUNICODE_STRING ServiceKeyName OPTIONAL, IN ACCESS_MASK DesiredAccess, IN BOOLEAN IgnoreNonCriticalErrors, IN PIOP_SUBKEY_CALLBACK_ROUTINE DevInstCallbackRoutine, IN OUT PVOID Context, OUT PULONG ServiceInstanceOrdinal OPTIONAL)
VOID | IopFreeUnicodeStringList (IN PUNICODE_STRING UnicodeStringList, IN ULONG StringCount)
NTSTATUS | IopDriverLoadingFailed (IN HANDLE KeyHandle OPTIONAL, IN PUNICODE_STRING KeyName OPTIONAL)
NTSTATUS | IopReadDeviceConfiguration (IN HANDLE Handle, IN ULONG Flags, OUT PCM_RESOURCE_LIST *CmResource, OUT PULONG Length)
BOOLEAN | IopIsFirmwareMapperDevicePresent (IN HANDLE KeyHandle)
VOID | IopInsertTreeDeviceNode (IN PDEVICE_NODE ParentNode, IN PDEVICE_NODE DeviceNode)
VOID | IopRemoveTreeDeviceNode (IN PDEVICE_NODE DeviceNode)
PDEVICE_NODE | IopAllocateDeviceNode (IN PDEVICE_OBJECT PhysicalDeviceObject)
NTSTATUS | IopForAllDeviceNodes (IN PENUM_CALLBACK Callback, IN PVOID Context)
ULONG | IopDetermineResourceListSize (IN PCM_RESOURCE_LIST ResourceList)
NTSTATUS | IopQueryDeviceConfigurationVector (IN PUNICODE_STRING ServiceKeyName, IN ULONG InstanceOrdinal, OUT PULONG DeviceInstanceFlags, OUT PIO_RESOURCE_REQUIREMENTS_LIST ConfigurationVector, IN ULONG BufferSize, OUT PULONG ActualBufferSize)
PDRIVER_OBJECT | IopReferenceDriverObjectByName (IN PUNICODE_STRING DriverName)
PDEVICE_OBJECT | IopDeviceObjectFromDeviceInstance (IN HANDLE DeviceInstanceHandle OPTIONAL, IN PUNICODE_STRING DeviceInstance OPTIONAL)
NTSTATUS | IopDeviceObjectToDeviceInstance (IN PDEVICE_OBJECT DeviceObject, IN PHANDLE DeviceInstanceHandle, IN ACCESS_MASK DesiredAccess)
BOOLEAN | IopIsDeviceInstanceEnabled (IN HANDLE DeviceInstanceHandle, IN PUNICODE_STRING DeviceInstance, IN BOOLEAN DisableIfEnabled)
NTSTATUS | IopAddDevicesToBootDriver (IN PDRIVER_OBJECT DriverObject)
USHORT | IopProcessAddDevices (IN PDEVICE_NODE DeviceNode, IN USHORT StartOrder, IN ULONG DriverStartType)
BOOLEAN | IopProcessAssignResources (IN PDEVICE_NODE DeviceNode, IN BOOLEAN Reallocation, IN BOOLEAN BootConfigsOK)
VOID | IopProcessStartDevices (IN PDEVICE_NODE DeviceNode, IN PSTART_CONTEXT StartContext)
VOID | IopStartDevice (IN PDEVICE_OBJECT TargetDevice)
NTSTATUS | IopEjectDevice (IN PDEVICE_OBJECT DeviceObject, PPENDING_RELATIONS_LIST_ENTRY PendingEntry)
NTSTATUS | IopRemoveDevice (IN PDEVICE_OBJECT TargetDevice, IN ULONG IrpMinorCode)
NTSTATUS | IopQueryDeviceRelations (IN DEVICE_RELATION_TYPE Relations, IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AsyncOk, OUT PDEVICE_RELATIONS *DeviceRelations)
NTSTATUS | IopQueryDeviceState (IN PDEVICE_OBJECT DeviceObject)
NTSTATUS | IopQueryDeviceSerialNumber (IN PDEVICE_OBJECT DeviceObject, OUT PWCHAR *SerialNumber)
NTSTATUS | IopForAllChildDeviceNodes (IN PDEVICE_NODE Parent, IN PENUM_CALLBACK Callback, IN PVOID Context)
NTSTATUS | IopCleanupDeviceRegistryValues (IN PUNICODE_STRING InstancePath, IN BOOLEAN KeepReference)
NTSTATUS | IopQueryDeviceId (IN PDEVICE_OBJECT DeviceObject, OUT PWCHAR *DeviceId)
NTSTATUS | IopQueryUniqueId (IN PDEVICE_OBJECT DeviceObject, OUT PWCHAR *UniqueId)
NTSTATUS | IopMakeGloballyUniqueId (IN PDEVICE_OBJECT DeviceObject, IN PWCHAR UniqueId, OUT PWCHAR *GloballyUniqueId)
NTSTATUS | IopQueryCompatibleIds (IN PDEVICE_OBJECT DeviceObject, IN BUS_QUERY_ID_TYPE IdType, OUT PWCHAR *CompatibleIds, OUT ULONG *Length)
NTSTATUS | IopQueryDeviceResources (IN PDEVICE_OBJECT DeviceObject, IN ULONG ResourceType, OUT PVOID *Resource, OUT ULONG *Length)
NTSTATUS | IopGetDeviceResourcesFromRegistry (IN PDEVICE_OBJECT DeviceObject, IN ULONG ResourceType, IN ULONG Preference, OUT PVOID *Resource, OUT PULONG Length)
VOID | IopResourceRequirementsChanged (IN PDEVICE_OBJECT PhysicalDeviceObject, IN BOOLEAN StopRequired)
NTSTATUS | IopReleaseDeviceResources (IN PDEVICE_NODE DeviceNode, IN BOOLEAN ReserveResources)
NTSTATUS | IopPnPAddDevice (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject)
BOOLEAN | IopProcessCriticalDevice (IN PDEVICE_NODE DeviceNode)
NTSTATUS | IopPnPDispatch (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
NTSTATUS | IopPowerDispatch (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
VOID | IopDestroyDeviceNode (PDEVICE_NODE DeviceNode)
NTSTATUS | IopStartAndEnumerateDevice (IN PDEVICE_NODE DeviceNode, IN PSTART_CONTEXT StartContext)
NTSTATUS | IopCallDriverAddDevice (IN PDEVICE_NODE DeviceNode, IN BOOLEAN LoadDriver, IN PADD_CONTEXT AddContext)
NTSTATUS | IopStartDriverDevices (IN PDRIVER_OBJECT DriverObject)
BOOLEAN | IopIsLegacyDriver (IN PDRIVER_OBJECT DriverObject)
VOID | IopNewDevice (IN PDEVICE_OBJECT DeviceObject)
NTSTATUS | IopProcessNewDeviceNode (IN OUT PDEVICE_NODE DeviceNode)
NTSTATUS | IopSynchronousCall (IN PDEVICE_OBJECT DeviceObject, IN PIO_STACK_LOCATION TopStackLocation, OUT PVOID *Information)
NTSTATUS | IopFilterResourceRequirementsList (IN PIO_RESOURCE_REQUIREMENTS_LIST IoList, IN PCM_RESOURCE_LIST CmList, IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *FilteredList, OUT PBOOLEAN ExactMatch)
NTSTATUS | IopMergeFilteredResourceRequirementsList (IN PIO_RESOURCE_REQUIREMENTS_LIST IoList1, IN PIO_RESOURCE_REQUIREMENTS_LIST IoList2, IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *MergedList)
NTSTATUS | IopMergeCmResourceLists (IN PCM_RESOURCE_LIST List1, IN PCM_RESOURCE_LIST List2, IN OUT PCM_RESOURCE_LIST *MergedList)
PIO_RESOURCE_REQUIREMENTS_LIST | IopCmResourcesToIoResources (IN ULONG SlotNumber, IN PCM_RESOURCE_LIST CmResourceList, IN ULONG Priority)
NTSTATUS | IopReportResourceListToPnp (IN PDRIVER_OBJECT DriverObject OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PCM_RESOURCE_LIST ResourceList, IN ULONG ListSize, IN BOOLEAN Translated)
NTSTATUS | IopAllocateResources (IN PULONG DeviceCountP, IN OUT PIOP_RESOURCE_REQUEST *AssignTablePP, IN BOOLEAN Locked, IN BOOLEAN BootConfigsOK)
VOID | IopReallocateResources (IN PDEVICE_OBJECT DeviceObject)
NTSTATUS | IopWriteResourceList (IN HANDLE ResourceMapKey, IN PUNICODE_STRING ClassName, IN PUNICODE_STRING DriverName, IN PUNICODE_STRING DeviceName, IN PCM_RESOURCE_LIST ResourceList, IN ULONG ResourceListSize)
VOID | IopRemoveResourceListFromPnp (IN PLIST_ENTRY ResourceList)
NTSTATUS | IopWriteAllocatedResourcesToRegistry (IN PDEVICE_NODE DeviceNode, IN PCM_RESOURCE_LIST ResourceList, IN ULONG Length)
USHORT | IopGetGroupOrderIndex (IN HANDLE ServiceHandle)
VOID | IopDeleteLegacyKey (IN PDRIVER_OBJECT DriverObject)
NTSTATUS | IopOpenDeviceParametersSubkey (OUT HANDLE *ParamKeyHandle, IN HANDLE ParentKeyHandle, IN PUNICODE_STRING SubKeyString, IN ACCESS_MASK DesiredAccess)
NTSTATUS | IopRequestDeviceAction (IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN DEVICE_REQUEST_TYPE RequestType, IN PKEVENT CompletionEvent OPTIONAL, IN PNTSTATUS CompletionStatus OPTIONAL)
NTSTATUS | IopRequestDeviceRemoval (IN PDEVICE_OBJECT DeviceObject, IN ULONG Problem)
NTSTATUS | IopRestartDeviceNode (IN PDEVICE_NODE DeviceNode)
NTSTATUS | IopDeleteKeyRecursive (IN HANDLE SubKeyHandle, IN PWCHAR SubKeyName)
NTSTATUS | IopQueryPnpBusInformation (IN PDEVICE_OBJECT DeviceObject, OUT LPGUID InterfaceGuid OPTIONAL, OUT INTERFACE_TYPE *InterfaceType OPTIONAL, OUT ULONG *BusNumber OPTIONAL)
NTSTATUS | IopQueryLegacyBusInformation (IN PDEVICE_OBJECT DeviceObject, OUT LPGUID InterfaceGuid OPTIONAL, OUT INTERFACE_TYPE *InterfaceType OPTIONAL, OUT ULONG *BusNumber OPTIONAL)
NTSTATUS | IopGetRootDevices (PDEVICE_RELATIONS *DeviceRelations)
NTSTATUS | IopLockDeviceRemovalRelations (IN PDEVICE_OBJECT DeviceObject, IN PLUGPLAY_DEVICE_DELETE_TYPE OperationCode, OUT PRELATION_LIST *RelationsList, IN BOOLEAN IsKernelInitiated)
NTSTATUS | IopDeleteLockedDeviceNodes (IN PDEVICE_OBJECT DeviceObject, IN PRELATION_LIST RelationsList, IN PLUGPLAY_DEVICE_DELETE_TYPE OperationCode, IN BOOLEAN IsKernelInitiated, IN BOOLEAN ProcessIndirectDescendants, IN ULONG Problem, OUT PDEVICE_OBJECT *VetoingDevice OPTIONAL)
NTSTATUS | IopUnlockDeviceRemovalRelations (IN PDEVICE_OBJECT DeviceObject, IN PRELATION_LIST RelationsList, IN UNLOCK_UNLINK_ACTION UnlinkAction)
NTSTATUS | IopInvalidateRelationsInList (PRELATION_LIST RelationsList, BOOLEAN OnlyIndirectDescendants, BOOLEAN UnlockDevNode, BOOLEAN RestartDevNode)
VOID | IopChainDereferenceComplete (IN PDEVICE_OBJECT PhysicalDeviceObject)
BOOLEAN | IopQueuePendingEject (PPENDING_RELATIONS_LIST_ENTRY Entry)
VOID | IopProcessCompletedEject (IN PVOID Context)
BOOLEAN | IopQueuePendingSurpriseRemoval (IN PDEVICE_OBJECT DeviceObject, IN PRELATION_LIST List, IN ULONG Problem)
BOOLEAN | IopIsAnyDeviceInstanceEnabled (IN PUNICODE_STRING ServiceKeyName, IN HANDLE ServiceHandle, IN BOOLEAN LegacyIncluded)
NTSTATUS | IopQueryResourceHandlerInterface (IN RESOURCE_HANDLER_TYPE HandlerType, IN PDEVICE_OBJECT DeviceObject, IN UCHAR ResourceType, IN OUT PVOID *Interface)
NTSTATUS | IopQueryReconfiguration (IN UCHAR Request, IN PDEVICE_OBJECT DeviceObject)
PDEVICE_NODE | IopFindBusDeviceNode (IN PDEVICE_NODE DeviceNode, IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN ULONG SlotNumber)
NTSTATUS | IopLegacyResourceAllocation (IN ARBITER_REQUEST_SOURCE AllocationType, IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject, IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements, IN OUT PCM_RESOURCE_LIST *AllocatedResources OPTIONAL)
NTSTATUS | IoReportResourceUsageInternal (IN ARBITER_REQUEST_SOURCE AllocationType, IN PUNICODE_STRING DriverClassName OPTIONAL, IN PDRIVER_OBJECT DriverObject, IN PCM_RESOURCE_LIST DriverList OPTIONAL, IN ULONG DriverListSize OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PCM_RESOURCE_LIST DeviceList OPTIONAL, IN ULONG DeviceListSize OPTIONAL, IN BOOLEAN OverrideConflict, OUT PBOOLEAN ConflictDetected)
NTSTATUS | IopDuplicateDetection (IN INTERFACE_TYPE LegacyBusType, IN ULONG BusNumber, IN ULONG SlotNumber, OUT PDEVICE_NODE *DeviceNode)
PDRIVER_OBJECT | IopLoadBootFilterDriver (IN PUNICODE_STRING DriverName, IN ULONG GroupIndex)
NTSTATUS | IopDeviceNodeCapabilitiesToRegistry (IN PDEVICE_NODE DeviceNode)
NTSTATUS | IopDeviceCapabilitiesToRegistry (IN PDEVICE_NODE DeviceNode, IN PDEVICE_CAPABILITIES Capabilities)
NTSTATUS | IopQueryDeviceCapabilities (IN PDEVICE_NODE DeviceNode, OUT PDEVICE_CAPABILITIES Capabilities)
VOID | IopIncDisableableDepends (IN OUT PDEVICE_NODE DeviceNode)
VOID | IopDecDisableableDepends (IN OUT PDEVICE_NODE DeviceNode)
NTSTATUS | IopQueryDockRemovalInterface (IN PDEVICE_OBJECT DeviceObject, IN OUT PDOCK_INTERFACE *DockInterface)
NTSTATUS | IopReserveBootResources (IN ARBITER_REQUEST_SOURCE ArbiterRequestSource, IN PDEVICE_OBJECT DeviceObject, IN PCM_RESOURCE_LIST BootResources)
NTSTATUS | IopAllocateBootResources (IN ARBITER_REQUEST_SOURCE ArbiterRequestSource, IN PDEVICE_OBJECT DeviceObject, IN PCM_RESOURCE_LIST BootResources)
NTSTATUS | IopReserveLegacyBootResources (IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber)
NTSTATUS | IopQueryConflictList (PDEVICE_OBJECT PhysicalDeviceObject, IN PCM_RESOURCE_LIST ResourceList, IN ULONG ResourceListSize, OUT PPLUGPLAY_CONTROL_CONFLICT_LIST ConflictList, IN ULONG ConflictListSize, IN ULONG Flags)
VOID | MapperProcessFirmwareTree (IN BOOLEAN OnlyProcessSerialPorts)
VOID | MapperConstructRootEnumTree (IN BOOLEAN CreatePhantomDevices)
VOID | MapperFreeList (VOID)
NTSTATUS | EisaBuildEisaDeviceNode (VOID)
VOID | MapperPhantomizeDetectedComPorts (VOID)
VOID | IopDumpCmResourceList (IN PCM_RESOURCE_LIST CmList)
VOID | IopDumpCmResourceDescriptor (IN PUCHAR Indent, IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Desc)
VOID | IopDumpAllocatedSystemResources (IN UCHAR ResourceType)
VOID | IopInitializePlugPlayNotification (VOID)
NTSTATUS | IopNotifySetupDeviceArrival (PDEVICE_OBJECT PhysicalDeviceObject, HANDLE EnumEntryKey, BOOLEAN InstallDriver)
NTSTATUS | IopRequestHwProfileChangeNotification (IN LPGUID EventGuid, IN PROFILE_NOTIFICATION_TIME NotificationTime, OUT PPNP_VETO_TYPE VetoType OPTIONAL, OUT PUNICODE_STRING VetoName OPTIONAL)
NTSTATUS | IopNotifyTargetDeviceChange (LPCGUID EventGuid, PDEVICE_OBJECT DeviceObject, PVOID NotificationStructure, PDRIVER_OBJECT *VetoingDriver)
NTSTATUS | IopGetRelatedTargetDevice (IN PFILE_OBJECT FileObject, OUT PDEVICE_NODE *DeviceNode)
NTSTATUS | IopNotifyDeviceClassChange (LPGUID EventGuid, LPGUID ClassGuid, PUNICODE_STRING SymbolicLinkName)
NTSTATUS | IopRegisterDeviceInterface (IN PUNICODE_STRING DeviceInstanceName, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, IN BOOLEAN UserModeFormat, OUT PUNICODE_STRING SymbolicLinkName)
NTSTATUS | IopUnregisterDeviceInterface (IN PUNICODE_STRING SymbolicLinkName)
NTSTATUS | IopRemoveDeviceInterfaces (IN PUNICODE_STRING DeviceInstancePath)
NTSTATUS | IopGetDeviceInterfaces (IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING DevicePath OPTIONAL, IN ULONG Flags, IN BOOLEAN UserModeFormat, OUT PWSTR *SymbolicLinkList, OUT PULONG SymbolicLinkListSize OPTIONAL)
NTSTATUS | IopDoDeferredSetInterfaceState (IN PDEVICE_NODE DeviceNode)
NTSTATUS | IopProcessSetInterfaceState (IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable, IN BOOLEAN DeferNotStarted)
NTSTATUS | IopReplaceSeperatorWithPound (OUT PUNICODE_STRING OutString, IN PUNICODE_STRING InString)
NTSTATUS | IopNotifyHwProfileChange (IN LPGUID EventGuid, OUT PPNP_VETO_TYPE VetoType OPTIONAL, OUT PUNICODE_STRING VetoName OPTIONAL)
VOID | IopUncacheInterfaceInformation (IN PDEVICE_OBJECT DeviceObject)
NTSTATUS | IopProcessNewProfile (VOID)
VOID | IopProcessNewProfileWorker (IN PVOID Context)
NTSTATUS | IopProcessNewProfileStateCallback (IN PDEVICE_NODE DeviceNode, IN PVOID Context)
VOID | IopProcessDeferredRegistrations (VOID)
NTSTATUS | IopPortInitialize (VOID)
NTSTATUS | IopMemInitialize (VOID)
NTSTATUS | IopIrqInitialize (VOID)
NTSTATUS | IopDmaInitialize (VOID)
NTSTATUS | IopBusNumberInitialize (VOID)
NTSTATUS | IopAllocateBuffer (IN PBUFFER_INFO Info, IN ULONG Size)
NTSTATUS | IopResizeBuffer (IN PBUFFER_INFO Info, IN ULONG NewSize, IN BOOLEAN CopyContents)
VOID | IopFreeBuffer (IN PBUFFER_INFO Info)
NTSTATUS | IopAllocateUnicodeString (IN OUT PUNICODE_STRING String, IN USHORT Length)
VOID | IopFreeAllocatedUnicodeString (PUNICODE_STRING String)
NTSTATUS | PnPBiosGetBiosInfo (OUT PVOID *BiosInfo, OUT ULONG *BiosInfoLength)
BOOLEAN | IopFixupDeviceId (PWCHAR DeviceId)
VOID | IopHardwareProfileBeginTransition (IN BOOLEAN SubsumeExistingDeparture)
VOID | IopHardwareProfileMarkDock (PDEVICE_NODE DeviceNode, PROFILE_STATUS ChangeInPresence)
NTSTATUS | IopHardwareProfileQueryChange (IN BOOLEAN SubsumeExistingDeparture, IN PROFILE_NOTIFICATION_TIME NotificationTime, OUT PPNP_VETO_TYPE VetoType, OUT PUNICODE_STRING VetoName OPTIONAL)
VOID | IopHardwareProfileCommitStartedDock (IN PDEVICE_NODE DeviceNode)
VOID | IopHardwareProfileCommitRemovedDock (IN PDEVICE_NODE DeviceNode)
VOID | IopHardwareProfileCancelRemovedDock (IN PDEVICE_NODE DeviceNode)
VOID | IopHardwareProfileCancelTransition (VOID)
VOID | IopHardwareProfileSetMarkedDocksEjected (VOID)
VOID | IopOrphanNotification (PDEVICE_NODE DeviceNode)
NTSTATUS | IopWarmEjectDevice (IN PDEVICE_OBJECT DeviceToEject, IN SYSTEM_POWER_STATE LightestSleepState)

## Variables

PVOID | IopPnpScratchBuffer1
PVOID | IopPnpScratchBuffer2
PCM_RESOURCE_LIST | IopInitHalResources
PDEVICE_NODE | IopInitHalDeviceNode
PIOP_RESERVED_RESOURCES_RECORD | IopInitReservedResourceList
PDEVICE_NODE | IopRootDeviceNode
PDRIVER_OBJECT | IopPnPDriverObject
KSPIN_LOCK | IopPnPSpinLock
LIST_ENTRY | IopPnpDeleteRequestList
LIST_ENTRY | IopPnpEnumerationRequestList
ERESOURCE | IopDeviceTreeLock
KEVENT | PiEventQueueEmpty
KEVENT | PiEnumerationLock
LONG | IopEnumerationCount
ULONG | IopNumberDeviceNodes
BOOLEAN | PnPInitialized
BOOLEAN | PnPBootDriversInitialized
BOOLEAN | PnPBootDriversLoaded
BOOLEAN | IopBootConfigsReserved
BOOLEAN | IopResourcesReleased
BOOLEAN | PnPDetectionEnabled
INTERFACE_TYPE | PnpDefaultInterfaceType
BOOLEAN | PnpAsyncOk
LIST_ENTRY | IopPendingEjects
LIST_ENTRY | IopPendingSurpriseRemovals
PIO_RESERVE_RESOURCES_ROUTINE | IopReserveResourcesRoutine
ULONG | IopMaxDeviceNodeLevel
ULONG | IoDeviceNodeTreeSequence
FAST_MUTEX | IopDeviceClassNotifyLock
LIST_ENTRY | IopDeviceClassNotifyList []
PSETUP_NOTIFY_DATA | IopSetupNotifyData
FAST_MUTEX | IopTargetDeviceNotifyLock
LIST_ENTRY | IopProfileNotifyList
FAST_MUTEX | IopHwProfileNotifyLock
PBUS_TYPE_GUID_LIST | IopBusTypeGuidList
ARBITER_INSTANCE | IopRootPortArbiter
ARBITER_INSTANCE | IopRootMemArbiter
ARBITER_INSTANCE | IopRootIrqArbiter
ARBITER_INSTANCE | IopRootDmaArbiter
ARBITER_INSTANCE | IopRootBusNumberArbiter
LIST_ENTRY | IopDockDeviceListHead
FAST_MUTEX | IopDockDeviceListLock
ULONG | IopDockDeviceCount
KSEMAPHORE | IopProfileChangeSemaphore
LONG | IopDocksInTransition
KEVENT | IopWarmEjectLock
PDEVICE_OBJECT | IopWarmEjectPdo

## Define Documentation

#define ASSERT_PDO | ( | d |  | ) |

Value:

    do { \
            if (    NULL == (d)->DeviceObjectExtension->DeviceNode || \
                    (((PDEVICE_NODE)(d)->DeviceObjectExtension->DeviceNode)->Flags & DNF_LEGACY_RESOURCE_DEVICENODE))  { \
                KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, PNP_ERR_INVALID_PDO, (ULONG_PTR)d, 0, 0); \
            } \
        } \
        while (0)

Definition at line 357 of file pnpiop.h.

Referenced by IoErrTerminateErrLog(), IoGetDeviceInterfaces(), IoGetDeviceProperty(), IoGetDmaAdapter(), IoInvalidateDeviceRelations(), IoInvalidateDeviceState(), IoReportTargetDeviceChange(), IoReportTargetDeviceChangeAsynchronous(), IoRequestDeviceEject(), and IoSynchronousInvalidateDeviceRelations().

#define BUS_DRIVER_GROUP 1

| Definition at line 673 of file pnpiop.h. Referenced by IopInitializeBootDrivers().

#define CmResourceTypeReserved 0xf0

| Definition at line 803 of file pnpiop.h. Referenced by IopChangeInterfaceType(), IopCmResourcesToIoResources(), IopQueryConflictListInternal(), and IopResourceRequirementsListToReqList().

#define DBG_SCOPE 1

| Definition at line 45 of file pnpiop.h.

#define DEVINSTANCE_FLAG_HWPROFILE_DISABLED 0x1

| Definition at line 906 of file pnpiop.h.

#define DEVINSTANCE_FLAG_PNP_ENUMERATED 0x2

| Definition at line 907 of file pnpiop.h.

#define DNF_ADD_PHASE (DNF_HAS_PROBLEM | DNF_HAS_PRIVATE_PROBLEM | DNF_DEVICE_GONE | DNF_REMOVE_PENDING_CLOSES | DNF_ADDED)

| Definition at line 613 of file pnpiop.h.

#define DNF_ADDED 0x00000040

| Definition at line 408 of file pnpiop.h. Referenced by IopCallDriverAddDevice(), IopCallDriverAddDeviceQueryRoutine(), IopDeleteLockedDeviceNode(), IopDeviceActionWorker(), IopInitializeDeviceInstanceKey(), IopInitializePlugPlayServices(), IopInvalidateRelationsInList(), IopLockDeviceRemovalRelations(), IopNewDevice(), IopProcessAddDevicesWorker(), IopProcessAssignResourcesWorker(), IopProcessStartDevicesWorker(), IopRemoveDevice(), IopRestartDeviceNode(), IopStartAndEnumerateDevice(), IopTestForReconfiguration(), and IoReportDetectedDevice().

#define DNF_ASSIGN_RESOURCE_PHASE

Value:

    (DNF_HAS_PROBLEM | DNF_HAS_PRIVATE_PROBLEM | DNF_DEVICE_GONE | DNF_REMOVE_PENDING_CLOSES | DNF_RESOURCE_ASSIGNED | DNF_RESOURCE_REPORTED |  \
                                           DNF_ASSIGNING_RESOURCES | DNF_NO_RESOURCE_REQUIRED)

Definition at line 623 of file pnpiop.h.

Referenced by IopProcessAssignResourcesWorker().

#define DNF_ASSIGNING_RESOURCES 0x00001000

| Definition at line 447 of file pnpiop.h. Referenced by IopLegacyResourceAllocation(), IopProcessAssignResources(), IopProcessAssignResourcesWorker(), IopQueryRebalanceWorker(), IopReallocateResources(), and IopTestForReconfiguration().

#define DNF_ASYNC_REQUEST_PENDING (DNF_START_REQUEST_PENDING | DNF_ENUMERATION_REQUEST_PENDING)

| Definition at line 621 of file pnpiop.h. Referenced by IopQueryRebalanceWorker(), IopTestForReconfiguration(), and IopWaitForBootDevicesStarted().

#define DNF_BEING_ENUMERATED 0x00400000

| Definition at line 515 of file pnpiop.h. Referenced by IoInvalidateDeviceRelations(), IopDeviceRelationsComplete(), IopEnumerateDevice(), and IopQueryDeviceRelations().

#define DNF_BOOT_CONFIG_RESERVED 0x00000100

| Definition at line 421 of file pnpiop.h. Referenced by IopReleaseDeviceResources(), IopReleaseFilteredBootResources(), IopReleaseResources(), IopReserveBootResourcesInternal(), IopRestartDeviceNode(), and IopTestForReconfiguration().

#define DNF_DEVICE_GONE 0x10000000

| Definition at line 563 of file pnpiop.h. Referenced by IopDeleteLockedDeviceNode(), IopEnumerateDevice(), IopProcessNewChildren(), IopReleaseResources(), and IovpCallDriver2().

#define DNF_DUPLICATE 0x00000002

| Definition at line 376 of file pnpiop.h. Referenced by IopAddDevicesToBootDriverWorker(), IopGetDriverDeviceListWorker(), and IopInitializeDeviceInstanceKey().

#define DNF_ENUMERATED 0x00000010

| Definition at line 396 of file pnpiop.h. Referenced by IopDeleteLockedDeviceNode(), IopDeviceActionWorker(), IopEnumerateDevice(), IopInitializeDeviceInstanceKey(), IopInitializePlugPlayServices(), IopInvalidateRelationsInList(), IopProcessNewChildren(), IopRestartDeviceNode(), IopUnlockDeviceRemovalRelations(), and IoReportDetectedDevice().

#define DNF_ENUMERATION_REQUEST_PENDING 0x01000000

| Definition at line 529 of file pnpiop.h. Referenced by IopDeviceRelationsComplete(), IopEnumerateDevice(), and IopQueryDeviceRelations().

#define DNF_ENUMERATION_REQUEST_QUEUED 0x00800000

| Definition at line 522 of file pnpiop.h. Referenced by IoInvalidateDeviceRelations(), IopQueryDeviceRelations(), and IopRestartDeviceNode().

#define DNF_HAL_NODE 0x00000004

| Definition at line 383 of file pnpiop.h. Referenced by IoBuildPoDeviceNotifyList(), and IoInitSystem().

#define DNF_HAS_BOOT_CONFIG 0x00000080

| Definition at line 415 of file pnpiop.h. Referenced by IopAllocateResources(), IopDeleteLockedDeviceNode(), IopDeviceCapabilitiesToRegistry(), IopInitializeDeviceInstanceKey(), IopProcessNewDeviceNode(), IopReleaseDeviceResources(), IopReleaseResources(), IopReserveLegacyBootResources(), IopRestartDeviceNode(), and IopTestForReconfiguration().

#define DNF_HAS_PRIVATE_PROBLEM 0x04000000

| Definition at line 544 of file pnpiop.h. Referenced by IopDeleteLockedDeviceNode(), and IopQueryDeviceState().

#define DNF_HAS_PROBLEM 0x02000000

| Definition at line 536 of file pnpiop.h. Referenced by IoReportDetectedDevice().

#define DNF_HAS_RESOURCE

Value:

    (DNF_RESOURCE_ASSIGNED | DNF_RESOURCE_REPORTED | \
                                           DNF_NO_RESOURCE_REQUIRED)

Definition at line 625 of file pnpiop.h.

Referenced by IopDeleteLockedDeviceNode(), IopProcessStartDevicesWorker(), IopReallocateResources(), and IopStartAndEnumerateDevice().

#define DNF_IO_INVALIDATE_DEVICE_RELATIONS_PENDING 0x00200000

| Definition at line 508 of file pnpiop.h. Referenced by IoInvalidateDeviceRelations(), IopDeviceRelationsComplete(), and IopQueryDeviceRelations().

#define DNF_LEGACY_DRIVER 0x00080000

| Definition at line 493 of file pnpiop.h. Referenced by IoInitSystem(), IopCallDriverAddDevice(), IopCallDriverAddDeviceQueryRoutine(), IopEliminateBogusConflict(), IopInitializeDeviceInstanceKey(), IopNewDevice(), IopQueryRebalanceWorker(), IopRemoveDevice(), IopTestForReconfiguration(), and IovpAssertNonLegacyDevice().

#define DNF_LEGACY_RESOURCE_DEVICENODE 0x20000000

| Definition at line 570 of file pnpiop.h. Referenced by IoAssignResources(), IopDestroyDeviceNode(), IopFindLegacyDeviceNode(), IoReportResourceForDetection(), and IoReportResourceUsage().

#define DNF_LOCKED_FOR_EJECT 0x80000000

| Definition at line 583 of file pnpiop.h. Referenced by IopInvalidateRelationsInList(), and IopProcessRelation().

#define DNF_MADEUP 0x00000001

| Definition at line 370 of file pnpiop.h. Referenced by IopAssignResourcesToDevices(), IopDeleteLegacyKey(), IopDriverLoadingFailed(), IopFindLegacyDeviceNode(), IopInitializeDeviceInstanceKey(), IopInitializePlugPlayServices(), IopQueryDeviceResources(), IopReleaseDeviceResources(), IopReleaseResources(), IopReserveBootResources(), IopRestartDeviceNode(), IopTestForReconfiguration(), and IoReportDetectedDevice().

#define DNF_NEED_ENUMERATION_ONLY 0x00100000

| Definition at line 500 of file pnpiop.h. Referenced by IopDeviceStartComplete(), IopEnumerateDevice(), IopRemoveDevice(), IopStartAndEnumerateDevice(), IopStartDevice(), and IoReportDetectedDevice().

#define DNF_NEED_QUERY_IDS 0x00000020

| Definition at line 402 of file pnpiop.h. Referenced by IopNewDevice(), IopProcessStartDevicesWorker(), IopRemoveDevice(), IopStartAndEnumerateDevice(), IopStartDriverDevices(), and IoReportDetectedDevice().

#define DNF_NEEDS_REBALANCE 0x40000000

| Definition at line 576 of file pnpiop.h. Referenced by IopAllocateResources(), IopQueryRebalanceWorker(), and IopTestForReconfiguration().

#define DNF_NO_RESOURCE_REQUIRED 0x00000400

| Definition at line 433 of file pnpiop.h. Referenced by IopDeleteLockedDeviceNode(), IopInitializeDeviceInstanceKey(), IopInitializePlugPlayServices(), IopNewDevice(), IopProcessAssignResources(), IopRebalance(), IopResourceRequirementsChanged(), IopRestartDeviceNode(), IopStartAndEnumerateDevice(), and IoReportDetectedDevice().

#define DNF_NON_STOPPED_REBALANCE 0x00010000

| Definition at line 473 of file pnpiop.h. Referenced by IopReallocateResources(), IopRebalance(), IopResourceRequirementsChanged(), and IopTestForReconfiguration().

#define DNF_PROCESSED 0x00000008

| Definition at line 390 of file pnpiop.h. Referenced by IopFindLegacyDeviceNode(), IopInitializeDeviceInstanceKey(), IopInitializePlugPlayServices(), IopInvalidateRelationsInList(), IopProcessNewChildren(), IopProcessNewDeviceNode(), IopRestartDeviceNode(), and IoReportDetectedDevice().

#define DNF_REMOVE_PENDING_CLOSES 0x08000000

| Definition at line 553 of file pnpiop.h. Referenced by IoInvalidateDeviceState(), IopCompleteUnloadOrDelete(), IopDeleteLockedDeviceNode(), IopDeleteLockedDeviceNodes(), IopEnumerateDevice(), IopInvalidateDeviceStateWorker(), IopProcessRelation(), and IopUnlockDeviceRemovalRelations().

#define DNF_RESOURCE_ASSIGNED 0x00002000

| Definition at line 453 of file pnpiop.h. Referenced by IopLegacyResourceAllocation(), IopNewDevice(), IopProcessAssignResources(), IopReallocateResources(), IopRebalance(), IopReleaseResources(), IopRestartDeviceNode(), and IopUnlockDeviceRemovalRelations().

#define DNF_RESOURCE_REPORTED 0x00004000

| Definition at line 459 of file pnpiop.h. Referenced by IopDeleteLockedDeviceNode(), IopLegacyResourceAllocation(), IopNewDevice(), IopProcessAssignResources(), IopReallocateResources(), IopRebalance(), IopReleaseResources(), IopRestartDeviceNode(), and IopStartDevice().

#define DNF_RESOURCE_REQUIREMENTS_CHANGED 0x00008000

| Definition at line 466 of file pnpiop.h. Referenced by IopGetResourceRequirementsForAssignTable(), IopReallocateResources(), IopRebalance(), IopResourceRequirementsChanged(), IopRestartDeviceNode(), and IopTestForReconfiguration().

#define DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED 0x00000800

| Definition at line 440 of file pnpiop.h. Referenced by IopGetResourceRequirementsForAssignTable(), IopProcessNewDeviceNode(), IopQueryDeviceResources(), and IopRestartDeviceNode().

#define DNF_START_PHASE (DNF_HAS_PROBLEM | DNF_HAS_PRIVATE_PROBLEM | DNF_DEVICE_GONE | DNF_REMOVE_PENDING_CLOSES | DNF_STARTED | DNF_START_REQUEST_PENDING)

| Definition at line 619 of file pnpiop.h. Referenced by IopProcessAssignResourcesWorker(), IopProcessStartDevicesWorker(), and IopStartAndEnumerateDevice().

#define DNF_START_REQUEST_PENDING 0x00000200

| Definition at line 427 of file pnpiop.h. Referenced by IopDeviceStartComplete(), and IopStartDevice().

#define DNF_STARTED 0x00040000

| Definition at line 487 of file pnpiop.h. Referenced by IoInitSystem(), IoInvalidateDeviceRelations(), IoInvalidateDeviceState(), IopCallDriverAddDeviceQueryRoutine(), IopDeleteLegacyKey(), IopDeleteLockedDeviceNodes(), IopDeviceActionWorker(), IopDeviceStartComplete(), IopDriverLoadingFailed(), IopEnumerateDevice(), IopFindResourcesForArbiter(), IopInitializeDeviceInstanceKey(), IopInitializePlugPlayServices(), IopInvalidateDeviceStateWorker(), IopProcessNewProfileStateCallback(), IopProcessRelation(), IopProcessStartDevices(), IopRemoveDevice(), IopResourceRequirementsChanged(), IopRestartDeviceNode(), IopStartAndEnumerateDevice(), IopStartDevice(), IopTestForReconfiguration(), IoReportDetectedDevice(), and IoSynchronousInvalidateDeviceRelations().

#define DNF_STOPPED 0x00020000

| Definition at line 480 of file pnpiop.h. Referenced by IopDeviceStartComplete(), IopQueryRebalanceWorker(), IopRebalance(), IopStartDevice(), and IopTestForReconfiguration().

#define DNUF_DONT_SHOW_IN_UI 0x00000002

| Definition at line 595 of file pnpiop.h. Referenced by IopProcessNewDeviceNode(), and IopQueryDeviceState().

#define DNUF_NEED_RESTART 0x00000004

| Definition at line 602 of file pnpiop.h. Referenced by IopRestartDeviceNode().

#define DNUF_NOT_DISABLEABLE 0x00000008

| Definition at line 610 of file pnpiop.h. Referenced by IopDestroyDeviceNode(), IopQueryDeviceState(), and IopRemoveDevice().

#define DNUF_WILL_BE_REMOVED 0x00000001

| Definition at line 589 of file pnpiop.h. Referenced by IopRestartDeviceNode().

#define FIELD_SIZE | ( | type,
|  | field |  | ) | (sizeof(((type *)0)->field))

| Definition at line 1867 of file pnpiop.h. Referenced by IopDeviceCapabilitiesToRegistry().

#define FUNCTIONSUBKEY_FLAG_DELETE_SUBKEYS 0x2

| Definition at line 914 of file pnpiop.h. Referenced by IopApplyFunctionToSubKeys(), and IopDeleteKeyRecursiveCallback().

#define FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS 0x1

| Definition at line 913 of file pnpiop.h. Referenced by IopApplyFunctionToSubKeys(), IopDeleteKeyRecursiveCallback(), IopGetRootDevices(), and IopInitializeDeviceKey().

#define IOP_ASSIGN_CLEAR_RESOURCE_REQUIREMENTS_CHANGE_FLAG 0x00000400

| Definition at line 761 of file pnpiop.h. Referenced by IopGetResourceRequirementsForAssignTable(), and IopRebalance().

#define IOP_ASSIGN_EXCLUDE 0x00000010

| Definition at line 755 of file pnpiop.h. Referenced by IopAllocateResources(), IopAssign(), IopBuildCmResourceLists(), IopIsBestConfiguration(), IopRebalance(), IopReleaseFilteredBootResources(), IopRestoreBestConfiguration(), and IopSaveCurrentConfiguration().

#define IOP_ASSIGN_IGNORE 0x00000020

| Definition at line 756 of file pnpiop.h. Referenced by IopAllocateResources(), IopBuildCmResourceLists(), IopGetResourceRequirementsForAssignTable(), and IopRebalance().

#define IOP_ASSIGN_KEEP_CURRENT_CONFIG 0x00000200

| Definition at line 759 of file pnpiop.h. Referenced by IopFreeResourceRequirementsForAssignTable(), IopGetResourceRequirementsForAssignTable(), and IopReallocateResources().

#define IOP_ASSIGN_NO_REBALANCE 0x00000080

| Definition at line 757 of file pnpiop.h. Referenced by IopAllocateResources(), IopLegacyResourceAllocation(), and IopReallocateResources().

#define IOP_ASSIGN_RESOURCES_RELEASED 0x00000100

| Definition at line 758 of file pnpiop.h. Referenced by IopRebalance().

#define IOP_ASSIGN_RETRY 0x00000008

| Definition at line 754 of file pnpiop.h. Referenced by IopAllocateResources(), and IopBuildCmResourceLists().

#define IOP_DNDT_TAG 'tdnD'

| Definition at line 38 of file pnpiop.h.

#define IOP_DNOD_TAG 'donD'

| Definition at line 37 of file pnpiop.h. Referenced by IopAllocateDeviceNode().

#define IOP_DPWR_TAG 'rwPD'

| Definition at line 39 of file pnpiop.h. Referenced by IoBuildPoDeviceNotifyList(), and IopCaptureObjectName().

#define IopAcquireDeviceTreeLock | (

)

ExAcquireResourceExclusive(&IopDeviceTreeLock, TRUE)

| Definition at line 1293 of file pnpiop.h. Referenced by IoBuildPoDeviceNotifyList(), IopChainDereferenceComplete(), IopDeviceActionWorker(), IopLockDeviceRemovalRelations(), IopProcessCompletedEject(), IopQueuePendingEject(), IopQueuePendingSurpriseRemoval(), and IopWarmEjectDevice().

#define IopAcquireEnumerationLock | ( | _devnode_ |  | ) |

Value:

    ExAcquireResourceShared(&IopDeviceTreeLock, TRUE);              \
        if ((_devnode_)) {                                              \
            KeWaitForSingleObject( &((PDEVICE_NODE)(_devnode_))->EnumerationMutex,      \
                                   Executive,                           \
                                   KernelMode,                          \
                                   FALSE,                               \
                                   NULL );                              \
        }

Definition at line 1266 of file pnpiop.h.

Referenced by IoGetLegacyVetoList(), IopDeviceActionWorker(), IopEnumerateDevice(), IopForAllDeviceNodes(), IopForAllDeviceNodesCallback(), IopGetDevicePDO(), IopProcessAddDevices(), IopProcessAddDevicesWorker(), IopProcessAssignResources(), IopProcessAssignResourcesWorker(), IopQueryDeviceRelations(), IopReallocateResources(), IopSetDeviceSecurityDescriptors(), and IopStartDevice().

#define IopAcquireNotifyLock | ( | Lock |  | ) | ExAcquireFastMutex(Lock);

| Definition at line 2053 of file pnpiop.h. Referenced by IopNotifyDeviceClassChange(), IopNotifyHwProfileChange(), IopNotifyTargetDeviceChange(), IopOrphanNotification(), IopProcessDeferredRegistrations(), IoRegisterPlugPlayNotification(), and IoUnregisterPlugPlayNotification().

#define IopClearDevNodeProblem | ( | devnode |  | ) |

Value:

    (devnode)->Flags &= ~DNF_HAS_PROBLEM;                       \
            (devnode)->Problem = 0;

Definition at line 831 of file pnpiop.h.

Referenced by IopCallDriverAddDevice(), IopDeleteLockedDeviceNode(), IopDisableDevice(), IopInitializeDeviceInstanceKey(), IopInvalidateRelationsInList(), IopNotifySetupDevices(), IopProcessAssignResourcesWorker(), IopProcessCriticalDevice(), IopProcessNewDeviceNode(), IopProcessNewProfileStateCallback(), and IopResourceRequirementsChanged().

#define IopCompareGuid | ( | g1,
|  | g2 |  | ) |

Value:

    ( (g1) == (g2) \
                                        ? TRUE \
                                        : RtlCompareMemory( (g1), (g2), sizeof(GUID) ) == sizeof(GUID) \
                                        )

Definition at line 2070 of file pnpiop.h.

Referenced by IopGetBusTypeGuidIndex(), IopNotifyDeviceClassChange(), IopNotifyHwProfileChange(), IopNotifyTargetDeviceChange(), IopPnPDispatch(), IopRequestHwProfileChangeNotification(), IoReportTargetDeviceChange(), and IoReportTargetDeviceChangeAsynchronous().

#define IopConstStringLength | ( | String |  | ) | ( ( sizeof(String) - sizeof(UNICODE_NULL) ) / sizeof(WCHAR) )

| Definition at line 1994 of file pnpiop.h. Referenced by IopParseSymbolicLinkName().

#define IopConstStringSize | ( | String |  | ) | ( sizeof(String) - sizeof(UNICODE_NULL) )

| Definition at line 1983 of file pnpiop.h. Referenced by IoGetDeviceInterfaceAlias(), IopBuildSymbolicLinkStrings(), IopOpenOrCreateDeviceInterfaceSubKeys(), IopParseSymbolicLinkName(), and IopUnregisterDeviceInterface().

#define IopDeviceNodeFlagsToCapabilities | ( | DeviceNode |  | ) |

Value:

    ((PDEVICE_CAPABILITIES) (((PUCHAR) (&(DeviceNode)->CapabilityFlags)) - \
                                  FIELD_OFFSET(DEVICE_CAPABILITIES, Version) - \
                                  FIELD_SIZE(DEVICE_CAPABILITIES, Version)))

Definition at line 1870 of file pnpiop.h.

Referenced by IopCallDriverAddDevice(), IopGetLegacyVetoListDevice(), and IopInitializeDeviceInstanceKey().

#define IopDoesDevNodeHaveProblem | ( | devnode |  | ) | ((devnode)->Flags & (DNF_HAS_PROBLEM | DNF_HAS_PRIVATE_PROBLEM))

| Definition at line 825 of file pnpiop.h. Referenced by IopCallDriverAddDeviceQueryRoutine(), IopDeleteLegacyKey(), IopDeleteLockedDeviceNode(), IopDeviceActionWorker(), IopDisableDevice(), IopGetDriverDeviceListWorker(), IopInitializeDeviceInstanceKey(), IopProcessCriticalDevice(), IopProcessNewDeviceNode(), IopQueryRebalanceWorker(), IopRestartDeviceNode(), IopStartDevice(), IopTestForReconfiguration(), IopUnlockDeviceRemovalRelations(), and IoReportDetectedDevice().

#define IopHashGuid | ( | _Guid |  | ) |

Value:

    ( ( ((PULONG)_Guid)[0] + ((PULONG)_Guid)[1] + ((PULONG)_Guid)[2] \
                    + ((PULONG)_Guid)[3]) % NOTIFY_DEVICE_CLASS_HASH_BUCKETS)

Definition at line 2040 of file pnpiop.h.

Referenced by IopNotifyDeviceClassChange(), and IoRegisterPlugPlayNotification().

#define IopIsDevNodeProblem | ( | devnode,
|  | problem |  | ) | (((devnode)->Flags & DNF_HAS_PROBLEM) && (devnode)->Problem == (problem))

| Definition at line 828 of file pnpiop.h. Referenced by IopDeleteLockedDeviceNode(), IopDisableDevice(), IopInitializeDeviceInstanceKey(), IopIsAnyDeviceInstanceEnabled(), IopIsDeviceInstanceEnabled(), IopNotifySetupDevices(), IopProcessAssignResourcesWorker(), IopProcessCriticalDevice(), IopProcessNewDeviceNode(), and IopProcessNewProfileStateCallback().

#define IopIsProblemReadonly | ( | problem |  | ) |

Value:

    ((problem) != CM_PROB_FAILED_INSTALL      && \
         (problem) != CM_PROB_FAILED_ADD          && \
         (problem) != CM_PROB_FAILED_START        && \
         (problem) != CM_PROB_NOT_CONFIGURED      && \
         (problem) != CM_PROB_NEED_RESTART        && \
         (problem) != CM_PROB_REINSTALL           && \
         (problem) != CM_PROB_REGISTRY            && \
         (problem) != CM_PROB_DISABLED)

Definition at line 842 of file pnpiop.h.

#define IopKMToUMSymbolicLinkName | ( | String |  | ) |

Value:

    ASSERT(String) \
        ASSERT(String->Length > 4) \
        String[1] = L'\\'

Definition at line 2008 of file pnpiop.h.

#define IopRegistryDataToUnicodeString | ( | u,
|  | p,
|  | l |  | ) |

Value:

    {                                            \
            ULONG len;                               \
                                                     \
            PiRegSzToString((p), (l), &len, NULL);   \
            (u)->Length = (USHORT)len;               \
            (u)->MaximumLength = (USHORT)(l);        \
            (u)->Buffer = (p);                       \
        }

Definition at line 862 of file pnpiop.h.

Referenced by IoGetDeviceInterfaceAlias(), IopApplyFunctionToServiceInstances(), IopCallDriverAddDevice(), IopCreateMadeupNode(), IopGetDriverTagPriority(), IopGetGroupOrderIndex(), IopInitializeDeviceInstanceKey(), IopProcessSetInterfaceState(), IopRemoveDeviceInterfaces(), and IopServiceInstanceToDeviceInstance().

#define IopReleaseDeviceTreeLock | (

)

ExReleaseResource(&IopDeviceTreeLock)

| Definition at line 1294 of file pnpiop.h. Referenced by IoFreePoDeviceNotifyList(), IopChainDereferenceComplete(), IopDeviceActionWorker(), IopLockDeviceRemovalRelations(), IopProcessCompletedEject(), IopQueuePendingEject(), IopQueuePendingSurpriseRemoval(), and IopWarmEjectDevice().

#define IopReleaseEnumerationLock | ( | _devnode_ |  | ) |

Value:

    if ((_devnode_)) {                                              \
            KeSetEvent( &((PDEVICE_NODE)(_devnode_))->EnumerationMutex, \
                        0,                                              \
                        FALSE );                                        \
        }                                                               \
        ExReleaseResource(&IopDeviceTreeLock);

Definition at line 1276 of file pnpiop.h.

Referenced by IoGetLegacyVetoList(), IopDeviceActionWorker(), IopEnumerateDevice(), IopForAllDeviceNodes(), IopForAllDeviceNodesCallback(), IopGetDevicePDO(), IopProcessAddDevices(), IopProcessAddDevicesWorker(), IopProcessAssignResources(), IopProcessAssignResourcesWorker(), IopProcessStartDevices(), IopReallocateResources(), and IopSetDeviceSecurityDescriptors().

#define IopReleaseEnumerationLockForThread | ( | _devnode_,
|  | _thread_ |  | ) |

Value:

    if ((_devnode_)) {                                              \
            KeSetEvent( &((PDEVICE_NODE)(_devnode_))->EnumerationMutex, \
                        0,                                              \
                        FALSE );                                        \
        }                                                               \
        ExReleaseResourceForThreadLite(&IopDeviceTreeLock, _thread_);

Definition at line 1285 of file pnpiop.h.

Referenced by IopDeviceRelationsComplete(), and IopDeviceStartComplete().

#define IopReleaseNotifyLock | ( | Lock |  | ) | ExReleaseFastMutex(Lock);

| Definition at line 2061 of file pnpiop.h. Referenced by IopNotifyDeviceClassChange(), IopNotifyHwProfileChange(), IopNotifyTargetDeviceChange(), IopOrphanNotification(), IopProcessDeferredRegistrations(), IoRegisterPlugPlayNotification(), and IoUnregisterPlugPlayNotification().

#define IopSetDevNodeProblem | ( | devnode,
|  | problem |  | ) |

Value:

    ASSERT(((devnode)->Flags & DNF_PROCESSED) || !((devnode)->Flags & DNF_ENUMERATED)); \
            ASSERT(!((devnode)->Flags & (DNF_STARTED | DNF_HAS_PROBLEM | DNF_HAS_PRIVATE_PROBLEM))); \
            ASSERT(problem != 0); \
            (devnode)->Flags |= DNF_HAS_PROBLEM;                        \
            (devnode)->Problem = (problem);

Definition at line 835 of file pnpiop.h.

Referenced by IopCallDriverAddDevice(), IopCallDriverAddDeviceQueryRoutine(), IopDeleteLegacyKey(), IopDeleteLockedDeviceNode(), IopDeviceStartComplete(), IopDisableDevice(), IopDriverLoadingFailed(), IopInitializeDeviceInstanceKey(), IopNewDevice(), IopProcessAssignResources(), IopProcessNewDeviceNode(), IopStartDevice(), and IoReportDetectedDevice().

#define IopUMToKMSymbolicLinkName | ( | String |  | ) |

Value:

    ASSERT(String) \
        ASSERT(String->Length > 4) \
        String[1] = L'?'

Definition at line 2020 of file pnpiop.h.

#define KEY_VALUE_DATA | ( | k |  | ) | ((PCHAR)(k) + (k)->DataOffset)

| Definition at line 813 of file pnpiop.h. Referenced by IoGetDeviceInterfaceAlias(), IoGetDeviceProperty(), IoOpenDeviceRegistryKey(), IopAppendStringToValueKey(), IopApplyFunctionToServiceInstances(), IopCallDriverAddDevice(), IopCallDriverAddDeviceQueryRoutine(), IopCreateMadeupNode(), IopDeleteLegacyKey(), IopDeviceObjectFromDeviceInstance(), IopDriverLoadingFailed(), IopGetDeviceInstanceCsConfigFlags(), IopGetDeviceInterfaces(), IopGetDeviceResourcesFromRegistry(), IopGetDriverDeviceList(), IopGetDriverTagPriority(), IopGetGroupOrderIndex(), IopGetServiceInstanceCsConfigFlags(), IopGetServiceType(), IopInitializeDeviceInstanceKey(), IopInitializePlugPlayServices(), IopInitializeSystemDrivers(), IopIsAnyDeviceInstanceEnabled(), IopIsDeviceInstanceEnabled(), IopIsFirmwareMapperDevicePresent(), IopIsReportedAlready(), IopPrepareDriverLoading(), IopProcessCriticalDeviceRoutine(), IopProcessSetInterfaceState(), IopReadDeviceConfiguration(), IopRegMultiSzToUnicodeStrings(), IopRemoveDeviceInterfaces(), IopRemoveStringFromValueKey(), IopServiceInstanceToDeviceInstance(), and IopUnregisterDeviceInterface().

#define NO_MORE_GROUP ((USHORT) -1)

| Definition at line 671 of file pnpiop.h. Referenced by IopBusCheck(), IopDeviceActionWorker(), IopGetGroupOrderIndex(), IopInitializeBootDrivers(), IopInitializeSystemDrivers(), IopNewDevice(), and IopProcessAddDevices().

#define NOTIFY_DEVICE_CLASS_HASH_BUCKETS 13

| Definition at line 2360 of file pnpiop.h. Referenced by IopInitializePlugPlayNotification().

#define OK_TO_ADD_DEVICE | ( | _devnode_ |  | ) |

Value:

    ( (_devnode_)->Flags & DNF_PROCESSED     &&                     \
          !((_devnode_)->Flags & DNF_ADD_PHASE) )

Definition at line 615 of file pnpiop.h.

Referenced by IopAddDevicesToBootDriverWorker(), IopCallDriverAddDevice(), IopCallDriverAddDeviceQueryRoutine(), IopProcessAddDevicesWorker(), and IopProcessNewChildren().

#define PI_ARBITER_HAS_SOMETHING 1

| Definition at line 722 of file pnpiop.h. Referenced by IopAddReqDescsToArbiters(), IopArbitrateDeviceResources(), IopPlacement(), and IopRemoveReqDescsFromArbiters().

#define PI_ARBITER_TEST_FAILED 2

| Definition at line 723 of file pnpiop.h. Referenced by IopArbitrateDeviceResources(), and IopPlacement().

#define PI_MAXIMUM_RESOURCE_TYPE_TRACKED 15

| Definition at line 698 of file pnpiop.h. Referenced by IopFindResourceHandlerInfo(), and IopSetupArbiterAndTranslators().

#define PLUGPLAY_REGKEY_CURRENT_HWPROFILE 4

| Definition at line 922 of file pnpiop.h.

#define PLUGPLAY_REGKEY_DEVICE 1

| Definition at line 920 of file pnpiop.h.

#define PLUGPLAY_REGKEY_DRIVER 2

| Definition at line 921 of file pnpiop.h.

#define PNP_ASSERT | ( | condition,
|  | message |  | ) |

| Definition at line 885 of file pnpiop.h.

#define PNP_DETECTION_ENABLED_DEFAULT TRUE

| Definition at line 893 of file pnpiop.h. Referenced by IopInitializePlugPlayServices().

#define PNP_ERR_ACTIVE_PDO_FREED 5

| Definition at line 635 of file pnpiop.h. Referenced by IopDestroyDeviceNode().

#define PNP_ERR_BOGUS_ID 3

| Definition at line 633 of file pnpiop.h. Referenced by IopProcessNewDeviceNode(), and IopStartAndEnumerateDevice().

#define PNP_ERR_DEVICE_MISSING_FROM_EJECT_LIST 6

| Definition at line 637 of file pnpiop.h. Referenced by IopProcessRelation().

#define PNP_ERR_DUPLICATE_PDO 1

| Definition at line 631 of file pnpiop.h. Referenced by IopProcessNewDeviceNode().

#define PNP_ERR_INVALID_PDO 2

| Definition at line 632 of file pnpiop.h. Referenced by IoAssignResources(), IoReportResourceForDetection(), and IoReportResourceUsage().

#define PNP_ERR_PDO_ENUMERATED_AFTER_DELETION 4

| Definition at line 634 of file pnpiop.h. Referenced by IopEnumerateDevice().

#define PNP_ERR_UNEXPECTED_ADD_RELATION_ERR 7

| Definition at line 638 of file pnpiop.h. Referenced by IopProcessRelation().

#define PNP_LARGE_SCRATCH_BUFFER_SIZE (PNP_SCRATCH_BUFFER_SIZE * 8)

| Definition at line 900 of file pnpiop.h. Referenced by IopDetermineDefaultInterfaceType(), IopGetRootDevices(), and IopInitializePlugPlayServices().

#define PNP_NOTIFICATION_VERSION 1

| Definition at line 2359 of file pnpiop.h. Referenced by IopNotifyDeviceClassChange(), IopNotifyHwProfileChange(), IopNotifySetupDeviceArrival(), IopNotifyTargetDeviceChange(), and IoRegisterPlugPlayNotification().

#define PNP_SCRATCH_BUFFER_SIZE 512

| Definition at line 899 of file pnpiop.h. Referenced by IopApplyFunctionToServiceInstances(), IopGetRootDevices(), and IopInitializeDeviceInstanceKey().

#define QUERY_RESOURCE_LIST 0

| Definition at line 740 of file pnpiop.h. Referenced by IopGetDeviceResourcesFromRegistry(), IopInitializeDeviceInstanceKey(), IopPnPDispatch(), IopProcessNewDeviceNode(), IopQueryDeviceResources(), and IopReleaseDeviceResources().

#define QUERY_RESOURCE_REQUIREMENTS 1

| Definition at line 741 of file pnpiop.h. Referenced by IopGetResourceRequirementsForAssignTable(), IopPnPDispatch(), and IopQueryDeviceResources().

#define REGISTRY_ALLOC_CONFIG 1

| Definition at line 743 of file pnpiop.h. Referenced by IopGetDeviceResourcesFromRegistry(), IopQueryDeviceResources(), and IopReadDeviceConfiguration().

#define REGISTRY_BASIC_CONFIGVECTOR 2

| Definition at line 747 of file pnpiop.h. Referenced by IopGetDeviceResourcesFromRegistry(), IopPnPDispatch(), and IopQueryDeviceResources().

#define REGISTRY_BOOT_CONFIG 4

| Definition at line 745 of file pnpiop.h. Referenced by IopGetDeviceResourcesFromRegistry(), IopInitializeDeviceInstanceKey(), IopPnPDispatch(), IopQueryDeviceResources(), and IopReadDeviceConfiguration().

#define REGISTRY_FORCED_CONFIG 2

| Definition at line 744 of file pnpiop.h. Referenced by IopGetDeviceResourcesFromRegistry(), IopQueryDeviceResources(), and IopReadDeviceConfiguration().

#define REGISTRY_OVERRIDE_CONFIGVECTOR 1

| Definition at line 746 of file pnpiop.h. Referenced by IopGetDeviceResourcesFromRegistry(), and IopQueryDeviceResources().

#define SAVE_FAILURE_INFO | ( | DeviceNode,
|  | Status |  | ) | (DeviceNode)->FailureStatus = (Status)

| Definition at line 820 of file pnpiop.h. Referenced by IopDeviceStartComplete(), and IopStartDevice().

#define SETUP_RESERVED_GROUP 0

| Definition at line 672 of file pnpiop.h. Referenced by IopInitializeBootDrivers().

#define TITLE_INDEX_VALUE 0

| Definition at line 876 of file pnpiop.h.

## Typedef Documentation

typedef struct _ADD_CONTEXT ADD_CONTEXT

typedef struct _BUFFER_INFO BUFFER_INFO

| Referenced by IopProcessCriticalDeviceRoutine().

typedef struct _BUS_TYPE_GUID_LIST BUS_TYPE_GUID_LIST

| Referenced by IopGetBusTypeGuidIndex(), and IopInitializePlugPlayServices().

typedef struct _DEVICE_CLASS_NOTIFY_ENTRY DEVICE_CLASS_NOTIFY_ENTRY

| Referenced by IoRegisterPlugPlayNotification().

typedef struct _DEVICE_NODE DEVICE_NODE

| Referenced by IopAllocateDeviceNode().

typedef enum _DEVICE_REQUEST_TYPE DEVICE_REQUEST_TYPE

| Referenced by IopRequestDeviceAction().

typedef enum _HARDWARE_PROFILE_BUS_TYPE HARDWARE_PROFILE_BUS_TYPE

typedef struct _HWPROFILE_NOTIFY_ENTRY HWPROFILE_NOTIFY_ENTRY

| Referenced by IoRegisterPlugPlayNotification().

typedef struct _IOP_RESOURCE_REQUEST IOP_RESOURCE_REQUEST

| Referenced by IopProcessAssignResources(), and IopRebalance().

typedef struct _IOPNP_DEVICE_EXTENSION IOPNP_DEVICE_EXTENSION

| Referenced by IopInitializePlugPlayServices().

typedef struct _NEW_DEVICE_WORK_ITEM NEW_DEVICE_WORK_ITEM

typedef struct _NOTIFY_ENTRY_HEADER NOTIFY_ENTRY_HEADER

typedef struct _ADD_CONTEXT * PADD_CONTEXT

| Referenced by IopProcessAddDevicesWorker().

typedef struct _BUFFER_INFO * PBUFFER_INFO

typedef struct _BUS_TYPE_GUID_LIST * PBUS_TYPE_GUID_LIST

typedef struct _DEVICE_CLASS_NOTIFY_ENTRY * PDEVICE_CLASS_NOTIFY_ENTRY

| Referenced by IopNotifyDeviceClassChange().

typedef struct _DEVICE_NODE* PDEVICE_NODE

| Definition at line 86 of file pnpiop.h.

typedef struct _PENDING_SET_INTERFACE_STATE PENDING_SET_INTERFACE_STATE

| Referenced by IopProcessSetInterfaceState().

typedef NTSTATUS(* PENUM_CALLBACK)(IN PDEVICE_NODE DeviceNode, IN PVOID Context)

| Definition at line 642 of file pnpiop.h. Referenced by IopForAllDeviceNodes().

typedef enum _HARDWARE_PROFILE_BUS_TYPE * PHARDWARE_PROFILE_BUS_TYPE

typedef struct _HWPROFILE_NOTIFY_ENTRY * PHWPROFILE_NOTIFY_ENTRY

| Referenced by IopNotifyHwProfileChange().

typedef struct _PI_DEVICE_REQUEST PI_DEVICE_REQUEST

| Referenced by IopRequestDeviceAction().

typedef struct _PI_RESOURCE_ARBITER_ENTRY PI_RESOURCE_ARBITER_ENTRY

typedef struct _PI_RESOURCE_TRANSLATOR_ENTRY PI_RESOURCE_TRANSLATOR_ENTRY

typedef NTSTATUS(* PIO_RESERVE_RESOURCES_ROUTINE)(IN ARBITER_REQUEST_SOURCE ArbiterRequestSource, IN PDEVICE_OBJECT DeviceObject, IN PCM_RESOURCE_LIST BootResources)

| Definition at line 1877 of file pnpiop.h.

typedef struct _IOP_RESERVED_RESOURCES_RECORD IOP_RESERVED_RESOURCES_RECORD* PIOP_RESERVED_RESOURCES_RECORD

| Definition at line 937 of file pnpiop.h. Referenced by IopReserveBootResources(), and IopReserveLegacyBootResources().

typedef struct _IOP_RESOURCE_REQUEST * PIOP_RESOURCE_REQUEST

typedef BOOLEAN(* PIOP_SUBKEY_CALLBACK_ROUTINE)(IN HANDLE, IN PUNICODE_STRING, IN OUT PVOID)

| Definition at line 661 of file pnpiop.h.

typedef struct _IOPNP_DEVICE_EXTENSION * PIOPNP_DEVICE_EXTENSION

| Referenced by IopPnPDispatch().

typedef struct _NEW_DEVICE_WORK_ITEM * PNEW_DEVICE_WORK_ITEM

| Referenced by IopDeviceActionWorker().

typedef struct _NOTIFY_ENTRY_HEADER * PNOTIFY_ENTRY_HEADER

typedef struct _PENDING_SET_INTERFACE_STATE * PPENDING_SET_INTERFACE_STATE

| Referenced by IopDestroyDeviceNode(), and IopDoDeferredSetInterfaceState().

typedef struct _PI_DEVICE_REQUEST * PPI_DEVICE_REQUEST

| Referenced by IopRequestDeviceAction().

typedef struct _PI_RESOURCE_ARBITER_ENTRY * PPI_RESOURCE_ARBITER_ENTRY

typedef struct _PI_RESOURCE_TRANSLATOR_ENTRY * PPI_RESOURCE_TRANSLATOR_ENTRY

| Referenced by IopDestroyDeviceNode().

typedef struct _SETUP_NOTIFY_DATA * PSETUP_NOTIFY_DATA

typedef struct _START_CONTEXT * PSTART_CONTEXT

typedef struct _TARGET_DEVICE_NOTIFY_ENTRY * PTARGET_DEVICE_NOTIFY_ENTRY

| Referenced by IopDereferenceNotify().

typedef enum _UNLOCK_UNLINK_ACTION * PUNLOCK_UNLINK_ACTION

typedef enum _RESOURCE_HANDLER_TYPE RESOURCE_HANDLER_TYPE

typedef struct _SETUP_NOTIFY_DATA SETUP_NOTIFY_DATA

| Referenced by IoRegisterPlugPlayNotification().

typedef struct _START_CONTEXT START_CONTEXT

| Referenced by IopInitializeBootDrivers().

typedef struct _TARGET_DEVICE_NOTIFY_ENTRY TARGET_DEVICE_NOTIFY_ENTRY

| Referenced by IoRegisterPlugPlayNotification().

typedef enum _UNLOCK_UNLINK_ACTION UNLOCK_UNLINK_ACTION

| Referenced by IopUnlockDeviceRemovalRelations().

## Enumeration Type Documentation

enum _DEVICE_REQUEST_TYPE

Enumeration values:

  ReenumerateDeviceTree |
  ReenumerateDeviceOnly |
  ReenumerateBootDevices |
  RestartEnumeration |
  AssignResources |
  ResourceRequirementsChanged |
  StartDevice |
  ReenumerateRootDevices |

Definition at line 784 of file pnpiop.h.

    00784                                   {
    00785     ReenumerateDeviceTree,
    00786     ReenumerateDeviceOnly,
    00787     ReenumerateBootDevices,
    00788     RestartEnumeration,
    00789     AssignResources,
    00790     ResourceRequirementsChanged,
    00791     StartDevice,
    00792     ReenumerateRootDevices
    00793 } DEVICE_REQUEST_TYPE;

enum _HARDWARE_PROFILE_BUS_TYPE

Enumeration values:

  HardwareProfileBusTypeACPI |

Definition at line 2530 of file pnpiop.h.

    02530                                         {
    02531     HardwareProfileBusTypeACPI
    02532 } HARDWARE_PROFILE_BUS_TYPE, * PHARDWARE_PROFILE_BUS_TYPE;

enum _RESOURCE_HANDLER_TYPE

Enumeration values:

  ResourceHandlerNull |
  ResourceTranslator |
  ResourceArbiter |
  ResourceLegacyDeviceDetection |

Definition at line 691 of file pnpiop.h.

    00691                                     {
    00692     ResourceHandlerNull,
    00693     ResourceTranslator,
    00694     ResourceArbiter,
    00695     ResourceLegacyDeviceDetection
    00696 } RESOURCE_HANDLER_TYPE;

enum _UNLOCK_UNLINK_ACTION

Enumeration values:

  UnlinkRemovedDeviceNodes |
  UnlinkAllDeviceNodesPendingClose |
  UnlinkOnlyChildDeviceNodesPendingClose |

Definition at line 80 of file pnpiop.h.

    00080                                    {
    00081     UnlinkRemovedDeviceNodes,
    00082     UnlinkAllDeviceNodesPendingClose,
    00083     UnlinkOnlyChildDeviceNodesPendingClose
    00084 }   UNLOCK_UNLINK_ACTION, *PUNLOCK_UNLINK_ACTION;

enum PROFILE_NOTIFICATION_TIME

Enumeration values:

  PROFILE_IN_PNPEVENT |
  PROFILE_NOT_IN_PNPEVENT |
  PROFILE_PERHAPS_IN_PNPEVENT |

Definition at line 65 of file pnpiop.h.

    00065              {
    00066
    00067     PROFILE_IN_PNPEVENT,
    00068     PROFILE_NOT_IN_PNPEVENT,
    00069     PROFILE_PERHAPS_IN_PNPEVENT
    00070
    00071 } PROFILE_NOTIFICATION_TIME;

enum PROFILE_STATUS

Enumeration values:

  DOCK_NOTDOCKDEVICE |
  DOCK_QUIESCENT |
  DOCK_ARRIVING |
  DOCK_DEPARTING |
  DOCK_EJECTIRP_COMPLETED |

Definition at line 55 of file pnpiop.h.

    00055              {
    00056
    00057     DOCK_NOTDOCKDEVICE,
    00058     DOCK_QUIESCENT,
    00059     DOCK_ARRIVING,
    00060     DOCK_DEPARTING,
    00061     DOCK_EJECTIRP_COMPLETED
    00062
    00063 } PROFILE_STATUS;

## Function Documentation

NTSTATUS EisaBuildEisaDeviceNode | ( | VOID |  | ) |

Definition at line 59 of file pnpeisa.c.

References BUFFER_LENGTH, EISA_DEVICE_NODE_NAME, EisaGetEisaDevicesResources(), ExFreePool(), IopCreateRegistryKeyEx(), IopOpenRegistryKeyEx(), L, NT_SUCCESS, NTSTATUS(), NULL, RtlInitUnicodeString(), and TITLE_INDEX_VALUE.

Referenced by IopInitializePlugPlayServices().

    00065                    :
    00066
    00067     This routine build an registry key to report eisa resources to arbiters.
    00068
    00069 Arguments:
    00070
    00071     None.
    00072
    00073 Return Value:
    00074
    00075     NTSTATUS code.
    00076
    00077 --*/
    00078
    00079 {
    00080     NTSTATUS            status;
    00081     ULONG               disposition, tmpValue;
    00082     WCHAR               buffer[BUFFER_LENGTH];
    00083
    00084     UNICODE_STRING      unicodeString;
    00085     HANDLE              rootHandle, deviceHandle, instanceHandle, logConfHandle;
    00086
    00087     PCM_RESOURCE_LIST   resourceList;
    00088     ULONG               resourceLength;
    00089
    00090     status = EisaGetEisaDevicesResources(&resourceList, &resourceLength);
    00091     if (!NT_SUCCESS(status) || resourceList == NULL) {
    00092         return STATUS_UNSUCCESSFUL;
    00093     }
    00094
    00095     RtlInitUnicodeString(&unicodeString, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\Root");
    00096     status = IopOpenRegistryKeyEx( &rootHandle,
    00097                                    NULL,
    00098                                    &unicodeString,
    00099                                    KEY_ALL_ACCESS
    00100                                    );
    00101
    00102     if (!NT_SUCCESS(status)) {
    00103         if (resourceList) {
    00104             ExFreePool (resourceList);
    00105         }
    00106         return status;
    00107     }
    00108
    00109     RtlInitUnicodeString(&unicodeString, EISA_DEVICE_NODE_NAME);
    00110     status = IopCreateRegistryKeyEx( &deviceHandle,
    00111                                      rootHandle,
    00112                                      &unicodeString,
    00113                                      KEY_ALL_ACCESS,
    00114                                      REG_OPTION_NON_VOLATILE,
    00115                                      NULL
    00116                                      );
    00117
    00118     ZwClose(rootHandle);
    00119     if (!NT_SUCCESS(status)) {
    00120         if (resourceList) {
    00121             ExFreePool (resourceList);
    00122         }
    00123         return status;
    00124     }
    00125
    00126     RtlInitUnicodeString( &unicodeString, L"0000" );
    00127     status = IopCreateRegistryKeyEx( &instanceHandle,
    00128                                      deviceHandle,
    00129                                      &unicodeString,
    00130                                      KEY_ALL_ACCESS,
    00131                                      REG_OPTION_NON_VOLATILE,
    00132                                      &disposition );
    00133     ZwClose(deviceHandle);
    00134     if (NT_SUCCESS(status))  {
    00135         if (disposition == REG_CREATED_NEW_KEY) {
    00136
    00137             RtlInitUnicodeString( &unicodeString, L"DeviceDesc" );
    00138             swprintf(buffer, L"%s", L"Device to report Eisa Slot Resources");
    00139
    00140             ZwSetValueKey(instanceHandle,
    00141                           &unicodeString,
    00142                           0,
    00143                           REG_SZ,
    00144                           buffer,
    00145                           (wcslen(buffer) + 1) * sizeof(WCHAR)
    00146                           );
    00147
    00148             RtlInitUnicodeString( &unicodeString, L"HardwareID" );
    00149             RtlZeroMemory(buffer, BUFFER_LENGTH * sizeof(WCHAR));
    00150             swprintf(buffer, L"%s", L"*Eisa_Resource_Device");
    00151
    00152             ZwSetValueKey(instanceHandle,
    00153                           &unicodeString,
    00154                           0,
    00155                           REG_MULTI_SZ,
    00156                           buffer,
    00157                           (wcslen(buffer) + 2) * sizeof(WCHAR)
    00158                           );
    00159
    00160             PiWstrToUnicodeString(&unicodeString, REGSTR_VALUE_CONFIG_FLAGS);
    00161             tmpValue = 0;
    00162             ZwSetValueKey(instanceHandle,
    00163                          &unicodeString,
    00164                          TITLE_INDEX_VALUE,
    00165                          REG_DWORD,
    00166                          &tmpValue,
    00167                          sizeof(tmpValue)
    00168                          );
    00169
    00170         }
    00171
    00172         RtlInitUnicodeString( &unicodeString, REGSTR_KEY_LOGCONF );
    00173         status = IopCreateRegistryKeyEx( &logConfHandle,
    00174                                          instanceHandle,
    00175                                          &unicodeString,
    00176                                          KEY_ALL_ACCESS,
    00177                                          REG_OPTION_NON_VOLATILE,
    00178                                          NULL
    00179                                          );
    00180         ZwClose(instanceHandle);
    00181         if (NT_SUCCESS(status))  {
    00182             RtlInitUnicodeString( &unicodeString, REGSTR_VAL_BOOTCONFIG );
    00183
    00184             status = ZwSetValueKey(logConfHandle,
    00185                                    &unicodeString,
    00186                                    0,
    00187                                    REG_RESOURCE_LIST,
    00188                                    resourceList,
    00189                                    resourceLength
    00190                                    );
    00191             ZwClose(logConfHandle);
    00192         }
    00193     }
    00194     if (resourceList) {
    00195         ExFreePool (resourceList);
    00196     }
    00197     return status;
    00198 }

NTSTATUS IopAddDevicesToBootDriver | ( | IN PDRIVER_OBJECT | DriverObject | ) |

Definition at line 117 of file pnpdd.c.

References IopAddDevicesToBootDriverWorker(), IopApplyFunctionToServiceInstances(), NTSTATUS(), NULL, and TRUE.

Referenced by IopInitializeBootDrivers().

    00123                    :
    00124
    00125     This functions is used by Pnp manager to inform a boot device driver of
    00126     all the devices it can possibly control.  This routine is for boot
    00127     drivers only.
    00128
    00129 Parameters:
    00130
    00131     DriverObject - Supplies a driver object to receive its boot devices.
    00132
    00133 Return Value:
    00134
    00135     NTSTATUS code.
    00136
    00137 --*/
    00138 {
    00139     NTSTATUS status;
    00140
    00141
    00142     //
    00143     // For each device instance in the driver's service/enum key, we will
    00144     // invoke the driver's AddDevice routine and perform enumeration on
    00145     // the device.
    00146     // Note, we don't acquire registry lock before calling IopApplyFunction
    00147     // routine.  We know this code is for boot driver initialization.  No
    00148     // one else would access the registry Enum key at this time and most
    00149     // important we need the registry lock in other down level routines.
    00150     //
    00151
    00152     status = IopApplyFunctionToServiceInstances(
    00153                                 NULL,
    00154                                 &DriverObject->DriverExtension->ServiceKeyName,
    00155                                 KEY_ALL_ACCESS,
    00156                                 TRUE,
    00157                                 IopAddDevicesToBootDriverWorker,
    00158                                 DriverObject,
    00159                                 NULL
    00160                                 );
    00161
    00162     return status;
    00163 }

NTSTATUS IopAllocateBootResources | ( | IN ARBITER_REQUEST_SOURCE | ArbiterRequestSource,
|  | IN PDEVICE_OBJECT | DeviceObject,
|  | IN PCM_RESOURCE_LIST | BootResources
| ) |

Definition at line 7141 of file pnpres.c.

References DebugMessage, DelayExecution, DUMP_ERROR, FALSE, IopRegistrySemaphore, IopReserveBootResourcesInternal(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

Referenced by IopInitializeBootDrivers(), IopReserveBootResources(), and IopReserveLegacyBootResources().

    07149                    :
    07150
    07151     This routine reports boot resources for the specified device to
    07152     arbiters.
    07153
    07154 Arguments:
    07155
    07156     DeviceObject - Supplies a pointer to the device object, could be NULL
    07157         if DeviceObject is NULL, the BootResources are reserved and will not be given
    07158             to a device unless there is no other choice. The caller must release the
    07159             pool for BootResources.
    07160         if DeviceObject is NON_NULL, BootResources are BOOT reserved (preallocated.)
    07161
    07162     BootResources - Supplies a pointer to the Boot resources.
    07163
    07164 Return Value:
    07165
    07166     None.
    07167
    07168 --*/
    07169 {
    07170     NTSTATUS    status;
    07171
    07172     PAGED_CODE();
    07173
    07174     KeEnterCriticalRegion( );
    07175
    07176     status = KeWaitForSingleObject( &IopRegistrySemaphore,
    07177                                     DelayExecution,
    07178                                     KernelMode,
    07179                                     FALSE,
    07180                                     NULL );
    07181
    07182     if (NT_SUCCESS(status)) {
    07183
    07184         status = IopReserveBootResourcesInternal(ArbiterRequestSource, DeviceObject, BootResources);
    07185         KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE);
    07186
    07187     } else {
    07188
    07189         DebugMessage(DUMP_ERROR, ("IopReserveBootResources: Get RegustrySemaphore failed. Status %x\n", status));
    07190     }
    07191
    07192     KeLeaveCriticalRegion();
    07193
    07194     return status;
    07195 }

NTSTATUS IopAllocateBuffer | ( | IN PBUFFER_INFO | Info,
|  | IN ULONG | Size
| ) |

Definition at line 2427 of file pnpioapi.c.

References ASSERT, ExAllocatePool, PagedPool, and Size.

Referenced by IopGetDeviceInterfaces(), IopProcessCriticalDeviceRoutine(), and IopRemoveDeviceInterfaces().

    02434                    :
    02435
    02436     Allocates a buffer of Size bytes and initialises the BUFFER_INFO
    02437     structure so the current position is at the start of the buffer.
    02438
    02439 Parameters:
    02440
    02441     Info - Pointer to a buffer info structure to be used to manage the new
    02442            buffer
    02443
    02444     Size - The number of bytes to be allocated for the buffer
    02445
    02446 Return Value:
    02447
    02448     Status code that indicates whether or not the function was successful.
    02449
    02450 --*/
    02451
    02452 {
    02453     ASSERT(Info);
    02454
    02455     if (!(Info->Buffer = ExAllocatePool(PagedPool, Size))) {
    02456         return STATUS_INSUFFICIENT_RESOURCES;
    02457     }
    02458
    02459     Info->Current = Info->Buffer;
    02460     Info->MaxSize = Size;
    02461
    02462     return STATUS_SUCCESS;
    02463 }

PDEVICE_NODE IopAllocateDeviceNode | ( | IN PDEVICE_OBJECT | PhysicalDeviceObject | ) |

Definition at line 56 of file devnode.c.

References _DEVICE_NODE::BusNumber, _DEVICE_NODE::ChildBusNumber, _DEVICE_NODE::ChildBusTypeIndex, _DEVICE_NODE::ChildInterfaceType, DEVICE_NODE, _DEVICE_NODE::DeviceArbiterList, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, _DEVICE_NODE::DeviceTranslatorList, DO_DEVICE_INITIALIZING, _DEVICE_NODE::DockInfo, _DEVICE_NODE::EnumerationMutex, ExAllocatePoolWithTag, _DEVICE_NODE::Flags, _DEVICE_NODE::InterfaceType, IOP_DNOD_TAG, IopNumberDeviceNodes, KeInitializeEvent, NonPagedPool, NULL, PAGED_CODE, _DEVICE_NODE::PendedSetInterfaceState, _DEVICE_NODE::PhysicalDeviceObject, _DEVICE_NODE::TargetDeviceNotify, TRUE, and USHORT.

Referenced by IopEnumerateDevice(), IopFindLegacyDeviceNode(), IopInitializeDeviceInstanceKey(), IopInitializePlugPlayServices(), and IoReportDetectedDevice().

    00062                    :
    00063
    00064     This function allocates a device node from nonpaged pool and initializes
    00065     the fields which do not require to hold lock to do so.  Since adding
    00066     the device node to pnp mgr's device node tree requires acquiring lock,
    00067     this routine does not add the device node to device node tree.
    00068
    00069 Arguments:
    00070
    00071     PhysicalDeviceObject - Supplies a pointer to its corresponding physical device
    00072         object.
    00073
    00074 Return Value:
    00075
    00076     a pointer to the newly created device node. Null is returned if failed.
    00077
    00078 --*/
    00079 {
    00080     PDEVICE_NODE deviceNode;
    00081
    00082     PAGED_CODE();
    00083
    00084     deviceNode = ExAllocatePoolWithTag(
    00085                     NonPagedPool,
    00086                     sizeof(DEVICE_NODE),
    00087                     IOP_DNOD_TAG
    00088                     );
    00089
    00090     if (deviceNode == NULL ){
    00091         return NULL;
    00092     }
    00093
    00094     InterlockedIncrement (&IopNumberDeviceNodes);
    00095
    00096     RtlZeroMemory(deviceNode, sizeof(DEVICE_NODE));
    00097     deviceNode->InterfaceType = InterfaceTypeUndefined;
    00098     deviceNode->BusNumber = (ULONG)-1;
    00099     deviceNode->ChildInterfaceType = InterfaceTypeUndefined;
    00100     deviceNode->ChildBusNumber = (ULONG)-1;
    00101     deviceNode->ChildBusTypeIndex = (USHORT)-1;
    00102
    00103     KeInitializeEvent( &deviceNode->EnumerationMutex,
    00104                        SynchronizationEvent,
    00105                        TRUE );
    00106
    00107     InitializeListHead(&deviceNode->DeviceArbiterList);
    00108     InitializeListHead(&deviceNode->DeviceTranslatorList);
    00109
    00110     if (PhysicalDeviceObject){
    00111
    00112         deviceNode->PhysicalDeviceObject = PhysicalDeviceObject;
    00113         PhysicalDeviceObject->DeviceObjectExtension->DeviceNode = (PVOID)deviceNode;
    00114         PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    00115     }
    00116
    00117     InitializeListHead(&deviceNode->TargetDeviceNotify);
    00118
    00119     InitializeListHead(&deviceNode->DockInfo.ListEntry);
    00120
    00121     InitializeListHead(&deviceNode->PendedSetInterfaceState);
    00122
    00123     return deviceNode;
    00124 }

NTSTATUS IopAllocateResources | ( | IN PULONG | DeviceCountP,
|  | IN OUT PIOP_RESOURCE_REQUEST * | AssignTablePP,
|  | IN BOOLEAN | Locked,
|  | IN BOOLEAN | BootConfigsOK
| ) |

Definition at line 720 of file pnpres.c.

References _IOP_RESOURCE_REQUEST::AllocationType, ArbiterRequestPnpDetected, ArbiterRequestPnpEnumerated, ASSERT, DebugMessage, DelayExecution, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_HAS_BOOT_CONFIG, DNF_NEEDS_REBALANCE, DUMP_ERROR, DUMP_INFO, ExAllocatePoolAT, ExFreePool(), FALSE, _IOP_RESOURCE_REQUEST::Flags, _DEVICE_NODE::Flags, _DEVICE_NODE::InstancePath, IOP_ASSIGN_EXCLUDE, IOP_ASSIGN_IGNORE, IOP_ASSIGN_NO_REBALANCE, IOP_ASSIGN_RETRY, IopAssignInner(), IopBootConfigsReserved, IopBuildCmResourceLists(), IopFreeResourceRequirementsForAssignTable(), IopGetResourceRequirementsForAssignTable(), IopRearrangeAssignTable(), IopRebalance(), IopRegistrySemaphore, IopReleaseFilteredBootResources(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, _IOP_RESOURCE_REQUEST::PhysicalDevice, _IOP_RESOURCE_REQUEST::ResourceAssignment, _IOP_RESOURCE_REQUEST::ResourceRequirements, Status, _IOP_RESOURCE_REQUEST::Status, and TRUE.

Referenced by IopAssignResourcesToDevices(), and IopLegacyResourceAllocation().

    00729                    :
    00730
    00731     For each AssignTable entry, this routine queries device's IO resource requirements
    00732     list and converts it to our internal REQ_LIST format; calls worker routine to perform
    00733     the resources assignment.
    00734
    00735 Parameters:
    00736
    00737     AssignTable - supplies a pointer to the first entry of a IOP_RESOURCE_REQUEST table.
    00738
    00739     AssignTableEnd - supplies a pointer to the end of IOP_RESOURCE_REQUEST table.
    00740
    00741     Locked - Indicates whether the IopRegistrySemaphore is acquired by the caller.
    00742
    00743     BootConfigsOK - Indicates whether we should assign BOOT configs.
    00744
    00745 Return Value:
    00746
    00747     Status code that indicates whether or not the function was successful.
    00748
    00749 --*/
    00750
    00751 {
    00752     PIOP_RESOURCE_REQUEST   AssignTable;
    00753     PIOP_RESOURCE_REQUEST   AssignTableEnd;
    00754     PIOP_RESOURCE_REQUEST   AssignTableTail;
    00755     PIOP_RESOURCE_REQUEST   AssignEntry;
    00756     PIOP_RESOURCE_REQUEST   AssignEntryOriginal;
    00757     ULONG                   AssignTableCount;
    00758     ULONG                   DeviceCount;
    00759     NTSTATUS                Status;
    00760     BOOLEAN                 FreeAssignTable;
    00761     BOOLEAN                 tryRebalance;
    00762
    00763     PAGED_CODE();
    00764
    00765     DeviceCount = *DeviceCountP;
    00766     FreeAssignTable = FALSE;
    00767     tryRebalance = TRUE;
    00768     AssignTable = *AssignTablePP;
    00769     AssignTableEnd = AssignTable + DeviceCount;
    00770
    00771     //
    00772     // If legacy device resource allocation, don't rebalance on failure,
    00773     // if the resource they want is already assigned, what they are looking
    00774     // for isn't there.
    00775     //
    00776
    00777     if ((DeviceCount == 1) && (AssignTable->Flags & IOP_ASSIGN_NO_REBALANCE)) {
    00778
    00779         tryRebalance = FALSE;
    00780
    00781     }
    00782
    00783     //
    00784     // Grab the IO registry semaphore to make sure no other device is
    00785     // reporting it's resource usage while we are searching for conflicts.
    00786     //
    00787
    00788     if (!Locked) {
    00789
    00790         KeEnterCriticalRegion();
    00791
    00792         Status = KeWaitForSingleObject( &IopRegistrySemaphore,
    00793                                         DelayExecution,
    00794                                         KernelMode,
    00795                                         FALSE,
    00796                                         NULL );
    00797
    00798         if (!NT_SUCCESS(Status)) {
    00799
    00800             DebugMessage(DUMP_ERROR, ("IopAllocateResources: Get RegistrySemaphore failed. Status %x\n", Status));
    00801             KeLeaveCriticalRegion();
    00802             return Status;
    00803
    00804         }
    00805     }
    00806
    00807     //
    00808     // Get the resource requirements.
    00809     //
    00810
    00811     Status = IopGetResourceRequirementsForAssignTable(AssignTable, AssignTableEnd, &DeviceCount);
    00812     if (DeviceCount == 0) {
    00813
    00814         DebugMessage(DUMP_INFO, ("IopAllocateResources: Get Requirements for Assign Table found nothing. status %x\n", Status));
    00815
    00816         if (!Locked) {
    00817
    00818             KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE);
    00819             KeLeaveCriticalRegion();
    00820
    00821         }
    00822
    00823         return Status;
    00824
    00825     }
    00826
    00827     //
    00828     // Check if it is OK to assign resources to devices with BOOT configs.
    00829     //
    00830
    00831     if (BootConfigsOK) {
    00832
    00833         if (!IopBootConfigsReserved) {
    00834
    00835             //
    00836             // Process devices with BOOT configs or no requirements first.
    00837             //
    00838
    00839             for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; AssignEntry++) {
    00840
    00841                 PDEVICE_NODE    deviceNode = (PDEVICE_NODE)AssignEntry->PhysicalDevice->DeviceObjectExtension->DeviceNode;
    00842
    00843                 if (deviceNode->Flags & DNF_HAS_BOOT_CONFIG) {
    00844
    00845                     break;
    00846                 }
    00847             }
    00848
    00849             if (AssignEntry != AssignTableEnd) {
    00850
    00851                 //
    00852                 // There are devices with BOOT config.
    00853                 //
    00854
    00855                 for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; AssignEntry++) {
    00856
    00857                     PDEVICE_NODE    deviceNode = (PDEVICE_NODE)AssignEntry->PhysicalDevice->DeviceObjectExtension->DeviceNode;
    00858
    00859                     if (    !(AssignEntry->Flags & IOP_ASSIGN_IGNORE) &&
    00860                             !(deviceNode->Flags & DNF_HAS_BOOT_CONFIG) &&
    00861                             AssignEntry->ResourceRequirements &&
    00862                             AssignEntry->AllocationType != ArbiterRequestPnpDetected) {
    00863
    00864                         DeviceCount--;
    00865                         DebugMessage(DUMP_INFO, ("Delaying non BOOT config device %ws...\n", deviceNode->InstancePath.Buffer));
    00866                         AssignEntry->Status = STATUS_RETRY;
    00867                         AssignEntry->Flags |= IOP_ASSIGN_IGNORE;
    00868                         IopFreeResourceRequirementsForAssignTable(AssignEntry, AssignEntry + 1);
    00869
    00870                     }
    00871                 }
    00872             }
    00873
    00874             if (DeviceCount == 0) {
    00875
    00876                 if (!Locked) {
    00877
    00878                     KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE);
    00879                     KeLeaveCriticalRegion();
    00880
    00881                 }
    00882
    00883                 return Status;
    00884             }
    00885         }
    00886
    00887         //
    00888         // Check if we need to allocate a new table.
    00889         //
    00890
    00891         if (DeviceCount != *DeviceCountP) {
    00892
    00893             //
    00894             // Allocate a new table.
    00895             //
    00896
    00897             AssignTable = (PIOP_RESOURCE_REQUEST) ExAllocatePoolAT( PagedPool,
    00898                                                                     sizeof(IOP_RESOURCE_REQUEST) * DeviceCount);
    00899             if (AssignTable == NULL) {
    00900
    00901                 IopFreeResourceRequirementsForAssignTable(*AssignTablePP, AssignTableEnd);
    00902
    00903                 if (!Locked) {
    00904
    00905                     KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE);
    00906                     KeLeaveCriticalRegion();
    00907
    00908                 }
    00909
    00910                 return STATUS_INSUFFICIENT_RESOURCES;
    00911             }
    00912
    00913             FreeAssignTable = TRUE;
    00914
    00915             //
    00916             // Process the AssignTable to remove any entry which is marked as IOP_ASSIGN_IGNORE.
    00917             //
    00918
    00919             AssignEntryOriginal = *AssignTablePP;
    00920             AssignTableEnd = AssignTable + DeviceCount;
    00921             for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd;) {
    00922
    00923                 if (!(AssignEntryOriginal->Flags & IOP_ASSIGN_IGNORE)) {
    00924
    00925                     *AssignEntry = *AssignEntryOriginal;
    00926                     AssignEntry++;
    00927
    00928                 }
    00929                 AssignEntryOriginal++;
    00930             }
    00931         }
    00932
    00933     } else {
    00934
    00935         //
    00936         // Only process devices with no resource requirements. Rest get STATUS_RETRY.
    00937         //
    00938
    00939         for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; AssignEntry++) {
    00940
    00941             if (    !(AssignEntry->Flags & IOP_ASSIGN_IGNORE) &&
    00942                     AssignEntry->ResourceRequirements) {
    00943
    00944                 PDEVICE_NODE    deviceNode = (PDEVICE_NODE)AssignEntry->PhysicalDevice->DeviceObjectExtension->DeviceNode;
    00945
    00946                 DebugMessage(DUMP_INFO, ("Delaying resources requiring device %ws...\n", deviceNode->InstancePath.Buffer));
    00947                 IopFreeResourceRequirementsForAssignTable(AssignEntry, AssignEntry + 1);
    00948                 AssignEntry->Status = STATUS_RETRY;
    00949
    00950             }
    00951         }
    00952
    00953         //
    00954         // Release the I/O Registry Semaphore
    00955         //
    00956
    00957         if (!Locked) {
    00958
    00959             KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE);
    00960             KeLeaveCriticalRegion();
    00961
    00962         }
    00963
    00964         return Status;
    00965     }
    00966     AssignTableCount = (ULONG)(AssignTableEnd - AssignTable);
    00967     ASSERT(AssignTableCount == DeviceCount);
    00968
    00969     //
    00970     // Sort the AssignTable
    00971     //
    00972
    00973     IopRearrangeAssignTable(AssignTable, DeviceCount);
    00974
    00975     for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; AssignEntry++) {
    00976
    00977         PDEVICE_NODE    deviceNode = (PDEVICE_NODE)AssignEntry->PhysicalDevice->DeviceObjectExtension->DeviceNode;
    00978
    00979         DebugMessage(DUMP_INFO, ("Pnpres: Trying to allocate resources for %ws.\n", deviceNode->InstancePath.Buffer));
    00980
    00981         Status = IopAssignInner(1, AssignEntry, FALSE);
    00982         if (NT_SUCCESS(Status)) {
    00983
    00984             IopBuildCmResourceLists(AssignEntry, AssignEntry + 1);
    00985             if (AssignEntry->AllocationType == ArbiterRequestPnpEnumerated) {
    00986
    00987                 IopReleaseFilteredBootResources(AssignEntry, AssignEntry + 1);
    00988             }
    00989         } else if (Status == STATUS_INSUFFICIENT_RESOURCES) {
    00990
    00991             DebugMessage(DUMP_ERROR, ("IopAllocateResource: Failed to allocate Pool.\n"));
    00992             break;
    00993
    00994         } else if (tryRebalance) {
    00995
    00996             DebugMessage(DUMP_INFO, ("IopAllocateResources: Initiating REBALANCE...\n"));
    00997
    00998             deviceNode->Flags |= DNF_NEEDS_REBALANCE;
    00999             Status = IopRebalance(1, AssignEntry);
    01000             deviceNode->Flags &= ~DNF_NEEDS_REBALANCE;
    01001             if (!NT_SUCCESS(Status)) {
    01002                 AssignEntry->Status = STATUS_CONFLICTING_ADDRESSES;
    01003             }
    01004         } else {
    01005             AssignEntry->Status = STATUS_CONFLICTING_ADDRESSES;
    01006         }
    01007     }
    01008
    01009     //
    01010     // IF we did not go through the entire table without any error,
    01011     // mark remaining entries as RETRY.
    01012     //
    01013
    01014     for (; AssignEntry < AssignTableEnd; AssignEntry++) {
    01015
    01016         AssignEntry->Status = STATUS_RETRY;
    01017     }
    01018
    01019     IopFreeResourceRequirementsForAssignTable(AssignTable, AssignTableEnd);
    01020
    01021     //
    01022     // Release the I/O Registry Semaphore
    01023     //
    01024
    01025     if (!Locked) {
    01026         KeReleaseSemaphore( &IopRegistrySemaphore, 0, 1, FALSE );
    01027         KeLeaveCriticalRegion( );
    01028     }
    01029
    01030     //
    01031     // Copy the information in our own AssignTable to caller's AssignTable
    01032     //
    01033
    01034     if (FreeAssignTable) {
    01035         AssignEntryOriginal = *AssignTablePP;
    01036         for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd;) {
    01037             if (AssignEntryOriginal->Flags & (IOP_ASSIGN_IGNORE | IOP_ASSIGN_RETRY)) {
    01038                 AssignEntryOriginal++;
    01039                 continue;
    01040             }
    01041             *AssignEntryOriginal = *AssignEntry;
    01042             AssignEntry++;
    01043             AssignEntryOriginal++;
    01044         }
    01045         ASSERT(AssignEntryOriginal <= *AssignTablePP + *DeviceCountP);
    01046         ExFreePool(AssignTable);
    01047     }
    01048
    01049     AssignEntry = *AssignTablePP;
    01050     while (AssignEntry < *AssignTablePP + *DeviceCountP) {
    01051         if (AssignEntry->Flags & (IOP_ASSIGN_IGNORE | IOP_ASSIGN_RETRY)) {
    01052             AssignEntry++;
    01053             continue;
    01054         }
    01055         if ((AssignEntry->Flags & IOP_ASSIGN_EXCLUDE) || AssignEntry->ResourceAssignment == NULL) {
    01056
    01057             AssignEntry->Status = STATUS_CONFLICTING_ADDRESSES;
    01058         }
    01059         AssignEntry++;
    01060     }
    01061
    01062     return Status;
    01063 }

NTSTATUS IopAllocateUnicodeString | ( | IN OUT PUNICODE_STRING | String,
|  | IN USHORT | Length
| ) |

Definition at line 5619 of file pnpioapi.c.

References ExAllocatePool, PAGED_CODE, PagedPool, and String.

Referenced by IopBuildSymbolicLinkStrings(), IopOpenOrCreateDeviceInterfaceSubKeys(), IopRemoveDeviceInterfaces(), IopSetRegistryStringValue(), and IopUnregisterDeviceInterface().

    05626                    :
    05627
    05628     This routine allocates a buffer for a unicode string of a given length
    05629     and initialises the UNICODE_STRING structure appropriately. When the
    05630     string is no longer required it can be freed using IopFreeAllocatedString.
    05631     The buffer also be directly deleted by ExFreePool and so can be handed
    05632     back to a caller.
    05633
    05634 Parameters:
    05635
    05636     String - Supplies a pointer to an uninitialised unicode string which will
    05637         be manipulated by the function.
    05638
    05639     Length - The number of BYTES long that the string will be.
    05640
    05641 Return Value:
    05642
    05643     Either STATUS_INSUFFICIENT_RESOURCES indicating paged pool is exhausted or
    05644     STATUS_SUCCESS.
    05645
    05646 Remarks:
    05647
    05648     The buffer allocated will be one character (2 bytes) more than length specified.
    05649     This is to allow for easy null termination of the strings - eg for registry
    05650     storage.
    05651
    05652 --*/
    05653
    05654 {
    05655     PAGED_CODE();
    05656
    05657     String->Length = 0;
    05658     String->MaximumLength = Length + sizeof(UNICODE_NULL);
    05659
    05660     if(!(String->Buffer = ExAllocatePool(PagedPool, Length + sizeof(UNICODE_NULL)))) {
    05661         return STATUS_INSUFFICIENT_RESOURCES;
    05662     } else {
    05663         return STATUS_SUCCESS;
    05664     }
    05665 }

NTSTATUS IopAppendStringToValueKey | ( | IN HANDLE | Handle,
|  | IN PWSTR | ValueName,
|  | IN PUNICODE_STRING | String,
|  | IN BOOLEAN | Create
| ) |

Definition at line 546 of file pnpsubs.c.

References Create(), ExAllocatePool, ExFreePool(), Handle, IopGetRegistryValue(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, RtlInitUnicodeString(), String, TITLE_INDEX_VALUE, and ValueName.

    00555                    :
    00556
    00557     This routine appends a string to a value entry specified by ValueName
    00558     under an already opened registry handle.  If the ValueName is not present
    00559     and Create is TRUE, a new value entry will be created using the name
    00560     ValueName.
    00561
    00562 Parameters:
    00563
    00564     Handle - Supplies the handle to a registry key whose value entry will
    00565         be modified.
    00566
    00567     ValueName - Supplies a pointer to a string to specify the value entry.
    00568
    00569     String - Supplies a unicode string to append to the value entry.
    00570
    00571     Create - Supplies a BOOLEAN variable to indicate if the ValueName
    00572         value entry should be created if it is not present.
    00573
    00574 Return Value:
    00575
    00576     Status code that indicates whether or not the function was successful.
    00577
    00578 --*/
    00579
    00580 {
    00581     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    00582     PWSTR destinationString, p;
    00583     UNICODE_STRING unicodeValueName;
    00584     ULONG size;
    00585     NTSTATUS status;
    00586
    00587     if ( !String || (String->Length < sizeof(WCHAR)) ) {
    00588         return STATUS_SUCCESS;
    00589     }
    00590
    00591     //
    00592     // Read registry value entry data
    00593     //
    00594
    00595     status = IopGetRegistryValue(Handle, ValueName, &keyValueInformation);
    00596
    00597     if(!NT_SUCCESS( status )) {
    00598         if (status == STATUS_OBJECT_NAME_NOT_FOUND && Create) {
    00599
    00600             //
    00601             // if no valid entry exists and user said ok to create one
    00602             //
    00603
    00604             keyValueInformation = NULL;
    00605         } else {
    00606             return status;
    00607         }
    00608     } else if(keyValueInformation->Type != REG_MULTI_SZ) {
    00609
    00610         ExFreePool(keyValueInformation);
    00611
    00612         if(Create) {
    00613             keyValueInformation = NULL;
    00614         } else {
    00615             return STATUS_INVALID_PARAMETER_2;
    00616         }
    00617
    00618     } else if(keyValueInformation->DataLength < sizeof(WCHAR) ||
    00619               *(PWCHAR)KEY_VALUE_DATA(keyValueInformation) == UNICODE_NULL) {  // empty or one NULL WCHAR
    00620
    00621         ExFreePool(keyValueInformation);
    00622         keyValueInformation = NULL;
    00623     }
    00624
    00625     //
    00626     // Allocate a buffer to hold new data for the specified key value entry
    00627     // Make sure the buffer is at least an empty MULTI_SZ big.
    00628     //
    00629
    00630     if (keyValueInformation) {
    00631         size = keyValueInformation->DataLength + String->Length + sizeof (UNICODE_NULL);
    00632     } else {
    00633         size =  String->Length + 2 * sizeof(UNICODE_NULL);
    00634     }
    00635
    00636     destinationString = p = (PWSTR)ExAllocatePool(PagedPool, size);
    00637     if (destinationString == NULL) {
    00638         if (keyValueInformation) {
    00639             ExFreePool(keyValueInformation);
    00640         }
    00641         return STATUS_INSUFFICIENT_RESOURCES;
    00642     }
    00643
    00644     //
    00645     // Copy the existing data to our newly allocated buffer, if any
    00646     //
    00647
    00648     if (keyValueInformation) {
    00649
    00650         //
    00651         // Note we  need to remove a UNICODE_NULL because the
    00652         // MULTI_SZ has two terminating UNICODE_NULL.
    00653         //
    00654
    00655         RtlMoveMemory(p,
    00656                       KEY_VALUE_DATA(keyValueInformation),
    00657                       keyValueInformation->DataLength - sizeof(WCHAR)
    00658                       );
    00659         p += keyValueInformation->DataLength / sizeof(WCHAR) - 1;
    00660
    00661         ExFreePool(keyValueInformation);
    00662     }
    00663
    00664     //
    00665     // Append the user specified unicode string to our buffer
    00666     //
    00667     RtlMoveMemory(p,
    00668                   String->Buffer,
    00669                   String->Length
    00670                   );
    00671     p += String->Length / sizeof(WCHAR);
    00672     *p = UNICODE_NULL;
    00673     p++;
    00674     *p = UNICODE_NULL;
    00675
    00676     //
    00677     // Finally write the data to the specified registy value entry
    00678     //
    00679
    00680     RtlInitUnicodeString(&unicodeValueName, ValueName);
    00681     status = ZwSetValueKey(
    00682                 Handle,
    00683                 &unicodeValueName,
    00684                 TITLE_INDEX_VALUE,
    00685                 REG_MULTI_SZ,
    00686                 destinationString,
    00687                 size
    00688                 );
    00689
    00690     ExFreePool(destinationString);
    00691     return status;
    00692 }

NTSTATUS IopApplyFunctionToServiceInstances | ( | IN HANDLE ServiceKeyHandle | OPTIONAL,
|  | IN PUNICODE_STRING ServiceKeyName | OPTIONAL,
|  | IN ACCESS_MASK | DesiredAccess,
|  | IN BOOLEAN | IgnoreNonCriticalErrors,
|  | IN PIOP_SUBKEY_CALLBACK_ROUTINE | DevInstCallbackRoutine,
|  | IN OUT PVOID | Context,
|  | OUT PULONG ServiceInstanceOrdinal | OPTIONAL
| ) |

Definition at line 2209 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetEnumName, ExAllocatePool, ExFreePool(), FALSE, IopGetRegistryValue(), IopOpenRegistryKey(), IopOpenServiceEnumKeys(), IopRegistryDataToUnicodeString, KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, PNP_SCRATCH_BUFFER_SIZE, Status, and TRUE.

Referenced by IopAddDevicesToBootDriver(), and IopGetDriverDeviceList().

    02221                    :
    02222
    02223     This routine enumerates all device instances referenced by the instance
    02224     ordinal entries under a service's volatile Enum key, and calls
    02225     the specified callback routine for each instance's corresponding subkey
    02226     under HKLM\System\Enum.
    02227
    02228 Arguments:
    02229
    02230     ServiceKeyHandle - Optional handle to the service entry. If this parameter
    02231         is not specified, then the service key name must be given in
    02232         ServiceKeyName (if both parameters are specified, then ServiceKeyHandle
    02233         is used, and ServiceKeyName is ignored).
    02234
    02235     ServiceKeyName - Optional name of the service entry key (under
    02236         HKLM\CurrentControlSet\Services). If this parameter is not specified,
    02237         then ServiceKeyHandle must contain a handle to the desired service key.
    02238
    02239     DesiredAccess - Specifies the desired access that the callback routine
    02240         needs to the enumerated device instance keys.  If no desired access is
    02241         specified (i.e., DesiredAccess is zero), then no handle will be opened
    02242         for the device instance keys, and the callback will be passed a NULL for
    02243         its DeviceInstanceHandle parameter.
    02244
    02245     IgnoreNonCriticalErrors - Specifies whether this function should
    02246         immediately terminate on all errors, or only on critical ones.
    02247         An example of a non-critical error is when an enumerated device instance
    02248         key cannot be opened for the desired access.
    02249
    02250     DevInstCallbackRoutine - Supplies a pointer to a function that will
    02251         be called for each device instance key referenced by a service instance
    02252         entry under the service's volatile Enum subkey. The prototype of the
    02253         function is as follows:
    02254
    02255             typedef BOOLEAN (*PIOP_SUBKEY_CALLBACK_ROUTINE) (
    02256                 IN     HANDLE DeviceInstanceHandle,
    02257                 IN     PUNICODE_STRING DeviceInstancePath,
    02258                 IN OUT PVOID Context
    02259                 );
    02260
    02261         where DeviceInstanceHandle is the handle to an enumerated device instance
    02262         key, DeviceInstancePath is the registry path (relative to
    02263         HKLM\System\Enum) to this device instance, and Context is a pointer to
    02264         user-defined data.
    02265
    02266         This function should return TRUE to continue enumeration, or
    02267         FALSE to terminate it.
    02268
    02269     Context - Supplies a pointer to user-defined data that will be passed
    02270         in to the callback routine at each device instance key invocation.
    02271
    02272     ServiceInstanceOrdinal - Optionally, receives the service instance ordinal (1 based)
    02273         that terminated the enumeration, or the total number of instances enumerated
    02274         if the enumeration completed without being aborted.
    02275
    02276 Return Value:
    02277
    02278     NT status code indicating whether the device instance keys were successfully
    02279     enumerated.  Note that this does not provide information on the success or
    02280     failure of the callback routine--if desired, this information should be
    02281     stored in the Context structure.
    02282
    02283 --*/
    02284
    02285 {
    02286     NTSTATUS Status;
    02287     HANDLE ServiceEnumHandle, SystemEnumHandle, DeviceInstanceHandle;
    02288     UNICODE_STRING TempUnicodeString;
    02289     ULONG ServiceInstanceCount, i, junk;
    02290     PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
    02291     WCHAR ValueNameString[20];
    02292     BOOLEAN ContinueEnumeration;
    02293
    02294     //
    02295     // First, open up the volatile Enum subkey under the specified service entry.
    02296     //
    02297
    02298     if(ARGUMENT_PRESENT(ServiceKeyHandle)) {
    02299         PiWstrToUnicodeString(&TempUnicodeString, REGSTR_KEY_ENUM);
    02300         Status = IopOpenRegistryKeyEx( &ServiceEnumHandle,
    02301                                        ServiceKeyHandle,
    02302                                        &TempUnicodeString,
    02303                                        KEY_READ
    02304                                        );
    02305     } else {
    02306         Status = IopOpenServiceEnumKeys(ServiceKeyName,
    02307                                         KEY_READ,
    02308                                         NULL,
    02309                                         &ServiceEnumHandle,
    02310                                         FALSE
    02311                                        );
    02312     }
    02313     if(!NT_SUCCESS(Status)) {
    02314         return Status;
    02315     }
    02316
    02317     //
    02318     // Find out how many instances are referenced in the service's Enum key.
    02319     //
    02320
    02321     ServiceInstanceCount = 0;   // assume none.
    02322
    02323     Status = IopGetRegistryValue(ServiceEnumHandle,
    02324                                  REGSTR_VALUE_COUNT,
    02325                                  &KeyValueInformation
    02326                                 );
    02327     if(NT_SUCCESS(Status)) {
    02328
    02329         if((KeyValueInformation->Type == REG_DWORD) &&
    02330            (KeyValueInformation->DataLength >= sizeof(ULONG))) {
    02331
    02332             ServiceInstanceCount = *(PULONG)KEY_VALUE_DATA(KeyValueInformation);
    02333
    02334         }
    02335         ExFreePool(KeyValueInformation);
    02336
    02337     } else if(Status != STATUS_OBJECT_NAME_NOT_FOUND) {
    02338         goto PrepareForReturn;
    02339     } else {
    02340         //
    02341         // If 'Count' value entry not found, consider this to mean there are simply
    02342         // no device instance controlled by this service.
    02343         //
    02344         Status = STATUS_SUCCESS;
    02345     }
    02346
    02347     //
    02348     // Now, enumerate each service instance, and call the specified callback function
    02349     // for the corresponding device instance.
    02350     //
    02351
    02352     if (ServiceInstanceCount) {
    02353
    02354         if (DesiredAccess) {
    02355             Status = IopOpenRegistryKeyEx( &SystemEnumHandle,
    02356                                            NULL,
    02357                                            &CmRegistryMachineSystemCurrentControlSetEnumName,
    02358                                            KEY_READ
    02359                                            );
    02360             if(!NT_SUCCESS(Status)) {
    02361                 goto PrepareForReturn;
    02362             }
    02363         } else {
    02364             //
    02365             // Set DeviceInstanceHandle to NULL, since we won't be opening up the
    02366             // device instance keys.
    02367             //
    02368             DeviceInstanceHandle = NULL;
    02369         }
    02370         KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePool(
    02371                                                               PagedPool,
    02372                                                               PNP_SCRATCH_BUFFER_SIZE);
    02373         if (!KeyValueInformation) {
    02374             Status = STATUS_INSUFFICIENT_RESOURCES;
    02375             goto PrepareForReturn;
    02376         }
    02377         i = 0;
    02378         while (TRUE) {
    02379             Status = ZwEnumerateValueKey (           // i was initialized to zero above.
    02380                             ServiceEnumHandle,
    02381                             i++,
    02382                             KeyValueFullInformation,
    02383                             KeyValueInformation,
    02384                             PNP_SCRATCH_BUFFER_SIZE,
    02385                             &junk
    02386                             );
    02387
    02388             if (!NT_SUCCESS (Status)) {
    02389                 if (Status == STATUS_NO_MORE_ENTRIES) {
    02390                     Status = STATUS_SUCCESS;
    02391                     break;
    02392                 } else if(IgnoreNonCriticalErrors) {
    02393                     continue;
    02394                 } else {
    02395                     break;
    02396                 }
    02397             }
    02398
    02399             if (KeyValueInformation->Type != REG_SZ) {
    02400                 continue;
    02401             }
    02402
    02403             ContinueEnumeration = TRUE;
    02404             TempUnicodeString.Length = 0;
    02405             IopRegistryDataToUnicodeString(&TempUnicodeString,
    02406                                            (PWSTR)KEY_VALUE_DATA(KeyValueInformation),
    02407                                            KeyValueInformation->DataLength
    02408                                            );
    02409             if (TempUnicodeString.Length) {
    02410
    02411                 //
    02412                 // We have retrieved a (non-empty) string for this service instance.
    02413                 // If the user specified a non-zero value for the DesiredAccess
    02414                 // parameter, we will attempt to open up the corresponding device
    02415                 // instance key under HKLM\System\Enum.
    02416                 //
    02417                 if (DesiredAccess) {
    02418                     Status = IopOpenRegistryKeyEx( &DeviceInstanceHandle,
    02419                                                    SystemEnumHandle,
    02420                                                    &TempUnicodeString,
    02421                                                    DesiredAccess
    02422                                                    );
    02423                 }
    02424
    02425                 if (NT_SUCCESS(Status)) {
    02426                     //
    02427                     // Invoke the specified callback routine for this device instance.
    02428                     //
    02429                     ContinueEnumeration = DevInstCallbackRoutine(DeviceInstanceHandle,
    02430                                                                  &TempUnicodeString,
    02431                                                                  Context
    02432                                                                 );
    02433                     if (DesiredAccess) {
    02434                         ZwClose(DeviceInstanceHandle);
    02435                     }
    02436                 } else if (IgnoreNonCriticalErrors) {
    02437                     continue;
    02438                 } else {
    02439                     break;
    02440                 }
    02441             } else {
    02442                 continue;
    02443             }
    02444             if (!ContinueEnumeration) {
    02445                 break;
    02446             }
    02447         }
    02448
    02449         if(DesiredAccess) {
    02450             ZwClose(SystemEnumHandle);
    02451         }
    02452         ExFreePool(KeyValueInformation);
    02453     }
    02454
    02455     if(ARGUMENT_PRESENT(ServiceInstanceOrdinal)) {
    02456         *ServiceInstanceOrdinal = i;
    02457     }
    02458
    02459 PrepareForReturn:
    02460
    02461     ZwClose(ServiceEnumHandle);
    02462
    02463     return Status;
    02464 }

NTSTATUS IopApplyFunctionToSubKeys | ( | IN HANDLE BaseHandle | OPTIONAL,
|  | IN PUNICODE_STRING | KeyName,
|  | IN ACCESS_MASK | DesiredAccess,
|  | IN ULONG | Flags,
|  | IN PIOP_SUBKEY_CALLBACK_ROUTINE | SubKeyCallbackRoutine,
|  | IN OUT PVOID | Context
| ) |

Definition at line 1844 of file pnpsubs.c.

    01855                    :
    01856
    01857     This routine enumerates all subkeys under the specified key, and calls
    01858     the specified callback routine for each subkey.
    01859
    01860 Arguments:
    01861
    01862     BaseHandle - Optional handle to the base registry path. If KeyName is also
    01863         specified, then KeyName represents a subkey under this path.  If KeyName
    01864         is not specified, the subkeys are enumerated under this handle.  If this
    01865         parameter is not specified, then the full path to the base key must be
    01866         given in KeyName.
    01867
    01868     KeyName - Optional name of the key whose subkeys are to be enumerated.
    01869
    01870     DesiredAccess - Specifies the desired access that the callback routine
    01871         needs to the subkeys.  If no desired access is specified (i.e.,
    01872         DesiredAccess is zero), then no handle will be opened for the
    01873         subkeys, and the callback will be passed a NULL for its SubKeyHandle
    01874         parameter.
    01875
    01876     Flags - Controls the behavior of subkey enumeration.  Currently, the
    01877         following flags are defined:
    01878
    01879         FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS - Specifies whether this
    01880             function should immediately terminate on all errors, or only on
    01881             critical ones.  An example of a non-critical error is when an
    01882             enumerated subkey cannot be opened for the desired access.
    01883
    01884         FUNCTION_SUBKEY_DELETE_SUBKEYS - Specifies that each subkey should be
    01885             deleted after the specified SubKeyCallBackRoutine has been performed
    01886             on it.  Note that this is NOT a recursive delete on each of the
    01887             subkeys, just an attempt to delete the subkey itself.  It the subkey
    01888             contains children, this will fail.
    01889
    01890     SubKeyCallbackRoutine - Supplies a pointer to a function that will
    01891         be called for each subkey found under the
    01892         specified key.  The prototype of the function
    01893         is as follows:
    01894
    01895             typedef BOOLEAN (*PIOP_SUBKEY_CALLBACK_ROUTINE) (
    01896                 IN     HANDLE SubKeyHandle,
    01897                 IN     PUNICODE_STRING SubKeyName,
    01898                 IN OUT PVOID Context
    01899                 );
    01900
    01901         where SubKeyHandle is the handle to an enumerated subkey under the
    01902         specified key, SubKeyName is its name, and Context is a pointer to
    01903         user-defined data.
    01904
    01905         This function should return TRUE to continue enumeration, or
    01906         FALSE to terminate it.
    01907
    01908     Context - Supplies a pointer to user-defined data that will be passed
    01909         in to the callback routine at each subkey invocation.
    01910
    01911 Return Value:
    01912
    01913     NT status code indicating whether the subkeys were successfully
    01914     enumerated.  Note that this does not provide information on the
    01915     success or failure of the callback routine--if desired, this
    01916     information should be stored in the Context structure.
    01917
    01918 --*/
    01919
    01920 {
    01921     NTSTATUS Status;
    01922     BOOLEAN CloseHandle = FALSE, ContinueEnumeration;
    01923     HANDLE Handle, SubKeyHandle;
    01924     ULONG i, RequiredBufferLength;
    01925     PKEY_BASIC_INFORMATION KeyInformation = NULL;
    01926     // Use an initial key name buffer size large enough for a 20-character key
    01927     // (+ terminating NULL)
    01928     ULONG KeyInformationLength = sizeof(KEY_BASIC_INFORMATION) + (20 * sizeof(WCHAR));
    01929     UNICODE_STRING SubKeyName;
    01930
    01931     if(ARGUMENT_PRESENT(KeyName)) {
    01932
    01933         Status = IopOpenRegistryKeyEx( &Handle,
    01934                                        BaseHandle,
    01935                                        KeyName,
    01936                                        KEY_READ
    01937                                        );
    01938         if(!NT_SUCCESS(Status)) {
    01939             return Status;
    01940         } else {
    01941             CloseHandle = TRUE;
    01942         }
    01943
    01944     } else {
    01945
    01946         Handle = BaseHandle;
    01947     }
    01948
    01949     //
    01950     // Enumerate the subkeys until we run out of them.
    01951     //
    01952     i = 0;
    01953     SubKeyHandle = NULL;
    01954
    01955     while(TRUE) {
    01956
    01957         if(!KeyInformation) {
    01958
    01959             KeyInformation = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool,
    01960                                                                     KeyInformationLength
    01961                                                                    );
    01962             if(!KeyInformation) {
    01963                 Status = STATUS_INSUFFICIENT_RESOURCES;
    01964                 break;
    01965             }
    01966         }
    01967
    01968         Status = ZwEnumerateKey(Handle,
    01969                                 i,
    01970                                 KeyBasicInformation,
    01971                                 KeyInformation,
    01972                                 KeyInformationLength,
    01973                                 &RequiredBufferLength
    01974                                );
    01975
    01976         if(!NT_SUCCESS(Status)) {
    01977             if(Status == STATUS_BUFFER_OVERFLOW) {
    01978                 //
    01979                 // Try again with larger buffer.
    01980                 //
    01981                 ExFreePool(KeyInformation);
    01982                 KeyInformation = NULL;
    01983                 KeyInformationLength = RequiredBufferLength;
    01984                 continue;
    01985
    01986             } else if(Status == STATUS_NO_MORE_ENTRIES) {
    01987                 //
    01988                 // break out of loop
    01989                 //
    01990                 Status = STATUS_SUCCESS;
    01991                 break;
    01992
    01993             } else {
    01994                 //
    01995                 // This is a non-critical error.
    01996                 //
    01997                 if(Flags & FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS) {
    01998                     goto ContinueWithNextSubKey;
    01999                 } else {
    02000                     break;
    02001                 }
    02002             }
    02003         }
    02004
    02005         //
    02006         // Initialize a unicode string with this key name.  Note that this string
    02007         // WILL NOT be NULL-terminated.
    02008         //
    02009         SubKeyName.Length = SubKeyName.MaximumLength = (USHORT)KeyInformation->NameLength;
    02010         SubKeyName.Buffer = KeyInformation->Name;
    02011
    02012         //
    02013         // If DesiredAccess is non-zero, open a handle to this subkey.
    02014         //
    02015         if(DesiredAccess) {
    02016             Status = IopOpenRegistryKeyEx( &SubKeyHandle,
    02017                                            Handle,
    02018                                            &SubKeyName,
    02019                                            DesiredAccess
    02020                                            );
    02021             if(!NT_SUCCESS(Status)) {
    02022                 //
    02023                 // This is a non-critical error.
    02024                 //
    02025                 if(Flags & FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS) {
    02026                     goto ContinueWithNextSubKey;
    02027                 } else {
    02028                     break;
    02029                 }
    02030             }
    02031         }
    02032
    02033         //
    02034         // Invoke the supplied callback function for this subkey.
    02035         //
    02036         ContinueEnumeration = SubKeyCallbackRoutine(SubKeyHandle, &SubKeyName, Context);
    02037
    02038         if (DesiredAccess) {
    02039             if (ContinueEnumeration &&
    02040                 (Flags & FUNCTIONSUBKEY_FLAG_DELETE_SUBKEYS)) {
    02041                 //
    02042                 // Delete the key when asked to, only if the callback routine
    02043                 // was successful, otherwise we may not be able to.
    02044                 //
    02045                 Status = ZwDeleteKey(SubKeyHandle);
    02046             }
    02047             ZwClose(SubKeyHandle);
    02048         }
    02049
    02050         if(!ContinueEnumeration) {
    02051             //
    02052             // Enumeration has been aborted.
    02053             //
    02054             Status = STATUS_SUCCESS;
    02055             break;
    02056
    02057         }
    02058
    02059 ContinueWithNextSubKey:
    02060         if (!(Flags & FUNCTIONSUBKEY_FLAG_DELETE_SUBKEYS)) {
    02061             //
    02062             // Only increment the enumeration index for non-deleted subkeys
    02063             //
    02064             i++;
    02065         }
    02066     }
    02067
    02068     if(KeyInformation) {
    02069         ExFreePool(KeyInformation);
    02070     }
    02071
    02072     if(CloseHandle) {
    02073         ZwClose(Handle);
    02074     }
    02075
    02076     return Status;
    02077 }

NTSTATUS IopBusNumberInitialize | ( | VOID |  | ) |

| Referenced by IopInitializePlugPlayServices().

NTSTATUS IopCallDriverAddDevice | ( | IN PDEVICE_NODE | DeviceNode,
|  | IN BOOLEAN | LoadDriver,
|  | IN PADD_CONTEXT | AddContext
| ) |

Definition at line 2525 of file pnpenum.c.

References ASSERT, ASSERT_INITED, ASSERTMSG, _DEVICE_OBJECT::AttachedDevice, CmRegistryMachineSystemCurrentControlSetControlClass, CmRegistryMachineSystemCurrentControlSetEnumName, DbgPrint, DebugPrint, _DEVICE_OBJECT::DeviceObjectExtension, DeviceService, DNF_ADDED, DNF_LEGACY_DRIVER, DO_DEVICE_INITIALIZING, DOE_BOTTOM_OF_FDO_STACK, DOE_DESIGNATED_FDO, DOE_RAW_FDO, ExFreePool(), _DEVOBJ_EXTENSION::ExtensionFlags, FALSE, _DEVICE_OBJECT::Flags, InitSafeBootMode, IoGetAttachedDevice(), IopBootLog(), IopCallDriverAddDeviceQueryRoutine(), IopChangeDeviceObjectFromRegistryProperties(), IopClearDevNodeProblem, IopDeviceNodeFlagsToCapabilities, IopGetRegistryValue(), IopOpenRegistryKeyEx(), IopQueryLegacyBusInformation(), IopRegistryDataToUnicodeString, IopRequestDeviceRemoval(), IopSafebootDriverLoad(), IopSetDevNodeProblem, KEY_VALUE_DATA, LowerClassFilters, LowerDeviceFilters, MaximumAddStage, _DRIVER_LIST_ENTRY::NextEntry, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, OK_TO_ADD_DEVICE, PDRIVER_ADD_DEVICE, PDRIVER_LIST_ENTRY, RtlInitUnicodeString(), RtlQueryRegistryValues(), TRUE, UpperClassFilters, and UpperDeviceFilters.

Referenced by IopAddDevicesToBootDriverWorker(), IopNewDevice(), IopProcessAddDevicesWorker(), and IopProcessNewChildren().

    02533                    :
    02534
    02535     This function checks if the driver for the DeviceNode is present and loads
    02536     the driver if necessary.
    02537
    02538 Arguments:
    02539
    02540     DeviceNode - Supplies a pointer to the device node to be enumerated.
    02541
    02542     LoadDriver - Supplies a BOOLEAN value to indicate should a driver be loaded
    02543                  to complete enumeration.
    02544
    02545     Context - Supplies a pointer to ADD_CONTEXT to control how the device be added.
    02546
    02547 Return Value:
    02548
    02549     NTSTATUS code.
    02550
    02551 --*/
    02552
    02553 {
    02554     HANDLE enumKey;
    02555     HANDLE instanceKey;
    02556     HANDLE classKey = NULL;
    02557     HANDLE classPropsKey = NULL;
    02558     PKEY_VALUE_FULL_INFORMATION keyValueInformation = NULL;
    02559     RTL_QUERY_REGISTRY_TABLE queryTable[3];
    02560     QUERY_CONTEXT queryContext;
    02561     BOOLEAN deviceRaw = FALSE;
    02562     BOOLEAN usePdoCharacteristics = TRUE;
    02563     NTSTATUS status;
    02564     DEVICE_CAPABILITIES capabilities;
    02565     ULONG index;
    02566     PDEVICE_OBJECT deviceObject;
    02567 #ifndef NO_SPECIAL_IRP
    02568     PDEVICE_OBJECT fdoDeviceObject, topOfPdoStack, topOfLowerFilterStack;
    02569     BOOLEAN deviceObjectHasBeenAttached = FALSE;
    02570 #endif
    02571
    02572     DebugPrint(1, ("IopCallDriverAddDevice: Processing devnode %#08lx\n",
    02573                    DeviceNode));
    02574
    02575     DebugPrint(1, ("IopCallDriverAddDevice: DevNode flags going in = %#08lx\n",
    02576                    DeviceNode->Flags));
    02577
    02578     //
    02579     // The device node may have been started at this point.  This is because
    02580     // some ill-behaved miniport drivers call IopReportedDetectedDevice at
    02581     // DriverEntry for the devices which we already know about.
    02582     //
    02583
    02584     if (!OK_TO_ADD_DEVICE(DeviceNode)) {
    02585         return STATUS_SUCCESS;
    02586     }
    02587
    02588     ASSERT_INITED(DeviceNode->PhysicalDeviceObject);
    02589
    02590     DebugPrint(1, ("IopCallDriverAddDevice:\t%s load driver\n",
    02591                    (LoadDriver ? "Will" : "Won't")));
    02592
    02593     DebugPrint(1, ("IopCallDriverAddDevice:\tOpening registry key %wZ\n",
    02594                    &DeviceNode->InstancePath));
    02595
    02596     //
    02597     // Open the HKLM\System\CCS\Enum key.
    02598     //
    02599
    02600     status = IopOpenRegistryKeyEx( &enumKey,
    02601                                    NULL,
    02602                                    &CmRegistryMachineSystemCurrentControlSetEnumName,
    02603                                    KEY_READ
    02604                                    );
    02605
    02606     if (!NT_SUCCESS(status)) {
    02607         DebugPrint(1, ("IopCallDriverAddDevice:\tUnable to open "
    02608                        "HKLM\\SYSTEM\\CCS\\ENUM\n"));
    02609         return status;
    02610     }
    02611
    02612     //
    02613     // Open the instance key for this devnode
    02614     //
    02615
    02616     status = IopOpenRegistryKeyEx( &instanceKey,
    02617                                    enumKey,
    02618                                    &DeviceNode->InstancePath,
    02619                                    KEY_READ
    02620                                    );
    02621
    02622     ZwClose(enumKey);
    02623
    02624     if (!NT_SUCCESS(status)) {
    02625
    02626         DebugPrint(1, ("IopCallDriverAddDevice:\t\tError %#08lx opening enum key\n",
    02627                     status));
    02628         return status;
    02629     }
    02630
    02631     //
    02632     // Get the class value to locate the class key for this devnode
    02633     //
    02634
    02635     status = IopGetRegistryValue(instanceKey,
    02636                                  REGSTR_VALUE_CLASSGUID,
    02637                                  &keyValueInformation);
    02638
    02639     if (NT_SUCCESS(status) && ((keyValueInformation->Type == REG_SZ) &&
    02640                               (keyValueInformation->DataLength != 0))) {
    02641
    02642         HANDLE controlKey;
    02643         UNICODE_STRING unicodeClassGuid;
    02644
    02645         IopRegistryDataToUnicodeString(
    02646             &unicodeClassGuid,
    02647             (PWSTR) KEY_VALUE_DATA(keyValueInformation),
    02648             keyValueInformation->DataLength);
    02649
    02650         DebugPrint(1, ("IopCallDriverAddDevice:\t\tClass GUID is %wZ\n",
    02651                        &unicodeClassGuid));
    02652
    02653         if (InitSafeBootMode) {
    02654             if (!IopSafebootDriverLoad(&unicodeClassGuid)) {
    02655                 PKEY_VALUE_FULL_INFORMATION ClassValueInformation = NULL;
    02656                 NTSTATUS s;
    02657
    02658                 //
    02659                 // don't load the driver
    02660                 //
    02661                 DbgPrint("SAFEBOOT: skipping device = %wZ\n",&unicodeClassGuid);
    02662                 s = IopGetRegistryValue(instanceKey,
    02663                                         REGSTR_VAL_DEVDESC,
    02664                                         &ClassValueInformation);
    02665                 if (NT_SUCCESS(s)) {
    02666                     UNICODE_STRING ClassString;
    02667
    02668                     RtlInitUnicodeString(&ClassString, (PCWSTR) KEY_VALUE_DATA(ClassValueInformation));
    02669
    02670                     IopBootLog(&ClassString, FALSE);
    02671                 } else {
    02672                     IopBootLog(&unicodeClassGuid, FALSE);
    02673                 }
    02674                 return STATUS_UNSUCCESSFUL;
    02675             }
    02676         }
    02677
    02678         //
    02679         // Open the class key
    02680         //
    02681
    02682         status = IopOpenRegistryKeyEx( &controlKey,
    02683                                        NULL,
    02684                                        &CmRegistryMachineSystemCurrentControlSetControlClass,
    02685                                        KEY_READ
    02686                                        );
    02687
    02688         if (!NT_SUCCESS(status)) {
    02689
    02690             DebugPrint(1, ("IopCallDriverAddDevice:\tUnable to open "
    02691                         "HKLM\\SYSTEM\\CCS\\CONTROL\\CLASS - %#08lx\n",
    02692                         status));
    02693             classKey = NULL;
    02694         } else {
    02695
    02696             status = IopOpenRegistryKeyEx( &classKey,
    02697                                            controlKey,
    02698                                            &unicodeClassGuid,
    02699                                            KEY_READ
    02700                                            );
    02701
    02702             ZwClose(controlKey);
    02703
    02704             if (!NT_SUCCESS(status)) {
    02705
    02706                 DebugPrint(1, ("IopCallDriverAddDevice:\tUnable to open GUID key "
    02707                             "%wZ - %#08lx\n",
    02708                             &unicodeClassGuid,
    02709                             status));
    02710
    02711                 classKey = NULL;
    02712             }
    02713         }
    02714
    02715         if (classKey != NULL) {
    02716
    02717             UNICODE_STRING unicodeProperties;
    02718
    02719             RtlInitUnicodeString(&unicodeProperties, REGSTR_KEY_DEVICE_PROPERTIES );
    02720
    02721             status = IopOpenRegistryKeyEx( &classPropsKey,
    02722                                            classKey,
    02723                                            &unicodeProperties,
    02724                                            KEY_READ
    02725                                            );
    02726
    02727             if (!NT_SUCCESS(status)) {
    02728
    02729                 DebugPrint(2, ("IopCallDriverAddDevice:\tUnable to open GUID\\Properties key "
    02730                             "%wZ - %#08lx\n",
    02731                             &unicodeClassGuid,
    02732                             status));
    02733
    02734                 classPropsKey = NULL;
    02735             }
    02736         }
    02737
    02738         ExFreePool(keyValueInformation);
    02739         keyValueInformation = NULL;
    02740
    02741     }
    02742
    02743     //
    02744     // Check to see if there's a service assigned to this device node.  If
    02745     // there's not then we can bail out without wasting too much time.
    02746     //
    02747
    02748     RtlZeroMemory(&queryContext, sizeof(queryContext));
    02749
    02750     queryContext.DeviceNode = DeviceNode;
    02751     queryContext.LoadDriver = LoadDriver;
    02752
    02753     queryContext.AddContext = Context;
    02754
    02755     RtlZeroMemory(queryTable, sizeof(queryTable));
    02756
    02757     queryTable[0].QueryRoutine =
    02758         (PRTL_QUERY_REGISTRY_ROUTINE) IopCallDriverAddDeviceQueryRoutine;
    02759     queryTable[0].Name = REGSTR_VAL_LOWERFILTERS;
    02760     queryTable[0].EntryContext = (PVOID) UIntToPtr(LowerDeviceFilters);
    02761
    02762     status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
    02763                                     (PWSTR) instanceKey,
    02764                                     queryTable,
    02765                                     &queryContext,
    02766                                     NULL);
    02767     if (NT_SUCCESS(status)) {
    02768
    02769         if (classKey != NULL) {
    02770
    02771             queryTable[0].QueryRoutine =
    02772                 (PRTL_QUERY_REGISTRY_ROUTINE) IopCallDriverAddDeviceQueryRoutine;
    02773             queryTable[0].Name = REGSTR_VAL_LOWERFILTERS;
    02774             queryTable[0].EntryContext = (PVOID) UIntToPtr(LowerClassFilters);
    02775             status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
    02776                                             (PWSTR) classKey,
    02777                                             queryTable,
    02778                                             &queryContext,
    02779                                             NULL);
    02780         }
    02781
    02782         if (NT_SUCCESS(status)) {
    02783             queryTable[0].QueryRoutine = (PRTL_QUERY_REGISTRY_ROUTINE) IopCallDriverAddDeviceQueryRoutine;
    02784             queryTable[0].Name = REGSTR_VALUE_SERVICE;
    02785             queryTable[0].EntryContext = (PVOID) UIntToPtr(DeviceService);
    02786             queryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
    02787
    02788             status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
    02789                                             (PWSTR) instanceKey,
    02790                                             queryTable,
    02791                                             &queryContext,
    02792                                             NULL);
    02793         }
    02794     }
    02795
    02796     if (DeviceNode->Flags & DNF_LEGACY_DRIVER) {
    02797
    02798         //
    02799         // One of the services for this device is a legacy driver.  Don't try
    02800         // to add any filters since we'll just screw up the device stack.
    02801         //
    02802
    02803         status = STATUS_SUCCESS;
    02804         goto Cleanup;
    02805
    02806     } else if (NT_SUCCESS(status)) {
    02807
    02808         //
    02809         // Call was successful so we must have been able to reference the
    02810         // driver object.
    02811         //
    02812
    02813         ASSERT(queryContext.DriverLists[DeviceService] != NULL);
    02814
    02815         if (queryContext.DriverLists[DeviceService]->NextEntry != NULL) {
    02816
    02817             //
    02818             // There's more than one service assigned to this device.  Configuration
    02819             // error
    02820
    02821             DebugPrint(1, ("IopCallDriverAddDevice: Configuration Error - more "
    02822                         "than one service in driver list\n"));
    02823
    02824             IopSetDevNodeProblem(DeviceNode, CM_PROB_REGISTRY);
    02825
    02826             status = STATUS_UNSUCCESSFUL;
    02827
    02828             goto Cleanup;
    02829         }
    02830         //
    02831         // this is the only case (FDO specified) where we can ignore PDO's characteristics
    02832         //
    02833         usePdoCharacteristics = FALSE;
    02834
    02835     } else if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
    02836
    02837         DebugPrint(1, ("IopCallDriverAddDevice\t\tError %#08lx reading service "
    02838                        "value for devnode %#08lx\n", status, DeviceNode));
    02839
    02840         if (!IopDeviceNodeFlagsToCapabilities(DeviceNode)->RawDeviceOK) {
    02841
    02842             //
    02843             // The device cannot be used raw.  Bail out now.
    02844             //
    02845
    02846             status = STATUS_UNSUCCESSFUL;
    02847             goto Cleanup;
    02848
    02849         } else {
    02850
    02851             //
    02852             // Raw device access is okay.
    02853             //
    02854
    02855             IopClearDevNodeProblem(DeviceNode);
    02856
    02857             usePdoCharacteristics = TRUE; // shouldn't need to do this, but better be safe than sorry
    02858             deviceRaw = TRUE;
    02859             status = STATUS_SUCCESS;
    02860
    02861         }
    02862
    02863     } else {
    02864
    02865         //
    02866         // something else went wrong while parsing the service key.  The
    02867         // query routine will have set the flags appropriately so we can
    02868         // just bail out.
    02869         //
    02870
    02871         goto Cleanup;
    02872
    02873     }
    02874
    02875     //
    02876     // For each type of filter driver we want to build a list of the driver
    02877     // objects to be loaded.  We'll build all the driver lists if we can
    02878     // and deal with error conditions afterwards.
    02879     //
    02880
    02881      //
    02882      // First get all the information we have to out of the instance key and
    02883      // the device node.
    02884      //
    02885
    02886      RtlZeroMemory(queryTable, sizeof(queryTable));
    02887
    02888      queryTable[0].QueryRoutine =
    02889          (PRTL_QUERY_REGISTRY_ROUTINE) IopCallDriverAddDeviceQueryRoutine;
    02890      queryTable[0].Name = REGSTR_VAL_UPPERFILTERS;
    02891      queryTable[0].EntryContext = (PVOID) UIntToPtr(UpperDeviceFilters);
    02892      status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
    02893                                      (PWSTR) instanceKey,
    02894                                      queryTable,
    02895                                      &queryContext,
    02896                                      NULL);
    02897
    02898      if (NT_SUCCESS(status) && classKey) {
    02899          queryTable[0].QueryRoutine =
    02900              (PRTL_QUERY_REGISTRY_ROUTINE) IopCallDriverAddDeviceQueryRoutine;
    02901          queryTable[0].Name = REGSTR_VAL_UPPERFILTERS;
    02902          queryTable[0].EntryContext = (PVOID) UIntToPtr(UpperClassFilters);
    02903
    02904          status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
    02905                                          (PWSTR) classKey,
    02906                                          queryTable,
    02907                                          &queryContext,
    02908                                          NULL);
    02909     }
    02910
    02911     if (NT_SUCCESS(status)) {
    02912
    02913         UCHAR serviceType = 0;
    02914         PDRIVER_LIST_ENTRY listEntry = queryContext.DriverLists[serviceType];
    02915
    02916         //
    02917         // Make sure there's no more than one device service.  Anything else is
    02918         // a configuration error.
    02919         //
    02920
    02921         ASSERT(!(DeviceNode->Flags & DNF_LEGACY_DRIVER));
    02922         ASSERT(!(DeviceNode->Flags & DNF_ADDED));
    02923
    02924         ASSERTMSG(
    02925             "Error - Device has no service but cannot be run RAW\n",
    02926             ((queryContext.DriverLists[DeviceService] != NULL) || (deviceRaw)));
    02927
    02928 #ifndef NO_SPECIAL_IRP
    02929         //
    02930         // Grab the top of PDO stack
    02931         //
    02932         topOfPdoStack = IoGetAttachedDevice(DeviceNode->PhysicalDeviceObject);
    02933 #endif
    02934
    02935         //
    02936         // It's okay to try adding all the drivers.
    02937         //
    02938         for (serviceType = 0; serviceType < MaximumAddStage; serviceType++) {
    02939
    02940             DebugPrint(1, ("IopCallDriverAddDevice: Adding Services (type %d)\n",
    02941                         serviceType));
    02942
    02943             if (serviceType == DeviceService) {
    02944
    02945                 if (deviceRaw&&(queryContext.DriverLists[serviceType]==NULL)) {
    02946
    02947                     //
    02948                     // Mark the devnode as added, as it has no service.
    02949                     //
    02950
    02951                     ASSERT(queryContext.DriverLists[serviceType] == NULL);
    02952                     DeviceNode->Flags |= DNF_ADDED;
    02953
    02954 #ifndef NO_SPECIAL_IRP
    02955                     //
    02956                     // For the purpose of asserting IRPs, we mark the FDO. We
    02957                     // don't mark a raw PDO as the BOTTOM of the FDO stack as
    02958                     // that would be the lower filter in this case.
    02959                     //
    02960                     DeviceNode->PhysicalDeviceObject->DeviceObjectExtension->ExtensionFlags |=
    02961                         DOE_DESIGNATED_FDO | DOE_RAW_FDO;
    02962
    02963                 } else {
    02964
    02965                     //
    02966                     // Since we are going to see a service, grab a pointer to
    02967                     // the current top of the stack. While here, assert there
    02968                     // is exactly one service driver to load...
    02969                     //
    02970                     ASSERT(queryContext.DriverLists[serviceType]);
    02971                     ASSERT(!queryContext.DriverLists[serviceType]->NextEntry);
    02972                     topOfLowerFilterStack = IoGetAttachedDevice(DeviceNode->PhysicalDeviceObject);
    02973 #endif
    02974                 }
    02975             }
    02976
    02977             for (listEntry = queryContext.DriverLists[serviceType];
    02978                 listEntry != NULL;
    02979                 listEntry = listEntry->NextEntry) {
    02980
    02981                 PDRIVER_ADD_DEVICE addDeviceRoutine;
    02982
    02983                 DebugPrint(1, ("IopCallDriverAddDevice:\tAdding driver %#08lx\n",
    02984                             listEntry->DriverObject));
    02985
    02986                 ASSERT(listEntry->DriverObject);
    02987                 ASSERT(listEntry->DriverObject->DriverExtension);
    02988                 ASSERT(listEntry->DriverObject->DriverExtension->AddDevice);
    02989
    02990                 //
    02991                 // Invoke the driver's AddDevice() entry point.
    02992                 //
    02993                 addDeviceRoutine =
    02994                     listEntry->DriverObject->DriverExtension->AddDevice;
    02995
    02996                 status = (addDeviceRoutine)(listEntry->DriverObject,
    02997                                             DeviceNode->PhysicalDeviceObject);
    02998
    02999                 DebugPrint(1, ("IopCallDriverAddDevice:\t\tRoutine returned "
    03000                             "%#08lx\n", status));
    03001
    03002                 if (NT_SUCCESS(status)) {
    03003
    03004 #ifndef NO_SPECIAL_IRP
    03005                    if (!deviceObjectHasBeenAttached) {
    03006
    03007                        //
    03008                        // Mark the first driver loaded by this routine as the
    03009                        // bottom of the FDO stack. These must detach on a remove.
    03010                        // Note we can't simply flag the top of the stack, as
    03011                        // someone might attach in AddDevice...
    03012                        //
    03013                        fdoDeviceObject = topOfPdoStack->AttachedDevice;
    03014                        if (fdoDeviceObject) {
    03015
    03016                           fdoDeviceObject->DeviceObjectExtension->ExtensionFlags |= DOE_BOTTOM_OF_FDO_STACK;
    03017                           deviceObjectHasBeenAttached = TRUE;
    03018                        }
    03019                    }
    03020
    03021                    //
    03022                    // Also note it is legal for a filter to succeed AddDevice
    03023                    // but fail to attach anything to the top of the stack.
    03024                    //
    03025                    if (serviceType == DeviceService) {
    03026
    03027                        //
    03028                        // ADRIAO BUGBUG 10/07/98 - Since we are temporarily
    03029                        // letting successful but Noop'd AddDevice's through,
    03030                        // mark the stack appropriately. We will make it look
    03031                        // like a RAW FDO
    03032                        //
    03033                        fdoDeviceObject = topOfLowerFilterStack->AttachedDevice;
    03034
    03035                        //ASSERT(fdoDeviceObject != NULL);
    03036
    03037                        if (!fdoDeviceObject) {
    03038
    03039                            //
    03040                            // Nope, didn't get an FDO. Mark the PDO raw.
    03041                            // ADRIAO BUGBUG 10/07/98 -
    03042                            //      Another reason to complain about the legality
    03043                            // of succeeding a FDO AddDevice without attaching
    03044                            // anything - how does the PDO know he also has to
    03045                            // respond as an FDO????
    03046                            //
    03047                            fdoDeviceObject = DeviceNode->PhysicalDeviceObject;
    03048                            fdoDeviceObject->DeviceObjectExtension->ExtensionFlags |= DOE_RAW_FDO;
    03049                        }
    03050
    03051                        //
    03052                        // Mark appropriate node "FDO".
    03053                        //
    03054                        fdoDeviceObject->DeviceObjectExtension->ExtensionFlags |= DOE_DESIGNATED_FDO;
    03055                    }
    03056 #endif
    03057
    03058                    DeviceNode->Flags |= DNF_ADDED;
    03059                 } else if (serviceType == DeviceService) {
    03060
    03061                     //
    03062                     // If filter drivers return failure, keep going.
    03063                     //
    03064
    03065                     DeviceNode->Flags &= ~DNF_ADDED;
    03066                     IopSetDevNodeProblem(DeviceNode, CM_PROB_FAILED_ADD);
    03067                     IopRequestDeviceRemoval(DeviceNode->PhysicalDeviceObject, CM_PROB_FAILED_ADD);
    03068                     goto Cleanup;
    03069                 }
    03070
    03071                 if (IoGetAttachedDevice(DeviceNode->PhysicalDeviceObject)->Flags & DO_DEVICE_INITIALIZING) {
    03072                     DebugPrint(1, ("***************** DO_DEVICE_INITIALIZING not cleared on %#08lx\n",
    03073                                 IoGetAttachedDevice(DeviceNode->PhysicalDeviceObject)));
    03074                 }
    03075
    03076                 ASSERT_INITED(IoGetAttachedDevice(DeviceNode->PhysicalDeviceObject));
    03077             }
    03078         }
    03079
    03080         //
    03081         // change PDO and all attached objects
    03082         // to have properties specified in the registry
    03083         //
    03084
    03085         IopChangeDeviceObjectFromRegistryProperties(DeviceNode->PhysicalDeviceObject, classPropsKey, instanceKey, usePdoCharacteristics);
    03086
    03087         //
    03088         // CapabilityFlags are refreshed with call to IopDeviceCapabilitiesToRegistry after device is started
    03089         //
    03090
    03091     } else {
    03092
    03093         DebugPrint(1, ("IopCallDriverAddDevice: Error %#08lx while building "
    03094                     "driver load list\n", status));
    03095     }
    03096
    03097     deviceObject = DeviceNode->PhysicalDeviceObject;
    03098
    03099     status = IopQueryLegacyBusInformation(
    03100                  deviceObject,
    03101                  NULL,
    03102                  &DeviceNode->InterfaceType,
    03103                  &DeviceNode->BusNumber
    03104              );
    03105
    03106     if (!NT_SUCCESS(status)) {
    03107
    03108         DeviceNode->InterfaceType = InterfaceTypeUndefined;
    03109         DeviceNode->BusNumber = 0xfffffff0;
    03110
    03111     }
    03112
    03113     status = STATUS_SUCCESS;
    03114
    03115 Cleanup:
    03116     {
    03117
    03118         UCHAR i;
    03119
    03120         DebugPrint(1, ("IopCallDriverAddDevice: DevNode flags leaving = %#08lx\n",
    03121                     DeviceNode->Flags));
    03122
    03123         DebugPrint(1, ("IopCallDriverAddDevice: Cleaning up\n"));
    03124
    03125         //
    03126         // Free the entries in the driver load list & release the references on
    03127         // their driver objects.
    03128         //
    03129
    03130         for (i = 0; i < MaximumAddStage; i++) {
    03131
    03132             PDRIVER_LIST_ENTRY listHead = queryContext.DriverLists[i];
    03133
    03134             while(listHead != NULL) {
    03135
    03136                 PDRIVER_LIST_ENTRY tmp = listHead;
    03137
    03138                 listHead = listHead->NextEntry;
    03139
    03140                 ASSERT(tmp->DriverObject != NULL);
    03141
    03142                 ObDereferenceObject(tmp->DriverObject);
    03143
    03144                 ExFreePool(tmp);
    03145             }
    03146         }
    03147     }
    03148
    03149     ZwClose(instanceKey);
    03150
    03151     if (classKey != NULL) {
    03152         ZwClose(classKey);
    03153     }
    03154
    03155     if (classPropsKey != NULL) {
    03156         ZwClose(classPropsKey);
    03157     }
    03158
    03159     DebugPrint(1, ("IopCallDriverAddDevice: Returning status %#08lx\n", status));
    03160
    03161     return status;
    03162 }

VOID IopChainDereferenceComplete | ( | IN PDEVICE_OBJECT | PhysicalDeviceObject | ) |

Definition at line 84 of file pnpdel.c.

References ASSERT, DelayedWorkQueue, ExInitializeWorkItem, ExQueueWorkItem(), IopAcquireDeviceTreeLock, IopDelayedRemoveWorker(), IopGetRelationsCount(), IopGetRelationsTaggedCount(), IopPendingSurpriseRemovals, IopReleaseDeviceTreeLock, IopSetRelationsTag(), NT_SUCCESS, NTSTATUS(), PAGED_CODE, PENDING_RELATIONS_LIST_ENTRY, PsGetCurrentProcess, PsInitialSystemProcess, _PENDING_RELATIONS_LIST_ENTRY::RelationsList, TRUE, and _PENDING_RELATIONS_LIST_ENTRY::WorkItem.

Referenced by IopCompleteUnloadOrDelete(), and IopNotifyPnpWhenChainDereferenced().

    00090                    :
    00091
    00092     This routine is invoked when the reference count on a PDO and all its
    00093     attached devices transitions to a zero.  It tags the devnode as ready for
    00094     removal.  If all the devnodes are tagged then IopDelayedRemoveWorker is
    00095     called to actually send the remove IRPs.
    00096
    00097 Arguments:
    00098
    00099     PhysicalDeviceObject - Supplies a pointer to the PDO whose references just
    00100         went to zero.
    00101
    00102 Return Value:
    00103
    00104     None.
    00105
    00106 --*/
    00107
    00108 {
    00109     PPENDING_RELATIONS_LIST_ENTRY   entry;
    00110     PLIST_ENTRY                     link;
    00111     ULONG                           count;
    00112     ULONG                           taggedCount;
    00113     NTSTATUS                        status;
    00114
    00115     PAGED_CODE();
    00116
    00117     //
    00118     // Lock the whole device node tree so no one can touch the tree.
    00119     //
    00120
    00121     IopAcquireDeviceTreeLock();
    00122
    00123     //
    00124     // Find the relation list this devnode is a member of.
    00125     //
    00126     for (link = IopPendingSurpriseRemovals.Flink;
    00127          link != &IopPendingSurpriseRemovals;
    00128          link = link->Flink) {
    00129
    00130         entry = CONTAINING_RECORD(link, PENDING_RELATIONS_LIST_ENTRY, Link);
    00131
    00132         //
    00133         // Tag the devnode as ready for remove.  If it isn't in this list
    00134         //
    00135         status = IopSetRelationsTag( entry->RelationsList, PhysicalDeviceObject, TRUE );
    00136
    00137         if (NT_SUCCESS(status)) {
    00138             taggedCount = IopGetRelationsTaggedCount( entry->RelationsList );
    00139             count = IopGetRelationsCount( entry->RelationsList );
    00140
    00141             if (taggedCount == count) {
    00142                 //
    00143                 // Remove relations list from list of pending surprise removals.
    00144                 //
    00145                 RemoveEntryList( link );
    00146
    00147                 IopReleaseDeviceTreeLock();
    00148
    00149                 if (PsGetCurrentProcess() != PsInitialSystemProcess) {
    00150
    00151                     //
    00152                     // Queue a work item to do the removal so we call the driver
    00153                     // in the system process context rather than the random one
    00154                     // we're in now.
    00155                     //
    00156
    00157                     ExInitializeWorkItem( &entry->WorkItem,
    00158                                         IopDelayedRemoveWorker,
    00159                                         entry);
    00160
    00161                     ExQueueWorkItem(&entry->WorkItem, DelayedWorkQueue);
    00162
    00163                 } else {
    00164
    00165                     //
    00166                     // We are already in the system process, so call the
    00167                     // worker inline.
    00168                     //
    00169
    00170                     IopDelayedRemoveWorker( entry );
    00171
    00172                 }
    00173
    00174                 return;
    00175             }
    00176
    00177             break;
    00178         }
    00179     }
    00180
    00181     IopReleaseDeviceTreeLock();
    00182
    00183     ASSERT(link != &IopPendingSurpriseRemovals);
    00184 }

NTSTATUS IopCleanupDeviceRegistryValues | ( | IN PUNICODE_STRING | InstancePath,
|  | IN BOOLEAN | KeepReference
| ) |

Definition at line 3960 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetEnumName, FALSE, IopOpenRegistryKey(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, and TITLE_INDEX_VALUE.

Referenced by IopDeleteLegacyKey(), IopDeleteLockedDeviceNode(), and IopUnlockDeviceRemovalRelations().

    03967                    :
    03968
    03969     This routine cleans up a device instance key when the device is no
    03970     longer present/enumerated.  If the device is registered to a Service
    03971     the Service's enum key will also been cleaned up.
    03972
    03973     Note the caller must lock the RegistryDeciceResource
    03974
    03975 Arguments:
    03976
    03977     InstancePath - supplies a pointer to the name of the device instance key.
    03978
    03979     KeepReference - supplies a boolean value to indicate if we should remove the
    03980         device instance path to device object mapping.
    03981
    03982 Return Value:
    03983
    03984     status
    03985
    03986 --*/
    03987
    03988 {
    03989     HANDLE handle, instanceHandle;
    03990     UNICODE_STRING unicodeValueName;
    03991     NTSTATUS status;
    03992     ULONG count = 0;
    03993     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    03994
    03995     PAGED_CODE();
    03996
    03997     //
    03998     // Open System\CurrentControlSet\Enum
    03999     //
    04000
    04001     status = IopOpenRegistryKeyEx( &handle,
    04002                                    NULL,
    04003                                    &CmRegistryMachineSystemCurrentControlSetEnumName,
    04004                                    KEY_ALL_ACCESS
    04005                                    );
    04006
    04007     if (!NT_SUCCESS( status )) {
    04008         return status;
    04009     }
    04010
    04011     //
    04012     // Open the device instance key
    04013     //
    04014
    04015     status = IopOpenRegistryKeyEx( &instanceHandle,
    04016                                    handle,
    04017                                    InstancePath,
    04018                                    KEY_ALL_ACCESS
    04019                                    );
    04020
    04021     ZwClose(handle);
    04022     if (!NT_SUCCESS( status )) {
    04023
    04024         //
    04025         // There is no registry key for the ServiceKeyName information.
    04026         //
    04027
    04028         return status;
    04029     }
    04030
    04031     //
    04032     // Delete the DeviceReference value name under Control key
    04033     //
    04034
    04035     if (!KeepReference) {
    04036
    04037         //
    04038         // BUGBUG (lonnym)--verify that removal of the following code fragment is valid.
    04039         //
    04040 #if 0
    04041         //
    04042         // Set the 'FoundAtEnum' value to false.
    04043         //
    04044
    04045         PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_FOUNDATENUM);
    04046         tmpValue = 0;
    04047         ZwSetValueKey(instanceHandle,
    04048                       &unicodeValueName,
    04049                       TITLE_INDEX_VALUE,
    04050                       REG_DWORD,
    04051                       &tmpValue,
    04052                       sizeof(tmpValue)
    04053                       );
    04054 #endif // (lonnym, verify removal to here)
    04055
    04056         PiWstrToUnicodeString(&unicodeValueName, REGSTR_KEY_CONTROL);
    04057         status = IopOpenRegistryKeyEx( &handle,
    04058                                        instanceHandle,
    04059                                        &unicodeValueName,
    04060                                        KEY_ALL_ACCESS
    04061                                        );
    04062         if (NT_SUCCESS( status )) {
    04063             PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_DEVICE_REFERENCE);
    04064             ZwDeleteValueKey(handle, &unicodeValueName);
    04065             ZwClose(handle);
    04066         }
    04067
    04068         //
    04069         // Deregister the device from its controlling service's service enum key
    04070         //
    04071
    04072         status = PiDeviceRegistration( InstancePath, FALSE, NULL );
    04073     }
    04074
    04075     ZwClose(instanceHandle);
    04076
    04077     return status;
    04078 }

PIO_RESOURCE_REQUIREMENTS_LIST IopCmResourcesToIoResources | ( | IN ULONG | SlotNumber,
|  | IN PCM_RESOURCE_LIST | CmResourceList,
|  | IN ULONG | Priority
| ) |

Definition at line 4392 of file pnpsubs.c.

References CmResourceTypeReserved, ExAllocatePool, NULL, PagedPool, and PnpDefaultInterfaceType.

Referenced by IopFilterResourceRequirementsList(), IopQueryConflictListInternal(), IopQueryDeviceResources(), IopReserveBootResourcesInternal(), IopRestoreResourcesInternal(), IoReportResourceUsageInternal(), and MapperMarkKey().

    04400                    :
    04401
    04402     This routines converts the input CmResourceList to IO_RESOURCE_REQUIREMENTS_LIST.
    04403
    04404 Arguments:
    04405
    04406     SlotNumber - supplies the SlotNumber the resources refer to.
    04407
    04408     CmResourceList - the cm resource list to convert.
    04409
    04410     Priority - specifies the priority of the logconfig
    04411
    04412 Return Value:
    04413
    04414     returns a IO_RESOURCE_REQUIREMENTS_LISTST if succeeds.  Otherwise a NULL value is
    04415     returned.
    04416
    04417 --*/
    04418 {
    04419     PIO_RESOURCE_REQUIREMENTS_LIST ioResReqList;
    04420     ULONG count = 0, size, i, j;
    04421     PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc;
    04422     PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartDesc;
    04423     PIO_RESOURCE_DESCRIPTOR ioDesc;
    04424
    04425     //
    04426     // First determine number of descriptors required.
    04427     //
    04428
    04429     cmFullDesc = &CmResourceList->List[0];
    04430     for (i = 0; i < CmResourceList->Count; i++) {
    04431         count += cmFullDesc->PartialResourceList.Count;
    04432         cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
    04433         for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) {
    04434             size = 0;
    04435             switch (cmPartDesc->Type) {
    04436             case CmResourceTypeDeviceSpecific:
    04437                  size = cmPartDesc->u.DeviceSpecificData.DataSize;
    04438                  count--;
    04439                  break;
    04440             }
    04441             cmPartDesc++;
    04442             cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size);
    04443         }
    04444         cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc;
    04445     }
    04446
    04447     if (count == 0) {
    04448         return NULL;
    04449     }
    04450
    04451     //
    04452     // Count the extra descriptors for InterfaceType and BusNumber information.
    04453     //
    04454
    04455     count += CmResourceList->Count - 1;
    04456
    04457     //
    04458     // Allocate heap space for IO RESOURCE REQUIREMENTS LIST
    04459     //
    04460
    04461     count++;           // add one for CmResourceTypeConfigData
    04462     ioResReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)ExAllocatePool(
    04463                        PagedPool,
    04464                        sizeof(IO_RESOURCE_REQUIREMENTS_LIST) +
    04465                            count * sizeof(IO_RESOURCE_DESCRIPTOR)
    04466                        );
    04467     if (!ioResReqList) {
    04468         return NULL;
    04469     }
    04470
    04471     //
    04472     // Parse the cm resource descriptor and build its corresponding IO resource descriptor
    04473     //
    04474
    04475     ioResReqList->InterfaceType = CmResourceList->List[0].InterfaceType;
    04476     ioResReqList->BusNumber = CmResourceList->List[0].BusNumber;
    04477     ioResReqList->SlotNumber = SlotNumber;
    04478     ioResReqList->Reserved[0] = 0;
    04479     ioResReqList->Reserved[1] = 0;
    04480     ioResReqList->Reserved[2] = 0;
    04481     ioResReqList->AlternativeLists = 1;
    04482     ioResReqList->List[0].Version = 1;
    04483     ioResReqList->List[0].Revision = 1;
    04484     ioResReqList->List[0].Count = count;
    04485
    04486     //
    04487     // Generate a CmResourceTypeConfigData descriptor
    04488     //
    04489
    04490     ioDesc = &ioResReqList->List[0].Descriptors[0];
    04491     ioDesc->Option = IO_RESOURCE_PREFERRED;
    04492     ioDesc->Type = CmResourceTypeConfigData;
    04493     ioDesc->ShareDisposition = CmResourceShareShared;
    04494     ioDesc->Flags = 0;
    04495     ioDesc->Spare1 = 0;
    04496     ioDesc->Spare2 = 0;
    04497     ioDesc->u.ConfigData.Priority = Priority;
    04498     ioDesc++;
    04499
    04500     cmFullDesc = &CmResourceList->List[0];
    04501     for (i = 0; i < CmResourceList->Count; i++) {
    04502         if (i != 0) {
    04503
    04504             //
    04505             // Set up descriptor to remember the InterfaceType and BusNumber.
    04506             //
    04507
    04508             ioDesc->Option = IO_RESOURCE_PREFERRED;
    04509             ioDesc->Type = CmResourceTypeReserved;
    04510             ioDesc->ShareDisposition = CmResourceShareUndetermined;
    04511             ioDesc->Flags = 0;
    04512             ioDesc->Spare1 = 0;
    04513             ioDesc->Spare2 = 0;
    04514             if (cmFullDesc->InterfaceType == InterfaceTypeUndefined) {
    04515                 ioDesc->u.DevicePrivate.Data[0] = PnpDefaultInterfaceType;
    04516             } else {
    04517                 ioDesc->u.DevicePrivate.Data[0] = cmFullDesc->InterfaceType;
    04518             }
    04519             ioDesc->u.DevicePrivate.Data[1] = cmFullDesc->BusNumber;
    04520             ioDesc->u.DevicePrivate.Data[2] = 0;
    04521             ioDesc++;
    04522         }
    04523         cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
    04524         for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) {
    04525             ioDesc->Option = IO_RESOURCE_PREFERRED;
    04526             ioDesc->Type = cmPartDesc->Type;
    04527             ioDesc->ShareDisposition = cmPartDesc->ShareDisposition;
    04528             ioDesc->Flags = cmPartDesc->Flags;
    04529             ioDesc->Spare1 = 0;
    04530             ioDesc->Spare2 = 0;
    04531
    04532             size = 0;
    04533             switch (cmPartDesc->Type) {
    04534             case CmResourceTypePort:
    04535                  ioDesc->u.Port.MinimumAddress = cmPartDesc->u.Port.Start;
    04536                  ioDesc->u.Port.MaximumAddress.QuadPart = cmPartDesc->u.Port.Start.QuadPart +
    04537                                                              cmPartDesc->u.Port.Length - 1;
    04538                  ioDesc->u.Port.Alignment = 1;
    04539                  ioDesc->u.Port.Length = cmPartDesc->u.Port.Length;
    04540                  ioDesc++;
    04541                  break;
    04542             case CmResourceTypeInterrupt:
    04543 #if defined(_X86_)
    04544                 ioDesc->u.Interrupt.MinimumVector = ioDesc->u.Interrupt.MaximumVector =
    04545                    cmPartDesc->u.Interrupt.Level;
    04546 #else
    04547                  ioDesc->u.Interrupt.MinimumVector = ioDesc->u.Interrupt.MaximumVector =
    04548                     cmPartDesc->u.Interrupt.Vector;
    04549 #endif
    04550                  ioDesc++;
    04551                  break;
    04552             case CmResourceTypeMemory:
    04553                  ioDesc->u.Memory.MinimumAddress = cmPartDesc->u.Memory.Start;
    04554                  ioDesc->u.Memory.MaximumAddress.QuadPart = cmPartDesc->u.Memory.Start.QuadPart +
    04555                                                                cmPartDesc->u.Memory.Length - 1;
    04556                  ioDesc->u.Memory.Alignment = 1;
    04557                  ioDesc->u.Memory.Length = cmPartDesc->u.Memory.Length;
    04558                  ioDesc++;
    04559                  break;
    04560             case CmResourceTypeDma:
    04561                  ioDesc->u.Dma.MinimumChannel = cmPartDesc->u.Dma.Channel;
    04562                  ioDesc->u.Dma.MaximumChannel = cmPartDesc->u.Dma.Channel;
    04563                  ioDesc++;
    04564                  break;
    04565             case CmResourceTypeDeviceSpecific:
    04566                  size = cmPartDesc->u.DeviceSpecificData.DataSize;
    04567                  break;
    04568             case CmResourceTypeBusNumber:
    04569                  ioDesc->u.BusNumber.MinBusNumber = cmPartDesc->u.BusNumber.Start;
    04570                  ioDesc->u.BusNumber.MaxBusNumber = cmPartDesc->u.BusNumber.Start +
    04571                                                     cmPartDesc->u.BusNumber.Length - 1;
    04572                  ioDesc->u.BusNumber.Length = cmPartDesc->u.BusNumber.Length;
    04573                  ioDesc++;
    04574                  break;
    04575             default:
    04576                  ioDesc->u.DevicePrivate.Data[0] = cmPartDesc->u.DevicePrivate.Data[0];
    04577                  ioDesc->u.DevicePrivate.Data[1] = cmPartDesc->u.DevicePrivate.Data[1];
    04578                  ioDesc->u.DevicePrivate.Data[2] = cmPartDesc->u.DevicePrivate.Data[2];
    04579                  ioDesc++;
    04580                  break;
    04581             }
    04582             cmPartDesc++;
    04583             cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size);
    04584         }
    04585         cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc;
    04586     }
    04587     ioResReqList->ListSize = (ULONG)((ULONG_PTR)ioDesc - (ULONG_PTR)ioResReqList);
    04588     return ioResReqList;
    04589 }

BOOLEAN IopConcatenateUnicodeStrings | ( | OUT PUNICODE_STRING | Destination,
|  | IN PUNICODE_STRING | String1,
|  | IN PUNICODE_STRING String2 | OPTIONAL
| ) |

Definition at line 695 of file pnpsubs.c.

References ExAllocatePool, FALSE, PagedPool, String1, String2, TRUE, and USHORT.

Referenced by IopCreateMadeupNode(), IopInitializeDeviceInstanceKey(), IopProcessNewDeviceNode(), IopServiceInstanceToDeviceInstance(), and IoReportDetectedDevice().

    00703                    :
    00704
    00705     This routine returns a buffer containing the concatenation of the
    00706     two specified strings.  Since String2 is optional, this function may
    00707     also be used to make a copy of a unicode string.  Paged pool space
    00708     is allocated for the destination string.  Caller must release the
    00709     space once done with it.
    00710
    00711 Parameters:
    00712
    00713     Destination - Supplies a variable to receive the handle of the
    00714         newly created key.
    00715
    00716     String1 - Supplies a pointer to the frist UNICODE_STRING.
    00717
    00718     String2 - Supplies an optional pointer to the second UNICODE_STRING.
    00719
    00720 Return Value:
    00721
    00722     Status code that indicates whether or not the function was successful.
    00723
    00724 --*/
    00725
    00726 {
    00727     ULONG length;
    00728     PWSTR buffer;
    00729
    00730     length = String1->Length + sizeof(UNICODE_NULL);
    00731     if (ARGUMENT_PRESENT(String2)) {
    00732         length += String2->Length;
    00733     }
    00734     buffer = (PWSTR)ExAllocatePool(PagedPool, length);
    00735     if (!buffer) {
    00736         return FALSE;
    00737     }
    00738     Destination->Buffer = buffer;
    00739     Destination->Length = (USHORT)length - sizeof(UNICODE_NULL);
    00740     Destination->MaximumLength = (USHORT)length;
    00741     RtlMoveMemory (Destination->Buffer, String1->Buffer, String1->Length);
    00742     if(ARGUMENT_PRESENT(String2)) {
    00743         RtlMoveMemory((PUCHAR)Destination->Buffer + String1->Length,
    00744                       String2->Buffer,
    00745                       String2->Length
    00746                      );
    00747     }
    00748     buffer[length / sizeof(WCHAR) - 1] = UNICODE_NULL;
    00749     return TRUE;
    00750 }

NTSTATUS IopCreateMadeupNode | ( | IN PUNICODE_STRING | ServiceKeyName,
|  | OUT PHANDLE | ReturnedHandle,
|  | OUT PUNICODE_STRING | KeyName,
|  | OUT PULONG | InstanceOrdinal,
|  | IN BOOLEAN | ResourceOwned
| ) |

Definition at line 91 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetEnumRootName, ExAcquireResourceShared, ExAllocatePool, ExFreePool(), ExReleaseResource, FALSE, IopConcatenateUnicodeStrings(), IopGetRegistryValue(), IopOpenRegistryKey(), IopOpenRegistryKeyPersist(), IopOpenServiceEnumKeys(), IopRegistryDataToUnicodeString, KeEnterCriticalRegion, KeLeaveCriticalRegion, KEY_VALUE_DATA, KeyName, L, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, PpDeviceRegistration(), PpRegistryDeviceResource, ReturnedHandle, RtlFreeUnicodeString(), RtlInitUnicodeString(), RtlUpcaseUnicodeString(), TITLE_INDEX_VALUE, and TRUE.

Referenced by IopPrepareDriverLoading().

    00101                    :
    00102
    00103     This routine creates a new instance node under System\Enum\Root\*Madeup<Name>
    00104     key and all the required default value entries.  Also a value entry under
    00105     Service\ServiceKeyName\Enum is created to point to the newly created madeup
    00106     entry.  A handle and the keyname of the new key are returned to caller.
    00107     Caller must free the unicode string when he is done with it.
    00108
    00109 Parameters:
    00110
    00111     ServiceKeyName - Supplies a pointer to the name of the subkey in the
    00112         system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services)
    00113         that caused the driver to load. This is the RegistryPath parameter
    00114         to the DriverEntry routine.
    00115
    00116     ReturnedHandle - Supplies a variable to receive the handle of the
    00117         newly created key.
    00118
    00119     KeyName - Supplies a variable to receive the name of the newly created
    00120         key.
    00121
    00122     InstanceNumber - supplies a variable to receive the InstanceNumber value
    00123         entry created under service\name\enum subkey.
    00124
    00125     ResourceOwned - supplies a BOOLEAN variable to indicate if caller owns
    00126         the registry resource exclusively.
    00127
    00128 Return Value:
    00129
    00130     Status code that indicates whether or not the function was successful.
    00131
    00132 --*/
    00133
    00134 {
    00135     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    00136     UNICODE_STRING tmpKeyName, unicodeInstanceName, unicodeString;
    00137     UNICODE_STRING rootKeyName, unicodeValueName, unicodeKeyName;
    00138     HANDLE handle, enumRootHandle, hTreeHandle;
    00139     ULONG instance;
    00140     UCHAR unicodeBuffer[20];
    00141     ULONG tmpValue, disposition = 0;
    00142     NTSTATUS status;
    00143     PWSTR p;
    00144     BOOLEAN releaseResource = FALSE;
    00145     BOOLEAN successful;
    00146
    00147     if (!ResourceOwned) {
    00148         KeEnterCriticalRegion();
    00149         ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE);
    00150         releaseResource = TRUE;
    00151     }
    00152
    00153     //
    00154     // Open LocalMachine\System\CurrentControlSet\Enum\Root
    00155     //
    00156
    00157     status = IopOpenRegistryKeyEx( &enumRootHandle,
    00158                                    NULL,
    00159                                    &CmRegistryMachineSystemCurrentControlSetEnumRootName,
    00160                                    KEY_ALL_ACCESS
    00161                                    );
    00162
    00163     if (!NT_SUCCESS(status)) {
    00164         goto local_exit0;
    00165     }
    00166
    00167     //
    00168     // Open, and create if not already exist, System\Enum\Root\LEGACY_<ServiceName>
    00169     // First, try to find the ServiceName by extracting it from user supplied
    00170     // ServiceKeyName.
    00171     //
    00172
    00173     PiWstrToUnicodeString(&tmpKeyName, REGSTR_KEY_MADEUP);
    00174     successful = IopConcatenateUnicodeStrings( &unicodeKeyName,
    00175                                                &tmpKeyName,
    00176                                                ServiceKeyName);
    00177
    00178     if (!successful) {
    00179         ZwClose(enumRootHandle);
    00180         status = STATUS_INSUFFICIENT_RESOURCES;
    00181         goto local_exit0;
    00182     }
    00183
    00184     RtlUpcaseUnicodeString(&unicodeKeyName, &unicodeKeyName, FALSE);
    00185     if (!IopFixupDeviceId(unicodeKeyName.Buffer)) {
    00186         status = STATUS_INVALID_PARAMETER;
    00187         RtlFreeUnicodeString(&unicodeKeyName);
    00188         goto local_exit0;
    00189     }
    00190
    00191     status = IopCreateRegistryKeyEx( &handle,
    00192                                      enumRootHandle,
    00193                                      &unicodeKeyName,
    00194                                      KEY_ALL_ACCESS,
    00195                                      REG_OPTION_NON_VOLATILE,
    00196                                      NULL
    00197                                      );
    00198     ZwClose(enumRootHandle);
    00199     if (!NT_SUCCESS(status)) {
    00200         RtlFreeUnicodeString(&unicodeKeyName);
    00201         goto local_exit0;
    00202     }
    00203
    00204     instance = 1;
    00205
    00206     PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_NEXT_INSTANCE);
    00207     status = ZwSetValueKey(
    00208                 handle,
    00209                 &unicodeValueName,
    00210                 TITLE_INDEX_VALUE,
    00211                 REG_DWORD,
    00212                 &instance,
    00213                 sizeof(instance)
    00214                 );
    00215
    00216     instance--;
    00217     *InstanceNumber = instance;
    00218     PiUlongToInstanceKeyUnicodeString(&unicodeInstanceName,
    00219                                       unicodeBuffer + sizeof(WCHAR), // reserve first WCHAR space
    00220                                       20 - sizeof(WCHAR),
    00221                                       instance
    00222                                       );
    00223     status = IopCreateRegistryKeyEx( ReturnedHandle,
    00224                                      handle,
    00225                                      &unicodeInstanceName,
    00226                                      KEY_ALL_ACCESS,
    00227                                      REG_OPTION_NON_VOLATILE,
    00228                                      &disposition
    00229                                      );
    00230     ZwClose(handle);
    00231     if (!NT_SUCCESS(status)) {
    00232         RtlFreeUnicodeString(&unicodeKeyName);
    00233         goto local_exit0;
    00234     }
    00235
    00236     //
    00237     // Prepare newly created registry key name for returning to caller
    00238     //
    00239
    00240     *(PWSTR)unicodeBuffer = OBJ_NAME_PATH_SEPARATOR;
    00241     unicodeInstanceName.Buffer = (PWSTR)unicodeBuffer;
    00242     unicodeInstanceName.Length += sizeof(WCHAR);
    00243     unicodeInstanceName.MaximumLength += sizeof(WCHAR);
    00244     PiWstrToUnicodeString(&rootKeyName, REGSTR_KEY_ROOTENUM);
    00245     RtlInitUnicodeString(&tmpKeyName, L"\\");
    00246     IopConcatenateUnicodeStrings(&unicodeString, &tmpKeyName, &unicodeKeyName);
    00247     RtlFreeUnicodeString(&unicodeKeyName);
    00248     IopConcatenateUnicodeStrings(&tmpKeyName, &rootKeyName, &unicodeString);
    00249     RtlFreeUnicodeString(&unicodeString);
    00250     IopConcatenateUnicodeStrings(KeyName, &tmpKeyName, &unicodeInstanceName);
    00251
    00252     if (disposition == REG_CREATED_NEW_KEY) {
    00253
    00254         //
    00255         // Create all the default value entry for the newly created key.
    00256         // Service = ServiceKeyName
    00257         // FoundAtEnum = 1
    00258         // Class = "LegacyDriver"
    00259         // ClassGUID = GUID for legacy driver class
    00260         // ConfigFlags = 0
    00261         //
    00262         // Create "Control" subkey with "NewlyCreated" value key
    00263         //
    00264
    00265         PiWstrToUnicodeString(&unicodeValueName, REGSTR_KEY_CONTROL);
    00266         status = IopCreateRegistryKeyEx( &handle,
    00267                                          *ReturnedHandle,
    00268                                          &unicodeValueName,
    00269                                          KEY_ALL_ACCESS,
    00270                                          REG_OPTION_VOLATILE,
    00271                                          NULL
    00272                                          );
    00273         if (NT_SUCCESS(status)) {
    00274             PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_NEWLY_CREATED);
    00275             tmpValue = 0;
    00276             ZwSetValueKey(handle,
    00277                           &unicodeValueName,
    00278                           TITLE_INDEX_VALUE,
    00279                           REG_DWORD,
    00280                           &tmpValue,
    00281                           sizeof(tmpValue)
    00282                           );
    00283             ZwClose(handle);
    00284         }
    00285
    00286         handle = *ReturnedHandle;
    00287
    00288         PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_SERVICE);
    00289         p = (PWSTR)ExAllocatePool(PagedPool,
    00290                                   ServiceKeyName->Length + sizeof(UNICODE_NULL));
    00291         if(p) {
    00292             RtlMoveMemory(p, ServiceKeyName->Buffer, ServiceKeyName->Length);
    00293             p[ServiceKeyName->Length / sizeof (WCHAR)] = UNICODE_NULL;
    00294             ZwSetValueKey(
    00295                         handle,
    00296                         &unicodeValueName,
    00297                         TITLE_INDEX_VALUE,
    00298                         REG_SZ,
    00299                         p,
    00300                         ServiceKeyName->Length + sizeof(UNICODE_NULL)
    00301                         );
    00302             //
    00303             // We'll keep the null-terminated service name buffer around for a while,
    00304             // because we may need it later on for the DeviceDesc in case the service
    00305             // has no DisplayName.
    00306             //
    00307             // ExFreePool(p);
    00308         }
    00309
    00310         PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_LEGACY);
    00311         tmpValue = 1;
    00312         ZwSetValueKey(
    00313                     handle,
    00314                     &unicodeValueName,
    00315                     TITLE_INDEX_VALUE,
    00316                     REG_DWORD,
    00317                     &tmpValue,
    00318                     sizeof(tmpValue)
    00319                     );
    00320
    00321         PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_CONFIG_FLAGS);
    00322         tmpValue = 0;
    00323         ZwSetValueKey(
    00324                     handle,
    00325                     &unicodeValueName,
    00326                     TITLE_INDEX_VALUE,
    00327                     REG_DWORD,
    00328                     &tmpValue,
    00329                     sizeof(tmpValue)
    00330                     );
    00331
    00332         PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_CLASS);
    00333         ZwSetValueKey(
    00334                     handle,
    00335                     &unicodeValueName,
    00336                     TITLE_INDEX_VALUE,
    00337                     REG_SZ,
    00338                     REGSTR_VALUE_LEGACY_DRIVER,
    00339                     sizeof(REGSTR_VALUE_LEGACY_DRIVER)
    00340                     );
    00341
    00342         PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_CLASSGUID);
    00343         ZwSetValueKey(
    00344                     handle,
    00345                     &unicodeValueName,
    00346                     TITLE_INDEX_VALUE,
    00347                     REG_SZ,
    00348                     REGSTR_VALUE_LEGACY_DRIVER_CLASS_GUID,
    00349                     sizeof(REGSTR_VALUE_LEGACY_DRIVER_CLASS_GUID)
    00350                     );
    00351
    00352
    00353         //
    00354         // Initialize DeviceDesc= value entry.  If the service key has a "DisplayName"
    00355         // value entry, it is used as the DeviceDesc value.  Otherwise, the service key
    00356         // name is used.
    00357         //
    00358
    00359         status = IopOpenServiceEnumKeys(ServiceKeyName,
    00360                                         KEY_READ,
    00361                                         &handle,
    00362                                         NULL,
    00363                                         FALSE
    00364                                         );
    00365         if (NT_SUCCESS(status)) {
    00366
    00367             keyValueInformation = NULL;
    00368             unicodeString.Length = 0;
    00369             status = IopGetRegistryValue(handle,
    00370                                          REGSTR_VALUE_DISPLAY_NAME,
    00371                                          &keyValueInformation
    00372                                         );
    00373             if (NT_SUCCESS(status)) {
    00374                 if (keyValueInformation->Type == REG_SZ) {
    00375                     if (keyValueInformation->DataLength > sizeof(UNICODE_NULL)) {
    00376                         IopRegistryDataToUnicodeString(&unicodeString,
    00377                                                        (PWSTR)KEY_VALUE_DATA(keyValueInformation),
    00378                                                        keyValueInformation->DataLength
    00379                                                        );
    00380                     }
    00381                 }
    00382             }
    00383             if ((unicodeString.Length == 0) && p) {
    00384
    00385                 //
    00386                 // No DisplayName--use the service key name.
    00387                 //
    00388
    00389                 unicodeString.Length = ServiceKeyName->Length;
    00390                 unicodeString.MaximumLength = ServiceKeyName->Length + sizeof(UNICODE_NULL);
    00391                 unicodeString.Buffer = p;
    00392             }
    00393
    00394             if(unicodeString.Length) {
    00395                 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_DEVICE_DESC);
    00396                 ZwSetValueKey(*ReturnedHandle,
    00397                               &unicodeValueName,
    00398                               TITLE_INDEX_VALUE,
    00399                               REG_SZ,
    00400                               unicodeString.Buffer,
    00401                               unicodeString.Length + sizeof(UNICODE_NULL)
    00402                               );
    00403             }
    00404             if (keyValueInformation) {
    00405                 ExFreePool(keyValueInformation);
    00406             }
    00407             ZwClose(handle);
    00408         }
    00409
    00410         if(p) {
    00411             ExFreePool(p);
    00412         }
    00413     }
    00414
    00415     //
    00416     // Create new value entry under ServiceKeyName\Enum to reflect the newly
    00417     // added made-up device instance node.
    00418     //
    00419
    00420     ExReleaseResource(&PpRegistryDeviceResource);
    00421     KeLeaveCriticalRegion();
    00422     releaseResource = FALSE;
    00423
    00424     status = PpDeviceRegistration( KeyName, TRUE, NULL );
    00425
    00426     if (ResourceOwned) {
    00427         KeEnterCriticalRegion();
    00428         ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE);
    00429     }
    00430     RtlFreeUnicodeString(&tmpKeyName);
    00431     if (!NT_SUCCESS( status )) {
    00432
    00433         //
    00434         // There is no registry key for the ServiceKeyName information.
    00435         //
    00436
    00437         ZwClose(*ReturnedHandle);
    00438         RtlFreeUnicodeString(KeyName);
    00439     }
    00440 local_exit0:
    00441     if (releaseResource) {
    00442         ExReleaseResource(&PpRegistryDeviceResource);
    00443         KeLeaveCriticalRegion();
    00444     }
    00445     return status;
    00446 }

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

Definition at line 1156 of file pnpsubs.c.

References FALSE, Handle, KeyName, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, TRUE, and USHORT.

Referenced by ComPortDBAdd(), EisaBuildEisaDeviceNode(), IoOpenDeviceInterfaceRegistryKey(), IoOpenDeviceRegistryKey(), IopBuildCmResourceList(), IopCreateMadeupNode(), IopGetDeviceInterfaces(), IopGetRootDevices(), IopInitializeDeviceInstanceKey(), IopInitializePlugPlayServices(), IopIsAnyDeviceInstanceEnabled(), IopIsFirmwareDisabled(), IopOpenCurrentHwProfileDeviceInstanceKey(), IopOpenDeviceParametersSubkey(), IopOpenOrCreateDeviceInterfaceSubKeys(), IopOpenServiceEnumKeys(), IopPrepareDriverLoading(), IopProcessNewDeviceNode(), IopProcessSetInterfaceState(), IopRegisterDeviceInterface(), IopReleaseDeviceResources(), IopStoreSystemPartitionInformation(), IopWriteAllocatedResourcesToRegistry(), IoReportDetectedDevice(), PnPBiosCopyIoDecode(), and PnPBiosWriteInfo().

    01167                    :
    01168
    01169     Opens or creates a registry key using the name
    01170     passed in based at the BaseHandle node. This name may specify a key
    01171     that is actually a registry path, in which case each intermediate subkey
    01172     will be created (if Create is TRUE).
    01173
    01174     NOTE: Creating a registry path (i.e., more than one of the keys in the path
    01175     do not presently exist) requires that a BaseHandle be specified.
    01176
    01177 Arguments:
    01178
    01179     Handle - Pointer to the handle which will contain the registry key that
    01180         was opened.
    01181
    01182     BaseHandle - Optional handle to the base path from which the key must be opened.
    01183         If KeyName specifies a registry path that must be created, then this parameter
    01184         must be specified, and KeyName must be a relative path.
    01185
    01186     KeyName - Name of the Key that must be opened/created (possibly a registry path)
    01187
    01188     DesiredAccess - Specifies the desired access that the caller needs to
    01189         the key.
    01190
    01191     CreateOptions - Options passed to ZwCreateKey.
    01192
    01193     Disposition - If Create is TRUE, this optional pointer receives a ULONG indicating
    01194         whether the key was newly created:
    01195
    01196             REG_CREATED_NEW_KEY - A new Registry Key was created
    01197             REG_OPENED_EXISTING_KEY - An existing Registry Key was opened
    01198
    01199 Return Value:
    01200
    01201    The function value is the final status of the operation.
    01202
    01203 --*/
    01204
    01205 {
    01206     OBJECT_ATTRIBUTES objectAttributes;
    01207     ULONG disposition, baseHandleIndex = 0, keyHandleIndex = 1, closeBaseHandle;
    01208     HANDLE handles[2];
    01209     BOOLEAN continueParsing;
    01210     PWCHAR pathEndPtr, pathCurPtr, pathBeginPtr;
    01211     ULONG pathComponentLength;
    01212     UNICODE_STRING unicodeString;
    01213     NTSTATUS status;
    01214
    01215     PAGED_CODE();
    01216
    01217     InitializeObjectAttributes( &objectAttributes,
    01218                                 KeyName,
    01219                                 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
    01220                                 BaseHandle,
    01221                                 (PSECURITY_DESCRIPTOR) NULL
    01222                                 );
    01223     //
    01224     // Attempt to create the path as specified. We have to try it this
    01225     // way first, because it allows us to create a key without a BaseHandle
    01226     // (if only the last component of the registry path is not present).
    01227     //
    01228     status = ZwCreateKey(&(handles[keyHandleIndex]),
    01229                          DesiredAccess,
    01230                          &objectAttributes,
    01231                          0,
    01232                          (PUNICODE_STRING) NULL,
    01233                          CreateOptions,
    01234                          &disposition
    01235                          );
    01236
    01237     if (status == STATUS_OBJECT_NAME_NOT_FOUND && ARGUMENT_PRESENT(BaseHandle)) {
    01238         //
    01239         // If we get to here, then there must be more than one element of the
    01240         // registry path that does not currently exist.  We will now parse the
    01241         // specified path, extracting each component and doing a ZwCreateKey on it.
    01242         //
    01243         handles[baseHandleIndex] = NULL;
    01244         handles[keyHandleIndex] = BaseHandle;
    01245         closeBaseHandle = 0;
    01246         continueParsing = TRUE;
    01247         pathBeginPtr = KeyName->Buffer;
    01248         pathEndPtr = (PWCHAR)((PCHAR)pathBeginPtr + KeyName->Length);
    01249         status = STATUS_SUCCESS;
    01250
    01251         while(continueParsing) {
    01252             //
    01253             // There's more to do, so close the previous base handle (if necessary),
    01254             // and replace it with the current key handle.
    01255             //
    01256             if(closeBaseHandle > 1) {
    01257                 ZwClose(handles[baseHandleIndex]);
    01258             }
    01259             baseHandleIndex = keyHandleIndex;
    01260             keyHandleIndex = (keyHandleIndex + 1) & 1;  // toggle between 0 and 1.
    01261             handles[keyHandleIndex] = NULL;
    01262
    01263             //
    01264             // Extract next component out of the specified registry path.
    01265             //
    01266             for(pathCurPtr = pathBeginPtr;
    01267                 ((pathCurPtr < pathEndPtr) && (*pathCurPtr != OBJ_NAME_PATH_SEPARATOR));
    01268                 pathCurPtr++);
    01269
    01270             if((pathComponentLength = (ULONG)((PCHAR)pathCurPtr - (PCHAR)pathBeginPtr))) {
    01271                 //
    01272                 // Then we have a non-empty path component (key name).  Attempt
    01273                 // to create this key.
    01274                 //
    01275                 unicodeString.Buffer = pathBeginPtr;
    01276                 unicodeString.Length = unicodeString.MaximumLength = (USHORT)pathComponentLength;
    01277
    01278                 InitializeObjectAttributes(&objectAttributes,
    01279                                            &unicodeString,
    01280                                            OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
    01281                                            handles[baseHandleIndex],
    01282                                            (PSECURITY_DESCRIPTOR) NULL
    01283                                           );
    01284                 status = ZwCreateKey(&(handles[keyHandleIndex]),
    01285                                      DesiredAccess,
    01286                                      &objectAttributes,
    01287                                      0,
    01288                                      (PUNICODE_STRING) NULL,
    01289                                      CreateOptions,
    01290                                      &disposition
    01291                                     );
    01292                 if(NT_SUCCESS(status)) {
    01293                     //
    01294                     // Increment the closeBaseHandle value, which basically tells us whether
    01295                     // the BaseHandle passed in has been 'shifted out' of our way, so that
    01296                     // we should start closing our base handles when we're finished with them.
    01297                     //
    01298                     closeBaseHandle++;
    01299                 } else {
    01300                     continueParsing = FALSE;
    01301                     continue;
    01302                 }
    01303             } else {
    01304                 //
    01305                 // Either a path separator ('\') was included at the beginning of
    01306                 // the path, or we hit 2 consecutive separators.
    01307                 //
    01308                 status = STATUS_INVALID_PARAMETER;
    01309                 continueParsing = FALSE;
    01310                 continue;
    01311             }
    01312
    01313             if((pathCurPtr == pathEndPtr) ||
    01314                ((pathBeginPtr = pathCurPtr + 1) == pathEndPtr)) {
    01315                 //
    01316                 // Then we've reached the end of the path
    01317                 //
    01318                 continueParsing = FALSE;
    01319             }
    01320         }
    01321
    01322         if(closeBaseHandle > 1) {
    01323             ZwClose(handles[baseHandleIndex]);
    01324         }
    01325     }
    01326
    01327     if(NT_SUCCESS(status)) {
    01328         *Handle = handles[keyHandleIndex];
    01329
    01330         if(ARGUMENT_PRESENT(Disposition)) {
    01331             *Disposition = disposition;
    01332         }
    01333     }
    01334
    01335     return status;
    01336 }

VOID IopDecDisableableDepends | ( | IN OUT PDEVICE_NODE | DeviceNode | ) |

Definition at line 3152 of file pnpirp.c.

References NULL.

Referenced by IopQueryDeviceState(), and IopRemoveDevice().

    03157                    :
    03158
    03159     Decrements the DisableableDepends field of this devicenode
    03160     and potentially every parent device node up the tree
    03161     A parent devicenode is only decremented if the child in question
    03162     is decremented from 1 to 0
    03163
    03164 Parameters:
    03165
    03166     DeviceNode - Supplies the device node where the depends is to be decremented
    03167
    03168 Return Value:
    03169
    03170     none.
    03171
    03172 --*/
    03173 {
    03174
    03175     while (DeviceNode != NULL) {
    03176
    03177         LONG newval;
    03178
    03179         newval = InterlockedDecrement(& DeviceNode->DisableableDepends);
    03180         if (newval != 0) {
    03181             //
    03182             // we are still non-disableable, so we don't have to bother parent
    03183             //
    03184             break;
    03185         }
    03186
    03187         DeviceNode = DeviceNode ->Parent;
    03188
    03189     }
    03190
    03191 }

NTSTATUS IopDeleteKeyRecursive | ( | IN HANDLE | SubKeyHandle,
|  | IN PWCHAR | SubKeyName
| ) |

VOID IopDeleteLegacyKey | ( | IN PDRIVER_OBJECT | DriverObject | ) |

Definition at line 5453 of file pnpsubs.c.

References ASSERT, CmRegistryMachineSystemCurrentControlSetEnumName, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_MADEUP, DNF_STARTED, ExAcquireResourceShared, ExFreePool(), exit, ExReleaseResource, FALSE, _DEVICE_NODE::Flags, IoDeleteDevice(), IopCleanupDeviceRegistryValues(), IopDeviceObjectFromDeviceInstance(), IopGetRegistryValue(), IopOpenRegistryKey(), IopReleaseDeviceResources(), IopSetDevNodeProblem, KeEnterCriticalRegion, KeLeaveCriticalRegion, KEY_VALUE_DATA, L, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, _DEVICE_NODE::OverUsed1, _DEVICE_NODE::OverUsed2, PpRegistryDeviceResource, TRUE, and USHORT.

Referenced by IopInitializeBuiltinDriver(), IopLoadDriver(), and IoReportDetectedDevice().

    05459                    :
    05460
    05461     This routine checks if the Legacy= value of the driver's legacy_xxx key
    05462     is one.  If yes, it deletes the Legacy key.
    05463
    05464 Parameters:
    05465
    05466     DriverObject - supplies a pointer to the driver object.
    05467
    05468 Return Value:
    05469
    05470     None.  If anything fails in this routine, the legacy key stays.
    05471
    05472 --*/
    05473
    05474 {
    05475     WCHAR buffer[100];
    05476     NTSTATUS status;
    05477     UNICODE_STRING deviceName, instanceName, unicodeName, *serviceName;
    05478     ULONG length;
    05479     HANDLE handle, handle1, handlex, enumHandle;
    05480     ULONG legacy;
    05481     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    05482     PDEVICE_OBJECT deviceObject;
    05483     PDEVICE_NODE deviceNode;
    05484
    05485     serviceName = &DriverObject->DriverExtension->ServiceKeyName;
    05486
    05487     KeEnterCriticalRegion();
    05488     ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE);
    05489
    05490     status = IopOpenRegistryKeyEx( &enumHandle,
    05491                                    NULL,
    05492                                    &CmRegistryMachineSystemCurrentControlSetEnumName,
    05493                                    KEY_ALL_ACCESS
    05494                                    );
    05495
    05496     if (!NT_SUCCESS(status)) {
    05497         goto exit;
    05498     }
    05499
    05500     length = _snwprintf(buffer, sizeof(buffer) / sizeof(WCHAR), L"ROOT\\LEGACY_%s", serviceName->Buffer);
    05501     deviceName.MaximumLength = sizeof(buffer);
    05502     ASSERT(length <= sizeof(buffer) - 10);
    05503     deviceName.Length = (USHORT)(length * sizeof(WCHAR));
    05504     deviceName.Buffer = buffer;
    05505
    05506     status = IopOpenRegistryKeyEx( &handle1,
    05507                                    enumHandle,
    05508                                    &deviceName,
    05509                                    KEY_ALL_ACCESS
    05510                                    );
    05511
    05512     if (NT_SUCCESS(status)) {
    05513
    05514         deviceName.Buffer[deviceName.Length / sizeof(WCHAR)] =
    05515                    OBJ_NAME_PATH_SEPARATOR;
    05516         deviceName.Length += sizeof(WCHAR);
    05517         PiUlongToInstanceKeyUnicodeString(
    05518                                 &instanceName,
    05519                                 buffer + deviceName.Length / sizeof(WCHAR),
    05520                                 sizeof(buffer) - deviceName.Length,
    05521                                 0
    05522                                 );
    05523         deviceName.Length += instanceName.Length;
    05524
    05525
    05526         status = IopOpenRegistryKeyEx( &handle,
    05527                                        handle1,
    05528                                        &instanceName,
    05529                                        KEY_ALL_ACCESS
    05530                                        );
    05531         if (NT_SUCCESS(status)) {
    05532             legacy = 1;
    05533             status = IopGetRegistryValue (handle,
    05534                                           REGSTR_VALUE_LEGACY,
    05535                                           &keyValueInformation);
    05536             if (NT_SUCCESS(status)) {
    05537                 if ((keyValueInformation->Type == REG_DWORD) &&
    05538                     (keyValueInformation->DataLength >= sizeof(ULONG))) {
    05539                     legacy = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    05540                 }
    05541                 ExFreePool(keyValueInformation);
    05542             }
    05543             if (legacy != 0) {
    05544
    05545                 //
    05546                 // We also want to delete the madeup device node
    05547                 //
    05548
    05549                 deviceObject = IopDeviceObjectFromDeviceInstance(handle, NULL);
    05550                 if (deviceObject) {
    05551
    05552                     PDEVICE_NODE devNodex, devNodey;
    05553
    05554                     deviceNode = (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode;
    05555                     if (deviceNode != NULL && (deviceNode->Flags & DNF_MADEUP)) {
    05556
    05557                         //
    05558                         // Now mark this one deleted.
    05559                         //
    05560                         if (!IopDoesDevNodeHaveProblem(deviceNode)) {
    05561                             deviceNode->Flags &= ~DNF_STARTED;
    05562                             IopSetDevNodeProblem(deviceNode, CM_PROB_DEVICE_NOT_THERE);
    05563                         }
    05564
    05565                         //
    05566                         // This is actually doing nothing because DeviceNode->ResourceList is NULL.
    05567                         //
    05568
    05569                         IopReleaseDeviceResources(deviceNode, FALSE);
    05570                         devNodex = deviceNode;
    05571                         while (devNodex) {
    05572                             devNodey = devNodex;
    05573                             devNodex = (PDEVICE_NODE)devNodey->OverUsed2.NextResourceDeviceNode;
    05574                             devNodey->OverUsed2.NextResourceDeviceNode = NULL;
    05575                             devNodey->OverUsed1.LegacyDeviceNode = NULL;
    05576                         }
    05577
    05578                         deviceNode->Flags &= ~DNF_MADEUP;  // remove its boot config if any
    05579                         IoDeleteDevice(deviceObject);
    05580                     }
    05581                     ObDereferenceObject(deviceObject);  // added via IopDeviceObjectFromDeviceInstance
    05582                 }
    05583
    05584                 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
    05585                 status = IopOpenRegistryKeyEx( &handlex,
    05586                                                handle,
    05587                                                &unicodeName,
    05588                                                KEY_ALL_ACCESS
    05589                                                );
    05590                 if (NT_SUCCESS(status)) {
    05591                     ZwDeleteKey(handlex);
    05592                 }
    05593                 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF);
    05594                 status = IopOpenRegistryKeyEx( &handlex,
    05595                                                handle,
    05596                                                &unicodeName,
    05597                                                KEY_ALL_ACCESS
    05598                                                );
    05599                 if (NT_SUCCESS(status)) {
    05600                     ZwDeleteKey(handlex);
    05601                 }
    05602
    05603                 ZwClose(enumHandle);
    05604
    05605                 //
    05606                 // We need to call IopCleanupDeviceRegistryValue even we are going to
    05607                 // delete it.  Because, it also cleans up related value names in other
    05608                 // keys.
    05609                 //
    05610
    05611                 IopCleanupDeviceRegistryValues(&deviceName, FALSE);
    05612                 ZwDeleteKey(handle);
    05613                 ZwDeleteKey(handle1);
    05614             } else {
    05615                 ZwClose(handle);
    05616                 ZwClose(handle1);
    05617                 ZwClose(enumHandle);
    05618             }
    05619         } else {
    05620             ZwClose(handle1);
    05621             ZwClose(enumHandle);
    05622         }
    05623     } else {
    05624         ZwClose(enumHandle);
    05625     }
    05626 exit:
    05627     ExReleaseResource(&PpRegistryDeviceResource);
    05628     KeLeaveCriticalRegion();
    05629     return;
    05630 }

NTSTATUS IopDeleteLockedDeviceNodes | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN PRELATION_LIST | RelationsList,
|  | IN PLUGPLAY_DEVICE_DELETE_TYPE | OperationCode,
|  | IN BOOLEAN | IsKernelInitiated,
|  | IN BOOLEAN | ProcessIndirectDescendants,
|  | IN ULONG | Problem,
|  | OUT PDEVICE_OBJECT *VetoingDevice | OPTIONAL
| ) |

Definition at line 557 of file pnpdel.c.

References ASSERT, AssignResources, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_REMOVE_PENDING_CLOSES, DNF_STARTED, exit, FALSE, _DEVICE_NODE::Flags, IopDeleteLockedDeviceNode(), IopEnumerateRelations(), IopRequestDeviceAction(), IRP_MN_CANCEL_REMOVE_DEVICE, IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE, IRP_MN_SURPRISE_REMOVAL, NTSTATUS(), NULL, PAGED_CODE, and TRUE.

Referenced by IopDelayedRemoveWorker().

    00569                    :
    00570
    00571     This routine performs requested operation on the DeviceObject and
    00572     the device objects specified in the DeviceRelations.
    00573
    00574 Arguments:
    00575
    00576     DeviceObject - Supplies a pointer to the device object.
    00577
    00578     DeviceRelations - supplies a pointer to the device's removal relations.
    00579
    00580     OperationCode - Operation code, i.e., QueryRemove, CancelRemove, Remove...
    00581
    00582 Return Value:
    00583
    00584     NTSTATUS code.
    00585
    00586 --*/
    00587
    00588 {
    00589     NTSTATUS status = STATUS_SUCCESS;
    00590     PDEVICE_NODE deviceNode;
    00591     PDEVICE_OBJECT deviceObject, relatedDeviceObject;
    00592     ULONG i;
    00593     ULONG marker;
    00594     ULONG irpCode;
    00595     BOOLEAN tagged, directDescendant;
    00596
    00597     PAGED_CODE();
    00598
    00599     PIDBGMSG( PIDBG_REMOVAL,
    00600               ("IopDeleteLockedDeviceNodes: Entered\n    DeviceObject = 0x%p\n    RelationsList = 0x%p\n    OperationCode = %d\n",
    00601               DeviceObject,
    00602               RelationsList,
    00603               OperationCode));
    00604
    00605     deviceNode = (PDEVICE_NODE) DeviceObject->DeviceObjectExtension->DeviceNode;
    00606
    00607     switch (OperationCode) {
    00608     case QueryRemoveDevice:
    00609         irpCode = IRP_MN_QUERY_REMOVE_DEVICE;
    00610         break;
    00611
    00612     case CancelRemoveDevice:
    00613         irpCode = IRP_MN_CANCEL_REMOVE_DEVICE;
    00614         break;
    00615
    00616     case RemoveDevice:
    00617         irpCode = IRP_MN_REMOVE_DEVICE;
    00618         break;
    00619
    00620     case SurpriseRemoveDevice:
    00621         irpCode = IRP_MN_SURPRISE_REMOVAL;
    00622         break;
    00623
    00624     case EjectDevice:
    00625     default:
    00626         ASSERT(0);
    00627         return STATUS_INVALID_PARAMETER;
    00628     }
    00629
    00630     marker = 0;
    00631     while (IopEnumerateRelations( RelationsList,
    00632                                   &marker,
    00633                                   &deviceObject,
    00634                                   &directDescendant,
    00635                                   &tagged,
    00636                                   TRUE)) {
    00637
    00638         //
    00639         // Depending on the operation we need to do different things.
    00640         //
    00641         //  QueryRemoveDevice / CancelRemoveDevice
    00642         //      Ignore tagged relations - they were processed by a previous eject
    00643         //      Process both direct and indirect descendants
    00644         //
    00645         //  SurpriseRemoveDevice / RemoveDevice
    00646         //      None of the relations should be tagged
    00647         //      Ignore indirect descendants
    00648         //
    00649
    00650         if (!tagged && (directDescendant || ProcessIndirectDescendants)) {
    00651             deviceNode = (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode;
    00652
    00653             if (OperationCode == SurpriseRemoveDevice) {
    00654                 deviceNode->Flags |= DNF_REMOVE_PENDING_CLOSES;
    00655             }
    00656
    00657             if (OperationCode == QueryRemoveDevice && !(deviceNode->Flags & DNF_STARTED)) {
    00658                 //
    00659                 // Don't send Queries to devices without FDOs (or filters)
    00660                 //
    00661                 continue;
    00662             }
    00663
    00664             if (!IopDeleteLockedDeviceNode( deviceNode,
    00665                                             irpCode,
    00666                                             RelationsList,
    00667                                             IsKernelInitiated,
    00668                                             Problem)) {
    00669
    00670                 if (OperationCode == QueryRemoveDevice) {
    00671
    00672                     if (VetoingDevice != NULL) {
    00673                         *VetoingDevice = deviceObject;
    00674                     }
    00675
    00676                     IopDeleteLockedDeviceNode( deviceNode,
    00677                                                IRP_MN_CANCEL_REMOVE_DEVICE,
    00678                                                RelationsList,
    00679                                                IsKernelInitiated,
    00680                                                Problem);
    00681
    00682                     while (IopEnumerateRelations( RelationsList,
    00683                                                   &marker,
    00684                                                   &deviceObject,
    00685                                                   NULL,
    00686                                                   &tagged,
    00687                                                   FALSE)) {
    00688
    00689                         if (!tagged) {
    00690
    00691                             deviceNode = (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode;
    00692
    00693                             IopDeleteLockedDeviceNode( deviceNode,
    00694                                                        IRP_MN_CANCEL_REMOVE_DEVICE,
    00695                                                        RelationsList,
    00696                                                        IsKernelInitiated,
    00697                                                        Problem);
    00698                         }
    00699                     }
    00700
    00701                     status = STATUS_UNSUCCESSFUL;
    00702                     goto exit;
    00703                 }
    00704             }
    00705         }
    00706     }
    00707
    00708     //
    00709     // As long as there is device removed, try satisfy the DNF_INSUFFICIENT_RESOURCES
    00710     // devices.
    00711     //
    00712
    00713     if (OperationCode == RemoveDevice) {
    00714         PIDBGMSG( PIDBG_REMOVAL,
    00715                   ("IopDeleteLockedDeviceNodes: Calling IopRequestDeviceEnumeration\n"));
    00716
    00717         IopRequestDeviceAction(NULL, AssignResources, NULL, NULL);
    00718     }
    00719
    00720 exit:
    00721     return status;
    00722 }

VOID IopDestroyDeviceNode | ( | PDEVICE_NODE | DeviceNode | ) |

| Referenced by IopDeleteDevice(), and IopRemoveLegacyDeviceNode().

ULONG IopDetermineResourceListSize | ( | IN PCM_RESOURCE_LIST | ResourceList | ) |

Definition at line 3631 of file pnpsubs.c.

References List.

Referenced by IopBuildCmResourceLists(), IopChangeInterfaceType(), IopCombineCmResourceList(), IopCombineLegacyResources(), IopLegacyResourceAllocation(), IopMergeCmResourceLists(), IopQueryDeviceResources(), IopReserveBootResources(), IopReserveBootResourcesInternal(), IopRestoreResourcesInternal(), and IoReportDetectedDevice().

    03637                    :
    03638
    03639     This routine determines size of the passed in ResourceList
    03640     structure.
    03641
    03642 Arguments:
    03643
    03644     Configuration1 - Supplies a pointer to the resource list.
    03645
    03646 Return Value:
    03647
    03648     size of the resource list structure.
    03649
    03650 --*/
    03651
    03652 {
    03653     ULONG totalSize, listSize, descriptorSize, i, j;
    03654     PCM_FULL_RESOURCE_DESCRIPTOR fullResourceDesc;
    03655     PCM_PARTIAL_RESOURCE_DESCRIPTOR partialDescriptor;
    03656
    03657     if (!ResourceList) {
    03658         totalSize = 0;
    03659     } else {
    03660         totalSize = FIELD_OFFSET(CM_RESOURCE_LIST, List);
    03661         fullResourceDesc = &ResourceList->List[0];
    03662         for (i = 0; i < ResourceList->Count; i++) {
    03663             listSize = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR,
    03664                                     PartialResourceList) +
    03665                        FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
    03666                                     PartialDescriptors);
    03667             partialDescriptor = &fullResourceDesc->PartialResourceList.PartialDescriptors[0];
    03668             for (j = 0; j < fullResourceDesc->PartialResourceList.Count; j++) {
    03669                 descriptorSize = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
    03670                 if (partialDescriptor->Type == CmResourceTypeDeviceSpecific) {
    03671                     descriptorSize += partialDescriptor->u.DeviceSpecificData.DataSize;
    03672                 }
    03673                 listSize += descriptorSize;
    03674                 partialDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
    03675                                         ((PUCHAR)partialDescriptor + descriptorSize);
    03676             }
    03677             totalSize += listSize;
    03678             fullResourceDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)
    03679                                       ((PUCHAR)fullResourceDesc + listSize);
    03680         }
    03681     }
    03682     return totalSize;
    03683 }

NTSTATUS IopDeviceCapabilitiesToRegistry | ( | IN PDEVICE_NODE | DeviceNode,
|  | IN PDEVICE_CAPABILITIES | Capabilities
| ) |

Definition at line 5675 of file pnpsubs.c.

    05682                    :
    05683
    05684     This routine updates device capabilities, must be called after a valid device instance key has been created
    05685     Called directly from IopProcessNewDeviceNode, and indirecly via IopDeviceNodeCapabilitiesToRegistry
    05686     after device is started.
    05687
    05688 Arguments:
    05689
    05690     DeviceObject - supplies a pointer to a device object whose registry
    05691         values are to be updated.
    05692
    05693 Return Value:
    05694
    05695     status
    05696
    05697 --*/
    05698
    05699 {
    05700     HANDLE handle;
    05701     NTSTATUS status;
    05702     UNICODE_STRING unicodeName;
    05703     ULONG tmpValue;
    05704
    05705     PAGED_CODE();
    05706
    05707     ASSERT(DeviceNode != NULL);
    05708     ASSERT(Capabilities != NULL);
    05709
    05710     //
    05711     // Open the device instance key
    05712     //
    05713     status = IopDeviceObjectToDeviceInstance(DeviceNode->PhysicalDeviceObject, &handle, KEY_ALL_ACCESS);
    05714     if (!NT_SUCCESS(status)) {
    05715         return status;
    05716     }
    05717
    05718     if (DeviceNode->Flags & DNF_HAS_BOOT_CONFIG) {
    05719         Capabilities->SurpriseRemovalOK = 0;
    05720     }
    05721
    05722     //
    05723     // Assert the bit fields are completely contained in a ULONG. This is a
    05724     // public structure, so it shouldn't ever change, but paranoia is a good
    05725     // thing...
    05726     //
    05727     ASSERT((FIELD_OFFSET(DEVICE_CAPABILITIES, Address) -
    05728             FIELD_OFFSET(DEVICE_CAPABILITIES, Version) -
    05729             FIELD_SIZE  (DEVICE_CAPABILITIES, Version)) == sizeof(ULONG));
    05730
    05731     DeviceNode->CapabilityFlags =
    05732         *((PULONG) (((PUCHAR) Capabilities) +
    05733         FIELD_OFFSET(DEVICE_CAPABILITIES, Version) +
    05734         FIELD_SIZE(DEVICE_CAPABILITIES, Version)));
    05735
    05736     PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_CAPABILITIES);
    05737     tmpValue = (Capabilities->LockSupported)          |
    05738                (Capabilities->EjectSupported    << 1) |
    05739                (Capabilities->WarmEjectSupported<< 1) |
    05740                (Capabilities->Removable         << 2) |
    05741                (Capabilities->DockDevice        << 3) |
    05742                (Capabilities->UniqueID          << 4) |
    05743                (Capabilities->SilentInstall     << 5) |
    05744                (Capabilities->RawDeviceOK       << 6) |
    05745                (Capabilities->SurpriseRemovalOK << 7) |
    05746                (Capabilities->HardwareDisabled  << 8) |
    05747                (Capabilities->NonDynamic        << 9);
    05748
    05749     status = ZwSetValueKey(
    05750                   handle,
    05751                   &unicodeName,
    05752                   TITLE_INDEX_VALUE,
    05753                   REG_DWORD,
    05754                   &tmpValue,
    05755                   sizeof(tmpValue)
    05756                   );
    05757
    05758     PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_UI_NUMBER);
    05759     tmpValue = Capabilities->UINumber;
    05760     if(tmpValue != (ULONG)-1) {
    05761         ZwSetValueKey(handle,
    05762                       &unicodeName,
    05763                       TITLE_INDEX_VALUE,
    05764                       REG_DWORD,
    05765                       &tmpValue,
    05766                       sizeof(tmpValue)
    05767                       );
    05768     } else {
    05769         ZwDeleteValueKey(handle, &unicodeName);
    05770     }
    05771
    05772     ZwClose(handle);
    05773     return status;
    05774 }

NTSTATUS IopDeviceNodeCapabilitiesToRegistry | ( | IN PDEVICE_NODE | DeviceNode | ) |

Definition at line 5633 of file pnpsubs.c.

References ASSERT, IopDeviceCapabilitiesToRegistry(), IopQueryDeviceCapabilities(), NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

Referenced by IopInitializeDeviceInstanceKey(), and IopStartAndEnumerateDevice().

    05639                    :
    05640
    05641     Called after start to refresh Capability flags
    05642
    05643 Arguments:
    05644
    05645     DeviceObject - supplies a pointer to a device object whose registry
    05646         values are to be updated.
    05647
    05648 Return Value:
    05649
    05650     status
    05651
    05652 --*/
    05653
    05654 {
    05655     NTSTATUS status;
    05656     DEVICE_CAPABILITIES capabilities;
    05657
    05658     PAGED_CODE();
    05659
    05660     ASSERT(DeviceNode != NULL);
    05661
    05662     //
    05663     // Open the device instance key
    05664     //
    05665
    05666     status = IopQueryDeviceCapabilities(DeviceNode, &capabilities);
    05667     if (!NT_SUCCESS(status)) {
    05668         return status;
    05669     }
    05670
    05671     return IopDeviceCapabilitiesToRegistry(DeviceNode,&capabilities);
    05672 }

PDEVICE_OBJECT IopDeviceObjectFromDeviceInstance | ( | IN HANDLE DeviceInstanceHandle | OPTIONAL,
|  | IN PUNICODE_STRING DeviceInstance | OPTIONAL
| ) |

Definition at line 3759 of file pnpsubs.c.

References ASSERT, CmRegistryMachineSystemCurrentControlSetEnumName, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, ExFreePool(), exit, FALSE, IO_TYPE_DEVICE, IopGetRegistryValue(), IopOpenRegistryKey(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, ObReferenceObject, PAGED_CODE, _DEVICE_NODE::PhysicalDeviceObject, and _DEVICE_OBJECT::Type.

Referenced by IopAddDevicesToBootDriverWorker(), IopDeleteLegacyKey(), IopDriverLoadingFailed(), IopGetDriverDeviceListWorker(), IopInitializeDeviceInstanceKey(), IopIsAnyDeviceInstanceEnabled(), IopIsDeviceInstanceEnabled(), IopProcessNewDeviceNode(), IopProcessSetInterfaceState(), IopSetLegacyDeviceInstance(), and IoReportDetectedDevice().

    03766                    :
    03767
    03768     This routine receives a DeviceInstance path (or DeviceInstance handle) and
    03769     returns a reference to a bus device object for the DeviceInstance.
    03770
    03771     Note, caller must owner the PpRegistryDeviceResource before calling the function,
    03772
    03773 Arguments:
    03774
    03775     DeviceInstanceHandle - Supplies a handle to the registry Device Instance key.
    03776         If this parameter is NULL, DeviceInstance must specify the registry path.
    03777
    03778     DeviceInstance - supplies a UNICODE_STRING to specify the device instance path.
    03779         if this parameter is NULL, DeviceInstanceHandle must specify the handle
    03780         to its registry key.
    03781
    03782 Returns:
    03783
    03784     A reference to the desired bus device object.
    03785
    03786 --*/
    03787
    03788 {
    03789     NTSTATUS status;
    03790     HANDLE handle, deviceHandle = NULL;
    03791     PDEVICE_OBJECT deviceReference = NULL;
    03792     UNICODE_STRING unicodeName;
    03793     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    03794     PDEVICE_NODE deviceNode;
    03795
    03796     PAGED_CODE();
    03797
    03798     if (!ARGUMENT_PRESENT(DeviceInstanceHandle)) {
    03799
    03800         //
    03801         // Treat HTREE\ROOT\0 specially
    03802         //
    03803         PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_ROOT_DEVNODE);
    03804
    03805         if (RtlEqualUnicodeString(&unicodeName, DeviceInstance, TRUE)) {
    03806
    03807             deviceReference = IopRootDeviceNode->PhysicalDeviceObject;
    03808             ASSERT(deviceReference);
    03809             ObReferenceObject(deviceReference);
    03810
    03811             return deviceReference;
    03812         }
    03813
    03814         //
    03815         // first open System\CCS\Enum key and then the device instance key.
    03816         //
    03817
    03818         status = IopOpenRegistryKeyEx( &handle,
    03819                                        NULL,
    03820                                        &CmRegistryMachineSystemCurrentControlSetEnumName,
    03821                                        KEY_READ
    03822                                        );
    03823
    03824         if (!NT_SUCCESS( status )) {
    03825             return deviceReference;
    03826         }
    03827
    03828         ASSERT(DeviceInstance);
    03829         status = IopOpenRegistryKeyEx( &deviceHandle,
    03830                                        handle,
    03831                                        DeviceInstance,
    03832                                        KEY_READ
    03833                                        );
    03834         ZwClose(handle);
    03835         if (!NT_SUCCESS(status)) {
    03836             return deviceReference;
    03837         }
    03838         DeviceInstanceHandle = deviceHandle;
    03839     }
    03840
    03841     //
    03842     // Read the address of device object
    03843     //
    03844
    03845     PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
    03846     status = IopOpenRegistryKeyEx( &handle,
    03847                                    DeviceInstanceHandle,
    03848                                    &unicodeName,
    03849                                    KEY_READ
    03850                                    );
    03851     if (!NT_SUCCESS(status)) {
    03852         goto exit;
    03853     }
    03854
    03855     status = IopGetRegistryValue (handle,
    03856                                   REGSTR_VALUE_DEVICE_REFERENCE,
    03857                                   &keyValueInformation);
    03858     ZwClose(handle);
    03859     if (NT_SUCCESS(status)) {
    03860         if ((keyValueInformation->Type == REG_DWORD) &&
    03861             (keyValueInformation->DataLength == sizeof(ULONG_PTR))) {
    03862
    03863             deviceReference = *(PDEVICE_OBJECT *)KEY_VALUE_DATA(keyValueInformation);
    03864         }
    03865         ExFreePool(keyValueInformation);
    03866     }
    03867     if (!deviceReference) {
    03868         goto exit;
    03869     }
    03870
    03871     //
    03872     // Make sure the address of the device object is not clobbered,
    03873     // unfortunately if the address is truly bogus we will bugcheck since
    03874     // try/except doesn't work for kernel addresses.
    03875     //
    03876
    03877     if (deviceReference->Type != IO_TYPE_DEVICE) {
    03878         deviceReference = NULL;
    03879     } else {
    03880         deviceNode = (PDEVICE_NODE)deviceReference->DeviceObjectExtension->DeviceNode;
    03881         if (deviceNode && (deviceNode->PhysicalDeviceObject == deviceReference)) {
    03882             ObReferenceObject(deviceReference);
    03883         } else {
    03884             deviceReference = NULL;
    03885         }
    03886     }
    03887
    03888 exit:
    03889     if (deviceHandle) {
    03890         ZwClose(deviceHandle);
    03891     }
    03892     return deviceReference;
    03893
    03894 }

NTSTATUS IopDeviceObjectToDeviceInstance | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN PHANDLE | DeviceInstanceHandle,
|  | IN ACCESS_MASK | DesiredAccess
| ) |

Definition at line 3897 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetEnumName, FALSE, _DEVICE_NODE::InstancePath, IopOpenRegistryKey(), NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

Referenced by IoGetDeviceProperty(), IoOpenDeviceRegistryKey(), IopAssignResourcesToDevices(), IopDeviceCapabilitiesToRegistry(), IopGetDeviceResourcesFromRegistry(), IopIsFirmwareDisabled(), IopNotifySetupDeviceArrival(), IopNotifySetupDevices(), IopQueryDeviceResources(), IopReleaseDeviceResources(), IopStartAndEnumerateDevice(), IopWriteAllocatedResourcesToRegistry(), and IoReportDetectedDevice().

    03905                    :
    03906
    03907     This routine receives a DeviceObject pointer and returns a handle to the device
    03908     instance path under registry System\ENUM key.
    03909
    03910     Note, caller must owner the PpRegistryDeviceResource before calling the function,
    03911
    03912 Arguments:
    03913
    03914     DeviceObject - supplies a pointer to a physical device object.
    03915
    03916     DeviceInstanceHandle - Supplies a variable to receive the handle to the registry
    03917              device instance key.
    03918
    03919     DesiredAccess - specifies the access that is needed to this key.
    03920
    03921 Returns:
    03922
    03923     NTSTATUS code to indicate success or failure.
    03924
    03925 --*/
    03926
    03927 {
    03928     NTSTATUS status;
    03929     HANDLE handle;
    03930     PDEVICE_NODE deviceNode;
    03931
    03932     PAGED_CODE();
    03933
    03934     status = IopOpenRegistryKeyEx( &handle,
    03935                                    NULL,
    03936                                    &CmRegistryMachineSystemCurrentControlSetEnumName,
    03937                                    KEY_READ
    03938                                    );
    03939
    03940     if (!NT_SUCCESS( status )) {
    03941         return status;
    03942     }
    03943
    03944     deviceNode = (PDEVICE_NODE) DeviceObject->DeviceObjectExtension->DeviceNode;
    03945     if (deviceNode && (deviceNode->InstancePath.Length != 0)) {
    03946         status = IopOpenRegistryKeyEx( DeviceInstanceHandle,
    03947                                        handle,
    03948                                        &deviceNode->InstancePath,
    03949                                        DesiredAccess
    03950                                        );
    03951     } else {
    03952         status = STATUS_INVALID_DEVICE_REQUEST;
    03953     }
    03954     ZwClose(handle);
    03955
    03956     return status;
    03957 }

NTSTATUS IopDmaInitialize | ( | VOID |  | ) |

| Referenced by IopInitializePlugPlayServices().

NTSTATUS IopDoDeferredSetInterfaceState | ( | IN PDEVICE_NODE | DeviceNode | ) |

Definition at line 9866 of file pnpioapi.c.

References _DEVICE_OBJECT::AttachedDevice, _DEVICE_OBJECT::DeviceObjectExtension, DOE_START_PENDING, ExAcquireResourceExclusive, ExFreePool(), ExReleaseResource, _DEVOBJ_EXTENSION::ExtensionFlags, FALSE, IopDatabaseLock, IopProcessSetInterfaceState(), KeEnterCriticalRegion, KeLeaveCriticalRegion, _PENDING_SET_INTERFACE_STATE::LinkName, PPENDING_SET_INTERFACE_STATE, PpRegistryDeviceResource, and TRUE.

Referenced by IopStartDevice(), and IoReportDetectedDevice().

    09871                    :
    09872
    09873     Process the queued IoSetDeviceInterfaceState calls.
    09874
    09875 Parameters:
    09876
    09877     DeviceNode - Device node which has just been started.
    09878
    09879 Return Value:
    09880
    09881     Status code that indicates whether or not the function was successful.
    09882
    09883 --*/
    09884 {
    09885     KIRQL           irql;
    09886     PDEVICE_OBJECT  attachedDevice;
    09887
    09888     KeEnterCriticalRegion();
    09889     ExAcquireResourceExclusive(&PpRegistryDeviceResource, TRUE);
    09890
    09891     ExAcquireFastLock( &IopDatabaseLock, &irql );
    09892
    09893     for (attachedDevice = DeviceNode->PhysicalDeviceObject;
    09894          attachedDevice;
    09895          attachedDevice = attachedDevice->AttachedDevice) {
    09896
    09897         attachedDevice->DeviceObjectExtension->ExtensionFlags &= ~DOE_START_PENDING;
    09898     }
    09899
    09900     ExReleaseFastLock( &IopDatabaseLock, irql );
    09901
    09902     while (!IsListEmpty(&DeviceNode->PendedSetInterfaceState)) {
    09903
    09904         PPENDING_SET_INTERFACE_STATE entry;
    09905
    09906         entry = (PPENDING_SET_INTERFACE_STATE)RemoveHeadList(&DeviceNode->PendedSetInterfaceState);
    09907
    09908         IopProcessSetInterfaceState(&entry->LinkName, TRUE, FALSE);
    09909
    09910         ExFreePool(entry->LinkName.Buffer);
    09911
    09912         ExFreePool(entry);
    09913     }
    09914
    09915     ExReleaseResource(&PpRegistryDeviceResource);
    09916     KeLeaveCriticalRegion();
    09917
    09918     return STATUS_SUCCESS;
    09919 }

NTSTATUS IopDriverLoadingFailed | ( | IN HANDLE KeyHandle | OPTIONAL,
|  | IN PUNICODE_STRING KeyName | OPTIONAL
| ) |

VOID IopDumpAllocatedSystemResources | ( | IN UCHAR | ResourceType | ) |

VOID IopDumpCmResourceDescriptor | ( | IN PUCHAR | Indent,
|  | IN PCM_PARTIAL_RESOURCE_DESCRIPTOR | Desc
| ) |

Definition at line 868 of file report.c.

References DbgPrint, and PAGED_CODE.

Referenced by IopDumpCmResourceList().

    00874                    :
    00875
    00876     This routine processes a IO_RESOURCE_DESCRIPTOR and displays it.
    00877
    00878 Arguments:
    00879
    00880     Indent - # char of indentation.
    00881
    00882     Desc - supplies a pointer to the IO_RESOURCE_DESCRIPTOR to be displayed.
    00883
    00884 Return Value:
    00885
    00886     None.
    00887
    00888 --*/
    00889 {
    00890     PAGED_CODE();
    00891
    00892     switch (Desc->Type) {
    00893         case CmResourceTypePort:
    00894             DbgPrint ("%sIO  Start: %x:%08x, Length:  %x\n",
    00895                 Indent,
    00896                 Desc->u.Port.Start.HighPart, Desc->u.Port.Start.LowPart,
    00897                 Desc->u.Port.Length
    00898                 );
    00899             break;
    00900
    00901         case CmResourceTypeMemory:
    00902             DbgPrint ("%sMEM Start: %x:%08x, Length:  %x\n",
    00903                 Indent,
    00904                 Desc->u.Memory.Start.HighPart, Desc->u.Memory.Start.LowPart,
    00905                 Desc->u.Memory.Length
    00906                 );
    00907             break;
    00908
    00909         case CmResourceTypeInterrupt:
    00910             DbgPrint ("%sINT Level: %x, Vector: %x, Affinity: %x\n",
    00911                 Indent,
    00912                 Desc->u.Interrupt.Level,
    00913                 Desc->u.Interrupt.Vector,
    00914                 Desc->u.Interrupt.Affinity
    00915                 );
    00916             break;
    00917
    00918         case CmResourceTypeDma:
    00919             DbgPrint ("%sDMA Channel: %x, Port: %x\n",
    00920                 Indent,
    00921                 Desc->u.Dma.Channel,
    00922                 Desc->u.Dma.Port
    00923                 );
    00924             break;
    00925     }
    00926 }

VOID IopDumpCmResourceList | ( | IN PCM_RESOURCE_LIST | CmList | ) |

Definition at line 929 of file report.c.

References DbgPrint, IopDumpCmResourceDescriptor(), and PAGED_CODE.

Referenced by IopBuildCmResourceLists(), and IopReserveLegacyBootResources().

    00934                    :
    00935
    00936     This routine displays CM resource list.
    00937
    00938 Arguments:
    00939
    00940     CmList - supplies a pointer to CM resource list
    00941
    00942 Return Value:
    00943
    00944     None.
    00945
    00946 --*/
    00947 {
    00948     PCM_FULL_RESOURCE_DESCRIPTOR fullDesc;
    00949     PCM_PARTIAL_RESOURCE_LIST partialDesc;
    00950     PCM_PARTIAL_RESOURCE_DESCRIPTOR desc;
    00951     ULONG count, i;
    00952
    00953     PAGED_CODE();
    00954
    00955     if (CmList->Count > 0) {
    00956         if (CmList) {
    00957             fullDesc = &CmList->List[0];
    00958             DbgPrint("Cm Resource List -\n");
    00959             DbgPrint("  List Count = %x, Bus Number = %x\n", CmList->Count, fullDesc->BusNumber);
    00960             partialDesc = &fullDesc->PartialResourceList;
    00961             DbgPrint("  Version = %x, Revision = %x, Desc count = %x\n", partialDesc->Version,
    00962                      partialDesc->Revision, partialDesc->Count);
    00963             count = partialDesc->Count;
    00964             desc = &partialDesc->PartialDescriptors[0];
    00965             for (i = 0; i < count; i++) {
    00966                 IopDumpCmResourceDescriptor("    ", desc);
    00967                 desc++;
    00968             }
    00969         }
    00970     }
    00971 }
    //#endif

NTSTATUS IopDuplicateDetection | ( | IN INTERFACE_TYPE | LegacyBusType,
|  | IN ULONG | BusNumber,
|  | IN ULONG | SlotNumber,
|  | OUT PDEVICE_NODE * | DeviceNode
| ) |

Definition at line 6528 of file pnpres.c.

References BusNumber, _INTERFACE::Context, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, ExFreePool(), _INTERFACE::InterfaceDereference, IopFindBusDeviceNode(), IopQueryResourceHandlerInterface(), IopRootDeviceNode, NT_SUCCESS, NTSTATUS(), NULL, _DEVICE_NODE::PhysicalDeviceObject, and ResourceLegacyDeviceDetection.

Referenced by IoReportDetectedDevice().

    06537                    :
    06538
    06539     This routine searches for the bus device driver for a given legacy device,
    06540     sends a query interface IRP for legacy device detection, and if the driver
    06541     implements this interface, requests the PDO for the given legacy device.
    06542
    06543 Parameters:
    06544
    06545     LegacyBusType - The legacy device's interface type.
    06546
    06547     BusNumber - The legacy device's bus number.
    06548
    06549     SlotNumber - The legacy device's slot number.
    06550
    06551     DeviceNode - specifies a pointer to a variable to receive the duplicated device node
    06552
    06553 Return Value:
    06554
    06555     NTSTATUS code.
    06556
    06557 --*/
    06558
    06559 {
    06560     PDEVICE_NODE deviceNode;
    06561     PDEVICE_OBJECT busDeviceObject;
    06562     PLEGACY_DEVICE_DETECTION_INTERFACE interface;
    06563     NTSTATUS status;
    06564     PDEVICE_OBJECT deviceObject;
    06565
    06566     //
    06567     // Initialize return parameter to "not found".
    06568     //
    06569
    06570     *DeviceNode = NULL;
    06571
    06572     //
    06573     // Search the device tree for the bus of the legacy device.
    06574     //
    06575
    06576     deviceNode = IopFindBusDeviceNode(
    06577                      IopRootDeviceNode,
    06578                      LegacyBusType,
    06579                      BusNumber,
    06580                      SlotNumber
    06581                  );
    06582
    06583     //
    06584     // Either a bus driver does not exist (or more likely, the legacy bus
    06585     // type and bus number were unspecified).  Either way, we can't make
    06586     // any further progress.
    06587     //
    06588
    06589     if (deviceNode == NULL) {
    06590
    06591         return STATUS_INVALID_DEVICE_REQUEST;
    06592
    06593     }
    06594
    06595     //
    06596     // We found the legacy device's bus driver.  Query it to determine
    06597     // whether it implements the LEGACY_DEVICE_DETECTION interface.
    06598     //
    06599
    06600     busDeviceObject = deviceNode->PhysicalDeviceObject;
    06601
    06602     status = IopQueryResourceHandlerInterface(
    06603                  ResourceLegacyDeviceDetection,
    06604                  busDeviceObject,
    06605                  0,
    06606                  (PINTERFACE *)&interface
    06607              );
    06608
    06609     //
    06610     // If it doesn't, we're stuck.
    06611     //
    06612
    06613     if (!NT_SUCCESS(status) || interface == NULL) {
    06614
    06615         return STATUS_INVALID_DEVICE_REQUEST;
    06616
    06617     }
    06618
    06619     //
    06620     // Invoke the bus driver's legacy device detection method.
    06621     //
    06622
    06623     status = (*interface->LegacyDeviceDetection)(
    06624                  interface->Context,
    06625                  LegacyBusType,
    06626                  BusNumber,
    06627                  SlotNumber,
    06628                  &deviceObject
    06629              );
    06630
    06631     //
    06632     // If it found a legacy device, update the return parameter.
    06633     //
    06634
    06635     if (NT_SUCCESS(status) && deviceObject != NULL) {
    06636
    06637         *DeviceNode =
    06638             (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode;
    06639
    06640         status = STATUS_SUCCESS;
    06641
    06642     } else {
    06643
    06644         status = STATUS_INVALID_DEVICE_REQUEST;
    06645
    06646     }
    06647
    06648     //
    06649     // Free the interface.
    06650     //
    06651
    06652     (*interface->InterfaceDereference)(interface->Context);
    06653
    06654     ExFreePool(interface);
    06655
    06656     return status;
    06657 }

NTSTATUS IopEjectDevice | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | PPENDING_RELATIONS_LIST_ENTRY | PendingEntry
| ) |

NTSTATUS IopFilterResourceRequirementsList | ( | IN PIO_RESOURCE_REQUIREMENTS_LIST | IoList,
|  | IN PCM_RESOURCE_LIST | CmList,
|  | IN OUT PIO_RESOURCE_REQUIREMENTS_LIST * | FilteredList,
|  | OUT PBOOLEAN | ExactMatch
| ) |

Definition at line 4592 of file pnpsubs.c.

References ASSERT, ExAllocatePool, ExFreePool(), FALSE, IopCmResourcesToIoResources(), NTSTATUS(), NULL, PAGED_CODE, PagedPool, TRUE, and USHORT.

Referenced by IopGetResourceRequirementsForAssignTable(), and IopQueryDeviceResources().

    04601                    :
    04602
    04603     This routines adjusts the input IoList based on input BootConfig.
    04604
    04605
    04606 Arguments:
    04607
    04608     IoList - supplies the pointer to an IoResourceRequirementsList
    04609
    04610     CmList - supplies the pointer to a BootConfig.
    04611
    04612     FilteredList - Supplies a variable to receive the filtered resource
    04613              requirements list.
    04614
    04615 Return Value:
    04616
    04617     A NTSTATUS code to indicate the result of the function.
    04618
    04619 --*/
    04620 {
    04621     NTSTATUS status;
    04622     PIO_RESOURCE_REQUIREMENTS_LIST ioList, newList;
    04623     PIO_RESOURCE_LIST ioResourceList, newIoResourceList, selectedResourceList = NULL;
    04624     PIO_RESOURCE_DESCRIPTOR ioResourceDescriptor, ioResourceDescriptorEnd;
    04625     PIO_RESOURCE_DESCRIPTOR newIoResourceDescriptor, configDataDescriptor;
    04626     LONG ioResourceDescriptorCount = 0;
    04627     USHORT version;
    04628     PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc;
    04629     PCM_PARTIAL_RESOURCE_DESCRIPTOR cmDescriptor;
    04630     ULONG cmDescriptorCount = 0;
    04631     ULONG size, i, j, oldCount, phase;
    04632     LONG k, alternativeLists;
    04633     BOOLEAN exactMatch;
    04634
    04635     PAGED_CODE();
    04636
    04637     *FilteredList = NULL;
    04638     *ExactMatch = FALSE;
    04639
    04640     //
    04641     // Make sure there is some resource requirements to be filtered.
    04642     // If no, we will convert CmList/BootConfig to an IoResourceRequirementsList
    04643     //
    04644
    04645     if (IoList == NULL || IoList->AlternativeLists == 0) {
    04646         if (CmList && CmList->Count != 0) {
    04647             *FilteredList = IopCmResourcesToIoResources (0, CmList, LCPRI_BOOTCONFIG);
    04648         }
    04649         return STATUS_SUCCESS;
    04650     }
    04651
    04652     //
    04653     // Make a copy of the Io Resource Requirements List
    04654     //
    04655
    04656     ioList = (PIO_RESOURCE_REQUIREMENTS_LIST) ExAllocatePool(PagedPool, IoList->ListSize);
    04657     if (ioList == NULL) {
    04658         return STATUS_INSUFFICIENT_RESOURCES;
    04659     }
    04660
    04661     RtlMoveMemory(ioList, IoList, IoList->ListSize);
    04662
    04663     //
    04664     // If there is no BootConfig, simply return the copy of the input Io list.
    04665     //
    04666
    04667     if (CmList == NULL || CmList->Count == 0) {
    04668         *FilteredList = ioList;
    04669         return STATUS_SUCCESS;
    04670     }
    04671
    04672     //
    04673     // First determine minimum number of descriptors required.
    04674     //
    04675
    04676     cmFullDesc = &CmList->List[0];
    04677     for (i = 0; i < CmList->Count; i++) {
    04678         cmDescriptorCount += cmFullDesc->PartialResourceList.Count;
    04679         cmDescriptor = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
    04680         for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) {
    04681             size = 0;
    04682             switch (cmDescriptor->Type) {
    04683             case CmResourceTypeConfigData:
    04684             case CmResourceTypeDevicePrivate:
    04685                  cmDescriptorCount--;
    04686                  break;
    04687             case CmResourceTypeDeviceSpecific:
    04688                  size = cmDescriptor->u.DeviceSpecificData.DataSize;
    04689                  cmDescriptorCount--;
    04690                  break;
    04691             default:
    04692
    04693                  //
    04694                  // Invalid cmresource list.  Ignore it and use io resources
    04695                  //
    04696
    04697                  if (cmDescriptor->Type == CmResourceTypeNull ||
    04698                      cmDescriptor->Type >= CmResourceTypeMaximum) {
    04699                      cmDescriptorCount--;
    04700                  }
    04701             }
    04702             cmDescriptor++;
    04703             cmDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmDescriptor + size);
    04704         }
    04705         cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmDescriptor;
    04706     }
    04707
    04708     if (cmDescriptorCount == 0) {
    04709         *FilteredList = ioList;
    04710         return STATUS_SUCCESS;
    04711     }
    04712
    04713     //
    04714     // cmDescriptorCount is the number of BootConfig Descriptors needs.
    04715     //
    04716     // For each IO list Alternative ...
    04717     //
    04718
    04719     ioResourceList = ioList->List;
    04720     k = ioList->AlternativeLists;
    04721     while (--k >= 0) {
    04722         ioResourceDescriptor = ioResourceList->Descriptors;
    04723         ioResourceDescriptorEnd = ioResourceDescriptor + ioResourceList->Count;
    04724         while (ioResourceDescriptor < ioResourceDescriptorEnd) {
    04725             ioResourceDescriptor->Spare1 = 0;
    04726             ioResourceDescriptor++;
    04727         }
    04728         ioResourceList = (PIO_RESOURCE_LIST) ioResourceDescriptorEnd;
    04729     }
    04730
    04731     ioResourceList = ioList->List;
    04732     k = alternativeLists = ioList->AlternativeLists;
    04733     while (--k >= 0) {
    04734         version = ioResourceList->Version;
    04735         if (version == 0xffff) {  // Convert bogus version to valid number
    04736             version = 1;
    04737         }
    04738
    04739         //
    04740         // We use Version field to store number of BootConfig found.
    04741         // Count field to store new number of descriptor in the alternative list.
    04742         //
    04743
    04744         ioResourceList->Version = 0;
    04745         oldCount = ioResourceList->Count;
    04746
    04747         ioResourceDescriptor = ioResourceList->Descriptors;
    04748         ioResourceDescriptorEnd = ioResourceDescriptor + ioResourceList->Count;
    04749
    04750         if (ioResourceDescriptor == ioResourceDescriptorEnd) {
    04751
    04752             //
    04753             // An alternative list with zero descriptor count
    04754             //
    04755
    04756             ioResourceList->Version = 0xffff;  // Mark it as invalid
    04757             ioList->AlternativeLists--;
    04758             continue;
    04759         }
    04760
    04761         exactMatch = TRUE;
    04762
    04763         //
    04764         // For each Cm Resource descriptor ... except DevicePrivate and
    04765         // DeviceSpecific...
    04766         //
    04767
    04768         cmFullDesc = &CmList->List[0];
    04769         for (i = 0; i < CmList->Count; i++) {
    04770             cmDescriptor = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
    04771             for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) {
    04772                 size = 0;
    04773                 switch (cmDescriptor->Type) {
    04774                 case CmResourceTypeDevicePrivate:
    04775                      break;
    04776                 case CmResourceTypeDeviceSpecific:
    04777                      size = cmDescriptor->u.DeviceSpecificData.DataSize;
    04778                      break;
    04779                 default:
    04780                     if (cmDescriptor->Type == CmResourceTypeNull ||
    04781                         cmDescriptor->Type >= CmResourceTypeMaximum) {
    04782                         break;
    04783                     }
    04784
    04785                     //
    04786                     // Check CmDescriptor against current Io Alternative list
    04787                     //
    04788
    04789                     for (phase = 0; phase < 2; phase++) {
    04790                         ioResourceDescriptor = ioResourceList->Descriptors;
    04791                         while (ioResourceDescriptor < ioResourceDescriptorEnd) {
    04792                             if ((ioResourceDescriptor->Type == cmDescriptor->Type) &&
    04793                                 (ioResourceDescriptor->Spare1 == 0)) {
    04794                                 ULONGLONG min1, max1, min2, max2;
    04795                                 ULONG len1 = 1, len2 = 1, align1, align2;
    04796                                 UCHAR share1, share2;
    04797
    04798                                 share2 = ioResourceDescriptor->ShareDisposition;
    04799                                 share1 = cmDescriptor->ShareDisposition;
    04800                                 if ((share1 == CmResourceShareUndetermined) ||
    04801                                     (share1 > CmResourceShareShared)) {
    04802                                     share1 = share2;
    04803                                 }
    04804                                 if ((share2 == CmResourceShareUndetermined) ||
    04805                                     (share2 > CmResourceShareShared)) {
    04806                                     share2 = share1;
    04807                                 }
    04808                                 align1 = align2 = 1;
    04809
    04810                                 switch (cmDescriptor->Type) {
    04811                                 case CmResourceTypePort:
    04812                                 case CmResourceTypeMemory:
    04813                                     min1 = cmDescriptor->u.Port.Start.QuadPart;
    04814                                     max1 = cmDescriptor->u.Port.Start.QuadPart + cmDescriptor->u.Port.Length - 1;
    04815                                     len1 = cmDescriptor->u.Port.Length;
    04816                                     min2 = ioResourceDescriptor->u.Port.MinimumAddress.QuadPart;
    04817                                     max2 = ioResourceDescriptor->u.Port.MaximumAddress.QuadPart;
    04818                                     len2 = ioResourceDescriptor->u.Port.Length;
    04819                                     align2 = ioResourceDescriptor->u.Port.Alignment;
    04820                                     break;
    04821                                 case CmResourceTypeInterrupt:
    04822                                     max1 = min1 = cmDescriptor->u.Interrupt.Vector;
    04823                                     min2 = ioResourceDescriptor->u.Interrupt.MinimumVector;
    04824                                     max2 = ioResourceDescriptor->u.Interrupt.MaximumVector;
    04825                                     break;
    04826                                 case CmResourceTypeDma:
    04827                                     min1 = max1 =cmDescriptor->u.Dma.Channel;
    04828                                     min2 = ioResourceDescriptor->u.Dma.MinimumChannel;
    04829                                     max2 = ioResourceDescriptor->u.Dma.MaximumChannel;
    04830                                     break;
    04831                                 case CmResourceTypeBusNumber:
    04832                                     min1 = cmDescriptor->u.BusNumber.Start;
    04833                                     max1 = cmDescriptor->u.BusNumber.Start + cmDescriptor->u.BusNumber.Length - 1;
    04834                                     len1 = cmDescriptor->u.BusNumber.Length;
    04835                                     min2 = ioResourceDescriptor->u.BusNumber.MinBusNumber;
    04836                                     max2 = ioResourceDescriptor->u.BusNumber.MaxBusNumber;
    04837                                     len2 = ioResourceDescriptor->u.BusNumber.Length;
    04838                                     break;
    04839                                 default:
    04840                                     ASSERT(0);
    04841                                     break;
    04842                                 }
    04843                                 if (phase == 0) {
    04844                                     if (share1 == share2 && min2 == min1 && max2 >= max1 && len2 >= len1) {
    04845
    04846                                         //
    04847                                         // For phase 0 match, we want near exact match...
    04848                                         //
    04849
    04850                                         if (max2 != max1) {
    04851                                             exactMatch = FALSE;
    04852                                         }
    04853                                         ioResourceList->Version++;
    04854                                         ioResourceDescriptor->Spare1 = 0x80;
    04855                                         if (ioResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) {
    04856                                             PIO_RESOURCE_DESCRIPTOR ioDesc;
    04857
    04858                                             ioDesc = ioResourceDescriptor;
    04859                                             ioDesc--;
    04860                                             while (ioDesc >= ioResourceList->Descriptors) {
    04861                                                 ioDesc->Type = CmResourceTypeNull;
    04862                                                 ioResourceList->Count--;
    04863                                                 if (ioDesc->Option == IO_RESOURCE_ALTERNATIVE) {
    04864                                                     ioDesc--;
    04865                                                 } else {
    04866                                                     break;
    04867                                                 }
    04868                                             }
    04869                                         }
    04870                                         ioResourceDescriptor->Option = IO_RESOURCE_PREFERRED;
    04871                                         ioResourceDescriptor->Flags = cmDescriptor->Flags;
    04872                                         if (ioResourceDescriptor->Type == CmResourceTypePort ||
    04873                                             ioResourceDescriptor->Type == CmResourceTypeMemory) {
    04874                                             ioResourceDescriptor->u.Port.MinimumAddress.QuadPart = min1;
    04875                                             ioResourceDescriptor->u.Port.MaximumAddress.QuadPart = min1 + len2 - 1;
    04876                                             ioResourceDescriptor->u.Port.Alignment = 1;
    04877                                         } else if (ioResourceDescriptor->Type == CmResourceTypeBusNumber) {
    04878                                             ioResourceDescriptor->u.BusNumber.MinBusNumber = (ULONG)min1;
    04879                                             ioResourceDescriptor->u.BusNumber.MaxBusNumber = (ULONG)(min1 + len2 - 1);
    04880                                         }
    04881                                         ioResourceDescriptor++;
    04882                                         while (ioResourceDescriptor < ioResourceDescriptorEnd) {
    04883                                             if (ioResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) {
    04884                                                 ioResourceDescriptor->Type = CmResourceTypeNull;
    04885                                                 ioResourceDescriptor++;
    04886                                                 ioResourceList->Count--;
    04887                                             } else {
    04888                                                 break;
    04889                                             }
    04890                                         }
    04891                                         phase = 1;   // skip phase 1
    04892                                         break;
    04893                                     } else {
    04894                                         ioResourceDescriptor++;
    04895                                     }
    04896                                 } else {
    04897                                     exactMatch = FALSE;
    04898                                     if (share1 == share2 && min2 <= min1 && max2 >= max1 && len2 >= len1 &&
    04899                                         (min1 & (align2 - 1)) == 0) {
    04900
    04901                                         //
    04902                                         // Io range covers Cm range ... Change the Io range to what is specified
    04903                                         // in BootConfig.
    04904                                         //
    04905                                         //
    04906
    04907                                         switch (cmDescriptor->Type) {
    04908                                         case CmResourceTypePort:
    04909                                         case CmResourceTypeMemory:
    04910                                             ioResourceDescriptor->u.Port.MinimumAddress.QuadPart = min1;
    04911                                             ioResourceDescriptor->u.Port.MaximumAddress.QuadPart = min1 + len2 - 1;
    04912                                             break;
    04913                                         case CmResourceTypeInterrupt:
    04914                                         case CmResourceTypeDma:
    04915                                             ioResourceDescriptor->u.Interrupt.MinimumVector = (ULONG)min1;
    04916                                             ioResourceDescriptor->u.Interrupt.MaximumVector = (ULONG)max1;
    04917                                             break;
    04918                                         case CmResourceTypeBusNumber:
    04919                                             ioResourceDescriptor->u.BusNumber.MinBusNumber = (ULONG)min1;
    04920                                             ioResourceDescriptor->u.BusNumber.MaxBusNumber = (ULONG)(min1 + len2 - 1);
    04921                                             break;
    04922                                         }
    04923                                         ioResourceList->Version++;
    04924                                         ioResourceDescriptor->Spare1 = 0x80;
    04925                                         ioResourceDescriptor->Flags = cmDescriptor->Flags;
    04926                                         if (ioResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) {
    04927                                             PIO_RESOURCE_DESCRIPTOR ioDesc;
    04928
    04929                                             ioDesc = ioResourceDescriptor;
    04930                                             ioDesc--;
    04931                                             while (ioDesc >= ioResourceList->Descriptors) {
    04932                                                 ioDesc->Type = CmResourceTypeNull;
    04933                                                 ioResourceList->Count--;
    04934                                                 if (ioDesc->Option == IO_RESOURCE_ALTERNATIVE) {
    04935                                                     ioDesc--;
    04936                                                 } else {
    04937                                                     break;
    04938                                                 }
    04939                                             }
    04940                                         }
    04941                                         ioResourceDescriptor->Option = IO_RESOURCE_PREFERRED;
    04942                                         ioResourceDescriptor++;
    04943                                         while (ioResourceDescriptor < ioResourceDescriptorEnd) {
    04944                                             if (ioResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) {
    04945                                                 ioResourceDescriptor->Type = CmResourceTypeNull;
    04946                                                 ioResourceList->Count--;
    04947                                                 ioResourceDescriptor++;
    04948                                             } else {
    04949                                                 break;
    04950                                             }
    04951                                         }
    04952                                         break;
    04953                                     } else {
    04954                                         ioResourceDescriptor++;
    04955                                     }
    04956                                 }
    04957                             } else {
    04958                                 ioResourceDescriptor++;
    04959                             }
    04960                         } // Don't add any instruction after this ...
    04961                     } // phase
    04962                 } // switch
    04963
    04964                 //
    04965                 // Move to next Cm Descriptor
    04966                 //
    04967
    04968                 cmDescriptor++;
    04969                 cmDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmDescriptor + size);
    04970             }
    04971
    04972             //
    04973             // Move to next Cm List
    04974             //
    04975
    04976             cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmDescriptor;
    04977         }
    04978
    04979         if (ioResourceList->Version != (USHORT)cmDescriptorCount) {
    04980
    04981             //
    04982             // If the current alternative list does not cover all the boot config
    04983             // descriptors, make it as invalid.
    04984             //
    04985
    04986             ioResourceList->Version = 0xffff;
    04987             ioList->AlternativeLists--;
    04988         } else {
    04989             if ((ioResourceList->Count == cmDescriptorCount) ||
    04990                 (ioResourceList->Count == (cmDescriptorCount + 1) &&
    04991                  ioResourceList->Descriptors[0].Type == CmResourceTypeConfigData)) {
    04992                 if (selectedResourceList) {
    04993                     ioResourceList->Version = 0xffff;
    04994                     ioList->AlternativeLists--;
    04995                 } else {
    04996                     selectedResourceList = ioResourceList;
    04997                     ioResourceDescriptorCount += ioResourceList->Count;
    04998                     ioResourceList->Version = version;
    04999                     if (exactMatch) {
    05000                         *ExactMatch = TRUE;
    05001                     }
    05002                 }
    05003             } else {
    05004                 ioResourceDescriptorCount += ioResourceList->Count;
    05005                 ioResourceList->Version = version;
    05006             }
    05007         }
    05008         ioResourceList->Count = oldCount;
    05009
    05010         //
    05011         // Move to next Io alternative list.
    05012         //
    05013
    05014         ioResourceList = (PIO_RESOURCE_LIST) ioResourceDescriptorEnd;
    05015     }
    05016
    05017     //
    05018     // If there is not any valid alternative, convert CmList to Io list.
    05019     //
    05020
    05021     if (ioList->AlternativeLists == 0) {
    05022          *FilteredList = IopCmResourcesToIoResources (0, CmList, LCPRI_BOOTCONFIG);
    05023         ExFreePool(ioList);
    05024         return STATUS_SUCCESS;
    05025     }
    05026
    05027     //
    05028     // we have finished filtering the resource requirements list.  Now allocate memory
    05029     // and rebuild a new list.
    05030     //
    05031
    05032     size = sizeof(IO_RESOURCE_REQUIREMENTS_LIST) +
    05033                sizeof(IO_RESOURCE_LIST) * (ioList->AlternativeLists - 1) +
    05034                sizeof(IO_RESOURCE_DESCRIPTOR) * (ioResourceDescriptorCount);
    05035     newList = (PIO_RESOURCE_REQUIREMENTS_LIST) ExAllocatePool(PagedPool, size);
    05036     if (newList == NULL) {
    05037         ExFreePool(ioList);
    05038         return STATUS_INSUFFICIENT_RESOURCES;
    05039     }
    05040
    05041     //
    05042     // Walk through the io resource requirements list and pick up any valid descriptor.
    05043     //
    05044
    05045     newList->ListSize = size;
    05046     newList->InterfaceType = CmList->List->InterfaceType;
    05047     newList->BusNumber = CmList->List->BusNumber;
    05048     newList->SlotNumber = ioList->SlotNumber;
    05049     if (ioList->AlternativeLists > 1) {
    05050         *ExactMatch = FALSE;
    05051     }
    05052     newList->AlternativeLists = ioList->AlternativeLists;
    05053     ioResourceList = ioList->List;
    05054     newIoResourceList = newList->List;
    05055     while (--alternativeLists >= 0) {
    05056         ioResourceDescriptor = ioResourceList->Descriptors;
    05057         ioResourceDescriptorEnd = ioResourceDescriptor + ioResourceList->Count;
    05058         if (ioResourceList->Version == 0xffff) {
    05059             ioResourceList = (PIO_RESOURCE_LIST)ioResourceDescriptorEnd;
    05060             continue;
    05061         }
    05062         newIoResourceList->Version = ioResourceList->Version;
    05063         newIoResourceList->Revision = ioResourceList->Revision;
    05064
    05065         newIoResourceDescriptor = newIoResourceList->Descriptors;
    05066         if (ioResourceDescriptor->Type != CmResourceTypeConfigData) {
    05067             newIoResourceDescriptor->Option = IO_RESOURCE_PREFERRED;
    05068             newIoResourceDescriptor->Type = CmResourceTypeConfigData;
    05069             newIoResourceDescriptor->ShareDisposition = CmResourceShareShared;
    05070             newIoResourceDescriptor->Flags = 0;
    05071             newIoResourceDescriptor->Spare1 = 0;
    05072             newIoResourceDescriptor->Spare2 = 0;
    05073             newIoResourceDescriptor->u.ConfigData.Priority = LCPRI_BOOTCONFIG;
    05074             configDataDescriptor = newIoResourceDescriptor;
    05075             newIoResourceDescriptor++;
    05076         } else {
    05077             newList->ListSize -= sizeof(IO_RESOURCE_DESCRIPTOR);
    05078             configDataDescriptor = newIoResourceDescriptor;
    05079         }
    05080
    05081         while (ioResourceDescriptor < ioResourceDescriptorEnd) {
    05082             if (ioResourceDescriptor->Type != CmResourceTypeNull) {
    05083                 *newIoResourceDescriptor = *ioResourceDescriptor;
    05084                 newIoResourceDescriptor++;
    05085             }
    05086             ioResourceDescriptor++;
    05087         }
    05088         newIoResourceList->Count = (ULONG)(newIoResourceDescriptor - newIoResourceList->Descriptors);
    05089
    05090         //if (newIoResourceList->Count == (cmDescriptorCount + 1)) {
    05091         configDataDescriptor->u.ConfigData.Priority =  LCPRI_BOOTCONFIG;
    05092         //}
    05093
    05094         //
    05095         // Move to next Io alternative list.
    05096         //
    05097
    05098         newIoResourceList = (PIO_RESOURCE_LIST) newIoResourceDescriptor;
    05099         ioResourceList = (PIO_RESOURCE_LIST) ioResourceDescriptorEnd;
    05100     }
    05101     ASSERT((PUCHAR)newIoResourceList == ((PUCHAR)newList + newList->ListSize));
    05102
    05103     *FilteredList = newList;
    05104     ExFreePool(ioList);
    05105     return STATUS_SUCCESS;
    05106 }

PDEVICE_NODE IopFindBusDeviceNode | ( | IN PDEVICE_NODE | DeviceNode,
|  | IN INTERFACE_TYPE | InterfaceType,
|  | IN ULONG | BusNumber,
|  | IN ULONG | SlotNumber
| ) |

Definition at line 6408 of file pnpres.c.

References BusNumber, DebugMessage, DUMP_DETAIL, _DEVICE_NODE::InstancePath, InterfaceType, IopFindBusDeviceNodeInternal(), IopRootDeviceNode, and NULL.

Referenced by IopChildToRootTranslation(), IopDuplicateDetection(), IopReleaseResourcesInternal(), and IopSetupArbiterAndTranslators().

    06417                    :
    06418
    06419     This routine finds the bus PDO which performs translation and arbitration for the
    06420     specified InterfaceType, BusNumber and SlotNumber.
    06421
    06422 Parameters:
    06423
    06424     DeviceNode - the root of the PDO to start our search
    06425
    06426     InterfaceType - Specifies the PDO's interface type.
    06427
    06428     BusNumber - specifies the PDO's bus number.
    06429
    06430     SlotNumber - specified the PDO's slot number (UNUSED).
    06431
    06432 Return Value:
    06433
    06434     A pointer to the BUS PDO.
    06435
    06436 --*/
    06437
    06438 {
    06439     PDEVICE_NODE busDeviceNode = NULL;
    06440
    06441     UNREFERENCED_PARAMETER(SlotNumber);
    06442
    06443     if (DeviceNode && InterfaceType != InterfaceTypeUndefined) {
    06444
    06445         if (InterfaceType == PNPBus) {
    06446             //
    06447             // if we specified PnpBus as InterfaceType, we know nobody specifies such a bus
    06448             // don't waste time looking for BusNumber because it doesn't exist
    06449             //
    06450             busDeviceNode = NULL;
    06451         } else {
    06452             //
    06453             // search for bus (recursive)
    06454             //
    06455             busDeviceNode = IopFindBusDeviceNodeInternal(DeviceNode, (InterfaceType == Eisa) ? Isa : InterfaceType, BusNumber);
    06456         }
    06457
    06458         if (busDeviceNode == NULL && DeviceNode == IopRootDeviceNode) {
    06459
    06460             DebugMessage(DUMP_DETAIL, ("IopFindBusDeviceNode: Found %ws with interface=%08X & bus=%08X\n", DeviceNode->InstancePath.Buffer, InterfaceType, BusNumber));
    06461             return DeviceNode;
    06462         }
    06463
    06464         if (busDeviceNode) {
    06465
    06466             DebugMessage(DUMP_DETAIL, ("IopFindBusDeviceNode: Found %ws with interface=%08X & bus=%08X\n", busDeviceNode->InstancePath.Buffer, InterfaceType, BusNumber));
    06467         }
    06468     }
    06469
    06470     return busDeviceNode;
    06471 }

BOOLEAN IopFixupDeviceId | ( | PWCHAR | DeviceId | ) |

| Referenced by IopCreateMadeupNode(), IopFixupIds(), and IopProcessNewDeviceNode().

NTSTATUS IopForAllChildDeviceNodes | ( | IN PDEVICE_NODE | Parent,
|  | IN PENUM_CALLBACK | Callback,
|  | IN PVOID | Context
| ) |

Definition at line 179 of file devnode.c.

References NT_SUCCESS, NTSTATUS(), PAGED_CODE, and _DEVICE_NODE::Sibling.

Referenced by IopForAllDeviceNodes(), IopForAllDeviceNodesCallback(), IopProcessAddDevicesWorker(), IopProcessAssignResourcesWorker(), and IopProcessStartDevicesWorker().

    00187                    :
    00188
    00189     This function walks the Parent's device node subtree and perform caller specified
    00190     'Callback' function for each device node under Parent.
    00191
    00192     Note, befor calling this rotuine, callers must acquire the enumeration mutex
    00193     of the 'Parent' device node to make sure its children won't go away unless the
    00194     call tells them to.
    00195
    00196 Arguments:
    00197
    00198     Parent - Supplies a pointer to the device node whose subtree is to be walked.
    00199
    00200     Callback - Supplies the call back routine for each device node.
    00201
    00202     Context - Supplies a parameter/context for the callback function.
    00203
    00204 Return Value:
    00205
    00206     NTSTATUS value.
    00207
    00208 --*/
    00209
    00210 {
    00211     PDEVICE_NODE nextChild = Parent->Child;
    00212     PDEVICE_NODE child;
    00213     NTSTATUS status = STATUS_SUCCESS;
    00214
    00215     PAGED_CODE();
    00216
    00217     //
    00218     // Process siblings until we find the end of the sibling list or
    00219     // the Callback() returns FALSE.  Set result = TRUE at the top of
    00220     // the loop so that if there are no siblings we will return TRUE,
    00221     // e.g. Keep Enumerating.
    00222     //
    00223     // Note, we need to find next child before calling Callback function
    00224     // in case the current child is deleted by the Callback function.
    00225     //
    00226
    00227     while (nextChild && NT_SUCCESS(status)) {
    00228         child = nextChild;
    00229         nextChild = child->Sibling;
    00230         status = Callback(child, Context);
    00231     }
    00232
    00233     return status;
    00234 }

NTSTATUS IopForAllDeviceNodes | ( | IN PENUM_CALLBACK | Callback,
|  | IN PVOID | Context
| ) |

Definition at line 127 of file devnode.c.

References _ENUM_CONTEXT::CallersCallback, _ENUM_CONTEXT::CallersContext, IopAcquireEnumerationLock, IopForAllChildDeviceNodes(), IopForAllDeviceNodesCallback(), IopReleaseEnumerationLock, IopRootDeviceNode, NTSTATUS(), PAGED_CODE, and PENUM_CALLBACK.

Referenced by IopProcessNewProfileWorker().

    00134                    :
    00135
    00136     This function walks the device node tree and perform caller specified
    00137     'Callback' function for each device node.
    00138
    00139     Note, this routine (or its worker routine) traverses the tree in a top
    00140     down manner.
    00141
    00142 Arguments:
    00143
    00144     Callback - Supplies the call back routine for each device node.
    00145
    00146     Context - Supplies a parameter/context for the callback function.
    00147
    00148 Return Value:
    00149
    00150     Status returned from Callback, if not successfull then the tree walking stops.
    00151
    00152 --*/
    00153 {
    00154     ENUM_CONTEXT enumContext;
    00155     NTSTATUS status;
    00156
    00157     PAGED_CODE();
    00158
    00159     enumContext.CallersCallback = Callback;
    00160     enumContext.CallersContext = Context;
    00161
    00162     //
    00163     // Start with a pointer to the root device node, recursively examine all the
    00164     // children until we the callback function says stop or we've looked at all
    00165     // of them.
    00166     //
    00167
    00168     IopAcquireEnumerationLock(IopRootDeviceNode);
    00169
    00170     status = IopForAllChildDeviceNodes(IopRootDeviceNode,
    00171                                        IopForAllDeviceNodesCallback,
    00172                                        (PVOID)&enumContext );
    00173
    00174     IopReleaseEnumerationLock(IopRootDeviceNode);
    00175     return status;
    00176 }

VOID IopFreeAllocatedUnicodeString | ( | PUNICODE_STRING | String | ) |

Definition at line 5668 of file pnpioapi.c.

References ASSERT, ExFreePool(), NULL, PAGED_CODE, and String.

Referenced by IoGetDeviceInterfaceAlias(), IopBuildSymbolicLinkStrings(), IopOpenOrCreateDeviceInterfaceSubKeys(), IopProcessCriticalDevice(), IopRegisterDeviceInterface(), IopRemoveDeviceInterfaces(), IopSetRegistryStringValue(), and IopUnregisterDeviceInterface().

    05674                    :
    05675
    05676     This routine frees a string previously allocated with IopAllocateUnicodeString.
    05677
    05678 Parameters:
    05679
    05680     String - Supplies a pointer to the string that has been previously allocated.
    05681
    05682 Return Value:
    05683
    05684     None
    05685
    05686 --*/
    05687
    05688 {
    05689     PAGED_CODE();
    05690
    05691     ASSERT(String);
    05692
    05693     //
    05694     // If we have a buffer free it
    05695     //
    05696
    05697     if(String->Buffer) {
    05698
    05699         ExFreePool(String->Buffer);
    05700
    05701     }
    05702
    05703     //
    05704     // Blank out the string
    05705     //
    05706
    05707     String->Buffer = NULL;
    05708     String->Length = 0;
    05709     String->MaximumLength = 0;
    05710
    05711 }

VOID IopFreeBuffer | ( | IN PBUFFER_INFO | Info | ) |

Definition at line 2536 of file pnpioapi.c.

References ASSERT, ExFreePool(), and NULL.

Referenced by IopGetDeviceInterfaces(), IopProcessCriticalDeviceRoutine(), and IopRemoveDeviceInterfaces().

    02542                    :
    02543
    02544     Frees the buffer associated with Info and resets all Info fields
    02545
    02546 Parameters:
    02547
    02548     Info - Pointer to a buffer info structure to be used to manage the buffer
    02549
    02550 Return Value:
    02551
    02552     Status code that indicates whether or not the function was successful.
    02553
    02554 --*/
    02555
    02556 {
    02557     ASSERT(Info);
    02558
    02559     //
    02560     // Free the buffer
    02561     //
    02562
    02563     ExFreePool(Info->Buffer);
    02564
    02565     //
    02566     // Zero out the info parameters so we can't accidently used the free buffer
    02567     //
    02568
    02569     Info->Buffer = NULL;
    02570     Info->Current = NULL;
    02571     Info->MaxSize = 0;
    02572 }

VOID IopFreeUnicodeStringList | ( | IN PUNICODE_STRING | UnicodeStringList,
|  | IN ULONG | StringCount
| ) |

Definition at line 2740 of file pnpsubs.c.

References Buffer, and ExFreePool().

Referenced by IopGetGroupOrderIndex(), and IopRegMultiSzToUnicodeStrings().

    02747                    :
    02748
    02749     This routine frees the buffer for each UNICODE_STRING in the specified list
    02750     (there are StringCount of them), and then frees the memory used for the
    02751     string list itself.
    02752
    02753 Arguments:
    02754
    02755     UnicodeStringList - Supplies a pointer to an array of UNICODE_STRINGs.
    02756
    02757     StringCount - Supplies the number of strings in the UnicodeStringList array.
    02758
    02759 Returns:
    02760
    02761     None.
    02762
    02763 --*/
    02764
    02765 {
    02766     ULONG i;
    02767
    02768     if(UnicodeStringList) {
    02769         for(i = 0; i < StringCount; i++) {
    02770             if(UnicodeStringList[i].Buffer) {
    02771                 ExFreePool(UnicodeStringList[i].Buffer);
    02772             }
    02773         }
    02774         ExFreePool(UnicodeStringList);
    02775     }
    02776 }

NTSTATUS IopGetDeviceInstanceCsConfigFlags | ( | IN PUNICODE_STRING | DeviceInstance,
|  | OUT PULONG | CsConfigFlags
| ) |

Definition at line 1477 of file pnpsubs.c.

    01484                    :
    01485
    01486     This routine retrieves the csconfig flags for the specified device.
    01487
    01488 Arguments:
    01489
    01490     DeviceInstance - Supplies a pointer to the devnode's instance path
    01491
    01492     CsConfigFlags - Supplies a variable to receive the device's CsConfigFlags
    01493
    01494 Return Value:
    01495
    01496     status
    01497
    01498 --*/
    01499
    01500 {
    01501     NTSTATUS status;
    01502     HANDLE handle1, handle2;
    01503     UNICODE_STRING tempUnicodeString;
    01504     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    01505
    01506     PAGED_CODE();
    01507
    01508     *CsConfigFlags = 0;
    01509
    01510     status = IopOpenRegistryKeyEx( &handle1,
    01511                                    NULL,
    01512                                    &CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent,
    01513                                    KEY_READ
    01514                                    );
    01515
    01516     if (!NT_SUCCESS(status)) {
    01517
    01518         return status;
    01519     }
    01520
    01521     //
    01522     // Now, we must open the System\CCS\Enum key under this.
    01523     //
    01524     //
    01525     // Open system\CurrentControlSet under current hardware profile key
    01526     //
    01527
    01528     PiWstrToUnicodeString(&tempUnicodeString, REGSTR_PATH_CURRENTCONTROLSET);
    01529     status = IopOpenRegistryKeyEx( &handle2,
    01530                                    handle1,
    01531                                    &tempUnicodeString,
    01532                                    KEY_READ
    01533                                    );
    01534     ZwClose(handle1);
    01535
    01536     if (!NT_SUCCESS(status)) {
    01537
    01538         return status;
    01539     }
    01540
    01541     PiWstrToUnicodeString(&tempUnicodeString, REGSTR_KEY_ENUM);
    01542
    01543     status = IopOpenRegistryKeyEx( &handle1,
    01544                                    handle2,
    01545                                    &tempUnicodeString,
    01546                                    KEY_READ
    01547                                    );
    01548
    01549     ZwClose(handle2);
    01550
    01551     if (!NT_SUCCESS(status)) {
    01552
    01553         return status;
    01554     }
    01555
    01556
    01557     status = IopOpenRegistryKeyEx( &handle2,
    01558                                    handle1,
    01559                                    DeviceInstance,
    01560                                    KEY_READ
    01561                                    );
    01562
    01563     ZwClose(handle1);
    01564
    01565     if (!NT_SUCCESS(status)) {
    01566
    01567         return status;
    01568     }
    01569
    01570
    01571     status = IopGetRegistryValue( handle2,
    01572                                   REGSTR_VALUE_CSCONFIG_FLAGS,
    01573                                   &keyValueInformation
    01574                                   );
    01575
    01576     ZwClose(handle2);
    01577
    01578     if (NT_SUCCESS(status)) {
    01579         if ((keyValueInformation->Type == REG_DWORD) &&
    01580             (keyValueInformation->DataLength >= sizeof(ULONG))) {
    01581
    01582             *CsConfigFlags = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    01583         }
    01584         ExFreePool(keyValueInformation);
    01585     }
    01586
    01587     return status;
    01588 }

NTSTATUS IopGetDeviceInterfaces | ( | IN CONST GUID * | InterfaceClassGuid,
|  | IN PUNICODE_STRING DevicePath | OPTIONAL,
|  | IN ULONG | Flags,
|  | IN BOOLEAN | UserModeFormat,
|  | OUT PWSTR * | SymbolicLinkList,
|  | OUT PULONG SymbolicLinkListSize | OPTIONAL
| ) |

Definition at line 2707 of file pnpioapi.c.

References ASSERT, _BUFFER_INFO::Buffer, _BUFFER_INFO::Current, DbgPrint, DEVICE_INTERFACE_INCLUDE_NONACTIVE, ExAcquireResourceExclusive, ExFreePool(), ExReleaseResource, FALSE, INITIAL_DEVNODE_NAME_BUFFER_SIZE, INITIAL_INFO_BUFFER_SIZE, INITIAL_RETURN_BUFFER_SIZE, INITIAL_SYMLINK_BUFFER_SIZE, IopAllocateBuffer(), IopAppendBuffer(), IopCreateRegistryKeyEx(), IopFreeBuffer(), IopGetRegistryValue(), IopOpenOrCreateDeviceInterfaceSubKeys(), IopOpenRegistryKeyEx(), IopResizeBuffer(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KERNEL_SYMLINK_STRING_PREFIX, KERNEL_SYMLINK_STRING_PREFIX_LENGTH, KEY_VALUE_DATA, _BUFFER_INFO::MaxSize, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PpRegistryDeviceResource, RtlCompareUnicodeString(), RtlFreeUnicodeString(), RtlStringFromGUID(), TRUE, and USHORT.

Referenced by IoGetDeviceInterfaces(), and IopRemoveDeviceInterfaces().

    02718                    :
    02719
    02720     This API allows a WDM driver to get a list of paths that represent all
    02721     devices registered for the specified interface class.
    02722
    02723 Parameters:
    02724
    02725     InterfaceClassGuid - Supplies a pointer to a GUID representing the interface class
    02726         for whom a list of members is to be retrieved
    02727
    02728     DevicePath - Optionally, supplies a pointer to a unicode string containing the
    02729         enumeration path for a device for whom interfaces of the specified class are
    02730         to be re-trieved.  If this parameter  is not supplied, then all interface
    02731         devices (regardless of what physical device exposes them) will be returned.
    02732
    02733     Flags - Supplies flags that modify the behavior of list retrieval.
    02734         The following flags are presently defined:
    02735
    02736         DEVICE_INTERFACE_INCLUDE_NONACTIVE -- If this flag is specified, then all
    02737             interface devices, whether currently active or not, will be returned
    02738             (potentially filtered based on the Physi-calDeviceObject, if specified).
    02739
    02740     UserModeFormat - If TRUE the multi-sz returned will have user mode prefixes
    02741         (\\?\) otherwise they will have kernel mode prefixes (\??\).
    02742
    02743     SymbolicLinkList - Supplies the address of a character pointer, that on
    02744         success will contain a multi-sz list of \??\ symbolic link
    02745         names that provide the requested functionality.  The caller is
    02746         responsible for freeing the memory via ExFreePool.
    02747
    02748 Return Value:
    02749
    02750     Status code that indicates whether or not the function was successful.
    02751
    02752 --*/
    02753
    02754 {
    02755     NTSTATUS status;
    02756     UNICODE_STRING guidString, tempString, defaultString, symLinkString, devnodeString;
    02757     BUFFER_INFO returnBuffer, infoBuffer, symLinkBuffer, devnodeNameBuffer;
    02758     PKEY_VALUE_FULL_INFORMATION pDefaultInfo;
    02759     ULONG tempLong, keyIndex, instanceKeyIndex, resultSize;
    02760     HANDLE hDeviceClasses, hClass, hKey, hInstanceKey, hControl;
    02761     BOOLEAN defaultPresent = FALSE;
    02762
    02763     PAGED_CODE();
    02764
    02765     //
    02766     // Initialise out parameters
    02767     //
    02768
    02769     *SymbolicLinkList = NULL;
    02770
    02771     //
    02772     // Convert the GUID into a string
    02773     //
    02774
    02775     status = RtlStringFromGUID(InterfaceClassGuid, &guidString);
    02776     if(!NT_SUCCESS(status)) {
    02777         goto finalClean;
    02778     }
    02779
    02780 #if DBG_GET_ASSOC
    02781     DbgPrint("Getting associations for class %wZ\n", &guidString);
    02782 #endif
    02783
    02784     //
    02785     // Allocate initial buffers
    02786     //
    02787
    02788     status = IopAllocateBuffer(&returnBuffer,
    02789                                INITIAL_RETURN_BUFFER_SIZE
    02790                                );
    02791
    02792     if (!NT_SUCCESS(status)) {
    02793         goto clean0;
    02794     }
    02795
    02796     status = IopAllocateBuffer(&infoBuffer,
    02797                                INITIAL_INFO_BUFFER_SIZE
    02798                                );
    02799
    02800     if (!NT_SUCCESS(status)) {
    02801         goto clean1;
    02802     }
    02803
    02804     status = IopAllocateBuffer(&symLinkBuffer,
    02805                                INITIAL_SYMLINK_BUFFER_SIZE
    02806                                );
    02807
    02808     if (!NT_SUCCESS(status)) {
    02809         goto clean2;
    02810     }
    02811
    02812     status = IopAllocateBuffer(&devnodeNameBuffer,
    02813                                INITIAL_DEVNODE_NAME_BUFFER_SIZE
    02814                                );
    02815
    02816     if (!NT_SUCCESS(status)) {
    02817         goto clean2a;
    02818     }
    02819
    02820     //
    02821     // Enter critical section and acquire a lock on the registry.  Both these
    02822     // mechanisms are required to prevent deadlock in the case where an APC
    02823     // routine calls this routine after the registry resource has been claimed
    02824     // in this case it would wait blocking this thread so the registry would
    02825     // never be released -> deadlock.  Critical sectioning the registry manipulation
    02826     // portion solves this problem
    02827     //
    02828
    02829     KeEnterCriticalRegion();
    02830     ExAcquireResourceExclusive(&PpRegistryDeviceResource, TRUE);
    02831
    02832     //
    02833     // Open HKLM\System\CurrentControlSet\Control\DeviceClasses key
    02834     //
    02835
    02836     PiWstrToUnicodeString(&tempString, REGSTR_FULL_PATH_DEVICE_CLASSES);
    02837     status = IopCreateRegistryKeyEx( &hDeviceClasses,
    02838                                      NULL,
    02839                                      &tempString,
    02840                                      KEY_ALL_ACCESS,
    02841                                      REG_OPTION_NON_VOLATILE,
    02842                                      NULL
    02843                                      );
    02844
    02845     if (!NT_SUCCESS(status)) {
    02846         goto clean3;
    02847     }
    02848
    02849     //
    02850     // Open function class GUID key
    02851     //
    02852
    02853     status = IopOpenRegistryKeyEx( &hClass,
    02854                                    hDeviceClasses,
    02855                                    &guidString,
    02856                                    KEY_ALL_ACCESS
    02857                                    );
    02858     ZwClose(hDeviceClasses);
    02859
    02860     if(status == STATUS_OBJECT_NAME_NOT_FOUND || status == STATUS_OBJECT_PATH_NOT_FOUND) {
    02861
    02862         //
    02863         // The path does not exist - return a single null character buffer
    02864         //
    02865
    02866         status = STATUS_SUCCESS;
    02867         goto clean5;
    02868     } else if (!NT_SUCCESS(status)) {
    02869         goto clean3;
    02870     }
    02871
    02872     //
    02873     // Get the default value if it exists
    02874     //
    02875
    02876     status = IopGetRegistryValue(hClass,
    02877                                  REGSTR_VAL_DEFAULT,
    02878                                  &pDefaultInfo
    02879                                  );
    02880
    02881
    02882     if (NT_SUCCESS(status)
    02883         && pDefaultInfo->Type == REG_SZ
    02884         && pDefaultInfo->DataLength >= sizeof(WCHAR)) {
    02885
    02886         //
    02887         // We have a default - construct a counted string from the default
    02888         //
    02889
    02890         defaultPresent = TRUE;
    02891         defaultString.Buffer = (PWSTR) KEY_VALUE_DATA(pDefaultInfo);
    02892         defaultString.Length = (USHORT) pDefaultInfo->DataLength - sizeof(UNICODE_NULL);
    02893         defaultString.MaximumLength = defaultString.Length;
    02894
    02895 #if DBG_GET_ASSOC
    02896         DbgPrint("Class default: %wZ\n", &defaultString);
    02897 #endif
    02898
    02899         //
    02900         // Open the device interface instance key for the default name.
    02901         //
    02902         status = IopOpenOrCreateDeviceInterfaceSubKeys(NULL,
    02903                                                        NULL,
    02904                                                        &hKey,
    02905                                                        NULL,
    02906                                                        hClass,
    02907                                                        &defaultString,
    02908                                                        KEY_READ,
    02909                                                        FALSE
    02910                                                       );
    02911
    02912         if (!NT_SUCCESS(status)) {
    02913             defaultPresent = FALSE;
    02914             ExFreePool(pDefaultInfo);
    02915             //
    02916             // Continue with the call but ignore the invalid default entry
    02917             //
    02918 #if DBG_GET_ASSOC
    02919             DbgPrint("WDM Warning: Default entry for class %zW is invalid\n", &guidString);
    02920 #endif
    02921         } else {
    02922
    02923             //
    02924             // If we are just supposed to return live interfaces, then make sure this default
    02925             // interface is linked.
    02926             //
    02927
    02928             if (!(Flags & DEVICE_INTERFACE_INCLUDE_NONACTIVE)) {
    02929
    02930                 defaultPresent = FALSE;
    02931
    02932                 //
    02933                 // Open the control subkey
    02934                 //
    02935
    02936                 PiWstrToUnicodeString(&tempString, REGSTR_KEY_CONTROL);
    02937                 status = IopOpenRegistryKeyEx( &hControl,
    02938                                                hKey,
    02939                                                &tempString,
    02940                                                KEY_ALL_ACCESS
    02941                                                );
    02942
    02943                 if (NT_SUCCESS(status)) {
    02944                     //
    02945                     // Get the linked value
    02946                     //
    02947
    02948                     PiWstrToUnicodeString(&tempString, REGSTR_VAL_LINKED);
    02949                     status = ZwQueryValueKey(hControl,
    02950                                              &tempString,
    02951                                              KeyValuePartialInformation,
    02952                                              (PVOID) infoBuffer.Buffer,
    02953                                              infoBuffer.MaxSize,
    02954                                              &resultSize
    02955                                              );
    02956
    02957                     ZwClose(hControl);
    02958
    02959                     //
    02960                     // We don't need to check the buffer was big enough because it starts
    02961                     // off that way and doesn't get any smaller!
    02962                     //
    02963
    02964                     if (NT_SUCCESS(status)
    02965                         && (((PKEY_VALUE_PARTIAL_INFORMATION)(infoBuffer.Buffer))->Type == REG_DWORD)
    02966                         && (((PKEY_VALUE_PARTIAL_INFORMATION)(infoBuffer.Buffer))->DataLength == sizeof(ULONG))) {
    02967
    02968                         defaultPresent = *(PULONG)(((PKEY_VALUE_PARTIAL_INFORMATION)(infoBuffer.Buffer))->Data)
    02969                                        ? TRUE
    02970                                        : FALSE;
    02971                     }
    02972                 }
    02973             }
    02974
    02975             ZwClose(hKey);
    02976
    02977             if(defaultPresent) {
    02978                 //
    02979                 // Add the default as the first entry in the return buffer and patch to usermode if necessary
    02980                 //
    02981                 status = IopAppendBuffer(&returnBuffer,
    02982                                          defaultString.Buffer,
    02983                                          defaultString.Length + sizeof(UNICODE_NULL)
    02984                                         );
    02985
    02986                 if (!UserModeFormat) {
    02987
    02988                     RtlCopyMemory(returnBuffer.Buffer,
    02989                                   KERNEL_SYMLINK_STRING_PREFIX,
    02990                                   KERNEL_SYMLINK_STRING_PREFIX_LENGTH
    02991                                   );
    02992                 }
    02993
    02994             } else {
    02995                 //
    02996                 // The default device interface isn't active--free the memory for the name buffer now.
    02997                 //
    02998                 ExFreePool(pDefaultInfo);
    02999             }
    03000         }
    03001
    03002     } else if (status == STATUS_OBJECT_NAME_NOT_FOUND || status == STATUS_OBJECT_PATH_NOT_FOUND) {
    03003         //
    03004         // Do nothing - there is no default
    03005         //
    03006     } else {
    03007         //
    03008         // An unexpected error occured - clean up
    03009         //
    03010         if (NT_SUCCESS(status)) {
    03011
    03012             ExFreePool(pDefaultInfo);
    03013             status = STATUS_UNSUCCESSFUL;
    03014         }
    03015
    03016         ZwClose(hClass);
    03017         goto clean4;
    03018     }
    03019
    03020     //
    03021     // Iterate through the subkeys under this interface class key.
    03022     //
    03023
    03024     keyIndex = 0;
    03025
    03026     while((status = ZwEnumerateKey(hClass,
    03027                                    keyIndex,
    03028                                    KeyBasicInformation,
    03029                                    (PVOID) infoBuffer.Buffer,
    03030                                    infoBuffer.MaxSize,
    03031                                    &resultSize
    03032                                    )) != STATUS_NO_MORE_ENTRIES)
    03033     {
    03034
    03035         if (status == STATUS_BUFFER_TOO_SMALL) {
    03036
    03037             status = IopResizeBuffer(&infoBuffer, resultSize, FALSE);
    03038
    03039             continue;
    03040
    03041         } else if (!NT_SUCCESS(status)) {
    03042             ZwClose(hClass);
    03043             goto clean4;
    03044         }
    03045
    03046         //
    03047         // Open up this interface key.
    03048         //
    03049         tempString.Length = (USHORT) ((PKEY_BASIC_INFORMATION)(infoBuffer.Buffer))->NameLength;
    03050         tempString.MaximumLength = tempString.Length;
    03051         tempString.Buffer = ((PKEY_BASIC_INFORMATION)(infoBuffer.Buffer))->Name;
    03052
    03053 #if DBG_GET_ASSOC
    03054         DbgPrint("Key %u enumerated %wZ\n", keyIndex, &tempString);
    03055 #endif
    03056
    03057         //
    03058         // Open the associated key
    03059         //
    03060
    03061         status = IopOpenRegistryKeyEx( &hKey,
    03062                                        hClass,
    03063                                        &tempString,
    03064                                        KEY_READ
    03065                                        );
    03066
    03067         if (!NT_SUCCESS(status)) {
    03068             //
    03069             // For some reason we couldn't open this key--skip it and move on.
    03070             //
    03071 #if DBG_GET_ASSOC
    03072             DbgPrint("\tCouldn't open interface key!\n");
    03073 #endif
    03074             keyIndex++;
    03075             continue;
    03076         }
    03077
    03078         //
    03079         // If we're filtering on a particular PDO, then retrieve the owning device
    03080         // instance name for this interface key, and make sure they match.
    03081         //
    03082         PiWstrToUnicodeString(&tempString, REGSTR_VAL_DEVICE_INSTANCE);
    03083         while ((status = ZwQueryValueKey(hKey,
    03084                                          &tempString,
    03085                                          KeyValuePartialInformation,
    03086                                          devnodeNameBuffer.Buffer,
    03087                                          devnodeNameBuffer.MaxSize,
    03088                                          &resultSize
    03089                                          )) == STATUS_BUFFER_TOO_SMALL ) {
    03090
    03091             status = IopResizeBuffer(&devnodeNameBuffer, resultSize, FALSE);
    03092
    03093             if (!NT_SUCCESS(status)) {
    03094                 ZwClose(hKey);
    03095                 ZwClose(hClass);
    03096                 goto clean4;
    03097             }
    03098         }
    03099
    03100         if (!(NT_SUCCESS(status)
    03101               && ((PKEY_VALUE_PARTIAL_INFORMATION)(devnodeNameBuffer.Buffer))->Type == REG_SZ
    03102               && ((PKEY_VALUE_PARTIAL_INFORMATION)(devnodeNameBuffer.Buffer))->DataLength > sizeof(WCHAR) ) ) {
    03103 #if DBG_GET_ASSOC
    03104             DbgPrint("\tDevice instance entry corrupt\n");
    03105 #endif
    03106             goto CloseInterfaceKeyAndContinue;
    03107         }
    03108
    03109         //
    03110         // Build counted string
    03111         //
    03112
    03113         devnodeString.Length = (USHORT) ((PKEY_VALUE_PARTIAL_INFORMATION)(devnodeNameBuffer.Buffer))->DataLength - sizeof(UNICODE_NULL);
    03114         devnodeString.MaximumLength = tempString.Length;
    03115         devnodeString.Buffer = (PWSTR) ((PKEY_VALUE_PARTIAL_INFORMATION)(devnodeNameBuffer.Buffer))->Data;
    03116
    03117         //
    03118         // Enumerate each interface instance subkey under this PDO's interface key.
    03119         //
    03120         instanceKeyIndex = 0;
    03121
    03122         while((status = ZwEnumerateKey(hKey,
    03123                                        instanceKeyIndex,
    03124                                        KeyBasicInformation,
    03125                                        (PVOID) infoBuffer.Buffer,
    03126                                        infoBuffer.MaxSize,
    03127                                        &resultSize
    03128                                        )) != STATUS_NO_MORE_ENTRIES)
    03129         {
    03130
    03131             if (status == STATUS_BUFFER_TOO_SMALL) {
    03132
    03133                 status = IopResizeBuffer(&infoBuffer, resultSize, FALSE);
    03134
    03135                 continue;
    03136
    03137             } else if (!NT_SUCCESS(status)) {
    03138                 ZwClose(hKey);
    03139                 ZwClose(hClass);
    03140                 goto clean4;
    03141             }
    03142
    03143             //
    03144             // Open up this interface instance key.
    03145             //
    03146             tempString.Length = (USHORT) ((PKEY_BASIC_INFORMATION)(infoBuffer.Buffer))->NameLength;
    03147             tempString.MaximumLength = tempString.Length;
    03148             tempString.Buffer = ((PKEY_BASIC_INFORMATION)(infoBuffer.Buffer))->Name;
    03149
    03150 #if DBG_GET_ASSOC
    03151             DbgPrint("Instance key %u enumerated %wZ\n", instanceKeyIndex, &tempString);
    03152 #endif
    03153
    03154             //
    03155             // Open the associated key
    03156             //
    03157
    03158             status = IopOpenRegistryKeyEx( &hInstanceKey,
    03159                                            hKey,
    03160                                            &tempString,
    03161                                            KEY_READ
    03162                                            );
    03163
    03164             if (!NT_SUCCESS(status)) {
    03165                 //
    03166                 // For some reason we couldn't open this key--skip it and move on.
    03167                 //
    03168 #if DBG_GET_ASSOC
    03169                 DbgPrint("\tCouldn't open interface key!\n");
    03170 #endif
    03171                 instanceKeyIndex++;
    03172                 continue;
    03173             }
    03174
    03175             if (!(Flags & DEVICE_INTERFACE_INCLUDE_NONACTIVE)) {
    03176
    03177                 //
    03178                 // Open the control subkey
    03179                 //
    03180
    03181                 PiWstrToUnicodeString(&tempString, REGSTR_KEY_CONTROL);
    03182                 status = IopOpenRegistryKeyEx( &hControl,
    03183                                                hInstanceKey,
    03184                                                &tempString,
    03185                                                KEY_READ
    03186                                                );
    03187
    03188                 if (!NT_SUCCESS(status)) {
    03189
    03190                     //
    03191                     // We have no control subkey so can't be linked -
    03192                     // continue enumerating the keys ignoring this one
    03193                     //
    03194
    03195 #if DBG_GET_ASSOC
    03196                     DbgPrint("\tNo control subkey\n");
    03197 #endif
    03198                     goto CloseInterfaceInstanceKeyAndContinue;
    03199                 }
    03200
    03201                 //
    03202                 // Get the linked value
    03203                 //
    03204
    03205                 PiWstrToUnicodeString(&tempString, REGSTR_VAL_LINKED);
    03206                 status = ZwQueryValueKey(hControl,
    03207                                          &tempString,
    03208                                          KeyValuePartialInformation,
    03209                                          (PVOID) infoBuffer.Buffer,
    03210                                          infoBuffer.MaxSize,
    03211                                          &resultSize
    03212                                          );
    03213
    03214                 ZwClose(hControl);
    03215
    03216                 //
    03217                 // We don't need to check the buffer was big enough because it starts
    03218                 // off that way and doesn't get any smaller!
    03219                 //
    03220
    03221                 if (!NT_SUCCESS(status)
    03222                     || (((PKEY_VALUE_PARTIAL_INFORMATION)(infoBuffer.Buffer))->Type != REG_DWORD)
    03223                     || (((PKEY_VALUE_PARTIAL_INFORMATION)(infoBuffer.Buffer))->DataLength != sizeof(ULONG))
    03224                     || !*(PULONG)(((PKEY_VALUE_PARTIAL_INFORMATION)(infoBuffer.Buffer))->Data)) {
    03225
    03226                     //
    03227                     // We are NOT linked so continue enumerating the keys ignoring this one
    03228                     //
    03229
    03230 #if DBG_GET_ASSOC
    03231                     DbgPrint("\tNot Linked\n");
    03232 #endif
    03233                     goto CloseInterfaceInstanceKeyAndContinue;
    03234                 }
    03235             }
    03236
    03237             //
    03238             // Open the "SymbolicLink" value and place the information into the symLink buffer
    03239             //
    03240
    03241             PiWstrToUnicodeString(&tempString, REGSTR_VAL_SYMBOLIC_LINK);
    03242             while ((status = ZwQueryValueKey(hInstanceKey,
    03243                                              &tempString,
    03244                                              KeyValuePartialInformation,
    03245                                              symLinkBuffer.Buffer,
    03246                                              symLinkBuffer.MaxSize,
    03247                                              &resultSize
    03248                                              )) == STATUS_BUFFER_TOO_SMALL ) {
    03249
    03250                 status = IopResizeBuffer(&symLinkBuffer, resultSize, FALSE);
    03251
    03252                 if (!NT_SUCCESS(status)) {
    03253                     ZwClose(hInstanceKey);
    03254                     ZwClose(hKey);
    03255                     ZwClose(hClass);
    03256                     goto clean4;
    03257                 }
    03258             }
    03259
    03260             if (!(NT_SUCCESS(status)
    03261                 && ((PKEY_VALUE_PARTIAL_INFORMATION)(symLinkBuffer.Buffer))->Type == REG_SZ
    03262                 && ((PKEY_VALUE_PARTIAL_INFORMATION)(symLinkBuffer.Buffer))->DataLength > sizeof(WCHAR) ) ) {
    03263 #if DBG_GET_ASSOC
    03264                 DbgPrint("\tSymbolic link entry corrupt\n");
    03265 #endif
    03266                 goto CloseInterfaceInstanceKeyAndContinue;
    03267             }
    03268
    03269             //
    03270             // Build counted string from value data
    03271             //
    03272
    03273             symLinkString.Length = (USHORT) ((PKEY_VALUE_PARTIAL_INFORMATION)(symLinkBuffer.Buffer))->DataLength - sizeof(UNICODE_NULL);
    03274             symLinkString.MaximumLength = symLinkString.Length;
    03275             symLinkString.Buffer = (PWSTR) ((PKEY_VALUE_PARTIAL_INFORMATION)(symLinkBuffer.Buffer))->Data;
    03276
    03277             //
    03278             // If we have a default, check this is not it
    03279             //
    03280
    03281             if (defaultPresent) {
    03282
    03283                 if (RtlCompareUnicodeString(&defaultString, &symLinkString, TRUE) == 0) {
    03284
    03285                     //
    03286                     // We have already added the default to the beginning of the buffer so skip it
    03287                     //
    03288
    03289 #if DBG_GET_ASSOC
    03290                     DbgPrint("\tDefault entry skipped\n");
    03291 #endif
    03292                     goto CloseInterfaceInstanceKeyAndContinue;
    03293                 }
    03294             }
    03295
    03296             //
    03297             // If we are only returning interfaces for a particular PDO then check
    03298             // this is from that PDO
    03299             //
    03300             if (ARGUMENT_PRESENT(DevicePath)) {
    03301                 //
    03302                 // Check if it is from the same PDO
    03303                 //
    03304                 if (RtlCompareUnicodeString(DevicePath, &devnodeString, TRUE) != 0) {
    03305                     //
    03306                     // If not then go onto the next key
    03307                     //
    03308 #if DBG_GET_ASSOC
    03309                     DbgPrint("\tNot from the correct PDO\n");
    03310 #endif
    03311                     goto CloseInterfaceInstanceKeyAndContinue;
    03312                 }
    03313             }
    03314
    03315             //
    03316             // Copy the symLink string to the return buffer including the NULL termination
    03317             //
    03318
    03319             status = IopAppendBuffer(&returnBuffer,
    03320                                      symLinkString.Buffer,
    03321                                      symLinkString.Length + sizeof(UNICODE_NULL)
    03322                                      );
    03323
    03324             ASSERT(((PWSTR) returnBuffer.Current)[-1] == UNICODE_NULL);
    03325
    03326 #if DBG_GET_ASSOC
    03327             DbgPrint("\tAdded to return buffer\n");
    03328 #endif
    03329
    03330             //
    03331             // If we are returning KM strings then patch the prefix
    03332             //
    03333
    03334             if (!UserModeFormat) {
    03335
    03336                 RtlCopyMemory(returnBuffer.Current - (symLinkString.Length + sizeof(UNICODE_NULL)),
    03337                               KERNEL_SYMLINK_STRING_PREFIX,
    03338                               KERNEL_SYMLINK_STRING_PREFIX_LENGTH
    03339                               );
    03340             }
    03341
    03342 CloseInterfaceInstanceKeyAndContinue:
    03343             ZwClose(hInstanceKey);
    03344             instanceKeyIndex++;
    03345         }
    03346
    03347 CloseInterfaceKeyAndContinue:
    03348         ZwClose(hKey);
    03349         keyIndex++;
    03350     }
    03351
    03352     ZwClose(hClass);
    03353
    03354 clean5:
    03355     //
    03356     // We've got then all!  Resize to leave space for a terminating NULL.
    03357     //
    03358
    03359     status = IopResizeBuffer(&returnBuffer,
    03360                              (ULONG) (returnBuffer.Current - returnBuffer.Buffer + sizeof(UNICODE_NULL)),
    03361                              TRUE
    03362                              );
    03363
    03364     if (NT_SUCCESS(status)) {
    03365
    03366         //
    03367         // Terminate the buffer
    03368         //
    03369         *((PWSTR) returnBuffer.Current) = UNICODE_NULL;
    03370     }
    03371
    03372 clean4:
    03373     if (defaultPresent) {
    03374         ExFreePool(pDefaultInfo);
    03375     }
    03376
    03377 clean3:
    03378     ExReleaseResource(&PpRegistryDeviceResource);
    03379     KeLeaveCriticalRegion();
    03380     IopFreeBuffer(&devnodeNameBuffer);
    03381
    03382 clean2a:
    03383     IopFreeBuffer(&symLinkBuffer);
    03384
    03385 clean2:
    03386     IopFreeBuffer(&infoBuffer);
    03387
    03388 clean1:
    03389     if (!NT_SUCCESS(status)) {
    03390         IopFreeBuffer(&returnBuffer);
    03391     }
    03392
    03393 clean0:
    03394     RtlFreeUnicodeString(&guidString);
    03395
    03396 finalClean:
    03397     if (NT_SUCCESS(status)) {
    03398
    03399         *SymbolicLinkList = (PWSTR) returnBuffer.Buffer;
    03400
    03401         if (ARGUMENT_PRESENT(SymbolicLinkListSize)) {
    03402             *SymbolicLinkListSize = returnBuffer.MaxSize;
    03403         }
    03404
    03405     } else {
    03406
    03407         *SymbolicLinkList = NULL;
    03408
    03409         if (ARGUMENT_PRESENT(SymbolicLinkListSize)) {
    03410             *SymbolicLinkListSize = 0;
    03411         }
    03412
    03413     }
    03414
    03415     return status;
    03416 }

NTSTATUS IopGetDeviceResourcesFromRegistry | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN ULONG | ResourceType,
|  | IN ULONG | Preference,
|  | OUT PVOID * | Resource,
|  | OUT PULONG | Length
| ) |

Definition at line 4081 of file pnpsubs.c.

References ExAllocatePool, ExFreePool(), FALSE, IopDeviceObjectToDeviceInstance(), IopGetRegistryValue(), IopOpenRegistryKey(), IopReadDeviceConfiguration(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, PnpDefaultInterfaceType, QUERY_RESOURCE_LIST, REGISTRY_ALLOC_CONFIG, REGISTRY_BASIC_CONFIGVECTOR, REGISTRY_BOOT_CONFIG, REGISTRY_FORCED_CONFIG, REGISTRY_OVERRIDE_CONFIGVECTOR, and Resource.

Referenced by IopInitializeDeviceInstanceKey(), IopPnPDispatch(), and IopQueryDeviceResources().

    04091                    :
    04092
    04093     This routine determines the resources decoded by the device specified.
    04094     If the device object is a madeup device, we will try to read the resources
    04095     from registry.  Otherwise, we need to traverse the internal assigned resource
    04096     list to compose the resource list.
    04097
    04098 Arguments:
    04099
    04100     DeviceObject - supplies a pointer to a device object whose registry
    04101         values are to be cleaned up.
    04102
    04103     ResourceType - 0 for CM_RESOURCE_LIST and 1 for IO_RESOURCE_REQUIREMENTS_LIS
    04104
    04105     Flags - specify the preference.
    04106
    04107     Resource - Specified a variable to receive the required resources.
    04108
    04109     Length - Specified a variable to receive the length of the resource structure.
    04110
    04111 Return Value:
    04112
    04113     status
    04114
    04115 --*/
    04116
    04117 {
    04118     PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
    04119     HANDLE handle, handlex;
    04120     NTSTATUS status;
    04121     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    04122     PCM_RESOURCE_LIST cmResource;
    04123     PIO_RESOURCE_REQUIREMENTS_LIST ioResource;
    04124     ULONG length;
    04125     UNICODE_STRING unicodeName;
    04126     PWCHAR valueName = NULL;
    04127
    04128     *Resource = NULL;
    04129     *Length = 0;
    04130
    04131     //
    04132     // Open the LogConfig key of the device instance.
    04133     //
    04134
    04135     status = IopDeviceObjectToDeviceInstance(DeviceObject, &handlex, KEY_READ);
    04136     if (!NT_SUCCESS(status)) {
    04137         return status;
    04138     }
    04139
    04140     if (ResourceType == QUERY_RESOURCE_LIST) {
    04141
    04142         //
    04143         // Caller is asking for CM_RESOURCE_LIST
    04144         //
    04145
    04146         if (Preference & REGISTRY_ALLOC_CONFIG) {
    04147
    04148             //
    04149             // Try alloc config first
    04150             //
    04151
    04152             PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
    04153             status = IopOpenRegistryKeyEx( &handle,
    04154                                            handlex,
    04155                                            &unicodeName,
    04156                                            KEY_READ
    04157                                            );
    04158             if (NT_SUCCESS(status)) {
    04159                 status = IopReadDeviceConfiguration (handle, REGISTRY_ALLOC_CONFIG, (PCM_RESOURCE_LIST *)Resource, Length);
    04160                 ZwClose(handle);
    04161                 if (NT_SUCCESS(status)) {
    04162                     ZwClose(handlex);
    04163                     return status;
    04164                 }
    04165             }
    04166         }
    04167
    04168         handle = NULL;
    04169         if (Preference & REGISTRY_FORCED_CONFIG) {
    04170
    04171             PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF);
    04172             status = IopOpenRegistryKeyEx( &handle,
    04173                                            handlex,
    04174                                            &unicodeName,
    04175                                            KEY_READ
    04176                                            );
    04177             if (NT_SUCCESS(status)) {
    04178                 status = IopReadDeviceConfiguration (handle, REGISTRY_FORCED_CONFIG, (PCM_RESOURCE_LIST *)Resource, Length);
    04179                 if (NT_SUCCESS(status)) {
    04180                     ZwClose(handle);
    04181                     ZwClose(handlex);
    04182                     return status;
    04183                 }
    04184             } else {
    04185                 ZwClose(handlex);
    04186                 return status;
    04187             }
    04188         }
    04189         if (Preference & REGISTRY_BOOT_CONFIG) {
    04190
    04191             //
    04192             // Try alloc config first
    04193             //
    04194
    04195             if (handle == NULL) {
    04196                 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF);
    04197                 status = IopOpenRegistryKeyEx( &handle,
    04198                                                handlex,
    04199                                                &unicodeName,
    04200                                                KEY_READ
    04201                                                );
    04202                 if (!NT_SUCCESS(status)) {
    04203                     ZwClose(handlex);
    04204                     return status;
    04205                 }
    04206             }
    04207             status = IopReadDeviceConfiguration( handle,
    04208                                                  REGISTRY_BOOT_CONFIG,
    04209                                                  (PCM_RESOURCE_LIST *)Resource,
    04210                                                  Length);
    04211         }
    04212         if (handle) {
    04213             ZwClose(handle);
    04214         }
    04215     } else {
    04216
    04217         PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF);
    04218         status = IopOpenRegistryKeyEx( &handle,
    04219                                        handlex,
    04220                                        &unicodeName,
    04221                                        KEY_READ
    04222                                        );
    04223         if (NT_SUCCESS(status)) {
    04224
    04225             if (Preference & REGISTRY_OVERRIDE_CONFIGVECTOR) {
    04226                 valueName = REGSTR_VALUE_OVERRIDE_CONFIG_VECTOR;
    04227             } else if (Preference & REGISTRY_BASIC_CONFIGVECTOR) {
    04228                 valueName = REGSTR_VALUE_BASIC_CONFIG_VECTOR;
    04229             }
    04230             if (valueName) {
    04231
    04232                 //
    04233                 // Try to read device's configuration vector
    04234                 //
    04235
    04236                 status = IopGetRegistryValue (handle,
    04237                                               valueName,
    04238                                               &keyValueInformation);
    04239                 if (NT_SUCCESS(status)) {
    04240
    04241                     //
    04242                     // Try to read what caller wants.
    04243                     //
    04244
    04245                     if ((keyValueInformation->Type == REG_RESOURCE_REQUIREMENTS_LIST) &&
    04246                         (keyValueInformation->DataLength != 0)) {
    04247
    04248                         *Resource = ExAllocatePool(PagedPool,
    04249                                                    keyValueInformation->DataLength);
    04250                         if (*Resource) {
    04251                             PIO_RESOURCE_REQUIREMENTS_LIST ioResource;
    04252
    04253                             *Length = keyValueInformation->DataLength;
    04254                             RtlMoveMemory(*Resource,
    04255                                           KEY_VALUE_DATA(keyValueInformation),
    04256                                           keyValueInformation->DataLength);
    04257
    04258                             //
    04259                             // Process the io resource requirements list to change undefined
    04260                             // interface type to our default type.
    04261                             //
    04262
    04263                             ioResource = *Resource;
    04264                             if (ioResource->InterfaceType == InterfaceTypeUndefined) {
    04265                                 ioResource->BusNumber = 0;
    04266                                 ioResource->InterfaceType = PnpDefaultInterfaceType;
    04267                             }
    04268                         } else {
    04269                             status = STATUS_INVALID_PARAMETER_2;
    04270                         }
    04271                     }
    04272                     ExFreePool(keyValueInformation);
    04273                 }
    04274             }
    04275             ZwClose(handle);
    04276         }
    04277     }
    04278     ZwClose(handlex);
    04279     return status;
    04280 }

USHORT IopGetGroupOrderIndex | ( | IN HANDLE | ServiceHandle | ) |

Definition at line 5334 of file pnpsubs.c.

References ExFreePool(), FALSE, IopFreeUnicodeStringList(), IopGetRegistryValue(), IopOpenRegistryKey(), IopRegistryDataToUnicodeString, IopRegMultiSzToUnicodeStrings(), KEY_VALUE_DATA, L, NO_MORE_GROUP, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, RtlEqualUnicodeString(), TRUE, and USHORT.

Referenced by IopCallDriverAddDeviceQueryRoutine(), and IopInitializeBootDrivers().

    05340                    :
    05341
    05342     This routine reads the Group value of the service key, finds its position in the
    05343     ServiceOrderList.  If ServiceHandle is NULL or unrecognized group value, it returns
    05344     a value with max group order + 1.
    05345     if any.
    05346
    05347 Parameters:
    05348
    05349     ServiceHandle - supplies a handle to the service key.
    05350
    05351 Return Value:
    05352
    05353     group order index.
    05354
    05355 --*/
    05356
    05357 {
    05358     NTSTATUS status;
    05359     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    05360     UNICODE_STRING *groupTable, group;
    05361     HANDLE handle;
    05362     ULONG count, index;
    05363
    05364     PAGED_CODE();
    05365
    05366     //
    05367     // Open System\CurrentControlSet\Control\ServiceOrderList
    05368     //
    05369
    05370     PiWstrToUnicodeString(&group, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ServiceGroupOrder");
    05371     status = IopOpenRegistryKeyEx( &handle,
    05372                                    NULL,
    05373                                    &group,
    05374                                    KEY_READ
    05375                                    );
    05376
    05377     if (!NT_SUCCESS( status )) {
    05378         return NO_MORE_GROUP;
    05379     }
    05380
    05381     //
    05382     // Read and build a unicode string array containing all the group names.
    05383     //
    05384
    05385     status = IopGetRegistryValue (handle,
    05386                                   L"List",
    05387                                   &keyValueInformation);
    05388     ZwClose(handle);
    05389     if (NT_SUCCESS(status)) {
    05390
    05391         if ((keyValueInformation->Type == REG_MULTI_SZ) &&
    05392             (keyValueInformation->DataLength != 0)) {
    05393
    05394             status = IopRegMultiSzToUnicodeStrings(keyValueInformation, &groupTable, &count);
    05395         } else {
    05396             status = STATUS_UNSUCCESSFUL;
    05397         }
    05398         ExFreePool(keyValueInformation);
    05399     }
    05400
    05401     if (!NT_SUCCESS(status)) {
    05402         return NO_MORE_GROUP;
    05403     }
    05404
    05405     if (ServiceHandle == NULL) {
    05406         IopFreeUnicodeStringList(groupTable, count);
    05407         return (USHORT)(count + 1);
    05408     }
    05409
    05410
    05411     //
    05412     // Read service key's Group value
    05413     //
    05414
    05415     status = IopGetRegistryValue (ServiceHandle,
    05416                                   L"Group",
    05417                                   &keyValueInformation);
    05418     if (NT_SUCCESS(status)) {
    05419
    05420         //
    05421         // Try to read what caller wants.
    05422         //
    05423
    05424         if ((keyValueInformation->Type == REG_SZ) &&
    05425             (keyValueInformation->DataLength != 0)) {
    05426             IopRegistryDataToUnicodeString(&group,
    05427                                            (PWSTR)KEY_VALUE_DATA(keyValueInformation),
    05428                                            keyValueInformation->DataLength
    05429                                            );
    05430         }
    05431     } else {
    05432
    05433         //
    05434         // If we failed to read the Group value, or no Group value...
    05435         //
    05436
    05437         IopFreeUnicodeStringList(groupTable, count);
    05438         return (USHORT)count;
    05439     }
    05440
    05441     index = 0;
    05442     for (index = 0; index < count; index++) {
    05443         if (RtlEqualUnicodeString(&group, &groupTable[index], TRUE)) {
    05444             break;
    05445         }
    05446     }
    05447     ExFreePool(keyValueInformation);
    05448     IopFreeUnicodeStringList(groupTable, count);
    05449     return (USHORT)index;
    05450 }

NTSTATUS IopGetRelatedTargetDevice | ( | IN PFILE_OBJECT | FileObject,
|  | OUT PDEVICE_NODE * | DeviceNode
| ) |

Definition at line 8036 of file pnpioapi.c.

References ASSERT, _DEVICE_RELATIONS::Count, DbgPrint, _DEVOBJ_EXTENSION::DeviceNode, _IO_STACK_LOCATION::DeviceObject, _DEVICE_OBJECT::DeviceObjectExtension, _DRIVER_OBJECT::DriverExtension, _DEVICE_OBJECT::DriverObject, ExFreePool(), _IO_STACK_LOCATION::FileObject, IoGetRelatedDeviceObject(), IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_DEVICE_RELATIONS, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), _DEVICE_RELATIONS::Objects, _IO_STACK_LOCATION::Parameters, _DRIVER_EXTENSION::ServiceKeyName, and TargetDeviceRelation.

Referenced by IoGetRelatedTargetDevice(), and IoRegisterPlugPlayNotification().

    08043                    :
    08044
    08045     IopGetRelatedTargetDevice retrieves the device object associated with
    08046     the specified file object and then sends a query device relations irp
    08047     to that device object.
    08048
    08049     NOTE: The PDO associated with the returned device node has been referenced,
    08050     and must be dereferenced when no longer needed.
    08051
    08052 Arguments:
    08053
    08054     FileObject - Specifies the file object that is associated with the device
    08055                  object that will receive the query device relations irp.
    08056
    08057     DeviceNode - Returns the related target device node.
    08058
    08059 ReturnValue
    08060
    08061     Returns an NTSTATUS value.
    08062
    08063 --*/
    08064
    08065 {
    08066     NTSTATUS status;
    08067     IO_STACK_LOCATION irpSp;
    08068     PDEVICE_OBJECT deviceObject;
    08069     PDEVICE_RELATIONS deviceRelations;
    08070
    08071     ASSERT(FileObject);
    08072
    08073     //
    08074     // Retrieve the device object associated with this file handle.
    08075     //
    08076
    08077     deviceObject = IoGetRelatedDeviceObject(FileObject);
    08078     if (!deviceObject) {
    08079         return STATUS_NO_SUCH_DEVICE;
    08080     }
    08081
    08082     //
    08083     // Query what the "actual" target device node should be for
    08084     // this file object. Initialize the stack location to pass to
    08085     // IopSynchronousCall() and then send the IRP to the device
    08086     // object that's associated with the file handle.
    08087     //
    08088
    08089     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    08090     irpSp.MajorFunction = IRP_MJ_PNP;
    08091     irpSp.MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
    08092     irpSp.Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
    08093     irpSp.DeviceObject = deviceObject;
    08094     irpSp.FileObject = FileObject;
    08095
    08096     status = IopSynchronousCall(deviceObject, &irpSp, &deviceRelations);
    08097     if (!NT_SUCCESS(status)) {
    08098 #if 0
    08099         DbgPrint("PnpMgr: Contact dev owner for %WZ, which may not correctly support\n",
    08100                  &deviceObject->DriverObject->DriverExtension->ServiceKeyName);
    08101         DbgPrint("        IRP_MN_QUERY_DEVICE_RELATIONS:TargetDeviceRelation\n");
    08102         //ASSERT(0);
    08103 #endif
    08104         return status;
    08105     }
    08106
    08107     ASSERT(deviceRelations);
    08108     ASSERT(deviceRelations->Count == 1);
    08109
    08110     *DeviceNode = (PDEVICE_NODE)deviceRelations->Objects[0]->DeviceObjectExtension->DeviceNode;
    08111     if (!*DeviceNode) {
    08112         status = STATUS_NO_SUCH_DEVICE;
    08113     }
    08114
    08115     ExFreePool(deviceRelations);
    08116     return status;
    08117 }

NTSTATUS IopGetRootDevices | ( | PDEVICE_RELATIONS * | DeviceRelations | ) |

Definition at line 680 of file pnpinit.c.

References CmRegistryMachineSystemCurrentControlSetEnumRootName, _DEVICE_RELATIONS::Count, _ROOT_ENUMERATOR_CONTEXT::DeviceCount, _ROOT_ENUMERATOR_CONTEXT::DeviceList, ExAcquireResourceExclusive, ExAllocatePool, ExFreePool(), ExReleaseResource, FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS, IopApplyFunctionToSubKeys(), IopCreateRegistryKeyEx(), IopInitializeDeviceKey(), KeEnterCriticalRegion, KeLeaveCriticalRegion, _ROOT_ENUMERATOR_CONTEXT::KeyName, _ROOT_ENUMERATOR_CONTEXT::MaxDeviceCount, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, _DEVICE_RELATIONS::Objects, PAGED_CODE, PagedPool, PDEVICE_OBJECT, PNP_LARGE_SCRATCH_BUFFER_SIZE, PNP_SCRATCH_BUFFER_SIZE, PpRegistryDeviceResource, RtlAppendStringToString(), _ROOT_ENUMERATOR_CONTEXT::Status, and TRUE.

Referenced by IopPnPDispatch().

    00686                    :
    00687
    00688     This routine scans through System\Enum\Root subtree to build a device node for
    00689     each root device.
    00690
    00691 Arguments:
    00692
    00693     DeviceRelations - supplies a variable to receive the returned DEVICE_RELATIONS structure.
    00694
    00695 Return Value:
    00696
    00697     A NTSTATUS code.
    00698
    00699 --*/
    00700
    00701 {
    00702     NTSTATUS status;
    00703     HANDLE baseHandle;
    00704     UNICODE_STRING workName, tmpName;
    00705     PVOID buffer;
    00706     ROOT_ENUMERATOR_CONTEXT context;
    00707     ULONG i;
    00708     PDEVICE_RELATIONS deviceRelations;
    00709
    00710     PAGED_CODE();
    00711
    00712     *DeviceRelations = NULL;
    00713     buffer = ExAllocatePool(PagedPool, PNP_LARGE_SCRATCH_BUFFER_SIZE);
    00714     if (!buffer) {
    00715         return STATUS_INSUFFICIENT_RESOURCES;
    00716     }
    00717
    00718     //
    00719     // Allocate a buffer to store the PDOs enumerated.
    00720     // Note, the the buffer turns out to be not big enough, it will be reallocated dynamically.
    00721     //
    00722
    00723     context.DeviceList = (PDEVICE_OBJECT *) ExAllocatePool(PagedPool, PNP_SCRATCH_BUFFER_SIZE * 2);
    00724     if (context.DeviceList) {
    00725         context.MaxDeviceCount = (PNP_SCRATCH_BUFFER_SIZE * 2) / sizeof(PDEVICE_OBJECT);
    00726         context.DeviceCount = 0;
    00727     } else {
    00728         ExFreePool(buffer);
    00729         return STATUS_INSUFFICIENT_RESOURCES;
    00730     }
    00731
    00732     KeEnterCriticalRegion();
    00733     ExAcquireResourceExclusive(&PpRegistryDeviceResource, TRUE);
    00734
    00735     //
    00736     // Open System\CurrentControlSet\Enum\Root key and call worker routine to recursively
    00737     // scan through the subkeys.
    00738     //
    00739
    00740     status = IopCreateRegistryKeyEx( &baseHandle,
    00741                                      NULL,
    00742                                      &CmRegistryMachineSystemCurrentControlSetEnumRootName,
    00743                                      KEY_READ,
    00744                                      REG_OPTION_NON_VOLATILE,
    00745                                      NULL
    00746                                      );
    00747
    00748     if (NT_SUCCESS(status)) {
    00749
    00750         workName.Buffer = (PWSTR)buffer;
    00751         RtlFillMemory(buffer, PNP_LARGE_SCRATCH_BUFFER_SIZE, 0);
    00752         workName.MaximumLength = PNP_LARGE_SCRATCH_BUFFER_SIZE;
    00753         workName.Length = 0;
    00754
    00755         //
    00756         // only look at ROOT key
    00757         //
    00758
    00759         PiWstrToUnicodeString(&tmpName, REGSTR_KEY_ROOTENUM);
    00760         RtlAppendStringToString((PSTRING)&workName, (PSTRING)&tmpName);
    00761
    00762         //
    00763         // Enumerate all subkeys under the System\CCS\Enum\Root.
    00764         //
    00765
    00766         context.Status = STATUS_SUCCESS;
    00767         context.KeyName = &workName;
    00768
    00769         status = IopApplyFunctionToSubKeys(baseHandle,
    00770                                            NULL,
    00771                                            KEY_ALL_ACCESS,
    00772                                            FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS,
    00773                                            IopInitializeDeviceKey,
    00774                                            &context
    00775                                            );
    00776         ZwClose(baseHandle);
    00777
    00778         //
    00779         // Build returned information from ROOT_ENUMERATOR_CONTEXT.
    00780         //
    00781
    00782
    00783         status = context.Status;
    00784         if (NT_SUCCESS(status) && context.DeviceCount != 0) {
    00785             deviceRelations = (PDEVICE_RELATIONS) ExAllocatePool(
    00786                 PagedPool,
    00787                 sizeof (DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * context.DeviceCount
    00788                 );
    00789             if (deviceRelations == NULL) {
    00790                 status = STATUS_INSUFFICIENT_RESOURCES;
    00791             } else {
    00792                 deviceRelations->Count = context.DeviceCount;
    00793                 RtlMoveMemory(deviceRelations->Objects,
    00794                               context.DeviceList,
    00795                               sizeof (PDEVICE_OBJECT) * context.DeviceCount);
    00796                 *DeviceRelations = deviceRelations;
    00797             }
    00798         }
    00799         if (!NT_SUCCESS(status)) {
    00800
    00801             //
    00802             // If somehow the enumeration failed, we need to derefernece all the
    00803             // device objects.
    00804             //
    00805
    00806             for (i = 0; i < context.DeviceCount; i++) {
    00807                 ObDereferenceObject(context.DeviceList[i]);
    00808             }
    00809         }
    00810     }
    00811     ExReleaseResource(&PpRegistryDeviceResource);
    00812     KeLeaveCriticalRegion();
    00813     ExFreePool(buffer);
    00814     ExFreePool(context.DeviceList);
    00815     return status;
    00816 }

NTSTATUS IopGetServiceInstanceCsConfigFlags | ( | IN PUNICODE_STRING | ServiceKeyName,
|  | IN ULONG | Instance,
|  | OUT PULONG | CsConfigFlags
| ) |

Definition at line 1591 of file pnpsubs.c.

References ExFreePool(), FALSE, IopGetRegistryValue(), IopOpenCurrentHwProfileDeviceInstanceKey(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), and PAGED_CODE.

Referenced by IopIsAnyDeviceInstanceEnabled().

    01599                    :
    01600
    01601     This routine retrieves the csconfig flags for the specified device
    01602     which is specified by the instance number under ServiceKeyName\Enum.
    01603
    01604 Arguments:
    01605
    01606     ServiceKeyName - Supplies a pointer to the name of the subkey in the
    01607         system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services)
    01608         that caused the driver to load.
    01609
    01610     Instance - Supplies the instance value under ServiceKeyName\Enum key
    01611
    01612     CsConfigFlags - Supplies a variable to receive the device's CsConfigFlags
    01613
    01614 Return Value:
    01615
    01616     status
    01617
    01618 --*/
    01619
    01620 {
    01621     NTSTATUS status;
    01622     HANDLE handle;
    01623     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    01624
    01625     PAGED_CODE();
    01626
    01627     *CsConfigFlags = 0;
    01628
    01629     status = IopOpenCurrentHwProfileDeviceInstanceKey(&handle,
    01630                                                       ServiceKeyName,
    01631                                                       Instance,
    01632                                                       KEY_READ,
    01633                                                       FALSE
    01634                                                      );
    01635     if(NT_SUCCESS(status)) {
    01636         status = IopGetRegistryValue(handle,
    01637                                      REGSTR_VALUE_CSCONFIG_FLAGS,
    01638                                      &keyValueInformation
    01639                                     );
    01640         if(NT_SUCCESS(status)) {
    01641             if((keyValueInformation->Type == REG_DWORD) &&
    01642                (keyValueInformation->DataLength >= sizeof(ULONG))) {
    01643                 *CsConfigFlags = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    01644             }
    01645             ExFreePool(keyValueInformation);
    01646         }
    01647         ZwClose(handle);
    01648     }
    01649     return status;
    01650 }

VOID IopHardwareProfileBeginTransition | ( | IN BOOLEAN | SubsumeExistingDeparture | ) |

Definition at line 103 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, Executive, FALSE, IopDocksInTransition, IopProfileChangeSemaphore, KernelMode, KeWaitForSingleObject(), NTSTATUS(), and NULL.

Referenced by IopStartDevice().

    00108                    :
    00109
    00110     This routine must be called before any dock devnodes can be marked for
    00111     transition (ie arriving or departing). After calling this function,
    00112     IopHardwareProfileMarkDock should be called for each dock that is appearing
    00113     or disappearing.
    00114
    00115     Functionally, this code acquires the profile change semaphore. Future
    00116     changes in the life of the added dock devnodes cause it to be released.
    00117
    00118 Arguments:
    00119
    00120     SubsumeExistingDeparture - Set if we are ejecting the parent of a
    00121                                device that is still in the process of
    00122                                ejecting...
    00123
    00124 Return Value:
    00125
    00126     None.
    00127
    00128 --*/
    00129 {
    00130     NTSTATUS status ;
    00131
    00132     if (SubsumeExistingDeparture) {
    00133
    00134         //
    00135         // We will already have queried in this case. Also, enumeration is
    00136         // locked right now, so the appropriate devices found cannot disappear.
    00137         // Assert everything is consistant.
    00138         //
    00139         ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ;
    00140         ASSERT(IopDocksInTransition != 0) ;
    00141         return ;
    00142     }
    00143
    00144     //
    00145     // Take the profile change semaphore. We do this whenever a dock is
    00146     // in our list, even if no query is going to occur.
    00147     //
    00148     status = KeWaitForSingleObject(
    00149         &IopProfileChangeSemaphore,
    00150         Executive,
    00151         KernelMode,
    00152         FALSE,
    00153         NULL
    00154         );
    00155
    00156     ASSERT(status == STATUS_SUCCESS) ;
    00157 }

VOID IopHardwareProfileCancelRemovedDock | ( | IN PDEVICE_NODE | DeviceNode | ) |

Definition at line 572 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, DOCK_EJECTIRP_COMPLETED, DOCK_QUIESCENT, FALSE, IO_NO_INCREMENT, IopDockDeviceListLock, IopDocksInTransition, IopHardwareProfileSendCancel(), IopHardwareProfileSendCommit(), IopProcessNewProfile(), IopProfileChangeCancelRequired, IopProfileChangeSemaphore, IopUpdateHardwareProfile(), KeReleaseSemaphore(), NT_SUCCESS, and NTSTATUS().

Referenced by IopEnumerateDevice().

    00577                    :
    00578
    00579     This routine is called when a dock that was marked to disappear didn't (ie,
    00580     after the eject, the dock device still enumerated). We remove it from the
    00581     transition list and complete/cancel the HW profile change as appropriate.
    00582     See IopHardwareProfileSetMarkedDocksEjected.
    00583
    00584 Arguments:
    00585
    00586     DeviceNode - Supplies a pointer to a device node which will be started and
    00587                  enumerated.
    00588
    00589 Return Value:
    00590
    00591     None.
    00592
    00593 --*/
    00594 {
    00595     NTSTATUS status;
    00596     BOOLEAN  profileChanged ;
    00597     LONG     remainingDockCount ;
    00598
    00599     //
    00600     // Acquire the lock on the list of dock devices
    00601     //
    00602     ExAcquireFastMutex(&IopDockDeviceListLock);
    00603
    00604     //
    00605     // Since we are about to remove this dock device from the list of
    00606     // all dock devices present, the list should not be empty.
    00607     //
    00608     ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ;
    00609     ASSERT(DeviceNode->DockInfo.DockStatus == DOCK_EJECTIRP_COMPLETED) ;
    00610     ASSERT(!IsListEmpty(&DeviceNode->DockInfo.ListEntry)) ;
    00611
    00612     DeviceNode->DockInfo.DockStatus = DOCK_QUIESCENT ;
    00613     remainingDockCount = InterlockedDecrement(&IopDocksInTransition) ;
    00614     ASSERT(remainingDockCount >= 0) ;
    00615
    00616     //
    00617     // Release the lock on the list of dock devices
    00618     //
    00619     ExReleaseFastMutex(&IopDockDeviceListLock);
    00620
    00621     if (remainingDockCount) {
    00622
    00623         return ;
    00624     }
    00625
    00626     //
    00627     // Update the current Hardware Profile after removing this device.
    00628     //
    00629     status = IopUpdateHardwareProfile(&profileChanged);
    00630
    00631     if (!NT_SUCCESS(status)) {
    00632
    00633         //
    00634         // So we're there physically, but not mentally? Too bad, where broadcasting
    00635         // change either way.
    00636         //
    00637         PIDBGMSG(
    00638             PIDBG_HWPROFILE,
    00639             ("IopUpdateHardwareProfile failed with status == %lx\n", status)
    00640             ) ;
    00641         ASSERT(NT_SUCCESS(status)) ;
    00642     }
    00643
    00644     if (NT_SUCCESS(status) && profileChanged) {
    00645
    00646         IopHardwareProfileSendCommit() ;
    00647         IopProcessNewProfile();
    00648
    00649     } else {
    00650
    00651         ASSERT(IopProfileChangeCancelRequired) ;
    00652         IopHardwareProfileSendCancel() ;
    00653     }
    00654
    00655     KeReleaseSemaphore(
    00656         &IopProfileChangeSemaphore,
    00657         IO_NO_INCREMENT,
    00658         1,
    00659         FALSE
    00660         );
    00661
    00662     return ;
    00663 }

VOID IopHardwareProfileCancelTransition | ( | VOID |  | ) |

Definition at line 666 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, DOCK_EJECTIRP_COMPLETED, DOCK_NOTDOCKDEVICE, DOCK_QUIESCENT, _DEVICE_NODE::DockInfo, FALSE, IO_NO_INCREMENT, IopDockDeviceListHead, IopDockDeviceListLock, IopDocksInTransition, IopHardwareProfileSendCancel(), IopProfileChangeCancelRequired, IopProfileChangeSemaphore, and KeReleaseSemaphore().

Referenced by IopStartDevice().

    00671                    :
    00672
    00673     This routine unmarks any marked devnodes (ie, sets them to no change,
    00674     appearing or disappearing), and sends the CancelQueryProfileChange as
    00675     appropriate. Once called, other profile changes can occur.
    00676
    00677 Arguments:
    00678
    00679     None.
    00680
    00681 Return Value:
    00682
    00683     Nodda.
    00684
    00685 --*/
    00686 {
    00687     PLIST_ENTRY  listEntry;
    00688     PDEVICE_NODE devNode;
    00689
    00690     ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ;
    00691
    00692     //
    00693     // Acquire the lock on the list of dock devices
    00694     //
    00695     ExAcquireFastMutex(&IopDockDeviceListLock);
    00696
    00697     for (listEntry  = IopDockDeviceListHead.Flink;
    00698         listEntry != &(IopDockDeviceListHead);
    00699         listEntry  = listEntry->Flink ) {
    00700
    00701         devNode = CONTAINING_RECORD(listEntry,
    00702                                     DEVICE_NODE,
    00703                                     DockInfo.ListEntry);
    00704
    00705         ASSERT((devNode->DockInfo.DockStatus != DOCK_NOTDOCKDEVICE)&&
    00706                (devNode->DockInfo.DockStatus != DOCK_EJECTIRP_COMPLETED)) ;
    00707         if (devNode->DockInfo.DockStatus != DOCK_QUIESCENT) {
    00708
    00709             InterlockedDecrement(&IopDocksInTransition) ;
    00710             devNode->DockInfo.DockStatus = DOCK_QUIESCENT ;
    00711         }
    00712     }
    00713
    00714     ASSERT(!IopDocksInTransition) ;
    00715
    00716     //
    00717     // Release the lock on the list of dock devices
    00718     //
    00719     ExReleaseFastMutex(&IopDockDeviceListLock);
    00720
    00721     if (IopProfileChangeCancelRequired) {
    00722
    00723         IopHardwareProfileSendCancel() ;
    00724     }
    00725
    00726     //
    00727     // No need to broadcast the cancels here, as IopQueryHardwareProfileChange
    00728     // will have taken care of the cancels for us.
    00729     //
    00730     KeReleaseSemaphore(
    00731         &IopProfileChangeSemaphore,
    00732         IO_NO_INCREMENT,
    00733         1,
    00734         FALSE
    00735         );
    00736 }

VOID IopHardwareProfileCommitRemovedDock | ( | IN PDEVICE_NODE | DeviceNode | ) |

Definition at line 465 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, DOCK_DEPARTING, DOCK_EJECTIRP_COMPLETED, DOCK_QUIESCENT, ExFreePool(), FALSE, IO_NO_INCREMENT, IopDockDeviceCount, IopDockDeviceListLock, IopDocksInTransition, IopHardwareProfileSendCancel(), IopHardwareProfileSendCommit(), IopProcessNewProfile(), IopProfileChangeCancelRequired, IopProfileChangeSemaphore, IopUpdateHardwareProfile(), KeReleaseSemaphore(), NT_SUCCESS, NTSTATUS(), and NULL.

Referenced by IopDeleteLockedDeviceNode().

    00470                    :
    00471
    00472     This routine removes the specified device from the list of current dock
    00473     devices and requests a Hardware Profile change.
    00474
    00475 Arguments:
    00476
    00477     DeviceNode - Supplies a pointer to a device node which has been listed as
    00478                  missing in a previous enumeration, has had the final remove IRP
    00479                  sent to it, and is about to be deleted.
    00480
    00481 Return Value:
    00482
    00483     None.
    00484
    00485 --*/
    00486 {
    00487     NTSTATUS status;
    00488     BOOLEAN  profileChanged ;
    00489     LONG     remainingDockCount ;
    00490
    00491     //
    00492     // Acquire the lock on the list of dock devices
    00493     //
    00494     ExAcquireFastMutex(&IopDockDeviceListLock);
    00495
    00496     //
    00497     // Since we are about to remove this dock device from the list of
    00498     // all dock devices present, the list should not be empty.
    00499     //
    00500     ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ;
    00501     ASSERT((DeviceNode->DockInfo.DockStatus == DOCK_DEPARTING)||
    00502            (DeviceNode->DockInfo.DockStatus == DOCK_EJECTIRP_COMPLETED)) ;
    00503     ASSERT(!IsListEmpty(&DeviceNode->DockInfo.ListEntry)) ;
    00504
    00505     //
    00506     // Remove the current devnode from the list of docks
    00507     //
    00508     RemoveEntryList(&DeviceNode->DockInfo.ListEntry);
    00509     InitializeListHead(&DeviceNode->DockInfo.ListEntry);
    00510     if (DeviceNode->DockInfo.SerialNumber) {
    00511
    00512         ExFreePool(DeviceNode->DockInfo.SerialNumber);
    00513         DeviceNode->DockInfo.SerialNumber = NULL;
    00514     }
    00515     IopDockDeviceCount--;
    00516
    00517     DeviceNode->DockInfo.DockStatus = DOCK_QUIESCENT ;
    00518     remainingDockCount = InterlockedDecrement(&IopDocksInTransition) ;
    00519     ASSERT(remainingDockCount >= 0) ;
    00520
    00521     //
    00522     // Release the lock on the list of dock devices
    00523     //
    00524     ExReleaseFastMutex(&IopDockDeviceListLock);
    00525
    00526     if (remainingDockCount) {
    00527
    00528         return ;
    00529     }
    00530
    00531     //
    00532     // Update the current Hardware Profile after removing this device.
    00533     //
    00534     status = IopUpdateHardwareProfile(&profileChanged);
    00535
    00536     if (!NT_SUCCESS(status)) {
    00537
    00538         //
    00539         // So we're there physically, but not mentally? Too bad, where broadcasting
    00540         // change either way.
    00541         //
    00542         PIDBGMSG(
    00543             PIDBG_HWPROFILE,
    00544             ("IopUpdateHardwareProfile failed with status == %lx\n", status)
    00545             ) ;
    00546
    00547         ASSERT(NT_SUCCESS(status)) ;
    00548     }
    00549
    00550     if (NT_SUCCESS(status) && profileChanged) {
    00551
    00552         IopHardwareProfileSendCommit() ;
    00553         IopProcessNewProfile();
    00554
    00555     } else {
    00556
    00557         ASSERT(IopProfileChangeCancelRequired) ;
    00558         IopHardwareProfileSendCancel() ;
    00559     }
    00560
    00561     KeReleaseSemaphore(
    00562         &IopProfileChangeSemaphore,
    00563         IO_NO_INCREMENT,
    00564         1,
    00565         FALSE
    00566         );
    00567
    00568     return ;
    00569 }

VOID IopHardwareProfileCommitStartedDock | ( | IN PDEVICE_NODE | DeviceNode | ) |

Definition at line 370 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, DOCK_ARRIVING, DOCK_QUIESCENT, FALSE, IO_NO_INCREMENT, IopDocksInTransition, IopHardwareProfileSendCancel(), IopHardwareProfileSendCommit(), IopProcessNewProfile(), IopProfileChangeCancelRequired, IopProfileChangeSemaphore, IopQueryDeviceSerialNumber(), IopUpdateHardwareProfile(), KeReleaseSemaphore(), NT_SUCCESS, NTSTATUS(), and NULL.

Referenced by IopStartDevice().

    00375                    :
    00376
    00377     This routine adds the specified device from the list of current dock
    00378     devices and requests a Hardware Profile change.
    00379
    00380 Arguments:
    00381
    00382     DeviceNode  - Supplies a pointer to a device node which will be started and
    00383                   enumerated.
    00384
    00385 Return Value:
    00386
    00387     None.
    00388
    00389 --*/
    00390 {
    00391     NTSTATUS status;
    00392     PDEVICE_OBJECT deviceObject;
    00393     PWCHAR  deviceSerialNumber;
    00394     BOOLEAN profileChanged = FALSE ;
    00395
    00396     ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ;
    00397     ASSERT(DeviceNode->DockInfo.DockStatus == DOCK_ARRIVING) ;
    00398     ASSERT(!IsListEmpty(&DeviceNode->DockInfo.ListEntry)) ;
    00399
    00400     DeviceNode->DockInfo.DockStatus = DOCK_QUIESCENT ;
    00401     InterlockedDecrement(&IopDocksInTransition) ;
    00402
    00403     //
    00404     // We only add one dock at a time. So this should have been the last!
    00405     //
    00406     ASSERT(!IopDocksInTransition) ;
    00407
    00408     //
    00409     // Retrieve the Serial Number from this dock device
    00410     //
    00411     if (DeviceNode->DockInfo.SerialNumber == NULL) {
    00412
    00413         deviceObject = DeviceNode->PhysicalDeviceObject;
    00414
    00415         status = IopQueryDeviceSerialNumber(deviceObject,
    00416                                             &deviceSerialNumber);
    00417
    00418         DeviceNode->DockInfo.SerialNumber = deviceSerialNumber;
    00419
    00420         //
    00421         // Update the current Hardware Profile after successfully starting this
    00422         // device. This routine does two things for us:
    00423         // 1) It determines whether the profile actually changed and updates
    00424         //    the global flag IopProfileChangeOccured appropriately.
    00425         // 2) If the profile changed, this routine updates the registry, but
    00426         //    does *not* broadcast the profile change around.
    00427         //
    00428         status = IopUpdateHardwareProfile(&profileChanged);
    00429         if (!NT_SUCCESS(status)) {
    00430
    00431             PIDBGMSG(
    00432                 PIDBG_HWPROFILE,
    00433                 ("IopUpdateHardwareProfile failed with status == %lx\n", status)
    00434                 ) ;
    00435         }
    00436
    00437     } else {
    00438         //
    00439         // Couldn't get Serial Number for this dock device, or serial number was NULL
    00440         //
    00441         status = STATUS_UNSUCCESSFUL;
    00442     }
    00443
    00444     if (NT_SUCCESS(status) && profileChanged) {
    00445
    00446         IopHardwareProfileSendCommit() ;
    00447         IopProcessNewProfile();
    00448
    00449     } else if (IopProfileChangeCancelRequired) {
    00450
    00451         IopHardwareProfileSendCancel() ;
    00452     }
    00453
    00454     KeReleaseSemaphore(
    00455         &IopProfileChangeSemaphore,
    00456         IO_NO_INCREMENT,
    00457         1,
    00458         FALSE
    00459         );
    00460
    00461     return ;
    00462 }

VOID IopHardwareProfileMarkDock | ( | PDEVICE_NODE | DeviceNode,
|  | PROFILE_STATUS | ChangeInPresence
| ) |

Definition at line 160 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, DOCK_ARRIVING, DOCK_DEPARTING, DOCK_QUIESCENT, _DEVICE_NODE::DockInfo, ExFreePool(), IopDockDeviceCount, IopDockDeviceListHead, IopDockDeviceListLock, IopDocksInTransition, IopProfileChangeSemaphore, IopQueryDeviceSerialNumber(), NT_SUCCESS, NTSTATUS(), NULL, and _DEVICE_NODE::PhysicalDeviceObject.

Referenced by IopStartDevice().

    00166                    :
    00167
    00168     This routine is called to mark a dock as "in transition", ie it is either
    00169     disappearing or appearing, the results of which determine our final
    00170     hardware profile state. After all the docks that are transitioning have
    00171     been passed into this function, IopHardwareProfileQueryChange is called.
    00172
    00173 Arguments:
    00174
    00175     DeviceNode          - The dock devnode that is appearing or disappearing
    00176     ChangeInPresence    - Either DOCK_DEPARTING or DOCK_ARRIVING
    00177
    00178 Return Value:
    00179
    00180     Nope.
    00181
    00182 --*/
    00183 {
    00184     PWCHAR          deviceSerialNumber;
    00185     PDEVICE_OBJECT  deviceObject;
    00186     NTSTATUS        status;
    00187
    00188     //
    00189     // Verify we are under semaphore, we aren't marking the dock twice, and
    00190     // our parameters are sensable.
    00191     //
    00192     ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ;
    00193     ASSERT(DeviceNode->DockInfo.DockStatus == DOCK_QUIESCENT) ;
    00194     ASSERT((ChangeInPresence == DOCK_DEPARTING)||
    00195            (ChangeInPresence == DOCK_ARRIVING)) ;
    00196
    00197     if (ChangeInPresence == DOCK_ARRIVING) {
    00198
    00199         //
    00200         // First, ensure this dock is a member of the dock list.
    00201         // ADRIAO BUGBUG 11/12/98 -
    00202         //     We should move this into IopProcessNewDeviceNode.
    00203         //
    00204         if (IsListEmpty(&DeviceNode->DockInfo.ListEntry)) {
    00205
    00206             //
    00207             // Acquire the lock on the list of dock devices
    00208             //
    00209             ExAcquireFastMutex(&IopDockDeviceListLock);
    00210
    00211             //
    00212             // Add this element to the head of the list
    00213             //
    00214             InsertHeadList(&IopDockDeviceListHead,
    00215                            &DeviceNode->DockInfo.ListEntry);
    00216             IopDockDeviceCount++;
    00217
    00218             //
    00219             // Release the lock on the list of dock devices
    00220             //
    00221             ExReleaseFastMutex(&IopDockDeviceListLock);
    00222         }
    00223
    00224         //
    00225         // Retrieve the Serial Number from this dock device. We do this just
    00226         // to test the BIOS today. Later we will be acquiring the information
    00227         // to determine the profile we are *about* to enter.
    00228         //
    00229         deviceObject = DeviceNode->PhysicalDeviceObject;
    00230         status = IopQueryDeviceSerialNumber(deviceObject,
    00231                                             &deviceSerialNumber);
    00232
    00233         if (NT_SUCCESS(status) && (deviceSerialNumber != NULL)) {
    00234
    00235             ExFreePool(deviceSerialNumber) ;
    00236         }
    00237
    00238     } else {
    00239
    00240         //
    00241         // DOCK_DEPARTING case, we must be a member of the dock list...
    00242         //
    00243         ASSERT(!IsListEmpty(&DeviceNode->DockInfo.ListEntry)) ;
    00244     }
    00245
    00246     InterlockedIncrement(&IopDocksInTransition) ;
    00247     DeviceNode->DockInfo.DockStatus = ChangeInPresence ;
    00248 }

NTSTATUS IopHardwareProfileQueryChange | ( | IN BOOLEAN | SubsumeExistingDeparture,
|  | IN PROFILE_NOTIFICATION_TIME | NotificationTime,
|  | OUT PPNP_VETO_TYPE | VetoType,
|  | OUT PUNICODE_STRING VetoName | OPTIONAL
| ) |

Definition at line 251 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, DOCK_ARRIVING, DOCK_EJECTIRP_COMPLETED, DOCK_NOTDOCKDEVICE, _DEVICE_NODE::DockInfo, FALSE, IopDockDeviceListHead, IopDockDeviceListLock, IopDocksInTransition, IopProfileChangeCancelRequired, IopProfileChangeSemaphore, IopRequestHwProfileChangeNotification(), NT_SUCCESS, NTSTATUS(), and TRUE.

Referenced by IopStartDevice().

    00259                    :
    00260
    00261     This function queries drivers to see if it is OK to exit the current
    00262     hardware profile and enter next one (as determined by which docks have
    00263     been marked). One of three functions should be used subsequently to this
    00264     call:
    00265         IopHardwareProfileCommitStartedDock (call when a dock has successfully
    00266                                              started)
    00267         IopHardwareProfileCommitRemovedDock (call when a dock is no longer
    00268                                              present in the system)
    00269         IopHardwareProfileCancelTransition  (call to abort a transition, say
    00270                                              if a dock failed to start or a
    00271                                              query returned failure for eject)
    00272
    00273 Arguments:
    00274
    00275     InPnpEvent  - This argument indicates whether an operation is being done
    00276                   within the context of another PnpEvent or not. If not, we
    00277                   will queue such an event and block on it. If so, we cannot
    00278                   queue&block (we'd deadlock), so we do the query manually.
    00279     VetoType    - If this function returns false, this parameter will describe
    00280                   who failed the query profile change. The below optional
    00281                   parameter will contain the name of said vetoer.
    00282     VetoName    - This optional parameter will get the name of the vetoer (ie
    00283                   devinst, service name, application name, etc). If VetoName
    00284                   is supplied, the caller must free the buffer returned.
    00285
    00286 Return Value:
    00287
    00288     NTSTATUS.
    00289
    00290 --*/
    00291 {
    00292     PROFILE_WORK_ITEM profileWorkItem;
    00293     NTSTATUS status;
    00294     BOOLEAN arrivingDockFound;
    00295     PLIST_ENTRY listEntry ;
    00296     PDEVICE_NODE devNode ;
    00297
    00298     ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ;
    00299
    00300     //
    00301     // Acquire the lock on the list of dock devices and determine whether any
    00302     // dock devnodes are arriving.
    00303     //
    00304     ExAcquireFastMutex(&IopDockDeviceListLock);
    00305
    00306     ASSERT(IopDocksInTransition) ;
    00307
    00308     arrivingDockFound = FALSE ;
    00309     for (listEntry  = IopDockDeviceListHead.Flink;
    00310         listEntry != &(IopDockDeviceListHead);
    00311         listEntry  = listEntry->Flink ) {
    00312
    00313         devNode = CONTAINING_RECORD(listEntry,
    00314                                     DEVICE_NODE,
    00315                                     DockInfo.ListEntry);
    00316
    00317         ASSERT((devNode->DockInfo.DockStatus != DOCK_NOTDOCKDEVICE)&&
    00318                (devNode->DockInfo.DockStatus != DOCK_EJECTIRP_COMPLETED)) ;
    00319
    00320         if (devNode->DockInfo.DockStatus == DOCK_ARRIVING) {
    00321
    00322             arrivingDockFound = TRUE ;
    00323         }
    00324     }
    00325
    00326     //
    00327     // Release the lock on the list of dock devices
    00328     //
    00329     ExReleaseFastMutex(&IopDockDeviceListLock);
    00330
    00331     if (SubsumingExistingDeparture) {
    00332
    00333         ASSERT(IopProfileChangeCancelRequired) ;
    00334         //
    00335         // We're nesting. Work off the last query, and don't requery.
    00336         //
    00337         return STATUS_SUCCESS ;
    00338     }
    00339
    00340     if (arrivingDockFound) {
    00341
    00342         //
    00343         // We currently don't actually query for hardware profile change on a
    00344         // dock event as the user may have the lid closed. If we ever find a
    00345         // piece of hardware that needs to be updated *prior* to actually
    00346         // switching over, we will have to remove this bit of code.
    00347         //
    00348         IopProfileChangeCancelRequired = FALSE ;
    00349         return STATUS_SUCCESS ;
    00350     }
    00351
    00352     PIDBGMSG(PIDBG_HWPROFILE, ("NTOSKRNL: Sending HW profile change [query]\n")) ;
    00353
    00354     status = IopRequestHwProfileChangeNotification(
    00355         (LPGUID) &GUID_HWPROFILE_QUERY_CHANGE,
    00356         InPnpEvent,
    00357         VetoType,
    00358         VetoName
    00359         );
    00360
    00361     if (NT_SUCCESS(status)) {
    00362         IopProfileChangeCancelRequired = TRUE ;
    00363     } else {
    00364         IopProfileChangeCancelRequired = FALSE ;
    00365     }
    00366     return status ;
    00367 }

VOID IopHardwareProfileSetMarkedDocksEjected | ( | VOID |  | ) |

Definition at line 739 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, DOCK_DEPARTING, DOCK_EJECTIRP_COMPLETED, DOCK_QUIESCENT, _DEVICE_NODE::DockInfo, IopDockDeviceListHead, IopDockDeviceListLock, and IopProfileChangeSemaphore.

Referenced by IopProcessCompletedEject().

    00744                    :
    00745
    00746     This routine moves any departing devnodes to the ejected state. If any
    00747     subsequent enumeration lists the device as present, we know the eject
    00748     failed and we appropriately cancel that piece of the profile change.
    00749     IopHardwareProfileCancelRemovedDock can only be called after this function
    00750     is called.
    00751
    00752 Arguments:
    00753
    00754     None.
    00755
    00756 Return Value:
    00757
    00758     Nodda.
    00759
    00760 --*/
    00761 {
    00762     PLIST_ENTRY  listEntry;
    00763     PDEVICE_NODE devNode;
    00764
    00765     ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ;
    00766
    00767     //
    00768     // Acquire the lock on the list of dock devices
    00769     //
    00770     ExAcquireFastMutex(&IopDockDeviceListLock);
    00771
    00772     for (listEntry  = IopDockDeviceListHead.Flink;
    00773         listEntry != &(IopDockDeviceListHead);
    00774         listEntry  = listEntry->Flink ) {
    00775
    00776         devNode = CONTAINING_RECORD(listEntry,
    00777                                     DEVICE_NODE,
    00778                                     DockInfo.ListEntry);
    00779
    00780         ASSERT((devNode->DockInfo.DockStatus == DOCK_QUIESCENT)||
    00781                (devNode->DockInfo.DockStatus == DOCK_DEPARTING)) ;
    00782         if (devNode->DockInfo.DockStatus != DOCK_QUIESCENT) {
    00783
    00784             devNode->DockInfo.DockStatus = DOCK_EJECTIRP_COMPLETED ;
    00785         }
    00786     }
    00787
    00788     //
    00789     // Release the lock on the list of dock devices
    00790     //
    00791     ExReleaseFastMutex(&IopDockDeviceListLock);
    00792 }

VOID IopIncDisableableDepends | ( | IN OUT PDEVICE_NODE | DeviceNode | ) |

Definition at line 3109 of file pnpirp.c.

References NULL.

Referenced by IopQueryDeviceState().

    03114                    :
    03115
    03116     Increments the DisableableDepends field of this devicenode
    03117     and potentially every parent device node up the tree
    03118     A parent devicenode is only incremented if the child in question
    03119     is incremented from 0 to 1
    03120
    03121 Parameters:
    03122
    03123     DeviceNode - Supplies the device node where the depends is to be incremented
    03124
    03125 Return Value:
    03126
    03127     none.
    03128
    03129 --*/
    03130 {
    03131
    03132     while (DeviceNode != NULL) {
    03133
    03134         LONG newval;
    03135
    03136         newval = InterlockedIncrement(& DeviceNode->DisableableDepends);
    03137         if (newval != 1) {
    03138             //
    03139             // we were already non-disableable, so we don't have to bother parent
    03140             //
    03141             break;
    03142         }
    03143
    03144         DeviceNode = DeviceNode ->Parent;
    03145
    03146     }
    03147
    03148 }

VOID IopInitializePlugPlayNotification | ( | VOID |  | ) |

| Referenced by IopInitializePlugPlayServices().

NTSTATUS IopInitializePlugPlayServices | ( | IN PLOADER_PARAMETER_BLOCK | LoaderBlock,
|  | IN ULONG | Phase
| ) |

Definition at line 93 of file pnpinit.c.

References ASSERT, BUS_TYPE_GUID_LIST, CmRegistryMachineSystemCurrentControlSet, CmRegistryMachineSystemCurrentControlSetEnumName, DNF_ADDED, DNF_ENUMERATED, DNF_MADEUP, DNF_NO_RESOURCE_REQUIRED, DNF_PROCESSED, DNF_STARTED, DO_BUS_ENUMERATED_DEVICE, EisaBuildEisaDeviceNode(), ExAllocatePool, ExFreePool(), ExInitializeFastMutex, ExInitializeResource, FALSE, _DEVICE_NODE::Flags, _DEVICE_OBJECT::Flags, _DEVICE_NODE::InstancePath, IoCreateDevice(), IoCreateDriver(), IoDeleteDevice(), IoDeleteDriver(), IopAllocateDeviceNode(), IopBusNumberInitialize(), IopBusTypeGuidList, IopCreateRegistryKeyEx(), IopDetermineDefaultInterfaceType(), IopDeviceTreeLock, IopDmaInitialize(), IopDockDeviceCount, IopDockDeviceListHead, IopDockDeviceListLock, IopGetRegistryValue(), IopInitializePlugPlayNotification(), IopInitReservedResourceList, IopIrqInitialize(), IopMemInitialize(), IOPNP_DEVICE_EXTENSION, IoPnpDriverObject, IopOpenRegistryKeyEx(), IopPendingEjects, IopPendingSurpriseRemovals, IopPnPDriverEntry(), IopPnpEnumerationRequestList, IopPnpScratchBuffer1, IopPnpScratchBuffer2, IopPnPSpinLock, IopPortInitialize(), IopRequestDeviceAction(), IopReserveBootResources(), IopReserveResourcesRoutine, IopRootDeviceNode, IopWarmEjectLock, IopWarmEjectPdo, KeInitializeEvent, KeInitializeSpinLock(), KEY_VALUE_DATA, _BUS_TYPE_GUID_LIST::Lock, MapperConstructRootEnumTree(), MapperFreeList(), MapperPhantomizeDetectedComPorts(), MapperProcessFirmwareTree(), NT_SUCCESS, NtClose(), NTSTATUS(), NULL, PagedPool, _DEVICE_NODE::PhysicalDeviceObject, PiEnumerationLock, PiEventQueueEmpty, PNP_DETECTION_ENABLED_DEFAULT, PNP_LARGE_SCRATCH_BUFFER_SIZE, PnPBiosMapper(), PnpDefaultInterfaceType, PnPDetectionEnabled, PnPInitialized, PpInitializeNotification(), ReenumerateRootDevices, RtlAddAccessAllowedAceEx(), RtlCreateAcl(), RtlCreateSecurityDescriptor(), RtlInitUnicodeString(), RtlLengthSid(), RtlSetDaclSecurityDescriptor(), RtlValidSecurityDescriptor(), SeLocalSystemSid, SeWorldSid, TRUE, and VOID().

Referenced by IoInitSystem().

    00100                    :
    00101
    00102     This routine initializes kernel mode Plug and Play services.
    00103
    00104 Arguments:
    00105
    00106     LoaderBlock - supplies a pointer to the LoaderBlock passed in from the
    00107         OS Loader.
    00108
    00109 Returns:
    00110
    00111     NTSTATUS code for sucess or reason of failure.
    00112
    00113 --*/
    00114 {
    00115     NTSTATUS status;
    00116     HANDLE hTreeHandle, parentHandle, handle, hCurrentControlSet = NULL;
    00117     UNICODE_STRING unicodeName;
    00118     PKEY_VALUE_FULL_INFORMATION detectionInfo;
    00119     PDEVICE_OBJECT deviceObject;
    00120     ULONG disposition;
    00121
    00122     if (Phase == 0) {
    00123         PnPInitialized = FALSE;
    00124
    00125         //
    00126         // Allocate two one-page scratch buffers to be used by our
    00127         // initialization code.  This avoids constant pool allocations.
    00128         //
    00129
    00130         IopPnpScratchBuffer1 = ExAllocatePool(PagedPool, PNP_LARGE_SCRATCH_BUFFER_SIZE);
    00131         if (!IopPnpScratchBuffer1) {
    00132             return STATUS_INSUFFICIENT_RESOURCES;
    00133         }
    00134         IopPnpScratchBuffer2 = ExAllocatePool(PagedPool, PNP_LARGE_SCRATCH_BUFFER_SIZE);
    00135         if (!IopPnpScratchBuffer2) {
    00136             ExFreePool(IopPnpScratchBuffer1);
    00137             return STATUS_INSUFFICIENT_RESOURCES;
    00138         }
    00139
    00140         IopInitReservedResourceList = NULL;
    00141
    00142         IopReserveResourcesRoutine = IopReserveBootResources;
    00143
    00144         //
    00145         // Determine the PnpDefaultInterfaceType.  For root enumerated devices if the Interface
    00146         // type of their resource list or resource requirements list are undefined.  We will use
    00147         // the default type instead.
    00148         //
    00149
    00150         PnpDefaultInterfaceType = IopDetermineDefaultInterfaceType();
    00151
    00152         //
    00153         // Initialize root arbiters
    00154         //
    00155
    00156         status = IopPortInitialize();
    00157         if (!NT_SUCCESS(status)) {
    00158             goto init_Exit0;
    00159         }
    00160
    00161         status = IopMemInitialize();
    00162         if (!NT_SUCCESS(status)) {
    00163             goto init_Exit0;
    00164         }
    00165
    00166         status = IopDmaInitialize();
    00167         if (!NT_SUCCESS(status)) {
    00168             goto init_Exit0;
    00169         }
    00170
    00171         status = IopIrqInitialize();
    00172         if (!NT_SUCCESS(status)) {
    00173             goto init_Exit0;
    00174         }
    00175
    00176         status = IopBusNumberInitialize();
    00177         if (!NT_SUCCESS(status)) {
    00178             goto init_Exit0;
    00179         }
    00180
    00181         //
    00182         // Next open/create System\CurrentControlSet\Enum\Root key.
    00183         //
    00184
    00185         status = IopOpenRegistryKeyEx( &hCurrentControlSet,
    00186                                        NULL,
    00187                                        &CmRegistryMachineSystemCurrentControlSet,
    00188                                        KEY_ALL_ACCESS
    00189                                        );
    00190         if (!NT_SUCCESS(status)) {
    00191             hCurrentControlSet = NULL;
    00192             goto init_Exit0;
    00193         }
    00194
    00195         PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_ENUM);
    00196         status = IopCreateRegistryKeyEx( &handle,
    00197                                          hCurrentControlSet,
    00198                                          &unicodeName,
    00199                                          KEY_ALL_ACCESS,
    00200                                          REG_OPTION_NON_VOLATILE,
    00201                                          &disposition
    00202                                          );
    00203         if (!NT_SUCCESS(status)) {
    00204             goto init_Exit0;
    00205         }
    00206
    00207         if (disposition == REG_CREATED_NEW_KEY) {
    00208             SECURITY_DESCRIPTOR     newSD;
    00209             PACL                    newDacl;
    00210             ULONG                   sizeDacl;
    00211
    00212             status = RtlCreateSecurityDescriptor( &newSD,
    00213                                                   SECURITY_DESCRIPTOR_REVISION );
    00214             ASSERT( NT_SUCCESS( status ) );
    00215
    00216             //
    00217             // calculate the size of the new DACL
    00218             //
    00219             sizeDacl = sizeof(ACL);
    00220             sizeDacl += sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(SeLocalSystemSid) - sizeof(ULONG);
    00221
    00222 #if ALLOW_WORLD_READ_OF_ENUM
    00223             sizeDacl += sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(SeWorldSid) - sizeof(ULONG);
    00224 #endif
    00225
    00226             //
    00227             // create and initialize the new DACL
    00228             //
    00229             newDacl = ExAllocatePool(PagedPool, sizeDacl);
    00230
    00231             if (newDacl != NULL) {
    00232
    00233                 status = RtlCreateAcl(newDacl, sizeDacl, ACL_REVISION);
    00234
    00235                 ASSERT( NT_SUCCESS( status ) );
    00236
    00237                 //
    00238                 // Add just the local system full control ace to this new DACL
    00239                 //
    00240                 status = RtlAddAccessAllowedAceEx( newDacl,
    00241                                                    ACL_REVISION,
    00242                                                    CONTAINER_INHERIT_ACE,
    00243                                                    KEY_ALL_ACCESS,
    00244                                                    SeLocalSystemSid
    00245                                                    );
    00246                 ASSERT( NT_SUCCESS( status ) );
    00247
    00248 #if ALLOW_WORLD_READ_OF_ENUM
    00249                 //
    00250                 // Add just the local system full control ace to this new DACL
    00251                 //
    00252                 status = RtlAddAccessAllowedAceEx( newDacl,
    00253                                                    ACL_REVISION,
    00254                                                    CONTAINER_INHERIT_ACE,
    00255                                                    KEY_READ,
    00256                                                    SeWorldSid
    00257                                                    );
    00258                 ASSERT( NT_SUCCESS( status ) );
    00259
    00260 #endif
    00261                 //
    00262                 // Set the new DACL in the absolute security descriptor
    00263                 //
    00264                 status = RtlSetDaclSecurityDescriptor( (PSECURITY_DESCRIPTOR) &newSD,
    00265                                                        TRUE,
    00266                                                        newDacl,
    00267                                                        FALSE
    00268                                                        );
    00269
    00270                 ASSERT( NT_SUCCESS( status ) );
    00271
    00272                 //
    00273                 // validate the new security descriptor
    00274                 //
    00275                 status = RtlValidSecurityDescriptor(&newSD);
    00276
    00277                 ASSERT( NT_SUCCESS( status ) );
    00278
    00279                 status = ZwSetSecurityObject( handle,
    00280                                               DACL_SECURITY_INFORMATION,
    00281                                               &newSD
    00282                                               );
    00283                 if (!NT_SUCCESS(status)) {
    00284
    00285                     KdPrint(("IopInitializePlugPlayServices: ZwSetSecurityObject on Enum key failed, status = %8.8X\n", status));
    00286                 }
    00287
    00288                 ExFreePool(newDacl);
    00289             } else {
    00290
    00291                 KdPrint(("IopInitializePlugPlayServices: ExAllocatePool failed allocating DACL for Enum key\n"));
    00292             }
    00293         }
    00294
    00295         parentHandle = handle;
    00296         PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_ROOTENUM);
    00297         status = IopCreateRegistryKeyEx( &handle,
    00298                                          parentHandle,
    00299                                          &unicodeName,
    00300                                          KEY_ALL_ACCESS,
    00301                                          REG_OPTION_NON_VOLATILE,
    00302                                          NULL
    00303                                          );
    00304         NtClose(parentHandle);
    00305         if (!NT_SUCCESS(status)) {
    00306             goto init_Exit0;
    00307         }
    00308         NtClose(handle);
    00309
    00310         //
    00311         // Create the registry entry for the root of the hardware tree (HTREE\ROOT\0).
    00312         //
    00313
    00314         status = IopOpenRegistryKeyEx( &handle,
    00315                                        NULL,
    00316                                        &CmRegistryMachineSystemCurrentControlSetEnumName,
    00317                                        KEY_ALL_ACCESS
    00318                                        );
    00319         if (NT_SUCCESS(status)) {
    00320             PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_ROOT_DEVNODE);
    00321             status = IopCreateRegistryKeyEx( &hTreeHandle,
    00322                                              handle,
    00323                                              &unicodeName,
    00324                                              KEY_ALL_ACCESS,
    00325                                              REG_OPTION_NON_VOLATILE,
    00326                                              NULL
    00327                                              );
    00328             NtClose(handle);
    00329             if (NT_SUCCESS(status)) {
    00330                 NtClose(hTreeHandle);
    00331             }
    00332         }
    00333
    00334         //
    00335         // Before creating device node tree, we need to initialize the device
    00336         // tree lock.
    00337         //
    00338
    00339         InitializeListHead(&IopPendingEjects);
    00340         InitializeListHead(&IopPendingSurpriseRemovals);
    00341         InitializeListHead(&IopPnpEnumerationRequestList);
    00342         ExInitializeResource(&IopDeviceTreeLock);
    00343         KeInitializeEvent(&PiEventQueueEmpty, NotificationEvent, TRUE );
    00344         KeInitializeEvent(&PiEnumerationLock, NotificationEvent, TRUE );
    00345         KeInitializeSpinLock(&IopPnPSpinLock);
    00346
    00347         //
    00348         // Initialize the list of dock devices, and its lock.
    00349         //
    00350         InitializeListHead(&IopDockDeviceListHead);
    00351         ExInitializeFastMutex(&IopDockDeviceListLock);
    00352         IopDockDeviceCount = 0;
    00353
    00354         //
    00355         // Initialize warm docking variables.
    00356         //
    00357         IopWarmEjectPdo = NULL;
    00358         KeInitializeEvent(&IopWarmEjectLock, SynchronizationEvent, TRUE );
    00359
    00360         //
    00361         // Create a PnP manager's driver object to own all the detected PDOs.
    00362         //
    00363
    00364         RtlInitUnicodeString(&unicodeName, PNPMGR_STR_PNP_DRIVER);
    00365         status = IoCreateDriver (&unicodeName, IopPnPDriverEntry);
    00366         if (NT_SUCCESS(status)) {
    00367
    00368             //
    00369             // Create empty device node tree, i.e., only contains only root device node
    00370             //     (No need to initialize Parent, Child and Sibling links.)
    00371
    00372             status = IoCreateDevice( IoPnpDriverObject,
    00373                                      sizeof(IOPNP_DEVICE_EXTENSION),
    00374                                      NULL,
    00375                                      FILE_DEVICE_CONTROLLER,
    00376                                      0,
    00377                                      FALSE,
    00378                                      &deviceObject );
    00379
    00380             if (NT_SUCCESS(status)) {
    00381                 deviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
    00382                 IopRootDeviceNode = IopAllocateDeviceNode(deviceObject);
    00383
    00384                 if (!IopRootDeviceNode) {
    00385                     IoDeleteDevice(deviceObject);
    00386                     IoDeleteDriver(IoPnpDriverObject);
    00387                     status = STATUS_INSUFFICIENT_RESOURCES;
    00388                 } else {
    00389                     IopRootDeviceNode->Flags |= DNF_STARTED + DNF_PROCESSED + DNF_ENUMERATED +
    00390                                                 DNF_MADEUP + DNF_NO_RESOURCE_REQUIRED +
    00391                                                 DNF_ADDED;
    00392
    00393                     IopRootDeviceNode->InstancePath.Buffer = ExAllocatePool( PagedPool,
    00394                                                                              sizeof(REGSTR_VAL_ROOT_DEVNODE));
    00395
    00396                     if (IopRootDeviceNode->InstancePath.Buffer != NULL) {
    00397                         IopRootDeviceNode->InstancePath.MaximumLength = sizeof(REGSTR_VAL_ROOT_DEVNODE);
    00398                         IopRootDeviceNode->InstancePath.Length = sizeof(REGSTR_VAL_ROOT_DEVNODE) - sizeof(WCHAR);
    00399
    00400                         RtlMoveMemory( IopRootDeviceNode->InstancePath.Buffer,
    00401                                        REGSTR_VAL_ROOT_DEVNODE,
    00402                                        sizeof(REGSTR_VAL_ROOT_DEVNODE));
    00403                     } else {
    00404                         //
    00405                         // BUGBUG - Need to bugcheck here
    00406                         //
    00407
    00408                         ASSERT(FALSE);
    00409                     }
    00410                 }
    00411             }
    00412         }
    00413
    00414         if (!NT_SUCCESS(status)) {
    00415             goto init_Exit0;
    00416         }
    00417
    00418         //
    00419         // Initialize PnPDetectionEnabled flag to determine should Wdm driver be loaded
    00420         // to run detection code.
    00421         // This is stored as a REG_DWORD under HKLM\System\CurrentControlSet\Control\Pnp\DetectionEnabled
    00422         // if it is not present then PNP_DETECTION_ENABLED_DEFAULT is used
    00423         //
    00424
    00425         //
    00426         // Open HKLM\System\CurrentControlSet\Control\Pnp
    00427         //
    00428
    00429         PiWstrToUnicodeString(&unicodeName, REGSTR_PATH_CONTROL_PNP);
    00430         status = IopCreateRegistryKeyEx( &handle,
    00431                                          hCurrentControlSet,
    00432                                          &unicodeName,
    00433                                          KEY_ALL_ACCESS,
    00434                                          REG_OPTION_NON_VOLATILE,
    00435                                          NULL
    00436                                          );
    00437         if (!NT_SUCCESS(status)) {
    00438             goto init_Exit0;
    00439         }
    00440
    00441         //
    00442         // Get the value of DetectionEnabled key if it exisit otherwise use the default
    00443         //
    00444
    00445         PnPDetectionEnabled = PNP_DETECTION_ENABLED_DEFAULT;
    00446
    00447         status = IopGetRegistryValue(handle,
    00448                                      REGSTR_VALUE_DETECTION_ENABLED,
    00449                                      &detectionInfo
    00450                                      );
    00451
    00452         if (NT_SUCCESS(status)) {
    00453
    00454             if (detectionInfo->Type == REG_DWORD && detectionInfo->DataLength == sizeof(ULONG)) {
    00455                 PnPDetectionEnabled = (BOOLEAN) *(KEY_VALUE_DATA(detectionInfo));
    00456             }
    00457
    00458             ExFreePool(detectionInfo);
    00459         }
    00460
    00461         NtClose(handle);
    00462
    00463         //
    00464         // Initialize the kernel mode pnp notification system
    00465         //
    00466
    00467         status = PpInitializeNotification();
    00468         if (!NT_SUCCESS(status)) {
    00469             goto init_Exit0;
    00470         }
    00471
    00472         IopInitializePlugPlayNotification();
    00473
    00474         //
    00475         // Initialize table for holding bus type guid list.
    00476         //
    00477
    00478         IopBusTypeGuidList = ExAllocatePool(PagedPool, sizeof(BUS_TYPE_GUID_LIST));
    00479         if (IopBusTypeGuidList == NULL) {
    00480             status = STATUS_INSUFFICIENT_RESOURCES;
    00481             goto init_Exit0;
    00482         }
    00483
    00484         RtlZeroMemory( IopBusTypeGuidList, sizeof(BUS_TYPE_GUID_LIST));
    00485
    00486         ExInitializeFastMutex(&IopBusTypeGuidList->Lock);
    00487
    00488         //
    00489         // Enumerate the ROOT bus synchronously.
    00490         //
    00491
    00492         IopRequestDeviceAction(IopRootDeviceNode->PhysicalDeviceObject, ReenumerateRootDevices, NULL, NULL);
    00493
    00494 init_Exit0:
    00495
    00496         //
    00497         // If we managed to open the Current Control Set close it
    00498         //
    00499
    00500         if(hCurrentControlSet) {
    00501             NtClose(hCurrentControlSet);
    00502         }
    00503
    00504         if (!NT_SUCCESS(status)) {
    00505             ExFreePool(IopPnpScratchBuffer1);
    00506             ExFreePool(IopPnpScratchBuffer2);
    00507         }
    00508
    00509     } else if (Phase == 1) {
    00510
    00511         BOOLEAN legacySerialPortMappingOnly = FALSE;
    00512
    00513         //
    00514         // Next open/create System\CurrentControlSet\Enum\Root key.
    00515         //
    00516
    00517         status = IopOpenRegistryKeyEx( &hCurrentControlSet,
    00518                                        NULL,
    00519                                        &CmRegistryMachineSystemCurrentControlSet,
    00520                                        KEY_ALL_ACCESS
    00521                                        );
    00522         if (!NT_SUCCESS(status)) {
    00523             hCurrentControlSet = NULL;
    00524             goto init_Exit1;
    00525         }
    00526
    00527         //
    00528         // Open HKLM\System\CurrentControlSet\Control\Pnp
    00529         //
    00530
    00531         PiWstrToUnicodeString(&unicodeName, REGSTR_PATH_CONTROL_PNP);
    00532         status = IopCreateRegistryKeyEx( &handle,
    00533                                          hCurrentControlSet,
    00534                                          &unicodeName,
    00535                                          KEY_ALL_ACCESS,
    00536                                          REG_OPTION_NON_VOLATILE,
    00537                                          NULL
    00538                                          );
    00539         if (!NT_SUCCESS(status)) {
    00540             goto init_Exit1;
    00541         }
    00542
    00543         //
    00544         // Check the "DisableFirmwareMapper" value entry to see whether we
    00545         // should skip mapping ntdetect/firmware reported devices (except for
    00546         // COM ports, which we always map).
    00547         //
    00548
    00549         status = IopGetRegistryValue(handle,
    00550                                      REGSTR_VALUE_DISABLE_FIRMWARE_MAPPER,
    00551                                      &detectionInfo
    00552                                      );
    00553
    00554         if (NT_SUCCESS(status)) {
    00555
    00556             if (detectionInfo->Type == REG_DWORD && detectionInfo->DataLength == sizeof(ULONG)) {
    00557                 legacySerialPortMappingOnly = (BOOLEAN) *(KEY_VALUE_DATA(detectionInfo));
    00558             }
    00559
    00560             ExFreePool(detectionInfo);
    00561
    00562         }
    00563         NtClose(handle);
    00564
    00565         //
    00566         // Collect the necessary firmware tree information.
    00567         //
    00568
    00569         MapperProcessFirmwareTree(legacySerialPortMappingOnly);
    00570
    00571         //
    00572         // Map this into the root enumerator tree
    00573         //
    00574
    00575         MapperConstructRootEnumTree(legacySerialPortMappingOnly);
    00576
    00577 #if i386
    00578         if (!legacySerialPortMappingOnly) {
    00579
    00580             //
    00581             // Now do the PnP BIOS enumerated devnodes.
    00582             //
    00583             extern NTSTATUS PnPBiosMapper(VOID);
    00584
    00585             status = PnPBiosMapper();
    00586
    00587             //
    00588             // If the previous call succeeds, we have a PNPBios, turn any newly
    00589             // created ntdetect COM ports into phantoms
    00590             //
    00591             if (NT_SUCCESS (status)) {
    00592                 MapperPhantomizeDetectedComPorts();
    00593             }
    00594         }
    00595         EisaBuildEisaDeviceNode();
    00596 #endif
    00597
    00598         //
    00599         // We're done with the firmware mapper device list.
    00600         //
    00601
    00602         MapperFreeList();
    00603
    00604
    00605         //
    00606         // Enumerate the ROOT bus synchronously.
    00607         //
    00608
    00609         IopRequestDeviceAction(IopRootDeviceNode->PhysicalDeviceObject, ReenumerateRootDevices, NULL, NULL);
    00610
    00611 init_Exit1:
    00612
    00613         //
    00614         // If we managed to open the Current Control Set close it
    00615         //
    00616
    00617         if(hCurrentControlSet) {
    00618             NtClose(hCurrentControlSet);
    00619         }
    00620
    00621         //
    00622         // Free our scratch buffers and exit.
    00623         //
    00624
    00625         ExFreePool(IopPnpScratchBuffer1);
    00626         ExFreePool(IopPnpScratchBuffer2);
    00627         status = STATUS_SUCCESS;
    00628     } else {
    00629         status = STATUS_INVALID_PARAMETER_1;
    00630     }
    00631
    00632     return status;
    00633 }

VOID IopInsertTreeDeviceNode | ( | IN PDEVICE_NODE | ParentNode,
|  | IN PDEVICE_NODE | DeviceNode
| ) |

Definition at line 447 of file devnode.c.

References ASSERT, IoDeviceNodeTreeSequence, IopMaxDeviceNodeLevel, IopRootDeviceNode, NULL, and _DEVICE_NODE::Parent.

Referenced by IopEnumerateDevice(), IopInitializeDeviceInstanceKey(), and IoReportDetectedDevice().

    00452 {
    00453     PDEVICE_NODE    deviceNode;
    00454     PLIST_ENTRY     *p;
    00455     LONG            i;
    00456
    00457     //
    00458     // Put this devnode at the end of the parent's list of children.
    00459     //
    00460
    00461     DeviceNode->Parent = ParentNode;
    00462     if (ParentNode->LastChild) {
    00463         ASSERT(ParentNode->LastChild->Sibling == NULL);
    00464         ParentNode->LastChild->Sibling = DeviceNode;
    00465         ParentNode->LastChild = DeviceNode;
    00466     } else {
    00467         ASSERT(ParentNode->Child == NULL);
    00468         ParentNode->Child = ParentNode->LastChild = DeviceNode;
    00469     }
    00470
    00471     //
    00472     // Determine the depth of the devnode.
    00473     //
    00474
    00475     for (deviceNode = DeviceNode;
    00476          deviceNode != IopRootDeviceNode;
    00477          deviceNode = deviceNode->Parent) {
    00478         DeviceNode->Level++;
    00479     }
    00480
    00481     if (DeviceNode->Level > IopMaxDeviceNodeLevel) {
    00482         IopMaxDeviceNodeLevel = DeviceNode->Level;
    00483     }
    00484
    00485     //
    00486     // Tree has changed
    00487     //
    00488
    00489     IoDeviceNodeTreeSequence += 1;
    00490 }

NTSTATUS IopInvalidateRelationsInList | ( | PRELATION_LIST | RelationsList,
|  | BOOLEAN | OnlyIndirectDescendants,
|  | BOOLEAN | UnlockDevNode,
|  | BOOLEAN | RestartDevNode
| ) |

Definition at line 1250 of file pnpdel.c.

References ASSERT, _DEVICE_NODE::Child, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_ADDED, DNF_ENUMERATED, DNF_LOCKED_FOR_EJECT, DNF_PROCESSED, _DEVICE_NODE::EnumerationMutex, FALSE, _DEVICE_NODE::Flags, IopAddRelationToList(), IopAllocateRelationList(), IopClearDevNodeProblem, IopEnumerateRelations(), IopFreeRelationList(), IopRequestDeviceAction(), IopRestartDeviceNode(), IopSetAllRelationsTags(), IopSetRelationsTag(), KeSetEvent(), _DEVICE_NODE::LockCount, NULL, ObDereferenceObject, PAGED_CODE, _DEVICE_NODE::Parent, _DEVICE_NODE::PhysicalDeviceObject, ReenumerateDeviceTree, and TRUE.

Referenced by IopProcessCompletedEject().

    01259                    :
    01260
    01261     Iterate over the relations in the list creating a second list containing the
    01262     parent of each entry skipping parents which are also in the list.  In other
    01263     words, if the list contains node P and node C where node C is a child of node
    01264     P then the parent of node P would be added but not node P itself.
    01265
    01266
    01267 Arguments:
    01268
    01269     RelationsList           - List of relations
    01270
    01271     OnlyIndirectDescendants - Indirect relations are those which aren't direct
    01272                               descendants (bus relations) of the PDO originally
    01273                               targetted for the operation or its direct
    01274                               descendants.  This would include Removal or
    01275                               Eject relations.
    01276
    01277     UnlockDevNode           - If true then any node who's parent was invalidated
    01278                               is unlocked.  In the case where the parent is also
    01279                               in the list the node is still unlocked as will the
    01280                               parent be once we process it.
    01281
    01282     RestartDevNode          - If true then any node who's parent was invalidated
    01283                               is restarted.  This flag requires that all the
    01284                               relations in the list have been previously
    01285                               sent a remove IRP.
    01286
    01287
    01288 Return Value:
    01289
    01290     NTSTATUS code.
    01291
    01292 --*/
    01293
    01294 {
    01295     PRELATION_LIST                  parentsList;
    01296     PDEVICE_OBJECT                  deviceObject, parentObject;
    01297     PDEVICE_NODE                    deviceNode, parentNode;
    01298     ULONG                           marker;
    01299     BOOLEAN                         directDescendant, tagged;
    01300
    01301     PAGED_CODE();
    01302
    01303     parentsList = IopAllocateRelationList();
    01304
    01305     if (parentsList == NULL) {
    01306         return STATUS_INSUFFICIENT_RESOURCES;
    01307     }
    01308
    01309     IopSetAllRelationsTags( RelationsList, FALSE );
    01310
    01311     //
    01312     // Traverse the list creating a new list with the topmost parents of
    01313     // each sublist contained in RelationsList.
    01314     //
    01315
    01316     marker = 0;
    01317
    01318     while (IopEnumerateRelations( RelationsList,
    01319                                   &marker,
    01320                                   &deviceObject,
    01321                                   &directDescendant,
    01322                                   &tagged,
    01323                                   TRUE)) {
    01324
    01325         if (!OnlyIndirectDescendants || !directDescendant) {
    01326
    01327             if (!tagged) {
    01328
    01329                 parentObject = deviceObject;
    01330
    01331                 while (IopSetRelationsTag( RelationsList, parentObject, TRUE ) == STATUS_SUCCESS) {
    01332
    01333                     deviceNode = parentObject->DeviceObjectExtension->DeviceNode;
    01334
    01335                     if (RestartDevNode)  {
    01336
    01337                         deviceNode->Flags &= ~DNF_LOCKED_FOR_EJECT;
    01338
    01339                         if ((deviceNode->Flags & (DNF_PROCESSED | DNF_ENUMERATED)) ==
    01340                             (DNF_PROCESSED | DNF_ENUMERATED)) {
    01341
    01342                             ASSERT(deviceNode->Child == NULL);
    01343                             ASSERT(!(deviceNode->Flags & DNF_ADDED));
    01344
    01345                             IopClearDevNodeProblem( deviceNode );
    01346                             IopRestartDeviceNode( deviceNode );
    01347                         }
    01348                     }
    01349
    01350                     if (UnlockDevNode) {
    01351                         parentNode = deviceNode->Parent;
    01352
    01353                         ASSERT(parentNode != NULL);
    01354
    01355                         ASSERT(deviceNode->LockCount > 0);
    01356
    01357                         if (--deviceNode->LockCount == 0) {
    01358                             KeSetEvent(&deviceNode->EnumerationMutex, 0, FALSE);
    01359                             ObDereferenceObject(deviceNode->PhysicalDeviceObject);
    01360                         }
    01361
    01362                         ASSERT(parentNode->LockCount > 0);
    01363
    01364                         if (--parentNode->LockCount == 0) {
    01365                             KeSetEvent(&parentNode->EnumerationMutex, 0, FALSE);
    01366                             ObDereferenceObject(parentNode->PhysicalDeviceObject);
    01367                         }
    01368                     }
    01369
    01370                     if (deviceNode->Parent != NULL) {
    01371
    01372                         parentObject = deviceNode->Parent->PhysicalDeviceObject;
    01373
    01374                     } else {
    01375                         parentObject = NULL;
    01376                         break;
    01377                     }
    01378                 }
    01379
    01380                 if (parentObject != NULL)  {
    01381                     IopAddRelationToList( parentsList, parentObject, FALSE, FALSE );
    01382                 }
    01383             }
    01384
    01385         }
    01386     }
    01387
    01388     //
    01389     // Reenumerate each of the parents
    01390     //
    01391
    01392     marker = 0;
    01393
    01394     while (IopEnumerateRelations( parentsList,
    01395                                   &marker,
    01396                                   &deviceObject,
    01397                                   NULL,
    01398                                   NULL,
    01399                                   FALSE)) {
    01400
    01401         IopRequestDeviceAction( deviceObject,
    01402                                 ReenumerateDeviceTree,
    01403                                 NULL,
    01404                                 NULL );
    01405     }
    01406
    01407     //
    01408     // Free the parents list
    01409     //
    01410
    01411     IopFreeRelationList( parentsList );
    01412
    01413     return STATUS_SUCCESS;
    01414 }

NTSTATUS IopIrqInitialize | ( | VOID |  | ) |

Definition at line 196 of file pnpirq.c.

References ArbInitializeArbiterInstance(), IopIrqPackResource(), IopIrqScoreRequirement(), IopIrqTranslateOrdering(), IopIrqUnpackRequirement(), IopIrqUnpackResource(), IopRootIrqArbiter, L, NULL, _ARBITER_INSTANCE::PackResource, _ARBITER_INSTANCE::ScoreRequirement, _ARBITER_INSTANCE::UnpackRequirement, and _ARBITER_INSTANCE::UnpackResource.

    00202                    :
    00203
    00204     This routine initializes the arbiter
    00205
    00206 Parameters:
    00207
    00208     None
    00209
    00210 Return Value:
    00211
    00212     None
    00213
    00214 --*/
    00215
    00216 {
    00217
    00218     IopRootIrqArbiter.UnpackRequirement = IopIrqUnpackRequirement;
    00219     IopRootIrqArbiter.PackResource      = IopIrqPackResource;
    00220     IopRootIrqArbiter.UnpackResource    = IopIrqUnpackResource;
    00221     IopRootIrqArbiter.ScoreRequirement  = IopIrqScoreRequirement;
    00222
    00223     return ArbInitializeArbiterInstance(&IopRootIrqArbiter,
    00224                                         NULL,     // Indicates ROOT arbiter
    00225                                         CmResourceTypeInterrupt,
    00226                                         L"RootIRQ",
    00227                                         L"Root",
    00228 #if defined(NO_LEGACY_DRIVERS)
    00229                                         NULL
    00230 #else
    00231                                         IopIrqTranslateOrdering
    00232 #endif // NO_LEGACY_DRIVERS
    00233                                         );
    00234 }

BOOLEAN IopIsAnyDeviceInstanceEnabled | ( | IN PUNICODE_STRING | ServiceKeyName,
|  | IN HANDLE | ServiceHandle,
|  | IN BOOLEAN | LegacyIncluded
| ) |

Definition at line 3181 of file pnpsubs.c.

References _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, ExFreePool(), FALSE, IopDeviceObjectFromDeviceInstance(), IopDisableDevice(), IopGetDeviceInstanceCsConfigFlags(), IopGetRegistryValue(), IopIsDevNodeProblem, IopOpenRegistryKey(), IopOpenServiceEnumKeys(), IopServiceInstanceToDeviceInstance(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, TITLE_INDEX_VALUE, and TRUE.

Referenced by IopInitializeBuiltinDriver(), IopLoadDriver(), and IopPrepareDriverLoading().

    03189                    :
    03190
    03191     This routine checks if any of the devices instances is turned on for the specified
    03192     service. This routine is used for Pnp Driver only and is temporary function to support
    03193     SUR.
    03194
    03195 Arguments:
    03196
    03197     ServiceKeyName - Specifies the service key unicode name
    03198
    03199     ServiceHandle - Optionally supplies a handle to the service key to be checked.
    03200
    03201     LegacyIncluded - TRUE, a legacy device instance key is counted as a device instance.
    03202                      FALSE, a legacy device instance key is not counted.
    03203
    03204 Returns:
    03205
    03206     A BOOLEAN value.
    03207
    03208 --*/
    03209
    03210 {
    03211     NTSTATUS status;
    03212     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    03213     HANDLE serviceEnumHandle, handle, controlHandle;
    03214     ULONG i, count, deviceFlags;
    03215     UNICODE_STRING unicodeName;
    03216     BOOLEAN enabled, setProblem, closeHandle = FALSE;
    03217     PDEVICE_OBJECT physicalDeviceObject;
    03218     PDEVICE_NODE deviceNode;
    03219
    03220     //
    03221     // Open registry ServiceKeyName\Enum branch
    03222     //
    03223
    03224     if (!ARGUMENT_PRESENT(ServiceHandle)) {
    03225         status = IopOpenServiceEnumKeys(ServiceKeyName,
    03226                                         KEY_READ,
    03227                                         &ServiceHandle,
    03228                                         &serviceEnumHandle,
    03229                                         FALSE
    03230                                         );
    03231         closeHandle = TRUE;
    03232     } else {
    03233         PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_ENUM);
    03234         status = IopOpenRegistryKeyEx( &serviceEnumHandle,
    03235                                        ServiceHandle,
    03236                                        &unicodeName,
    03237                                        KEY_READ
    03238                                        );
    03239     }
    03240     if (!NT_SUCCESS( status )) {
    03241
    03242         //
    03243         // No Service Enum key? no device instance.  Return FALSE.
    03244         //
    03245
    03246         return FALSE;
    03247     }
    03248
    03249     //
    03250     // Find out how many device instances listed in the ServiceName's
    03251     // Enum key.
    03252     //
    03253
    03254     status = IopGetRegistryValue ( serviceEnumHandle,
    03255                                    REGSTR_VALUE_COUNT,
    03256                                    &keyValueInformation
    03257                                    );
    03258     ZwClose(serviceEnumHandle);
    03259     count = 0;
    03260     if (NT_SUCCESS(status)) {
    03261         if ((keyValueInformation->Type == REG_DWORD) &&
    03262             (keyValueInformation->DataLength >= sizeof(ULONG))) {
    03263
    03264             count = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    03265         }
    03266         ExFreePool(keyValueInformation);
    03267     }
    03268     if (count == 0) {
    03269         if (closeHandle) {
    03270             ZwClose(ServiceHandle);
    03271         }
    03272         return FALSE;
    03273     }
    03274
    03275     //
    03276     // Walk through each registered device instance to check it is enabled.
    03277     //
    03278
    03279     enabled = FALSE;
    03280     for (i = 0; i < count; i++) {
    03281
    03282         //
    03283         // Get device instance handle.  If it fails, we will skip this device
    03284         // instance.
    03285         //
    03286
    03287         status = IopServiceInstanceToDeviceInstance (
    03288                      ServiceHandle,
    03289                      NULL,
    03290                      i,
    03291                      NULL,
    03292                      &handle,
    03293                      KEY_ALL_ACCESS
    03294                      );
    03295         if (!NT_SUCCESS(status)) {
    03296             continue;
    03297         }
    03298
    03299         physicalDeviceObject = IopDeviceObjectFromDeviceInstance(handle, NULL);
    03300         if (physicalDeviceObject) {
    03301             deviceNode = (PDEVICE_NODE)physicalDeviceObject->DeviceObjectExtension->DeviceNode;
    03302             if (deviceNode && (IopIsDevNodeProblem(deviceNode, CM_PROB_DISABLED) || IopIsDevNodeProblem(deviceNode, CM_PROB_HARDWARE_DISABLED))) {
    03303                 ZwClose(handle);
    03304                 ObDereferenceObject(physicalDeviceObject);
    03305                 continue;
    03306             }
    03307         } else {
    03308             deviceNode = NULL;
    03309         }
    03310
    03311         //
    03312         // Check if the device instance has been disabled.
    03313         // First check global flag: CONFIGFLAG and then CSCONFIGFLAG.
    03314         //
    03315
    03316         deviceFlags = 0;
    03317         status = IopGetRegistryValue(handle,
    03318                                      REGSTR_VALUE_CONFIG_FLAGS,
    03319                                      &keyValueInformation);
    03320         if (NT_SUCCESS(status)) {
    03321             if ((keyValueInformation->Type == REG_DWORD) &&
    03322                 (keyValueInformation->DataLength >= sizeof(ULONG))) {
    03323
    03324                 deviceFlags = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    03325             }
    03326             ExFreePool(keyValueInformation);
    03327         }
    03328
    03329         if (deviceFlags & CONFIGFLAG_DISABLED) {
    03330
    03331             //
    03332             // Convert this flag into the hardware profile-specific version, so it'll
    03333             // look the same as the CsConfigFlags we retrieve below.
    03334             //
    03335
    03336             deviceFlags = CSCONFIGFLAG_DISABLED;
    03337
    03338         } else {
    03339
    03340             status = IopGetServiceInstanceCsConfigFlags( ServiceKeyName,
    03341                                                          i,
    03342                                                          &deviceFlags
    03343                                                          );
    03344
    03345             if (!NT_SUCCESS(status)) {
    03346                 deviceFlags = 0;
    03347             }
    03348         }
    03349
    03350         //
    03351         // If the device is disabled (either globally, or specifically for this
    03352         // hardware profile), then mark the devnode as DNF_DISABLED.
    03353         //
    03354
    03355         if ((deviceFlags & CSCONFIGFLAG_DISABLED) || (deviceFlags & CSCONFIGFLAG_DO_NOT_START)) {
    03356
    03357             if (deviceNode) {
    03358                 IopDisableDevice(deviceNode, handle);
    03359             }
    03360         }
    03361
    03362         if (physicalDeviceObject) {
    03363             ObDereferenceObject(physicalDeviceObject);
    03364         }
    03365
    03366         //
    03367         // Finally, we need to set the STATUSFLAGS of the device instance to
    03368         // indicate if the driver is successfully started.
    03369         //
    03370
    03371         if (!(deviceFlags & (CSCONFIGFLAG_DISABLED | CSCONFIGFLAG_DO_NOT_CREATE | CSCONFIGFLAG_DO_NOT_START))) {
    03372
    03373             ULONG legacy;
    03374
    03375             //
    03376             // Check should legacy instance key be counted as an enabled device
    03377             //
    03378
    03379             if (LegacyIncluded == FALSE) {
    03380
    03381                 //
    03382                 // The legacy variable must be initialized to zero.  Because the device
    03383                 // instance key may be an enumerated device.  In this case, there is no
    03384                 // legacy value name.
    03385                 //
    03386
    03387                 legacy = 0;
    03388                 status = IopGetRegistryValue(handle,
    03389                                              REGSTR_VALUE_LEGACY,
    03390                                              &keyValueInformation
    03391                                              );
    03392                 if (NT_SUCCESS(status)) {
    03393                     if ((keyValueInformation->Type == REG_DWORD) &&
    03394                         (keyValueInformation->DataLength >= sizeof(ULONG))) {
    03395                         legacy = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    03396                     }
    03397                     ExFreePool(keyValueInformation);
    03398                 }
    03399             } else {
    03400                 legacy = 0;
    03401             }
    03402
    03403             if (legacy == 0) {
    03404
    03405                 //
    03406                 // Mark that the driver has at least a device instance to work with.
    03407                 //
    03408
    03409                 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
    03410                 status = IopCreateRegistryKeyEx( &controlHandle,
    03411                                                  handle,
    03412                                                  &unicodeName,
    03413                                                  KEY_ALL_ACCESS,
    03414                                                  REG_OPTION_VOLATILE,
    03415                                                  NULL
    03416                                                  );
    03417                 if (NT_SUCCESS(status)) {
    03418                     PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_ACTIVESERVICE);
    03419                     ZwSetValueKey(
    03420                                 controlHandle,
    03421                                 &unicodeName,
    03422                                 TITLE_INDEX_VALUE,
    03423                                 REG_SZ,
    03424                                 ServiceKeyName->Buffer,
    03425                                 ServiceKeyName->Length + sizeof(UNICODE_NULL)
    03426                                 );
    03427
    03428                     ZwClose(controlHandle);
    03429                 }
    03430                 enabled = TRUE;
    03431             }
    03432         }
    03433         ZwClose(handle);
    03434     }
    03435
    03436     if (closeHandle) {
    03437         ZwClose(ServiceHandle);
    03438     }
    03439     return enabled;
    03440 }

BOOLEAN IopIsDeviceInstanceEnabled | ( | IN HANDLE | DeviceInstanceHandle,
|  | IN PUNICODE_STRING | DeviceInstance,
|  | IN BOOLEAN | DisableIfEnabled
| ) |

Definition at line 3443 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetEnumName, CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, ExFreePool(), exit, FALSE, IopDeviceObjectFromDeviceInstance(), IopDisableDevice(), IopGetRegistryValue(), IopIsDevNodeProblem, IopOpenRegistryKey(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, and TRUE.

Referenced by IopGetDriverDeviceListWorker(), IopInitializeDeviceInstanceKey(), IopProcessNewDeviceNode(), and IopProcessNewProfileStateCallback().

    03451                    :
    03452
    03453     This routine checks if the specified devices instances is enabled.
    03454
    03455 Arguments:
    03456
    03457     DeviceInstanceHandle - Optionally supplies a handle to the device instance
    03458         key to be checked.
    03459
    03460     DeviceInstance - Specifies the device instance key unicode name.  Caller
    03461         must at least specified DeviceInstanceHandle or DeviceInstance.
    03462
    03463     DisableIfEnabled - If this flag is set, and the device should be disabled
    03464         but is currently disabled, then the device is disabled.
    03465
    03466 Returns:
    03467
    03468     A BOOLEAN value.
    03469
    03470 --*/
    03471
    03472 {
    03473     NTSTATUS status;
    03474     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    03475     HANDLE handle, handle1;
    03476     ULONG deviceFlags;
    03477     BOOLEAN enabled, closeHandle = FALSE;
    03478     UNICODE_STRING unicodeString;
    03479     PDEVICE_OBJECT deviceObject = NULL;
    03480     PDEVICE_NODE deviceNode = NULL;
    03481
    03482     //
    03483     // Open registry ServiceKeyName\Enum branch
    03484     //
    03485
    03486     if (!ARGUMENT_PRESENT(DeviceInstanceHandle)) {
    03487         status = IopOpenRegistryKeyEx( &handle,
    03488                                        NULL,
    03489                                        &CmRegistryMachineSystemCurrentControlSetEnumName,
    03490                                        KEY_READ
    03491                                        );
    03492
    03493         if (NT_SUCCESS( status )) {
    03494
    03495             status = IopOpenRegistryKeyEx( &DeviceInstanceHandle,
    03496                                            handle,
    03497                                            DeviceInstance,
    03498                                            KEY_READ
    03499                                            );
    03500             ZwClose(handle);
    03501         }
    03502
    03503         if (!NT_SUCCESS( status )) {
    03504             return FALSE;
    03505         }
    03506         closeHandle = TRUE;
    03507     }
    03508
    03509     enabled = TRUE;
    03510
    03511     //
    03512     // First check the device node
    03513     //
    03514
    03515     deviceObject = IopDeviceObjectFromDeviceInstance(DeviceInstanceHandle, NULL);
    03516     if (deviceObject) {
    03517         deviceNode = (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode;
    03518         if (deviceNode && (IopIsDevNodeProblem(deviceNode, CM_PROB_DISABLED) || IopIsDevNodeProblem(deviceNode, CM_PROB_DISABLED))) {
    03519             enabled = FALSE;
    03520             goto exit;
    03521         }
    03522     }
    03523
    03524     //
    03525     // Check if the device instance has been disabled.
    03526     // First check global flag: CONFIGFLAG and then CSCONFIGFLAG.
    03527     //
    03528
    03529     deviceFlags = 0;
    03530     status = IopGetRegistryValue(DeviceInstanceHandle,
    03531                                  REGSTR_VALUE_CONFIG_FLAGS,
    03532                                  &keyValueInformation);
    03533     if (NT_SUCCESS(status)) {
    03534         if ((keyValueInformation->Type == REG_DWORD) &&
    03535             (keyValueInformation->DataLength >= sizeof(ULONG))) {
    03536             deviceFlags = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    03537         }
    03538         ExFreePool(keyValueInformation);
    03539     }
    03540     if (!(deviceFlags & CONFIGFLAG_DISABLED)) {
    03541         enabled = TRUE;
    03542
    03543         //
    03544         // See if we can open current hardware profile
    03545         //
    03546         status = IopOpenRegistryKeyEx( &handle1,
    03547                                        NULL,
    03548                                        &CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent,
    03549                                        KEY_READ
    03550                                        );
    03551
    03552         if (NT_SUCCESS(status) && DeviceInstance != NULL) {
    03553
    03554             //
    03555             // Now, we must open the System\CCS\Enum key under this.
    03556             //
    03557             //
    03558             // Open system\CurrentControlSet under current hardware profile key
    03559             //
    03560
    03561             PiWstrToUnicodeString(&unicodeString, REGSTR_PATH_CURRENTCONTROLSET);
    03562             status = IopOpenRegistryKeyEx( &handle,
    03563                                            handle1,
    03564                                            &unicodeString,
    03565                                            KEY_READ
    03566                                            );
    03567             ZwClose(handle1);
    03568             if (NT_SUCCESS(status)) {
    03569                 PiWstrToUnicodeString(&unicodeString, REGSTR_KEY_ENUM);
    03570                 status = IopOpenRegistryKeyEx( &handle1,
    03571                                                handle,
    03572                                                &unicodeString,
    03573                                                KEY_READ
    03574                                                );
    03575                 ZwClose(handle);
    03576                 if (NT_SUCCESS(status)) {
    03577                     status = IopOpenRegistryKeyEx( &handle,
    03578                                                    handle1,
    03579                                                    DeviceInstance,
    03580                                                    KEY_READ
    03581                                                    );
    03582                     ZwClose(handle1);
    03583                     if (NT_SUCCESS(status)) {
    03584                         status = IopGetRegistryValue(
    03585                                         handle,
    03586                                         REGSTR_VALUE_CSCONFIG_FLAGS,
    03587                                         &keyValueInformation
    03588                                         );
    03589                         if (NT_SUCCESS(status)) {
    03590                             if((keyValueInformation->Type == REG_DWORD) &&
    03591                                (keyValueInformation->DataLength >= sizeof(ULONG))) {
    03592                                deviceFlags = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    03593                             }
    03594                             ExFreePool(keyValueInformation);
    03595                         }
    03596                         ZwClose(handle);
    03597                         if (NT_SUCCESS(status)) {
    03598                             if ((deviceFlags & CSCONFIGFLAG_DISABLED) ||
    03599                                 (deviceFlags & CSCONFIGFLAG_DO_NOT_CREATE) ||
    03600                                 (deviceFlags & CSCONFIGFLAG_DO_NOT_START)) {
    03601                                 enabled = FALSE;
    03602                             }
    03603                         }
    03604                     }
    03605                 }
    03606             }
    03607         }
    03608     } else {
    03609         enabled = FALSE;
    03610     }
    03611
    03612     //
    03613     // If the device is disabled and has device node associated with it.
    03614     // disable the device.
    03615     //
    03616
    03617     if (enabled == FALSE && deviceNode && DisableIfEnabled) {
    03618         IopDisableDevice(deviceNode, DeviceInstanceHandle);
    03619     }
    03620 exit:
    03621     if (deviceObject) {
    03622         ObDereferenceObject(deviceObject);
    03623     }
    03624     if (closeHandle) {
    03625         ZwClose(DeviceInstanceHandle);
    03626     }
    03627     return enabled;
    03628 }

BOOLEAN IopIsDuplicatedDevices | ( | IN PCM_RESOURCE_LIST | Configuration1,
|  | IN PCM_RESOURCE_LIST | Configuration2,
|  | IN PHAL_BUS_INFORMATION BusInfo1 | OPTIONAL,
|  | IN PHAL_BUS_INFORMATION BusInfo2 | OPTIONAL
| ) |

Definition at line 2554 of file pnpsubs.c.

References FALSE, HalTranslateBusAddress(), NULL, and TRUE.

Referenced by IopIsReportedAlready().

    02563                    :
    02564
    02565     This routine compares two set of configurations and bus information to
    02566     determine if the resources indicate the same device.  If BusInfo1 and
    02567     BusInfo2 both are absent, it means caller wants to compare the raw
    02568     resources.
    02569
    02570 Arguments:
    02571
    02572     Configuration1 - Supplies a pointer to the first set of resource.
    02573
    02574     Configuration2 - Supplies a pointer to the second set of resource.
    02575
    02576     BusInfo1 - Supplies a pointer to the first set of bus information.
    02577
    02578     BusInfo2 - Supplies a pointer to the second set of bus information.
    02579
    02580 Return Value:
    02581
    02582     returns TRUE if the two set of resources indicate the same device;
    02583     otherwise a value of FALSE is returned.
    02584
    02585 --*/
    02586
    02587 {
    02588     PCM_PARTIAL_RESOURCE_LIST list1, list2;
    02589     PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor1, descriptor2;
    02590
    02591     ULONG i, j;
    02592     ULONG pass = 0;
    02593
    02594     //
    02595     // The BusInfo for both resources must be both present or not present.
    02596     //
    02597
    02598     if ((ARGUMENT_PRESENT(BusInfo1) && !ARGUMENT_PRESENT(BusInfo2)) ||
    02599         (!ARGUMENT_PRESENT(BusInfo1) && ARGUMENT_PRESENT(BusInfo2))) {
    02600
    02601         //
    02602         // Unable to determine.
    02603         //
    02604
    02605         return FALSE;
    02606     }
    02607
    02608     //
    02609     // Next check resources used by the two devices.
    02610     // Currently, we *only* check the Io ports.
    02611     //
    02612
    02613     if (Configuration1->Count == 0 || Configuration2->Count == 0) {
    02614
    02615         //
    02616         // If any one of the configuration data is empty, we assume
    02617         // the devices are not duplicates.
    02618         //
    02619
    02620         return FALSE;
    02621     }
    02622
    02623 RedoScan:
    02624
    02625     list1 = &(Configuration1->List[0].PartialResourceList);
    02626     list2 = &(Configuration2->List[0].PartialResourceList);
    02627
    02628     for(i = 0, descriptor1 = list1->PartialDescriptors;
    02629         i < list1->Count;
    02630         i++, descriptor1++) {
    02631
    02632         //
    02633         // If this is an i/o port or a memory range then look for a match
    02634         // in the other list.
    02635         //
    02636
    02637         if((descriptor1->Type == CmResourceTypePort) ||
    02638            (descriptor1->Type == CmResourceTypeMemory)) {
    02639
    02640             for(j = 0, descriptor2 = list2->PartialDescriptors;
    02641                 j < list2->Count;
    02642                 j++, descriptor2++) {
    02643
    02644                 //
    02645                 // If the types match then check to see if both addresses
    02646                 // match as well.  If bus info was provided then go ahead
    02647                 // and translate the ranges first.
    02648                 //
    02649
    02650                 if(descriptor1->Type == descriptor2->Type) {
    02651
    02652                     PHYSICAL_ADDRESS range1, range1Translated;
    02653                     PHYSICAL_ADDRESS range2, range2Translated;
    02654                     ULONG range1IoSpace, range2IoSpace;
    02655
    02656                     range1 = descriptor1->u.Generic.Start;
    02657                     range2 = descriptor2->u.Generic.Start;
    02658
    02659                     if((range1.QuadPart == 0) ||
    02660                        (BusInfo1 == NULL) ||
    02661                        (HalTranslateBusAddress(
    02662                             BusInfo1->BusType,
    02663                             BusInfo1->BusNumber,
    02664                             range1,
    02665                             &range1IoSpace,
    02666                             &range1Translated) == FALSE)) {
    02667
    02668                         range1Translated = range1;
    02669                         range1IoSpace =
    02670                             (descriptor1->Type == CmResourceTypePort) ? TRUE :
    02671                                                                         FALSE;
    02672                     }
    02673
    02674                     if((range2.QuadPart == 0) ||
    02675                        (BusInfo2 == NULL) ||
    02676                        (HalTranslateBusAddress(
    02677                             BusInfo2->BusType,
    02678                             BusInfo2->BusNumber,
    02679                             range2,
    02680                             &range2IoSpace,
    02681                             &range2Translated) == FALSE)) {
    02682
    02683                         range2Translated = range2;
    02684                         range2IoSpace =
    02685                             (descriptor2->Type == CmResourceTypePort) ? TRUE :
    02686                                                                         FALSE;
    02687                     }
    02688
    02689                     //
    02690                     // If the ranges are in the same space and start at the
    02691                     // same location then break out and go on to the next
    02692                     // range
    02693                     //
    02694
    02695                     if((range1Translated.QuadPart == range2Translated.QuadPart) &&
    02696                        (range1IoSpace == range2IoSpace)) {
    02697
    02698                         break;
    02699                     }
    02700                 }
    02701             }
    02702
    02703             //
    02704             // If we made it all the way through the resource list without
    02705             // finding a match then these are not duplicates.
    02706             //
    02707
    02708             if(j == list2->Count) {
    02709                 return FALSE;
    02710             }
    02711         }
    02712     }
    02713
    02714     //
    02715     // If every resource in list 1 exists in list 2 then we also need to make
    02716     // sure that every resource in list 2 exists in list 1.
    02717     //
    02718
    02719     if(pass == 0) {
    02720
    02721         PVOID tmp ;
    02722
    02723         tmp = Configuration2;
    02724         Configuration2 = Configuration1;
    02725         Configuration1 = tmp;
    02726
    02727         tmp = BusInfo2;
    02728         BusInfo2 = BusInfo1;
    02729         BusInfo1 = tmp;
    02730
    02731         pass = 1;
    02732
    02733         goto RedoScan;
    02734     }
    02735
    02736     return TRUE;
    02737 }

BOOLEAN IopIsFirmwareMapperDevicePresent | ( | IN HANDLE | KeyHandle | ) |

Definition at line 1572 of file pnpinit.c.

References ExFreePool(), FALSE, IopGetRegistryValue(), IopOpenRegistryKeyEx(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), PAGED_CODE, and TRUE.

Referenced by IopInitializeDeviceInstanceKey().

    01578                    :
    01579
    01580     This routine checks if the registry key is created by FirmwareMapper.
    01581     If Yes, it further checks if the device for the key is present in this
    01582     boot.
    01583
    01584 Parameters:
    01585
    01586     KeyHandle - Specifies a handle to the registry key to be checked.
    01587
    01588 Return Value:
    01589
    01590     A BOOLEAN vaStatus code that indicates whether or not the function was successful.
    01591
    01592 --*/
    01593 {
    01594     NTSTATUS status;
    01595     HANDLE handle;
    01596     UNICODE_STRING unicodeName;
    01597     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    01598     ULONG tmp = 0;
    01599
    01600     PAGED_CODE();
    01601
    01602     //
    01603     // First check to see if this device instance key is a firmware-created one
    01604     //
    01605
    01606     status = IopGetRegistryValue (KeyHandle,
    01607                                   REGSTR_VAL_FIRMWAREIDENTIFIED,
    01608                                   &keyValueInformation);
    01609     if (NT_SUCCESS(status)) {
    01610         if ((keyValueInformation->Type == REG_DWORD) &&
    01611             (keyValueInformation->DataLength == sizeof(ULONG))) {
    01612
    01613             tmp = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    01614         }
    01615         ExFreePool(keyValueInformation);
    01616     }
    01617     if (tmp == 0) {
    01618         return TRUE;
    01619     }
    01620
    01621     //
    01622     // Make sure the device is present.
    01623     //
    01624
    01625     PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
    01626     status = IopOpenRegistryKeyEx( &handle,
    01627                                    KeyHandle,
    01628                                    &unicodeName,
    01629                                    KEY_READ
    01630                                    );
    01631     if (!NT_SUCCESS(status)) {
    01632         return FALSE;
    01633     }
    01634
    01635     status = IopGetRegistryValue (handle,
    01636                                   REGSTR_VAL_FIRMWAREMEMBER,
    01637                                   &keyValueInformation);
    01638     ZwClose(handle);
    01639     tmp = 0;
    01640
    01641     if (NT_SUCCESS(status)) {
    01642         if ((keyValueInformation->Type == REG_DWORD) &&
    01643             (keyValueInformation->DataLength == sizeof(ULONG))) {
    01644
    01645             tmp = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    01646         }
    01647         ExFreePool(keyValueInformation);
    01648     }
    01649     if (!tmp) {
    01650         return FALSE;
    01651     } else {
    01652         return TRUE;
    01653     }
    01654 }

BOOLEAN IopIsLegacyDriver | ( | IN PDRIVER_OBJECT | DriverObject | ) |

Definition at line 5290 of file pnpsubs.c.

References DRVO_LEGACY_DRIVER, FALSE, PAGED_CODE, and TRUE.

Referenced by IopCallDriverAddDeviceQueryRoutine(), IopInitializeBootDrivers(), IopInitializeBuiltinDriver(), and IopLoadDriver().

    05296                    :
    05297
    05298     This routine checks if the driver object specifies a legacy driver.
    05299
    05300 Arguments:
    05301
    05302     DriverObject - supplies a pointer to the driver object to be checked.
    05303
    05304 Return Value:
    05305
    05306     BOOLEAN
    05307
    05308 --*/
    05309
    05310 {
    05311
    05312     PAGED_CODE();
    05313
    05314     //
    05315     // If AddDevice entry is not empty it is a wdm driver
    05316     //
    05317
    05318     if (DriverObject->DriverExtension->AddDevice) {
    05319         return FALSE;
    05320     }
    05321
    05322     //
    05323     // Else if LEGACY flag is set in the driver object, it's a legacy driver.
    05324     //
    05325
    05326     if (DriverObject->Flags & DRVO_LEGACY_DRIVER) {
    05327         return TRUE;
    05328     } else {
    05329         return FALSE;
    05330     }
    05331 }

NTSTATUS IopLegacyResourceAllocation | ( | IN ARBITER_REQUEST_SOURCE | AllocationType,
|  | IN PDRIVER_OBJECT | DriverObject,
|  | IN PDEVICE_OBJECT | DeviceObject,
|  | IN PIO_RESOURCE_REQUIREMENTS_LIST | ResourceRequirements,
|  | IN OUT PCM_RESOURCE_LIST *AllocatedResources | OPTIONAL
| ) |

Definition at line 6180 of file pnpres.c.

References _IOP_RESOURCE_REQUEST::AllocationType, ArbiterRequestPnpDetected, ASSERT, DebugMessage, DelayExecution, DNF_ASSIGNING_RESOURCES, DNF_RESOURCE_ASSIGNED, DNF_RESOURCE_REPORTED, DRVO_LEGACY_RESOURCES, DUMP_ERROR, ExAllocatePoolIORL, ExFreePool(), FALSE, _DEVICE_NODE::Flags, _IOP_RESOURCE_REQUEST::Flags, IOP_ASSIGN_NO_REBALANCE, IopAllocateResources(), IopCombineLegacyResources(), IopDatabaseLock, IopDetermineResourceListSize(), IopFindLegacyDeviceNode(), IoPnpDriverObject, IopRegistrySemaphore, IopReleaseResources(), IopRemoveLegacyDeviceNode(), IopRootDeviceNode, IopWriteAllocatedResourcesToRegistry(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, _DEVICE_NODE::OverUsed1, PagedPool, _DEVICE_NODE::Parent, _IOP_RESOURCE_REQUEST::PhysicalDevice, PnpDefaultInterfaceType, _DEVICE_NODE::ResourceList, _DEVICE_NODE::ResourceListTranslated, _IOP_RESOURCE_REQUEST::ResourceRequirements, and TRUE.

Referenced by IoAssignResources(), IopReleaseDeviceResources(), and IoReportResourceUsageInternal().

    06190                    :
    06191
    06192     This routine handles legacy interface IoAssignResources and IoReportResourcesUsage,
    06193     It converts the request to call IopAllocateResources.
    06194
    06195 Parameters:
    06196
    06197     AllocationType - Allocation type for the legacy request.
    06198
    06199     DriverObject - Driver object doing the legacy allocation.
    06200
    06201     DeviceObject - Device object.
    06202
    06203     ResourceRequirements - Legacy resource requirements. If NULL, caller want to free resources.
    06204
    06205     AllocatedResources - Pointer to a variable that receives pointer to allocated resources.
    06206
    06207 Return Value:
    06208
    06209     Status code that indicates whether or not the function was successful.
    06210
    06211 --*/
    06212
    06213 {
    06214     PDEVICE_OBJECT      pdo;
    06215     PDEVICE_NODE        deviceNode;
    06216     PDEVICE_NODE        legacyDeviceNode;
    06217     NTSTATUS            status;
    06218     PCM_RESOURCE_LIST   combinedResources;
    06219     KIRQL               irql;
    06220
    06221     ASSERT(DriverObject);
    06222
    06223     //
    06224     // Grab the IO registry semaphore to make sure no other device is
    06225     // reporting it's resource usage while we are searching for conflicts.
    06226     //
    06227
    06228     KeEnterCriticalRegion();
    06229
    06230     status = KeWaitForSingleObject( &IopRegistrySemaphore,
    06231                                     DelayExecution,
    06232                                     KernelMode,
    06233                                     FALSE,
    06234                                     NULL);
    06235     if (NT_SUCCESS(status)) {
    06236
    06237         status = IopFindLegacyDeviceNode(DriverObject, DeviceObject, &deviceNode, &pdo);
    06238         if (NT_SUCCESS(status)) {
    06239
    06240             legacyDeviceNode = NULL;
    06241             if (!deviceNode->Parent && ResourceRequirements) {
    06242
    06243                 //
    06244                 // Make IopRootDeviceNode the bus pdo so we will search the right bus pdo
    06245                 // on resource descriptor level.
    06246                 //
    06247
    06248                 if (ResourceRequirements->InterfaceType == InterfaceTypeUndefined) {
    06249
    06250                     ResourceRequirements->InterfaceType = PnpDefaultInterfaceType;
    06251
    06252                 }
    06253                 deviceNode->Parent = IopRootDeviceNode;
    06254
    06255             }
    06256
    06257             //
    06258             // Release resources for this device node.
    06259             //
    06260
    06261             if (    (!ResourceRequirements && deviceNode->Parent) ||
    06262                     (deviceNode->Flags & (DNF_RESOURCE_REPORTED | DNF_RESOURCE_ASSIGNED))) {
    06263
    06264                 IopReleaseResources(deviceNode);
    06265
    06266             }
    06267
    06268             if (ResourceRequirements) {
    06269
    06270                 IOP_RESOURCE_REQUEST    requestTable;
    06271                 IOP_RESOURCE_REQUEST    *requestTablep;
    06272                 ULONG                   count;
    06273
    06274                 //
    06275                 // Try to allocate these resource requirements.
    06276                 //
    06277
    06278                 count = 1;
    06279                 RtlZeroMemory(&requestTable, sizeof(IOP_RESOURCE_REQUEST));
    06280                 requestTable.ResourceRequirements = ResourceRequirements;
    06281                 requestTable.PhysicalDevice = pdo;
    06282                 requestTable.Flags = IOP_ASSIGN_NO_REBALANCE;
    06283                 requestTable.AllocationType =  AllocationType;
    06284
    06285                 deviceNode->Flags |= DNF_ASSIGNING_RESOURCES;
    06286                 requestTablep = &requestTable;
    06287                 IopAllocateResources(&count, &requestTablep, TRUE, TRUE);
    06288                 deviceNode->Flags &= ~DNF_ASSIGNING_RESOURCES;
    06289                 status = requestTable.Status;
    06290                 if (NT_SUCCESS(status)) {
    06291
    06292                     deviceNode->Flags |= DNF_RESOURCE_REPORTED;
    06293                     //deviceNode->Flags &= ~DNF_INSUFFICIENT_RESOURCES;
    06294                     deviceNode->ResourceListTranslated = requestTable.TranslatedResourceAssignment;
    06295                     count = IopDetermineResourceListSize((*AllocatedResources) ? *AllocatedResources : requestTable.ResourceAssignment);
    06296                     deviceNode->ResourceList = ExAllocatePoolIORL(PagedPool, count);
    06297                     if (deviceNode->ResourceList) {
    06298
    06299                         if (*AllocatedResources) {
    06300
    06301                             //
    06302                             // We got called from IoReportResourceUsage.
    06303                             //
    06304
    06305                             ASSERT(requestTable.ResourceAssignment);
    06306                             ExFreePool(requestTable.ResourceAssignment);
    06307
    06308                         } else {
    06309
    06310                             //
    06311                             // We got called from IoAssignResources.
    06312                             //
    06313
    06314                             *AllocatedResources = requestTable.ResourceAssignment;
    06315
    06316                         }
    06317                         RtlCopyMemory(deviceNode->ResourceList, *AllocatedResources, count);
    06318                         legacyDeviceNode = (PDEVICE_NODE)deviceNode->OverUsed1.LegacyDeviceNode;
    06319
    06320                     } else {
    06321
    06322                         deviceNode->ResourceList = requestTable.ResourceAssignment;
    06323                         IopReleaseResources(deviceNode);
    06324                         status = STATUS_INSUFFICIENT_RESOURCES;
    06325
    06326                     }
    06327                 }
    06328
    06329                 //
    06330                 // Remove the madeup PDO and device node if there was some error.
    06331                 //
    06332
    06333                 if (!NT_SUCCESS(status)) {
    06334
    06335                     IopRemoveLegacyDeviceNode(DeviceObject, deviceNode);
    06336
    06337                 }
    06338
    06339             } else {
    06340
    06341                 //
    06342                 // Caller wants to release resources.
    06343                 //
    06344
    06345                 legacyDeviceNode = (PDEVICE_NODE)deviceNode->OverUsed1.LegacyDeviceNode;
    06346                 IopRemoveLegacyDeviceNode(DeviceObject, deviceNode);
    06347
    06348             }
    06349
    06350             if (NT_SUCCESS(status)) {
    06351
    06352                 if (legacyDeviceNode) {
    06353
    06354                     //
    06355                     // After the resource is modified, update the allocated resource list
    06356                     // for the Root\Legacy_xxxx\0000 device instance.
    06357                     //
    06358
    06359                     combinedResources = IopCombineLegacyResources(legacyDeviceNode);
    06360                     if (combinedResources) {
    06361
    06362                         IopWriteAllocatedResourcesToRegistry(   legacyDeviceNode,
    06363                                                                 combinedResources,
    06364                                                                 IopDetermineResourceListSize(combinedResources));
    06365                         ExFreePool(combinedResources);
    06366                     }
    06367                 }
    06368
    06369                 //
    06370                 // BUGBUG: Santoshj 10/01/99
    06371                 // Since IoReportDetectedDevice always uses IoPnpDriverObject instead of the one
    06372                 // passed in, we put in this hack so that we dont taint ourselves. Other bugs need
    06373                 // to be fixed before removing this hack (dont do resource allocation if this
    06374                 // was already reported).
    06375                 //
    06376
    06377                 if (AllocationType != ArbiterRequestPnpDetected && DriverObject != IoPnpDriverObject) {
    06378                     //
    06379                     // Modify the DRVOBJ flags.
    06380                     //
    06381                     ExAcquireFastLock(&IopDatabaseLock, &irql);
    06382                     if (ResourceRequirements) {
    06383                         //
    06384                         // Once tainted, a driver can never lose it's legacy history
    06385                         // (unless unloaded). This is because the device object
    06386                         // field is optional, and we don't bother counting here...
    06387                         //
    06388                         DriverObject->Flags |= DRVO_LEGACY_RESOURCES;
    06389                     }
    06390                     ExReleaseFastLock(&IopDatabaseLock, irql);
    06391                 }
    06392             }
    06393         }
    06394
    06395         KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE);
    06396
    06397     } else {
    06398
    06399         DebugMessage(DUMP_ERROR, ("PNPRES: IopLegacyResourceAllocation: Failed to acquire registry semaphore, status %08X\n", status));
    06400     }
    06401
    06402     KeLeaveCriticalRegion();
    06403
    06404     return status;
    06405 }

PDRIVER_OBJECT IopLoadBootFilterDriver | ( | IN PUNICODE_STRING | DriverName,
|  | IN ULONG | GroupIndex
| ) |

Definition at line 4654 of file ioinit.c.

References _DRIVER_INFORMATION::DataTableEntry, _DRIVER_INFORMATION::DriverObject, ExFreePool(), FALSE, IopGetDriverNameFromKeyNode(), IopGroupIndex, IopGroupTable, IopInitializeBuiltinDriver(), _BOOT_DRIVER_LIST_ENTRY::LdrEntry, NT_SUCCESS, NTSTATUS(), NULL, ObReferenceObject, PDRIVER_INFORMATION, PDRIVER_INITIALIZE, _DRIVER_INFORMATION::Processed, _BOOT_DRIVER_LIST_ENTRY::RegistryPath, RtlEqualUnicodeString(), _DRIVER_INFORMATION::ServiceHandle, and TRUE.

Referenced by IopCallDriverAddDeviceQueryRoutine().

    04661                    :
    04662
    04663     This initializes boot filter drivers.
    04664
    04665 Arguments:
    04666
    04667     DriverName - specifies the name of the driver to be initialized.
    04668
    04669     GroupIndex - specifies the Driver's group index (could be anything)
    04670
    04671 Return Value:
    04672
    04673     PDRIVER_OBJECT
    04674
    04675 --*/
    04676
    04677 {
    04678     PDRIVER_OBJECT driverObject = NULL;
    04679     PLIST_ENTRY nextEntry;
    04680     PDRIVER_INFORMATION driverInfo;
    04681     UNICODE_STRING completeName;
    04682     PBOOT_DRIVER_LIST_ENTRY bootDriver;
    04683     PLDR_DATA_TABLE_ENTRY driverEntry;
    04684     HANDLE keyHandle;
    04685     NTSTATUS status;
    04686
    04687     if (IopGroupTable == NULL || GroupIndex >= IopGroupIndex) {
    04688
    04689         //
    04690         // If we have not reached the boot driver initialization phase or
    04691         // the filter driver is not a boot driver.
    04692         //
    04693
    04694         return driverObject;
    04695     }
    04696
    04697     //
    04698     // Go thru every driver that we initialized.  If it supports AddDevice entry and
    04699     // did not create any device object after we start it.  We mark it as failure so
    04700     // text mode setup knows this driver is not needed.
    04701     //
    04702
    04703     nextEntry = IopGroupTable[GroupIndex].Flink;
    04704     while (nextEntry != &IopGroupTable[GroupIndex]) {
    04705
    04706         driverInfo = CONTAINING_RECORD(nextEntry, DRIVER_INFORMATION, Link);
    04707         if (driverInfo->Processed == FALSE) {
    04708
    04709             keyHandle = driverInfo->ServiceHandle;
    04710
    04711             status = IopGetDriverNameFromKeyNode( keyHandle,
    04712                                                   &completeName );
    04713             if (NT_SUCCESS( status )) {
    04714                 if (RtlEqualUnicodeString(DriverName,
    04715                                           &completeName,
    04716                                           TRUE)) {    // case-insensitive
    04717
    04718                     bootDriver = driverInfo->DataTableEntry;
    04719                     driverEntry = bootDriver->LdrEntry;
    04720
    04721                     driverObject = IopInitializeBuiltinDriver(
    04722                                        &completeName,
    04723                                        &bootDriver->RegistryPath,
    04724                                        (PDRIVER_INITIALIZE) driverEntry->EntryPoint,
    04725                                        driverEntry,
    04726                                        FALSE);
    04727                     driverInfo->DriverObject = driverObject;
    04728                     driverInfo->Processed = TRUE;
    04729                     //
    04730                     // Pnp might unload the driver before we get a chance to look at this. So take an extra
    04731                     // reference.
    04732                     //
    04733                     if (driverObject) {
    04734                         ObReferenceObject(driverObject);
    04735                     }
    04736                     ExFreePool(completeName.Buffer);
    04737                     break;
    04738                 }
    04739                 ExFreePool(completeName.Buffer);
    04740             }
    04741         }
    04742
    04743         nextEntry = nextEntry->Flink;
    04744     }
    04745     return driverObject;
    04746 }
    #if 0

NTSTATUS IopLockDeviceRemovalRelations | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN PLUGPLAY_DEVICE_DELETE_TYPE | OperationCode,
|  | OUT PRELATION_LIST * | RelationsList,
|  | IN BOOLEAN | IsKernelInitiated
| ) |

Definition at line 725 of file pnpdel.c.

References ASSERT, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_ADDED, _DEVICE_NODE::EnumerationMutex, FALSE, _DEVICE_NODE::Flags, IopAcquireDeviceTreeLock, IopAllocateRelationList(), IopCompressRelationList(), IopEnumerateRelations(), IopFreeRelationList(), IopProcessRelation(), IopReleaseDeviceTreeLock, IopRootDeviceNode, KeClearEvent, KeSetEvent(), _DEVICE_NODE::LockCount, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObject, PAGED_CODE, _DEVICE_NODE::Parent, _DEVICE_NODE::PhysicalDeviceObject, and TRUE.

    00734                    :
    00735
    00736     This routine locks the device subtrees for removal operation and returns
    00737     a list of device objects which need to be removed with the specified
    00738     DeviceObject.
    00739
    00740     Caller must hold a reference to the DeviceObject.
    00741
    00742 Arguments:
    00743
    00744     DeviceObject - Supplies a pointer to the device object to be removed.
    00745
    00746     OperationCode - Operation code, i.e., QueryEject, CancelEject, Eject...
    00747
    00748     DeviceRelations - supplies a pointer to a variable to receive the device's
    00749                    removal relations.
    00750
    00751 Return Value:
    00752
    00753     NTSTATUS code.
    00754
    00755 --*/
    00756
    00757 {
    00758     NTSTATUS                status;
    00759     PDEVICE_OBJECT          deviceObject;
    00760     PDEVICE_NODE            deviceNode, parent;
    00761     PRELATION_LIST          relationsList;
    00762     ULONG                   marker;
    00763     BOOLEAN                 tagged;
    00764
    00765     PAGED_CODE();
    00766
    00767     *RelationsList = NULL;
    00768
    00769     deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
    00770
    00771     if (!IsKernelInitiated && !(deviceNode->Flags & DNF_ADDED) && OperationCode != EjectDevice) {
    00772
    00773         return STATUS_SUCCESS;
    00774     }
    00775
    00776     //
    00777     // Obviously no one should try to delete the whole device node tree.
    00778     //
    00779
    00780     ASSERT(DeviceObject != IopRootDeviceNode->PhysicalDeviceObject);
    00781
    00782     //
    00783     // Lock the whole device node tree so no one can touch the tree.
    00784     //
    00785
    00786     IopAcquireDeviceTreeLock();
    00787
    00788     if (IsKernelInitiated) {
    00789         //
    00790         // For kernel initiated removes it means that the device itself is
    00791         // physically gone.
    00792         //
    00793
    00794         //
    00795         // We'll take advantage of that signal to go and check if there
    00796         // previously was a QueryRemove done on this devnode.  If
    00797         // so, we need to reenumerate the parents of all the relations in
    00798         // case some of them were speculative.
    00799         //
    00800     }
    00801
    00802     if ((relationsList = IopAllocateRelationList()) == NULL) {
    00803
    00804         IopReleaseDeviceTreeLock();
    00805         return STATUS_INSUFFICIENT_RESOURCES;
    00806     }
    00807
    00808     //
    00809     // First process the object itself
    00810     //
    00811     status = IopProcessRelation( DeviceObject,
    00812                                  OperationCode,
    00813                                  relationsList,
    00814                                  IsKernelInitiated,
    00815                                  TRUE);
    00816
    00817     ASSERT(status != STATUS_INVALID_DEVICE_REQUEST);
    00818
    00819     marker = 0;
    00820     while (IopEnumerateRelations( relationsList,
    00821                                   &marker,
    00822                                   &deviceObject,
    00823                                   NULL,
    00824                                   &tagged,
    00825                                   FALSE)) {
    00826
    00827         deviceNode = (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode;
    00828
    00829         //
    00830         // If we were successful we need to lock the parents of each of the
    00831         // relations, otherwise we need to unlock each relation.
    00832         //
    00833
    00834
    00835         if (NT_SUCCESS(status)) {
    00836             //
    00837             // For all the device nodes in the DeviceRelations, we need to lock
    00838             // their parents' enumeration mutex.
    00839             //
    00840
    00841             if (tagged) {
    00842
    00843                 //
    00844                 // If the tagged bit is set then the relation was merged from
    00845                 // a pending eject.  In this case the devnode isn't locked so
    00846                 // we do it now.
    00847                 //
    00848
    00849                 if (deviceNode->LockCount++ == 0) {
    00850                     ObReferenceObject(deviceNode->PhysicalDeviceObject);
    00851                     KeClearEvent(&deviceNode->EnumerationMutex);
    00852                 }
    00853             }
    00854
    00855             parent = deviceNode->Parent;
    00856
    00857             if (parent->LockCount++ == 0) {
    00858                 ObReferenceObject(parent->PhysicalDeviceObject);
    00859                 KeClearEvent(&parent->EnumerationMutex);
    00860             }
    00861
    00862         } else {
    00863
    00864             if (!tagged) {
    00865
    00866                 //
    00867                 // If the tagged bit is set then the relation was merged from
    00868                 // an pending eject.  In this case the devnode isn't locked so
    00869                 // we don't need to unlock it, all the others we unlock now.
    00870                 //
    00871
    00872                 ASSERT(deviceNode->LockCount > 0);
    00873
    00874                 if (--deviceNode->LockCount == 0) {
    00875                     KeSetEvent(&deviceNode->EnumerationMutex, 0, FALSE);
    00876                     ObDereferenceObject(deviceObject);
    00877                 }
    00878             }
    00879         }
    00880     }
    00881
    00882     //
    00883     // Release the device tree.
    00884     //
    00885
    00886     IopReleaseDeviceTreeLock();
    00887
    00888     if (NT_SUCCESS(status)) {
    00889         IopCompressRelationList(&relationsList);
    00890         *RelationsList = relationsList;
    00891
    00892         //
    00893         // At this point we have a list of all the relations, those that are
    00894         // direct descendants of the original device we are ejecting or
    00895         // removing have the DirectDescendant bit set.
    00896         //
    00897         // Relations which were merged from an existing eject have the tagged
    00898         // bit set.
    00899         //
    00900         // All of the relations and their parents are locked.
    00901         //
    00902         // There is a reference on each device object by virtue of it being in
    00903         // the list.  There is another one on each device object because it is
    00904         // locked and the lock count is >= 1.
    00905         //
    00906         // There is also a reference on each relation's parent and it's lock
    00907         // count is >= 1.
    00908         //
    00909     } else {
    00910         IopFreeRelationList(relationsList);
    00911     }
    00912
    00913     return status;
    00914 }

NTSTATUS IopMakeGloballyUniqueId | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN PWCHAR | UniqueId,
|  | OUT PWCHAR * | GloballyUniqueId
| ) |

Definition at line 1891 of file pnpirp.c.

References ASSERT, CmRegistryMachineSystemCurrentControlSetEnumName, DbgPrint, ExAcquireResourceShared, ExAllocatePool, ExFreePool(), ExReleaseResource, HASH_UNICODE_STRING, _DEVICE_NODE::InstancePath, IopOpenRegistryKeyEx(), KeEnterCriticalRegion, KeLeaveCriticalRegion, L, _DEVICE_NODE::Level, max, MAX_PARENT_PREFIX, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, _DEVICE_NODE::Parent, PpRegistryDeviceResource, RtlFreeUnicodeString(), RtlInitUnicodeString(), RtlUpcaseUnicodeString(), TITLE_INDEX_VALUE, and TRUE.

Referenced by IopProcessNewDeviceNode().

    01896 {
    01897     NTSTATUS status;
    01898     ULONG length;
    01899     PWSTR id, Prefix = NULL;
    01900     HANDLE enumKey;
    01901     HANDLE instanceKey;
    01902     UCHAR keyBuffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + sizeof(ULONG)];
    01903     PKEY_VALUE_PARTIAL_INFORMATION keyValue, stringValueBuffer = NULL;
    01904     UNICODE_STRING valueName;
    01905     ULONG uniqueIdValue, Hash, hashInstance;
    01906     PDEVICE_NODE parentNode;
    01907
    01908     PAGED_CODE();
    01909
    01910     //
    01911     // We need to build an instance id to uniquely identify this
    01912     // device.  We will accomplish this by producing a prefix that will be
    01913     // prepended to the non-unique device id supplied.
    01914     //
    01915
    01916     //
    01917     // To 'unique-ify' the child's instance ID, we will retrieve
    01918     // the unique "UniqueParentID" number that has been assigned
    01919     // to the parent and use it to construct a prefix.  This is
    01920     // the legacy mechanism supported here so that existing device
    01921     // settings are not lost on upgrade.
    01922     //
    01923
    01924     KeEnterCriticalRegion();
    01925     ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE);
    01926
    01927     parentNode = ((PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode)->Parent;
    01928
    01929     status = IopOpenRegistryKeyEx( &enumKey,
    01930                                    NULL,
    01931                                    &CmRegistryMachineSystemCurrentControlSetEnumName,
    01932                                    KEY_READ | KEY_WRITE
    01933                                    );
    01934
    01935     if (!NT_SUCCESS(status)) {
    01936         DbgPrint("IopQueryUniqueId:\tUnable to open HKLM\\SYSTEM\\CCS\\ENUM (status %08lx)\n",
    01937                  status
    01938                 );
    01939         goto clean0;
    01940     }
    01941
    01942     //
    01943     // Open the instance key for this devnode
    01944     //
    01945     status = IopOpenRegistryKeyEx( &instanceKey,
    01946                                    enumKey,
    01947                                    &parentNode->InstancePath,
    01948                                    KEY_READ | KEY_WRITE
    01949                                    );
    01950
    01951     if (!NT_SUCCESS(status)) {
    01952         DbgPrint("IopQueryUniqueId:\tUnable to open registry key for %wZ (status %08lx)\n",
    01953                  &parentNode->InstancePath,
    01954                  status
    01955                 );
    01956         goto clean1;
    01957     }
    01958
    01959     //
    01960     // Attempt to retrieve the "UniqueParentID" value from the device
    01961     // instance key.
    01962     //
    01963     keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)keyBuffer;
    01964     PiWstrToUnicodeString(&valueName, REGSTR_VALUE_UNIQUE_PARENT_ID);
    01965
    01966     status = ZwQueryValueKey(instanceKey,
    01967                              &valueName,
    01968                              KeyValuePartialInformation,
    01969                              keyValue,
    01970                              sizeof(keyBuffer),
    01971                              &length
    01972                              );
    01973
    01974     if (NT_SUCCESS(status)) {
    01975         ASSERT(keyValue->Type == REG_DWORD);
    01976         ASSERT(keyValue->DataLength == sizeof(ULONG));
    01977         if ((keyValue->Type != REG_DWORD) ||
    01978             (keyValue->DataLength != sizeof(ULONG))) {
    01979             status = STATUS_INVALID_PARAMETER;
    01980             goto clean2;
    01981         }
    01982
    01983         uniqueIdValue = *(PULONG)(keyValue->Data);
    01984
    01985         //
    01986         // OK, we have a unique parent ID number to prefix to the
    01987         // instance ID.
    01988         Prefix = (PWSTR)ExAllocatePool(PagedPool, 9 * sizeof(WCHAR));
    01989         if (!Prefix) {
    01990             status = STATUS_INSUFFICIENT_RESOURCES;
    01991             goto clean2;
    01992         }
    01993         swprintf(Prefix, L"%x", uniqueIdValue);
    01994     } else {
    01995
    01996         //
    01997         // This is the current mechanism for finding existing
    01998         // device instance prefixes and calculating new ones if
    01999         // required.
    02000         //
    02001
    02002         //
    02003         // Attempt to retrieve the "ParentIdPrefix" value from the device
    02004         // instance key.
    02005         //
    02006
    02007         PiWstrToUnicodeString(&valueName, REGSTR_VALUE_PARENT_ID_PREFIX);
    02008         length = (MAX_PARENT_PREFIX + 1) * sizeof(WCHAR) +
    02009             FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
    02010         stringValueBuffer = ExAllocatePool(PagedPool,
    02011                                            length);
    02012         if (stringValueBuffer) {
    02013             status = ZwQueryValueKey(instanceKey,
    02014                                      &valueName,
    02015                                      KeyValuePartialInformation,
    02016                                      stringValueBuffer,
    02017                                      length,
    02018                                      &length);
    02019         }
    02020         else {
    02021             status = STATUS_INSUFFICIENT_RESOURCES;
    02022             goto clean2;
    02023         }
    02024
    02025         if (NT_SUCCESS(status)) {
    02026
    02027             ASSERT(stringValueBuffer->Type == REG_SZ);
    02028             if (stringValueBuffer->Type != REG_SZ) {
    02029                 status = STATUS_INVALID_PARAMETER;
    02030                 goto clean2;
    02031             }
    02032
    02033             //
    02034             // Parent has already been assigned a "ParentIdPrefix".
    02035             //
    02036
    02037             Prefix = (PWSTR) ExAllocatePool(PagedPool,
    02038                                             stringValueBuffer->DataLength);
    02039             if (!Prefix)
    02040             {
    02041                 status = STATUS_INSUFFICIENT_RESOURCES;
    02042                 goto clean2;
    02043             }
    02044             wcscpy(Prefix, (PWSTR) stringValueBuffer->Data);
    02045         }
    02046         else
    02047         {
    02048             //
    02049             // Parent has not been assigned a "ParentIdPrefix".
    02050             // Compute the prefix:
    02051             //    * Compute Hash
    02052             //    * Look for value of the form:
    02053             //        NextParentId.<level>.<hash>:REG_DWORD: <NextInstance>
    02054             //      under CCS\Enum.  If not present, create it.
    02055             //    * Assign the new "ParentIdPrefix" which will be of
    02056             //      of the form:
    02057             //        <level>&<hash>&<instance>
    02058             //
    02059
    02060             // Allocate a buffer once for the NextParentId... value
    02061             // and for the prefix.
    02062             length = max(wcslen(REGSTR_VALUE_NEXT_PARENT_ID) + 2 + 8 + 8,
    02063                          MAX_PARENT_PREFIX) + 1;
    02064
    02065             // Device instances are case in-sensitive.  Upcase before
    02066             // performing hash to ensure that the hash is case-insensitve.
    02067             status = RtlUpcaseUnicodeString(&valueName,
    02068                                             &parentNode->InstancePath,
    02069                                             TRUE);
    02070             if (!NT_SUCCESS(status))
    02071             {
    02072                 goto clean2;
    02073             }
    02074             HASH_UNICODE_STRING(&valueName, &Hash);
    02075             RtlFreeUnicodeString(&valueName);
    02076
    02077             Prefix = (PWSTR) ExAllocatePool(PagedPool,
    02078                                             length * sizeof(WCHAR));
    02079             if (!Prefix) {
    02080                 status = STATUS_INSUFFICIENT_RESOURCES;
    02081                 goto clean2;
    02082             }
    02083
    02084             // Check for existence of "NextParentId...." value and update.
    02085             swprintf(Prefix, L"%s.%x.%x", REGSTR_VALUE_NEXT_PARENT_ID,
    02086                      Hash, parentNode->Level);
    02087             RtlInitUnicodeString(&valueName, Prefix);
    02088             keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)keyBuffer;
    02089             status = ZwQueryValueKey(enumKey,
    02090                                      &valueName,
    02091                                      KeyValuePartialInformation,
    02092                                      keyValue,
    02093                                      sizeof(keyBuffer),
    02094                                      &length
    02095                                      );
    02096             if (NT_SUCCESS(status) && (keyValue->Type == REG_DWORD) &&
    02097                 (keyValue->DataLength == sizeof(ULONG))) {
    02098                 hashInstance = *(PULONG)(keyValue->Data);
    02099             }
    02100             else {
    02101                 hashInstance = 0;
    02102             }
    02103
    02104             hashInstance++;
    02105
    02106             status = ZwSetValueKey(enumKey,
    02107                                    &valueName,
    02108                                    TITLE_INDEX_VALUE,
    02109                                    REG_DWORD,
    02110                                    &hashInstance,
    02111                                    sizeof(hashInstance)
    02112                                    );
    02113
    02114             if (!NT_SUCCESS(status)) {
    02115                 goto clean2;
    02116             }
    02117
    02118             hashInstance--;
    02119
    02120             // Create actual ParentIdPrefix string
    02121             PiWstrToUnicodeString(&valueName, REGSTR_VALUE_PARENT_ID_PREFIX);
    02122             length = swprintf(Prefix, L"%x&%x&%x", parentNode->Level,
    02123                      Hash, hashInstance) + 1;
    02124             status = ZwSetValueKey(instanceKey,
    02125                                    &valueName,
    02126                                    TITLE_INDEX_VALUE,
    02127                                    REG_SZ,
    02128                                    Prefix,
    02129                                    length * sizeof(WCHAR)
    02130                                    );
    02131             if (!NT_SUCCESS(status))
    02132             {
    02133                 goto clean2;
    02134             }
    02135         }
    02136     }
    02137
    02138     // Construct the instance id from the non-unique id (if any)
    02139     // provided by the child and the prefix we've constructed.
    02140     length = wcslen(Prefix) + (UniqueId ? wcslen(UniqueId) : 0) + 2;
    02141     id = (PWSTR)ExAllocatePool(PagedPool, length * sizeof(WCHAR));
    02142     if (!id) {
    02143         status = STATUS_INSUFFICIENT_RESOURCES;
    02144     } else if (UniqueId) {
    02145         swprintf(id, L"%s&%s", Prefix, UniqueId);
    02146     } else {
    02147         wcscpy(id, Prefix);
    02148     }
    02149
    02150 clean2:
    02151     ZwClose(instanceKey);
    02152
    02153 clean1:
    02154     ZwClose(enumKey);
    02155
    02156 clean0:
    02157     ExReleaseResource(&PpRegistryDeviceResource);
    02158     KeLeaveCriticalRegion();
    02159
    02160     if (stringValueBuffer) {
    02161         ExFreePool(stringValueBuffer);
    02162     }
    02163
    02164     if (Prefix) {
    02165         ExFreePool(Prefix);
    02166     }
    02167
    02168     *GloballyUniqueId = id;
    02169     return status;
    02170 }

NTSTATUS IopMarkDuplicateDevice | ( | IN PUNICODE_STRING | TargetKeyName,
|  | IN ULONG | TargetInstance,
|  | IN PUNICODE_STRING | SourceKeyName,
|  | IN ULONG | SourceInstance
| ) |

Definition at line 2467 of file pnpsubs.c.

References IopServiceInstanceToDeviceInstance(), NT_SUCCESS, NTSTATUS(), NULL, and TITLE_INDEX_VALUE.

    02476                    :
    02477
    02478     This routine marks the device instance specified by TargetKeyName and TargetInstance
    02479     as DuplicateOf the device specified by SourceKeyName and SourceInstance.
    02480
    02481 Arguments:
    02482
    02483     TargetKeyName - supplies a pointer to the name of service key which will be marked
    02484         as duplicate.
    02485
    02486     TargetInstance - the instance number of the target device.
    02487
    02488     SourceKeyName - supplies a pointer to the name of service key.
    02489
    02490     SourceInstance - the instance number of the source device.
    02491
    02492
    02493 Returns:
    02494
    02495     NTSTATUS code.
    02496
    02497 --*/
    02498
    02499 {
    02500     HANDLE handle;
    02501     NTSTATUS status;
    02502     UNICODE_STRING sourceDeviceString, unicodeValueName;
    02503
    02504     //
    02505     // Open the handle of the target device instance.
    02506     //
    02507
    02508     status = IopServiceInstanceToDeviceInstance(
    02509                        NULL,
    02510                        TargetKeyName,
    02511                        TargetInstance,
    02512                        NULL,
    02513                        &handle,
    02514                        0
    02515                        );
    02516     if (!NT_SUCCESS(status)) {
    02517         return status;
    02518     }
    02519
    02520     //
    02521     // Get the name of the source device instance
    02522     //
    02523
    02524     status = IopServiceInstanceToDeviceInstance(
    02525                        NULL,
    02526                        SourceKeyName,
    02527                        SourceInstance,
    02528                        &sourceDeviceString,
    02529                        NULL,
    02530                        0
    02531                        );
    02532     if (!NT_SUCCESS(status)) {
    02533         return status;
    02534     }
    02535
    02536     //
    02537     // Write the name of the source device to the DuplicateOf value entry of
    02538     // target device key.
    02539     //
    02540
    02541     PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_DUPLICATEOF);
    02542     status = ZwSetValueKey(
    02543                 handle,
    02544                 &unicodeValueName,
    02545                 TITLE_INDEX_VALUE,
    02546                 REG_SZ,
    02547                 &sourceDeviceString,
    02548                 sourceDeviceString.Length + sizeof(WCHAR)
    02549                 );
    02550     return status;
    02551 }

NTSTATUS IopMemInitialize | ( | VOID |  | ) |

Definition at line 396 of file pnpmemio.c.

References _ARBITER_INSTANCE::Allocation, ArbInitializeArbiterInstance(), _ARBITER_INSTANCE::FindSuitableRange, IopGenericPackResource(), IopGenericScoreRequirement(), IopGenericTranslateOrdering(), IopGenericUnpackRequirement(), IopGenericUnpackResource(), IopMemFindSuitableRange(), IopRootMemArbiter, L, NT_SUCCESS, NTSTATUS(), NULL, _ARBITER_INSTANCE::PackResource, PAGE_SIZE, PAGED_CODE, RtlAddRange(), _ARBITER_INSTANCE::ScoreRequirement, _ARBITER_INSTANCE::UnpackRequirement, and _ARBITER_INSTANCE::UnpackResource.

    00402                    :
    00403
    00404     This routine initializes the arbiter
    00405
    00406 Parameters:
    00407
    00408     None
    00409
    00410 Return Value:
    00411
    00412     None
    00413
    00414 --*/
    00415
    00416 {
    00417     NTSTATUS status;
    00418
    00419     PAGED_CODE();
    00420
    00421     IopRootMemArbiter.UnpackRequirement = IopGenericUnpackRequirement;
    00422     IopRootMemArbiter.PackResource      = IopGenericPackResource;
    00423     IopRootMemArbiter.UnpackResource    = IopGenericUnpackResource;
    00424     IopRootMemArbiter.ScoreRequirement  = IopGenericScoreRequirement;
    00425
    00426     IopRootMemArbiter.FindSuitableRange    = IopMemFindSuitableRange;
    00427
    00428     status = ArbInitializeArbiterInstance(&IopRootMemArbiter,
    00429                                           NULL,     // Indicates ROOT arbiter
    00430                                           CmResourceTypeMemory,
    00431                                           L"RootMemory",
    00432                                           L"Root",
    00433                                           IopGenericTranslateOrdering
    00434                                           );
    00435
    00436     if (!NT_SUCCESS(status)) {
    00437         return status;
    00438     }
    00439
    00440     //
    00441     // Allocate the first page of physical memory as the firmware uses it and
    00442     // doesn't report it as so Mm doesn't reuse it.
    00443     //
    00444
    00445     status = RtlAddRange(IopRootMemArbiter.Allocation,
    00446                          0,
    00447                          PAGE_SIZE,
    00448                          0, // RangeAttributes
    00449                          0, // Flags
    00450                          NULL,
    00451                          NULL
    00452                          );
    00453     return status;
    00454
    00455 }

NTSTATUS IopMergeCmResourceLists | ( | IN PCM_RESOURCE_LIST | List1,
|  | IN PCM_RESOURCE_LIST | List2,
|  | IN OUT PCM_RESOURCE_LIST * | MergedList
| ) |

Definition at line 5198 of file pnpsubs.c.

References ExAllocatePool, IopDetermineResourceListSize(), List, NTSTATUS(), NULL, PAGED_CODE, and PagedPool.

    05206                    :
    05207
    05208     This routines merges two IoLists into one.
    05209
    05210
    05211 Arguments:
    05212
    05213     IoList1 - supplies the pointer to the first CmResourceList
    05214
    05215     IoList2 - supplies the pointer to the second CmResourceList
    05216
    05217     MergedList - Supplies a variable to receive the merged resource
    05218              list.
    05219
    05220 Return Value:
    05221
    05222     A NTSTATUS code to indicate the result of the function.
    05223
    05224 --*/
    05225 {
    05226     NTSTATUS status = STATUS_SUCCESS;
    05227     PCM_RESOURCE_LIST cmList, newList;
    05228     ULONG size, size1, size2;
    05229     PUCHAR p;
    05230
    05231     PAGED_CODE();
    05232
    05233     *MergedList = NULL;
    05234
    05235     //
    05236     // First handle the easy cases that both IO Lists are empty or any one of
    05237     // them is empty.
    05238     //
    05239
    05240     if ((List1 == NULL || List1->Count == 0) &&
    05241         (List2 == NULL || List2->Count == 0)) {
    05242         return status;
    05243     }
    05244
    05245     cmList = NULL;
    05246     if (List1 == NULL || List1->Count == 0) {
    05247         cmList = List2;
    05248     } else if (List2 == NULL || List2->Count == 0) {
    05249         cmList = List1;
    05250     }
    05251     if (cmList) {
    05252         size =  IopDetermineResourceListSize(cmList);
    05253         newList = (PCM_RESOURCE_LIST) ExAllocatePool(PagedPool, size);
    05254         if (newList == NULL) {
    05255             return STATUS_INSUFFICIENT_RESOURCES;
    05256         }
    05257         RtlMoveMemory(newList, cmList, size);
    05258         *MergedList = newList;
    05259         return status;
    05260     }
    05261
    05262     //
    05263     // Do real work...
    05264     //
    05265
    05266     size1 =  IopDetermineResourceListSize(List1);
    05267     size2 =  IopDetermineResourceListSize(List2);
    05268     size = size1 + size2;
    05269     newList = (PCM_RESOURCE_LIST) ExAllocatePool(
    05270                           PagedPool,
    05271                           size
    05272                           );
    05273     if (newList == NULL) {
    05274         return STATUS_INSUFFICIENT_RESOURCES;
    05275     }
    05276     p = (PUCHAR)newList;
    05277     RtlMoveMemory(p, List1, size1);
    05278     p += size1;
    05279     RtlMoveMemory(p,
    05280                   &List2->List[0],
    05281                   size2 - FIELD_OFFSET(CM_RESOURCE_LIST, List)
    05282                   );
    05283     newList->Count = List1->Count + List2->Count;
    05284     *MergedList = newList;
    05285     return status;
    05286
    05287 }

NTSTATUS IopMergeFilteredResourceRequirementsList | ( | IN PIO_RESOURCE_REQUIREMENTS_LIST | IoList1,
|  | IN PIO_RESOURCE_REQUIREMENTS_LIST | IoList2,
|  | IN OUT PIO_RESOURCE_REQUIREMENTS_LIST * | MergedList
| ) |

Definition at line 5109 of file pnpsubs.c.

References ExAllocatePool, List, NTSTATUS(), NULL, PAGED_CODE, and PagedPool.

Referenced by IopQueryDeviceResources().

    05117                    :
    05118
    05119     This routines merges two IoLists into one.
    05120
    05121
    05122 Arguments:
    05123
    05124     IoList1 - supplies the pointer to the first IoResourceRequirementsList
    05125
    05126     IoList2 - supplies the pointer to the second IoResourceRequirementsList
    05127
    05128     MergedList - Supplies a variable to receive the merged resource
    05129              requirements list.
    05130
    05131 Return Value:
    05132
    05133     A NTSTATUS code to indicate the result of the function.
    05134
    05135 --*/
    05136 {
    05137     NTSTATUS status = STATUS_SUCCESS;
    05138     PIO_RESOURCE_REQUIREMENTS_LIST ioList, newList;
    05139     ULONG size;
    05140     PUCHAR p;
    05141
    05142     PAGED_CODE();
    05143
    05144     *MergedList = NULL;
    05145
    05146     //
    05147     // First handle the easy cases that both IO Lists are empty or any one of
    05148     // them is empty.
    05149     //
    05150
    05151     if ((IoList1 == NULL || IoList1->AlternativeLists == 0) &&
    05152         (IoList2 == NULL || IoList2->AlternativeLists == 0)) {
    05153         return status;
    05154     }
    05155     ioList = NULL;
    05156     if (IoList1 == NULL || IoList1->AlternativeLists == 0) {
    05157         ioList = IoList2;
    05158     } else if (IoList2 == NULL || IoList2->AlternativeLists == 0) {
    05159         ioList = IoList1;
    05160     }
    05161     if (ioList) {
    05162         newList = (PIO_RESOURCE_REQUIREMENTS_LIST) ExAllocatePool(PagedPool, ioList->ListSize);
    05163         if (newList == NULL) {
    05164             return STATUS_INSUFFICIENT_RESOURCES;
    05165         }
    05166         RtlMoveMemory(newList, ioList, ioList->ListSize);
    05167         *MergedList = newList;
    05168         return status;
    05169     }
    05170
    05171     //
    05172     // Do real work...
    05173     //
    05174
    05175     size = IoList1->ListSize + IoList2->ListSize - FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List);
    05176     newList = (PIO_RESOURCE_REQUIREMENTS_LIST) ExAllocatePool(
    05177                           PagedPool,
    05178                           size
    05179                           );
    05180     if (newList == NULL) {
    05181         return STATUS_INSUFFICIENT_RESOURCES;
    05182     }
    05183     p = (PUCHAR)newList;
    05184     RtlMoveMemory(p, IoList1, IoList1->ListSize);
    05185     p += IoList1->ListSize;
    05186     RtlMoveMemory(p,
    05187                   &IoList2->List[0],
    05188                   size - IoList1->ListSize
    05189                   );
    05190     newList->ListSize = size;
    05191     newList->AlternativeLists += IoList2->AlternativeLists;
    05192     *MergedList = newList;
    05193     return status;
    05194
    05195 }

VOID IopNewDevice | ( | IN PDEVICE_OBJECT | DeviceObject | ) |

Definition at line 1596 of file pnpdd.c.

References _START_CONTEXT::AddContext, DNF_ADDED, DNF_LEGACY_DRIVER, DNF_NEED_QUERY_IDS, DNF_NO_RESOURCE_REQUIRED, DNF_RESOURCE_ASSIGNED, DNF_RESOURCE_REPORTED, _ADD_CONTEXT::DriverStartType, exit, FALSE, _DEVICE_NODE::Flags, _ADD_CONTEXT::GroupsToStart, _ADD_CONTEXT::GroupToStartNext, IopAssignResourcesToDevices(), IopCallDriverAddDevice(), IopProcessAssignResources(), IopProcessStartDevices(), IopSetDevNodeProblem, IopStartAndEnumerateDevice(), _START_CONTEXT::LoadDriver, _START_CONTEXT::NewDevice, NO_MORE_GROUP, NT_SUCCESS, NTSTATUS(), PAGED_CODE, _IOP_RESOURCE_REQUEST::PhysicalDevice, _IOP_RESOURCE_REQUEST::Priority, _IOP_RESOURCE_REQUEST::ResourceAssignment, _DEVICE_NODE::ResourceList, _DEVICE_NODE::ResourceListTranslated, _IOP_RESOURCE_REQUEST::Status, _IOP_RESOURCE_REQUEST::TranslatedResourceAssignment, and TRUE.

Referenced by IopDeviceActionWorker().

    01602                    :
    01603
    01604     This routine handles user-mode initiated starts of devices.
    01605
    01606 Parameters:
    01607
    01608     DeviceObject - PDO.
    01609
    01610 ReturnValue:
    01611
    01612     None.
    01613
    01614 --*/
    01615
    01616 {
    01617     PDEVICE_NODE deviceNode, parent;
    01618     IOP_RESOURCE_REQUEST requestTable;
    01619     NTSTATUS status;
    01620     BOOLEAN newDevice;
    01621     START_CONTEXT startContext;
    01622     ADD_CONTEXT addContext;
    01623
    01624     PAGED_CODE();
    01625
    01626     deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
    01627
    01628     //
    01629     // Make sure the device is not started
    01630     //
    01631
    01632     if (deviceNode->Flags & DNF_ADDED) {
    01633         goto exit;
    01634     }
    01635
    01636     //
    01637     // Need enumeration on IoReportDetectedDevice
    01638     //
    01639
    01640     if (!(deviceNode->Flags & DNF_NEED_QUERY_IDS)) {
    01641         //
    01642         // Invoke the driver's AddDevice() entry and enumerate the device.
    01643         //
    01644
    01645         addContext.GroupsToStart = 0xffff;
    01646         addContext.GroupToStartNext = 0xffff;
    01647         addContext.DriverStartType = SERVICE_DEMAND_START;
    01648
    01649         status = IopCallDriverAddDevice(deviceNode, TRUE, &addContext);
    01650         if (!NT_SUCCESS(status) || (deviceNode->Flags & DNF_LEGACY_DRIVER)) {
    01651             goto exit;
    01652         } else if (deviceNode->Flags & DNF_NEED_QUERY_IDS) {
    01653
    01654             //
    01655             // The driver may perform IoReportDetectedDevice
    01656             //
    01657
    01658             goto enumerate;
    01659         }
    01660
    01661         //
    01662         // Assign resource to the device
    01663         //
    01664
    01665         requestTable.PhysicalDevice = DeviceObject;
    01666         requestTable.Priority = 0;
    01667
    01668         IopAssignResourcesToDevices(1, &requestTable, TRUE);
    01669
    01670         if (NT_SUCCESS(requestTable.Status)) {
    01671             if (requestTable.ResourceAssignment) {
    01672                 if (!(deviceNode->Flags & DNF_RESOURCE_REPORTED)) {
    01673                     deviceNode->Flags |= DNF_RESOURCE_ASSIGNED;
    01674                 }
    01675                 // deviceNode->Flags &= ~DNF_INSUFFICIENT_RESOURCES;
    01676                 deviceNode->ResourceList = requestTable.ResourceAssignment;
    01677                 deviceNode->ResourceListTranslated = requestTable.TranslatedResourceAssignment;
    01678             } else {
    01679                 deviceNode->Flags |= DNF_NO_RESOURCE_REQUIRED;
    01680             }
    01681         } else if (requestTable.Status == STATUS_DEVICE_CONFIGURATION_ERROR) {
    01682             IopSetDevNodeProblem(deviceNode, CM_PROB_NO_SOFTCONFIG);
    01683             goto exit;
    01684         } else if (requestTable.Status == STATUS_PNP_BAD_MPS_TABLE) {
    01685             IopSetDevNodeProblem(deviceNode, CM_PROB_BIOS_TABLE);
    01686             goto exit;
    01687         } else if (requestTable.Status == STATUS_PNP_TRANSLATION_FAILED) {
    01688             IopSetDevNodeProblem(deviceNode, CM_PROB_TRANSLATION_FAILED);
    01689             goto exit;
    01690         } else if (requestTable.Status == STATUS_PNP_IRQ_TRANSLATION_FAILED) {
    01691             IopSetDevNodeProblem(deviceNode, CM_PROB_IRQ_TRANSLATION_FAILED);
    01692             goto exit;
    01693         } else {
    01694             IopSetDevNodeProblem(deviceNode, CM_PROB_NORMAL_CONFLICT);
    01695             goto exit;
    01696         }
    01697     }
    01698
    01699 enumerate:
    01700
    01701     //
    01702     // Start and enumerate the device
    01703     //
    01704
    01705     startContext.LoadDriver = TRUE;
    01706     startContext.NewDevice = FALSE;
    01707     startContext.AddContext.GroupsToStart = NO_MORE_GROUP;
    01708     startContext.AddContext.GroupToStartNext = NO_MORE_GROUP;
    01709     startContext.AddContext.DriverStartType = SERVICE_DEMAND_START;
    01710
    01711     IopStartAndEnumerateDevice(deviceNode, &startContext);
    01712     newDevice = startContext.NewDevice;
    01713     while (newDevice) {
    01714
    01715         startContext.NewDevice = FALSE;
    01716
    01717         //
    01718         // Process the whole device tree to assign resources to those devices who
    01719         // have been successfully added to their drivers.
    01720         //
    01721
    01722         newDevice = IopProcessAssignResources(deviceNode, FALSE, TRUE);
    01723
    01724         //
    01725         // Process the whole device tree to start those devices who have been allocated
    01726         // resources and waiting to be started.
    01727         // Note, the IopProcessStartDevices routine may enumerate new devices.
    01728         //
    01729
    01730         IopProcessStartDevices(deviceNode, &startContext);
    01731         newDevice |= startContext.NewDevice;
    01732
    01733     }
    01734
    01735 exit:
    01736     ;
    01737 }

NTSTATUS IopNotifyDeviceClassChange | ( | LPGUID | EventGuid,
|  | LPGUID | ClassGuid,
|  | PUNICODE_STRING | SymbolicLinkName
| ) |

Definition at line 7330 of file pnpioapi.c.

References _NOTIFY_ENTRY_HEADER::Callback, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Callout, _DEVICE_CLASS_NOTIFY_ENTRY::ClassGuid, _NOTIFY_ENTRY_HEADER::Context, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Context, DbgPrint, _DRIVER_OBJECT::DriverName, _NOTIFY_ENTRY_HEADER::DriverObject, _DEVICE_INTERFACE_CHANGE_NOTIFICATION::Event, _DEVICE_INTERFACE_CHANGE_NOTIFICATION::InterfaceClassGuid, IopAcquireNotifyLock, IopCompareGuid, IopDereferenceNotify(), IopDeviceClassNotifyList, IopDeviceClassNotifyLock, IopHashGuid, IopPnPHydraCallback(), IopReferenceNotify(), IopReleaseNotifyLock, KeGetCurrentThread, MmDispatchWin32Callout(), _NOTIFICATION_CALLBACK_PARAM_BLOCK::NotificationStructure, NTSTATUS(), PAGED_CODE, PDEVICE_CLASS_NOTIFY_ENTRY, PKWIN32_CALLOUT, PNP_NOTIFICATION_VERSION, _DEVICE_INTERFACE_CHANGE_NOTIFICATION::Size, _DEVICE_INTERFACE_CHANGE_NOTIFICATION::SymbolicLinkName, _DEVICE_CLASS_NOTIFY_ENTRY::Unregistered, and _DEVICE_INTERFACE_CHANGE_NOTIFICATION::Version.

    07338                    :
    07339
    07340     This routine is used to notify all registered drivers of a changes to a
    07341     particular class of device. It does not return until all interested parties have
    07342     been notified.
    07343
    07344 Parameters:
    07345
    07346     EventTypeGuid - The event that has occured
    07347
    07348     ClassGuid - The device class this change has occured in
    07349
    07350     SymbolicLinkName - The kernel mode symbolic link name of the interface device
    07351         that changed
    07352
    07353 Return Value:
    07354
    07355     Status code that indicates whether or not the function was successful.
    07356
    07357 Note:
    07358
    07359     The contents of the notification structure *including* all pointers is only
    07360     valid during the callback routine to which it was passed.  If the data is
    07361     required after the duration of the callback then it must be physically copied
    07362     by the callback routine.
    07363
    07364 --*/
    07365
    07366 {
    07367     NTSTATUS status = STATUS_SUCCESS;
    07368     PLIST_ENTRY link;
    07369     PDEVICE_CLASS_NOTIFY_ENTRY entry;
    07370     DEVICE_INTERFACE_CHANGE_NOTIFICATION notification;
    07371     ULONG hash;
    07372 #if DBG
    07373     KIRQL originalIrql;
    07374     ULONG originalApcDisable;
    07375 #endif
    07376
    07377     PAGED_CODE();
    07378
    07379     //
    07380     // Fill in the notification
    07381     //
    07382
    07383     notification.Version = PNP_NOTIFICATION_VERSION;
    07384     notification.Size = sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION);
    07385     notification.Event = *EventGuid;
    07386     notification.InterfaceClassGuid = *ClassGuid;
    07387     notification.SymbolicLinkName = SymbolicLinkName;
    07388
    07389     //
    07390     // Lock the notify list
    07391     //
    07392
    07393     IopAcquireNotifyLock(&IopDeviceClassNotifyLock);
    07394
    07395     //
    07396     // Get the first entry
    07397     //
    07398
    07399     hash = IopHashGuid(ClassGuid);
    07400     link = IopDeviceClassNotifyList[hash].Flink;
    07401
    07402     //
    07403     // Iterate through the list
    07404     //
    07405
    07406     while (link != &IopDeviceClassNotifyList[hash]) {
    07407
    07408         entry = (PDEVICE_CLASS_NOTIFY_ENTRY) link;
    07409
    07410         //
    07411         // Only callback on registered nodes of the correct device class
    07412         //
    07413
    07414         if ( !entry->Unregistered && IopCompareGuid(&(entry->ClassGuid), ClassGuid) ) {
    07415
    07416             NOTIFICATION_CALLBACK_PARAM_BLOCK callparams;
    07417             ULONG Console=0;
    07418             //
    07419             // Reference the entry so that no one deletes during the callback
    07420             // and then release the lock
    07421             //
    07422
    07423             IopReferenceNotify( (PNOTIFY_ENTRY_HEADER) entry );
    07424             IopReleaseNotifyLock(&IopDeviceClassNotifyLock);
    07425
    07426 #if DBG
    07427             originalIrql = KeGetCurrentIrql();
    07428             originalApcDisable = KeGetCurrentThread()->KernelApcDisable;
    07429 #endif
    07430
    07431             //
    07432             // Callback the entity that registered and ignore the return value as
    07433             // we arn't interested in it
    07434             //
    07435
    07436             callparams.Callout=(entry->Callback);
    07437             callparams.NotificationStructure=&notification;
    07438             callparams.Context=entry->Context;
    07439
    07440
    07441             //
    07442             // Dispatch this function via the memory manager.
    07443             // Win32K is a driver that can have multiple copies. If Hydra
    07444             // is running, the Mem. manager will check if the callback exists
    07445             // in "per session" space. If that is the case, it will attach to the
    07446             // console (hence the 3rd param of PULONG containing 0) session and deliver
    07447             // it. If either Hydra is not running, or the callback is outside session space
    07448             // then the callback is called directly.
    07449             //
    07450             MmDispatchWin32Callout ((PKWIN32_CALLOUT)callparams.Callout,&IopPnPHydraCallback,&callparams,&Console);
    07451
    07452
    07453
    07454 #if DBG
    07455             if (originalIrql != KeGetCurrentIrql()) {
    07456                 DbgPrint("IopNotifyDeviceClassChange: Driver %Z, notification handler @ 0x%p returned at raised IRQL = %d, original = %d\n",
    07457                          &entry->DriverObject->DriverName, entry->Callback, KeGetCurrentIrql(), originalIrql);
    07458                 DbgBreakPoint();
    07459             }
    07460             if (originalApcDisable != KeGetCurrentThread()->KernelApcDisable) {
    07461                 DbgPrint("IopNotifyDeviceClassChange: Driver %Z, notification handler @ 0x%p returned with different KernelApcDisable = %d, original = %d\n",
    07462                          &entry->DriverObject->DriverName, entry->Callback, KeGetCurrentThread()->KernelApcDisable, originalApcDisable);
    07463                 DbgBreakPoint();
    07464             }
    07465 #endif
    07466             //
    07467             // Reacquire the lock and dereference
    07468             //
    07469
    07470             IopAcquireNotifyLock(&IopDeviceClassNotifyLock);
    07471             link = link->Flink;
    07472             IopDereferenceNotify( (PNOTIFY_ENTRY_HEADER) entry );
    07473
    07474         } else {
    07475
    07476             //
    07477             // Advance down the list
    07478             //
    07479
    07480             link = link->Flink;
    07481         }
    07482     }
    07483
    07484     //
    07485     // Release the lock
    07486     //
    07487
    07488     IopReleaseNotifyLock(&IopDeviceClassNotifyLock);
    07489
    07490     return status;
    07491 }

NTSTATUS IopNotifyHwProfileChange | ( | IN LPGUID | EventGuid,
|  | OUT PPNP_VETO_TYPE VetoType | OPTIONAL,
|  | OUT PUNICODE_STRING VetoName | OPTIONAL
| ) |

Definition at line 6858 of file pnpioapi.c.

References _NOTIFY_ENTRY_HEADER::Callback, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Callout, _NOTIFY_ENTRY_HEADER::Context, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Context, DbgPrint, _DRIVER_OBJECT::DriverName, _NOTIFY_ENTRY_HEADER::DriverObject, _HWPROFILE_CHANGE_NOTIFICATION::Event, IopAcquireNotifyLock, IopCompareGuid, IopDereferenceNotify(), IopHwProfileNotifyLock, IopPnPHydraCallback(), IopProfileNotifyList, IopReferenceNotify(), IopReleaseNotifyLock, KeGetCurrentThread, MmDispatchWin32Callout(), _NOTIFICATION_CALLBACK_PARAM_BLOCK::NotificationStructure, NT_SUCCESS, NTSTATUS(), PAGED_CODE, PHWPROFILE_NOTIFY_ENTRY, PKWIN32_CALLOUT, PNP_NOTIFICATION_VERSION, RtlCopyUnicodeString(), _HWPROFILE_CHANGE_NOTIFICATION::Size, _NOTIFY_ENTRY_HEADER::Unregistered, _HWPROFILE_NOTIFY_ENTRY::Unregistered, and _HWPROFILE_CHANGE_NOTIFICATION::Version.

Referenced by IopRequestHwProfileChangeNotification().

    06865                    :
    06866
    06867     This routine is used to deliver the HWProfileNotifications. It is
    06868     called from the worker thread only
    06869     It does not return until all interested parties have been notified.
    06870
    06871 Parameters:
    06872
    06873     EventTypeGuid - The event that has occured
    06874
    06875 Return Value:
    06876
    06877     Status code that indicates whether or not the function was successful.
    06878
    06879 Note:
    06880
    06881     The contents of the notification structure *including* all pointers is only
    06882     valid during the callback routine to which it was passed.  If the data is
    06883     required after the duration of the callback then it must be physically copied
    06884     by the callback routine.
    06885
    06886 --*/
    06887 {
    06888     NTSTATUS status=STATUS_SUCCESS;
    06889     PHWPROFILE_NOTIFY_ENTRY  pNotifyList;
    06890     PLIST_ENTRY link;
    06891 #if DBG
    06892     ULONG originalApcDisable;
    06893 #endif
    06894
    06895
    06896     PAGED_CODE();
    06897
    06898     //Lock the Profile Notification List
    06899     IopAcquireNotifyLock (&IopHwProfileNotifyLock);
    06900
    06901     //
    06902     //  Grab the list head (inside the lock)
    06903     //
    06904     link = IopProfileNotifyList.Flink;
    06905     pNotifyList=(PHWPROFILE_NOTIFY_ENTRY)link;
    06906
    06907     //
    06908     //circular list
    06909     //
    06910     while (link != (PLIST_ENTRY)&IopProfileNotifyList) {
    06911         if (!pNotifyList->Unregistered) {
    06912
    06913             HWPROFILE_CHANGE_NOTIFICATION notification;
    06914
    06915             NOTIFICATION_CALLBACK_PARAM_BLOCK callparams;
    06916             ULONG Console=0;
    06917
    06918             //
    06919             // Reference the entry so that no one deletes during the callback
    06920             // and then release the lock
    06921             //
    06922             IopReferenceNotify((PNOTIFY_ENTRY_HEADER)pNotifyList);
    06923             IopReleaseNotifyLock(&IopHwProfileNotifyLock);
    06924
    06925             //
    06926             // Fill in the notification
    06927             //
    06928
    06929             notification.Version = PNP_NOTIFICATION_VERSION;
    06930             notification.Size = sizeof(HWPROFILE_CHANGE_NOTIFICATION);
    06931             notification.Event = *EventGuid;
    06932
    06933 #if DBG
    06934             originalApcDisable = KeGetCurrentThread()->KernelApcDisable;
    06935 #endif
    06936             //
    06937             // Reference the notify and call back
    06938             //
    06939             callparams.Callout=(pNotifyList->Callback);
    06940             callparams.NotificationStructure=&notification;
    06941             callparams.Context=pNotifyList->Context;
    06942
    06943
    06944             //
    06945             // Dispatch this function via the memory manager.
    06946             // Win32K is a driver that can have multiple copies. If Hydra
    06947             // is running, the Mem. manager will check if the callback exists
    06948             // in "per session" space. If that is the case, it will attach to the
    06949             // console (hence the 3rd param of PULONG containing 0) session and deliver
    06950             // it. If either Hydra is not running, or the callback is outside session space
    06951             // then the callback is called directly.
    06952             //
    06953             status = MmDispatchWin32Callout ((PKWIN32_CALLOUT)callparams.Callout,&IopPnPHydraCallback,&callparams,&Console);
    06954 #if DBG
    06955             if (originalApcDisable != KeGetCurrentThread()->KernelApcDisable) {
    06956                 DbgPrint("IopNotifyHwProfileChange: Driver %Z, notification handler @ 0x%p returned with different KernelApcDisable = %d, original = %d\n",
    06957                          &pNotifyList->DriverObject->DriverName, pNotifyList->Callback, KeGetCurrentThread()->KernelApcDisable, originalApcDisable);
    06958                 DbgBreakPoint();
    06959             }
    06960 #endif
    06961
    06962             //
    06963             // If the caller returned anything other than success and it was a
    06964             // query hardware profile change, we veto the query and send cancels
    06965             // to all callers that already got the query.
    06966             //
    06967
    06968             if (!NT_SUCCESS(status) &&
    06969                 IopCompareGuid(EventGuid, (LPGUID)&GUID_HWPROFILE_QUERY_CHANGE)) {
    06970
    06971                 if (VetoType) {
    06972                     *VetoType = PNP_VetoDriver;
    06973                 }
    06974                 if (VetoName) {
    06975                     VetoName->Length = 0;
    06976                     RtlCopyUnicodeString(VetoName, &pNotifyList->DriverObject->DriverName);
    06977                 }
    06978
    06979                 notification.Event = GUID_HWPROFILE_CHANGE_CANCELLED;
    06980                 notification.Size = sizeof(GUID_HWPROFILE_CHANGE_CANCELLED);
    06981
    06982                 //
    06983                 // Dereference the entry which vetoed the query change.
    06984                 //
    06985                 IopAcquireNotifyLock(&IopHwProfileNotifyLock);
    06986                 IopDereferenceNotify((PNOTIFY_ENTRY_HEADER)pNotifyList);
    06987
    06988                 do {
    06989                     pNotifyList = (PHWPROFILE_NOTIFY_ENTRY)link;
    06990                     if (!pNotifyList->Unregistered) {
    06991                         IopReferenceNotify((PNOTIFY_ENTRY_HEADER)pNotifyList);
    06992                         IopReleaseNotifyLock(&IopHwProfileNotifyLock);
    06993
    06994 #if DBG
    06995                         originalApcDisable = KeGetCurrentThread()->KernelApcDisable;
    06996 #endif
    06997                         callparams.Callout=(pNotifyList->Callback);
    06998                         callparams.NotificationStructure=&notification;
    06999                         callparams.Context=pNotifyList->Context;
    07000
    07001                         MmDispatchWin32Callout ((PKWIN32_CALLOUT)callparams.Callout,&IopPnPHydraCallback,&callparams,&Console);
    07002 #if DBG
    07003                         if (originalApcDisable != KeGetCurrentThread()->KernelApcDisable) {
    07004                             DbgPrint("IopNotifyHwProfileChange: Driver %Z, notification handler @ 0x%p returned with different KernelApcDisable = %d, original = %d\n",
    07005                                      &pNotifyList->DriverObject->DriverName, pNotifyList->Callback, KeGetCurrentThread()->KernelApcDisable, originalApcDisable);
    07006                             DbgBreakPoint();
    07007                         }
    07008 #endif
    07009
    07010                         IopAcquireNotifyLock(&IopHwProfileNotifyLock);
    07011                         link = link->Blink;
    07012                         IopDereferenceNotify((PNOTIFY_ENTRY_HEADER)pNotifyList);
    07013
    07014                     } else {
    07015                         link = link->Blink;
    07016                     }
    07017                 } while (link != (PLIST_ENTRY)&IopProfileNotifyList);
    07018
    07019                 goto Clean0;
    07020             }
    07021
    07022             //
    07023             // Reacquire the lock, walk forward, and dereference
    07024             //
    07025             IopAcquireNotifyLock (&IopHwProfileNotifyLock);
    07026             link = link->Flink;
    07027             IopDereferenceNotify((PNOTIFY_ENTRY_HEADER)pNotifyList);
    07028             pNotifyList=(PHWPROFILE_NOTIFY_ENTRY)link;
    07029
    07030         } else {
    07031             //
    07032             //Walk forward if we hit an unregistered node
    07033             //
    07034             if (pNotifyList) {
    07035                 //
    07036                 //walk forward
    07037                 //
    07038                 link = link->Flink;
    07039                 pNotifyList=(PHWPROFILE_NOTIFY_ENTRY)link;
    07040             }
    07041         }
    07042     }
    07043
    07044  Clean0:
    07045
    07046     //UnLock the Profile Notification List
    07047     IopReleaseNotifyLock (&IopHwProfileNotifyLock);
    07048
    07049     return status;
    07050 }

NTSTATUS IopNotifySetupDeviceArrival | ( | PDEVICE_OBJECT | PhysicalDeviceObject,
|  | HANDLE | EnumEntryKey,
|  | BOOLEAN | InstallDriver
| ) |

Definition at line 8162 of file pnpioapi.c.

References _SETUP_NOTIFY_DATA::Callback, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Callout, _SETUP_NOTIFY_DATA::Context, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Context, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, _SETUP_DEVICE_ARRIVAL_NOTIFICATION::EnumEntryKey, _SETUP_DEVICE_ARRIVAL_NOTIFICATION::EnumPath, _SETUP_DEVICE_ARRIVAL_NOTIFICATION::Event, _SETUP_DEVICE_ARRIVAL_NOTIFICATION::InstallDriver, _DEVICE_NODE::InstancePath, IopDeviceObjectToDeviceInstance(), IopPnPHydraCallback(), IopSetupNotifyData, MmDispatchWin32Callout(), _NOTIFICATION_CALLBACK_PARAM_BLOCK::NotificationStructure, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, _SETUP_DEVICE_ARRIVAL_NOTIFICATION::PhysicalDeviceObject, PKWIN32_CALLOUT, PNP_NOTIFICATION_VERSION, SETUP_DEVICE_ARRIVAL_NOTIFICATION, _SETUP_DEVICE_ARRIVAL_NOTIFICATION::Size, and _SETUP_DEVICE_ARRIVAL_NOTIFICATION::Version.

Referenced by IopInitializeDeviceInstanceKey(), IopNotifySetupDevices(), IopProcessNewDeviceNode(), and IoReportDetectedDevice().

    08170                    :
    08171
    08172     This routine is used to notify setup (during text-mode setup) of arrivals
    08173     of a particular device. It does not return until all interested parties have
    08174     been notified.
    08175
    08176 Parameters:
    08177
    08178     PhysicalDeviceObject - Supplies a pointer to the PDO of the newly arrived
    08179         device.
    08180
    08181     EnumEntryKey - Supplies a handle to the key associated with the devide under
    08182         the Enum\ branch of the registry.  Can be NULL in which case the key
    08183         will be opened here.
    08184
    08185     InstallDriver - Indicates whether setup should attempt to install a driver
    08186                     for this object.  Device objects created through
    08187                     IoReportDetectedDevice() already have a driver but we want
    08188                     to indicate them to setup anyway.
    08189
    08190 Return Value:
    08191
    08192     Status code that indicates whether or not the function was successful.
    08193
    08194 Note:
    08195
    08196     The contents of the notification structure *including* all pointers is only
    08197     valid during the callback routine to which it was passed.  If the data is
    08198     required after the duration of the callback then it must be physically copied
    08199     by the callback routine.
    08200
    08201 --*/
    08202
    08203 {
    08204     PAGED_CODE();
    08205
    08206     //
    08207     // Only perform notifications if someone has registered
    08208     //
    08209
    08210     if (IopSetupNotifyData) {
    08211
    08212         NTSTATUS status;
    08213         SETUP_DEVICE_ARRIVAL_NOTIFICATION notification;
    08214         NOTIFICATION_CALLBACK_PARAM_BLOCK callparams;
    08215         ULONG Console=0;
    08216         PDEVICE_NODE deviceNode;
    08217         HANDLE enumKey = NULL;
    08218
    08219         //
    08220         // Fill in the notification
    08221         //
    08222
    08223         if (!EnumEntryKey) {
    08224             status = IopDeviceObjectToDeviceInstance(PhysicalDeviceObject,
    08225                                                      &enumKey,
    08226                                                      KEY_WRITE);
    08227             if (!NT_SUCCESS(status)) {
    08228                 return status;
    08229             }
    08230             EnumEntryKey = enumKey;
    08231         }
    08232
    08233         notification.Version = PNP_NOTIFICATION_VERSION;
    08234         notification.Size = sizeof(SETUP_DEVICE_ARRIVAL_NOTIFICATION);
    08235         notification.Event = GUID_SETUP_DEVICE_ARRIVAL;
    08236         notification.PhysicalDeviceObject = PhysicalDeviceObject;
    08237         notification.EnumEntryKey = EnumEntryKey;
    08238         deviceNode = (PDEVICE_NODE) PhysicalDeviceObject->DeviceObjectExtension->DeviceNode;
    08239         notification.EnumPath = &deviceNode->InstancePath;
    08240         notification.InstallDriver = InstallDriver;
    08241
    08242         //
    08243         // Reference the notify and call back
    08244         //
    08245
    08246         callparams.Callout=(IopSetupNotifyData->Callback);
    08247         callparams.NotificationStructure=&notification;
    08248         callparams.Context=IopSetupNotifyData->Context;
    08249
    08250
    08251         //
    08252         // Dispatch this function via the memory manager.
    08253         // Win32K is a driver that can have multiple copies. If Hydra
    08254         // is running, the Mem. manager will check if the callback exists
    08255         // in "per session" space. If that is the case, it will attach to the
    08256         // console (hence the 3rd param of PULONG containing 0) session and deliver
    08257         // it. If either Hydra is not running, or the callback is outside session space
    08258         // then the callback is called directly.
    08259         //
    08260         status = MmDispatchWin32Callout ((PKWIN32_CALLOUT)callparams.Callout,&IopPnPHydraCallback,&callparams,&Console);
    08261         if (enumKey) {
    08262             ZwClose(enumKey);
    08263         }
    08264
    08265         return status;
    08266
    08267     } else {
    08268
    08269         return STATUS_OBJECT_NAME_NOT_FOUND;
    08270
    08271     }
    08272 }

NTSTATUS IopNotifyTargetDeviceChange | ( | LPCGUID | EventGuid,
|  | PDEVICE_OBJECT | DeviceObject,
|  | PVOID | NotificationStructure,
|  | PDRIVER_OBJECT * | VetoingDriver
| ) |

Definition at line 7055 of file pnpioapi.c.

References ASSERT, _NOTIFY_ENTRY_HEADER::Callback, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Callout, _NOTIFY_ENTRY_HEADER::Context, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Context, DbgPrint, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, _DRIVER_OBJECT::DriverName, _NOTIFY_ENTRY_HEADER::DriverObject, _TARGET_DEVICE_REMOVAL_NOTIFICATION::Event, _TARGET_DEVICE_REMOVAL_NOTIFICATION::FileObject, _TARGET_DEVICE_CUSTOM_NOTIFICATION::FileObject, IopAcquireNotifyLock, IopCompareGuid, IopDereferenceNotify(), IopPnPHydraCallback(), IopReferenceNotify(), IopReleaseNotifyLock, IopTargetDeviceNotifyLock, KeGetCurrentThread, MmDispatchWin32Callout(), _NOTIFICATION_CALLBACK_PARAM_BLOCK::NotificationStructure, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObject, PAGED_CODE, PKWIN32_CALLOUT, PNP_NOTIFICATION_VERSION, _TARGET_DEVICE_REMOVAL_NOTIFICATION::Size, _DEVICE_NODE::TargetDeviceNotify, _NOTIFY_ENTRY_HEADER::Unregistered, _TARGET_DEVICE_NOTIFY_ENTRY::Unregistered, and _TARGET_DEVICE_REMOVAL_NOTIFICATION::Version.

    07064                    :
    07065
    07066     This routine is used to notify all registered drivers of a change to a
    07067     particular device. It does not return until all interested parties have
    07068     been notified.
    07069
    07070 Parameters:
    07071
    07072     EventGuid - The event that has occured
    07073
    07074     DeviceObject - The device object that has changed.  The devnode for this
    07075         device object contains a list of callback routines that have registered
    07076         for notification of any changes on this device object.
    07077
    07078 Return Value:
    07079
    07080     Status code that indicates whether or not the function was successful.
    07081
    07082 Note:
    07083
    07084     The contents of the notification structure *including* all pointers is only
    07085     valid during the callback routine to which it was passed.  If the data is
    07086     required after the duration of the callback then it must be physically copied
    07087     by the callback routine.
    07088
    07089 --*/
    07090
    07091 {
    07092     NTSTATUS status = STATUS_SUCCESS;
    07093     PLIST_ENTRY link, lastLink;
    07094     PTARGET_DEVICE_NOTIFY_ENTRY entry;
    07095     TARGET_DEVICE_REMOVAL_NOTIFICATION notification;
    07096     PDEVICE_NODE deviceNode;
    07097     BOOLEAN reverse;
    07098 #if DBG
    07099     KIRQL originalIrql;
    07100     ULONG originalApcDisable;
    07101 #endif
    07102
    07103     PAGED_CODE();
    07104
    07105     ASSERT(DeviceObject != NULL);
    07106     ASSERT(EventGuid != NULL);
    07107
    07108     //
    07109     // Reference the device object so it can't go away while we're doing notification
    07110     //
    07111     ObReferenceObject(DeviceObject);
    07112
    07113     deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
    07114
    07115     ASSERT(deviceNode != NULL);
    07116
    07117
    07118     if (NotificationStructure) {
    07119         //
    07120         //We're handling a custom notification
    07121         //
    07122
    07123         ((PTARGET_DEVICE_CUSTOM_NOTIFICATION)NotificationStructure)->Version = PNP_NOTIFICATION_VERSION;
    07124
    07125     } else {
    07126         //
    07127         // Fill in the notification
    07128         //
    07129
    07130         notification.Version = PNP_NOTIFICATION_VERSION;
    07131         notification.Size = sizeof(TARGET_DEVICE_REMOVAL_NOTIFICATION);
    07132         notification.Event = *EventGuid;
    07133     }
    07134
    07135     //
    07136     // Lock the notify list
    07137     //
    07138
    07139     IopAcquireNotifyLock(&IopTargetDeviceNotifyLock);
    07140
    07141     //
    07142     // Get the first entry
    07143     //
    07144
    07145     reverse = IopCompareGuid(EventGuid, (LPGUID)&GUID_TARGET_DEVICE_REMOVE_CANCELLED);
    07146
    07147     if (reverse) {
    07148         link = deviceNode->TargetDeviceNotify.Blink;
    07149     } else {
    07150         link = deviceNode->TargetDeviceNotify.Flink;
    07151     }
    07152
    07153     //
    07154     // Iterate through the list
    07155     //
    07156
    07157     while (link != &deviceNode->TargetDeviceNotify) {
    07158
    07159         entry = (PTARGET_DEVICE_NOTIFY_ENTRY)link;
    07160
    07161         //
    07162         // Only callback on registered nodes
    07163         //
    07164
    07165         if (!entry->Unregistered) {
    07166
    07167             NOTIFICATION_CALLBACK_PARAM_BLOCK callparams;
    07168             ULONG Console=0;
    07169
    07170             //
    07171             // Reference the entry so that no one deletes during the callback
    07172             // and then release the lock
    07173             //
    07174
    07175             IopReferenceNotify((PNOTIFY_ENTRY_HEADER)entry);
    07176             IopReleaseNotifyLock(&IopTargetDeviceNotifyLock);
    07177
    07178 #if DBG
    07179             originalIrql = KeGetCurrentIrql();
    07180             originalApcDisable = KeGetCurrentThread()->KernelApcDisable;
    07181 #endif
    07182
    07183             //
    07184             // Callback the entity that registered and examine return value
    07185             //
    07186
    07187             if (NotificationStructure) {
    07188                 TARGET_DEVICE_CUSTOM_NOTIFICATION *notificationStructure = NotificationStructure;
    07189
    07190                 notificationStructure->FileObject = entry->FileObject;
    07191
    07192                 callparams.Callout=(entry->Callback);
    07193                 callparams.NotificationStructure=NotificationStructure;
    07194                 callparams.Context=entry->Context;
    07195
    07196
    07197                 //
    07198                 // Dispatch this function via the memory manager.
    07199                 // Win32K is a driver that can have multiple copies. If Hydra
    07200                 // is running, the Mem. manager will check if the callback exists
    07201                 // in "per session" space. If that is the case, it will attach to the
    07202                 // console (hence the 3rd param of PULONG containing 0) session and deliver
    07203                 // it. If either Hydra is not running, or the callback is outside session space
    07204                 // then the callback is called directly.
    07205                 //
    07206                 status = MmDispatchWin32Callout ((PKWIN32_CALLOUT)callparams.Callout,&IopPnPHydraCallback,&callparams,&Console);
    07207
    07208
    07209             } else {
    07210                 notification.FileObject = entry->FileObject;
    07211
    07212                 callparams.Callout=(entry->Callback);
    07213                 callparams.NotificationStructure=&notification;
    07214                 callparams.Context=entry->Context;
    07215
    07216                 status = MmDispatchWin32Callout ((PKWIN32_CALLOUT)callparams.Callout,&IopPnPHydraCallback,&callparams,&Console);
    07217
    07218             }
    07219
    07220 #if DBG
    07221             if (originalIrql != KeGetCurrentIrql()) {
    07222                 DbgPrint("IopNotifyTargetDeviceChange: Driver %Z, notification handler @ 0x%p returned at raised IRQL = %d, original = %d\n",
    07223                          &entry->DriverObject->DriverName, entry->Callback, KeGetCurrentIrql(), originalIrql);
    07224                 DbgBreakPoint();
    07225             }
    07226             if (originalApcDisable != KeGetCurrentThread()->KernelApcDisable) {
    07227                 DbgPrint("IopNotifyTargetDeviceChange: Driver %Z, notification handler @ 0x%p returned with different KernelApcDisable = %d, original = %d\n",
    07228                          &entry->DriverObject->DriverName, entry->Callback, KeGetCurrentThread()->KernelApcDisable, originalApcDisable);
    07229                 DbgBreakPoint();
    07230             }
    07231 #endif
    07232
    07233             //
    07234             // If the caller returned anything other than success and it was
    07235             // a query remove, we veto the query remove and send cancels to
    07236             // all callers that already got the query remove.
    07237             //
    07238
    07239             if (!NT_SUCCESS(status) &&
    07240                 IopCompareGuid(EventGuid, (LPGUID)&GUID_TARGET_DEVICE_QUERY_REMOVE)) {
    07241
    07242                 if (VetoingDriver != NULL) {
    07243                     *VetoingDriver = entry->DriverObject;
    07244                 }
    07245
    07246                 notification.Event = GUID_TARGET_DEVICE_REMOVE_CANCELLED;
    07247
    07248                 //
    07249                 // Dereference the entry which vetoed the query remove.
    07250                 //
    07251                 IopAcquireNotifyLock(&IopTargetDeviceNotifyLock);
    07252                 IopDereferenceNotify((PNOTIFY_ENTRY_HEADER)entry);
    07253
    07254                 do {
    07255                     entry = (PTARGET_DEVICE_NOTIFY_ENTRY)link;
    07256                     if (!entry->Unregistered) {
    07257                         IopReferenceNotify((PNOTIFY_ENTRY_HEADER)entry);
    07258                         IopReleaseNotifyLock(&IopTargetDeviceNotifyLock);
    07259
    07260                         notification.FileObject = entry->FileObject;
    07261 #if DBG
    07262                         originalApcDisable = KeGetCurrentThread()->KernelApcDisable;
    07263 #endif
    07264
    07265                         callparams.Callout=(entry->Callback);
    07266                         callparams.NotificationStructure=&notification;
    07267                         callparams.Context=entry->Context;
    07268
    07269                         MmDispatchWin32Callout ((PKWIN32_CALLOUT)callparams.Callout,&IopPnPHydraCallback,&callparams,&Console);
    07270
    07271 #if DBG
    07272                         if (originalApcDisable != KeGetCurrentThread()->KernelApcDisable) {
    07273                             DbgPrint("IopNotifyTargetDeviceChange: Driver %Z, notification handler @ 0x%p returned with different KernelApcDisable = %d, original = %d\n",
    07274                                      &entry->DriverObject->DriverName, entry->Callback, KeGetCurrentThread()->KernelApcDisable, originalApcDisable);
    07275                             DbgBreakPoint();
    07276                         }
    07277 #endif
    07278
    07279                         IopAcquireNotifyLock(&IopTargetDeviceNotifyLock);
    07280                         link = link->Blink;
    07281                         IopDereferenceNotify( (PNOTIFY_ENTRY_HEADER) entry );
    07282
    07283                     } else {
    07284                         link = link->Blink;
    07285                     }
    07286                 } while (link != &deviceNode->TargetDeviceNotify);
    07287
    07288                 goto Clean0;
    07289             }
    07290
    07291             //
    07292             // Reacquire the lock and dereference
    07293             //
    07294             IopAcquireNotifyLock(&IopTargetDeviceNotifyLock);
    07295             if (reverse) {
    07296                 link = link->Blink;
    07297             } else {
    07298                 link = link->Flink;
    07299             }
    07300             IopDereferenceNotify((PNOTIFY_ENTRY_HEADER)entry);
    07301
    07302         } else {
    07303
    07304             //
    07305             // Advance down the list
    07306             //
    07307             if (reverse) {
    07308                 link = link->Blink;
    07309             } else {
    07310                 link = link->Flink;
    07311             }
    07312         }
    07313     }
    07314
    07315 Clean0:
    07316
    07317     //
    07318     // Release the lock and dereference the object
    07319     //
    07320
    07321     IopReleaseNotifyLock(&IopTargetDeviceNotifyLock);
    07322
    07323     ObDereferenceObject(DeviceObject);
    07324
    07325     return status;
    07326 }

NTSTATUS IopOpenCurrentHwProfileDeviceInstanceKey | ( | OUT PHANDLE | Handle,
|  | IN PUNICODE_STRING | ServiceKeyName,
|  | IN ULONG | Instance,
|  | IN ACCESS_MASK | DesiredAccess,
|  | IN BOOLEAN | Create
| ) |

Definition at line 1712 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent, Create(), FALSE, Handle, IopOpenRegistryKey(), IopServiceInstanceToDeviceInstance(), NT_SUCCESS, NTSTATUS(), NULL, and RtlFreeUnicodeString().

Referenced by IopGetDeviceInstanceCsConfigFlags(), IopGetServiceInstanceCsConfigFlags(), IopSetDeviceInstanceCsConfigFlags(), and IopSetServiceInstanceCsConfigFlags().

    01722                    :
    01723
    01724     This routine sets the csconfig flags for the specified device
    01725     which is specified by the instance number under ServiceKeyName\Enum.
    01726
    01727 Arguments:
    01728
    01729     ServiceKeyName - Supplies a pointer to the name of the subkey in the
    01730         system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services)
    01731         that caused the driver to load. This is the RegistryPath parameter
    01732         to the DriverEntry routine.
    01733
    01734     Instance - Supplies the instance value under ServiceKeyName\Enum key
    01735
    01736     DesiredAccess - Specifies the desired access that the caller needs to
    01737         the key.
    01738
    01739     Create - Determines if the key is to be created if it does not exist.
    01740
    01741 Return Value:
    01742
    01743     status
    01744
    01745 --*/
    01746
    01747 {
    01748     NTSTATUS status;
    01749     UNICODE_STRING tempUnicodeString;
    01750     HANDLE profileHandle, profileEnumHandle, tmpHandle;
    01751
    01752     //
    01753     // See if we can open current hardware profile
    01754     //
    01755
    01756     if (Create) {
    01757         status = IopCreateRegistryKeyEx( &profileHandle,
    01758                                          NULL,
    01759                                          &CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent,
    01760                                          KEY_READ,
    01761                                          REG_OPTION_NON_VOLATILE,
    01762                                          NULL
    01763                                          );
    01764     } else {
    01765         status = IopOpenRegistryKeyEx( &profileHandle,
    01766                                        NULL,
    01767                                        &CmRegistryMachineSystemCurrentControlSetHardwareProfilesCurrent,
    01768                                        KEY_READ
    01769                                        );
    01770     }
    01771
    01772     if(NT_SUCCESS(status)) {
    01773         //
    01774         // Now, we must open the System\CCS\Enum key under this.
    01775         //
    01776         //
    01777         // Open system\CurrentControlSet under current hardware profile key
    01778         //
    01779
    01780         PiWstrToUnicodeString(&tempUnicodeString, REGSTR_PATH_CURRENTCONTROLSET);
    01781         status = IopOpenRegistryKeyEx( &tmpHandle,
    01782                                        profileHandle,
    01783                                        &tempUnicodeString,
    01784                                        DesiredAccess
    01785                                        );
    01786         ZwClose(profileHandle);
    01787         if (!NT_SUCCESS(status)) {
    01788             return status;
    01789         }
    01790
    01791         PiWstrToUnicodeString(&tempUnicodeString, REGSTR_KEY_ENUM);
    01792
    01793         if (Create) {
    01794             status = IopCreateRegistryKeyEx( &profileEnumHandle,
    01795                                              tmpHandle,
    01796                                              &tempUnicodeString,
    01797                                              KEY_READ,
    01798                                              REG_OPTION_NON_VOLATILE,
    01799                                              NULL
    01800                                              );
    01801         } else {
    01802             status = IopOpenRegistryKeyEx( &profileEnumHandle,
    01803                                            tmpHandle,
    01804                                            &tempUnicodeString,
    01805                                            KEY_READ
    01806                                            );
    01807         }
    01808
    01809         ZwClose(tmpHandle);
    01810         if(NT_SUCCESS(status)) {
    01811
    01812             status = IopServiceInstanceToDeviceInstance(NULL,
    01813                                                         ServiceKeyName,
    01814                                                         Instance,
    01815                                                         &tempUnicodeString,
    01816                                                         NULL,
    01817                                                         0
    01818                                                        );
    01819             if (NT_SUCCESS(status)) {
    01820                 if (Create) {
    01821                     status = IopCreateRegistryKeyEx( Handle,
    01822                                                      profileEnumHandle,
    01823                                                      &tempUnicodeString,
    01824                                                      DesiredAccess,
    01825                                                      REG_OPTION_NON_VOLATILE,
    01826                                                      NULL
    01827                                                      );
    01828                 } else {
    01829                     status = IopOpenRegistryKeyEx( Handle,
    01830                                                    profileEnumHandle,
    01831                                                    &tempUnicodeString,
    01832                                                    DesiredAccess
    01833                                                    );
    01834                 }
    01835                 RtlFreeUnicodeString(&tempUnicodeString);
    01836             }
    01837             ZwClose(profileEnumHandle);
    01838         }
    01839     }
    01840     return status;
    01841 }

NTSTATUS IopOpenDeviceParametersSubkey | ( | OUT HANDLE * | ParamKeyHandle,
|  | IN HANDLE | ParentKeyHandle,
|  | IN PUNICODE_STRING | SubKeyString,
|  | IN ACCESS_MASK | DesiredAccess
| ) |

Definition at line 8501 of file pnpioapi.c.

References ASSERT, ExAllocatePool, ExFreePool(), FALSE, IopCreateRegistryKeyEx(), IopOpenRegistryKeyEx(), NT_SUCCESS, NTSTATUS(), NULL, PagedPool, RtlAddAccessAllowedAceEx(), RtlAddAce(), RtlCreateAcl(), RtlCreateSecurityDescriptor(), RtlEqualSid(), RtlGetAce(), RtlGetDaclSecurityDescriptor(), RtlInitUnicodeString(), RtlLengthSid(), RtlQueryInformationAcl(), RtlSetDaclSecurityDescriptor(), RtlValidSecurityDescriptor(), SeAliasAdminsSid, and TRUE.

Referenced by IoOpenDeviceRegistryKey(), MapperSeedKey(), and PnPBiosCopyDeviceParamKey().

    08510                    :
    08511
    08512     This routine reports whether WDM functionality is available that
    08513     is greater than or equal to the specified major and minor version.
    08514
    08515 Parameters:
    08516
    08517     MajorVersion - Supplies the WDM major version that is required.
    08518
    08519     MinorVersion - Supplies the WDM minor version that is required.
    08520
    08521 Return Value:
    08522
    08523     If WDM support is available at _at least_ the requested level, the
    08524     return value is TRUE, otherwise it is FALSE.
    08525
    08526 --*/
    08527
    08528 {
    08529     NTSTATUS                    status;
    08530     ULONG                       disposition;
    08531     ULONG                       lengthSD;
    08532     PSECURITY_DESCRIPTOR        oldSD = NULL;
    08533     SECURITY_DESCRIPTOR         newSD;
    08534     ACL_SIZE_INFORMATION        aclSizeInfo;
    08535     PACL                        oldDacl;
    08536     PACL                        newDacl = NULL;
    08537     ULONG                       sizeDacl;
    08538     BOOLEAN                     daclPresent, daclDefaulted;
    08539     PACCESS_ALLOWED_ACE         ace;
    08540     ULONG                       aceIndex;
    08541     HANDLE                      deviceKeyHandle;
    08542     UNICODE_STRING              deviceParamString;
    08543
    08544     //
    08545     // First try and open the device key
    08546     //
    08547     status = IopOpenRegistryKeyEx( &deviceKeyHandle,
    08548                                    ParentKeyHandle,
    08549                                    SubKeyString,
    08550                                    KEY_WRITE
    08551                                    );
    08552
    08553     if (!NT_SUCCESS(status)) {
    08554         return status;
    08555     }
    08556
    08557     RtlInitUnicodeString(&deviceParamString, REGSTR_KEY_DEVICEPARAMETERS);
    08558
    08559     status = IopCreateRegistryKeyEx( ParamKeyHandle,
    08560                                      deviceKeyHandle,
    08561                                      &deviceParamString,
    08562                                      DesiredAccess | READ_CONTROL | WRITE_DAC,
    08563                                      REG_OPTION_NON_VOLATILE,
    08564                                      &disposition
    08565                                      );
    08566
    08567     ZwClose(deviceKeyHandle);
    08568
    08569     if (!NT_SUCCESS(status)) {
    08570         KdPrint(("IopOpenDeviceParametersSubkey: IopCreateRegistryKeyEx failed, status = %8.8X\n", status));
    08571         return status;
    08572     }
    08573
    08574     if (disposition == REG_CREATED_NEW_KEY) {
    08575
    08576         //
    08577         // Need to set an ACL on the key if it was created
    08578         //
    08579         //
    08580         // Get the security descriptor from the key so we can add the
    08581         // administrator.
    08582         //
    08583         status = ZwQuerySecurityObject(*ParamKeyHandle,
    08584                                        DACL_SECURITY_INFORMATION,
    08585                                        NULL,
    08586                                        0,
    08587                                        &lengthSD);
    08588
    08589         if (status == STATUS_BUFFER_TOO_SMALL) {
    08590             oldSD = ExAllocatePool( PagedPool, lengthSD );
    08591
    08592             if (oldSD != NULL) {
    08593
    08594                 status = ZwQuerySecurityObject(*ParamKeyHandle,
    08595                                                DACL_SECURITY_INFORMATION,
    08596                                                oldSD,
    08597                                                lengthSD,
    08598                                                &lengthSD);
    08599                 if (!NT_SUCCESS(status)) {
    08600                     KdPrint(("IopOpenDeviceParametersSubkey: ZwQuerySecurityObject failed, status = %8.8X\n", status));
    08601                     goto Cleanup0;
    08602                 }
    08603             } else  {
    08604
    08605                 KdPrint(("IopOpenDeviceParametersSubkey: Failed to allocate memory, status = %8.8X\n", status));
    08606                 status = STATUS_NO_MEMORY;
    08607                 goto Cleanup0;
    08608             }
    08609         } else {
    08610            KdPrint(("IopOpenDeviceParametersSubkey: ZwQuerySecurityObject failed %8.8X\n",status));
    08611            status = STATUS_UNSUCCESSFUL;
    08612            goto Cleanup0;
    08613         }
    08614
    08615         status = RtlCreateSecurityDescriptor( (PSECURITY_DESCRIPTOR) &newSD,
    08616                                               SECURITY_DESCRIPTOR_REVISION );
    08617         ASSERT( NT_SUCCESS( status ) );
    08618
    08619         if (!NT_SUCCESS(status)) {
    08620
    08621             KdPrint(("IopOpenDeviceParametersSubkey: RtlCreateSecurityDescriptor failed, status = %8.8X\n", status));
    08622             goto Cleanup0;
    08623         }
    08624         //
    08625         // get the current DACL
    08626         //
    08627         status = RtlGetDaclSecurityDescriptor(oldSD, &daclPresent, &oldDacl, &daclDefaulted);
    08628
    08629         ASSERT( NT_SUCCESS( status ) );
    08630
    08631         //
    08632         // calculate the size of the new DACL
    08633         //
    08634
    08635         if (daclPresent) {
    08636
    08637             status = RtlQueryInformationAcl( oldDacl,
    08638                                              &aclSizeInfo,
    08639                                              sizeof(ACL_SIZE_INFORMATION),
    08640                                              AclSizeInformation);
    08641
    08642
    08643             if (!NT_SUCCESS(status)) {
    08644
    08645                 KdPrint(("IopOpenDeviceParametersSubkey: RtlQueryInformationAcl failed, status = %8.8X\n", status));
    08646                 goto Cleanup0;
    08647             }
    08648
    08649             sizeDacl = aclSizeInfo.AclBytesInUse;
    08650         } else {
    08651             sizeDacl = sizeof(ACL);
    08652         }
    08653
    08654         sizeDacl += sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(SeAliasAdminsSid) - sizeof(ULONG);
    08655
    08656         //
    08657         // create and initialize the new DACL
    08658         //
    08659         newDacl = ExAllocatePool(PagedPool, sizeDacl);
    08660
    08661         if (newDacl == NULL) {
    08662
    08663             KdPrint(("IopOpenDeviceParametersSubkey: ExAllocatePool failed\n"));
    08664             goto Cleanup0;
    08665         }
    08666
    08667         status = RtlCreateAcl(newDacl, sizeDacl, ACL_REVISION);
    08668
    08669         if (!NT_SUCCESS(status)) {
    08670
    08671             KdPrint(("IopOpenDeviceParametersSubkey: RtlCreateAcl failed, status = %8.8X\n", status));
    08672             goto Cleanup0;
    08673         }
    08674
    08675         //
    08676         // copy the current (original) DACL into this new one
    08677         //
    08678         if (daclPresent) {
    08679
    08680             for (aceIndex = 0; aceIndex < aclSizeInfo.AceCount; aceIndex++) {
    08681
    08682                 status = RtlGetAce(oldDacl, aceIndex, (PVOID *)&ace);
    08683
    08684                 if (!NT_SUCCESS(status)) {
    08685
    08686                     KdPrint(("IopOpenDeviceParametersSubkey: RtlGetAce failed, status = %8.8X\n", status));
    08687                     goto Cleanup0;
    08688                 }
    08689
    08690                 //
    08691                 // We need to skip copying any ACEs which refer to the Administrator
    08692                 // to ensure that our full control ACE is the one and only.
    08693                 //
    08694                 if ((ace->Header.AceType != ACCESS_ALLOWED_ACE_TYPE &&
    08695                      ace->Header.AceType != ACCESS_DENIED_ACE_TYPE) ||
    08696                      !RtlEqualSid((PSID)&ace->SidStart, SeAliasAdminsSid)) {
    08697
    08698                     status = RtlAddAce( newDacl,
    08699                                         ACL_REVISION,
    08700                                         ~0U,
    08701                                         ace,
    08702                                         ace->Header.AceSize
    08703                                         );
    08704
    08705                     if (!NT_SUCCESS(status)) {
    08706
    08707                         KdPrint(("IopOpenDeviceParametersSubkey: RtlAddAce failed, status = %8.8X\n", status));
    08708                         goto Cleanup0;
    08709                     }
    08710                 }
    08711             }
    08712         }
    08713
    08714         //
    08715         // and my new admin-full ace to this new DACL
    08716         //
    08717         status = RtlAddAccessAllowedAceEx( newDacl,
    08718                                            ACL_REVISION,
    08719                                            CONTAINER_INHERIT_ACE,
    08720                                            KEY_ALL_ACCESS,
    08721                                            SeAliasAdminsSid
    08722                                            );
    08723         if (!NT_SUCCESS(status)) {
    08724
    08725             KdPrint(("IopOpenDeviceParametersSubkey: RtlAddAccessAllowedAceEx failed, status = %8.8X\n", status));
    08726             goto Cleanup0;
    08727         }
    08728
    08729         //
    08730         // Set the new DACL in the absolute security descriptor
    08731         //
    08732         status = RtlSetDaclSecurityDescriptor( (PSECURITY_DESCRIPTOR) &newSD,
    08733                                                TRUE,
    08734                                                newDacl,
    08735                                                FALSE
    08736                                                );
    08737
    08738         if (!NT_SUCCESS(status)) {
    08739
    08740             KdPrint(("IopOpenDeviceParametersSubkey: RtlSetDaclSecurityDescriptor failed, status = %8.8X\n", status));
    08741             goto Cleanup0;
    08742         }
    08743
    08744         //
    08745         // validate the new security descriptor
    08746         //
    08747         status = RtlValidSecurityDescriptor(&newSD);
    08748
    08749         if (!NT_SUCCESS(status)) {
    08750
    08751             KdPrint(("IopOpenDeviceParametersSubkey: RtlValidSecurityDescriptor failed, status = %8.8X\n", status));
    08752             goto Cleanup0;
    08753         }
    08754
    08755
    08756         status = ZwSetSecurityObject( *ParamKeyHandle,
    08757                                       DACL_SECURITY_INFORMATION,
    08758                                       &newSD
    08759                                       );
    08760         if (!NT_SUCCESS(status)) {
    08761
    08762             KdPrint(("IopOpenDeviceParametersSubkey: ZwSetSecurityObject failed, status = %8.8X\n", status));
    08763             goto Cleanup0;
    08764         }
    08765     }
    08766
    08767     //
    08768     // If we encounter an error updating the DACL we still return success.
    08769     //
    08770
    08771 Cleanup0:
    08772
    08773     if (oldSD != NULL) {
    08774         ExFreePool(oldSD);
    08775     }
    08776
    08777     if (newDacl != NULL) {
    08778         ExFreePool(newDacl);
    08779     }
    08780
    08781     return STATUS_SUCCESS;
    08782 }

NTSTATUS IopOpenRegistryKeyEx | ( | OUT PHANDLE | Handle,
|  | IN HANDLE BaseHandle | OPTIONAL,
|  | IN PUNICODE_STRING | KeyName,
|  | IN ACCESS_MASK | DesiredAccess
| ) |

Definition at line 1104 of file pnpsubs.c.

References Handle, KeyName, NULL, and PAGED_CODE.

Referenced by EisaBuildEisaDeviceNode(), EisaGetEisaDevicesResources(), IoGetDeviceProperty(), IoOpenDeviceRegistryKey(), IopApplyFunctionToServiceInstances(), IopApplyFunctionToSubKeys(), IopCallDriverAddDevice(), IopCleanupDeviceRegistryValues(), IopCreateMadeupNode(), IopDeleteKeyRecursive(), IopDeleteLegacyKey(), IopDeviceInterfaceKeysFromSymbolicLink(), IopDeviceObjectFromDeviceInstance(), IopDeviceObjectToDeviceInstance(), IopDriverLoadingFailed(), IopGetDeviceInstanceCsConfigFlags(), IopGetDeviceInterfaces(), IopGetDeviceResourcesFromRegistry(), IopGetDriverTagPriority(), IopGetGroupOrderIndex(), IopInitializeBootDrivers(), IopInitializeBuiltinDriver(), IopInitializePlugPlayServices(), IopInitializeSystemDrivers(), IopIsAnyDeviceInstanceEnabled(), IopIsDeviceInstanceEnabled(), IopIsFirmwareMapperDevicePresent(), IopIsReportedAlready(), IopMakeGloballyUniqueId(), IopOpenCurrentHwProfileDeviceInstanceKey(), IopOpenDeviceParametersSubkey(), IopOpenOrCreateDeviceInterfaceSubKeys(), IopOpenServiceEnumKeys(), IopProcessCriticalDevice(), IopProcessCriticalDeviceRoutine(), IopProcessNewDeviceNode(), IopQueryDeviceResources(), IopRemoveDeviceInterfaces(), IopServiceInstanceToDeviceInstance(), IopStoreSystemPartitionInformation(), IopUnregisterDeviceInterface(), IoReportDetectedDevice(), PnPBiosCopyDeviceParamKey(), PnPBiosEliminateDupes(), PnPBiosGetBiosInfo(), PnPBiosWriteInfo(), PnPCheckFixedIoOverrideDecodes(), and PnPGetDevnodeExcludeList().

    01113                    :
    01114
    01115     Opens a registry key using the name passed in based at the BaseHandle node.
    01116     This name may specify a key that is actually a registry path.
    01117
    01118 Arguments:
    01119
    01120     Handle - Pointer to the handle which will contain the registry key that
    01121         was opened.
    01122
    01123     BaseHandle - Optional handle to the base path from which the key must be opened.
    01124         If KeyName specifies a registry path that must be created, then this parameter
    01125         must be specified, and KeyName must be a relative path.
    01126
    01127     KeyName - Name of the Key that must be opened/created (possibly a registry path)
    01128
    01129     DesiredAccess - Specifies the desired access that the caller needs to
    01130         the key.
    01131
    01132 Return Value:
    01133
    01134    The function value is the final status of the operation.
    01135
    01136 --*/
    01137
    01138 {
    01139     OBJECT_ATTRIBUTES objectAttributes;
    01140
    01141     PAGED_CODE();
    01142
    01143     InitializeObjectAttributes( &objectAttributes,
    01144                                 KeyName,
    01145                                 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
    01146                                 BaseHandle,
    01147                                 (PSECURITY_DESCRIPTOR) NULL
    01148                                 );
    01149     //
    01150     // Simply attempt to open the path, as specified.
    01151     //
    01152     return ZwOpenKey( Handle, DesiredAccess, &objectAttributes );
    01153 }

NTSTATUS IopOpenServiceEnumKeys | ( | IN PUNICODE_STRING | ServiceKeyName,
|  | IN ACCESS_MASK | DesiredAccess,
|  | OUT PHANDLE ServiceHandle | OPTIONAL,
|  | OUT PHANDLE ServiceEnumHandle | OPTIONAL,
|  | IN BOOLEAN | CreateEnum
| ) |

Definition at line 1339 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetServices, FALSE, IopOpenRegistryKey(), NT_SUCCESS, NTSTATUS(), and NULL.

Referenced by IopApplyFunctionToServiceInstances(), IopCallDriverAddDeviceQueryRoutine(), IopCreateMadeupNode(), IopDriverLoadingFailed(), IopGetDriverDeviceList(), IopGetServiceType(), IopIsAnyDeviceInstanceEnabled(), and IopServiceInstanceToDeviceInstance().

    01349                    :
    01350
    01351     This routine opens the HKEY_LOCAL_MACHINE\CurrentControlSet\Services\
    01352     ServiceKeyName and its Enum subkey and returns handles for both key.
    01353     It is caller's responsibility to close the returned handles.
    01354
    01355 Arguments:
    01356
    01357     ServiceKeyName - Supplies a pointer to the name of the subkey in the
    01358         system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services)
    01359         that caused the driver to load. This is the RegistryPath parameter
    01360         to the DriverEntry routine.
    01361
    01362     DesiredAccess - Specifies the desired access to the keys.
    01363
    01364     ServiceHandle - Supplies a variable to receive a handle to ServiceKeyName.
    01365         A NULL ServiceHandle indicates caller does not want need the handle to
    01366         the ServiceKeyName.
    01367
    01368     ServiceEnumHandle - Supplies a variable to receive a handle to ServiceKeyName\Enum.
    01369         A NULL ServiceEnumHandle indicates caller does not need the handle to
    01370         the ServiceKeyName\Enum.
    01371
    01372     CreateEnum - Supplies a BOOLEAN variable to indicate should the Enum subkey be
    01373         created if not present.
    01374
    01375 Return Value:
    01376
    01377     status
    01378
    01379 --*/
    01380
    01381 {
    01382     HANDLE handle, serviceHandle, enumHandle;
    01383     UNICODE_STRING enumName;
    01384     NTSTATUS status;
    01385
    01386     //
    01387     // Open System\CurrentControlSet\Services
    01388     //
    01389
    01390     status = IopOpenRegistryKeyEx( &handle,
    01391                                    NULL,
    01392                                    &CmRegistryMachineSystemCurrentControlSetServices,
    01393                                    DesiredAccess
    01394                                    );
    01395
    01396     if (!NT_SUCCESS( status )) {
    01397         return status;
    01398     }
    01399
    01400     //
    01401     // Open the registry ServiceKeyName key.
    01402     //
    01403
    01404     status = IopOpenRegistryKeyEx( &serviceHandle,
    01405                                    handle,
    01406                                    ServiceKeyName,
    01407                                    DesiredAccess
    01408                                    );
    01409
    01410     ZwClose(handle);
    01411     if (!NT_SUCCESS( status )) {
    01412
    01413         //
    01414         // There is no registry key for the ServiceKeyName information.
    01415         //
    01416
    01417         return status;
    01418     }
    01419
    01420     if (ARGUMENT_PRESENT(ServiceEnumHandle) || CreateEnum) {
    01421
    01422         //
    01423         // Open registry ServiceKeyName\Enum branch if caller wants
    01424         // the handle or wants to create it.
    01425         //
    01426
    01427         PiWstrToUnicodeString(&enumName, REGSTR_KEY_ENUM);
    01428
    01429         if (CreateEnum) {
    01430             status = IopCreateRegistryKeyEx( &enumHandle,
    01431                                              serviceHandle,
    01432                                              &enumName,
    01433                                              DesiredAccess,
    01434                                              REG_OPTION_VOLATILE,
    01435                                              NULL
    01436                                              );
    01437         } else {
    01438             status = IopOpenRegistryKeyEx( &enumHandle,
    01439                                            serviceHandle,
    01440                                            &enumName,
    01441                                            DesiredAccess
    01442                                            );
    01443
    01444         }
    01445
    01446         if (!NT_SUCCESS( status )) {
    01447
    01448             //
    01449             // There is no registry key for the ServiceKeyName\Enum information.
    01450             //
    01451
    01452             ZwClose(serviceHandle);
    01453             return status;
    01454         }
    01455         if (ARGUMENT_PRESENT(ServiceEnumHandle)) {
    01456             *ServiceEnumHandle = enumHandle;
    01457         } else {
    01458             ZwClose(enumHandle);
    01459         }
    01460     }
    01461
    01462     //
    01463     // if caller wants to have the ServiceKey handle, we return it.  Otherwise
    01464     // we close it.
    01465     //
    01466
    01467     if (ARGUMENT_PRESENT(ServiceHandle)) {
    01468         *ServiceHandle = serviceHandle;
    01469     } else {
    01470         ZwClose(serviceHandle);
    01471     }
    01472
    01473     return STATUS_SUCCESS;
    01474 }

VOID IopOrphanNotification | ( | PDEVICE_NODE | DeviceNode | ) |

| Referenced by IopRemoveTreeDeviceNode().

NTSTATUS IopPnPAddDevice | ( | IN PDRIVER_OBJECT | DriverObject,
|  | IN PDEVICE_OBJECT | DeviceObject
| ) |

Definition at line 419 of file pnpdd.c.

References PAGED_CODE.

Referenced by IopPnPDriverEntry().

    00426                    :
    00427
    00428     This routine handles AddDevice for an madeup PDO device.
    00429
    00430 Arguments:
    00431
    00432     DriverObject - Pointer to our pseudo driver object.
    00433
    00434     DeviceObject - Pointer to the device object for which this requestapplies.
    00435
    00436 Return Value:
    00437
    00438     NT status.
    00439
    00440 --*/
    00441 {
    00442     PAGED_CODE();
    00443
    00444 #if DBG
    00445
    00446     //
    00447     // We should never get an AddDevice request.
    00448     //
    00449
    00450     DbgBreakPoint();
    00451
    00452 #endif
    00453
    00454     return STATUS_SUCCESS;
    00455 }
    //  PNPRES test

NTSTATUS IopPnPDispatch | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN OUT PIRP | Irp
| ) |

Definition at line 648 of file pnpdd.c.

References ArbArbiterHandler(), _ARBITER_INTERFACE::ArbiterHandler, _PNP_BUS_INFORMATION::BusNumber, BusQueryCompatibleIDs, BusQueryDeviceID, BusQueryInstanceID, BusRelations, _PNP_BUS_INFORMATION::BusTypeGuid, _IOPNP_DEVICE_EXTENSION::CompatibleIdList, _IOPNP_DEVICE_EXTENSION::CompatibleIdListSize, _ARBITER_INTERFACE::Context, _DEVICE_RELATIONS::Count, _DEVICE_CAPABILITIES::DeviceState, ExAllocatePool, _DEVICE_CAPABILITIES::HardwareDisabled, _DEVICE_NODE::InstancePath, IoGetCurrentIrpStackLocation, IopCompareGuid, IopGetDeviceResourcesFromRegistry(), IopGetRootDevices(), IopIsFirmwareDisabled(), IopPnPCompleteRequest(), IopRootBusNumberArbiter, IopRootDeviceNode, IopRootDmaArbiter, IopRootIrqArbiter, IopRootMemArbiter, IopRootPortArbiter, IopTranslatorHandlerCm(), IopTranslatorHandlerIo(), _IRP::IoStatus, Irp, IRP_MN_CANCEL_REMOVE_DEVICE, IRP_MN_CANCEL_STOP_DEVICE, IRP_MN_DEVICE_USAGE_NOTIFICATION, IRP_MN_QUERY_BUS_INFORMATION, IRP_MN_QUERY_CAPABILITIES, IRP_MN_QUERY_DEVICE_RELATIONS, IRP_MN_QUERY_ID, IRP_MN_QUERY_INTERFACE, IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_QUERY_RESOURCE_REQUIREMENTS, IRP_MN_QUERY_RESOURCES, IRP_MN_QUERY_STOP_DEVICE, IRP_MN_REMOVE_DEVICE, IRP_MN_START_DEVICE, IRP_MN_STOP_DEVICE, _PNP_BUS_INFORMATION::LegacyBusType, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, _DEVICE_RELATIONS::Objects, ObReferenceObject, PAGED_CODE, PagedPool, _IO_STACK_LOCATION::Parameters, _DEVICE_NODE::PhysicalDeviceObject, PIOPNP_DEVICE_EXTENSION, PnpDefaultInterfaceType, QUERY_RESOURCE_LIST, QUERY_RESOURCE_REQUIREMENTS, REGISTRY_BASIC_CONFIGVECTOR, REGISTRY_BOOT_CONFIG, _DEVICE_CAPABILITIES::Size, TargetDeviceRelation, _TRANSLATOR_INTERFACE::TranslateResourceRequirements, _TRANSLATOR_INTERFACE::TranslateResources, TRUE, and _DEVICE_CAPABILITIES::Version.

Referenced by IopPnPDriverEntry().

    00655                    :
    00656
    00657     This routine handles all IRP_MJ_PNP IRPs for madeup PDO device.
    00658
    00659 Arguments:
    00660
    00661     DeviceObject - Pointer to the device object for which this IRP applies.
    00662
    00663     Irp - Pointer to the IRP_MJ_PNP IRP to dispatch.
    00664
    00665 Return Value:
    00666
    00667     NT status.
    00668
    00669 --*/
    00670 {
    00671     PIOPNP_DEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
    00672     PIO_STACK_LOCATION irpSp;
    00673     NTSTATUS status;
    00674     PVOID information = NULL;
    00675     ULONG length;
    00676     PWCHAR id, wp;
    00677     PDEVICE_NODE deviceNode;
    00678     PARBITER_INTERFACE arbiterInterface;  // PNPRES test
    00679     PTRANSLATOR_INTERFACE translatorInterface;  // PNPRES test
    00680
    00681     PAGED_CODE();
    00682
    00683     //
    00684     // Get a pointer to our stack location and take appropriate action based
    00685     // on the minor function.
    00686     //
    00687
    00688     irpSp = IoGetCurrentIrpStackLocation(Irp);
    00689     switch (irpSp->MinorFunction){
    00690
    00691     case IRP_MN_DEVICE_USAGE_NOTIFICATION:
    00692     case IRP_MN_START_DEVICE:
    00693
    00694         //
    00695         // If we get a start device request for a PDO, we simply
    00696         // return success.
    00697         //
    00698
    00699         status = STATUS_SUCCESS;
    00700         break;
    00701
    00702     case IRP_MN_CANCEL_STOP_DEVICE:
    00703
    00704         //
    00705         // As we fail all STOP's, this cancel is always successful, and we have
    00706         // no work to do.
    00707         //
    00708         status = STATUS_SUCCESS;
    00709         break;
    00710
    00711     case IRP_MN_QUERY_STOP_DEVICE:
    00712     case IRP_MN_STOP_DEVICE:
    00713
    00714         //
    00715         // We can not success the query stop.  We don't handle it.  because
    00716         // we don't know how to stop a root enumerated device.
    00717         //
    00718         status = STATUS_UNSUCCESSFUL ;
    00719         break;
    00720
    00721     case IRP_MN_QUERY_RESOURCES:
    00722
    00723         status = IopGetDeviceResourcesFromRegistry(
    00724                          DeviceObject,
    00725                          QUERY_RESOURCE_LIST,
    00726                          REGISTRY_BOOT_CONFIG,
    00727                          &information,
    00728                          &length);
    00729         if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
    00730             status = STATUS_SUCCESS;
    00731             information = NULL;
    00732         }
    00733         break;
    00734
    00735     case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
    00736
    00737         status = IopGetDeviceResourcesFromRegistry(
    00738                          DeviceObject,
    00739                          QUERY_RESOURCE_REQUIREMENTS,
    00740                          REGISTRY_BASIC_CONFIGVECTOR,
    00741                          &information,
    00742                          &length);
    00743         if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
    00744             status = STATUS_SUCCESS;
    00745             information = NULL;
    00746         }
    00747         break;
    00748
    00749     case IRP_MN_QUERY_REMOVE_DEVICE:
    00750     case IRP_MN_REMOVE_DEVICE:
    00751     case IRP_MN_CANCEL_REMOVE_DEVICE:
    00752
    00753         //
    00754         // For root enumerated devices we let the device objects stays.
    00755         // So, they will be marked as deleted but still show up in the tree.
    00756         //
    00757
    00758         //IoDeleteDevice(DeviceObject);
    00759         status = STATUS_SUCCESS;
    00760         break;
    00761
    00762     case IRP_MN_QUERY_DEVICE_RELATIONS:
    00763
    00764         if (DeviceObject == IopRootDeviceNode->PhysicalDeviceObject &&
    00765             irpSp->Parameters.QueryDeviceRelations.Type == BusRelations) {
    00766             status = IopGetRootDevices((PDEVICE_RELATIONS *)&information);
    00767         } else {
    00768             if (irpSp->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation) {
    00769                 PDEVICE_RELATIONS deviceRelations;
    00770
    00771                 deviceRelations = ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
    00772                 if (deviceRelations == NULL) {
    00773                     status = STATUS_INSUFFICIENT_RESOURCES;
    00774                 } else {
    00775                     deviceRelations->Count = 1;
    00776                     deviceRelations->Objects[0] = DeviceObject;
    00777                     ObReferenceObject(DeviceObject);
    00778                     information = (PVOID)deviceRelations;
    00779                     status = STATUS_SUCCESS;
    00780                 }
    00781             } else {
    00782                 information = (PVOID)Irp->IoStatus.Information;
    00783                 status = Irp->IoStatus.Status;
    00784             }
    00785         }
    00786         break;
    00787
    00788     case IRP_MN_QUERY_INTERFACE:
    00789         deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
    00790         if (deviceNode == IopRootDeviceNode) {
    00791             if ( IopCompareGuid((PVOID)irpSp->Parameters.QueryInterface.InterfaceType, (PVOID)&GUID_ARBITER_INTERFACE_STANDARD)) {
    00792                 status = STATUS_SUCCESS;
    00793                 arbiterInterface = (PARBITER_INTERFACE) irpSp->Parameters.QueryInterface.Interface;
    00794                 arbiterInterface->ArbiterHandler = ArbArbiterHandler;
    00795                 switch ((UCHAR)((ULONG_PTR)irpSp->Parameters.QueryInterface.InterfaceSpecificData)) {
    00796                 case CmResourceTypePort:
    00797                     arbiterInterface->Context = (PVOID) &IopRootPortArbiter;
    00798                     break;
    00799                 case CmResourceTypeMemory:
    00800                     arbiterInterface->Context = (PVOID) &IopRootMemArbiter;
    00801                     break;
    00802                 case CmResourceTypeInterrupt:
    00803                     arbiterInterface->Context = (PVOID) &IopRootIrqArbiter;
    00804                     break;
    00805                 case CmResourceTypeDma:
    00806                     arbiterInterface->Context = (PVOID) &IopRootDmaArbiter;
    00807                     break;
    00808                 case CmResourceTypeBusNumber:
    00809                     arbiterInterface->Context = (PVOID) &IopRootBusNumberArbiter;
    00810                     break;
    00811                 default:
    00812                     status = STATUS_INVALID_PARAMETER;
    00813                     break;
    00814                 }
    00815             } else if ( IopCompareGuid((PVOID)irpSp->Parameters.QueryInterface.InterfaceType, (PVOID)&GUID_TRANSLATOR_INTERFACE_STANDARD)) {
    00816                 translatorInterface = (PTRANSLATOR_INTERFACE) irpSp->Parameters.QueryInterface.Interface;
    00817                 translatorInterface->TranslateResources = IopTranslatorHandlerCm;
    00818                 translatorInterface->TranslateResourceRequirements = IopTranslatorHandlerIo;
    00819                 status = STATUS_SUCCESS;
    00820             }
    00821             break;
    00822         }
    00823
    00824         status = Irp->IoStatus.Status;
    00825         break;
    00826
    00827     case IRP_MN_QUERY_CAPABILITIES:
    00828
    00829         {
    00830             ULONG i;
    00831             PDEVICE_POWER_STATE state;
    00832             PDEVICE_CAPABILITIES deviceCapabilities;
    00833
    00834             deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
    00835
    00836             deviceCapabilities = irpSp->Parameters.DeviceCapabilities.Capabilities;
    00837             deviceCapabilities->Size = sizeof(DEVICE_CAPABILITIES);
    00838             deviceCapabilities->Version = 1;
    00839
    00840             deviceCapabilities->DeviceState[PowerSystemUnspecified]=PowerDeviceUnspecified;
    00841             deviceCapabilities->DeviceState[PowerSystemWorking]=PowerDeviceD0;
    00842
    00843             state = &deviceCapabilities->DeviceState[PowerSystemSleeping1];
    00844
    00845             for (i = PowerSystemSleeping1; i < PowerSystemMaximum; i++) {
    00846
    00847                 //
    00848                 // Only supported state, currently, is off.
    00849                 //
    00850
    00851                 *state++ = PowerDeviceD3;
    00852             }
    00853
    00854
    00855             if(IopIsFirmwareDisabled(deviceNode)) {
    00856                 //
    00857                 // this device has been disabled by BIOS
    00858                 //
    00859                 deviceCapabilities->HardwareDisabled = TRUE;
    00860             }
    00861
    00862             status = STATUS_SUCCESS;
    00863         }
    00864         break;
    00865
    00866     case IRP_MN_QUERY_ID:
    00867         if (DeviceObject != IopRootDeviceNode->PhysicalDeviceObject &&
    00868             (!NT_SUCCESS(Irp->IoStatus.Status) || !Irp->IoStatus.Information)) {
    00869
    00870             deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
    00871             switch (irpSp->Parameters.QueryId.IdType) {
    00872
    00873             case BusQueryInstanceID:
    00874             case BusQueryDeviceID:
    00875
    00876                 id = (PWCHAR)ExAllocatePool(PagedPool, deviceNode->InstancePath.Length);
    00877                 if (id) {
    00878                     ULONG separatorCount = 0;
    00879
    00880                     RtlZeroMemory(id, deviceNode->InstancePath.Length);
    00881                     information = id;
    00882                     status = STATUS_SUCCESS;
    00883                     wp = deviceNode->InstancePath.Buffer;
    00884                     if (irpSp->Parameters.QueryId.IdType == BusQueryDeviceID) {
    00885                         while(*wp) {
    00886                             if (*wp == OBJ_NAME_PATH_SEPARATOR) {
    00887                                 separatorCount++;
    00888                                 if (separatorCount == 2) {
    00889                                     break;
    00890                                 }
    00891                             }
    00892                             *id = *wp;
    00893                             id++;
    00894                             wp++;
    00895                         }
    00896                     } else {
    00897                         while(*wp) {
    00898                             if (*wp == OBJ_NAME_PATH_SEPARATOR) {
    00899                                 separatorCount++;
    00900                                 if (separatorCount == 2) {
    00901                                     wp++;
    00902                                     break;
    00903                                 }
    00904                             }
    00905                             wp++;
    00906                         }
    00907                         while (*wp) {
    00908                             *id = *wp;
    00909                             id++;
    00910                             wp++;
    00911                         }
    00912                     }
    00913                 } else {
    00914                     status = STATUS_INSUFFICIENT_RESOURCES;
    00915                 }
    00916                 break;
    00917
    00918             case BusQueryCompatibleIDs:
    00919
    00920                 if((Irp->IoStatus.Status != STATUS_NOT_SUPPORTED) ||
    00921                    (deviceExtension == NULL))  {
    00922
    00923                     //
    00924                     // Upper driver has given some sort of reply or this device
    00925                     // object wasn't allocated to handle these requests.
    00926                     //
    00927
    00928                     status = Irp->IoStatus.Status;
    00929                     break;
    00930                 }
    00931
    00932                 if(deviceExtension->CompatibleIdListSize != 0) {
    00933
    00934                     id = ExAllocatePool(PagedPool,
    00935                                         deviceExtension->CompatibleIdListSize);
    00936
    00937                     if(id == NULL) {
    00938                         status = STATUS_INSUFFICIENT_RESOURCES;
    00939                         break;
    00940                     }
    00941
    00942                     RtlCopyMemory(id,
    00943                                   deviceExtension->CompatibleIdList,
    00944                                   deviceExtension->CompatibleIdListSize);
    00945
    00946                     information = id;
    00947                     status = STATUS_SUCCESS;
    00948                     break;
    00949                 }
    00950
    00951             default:
    00952
    00953                 information = (PVOID)Irp->IoStatus.Information;
    00954                 status = Irp->IoStatus.Status;
    00955             }
    00956         } else {
    00957             information = (PVOID)Irp->IoStatus.Information;
    00958             status = Irp->IoStatus.Status;
    00959         }
    00960
    00961         break;
    00962 #if 0
    00963     case IRP_MN_QUERY_BUS_INFORMATION:
    00964         deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
    00965         if (deviceNode == IopRootDeviceNode) {
    00966             PPNP_BUS_INFORMATION busInfo;
    00967
    00968             busInfo = (PPNP_BUS_INFORMATION) ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
    00969             if (busInfo) {
    00970                 busInfo->LegacyBusType = PnpDefaultInterfaceType;
    00971                 busInfo->BusNumber = 0;
    00972                 if (PnpDefaultInterfaceType == Isa) {
    00973                     busInfo->BusTypeGuid = GUID_BUS_TYPE_ISAPNP; // BUGBUG
    00974                 } else if (PnpDefaultInterfaceType == Eisa) {
    00975                     busInfo->BusTypeGuid = GUID_BUS_TYPE_EISA;
    00976                 } else { // Microchannel
    00977                     busInfo->BusTypeGuid = GUID_BUS_TYPE_MCA;
    00978                 }
    00979                 information = busInfo;
    00980                 status = STATUS_SUCCESS;
    00981             } else {
    00982                 status = STATUS_INSUFFICIENT_RESOURCES;
    00983                 information = NULL;
    00984             }
    00985             break;
    00986         }
    00987 #endif
    00988
    00989         //
    00990         // Otherwise, let it fall through the default path.
    00991         //
    00992
    00993     default:
    00994
    00995         information = (PVOID)Irp->IoStatus.Information;
    00996         status = Irp->IoStatus.Status;
    00997         break;
    00998     }
    00999
    01000     //
    01001     // Complete the Irp and return.
    01002     //
    01003
    01004     IopPnPCompleteRequest(Irp, status, (ULONG_PTR)information);
    01005     return status;
    01006 }

NTSTATUS IopPortInitialize | ( | VOID |  | ) |

Definition at line 349 of file pnpmemio.c.

References _ARBITER_INSTANCE::AddAllocation, ArbInitializeArbiterInstance(), _ARBITER_INSTANCE::BacktrackAllocation, _ARBITER_INSTANCE::FindSuitableRange, IopGenericPackResource(), IopGenericScoreRequirement(), IopGenericTranslateOrdering(), IopGenericUnpackRequirement(), IopGenericUnpackResource(), IopPortAddAllocation(), IopPortBacktrackAllocation(), IopPortFindSuitableRange(), IopRootPortArbiter, L, NULL, _ARBITER_INSTANCE::PackResource, PAGED_CODE, _ARBITER_INSTANCE::ScoreRequirement, _ARBITER_INSTANCE::UnpackRequirement, and _ARBITER_INSTANCE::UnpackResource.

Referenced by IopInitializePlugPlayServices().

    00355                    :
    00356
    00357     This routine initializes the arbiter
    00358
    00359 Parameters:
    00360
    00361     None
    00362
    00363 Return Value:
    00364
    00365     None
    00366
    00367 --*/
    00368
    00369 {
    00370     PAGED_CODE();
    00371
    00372     //
    00373     // Fill in the non-default action handlers
    00374     //
    00375
    00376     IopRootPortArbiter.FindSuitableRange    = IopPortFindSuitableRange;
    00377     IopRootPortArbiter.AddAllocation        = IopPortAddAllocation;
    00378     IopRootPortArbiter.BacktrackAllocation  = IopPortBacktrackAllocation;
    00379
    00380     IopRootPortArbiter.UnpackRequirement    = IopGenericUnpackRequirement;
    00381     IopRootPortArbiter.PackResource         = IopGenericPackResource;
    00382     IopRootPortArbiter.UnpackResource       = IopGenericUnpackResource;
    00383     IopRootPortArbiter.ScoreRequirement     = IopGenericScoreRequirement;
    00384
    00385     return ArbInitializeArbiterInstance(&IopRootPortArbiter,
    00386                                         NULL,     // Indicates ROOT arbiter
    00387                                         CmResourceTypePort,
    00388                                         L"RootPort",
    00389                                         L"Root",
    00390                                         IopGenericTranslateOrdering
    00391                                         );
    00392
    00393 }

NTSTATUS IopPowerDispatch | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN OUT PIRP | Irp
| ) |

Definition at line 570 of file pnpdd.c.

References IO_NO_INCREMENT, IoCompleteRequest, IoGetCurrentIrpStackLocation, _IRP::IoStatus, Irp, IRP_MN_POWER_SEQUENCE, IRP_MN_QUERY_POWER, IRP_MN_SET_POWER, IRP_MN_WAIT_WAKE, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), _IO_STACK_LOCATION::Parameters, PoPowerSequence, PoStartNextPowerIrp(), _POWER_SEQUENCE::SequenceD1, _POWER_SEQUENCE::SequenceD2, _POWER_SEQUENCE::SequenceD3, and Status.

Referenced by IopPnPDriverEntry().

    00574 {
    00575     PIO_STACK_LOCATION      IrpSp;
    00576     PPOWER_SEQUENCE         PowerSequence;
    00577     NTSTATUS                Status;
    00578
    00579
    00580     UNREFERENCED_PARAMETER( DeviceObject );
    00581
    00582     IrpSp = IoGetCurrentIrpStackLocation (Irp);
    00583     Status = Irp->IoStatus.Status;
    00584
    00585     switch (IrpSp->MinorFunction) {
    00586         case IRP_MN_WAIT_WAKE:
    00587             Status = STATUS_NOT_SUPPORTED;
    00588             break;
    00589
    00590         case IRP_MN_POWER_SEQUENCE:
    00591             PowerSequence = IrpSp->Parameters.PowerSequence.PowerSequence;
    00592             PowerSequence->SequenceD1 = PoPowerSequence;
    00593             PowerSequence->SequenceD2 = PoPowerSequence;
    00594             PowerSequence->SequenceD3 = PoPowerSequence;
    00595             Status = STATUS_SUCCESS;
    00596             break;
    00597
    00598         case IRP_MN_QUERY_POWER:
    00599             Status = STATUS_SUCCESS;
    00600             break;
    00601
    00602         case IRP_MN_SET_POWER:
    00603             switch (IrpSp->Parameters.Power.Type) {
    00604                 case SystemPowerState:
    00605                     Status = STATUS_SUCCESS;
    00606                     break;
    00607
    00608                 case DevicePowerState:
    00609                     //
    00610                     // To be here the FDO must have passed the IRP on.
    00611                     // We do not know how to turn the device off, but the
    00612                     // FDO is prepaired for it work
    00613                     //
    00614
    00615                     Status = STATUS_SUCCESS;
    00616                     break;
    00617
    00618                 default:
    00619                     // Unkown power type
    00620                     Status = STATUS_NOT_SUPPORTED;
    00621                     break;
    00622             }
    00623             break;
    00624
    00625         default:
    00626             // Unkown power minor code
    00627             Status = STATUS_NOT_SUPPORTED;
    00628             break;
    00629     }
    00630
    00631
    00632     //
    00633     // For lagecy devices that do not have drivers loaded, complete
    00634     // power irps with success.
    00635     //
    00636
    00637     PoStartNextPowerIrp(Irp);
    00638     if (Status != STATUS_NOT_SUPPORTED) {
    00639        Irp->IoStatus.Status = Status;
    00640     } else {
    00641        Status = Irp->IoStatus.Status;
    00642     }
    00643     IoCompleteRequest( Irp, IO_NO_INCREMENT );
    00644     return Status;
    00645 }

NTSTATUS IopPrepareDriverLoading | ( | IN PUNICODE_STRING | KeyName,
|  | IN HANDLE | KeyHandle,
|  | IN PIMAGE_NT_HEADERS | Header
| ) |

Definition at line 753 of file pnpsubs.c.

References ExAcquireResourceShared, ExFreePool(), exit, ExReleaseResource, FALSE, Header, IopCreateMadeupNode(), IopGetRegistryValue(), IopIsAnyDeviceInstanceEnabled(), IopOpenRegistryKey(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KEY_VALUE_DATA, KeyName, NT_SUCCESS, NTSTATUS(), NULL, PnPDetectionEnabled, PpRegistryDeviceResource, RtlFreeUnicodeString(), TITLE_INDEX_VALUE, and TRUE.

Referenced by IopInitializeBuiltinDriver(), and IopLoadDriver().

    00761                    :
    00762
    00763     This routine first checks if the driver is loadable.  If its a
    00764     PnP driver, it will always be loaded (we trust it to do the right
    00765     things.)  If it is a legacy driver, we need to check if its device
    00766     has been disabled.  Once we decide to load the driver, the Enum
    00767     subkey of the service node will be checked for duplicates, if any.
    00768
    00769 Parameters:
    00770
    00771     KeyName - Supplies a pointer to the driver's service key unicode string
    00772
    00773     KeyHandle - Supplies a handle to the driver service node in the registry
    00774         that describes the driver to be loaded.
    00775
    00776 Return Value:
    00777
    00778     The function value is the final status of the load operation.
    00779
    00780 --*/
    00781
    00782 {
    00783     NTSTATUS status;
    00784     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    00785     ULONG tmp, count;
    00786     HANDLE serviceEnumHandle = NULL, sysEnumXxxHandle, controlHandle;
    00787     UNICODE_STRING unicodeKeyName, unicodeValueName;
    00788     BOOLEAN IsPlugPlayDriver;
    00789
    00790     status = STATUS_SUCCESS;
    00791     IsPlugPlayDriver = (Header &&
    00792                         (Header->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_WDM_DRIVER))? TRUE : FALSE;
    00793
    00794     if (!IopIsAnyDeviceInstanceEnabled(KeyName, KeyHandle, (BOOLEAN)(IsPlugPlayDriver ? FALSE : TRUE))) {
    00795
    00796         if (IsPlugPlayDriver) {
    00797
    00798             if (!PnPDetectionEnabled) {
    00799
    00800                 status = STATUS_PLUGPLAY_NO_DEVICE;
    00801
    00802             }
    00803
    00804         } else {
    00805
    00806             KeEnterCriticalRegion();
    00807             ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE);
    00808
    00809             //
    00810             // First open registry ServiceKeyName\Enum branch
    00811             //
    00812
    00813             PiWstrToUnicodeString(&unicodeKeyName, REGSTR_KEY_ENUM);
    00814             status = IopCreateRegistryKeyEx( &serviceEnumHandle,
    00815                                              KeyHandle,
    00816                                              &unicodeKeyName,
    00817                                              KEY_ALL_ACCESS,
    00818                                              REG_OPTION_VOLATILE,
    00819                                              NULL
    00820                                              );
    00821             if (NT_SUCCESS(status)) {
    00822
    00823                 //
    00824                 // Find out how many device instances listed in the ServiceName's
    00825                 // Enum key.
    00826                 //
    00827
    00828                 count = 0;
    00829                 status = IopGetRegistryValue ( serviceEnumHandle,
    00830                                                REGSTR_VALUE_COUNT,
    00831                                                &keyValueInformation);
    00832                 if (NT_SUCCESS(status)) {
    00833
    00834                     if (    keyValueInformation->Type == REG_DWORD &&
    00835                             keyValueInformation->DataLength >= sizeof(ULONG)) {
    00836
    00837                         count = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
    00838
    00839                     }
    00840
    00841                     ExFreePool(keyValueInformation);
    00842
    00843                 }
    00844                 if (    NT_SUCCESS(status) ||
    00845                         status == STATUS_OBJECT_PATH_NOT_FOUND ||
    00846                         status == STATUS_OBJECT_NAME_NOT_FOUND) {
    00847
    00848                     if (count) {
    00849
    00850                         status = STATUS_PLUGPLAY_NO_DEVICE;
    00851
    00852                     } else {
    00853
    00854                         //
    00855                         // If there is no Enum key or instance under Enum for the
    00856                         // legacy driver we will create a madeup node for it.
    00857                         //
    00858
    00859                         status = IopCreateMadeupNode(   KeyName,
    00860                                                         &sysEnumXxxHandle,
    00861                                                         &unicodeKeyName,
    00862                                                         &tmp,
    00863                                                         TRUE);
    00864                         if (NT_SUCCESS(status)) {
    00865
    00866                             RtlFreeUnicodeString(&unicodeKeyName);
    00867
    00868                             //
    00869                             // Create and set Control\ActiveService value
    00870                             //
    00871
    00872                             PiWstrToUnicodeString(&unicodeValueName, REGSTR_KEY_CONTROL);
    00873                             status = IopCreateRegistryKeyEx( &controlHandle,
    00874                                                              sysEnumXxxHandle,
    00875                                                              &unicodeValueName,
    00876                                                              KEY_ALL_ACCESS,
    00877                                                              REG_OPTION_VOLATILE,
    00878                                                              NULL
    00879                                                              );
    00880                             if (NT_SUCCESS(status)) {
    00881
    00882                                 PiWstrToUnicodeString(&unicodeValueName, REGSTR_VAL_ACTIVESERVICE);
    00883                                 ZwSetValueKey(  controlHandle,
    00884                                                 &unicodeValueName,
    00885                                                 TITLE_INDEX_VALUE,
    00886                                                 REG_SZ,
    00887                                                 KeyName->Buffer,
    00888                                                 KeyName->Length + sizeof(UNICODE_NULL));
    00889                                 ZwClose(controlHandle);
    00890
    00891                             }
    00892                             count++;
    00893                             //
    00894                             // Don't forget to update the "Count=" and "NextInstance=" value entries
    00895                             //
    00896
    00897                             PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_COUNT);
    00898                             ZwSetValueKey(  serviceEnumHandle,
    00899                                             &unicodeValueName,
    00900                                             TITLE_INDEX_VALUE,
    00901                                             REG_DWORD,
    00902                                             &count,
    00903                                             sizeof(count));
    00904
    00905                             PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_NEXT_INSTANCE);
    00906                             ZwSetValueKey(  serviceEnumHandle,
    00907                                             &unicodeValueName,
    00908                                             TITLE_INDEX_VALUE,
    00909                                             REG_DWORD,
    00910                                             &count,
    00911                                             sizeof(count));
    00912
    00913                             ZwClose(sysEnumXxxHandle);
    00914                             status = STATUS_SUCCESS;
    00915                         }
    00916                     }
    00917                 }
    00918
    00919                 ZwClose(serviceEnumHandle);
    00920             }
    00921
    00922             ExReleaseResource(&PpRegistryDeviceResource);
    00923             KeLeaveCriticalRegion();
    00924         }
    00925     }
    00926
    00927     return status;
    00928 }

USHORT IopProcessAddDevices | ( | IN PDEVICE_NODE | DeviceNode,
|  | IN USHORT | StartOrder,
|  | IN ULONG | DriverStartType
| ) |

Definition at line 1053 of file pnpdd.c.

References _DEVICE_NODE::Child, _ADD_CONTEXT::DriverStartType, _ADD_CONTEXT::GroupsToStart, _ADD_CONTEXT::GroupToStartNext, IopAcquireEnumerationLock, IopProcessAddDevicesWorker(), IopReleaseEnumerationLock, IopRootDeviceNode, NO_MORE_GROUP, _DEVICE_NODE::Sibling, and USHORT.

Referenced by IopInitializeSystemDrivers().

    01061                    :
    01062
    01063     This functions is used by Pnp manager to load driver and perform AddDevice for
    01064     all the devices under DeviceNode subtree.  This routine is used at boot time
    01065     to process devices which were not processed during boot driver initialization.
    01066
    01067     Note, caller must acquire the enumeration mutex of the DeviceNode before calling
    01068     this routine.
    01069
    01070 Parameters:
    01071
    01072     DeviceNode - Specifies the device node whose subtree is to be checked for StartDevice.
    01073
    01074     StartOrder - The group orders to start.
    01075
    01076 Return Value:
    01077
    01078     TRUE - if any new device is successfully added to its driver.
    01079
    01080 --*/
    01081 {
    01082     PDEVICE_NODE deviceNode, nextDeviceNode;
    01083     USHORT returnValue = NO_MORE_GROUP;
    01084     ADD_CONTEXT context;
    01085
    01086     context.GroupsToStart = StartOrder;
    01087     context.GroupToStartNext = NO_MORE_GROUP;
    01088     context.DriverStartType = DriverStartType;
    01089
    01090     //
    01091     // Traverse the device node subtree to perform AddDevice call.
    01092     //
    01093
    01094     if (DeviceNode != IopRootDeviceNode) {
    01095         IopAcquireEnumerationLock(DeviceNode);
    01096     }
    01097
    01098     deviceNode = DeviceNode->Child;
    01099     while (deviceNode) {
    01100
    01101         //
    01102         // We need to remember the 'next' device node.  If the deviceNode is a madeup device
    01103         // it may be deleted while processing the IopProcessAddDeviceWorker.
    01104         //
    01105
    01106         nextDeviceNode = deviceNode->Sibling;
    01107         IopProcessAddDevicesWorker(deviceNode, &context);
    01108         deviceNode = nextDeviceNode;
    01109     }
    01110     if (DeviceNode != IopRootDeviceNode) {
    01111         IopReleaseEnumerationLock(DeviceNode);
    01112     }
    01113     return context.GroupToStartNext;
    01114 }

BOOLEAN IopProcessAssignResources | ( | IN PDEVICE_NODE | DeviceNode,
|  | IN BOOLEAN | Reallocation,
|  | IN BOOLEAN | BootConfigsOK
| ) |

Definition at line 1185 of file pnpdd.c.

References _DEVICE_NODE::Child, _DEVICE_LIST_CONTEXT::DeviceCount, _DEVICE_LIST_CONTEXT::DeviceList, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_ASSIGNING_RESOURCES, DNF_NO_RESOURCE_REQUIRED, DNF_RESOURCE_ASSIGNED, DNF_RESOURCE_REPORTED, ExAcquireResourceShared, ExAllocatePool, ExFreePool(), ExReleaseResource, FALSE, _DEVICE_NODE::Flags, IOP_RESOURCE_REQUEST, IopAcquireEnumerationLock, IopAssignResourcesToDevices(), IopDeviceTreeLock, IopNumberDeviceNodes, IopProcessAssignResourcesWorker(), IopReleaseEnumerationLock, IopSetDevNodeProblem, NT_SUCCESS, PAGED_CODE, PagedPool, PDEVICE_LIST_CONTEXT, _IOP_RESOURCE_REQUEST::PhysicalDevice, _IOP_RESOURCE_REQUEST::Priority, _DEVICE_LIST_CONTEXT::Reallocation, _IOP_RESOURCE_REQUEST::ResourceAssignment, _DEVICE_NODE::ResourceList, _DEVICE_NODE::ResourceListTranslated, _DEVICE_NODE::Sibling, _IOP_RESOURCE_REQUEST::Status, Status, _IOP_RESOURCE_REQUEST::TranslatedResourceAssignment, and TRUE.

Referenced by IopBusCheck(), IopDeviceActionWorker(), IopInitializeSystemDrivers(), and IopNewDevice().

    01193                    :
    01194
    01195     This functions is used by Pnp manager to allocate resources for the devices
    01196     which have been successfully added to their drivers and waiting to be started.
    01197
    01198     Note, the caller must acquire the enumeration mutex before calling this routine.
    01199
    01200 Parameters:
    01201
    01202     DeviceNode - specifies the device node whose subtree is to be checked for AssignRes.
    01203
    01204     Reallocation - specifies if we are assigning resources for DNF_INSUFFICIENT_RESOURCES
    01205                    devices.
    01206
    01207     BootConfigsOK  - Indicates that it is OK to assign BOOT configs.
    01208
    01209 Return Value:
    01210
    01211     TRUE - if more devices need resources.  This means we did not assign resources for all
    01212     the devices.  caller must call this routine again.
    01213
    01214 --*/
    01215 {
    01216     PDEVICE_NODE deviceNode;
    01217     PDEVICE_LIST_CONTEXT context;
    01218     BOOLEAN again = FALSE;
    01219     ULONG count, i;
    01220     PIOP_RESOURCE_REQUEST requestTable;
    01221
    01222     PAGED_CODE();
    01223
    01224     //
    01225     // Allocate and init memory for resource context
    01226     //
    01227
    01228     context = (PDEVICE_LIST_CONTEXT) ExAllocatePool(
    01229                                     PagedPool,
    01230                                     sizeof(DEVICE_LIST_CONTEXT) +
    01231                                     sizeof(PDEVICE_OBJECT) * IopNumberDeviceNodes
    01232                                     );
    01233     if (!context) {
    01234         return again;
    01235     }
    01236     context->DeviceCount = 0;
    01237     context->Reallocation = Reallocation;
    01238
    01239     //
    01240     // Parse the device node subtree to determine which devices need resources
    01241     //
    01242
    01243     IopAcquireEnumerationLock(DeviceNode);
    01244     deviceNode = DeviceNode->Child;
    01245
    01246     while (deviceNode) {
    01247         IopProcessAssignResourcesWorker(deviceNode, context);
    01248         deviceNode = deviceNode->Sibling;
    01249     }
    01250     IopReleaseEnumerationLock(DeviceNode);
    01251     count = context->DeviceCount;
    01252     if (count == 0) {
    01253         ExFreePool(context);
    01254         return again;
    01255     }
    01256
    01257     //
    01258     // Need to assign resources to devices.  Build the resource request table and call
    01259     // resource assignment routine.
    01260     //
    01261
    01262     requestTable = (PIOP_RESOURCE_REQUEST) ExAllocatePool(
    01263                                     PagedPool,
    01264                                     sizeof(IOP_RESOURCE_REQUEST) * count
    01265                                     );
    01266     if (requestTable) {
    01267
    01268         for (i = 0; i < count; i++) {
    01269             requestTable[i].Priority = 0;
    01270             requestTable[i].PhysicalDevice = context->DeviceList[i];
    01271         }
    01272
    01273         //
    01274         // Assign resources
    01275         //
    01276
    01277         ExAcquireResourceShared(&IopDeviceTreeLock, TRUE);
    01278         IopAssignResourcesToDevices(count, requestTable, BootConfigsOK);
    01279
    01280         //
    01281         // Check the results
    01282         //
    01283
    01284         for (i = 0; i < count; i++) {
    01285
    01286             deviceNode = (PDEVICE_NODE)
    01287                           requestTable[i].PhysicalDevice->DeviceObjectExtension->DeviceNode;
    01288             if (NT_SUCCESS(requestTable[i].Status)) {
    01289                 if (requestTable[i].ResourceAssignment) {
    01290                     if (!(deviceNode->Flags & DNF_RESOURCE_REPORTED)) {
    01291                         deviceNode->Flags |= DNF_RESOURCE_ASSIGNED;
    01292                     }
    01293                     //deviceNode->Flags &= ~DNF_INSUFFICIENT_RESOURCES;
    01294                     deviceNode->ResourceList = requestTable[i].ResourceAssignment;
    01295                     deviceNode->ResourceListTranslated = requestTable[i].TranslatedResourceAssignment;
    01296                 } else {
    01297                     deviceNode->Flags |= DNF_NO_RESOURCE_REQUIRED;
    01298                 }
    01299             } else if (requestTable[i].Status == STATUS_RETRY) {
    01300                 again = TRUE;
    01301             } else if (requestTable[i].Status == STATUS_DEVICE_CONFIGURATION_ERROR) {
    01302                 IopSetDevNodeProblem(deviceNode, CM_PROB_NO_SOFTCONFIG);
    01303             } else if (requestTable[i].Status == STATUS_PNP_BAD_MPS_TABLE) {
    01304                 IopSetDevNodeProblem(deviceNode, CM_PROB_BIOS_TABLE);
    01305             } else if (requestTable[i].Status == STATUS_PNP_TRANSLATION_FAILED) {
    01306                 IopSetDevNodeProblem(deviceNode, CM_PROB_TRANSLATION_FAILED);
    01307             } else if (requestTable[i].Status == STATUS_PNP_IRQ_TRANSLATION_FAILED) {
    01308                 IopSetDevNodeProblem(deviceNode, CM_PROB_IRQ_TRANSLATION_FAILED);
    01309             } else {
    01310                 IopSetDevNodeProblem(deviceNode, CM_PROB_NORMAL_CONFLICT);
    01311             }
    01312
    01313             //
    01314             // IopProcessAssignReourcesWork marks the device nodes as DNF_ASSIGNING_RESOURCES
    01315             // We need to clear it to indicate the assigment is done.
    01316             //
    01317
    01318             deviceNode->Flags &= ~DNF_ASSIGNING_RESOURCES;
    01319         }
    01320         ExReleaseResource(&IopDeviceTreeLock);
    01321         ExFreePool(requestTable);
    01322     }
    01323     ExFreePool(context);
    01324     return again;
    01325 }

VOID IopProcessCompletedEject | ( | IN PVOID | Context | ) |

Definition at line 1417 of file pnpdel.c.

References _PENDING_RELATIONS_LIST_ENTRY::DeviceEvent, _PENDING_RELATIONS_LIST_ENTRY::DeviceObject, _PENDING_RELATIONS_LIST_ENTRY::DisplaySafeRemovalDialog, _PENDING_RELATIONS_LIST_ENTRY::DockInterface, ExFreePool(), FALSE, IopAcquireDeviceTreeLock, IopFreeRelationList(), IopHardwareProfileSetMarkedDocksEjected(), IopInvalidateRelationsInList(), IopReleaseDeviceTreeLock, IopWarmEjectDevice(), _PENDING_RELATIONS_LIST_ENTRY::LightestSleepState, _PENDING_RELATIONS_LIST_ENTRY::Link, NTSTATUS(), NULL, PAGED_CODE, PpSetDeviceRemovalSafe(), _PENDING_RELATIONS_LIST_ENTRY::ProfileChangingEject, _PENDING_RELATIONS_LIST_ENTRY::RelationsList, and TRUE.

Referenced by IopDeviceEjectComplete(), and IopEjectDevice().

    01422                    :
    01423
    01424     This routine is called at passive level from a worker thread that was queued
    01425     either when an eject IRP completed (see io\pnpirp.c - IopDeviceEjectComplete
    01426     or io\pnpirp.c - IopEjectDevice), or when a warm eject needs to be performed.
    01427     We also may need to fire off any enumerations of parents of ejected devices
    01428     to verify they have indeed left.
    01429
    01430 Arguments:
    01431
    01432     Context - Pointer to the pending relations list which contains the device
    01433               to eject (warm) and the list of parents to reenumerate.
    01434
    01435 Return Value:
    01436
    01437     None.
    01438
    01439 --*/
    01440 {
    01441     PPENDING_RELATIONS_LIST_ENTRY entry = (PPENDING_RELATIONS_LIST_ENTRY)Context;
    01442     NTSTATUS status = STATUS_SUCCESS;
    01443
    01444     PAGED_CODE();
    01445
    01446     if ((entry->LightestSleepState != PowerSystemWorking) &&
    01447         (entry->LightestSleepState != PowerSystemUnspecified)) {
    01448
    01449         //
    01450         // For docks, WinLogon gets to do the honors. For other devices, the
    01451         // user must infer when it's safe to remove the device (if we've powered
    01452         // up, it may not be safe now!)
    01453         //
    01454         entry->DisplaySafeRemovalDialog = FALSE;
    01455
    01456         //
    01457         // This is a warm eject request, initiate it here.
    01458         //
    01459         status = IopWarmEjectDevice(entry->DeviceObject, entry->LightestSleepState);
    01460
    01461         //
    01462         // We're back and we either succeeded or failed. Either way...
    01463         //
    01464     }
    01465
    01466     if (entry->DockInterface) {
    01467
    01468         entry->DockInterface->ProfileDepartureSetMode(
    01469             entry->DockInterface->Context,
    01470             PDS_UPDATE_DEFAULT
    01471             );
    01472
    01473         entry->DockInterface->InterfaceDereference(
    01474             entry->DockInterface->Context
    01475             );
    01476     }
    01477
    01478     IopAcquireDeviceTreeLock();
    01479
    01480     RemoveEntryList( &entry->Link );
    01481
    01482     //
    01483     // Check if the RelationsList pointer in the context structure is NULL.  If
    01484     // so, this means we were cancelled because this eject is part of a new
    01485     // larger eject.  In that case all we want to do is unlink and free the
    01486     // context structure.
    01487     //
    01488
    01489     //
    01490     // Two interesting points about such code.
    01491     //
    01492     // 1) If you wait forever to complete an eject of a dock, we *wait* forever
    01493     //    in the Query profile change state. No sneaky adding another dock. You
    01494     //    must finish what you started...
    01495     // 2) Let's say you are ejecting a dock, and it is taking a long time. If
    01496     //    you try to eject the parent, that eject will *not* grab this lower
    01497     //    eject as we will block on the profile change semaphore. Again, finish
    01498     //    what you started...
    01499     //
    01500
    01501     if (entry->RelationsList != NULL)  {
    01502
    01503         if (entry->ProfileChangingEject) {
    01504
    01505             IopHardwareProfileSetMarkedDocksEjected();
    01506         }
    01507
    01508         IopInvalidateRelationsInList( entry->RelationsList, FALSE, FALSE, TRUE );
    01509
    01510         //
    01511         // Free the relations list
    01512         //
    01513
    01514         IopFreeRelationList( entry->RelationsList );
    01515
    01516     } else {
    01517
    01518         entry->DisplaySafeRemovalDialog = FALSE;
    01519     }
    01520
    01521     IopReleaseDeviceTreeLock();
    01522
    01523     //
    01524     // Complete the event
    01525     //
    01526     if (entry->DeviceEvent != NULL ) {
    01527
    01528         PpCompleteDeviceEvent( entry->DeviceEvent, status );
    01529     }
    01530
    01531     if (entry->DisplaySafeRemovalDialog) {
    01532
    01533         PpSetDeviceRemovalSafe(entry->DeviceObject, NULL, NULL);
    01534     }
    01535
    01536     ExFreePool( entry );
    01537 }

BOOLEAN IopProcessCriticalDevice | ( | IN PDEVICE_NODE | DeviceNode | ) |

| Referenced by IopInitializeDeviceInstanceKey(), and IopProcessNewDeviceNode().

VOID IopProcessDeferredRegistrations | ( | VOID |  | ) |

Definition at line 5954 of file pnpioapi.c.

References ExFreePool(), FALSE, IopAcquireNotifyLock, IopDeferredRegistrationList, IopDeferredRegistrationLock, IopDereferenceNotify(), IopReleaseNotifyLock, _NOTIFY_ENTRY_HEADER::Lock, _DEFERRED_REGISTRATION_ENTRY::NotifyEntry, NULL, PDEFERRED_REGISTRATION_ENTRY, and _NOTIFY_ENTRY_HEADER::Unregistered.

    05959                    :
    05960
    05961     This routine removes notification entries from the deferred registration
    05962     list, marking them as "registered" so that they can receive notifications.
    05963
    05964 Parameters:
    05965
    05966     None.
    05967
    05968 Return Value:
    05969
    05970     None.
    05971
    05972   --*/
    05973 {
    05974     PDEFERRED_REGISTRATION_ENTRY deferredNode;
    05975     PFAST_MUTEX lock;
    05976
    05977     IopAcquireNotifyLock(&IopDeferredRegistrationLock);
    05978
    05979     while (!IsListEmpty(&IopDeferredRegistrationList)) {
    05980
    05981         deferredNode = (PDEFERRED_REGISTRATION_ENTRY)RemoveHeadList(&IopDeferredRegistrationList);
    05982
    05983         //
    05984         // Acquire this entry's list lock.
    05985         //
    05986         lock = deferredNode->NotifyEntry->Lock;
    05987         if (lock) {
    05988             IopAcquireNotifyLock(lock);
    05989         }
    05990
    05991         //
    05992         // Mark this entry as registered.
    05993         //
    05994         deferredNode->NotifyEntry->Unregistered = FALSE;
    05995
    05996         //
    05997         // Dereference the notification entry when removing it from the deferred
    05998         // list, and free the node.
    05999         //
    06000         IopDereferenceNotify((PNOTIFY_ENTRY_HEADER)deferredNode->NotifyEntry);
    06001         ExFreePool(deferredNode);
    06002
    06003         //
    06004         // Release this entry's list lock.
    06005         //
    06006         if (lock) {
    06007             IopReleaseNotifyLock(lock);
    06008             lock = NULL;
    06009         }
    06010     }
    06011
    06012     IopReleaseNotifyLock(&IopDeferredRegistrationLock);
    06013 }

NTSTATUS IopProcessNewDeviceNode | ( | IN OUT PDEVICE_NODE | DeviceNode | ) |

Definition at line 1538 of file pnpenum.c.

References ArbiterRequestPnpEnumerated, ASSERT, BusQueryCompatibleIDs, BusQueryHardwareIDs, CmRegistryMachineSystemCurrentControlSetEnumName, DebugPrint, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DeviceTextDescription, DeviceTextLocationInformation, DNF_HAS_BOOT_CONFIG, DNF_PROCESSED, DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED, DNUF_DONT_SHOW_IN_UI, DOCK_NOTDOCKDEVICE, DOCK_QUIESCENT, _DEVICE_CAPABILITIES::DockDevice, DOE_START_PENDING, dummy(), ExAcquireResourceShared, ExAllocatePool, ExFreePool(), exit, ExReleaseResource, _DEVOBJ_EXTENSION::ExtensionFlags, FALSE, _DEVICE_CAPABILITIES::HardwareDisabled, IO_STACK_LOCATION, IopClearDevNodeProblem, IopConcatenateUnicodeStrings(), IopCreateRegistryKeyEx(), IopDeviceCapabilitiesToRegistry(), IopDeviceObjectFromDeviceInstance(), IopDoesDevNodeHaveProblem, IopFixupDeviceId(), IopFixupIds(), IopGetBusTypeGuidIndex(), IopIsDeviceInstanceEnabled(), IopIsDevNodeProblem, IopIsRemoteBootCard(), IopLoaderBlock, IopMakeGloballyUniqueId(), IopNotifySetupDeviceArrival(), IopOpenRegistryKeyEx(), IopProcessCriticalDevice(), IopQueryCompatibleIds(), IopQueryDeviceCapabilities(), IopQueryDeviceId(), IopQueryDeviceResources(), IopQueryPnpBusInformation(), IopQueryUniqueId(), IopRemoveDevice(), IopRequestDeviceRemoval(), IopRootDeviceNode, IopSetDevNodeProblem, IopSetupRemoteBootCard(), IopSynchronousCall(), IoRemoteBootClient, IRP_MJ_PNP, IRP_MN_QUERY_DEVICE_TEXT, IRP_MN_QUERY_RESOURCE_REQUIREMENTS, IRP_MN_REMOVE_DEVICE, KeBugCheckEx(), KeEnterCriticalRegion, KeLeaveCriticalRegion, L, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, _DEVICE_CAPABILITIES::NoDisplayInUI, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, PAGED_CODE, PagedPool, _IO_STACK_LOCATION::Parameters, _DEVICE_NODE::Parent, PNP_ERR_BOGUS_ID, PNP_ERR_DUPLICATE_PDO, PpDeviceRegistration(), PpRegistryDeviceResource, PpSetPlugPlayEvent(), PsDefaultSystemLocaleId, QUERY_RESOURCE_LIST, _DEVICE_CAPABILITIES::RawDeviceOK, RtlInitUnicodeString(), TITLE_INDEX_VALUE, TRUE, and _DEVICE_CAPABILITIES::UniqueID.

Referenced by IopDeviceActionWorker(), and IopProcessNewChildren().

    01544                    :
    01545
    01546     This function creates a device instance key for the specified device.
    01547     If LoadDriver is true and the device driver for the device is installed,
    01548     this routine will load the driver to start enumerating its children.
    01549
    01550 Arguments:
    01551
    01552     DeviceNode - Supplies a pointer to the device node to be processed.
    01553
    01554 Return Value:
    01555
    01556     NTSTATUS code.
    01557
    01558 --*/
    01559
    01560 {
    01561     NTSTATUS status;
    01562     PWCHAR deviceId, busId, uniqueId, compatibleIds, id, hwIds, deviceText, globallyUniqueId;
    01563     HANDLE handle, enumHandle, busIdHandle, deviceIdHandle;
    01564     HANDLE uniqueIdHandle, logConfHandle;
    01565     UNICODE_STRING unicodeName, unicodeString, unicodeDeviceInstance;
    01566     ULONG disposition, tmpValue, length, cmLength, ioLength, hwIdLength, compatibleIdLength;
    01567     PCM_RESOURCE_LIST cmResource;
    01568     PIO_RESOURCE_REQUIREMENTS_LIST ioResource;
    01569     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    01570     PWCHAR buffer = NULL;
    01571     PDEVICE_OBJECT deviceObject;
    01572     PDEVICE_NODE deviceNode;
    01573     IO_STACK_LOCATION irpSp;
    01574     DEVICE_CAPABILITIES capabilities;
    01575     PVOID dummy = NULL;
    01576     BOOLEAN globallyUnique = FALSE;
    01577     PWCHAR location = NULL, description = NULL;
    01578     PKEY_VALUE_PARTIAL_INFORMATION keyValue;
    01579     UCHAR CLSIDBuffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + 128];
    01580
    01581     BOOLEAN processCriticalDevice = FALSE;
    01582     BOOLEAN isRemoteBootCard = FALSE;
    01583     BOOLEAN configuredBySetup;
    01584     PWCHAR wp;
    01585     GUID busTypeGuid;
    01586
    01587     PAGED_CODE();
    01588
    01589     deviceObject = DeviceNode->PhysicalDeviceObject;
    01590
    01591     //
    01592     // First open HKLM\System\CCS\Enum key.
    01593     //
    01594
    01595     status = IopOpenRegistryKeyEx( &enumHandle,
    01596                                    NULL,
    01597                                    &CmRegistryMachineSystemCurrentControlSetEnumName,
    01598                                    KEY_ALL_ACCESS
    01599                                    );
    01600     if (!NT_SUCCESS(status)) {
    01601         KdPrint(("IopProcessNewDeviceNode: Unable to open HKLM\\SYSTEM\\CCS\\ENUM\n"));
    01602         return status;
    01603     }
    01604
    01605     //
    01606     // First, get the device id and this will be the device key name
    01607     //
    01608
    01609     status = IopQueryDeviceId(deviceObject, &id);
    01610
    01611     if (!NT_SUCCESS(status) || id == NULL) {
    01612         ZwClose(enumHandle);
    01613         return status;
    01614     }
    01615
    01616     //
    01617     // Fix up the id if necessary
    01618     //
    01619     if (!IopFixupDeviceId(id)) {
    01620         KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
    01621                       PNP_ERR_BOGUS_ID,
    01622                       (ULONG_PTR)deviceObject,
    01623                       (ULONG_PTR)id,
    01624                       1);
    01625
    01626
    01627     }
    01628
    01629     //
    01630     // Extract  bus id out of the returned id
    01631     //
    01632
    01633     for (wp = id; *wp != UNICODE_NULL; wp++) {
    01634         if (*wp == OBJ_NAME_PATH_SEPARATOR) {
    01635             deviceId = wp + 1;
    01636             busId = id;
    01637             break;
    01638         }
    01639     }
    01640
    01641     if (*wp != OBJ_NAME_PATH_SEPARATOR) {
    01642         ZwClose(enumHandle);
    01643         ExFreePool(id);
    01644         KdPrint(("IopProcessNewDevice: Invalid device id return by driver (not in bus\\device format)\n"));
    01645         return STATUS_UNSUCCESSFUL;
    01646     }
    01647
    01648     *wp = UNICODE_NULL;
    01649
    01650     KeEnterCriticalRegion();
    01651     ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE);
    01652
    01653     //
    01654     // Open/Create enumerator key under HKLM\CCS\System\Enum
    01655     //
    01656
    01657     RtlInitUnicodeString(&unicodeName, busId);
    01658
    01659     status = IopCreateRegistryKeyEx( &busIdHandle,
    01660                                      enumHandle,
    01661                                      &unicodeName,
    01662                                      KEY_ALL_ACCESS,
    01663                                      REG_OPTION_NON_VOLATILE,
    01664                                      NULL
    01665                                      );
    01666
    01667     if (!NT_SUCCESS(status)) {
    01668         ExFreePool(id);
    01669         ZwClose(enumHandle);
    01670         goto exit;
    01671     }
    01672
    01673     //
    01674     // Open/create this registry path under HKLM\CCS\System\Enum<Enumerator>
    01675     //
    01676
    01677     RtlInitUnicodeString(&unicodeName, deviceId);
    01678     status = IopCreateRegistryKeyEx( &deviceIdHandle,
    01679                                      busIdHandle,
    01680                                      &unicodeName,
    01681                                      KEY_ALL_ACCESS,
    01682                                      REG_OPTION_NON_VOLATILE,
    01683                                      NULL
    01684                                      );
    01685
    01686     ZwClose(busIdHandle);
    01687     if (!NT_SUCCESS(status)) {
    01688         ExFreePool(id);
    01689         ZwClose(enumHandle);
    01690         goto exit;
    01691     }
    01692
    01693     ExReleaseResource(&PpRegistryDeviceResource);
    01694     KeLeaveCriticalRegion();
    01695
    01696     //
    01697     // Query the device's capabilities
    01698     // we will add this stuff to registry once we've processed it a bit
    01699     //
    01700
    01701     status = IopQueryDeviceCapabilities(DeviceNode, &capabilities);
    01702
    01703     if (capabilities.NoDisplayInUI) {
    01704
    01705         DeviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI;
    01706     }
    01707
    01708     //
    01709     // From the query capabilities call, determine if this a globally unique ID?
    01710     //
    01711
    01712     if (NT_SUCCESS(status) && (capabilities.UniqueID)) {
    01713         globallyUnique = TRUE;
    01714     }
    01715
    01716     //
    01717     // Record, is this a dock?
    01718     //
    01719     DeviceNode->DockInfo.DockStatus =
    01720         capabilities.DockDevice ? DOCK_QUIESCENT : DOCK_NOTDOCKDEVICE;
    01721
    01722     //
    01723     // Initialize the stack location to pass to IopSynchronousCall()
    01724     //
    01725
    01726     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    01727
    01728     //
    01729     // Query the device's description.
    01730     //
    01731
    01732     irpSp.MajorFunction = IRP_MJ_PNP;
    01733     irpSp.MinorFunction = IRP_MN_QUERY_DEVICE_TEXT;
    01734     irpSp.Parameters.QueryDeviceText.DeviceTextType = DeviceTextDescription;
    01735     irpSp.Parameters.QueryDeviceText.LocaleId = PsDefaultSystemLocaleId;
    01736     status = IopSynchronousCall(deviceObject, &irpSp, &description);
    01737
    01738     if (!NT_SUCCESS(status)) {
    01739         description = NULL;
    01740     }
    01741
    01742     //
    01743     // Initialize the stack location to pass to IopSynchronousCall()
    01744     //
    01745
    01746     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    01747
    01748     //
    01749     // Query the device's location information.
    01750     //
    01751
    01752     irpSp.MajorFunction = IRP_MJ_PNP;
    01753     irpSp.MinorFunction = IRP_MN_QUERY_DEVICE_TEXT;
    01754     irpSp.Parameters.QueryDeviceText.DeviceTextType = DeviceTextLocationInformation;
    01755     irpSp.Parameters.QueryDeviceText.LocaleId = PsDefaultSystemLocaleId;
    01756     status = IopSynchronousCall(deviceObject, &irpSp, &location);
    01757
    01758     if (!NT_SUCCESS(status)) {
    01759         location = NULL;
    01760     }
    01761
    01762     //
    01763     // Query the unique id for the device
    01764     //
    01765
    01766     IopQueryUniqueId(deviceObject, &uniqueId);
    01767
    01768     deviceNode = (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode;
    01769
    01770     if (!globallyUnique && deviceNode->Parent != IopRootDeviceNode) {
    01771         globallyUniqueId = NULL;
    01772
    01773         status = IopMakeGloballyUniqueId(deviceObject, uniqueId, &globallyUniqueId);
    01774
    01775         if (uniqueId != NULL) {
    01776             ExFreePool(uniqueId);
    01777         }
    01778
    01779         uniqueId = globallyUniqueId;
    01780
    01781     } else {
    01782
    01783         status = STATUS_SUCCESS;
    01784     }
    01785
    01786     if (!NT_SUCCESS(status) || uniqueId == NULL) {
    01787         if (description) {
    01788             ExFreePool(description);
    01789         }
    01790         if (location) {
    01791             ExFreePool(location);
    01792         }
    01793         ZwClose(deviceIdHandle);
    01794         ZwClose(enumHandle);
    01795         ExFreePool(id);
    01796         return status;
    01797     }
    01798
    01799     KeEnterCriticalRegion();
    01800     ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE);
    01801
    01802 RetryDuplicateId:
    01803
    01804     //
    01805     // Fixup the unique instance id if necessary
    01806     //
    01807     if (!IopFixupDeviceId(uniqueId)) {
    01808         KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
    01809                       PNP_ERR_BOGUS_ID,
    01810                       (ULONG_PTR)deviceObject,
    01811                       (ULONG_PTR)uniqueId,
    01812                       2);
    01813     }
    01814
    01815     length = (wcslen(busId) + wcslen(deviceId) + wcslen(uniqueId) + 5) * sizeof(WCHAR);
    01816     buffer = (PWCHAR)ExAllocatePool(PagedPool, length);
    01817     if (!buffer) {
    01818
    01819         ExReleaseResource(&PpRegistryDeviceResource);
    01820         KeLeaveCriticalRegion();
    01821
    01822         if (description) {
    01823             ExFreePool(description);
    01824         }
    01825         if (location) {
    01826             ExFreePool(location);
    01827         }
    01828         ZwClose(deviceIdHandle);
    01829         ZwClose(enumHandle);
    01830         ExFreePool(id);
    01831         return STATUS_INSUFFICIENT_RESOURCES;
    01832     }
    01833     swprintf(buffer, L"%s\\%s\\%s", busId, deviceId, uniqueId);
    01834     RtlInitUnicodeString(&unicodeDeviceInstance, buffer);
    01835
    01836     if (DeviceNode->InstancePath.Buffer != NULL) {
    01837
    01838         ExFreePool(DeviceNode->InstancePath.Buffer);
    01839         RtlInitUnicodeString(&DeviceNode->InstancePath, NULL);
    01840     }
    01841
    01842     IopConcatenateUnicodeStrings(&DeviceNode->InstancePath, &unicodeDeviceInstance, NULL);
    01843
    01844     //
    01845     // Open/create this registry device instance path under
    01846     // HKLM\System\Enum<Enumerator>\deviceId
    01847     //
    01848
    01849     RtlInitUnicodeString(&unicodeName, uniqueId);
    01850     status = IopCreateRegistryKeyEx( &uniqueIdHandle,
    01851                                      deviceIdHandle,
    01852                                      &unicodeName,
    01853                                      KEY_ALL_ACCESS,
    01854                                      REG_OPTION_NON_VOLATILE,
    01855                                      &disposition
    01856                                      );
    01857
    01858     if (!NT_SUCCESS(status)) {
    01859         ZwClose(enumHandle);
    01860         ExFreePool(id);
    01861         ZwClose(deviceIdHandle);
    01862         ExFreePool(uniqueId);
    01863         goto exit;
    01864     }
    01865
    01866     deviceObject->DeviceObjectExtension->ExtensionFlags |= DOE_START_PENDING;
    01867
    01868     DeviceNode->Flags |= DNF_PROCESSED;
    01869
    01870     //
    01871     // Check if the device instance is already reported.  If yes fail this request.
    01872     //
    01873
    01874     if (disposition != REG_CREATED_NEW_KEY) {
    01875
    01876         PDEVICE_OBJECT dupCheckDeviceObject;
    01877
    01878         //
    01879         // Retrieve the device node associated with this device instance name (if
    01880         // there is one).  If it's different from the device node we're currently
    01881         // working with, then we have a duplicate, and we want to remove it.
    01882         //
    01883
    01884         dupCheckDeviceObject = IopDeviceObjectFromDeviceInstance(uniqueIdHandle, NULL);
    01885
    01886         if (dupCheckDeviceObject) {
    01887
    01888             //
    01889             // Go ahead and dereference the device object now--we only need the
    01890             // value for comparison.
    01891             //
    01892
    01893             ObDereferenceObject(dupCheckDeviceObject);
    01894
    01895             if (dupCheckDeviceObject != deviceObject) {
    01896
    01897                 if (globallyUnique) {
    01898                     globallyUnique = FALSE;
    01899
    01900                     IopMakeGloballyUniqueId(deviceObject, uniqueId, &globallyUniqueId);
    01901
    01902                     if (uniqueId != NULL) {
    01903                         ExFreePool(uniqueId);
    01904                     }
    01905
    01906                     uniqueId = globallyUniqueId;
    01907
    01908                     ExFreePool(buffer);
    01909                     buffer = NULL;
    01910                     ZwClose(uniqueIdHandle);
    01911                     IopSetDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART);
    01912                     goto RetryDuplicateId;
    01913                 }
    01914
    01915                 KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
    01916                               PNP_ERR_DUPLICATE_PDO,
    01917                               (ULONG_PTR)deviceObject,
    01918                               (ULONG_PTR)dupCheckDeviceObject,
    01919                               0);
    01920
    01921 #if 0
    01922                 ZwClose(enumHandle);
    01923                 ZwClose(uniqueIdHandle);
    01924
    01925                 if (DeviceNode->InstancePath.Length != 0) {
    01926                     ExFreePool(DeviceNode->InstancePath.Buffer);
    01927                     DeviceNode->InstancePath.Length = 0;
    01928                     DeviceNode->InstancePath.Buffer = NULL;
    01929                 }
    01930
    01931                 IopRequestDeviceRemoval(deviceObject, CM_PROB_DEVICE_NOT_THERE);
    01932                 goto exit;
    01933 #endif
    01934             }
    01935         }
    01936     } else {
    01937
    01938         if (description) {
    01939             PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_DEVDESC);
    01940             ZwSetValueKey(uniqueIdHandle,
    01941                             &unicodeName,
    01942                             TITLE_INDEX_VALUE,
    01943                             REG_SZ,
    01944                             description,
    01945                             (wcslen(description)+1) * sizeof(WCHAR)
    01946                             );
    01947             ExFreePool(description);
    01948             description = NULL;
    01949         }
    01950     }
    01951
    01952     ExFreePool(id);
    01953     ZwClose(deviceIdHandle);
    01954     ExFreePool(uniqueId);
    01955
    01956     if (location) {
    01957         PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_LOCATION_INFORMATION);
    01958         ZwSetValueKey(uniqueIdHandle,
    01959                       &unicodeName,
    01960                       TITLE_INDEX_VALUE,
    01961                       REG_SZ,
    01962                       location,
    01963                       (wcslen(location)+1) * sizeof(WCHAR)
    01964                       );
    01965         ExFreePool(location);
    01966         location = NULL;
    01967     }
    01968
    01969     //
    01970     // now add the capabilities and UI_NUMBER into registry
    01971     //
    01972     status = IopDeviceCapabilitiesToRegistry(DeviceNode, &capabilities);
    01973
    01974 #if DBG
    01975     ASSERT(status == STATUS_SUCCESS);
    01976 #endif
    01977
    01978     PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF);
    01979     status = IopCreateRegistryKeyEx( &logConfHandle,
    01980                                      uniqueIdHandle,
    01981                                      &unicodeName,
    01982                                      KEY_ALL_ACCESS,
    01983                                      REG_OPTION_NON_VOLATILE,
    01984                                      NULL
    01985                                      );
    01986     if (!NT_SUCCESS(status)) {
    01987         logConfHandle = NULL;          // just to make sure
    01988     }
    01989
    01990     if (disposition == REG_CREATED_NEW_KEY) {    // disposition from uniqueId
    01991
    01992         //
    01993         // "new registry key" device installation case
    01994         //
    01995         // Set flags to control whether device installation needs to
    01996         // happen later. This means setting the devnode flag to
    01997         // DNF_NOT_CONFIGURED and setting the ConfigFlag ONLY if it's
    01998         // raw.
    01999         //
    02000
    02001         if (!IopIsDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART)) {
    02002             if (capabilities.RawDeviceOK) {
    02003                 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_CONFIG_FLAGS);
    02004                 tmpValue = CONFIGFLAG_FINISH_INSTALL;
    02005                 ZwSetValueKey(uniqueIdHandle,
    02006                                 &unicodeName,
    02007                                 TITLE_INDEX_VALUE,
    02008                                 REG_DWORD,
    02009                                 &tmpValue,
    02010                                 sizeof(tmpValue)
    02011                                 );
    02012             } else {
    02013                 IopSetDevNodeProblem(DeviceNode, CM_PROB_NOT_CONFIGURED);
    02014             }
    02015
    02016             //
    02017             // Process this as a critical device node.  This will setup
    02018             // the service, if necessary, so that the system can boot far
    02019             // enough to get to the config manager
    02020             //
    02021
    02022             processCriticalDevice = TRUE;
    02023         }
    02024
    02025     } else {
    02026
    02027         UCHAR buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION)+sizeof(ULONG)];
    02028         PKEY_VALUE_PARTIAL_INFORMATION keyInfo =
    02029             (PKEY_VALUE_PARTIAL_INFORMATION) buffer;
    02030
    02031         ULONG length;
    02032
    02033         UNICODE_STRING valueName;
    02034
    02035         NTSTATUS tmpStatus;
    02036
    02037         if (!IopIsDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART)) {
    02038
    02039             RtlInitUnicodeString(&valueName, REGSTR_VALUE_CONFIG_FLAGS);
    02040             tmpStatus = ZwQueryValueKey(uniqueIdHandle,
    02041                                         &valueName,
    02042                                         KeyValuePartialInformation,
    02043                                         keyInfo,
    02044                                         sizeof(buffer),
    02045                                         &length);
    02046
    02047             if (NT_SUCCESS(tmpStatus)) {
    02048
    02049                 ULONG configFlags = *(PULONG)keyInfo->Data;
    02050
    02051                 //
    02052                 // The ConfigFlags value exists in the registry
    02053                 // If DNF_REINSTALL is set.  We mark it as DNF_DELETED such that we will not
    02054                 // start the device.  Later when the reinstallation completes, the
    02055                 // DNF_RESTART_OK bit will be set and DNF_DELETED will be deleted.
    02056                 //
    02057
    02058                 if (configFlags & CONFIGFLAG_REINSTALL) {
    02059                     IopSetDevNodeProblem(DeviceNode, CM_PROB_REINSTALL);
    02060                     processCriticalDevice = TRUE;  // to install critical driver
    02061                 } else if (configFlags & CONFIGFLAG_FAILEDINSTALL) {
    02062                     IopSetDevNodeProblem(DeviceNode, CM_PROB_FAILED_INSTALL);
    02063                     processCriticalDevice = TRUE;  // to install critical driver
    02064                 }
    02065             } else {
    02066                 //
    02067                 // The ConfigFlag value does not exist in the registry
    02068                 //
    02069                 IopSetDevNodeProblem(DeviceNode, CM_PROB_NOT_CONFIGURED);
    02070             }
    02071         }
    02072
    02073         RtlInitUnicodeString(&valueName, REGSTR_VALUE_SERVICE);
    02074
    02075         tmpStatus = ZwQueryValueKey(uniqueIdHandle,
    02076                                     &valueName,
    02077                                     KeyValuePartialInformation,
    02078                                     keyInfo,
    02079                                     sizeof(buffer),
    02080                                     &length);
    02081
    02082         //
    02083         // if there's no service setup then check to see if this should
    02084         // be processed as a critical device.
    02085         //
    02086
    02087         if (NT_SUCCESS(tmpStatus) && (keyInfo->DataLength <= sizeof(L'\0'))) {
    02088             processCriticalDevice = TRUE;
    02089         } else if (tmpStatus == STATUS_OBJECT_NAME_NOT_FOUND) {
    02090             processCriticalDevice = TRUE;
    02091         }
    02092     }
    02093
    02094     if (capabilities.HardwareDisabled &&
    02095         !IopIsDevNodeProblem(DeviceNode, CM_PROB_NOT_CONFIGURED) &&
    02096         !IopIsDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART)) {
    02097         //
    02098         // mark the node as hardware disabled, if no configuration problems
    02099         //
    02100         IopClearDevNodeProblem(DeviceNode);
    02101         IopSetDevNodeProblem(DeviceNode, CM_PROB_HARDWARE_DISABLED);
    02102         //
    02103         // Issue a PNP REMOVE_DEVICE Irp so when we query resources
    02104         // we have those required after boot
    02105         //
    02106         status = IopRemoveDevice(deviceObject, IRP_MN_REMOVE_DEVICE);
    02107         ASSERT(NT_SUCCESS(status));
    02108
    02109     } else {
    02110         //
    02111         // these are the only problems I expect at this point
    02112         //
    02113         ASSERT(!IopDoesDevNodeHaveProblem(DeviceNode) ||
    02114                IopIsDevNodeProblem(DeviceNode, CM_PROB_NOT_CONFIGURED) ||
    02115                IopIsDevNodeProblem(DeviceNode, CM_PROB_REINSTALL) ||
    02116                IopIsDevNodeProblem(DeviceNode, CM_PROB_FAILED_INSTALL) ||
    02117                IopIsDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART));
    02118     }
    02119
    02120     //
    02121     // Create all the default value entry for the newly created key.
    02122     // Configuration = REG_RESOURCE_LIST
    02123     // ConfigurationVector = REG_RESOUCE_REQUIREMENTS_LIST
    02124     // HardwareID = MULTI_SZ
    02125     // CompatibleIDs = MULTI_SZ
    02126     // Create "Control" volatile subkey.
    02127     //
    02128
    02129     PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
    02130     status = IopCreateRegistryKeyEx( &handle,
    02131                                      uniqueIdHandle,
    02132                                      &unicodeName,
    02133                                      KEY_ALL_ACCESS,
    02134                                      REG_OPTION_VOLATILE,
    02135                                      NULL
    02136                                      );
    02137     if (NT_SUCCESS(status)) {
    02138
    02139         //
    02140         // Write DeviceObject reference ...
    02141         //
    02142
    02143         PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_DEVICE_REFERENCE);
    02144         status = ZwSetValueKey( handle,
    02145                                 &unicodeName,
    02146                                 TITLE_INDEX_VALUE,
    02147                                 REG_DWORD,
    02148                                 (PULONG_PTR)&deviceObject,
    02149                                 sizeof(ULONG_PTR)
    02150                                 );
    02151         ZwClose(handle);
    02152     }
    02153
    02154     if (!NT_SUCCESS(status)) {
    02155         ZwClose(enumHandle);
    02156         ZwClose(uniqueIdHandle);
    02157         if (logConfHandle) {
    02158             ZwClose(logConfHandle);
    02159         }
    02160         goto exit;
    02161     }
    02162
    02163     ZwClose(enumHandle);
    02164
    02165     //
    02166     // Release registry lock before calling device driver
    02167     //
    02168
    02169     ExReleaseResource(&PpRegistryDeviceResource);
    02170     KeLeaveCriticalRegion();
    02171
    02172     status = IopQueryCompatibleIds( deviceObject,
    02173                                     BusQueryHardwareIDs,
    02174                                     &hwIds,
    02175                                     &hwIdLength);
    02176
    02177     if (!NT_SUCCESS(status)) {
    02178         hwIds = NULL;
    02179     }
    02180
    02181     status = IopQueryCompatibleIds( deviceObject,
    02182                                     BusQueryCompatibleIDs,
    02183                                     &compatibleIds,
    02184                                     &compatibleIdLength);
    02185     if (!NT_SUCCESS(status)) {
    02186         compatibleIds = NULL;
    02187     }
    02188
    02189     //
    02190     // Query the device's basic config vector. This needs to be done before we check if
    02191     // this is a remote BOOT card.
    02192     //
    02193
    02194     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    02195     irpSp.MajorFunction = IRP_MJ_PNP;
    02196     irpSp.MinorFunction = IRP_MN_QUERY_RESOURCE_REQUIREMENTS;
    02197     status = IopSynchronousCall(deviceObject, &irpSp, &ioResource);
    02198
    02199     if (!NT_SUCCESS(status)) {
    02200         ioResource = NULL;
    02201     }
    02202     if (ioResource) {
    02203         ioLength = ioResource->ListSize;
    02204     }
    02205
    02206     KeEnterCriticalRegion();
    02207     ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE);
    02208
    02209     //
    02210     // Write resource requirements to registry
    02211     //
    02212
    02213     if (logConfHandle) {
    02214         PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_BASIC_CONFIG_VECTOR);
    02215         if (ioResource) {
    02216             ZwSetValueKey(logConfHandle,
    02217                             &unicodeName,
    02218                             TITLE_INDEX_VALUE,
    02219                             REG_RESOURCE_REQUIREMENTS_LIST,
    02220                             ioResource,
    02221                             ioLength
    02222                             );
    02223             DeviceNode->ResourceRequirements = ioResource;
    02224             DeviceNode->Flags |= DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED;
    02225         } else {
    02226             ZwDeleteValueKey(logConfHandle, &unicodeName);
    02227         }
    02228     }
    02229
    02230     //
    02231     // While we have the hwIds, check if this is the device node
    02232     // for the remote boot net card. If IopLoaderBlock is NULL
    02233     // then we are not initilizing boot drivers so we don't have
    02234     // to check for this.
    02235     //
    02236
    02237     if (IoRemoteBootClient && (IopLoaderBlock != NULL)) {
    02238
    02239         if (hwIds) {
    02240             isRemoteBootCard = IopIsRemoteBootCard(
    02241                                     DeviceNode,
    02242                                     (PLOADER_PARAMETER_BLOCK)IopLoaderBlock,
    02243                                     hwIds);
    02244         }
    02245         if (!isRemoteBootCard && compatibleIds) {
    02246             isRemoteBootCard = IopIsRemoteBootCard(
    02247                                     DeviceNode,
    02248                                     (PLOADER_PARAMETER_BLOCK)IopLoaderBlock,
    02249                                     compatibleIds);
    02250         }
    02251     }
    02252
    02253     //
    02254     // create HardwareId value name.  It is a MULTI_SZ,
    02255     //
    02256
    02257     if (hwIds) {
    02258
    02259         if (!IopFixupIds(hwIds, hwIdLength)) {
    02260             KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
    02261                           PNP_ERR_BOGUS_ID,
    02262                           (ULONG_PTR)deviceObject,
    02263                           (ULONG_PTR)hwIds,
    02264                           3);
    02265         }
    02266         PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_HARDWAREID);
    02267         ZwSetValueKey(uniqueIdHandle,
    02268                         &unicodeName,
    02269                         TITLE_INDEX_VALUE,
    02270                         REG_MULTI_SZ,
    02271                         hwIds,
    02272                         hwIdLength
    02273                         );
    02274         ExFreePool(hwIds);
    02275     }
    02276
    02277     //
    02278     // create CompatibleId value name.  It is a MULTI_SZ,
    02279     //
    02280
    02281     if (compatibleIds) {
    02282
    02283         if (!IopFixupIds(compatibleIds, compatibleIdLength)) {
    02284             KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
    02285                             PNP_ERR_BOGUS_ID,
    02286                             (ULONG_PTR)deviceObject,
    02287                             (ULONG_PTR)compatibleIds,
    02288                             4);
    02289         }
    02290         PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_COMPATIBLEIDS);
    02291         ZwSetValueKey(uniqueIdHandle,
    02292                         &unicodeName,
    02293                         TITLE_INDEX_VALUE,
    02294                         REG_MULTI_SZ,
    02295                         compatibleIds,
    02296                         compatibleIdLength
    02297                         );
    02298         ExFreePool(compatibleIds);
    02299     }
    02300
    02301     //
    02302     // If this is the devnode for the remote boot card, do
    02303     // special setup for it.
    02304     //
    02305
    02306     if (isRemoteBootCard) {
    02307
    02308         status = IopSetupRemoteBootCard(
    02309                         (PLOADER_PARAMETER_BLOCK)IopLoaderBlock,
    02310                         uniqueIdHandle,
    02311                         &unicodeDeviceInstance);
    02312
    02313         if (status != STATUS_SUCCESS) {
    02314             goto exit;
    02315         }
    02316
    02317         //
    02318         // HACK BUGBUG: Need to turn this off, or else the device won't
    02319         // be allowed to be opened until the PNP start IRP is done. Unfortunately
    02320         // that is exactly what NDIS does in the start IRP handler - adamba 3/31/99
    02321         //
    02322
    02323         deviceObject->DeviceObjectExtension->ExtensionFlags &= ~DOE_START_PENDING;
    02324
    02325     }
    02326
    02327     ExReleaseResource(&PpRegistryDeviceResource);
    02328     KeLeaveCriticalRegion();
    02329
    02330     //
    02331     // we've pretty much got the PDO information ready, apart from Child bus information
    02332     // get that now, because class-installer may want it
    02333     //
    02334     status = IopQueryPnpBusInformation(
    02335                  deviceObject,
    02336                  &busTypeGuid,
    02337                  &DeviceNode->ChildInterfaceType,
    02338                  &DeviceNode->ChildBusNumber
    02339              );
    02340
    02341     if (NT_SUCCESS(status)) {
    02342
    02343         DeviceNode->ChildBusTypeIndex = IopGetBusTypeGuidIndex(&busTypeGuid);
    02344
    02345     } else {
    02346
    02347         DeviceNode->ChildBusTypeIndex = 0xffff;
    02348         DeviceNode->ChildInterfaceType = InterfaceTypeUndefined;
    02349         DeviceNode->ChildBusNumber = 0xfffffff0;
    02350
    02351     }
    02352
    02353     //
    02354     // we check HardwareDisabled directly in case it's a new device
    02355     //
    02356     if (processCriticalDevice && !capabilities.HardwareDisabled &&
    02357         !IopIsDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART)) {
    02358
    02359         IopProcessCriticalDevice(DeviceNode);
    02360     }
    02361
    02362     //
    02363     // Set DNF_DISABLED flag if the device instance is disabled.
    02364     //
    02365
    02366     ASSERT(!IopDoesDevNodeHaveProblem(DeviceNode) ||
    02367            IopIsDevNodeProblem(DeviceNode, CM_PROB_NOT_CONFIGURED) ||
    02368            IopIsDevNodeProblem(DeviceNode, CM_PROB_REINSTALL) ||
    02369            IopIsDevNodeProblem(DeviceNode, CM_PROB_FAILED_INSTALL) ||
    02370            IopIsDevNodeProblem(DeviceNode, CM_PROB_PARTIAL_LOG_CONF) ||
    02371            IopIsDevNodeProblem(DeviceNode, CM_PROB_HARDWARE_DISABLED) ||
    02372            IopIsDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART));
    02373     if (!IopIsDevNodeProblem(DeviceNode, CM_PROB_DISABLED) &&
    02374         !IopIsDevNodeProblem(DeviceNode, CM_PROB_HARDWARE_DISABLED) &&
    02375         !IopIsDevNodeProblem(DeviceNode, CM_PROB_NEED_RESTART)) {
    02376
    02377         IopIsDeviceInstanceEnabled(uniqueIdHandle, &unicodeDeviceInstance, TRUE);
    02378     }
    02379
    02380     //
    02381     // This code HAS to be after we have checked for DISABLED device.
    02382     // We could end up here from an ENABLE following a DISABLE.
    02383     // Query for BOOT config if there is none already present.
    02384     //
    02385
    02386     cmResource = NULL;
    02387     if (DeviceNode->BootResources == NULL) {
    02388         status = IopQueryDeviceResources( deviceObject,
    02389                                           QUERY_RESOURCE_LIST,
    02390                                           &cmResource,
    02391                                           &cmLength );
    02392         if (!NT_SUCCESS(status)) {
    02393             cmResource = NULL;
    02394         }
    02395     } else {
    02396
    02397         DebugPrint(1,
    02398                    ("PNPENUM: %ws already has BOOT config in IopProcessNewDeviceNode!\n",
    02399                    DeviceNode->InstancePath.Buffer));
    02400     }
    02401
    02402     KeEnterCriticalRegion();
    02403     ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE);
    02404
    02405     //
    02406     // Write boot resources to registry
    02407     //
    02408     if (logConfHandle && DeviceNode->BootResources == NULL) {
    02409         PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_BOOTCONFIG);
    02410         if (cmResource) {
    02411             ZwSetValueKey(
    02412                         logConfHandle,
    02413                         &unicodeName,
    02414                         TITLE_INDEX_VALUE,
    02415                         REG_RESOURCE_LIST,
    02416                         cmResource,
    02417                         cmLength
    02418                         );
    02419
    02420             ExReleaseResource(&PpRegistryDeviceResource);
    02421
    02422             //
    02423             // This device consumes BOOT resources.  Reserve its boot resources
    02424             //
    02425
    02426             status = (*IopReserveResourcesRoutine)(ArbiterRequestPnpEnumerated,
    02427                                                     deviceObject,
    02428                                                     cmResource);
    02429
    02430             ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE);
    02431
    02432             if (NT_SUCCESS(status)) {
    02433                 DeviceNode->Flags |= DNF_HAS_BOOT_CONFIG;
    02434             }
    02435             ExFreePool(cmResource);
    02436         } else {
    02437             ZwDeleteValueKey(logConfHandle, &unicodeName);
    02438         }
    02439     }
    02440
    02441     //
    02442     // SurpriseRemovalOK bits may have changed due to DNF_HAS_BOOT_CONFIG.
    02443     //
    02444     status = IopDeviceCapabilitiesToRegistry(DeviceNode,&capabilities);
    02445
    02446 #if DBG
    02447     ASSERT(status == STATUS_SUCCESS);
    02448 #endif
    02449
    02450     //
    02451     // Clean up
    02452     //
    02453
    02454     if (logConfHandle) {
    02455         ZwClose(logConfHandle);
    02456     }
    02457
    02458     ExReleaseResource(&PpRegistryDeviceResource);
    02459     KeLeaveCriticalRegion();
    02460
    02461     //
    02462     // Create new value entry under ServiceKeyName\Enum to reflect the newly
    02463     // added made-up device instance node.
    02464     //
    02465
    02466     status = IopNotifySetupDeviceArrival( deviceObject,
    02467                                           uniqueIdHandle,
    02468                                           TRUE);
    02469
    02470     configuredBySetup = NT_SUCCESS(status);
    02471
    02472     status = PpDeviceRegistration(
    02473                  &unicodeDeviceInstance,
    02474                  TRUE,
    02475                  &DeviceNode->ServiceName
    02476                  );
    02477
    02478     if (NT_SUCCESS(status) && (configuredBySetup || isRemoteBootCard) &&
    02479         IopIsDevNodeProblem(DeviceNode, CM_PROB_NOT_CONFIGURED)) {
    02480
    02481         IopClearDevNodeProblem(DeviceNode);
    02482     }
    02483
    02484     //
    02485     // Add an event so user-mode will attempt to install this device later.
    02486     //
    02487     PpSetPlugPlayEvent( &GUID_DEVICE_ENUMERATED,
    02488                         deviceObject);
    02489
    02490     ZwClose(uniqueIdHandle);
    02491
    02492     if (buffer) {
    02493         ExFreePool(buffer);
    02494     }
    02495     if (description) {
    02496         ExFreePool(description);
    02497     }
    02498     if (location) {
    02499         ExFreePool(location);
    02500     }
    02501     return STATUS_SUCCESS;
    02502
    02503 exit:
    02504
    02505     //
    02506     // In case of failure, we don't set the DNF_PROCESSED flags.  So the device
    02507     // will be processed again later.
    02508     //
    02509
    02510     ExReleaseResource(&PpRegistryDeviceResource);
    02511     KeLeaveCriticalRegion();
    02512     if (buffer) {
    02513         ExFreePool(buffer);
    02514     }
    02515     if (description) {
    02516         ExFreePool(description);
    02517     }
    02518     if (location) {
    02519         ExFreePool(location);
    02520     }
    02521     return status;
    02522 }

NTSTATUS IopProcessNewProfile | ( | VOID |  | ) |

Definition at line 5034 of file pnpenum.c.

References CriticalWorkQueue, ExAllocatePool, ExInitializeWorkItem, ExQueueWorkItem(), IopProcessNewProfileWorker(), NonPagedPool, and PAGED_CODE.

Referenced by IopHardwareProfileCancelRemovedDock(), IopHardwareProfileCommitRemovedDock(), and IopHardwareProfileCommitStartedDock().

    05040                    :
    05041
    05042     This function is called after the system has transitioned into a new
    05043     hardware profile. The thread from which it is called may be holding an
    05044     enumeration lock. Calling this function does two tasks:
    05045
    05046     1) If a disabled devnode in the tree should be enabled in this new hardware
    05047        profile state, it will be started.
    05048
    05049     2) If an enabled devnode in the tree should be disabled in this new hardware
    05050        profile state, it will be (surprise) removed.
    05051
    05052     ADRIAO N.B. 02/19/1999 -
    05053         Why surprise remove? There are four cases to be handled:
    05054         a) Dock disappearing, need to enable device in new profile
    05055         b) Dock appearing, need to enable device in new profile
    05056         c) Dock disappearing, need to disable device in new profile
    05057         d) Dock appearing, need to disable device in new profile
    05058
    05059         a) and b) are trivial. c) involves treating the appropriate devices as
    05060         if they were in the removal relation lists for the dock. d) is another
    05061         matter altogether as we need to query-remove/remove devices before
    05062         starting another. NT5's PnP state machine cannot handle this, so for
    05063         this release we cleanup rather hastily after the profile change.
    05064
    05065 Parameters:
    05066
    05067     NONE.
    05068
    05069 Return Value:
    05070
    05071     NTSTATUS.
    05072
    05073 --*/
    05074 {
    05075     PWORK_QUEUE_ITEM workQueueItem;
    05076
    05077     PAGED_CODE();
    05078
    05079     workQueueItem = (PWORK_QUEUE_ITEM) ExAllocatePool(
    05080         NonPagedPool,
    05081         sizeof(WORK_QUEUE_ITEM)
    05082         );
    05083
    05084     if (workQueueItem) {
    05085
    05086         //
    05087         // Queue this up so we can walk the tree outside of the enumeration lock.
    05088         //
    05089         ExInitializeWorkItem(
    05090             workQueueItem,
    05091             IopProcessNewProfileWorker,
    05092             workQueueItem
    05093             );
    05094
    05095         ExQueueWorkItem(
    05096             workQueueItem,
    05097             CriticalWorkQueue
    05098             );
    05099
    05100         return STATUS_SUCCESS;
    05101
    05102     } else {
    05103
    05104         return STATUS_INSUFFICIENT_RESOURCES;
    05105     }
    05106 }

NTSTATUS IopProcessNewProfileStateCallback | ( | IN PDEVICE_NODE | DeviceNode,
|  | IN PVOID | Context
| ) |

Definition at line 5138 of file pnpenum.c.

References BusRelations, DNF_STARTED, FALSE, IoInvalidateDeviceRelations(), IopClearDevNodeProblem, IopIsDeviceInstanceEnabled(), IopIsDevNodeProblem, IopRequestDeviceRemoval(), NULL, PAGED_CODE, _DEVICE_NODE::Parent, and _DEVICE_NODE::PhysicalDeviceObject.

Referenced by IopProcessNewProfileWorker().

    05145                    :
    05146
    05147     This function is called for each devnode after the system has transitioned
    05148     hardware profile states.
    05149
    05150 Parameters:
    05151
    05152     NONE.
    05153
    05154 Return Value:
    05155
    05156     NONE.
    05157
    05158 --*/
    05159 {
    05160     PDEVICE_NODE parentDevNode;
    05161
    05162     PAGED_CODE();
    05163
    05164     if (DeviceNode->Flags & DNF_STARTED) {
    05165
    05166         //
    05167         // Calling this function will disable the device if it is appropriate
    05168         // to do so.
    05169         //
    05170         if (!IopIsDeviceInstanceEnabled(NULL, &DeviceNode->InstancePath, FALSE)) {
    05171
    05172             IopRequestDeviceRemoval(
    05173                 DeviceNode->PhysicalDeviceObject,
    05174                 CM_PROB_DISABLED
    05175                 );
    05176         }
    05177
    05178     } else if (IopIsDevNodeProblem(DeviceNode, CM_PROB_DISABLED)) {
    05179
    05180         //
    05181         // We might be turning on the device. So we will clear the problem
    05182         // flags iff the device problem was CM_PROB_DISABLED.
    05183         //
    05184         IopClearDevNodeProblem(DeviceNode);
    05185
    05186         //
    05187         // Make sure the device stays down iff appropriate.
    05188         //
    05189         if (IopIsDeviceInstanceEnabled(NULL, &DeviceNode->InstancePath, FALSE)) {
    05190
    05191             //
    05192             // This device should come back online. Queue up an enumeration
    05193             // at the parent level for him.
    05194             //
    05195             parentDevNode = DeviceNode->Parent;
    05196
    05197             IoInvalidateDeviceRelations(
    05198                 parentDevNode->PhysicalDeviceObject,
    05199                 BusRelations
    05200                 );
    05201         }
    05202     }
    05203
    05204     return STATUS_SUCCESS;
    05205 }
    }

VOID IopProcessNewProfileWorker | ( | IN PVOID | Context | ) |

Definition at line 5109 of file pnpenum.c.

References ExFreePool(), IopForAllDeviceNodes(), IopProcessNewProfileStateCallback(), NULL, and PAGED_CODE.

Referenced by IopProcessNewProfile().

    05115                    :
    05116
    05117     This function is called for each devnode after the system has transitioned
    05118     to a new hardware profile.
    05119
    05120 Parameters:
    05121
    05122     NONE.
    05123
    05124 Return Value:
    05125
    05126     NONE.
    05127
    05128 --*/
    05129 {
    05130     PAGED_CODE();
    05131
    05132     IopForAllDeviceNodes(IopProcessNewProfileStateCallback, NULL);
    05133
    05134     ExFreePool(Context);
    05135 }

NTSTATUS IopProcessSetInterfaceState | ( | IN PUNICODE_STRING | SymbolicLinkName,
|  | IN BOOLEAN | Enable,
|  | IN BOOLEAN | DeferNotStarted
| ) |

Definition at line 9922 of file pnpioapi.c.

References ASSERT, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DevicePropertyPhysicalDeviceObjectName, DOE_START_PENDING, ExAllocatePool, ExFreePool(), _DEVOBJ_EXTENSION::ExtensionFlags, IoCreateSymbolicLink(), IoDeleteSymbolicLink(), IoGetDeviceProperty(), IopCreateRegistryKeyEx(), IopDeviceInterfaceKeysFromSymbolicLink(), IopDeviceObjectFromDeviceInstance(), IopDropReferenceString(), IopGetRegistryValue(), IopParseSymbolicLinkName(), IopRegistryDataToUnicodeString, IopSetupDeviceObjectFromDeviceClass(), KEY_VALUE_DATA, _PENDING_SET_INTERFACE_STATE::LinkName, List, _PENDING_SET_INTERFACE_STATE::List, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, PAGED_CODE, PagedPool, _DEVICE_NODE::PendedSetInterfaceState, PENDING_SET_INTERFACE_STATE, PpSetDeviceClassChange(), RtlEqualUnicodeString(), RtlInitUnicodeString(), and TRUE.

Referenced by IopDoDeferredSetInterfaceState(), and IoSetDeviceInterfaceState().

    09929                    :
    09930
    09931     This DDI allows a device class to activate and deactivate an association
    09932     previously registered using IoRegisterDeviceInterface
    09933
    09934 Parameters:
    09935
    09936     SymbolicLinkName - Supplies a pointer to the symbolic link name which was
    09937         returned by IoRegisterDeviceInterface when the interface was registered,
    09938         or as returned by IoGetDeviceInterfaces.
    09939
    09940     Enable - If TRUE (non-zero), the interface will be enabled.  If FALSE, it
    09941         will be disabled.
    09942
    09943     DeferNotStarted - If TRUE then enables will be queued if the PDO isn't
    09944         started.  It is FALSE when we've started the PDO and are processing the
    09945         queued enables.
    09946
    09947 Return Value:
    09948
    09949     Status code that indicates whether or not the function was successful.
    09950
    09951 --*/
    09952
    09953 {
    09954     NTSTATUS status;
    09955     HANDLE hInterfaceClassKey = NULL;
    09956     HANDLE hInterfaceParentKey= NULL, hInterfaceInstanceKey = NULL;
    09957     HANDLE hInterfaceParentControl = NULL, hInterfaceInstanceControl = NULL;
    09958     UNICODE_STRING tempString, actualSymbolicLinkName, deviceNameString;
    09959     PKEY_VALUE_FULL_INFORMATION pKeyValueInfo;
    09960     ULONG linked, refcount;
    09961     GUID guid;
    09962     PDEVICE_OBJECT physicalDeviceObject;
    09963     PWCHAR deviceNameBuffer = NULL;
    09964     ULONG deviceNameBufferLength;
    09965
    09966     PAGED_CODE();
    09967
    09968     //
    09969     // Get the symbolic link name without the ref string
    09970     //
    09971
    09972     status = IopDropReferenceString(&actualSymbolicLinkName, SymbolicLinkName);
    09973     if (!NT_SUCCESS(status)) {
    09974         goto clean0;
    09975     }
    09976
    09977     //
    09978     // Extract the device class guid
    09979     //
    09980
    09981     status = IopParseSymbolicLinkName(SymbolicLinkName, NULL, NULL, NULL, NULL, NULL, &guid);
    09982
    09983     //
    09984     // Get function class instance handle
    09985     //
    09986
    09987     status = IopDeviceInterfaceKeysFromSymbolicLink(SymbolicLinkName,
    09988                                                     KEY_READ | KEY_WRITE,
    09989                                                     &hInterfaceClassKey,
    09990                                                     &hInterfaceParentKey,
    09991                                                     &hInterfaceInstanceKey
    09992                                                     );
    09993
    09994     if (!NT_SUCCESS(status)) {
    09995         goto clean1;
    09996     }
    09997
    09998     //
    09999     // Open the parent interface control subkey
    10000     //
    10001     PiWstrToUnicodeString(&tempString, REGSTR_KEY_CONTROL);
    10002     status = IopCreateRegistryKeyEx( &hInterfaceParentControl,
    10003                                      hInterfaceParentKey,
    10004                                      &tempString,
    10005                                      KEY_READ,
    10006                                      REG_OPTION_VOLATILE,
    10007                                      NULL
    10008                                      );
    10009     if (!NT_SUCCESS(status)) {
    10010         goto clean1;
    10011     }
    10012
    10013
    10014     //
    10015     // Find out the name of the device instance that 'owns' this interface.
    10016     //
    10017     status = IopGetRegistryValue(hInterfaceParentKey,
    10018                                  REGSTR_VAL_DEVICE_INSTANCE,
    10019                                  &pKeyValueInfo
    10020                                  );
    10021
    10022     if(NT_SUCCESS(status)) {
    10023         //
    10024         // Open the device instance control subkey
    10025         //
    10026         PiWstrToUnicodeString(&tempString, REGSTR_KEY_CONTROL);
    10027         status = IopCreateRegistryKeyEx( &hInterfaceInstanceControl,
    10028                                          hInterfaceInstanceKey,
    10029                                          &tempString,
    10030                                          KEY_READ,
    10031                                          REG_OPTION_VOLATILE,
    10032                                          NULL
    10033                                          );
    10034         if(!NT_SUCCESS(status)) {
    10035             ExFreePool(pKeyValueInfo);
    10036             hInterfaceInstanceControl = NULL;
    10037         }
    10038     }
    10039
    10040     if (!NT_SUCCESS(status)) {
    10041         goto clean2;
    10042     }
    10043
    10044     //
    10045     // Find the PDO corresponding to this device instance name.
    10046     //
    10047     if (pKeyValueInfo->Type == REG_SZ) {
    10048
    10049         IopRegistryDataToUnicodeString(&tempString,
    10050                                         (PWSTR)KEY_VALUE_DATA(pKeyValueInfo),
    10051                                         pKeyValueInfo->DataLength
    10052                                         );
    10053
    10054         physicalDeviceObject = IopDeviceObjectFromDeviceInstance(NULL, &tempString);
    10055
    10056         if (physicalDeviceObject) {
    10057
    10058             //
    10059             // DeferNotStarted is set TRUE if we are being called from
    10060             // IoSetDeviceInterfaceState.  It will be set FALSE if we are
    10061             // processing previously queued operations as we are starting the
    10062             // device.
    10063             //
    10064
    10065             if (DeferNotStarted) {
    10066
    10067                 if (physicalDeviceObject->DeviceObjectExtension->ExtensionFlags & DOE_START_PENDING) {
    10068
    10069                     PDEVICE_NODE deviceNode;
    10070                     PPENDING_SET_INTERFACE_STATE pendingSetState;
    10071
    10072                     //
    10073                     // The device hasn't been started yet.  We need to queue
    10074                     // any enables and remove items from the queue on a disable.
    10075                     //
    10076                     deviceNode = (PDEVICE_NODE)physicalDeviceObject->DeviceObjectExtension->DeviceNode;
    10077
    10078                     if (Enable) {
    10079
    10080                         pendingSetState = ExAllocatePool( PagedPool,
    10081                                                           sizeof(PENDING_SET_INTERFACE_STATE));
    10082
    10083                         if (pendingSetState != NULL) {
    10084
    10085                             pendingSetState->LinkName.Buffer = ExAllocatePool( PagedPool,
    10086                                                                                SymbolicLinkName->Length);
    10087
    10088                             if (pendingSetState->LinkName.Buffer != NULL) {
    10089
    10090                                 //
    10091                                 // Capture the callers info and queue it to the
    10092                                 // devnode.  Once the device stack is started
    10093                                 // we will dequeue and process it.
    10094                                 //
    10095                                 pendingSetState->LinkName.MaximumLength = SymbolicLinkName->Length;
    10096                                 pendingSetState->LinkName.Length = SymbolicLinkName->Length;
    10097                                 RtlCopyMemory( pendingSetState->LinkName.Buffer,
    10098                                                SymbolicLinkName->Buffer,
    10099                                                SymbolicLinkName->Length);
    10100                                 InsertTailList( &deviceNode->PendedSetInterfaceState,
    10101                                                 &pendingSetState->List);
    10102
    10103                                 ExFreePool(pKeyValueInfo);
    10104
    10105                                 ObDereferenceObject(physicalDeviceObject);
    10106
    10107                                 status = STATUS_SUCCESS;
    10108                                 goto clean2;
    10109
    10110                             } else {
    10111                                 //
    10112                                 // Couldn't allocate a buffer to hold the
    10113                                 // symbolic link name.
    10114                                 //
    10115
    10116                                 ExFreePool(pendingSetState);
    10117                                 status = STATUS_INSUFFICIENT_RESOURCES;
    10118                             }
    10119
    10120                         } else {
    10121                             //
    10122                             // Couldn't allocate the PENDING_SET_INTERFACE_STATE
    10123                             // structure.
    10124                             //
    10125
    10126
    10127                             status = STATUS_INSUFFICIENT_RESOURCES;
    10128                         }
    10129
    10130                     } else {
    10131
    10132                         PLIST_ENTRY entry;
    10133
    10134                         //
    10135                         // We are disabling an interface.  Since we aren't
    10136                         // started yet we should have queued the enable.  Now
    10137                         // we go back and find the matching enable and remove
    10138                         // it from the queue.
    10139                         //
    10140
    10141                         for (entry = deviceNode->PendedSetInterfaceState.Flink;
    10142                              entry != &deviceNode->PendedSetInterfaceState;
    10143                              entry = entry->Flink)  {
    10144
    10145                             pendingSetState = CONTAINING_RECORD( entry,
    10146                                                                  PENDING_SET_INTERFACE_STATE,
    10147                                                                  List );
    10148
    10149                             if (RtlEqualUnicodeString( &pendingSetState->LinkName,
    10150                                                        SymbolicLinkName,
    10151                                                        TRUE)) {
    10152
    10153                                 //
    10154                                 // We found it, remove it from the list and
    10155                                 // free it.
    10156                                 //
    10157                                 RemoveEntryList(&pendingSetState->List);
    10158
    10159                                 ExFreePool(pendingSetState->LinkName.Buffer);
    10160                                 ExFreePool(pendingSetState);
    10161
    10162                                 break;
    10163                             }
    10164                         }
    10165
    10166 #if 0
    10167                         //
    10168                         // Debug code to catch the case where we couldn't find
    10169                         // the entry to remove.  This could happen if we messed
    10170                         // up adding the entry to the list or the driver disabled
    10171                         // an interface without first enabling it.  Either way
    10172                         // it probably merits some investigation.
    10173                         //
    10174                         if (entry == &deviceNode->PendedSetInterfaceState) {
    10175                             PIDBGMSG(PIDBG_ERROR,
    10176                                      ("IopProcessSetInterfaceState: Disable couldn't find deferred enable, DeviceNode = 0x%p, SymbolicLink = \"%Z\"\n",
    10177                                      deviceNode,
    10178                                      SymbolicLinkName));
    10179                         }
    10180
    10181                         ASSERT(entry != &deviceNode->PendedSetInterfaceState);
    10182 #endif
    10183                         ExFreePool(pKeyValueInfo);
    10184
    10185                         ObDereferenceObject(physicalDeviceObject);
    10186
    10187                         status = STATUS_SUCCESS;
    10188                         goto clean2;
    10189                     }
    10190                 }
    10191             }
    10192
    10193             if (!Enable || !NT_SUCCESS(status)) {
    10194                 ObDereferenceObject(physicalDeviceObject);
    10195             }
    10196         } else {
    10197
    10198             status = STATUS_INVALID_DEVICE_REQUEST;
    10199         }
    10200
    10201     } else {
    10202         //
    10203         // This will only happen if the registry information is screwed up.
    10204         //
    10205         physicalDeviceObject = NULL;
    10206         status = STATUS_INVALID_DEVICE_REQUEST;
    10207     }
    10208
    10209     if (!Enable) {
    10210         //
    10211         // In the case of Disable we want to continue even if there was an error
    10212         // finding the PDO.  Prior to adding support for deferring the
    10213         // IoSetDeviceInterfaceState calls, we never looked up the PDO for
    10214         // disables.  This will make sure that we continue to behave the same as
    10215         // we used to in the case where we can't find the PDO.
    10216         //
    10217         status = STATUS_SUCCESS;
    10218     }
    10219
    10220     ExFreePool(pKeyValueInfo);
    10221
    10222     if (!NT_SUCCESS(status)) {
    10223         goto clean2;
    10224     }
    10225
    10226     if (Enable) {
    10227         //
    10228         // Retrieve the PDO's device object name.  (Start out with a reasonably-sized
    10229         // buffer so we hopefully only have to retrieve this once.
    10230         //
    10231         deviceNameBufferLength = 256 * sizeof(WCHAR);
    10232
    10233         while (TRUE) {
    10234
    10235             deviceNameBuffer = ExAllocatePool(PagedPool, deviceNameBufferLength);
    10236             if (!deviceNameBuffer) {
    10237                 status = STATUS_INSUFFICIENT_RESOURCES;
    10238                 break;
    10239             }
    10240
    10241             status = IoGetDeviceProperty( physicalDeviceObject,
    10242                                           DevicePropertyPhysicalDeviceObjectName,
    10243                                           deviceNameBufferLength,
    10244                                           deviceNameBuffer,
    10245                                           &deviceNameBufferLength
    10246                                          );
    10247
    10248             if (NT_SUCCESS(status)) {
    10249                 break;
    10250             } else {
    10251                 //
    10252                 // Free the current buffer before we figure out what went wrong.
    10253                 //
    10254                 ExFreePool(deviceNameBuffer);
    10255
    10256                 if (status != STATUS_BUFFER_TOO_SMALL) {
    10257                     //
    10258                     // Our failure wasn't because the buffer was too small--bail now.
    10259                     //
    10260                     break;
    10261                 }
    10262
    10263                 //
    10264                 // Otherwise, loop back and try again with our new buffer size.
    10265                 //
    10266             }
    10267         }
    10268
    10269         //
    10270         // OK, we don't need the PDO anymore.
    10271         //
    10272         ObDereferenceObject(physicalDeviceObject);
    10273
    10274         if (!NT_SUCCESS(status)) {
    10275             goto clean2;
    10276         }
    10277
    10278         //
    10279         // Now create a unicode string based on the device object name we just retrieved.
    10280         //
    10281
    10282         RtlInitUnicodeString(&deviceNameString, deviceNameBuffer);
    10283     }
    10284
    10285     //
    10286     // Retrieve the linked value from the control subkey.
    10287     //
    10288     pKeyValueInfo=NULL;
    10289     status = IopGetRegistryValue(hInterfaceInstanceControl, REGSTR_VAL_LINKED, &pKeyValueInfo);
    10290
    10291     if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
    10292
    10293         //
    10294         // The absence of a linked value is taken to mean not linked
    10295         //
    10296
    10297         linked = 0;
    10298
    10299     } else {
    10300         if (!NT_SUCCESS(status)) {
    10301             //
    10302             // If the call failed, pKeyValueInfo was never allocated
    10303             //
    10304             goto clean3;
    10305         }
    10306
    10307         //
    10308         // Check linked is a DWORD
    10309         //
    10310
    10311         if(pKeyValueInfo->Type == REG_DWORD && pKeyValueInfo->DataLength == sizeof(ULONG)) {
    10312
    10313             linked = *((PULONG) KEY_VALUE_DATA(pKeyValueInfo));
    10314
    10315         } else {
    10316
    10317             //
    10318             // The registry is screwed up - assume linked is 0 and the registry will be fixed when
    10319             // we update linked in a few moments
    10320             //
    10321
    10322             linked = 0;
    10323
    10324         }
    10325
    10326     }
    10327     if (pKeyValueInfo) {
    10328         ExFreePool (pKeyValueInfo);
    10329     }
    10330
    10331     //
    10332     // Retrieve the refcount value from the control subkey.
    10333     //
    10334
    10335     RtlInitUnicodeString(&tempString, REGSTR_VAL_REFERENCECOUNT);
    10336     status = IopGetRegistryValue(hInterfaceParentControl,
    10337                                  tempString.Buffer,
    10338                                  &pKeyValueInfo
    10339                                  );
    10340
    10341     if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
    10342
    10343         //
    10344         // The absence of a refcount value is taken to mean refcount == 0
    10345         //
    10346
    10347         refcount = 0;
    10348
    10349     } else {
    10350         if (!NT_SUCCESS(status)) {
    10351             goto clean3;
    10352         }
    10353
    10354         //
    10355         // Check refcount is a DWORD
    10356         //
    10357
    10358         if(pKeyValueInfo->Type == REG_DWORD && pKeyValueInfo->DataLength == sizeof(ULONG)) {
    10359
    10360             refcount = *((PULONG) KEY_VALUE_DATA(pKeyValueInfo));
    10361
    10362         } else {
    10363
    10364             //
    10365             // The registry is screwed up - assume refcount is 0 and the registry will be fixed when
    10366             // we update refcount in a few moments
    10367             //
    10368
    10369             refcount = 0;
    10370
    10371         }
    10372
    10373         ExFreePool(pKeyValueInfo);
    10374     }
    10375
    10376
    10377     if (Enable) {
    10378
    10379         if (!linked) {
    10380             //
    10381             // check and update the reference count
    10382             //
    10383
    10384             if (refcount > 0) {
    10385                 //
    10386                 // Another device instance has already referenced this interface;
    10387                 // just increment the reference count; don't try create a symbolic link.
    10388                 //
    10389                 refcount += 1;
    10390             } else {
    10391                 //
    10392                 // According to the reference count, no other device instances currently
    10393                 // reference this interface, and therefore no symbolic links should exist,
    10394                 // so we should create one.
    10395                 //
    10396                 refcount = 1;
    10397                 status = IoCreateSymbolicLink(&actualSymbolicLinkName, &deviceNameString);
    10398
    10399                 if (status == STATUS_OBJECT_NAME_COLLISION) {
    10400                     //
    10401                     // The reference count is screwed up.
    10402                     //
    10403                     KdPrint(("IoSetDeviceInterfaceState: symbolic link for %ws already exists! status = %8.8X\n",
    10404                              actualSymbolicLinkName.Buffer, status));
    10405                     status = STATUS_SUCCESS;
    10406                 }
    10407
    10408             }
    10409
    10410             linked = 1;
    10411
    10412 #if 0
    10413             IopSetupDeviceObjectFromDeviceClass(physicalDeviceObject,
    10414                                                 hInterfaceClassKey);
    10415 #endif
    10416
    10417         } else {
    10418
    10419             //
    10420             // The association already exists - don't perform the notification
    10421             //
    10422
    10423             status = STATUS_OBJECT_NAME_EXISTS; // Informational message not error
    10424             goto clean3;
    10425
    10426         }
    10427     } else {
    10428
    10429         if (linked) {
    10430
    10431             //
    10432             // check and update the reference count
    10433             //
    10434
    10435             if (refcount > 1) {
    10436                 //
    10437                 // Another device instance already references this interface;
    10438                 // just decrement the reference count; don't try to remove the symbolic link.
    10439                 //
    10440                 refcount -= 1;
    10441             } else {
    10442                 //
    10443                 // According to the reference count, only this device instance currently
    10444                 // references this interface, so it is ok to delete this symbolic link
    10445                 //
    10446                 refcount = 0;
    10447                 status = IoDeleteSymbolicLink(&actualSymbolicLinkName);
    10448
    10449                 if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
    10450                     //
    10451                     // The reference count is screwed up.
    10452                     //
    10453                     KdPrint(("IoSetDeviceInterfaceState: no symbolic link for %ws to delete! status = %8.8X\n",
    10454                              actualSymbolicLinkName.Buffer, status));
    10455                     status = STATUS_SUCCESS;
    10456                 }
    10457
    10458             }
    10459
    10460             linked = 0;
    10461
    10462         } else {
    10463
    10464             //
    10465             // The association does not exists - fail and do not perform notification
    10466             //
    10467
    10468             status = STATUS_OBJECT_NAME_NOT_FOUND;
    10469         }
    10470     }
    10471
    10472     if (!NT_SUCCESS(status)) {
    10473         goto clean3;
    10474     }
    10475
    10476     //
    10477     // Update the value of linked
    10478     //
    10479
    10480     PiWstrToUnicodeString(&tempString, REGSTR_VAL_LINKED);
    10481     status = ZwSetValueKey(hInterfaceInstanceControl,
    10482                            &tempString,
    10483                            0,
    10484                            REG_DWORD,
    10485                            &linked,
    10486                            sizeof(linked)
    10487                           );
    10488
    10489     //
    10490     // Update the value of refcount
    10491     //
    10492
    10493     RtlInitUnicodeString(&tempString, REGSTR_VAL_REFERENCECOUNT);
    10494     status = ZwSetValueKey(hInterfaceParentControl,
    10495                            &tempString,
    10496                            0,
    10497                            REG_DWORD,
    10498                            &refcount,
    10499                            sizeof(refcount)
    10500                           );
    10501
    10502
    10503     //
    10504     // Notify anyone that is interested
    10505     //
    10506
    10507     if (linked) {
    10508
    10509         PpSetDeviceClassChange( (LPGUID) &GUID_DEVICE_INTERFACE_ARRIVAL, &guid, SymbolicLinkName);
    10510
    10511     } else {
    10512
    10513         PpSetDeviceClassChange( (LPGUID) &GUID_DEVICE_INTERFACE_REMOVAL, &guid, SymbolicLinkName);
    10514
    10515     }
    10516
    10517 clean3:
    10518     if (deviceNameBuffer != NULL) {
    10519         ExFreePool(deviceNameBuffer);
    10520     }
    10521
    10522 clean2:
    10523     if (hInterfaceParentControl) {
    10524         ZwClose(hInterfaceParentControl);
    10525     }
    10526     if (hInterfaceInstanceControl) {
    10527         ZwClose(hInterfaceInstanceControl);
    10528     }
    10529
    10530 clean1:
    10531     if (hInterfaceParentKey) {
    10532         ZwClose(hInterfaceParentKey);
    10533     }
    10534     if (hInterfaceInstanceKey) {
    10535         ZwClose(hInterfaceInstanceKey);
    10536     }
    10537     if(hInterfaceClassKey != NULL) {
    10538         ZwClose(hInterfaceClassKey);
    10539     }
    10540
    10541 clean0:
    10542     if (!NT_SUCCESS(status) && !Enable) {
    10543         //
    10544         // If we failed to disable an interface (most likely because the
    10545         // interface keys have already been deleted) report success.
    10546         //
    10547         status = STATUS_SUCCESS;
    10548     }
    10549
    10550     return status;
    10551 }
    }

VOID IopProcessStartDevices | ( | IN PDEVICE_NODE | DeviceNode,
|  | IN PSTART_CONTEXT | StartContext
| ) |

Definition at line 821 of file pnpenum.c.

References _DEVICE_NODE::Child, DNF_STARTED, ExAcquireResourceShared, Executive, ExReleaseResource, FALSE, IopDeviceTreeLock, IopProcessStartDevicesWorker(), IopReleaseEnumerationLock, KernelMode, KeSetEvent(), KeWaitForSingleObject(), NTSTATUS(), NULL, PAGED_CODE, PpSynchronizeDeviceEventQueue(), _DEVICE_NODE::Sibling, and TRUE.

Referenced by IopBusCheck(), IopDeviceActionWorker(), IopInitializeSystemDrivers(), and IopNewDevice().

    00828                    :
    00829
    00830     This function is used by Pnp manager to start the devices which have been
    00831     allocated resources and waiting to be started.
    00832
    00833 Parameters:
    00834
    00835     DeviceNode - Specifies the device node whose subtree is to be checked for StartDevice.
    00836
    00837     StartContext - specifies if new driver should be loaded to complete the enumeration.
    00838
    00839 Return Value:
    00840
    00841     NONE.
    00842
    00843 --*/
    00844 {
    00845     NTSTATUS status;
    00846     PDEVICE_NODE deviceNode, nextDeviceNode;
    00847
    00848     PAGED_CODE();
    00849
    00850     //
    00851     // Parse the device node subtree to determine which devices need to be started
    00852     //
    00853
    00854     ExAcquireResourceShared(&IopDeviceTreeLock, TRUE);
    00855     if (DeviceNode->LockCount == 0) {
    00856
    00857         KeWaitForSingleObject( &DeviceNode->EnumerationMutex,
    00858                                Executive,
    00859                                KernelMode,
    00860                                FALSE,
    00861                                NULL );
    00862
    00863         deviceNode = DeviceNode->Child;
    00864         while (deviceNode) {
    00865             nextDeviceNode = deviceNode->Sibling;
    00866             status = IopProcessStartDevicesWorker(deviceNode, StartContext);
    00867
    00868             if (status == STATUS_PNP_RESTART_ENUMERATION) {
    00869
    00870                 IopReleaseEnumerationLock(DeviceNode);
    00871
    00872                 PpSynchronizeDeviceEventQueue();
    00873
    00874                 ExAcquireResourceShared(&IopDeviceTreeLock, TRUE);
    00875                 if (DeviceNode->LockCount == 0) {
    00876
    00877                     KeWaitForSingleObject( &DeviceNode->EnumerationMutex,
    00878                                            Executive,
    00879                                            KernelMode,
    00880                                            FALSE,
    00881                                            NULL );
    00882
    00883
    00884                     if (!(DeviceNode->Flags & DNF_STARTED)) {
    00885                         break;
    00886                     }
    00887
    00888                     deviceNode = DeviceNode->Child;
    00889
    00890                     continue;
    00891
    00892                 } else {
    00893
    00894                     ExReleaseResource(&IopDeviceTreeLock);
    00895                     return;
    00896
    00897                 }
    00898             }
    00899
    00900             deviceNode = nextDeviceNode;
    00901         }
    00902
    00903         KeSetEvent( &DeviceNode->EnumerationMutex,
    00904                     0,
    00905                     FALSE );
    00906     }
    00907
    00908     ExReleaseResource(&IopDeviceTreeLock);
    00909 }

NTSTATUS IopQueryCompatibleIds | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN BUS_QUERY_ID_TYPE | IdType,
|  | OUT PWCHAR * | CompatibleIds,
|  | OUT ULONG * | Length
| ) |

Definition at line 2173 of file pnpirp.c.

References BusQueryCompatibleIDs, BusQueryHardwareIDs, IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_ID, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), PAGED_CODE, and _IO_STACK_LOCATION::Parameters.

Referenced by IopProcessNewDeviceNode(), and IopStartAndEnumerateDevice().

    02182                    :
    02183
    02184     This routine sends irp to query HardwareIds or CompatibleIds.  This rotine
    02185     queries MULTISZ Ids.
    02186
    02187 Parameters:
    02188
    02189     DeviceObject - Supplies the device object of the device being queried/
    02190
    02191     IdType - Specifies the Id type interested.  Only HardwareIDs and CompatibleIDs
    02192              are supported by this routine.
    02193
    02194     CompatibleId - Supplies a pointer to a variable to receive the returned Ids.
    02195                    This must be freed by the caller.
    02196
    02197     Length - Supplies a pointer to a variable to receive the length of the IDs.
    02198
    02199 Return Value:
    02200
    02201     NTSTATUS code.
    02202
    02203 --*/
    02204 {
    02205     IO_STACK_LOCATION irpSp;
    02206     NTSTATUS status;
    02207
    02208     PAGED_CODE();
    02209
    02210     *Length = 0;
    02211     if ((IdType != BusQueryHardwareIDs) && (IdType != BusQueryCompatibleIDs)) {
    02212         return STATUS_INVALID_PARAMETER_2;
    02213     }
    02214
    02215     //
    02216     // Initialize the stack location to pass to IopSynchronousCall()
    02217     //
    02218
    02219     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    02220
    02221     //
    02222     // Set the function codes.
    02223     //
    02224
    02225     irpSp.MajorFunction = IRP_MJ_PNP;
    02226     irpSp.MinorFunction = IRP_MN_QUERY_ID;
    02227
    02228     //
    02229     // Set the pointer to the resource list
    02230     //
    02231
    02232     irpSp.Parameters.QueryId.IdType = IdType;
    02233
    02234     //
    02235     // Make the call and return.
    02236     //
    02237
    02238     status = IopSynchronousCall(DeviceObject, &irpSp, CompatibleIds);
    02239
    02240     if (NT_SUCCESS(status) && *CompatibleIds) {
    02241
    02242         //
    02243         // The Compatible IDs and Hardware IDs are multi_sz,
    02244         // try to determine its size.
    02245         //
    02246
    02247         PWCHAR wp;
    02248
    02249         for (wp = *CompatibleIds;
    02250              (*wp != UNICODE_NULL) || (*(wp + 1) != UNICODE_NULL);
    02251              wp++) {
    02252
    02253             *Length += 2;
    02254         }
    02255         *Length += 4;
    02256     }
    02257
    02258     return status;
    02259 }

NTSTATUS IopQueryConflictList | ( | PDEVICE_OBJECT | PhysicalDeviceObject,
|  | IN PCM_RESOURCE_LIST | ResourceList,
|  | IN ULONG | ResourceListSize,
|  | OUT PPLUGPLAY_CONTROL_CONFLICT_LIST | ConflictList,
|  | IN ULONG | ConflictListSize,
|  | IN ULONG | Flags
| ) |

Definition at line 7717 of file pnpres.c.

References DebugMessage, DelayExecution, DUMP_ERROR, FALSE, IopQueryConflictListInternal(), IopRegistrySemaphore, KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

    07727                    :
    07728
    07729     This routine performs the querying of device conflicts
    07730     returning data in ConflictList
    07731
    07732 Arguments:
    07733
    07734     PhysicalDeviceObject PDO of device to Query
    07735     ResourceList      CM resource list containing single resource to query
    07736     ResourceListSize  Size of ResourceList
    07737     ConflictList      Conflict list to fill query details in
    07738     ConflictListSize  Size of buffer that we can fill with Conflict information
    07739     Flags             Currently unused (zero) for future passing of flags
    07740
    07741 Return Value:
    07742
    07743     Should be success in most cases
    07744
    07745 --*/
    07746 {
    07747     NTSTATUS status;
    07748
    07749     PAGED_CODE();
    07750
    07751     KeEnterCriticalRegion( );
    07752
    07753     status = KeWaitForSingleObject( &IopRegistrySemaphore,
    07754                                     DelayExecution,
    07755                                     KernelMode,
    07756                                     FALSE,
    07757                                     NULL );
    07758
    07759     if (!NT_SUCCESS( status )) {
    07760         DebugMessage(DUMP_ERROR, ("IopQueryConflictList: Get RegustrySemaphore failed. Status %x\n", status));
    07761         KeLeaveCriticalRegion( );
    07762         return status;
    07763     } else {
    07764         status = IopQueryConflictListInternal(PhysicalDeviceObject, ResourceList, ResourceListSize, ConflictList, ConflictListSize, Flags);
    07765         KeReleaseSemaphore( &IopRegistrySemaphore, 0, 1, FALSE );
    07766         KeLeaveCriticalRegion( );
    07767     }
    07768
    07769     return status;
    07770 }

NTSTATUS IopQueryDeviceCapabilities | ( | IN PDEVICE_NODE | DeviceNode,
|  | OUT PDEVICE_CAPABILITIES | Capabilities
| ) |

Definition at line 3694 of file pnpenum.c.

References ASSERT, DEVICE_CAPABILITIES, dummy(), IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_CAPABILITIES, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), and _IO_STACK_LOCATION::Parameters.

Referenced by IoGetDeviceProperty(), IopDeviceCapabilitiesToRegistry(), IopDeviceNodeCapabilitiesToRegistry(), and IopProcessNewDeviceNode().

    03701                    :
    03702
    03703     This routine will issue an irp to the DeviceObject to retrieve the
    03704     pnp device capabilities.
    03705     Should only be called twice - first from IopProcessNewDeviceNode,
    03706     and second from IopDeviceNodeCapabilitiesToRegistry, called after
    03707     device is started. If you consider calling this device, see if
    03708     DeviceNode->CapabilityFlags does what you need instead (accessed
    03709     via IopDeviceNodeFlagsToCapabilities(...).
    03710
    03711 Arguments:
    03712
    03713     DeviceNode - the device object the request should be sent to.
    03714
    03715     Capabilities - a capabilities structure to be filled in by the driver.
    03716
    03717 Return Value:
    03718
    03719     status
    03720
    03721 --*/
    03722
    03723 {
    03724     IO_STACK_LOCATION irpStack;
    03725     PVOID dummy;
    03726
    03727     NTSTATUS status;
    03728
    03729     //
    03730     // Initialize the capabilities structure.
    03731     //
    03732
    03733     RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES));
    03734     Capabilities->Size = sizeof(DEVICE_CAPABILITIES);
    03735     Capabilities->Version = 1;
    03736     Capabilities->Address = Capabilities->UINumber = (ULONG)-1;
    03737
    03738     //
    03739     // Initialize the stack location to pass to IopSynchronousCall()
    03740     //
    03741
    03742     RtlZeroMemory(&irpStack, sizeof(IO_STACK_LOCATION));
    03743
    03744     //
    03745     // Query the device's capabilities
    03746     //
    03747
    03748     irpStack.MajorFunction = IRP_MJ_PNP;
    03749     irpStack.MinorFunction = IRP_MN_QUERY_CAPABILITIES;
    03750     irpStack.Parameters.DeviceCapabilities.Capabilities = Capabilities;
    03751
    03752     status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject,
    03753                                 &irpStack,
    03754                                 &dummy);
    03755
    03756     ASSERT(status != STATUS_PENDING);
    03757
    03758     return status;
    03759 }

NTSTATUS IopQueryDeviceConfigurationVector | ( | IN PUNICODE_STRING | ServiceKeyName,
|  | IN ULONG | InstanceOrdinal,
|  | OUT PULONG | DeviceInstanceFlags,
|  | OUT PIO_RESOURCE_REQUIREMENTS_LIST | ConfigurationVector,
|  | IN ULONG | BufferSize,
|  | OUT PULONG | ActualBufferSize
| ) |

NTSTATUS IopQueryDeviceId | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | OUT PWCHAR * | DeviceId
| ) |

Definition at line 1762 of file pnpirp.c.

References BusQueryDeviceID, IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_ID, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), PAGED_CODE, and _IO_STACK_LOCATION::Parameters.

Referenced by IopProcessNewDeviceNode().

    01769                    :
    01770
    01771     This routine sends a query device id irp to the specified device object.
    01772
    01773 Parameters:
    01774
    01775     DeviceObject - Supplies the device object of the device being queried/
    01776
    01777     DeviceId - Supplies a pointer to a variable to receive the returned Id.
    01778                This must be freed by the caller.
    01779
    01780 Return Value:
    01781
    01782     NTSTATUS code.
    01783
    01784 --*/
    01785 {
    01786     IO_STACK_LOCATION irpSp;
    01787     NTSTATUS status;
    01788
    01789     PAGED_CODE();
    01790
    01791     //
    01792     // Initialize the stack location to pass to IopSynchronousCall()
    01793     //
    01794
    01795     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    01796
    01797     //
    01798     // Set the function codes.
    01799     //
    01800
    01801     irpSp.MajorFunction = IRP_MJ_PNP;
    01802     irpSp.MinorFunction = IRP_MN_QUERY_ID;
    01803
    01804     //
    01805     // Set the pointer to the resource list
    01806     //
    01807
    01808     irpSp.Parameters.QueryId.IdType = BusQueryDeviceID;
    01809
    01810     //
    01811     // Make the call and return.
    01812     //
    01813
    01814     status = IopSynchronousCall(DeviceObject, &irpSp, DeviceId);
    01815
    01816     return status;
    01817 }

NTSTATUS IopQueryDeviceRelations | ( | IN DEVICE_RELATION_TYPE | Relations,
|  | IN PDEVICE_OBJECT | DeviceObject,
|  | IN BOOLEAN | AsyncOk,
|  | OUT PDEVICE_RELATIONS * | DeviceRelations
| ) |

Definition at line 1604 of file pnpirp.c.

References BusRelations, _DEVICE_COMPLETION_CONTEXT::DeviceNode, DNF_BEING_ENUMERATED, DNF_ENUMERATION_REQUEST_PENDING, DNF_ENUMERATION_REQUEST_QUEUED, DNF_IO_INVALIDATE_DEVICE_RELATIONS_PENDING, ExAllocatePool, ExGetCurrentResourceThread, FALSE, _DEVICE_NODE::Flags, IopAcquireEnumerationLock, IopAsynchronousCall(), IopDeviceRelationsComplete(), IopPnPSpinLock, IopRequestDeviceAction(), IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_DEVICE_RELATIONS, _DEVICE_COMPLETION_CONTEXT::IrpMinorCode, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NonPagedPool, NTSTATUS(), NULL, _DEVICE_NODE::OverUsed1, _IO_STACK_LOCATION::Parameters, PDEVICE_COMPLETION_CONTEXT, ReenumerateDeviceTree, _DEVICE_COMPLETION_CONTEXT::Thread, and TRUE.

Referenced by IopEnumerateDevice(), and IopProcessRelation().

    01613                    :
    01614
    01615     This routine sends query device relation irp to the specified device object.
    01616
    01617 Parameters:
    01618
    01619     Relations - specifies the type of relation interested.
    01620
    01621     DeviceObjet - Supplies the device object of the device being queried.
    01622
    01623     AsyncOk - Specifies if we can perform Async QueryDeviceRelations
    01624
    01625     DeviceRelations - Supplies a pointer to a variable to receive the returned
    01626                       relation information. This must be freed by the caller.
    01627
    01628 Return Value:
    01629
    01630     NTSTATUS code.
    01631
    01632 --*/
    01633
    01634 {
    01635     IO_STACK_LOCATION irpSp;
    01636     NTSTATUS status;
    01637     PDEVICE_RELATIONS deviceRelations;
    01638     PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
    01639     PDEVICE_COMPLETION_CONTEXT completionContext;
    01640     BOOLEAN requestEnumeration = FALSE;
    01641     KIRQL oldIrql;
    01642
    01643     //
    01644     // Do not allow two bus relations at the same time
    01645     //
    01646
    01647     if (Relations == BusRelations) {
    01648         ExAcquireSpinLock(&IopPnPSpinLock, &oldIrql);
    01649         if (deviceNode->Flags & DNF_BEING_ENUMERATED) {
    01650             ExReleaseSpinLock(&IopPnPSpinLock, oldIrql);
    01651             return STATUS_UNSUCCESSFUL;
    01652         }
    01653         deviceNode->Flags &= ~DNF_ENUMERATION_REQUEST_QUEUED;
    01654         deviceNode->Flags  |= DNF_BEING_ENUMERATED;
    01655         ExReleaseSpinLock(&IopPnPSpinLock, oldIrql);
    01656     }
    01657
    01658     //
    01659     // Initialize the stack location to pass to IopSynchronousCall()
    01660     //
    01661
    01662     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    01663
    01664     //
    01665     // Set the function codes.
    01666     //
    01667
    01668     irpSp.MajorFunction = IRP_MJ_PNP;
    01669     irpSp.MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
    01670
    01671     //
    01672     // Set the pointer to the resource list
    01673     //
    01674
    01675     irpSp.Parameters.QueryDeviceRelations.Type = Relations;
    01676
    01677     //
    01678     // Make the call and return.
    01679     //
    01680
    01681     if (AsyncOk && Relations == BusRelations) {
    01682         completionContext = (PDEVICE_COMPLETION_CONTEXT) ExAllocatePool(
    01683                               NonPagedPool,
    01684                               sizeof(DEVICE_COMPLETION_CONTEXT));
    01685         if (completionContext == NULL) {
    01686             return STATUS_INSUFFICIENT_RESOURCES;   // BUGBUG - Should try it again.
    01687         }
    01688
    01689         completionContext->DeviceNode = deviceNode;
    01690         completionContext->IrpMinorCode = IRP_MN_QUERY_DEVICE_RELATIONS;
    01691         completionContext->Thread = ExGetCurrentResourceThread();
    01692
    01693         //
    01694         // Make the call and return.
    01695         //
    01696
    01697         IopAcquireEnumerationLock(NULL);  // To block IopAcquireTreeLock();
    01698         status = IopAsynchronousCall(DeviceObject, &irpSp, completionContext, IopDeviceRelationsComplete);
    01699         if (status == STATUS_PENDING) {
    01700             KIRQL oldIrql;
    01701
    01702             ExAcquireSpinLock(&IopPnPSpinLock, &oldIrql);
    01703
    01704             //
    01705             // Check if the completion routine completes before we setting
    01706             // the DNF_ENUMERATION_REQUEST_PENDING flags.
    01707             //
    01708
    01709             if (deviceNode->Flags & DNF_ENUMERATION_REQUEST_PENDING) {
    01710                 deviceNode->Flags &= ~DNF_ENUMERATION_REQUEST_PENDING;
    01711                 *DeviceRelations = deviceNode->OverUsed1.PendingDeviceRelations;
    01712                 deviceNode->OverUsed1.PendingDeviceRelations = NULL;
    01713                 status = STATUS_SUCCESS;
    01714             } else {
    01715
    01716                 //
    01717                 // Set DNF_ENUMERATION_REQUEST_PENDING such that the completion routine knows it
    01718                 // needs to request enumeration when the Q_bus_relations completed successfully.
    01719                 //
    01720
    01721                 deviceNode->Flags |= DNF_ENUMERATION_REQUEST_PENDING;
    01722             }
    01723
    01724             ExReleaseSpinLock(&IopPnPSpinLock, oldIrql);
    01725         } else {
    01726             deviceNode->Flags &= ~DNF_ENUMERATION_REQUEST_PENDING;
    01727             *DeviceRelations = deviceNode->OverUsed1.PendingDeviceRelations;
    01728             deviceNode->OverUsed1.PendingDeviceRelations = NULL;
    01729         }
    01730         return status;
    01731     } else {
    01732         status = IopSynchronousCall(DeviceObject, &irpSp, DeviceRelations);
    01733
    01734         //
    01735         // To prevent the scenario that a driver calls IoInvalidateDeviceRelations while servicing
    01736         // an Async Q-D-R irp, and receives another q-d-r irp before first one completed, we will
    01737         // set a flag when it calls IoInvalidateDeviceRelations and delay queuing the request till
    01738         // the original one is completed.
    01739         //
    01740
    01741         if (Relations == BusRelations) {
    01742             ExAcquireSpinLock(&IopPnPSpinLock, &oldIrql);
    01743             deviceNode->Flags  &= ~DNF_BEING_ENUMERATED;
    01744             if (deviceNode->Flags & DNF_IO_INVALIDATE_DEVICE_RELATIONS_PENDING) {
    01745                 deviceNode->Flags &= ~DNF_IO_INVALIDATE_DEVICE_RELATIONS_PENDING;
    01746                 requestEnumeration = TRUE;
    01747             }
    01748             ExReleaseSpinLock(&IopPnPSpinLock, oldIrql);
    01749             if (requestEnumeration) {
    01750                 IopRequestDeviceAction( DeviceObject,
    01751                                         ReenumerateDeviceTree,
    01752                                         NULL,
    01753                                         NULL );
    01754             }
    01755         }
    01756     }
    01757
    01758     return status;
    01759 }

NTSTATUS IopQueryDeviceResources | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN ULONG | ResourceType,
|  | OUT PVOID * | Resource,
|  | OUT ULONG * | Length
| ) |

Definition at line 2262 of file pnpirp.c.

References ASSERT, DbgPrint, DNF_MADEUP, DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED, ExAllocatePool, ExFreePool(), FALSE, _DEVICE_NODE::Flags, IopCmResourcesToIoResources(), IopDetermineResourceListSize(), IopDeviceObjectToDeviceInstance(), IopFilterResourceRequirementsCall(), IopFilterResourceRequirementsList(), IopGetDeviceResourcesFromRegistry(), IopMergeFilteredResourceRequirementsList(), IopOpenRegistryKeyEx(), IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_RESOURCE_REQUIREMENTS, IRP_MN_QUERY_RESOURCES, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, QUERY_RESOURCE_LIST, QUERY_RESOURCE_REQUIREMENTS, REGISTRY_ALLOC_CONFIG, REGISTRY_BASIC_CONFIGVECTOR, REGISTRY_BOOT_CONFIG, REGISTRY_FORCED_CONFIG, REGISTRY_OVERRIDE_CONFIGVECTOR, Resource, _DEVICE_NODE::ResourceRequirements, and TITLE_INDEX_VALUE.

Referenced by IopGetResourceRequirementsForAssignTable(), IopProcessNewDeviceNode(), and IopReleaseDeviceResources().

    02271                    :
    02272
    02273     This routine sends irp to queries resources or resource requirements list
    02274     of the specified device object.
    02275
    02276     If the device object is a detected device, its resources will be read from
    02277     registry.  Otherwise, an irp is sent to the bus driver to query its resources.
    02278
    02279 Parameters:
    02280
    02281     DeviceObject - Supplies the device object of the device being queries.
    02282
    02283     ResourceType - 0 for device resources and 1 for resource requirements list.
    02284
    02285     Resource - Supplies a pointer to a variable to receive the returned resources
    02286
    02287     Length - Supplies a pointer to a variable to receive the length of the returned
    02288              resources or resource requirements list.
    02289
    02290 Return Value:
    02291
    02292     NTSTATUS code.
    02293
    02294 --*/
    02295 {
    02296     IO_STACK_LOCATION irpSp;
    02297     PDEVICE_NODE deviceNode;
    02298     NTSTATUS status;
    02299     PIO_RESOURCE_REQUIREMENTS_LIST resReqList, newResources;
    02300     ULONG junk;
    02301     PCM_RESOURCE_LIST cmList;
    02302     PIO_RESOURCE_REQUIREMENTS_LIST filteredList, mergedList;
    02303     BOOLEAN exactMatch;
    02304
    02305     PAGED_CODE();
    02306
    02307 #if DBG
    02308
    02309     if ((ResourceType != QUERY_RESOURCE_LIST) &&
    02310         (ResourceType != QUERY_RESOURCE_REQUIREMENTS)) {
    02311         return STATUS_INVALID_PARAMETER_2;
    02312     }
    02313 #endif
    02314
    02315     *Resource = NULL;
    02316     *Length = 0;
    02317
    02318     //
    02319     // Initialize the stack location to pass to IopSynchronousCall()
    02320     //
    02321
    02322     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    02323
    02324     deviceNode = (PDEVICE_NODE) DeviceObject->DeviceObjectExtension->DeviceNode;
    02325
    02326     if (ResourceType == QUERY_RESOURCE_LIST) {
    02327
    02328         //
    02329         // caller is asked for RESOURCE_LIST.  If this is a madeup device, we will
    02330         // read it from registry.  Otherwise, we ask drivers.
    02331         //
    02332
    02333         if (deviceNode->Flags & DNF_MADEUP) {
    02334
    02335             status = IopGetDeviceResourcesFromRegistry(
    02336                              DeviceObject,
    02337                              ResourceType,
    02338                              REGISTRY_ALLOC_CONFIG + REGISTRY_FORCED_CONFIG + REGISTRY_BOOT_CONFIG,
    02339                              Resource,
    02340                              Length);
    02341             if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
    02342                 status = STATUS_SUCCESS;
    02343             }
    02344             return status;
    02345         } else {
    02346             irpSp.MinorFunction = IRP_MN_QUERY_RESOURCES;
    02347             irpSp.MajorFunction = IRP_MJ_PNP;
    02348             status = IopSynchronousCall(DeviceObject, &irpSp, Resource);
    02349             if (status == STATUS_NOT_SUPPORTED) {
    02350
    02351                 //
    02352                 // If driver doesn't implement this request, it
    02353                 // doesn't consume any resources.
    02354                 //
    02355
    02356                 *Resource = NULL;
    02357                 status = STATUS_SUCCESS;
    02358             }
    02359             if (NT_SUCCESS(status)) {
    02360                 *Length = IopDetermineResourceListSize((PCM_RESOURCE_LIST)*Resource);
    02361             }
    02362             return status;
    02363         }
    02364     } else {
    02365
    02366         //
    02367         // Caller is asked for resource requirements list.  We will check:
    02368         // if there is a ForcedConfig, it will be converted to resource requirements
    02369         //     list and return.  Otherwise,
    02370         // If there is an OVerrideConfigVector, we will use it as our
    02371         //     FilterConfigVector.  Otherwise we ask driver for the config vector and
    02372         //     use it as our FilterConfigVector.
    02373         //     Finaly, we pass the FilterConfigVector to driver stack to let drivers
    02374         //     filter the requirements.
    02375         //
    02376
    02377         status = IopGetDeviceResourcesFromRegistry(
    02378                          DeviceObject,
    02379                          QUERY_RESOURCE_LIST,
    02380                          REGISTRY_FORCED_CONFIG,
    02381                          Resource,
    02382                          &junk);
    02383         if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
    02384             status = IopGetDeviceResourcesFromRegistry(
    02385                              DeviceObject,
    02386                              QUERY_RESOURCE_REQUIREMENTS,
    02387                              REGISTRY_OVERRIDE_CONFIGVECTOR,
    02388                              &resReqList,
    02389                              &junk);
    02390             if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
    02391                 if (deviceNode->Flags & DNF_MADEUP) {
    02392                     status = IopGetDeviceResourcesFromRegistry(
    02393                                      DeviceObject,
    02394                                      QUERY_RESOURCE_REQUIREMENTS,
    02395                                      REGISTRY_BASIC_CONFIGVECTOR,
    02396                                      &resReqList,
    02397                                      &junk);
    02398                     if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
    02399                         status = STATUS_SUCCESS;
    02400                         resReqList = NULL;
    02401                     }
    02402                 } else {
    02403
    02404                     //
    02405                     // We are going to ask the bus driver ...
    02406                     //
    02407
    02408                     if (deviceNode->ResourceRequirements) {
    02409                         ASSERT(deviceNode->Flags & DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED);
    02410                         resReqList = ExAllocatePool(PagedPool, deviceNode->ResourceRequirements->ListSize);
    02411                         if (resReqList) {
    02412                             RtlMoveMemory(resReqList,
    02413                                          deviceNode->ResourceRequirements,
    02414                                          deviceNode->ResourceRequirements->ListSize
    02415                                          );
    02416                             status = STATUS_SUCCESS;
    02417                         } else {
    02418                             return STATUS_NO_MEMORY;
    02419                         }
    02420                     } else {
    02421                         irpSp.MinorFunction = IRP_MN_QUERY_RESOURCE_REQUIREMENTS;
    02422                         irpSp.MajorFunction = IRP_MJ_PNP;
    02423                         status = IopSynchronousCall(DeviceObject, &irpSp, &resReqList);
    02424                         if (status == STATUS_NOT_SUPPORTED) {
    02425
    02426                             //
    02427                             // If driver doesn't implement this request, it
    02428                             // doesn't require any resources.
    02429                             //
    02430
    02431                             status = STATUS_SUCCESS;
    02432                             resReqList = NULL;
    02433
    02434                         }
    02435                     }
    02436                 }
    02437                 if (!NT_SUCCESS(status)) {
    02438                     return status;
    02439                 }
    02440             }
    02441
    02442             //
    02443             // For devices with boot config, we need to filter the resource requirements
    02444             // list against boot config.
    02445             //
    02446
    02447             status = IopGetDeviceResourcesFromRegistry(
    02448                              DeviceObject,
    02449                              QUERY_RESOURCE_LIST,
    02450                              REGISTRY_BOOT_CONFIG,
    02451                              &cmList,
    02452                              &junk);
    02453             if (NT_SUCCESS(status) &&
    02454                 (!cmList || cmList->Count == 0 || cmList->List[0].InterfaceType != PCIBus)) {
    02455                 status = IopFilterResourceRequirementsList (
    02456                              resReqList,
    02457                              cmList,
    02458                              &filteredList,
    02459                              &exactMatch);
    02460                 if (cmList) {
    02461                     ExFreePool(cmList);
    02462                 }
    02463                 if (!NT_SUCCESS(status)) {
    02464                     if (resReqList) {
    02465                         ExFreePool(resReqList);
    02466                     }
    02467                     return status;
    02468                 } else {
    02469
    02470                     //
    02471                     // For non-root-enumerated devices, we merge filtered config with basic config
    02472                     // vectors to form a new res req list.  For root-enumerated devices, we don't
    02473                     // consider Basic config vector.
    02474                     //
    02475
    02476                     if (!(deviceNode->Flags & DNF_MADEUP) &&
    02477                         (exactMatch == FALSE || resReqList->AlternativeLists > 1)) {
    02478                         status = IopMergeFilteredResourceRequirementsList (
    02479                                  filteredList,
    02480                                  resReqList,
    02481                                  &mergedList
    02482                                  );
    02483                         if (resReqList) {
    02484                             ExFreePool(resReqList);
    02485                         }
    02486                         if (filteredList) {
    02487                             ExFreePool(filteredList);
    02488                         }
    02489                         if (NT_SUCCESS(status)) {
    02490                             resReqList = mergedList;
    02491                         } else {
    02492                             return status;
    02493                         }
    02494                     } else {
    02495                         if (resReqList) {
    02496                             ExFreePool(resReqList);
    02497                         }
    02498                         resReqList = filteredList;
    02499                     }
    02500                 }
    02501             }
    02502
    02503         } else {
    02504             ASSERT(NT_SUCCESS(status));
    02505
    02506             //
    02507             // We have Forced Config.  Convert it to resource requirements and return it.
    02508             //
    02509
    02510             if (*Resource) {
    02511                 resReqList = IopCmResourcesToIoResources (0, (PCM_RESOURCE_LIST)*Resource, LCPRI_FORCECONFIG);
    02512                 ExFreePool(*Resource);
    02513                 if (resReqList) {
    02514                     *Resource = (PVOID)resReqList;
    02515                     *Length = resReqList->ListSize;
    02516                 } else {
    02517                     *Resource = NULL;
    02518                     *Length = 0;
    02519                     status = STATUS_INSUFFICIENT_RESOURCES;
    02520                     return status;
    02521                 }
    02522             } else {
    02523                 resReqList = NULL;
    02524             }
    02525         }
    02526
    02527         //
    02528         // If we are here, we have a resource requirements list for drivers to examine ...
    02529         // NOTE: Per Lonny's request, we let drivers filter ForcedConfig
    02530         //
    02531
    02532         status = IopFilterResourceRequirementsCall(
    02533             DeviceObject,
    02534             resReqList,
    02535             &newResources
    02536             );
    02537
    02538         if (NT_SUCCESS(status)) {
    02539             UNICODE_STRING unicodeName;
    02540             HANDLE handle, handlex;
    02541
    02542 #if DBG
    02543             if (newResources == NULL && resReqList) {
    02544                 DbgPrint("PnpMgr: Non-NULL resource requirements list filtered to NULL\n");
    02545             }
    02546 #endif
    02547             if (newResources) {
    02548
    02549                 *Length = newResources->ListSize;
    02550                 ASSERT(*Length);
    02551
    02552                 //
    02553                 // Make our own copy of the allocation. We do this so that the
    02554                 // verifier doesn't believe the driver has leaked memory if
    02555                 // unloaded.
    02556                 //
    02557
    02558                 *Resource = (PVOID) ExAllocatePool(PagedPool, *Length);
    02559                 if (*Resource == NULL) {
    02560
    02561                     ExFreePool(newResources);
    02562                     return STATUS_INSUFFICIENT_RESOURCES;
    02563                 }
    02564
    02565                 RtlCopyMemory(*Resource, newResources, *Length);
    02566                 ExFreePool(newResources);
    02567
    02568             } else {
    02569                 *Length = 0;
    02570                 *Resource = NULL;
    02571             }
    02572
    02573             //
    02574             // Write filtered res req to registry
    02575             //
    02576
    02577             status = IopDeviceObjectToDeviceInstance(DeviceObject, &handlex, KEY_ALL_ACCESS);
    02578             if (NT_SUCCESS(status)) {
    02579                 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL);
    02580                 status = IopOpenRegistryKeyEx( &handle,
    02581                                                handlex,
    02582                                                &unicodeName,
    02583                                                KEY_READ
    02584                                                );
    02585                 if (NT_SUCCESS(status)) {
    02586                     PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_FILTERED_CONFIG_VECTOR);
    02587                     ZwSetValueKey(handle,
    02588                                   &unicodeName,
    02589                                   TITLE_INDEX_VALUE,
    02590                                   REG_RESOURCE_REQUIREMENTS_LIST,
    02591                                   *Resource,
    02592                                   *Length
    02593                                   );
    02594                     ZwClose(handle);
    02595                     ZwClose(handlex);
    02596                 }
    02597             }
    02598         } else {
    02599
    02600             //
    02601             // ADRIAO BUGBUG 05/26/1999 -
    02602             //     Why do we not bubble up non-STATUS_NOT_SUPPORTED failure
    02603             // codes?
    02604             //
    02605             *Resource = resReqList;
    02606             if (resReqList) {
    02607                 *Length = resReqList->ListSize;
    02608             } else {
    02609                 *Length = 0;
    02610             }
    02611         }
    02612         return STATUS_SUCCESS;
    02613     }
    02614 }

NTSTATUS IopQueryDeviceSerialNumber | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | OUT PWCHAR * | SerialNumber
| ) |

Definition at line 3195 of file pnpirp.c.

References ASSERT, BusQueryDeviceSerialNumber, IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_ID, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, and _IO_STACK_LOCATION::Parameters.

Referenced by IopHardwareProfileCommitStartedDock(), and IopHardwareProfileMarkDock().

    03202                    :
    03203
    03204     This routine retrieves a hardware serial number for the specified device object.
    03205     If the routine fails, SerialNumber is guarenteed to be to NULL.
    03206
    03207 Parameters:
    03208
    03209     DeviceObject - Supplies the device object of the device being queried
    03210
    03211     SerialNumber - Supplies a pointer to a variable to receive the returned Id.
    03212                    This must be freed by the caller.
    03213
    03214 Return Value:
    03215
    03216     NTSTATUS code.
    03217
    03218 --*/
    03219 {
    03220     IO_STACK_LOCATION irpSp;
    03221     NTSTATUS status;
    03222
    03223     PAGED_CODE();
    03224
    03225     *SerialNumber = NULL;
    03226
    03227     //
    03228     // Initialize the stack location to pass to IopSynchronousCall()
    03229     //
    03230
    03231     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    03232
    03233     //
    03234     // Set the function codes.
    03235     //
    03236
    03237     irpSp.MajorFunction = IRP_MJ_PNP;
    03238     irpSp.MinorFunction = IRP_MN_QUERY_ID;
    03239     irpSp.Parameters.QueryId.IdType = BusQueryDeviceSerialNumber;
    03240
    03241     //
    03242     // Make the call and return.
    03243     //
    03244
    03245     status = IopSynchronousCall(DeviceObject, &irpSp, SerialNumber);
    03246
    03247     ASSERT(NT_SUCCESS(status) || (*SerialNumber == NULL));
    03248     if (!NT_SUCCESS(status)) {
    03249         *SerialNumber = NULL;
    03250     }
    03251     return status;
    03252 }

NTSTATUS IopQueryDeviceState | ( | IN PDEVICE_OBJECT | DeviceObject | ) |

Definition at line 2976 of file pnpirp.c.

References DNF_HAS_PRIVATE_PROBLEM, DNUF_DONT_SHOW_IN_UI, DNUF_NOT_DISABLEABLE, FALSE, _DEVICE_NODE::Flags, IopDecDisableableDepends(), IopIncDisableableDepends(), IopRequestDeviceRemoval(), IopResourceRequirementsChanged(), IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_PNP_DEVICE_STATE, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), PAGED_CODE, PNP_DEVICE_DISABLED, PNP_DEVICE_DONT_DISPLAY_IN_UI, PNP_DEVICE_FAILED, PNP_DEVICE_NOT_DISABLEABLE, PNP_DEVICE_REMOVED, PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED, PNP_DEVICE_STATE, TRUE, and _DEVICE_NODE::UserFlags.

Referenced by IopInvalidateDeviceStateWorker(), and IopStartAndEnumerateDevice().

    02982                    :
    02983
    02984     This routine sends query device state irp to the specified device object.
    02985
    02986 Parameters:
    02987
    02988     DeviceObjet - Supplies the device object of the device being queried.
    02989
    02990 Return Value:
    02991
    02992     NTSTATUS code.
    02993
    02994 --*/
    02995
    02996 {
    02997     IO_STACK_LOCATION irpSp;
    02998     PDEVICE_NODE deviceNode;
    02999     PNP_DEVICE_STATE deviceState;
    03000     PDEVICE_RELATIONS deviceRelations;
    03001     KEVENT userEvent;
    03002     ULONG eventResult;
    03003     NTSTATUS status;
    03004
    03005     PAGED_CODE();
    03006
    03007     //
    03008     // Initialize the stack location to pass to IopSynchronousCall()
    03009     //
    03010
    03011     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    03012
    03013     //
    03014     // Set the function codes.
    03015     //
    03016
    03017     irpSp.MajorFunction = IRP_MJ_PNP;
    03018     irpSp.MinorFunction = IRP_MN_QUERY_PNP_DEVICE_STATE;
    03019
    03020     //
    03021     // Make the call.
    03022     //
    03023
    03024     status = IopSynchronousCall(DeviceObject, &irpSp, (PVOID *)&deviceState);
    03025
    03026     //
    03027     // Now perform the appropriate action based on the returned state
    03028     //
    03029
    03030     if (NT_SUCCESS(status)) {
    03031
    03032         deviceNode = DeviceObject->DeviceObjectExtension->DeviceNode;
    03033
    03034         if (deviceState != 0) {
    03035
    03036             //
    03037             // everything here can only be turned on (state set)
    03038             //
    03039
    03040             if (deviceState & PNP_DEVICE_DONT_DISPLAY_IN_UI) {
    03041
    03042                 deviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI;
    03043             }
    03044
    03045             if (deviceState & PNP_DEVICE_NOT_DISABLEABLE) {
    03046
    03047                 if ((deviceNode->UserFlags & DNUF_NOT_DISABLEABLE)==0) {
    03048                     //
    03049                     // this node itself is not disableable
    03050                     //
    03051                     deviceNode->UserFlags |= DNUF_NOT_DISABLEABLE;
    03052                     //
    03053                     // propagate up tree
    03054                     //
    03055                     IopIncDisableableDepends(deviceNode);
    03056
    03057                 }
    03058             }
    03059
    03060             if (deviceState & (PNP_DEVICE_DISABLED | PNP_DEVICE_REMOVED)) {
    03061
    03062                 IopRequestDeviceRemoval( DeviceObject,
    03063                                          (deviceState & PNP_DEVICE_DISABLED) ?
    03064                                             CM_PROB_HARDWARE_DISABLED : CM_PROB_DEVICE_NOT_THERE
    03065                                          );
    03066
    03067             } else if (deviceState & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED) {
    03068
    03069                 if (deviceState & PNP_DEVICE_FAILED) {
    03070
    03071                     IopResourceRequirementsChanged(DeviceObject, TRUE);
    03072
    03073                 } else {
    03074
    03075                     IopResourceRequirementsChanged(DeviceObject, FALSE);
    03076
    03077                 }
    03078             } else if (deviceState & PNP_DEVICE_FAILED) {
    03079
    03080                 deviceNode->Flags |= DNF_HAS_PRIVATE_PROBLEM;
    03081
    03082                 IopRequestDeviceRemoval(DeviceObject, 0);
    03083             }
    03084         } else {
    03085
    03086             //
    03087             // handle things that can be turned off (state cleared)
    03088             //
    03089
    03090             if (deviceNode->UserFlags & DNUF_NOT_DISABLEABLE) {
    03091                 //
    03092                 // this node itself is now disableable
    03093                 //
    03094                 //
    03095                 // check tree
    03096                 //
    03097                 IopDecDisableableDepends(deviceNode);
    03098             }
    03099
    03100             deviceNode->UserFlags &= ~(DNUF_DONT_SHOW_IN_UI | DNUF_NOT_DISABLEABLE);
    03101         }
    03102     }
    03103
    03104     return status;
    03105 }

NTSTATUS IopQueryDockRemovalInterface | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN OUT PDOCK_INTERFACE * | DockInterface
| ) |

Definition at line 3395 of file pnpirp.c.

References dummy(), ExAllocatePool, ExFreePool(), IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_INTERFACE, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, _IO_STACK_LOCATION::Parameters, _INTERFACE::Size, USHORT, and _INTERFACE::Version.

    03402                    :
    03403
    03404     This routine queries the specified DeviceObject for the dock removal
    03405     interface. We use this interface to send pseudo-remove's. We use this
    03406     to solve the removal orderings problem.
    03407
    03408 Parameters:
    03409
    03410     DeviceObject - Supplies a pointer to the Device object to be queried.
    03411
    03412     Interface - supplies a variable to receive the desired interface.
    03413
    03414 Return Value:
    03415
    03416     Status code that indicates whether or not the function was successful.
    03417
    03418 --*/
    03419 {
    03420     IO_STACK_LOCATION irpSp;
    03421     NTSTATUS status;
    03422     PVOID dummy;
    03423     PINTERFACE interface;
    03424     USHORT size;
    03425     GUID interfaceType;
    03426
    03427     PAGED_CODE();
    03428
    03429     size = sizeof(DOCK_INTERFACE);
    03430     interfaceType = GUID_DOCK_INTERFACE;
    03431     interface = (PINTERFACE) ExAllocatePool(PagedPool, size);
    03432     if (interface == NULL) {
    03433         return STATUS_INSUFFICIENT_RESOURCES;
    03434     }
    03435
    03436     RtlZeroMemory(interface, size);
    03437     interface->Size = size;
    03438
    03439     //
    03440     // Initialize the stack location to pass to IopSynchronousCall()
    03441     //
    03442
    03443     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    03444
    03445     //
    03446     // Set the function codes.
    03447     //
    03448
    03449     irpSp.MajorFunction = IRP_MJ_PNP;
    03450     irpSp.MinorFunction = IRP_MN_QUERY_INTERFACE;
    03451
    03452     //
    03453     // Set the pointer to the resource list
    03454     //
    03455
    03456     irpSp.Parameters.QueryInterface.InterfaceType = &interfaceType;
    03457     irpSp.Parameters.QueryInterface.Size = interface->Size;
    03458     irpSp.Parameters.QueryInterface.Version = interface->Version = 0;
    03459     irpSp.Parameters.QueryInterface.Interface = interface;
    03460     irpSp.Parameters.QueryInterface.InterfaceSpecificData = NULL;
    03461
    03462     //
    03463     // Make the call and return.
    03464     //
    03465
    03466     status = IopSynchronousCall(DeviceObject, &irpSp, &dummy);
    03467     if (NT_SUCCESS(status)) {
    03468         *DockInterface = (PDOCK_INTERFACE) interface;
    03469     } else {
    03470         ExFreePool(interface);
    03471     }
    03472     return status;
    03473 }

NTSTATUS IopQueryLegacyBusInformation | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | OUT LPGUID InterfaceGuid | OPTIONAL,
|  | OUT INTERFACE_TYPE *InterfaceType | OPTIONAL,
|  | OUT ULONG *BusNumber | OPTIONAL
| ) |

NTSTATUS IopQueryPnpBusInformation | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | OUT LPGUID InterfaceGuid | OPTIONAL,
|  | OUT INTERFACE_TYPE *InterfaceType | OPTIONAL,
|  | OUT ULONG *BusNumber | OPTIONAL
| ) |

NTSTATUS IopQueryReconfiguration | ( | IN UCHAR | Request,
|  | IN PDEVICE_OBJECT | DeviceObject
| ) |

Definition at line 2733 of file pnpirp.c.

References ASSERT, dummy(), IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_CANCEL_STOP_DEVICE, IRP_MN_QUERY_STOP_DEVICE, IRP_MN_STOP_DEVICE, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), PAGED_CODE, and Request().

Referenced by IopRebalance(), and IopTestForReconfiguration().

    02740                    :
    02741
    02742     This routine queries the specified DeviceObject for the specified ResourceType
    02743     resource translator.
    02744
    02745 Parameters:
    02746
    02747     HandlerType - specifies Arbiter or Translator
    02748
    02749     DeviceObject - Supplies a pointer to the Device object to be queried.
    02750
    02751     ResourceType - Specifies the desired type of translator.
    02752
    02753     Interface - supplies a variable to receive the desired interface.
    02754
    02755 Return Value:
    02756
    02757     Status code that indicates whether or not the function was successful.
    02758
    02759 --*/
    02760 {
    02761     IO_STACK_LOCATION irpSp;
    02762     NTSTATUS status;
    02763     PVOID dummy;
    02764
    02765     PAGED_CODE();
    02766
    02767     ASSERT (Request == IRP_MN_QUERY_STOP_DEVICE ||
    02768             Request == IRP_MN_STOP_DEVICE ||
    02769             Request == IRP_MN_CANCEL_STOP_DEVICE);
    02770
    02771     //
    02772     // Initialize the stack location to pass to IopSynchronousCall()
    02773     //
    02774
    02775     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    02776
    02777     //
    02778     // Set the function codes.
    02779     //
    02780
    02781     irpSp.MajorFunction = IRP_MJ_PNP;
    02782     irpSp.MinorFunction = Request;
    02783
    02784     //
    02785     // Make the call and return.
    02786     //
    02787
    02788     status = IopSynchronousCall(DeviceObject, &irpSp, &dummy);
    02789     return status;
    02790 }

NTSTATUS IopQueryResourceHandlerInterface | ( | IN RESOURCE_HANDLER_TYPE | HandlerType,
|  | IN PDEVICE_OBJECT | DeviceObject,
|  | IN UCHAR | ResourceType,
|  | IN OUT PVOID * | Interface
| ) |

Definition at line 2617 of file pnpirp.c.

References DO_BUS_ENUMERATED_DEVICE, _DEVICE_OBJECT::DriverObject, dummy(), _DEVICE_NODE::DuplicatePDO, ExAllocatePool, ExFreePool(), IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_INTERFACE, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, _IO_STACK_LOCATION::Parameters, ResourceArbiter, ResourceLegacyDeviceDetection, ResourceTranslator, _INTERFACE::Size, USHORT, and _INTERFACE::Version.

Referenced by IopDuplicateDetection(), and IopSetupArbiterAndTranslators().

    02626                    :
    02627
    02628     This routine queries the specified DeviceObject for the specified ResourceType
    02629     resource translator.
    02630
    02631 Parameters:
    02632
    02633     HandlerType - specifies Arbiter or Translator
    02634
    02635     DeviceObject - Supplies a pointer to the Device object to be queried.
    02636
    02637     ResourceType - Specifies the desired type of translator.
    02638
    02639     Interface - supplies a variable to receive the desired interface.
    02640
    02641 Return Value:
    02642
    02643     Status code that indicates whether or not the function was successful.
    02644
    02645 --*/
    02646 {
    02647     IO_STACK_LOCATION irpSp;
    02648     NTSTATUS status;
    02649     PVOID dummy;
    02650     PINTERFACE interface;
    02651     USHORT size;
    02652     GUID interfaceType;
    02653     PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
    02654
    02655     PAGED_CODE();
    02656
    02657     //
    02658     // If this device object is created by pnp mgr for legacy resource allocation,
    02659     // skip it.
    02660     //
    02661
    02662     if ((deviceNode->DuplicatePDO == (PDEVICE_OBJECT) DeviceObject->DriverObject) ||
    02663         !(DeviceObject->Flags & DO_BUS_ENUMERATED_DEVICE)) {
    02664         return STATUS_NOT_SUPPORTED;
    02665     }
    02666
    02667     switch (HandlerType) {
    02668     case ResourceTranslator:
    02669         size = sizeof(TRANSLATOR_INTERFACE) + 4;  // Pnptest
    02670         //size = sizeof(TRANSLATOR_INTERFACE);
    02671         interfaceType = GUID_TRANSLATOR_INTERFACE_STANDARD;
    02672         break;
    02673
    02674     case ResourceArbiter:
    02675         size = sizeof(ARBITER_INTERFACE);
    02676         interfaceType = GUID_ARBITER_INTERFACE_STANDARD;
    02677         break;
    02678
    02679     case ResourceLegacyDeviceDetection:
    02680         size = sizeof(LEGACY_DEVICE_DETECTION_INTERFACE);
    02681         interfaceType = GUID_LEGACY_DEVICE_DETECTION_STANDARD;
    02682         break;
    02683
    02684     default:
    02685         return STATUS_INVALID_PARAMETER;
    02686     }
    02687
    02688     interface = (PINTERFACE) ExAllocatePool(PagedPool, size);
    02689     if (interface == NULL) {
    02690         return STATUS_INSUFFICIENT_RESOURCES;
    02691     }
    02692
    02693     RtlZeroMemory(interface, size);
    02694     interface->Size = size;
    02695
    02696     //
    02697     // Initialize the stack location to pass to IopSynchronousCall()
    02698     //
    02699
    02700     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    02701
    02702     //
    02703     // Set the function codes.
    02704     //
    02705
    02706     irpSp.MajorFunction = IRP_MJ_PNP;
    02707     irpSp.MinorFunction = IRP_MN_QUERY_INTERFACE;
    02708
    02709     //
    02710     // Set the pointer to the resource list
    02711     //
    02712
    02713     irpSp.Parameters.QueryInterface.InterfaceType = &interfaceType;
    02714     irpSp.Parameters.QueryInterface.Size = interface->Size;
    02715     irpSp.Parameters.QueryInterface.Version = interface->Version = 0;
    02716     irpSp.Parameters.QueryInterface.Interface = interface;
    02717     irpSp.Parameters.QueryInterface.InterfaceSpecificData = (PVOID) ResourceType;
    02718
    02719     //
    02720     // Make the call and return.
    02721     //
    02722
    02723     status = IopSynchronousCall(DeviceObject, &irpSp, &dummy);
    02724     if (NT_SUCCESS(status)) {
    02725         *Interface = interface;
    02726     } else {
    02727         ExFreePool(interface);
    02728     }
    02729     return status;
    02730 }

NTSTATUS IopQueryUniqueId | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | OUT PWCHAR * | UniqueId
| ) |

Definition at line 1820 of file pnpirp.c.

References BusQueryInstanceID, IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_ID, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, and _IO_STACK_LOCATION::Parameters.

Referenced by IopProcessNewDeviceNode().

    01827                    :
    01828
    01829
    01830     This routine generates a unique id for the specified device object.
    01831
    01832 Parameters:
    01833
    01834     DeviceObject - Supplies the device object of the device being queried
    01835
    01836     UniqueId - Supplies a pointer to a variable to receive the returned Id.
    01837                This must be freed by the caller.
    01838
    01839     GloballyUnique - Indicates (from a previous call to query capabilities
    01840                      whether the id is globally unique.
    01841 Return Value:
    01842
    01843     NTSTATUS code.
    01844
    01845 --*/
    01846 {
    01847     IO_STACK_LOCATION irpSp;
    01848     NTSTATUS status;
    01849
    01850     PAGED_CODE();
    01851
    01852     *UniqueId = NULL;
    01853
    01854     //
    01855     // First ask for for InstanceId.
    01856     //
    01857
    01858     // Initialize the stack location to pass to IopSynchronousCall()
    01859     //
    01860
    01861     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    01862
    01863     //
    01864     // Set the function codes.
    01865     //
    01866
    01867     irpSp.MajorFunction = IRP_MJ_PNP;
    01868     irpSp.MinorFunction = IRP_MN_QUERY_ID;
    01869
    01870     //
    01871     // Set the pointer to the resource list
    01872     //
    01873
    01874     irpSp.Parameters.QueryId.IdType = BusQueryInstanceID;
    01875
    01876     //
    01877     // Make the call and return.
    01878     //
    01879
    01880     status = IopSynchronousCall(DeviceObject, &irpSp, UniqueId);
    01881
    01882     if (!NT_SUCCESS(status)) {
    01883         *UniqueId = NULL;
    01884     }
    01885
    01886     return status;
    01887
    01888 }

BOOLEAN IopQueuePendingEject | ( | PPENDING_RELATIONS_LIST_ENTRY | Entry | ) |

Definition at line 1234 of file pnpdel.c.

References IopAcquireDeviceTreeLock, IopPendingEjects, IopReleaseDeviceTreeLock, _PENDING_RELATIONS_LIST_ENTRY::Link, PAGED_CODE, and TRUE.

Referenced by IopEjectDevice().

    01237 {
    01238     PAGED_CODE();
    01239
    01240     IopAcquireDeviceTreeLock();
    01241
    01242     InsertTailList(&IopPendingEjects, &Entry->Link);
    01243
    01244     IopReleaseDeviceTreeLock();
    01245
    01246     return TRUE;
    01247 }

BOOLEAN IopQueuePendingSurpriseRemoval | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN PRELATION_LIST | List,
|  | IN ULONG | Problem
| ) |

Definition at line 1540 of file pnpdel.c.

References _PENDING_RELATIONS_LIST_ENTRY::DeviceObject, ExAllocatePool, FALSE, IopAcquireDeviceTreeLock, IopPendingSurpriseRemovals, IopReleaseDeviceTreeLock, _PENDING_RELATIONS_LIST_ENTRY::Link, List, NonPagedPool, NULL, PAGED_CODE, _PENDING_RELATIONS_LIST_ENTRY::Problem, _PENDING_RELATIONS_LIST_ENTRY::ProfileChangingEject, _PENDING_RELATIONS_LIST_ENTRY::RelationsList, and TRUE.

    01545 {
    01546     PPENDING_RELATIONS_LIST_ENTRY   entry;
    01547
    01548     PAGED_CODE();
    01549
    01550     entry = ExAllocatePool( NonPagedPool, sizeof(PENDING_RELATIONS_LIST_ENTRY) );
    01551
    01552     if (entry != NULL) {
    01553
    01554         entry->DeviceObject = DeviceObject;
    01555         entry->RelationsList = List;
    01556         entry->Problem = Problem;
    01557         entry->ProfileChangingEject = FALSE ;
    01558
    01559         IopAcquireDeviceTreeLock();
    01560
    01561         InsertTailList(&IopPendingSurpriseRemovals, &entry->Link);
    01562
    01563         IopReleaseDeviceTreeLock();
    01564
    01565         return TRUE;
    01566     }
    01567
    01568     return FALSE;
    01569 }

NTSTATUS IopReadDeviceConfiguration | ( | IN HANDLE | Handle,
|  | IN ULONG | Flags,
|  | OUT PCM_RESOURCE_LIST * | CmResource,
|  | OUT PULONG | Length
| ) |

Definition at line 4283 of file pnpsubs.c.

References ExAllocatePool, ExFreePool(), Handle, IopGetRegistryValue(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, PnpDefaultInterfaceType, REGISTRY_ALLOC_CONFIG, REGISTRY_BOOT_CONFIG, and REGISTRY_FORCED_CONFIG.

Referenced by IopGetDeviceResourcesFromRegistry().

    04292                    :
    04293
    04294     This routine read the specified ALLOC config or ForcedConfig or Boot config.
    04295
    04296 Arguments:
    04297
    04298     Hanle - supplies a handle to the registry key to read resources.
    04299
    04300 Return Value:
    04301
    04302     status
    04303
    04304 --*/
    04305
    04306 {
    04307     NTSTATUS status;
    04308     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    04309     PWCHAR valueName;
    04310
    04311     *CmResource = NULL;
    04312     *Length = 0;
    04313
    04314     if (Flags == REGISTRY_ALLOC_CONFIG) {
    04315         valueName = REGSTR_VALUE_ALLOC_CONFIG;
    04316     } else if (Flags == REGISTRY_FORCED_CONFIG) {
    04317         valueName = REGSTR_VALUE_FORCED_CONFIG;
    04318     } else if (Flags == REGISTRY_BOOT_CONFIG) {
    04319         valueName = REGSTR_VALUE_BOOT_CONFIG;
    04320     } else {
    04321         return STATUS_INVALID_PARAMETER_2;
    04322     }
    04323
    04324     //
    04325     // Read the registry value of the desired value name
    04326     //
    04327
    04328     status = IopGetRegistryValue (Handle,
    04329                                   valueName,
    04330                                   &keyValueInformation);
    04331     if (NT_SUCCESS(status)) {
    04332
    04333         //
    04334         // Try to read what caller wants.
    04335         //
    04336
    04337         if ((keyValueInformation->Type == REG_RESOURCE_LIST) &&
    04338             (keyValueInformation->DataLength != 0)) {
    04339             *CmResource = ExAllocatePool(PagedPool,
    04340                                          keyValueInformation->DataLength);
    04341             if (*CmResource) {
    04342                 if (*CmResource) {
    04343                     *Length = keyValueInformation->DataLength;
    04344                     RtlMoveMemory(*CmResource,
    04345                                   KEY_VALUE_DATA(keyValueInformation),
    04346                                   keyValueInformation->DataLength);
    04347                 } else {
    04348                     status = STATUS_INSUFFICIENT_RESOURCES;
    04349                 }
    04350             }
    04351             ExFreePool(keyValueInformation);
    04352             if (*CmResource) {
    04353                 PCM_RESOURCE_LIST resourceList;
    04354                 PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc;
    04355                 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartDesc;
    04356                 ULONG j, k, size, count;
    04357
    04358                 //
    04359                 // Process the resource list read from Registry to change undefined
    04360                 // interface type to our default interface type.
    04361                 //
    04362
    04363                 resourceList = *CmResource;
    04364                 cmFullDesc = &resourceList->List[0];
    04365                 for (j = 0; j < resourceList->Count; j++) {
    04366                     if (cmFullDesc->InterfaceType == InterfaceTypeUndefined) {
    04367                         cmFullDesc->BusNumber = 0;
    04368                         cmFullDesc->InterfaceType = PnpDefaultInterfaceType;
    04369                     }
    04370                     cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
    04371                     for (k = 0; k < cmFullDesc->PartialResourceList.Count; k++) {
    04372                         size = 0;
    04373                         switch (cmPartDesc->Type) {
    04374                         case CmResourceTypeDeviceSpecific:
    04375                              size = cmPartDesc->u.DeviceSpecificData.DataSize;
    04376                              break;
    04377                         }
    04378                         cmPartDesc++;
    04379                         cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size);
    04380                     }
    04381                     cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc;
    04382                 }
    04383             }
    04384         } else if (keyValueInformation->Type != REG_RESOURCE_LIST) {
    04385             status = STATUS_UNSUCCESSFUL;
    04386         }
    04387     }
    04388     return status;
    04389 }

VOID IopReallocateResources | ( | IN PDEVICE_OBJECT | DeviceObject | ) |

Definition at line 7470 of file pnpres.c.

References ASSERT, DebugMessage, DelayExecution, DNF_ASSIGNING_RESOURCES, DNF_HAS_RESOURCE, DNF_NON_STOPPED_REBALANCE, DNF_RESOURCE_ASSIGNED, DNF_RESOURCE_REPORTED, DNF_RESOURCE_REQUIREMENTS_CHANGED, DUMP_ERROR, ExAcquireResourceShared, ExFreePool(), ExReleaseResource, FALSE, _DEVICE_NODE::Flags, _IOP_RESOURCE_REQUEST::Flags, IOP_ASSIGN_KEEP_CURRENT_CONFIG, IOP_ASSIGN_NO_REBALANCE, IopAcquireEnumerationLock, IopAssignInner(), IopBuildCmResourceLists(), IopDeviceTreeLock, IopFreeResourceRequirementsForAssignTable(), IopGetResourceRequirementsForAssignTable(), IopRebalance(), IopRegistrySemaphore, IopReleaseEnumerationLock, IopReleaseResourcesInternal(), IopRequestDeviceRemoval(), IopRestoreResourcesInternal(), IopStartDevice(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, _IOP_RESOURCE_REQUEST::PhysicalDevice, _DEVICE_NODE::PhysicalDeviceObject, _IOP_RESOURCE_REQUEST::ResourceAssignment, _DEVICE_NODE::ResourceList, _DEVICE_NODE::ResourceListTranslated, _IOP_RESOURCE_REQUEST::TranslatedResourceAssignment, and TRUE.

Referenced by IopDeviceActionWorker().

    07476                    :
    07477
    07478     This routine performs the real work for IoInvalidateDeviceState - ResourceRequirementsChanged.
    07479
    07480 Arguments:
    07481
    07482     DeviceObject - Supplies a pointer to the device object.
    07483
    07484 Return Value:
    07485
    07486     None.
    07487
    07488 --*/
    07489 {
    07490     PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
    07491     IOP_RESOURCE_REQUEST requestTable, *requestTablep;
    07492     ULONG deviceCount, oldFlags;
    07493     NTSTATUS status;
    07494
    07495     PAGED_CODE();
    07496
    07497     //
    07498     // Grab the IO registry semaphore to make sure no other device is
    07499     // reporting it's resource usage while we are searching for conflicts.
    07500     //
    07501
    07502     KeEnterCriticalRegion();
    07503     status = KeWaitForSingleObject( &IopRegistrySemaphore,
    07504                                     DelayExecution,
    07505                                     KernelMode,
    07506                                     FALSE,
    07507                                     NULL);
    07508     if (NT_SUCCESS(status)) {
    07509
    07510         //
    07511         // Acquire the tree lock so we block remove for this device node.
    07512         //
    07513
    07514         ExAcquireResourceShared(&IopDeviceTreeLock, TRUE);
    07515
    07516         //
    07517         // Check the flags after acquiring the semaphore.
    07518         //
    07519
    07520         if (deviceNode->Flags & DNF_RESOURCE_REQUIREMENTS_CHANGED) {
    07521             //
    07522             // Save the flags which we may have to restore in case of failure.
    07523             //
    07524
    07525             oldFlags = deviceNode->Flags & DNF_HAS_RESOURCE;
    07526             deviceNode->Flags &= ~(DNF_HAS_RESOURCE);
    07527
    07528             if (deviceNode->Flags & DNF_NON_STOPPED_REBALANCE) {
    07529
    07530                 IopAcquireEnumerationLock(deviceNode);
    07531
    07532                 //
    07533                 // Set up parameters to call real routine
    07534                 //
    07535
    07536                 deviceNode->Flags |= DNF_ASSIGNING_RESOURCES;
    07537
    07538                 RtlZeroMemory(&requestTable, sizeof(IOP_RESOURCE_REQUEST));
    07539                 requestTable.PhysicalDevice = DeviceObject;
    07540                 requestTablep = &requestTable;
    07541                 requestTable.Flags |= IOP_ASSIGN_NO_REBALANCE + IOP_ASSIGN_KEEP_CURRENT_CONFIG;
    07542
    07543                 status = IopGetResourceRequirementsForAssignTable(  requestTablep,
    07544                                                                     requestTablep + 1,
    07545                                                                     &deviceCount);
    07546                 if (NT_SUCCESS(status) && deviceCount) {
    07547
    07548                     //
    07549                     // Release the current resources to the arbiters.
    07550                     // Memory for ResourceList is not released.
    07551                     //
    07552
    07553                     if (deviceNode->ResourceList) {
    07554
    07555                         IopReleaseResourcesInternal(deviceNode);
    07556                     }
    07557
    07558                     //
    07559                     // Try to do the assignment.
    07560                     //
    07561
    07562                     status = IopAssignInner(deviceCount, requestTablep, FALSE);
    07563                     if (NT_SUCCESS(status)) {
    07564
    07565                         deviceNode->Flags &= ~(DNF_RESOURCE_REQUIREMENTS_CHANGED | DNF_NON_STOPPED_REBALANCE);
    07566
    07567                         IopBuildCmResourceLists(requestTablep, requestTablep + 1);
    07568
    07569                         //
    07570                         // We need to release the pool space for ResourceList and ResourceListTranslated.
    07571                         // Because the earlier IopReleaseResourcesInternal does not release the pool.
    07572                         //
    07573
    07574                         if (deviceNode->ResourceList) {
    07575
    07576                             ExFreePool(deviceNode->ResourceList);
    07577
    07578                         }
    07579                         if (deviceNode->ResourceListTranslated) {
    07580
    07581                             ExFreePool(deviceNode->ResourceListTranslated);
    07582
    07583                         }
    07584
    07585                         deviceNode->ResourceList = requestTablep->ResourceAssignment;
    07586                         deviceNode->ResourceListTranslated = requestTablep->TranslatedResourceAssignment;
    07587                         deviceNode->Flags |= DNF_RESOURCE_ASSIGNED;
    07588                         deviceNode->Flags &= ~DNF_RESOURCE_REPORTED;
    07589
    07590                         IopStartDevice(deviceNode->PhysicalDeviceObject);
    07591
    07592                     } else {
    07593
    07594                         NTSTATUS restoreResourcesStatus;
    07595
    07596                         restoreResourcesStatus = IopRestoreResourcesInternal(deviceNode);
    07597                         if (!NT_SUCCESS(restoreResourcesStatus)) {
    07598
    07599                             ASSERT(NT_SUCCESS(restoreResourcesStatus));
    07600                             IopRequestDeviceRemoval(DeviceObject, CM_PROB_NORMAL_CONFLICT);
    07601
    07602                         }
    07603
    07604                         //
    07605                         // BUGBUG - once we failed, what will trigger us to try again?
    07606                         //
    07607                     }
    07608
    07609                     IopFreeResourceRequirementsForAssignTable(requestTablep, requestTablep + 1);
    07610
    07611
    07612                 } else {
    07613
    07614                     status = NT_SUCCESS(status)? STATUS_UNSUCCESSFUL : status;
    07615
    07616                 }
    07617
    07618                 deviceNode->Flags &= ~DNF_ASSIGNING_RESOURCES;
    07619                 IopReleaseEnumerationLock(deviceNode);
    07620
    07621             } else {
    07622
    07623                 //
    07624                 // The device needs to be stopped to change resources.
    07625                 //
    07626
    07627                 status = IopRebalance(0, NULL);
    07628
    07629             }
    07630
    07631             //
    07632             // Restore the flags in case of failure.
    07633             //
    07634
    07635             if (!NT_SUCCESS(status)) {
    07636
    07637                 deviceNode->Flags &= ~DNF_HAS_RESOURCE;
    07638                 deviceNode->Flags |= oldFlags;
    07639
    07640             }
    07641
    07642         } else {
    07643
    07644             DebugMessage(DUMP_ERROR, ("PNPRES: Resource requirements not changed in IopReallocateResources, returning error!\n"));
    07645         }
    07646
    07647         ExReleaseResource(&IopDeviceTreeLock);
    07648         KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE);
    07649
    07650     } else {
    07651
    07652         DebugMessage(DUMP_ERROR, ("PNPRES: IopReallocateResources failed to acquire Registry semaphore, status %08X\n", status));
    07653
    07654     }
    07655
    07656     KeLeaveCriticalRegion();
    07657 }

PDRIVER_OBJECT IopReferenceDriverObjectByName | ( | IN PUNICODE_STRING | DriverName | ) |

Definition at line 3686 of file pnpsubs.c.

References IoDriverObjectType, KernelMode, NT_SUCCESS, NtClose(), NTSTATUS(), NULL, ObOpenObjectByName(), and ObReferenceObjectByHandle().

Referenced by IopCallDriverAddDeviceQueryRoutine(), and IopInitializeSystemDrivers().

    03692                    :
    03693
    03694     This routine references a driver object by a given driver name.
    03695
    03696 Arguments:
    03697
    03698     DriverName - supplies a pointer to the name of the driver whose driver object is
    03699         to be referenced.
    03700
    03701 Returns:
    03702
    03703     A pointer to a DRIVER_OBJECT if succeeds.  Otherwise, a NULL value.
    03704
    03705 --*/
    03706
    03707 {
    03708     OBJECT_ATTRIBUTES objectAttributes;
    03709     HANDLE driverHandle;
    03710     NTSTATUS status;
    03711     PDRIVER_OBJECT driverObject;
    03712
    03713     //
    03714     // Make sure the driver name is valid.
    03715     //
    03716
    03717     if (DriverName->Length == 0) {
    03718         return NULL;
    03719     }
    03720
    03721     InitializeObjectAttributes(&objectAttributes,
    03722                                DriverName,
    03723                                OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
    03724                                NULL,
    03725                                NULL
    03726                                );
    03727     status = ObOpenObjectByName(&objectAttributes,
    03728                                 IoDriverObjectType,
    03729                                 KernelMode,
    03730                                 NULL,
    03731                                 FILE_READ_ATTRIBUTES,
    03732                                 NULL,
    03733                                 &driverHandle
    03734                                 );
    03735     if (NT_SUCCESS(status)) {
    03736
    03737         //
    03738         // Now reference the driver object.
    03739         //
    03740
    03741         status = ObReferenceObjectByHandle(driverHandle,
    03742                                            0,
    03743                                            IoDriverObjectType,
    03744                                            KernelMode,
    03745                                            &driverObject,
    03746                                            NULL
    03747                                            );
    03748         NtClose(driverHandle);
    03749     }
    03750
    03751     if (NT_SUCCESS(status)) {
    03752         return driverObject;
    03753     } else {
    03754         return NULL;
    03755     }
    03756 }

NTSTATUS IopRegisterDeviceInterface | ( | IN PUNICODE_STRING | DeviceInstanceName,
|  | IN CONST GUID * | InterfaceClassGuid,
|  | IN PUNICODE_STRING ReferenceString | OPTIONAL,
|  | IN BOOLEAN | UserModeFormat,
|  | OUT PUNICODE_STRING | SymbolicLinkName
| ) |

Definition at line 3929 of file pnpioapi.c.

References ExAcquireResourceExclusive, ExReleaseResource, IopBuildSymbolicLinkStrings(), IopCreateRegistryKeyEx(), IopFreeAllocatedUnicodeString(), IopOpenOrCreateDeviceInterfaceSubKeys(), IopSetRegistryStringValue(), KeEnterCriticalRegion, KeLeaveCriticalRegion, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PpRegistryDeviceResource, RtlFreeUnicodeString(), RtlStringFromGUID(), and TRUE.

Referenced by IoRegisterDeviceInterface().

    03939                    :
    03940
    03941     This is the worker routine for PnpRegisterDeviceInterface.  It is also
    03942     called by the user-mode ConfigMgr (via an NtPlugPlayControl), which is why it
    03943     must take a device instance name instead of a PDO (since the device instance
    03944     may not currently be 'live'), and also why it must optionally return the user-
    03945     mode form of the interface device name (i.e., "\\?\" instead of "\??\").
    03946
    03947 Parameters:
    03948
    03949     DeviceInstanceName - Supplies the name of the device instance for which a
    03950         device interface is being registered.
    03951
    03952     InterfaceClassGuid - Supplies a pointer to the GUID representring the class
    03953         of the device interface being registered.
    03954
    03955     ReferenceString - Optionally, supplies an additional context string which is
    03956         appended to the enumeration path of the device
    03957
    03958     UserModeFormat - If non-zero, then the symbolic link name returned for the
    03959         interface device is in user-mode form (i.e., "\\?\").  If zero (FALSE),
    03960         it is in kernel-mode form (i.e., "\??\").
    03961
    03962     SymbolicLinkName - Supplies a pointer to a string which on success will contain
    03963         either the kernel-mode or user-mode path of the symbolic link used to open
    03964         this device.
    03965
    03966 Return Value:
    03967
    03968     Status code that indicates whether or not the function was successful.
    03969
    03970 --*/
    03971
    03972 {
    03973     NTSTATUS status;
    03974     UNICODE_STRING tempString, guidString, otherString;
    03975     PUNICODE_STRING pUserString, pKernelString;
    03976     HANDLE hTemp1, hTemp2, hInterfaceInstanceKey;
    03977     ULONG InterfaceDisposition, InterfaceInstanceDisposition;
    03978
    03979     PAGED_CODE();
    03980
    03981     //
    03982     // Convert the class guid into string form
    03983     //
    03984
    03985     status = RtlStringFromGUID(InterfaceClassGuid, &guidString);
    03986     if( !NT_SUCCESS(status) ){
    03987         goto clean0;
    03988     }
    03989
    03990     //
    03991     // Construct both flavors of symbolic link name (go ahead and store the form
    03992     // that the user wants in the SymbolicLinkName parameter they supplied--this
    03993     // saves us from having to copy the appropriate string over to their string
    03994     // later).
    03995     //
    03996     if(UserModeFormat) {
    03997         pUserString = SymbolicLinkName;
    03998         pKernelString = &otherString;
    03999     } else {
    04000         pKernelString = SymbolicLinkName;
    04001         pUserString = &otherString;
    04002     }
    04003
    04004     status = IopBuildSymbolicLinkStrings(DeviceInstanceName,
    04005                                          &guidString,
    04006                                          ReferenceString,
    04007                                          pUserString,
    04008                                          pKernelString
    04009                                          );
    04010     if (!NT_SUCCESS(status)) {
    04011         goto clean1;
    04012     }
    04013
    04014     //
    04015     // Enter critical section and acquire a lock on the registry.  Both these
    04016     // mechanisms are required to prevent deadlock in the case where an APC
    04017     // routine calls this routine after the registry resource has been claimed
    04018     // in this case it would wait blocking this thread so the registry would
    04019     // never be released -> deadlock.  Critical sectioning the registry manipulation
    04020     // portion solves this problem
    04021     //
    04022
    04023     KeEnterCriticalRegion();
    04024     ExAcquireResourceExclusive(&PpRegistryDeviceResource, TRUE);
    04025
    04026     //
    04027     // Open HKLM\System\CurrentControlSet\Control\DeviceClasses key into hTemp1
    04028     //
    04029
    04030     PiWstrToUnicodeString(&tempString, REGSTR_FULL_PATH_DEVICE_CLASSES);
    04031     status = IopCreateRegistryKeyEx( &hTemp1,
    04032                                      NULL,
    04033                                      &tempString,
    04034                                      KEY_CREATE_SUB_KEY,
    04035                                      REG_OPTION_NON_VOLATILE,
    04036                                      NULL
    04037                                      );
    04038
    04039     if( !NT_SUCCESS(status) ){
    04040         goto clean2;
    04041     }
    04042
    04043     //
    04044     // Open/create function class GUID key into hTemp2
    04045     //
    04046
    04047     status = IopCreateRegistryKeyEx( &hTemp2,
    04048                                      hTemp1,
    04049                                      &guidString,
    04050                                      KEY_CREATE_SUB_KEY,
    04051                                      REG_OPTION_NON_VOLATILE,
    04052                                      NULL
    04053                                      );
    04054     ZwClose(hTemp1);
    04055
    04056     if( !NT_SUCCESS(status) ){
    04057         goto clean2;
    04058     }
    04059
    04060     //
    04061     // Now open/create the two-level device interface hierarchy underneath this
    04062     // interface class key.
    04063     //
    04064     status = IopOpenOrCreateDeviceInterfaceSubKeys(&hTemp1,
    04065                                                    &InterfaceDisposition,
    04066                                                    &hInterfaceInstanceKey,
    04067                                                    &InterfaceInstanceDisposition,
    04068                                                    hTemp2,
    04069                                                    pUserString,
    04070                                                    KEY_WRITE | DELETE,
    04071                                                    TRUE
    04072                                                   );
    04073
    04074     ZwClose(hTemp2);
    04075
    04076     if(!NT_SUCCESS(status)) {
    04077         goto clean2;
    04078     }
    04079
    04080     //
    04081     // Create the device instance value under the device interface key
    04082     //
    04083
    04084     PiWstrToUnicodeString(&tempString, REGSTR_VAL_DEVICE_INSTANCE);
    04085     status = IopSetRegistryStringValue(hTemp1,
    04086                                        &tempString,
    04087                                        DeviceInstanceName
    04088                                        );
    04089     if(!NT_SUCCESS(status)) {
    04090         goto clean3;
    04091     }
    04092
    04093     //
    04094     // Create symbolic link value under interface instance subkey
    04095     //
    04096
    04097     PiWstrToUnicodeString(&tempString, REGSTR_VAL_SYMBOLIC_LINK);
    04098     status = IopSetRegistryStringValue(hInterfaceInstanceKey,
    04099                                        &tempString,
    04100                                        pUserString
    04101                                        );
    04102
    04103 clean3:
    04104     if (!NT_SUCCESS(status)) {
    04105         //
    04106         // Since we failed to register the device interface, delete any keys
    04107         // that were newly created in the attempt.
    04108         //
    04109         if(InterfaceInstanceDisposition == REG_CREATED_NEW_KEY) {
    04110             ZwDeleteKey(hInterfaceInstanceKey);
    04111         } else {
    04112             ZwClose(hInterfaceInstanceKey);
    04113         }
    04114
    04115         if(InterfaceDisposition == REG_CREATED_NEW_KEY) {
    04116             ZwDeleteKey(hTemp1);
    04117         } else {
    04118             ZwClose(hTemp1);
    04119         }
    04120     } else {
    04121         ZwClose(hInterfaceInstanceKey);
    04122         ZwClose(hTemp1);
    04123     }
    04124
    04125 clean2:
    04126     ExReleaseResource(&PpRegistryDeviceResource);
    04127     KeLeaveCriticalRegion();
    04128     IopFreeAllocatedUnicodeString(&otherString);
    04129     if (!NT_SUCCESS(status)) {
    04130         IopFreeAllocatedUnicodeString(SymbolicLinkName);
    04131     }
    04132
    04133 clean1:
    04134     RtlFreeUnicodeString(&guidString);
    04135 clean0:
    04136     return status;
    04137 }

NTSTATUS IopRegMultiSzToUnicodeStrings | ( | IN PKEY_VALUE_FULL_INFORMATION | KeyValueInformation,
|  | IN PUNICODE_STRING * | UnicodeStringList,
|  | OUT PULONG | UnicodeStringCount
| ) |

NTSTATUS IopReleaseDeviceResources | ( | IN PDEVICE_NODE | DeviceNode,
|  | IN BOOLEAN | ReserveResources
| ) |

Definition at line 263 of file pnpdd.c.

References ArbiterRequestPnpEnumerated, ArbiterRequestUndefined, ASSERT, DNF_BOOT_CONFIG_RESERVED, DNF_HAS_BOOT_CONFIG, DNF_MADEUP, ExAcquireResourceShared, ExReleaseResource, IopCreateRegistryKeyEx(), IopDeviceObjectToDeviceInstance(), IopLegacyResourceAllocation(), IoPnpDriverObject, IopQueryDeviceResources(), IopResourcesReleased, KeEnterCriticalRegion, KeLeaveCriticalRegion, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PpRegistryDeviceResource, QUERY_RESOURCE_LIST, TITLE_INDEX_VALUE, and TRUE.

Referenced by IopDeleteLegacyKey(), IopDeleteLockedDeviceNode(), IopDisableDevice(), IopDriverLoadingFailed(), and IoReportDetectedDevice().

    00270                    :
    00271
    00272     This routine releases the resources assigned to a device.
    00273
    00274 Arguments:
    00275
    00276     DeviceObject - supplies a pointer to a device whose resources are to be released.
    00277
    00278     ReserveResources - indicates whether we need to re-query and reserve BOOT config for DeviceObject.
    00279
    00280 Return Value:
    00281
    00282     NTSTATUS code.
    00283
    00284
    00285 --*/
    00286 {
    00287     BOOLEAN             conflict;
    00288     NTSTATUS            status= STATUS_SUCCESS;
    00289     PCM_RESOURCE_LIST   cmResource;
    00290     ULONG               cmLength;
    00291
    00292     PAGED_CODE();
    00293
    00294     if (DeviceNode->ResourceList || (DeviceNode->Flags & DNF_BOOT_CONFIG_RESERVED)) {
    00295
    00296         cmResource = NULL;
    00297         cmLength = 0;
    00298
    00299         //
    00300         // If needed, re-query for BOOT configs. We need to do this BEFORE we
    00301         // release the BOOT config (otherwise ROOT devices cannot report BOOT
    00302         // config).
    00303         //
    00304
    00305         if (ReserveResources && !(DeviceNode->Flags & DNF_MADEUP)) {
    00306
    00307             //
    00308             // First query for new BOOT config (order important for ROOT devices).
    00309             //
    00310
    00311             status = IopQueryDeviceResources (  DeviceNode->PhysicalDeviceObject,
    00312                                                 QUERY_RESOURCE_LIST,
    00313                                                 &cmResource,
    00314                                                 &cmLength);
    00315
    00316             if (!NT_SUCCESS(status)) {
    00317
    00318                 cmResource = NULL;
    00319                 cmLength = 0;
    00320
    00321             }
    00322         }
    00323
    00324         //
    00325         // Release resources for this device.
    00326         //
    00327
    00328         status = IopLegacyResourceAllocation(   ArbiterRequestUndefined,
    00329                                                 IoPnpDriverObject,
    00330                                                 DeviceNode->PhysicalDeviceObject,
    00331                                                 NULL,
    00332                                                 NULL);
    00333         if (NT_SUCCESS(status)) {
    00334
    00335             IopResourcesReleased = TRUE;        // Signal there are resources available.
    00336
    00337             //
    00338             // If needed, re-query and reserve current BOOT config for this device.
    00339             // We always rereserve the boot config (ie DNF_MADEUP root enumerated
    00340             // and IoReportDetected) devices in IopLegacyResourceAllocation.
    00341             //
    00342
    00343             if (ReserveResources && !(DeviceNode->Flags & DNF_MADEUP)) {
    00344
    00345                 UNICODE_STRING      unicodeName;
    00346                 HANDLE              logConfHandle;
    00347                 HANDLE              handle;
    00348
    00349                 ASSERT(DeviceNode->BootResources == NULL);
    00350
    00351                 status = IopDeviceObjectToDeviceInstance(DeviceNode->PhysicalDeviceObject, &handle, KEY_ALL_ACCESS);
    00352                 logConfHandle = NULL;
    00353                 if (NT_SUCCESS(status)) {
    00354
    00355
    00356                     PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF);
    00357                     status = IopCreateRegistryKeyEx( &logConfHandle,
    00358                                                      handle,
    00359                                                      &unicodeName,
    00360                                                      KEY_ALL_ACCESS,
    00361                                                      REG_OPTION_NON_VOLATILE,
    00362                                                      NULL);
    00363                     if (!NT_SUCCESS(status)) {
    00364
    00365                         logConfHandle = NULL;
    00366
    00367                     }
    00368                 }
    00369
    00370                 if (logConfHandle) {
    00371
    00372                     PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_BOOTCONFIG);
    00373                     KeEnterCriticalRegion();
    00374                     ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE);
    00375                     if (cmResource) {
    00376
    00377                         ZwSetValueKey(  logConfHandle,
    00378                                         &unicodeName,
    00379                                         TITLE_INDEX_VALUE,
    00380                                         REG_RESOURCE_LIST,
    00381                                         cmResource,
    00382                                         cmLength);
    00383                     } else {
    00384
    00385                         ZwDeleteValueKey(logConfHandle, &unicodeName);
    00386
    00387                     }
    00388                     ExReleaseResource(&PpRegistryDeviceResource);
    00389                     KeLeaveCriticalRegion();
    00390
    00391                     ZwClose(logConfHandle);
    00392                 }
    00393
    00394                 //
    00395                 // Reserve any remaining BOOT config.
    00396                 //
    00397
    00398                 if (cmResource) {
    00399
    00400                     DeviceNode->Flags |= DNF_HAS_BOOT_CONFIG;
    00401                     DeviceNode->BootResources = cmResource;
    00402
    00403                     //
    00404                     // This device consumes BOOT resources.  Reserve its boot resources
    00405                     //
    00406
    00407                     (*IopReserveResourcesRoutine)(  ArbiterRequestPnpEnumerated,
    00408                                                     DeviceNode->PhysicalDeviceObject,
    00409                                                     cmResource);
    00410                 }
    00411             }
    00412         }
    00413     }
    00414
    00415     return status;
    00416 }

NTSTATUS IopRemoveDevice | ( | IN PDEVICE_OBJECT | TargetDevice,
|  | IN ULONG | IrpMinorCode
| ) |

Definition at line 927 of file pnpirp.c.

References ASSERT, ASSERTMSG, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_ADDED, DNF_LEGACY_DRIVER, DNF_NEED_ENUMERATION_ONLY, DNF_NEED_QUERY_IDS, DNF_STARTED, DNUF_NOT_DISABLEABLE, dummy(), FALSE, IopDecDisableableDepends(), IopFindMountableDevice(), IopInvalidateVolumesForDevice(), IopLockMountedDeviceForRemove(), IopSynchronousCall(), IopUncacheInterfaceInformation(), IopUnlockMountedDeviceForRemove(), IRP_MJ_PNP, IRP_MN_CANCEL_REMOVE_DEVICE, IRP_MN_EJECT, IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE, IRP_MN_SURPRISE_REMOVAL, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, TRUE, and _DEVICE_NODE::UserFlags.

Referenced by IopDeleteLockedDeviceNode(), IopDisableDevice(), and IopProcessNewDeviceNode().

    00934                    :
    00935
    00936     This function sends a requested DeviceRemoval related irp to the top level device
    00937     object which roots on TargetDevice.  If there is a VPB associated with the
    00938     TargetDevice, the corresponding filesystem's VDO will be used.  Otherwise
    00939     the irp will be sent directly to the target device/ or its assocated device
    00940     object.
    00941
    00942 Parameters:
    00943
    00944     TargetDevice - Supplies the device object of the device being removed.
    00945
    00946     Operation - Specifies the operation requested.
    00947         The following IRP codes are used with IRP_MJ_DEVICE_CHANGE for removing
    00948         devices:
    00949             IRP_MN_QUERY_REMOVE_DEVICE
    00950             IRP_MN_CANCEL_REMOVE_DEVICE
    00951             IRP_MN_REMOVE_DEVICE
    00952             IRP_MN_EJECT
    00953 Return Value:
    00954
    00955     NTSTATUS code.
    00956
    00957 --*/
    00958 {
    00959     PDEVICE_OBJECT deviceObject;
    00960     PIRP irp;
    00961     IO_STACK_LOCATION irpSp;
    00962     NTSTATUS status;
    00963
    00964     BOOLEAN isMountable = FALSE;
    00965     PDEVICE_OBJECT mountedDevice;
    00966
    00967     PVOID dummy;
    00968     LOCK_MOUNTABLE_DEVICE_CONTEXT lockContext;
    00969
    00970     PAGED_CODE();
    00971
    00972     ASSERT(IrpMinorCode == IRP_MN_QUERY_REMOVE_DEVICE ||
    00973            IrpMinorCode == IRP_MN_CANCEL_REMOVE_DEVICE ||
    00974            IrpMinorCode == IRP_MN_REMOVE_DEVICE ||
    00975            IrpMinorCode == IRP_MN_SURPRISE_REMOVAL ||
    00976            IrpMinorCode == IRP_MN_EJECT);
    00977
    00978     if (IrpMinorCode == IRP_MN_REMOVE_DEVICE ||
    00979         IrpMinorCode == IRP_MN_QUERY_REMOVE_DEVICE) {
    00980         IopUncacheInterfaceInformation(TargetDevice);
    00981     }
    00982
    00983     //
    00984     // Initialize the stack location to pass to IopSynchronousCall()
    00985     //
    00986
    00987     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    00988
    00989     irpSp.MajorFunction = IRP_MJ_PNP;
    00990     irpSp.MinorFunction = (UCHAR)IrpMinorCode;
    00991
    00992     //
    00993     // BUGBUG - this should probably go at a higher level but then it goes
    00994     // in way too many places.  The only thing we do to the VPB is make sure
    00995     // that it won't go away while the operation is in the file system and
    00996     // that no one new can mount on the device if the FS decides to bail out.
    00997     //
    00998
    00999     //
    01000     // Check to see if there's a VPB anywhere in the device stack.  If there
    01001     // is then we'll have to lock the stack.
    01002     //
    01003
    01004     mountedDevice = IopFindMountableDevice(TargetDevice);
    01005
    01006     if (mountedDevice != NULL) {
    01007
    01008         //
    01009         // This routine will cause any mount operations on the VPB to fail.
    01010         // It will also release the VPB spinlock.
    01011         //
    01012
    01013         mountedDevice = IopLockMountedDeviceForRemove(TargetDevice,
    01014                                                       IrpMinorCode,
    01015                                                       &lockContext);
    01016
    01017         isMountable = TRUE;
    01018
    01019     } else {
    01020         ASSERTMSG("Mass storage device does not have VPB - this is odd",
    01021                   !((TargetDevice->Type == FILE_DEVICE_DISK) ||
    01022                     (TargetDevice->Type == FILE_DEVICE_CD_ROM) ||
    01023                     (TargetDevice->Type == FILE_DEVICE_TAPE) ||
    01024                     (TargetDevice->Type == FILE_DEVICE_VIRTUAL_DISK)));
    01025
    01026         mountedDevice = TargetDevice;
    01027     }
    01028
    01029     //
    01030     // Make the call and return.
    01031     //
    01032
    01033     if (IrpMinorCode == IRP_MN_SURPRISE_REMOVAL || IrpMinorCode == IRP_MN_REMOVE_DEVICE) {
    01034         //
    01035         // if device was not disableable, we cleanup the tree
    01036         // and debug-trace that we surprise-removed a non-disableable device
    01037         //
    01038         PDEVICE_NODE deviceNode = TargetDevice->DeviceObjectExtension->DeviceNode;
    01039
    01040         if (deviceNode->UserFlags & DNUF_NOT_DISABLEABLE) {
    01041             //
    01042             // this device was marked as disableable, update the depends
    01043             // before this device disappears
    01044             // (by momentarily marking this node as disableable)
    01045             //
    01046             deviceNode->UserFlags &= ~DNUF_NOT_DISABLEABLE;
    01047             IopDecDisableableDepends(deviceNode);
    01048         }
    01049     }
    01050
    01051     status = IopSynchronousCall(mountedDevice, &irpSp, &dummy);
    01052
    01053     if (isMountable) {
    01054
    01055         IopUnlockMountedDeviceForRemove(TargetDevice,
    01056                                         IrpMinorCode,
    01057                                         &lockContext);
    01058
    01059         //
    01060         // Succesful query should follow up with invalidation of all volumes
    01061         // which have been on this device but which are not currently mounted.
    01062         //
    01063
    01064         if (IrpMinorCode == IRP_MN_QUERY_REMOVE_DEVICE && NT_SUCCESS( status )) {
    01065
    01066             status = IopInvalidateVolumesForDevice( TargetDevice );
    01067         }
    01068     }
    01069
    01070     if (IrpMinorCode == IRP_MN_REMOVE_DEVICE) {
    01071         ((PDEVICE_NODE)TargetDevice->DeviceObjectExtension->DeviceNode)->Flags &=
    01072             ~(DNF_ADDED | DNF_STARTED | DNF_LEGACY_DRIVER | DNF_NEED_QUERY_IDS | DNF_NEED_ENUMERATION_ONLY);
    01073     }
    01074
    01075     return status;
    01076 }

NTSTATUS IopRemoveDeviceInterfaces | ( | IN PUNICODE_STRING | DeviceInstancePath | ) |

Definition at line 4414 of file pnpioapi.c.

References _BUFFER_INFO::Buffer, DEVICE_INTERFACE_INCLUDE_NONACTIVE, ExFreePool(), FALSE, INITIAL_INFO_BUFFER_SIZE, IopAllocateBuffer(), IopAllocateUnicodeString(), IopDeleteKeyRecursive(), IopFreeAllocatedUnicodeString(), IopFreeBuffer(), IopGetDeviceInterfaces(), IopGetRegistryValue(), IopOpenRegistryKeyEx(), IopRegistryDataToUnicodeString, IopResizeBuffer(), IopUnregisterDeviceInterface(), KEY_VALUE_DATA, _BUFFER_INFO::MaxSize, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, RtlEqualUnicodeString(), RtlGUIDFromString(), RtlInitUnicodeString(), TRUE, and USHORT.

    04420                    :
    04421
    04422     This routine checks all device class keys under
    04423     HKLM\SYSTEM\CCS\Control\DeviceClasses for interfaces for which the
    04424     DeviceInstance value matches the supplied DeviceInstancePath.  Instances of
    04425     such device interfaces are unregistered, and the device interface subkey
    04426     itself is removed.
    04427
    04428     Note that a lock on the registry must have already been acquired,
    04429     by the caller of this routine.
    04430
    04431 Parameters:
    04432
    04433     DeviceInterfacePath - Supplies a pointer to a unicode string which
    04434         contains the DeviceInterface name of the device for which
    04435         interfaces to are to be removed.
    04436
    04437 Return Value:
    04438
    04439     Status code that indicates whether or not the function was
    04440     successful.
    04441
    04442 --*/
    04443
    04444 {
    04445     NTSTATUS       status, context;
    04446     HANDLE         hDeviceClasses=NULL, hClassGUID=NULL, hInterface=NULL;
    04447     UNICODE_STRING tempString, guidString, interfaceString, deviceInstanceString;
    04448     ULONG          resultSize, classIndex, interfaceIndex;
    04449     ULONG          symbolicLinkListSize;
    04450     PWCHAR         symbolicLinkList, symLink;
    04451     BUFFER_INFO    classInfoBuffer, interfaceInfoBuffer;
    04452     PKEY_VALUE_FULL_INFORMATION deviceInstanceInfo;
    04453     BOOLEAN        deletedInterface;
    04454     GUID           classGUID;
    04455
    04456     PAGED_CODE();
    04457
    04458     //
    04459     // Allocate initial buffers
    04460     //
    04461     status = IopAllocateBuffer(&classInfoBuffer,
    04462                                INITIAL_INFO_BUFFER_SIZE);
    04463     if (!NT_SUCCESS(status)) {
    04464         goto clean0;
    04465     }
    04466
    04467     status = IopAllocateBuffer(&interfaceInfoBuffer,
    04468                                INITIAL_INFO_BUFFER_SIZE);
    04469     if (!NT_SUCCESS(status)) {
    04470         IopFreeBuffer(&classInfoBuffer);
    04471         goto clean0;
    04472     }
    04473
    04474     //
    04475     // Open HKLM\System\CurrentControlSet\Control\DeviceClasses
    04476     //
    04477     PiWstrToUnicodeString(&tempString, REGSTR_FULL_PATH_DEVICE_CLASSES);
    04478     status = IopOpenRegistryKeyEx( &hDeviceClasses,
    04479                                    NULL,
    04480                                    &tempString,
    04481                                    KEY_READ
    04482                                    );
    04483     if(!NT_SUCCESS(status)){
    04484         goto clean1;
    04485     }
    04486
    04487     //
    04488     // Enumerate all device classes
    04489     //
    04490     classIndex = 0;
    04491
    04492     while((status = ZwEnumerateKey(hDeviceClasses,
    04493                                    classIndex,
    04494                                    KeyBasicInformation,
    04495                                    (PVOID) classInfoBuffer.Buffer,
    04496                                    classInfoBuffer.MaxSize,
    04497                                    &resultSize)) != STATUS_NO_MORE_ENTRIES) {
    04498
    04499         if (status == STATUS_BUFFER_TOO_SMALL) {
    04500             status = IopResizeBuffer(&classInfoBuffer, resultSize, FALSE);
    04501             continue;
    04502         } else if (!NT_SUCCESS(status)) {
    04503             goto clean1;
    04504         }
    04505
    04506         //
    04507         // Get the key name for this device class
    04508         //
    04509         guidString.Length = (USHORT)((PKEY_BASIC_INFORMATION)(classInfoBuffer.Buffer))->NameLength;
    04510         guidString.MaximumLength = guidString.Length;
    04511         guidString.Buffer = ((PKEY_BASIC_INFORMATION)(classInfoBuffer.Buffer))->Name;
    04512
    04513         //
    04514         // Open the key for this device class
    04515         //
    04516         status = IopOpenRegistryKeyEx( &hClassGUID,
    04517                                        hDeviceClasses,
    04518                                        &guidString,
    04519                                        KEY_ALL_ACCESS
    04520                                        );
    04521         if (!NT_SUCCESS(status)) {
    04522             //
    04523             // Couldn't open key for this device class -- skip it and move on.
    04524             //
    04525             goto CloseClassKeyAndContinue;
    04526         }
    04527
    04528         //
    04529         // Enumerate all device interfaces for this device class
    04530         //
    04531         interfaceIndex = 0;
    04532
    04533         while((status = ZwEnumerateKey(hClassGUID,
    04534                                        interfaceIndex,
    04535                                        KeyBasicInformation,
    04536                                        (PVOID) interfaceInfoBuffer.Buffer,
    04537                                        interfaceInfoBuffer.MaxSize,
    04538                                        &resultSize)) != STATUS_NO_MORE_ENTRIES) {
    04539
    04540             if (status == STATUS_BUFFER_TOO_SMALL) {
    04541                 status = IopResizeBuffer(&interfaceInfoBuffer, resultSize, FALSE);
    04542                 continue;
    04543             } else if (!NT_SUCCESS(status)) {
    04544                 goto clean1;
    04545             }
    04546
    04547             //
    04548             // This interface key has not yet been deleted
    04549             //
    04550             deletedInterface = FALSE;
    04551
    04552             //
    04553             // Create a NULL-terminated unicode string for the interface key name
    04554             //
    04555             status = IopAllocateUnicodeString(&interfaceString,
    04556                                               (USHORT)((PKEY_BASIC_INFORMATION)(interfaceInfoBuffer.Buffer))->NameLength);
    04557
    04558             if (!NT_SUCCESS(status)) {
    04559                 goto clean1;
    04560             }
    04561
    04562             interfaceString.Length = (USHORT)((PKEY_BASIC_INFORMATION)(interfaceInfoBuffer.Buffer))->NameLength;
    04563             interfaceString.MaximumLength = interfaceString.Length + sizeof(UNICODE_NULL);
    04564             RtlCopyMemory(interfaceString.Buffer,
    04565                           ((PKEY_BASIC_INFORMATION)(interfaceInfoBuffer.Buffer))->Name,
    04566                           interfaceString.Length);
    04567             interfaceString.Buffer[interfaceString.Length/sizeof(WCHAR)] = UNICODE_NULL;
    04568
    04569             //
    04570             // Open the device interface key
    04571             //
    04572             status = IopOpenRegistryKeyEx( &hInterface,
    04573                                            hClassGUID,
    04574                                            &interfaceString,
    04575                                            KEY_ALL_ACCESS
    04576                                            );
    04577             if (!NT_SUCCESS(status)) {
    04578                 //
    04579                 // Couldn't open the device interface key -- skip it and move on.
    04580                 //
    04581                 hInterface = NULL;
    04582                 goto CloseInterfaceKeyAndContinue;
    04583             }
    04584
    04585             //
    04586             // Get the DeviceInstance value for this interface key
    04587             //
    04588             status = IopGetRegistryValue(hInterface,
    04589                                          REGSTR_VAL_DEVICE_INSTANCE,
    04590                                          &deviceInstanceInfo);
    04591
    04592             if(!NT_SUCCESS(status)) {
    04593                 //
    04594                 //  Couldn't get the DeviceInstance for this interface --
    04595                 //  skip it and move on.
    04596                 //
    04597                 goto CloseInterfaceKeyAndContinue;
    04598             }
    04599
    04600             if((deviceInstanceInfo->Type == REG_SZ) &&
    04601                (deviceInstanceInfo->DataLength != 0)) {
    04602
    04603                 IopRegistryDataToUnicodeString(&deviceInstanceString,
    04604                                                (PWSTR)KEY_VALUE_DATA(deviceInstanceInfo),
    04605                                                deviceInstanceInfo->DataLength);
    04606
    04607             } else {
    04608                 //
    04609                 // DeviceInstance value is invalid -- skip it and move on.
    04610                 //
    04611                 ExFreePool(deviceInstanceInfo);
    04612                 goto CloseInterfaceKeyAndContinue;
    04613
    04614             }
    04615
    04616             //
    04617             // Compare the DeviceInstance of this interface to DeviceInstancePath
    04618             //
    04619             if (RtlEqualUnicodeString(&deviceInstanceString, DeviceInstancePath, TRUE)) {
    04620
    04621                 ZwClose(hInterface);
    04622                 hInterface = NULL;
    04623
    04624                 //
    04625                 // Retrieve all instances of this device interface
    04626                 // (active and non-active)
    04627                 //
    04628                 RtlGUIDFromString(&guidString, &classGUID);
    04629
    04630                 status = IopGetDeviceInterfaces(&classGUID,
    04631                                                 DeviceInstancePath,
    04632                                                 DEVICE_INTERFACE_INCLUDE_NONACTIVE,
    04633                                                 FALSE,       // kernel-mode format
    04634                                                 &symbolicLinkList,
    04635                                                 &symbolicLinkListSize);
    04636
    04637                 if (NT_SUCCESS(status)) {
    04638
    04639                     //
    04640                     // Iterate through all instances of the interface
    04641                     //
    04642                     symLink = symbolicLinkList;
    04643                     while(*symLink != UNICODE_NULL) {
    04644
    04645                         RtlInitUnicodeString(&tempString, symLink);
    04646
    04647                         //
    04648                         // Unregister this instance of the interface.  Since we are
    04649                         // removing the device, ignore any returned status, since
    04650                         // there isn't anything we can do about interfaces which
    04651                         // fail unregistration.
    04652                         //
    04653                         IopUnregisterDeviceInterface(&tempString);
    04654
    04655                         symLink += ((tempString.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR));
    04656                     }
    04657                     ExFreePool(symbolicLinkList);
    04658                 }
    04659
    04660                 //
    04661                 // Recursively delete the interface key, if it still exists.
    04662                 // While IopUnregisterDeviceInterface will itself delete the
    04663                 // interface key if no interface instance subkeys remain, if any
    04664                 // of the above calls to IopUnregisterDeviceInterface failed to
    04665                 // delete an interface instance key, subkeys will remain, and
    04666                 // the interface key will not have been deleted.  We'll catch
    04667                 // that here.
    04668                 //
    04669                 status = IopOpenRegistryKeyEx( &hInterface,
    04670                                                hClassGUID,
    04671                                                &interfaceString,
    04672                                                KEY_READ
    04673                                                );
    04674                 if(NT_SUCCESS(status)){
    04675                     if (NT_SUCCESS(IopDeleteKeyRecursive(hClassGUID,
    04676                                                          interfaceString.Buffer))) {
    04677                         deletedInterface = TRUE;
    04678                     }
    04679                     ZwDeleteKey(hInterface);
    04680                     ZwClose(hInterface);
    04681                     hInterface = NULL;
    04682                 } else if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
    04683                     //
    04684                     // Interface was already deleted by IopUnregisterDeviceInterface
    04685                     //
    04686                     deletedInterface = TRUE;
    04687                 }
    04688             }
    04689
    04690             //
    04691             // Free allocated key info structure
    04692             //
    04693             ExFreePool(deviceInstanceInfo);
    04694
    04695 CloseInterfaceKeyAndContinue:
    04696
    04697             if (hInterface != NULL) {
    04698                 ZwClose(hInterface);
    04699                 hInterface = NULL;
    04700             }
    04701
    04702             IopFreeAllocatedUnicodeString(&interfaceString);
    04703
    04704             //
    04705             // Only increment the enumeration index for non-deleted keys
    04706             //
    04707             if (!deletedInterface) {
    04708                 interfaceIndex++;
    04709             }
    04710
    04711         }
    04712
    04713 CloseClassKeyAndContinue:
    04714
    04715         if (hClassGUID != NULL) {
    04716             ZwClose(hClassGUID);
    04717             hClassGUID = NULL;
    04718         }
    04719         classIndex++;
    04720     }
    04721
    04722 clean1:
    04723     if (hInterface) {
    04724         ZwClose(hInterface);
    04725     }
    04726     if (hClassGUID) {
    04727         ZwClose(hClassGUID);
    04728     }
    04729     if (hDeviceClasses) {
    04730         ZwClose(hDeviceClasses);
    04731     }
    04732
    04733     IopFreeBuffer(&interfaceInfoBuffer);
    04734     IopFreeBuffer(&classInfoBuffer);
    04735
    04736 clean0:
    04737     return status;
    04738 }

VOID IopRemoveResourceListFromPnp | ( | IN PLIST_ENTRY | ResourceList | ) |

NTSTATUS IopRemoveStringFromValueKey | ( | IN HANDLE | Handle,
|  | IN PWSTR | ValueName,
|  | IN PUNICODE_STRING | String
| ) |

Definition at line 449 of file pnpsubs.c.

References ExFreePool(), FALSE, Handle, IopGetRegistryValue(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, RtlEqualUnicodeString(), RtlInitUnicodeString(), String, TITLE_INDEX_VALUE, TRUE, USHORT, and ValueName.

    00457                    :
    00458
    00459     This routine remove a string from a value entry specified by ValueName
    00460     under an already opened registry handle.  Note, this routine will not
    00461     delete the ValueName entry even it becomes empty after the removal.
    00462
    00463 Parameters:
    00464
    00465     Handle - Supplies the handle to a registry key whose value entry will
    00466         be modified.
    00467
    00468     ValueName - Supplies a unicode string to specify the value entry.
    00469
    00470     String - Supplies a unicode string to remove from value entry.
    00471
    00472 Return Value:
    00473
    00474     Status code that indicates whether or not the function was successful.
    00475
    00476 --*/
    00477
    00478 {
    00479     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    00480     UNICODE_STRING unicodeString;
    00481     PWSTR nextString, currentString;
    00482     ULONG length, leftLength;
    00483     NTSTATUS status;
    00484     BOOLEAN found = FALSE;
    00485
    00486     if (String == NULL || String->Length / sizeof(WCHAR) == 0) {
    00487         return STATUS_SUCCESS;
    00488     }
    00489
    00490     //
    00491     // Read registry value entry data
    00492     //
    00493
    00494     status = IopGetRegistryValue(Handle, ValueName, &keyValueInformation);
    00495
    00496     if (!NT_SUCCESS( status )) {
    00497         return status;
    00498     } else if ((keyValueInformation->Type != REG_MULTI_SZ) ||
    00499                (keyValueInformation->DataLength == 0)) {
    00500
    00501         status = (keyValueInformation->Type == REG_MULTI_SZ) ? STATUS_SUCCESS
    00502                                                              : STATUS_INVALID_PARAMETER;
    00503         ExFreePool(keyValueInformation);
    00504         return status;
    00505     }
    00506
    00507     //
    00508     // Scan through the multi_sz string to find the matching string
    00509     // and remove it.
    00510     //
    00511
    00512     status = STATUS_SUCCESS;
    00513     currentString = (PWSTR)KEY_VALUE_DATA(keyValueInformation);
    00514     leftLength = keyValueInformation->DataLength;
    00515     while (!found && leftLength >= String->Length + sizeof(WCHAR)) {
    00516         unicodeString.Buffer = currentString;
    00517         length = wcslen( currentString ) * sizeof( WCHAR );
    00518         unicodeString.Length = (USHORT)length;
    00519         length += sizeof(UNICODE_NULL);
    00520         unicodeString.MaximumLength = (USHORT)length;
    00521         nextString = currentString + length / sizeof(WCHAR);
    00522         leftLength -= length;
    00523
    00524         if (RtlEqualUnicodeString(&unicodeString, String, TRUE)) {
    00525             found = TRUE;
    00526             RtlMoveMemory(currentString, nextString, leftLength);
    00527             RtlInitUnicodeString(&unicodeString, ValueName);
    00528             status = ZwSetValueKey(
    00529                         Handle,
    00530                         &unicodeString,
    00531                         TITLE_INDEX_VALUE,
    00532                         REG_MULTI_SZ,
    00533                         KEY_VALUE_DATA(keyValueInformation),
    00534                         keyValueInformation->DataLength - length
    00535                         );
    00536             break;
    00537         } else {
    00538             currentString = nextString;
    00539         }
    00540     }
    00541     ExFreePool(keyValueInformation);
    00542     return status;
    00543 }

VOID IopRemoveTreeDeviceNode | ( | IN PDEVICE_NODE | DeviceNode | ) |

Definition at line 494 of file devnode.c.

References _DEVICE_NODE::Child, IopOrphanNotification(), _DEVICE_NODE::LastChild, NULL, _DEVICE_NODE::Parent, and _DEVICE_NODE::Sibling.

Referenced by IopDeleteLockedDeviceNode(), and IopUnlockDeviceRemovalRelations().

    00499                    :
    00500
    00501     This function removes the device node from the device node tree
    00502
    00503     N.B. The caller must own the device tree lock of the parent's enumeration lock
    00504
    00505 Arguments:
    00506
    00507     DeviceNode      - Device node to remove
    00508
    00509 Return Value:
    00510
    00511
    00512 --*/
    00513 {
    00514     PDEVICE_NODE        *Node;
    00515
    00516     //
    00517     // Ulink the pointer to this device node.  (If this is the
    00518     // first entry, unlink it from the parents child pointer, else
    00519     // remove it from the sibling list)
    00520     //
    00521
    00522     Node = &DeviceNode->Parent->Child;
    00523     while (*Node != DeviceNode) {
    00524         Node = &(*Node)->Sibling;
    00525     }
    00526     *Node = DeviceNode->Sibling;
    00527
    00528     if (DeviceNode->Parent->Child == NULL) {
    00529         DeviceNode->Parent->LastChild = NULL;
    00530     } else {
    00531         while (*Node) {
    00532             Node = &(*Node)->Sibling;
    00533         }
    00534         DeviceNode->Parent->LastChild = CONTAINING_RECORD(Node, DEVICE_NODE, Sibling);
    00535     }
    00536
    00537
    00538     //
    00539     // Orphan any outstanding device change notifications on these nodes.
    00540     //
    00541     IopOrphanNotification(DeviceNode);
    00542
    00543     //
    00544     // No longer linked
    00545     //
    00546
    00547     DeviceNode->Parent    = NULL;
    00548     DeviceNode->Child     = NULL;
    00549     DeviceNode->Sibling   = NULL;
    00550     DeviceNode->LastChild = NULL;
    00551 }

NTSTATUS IopReplaceSeperatorWithPound | ( | OUT PUNICODE_STRING | OutString,
|  | IN PUNICODE_STRING | InString
| ) |

| Referenced by IopBuildSymbolicLinkStrings(), IopOpenOrCreateDeviceInterfaceSubKeys(), and IopProcessCriticalDeviceRoutine().

NTSTATUS IopReportResourceListToPnp | ( | IN PDRIVER_OBJECT DriverObject | OPTIONAL,
|  | IN PDEVICE_OBJECT DeviceObject | OPTIONAL,
|  | IN PCM_RESOURCE_LIST | ResourceList,
|  | IN ULONG | ListSize,
|  | IN BOOLEAN | Translated
| ) |

NTSTATUS IopRequestDeviceAction | ( | IN PDEVICE_OBJECT DeviceObject | OPTIONAL,
|  | IN DEVICE_REQUEST_TYPE | RequestType,
|  | IN PKEVENT CompletionEvent | OPTIONAL,
|  | IN PNTSTATUS CompletionStatus | OPTIONAL
| ) |

Definition at line 207 of file pnpenum.c.

References _PI_DEVICE_REQUEST::CompletionEvent, _PI_DEVICE_REQUEST::CompletionStatus, DelayedWorkQueue, DEVICE_REQUEST_TYPE, _PI_DEVICE_REQUEST::DeviceObject, ExAllocatePool, ExInitializeWorkItem, ExQueueWorkItem(), IopDeviceActionWorker(), IopDeviceEnumerationWorkItem, IopEnumerationInProgress, IopPnpEnumerationRequestList, IopPnPSpinLock, KeClearEvent, _PI_DEVICE_REQUEST::ListEntry, NonPagedPool, NULL, ObReferenceObject, PI_DEVICE_REQUEST, PiEnumerationLock, PnPBootDriversLoaded, PPI_DEVICE_REQUEST, ReenumerateBootDevices, ReenumerateRootDevices, _PI_DEVICE_REQUEST::RequestType, and TRUE.

Referenced by IoInvalidateDeviceRelations(), IopDeleteLockedDeviceNodes(), IopDeviceRelationsComplete(), IopDeviceStartComplete(), IopInitializeBootDrivers(), IopInitializePlugPlayServices(), IopInvalidateRelationsInList(), IopQueryDeviceRelations(), IopResourceRequirementsChanged(), IopStartDriverDevices(), and IoSynchronousInvalidateDeviceRelations().

    00216                    :
    00217
    00218     This routine queues a work item to enumerate a device. This is for IO
    00219     internal use only.
    00220
    00221 Arguments:
    00222
    00223     DeviceObject - Supplies a pointer to the device object to be enumerated.
    00224                    if NULL, this is a request to retry resources allocation
    00225                    failed devices.
    00226
    00227     Request - the reason for the enumeration.
    00228
    00229 Return Value:
    00230
    00231     NTSTATUS code.
    00232
    00233 --*/
    00234
    00235 {
    00236     PPI_DEVICE_REQUEST  request;
    00237     PDEVICE_NODE        deviceNode;
    00238     KIRQL               oldIrql;
    00239
    00240     //
    00241     // If this node is ready for enumeration, enqueue it
    00242     //
    00243
    00244     request = ExAllocatePool(NonPagedPool, sizeof(PI_DEVICE_REQUEST));
    00245
    00246     if (request) {
    00247         //
    00248         // Put this request onto the pending list
    00249         //
    00250
    00251         if (DeviceObject) {
    00252             ObReferenceObject(DeviceObject);
    00253         }
    00254
    00255         request->DeviceObject = DeviceObject;
    00256         request->RequestType = RequestType;
    00257         request->CompletionEvent = CompletionEvent;
    00258         request->CompletionStatus = (RequestType == ReenumerateBootDevices)? NULL : CompletionStatus;
    00259
    00260         InitializeListHead(&request->ListEntry);
    00261
    00262         //
    00263         // Insert the  request to the request queue.  If the request queue is
    00264         // not currently being worked on, request a worker thread to start it.
    00265         //
    00266
    00267         ExAcquireSpinLock(&IopPnPSpinLock, &oldIrql);
    00268
    00269         InsertTailList(&IopPnpEnumerationRequestList, &request->ListEntry);
    00270
    00271         if (    RequestType == ReenumerateBootDevices ||
    00272                 RequestType == ReenumerateRootDevices) {
    00273             //
    00274             // This is a special request used when booting the system.  Instead
    00275             // of queuing a work item it synchronously calls the work routine.
    00276             //
    00277
    00278             IopEnumerationInProgress = TRUE;
    00279             KeClearEvent(&PiEnumerationLock);
    00280             ExReleaseSpinLock(&IopPnPSpinLock, oldIrql);
    00281
    00282             IopDeviceActionWorker((PVOID)CompletionStatus);
    00283
    00284         } else if (PnPBootDriversLoaded && !IopEnumerationInProgress) {
    00285             IopEnumerationInProgress = TRUE;
    00286             KeClearEvent(&PiEnumerationLock);
    00287             ExReleaseSpinLock(&IopPnPSpinLock, oldIrql);
    00288
    00289             //
    00290             // Queue a work item to do the enumeration
    00291             //
    00292
    00293             ExInitializeWorkItem(&IopDeviceEnumerationWorkItem, IopDeviceActionWorker, NULL);
    00294             ExQueueWorkItem(&IopDeviceEnumerationWorkItem, DelayedWorkQueue);
    00295         } else {
    00296             ExReleaseSpinLock(&IopPnPSpinLock, oldIrql);
    00297         }
    00298     } else {
    00299         return STATUS_INSUFFICIENT_RESOURCES;
    00300     }
    00301
    00302     return STATUS_SUCCESS;
    00303 }

NTSTATUS IopRequestDeviceRemoval | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN ULONG | Problem
| ) |

Definition at line 1708 of file pnpdel.c.

References ASSERT, FALSE, NULL, PAGED_CODE, PpSetTargetDeviceRemove(), and TRUE.

Referenced by IopCallDriverAddDevice(), IopDeviceStartComplete(), IopEnumerateDevice(), IopProcessNewDeviceNode(), IopProcessNewProfileStateCallback(), IopQueryDeviceState(), IopReallocateResources(), IopRebalance(), and IopStartDevice().

    01715                    :
    01716
    01717     This routine queues a work item to delete a device.  (This is because
    01718     to delete a device we need to lock device tree.  Most of the places where
    01719     we want to delete a device have DeviceNode Enumeration lock acquired.)
    01720     This is for IO internal use only.
    01721
    01722 Arguments:
    01723
    01724     DeviceObject - Supplies a pointer to the device object to be eject.
    01725
    01726 Return Value:
    01727
    01728     NTSTATUS code.
    01729
    01730 --*/
    01731
    01732 {
    01733     PAGED_CODE();
    01734
    01735     ASSERT(DeviceObject->DeviceObjectExtension->DeviceNode != NULL);
    01736
    01737     ASSERT(((PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode)->InstancePath.Length != 0);
    01738
    01739     //
    01740     // Queue the event, we'll return immediately after it's queued.
    01741     //
    01742
    01743     return PpSetTargetDeviceRemove( DeviceObject,
    01744                                     TRUE,
    01745                                     TRUE,
    01746                                     FALSE,
    01747                                     Problem,
    01748                                     NULL,
    01749                                     NULL,
    01750                                     NULL,
    01751                                     NULL);
    01752 }

NTSTATUS IopRequestHwProfileChangeNotification | ( | IN LPGUID | EventGuid,
|  | IN PROFILE_NOTIFICATION_TIME | NotificationTime,
|  | OUT PPNP_VETO_TYPE VetoType | OPTIONAL,
|  | OUT PUNICODE_STRING VetoName | OPTIONAL
| ) |

Definition at line 6672 of file pnpioapi.c.

References ASSERT, DbgPrint, ExAllocatePoolWithTag, Executive, FALSE, IopCompareGuid, IopNotifyHwProfileChange(), KeInitializeEvent, KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, PiNotificationInProgress, PiNotifyUserMode(), PNP_DEVICE_EVENT_ENTRY_TAG, PpSetHwProfileChangeEvent(), PROFILE_NOT_IN_PNPEVENT, PROFILE_PERHAPS_IN_PNPEVENT, and TRUE.

Referenced by IopHardwareProfileQueryChange(), IopHardwareProfileSendCancel(), and IopHardwareProfileSendCommit().

    06681                    :
    06682
    06683     This routine is used to notify all registered drivers of a hardware profile
    06684     change.  If the operation is a HW provile change query then the operation
    06685     is synchronous and the veto information is propagated.  All other operations
    06686     are asynchronous and veto information is not returned.
    06687
    06688 Parameters:
    06689
    06690     EventTypeGuid       - The event that has occured
    06691
    06692     NotificationTime    - This is used to tell if we are already in an event
    06693                           when delivering a synchronous notification (ie,
    06694                           querying profile change to eject). It is one of
    06695                           three values:
    06696                               PROFILE_IN_PNPEVENT
    06697                               PROFILE_NOT_IN_PNPEVENT
    06698                               PROFILE_PERHAPS_IN_PNPEVENT
    06699
    06700     VetoType            - Type of vetoer.
    06701
    06702     VetoName            - Name of vetoer.
    06703
    06704 Return Value:
    06705
    06706     Status code that indicates whether or not the function was successful.
    06707
    06708 Note:
    06709
    06710     The contents of the notification structure *including* all pointers is only
    06711     valid during the callback routine to which it was passed.  If the data is
    06712     required after the duration of the callback then it must be physically copied
    06713     by the callback routine.
    06714
    06715 --*/
    06716
    06717 {
    06718     NTSTATUS status=STATUS_SUCCESS,completionStatus;
    06719     KEVENT completionEvent;
    06720     ULONG dataSize,totalSize;
    06721     PPNP_DEVICE_EVENT_ENTRY deviceEvent;
    06722
    06723     PAGED_CODE();
    06724
    06725     if (
    06726          (!IopCompareGuid(EventGuid,
    06727                        (LPGUID)&GUID_HWPROFILE_QUERY_CHANGE)) &&
    06728          (!IopCompareGuid(EventGuid,
    06729                        (LPGUID)&GUID_HWPROFILE_CHANGE_CANCELLED)) &&
    06730          (!IopCompareGuid(EventGuid,
    06731                        (LPGUID)&GUID_HWPROFILE_CHANGE_COMPLETE)) ) {
    06732
    06733          //
    06734          //  Passed in an illegal value
    06735          //
    06736
    06737  #if DBG
    06738          DbgPrint ("Illegal Event type passed as profile notification\n");
    06739  #endif
    06740          return STATUS_INVALID_DEVICE_REQUEST;
    06741      }
    06742
    06743
    06744      //
    06745      // Only the query changes are synchronous, and in that case we must
    06746      // know definitely whether we are nested within a Pnp event or not.
    06747      //
    06748      ASSERT((!IopCompareGuid(EventGuid, (LPGUID)&GUID_HWPROFILE_QUERY_CHANGE))||
    06749             (NotificationTime != PROFILE_PERHAPS_IN_PNPEVENT)) ;
    06750
    06751      if (!IopCompareGuid(EventGuid, (LPGUID)&GUID_HWPROFILE_QUERY_CHANGE) ) {
    06752
    06753          //
    06754          // Asynchronous case. Very easy.
    06755          //
    06756          ASSERT(!ARGUMENT_PRESENT(VetoName));
    06757          ASSERT(!ARGUMENT_PRESENT(VetoType));
    06758
    06759          return PpSetHwProfileChangeEvent( EventGuid,
    06760                                            NULL,
    06761                                            NULL,
    06762                                            NULL,
    06763                                            NULL
    06764                                            );
    06765      }
    06766
    06767      //
    06768      // Query notifications are synchronous. Determine if we are currently
    06769      // within an event, in which case we must do the notify here instead
    06770      // of queueing it up.
    06771      //
    06772      if (NotificationTime == PROFILE_NOT_IN_PNPEVENT) {
    06773
    06774          //
    06775          // Queue up and block on the notification.
    06776          //
    06777          KeInitializeEvent(&completionEvent, NotificationEvent, FALSE);
    06778
    06779          status = PpSetHwProfileChangeEvent( EventGuid,
    06780                                              &completionEvent,
    06781                                              &completionStatus,
    06782                                              VetoType,
    06783                                              VetoName
    06784                                              );
    06785
    06786          if (NT_SUCCESS(status))  {
    06787
    06788              KeWaitForSingleObject( &completionEvent, Executive, KernelMode, FALSE, NULL );
    06789
    06790              status = completionStatus;
    06791          }
    06792
    06793          return status ;
    06794      }
    06795
    06796      //
    06797      // Synchronous notify inside our Pnp event.
    06798      //
    06799      // ADRIAO BUGBUG 11/12/98 -
    06800      //     GROSS, UGLY, SINFUL HACK - We are MANUALLY sending the profile
    06801      // query change notification because we are blocking inside a PnPEvent and
    06802      // thus can't queue/wait on another!
    06803      //
    06804      ASSERT(PiNotificationInProgress == TRUE);
    06805
    06806      dataSize =  sizeof(PLUGPLAY_EVENT_BLOCK);
    06807
    06808      totalSize = dataSize + FIELD_OFFSET (PNP_DEVICE_EVENT_ENTRY,Data);
    06809
    06810      deviceEvent = ExAllocatePoolWithTag (PagedPool,
    06811                                           totalSize,
    06812                                           PNP_DEVICE_EVENT_ENTRY_TAG);
    06813
    06814      if (NULL == deviceEvent) {
    06815          return STATUS_INSUFFICIENT_RESOURCES;
    06816      }
    06817
    06818      //
    06819      //Setup the PLUGPLAY_EVENT_BLOCK
    06820      //
    06821      RtlZeroMemory ((PVOID)deviceEvent,totalSize);
    06822      deviceEvent->Data.EventCategory = HardwareProfileChangeEvent;
    06823      RtlCopyMemory(&deviceEvent->Data.EventGuid, EventGuid, sizeof(GUID));
    06824      deviceEvent->Data.TotalSize = dataSize;
    06825      deviceEvent->CallerEvent = &completionEvent;
    06826      deviceEvent->Data.Result = &completionStatus;
    06827      deviceEvent->VetoType = VetoType;
    06828      deviceEvent->VetoName = VetoName;
    06829
    06830      //
    06831      // Notify K-Mode
    06832      //
    06833      status = IopNotifyHwProfileChange(&deviceEvent->Data.EventGuid,
    06834                                        VetoType,
    06835                                        VetoName);
    06836
    06837      if (!NT_SUCCESS(status)) {
    06838          return status;
    06839      }
    06840
    06841      //
    06842      // Notify user-mode (synchronously).
    06843      //
    06844      status = PiNotifyUserMode(deviceEvent);
    06845
    06846      if (!NT_SUCCESS(status)) {
    06847          //
    06848          // Notify K-mode that the query has been cancelled.
    06849          //
    06850          IopNotifyHwProfileChange((LPGUID)&GUID_HWPROFILE_CHANGE_CANCELLED,
    06851                                   NULL,
    06852                                   NULL);
    06853      }
    06854      return status;
    06855 }

NTSTATUS IopReserveBootResources | ( | IN ARBITER_REQUEST_SOURCE | ArbiterRequestSource,
|  | IN PDEVICE_OBJECT | DeviceObject,
|  | IN PCM_RESOURCE_LIST | BootResources
| ) |

Definition at line 7291 of file pnpres.c.

References ASSERT, _DEVICE_NODE::BootResources, DNF_MADEUP, ExAllocatePoolIORL, ExAllocatePoolIORRR, ExFreePool(), _DEVICE_NODE::Flags, IopAllocateBootResources(), IopDetermineResourceListSize(), IopInitReservedResourceList, NTSTATUS(), NULL, PagedPool, and PIOP_RESERVED_RESOURCES_RECORD.

Referenced by IopInitializePlugPlayServices().

    07299                    :
    07300
    07301     This routine reports boot resources for the specified device to
    07302     arbiters.  Since the real resource pre-alloc routine can only be called after
    07303     all the arbiters and translators are present, all the calls to pre-alloc resources
    07304     before the preallocation routine is available will be routed to this routine.
    07305
    07306 Arguments:
    07307
    07308     DeviceObject - Supplies a pointer to the device object.  If present, caller wants to
    07309         preallocate BOOT resources for a device object.  If NULL, caller wants to reserved
    07310         resources for some unknown devices.
    07311
    07312     BootResources - Supplies a pointer to the Boot resources.
    07313
    07314 Return Value:
    07315
    07316     None.
    07317
    07318 --*/
    07319 {
    07320     PIOP_RESERVED_RESOURCES_RECORD  resourceRecord;
    07321     PDEVICE_NODE                    deviceNode;
    07322     ULONG                           size;
    07323     NTSTATUS                        status;
    07324
    07325     status = STATUS_SUCCESS;;
    07326     size = IopDetermineResourceListSize(BootResources);
    07327     if (size != 0) {
    07328
    07329         deviceNode = (PDEVICE_NODE)((DeviceObject)?  DeviceObject->DeviceObjectExtension->DeviceNode : NULL);
    07330
    07331         //
    07332         // Pre-allocate BOOT configs right away for non-madeup devices.
    07333         //
    07334
    07335         if (DeviceObject && !(deviceNode->Flags & DNF_MADEUP)) {
    07336
    07337             return IopAllocateBootResources(ArbiterRequestSource, DeviceObject, BootResources);
    07338
    07339         }
    07340
    07341
    07342         if (DeviceObject) {
    07343
    07344             ASSERT(deviceNode);
    07345             deviceNode->BootResources = ExAllocatePoolIORL(PagedPool, size);
    07346             if (deviceNode->BootResources) {
    07347
    07348                 RtlMoveMemory(deviceNode->BootResources, BootResources, size);
    07349
    07350             } else {
    07351
    07352                 return STATUS_INSUFFICIENT_RESOURCES;
    07353
    07354             }
    07355         }
    07356
    07357         resourceRecord = (PIOP_RESERVED_RESOURCES_RECORD) ExAllocatePoolIORRR(  PagedPool,
    07358                                                                                 sizeof(IOP_RESERVED_RESOURCES_RECORD));
    07359         if (resourceRecord) {
    07360
    07361             resourceRecord->ReservedResources = (DeviceObject)? deviceNode->BootResources : BootResources;
    07362             resourceRecord->DeviceObject = DeviceObject;
    07363             resourceRecord->Next = IopInitReservedResourceList;
    07364             IopInitReservedResourceList = resourceRecord;
    07365
    07366         } else {
    07367
    07368             if (deviceNode && deviceNode->BootResources) {
    07369
    07370                 ExFreePool(deviceNode->BootResources);
    07371
    07372             }
    07373
    07374             return STATUS_INSUFFICIENT_RESOURCES;
    07375
    07376         }
    07377     }
    07378
    07379     return status;
    07380 }

NTSTATUS IopReserveLegacyBootResources | ( | IN INTERFACE_TYPE | InterfaceType,
|  | IN ULONG | BusNumber
| ) |

Definition at line 6996 of file pnpres.c.

References ArbiterRequestHalReported, ArbiterRequestPnpEnumerated, ASSERT, _DEVICE_NODE::BootResources, BusNumber, DbgPrint, DebugMessage, DNF_HAS_BOOT_CONFIG, DUMP_INFO, ExFreePool(), _DEVICE_NODE::Flags, InterfaceType, IopAllocateBootResources(), IopCombineCmResourceList(), IopCreateCmResourceList(), IopDumpCmResourceList(), IopInitHalDeviceNode, IopInitHalResources, IopInitReservedResourceList, NT_SUCCESS, NTSTATUS(), NULL, _DEVICE_NODE::PhysicalDeviceObject, PIOP_RESERVED_RESOURCES_RECORD, and PnpResDebugLevel.

Referenced by IopEnumerateDevice(), and IopInitializeBootDrivers().

    07003                    :
    07004
    07005     This routine is called to reserve legacy BOOT resources for the specified InterfaceType
    07006     and BusNumber. This is done everytime a new bus with a legacy InterfaceType gets enumerated.
    07007
    07008 Arguments:
    07009
    07010     InterfaceType - Legacy InterfaceType.
    07011
    07012     BusNumber - Legacy BusNumber
    07013
    07014 Return Value:
    07015
    07016     The status returned is the final completion status of the operation.
    07017
    07018 --*/
    07019
    07020 {
    07021     NTSTATUS    status;
    07022     PIOP_RESERVED_RESOURCES_RECORD  resourceRecord, prevRecord;
    07023     PCM_RESOURCE_LIST   newList, remainingList;
    07024
    07025     if (IopInitHalDeviceNode && IopInitHalResources) {
    07026
    07027         remainingList = NULL;
    07028         newList = IopCreateCmResourceList(IopInitHalResources, InterfaceType, BusNumber, &remainingList);
    07029         if (newList) {
    07030
    07031             if (remainingList == NULL) {
    07032
    07033                 //
    07034                 // Full match. Check for error.
    07035                 //
    07036
    07037                 ASSERT(newList == IopInitHalResources);
    07038
    07039             } else {
    07040
    07041                 //
    07042                 // Partial match. Check for error.
    07043                 //
    07044
    07045                 ASSERT(IopInitHalResources != newList);
    07046                 ASSERT(IopInitHalResources != remainingList);
    07047
    07048             }
    07049
    07050             DebugMessage(DUMP_INFO, ("IopReserveLegacyBootResources: Allocating HAL BOOT config for interface %08X and bus %08X...\n", InterfaceType, BusNumber));
    07051             if (PnpResDebugLevel & DUMP_INFO) {
    07052
    07053                 IopDumpCmResourceList(newList);
    07054
    07055             }
    07056             if (remainingList) {
    07057                 ExFreePool(IopInitHalResources);
    07058             }
    07059             IopInitHalResources = remainingList;
    07060             remainingList = IopInitHalDeviceNode->BootResources;
    07061             IopInitHalDeviceNode->Flags |= DNF_HAS_BOOT_CONFIG;
    07062             status = IopAllocateBootResources(  ArbiterRequestHalReported,
    07063                                                 IopInitHalDeviceNode->PhysicalDeviceObject,
    07064                                                 newList);
    07065             ASSERT(NT_SUCCESS(status));
    07066             IopInitHalDeviceNode->BootResources = IopCombineCmResourceList(remainingList, newList);
    07067             ASSERT(IopInitHalDeviceNode->BootResources);
    07068
    07069             //
    07070             // Free previous BOOT config if any.
    07071             //
    07072
    07073             if (remainingList) {
    07074
    07075                 ExFreePool(remainingList);
    07076
    07077             }
    07078         } else {
    07079
    07080             //
    07081             // No match. Check that there was no error.
    07082             //
    07083
    07084             ASSERT(remainingList && remainingList == IopInitHalResources);
    07085         }
    07086     }
    07087
    07088     for (prevRecord = NULL, resourceRecord = IopInitReservedResourceList; resourceRecord;) {
    07089
    07090         if (    resourceRecord->ReservedResources &&
    07091                 resourceRecord->ReservedResources->List[0].InterfaceType == InterfaceType &&
    07092                 resourceRecord->ReservedResources->List[0].BusNumber == BusNumber) {
    07093
    07094             DebugMessage(DUMP_INFO, ("IopReserveLegacyBootResources: Allocating BOOT config...\n"));
    07095             if (PnpResDebugLevel & DUMP_INFO) {
    07096
    07097                 IopDumpCmResourceList(resourceRecord->ReservedResources);
    07098
    07099             }
    07100
    07101             status = IopAllocateBootResources(  ArbiterRequestPnpEnumerated,
    07102                                                 resourceRecord->DeviceObject,
    07103                                                 resourceRecord->ReservedResources);
    07104             if (!NT_SUCCESS(status)) {
    07105
    07106                 DbgPrint("IopReserveLegacyBootResources: IopAllocateBootResources failed with status = %08X\n", status);
    07107                 ASSERT(NT_SUCCESS(status));
    07108
    07109             }
    07110
    07111             if (resourceRecord->DeviceObject == NULL) {
    07112
    07113                 ExFreePool(resourceRecord->ReservedResources);
    07114
    07115             }
    07116
    07117             if (prevRecord) {
    07118
    07119                 prevRecord->Next = resourceRecord->Next;
    07120
    07121             } else {
    07122
    07123                 IopInitReservedResourceList = resourceRecord->Next;
    07124
    07125             }
    07126             ExFreePool(resourceRecord);
    07127             resourceRecord = (prevRecord)? prevRecord->Next : IopInitReservedResourceList;
    07128
    07129         } else {
    07130
    07131             prevRecord = resourceRecord;
    07132             resourceRecord = resourceRecord->Next;
    07133
    07134         }
    07135     }
    07136
    07137     return STATUS_SUCCESS;
    07138 }

NTSTATUS IopResizeBuffer | ( | IN PBUFFER_INFO | Info,
|  | IN ULONG | NewSize,
|  | IN BOOLEAN | CopyContents
| ) |

Definition at line 2467 of file pnpioapi.c.

References ASSERT, ExAllocatePool, ExFreePool(), and PagedPool.

Referenced by IopAppendBuffer(), IopGetDeviceInterfaces(), IopOverwriteBuffer(), IopProcessCriticalDeviceRoutine(), and IopRemoveDeviceInterfaces().

    02475                    :
    02476
    02477     Allocates a new buffer of NewSize bytes and associates it with Info, freeing the
    02478     old buffer.  It will optionally copy the data stored in the old buffer into the
    02479     new buffer and update the current position.
    02480
    02481 Parameters:
    02482
    02483     Info - Pointer to a buffer info structure to be used to manage the buffer
    02484
    02485     NewSize - The new size of the buffer in bytes
    02486
    02487     CopyContents - If TRUE indicates that the contents of the old buffer should be
    02488                    copied to the new buffer
    02489
    02490 Return Value:
    02491
    02492     Status code that indicates whether or not the function was successful.
    02493
    02494 --*/
    02495
    02496 {
    02497     ULONG used;
    02498     PCHAR newBuffer;
    02499
    02500     ASSERT(Info);
    02501
    02502     used = (ULONG)(Info->Current - Info->Buffer);
    02503
    02504     if (!(newBuffer = ExAllocatePool(PagedPool, NewSize))) {
    02505         return STATUS_INSUFFICIENT_RESOURCES;
    02506     }
    02507
    02508     if (CopyContents) {
    02509
    02510         //
    02511         // Assert there is room in the buffer
    02512         //
    02513
    02514         ASSERT(used < NewSize);
    02515
    02516         RtlCopyMemory(newBuffer,
    02517                       Info->Buffer,
    02518                       used);
    02519
    02520         Info->Current = newBuffer + used;
    02521
    02522     } else {
    02523
    02524         Info->Current = newBuffer;
    02525     }
    02526
    02527     ExFreePool(Info->Buffer);
    02528
    02529     Info->Buffer = newBuffer;
    02530     Info->MaxSize = NewSize;
    02531
    02532     return STATUS_SUCCESS;
    02533 }

VOID IopResourceRequirementsChanged | ( | IN PDEVICE_OBJECT | PhysicalDeviceObject,
|  | IN BOOLEAN | StopRequired
| ) |

Definition at line 6439 of file pnpioapi.c.

References DNF_NO_RESOURCE_REQUIRED, DNF_NON_STOPPED_REBALANCE, DNF_RESOURCE_REQUIREMENTS_CHANGED, DNF_STARTED, FALSE, _DEVICE_NODE::Flags, IopClearDevNodeProblem, IopRequestDeviceAction(), NULL, PAGED_CODE, and ResourceRequirementsChanged.

Referenced by IopQueryDeviceState().

    06446                    :
    06447
    06448     This routine handles request of device resource requirements list change.
    06449
    06450 Parameters:
    06451
    06452     PhysicalDeviceObject - Provides a pointer to the PDO who's state is to be invalidated.
    06453
    06454     StopRequired - Supplies a BOOLEAN value to indicate if the resources reallocation needs
    06455                    to be done after device stopped.
    06456
    06457 Return Value:
    06458
    06459     none.
    06460
    06461 --*/
    06462
    06463 {
    06464     PDEVICE_NODE deviceNode;
    06465     PDEVICE_OBJECT device = NULL;
    06466
    06467     PAGED_CODE();
    06468
    06469     deviceNode = (PDEVICE_NODE)PhysicalDeviceObject->DeviceObjectExtension->DeviceNode;
    06470
    06471     //
    06472     // Clear the NO_RESOURCE_REQUIRED flags.
    06473     //
    06474
    06475     deviceNode->Flags &= ~DNF_NO_RESOURCE_REQUIRED;
    06476
    06477     //
    06478     // If for some reason this device did not start, we need to clear some flags
    06479     // such that it can be started later.  In this case, we call IopRequestDeviceEnumeration
    06480     // with NULL device object, so the devices will be handled in non-started case.  They will
    06481     // be assigned resources, started and enumerated.
    06482     //
    06483
    06484     deviceNode->Flags |= DNF_RESOURCE_REQUIREMENTS_CHANGED;
    06485
    06486     IopClearDevNodeProblem(deviceNode);
    06487
    06488     //
    06489     // If the device is already started, we call IopRequestDeviceEnumeration with
    06490     // the device object.
    06491     //
    06492
    06493     if (deviceNode->Flags & DNF_STARTED) {
    06494         device = PhysicalDeviceObject;
    06495         if (StopRequired == FALSE) {
    06496             deviceNode->Flags |= DNF_NON_STOPPED_REBALANCE;
    06497         } else {
    06498
    06499             //
    06500             // Explicitly clear it.
    06501             //
    06502
    06503             deviceNode->Flags &= ~DNF_NON_STOPPED_REBALANCE;
    06504         }
    06505     }
    06506
    06507     IopRequestDeviceAction( device, ResourceRequirementsChanged, NULL, NULL );
    06508 }

NTSTATUS IopRestartDeviceNode | ( | IN PDEVICE_NODE | DeviceNode | ) |

Definition at line 5777 of file pnpsubs.c.

References ASSERT, DNF_ADDED, DNF_BOOT_CONFIG_RESERVED, DNF_ENUMERATED, DNF_ENUMERATION_REQUEST_QUEUED, DNF_HAS_BOOT_CONFIG, DNF_MADEUP, DNF_NO_RESOURCE_REQUIRED, DNF_PROCESSED, DNF_RESOURCE_ASSIGNED, DNF_RESOURCE_REPORTED, DNF_RESOURCE_REQUIREMENTS_CHANGED, DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED, DNF_STARTED, DNUF_NEED_RESTART, DNUF_WILL_BE_REMOVED, ExFreePool(), IopDoesDevNodeHaveProblem, NULL, PAGED_CODE, and RtlInitUnicodeString().

Referenced by IopDeviceActionWorker(), and IopInvalidateRelationsInList().

    05780 {
    05781     PAGED_CODE();
    05782
    05783     ASSERT(!(IopDoesDevNodeHaveProblem(DeviceNode) ||
    05784             (DeviceNode->Flags & (DNF_STARTED |
    05785                                  DNF_ADDED |
    05786                                  DNF_RESOURCE_ASSIGNED |
    05787                                  DNF_RESOURCE_REPORTED)) ||
    05788             (DeviceNode->UserFlags & DNUF_WILL_BE_REMOVED)));
    05789
    05790     ASSERT(DeviceNode->Flags & DNF_ENUMERATED);
    05791
    05792     if (!(DeviceNode->Flags & DNF_ENUMERATED)) {
    05793         return STATUS_UNSUCCESSFUL;
    05794     }
    05795
    05796     DeviceNode->UserFlags &= ~DNUF_NEED_RESTART;
    05797
    05798 #if DBG_SCOPE
    05799     DeviceNode->FailureStatus = 0;
    05800     if (DeviceNode->PreviousResourceList) {
    05801         ExFreePool(DeviceNode->PreviousResourceList);
    05802         DeviceNode->PreviousResourceList = NULL;
    05803     }
    05804     if (DeviceNode->PreviousResourceRequirements) {
    05805         ExFreePool(DeviceNode->PreviousResourceRequirements);
    05806         DeviceNode->PreviousResourceRequirements = NULL;
    05807     }
    05808 #endif
    05809
    05810     //
    05811     // Free any existing devnode strings so we can recreate them
    05812     // during enumeration.
    05813     //
    05814
    05815     if (DeviceNode->Flags & DNF_PROCESSED) {
    05816
    05817         DeviceNode->Flags &= ~(DNF_PROCESSED |
    05818                                DNF_ENUMERATION_REQUEST_QUEUED |
    05819                                DNF_NO_RESOURCE_REQUIRED |
    05820                                DNF_RESOURCE_REQUIREMENTS_CHANGED);
    05821
    05822         if (DeviceNode->ServiceName.Length != 0) {
    05823             ExFreePool(DeviceNode->ServiceName.Buffer);
    05824             RtlInitUnicodeString(&DeviceNode->ServiceName, NULL);
    05825         }
    05826
    05827         if (DeviceNode->ResourceRequirements != NULL) {
    05828             ExFreePool(DeviceNode->ResourceRequirements);
    05829             DeviceNode->ResourceRequirements = NULL;
    05830             DeviceNode->Flags &= ~DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED;
    05831         }
    05832     }
    05833
    05834     ASSERT(DeviceNode->ServiceName.Length == 0 &&
    05835            DeviceNode->ServiceName.MaximumLength == 0 &&
    05836            DeviceNode->ServiceName.Buffer == NULL);
    05837
    05838     ASSERT(!(DeviceNode->Flags &
    05839            ~(DNF_MADEUP | DNF_ENUMERATED | DNF_HAS_BOOT_CONFIG |
    05840              DNF_BOOT_CONFIG_RESERVED | DNF_NO_RESOURCE_REQUIRED)));
    05841
    05842     return STATUS_SUCCESS;
    05843 }

NTSTATUS IopServiceInstanceToDeviceInstance | ( | IN HANDLE ServiceKeyHandle | OPTIONAL,
|  | IN PUNICODE_STRING ServiceKeyName | OPTIONAL,
|  | IN ULONG | ServiceInstanceOrdinal,
|  | OUT PUNICODE_STRING DeviceInstanceRegistryPath | OPTIONAL,
|  | OUT PHANDLE DeviceInstanceHandle | OPTIONAL,
|  | IN ACCESS_MASK | DesiredAccess
| ) |

Definition at line 931 of file pnpsubs.c.

References CmRegistryMachineSystemCurrentControlSetEnumName, ExFreePool(), FALSE, IopConcatenateUnicodeStrings(), IopGetRegistryValue(), IopOpenRegistryKey(), IopOpenServiceEnumKeys(), IopRegistryDataToUnicodeString, KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), and NULL.

Referenced by IopDriverLoadingFailed(), IopIsAnyDeviceInstanceEnabled(), IopMarkDuplicateDevice(), IopOpenCurrentHwProfileDeviceInstanceKey(), and IopSetLegacyDeviceInstance().

    00942                    :
    00943
    00944     This routine reads the service node enum entry to find the desired device instance
    00945     under the System\Enum tree.  It then optionally returns the registry path of the
    00946     specified device instance (relative to HKLM\System\Enum) and an open handle
    00947     to that registry key.
    00948
    00949     It is the caller's responsibility to close the handle returned if
    00950     DeviceInstanceHandle is supplied, and also to free the (PagedPool) memory
    00951     allocated for the unicode string buffer of DeviceInstanceRegistryPath, if
    00952     supplied.
    00953
    00954 Parameters:
    00955
    00956     ServiceKeyHandle - Optionally, supplies a handle to the driver service node in the
    00957         registry that controls this device instance.  If this argument is not specified,
    00958         then ServiceKeyName is used to specify the service entry.
    00959
    00960     ServiceKeyName - Optionally supplies the name of the service entry that controls
    00961         the device instance. This must be specified if ServiceKeyHandle isn't given.
    00962
    00963     ServiceInstanceOrdinal - Supplies the instance value under the service entry's
    00964         volatile Enum subkey that references the desired device instance.
    00965
    00966     DeviceInstanceRegistryPath - Optionally, supplies a pointer to a unicode string
    00967         that will be initialized with the registry path (relative to HKLM\System\Enum)
    00968         to the device instance key.
    00969
    00970     DeviceInstanceHandle - Optionally, supplies a pointer to a variable that will
    00971         receive a handle to the opened device instance registry key.
    00972
    00973     DesiredAccess - If DeviceInstanceHandle is specified (i.e., the device instance
    00974         key is to be opened), then this variable specifies the access that is needed
    00975         to this key.
    00976
    00977 Return Value:
    00978
    00979     NT status code indicating whether the function was successful.
    00980
    00981 --*/
    00982
    00983 {
    00984     WCHAR unicodeBuffer[20];
    00985     UNICODE_STRING unicodeKeyName;
    00986     NTSTATUS status;
    00987     HANDLE handle;
    00988     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    00989
    00990     //
    00991     // Open registry ServiceKeyName\Enum branch
    00992     //
    00993     if(ARGUMENT_PRESENT(ServiceKeyHandle)) {
    00994
    00995         PiWstrToUnicodeString(&unicodeKeyName, REGSTR_KEY_ENUM);
    00996         status = IopOpenRegistryKeyEx( &handle,
    00997                                        ServiceKeyHandle,
    00998                                        &unicodeKeyName,
    00999                                        KEY_READ
    01000                                        );
    01001     } else {
    01002
    01003         status = IopOpenServiceEnumKeys(ServiceKeyName,
    01004                                         KEY_READ,
    01005                                         NULL,
    01006                                         &handle,
    01007                                         FALSE
    01008                                        );
    01009     }
    01010
    01011     if (!NT_SUCCESS( status )) {
    01012
    01013         //
    01014         // There is no registry key for the ServiceKeyName\Enum information.
    01015         //
    01016
    01017         return status;
    01018     }
    01019
    01020     //
    01021     // Read a path to System\Enum hardware tree branch specified by the service
    01022     // instance ordinal
    01023     //
    01024
    01025     swprintf(unicodeBuffer, REGSTR_VALUE_STANDARD_ULONG_FORMAT, ServiceInstanceOrdinal);
    01026     status = IopGetRegistryValue ( handle,
    01027                                    unicodeBuffer,
    01028                                    &keyValueInformation
    01029                                    );
    01030
    01031     ZwClose(handle);
    01032     if (!NT_SUCCESS( status )) {
    01033         return status;
    01034     } else {
    01035         if(keyValueInformation->Type == REG_SZ) {
    01036             IopRegistryDataToUnicodeString(&unicodeKeyName,
    01037                                            (PWSTR)KEY_VALUE_DATA(keyValueInformation),
    01038                                            keyValueInformation->DataLength
    01039                                           );
    01040             if(!unicodeKeyName.Length) {
    01041                 status = STATUS_OBJECT_PATH_NOT_FOUND;
    01042             }
    01043         } else {
    01044             status = STATUS_INVALID_PLUGPLAY_DEVICE_PATH;
    01045         }
    01046
    01047         if(!NT_SUCCESS(status)) {
    01048             goto PrepareForReturn;
    01049         }
    01050     }
    01051
    01052     //
    01053     // If the DeviceInstanceHandle argument was specified, open the device instance
    01054     // key under HKLM\System\CurrentControlSet\Enum
    01055     //
    01056
    01057     if (ARGUMENT_PRESENT(DeviceInstanceHandle)) {
    01058
    01059         status = IopOpenRegistryKeyEx( &handle,
    01060                                        NULL,
    01061                                        &CmRegistryMachineSystemCurrentControlSetEnumName,
    01062                                        KEY_READ
    01063                                        );
    01064
    01065         if (NT_SUCCESS( status )) {
    01066
    01067             status = IopOpenRegistryKeyEx( DeviceInstanceHandle,
    01068                                            handle,
    01069                                            &unicodeKeyName,
    01070                                            DesiredAccess
    01071                                            );
    01072             ZwClose(handle);
    01073         }
    01074
    01075         if (!NT_SUCCESS( status )) {
    01076             goto PrepareForReturn;
    01077         }
    01078     }
    01079
    01080     //
    01081     // If the DeviceInstanceRegistryPath argument was specified, then store a
    01082     // copy of the device instance path in the supplied unicode string variable.
    01083     //
    01084     if (ARGUMENT_PRESENT(DeviceInstanceRegistryPath)) {
    01085
    01086         if (!IopConcatenateUnicodeStrings(DeviceInstanceRegistryPath,
    01087                                           &unicodeKeyName,
    01088                                           NULL)) {
    01089
    01090             if(ARGUMENT_PRESENT(DeviceInstanceHandle)) {
    01091                 ZwClose(*DeviceInstanceHandle);
    01092             }
    01093             status = STATUS_INSUFFICIENT_RESOURCES;
    01094         }
    01095     }
    01096
    01097 PrepareForReturn:
    01098
    01099     ExFreePool(keyValueInformation);
    01100     return status;
    01101 }

NTSTATUS IopSetServiceInstanceCsConfigFlags | ( | IN PUNICODE_STRING | ServiceKeyName,
|  | IN ULONG | Instance,
|  | IN ULONG | CsConfigFlags
| ) |

Definition at line 1653 of file pnpsubs.c.

References IopOpenCurrentHwProfileDeviceInstanceKey(), NT_SUCCESS, NTSTATUS(), PAGED_CODE, TITLE_INDEX_VALUE, and TRUE.

    01661                    :
    01662
    01663     This routine sets the csconfig flags for the specified device
    01664     which is specified by the instance number under ServiceKeyName\Enum.
    01665
    01666 Arguments:
    01667
    01668     ServiceKeyName - Supplies a pointer to the name of the subkey in the
    01669         system service list (HKEY_LOCAL_MACHINE\CurrentControlSet\Services)
    01670         that caused the driver to load. This is the RegistryPath parameter
    01671         to the DriverEntry routine.
    01672
    01673     Instance - Supplies the instance value under ServiceKeyName\Enum key
    01674
    01675     CsConfigFlags - Supplies the device instance's new CsConfigFlags
    01676
    01677 Return Value:
    01678
    01679     status
    01680
    01681 --*/
    01682
    01683 {
    01684     HANDLE handle;
    01685     NTSTATUS status;
    01686     UNICODE_STRING tempUnicodeString;
    01687
    01688     PAGED_CODE();
    01689
    01690     status = IopOpenCurrentHwProfileDeviceInstanceKey(&handle,
    01691                                                       ServiceKeyName,
    01692                                                       Instance,
    01693                                                       KEY_READ | KEY_WRITE,
    01694                                                       TRUE
    01695                                                      );
    01696     if(NT_SUCCESS(status)) {
    01697
    01698         PiWstrToUnicodeString(&tempUnicodeString, REGSTR_VALUE_CSCONFIG_FLAGS);
    01699         status = ZwSetValueKey(handle,
    01700                                &tempUnicodeString,
    01701                                TITLE_INDEX_VALUE,
    01702                                REG_DWORD,
    01703                                &CsConfigFlags,
    01704                                sizeof(CsConfigFlags)
    01705                               );
    01706         ZwClose(handle);
    01707     }
    01708     return status;
    01709 }

NTSTATUS IopStartAndEnumerateDevice | ( | IN PDEVICE_NODE | DeviceNode,
|  | IN PSTART_CONTEXT | StartContext
| ) |

Definition at line 994 of file pnpenum.c.

References ASSERT, BusQueryCompatibleIDs, BusQueryHardwareIDs, DNF_ADDED, DNF_HAS_RESOURCE, DNF_NEED_ENUMERATION_ONLY, DNF_NEED_QUERY_IDS, DNF_NO_RESOURCE_REQUIRED, DNF_START_PHASE, DNF_STARTED, ExAcquireResourceShared, ExFreePool(), ExReleaseResource, IopDeviceNodeCapabilitiesToRegistry(), IopDeviceObjectToDeviceInstance(), IopEnumerateDevice(), IopFixupIds(), IopQueryCompatibleIds(), IopQueryDeviceState(), IopStartDevice(), KeBugCheckEx(), KeEnterCriticalRegion, KeLeaveCriticalRegion, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PNP_ERR_BOGUS_ID, PnpAsyncOk, PpRegistryDeviceResource, TITLE_INDEX_VALUE, and TRUE.

Referenced by IopNewDevice(), and IopProcessStartDevicesWorker().

    01001                    :
    01002
    01003     This routine starts the specified device and enumerates it.
    01004
    01005     NOTE: The resources for the device should already been allocated.
    01006
    01007 Arguments:
    01008
    01009     DeviceNode - Supplies a pointer to a device node which will be started and
    01010                  enumerated.
    01011
    01012     StartContext - Supplies a pointer to START_CONTEXT structure to control
    01013                  how the start should be handled.
    01014
    01015 Return Value:
    01016
    01017     NTSTATUS code.
    01018
    01019 --*/
    01020
    01021 {
    01022     NTSTATUS status;
    01023     UNICODE_STRING unicodeName;
    01024     PDEVICE_OBJECT deviceObject;
    01025     HANDLE         handle;
    01026
    01027     PAGED_CODE();
    01028
    01029     //
    01030     // If no driver is loaded or add device failed, don't start it.
    01031     //
    01032
    01033     ASSERT((DeviceNode->Flags & DNF_ADDED) &&
    01034            (DeviceNode->Flags & (DNF_HAS_RESOURCE | DNF_NO_RESOURCE_REQUIRED)) &&
    01035            (!(DeviceNode->Flags & DNF_START_PHASE) || (DeviceNode->Flags & DNF_NEED_QUERY_IDS))
    01036            );
    01037
    01038     deviceObject = DeviceNode->PhysicalDeviceObject;
    01039
    01040     //
    01041     // First start the device, if it hasn't
    01042     //
    01043
    01044     if (!(DeviceNode->Flags & DNF_STARTED)) {
    01045
    01046         IopStartDevice(deviceObject);
    01047
    01048         //
    01049         // ADRIAO BUGBUG 11/11/98 -
    01050         //     Everything in this if clause expects the start call to
    01051         // returns synchronously. When AsyncOk == TRUE functionality is fixed,
    01052         // code in here should be moved into IopStartDevice.
    01053         //
    01054         if (DeviceNode->Flags & DNF_STARTED) {
    01055
    01056             IopDeviceNodeCapabilitiesToRegistry(DeviceNode);
    01057             IopQueryDeviceState(deviceObject);
    01058         }
    01059     }
    01060
    01061     if (DeviceNode->Flags & DNF_NEED_QUERY_IDS) {
    01062
    01063         PWCHAR compatibleIds, hwIds;
    01064         ULONG hwIdLength, compatibleIdLength;
    01065
    01066         //
    01067         // If the DNF_NEED_QUERY_IDS is set, the device is a reported device.
    01068         // It should already be started.  We need to enumerate its children and ask
    01069         // the HardwareId and the Compatible ids of the detected device.
    01070         //
    01071
    01072         DeviceNode->Flags &= ~DNF_NEED_QUERY_IDS;
    01073         status = IopDeviceObjectToDeviceInstance (deviceObject,
    01074                                                   &handle,
    01075                                                   KEY_READ
    01076                                                   );
    01077         if (NT_SUCCESS(status)) {
    01078             status = IopQueryCompatibleIds(deviceObject,
    01079                                            BusQueryHardwareIDs,
    01080                                            &hwIds,
    01081                                            &hwIdLength);
    01082
    01083             if (!NT_SUCCESS(status)) {
    01084                 hwIds = NULL;
    01085             }
    01086
    01087             status = IopQueryCompatibleIds(deviceObject,
    01088                                            BusQueryCompatibleIDs,
    01089                                            &compatibleIds,
    01090                                            &compatibleIdLength);
    01091             if (!NT_SUCCESS(status)) {
    01092                 compatibleIds = NULL;
    01093             }
    01094
    01095             if (hwIds || compatibleIds) {
    01096                 KeEnterCriticalRegion();
    01097                 ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE);
    01098
    01099                 if (hwIds) {
    01100
    01101                     if (!IopFixupIds(hwIds, hwIdLength)) {
    01102                         KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
    01103                                       PNP_ERR_BOGUS_ID,
    01104                                       (ULONG_PTR)deviceObject,
    01105                                       (ULONG_PTR)hwIds,
    01106                                       3);
    01107                     }
    01108                     PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_HARDWAREID);
    01109                     ZwSetValueKey(handle,
    01110                                   &unicodeName,
    01111                                   TITLE_INDEX_VALUE,
    01112                                   REG_MULTI_SZ,
    01113                                   hwIds,
    01114                                   hwIdLength
    01115                                   );
    01116                     ExFreePool(hwIds);
    01117                 }
    01118
    01119                 //
    01120                 // create CompatibleId value name.  It is a MULTI_SZ,
    01121                 //
    01122
    01123                 if (compatibleIds) {
    01124
    01125                     if (!IopFixupIds(compatibleIds, compatibleIdLength)) {
    01126                         KeBugCheckEx( PNP_DETECTED_FATAL_ERROR,
    01127                                       PNP_ERR_BOGUS_ID,
    01128                                       (ULONG_PTR)deviceObject,
    01129                                       (ULONG_PTR)compatibleIds,
    01130                                       4);
    01131                     }
    01132
    01133                     PiWstrToUnicodeString(&unicodeName, REGSTR_VAL_COMPATIBLEIDS);
    01134                     ZwSetValueKey(handle,
    01135                                   &unicodeName,
    01136                                   TITLE_INDEX_VALUE,
    01137                                   REG_MULTI_SZ,
    01138                                   compatibleIds,
    01139                                   compatibleIdLength
    01140                                   );
    01141                     ExFreePool(compatibleIds);
    01142                 }
    01143
    01144                 ExReleaseResource(&PpRegistryDeviceResource);
    01145                 KeLeaveCriticalRegion();
    01146             }
    01147             ZwClose(handle);
    01148         }
    01149     }
    01150
    01151     if ((DeviceNode->Flags & DNF_STARTED) &&
    01152         (DeviceNode->Flags & DNF_NEED_ENUMERATION_ONLY)) {
    01153
    01154         status = IopEnumerateDevice(deviceObject, StartContext, PnpAsyncOk);
    01155     } else {
    01156         status = STATUS_SUCCESS;
    01157     }
    01158
    01159     return status;
    01160 }

VOID IopStartDevice | ( | IN PDEVICE_OBJECT | TargetDevice | ) |

Definition at line 510 of file pnpirp.c.

References ASSERT, _DEVICE_COMPLETION_CONTEXT::DeviceNode, DNF_NEED_ENUMERATION_ONLY, DNF_RESOURCE_REPORTED, DNF_START_REQUEST_PENDING, DNF_STARTED, DNF_STOPPED, DOCK_ARRIVING, DOCK_NOTDOCKDEVICE, DOCK_QUIESCENT, _DEVICE_NODE::DockInfo, dummy(), ExAllocatePool, ExGetCurrentResourceThread, FALSE, _DEVICE_NODE::Flags, IopAcquireEnumerationLock, IopAsynchronousCall(), IopDeviceStartComplete(), IopDoDeferredSetInterfaceState(), IopDoesDevNodeHaveProblem, IopHardwareProfileBeginTransition(), IopHardwareProfileCancelTransition(), IopHardwareProfileCommitStartedDock(), IopHardwareProfileMarkDock(), IopHardwareProfileQueryChange(), IopPnPSpinLock, IopRequestDeviceRemoval(), IopSetDevNodeProblem, IopSynchronousCall(), IopUncacheInterfaceInformation(), IRP_MJ_PNP, IRP_MN_START_DEVICE, _DEVICE_COMPLETION_CONTEXT::IrpMinorCode, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, _IO_STACK_LOCATION::Parameters, PDEVICE_COMPLETION_CONTEXT, _DEVICE_NODE::PhysicalDeviceObject, PnpAsyncOk, PpSetTargetDeviceRemove(), PROFILE_PERHAPS_IN_PNPEVENT, _DEVICE_NODE::ResourceList, _DEVICE_NODE::ResourceListTranslated, SAVE_FAILURE_INFO, _DEVICE_COMPLETION_CONTEXT::Thread, and TRUE.

Referenced by IopReallocateResources(), IopRebalance(), and IopStartAndEnumerateDevice().

    00516                    :
    00517
    00518     This function sends a start device irp to the top level device
    00519     object which roots on DeviceObject.
    00520
    00521 Parameters:
    00522
    00523     DeviceObject - Supplies the pointer to the device object of the device
    00524                    being removed.
    00525
    00526 Return Value:
    00527
    00528     NTSTATUS code.
    00529
    00530 --*/
    00531
    00532 {
    00533     IO_STACK_LOCATION irpSp;
    00534     PVOID dummy;
    00535     PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
    00536     PDEVICE_COMPLETION_CONTEXT completionContext;
    00537     NTSTATUS status;
    00538     PNP_VETO_TYPE  vetoType;
    00539
    00540 //    PAGED_CODE();
    00541
    00542     //
    00543     // Initialize the stack location to pass to IopSynchronousCall()
    00544     //
    00545
    00546     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    00547
    00548     //
    00549     // Set the function codes.
    00550     //
    00551
    00552     irpSp.MajorFunction = IRP_MJ_PNP;
    00553     irpSp.MinorFunction = IRP_MN_START_DEVICE;
    00554
    00555     //
    00556     // Set the pointers for the raw and translated resource lists
    00557     //
    00558
    00559     if (!(deviceNode->Flags & DNF_RESOURCE_REPORTED)) {
    00560         irpSp.Parameters.StartDevice.AllocatedResources = deviceNode->ResourceList;
    00561         irpSp.Parameters.StartDevice.AllocatedResourcesTranslated = deviceNode->ResourceListTranslated;
    00562     }
    00563
    00564     if (!(deviceNode->Flags & DNF_STOPPED)) {
    00565         IopUncacheInterfaceInformation(DeviceObject);
    00566     }
    00567
    00568     if (PnpAsyncOk) {
    00569
    00570         //
    00571         // ADRIAO BUGBUG 11/18/98 -
    00572         //     The dock code has not been duplicated in the async case, but as
    00573         // PnpAsync support is totally broken and disabled anyway, this should
    00574         // not matter right now.
    00575         //
    00576         ASSERT(0);
    00577         completionContext = (PDEVICE_COMPLETION_CONTEXT) ExAllocatePool(
    00578                               NonPagedPool,
    00579                               sizeof(DEVICE_COMPLETION_CONTEXT));
    00580         if (completionContext == NULL) {
    00581             return;   // BUGBUG - Should try it again *explicitly*
    00582         }
    00583
    00584         completionContext->DeviceNode = deviceNode;
    00585         completionContext->IrpMinorCode = IRP_MN_START_DEVICE;
    00586         completionContext->Thread = ExGetCurrentResourceThread();
    00587
    00588         //
    00589         // Make the call and return.
    00590         //
    00591
    00592         IopAcquireEnumerationLock(NULL);  // To block IopAcquireTreeLock();
    00593         status = IopAsynchronousCall(DeviceObject, &irpSp, completionContext, IopDeviceStartComplete);
    00594         if (status == STATUS_PENDING) {
    00595
    00596             KIRQL oldIrql;
    00597
    00598             //
    00599             // Set DNF_START_REQUEST_PENDING flag such that the completion routine knows it
    00600             // needs to request enumeration when the start completed successfully.
    00601             //
    00602
    00603             ExAcquireSpinLock(&IopPnPSpinLock, &oldIrql);
    00604
    00605             if (!(IopDoesDevNodeHaveProblem(deviceNode) || (deviceNode->Flags & DNF_STARTED))) {
    00606                 deviceNode->Flags |= DNF_START_REQUEST_PENDING;
    00607             }
    00608             ExReleaseSpinLock(&IopPnPSpinLock, oldIrql);
    00609         }
    00610     } else {
    00611
    00612         if ((deviceNode->Flags & DNF_STOPPED)||
    00613             (deviceNode->DockInfo.DockStatus == DOCK_NOTDOCKDEVICE)) {
    00614
    00615
    00616             //
    00617             // This is either the rebalance case in which we are restarting a
    00618             // temporarily stopped device, or we are starting a non-dock device,
    00619             // and it was previously off.
    00620             //
    00621             status = IopSynchronousCall(DeviceObject, &irpSp, &dummy);
    00622
    00623         } else {
    00624
    00625             //
    00626             // This is a dock so we a little bit of work before starting it.
    00627             // Take the profile change semaphore. We do this whenever a dock
    00628             // is in our list, even if no query is going to occur.
    00629             //
    00630             IopHardwareProfileBeginTransition(FALSE);
    00631
    00632             //
    00633             // Tell the profile code what dock device object may be bringing the
    00634             // new hardware profile online.
    00635             //
    00636             IopHardwareProfileMarkDock(deviceNode, DOCK_ARRIVING);
    00637
    00638             //
    00639             // Ask everyone if this is really a good idea right now. Note that
    00640             // PiProcessStart calls IopNewDevice calls IopStartAndEnumerateDevice
    00641             // who calls this function on that thread. Therefore we may indded be
    00642             // in an event, although this would probably be a fairly rare event
    00643             // for a dock.
    00644             //
    00645             status = IopHardwareProfileQueryChange(
    00646                 FALSE,
    00647                 PROFILE_PERHAPS_IN_PNPEVENT,
    00648                 &vetoType,
    00649                 NULL
    00650                 );
    00651
    00652             if (NT_SUCCESS(status)) {
    00653
    00654                 status = IopSynchronousCall(DeviceObject, &irpSp, &dummy);
    00655             }
    00656
    00657             if (NT_SUCCESS(status)) {
    00658
    00659                 //
    00660                 // Commit the current Hardware Profile as necessary.
    00661                 //
    00662                 IopHardwareProfileCommitStartedDock(deviceNode);
    00663
    00664             } else {
    00665
    00666                 IopHardwareProfileCancelTransition();
    00667             }
    00668         }
    00669
    00670         if (!NT_SUCCESS(status)) {
    00671             ULONG Problem = CM_PROB_FAILED_START;
    00672
    00673             SAVE_FAILURE_INFO(deviceNode, status);
    00674
    00675             //
    00676             // Handle certain problems determined by the status code
    00677             //
    00678             switch (status) {
    00679                 case STATUS_PNP_REBOOT_REQUIRED:
    00680                     Problem = CM_PROB_NEED_RESTART;
    00681                     break;
    00682
    00683                 default:
    00684                     Problem = CM_PROB_FAILED_START;
    00685             }
    00686             IopSetDevNodeProblem(deviceNode, Problem);
    00687
    00688             if (deviceNode->DockInfo.DockStatus == DOCK_NOTDOCKDEVICE) {
    00689
    00690                 IopRequestDeviceRemoval(deviceNode->PhysicalDeviceObject, CM_PROB_FAILED_START);
    00691             } else {
    00692
    00693                 ASSERT(deviceNode->DockInfo.DockStatus == DOCK_QUIESCENT);
    00694
    00695                 PpSetTargetDeviceRemove( deviceNode->PhysicalDeviceObject,
    00696                                          FALSE,
    00697                                          TRUE,
    00698                                          TRUE,
    00699                                          CM_PROB_DEVICE_NOT_THERE,
    00700                                          NULL,
    00701                                          NULL,
    00702                                          NULL,
    00703                                          NULL);
    00704             }
    00705
    00706         } else {
    00707
    00708             IopDoDeferredSetInterfaceState(deviceNode);
    00709
    00710             deviceNode->Flags |= DNF_STARTED;
    00711
    00712             if (deviceNode->Flags & DNF_STOPPED) {
    00713
    00714                 //
    00715                 // If the start is initiated by rebalancing, do NOT do enumeration
    00716                 //
    00717
    00718                 deviceNode->Flags &= ~DNF_STOPPED;
    00719
    00720             } else {
    00721
    00722                 deviceNode->Flags |= DNF_NEED_ENUMERATION_ONLY;
    00723
    00724             }
    00725         }
    00726     }
    00727 }

NTSTATUS IopStartDriverDevices | ( | IN PDRIVER_OBJECT | DriverObject | ) |

Definition at line 1740 of file pnpdd.c.

References ASSERT, _DEVICE_LIST_CONTEXT::DeviceCount, _DEVICE_LIST_CONTEXT::DeviceList, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_NEED_QUERY_IDS, ExFreePool(), _DEVICE_NODE::Flags, IopGetDriverDeviceList(), IopRequestDeviceAction(), NTSTATUS(), NULL, ObDereferenceObject, PAGED_CODE, PDEVICE_LIST_CONTEXT, PDRIVER_ADD_DEVICE, PnPInitialized, and StartDevice.

Referenced by IopLoadDriver().

    01746                    :
    01747
    01748     This routine is used by IopLoadDriver to add/start the devices controlled by
    01749     the newly loaded driver.
    01750
    01751 Arguments:
    01752
    01753     DriverObject - specifies the driver object which is being started thru
    01754                    IopLoadDriver after the boot drivers and system drivers init
    01755                    phase.
    01756
    01757 Return Value:
    01758
    01759     NTSTATUS code.
    01760
    01761 --*/
    01762
    01763 {
    01764     ULONG count, i;
    01765     PDEVICE_LIST_CONTEXT deviceList;
    01766     PDEVICE_NODE deviceNode;
    01767     NTSTATUS status = STATUS_SUCCESS;
    01768     PDRIVER_ADD_DEVICE addDeviceRoutine;
    01769
    01770     PAGED_CODE();
    01771
    01772     if (!PnPInitialized) {
    01773
    01774         //
    01775         // If this function is called at PnP Init time, we don't start the devices
    01776         // for the specified driver.  The device add/start is handled by pnp based
    01777         // on the device enumeration.
    01778         //
    01779
    01780         return status;
    01781     }
    01782
    01783     addDeviceRoutine = DriverObject->DriverExtension->AddDevice;
    01784     if (addDeviceRoutine == NULL) {
    01785         ASSERT(addDeviceRoutine);
    01786         return status;
    01787     }
    01788
    01789     IopGetDriverDeviceList(DriverObject, &deviceList);
    01790     count = deviceList ? deviceList->DeviceCount : 0;
    01791     if (count == 0) {
    01792
    01793         if (deviceList != NULL) {
    01794             ExFreePool(deviceList);
    01795         }
    01796
    01797         return STATUS_PLUGPLAY_NO_DEVICE;
    01798     }
    01799
    01800     //
    01801     // For each device int the list queue an IopNewDeviceEvent if the device is reported by driver
    01802     //
    01803
    01804     for (i = 0; i < count; i++) {
    01805
    01806         deviceNode = (PDEVICE_NODE)deviceList->DeviceList[i]->DeviceObjectExtension->DeviceNode;
    01807         if (!deviceNode || !(deviceNode->Flags & DNF_NEED_QUERY_IDS) ) {
    01808             ObDereferenceObject(deviceList->DeviceList[i]);
    01809             continue;
    01810         }
    01811         IopRequestDeviceAction(deviceList->DeviceList[i], StartDevice, NULL, NULL);
    01812     }
    01813
    01814     ExFreePool(deviceList);
    01815     return status;
    01816 }

NTSTATUS IopSynchronousCall | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN PIO_STACK_LOCATION | TopStackLocation,
|  | OUT PVOID * | Information
| ) |

Definition at line 381 of file pnpirp.c.

References Executive, FALSE, IoAllocateIrp(), IoCallDriver, IoGetAttachedDevice(), IoGetNextIrpStackLocation, IopQueueThreadIrp, _IRP::IoStatus, IRP_SYSTEM_RESTRICTED, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), NTSTATUS(), NULL, PAGED_CODE, PnpIrpStatusTracking, PsGetCurrentThread, SPECIALIRP_WATERMARK_IRP, _DEVICE_OBJECT::StackSize, _IRP::Tail, _IRP::UserEvent, _IRP::UserIosb, and VOID().

Referenced by IoFreeDumpStack(), IopEnumerateDevice(), IopGetDumpStack(), IopGetRelatedTargetDevice(), IopProcessNewDeviceNode(), IopQueryCompatibleIds(), IopQueryDeviceCapabilities(), IopQueryDeviceId(), IopQueryDeviceRelations(), IopQueryDeviceResources(), IopQueryDeviceSerialNumber(), IopQueryDeviceState(), IopQueryDockRemovalInterface(), IopQueryLegacyBusInformation(), IopQueryPnpBusInformation(), IopQueryReconfiguration(), IopQueryResourceHandlerInterface(), IopQueryUniqueId(), IopRemoveDevice(), and IopStartDevice().

    00389                    :
    00390
    00391     This function sends a synchronous irp to the top level device
    00392     object which roots on DeviceObject.
    00393
    00394 Parameters:
    00395
    00396     DeviceObject - Supplies the device object of the device being removed.
    00397
    00398     TopStackLocation - Supplies a pointer to the parameter block for the irp.
    00399
    00400     Information - Supplies a pointer to a variable to receive the returned
    00401                   information of the irp.
    00402
    00403 Return Value:
    00404
    00405     NTSTATUS code.
    00406
    00407 --*/
    00408
    00409 {
    00410     PIRP irp;
    00411     PIO_STACK_LOCATION irpSp;
    00412     IO_STATUS_BLOCK statusBlock;
    00413     KEVENT event;
    00414     NTSTATUS status;
    00415     PULONG_PTR returnInfo = (PULONG_PTR)Information;
    00416     PDEVICE_OBJECT deviceObject;
    00417
    00418     PAGED_CODE();
    00419
    00420     //
    00421     // Get a pointer to the topmost device object in the stack of devices,
    00422     // beginning with the deviceObject.
    00423     //
    00424
    00425     deviceObject = IoGetAttachedDevice(DeviceObject);
    00426
    00427     //
    00428     // Begin by allocating the IRP for this request.  Do not charge quota to
    00429     // the current process for this IRP.
    00430     //
    00431
    00432     irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
    00433     if (irp == NULL){
    00434
    00435         return STATUS_INSUFFICIENT_RESOURCES;
    00436     }
    00437
    00438     SPECIALIRP_WATERMARK_IRP(irp, IRP_SYSTEM_RESTRICTED);
    00439
    00440     //
    00441     // Initialize it to failure.
    00442     //
    00443
    00444     irp->IoStatus.Status = statusBlock.Status = STATUS_NOT_SUPPORTED;
    00445     irp->IoStatus.Information = statusBlock.Information = 0;
    00446
    00447     //
    00448     // Set the pointer to the status block and initialized event.
    00449     //
    00450
    00451     KeInitializeEvent( &event,
    00452                        SynchronizationEvent,
    00453                        FALSE );
    00454
    00455     irp->UserIosb = &statusBlock;
    00456     irp->UserEvent = &event;
    00457
    00458     //
    00459     // Set the address of the current thread
    00460     //
    00461
    00462     irp->Tail.Overlay.Thread = PsGetCurrentThread();
    00463
    00464     //
    00465     // Queue this irp onto the current thread
    00466     //
    00467
    00468     IopQueueThreadIrp(irp);
    00469
    00470     //
    00471     // Get a pointer to the stack location of the first driver which will be
    00472     // invoked.  This is where the function codes and parameters are set.
    00473     //
    00474
    00475     irpSp = IoGetNextIrpStackLocation(irp);
    00476
    00477     //
    00478     // Copy in the caller-supplied stack location contents
    00479     //
    00480
    00481     *irpSp = *TopStackLocation;
    00482
    00483     //
    00484     // Call the driver
    00485     //
    00486
    00487     status = IoCallDriver(deviceObject, irp);
    00488
    00489     PnpIrpStatusTracking(status, TopStackLocation->MinorFunction, deviceObject);
    00490
    00491     //
    00492     // If a driver returns STATUS_PENDING, we will wait for it to complete
    00493     //
    00494
    00495     if (status == STATUS_PENDING) {
    00496         (VOID) KeWaitForSingleObject( &event,
    00497                                       Executive,
    00498                                       KernelMode,
    00499                                       FALSE,
    00500                                       (PLARGE_INTEGER) NULL );
    00501         status = statusBlock.Status;
    00502     }
    00503
    00504     *returnInfo = (ULONG_PTR) statusBlock.Information;
    00505
    00506     return status;
    00507 }

VOID IopUncacheInterfaceInformation | ( | IN PDEVICE_OBJECT | DeviceObject | ) |

Definition at line 191 of file pnpirp.c.

References _INTERFACE::Context, _DEVICE_NODE::DeviceArbiterList, _DEVICE_NODE::DeviceTranslatorList, ExFreePool(), _INTERFACE::InterfaceDereference, _DEVICE_NODE::NoArbiterMask, _DEVICE_NODE::NoTranslatorMask, _DEVICE_NODE::QueryArbiterMask, _DEVICE_NODE::QueryTranslatorMask, and _PI_RESOURCE_TRANSLATOR_ENTRY::TranslatorInterface.

Referenced by IopDestroyDeviceNode(), IopInvalidateDeviceStateWorker(), IopRemoveDevice(), and IopStartDevice().

    00197                    :
    00198
    00199     This function removes all the cached translators and arbiters information
    00200     from the device object.
    00201
    00202 Parameters:
    00203
    00204     DeviceObject - Supplies the device object of the device being removed.
    00205
    00206 Return Value:
    00207
    00208     NTSTATUS code.
    00209
    00210 --*/
    00211
    00212 {
    00213     PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode;
    00214     PLIST_ENTRY listHead, nextEntry, entry;
    00215     PPI_RESOURCE_TRANSLATOR_ENTRY handlerEntry;
    00216     PINTERFACE interface;
    00217
    00218     //
    00219     // Dereference all the arbiters on this PDO.
    00220     //
    00221
    00222     listHead = &deviceNode->DeviceArbiterList;
    00223     nextEntry = listHead->Flink;
    00224     while (nextEntry != listHead) {
    00225         entry = nextEntry;
    00226         nextEntry = nextEntry->Flink;
    00227         handlerEntry = CONTAINING_RECORD(entry, PI_RESOURCE_TRANSLATOR_ENTRY, DeviceTranslatorList);
    00228         if (interface = (PINTERFACE)handlerEntry->TranslatorInterface) {
    00229             (interface->InterfaceDereference)(interface->Context);
    00230             ExFreePool(interface);
    00231         }
    00232         ExFreePool(entry);
    00233     }
    00234     InitializeListHead(&deviceNode->DeviceArbiterList);
    00235
    00236     //
    00237     // Dereference all the translators on this PDO.
    00238     //
    00239
    00240     listHead = &deviceNode->DeviceTranslatorList;
    00241     nextEntry = listHead->Flink;
    00242     while (nextEntry != listHead) {
    00243         entry = nextEntry;
    00244         nextEntry = nextEntry->Flink;
    00245         handlerEntry = CONTAINING_RECORD(entry, PI_RESOURCE_TRANSLATOR_ENTRY, DeviceTranslatorList);
    00246         if (interface = (PINTERFACE)handlerEntry->TranslatorInterface) {
    00247             (interface->InterfaceDereference)(interface->Context);
    00248             ExFreePool(interface);
    00249         }
    00250         ExFreePool(entry);
    00251     }
    00252
    00253     InitializeListHead(&deviceNode->DeviceTranslatorList);
    00254
    00255     deviceNode->NoArbiterMask = 0;
    00256     deviceNode->QueryArbiterMask = 0;
    00257     deviceNode->NoTranslatorMask = 0;
    00258     deviceNode->QueryTranslatorMask = 0;
    00259 }

NTSTATUS IopUnlockDeviceRemovalRelations | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN PRELATION_LIST | RelationsList,
|  | IN UNLOCK_UNLINK_ACTION | UnlinkAction
| ) |

Definition at line 1572 of file pnpdel.c.

References ASSERT, _DEVICE_NODE::Child, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_ENUMERATED, DNF_REMOVE_PENDING_CLOSES, DNF_RESOURCE_ASSIGNED, _DEVICE_NODE::EnumerationMutex, ExAcquireResourceExclusive, ExReleaseResource, FALSE, _DEVICE_NODE::Flags, _DEVICE_NODE::InstancePath, IopCleanupDeviceRegistryValues(), IopDoesDevNodeHaveProblem, IopEnumerateRelations(), IopRemoveRelationFromList(), IopRemoveTreeDeviceNode(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KeSetEvent(), _DEVICE_NODE::LockCount, NTSTATUS(), NULL, ObDereferenceObject, PAGED_CODE, _DEVICE_NODE::Parent, _DEVICE_NODE::PhysicalDeviceObject, PpRegistryDeviceResource, TRUE, UnlinkAllDeviceNodesPendingClose, UnlinkRemovedDeviceNodes, and UNLOCK_UNLINK_ACTION.

    01580                    :
    01581
    01582     This routine unlocks the device tree deletion operation.
    01583     If there is any pending kernel deletion, this routine initiates
    01584     a worker thread to perform the work.
    01585
    01586 Arguments:
    01587
    01588     DeviceObject - Supplies a pointer to the device object to which the remove
    01589         was originally targetted (as opposed to one of the relations).
    01590
    01591     DeviceRelations - supplies a pointer to the device's removal relations.
    01592
    01593     UnlinkAction - Specifies which devnodes will be unlinked from the devnode
    01594         tree.
    01595
    01596         UnLinkRemovedDeviceNodes - Devnodes which are no longer enumerated and
    01597             have been sent a REMOVE_DEVICE IRP are unlinked.
    01598
    01599         UnlinkAllDeviceNodesPendingClose - This is used when a device is
    01600             surprise removed.  Devnodes in RelationsList are unlinked from the
    01601             tree if they don't have children and aren't consuming any resources.
    01602
    01603         UnlinkOnlyChildDeviceNodesPendingClose - This is used when a device fails
    01604             while started.  We unlink any child devnodes of the device which
    01605             failed but not the failed device's devnode.
    01606
    01607 Return Value:
    01608
    01609     NTSTATUS code.
    01610
    01611 --*/
    01612
    01613 {
    01614     NTSTATUS status;
    01615     PDEVICE_NODE deviceNode, parent;
    01616     PDEVICE_OBJECT deviceObject, relatedDeviceObject;
    01617     ULONG i;
    01618     ULONG marker;
    01619
    01620     PAGED_CODE();
    01621
    01622     KeEnterCriticalRegion();
    01623     ExAcquireResourceExclusive(&PpRegistryDeviceResource, TRUE);
    01624
    01625     if (ARGUMENT_PRESENT(RelationsList)) {
    01626         marker = 0;
    01627         while (IopEnumerateRelations( RelationsList,
    01628                                       &marker,
    01629                                       &deviceObject,
    01630                                       NULL,
    01631                                       NULL,
    01632                                       TRUE)) {
    01633
    01634             deviceNode = (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode;
    01635             parent = deviceNode->Parent;
    01636
    01637             //
    01638             // There are three different scenarios in which we want to unlink a
    01639             // devnode from the tree.  The first case is tested in the first
    01640             // part of the condition.  The other two in the second part.
    01641             //
    01642             // 1) A devnode is no longer enumerated and has been sent a
    01643             //    remove IRP.
    01644             //
    01645             // 2) A devnode has been surprise removed, has no children, has
    01646             //    no resources or they've been freed.  UnlinkAction will be
    01647             //    UnlinkAllDeviceNodesPendingClose.
    01648             //
    01649             // 3) A devnode has failed and a surprise remove IRP has been sent.
    01650             //    Then we want to remove children without resources but not the
    01651             //    failed devnode itself.  UnlinkAction will be
    01652             //    UnlinkOnlyChildDeviceNodesPendingClose.
    01653             //
    01654
    01655             if ((!(deviceNode->Flags & (DNF_ENUMERATED | DNF_REMOVE_PENDING_CLOSES)) &&
    01656                     IopDoesDevNodeHaveProblem(deviceNode)) ||
    01657                 (UnlinkAction != UnlinkRemovedDeviceNodes &&
    01658                     (deviceNode->Flags & DNF_REMOVE_PENDING_CLOSES) &&
    01659                     !(deviceNode->Flags & DNF_RESOURCE_ASSIGNED) &&
    01660                     deviceNode->Child == NULL &&
    01661                     (UnlinkAction == UnlinkAllDeviceNodesPendingClose ||
    01662                      deviceObject != DeviceObject))) {
    01663
    01664                 PIDBGMSG( PIDBG_REMOVAL,
    01665                           ("IopUnlockDeviceRemovalRelations: Cleaning up registry values, instance = %wZ\n",
    01666                           &deviceNode->InstancePath));
    01667
    01668                 IopCleanupDeviceRegistryValues(&deviceNode->InstancePath, FALSE);
    01669
    01670                 PIDBGMSG( PIDBG_REMOVAL,
    01671                           ("IopUnlockDeviceRemovalRelations: Removing DevNode tree, DevNode = 0x%p\n",
    01672                           deviceNode));
    01673
    01674                 IopRemoveTreeDeviceNode(deviceNode);
    01675
    01676                 if (!(deviceNode->Flags & DNF_REMOVE_PENDING_CLOSES)) {
    01677                     IopRemoveRelationFromList(RelationsList, deviceObject);
    01678                 }
    01679                 ObDereferenceObject(deviceObject); // Added during enum
    01680             }
    01681
    01682             ASSERT(deviceNode->LockCount > 0);
    01683
    01684             if (--deviceNode->LockCount == 0) {
    01685                 KeSetEvent(&deviceNode->EnumerationMutex, 0, FALSE);
    01686                 ObDereferenceObject(deviceObject);
    01687             }
    01688
    01689             ASSERT(parent->LockCount > 0);
    01690
    01691             if (--parent->LockCount == 0) {
    01692                 KeSetEvent(&parent->EnumerationMutex, 0, FALSE);
    01693                 ObDereferenceObject(parent->PhysicalDeviceObject);
    01694             }
    01695         }
    01696     }
    01697
    01698     ExReleaseResource(&PpRegistryDeviceResource);
    01699     KeLeaveCriticalRegion();
    01700
    01701     return STATUS_SUCCESS;
    01702 }

NTSTATUS IopUnregisterDeviceInterface | ( | IN PUNICODE_STRING | SymbolicLinkName | ) |

Definition at line 4140 of file pnpioapi.c.

References ExAcquireResourceExclusive, ExFreePool(), ExReleaseResource, FALSE, IopAllocateUnicodeString(), IopConstStringSize, IopDeleteKeyRecursive(), IopDeviceInterfaceKeysFromSymbolicLink(), IopFreeAllocatedUnicodeString(), IopGetRegistryKeyInformation(), IopGetRegistryValue(), IopOpenRegistryKeyEx(), IopParseSymbolicLinkName(), IoSetDeviceInterfaceState(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KEY_STRING_PREFIX, KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PpRegistryDeviceResource, REFSTRING_PREFIX_CHAR, RtlAppendUnicodeStringToString(), TRUE, and USHORT.

Referenced by IopRemoveDeviceInterfaces().

    04146                    :
    04147
    04148     This routine removes the interface instance subkey of
    04149     ReferenceString from the interface for DeviceInstanceName to the
    04150     given InterfaceClassGuid.  If the interface instance specified by
    04151     the Reference String portion of SymbolicLinkName is the only
    04152     instance of the interface, the interface subkey is removed from
    04153     the device class key as well.
    04154
    04155 Parameters:
    04156
    04157     SymbolicLinkName - Supplies a pointer to a unicode string which
    04158         contains the symbolic link name of the device to unregister.
    04159
    04160 Return Value:
    04161
    04162     Status code that indicates whether or not the function was successful.
    04163
    04164 --*/
    04165
    04166 {
    04167     NTSTATUS        status = STATUS_SUCCESS, context;
    04168     HANDLE          hInterfaceClassKey=NULL, hInterfaceKey=NULL,
    04169                     hInterfaceInstanceKey=NULL, hControl=NULL;
    04170     UNICODE_STRING  tempString, mungedPathString, guidString, refString;
    04171     BOOLEAN         refStringPresent;
    04172     GUID            guid;
    04173     UNICODE_STRING  interfaceKeyName, instanceKeyName;
    04174     ULONG           linked, remainingSubKeys;
    04175     USHORT          length;
    04176     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    04177     PKEY_FULL_INFORMATION keyInformation;
    04178
    04179
    04180     PAGED_CODE();
    04181
    04182     //
    04183     // Check that the supplied symbolic link is present, and can be parsed
    04184     //
    04185     if ( (!ARGUMENT_PRESENT(SymbolicLinkName)) ||
    04186          (!NT_SUCCESS(IopParseSymbolicLinkName(SymbolicLinkName,
    04187                                               NULL,
    04188                                               &mungedPathString,
    04189                                               &guidString,
    04190                                               &refString,
    04191                                               &refStringPresent,
    04192                                               &guid))) ) {
    04193         status = STATUS_INVALID_PARAMETER;
    04194         goto clean0;
    04195     }
    04196
    04197     //
    04198     // Allocate a unicode string for the interface instance key name.
    04199     // (includes the REFSTRING_PREFIX_CHAR, and ReferenceString, if present)
    04200     //
    04201     length = sizeof(WCHAR) + refString.Length;
    04202     status = IopAllocateUnicodeString(&instanceKeyName,
    04203                                       length);
    04204     if(!NT_SUCCESS(status)) {
    04205         goto clean0;
    04206     }
    04207
    04208     //
    04209     // Set the MaximumLength of the Buffer, and append the
    04210     // REFSTRING_PREFIX_CHAR to it.
    04211     //
    04212     *instanceKeyName.Buffer = REFSTRING_PREFIX_CHAR;
    04213     instanceKeyName.Length = sizeof(WCHAR);
    04214     instanceKeyName.MaximumLength = length + sizeof(UNICODE_NULL);
    04215
    04216     //
    04217     // Append the ReferenceString to the prefix char, if necessary.
    04218     //
    04219     if (refStringPresent) {
    04220         RtlAppendUnicodeStringToString(&instanceKeyName, &refString);
    04221     }
    04222
    04223     instanceKeyName.Buffer[instanceKeyName.Length/sizeof(WCHAR)] = UNICODE_NULL;
    04224
    04225     //
    04226     // Allocate a unicode string for the interface key name.
    04227     // (includes KEY_STRING_PREFIX, mungedPathString, separating '#'
    04228     //  char, and the guidString)
    04229     //
    04230     length = IopConstStringSize(KEY_STRING_PREFIX) + mungedPathString.Length +
    04231              sizeof(WCHAR) + guidString.Length;
    04232
    04233     status = IopAllocateUnicodeString(&interfaceKeyName,
    04234                                       length);
    04235     if(!NT_SUCCESS(status)) {
    04236         goto clean1;
    04237     }
    04238
    04239     interfaceKeyName.MaximumLength = length + sizeof(UNICODE_NULL);
    04240
    04241     //
    04242     // Copy the symbolic link name (without refString) to the interfaceKeyNam
    04243     //
    04244     RtlCopyMemory(interfaceKeyName.Buffer, SymbolicLinkName->Buffer, length);
    04245     interfaceKeyName.Length = length;
    04246     interfaceKeyName.Buffer[interfaceKeyName.Length/sizeof(WCHAR)] = UNICODE_NULL;
    04247
    04248     //
    04249     // Replace the "\??\" or "\\?\" symbolic link name prefix with "##?#"
    04250     //
    04251     RtlCopyMemory(interfaceKeyName.Buffer,
    04252                   KEY_STRING_PREFIX,
    04253                   IopConstStringSize(KEY_STRING_PREFIX));
    04254
    04255     //
    04256     // Enter critical section and acquire a lock on the registry.  Both these
    04257     // mechanisms are required to prevent deadlock in the case where an APC
    04258     // routine calls this routine after the registry resource has been claimed
    04259     // in this case it would wait blocking this thread so the registry would
    04260     // never be released -> deadlock.  Critical sectioning the registry manipulation
    04261     // portion solves this problem
    04262     //
    04263
    04264     KeEnterCriticalRegion();
    04265     ExAcquireResourceExclusive(&PpRegistryDeviceResource, TRUE);
    04266
    04267     //
    04268     // Get class, interface, and instance handles
    04269     //
    04270     status = IopDeviceInterfaceKeysFromSymbolicLink(SymbolicLinkName,
    04271                                                     KEY_ALL_ACCESS,
    04272                                                     &hInterfaceClassKey,
    04273                                                     &hInterfaceKey,
    04274                                                     &hInterfaceInstanceKey
    04275                                                     );
    04276     if (!NT_SUCCESS(status)) {
    04277         goto clean2;
    04278     }
    04279
    04280     //
    04281     // Determine whether this interface is currently "enabled"
    04282     //
    04283     linked = 0;
    04284     PiWstrToUnicodeString(&tempString, REGSTR_KEY_CONTROL);
    04285     status = IopOpenRegistryKeyEx( &hControl,
    04286                                    hInterfaceInstanceKey,
    04287                                    &tempString,
    04288                                    KEY_ALL_ACCESS
    04289                                    );
    04290     if (NT_SUCCESS(status)) {
    04291         //
    04292         // Check the "linked" value under the "Control" subkey of this
    04293         // interface instance
    04294         //
    04295         keyValueInformation=NULL;
    04296         status = IopGetRegistryValue(hControl,
    04297                                      REGSTR_VAL_LINKED,
    04298                                      &keyValueInformation);
    04299
    04300         if(NT_SUCCESS(status)) {
    04301             if (keyValueInformation->Type == REG_DWORD &&
    04302                 keyValueInformation->DataLength == sizeof(ULONG)) {
    04303
    04304                 linked = *((PULONG) KEY_VALUE_DATA(keyValueInformation));
    04305                 ExFreePool(keyValueInformation);
    04306             }
    04307         }
    04308
    04309         ZwClose(hControl);
    04310         hControl = NULL;
    04311     }
    04312
    04313     //
    04314     // Ignore any status code returned while attempting to retieve the
    04315     // state of the device.  The value of linked will tell us if we
    04316     // need to disable the interface instance first.
    04317     //
    04318     // If no instance "Control" subkey or "linked" value was present
    04319     //     (status == STATUS_OBJECT_NAME_NOT_FOUND), this interface instance
    04320     //     is not currently enabled -- ok to delete.
    04321     //
    04322     // If the attempt to retrieve these values failed with some other error,
    04323     //     any attempt to disable the interface will also likely fail,
    04324     //     so we'll just have to delete this instance anyways.
    04325     //
    04326     status = STATUS_SUCCESS;
    04327
    04328     if (linked) {
    04329         //
    04330         // Disabled the active interface before unregistering it, ignore any
    04331         // status returned, we'll delete this interface instance key anyways.
    04332         //
    04333         IoSetDeviceInterfaceState(SymbolicLinkName, FALSE);
    04334     }
    04335
    04336     //
    04337     // Recursively delete the interface instance key, if it exists.
    04338     //
    04339     ZwClose(hInterfaceInstanceKey);
    04340     hInterfaceInstanceKey = NULL;
    04341     IopDeleteKeyRecursive (hInterfaceKey, instanceKeyName.Buffer);
    04342
    04343     //
    04344     // Find out how many subkeys to the interface key remain.
    04345     //
    04346     status = IopGetRegistryKeyInformation(hInterfaceKey,
    04347                                           &keyInformation);
    04348     if (!NT_SUCCESS(status)) {
    04349         goto clean3;
    04350     }
    04351
    04352     remainingSubKeys = keyInformation->SubKeys;
    04353
    04354     ExFreePool(keyInformation);
    04355
    04356     //
    04357     // See if a volatile "Control" subkey exists under this interface key
    04358     //
    04359     PiWstrToUnicodeString(&tempString, REGSTR_KEY_CONTROL);
    04360     status = IopOpenRegistryKeyEx( &hControl,
    04361                                    hInterfaceKey,
    04362                                    &tempString,
    04363                                    KEY_READ
    04364                                    );
    04365     if (NT_SUCCESS(status)) {
    04366         ZwClose(hControl);
    04367         hControl = NULL;
    04368     }
    04369     if ((remainingSubKeys==0) ||
    04370         ((remainingSubKeys==1) && (NT_SUCCESS(status)))) {
    04371         //
    04372         // If the interface key has no subkeys, or the only the remaining subkey
    04373         // is the volatile interface "Control" subkey, then there are no more
    04374         // instances to this interface.  We should delete the interface key
    04375         // itself also.
    04376         //
    04377         ZwClose(hInterfaceKey);
    04378         hInterfaceKey = NULL;
    04379
    04380         IopDeleteKeyRecursive (hInterfaceClassKey, interfaceKeyName.Buffer);
    04381     }
    04382
    04383     status = STATUS_SUCCESS;
    04384
    04385
    04386 clean3:
    04387     if (hControl) {
    04388         ZwClose(hControl);
    04389     }
    04390     if (hInterfaceInstanceKey) {
    04391         ZwClose(hInterfaceInstanceKey);
    04392     }
    04393     if (hInterfaceKey) {
    04394         ZwClose(hInterfaceKey);
    04395     }
    04396     if (hInterfaceClassKey) {
    04397         ZwClose(hInterfaceClassKey);
    04398     }
    04399
    04400 clean2:
    04401     ExReleaseResource(&PpRegistryDeviceResource);
    04402     KeLeaveCriticalRegion();
    04403
    04404     IopFreeAllocatedUnicodeString(&interfaceKeyName);
    04405
    04406 clean1:
    04407     IopFreeAllocatedUnicodeString(&instanceKeyName);
    04408
    04409 clean0:
    04410     return status;
    04411 }

NTSTATUS IopWarmEjectDevice | ( | IN PDEVICE_OBJECT | DeviceToEject,
|  | IN SYSTEM_POWER_STATE | LightestSleepState
| ) |

Definition at line 422 of file pnppower.c.

References ASSERT, Executive, FALSE, IO_NO_INCREMENT, IoDeviceNodeTreeSequence, IopAcquireDeviceTreeLock, IopReleaseDeviceTreeLock, IopWarmEjectLock, IopWarmEjectPdo, KernelMode, KeSetEvent(), KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

Referenced by IopProcessCompletedEject().

    00428                    :
    00429
    00430     This function is invoked to initiate a warm eject. The eject progresses
    00431     from S1 to the passed in lightest sleep state.
    00432
    00433 Arguments:
    00434
    00435     DeviceToEject       - The device to eject
    00436
    00437     LightestSleepState  - The lightest S state (at least S1) that the device
    00438                           may be ejected in. This might be S4 if we are truely
    00439                           low on power.
    00440
    00441 Return Value:
    00442
    00443     NTSTATUS value.
    00444
    00445 --*/
    00446 {
    00447     NTSTATUS       status;
    00448
    00449     PAGED_CODE();
    00450
    00451     //
    00452     // Acquire the warm eject device lock. A warm eject requires we enter a
    00453     // specific S-state, and two different devices may have conflicting options.
    00454     // Therefore only one is allowed to occur at once.
    00455     //
    00456     status = KeWaitForSingleObject(
    00457         &IopWarmEjectLock,
    00458         Executive,
    00459         KernelMode,
    00460         FALSE,
    00461         NULL
    00462         );
    00463
    00464     ASSERT(status == STATUS_SUCCESS) ;
    00465
    00466     //
    00467     // Acquire device node lock. We are not allowed to set or clear this field
    00468     // unless we are under this lock.
    00469     //
    00470     IopAcquireDeviceTreeLock();
    00471
    00472     //
    00473     // Set the current Pdo to eject.
    00474     //
    00475     ASSERT(IopWarmEjectPdo == NULL);
    00476     IopWarmEjectPdo = DeviceToEject;
    00477
    00478     //
    00479     // Release the tree lock.
    00480     //
    00481     IopReleaseDeviceTreeLock();
    00482
    00483     //
    00484     // Attempt to invalidate Po's cached notification list. This should cause
    00485     // IoBuildPoDeviceNotifyList to be called at which time it will in theory
    00486     // pickup the above placed warm eject Pdo.
    00487     //
    00488     // ADRIAO NOTE 01/07/1999 -
    00489     //     Actually, this whole IoDeviceNodeTreeSequence stuff isn't neccessary.
    00490     // PnP will make no changes to the tree while the device tree lock is owned,
    00491     // and it's owned for the duration of a power notification.
    00492     //
    00493     IoDeviceNodeTreeSequence++;
    00494
    00495     //
    00496     // Sleep...
    00497     //
    00498     status = NtInitiatePowerAction(
    00499         PowerActionWarmEject,
    00500         LightestSleepState,
    00501         POWER_ACTION_QUERY_ALLOWED |
    00502         POWER_ACTION_UI_ALLOWED,
    00503         FALSE // Asynchronous == FALSE
    00504         );
    00505
    00506     //
    00507     // Acquire device node lock. We are not allowed to set or clear this field
    00508     // unless we are under this lock.
    00509     //
    00510     IopAcquireDeviceTreeLock();
    00511
    00512     //
    00513     // Clear the current PDO to eject, and see if the Pdo was actually picked
    00514     // up.
    00515     //
    00516     if (IopWarmEjectPdo) {
    00517
    00518         if (NT_SUCCESS(status)) {
    00519
    00520             //
    00521             // If our device wasn't picked up, the return of
    00522             // NtInitiatePowerAction should *not* be successful!
    00523             //
    00524             ASSERT(0);
    00525             status = STATUS_UNSUCCESSFUL;
    00526         }
    00527
    00528         IopWarmEjectPdo = NULL;
    00529     }
    00530
    00531     //
    00532     // Release the tree lock.
    00533     //
    00534     IopReleaseDeviceTreeLock();
    00535
    00536     //
    00537     // Release the warm eject device lock
    00538     //
    00539     KeSetEvent(
    00540         &IopWarmEjectLock,
    00541         IO_NO_INCREMENT,
    00542         FALSE
    00543         );
    00544
    00545     return status;
    00546 }

NTSTATUS IopWriteAllocatedResourcesToRegistry | ( | IN PDEVICE_NODE | DeviceNode,
|  | IN PCM_RESOURCE_LIST | ResourceList,
|  | IN ULONG | Length
| ) |

| Referenced by IopBuildCmResourceLists(), IopLegacyResourceAllocation(), IopReleaseResourcesInternal(), IopRestoreResourcesInternal(), and IoReportDetectedDevice().

NTSTATUS IopWriteResourceList | ( | IN HANDLE | ResourceMapKey,
|  | IN PUNICODE_STRING | ClassName,
|  | IN PUNICODE_STRING | DriverName,
|  | IN PUNICODE_STRING | DeviceName,
|  | IN PCM_RESOURCE_LIST | ResourceList,
|  | IN ULONG | ResourceListSize
| ) |

NTSTATUS IoReportResourceUsageInternal | ( | IN ARBITER_REQUEST_SOURCE | AllocationType,
|  | IN PUNICODE_STRING DriverClassName | OPTIONAL,
|  | IN PDRIVER_OBJECT | DriverObject,
|  | IN PCM_RESOURCE_LIST DriverList | OPTIONAL,
|  | IN ULONG DriverListSize | OPTIONAL,
|  | IN PDEVICE_OBJECT DeviceObject | OPTIONAL,
|  | IN PCM_RESOURCE_LIST DeviceList | OPTIONAL,
|  | IN ULONG DeviceListSize | OPTIONAL,
|  | IN BOOLEAN | OverrideConflict,
|  | OUT PBOOLEAN | ConflictDetected
| ) |

Definition at line 469 of file report.c.

References ASSERT, ExFreePool(), FALSE, IopChangeInterfaceType(), IopCmResourcesToIoResources(), IopLegacyResourceAllocation(), NT_SUCCESS, NTSTATUS(), NULL, and TRUE.

Referenced by IoReportDetectedDevice(), IoReportResourceForDetection(), and IoReportResourceUsage().

    00484                    :
    00485
    00486     This internal routine will do all the work for IoReportResourceUsage.
    00487
    00488 Arguments:
    00489
    00490     AllocationType - Specifies the request type.
    00491
    00492     DriverClassName - Optional pointer to a UNICODE_STRING which describes
    00493         the class of driver under which the driver information should be
    00494         stored. A default type is used if none is given.
    00495
    00496     DriverObject - Pointer to the driver's driver object.
    00497
    00498     DriverList - Optional pointer to the driver's resource list.
    00499
    00500     DriverListSize - Optional value determining the size of the driver's
    00501         resource list.
    00502
    00503     DeviceObject - Optional pointer to driver's device object.
    00504
    00505     DeviceList - Optional pointer to the device's resource list.
    00506
    00507     DriverListSize - Optional value determining the size of the driver's
    00508         resource list.
    00509
    00510     OverrideConflict - Determines if the information should be reported
    00511         in the configuration registry eventhough a conflict was found with
    00512         another driver or device.
    00513
    00514     ConflictDetected - Supplies a pointer to a boolean that is set to TRUE
    00515         if the resource list conflicts with an already existing resource
    00516         list in the configuration registry.
    00517
    00518 Return Value:
    00519
    00520     The status returned is the final completion status of the operation.
    00521
    00522 --*/
    00523
    00524 {
    00525     NTSTATUS                        status = STATUS_UNSUCCESSFUL;
    00526     PCM_RESOURCE_LIST               resourceList;
    00527     PCM_RESOURCE_LIST               allocatedResources;
    00528     PIO_RESOURCE_REQUIREMENTS_LIST  resourceRequirements;
    00529     ULONG                           attempt;
    00530     BOOLEAN                         freeAllocatedResources;
    00531
    00532     ASSERT(DriverObject && ConflictDetected);
    00533
    00534     if (DeviceList) {
    00535
    00536         resourceList = DeviceList;
    00537
    00538     } else if (DriverList) {
    00539
    00540         resourceList = DriverList;
    00541
    00542     } else {
    00543
    00544         resourceList = NULL;
    00545
    00546     }
    00547
    00548     resourceRequirements = NULL;
    00549
    00550     if (resourceList) {
    00551
    00552         if (resourceList->Count && resourceList->List[0].PartialResourceList.Count) {
    00553
    00554             resourceRequirements = IopCmResourcesToIoResources (0, resourceList, LCPRI_NORMAL);
    00555
    00556             if (resourceRequirements == NULL) {
    00557
    00558                 return status;
    00559
    00560             }
    00561
    00562         } else {
    00563
    00564             resourceList = NULL;
    00565
    00566         }
    00567
    00568     }
    00569
    00570     *ConflictDetected = TRUE;
    00571     attempt = 0;
    00572     allocatedResources = resourceList;
    00573     freeAllocatedResources = FALSE;
    00574     do {
    00575
    00576         //
    00577         // Do the legacy resource allocation.
    00578         //
    00579
    00580         status = IopLegacyResourceAllocation (  AllocationType,
    00581                                                 DriverObject,
    00582                                                 DeviceObject,
    00583                                                 resourceRequirements,
    00584                                                 &allocatedResources);
    00585
    00586         if (NT_SUCCESS(status)) {
    00587
    00588             *ConflictDetected = FALSE;
    00589             break;
    00590         }
    00591
    00592         //
    00593         // Change the interface type and try again.
    00594         //
    00595
    00596         if (!IopChangeInterfaceType(resourceRequirements, &allocatedResources)) {
    00597
    00598             break;
    00599         }
    00600         freeAllocatedResources = TRUE;
    00601
    00602     } while (++attempt < 2);
    00603
    00604     if (resourceRequirements) {
    00605
    00606         ExFreePool(resourceRequirements);
    00607
    00608     }
    00609
    00610     if (freeAllocatedResources) {
    00611
    00612         ExFreePool(allocatedResources);
    00613     }
    00614
    00615     if (NT_SUCCESS(status)) {
    00616
    00617         status = STATUS_SUCCESS;
    00618
    00619     } else {
    00620
    00621         status = STATUS_INSUFFICIENT_RESOURCES;
    00622
    00623     }
    00624
    00625     return status;
    00626 }

VOID MapperConstructRootEnumTree | ( | IN BOOLEAN | CreatePhantomDevices | ) |

Definition at line 1600 of file mapper.c.

References _FIRMWARE_CONFIGURATION::BusNumber, _FIRMWARE_CONFIGURATION::BusType, _FIRMWARE_CONFIGURATION::ControllerNumber, _FIRMWARE_CONFIGURATION::ControllerType, DebugPrint, ENUM_KEY_BUFFER_SIZE, ExAllocatePool, ExFreePool(), FALSE, _DEVICE_EXTENSION::FirmwareList, _FIRMWARE_CONFIGURATION::Identifier, INSTANCE_BUFFER_SIZE, L, MapperDeviceExtension, MapperFreeList(), MapperMarkKey(), MapperSeedKey(), _FIRMWARE_CONFIGURATION::NewlyCreated, _FIRMWARE_CONFIGURATION::Next, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, PDEVICE_EXTENSION, _FIRMWARE_CONFIGURATION::PeripheralNumber, _FIRMWARE_CONFIGURATION::PeripheralType, PFIRMWARE_CONFIGURATION, _FIRMWARE_CONFIGURATION::PnPId, _FIRMWARE_CONFIGURATION::ResourceDescriptor, RtlAppendUnicodeToString(), RtlInitUnicodeString(), and TRUE.

Referenced by IopInitializePlugPlayServices().

    01606                    :
    01607
    01608     This routine walks through the list of firmware entries
    01609     in the device extension and migrates the information into
    01610     the root enumerator's tree in the registry.
    01611
    01612 Arguments:
    01613
    01614     CreatePhantomDevices - If non-zero, then the device instances are created
    01615         as "phantoms" (i.e., they are marked with the "Phantom" value entry so
    01616         that the root enumerator will ignore them).  The only time these device
    01617         instance registry keys will ever turn into real live devnodes is if the
    01618         class installer (in response to DIF_FIRSTTIMESETUP or DIF_DETECT)
    01619         decides that these devices aren't duplicates of any PnP-enumerated
    01620         devnodes, and subsequently registers and installs them.
    01621
    01622 Return Value:
    01623
    01624     None
    01625
    01626 --*/
    01627
    01628 {
    01629 #define ENUM_KEY_BUFFER_SIZE (1024 * sizeof(WCHAR))
    01630 #define INSTANCE_BUFFER_SIZE (256 * sizeof(WCHAR))
    01631     UNICODE_STRING          enumKey;
    01632     PFIRMWARE_CONFIGURATION firmwareEntry;
    01633     OBJECT_ATTRIBUTES       objectAttributes;
    01634     NTSTATUS                status;
    01635     BOOLEAN                 keyPresent;
    01636     PWCHAR                  registryBase;
    01637     PWCHAR                  instanceBuffer;
    01638     HANDLE                  handle;
    01639     ULONG                   disposition;
    01640     PVOID                   buffer;
    01641     PDEVICE_EXTENSION       DeviceExtension = &MapperDeviceExtension;
    01642
    01643     //
    01644     // allocate space needed for the registry path into the root
    01645     // enumerator tree.  Note, limited size on path length.
    01646     //
    01647
    01648     buffer = ExAllocatePool(NonPagedPool, ENUM_KEY_BUFFER_SIZE);
    01649
    01650     if (!buffer) {
    01651         MapperFreeList();
    01652         DebugPrint((MAPPER_ERROR,
    01653                     "Mapper: could not allocate memory for registry update\n"));
    01654         return;
    01655     }
    01656
    01657     instanceBuffer = ExAllocatePool(NonPagedPool, INSTANCE_BUFFER_SIZE);
    01658     if (!instanceBuffer) {
    01659         MapperFreeList();
    01660         ExFreePool(buffer);
    01661         DebugPrint((MAPPER_ERROR,
    01662                     "Mapper: could not allocate memory for instance buffer\n"));
    01663         return;
    01664     }
    01665
    01666     InitializeObjectAttributes(&objectAttributes,
    01667                                &enumKey,
    01668                                OBJ_CASE_INSENSITIVE,
    01669                                NULL,
    01670                                NULL);
    01671
    01672 #if UMODETEST
    01673     registryBase = L"\\Registry\\Machine\\System\\TestControlSet\\Enum\\Root\\";
    01674 #else
    01675     registryBase = L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\Root\\";
    01676 #endif
    01677
    01678     firmwareEntry = DeviceExtension->FirmwareList;
    01679     while (firmwareEntry) {
    01680
    01681         //
    01682         // Construct the base for the path for this entry.
    01683         //
    01684
    01685
    01686         RtlInitUnicodeString(&enumKey, NULL);
    01687         enumKey.MaximumLength = ENUM_KEY_BUFFER_SIZE;
    01688         enumKey.Buffer = buffer;
    01689         RtlZeroMemory(buffer, ENUM_KEY_BUFFER_SIZE);
    01690         RtlAppendUnicodeToString(&enumKey, registryBase);
    01691         RtlAppendUnicodeToString(&enumKey, firmwareEntry->PnPId);
    01692
    01693         //
    01694         // Build the pnp Key.
    01695         //
    01696
    01697         status = ZwCreateKey(&handle,
    01698                              KEY_READ | KEY_WRITE,
    01699                              &objectAttributes,
    01700                              0,
    01701                              NULL,
    01702                              REG_OPTION_NON_VOLATILE,
    01703                              &disposition);
    01704
    01705         if (NT_SUCCESS(status)) {
    01706
    01707             //
    01708             // Do not need the handle, so close it
    01709             // Remember if the key was present prior to call
    01710             //
    01711
    01712             ZwClose(handle);
    01713             keyPresent = (disposition == REG_OPENED_EXISTING_KEY) ? TRUE : FALSE;
    01714             DebugPrint((MAPPER_INFORMATION,
    01715                         "Mapper: Key was %s\n",
    01716                         keyPresent ? "Present" : "Created"));
    01717
    01718             //
    01719             // Construct the instance name.
    01720             //
    01721
    01722             RtlZeroMemory(instanceBuffer, INSTANCE_BUFFER_SIZE);
    01723             swprintf(instanceBuffer,
    01724                      L"\\%d_%d_%d_%d_%d_%d",
    01725                      firmwareEntry->BusType,
    01726                      firmwareEntry->BusNumber,
    01727                      firmwareEntry->ControllerType,
    01728                      firmwareEntry->ControllerNumber,
    01729                      firmwareEntry->PeripheralType,
    01730                      firmwareEntry->PeripheralNumber);
    01731             RtlAppendUnicodeToString(&enumKey, instanceBuffer);
    01732
    01733             status = ZwCreateKey(&handle,
    01734                                  KEY_READ | KEY_WRITE,
    01735                                  &objectAttributes,
    01736                                  0,
    01737                                  NULL,
    01738                                  REG_OPTION_NON_VOLATILE,
    01739                                  &disposition);
    01740
    01741             if (NT_SUCCESS(status)) {
    01742
    01743                 if (firmwareEntry->ResourceDescriptor) {
    01744                     DebugPrint((MAPPER_INFORMATION,
    01745                                 "Mapper: firmware entry has resources %x\n",
    01746                                 firmwareEntry->ResourceDescriptor));
    01747                 }
    01748
    01749                 if (firmwareEntry->Identifier) {
    01750                     DebugPrint((MAPPER_INFORMATION,
    01751                                 "Mapper: firmware entry has identifier %x\n",
    01752                                 firmwareEntry->Identifier));
    01753                 }
    01754
    01755                 //
    01756                 // Only if this is a new entry do we see the key.
    01757                 //
    01758
    01759                 if (disposition == REG_CREATED_NEW_KEY) {
    01760
    01761                     //
    01762                     // Remember the fact that the key was newly-created for the
    01763                     // PnP BIOS case where we need to come along and "phantomize"
    01764                     // all newly-created ntdetect COM ports.
    01765                     //
    01766
    01767                     firmwareEntry->NewlyCreated = TRUE;
    01768
    01769                     //
    01770                     // Create enough information to get pnp to
    01771                     // install drivers
    01772                     //
    01773
    01774                     MapperSeedKey(handle,
    01775                                   &enumKey,
    01776                                   firmwareEntry,
    01777                                   CreatePhantomDevices
    01778                                  );
    01779                 }
    01780                 MapperMarkKey(handle,
    01781                               &enumKey,
    01782                               firmwareEntry);
    01783                 ZwClose(handle);
    01784
    01785             } else {
    01786                 DebugPrint((MAPPER_ERROR,
    01787                             "Mapper: create of instance key failed %x\n",
    01788                             status));
    01789             }
    01790
    01791         } else {
    01792             DebugPrint((MAPPER_ERROR,
    01793                         "Mapper: create pnp key failed %x\n",
    01794                         status));
    01795         }
    01796
    01797         firmwareEntry = firmwareEntry->Next;
    01798     }
    01799     ExFreePool(instanceBuffer);
    01800 }

VOID MapperFreeList | ( | VOID |  | ) |

Definition at line 1549 of file mapper.c.

References ExFreePool(), _DEVICE_EXTENSION::FirmwareList, _FIRMWARE_CONFIGURATION::Identifier, MapperDeviceExtension, _FIRMWARE_CONFIGURATION::Next, PDEVICE_EXTENSION, PFIRMWARE_CONFIGURATION, and _FIRMWARE_CONFIGURATION::ResourceDescriptor.

Referenced by IopInitializePlugPlayServices(), and MapperConstructRootEnumTree().

    01555                    :
    01556
    01557     This routine walks through the list of firmware entries
    01558     and frees all allocated memory.
    01559
    01560 Arguments:
    01561
    01562     None
    01563
    01564 Return Value:
    01565
    01566     None
    01567
    01568 --*/
    01569
    01570 {
    01571     PDEVICE_EXTENSION       deviceExtension = &MapperDeviceExtension;
    01572     PFIRMWARE_CONFIGURATION tempEntry;
    01573     PFIRMWARE_CONFIGURATION firmwareEntry;
    01574
    01575     firmwareEntry = deviceExtension->FirmwareList;
    01576     while (firmwareEntry) {
    01577
    01578         //
    01579         // free allocated structures associated with the firmware entry
    01580         //
    01581
    01582         if (firmwareEntry->ResourceDescriptor) {
    01583             ExFreePool(firmwareEntry->ResourceDescriptor);
    01584         }
    01585         if (firmwareEntry->Identifier) {
    01586             ExFreePool(firmwareEntry->Identifier);
    01587         }
    01588
    01589         //
    01590         // free this entry and move to the next
    01591         //
    01592
    01593         tempEntry = firmwareEntry->Next;
    01594         ExFreePool(firmwareEntry);
    01595         firmwareEntry = tempEntry;
    01596     }
    01597 }

VOID MapperPhantomizeDetectedComPorts | ( | VOID |  | ) |

Definition at line 2060 of file mapper.c.

References _FIRMWARE_CONFIGURATION::BusNumber, _FIRMWARE_CONFIGURATION::BusType, _FIRMWARE_CONFIGURATION::ControllerNumber, _FIRMWARE_CONFIGURATION::ControllerType, DebugPrint, ENUM_KEY_BUFFER_SIZE, ExAllocatePool, ExFreePool(), _DEVICE_EXTENSION::FirmwareList, INSTANCE_BUFFER_SIZE, L, MapperDeviceExtension, _FIRMWARE_CONFIGURATION::NewlyCreated, _FIRMWARE_CONFIGURATION::Next, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, PDEVICE_EXTENSION, _FIRMWARE_CONFIGURATION::PeripheralNumber, _FIRMWARE_CONFIGURATION::PeripheralType, PFIRMWARE_CONFIGURATION, _FIRMWARE_CONFIGURATION::PnPId, regValue(), RtlAppendUnicodeToString(), RtlInitUnicodeString(), and SerialController.

Referenced by IopInitializePlugPlayServices().

    02065                    :
    02066
    02067     This routine turns all newly-created firmware/ntdetect COM ports into
    02068     phantoms.
    02069
    02070 Arguments:
    02071
    02072     None
    02073
    02074 Return Value:
    02075
    02076     None
    02077
    02078 --*/
    02079 {
    02080     PFIRMWARE_CONFIGURATION firmwareEntry;
    02081     NTSTATUS                status;
    02082     PWCHAR                  registryBase;
    02083     PWCHAR                  instanceBuffer;
    02084     HANDLE                  handle;
    02085     PWCHAR                  buffer;
    02086     PDEVICE_EXTENSION       DeviceExtension = &MapperDeviceExtension;
    02087     UNICODE_STRING          enumKey;
    02088     OBJECT_ATTRIBUTES       objectAttributes;
    02089     UNICODE_STRING          unicodeName;
    02090     ULONG                   regValue;
    02091
    02092     //
    02093     // allocate space needed for the registry path into the root
    02094     // enumerator tree.  Note, limited size on path length.
    02095     //
    02096
    02097     buffer = ExAllocatePool(NonPagedPool, ENUM_KEY_BUFFER_SIZE);
    02098
    02099     if (!buffer) {
    02100         DebugPrint((MAPPER_ERROR,
    02101                     "Mapper: could not allocate memory for registry update\n"));
    02102         return;
    02103     }
    02104
    02105     instanceBuffer = ExAllocatePool(NonPagedPool, INSTANCE_BUFFER_SIZE);
    02106     if (!instanceBuffer) {
    02107         ExFreePool(buffer);
    02108         DebugPrint((MAPPER_ERROR,
    02109                     "Mapper: could not allocate memory for instance buffer\n"));
    02110         return;
    02111     }
    02112
    02113     InitializeObjectAttributes(&objectAttributes,
    02114                                &enumKey,
    02115                                OBJ_CASE_INSENSITIVE,
    02116                                NULL,
    02117                                NULL);
    02118
    02119 #if UMODETEST
    02120     registryBase = L"\\Registry\\Machine\\System\\TestControlSet\\Enum\\Root\\";
    02121 #else
    02122     registryBase = L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\Root\\";
    02123 #endif
    02124
    02125     firmwareEntry = DeviceExtension->FirmwareList;
    02126     while (firmwareEntry) {
    02127
    02128         //
    02129         // Construct the base for the path for this entry.
    02130         //
    02131
    02132
    02133         if ((firmwareEntry->ControllerType == SerialController) &&
    02134             firmwareEntry->NewlyCreated) {
    02135
    02136             RtlInitUnicodeString(&enumKey, NULL);
    02137             enumKey.MaximumLength = ENUM_KEY_BUFFER_SIZE;
    02138             enumKey.Buffer = buffer;
    02139             RtlZeroMemory(buffer, ENUM_KEY_BUFFER_SIZE);
    02140             RtlAppendUnicodeToString(&enumKey, registryBase);
    02141             RtlAppendUnicodeToString(&enumKey, firmwareEntry->PnPId);
    02142
    02143             //
    02144             // Construct the instance name.
    02145             //
    02146
    02147             RtlZeroMemory(instanceBuffer, INSTANCE_BUFFER_SIZE);
    02148             swprintf(instanceBuffer,
    02149                      L"\\%d_%d_%d_%d_%d_%d",
    02150                      firmwareEntry->BusType,
    02151                      firmwareEntry->BusNumber,
    02152                      firmwareEntry->ControllerType,
    02153                      firmwareEntry->ControllerNumber,
    02154                      firmwareEntry->PeripheralType,
    02155                      firmwareEntry->PeripheralNumber);
    02156             RtlAppendUnicodeToString(&enumKey, instanceBuffer);
    02157
    02158             status = ZwOpenKey(&handle,
    02159                                KEY_READ | KEY_WRITE,
    02160                                &objectAttributes
    02161                               );
    02162
    02163             if (NT_SUCCESS(status)) {
    02164
    02165                 RtlInitUnicodeString(&unicodeName, REGSTR_VAL_PHANTOM);
    02166                 regValue = 1;
    02167                 ZwSetValueKey(handle,
    02168                               &unicodeName,
    02169                               0,
    02170                               REG_DWORD,
    02171                               &regValue,
    02172                               sizeof(regValue)
    02173                              );
    02174
    02175                 ZwClose(handle);
    02176             }
    02177         }
    02178
    02179         firmwareEntry = firmwareEntry->Next;
    02180     }
    02181
    02182     ExFreePool (buffer);
    02183     ExFreePool (instanceBuffer);
    02184 }

VOID MapperProcessFirmwareTree | ( | IN BOOLEAN | OnlyProcessSerialPorts | ) |

Definition at line 1009 of file mapper.c.

References CONFIGURATION_TYPE, CONTROLLER_TYPES_COUNT, DebugPrint, DiskController, FloppyDiskPeripheral, IoQueryDeviceDescription(), KeyboardController, MapperCallback(), MapperDeviceExtension, NULL, ParallelController, PointerController, and SerialController.

Referenced by IopInitializePlugPlayServices().

    01015                    :
    01016
    01017     Query the information in the firmware tree to know what
    01018     system board devices were located.  This will cause a FirmwareList
    01019     to be created on the device extention passed.
    01020
    01021 Arguments:
    01022
    01023     OnlyProcessSerialPorts - if non-zero, then we'll only look at serial ports.
    01024         This is done on ACPI machines where, in general, we don't want to pay
    01025         attention to ntdetect/firmware information (but we have to for serial
    01026         ports so that legacy add-in ISA serial ports and modems are detected
    01027         automatically as in previous versions of NT as well as Win9x).
    01028
    01029 Return Value:
    01030
    01031     None
    01032
    01033 --*/
    01034
    01035 {
    01036     INTERFACE_TYPE     interfaceType;
    01037     ULONG              index;
    01038     CONFIGURATION_TYPE sc;
    01039     CONFIGURATION_TYPE controllerTypes[] = { PointerController,
    01040                                              KeyboardController,
    01041                                              ParallelController,
    01042                                              DiskController,
    01043                                              FloppyDiskPeripheral,
    01044                                              SerialController   // must be last
    01045                                            };
    01046 #define CONTROLLER_TYPES_COUNT (sizeof(controllerTypes) / sizeof(controllerTypes[0]))
    01047
    01048     //
    01049     // Locate all firmware controller information and save its resource usage.
    01050     //
    01051     // BUGBUG (lonnym)--it's pretty inefficient to be going through all
    01052     // interface types, when we really only care about a very small subset of
    01053     // non-PnP buses (e.g., ISA, EISA, maybe Internal).
    01054     //
    01055
    01056     for (interfaceType = 0; interfaceType < MaximumInterfaceType; interfaceType++) {
    01057
    01058         DebugPrint((MAPPER_VERBOSE,
    01059                     "Mapper: searching on interface ===> %d\n",
    01060                     interfaceType));
    01061
    01062         if(OnlyProcessSerialPorts) {
    01063
    01064             //
    01065             // Start out at the last element of the array, so we only process
    01066             // SerialControllers.
    01067             //
    01068
    01069             index = CONTROLLER_TYPES_COUNT - 1;
    01070         } else {
    01071             index = 0;
    01072         }
    01073
    01074         for ( ; index < CONTROLLER_TYPES_COUNT; index++) {
    01075             sc = controllerTypes[index];
    01076
    01077             IoQueryDeviceDescription(&interfaceType,
    01078                                      NULL,
    01079                                      &sc,
    01080                                      NULL,
    01081                                      NULL,
    01082                                      NULL,
    01083                                      MapperCallback,
    01084                                      &MapperDeviceExtension);
    01085         }
    01086     }
    01087 }

NTSTATUS PnPBiosGetBiosInfo | ( | OUT PVOID * | BiosInfo,
|  | OUT ULONG * | BiosInfoLength
| ) |

Definition at line 399 of file pnpmap.c.

References ASSERT, DebugPrint, DEFAULT_STRING_SIZE, ExAllocatePool, ExFreePool(), IopOpenRegistryKeyEx(), L, MULTIFUNCTION_KEY_NAME, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, and RtlInitUnicodeString().

Referenced by PnPBiosMapper().

    00405                    :
    00406
    00407     This function retrieves the PnP BIOS info accumulated by NTDETECT.COM and
    00408     placed in the registry.
    00409
    00410 Arguments:
    00411
    00412     BiosInfo - Set to a dynamically allocated block of information retrieved
    00413         from the PnP BIOS by NTDETECT.  This block should be freed using
    00414         ExFreePool.  The contents of the block are the PnP BIOS
    00415         Installation Check Structure followed by the DevNode Structures reported
    00416         by the BIOS.  The detailed format is documented in the PnP BIOS spec.
    00417
    00418     BiosInfoLength - Length of the block whose address is stored in BiosInfo.
    00419
    00420
    00421 Return Value:
    00422
    00423     STATUS_SUCCESS if no errors, otherwise the appropriate error.
    00424
    00425 --*/
    00426 {
    00427     UNICODE_STRING                  multifunctionKeyName, biosKeyName, valueName;
    00428     HANDLE                          multifunctionKey = NULL, biosKey = NULL;
    00429     PKEY_BASIC_INFORMATION          keyBasicInfo = NULL;
    00430     ULONG                           keyBasicInfoLength;
    00431     PKEY_VALUE_PARTIAL_INFORMATION  valueInfo = NULL;
    00432     ULONG                           valueInfoLength;
    00433     ULONG                           returnedLength;
    00434
    00435     PCM_FULL_RESOURCE_DESCRIPTOR    biosValue;
    00436
    00437     ULONG                           index;
    00438     NTSTATUS                        status = STATUS_UNSUCCESSFUL;
    00439
    00440     //
    00441     // The PnP BIOS info is written to one of the subkeys under
    00442     // MULTIFUNCTION_KEY_NAME.  The appropriate key is determined by
    00443     // enumerating the subkeys and using the first one which has a value named
    00444     // "Identifier" that is "PNP BIOS".
    00445     //
    00446
    00447     RtlInitUnicodeString(&multifunctionKeyName, MULTIFUNCTION_KEY_NAME);
    00448
    00449     status = IopOpenRegistryKeyEx( &multifunctionKey,
    00450                                    NULL,
    00451                                    &multifunctionKeyName,
    00452                                    KEY_READ
    00453                                    );
    00454
    00455     if (!NT_SUCCESS(status)) {
    00456
    00457         DebugPrint( (MAPPER_ERROR,
    00458                     "Could not open %S, status = %8.8X\n",
    00459                     MULTIFUNCTION_KEY_NAME,
    00460                     status) );
    00461
    00462         return STATUS_UNSUCCESSFUL;
    00463     }
    00464
    00465     //
    00466     // Allocate memory for key names returned from ZwEnumerateKey and values
    00467     // returned from ZwQueryValueKey.
    00468     //
    00469     keyBasicInfoLength = sizeof(KEY_BASIC_INFORMATION) + DEFAULT_STRING_SIZE;
    00470     keyBasicInfo = ExAllocatePool(PagedPool, keyBasicInfoLength + sizeof(UNICODE_NULL));
    00471
    00472     if (keyBasicInfo == NULL)  {
    00473
    00474         ZwClose( multifunctionKey );
    00475
    00476         return STATUS_NO_MEMORY;
    00477     }
    00478
    00479     valueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + DEFAULT_STRING_SIZE;
    00480     valueInfo = ExAllocatePool(PagedPool, valueInfoLength);
    00481
    00482     if (valueInfo == NULL)  {
    00483
    00484         ExFreePool( keyBasicInfo );
    00485
    00486         ZwClose( multifunctionKey );
    00487
    00488         return STATUS_NO_MEMORY;
    00489     }
    00490
    00491     //
    00492     // Enumerate each key under HKLM\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter
    00493     // to locate the one representing the PnP BIOS information.
    00494     //
    00495     for (index = 0; ; index++) {
    00496
    00497         status = ZwEnumerateKey( multifunctionKey,   // handle of key to enumerate
    00498                                  index,              // index of subkey to enumerate
    00499                                  KeyBasicInformation,
    00500                                  keyBasicInfo,
    00501                                  keyBasicInfoLength,
    00502                                  &returnedLength);
    00503
    00504         if (!NT_SUCCESS(status)) {
    00505
    00506             if (status != STATUS_NO_MORE_ENTRIES)  {
    00507
    00508                 DebugPrint( (MAPPER_ERROR,
    00509                             "Could not enumerate under key %S, status = %8.8X\n",
    00510                             MULTIFUNCTION_KEY_NAME,
    00511                             status) );
    00512             }
    00513
    00514             break;
    00515         }
    00516
    00517         //
    00518         // We found a subkey, NUL terminate the name and open the subkey.
    00519         //
    00520         keyBasicInfo->Name[ keyBasicInfo->NameLength / 2 ] = L'\0';
    00521
    00522         RtlInitUnicodeString(&biosKeyName, keyBasicInfo->Name);
    00523
    00524         status = IopOpenRegistryKeyEx( &biosKey,
    00525                                        multifunctionKey,
    00526                                        &biosKeyName,
    00527                                        KEY_READ
    00528                                        );
    00529
    00530         if (!NT_SUCCESS(status)) {
    00531
    00532             DebugPrint( (MAPPER_ERROR,
    00533                         "Could not open registry key %S\\%S, status = %8.8X\n",
    00534                         MULTIFUNCTION_KEY_NAME,
    00535                         keyBasicInfo->Name,
    00536                         status) );
    00537             break;
    00538         }
    00539
    00540         //
    00541         // Now we need to check the Identifier value in the subkey to see if
    00542         // it is PNP BIOS.
    00543         //
    00544         RtlInitUnicodeString(&valueName, L"Identifier");
    00545
    00546         status = ZwQueryValueKey( biosKey,
    00547                                   &valueName,
    00548                                   KeyValuePartialInformation,
    00549                                   valueInfo,
    00550                                   valueInfoLength,
    00551                                   &returnedLength);
    00552
    00553
    00554         // lets see if its the PNP BIOS identifier
    00555         if (NT_SUCCESS(status)) {
    00556
    00557             if (wcscmp((PWSTR)valueInfo->Data, L"PNP BIOS") == 0) {
    00558
    00559                 //
    00560                 // We found the PnP BIOS subkey, retrieve the BIOS info which
    00561                 // is stored in the "Configuration Data" value.
    00562                 //
    00563                 // We'll start off with our default value buffer and increase
    00564                 // its size if necessary.
    00565                 //
    00566
    00567                 RtlInitUnicodeString(&valueName, L"Configuration Data");
    00568
    00569                 status = ZwQueryValueKey( biosKey,
    00570                                           &valueName,
    00571                                           KeyValuePartialInformation,
    00572                                           valueInfo,
    00573                                           valueInfoLength,
    00574                                           &returnedLength);
    00575
    00576                 if (!NT_SUCCESS(status)) {
    00577
    00578                     if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_BUFFER_OVERFLOW) {
    00579
    00580                         //
    00581                         // The default buffer was too small, free it and reallocate
    00582                         // it to the required size.
    00583                         //
    00584                         ExFreePool( valueInfo );
    00585
    00586                         valueInfoLength = returnedLength;
    00587                         valueInfo = ExAllocatePool( PagedPool, valueInfoLength );
    00588
    00589                         if (valueInfo != NULL)  {
    00590
    00591                             status = ZwQueryValueKey( biosKey,
    00592                                                       &valueName,
    00593                                                       KeyValuePartialInformation,
    00594                                                       valueInfo,
    00595                                                       valueInfoLength,
    00596                                                       &returnedLength );
    00597                         } else {
    00598
    00599                             status = STATUS_NO_MEMORY;
    00600                         }
    00601                     }
    00602                 }
    00603
    00604                 if (NT_SUCCESS(status)) {
    00605
    00606                     //
    00607                     // We now have the PnP BIOS data but it is buried inside
    00608                     // the resource structures.  Do some consistency checks and
    00609                     // then extract it into its own buffer.
    00610                     //
    00611
    00612                     ASSERT(valueInfo->Type == REG_FULL_RESOURCE_DESCRIPTOR);
    00613
    00614                     biosValue = (PCM_FULL_RESOURCE_DESCRIPTOR)valueInfo->Data;
    00615
    00616                     //
    00617                     // BUGBUG - The WMI folks added another list so we should
    00618                     // search for the PnPBIOS one, but for now the BIOS one is
    00619                     // always first.
    00620                     //
    00621                     //ASSERT(biosValue->PartialResourceList.Count == 1);
    00622
    00623                     *BiosInfoLength = biosValue->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize;
    00624                     *BiosInfo = ExAllocatePool(PagedPool, *BiosInfoLength);
    00625
    00626                     if (*BiosInfo != NULL) {
    00627
    00628                         RtlCopyMemory( *BiosInfo,
    00629                                        &biosValue->PartialResourceList.PartialDescriptors[1],
    00630                                        *BiosInfoLength );
    00631
    00632                         status = STATUS_SUCCESS;
    00633
    00634                     } else {
    00635
    00636                         *BiosInfoLength = 0;
    00637
    00638                         status = STATUS_NO_MEMORY;
    00639                     }
    00640
    00641                 } else {
    00642
    00643                     DebugPrint( (MAPPER_ERROR,
    00644                                 "Error retrieving %S\\%S\\Configuration Data, status = %8.8X\n",
    00645                                 MULTIFUNCTION_KEY_NAME,
    00646                                 keyBasicInfo->Name,
    00647                                 status) );
    00648                 }
    00649
    00650                 //
    00651                 // We found the PnP BIOS entry, so close the key handle and
    00652                 // return.
    00653                 //
    00654
    00655                 ZwClose(biosKey);
    00656
    00657                 break;
    00658             }
    00659         }
    00660
    00661         //
    00662         // That wasn't it so close this handle and try the next subkey.
    00663         //
    00664         ZwClose(biosKey);
    00665     }
    00666
    00667     //
    00668     // Cleanup the dynamically allocated temporary buffers.
    00669     //
    00670
    00671     if (valueInfo != NULL) {
    00672
    00673         ExFreePool(valueInfo);
    00674     }
    00675
    00676     if (keyBasicInfo != NULL) {
    00677
    00678         ExFreePool(keyBasicInfo);
    00679     }
    00680
    00681     ZwClose(multifunctionKey);
    00682
    00683     return status;
    00684 }

## Variable Documentation

ULONG IoDeviceNodeTreeSequence

| Definition at line 2366 of file pnpiop.h. Referenced by IoBuildPoDeviceNotifyList(), IopInsertTreeDeviceNode(), and IopWarmEjectDevice().

BOOLEAN IopBootConfigsReserved

| Definition at line 1047 of file pnpiop.h. Referenced by IopAllocateResources(), IopEnumerateDevice(), and IopInitializeBootDrivers().

PBUS_TYPE_GUID_LIST IopBusTypeGuidList

| Definition at line 2432 of file pnpiop.h. Referenced by IoGetDeviceProperty(), IopGetBusTypeGuidIndex(), and IopInitializePlugPlayServices().

LIST_ENTRY IopDeviceClassNotifyList[]

| Definition at line 2373 of file pnpiop.h. Referenced by IopInitializePlugPlayNotification(), IopNotifyDeviceClassChange(), and IoRegisterPlugPlayNotification().

FAST_MUTEX IopDeviceClassNotifyLock

| Definition at line 2372 of file pnpiop.h. Referenced by IopInitializePlugPlayNotification(), IopNotifyDeviceClassChange(), and IoRegisterPlugPlayNotification().

ERESOURCE IopDeviceTreeLock

| Definition at line 999 of file pnpiop.h. Referenced by IopDeviceActionWorker(), IopInitializePlugPlayServices(), IopProcessAssignResources(), IopProcessStartDevices(), IopProcessStartDevicesWorker(), and IopReallocateResources().

ULONG IopDockDeviceCount

| Definition at line 2536 of file pnpiop.h. Referenced by IopHardwareProfileCommitRemovedDock(), IopHardwareProfileMarkDock(), IopInitializePlugPlayServices(), and IopUpdateHardwareProfile().

LIST_ENTRY IopDockDeviceListHead

| Definition at line 2534 of file pnpiop.h. Referenced by IopHardwareProfileCancelTransition(), IopHardwareProfileMarkDock(), IopHardwareProfileQueryChange(), IopHardwareProfileSetMarkedDocksEjected(), IopInitializePlugPlayServices(), and IopUpdateHardwareProfile().

FAST_MUTEX IopDockDeviceListLock

| Definition at line 2535 of file pnpiop.h. Referenced by IopHardwareProfileCancelRemovedDock(), IopHardwareProfileCancelTransition(), IopHardwareProfileCommitRemovedDock(), IopHardwareProfileMarkDock(), IopHardwareProfileQueryChange(), IopHardwareProfileSetMarkedDocksEjected(), IopInitializePlugPlayServices(), and IopUpdateHardwareProfile().

LONG IopDocksInTransition

| Definition at line 2538 of file pnpiop.h. Referenced by IopHardwareProfileBeginTransition(), IopHardwareProfileCancelRemovedDock(), IopHardwareProfileCancelTransition(), IopHardwareProfileCommitRemovedDock(), IopHardwareProfileCommitStartedDock(), IopHardwareProfileMarkDock(), and IopHardwareProfileQueryChange().

LONG IopEnumerationCount

| Definition at line 1017 of file pnpiop.h.

FAST_MUTEX IopHwProfileNotifyLock

| Definition at line 2377 of file pnpiop.h. Referenced by IopInitializePlugPlayNotification(), IopNotifyHwProfileChange(), and IoRegisterPlugPlayNotification().

PDEVICE_NODE IopInitHalDeviceNode

| Definition at line 955 of file pnpiop.h. Referenced by IoInitSystem(), and IopReserveLegacyBootResources().

PCM_RESOURCE_LIST IopInitHalResources

| Definition at line 954 of file pnpiop.h. Referenced by IopInitializeBootDrivers(), IopReserveLegacyBootResources(), and IoReportHalResourceUsage().

PIOP_RESERVED_RESOURCES_RECORD IopInitReservedResourceList

| Definition at line 956 of file pnpiop.h. Referenced by IopInitializeBootDrivers(), IopInitializePlugPlayServices(), IopReserveBootResources(), and IopReserveLegacyBootResources().

ULONG IopMaxDeviceNodeLevel

| Definition at line 2365 of file pnpiop.h. Referenced by IopAllocateRelationList(), and IopInsertTreeDeviceNode().

ULONG IopNumberDeviceNodes

| Definition at line 1023 of file pnpiop.h. Referenced by IopAddRelationToList(), IopAllocateDeviceNode(), IopDestroyDeviceNode(), IopFindLegacyDeviceNode(), IopInitializeDeviceInstanceKey(), IopProcessAssignResources(), IopRebalance(), and IoReportDetectedDevice().

LIST_ENTRY IopPendingEjects

| Definition at line 1078 of file pnpiop.h. Referenced by IopInitializePlugPlayServices(), IopProcessRelation(), and IopQueuePendingEject().

LIST_ENTRY IopPendingSurpriseRemovals

| Definition at line 1083 of file pnpiop.h. Referenced by IopChainDereferenceComplete(), IopInitializePlugPlayServices(), and IopQueuePendingSurpriseRemoval().

LIST_ENTRY IopPnpDeleteRequestList

| Definition at line 984 of file pnpiop.h.

PDRIVER_OBJECT IopPnPDriverObject

| Definition at line 972 of file pnpiop.h.

LIST_ENTRY IopPnpEnumerationRequestList

| Definition at line 990 of file pnpiop.h. Referenced by IopDeviceActionWorker(), IopInitializePlugPlayServices(), and IopRequestDeviceAction().

PVOID IopPnpScratchBuffer1

| Definition at line 952 of file pnpiop.h. Referenced by IopDetermineDefaultInterfaceType(), and IopInitializePlugPlayServices().

PVOID IopPnpScratchBuffer2

| Definition at line 953 of file pnpiop.h. Referenced by IopInitializePlugPlayServices().

KSPIN_LOCK IopPnPSpinLock

| Definition at line 978 of file pnpiop.h. Referenced by IoInvalidateDeviceRelations(), IopDeviceActionWorker(), IopDeviceRelationsComplete(), IopDeviceStartComplete(), IopInitializePlugPlayServices(), IopQueryDeviceRelations(), IopRequestDeviceAction(), IopStartDevice(), and IopWaitForBootDevicesStarted().

KSEMAPHORE IopProfileChangeSemaphore

| Definition at line 2537 of file pnpiop.h. Referenced by IoInitSystem(), IopHardwareProfileBeginTransition(), IopHardwareProfileCancelRemovedDock(), IopHardwareProfileCancelTransition(), IopHardwareProfileCommitRemovedDock(), IopHardwareProfileCommitStartedDock(), IopHardwareProfileMarkDock(), IopHardwareProfileQueryChange(), IopHardwareProfileSendCancel(), IopHardwareProfileSendCommit(), and IopHardwareProfileSetMarkedDocksEjected().

LIST_ENTRY IopProfileNotifyList

| Definition at line 2376 of file pnpiop.h. Referenced by IopInitializePlugPlayNotification(), IopNotifyHwProfileChange(), and IoRegisterPlugPlayNotification().

PIO_RESERVE_RESOURCES_ROUTINE IopReserveResourcesRoutine

| Definition at line 1903 of file pnpiop.h. Referenced by IopInitializeBootDrivers(), and IopInitializePlugPlayServices().

BOOLEAN IopResourcesReleased

| Definition at line 1055 of file pnpiop.h. Referenced by IopDeviceActionWorker(), IopInitializeBootDrivers(), and IopReleaseDeviceResources().

ARBITER_INSTANCE IopRootBusNumberArbiter

| Definition at line 2471 of file pnpiop.h. Referenced by IopBusNumberInitialize(), and IopPnPDispatch().

PDEVICE_NODE IopRootDeviceNode

| Definition at line 966 of file pnpiop.h. Referenced by IoBuildPoDeviceNotifyList(), IoGetLegacyVetoList(), IoInitSystem(), IoNotifyPowerOperationVetoed(), IopAssignInner(), IopChildToRootTranslation(), IopDeviceActionWorker(), IopDeviceObjectFromDeviceInstance(), IopDuplicateDetection(), IopFindBusDeviceNode(), IopForAllDeviceNodes(), IopInitializeBootDrivers(), IopInitializeDeviceInstanceKey(), IopInitializePlugPlayServices(), IopInitializeSystemDrivers(), IopInsertTreeDeviceNode(), IopLegacyResourceAllocation(), IopLockDeviceRemovalRelations(), IopPlacement(), IopPnPDispatch(), IopProcessAddDevices(), IopProcessNewDeviceNode(), IopQueryConflictFillString(), IopQueryConflictListInternal(), IopRebalance(), IopReleaseResourcesInternal(), IopReserve(), IopSetupArbiterAndTranslators(), IopWaitForBootDevicesStarted(), and IoReportDetectedDevice().

ARBITER_INSTANCE IopRootDmaArbiter

| Definition at line 2470 of file pnpiop.h. Referenced by IopDmaInitialize(), and IopPnPDispatch().

ARBITER_INSTANCE IopRootIrqArbiter

| Definition at line 2469 of file pnpiop.h. Referenced by IopIrqInitialize(), and IopPnPDispatch().

ARBITER_INSTANCE IopRootMemArbiter

| Definition at line 2468 of file pnpiop.h. Referenced by IopMemInitialize(), and IopPnPDispatch().

ARBITER_INSTANCE IopRootPortArbiter

| Definition at line 2467 of file pnpiop.h. Referenced by IopPnPDispatch(), and IopPortInitialize().

PSETUP_NOTIFY_DATA IopSetupNotifyData

| Definition at line 2374 of file pnpiop.h. Referenced by IopNotifySetupDeviceArrival(), and IoRegisterPlugPlayNotification().

FAST_MUTEX IopTargetDeviceNotifyLock

| Definition at line 2375 of file pnpiop.h. Referenced by IopInitializePlugPlayNotification(), IopNotifyTargetDeviceChange(), IopOrphanNotification(), and IoRegisterPlugPlayNotification().

KEVENT IopWarmEjectLock

| Definition at line 2597 of file pnpiop.h. Referenced by IopInitializePlugPlayServices(), and IopWarmEjectDevice().

PDEVICE_OBJECT IopWarmEjectPdo

| Definition at line 2598 of file pnpiop.h. Referenced by IoBuildPoDeviceNotifyList(), IopInitializePlugPlayServices(), and IopWarmEjectDevice().

KEVENT PiEnumerationLock

| Definition at line 1011 of file pnpiop.h. Referenced by IopDeviceActionWorker(), IopInitializePlugPlayServices(), IopRequestDeviceAction(), and IopWaitForBootDevicesStarted().

KEVENT PiEventQueueEmpty

| Definition at line 1005 of file pnpiop.h. Referenced by IopInitializePlugPlayServices(), and IopWaitForBootDevicesDeleted().

BOOLEAN PnpAsyncOk

| Definition at line 1073 of file pnpiop.h. Referenced by IopDeviceActionWorker(), IopInitializeBootDrivers(), IopStartAndEnumerateDevice(), IopStartDevice(), and IopWaitForBootDevicesStarted().

BOOLEAN PnPBootDriversInitialized

| Definition at line 1035 of file pnpiop.h. Referenced by IopCallDriverAddDeviceQueryRoutine(), IopDeviceActionWorker(), and IopInitializeBootDrivers().

BOOLEAN PnPBootDriversLoaded

| Definition at line 1041 of file pnpiop.h. Referenced by IopInitializeBootDrivers(), and IopRequestDeviceAction().

INTERFACE_TYPE PnpDefaultInterfaceType

| Definition at line 1067 of file pnpiop.h. Referenced by IoGetDmaAdapter(), IopChangeInterfaceType(), IopCmResourcesToIoResources(), IopGetDeviceResourcesFromRegistry(), IopInitializePlugPlayServices(), IopLegacyResourceAllocation(), IopPnPDispatch(), IopQueryConflictListInternal(), IopReadDeviceConfiguration(), IopReleaseResourcesInternal(), and IopResourceRequirementsListToReqList().

BOOLEAN PnPDetectionEnabled

| Definition at line 1061 of file pnpiop.h. Referenced by IopInitializePlugPlayServices(), and IopPrepareDriverLoading().

BOOLEAN PnPInitialized

| Definition at line 1029 of file pnpiop.h. Referenced by IoGetLegacyVetoList(), IopCallDriverAddDeviceQueryRoutine(), IopInitializePlugPlayServices(), IopInitializeSystemDrivers(), IopLoadDriver(), IopStartDriverDevices(), and IoSynchronousInvalidateDeviceRelations().