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_STATEPPENDING_SET_INTERFACE_STATE
typedef enum _UNLOCK_UNLINK_ACTION UNLOCK_UNLINK_ACTION
typedef enum _UNLOCK_UNLINK_ACTIONPUNLOCK_UNLINK_ACTION
typedef _DEVICE_NODEPDEVICE_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_ITEMPNEW_DEVICE_WORK_ITEM
typedef BOOLEAN(* PIOP_SUBKEY_CALLBACK_ROUTINE )(IN HANDLE, IN PUNICODE_STRING, IN OUT PVOID)
typedef _ADD_CONTEXT ADD_CONTEXT
typedef _ADD_CONTEXTPADD_CONTEXT
typedef _START_CONTEXT START_CONTEXT
typedef _START_CONTEXTPSTART_CONTEXT
typedef enum _RESOURCE_HANDLER_TYPE RESOURCE_HANDLER_TYPE
typedef _PI_RESOURCE_ARBITER_ENTRY PI_RESOURCE_ARBITER_ENTRY
typedef _PI_RESOURCE_ARBITER_ENTRYPPI_RESOURCE_ARBITER_ENTRY
typedef _PI_RESOURCE_TRANSLATOR_ENTRY PI_RESOURCE_TRANSLATOR_ENTRY
typedef _PI_RESOURCE_TRANSLATOR_ENTRYPPI_RESOURCE_TRANSLATOR_ENTRY
typedef _IOP_RESOURCE_REQUEST IOP_RESOURCE_REQUEST
typedef _IOP_RESOURCE_REQUESTPIOP_RESOURCE_REQUEST
typedef enum _DEVICE_REQUEST_TYPE DEVICE_REQUEST_TYPE
typedef _PI_DEVICE_REQUEST PI_DEVICE_REQUEST
typedef _PI_DEVICE_REQUESTPPI_DEVICE_REQUEST
typedef _IOPNP_DEVICE_EXTENSION IOPNP_DEVICE_EXTENSION
typedef _IOPNP_DEVICE_EXTENSIONPIOPNP_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_HEADERPNOTIFY_ENTRY_HEADER
typedef _TARGET_DEVICE_NOTIFY_ENTRY TARGET_DEVICE_NOTIFY_ENTRY
typedef _TARGET_DEVICE_NOTIFY_ENTRYPTARGET_DEVICE_NOTIFY_ENTRY
typedef _DEVICE_CLASS_NOTIFY_ENTRY DEVICE_CLASS_NOTIFY_ENTRY
typedef _DEVICE_CLASS_NOTIFY_ENTRYPDEVICE_CLASS_NOTIFY_ENTRY
typedef _SETUP_NOTIFY_DATA SETUP_NOTIFY_DATA
typedef _SETUP_NOTIFY_DATAPSETUP_NOTIFY_DATA
typedef _HWPROFILE_NOTIFY_ENTRY HWPROFILE_NOTIFY_ENTRY
typedef _HWPROFILE_NOTIFY_ENTRYPHWPROFILE_NOTIFY_ENTRY
typedef _BUFFER_INFO BUFFER_INFO
typedef _BUFFER_INFOPBUFFER_INFO
typedef _BUS_TYPE_GUID_LIST BUS_TYPE_GUID_LIST
typedef _BUS_TYPE_GUID_LISTPBUS_TYPE_GUID_LIST
typedef enum _HARDWARE_PROFILE_BUS_TYPE HARDWARE_PROFILE_BUS_TYPE
typedef enum _HARDWARE_PROFILE_BUS_TYPEPHARDWARE_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  ) 
 

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:

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:

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,
 ) 
 

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  )     ((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.

enum _HARDWARE_PROFILE_BUS_TYPE
 

Enumeration values:
HardwareProfileBusTypeACPI 

Definition at line 2530 of file pnpiop.h.

enum _RESOURCE_HANDLER_TYPE
 

Enumeration values:
ResourceHandlerNull 
ResourceTranslator 
ResourceArbiter 
ResourceLegacyDeviceDetection 

Definition at line 691 of file pnpiop.h.

enum _UNLOCK_UNLINK_ACTION
 

Enumeration values:
UnlinkRemovedDeviceNodes 
UnlinkAllDeviceNodesPendingClose 
UnlinkOnlyChildDeviceNodesPendingClose 

Definition at line 80 of file pnpiop.h.

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.

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().


Generated on Sat May 15 19:45:13 2004 for test by doxygen 1.3.7