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

pnpioapi.c File Reference

#include "iop.h"
#include <stddef.h>
#include <wdmguid.h>
#include <pnpmgr.h>
#include <pnpsetup.h>
#include "..\pnp\pnpi.h"

Go to the source code of this file.

Classes

struct  _DEVICE_WORK_ITEM
struct  _ASYNC_TDC_WORK_ITEM
struct  _NOTIFICATION_CALLBACK_PARAM_BLOCK
struct  _DEFERRED_REGISTRATION_ENTRY
struct  IO_GET_LEGACY_VETO_LIST_CONTEXT

Defines

#define PNP_DEVICE_EVENT_ENTRY_TAG   'EEpP'
#define PATH_CURRENTCONTROLSET_HW_PROFILE_CURRENT   TEXT("\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet")
#define PATH_CURRENTCONTROLSET   TEXT("\\Registry\\Machine\\System\\CurrentControlSet")
#define PATH_ENUM   TEXT("Enum\\")
#define PATH_CONTROL_CLASS   TEXT("Control\\Class\\")
#define MAX_RESTPATH_BUF_LEN   512
#define INITIAL_INFO_BUFFER_SIZE   512
#define INFO_BUFFER_GROW_SIZE   64
#define INITIAL_SYMLINK_BUFFER_SIZE   1024
#define SYMLINK_BUFFER_GROW_SIZE   128
#define INITIAL_RETURN_BUFFER_SIZE   4096
#define RETURN_BUFFER_GROW_SIZE   512
#define INITIAL_DEVNODE_NAME_BUFFER_SIZE   (FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + (200 * sizeof(WCHAR)))
#define KEY_STRING_PREFIX   TEXT("##?#")
#define KEY_STRING_PREFIX_SIZE   ( sizeof(KEY_STRING_PREFIX) - sizeof(UNICODE_NULL) )
#define KEY_STRING_PREFIX_LENGTH   ( KEY_STRING_PREFIX_SIZE / sizeof(WCHAR) )
#define SEPERATOR_STRING   TEXT("\\")
#define SEPERATOR_CHAR   (L'\\')
#define ALT_SEPERATOR_CHAR   (L'/')
#define REPLACED_SEPERATOR_STRING   TEXT("#")
#define REPLACED_SEPERATOR_CHAR   (L'#')
#define USER_SYMLINK_STRING_PREFIX   TEXT("\\\\?\\")
#define USER_SYMLINK_STRING_PREFIX_LENGTH   (( sizeof(USER_SYMLINK_STRING_PREFIX) - sizeof(UNICODE_NULL) ) / sizeof(WCHAR) )
#define KERNEL_SYMLINK_STRING_PREFIX   TEXT("\\??\\")
#define KERNEL_SYMLINK_STRING_PREFIX_LENGTH   (( sizeof(KERNEL_SYMLINK_STRING_PREFIX) - sizeof(UNICODE_NULL) ) / sizeof(WCHAR) )
#define REFSTRING_PREFIX_CHAR   (L'#')
#define LEGACY_COMPATIBLE_ID_BASE   TEXT("DETECTED")
#define GUID_STRING_LENGTH   38
#define GUID_STRING_SIZE   GUID_STRING_LENGTH * sizeof(WCHAR)
#define DBG_GET_ASSOC   0
#define MAX_VETO_NAME_LENGTH   512

Typedefs

typedef _DEVICE_WORK_ITEM DEVICE_WORK_ITEM
typedef _DEVICE_WORK_ITEMPDEVICE_WORK_ITEM
typedef _ASYNC_TDC_WORK_ITEM ASYNC_TDC_WORK_ITEM
typedef _ASYNC_TDC_WORK_ITEMPASYNC_TDC_WORK_ITEM
typedef _NOTIFICATION_CALLBACK_PARAM_BLOCK NOTIFICATION_CALLBACK_PARAM_BLOCK
typedef _NOTIFICATION_CALLBACK_PARAM_BLOCKPNOTIFICATION_CALLBACK_PARAM_BLOCK
typedef _DEFERRED_REGISTRATION_ENTRY DEFERRED_REGISTRATION_ENTRY
typedef _DEFERRED_REGISTRATION_ENTRYPDEFERRED_REGISTRATION_ENTRY
typedef * PIO_GET_LEGACY_VETO_LIST_CONTEXT

Functions

NTSTATUS IopQueueDeviceWorkItem (IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID WorkerRoutine, IN PVOID Context)
VOID IopInvalidateDeviceStateWorker (PVOID Context)
VOID IopReportTargetDeviceChangeAsyncWorker (PVOID Context)
VOID IopRequestDeviceEjectWorker (PVOID Context)
BOOLEAN IopIsReportedAlready (IN HANDLE Handle, IN PUNICODE_STRING ServiceName, IN PCM_RESOURCE_LIST ResourceList)
NTSTATUS IopSetupDeviceObjectFromDeviceClass (IN PDEVICE_OBJECT Pdo, IN HANDLE InterfaceClassKey)
NTSTATUS IopSetSecurityObjectFromRegistry (IN PVOID Object, IN HANDLE Key)
NTSTATUS IopPnPHydraCallback (PVOID CallbackParams)
NTSTATUS PiNotifyUserMode (PPNP_DEVICE_EVENT_ENTRY DeviceEvent)
NTSTATUS IopAppendBuffer (IN PBUFFER_INFO Info, IN PVOID Data, IN ULONG DataSize)
NTSTATUS IopOverwriteBuffer (IN PBUFFER_INFO Info, IN PVOID Data, IN ULONG DataSize)
NTSTATUS IopRealloc (IN OUT PVOID *Buffer, IN ULONG OldSize, IN ULONG NewSize)
NTSTATUS IopDeviceInterfaceKeysFromSymbolicLink (IN PUNICODE_STRING SymbolicLinkName, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DeviceInterfaceClassKey OPTIONAL, OUT PHANDLE DeviceInterfaceKey OPTIONAL, OUT PHANDLE DeviceInterfaceInstanceKey OPTIONAL)
NTSTATUS IopBuildSymbolicLinkStrings (IN PUNICODE_STRING DeviceString, IN PUNICODE_STRING GuidString, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING UserString, OUT PUNICODE_STRING KernelString)
NTSTATUS IopReplaceSeperatorWithPound (OUT PUNICODE_STRING OutString, IN PUNICODE_STRING InString)
NTSTATUS IopDropReferenceString (OUT PUNICODE_STRING OutString, IN PUNICODE_STRING InString)
NTSTATUS IopParseSymbolicLinkName (IN PUNICODE_STRING SymbolicLinkName, OUT PUNICODE_STRING PrefixString OPTIONAL, OUT PUNICODE_STRING MungedPathString OPTIONAL, OUT PUNICODE_STRING GuidString OPTIONAL, OUT PUNICODE_STRING RefString OPTIONAL, OUT PBOOLEAN RefStringPresent OPTIONAL, OUT LPGUID Guid OPTIONAL)
NTSTATUS IopSetRegistryStringValue (IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN PUNICODE_STRING ValueData)
VOID IopInitializePlugPlayNotification (VOID)
VOID IopReferenceNotify (PNOTIFY_ENTRY_HEADER notify)
VOID IopDereferenceNotify (PNOTIFY_ENTRY_HEADER Notify)
NTSTATUS IopRegisterTargetDeviceNotification (IN ULONG Flags, IN PFILE_OBJECT FileObject, IN PDRIVER_OBJECT DriverObject, IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine, IN PVOID Context, IN BOOLEAN AddLast, OUT PVOID *NotificationEntry)
NTSTATUS IopOpenOrCreateDeviceInterfaceSubKeys (OUT PHANDLE InterfaceKeyHandle OPTIONAL, OUT PULONG InterfaceKeyDisposition OPTIONAL, OUT PHANDLE InterfaceInstanceKeyHandle OPTIONAL, OUT PULONG InterfaceInstanceDisposition OPTIONAL, IN HANDLE InterfaceClassKeyHandle, IN PUNICODE_STRING DeviceInterfaceName, IN ACCESS_MASK DesiredAccess, IN BOOLEAN Create)
NTSTATUS PpCreateLegacyDeviceIds (IN PDEVICE_OBJECT DeviceObject, IN PUNICODE_STRING DriverName, IN PCM_RESOURCE_LIST Resources)
NTSTATUS IoGetDeviceProperty (IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength)
NTSTATUS IoOpenDeviceRegistryKey (IN PDEVICE_OBJECT PhysicalDeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
NTSTATUS IoCreateDriver (IN PUNICODE_STRING DriverName OPTIONAL, IN PDRIVER_INITIALIZE InitializationFunction)
VOID IoDeleteDriver (IN PDRIVER_OBJECT DriverObject)
NTSTATUS IoSynchronousInvalidateDeviceRelations (PDEVICE_OBJECT DeviceObject, DEVICE_RELATION_TYPE Type)
VOID IoInvalidateDeviceRelations (PDEVICE_OBJECT DeviceObject, DEVICE_RELATION_TYPE Type)
VOID IoRequestDeviceEject (PDEVICE_OBJECT DeviceObject)
NTSTATUS IoReportDetectedDevice (IN PDRIVER_OBJECT DriverObject, IN INTERFACE_TYPE LegacyBusType, IN ULONG BusNumber, IN ULONG SlotNumber, IN PCM_RESOURCE_LIST ResourceList, IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements OPTIONAL, IN BOOLEAN ResourceAssigned, IN OUT PDEVICE_OBJECT *DeviceObject)
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 IopGetDeviceInterfaces (IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING DevicePath OPTIONAL, IN ULONG Flags, IN BOOLEAN UserModeFormat, OUT PWSTR *SymbolicLinkList, OUT PULONG SymbolicLinkListSize OPTIONAL)
NTSTATUS IoGetDeviceInterfaces (IN CONST GUID *InterfaceClassGuid, IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, IN ULONG Flags, OUT PWSTR *SymbolicLinkList)
NTSTATUS IoSetDeviceInterfaceState (IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
NTSTATUS IoOpenDeviceInterfaceRegistryKey (IN PUNICODE_STRING SymbolicLinkName, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DeviceInterfaceKey)
NTSTATUS IoRegisterDeviceInterface (IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT 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 IoGetDeviceInterfaceAlias (IN PUNICODE_STRING SymbolicLinkName, IN CONST GUID *AliasInterfaceClassGuid, OUT PUNICODE_STRING AliasSymbolicLinkName)
NTSTATUS IopAllocateUnicodeString (IN OUT PUNICODE_STRING String, IN USHORT Length)
VOID IopFreeAllocatedUnicodeString (PUNICODE_STRING String)
NTSTATUS IoUnregisterPlugPlayNotification (IN PVOID NotificationEntry)
VOID IopProcessDeferredRegistrations (VOID)
NTSTATUS IoReportTargetDeviceChange (IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure)
NTSTATUS IoReportTargetDeviceChangeAsynchronous (IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, IN PVOID Context OPTIONAL)
VOID IoInvalidateDeviceState (IN PDEVICE_OBJECT PhysicalDeviceObject)
VOID IopResourceRequirementsChanged (IN PDEVICE_OBJECT PhysicalDeviceObject, IN BOOLEAN StopRequired)
NTSTATUS IopRequestHwProfileChangeNotification (IN LPGUID EventGuid, IN PROFILE_NOTIFICATION_TIME NotificationTime, OUT PPNP_VETO_TYPE VetoType OPTIONAL, OUT PUNICODE_STRING VetoName OPTIONAL)
NTSTATUS IopNotifyHwProfileChange (IN LPGUID EventGuid, OUT PPNP_VETO_TYPE VetoType OPTIONAL, OUT PUNICODE_STRING VetoName OPTIONAL)
NTSTATUS IopNotifyTargetDeviceChange (LPCGUID EventGuid, PDEVICE_OBJECT DeviceObject, PVOID NotificationStructure, PDRIVER_OBJECT *VetoingDriver)
NTSTATUS IopNotifyDeviceClassChange (LPGUID EventGuid, LPGUID ClassGuid, PUNICODE_STRING SymbolicLinkName)
NTSTATUS IoRegisterPlugPlayNotification (IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory, IN ULONG EventCategoryFlags, IN PVOID EventCategoryData OPTIONAL, IN PDRIVER_OBJECT DriverObject, IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine, IN PVOID Context, OUT PVOID *NotificationEntry)
NTSTATUS IopGetRelatedTargetDevice (IN PFILE_OBJECT FileObject, OUT PDEVICE_NODE *DeviceNode)
NTSTATUS IoGetRelatedTargetDevice (IN PFILE_OBJECT FileObject, OUT PDEVICE_OBJECT *DeviceObject)
NTSTATUS IopNotifySetupDeviceArrival (PDEVICE_OBJECT PhysicalDeviceObject, HANDLE EnumEntryKey, BOOLEAN InstallDriver)
BOOLEAN IoIsWdmVersionAvailable (IN UCHAR MajorVersion, IN UCHAR MinorVersion)
NTKERNELAPI PDMA_ADAPTER IoGetDmaAdapter (IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, IN PDEVICE_DESCRIPTION DeviceDescription, IN OUT PULONG NumberOfMapRegisters)
NTSTATUS IopOpenDeviceParametersSubkey (OUT HANDLE *ParamKeyHandle, IN HANDLE ParentKeyHandle, IN PUNICODE_STRING SubKeyString, IN ACCESS_MASK DesiredAccess)
NTSTATUS IoNotifyPowerOperationVetoed (IN POWER_ACTION VetoedPowerOperation, IN PDEVICE_OBJECT TargetedDeviceObject OPTIONAL, IN PDEVICE_OBJECT VetoingDeviceObject)
ULONG IoPnPDeliverServicePowerNotification (ULONG PwrNotification, BOOLEAN Synchronous)
VOID IopOrphanNotification (IN PDEVICE_NODE TargetNode)
BOOLEAN IopAppendLegacyVeto (IN PIO_GET_LEGACY_VETO_LIST_CONTEXT Context, IN PUNICODE_STRING VetoName)
BOOLEAN IopGetLegacyVetoListDevice (IN PDEVICE_NODE DeviceNode, IN PIO_GET_LEGACY_VETO_LIST_CONTEXT Context)
BOOLEAN IopGetLegacyVetoListDeviceNode (IN PDEVICE_NODE DeviceNode, IN PIO_GET_LEGACY_VETO_LIST_CONTEXT Context)
VOID IopGetLegacyVetoListDrivers (IN PIO_GET_LEGACY_VETO_LIST_CONTEXT Context)
NTSTATUS IoGetLegacyVetoList (OUT PWSTR *VetoList OPTIONAL, OUT PPNP_VETO_TYPE VetoType)
NTSTATUS IopDoDeferredSetInterfaceState (IN PDEVICE_NODE DeviceNode)
NTSTATUS IopProcessSetInterfaceState (IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable, IN BOOLEAN DeferNotStarted)

Variables

LIST_ENTRY IopDeviceClassNotifyList [NOTIFY_DEVICE_CLASS_HASH_BUCKETS]
FAST_MUTEX IopDeviceClassNotifyLock
PSETUP_NOTIFY_DATA IopSetupNotifyData = NULL
FAST_MUTEX IopTargetDeviceNotifyLock
LIST_ENTRY IopProfileNotifyList
FAST_MUTEX IopHwProfileNotifyLock
BOOLEAN PiNotificationInProgress
FAST_MUTEX PiNotificationInProgressLock
LIST_ENTRY IopDeferredRegistrationList
FAST_MUTEX IopDeferredRegistrationLock


Define Documentation

#define ALT_SEPERATOR_CHAR   (L'/')
 

Definition at line 157 of file pnpioapi.c.

Referenced by IopReplaceSeperatorWithPound(), and IoRegisterDeviceInterface().

#define DBG_GET_ASSOC   0
 

Definition at line 2704 of file pnpioapi.c.

#define GUID_STRING_LENGTH   38
 

Definition at line 176 of file pnpioapi.c.

Referenced by IopParseSymbolicLinkName().

#define GUID_STRING_SIZE   GUID_STRING_LENGTH * sizeof(WCHAR)
 

Definition at line 177 of file pnpioapi.c.

Referenced by IopParseSymbolicLinkName(), and RtlStringFromGUID().

#define INFO_BUFFER_GROW_SIZE   64
 

Definition at line 130 of file pnpioapi.c.

#define INITIAL_DEVNODE_NAME_BUFFER_SIZE   (FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + (200 * sizeof(WCHAR)))
 

Definition at line 139 of file pnpioapi.c.

Referenced by IopGetDeviceInterfaces().

#define INITIAL_INFO_BUFFER_SIZE   512
 

Definition at line 129 of file pnpioapi.c.

Referenced by IopGetDeviceInterfaces(), and IopRemoveDeviceInterfaces().

#define INITIAL_RETURN_BUFFER_SIZE   4096
 

Definition at line 133 of file pnpioapi.c.

Referenced by IopGetDeviceInterfaces().

#define INITIAL_SYMLINK_BUFFER_SIZE   1024
 

Definition at line 131 of file pnpioapi.c.

Referenced by IopGetDeviceInterfaces().

#define KERNEL_SYMLINK_STRING_PREFIX   TEXT("\\??\\")
 

Definition at line 162 of file pnpioapi.c.

Referenced by IopBuildSymbolicLinkStrings(), IopGetDeviceInterfaces(), and IopParseSymbolicLinkName().

#define KERNEL_SYMLINK_STRING_PREFIX_LENGTH   (( sizeof(KERNEL_SYMLINK_STRING_PREFIX) - sizeof(UNICODE_NULL) ) / sizeof(WCHAR) )
 

Definition at line 163 of file pnpioapi.c.

Referenced by IopGetDeviceInterfaces().

#define KEY_STRING_PREFIX   TEXT("##?#")
 

Definition at line 145 of file pnpioapi.c.

Referenced by IopOpenOrCreateDeviceInterfaceSubKeys(), and IopUnregisterDeviceInterface().

#define KEY_STRING_PREFIX_LENGTH   ( KEY_STRING_PREFIX_SIZE / sizeof(WCHAR) )
 

Definition at line 147 of file pnpioapi.c.

#define KEY_STRING_PREFIX_SIZE   ( sizeof(KEY_STRING_PREFIX) - sizeof(UNICODE_NULL) )
 

Definition at line 146 of file pnpioapi.c.

#define LEGACY_COMPATIBLE_ID_BASE   TEXT("DETECTED")
 

Definition at line 170 of file pnpioapi.c.

Referenced by PpCreateLegacyDeviceIds().

#define MAX_RESTPATH_BUF_LEN   512
 

Definition at line 123 of file pnpioapi.c.

Referenced by IoOpenDeviceRegistryKey().

#define MAX_VETO_NAME_LENGTH   512
 

Referenced by IoPnPDeliverServicePowerNotification().

#define PATH_CONTROL_CLASS   TEXT("Control\\Class\\")
 

Definition at line 122 of file pnpioapi.c.

Referenced by IoOpenDeviceRegistryKey().

#define PATH_CURRENTCONTROLSET   TEXT("\\Registry\\Machine\\System\\CurrentControlSet")
 

Definition at line 120 of file pnpioapi.c.

Referenced by IoOpenDeviceRegistryKey().

#define PATH_CURRENTCONTROLSET_HW_PROFILE_CURRENT   TEXT("\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet")
 

Definition at line 119 of file pnpioapi.c.

Referenced by IoOpenDeviceRegistryKey().

#define PATH_ENUM   TEXT("Enum\\")
 

Definition at line 121 of file pnpioapi.c.

Referenced by IoOpenDeviceRegistryKey().

#define PNP_DEVICE_EVENT_ENTRY_TAG   'EEpP'
 

Definition at line 42 of file pnpioapi.c.

Referenced by IopRequestHwProfileChangeNotification().

#define REFSTRING_PREFIX_CHAR   (L'#')
 

Definition at line 164 of file pnpioapi.c.

Referenced by IopOpenOrCreateDeviceInterfaceSubKeys(), and IopUnregisterDeviceInterface().

#define REPLACED_SEPERATOR_CHAR   (L'#')
 

Definition at line 159 of file pnpioapi.c.

Referenced by IopReplaceSeperatorWithPound().

#define REPLACED_SEPERATOR_STRING   TEXT("#")
 

Definition at line 158 of file pnpioapi.c.

Referenced by IopBuildSymbolicLinkStrings().

#define RETURN_BUFFER_GROW_SIZE   512
 

Definition at line 134 of file pnpioapi.c.

#define SEPERATOR_CHAR   (L'\\')
 

Definition at line 156 of file pnpioapi.c.

Referenced by IopParseSymbolicLinkName(), IopReplaceSeperatorWithPound(), and IoRegisterDeviceInterface().

#define SEPERATOR_STRING   TEXT("\\")
 

Definition at line 155 of file pnpioapi.c.

Referenced by IopBuildSymbolicLinkStrings().

#define SYMLINK_BUFFER_GROW_SIZE   128
 

Definition at line 132 of file pnpioapi.c.

#define USER_SYMLINK_STRING_PREFIX   TEXT("\\\\?\\")
 

Definition at line 160 of file pnpioapi.c.

Referenced by IoGetDeviceInterfaceAlias(), IopBuildSymbolicLinkStrings(), and IopParseSymbolicLinkName().

#define USER_SYMLINK_STRING_PREFIX_LENGTH   (( sizeof(USER_SYMLINK_STRING_PREFIX) - sizeof(UNICODE_NULL) ) / sizeof(WCHAR) )
 

Definition at line 161 of file pnpioapi.c.


Typedef Documentation

typedef struct _ASYNC_TDC_WORK_ITEM ASYNC_TDC_WORK_ITEM
 

Referenced by IoReportTargetDeviceChangeAsynchronous().

typedef struct _DEFERRED_REGISTRATION_ENTRY DEFERRED_REGISTRATION_ENTRY
 

typedef struct _DEVICE_WORK_ITEM DEVICE_WORK_ITEM
 

typedef struct _NOTIFICATION_CALLBACK_PARAM_BLOCK NOTIFICATION_CALLBACK_PARAM_BLOCK
 

typedef struct _ASYNC_TDC_WORK_ITEM * PASYNC_TDC_WORK_ITEM
 

Referenced by IopReportTargetDeviceChangeAsyncWorker(), and IoReportTargetDeviceChangeAsynchronous().

typedef struct _DEFERRED_REGISTRATION_ENTRY * PDEFERRED_REGISTRATION_ENTRY
 

Referenced by IopProcessDeferredRegistrations(), IoRegisterPlugPlayNotification(), and IoUnregisterPlugPlayNotification().

typedef struct _DEVICE_WORK_ITEM * PDEVICE_WORK_ITEM
 

Referenced by IopInvalidateDeviceStateWorker(), IopQueueDeviceWorkItem(), and IopRequestDeviceEjectWorker().

typedef * PIO_GET_LEGACY_VETO_LIST_CONTEXT
 

typedef struct _NOTIFICATION_CALLBACK_PARAM_BLOCK * PNOTIFICATION_CALLBACK_PARAM_BLOCK
 

Referenced by IopPnPHydraCallback().


Function Documentation

NTSTATUS IoCreateDriver IN PUNICODE_STRING DriverName  OPTIONAL,
IN PDRIVER_INITIALIZE  InitializationFunction
 

Definition at line 1071 of file pnpioapi.c.

References _DRIVER_OBJECT::DriverExtension, _DRIVER_OBJECT::DriverInit, _DRIVER_EXTENSION::DriverObject, DRVO_BUILTIN_DRIVER, ExAllocatePool, _DRIVER_OBJECT::Flags, IO_TYPE_DRIVER, IoDriverObjectType, IopInvalidDeviceRequest(), IRP_MJ_MAXIMUM_FUNCTION, KernelMode, KeTickCount, L, _DRIVER_OBJECT::MajorFunction, NT_SUCCESS, NTSTATUS(), NULL, ObCreateObject(), ObDereferenceObject, ObInsertObject(), ObMakeTemporaryObject(), ObReferenceObjectByHandle(), PAGED_CODE, PagedPool, _DRIVER_EXTENSION::ServiceKeyName, _DRIVER_OBJECT::Size, _DRIVER_OBJECT::Type, and USHORT.

Referenced by IopInitializePlugPlayServices(), and xxxRegisterForDeviceClassNotifications().

01077 : 01078 01079 This routine creates a driver object for a kernel component that 01080 was not loaded as a driver. If the creation of the driver object 01081 succeeds, Initialization function is invoked with the same parameters 01082 as passed to DriverEntry. 01083 01084 Parameters: 01085 01086 DriverName - Supplies the name of the driver for which a driver object 01087 is to be created. 01088 01089 InitializationFunction - Equivalent to DriverEntry(). 01090 01091 ReturnValue: 01092 01093 Status code that indicates whether or not the function was successful. 01094 01095 Notes: 01096 01097 --*/ 01098 { 01099 OBJECT_ATTRIBUTES objectAttributes; 01100 NTSTATUS status; 01101 PDRIVER_OBJECT driverObject; 01102 HANDLE driverHandle; 01103 ULONG objectSize; 01104 USHORT length; 01105 UNICODE_STRING driverName, serviceName; 01106 WCHAR buffer[60]; 01107 ULONG i; 01108 01109 PAGED_CODE(); 01110 01111 if (DriverName == NULL) { 01112 01113 // 01114 // Madeup a name for the driver object. 01115 // 01116 01117 length = (USHORT) _snwprintf(buffer, sizeof(buffer) / sizeof(WCHAR), L"\\Driver\\%08u", KeTickCount); 01118 driverName.Length = length * sizeof(WCHAR); 01119 driverName.MaximumLength = driverName.Length + sizeof(UNICODE_NULL); 01120 driverName.Buffer = buffer; \ 01121 } else { 01122 driverName = *DriverName; 01123 } 01124 01125 // 01126 // Attempt to create the driver object 01127 // 01128 01129 InitializeObjectAttributes( &objectAttributes, 01130 &driverName, 01131 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, 01132 NULL, 01133 NULL ); 01134 01135 objectSize = sizeof( DRIVER_OBJECT ) + sizeof( DRIVER_EXTENSION ); 01136 status = ObCreateObject( KernelMode, 01137 IoDriverObjectType, 01138 &objectAttributes, 01139 KernelMode, 01140 NULL, 01141 objectSize, 01142 0, 01143 0, 01144 &driverObject ); 01145 01146 if( !NT_SUCCESS( status )){ 01147 01148 // 01149 // Driver object creation failed 01150 // 01151 01152 return status; 01153 } 01154 01155 // 01156 // We've created a driver object, initialize it. 01157 // 01158 01159 RtlZeroMemory( driverObject, objectSize ); 01160 driverObject->DriverExtension = (PDRIVER_EXTENSION)(driverObject + 1); 01161 driverObject->DriverExtension->DriverObject = driverObject; 01162 driverObject->Type = IO_TYPE_DRIVER; 01163 driverObject->Size = sizeof( DRIVER_OBJECT ); 01164 driverObject->Flags = DRVO_BUILTIN_DRIVER; 01165 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) 01166 driverObject->MajorFunction[i] = IopInvalidDeviceRequest; 01167 driverObject->DriverInit = InitializationFunction; 01168 01169 serviceName.Buffer = (PWSTR)ExAllocatePool(PagedPool, driverName.Length + sizeof(WCHAR)); 01170 if (serviceName.Buffer) { 01171 serviceName.MaximumLength = driverName.Length + sizeof(WCHAR); 01172 serviceName.Length = driverName.Length; 01173 RtlMoveMemory(serviceName.Buffer, driverName.Buffer, driverName.Length); 01174 serviceName.Buffer[serviceName.Length / sizeof(WCHAR)] = UNICODE_NULL; 01175 driverObject->DriverExtension->ServiceKeyName = serviceName; 01176 } else { 01177 status = STATUS_INSUFFICIENT_RESOURCES; 01178 goto errorFreeDriverObject; 01179 } 01180 01181 // 01182 // Insert it into the object table. 01183 // 01184 01185 status = ObInsertObject( driverObject, 01186 NULL, 01187 FILE_READ_DATA, 01188 0, 01189 NULL, 01190 &driverHandle ); 01191 01192 if( !NT_SUCCESS( status )){ 01193 01194 // 01195 // Couldn't insert the driver object into the table. 01196 // The object got dereferenced by the object manager. Just exit 01197 // 01198 01199 goto errorReturn; 01200 } 01201 01202 // 01203 // Reference the handle and obtain a pointer to the driver object so that 01204 // the handle can be deleted without the object going away. 01205 // 01206 01207 status = ObReferenceObjectByHandle( driverHandle, 01208 0, 01209 IoDriverObjectType, 01210 KernelMode, 01211 (PVOID *) &driverObject, 01212 (POBJECT_HANDLE_INFORMATION) NULL ); 01213 if( !NT_SUCCESS( status )) { 01214 // 01215 // Backout here is probably bogus. If the ref didn't work then the handle is probably bad 01216 // Do this right though just in case there are other common error returns for ObRef... 01217 // 01218 ZwMakeTemporaryObject( driverHandle ); // Cause handle close to free the object 01219 ZwClose( driverHandle ); // Close the handle. 01220 goto errorReturn; 01221 } 01222 01223 ZwClose( driverHandle ); 01224 01225 // 01226 // Store the name of the device driver in the driver object so that it 01227 // can be easily found by the error log thread. 01228 // 01229 01230 driverObject->DriverName.Buffer = ExAllocatePool( PagedPool, 01231 driverName.MaximumLength ); 01232 if (driverObject->DriverName.Buffer) { 01233 driverObject->DriverName.MaximumLength = driverName.MaximumLength; 01234 driverObject->DriverName.Length = driverName.Length; 01235 01236 RtlCopyMemory( driverObject->DriverName.Buffer, 01237 driverName.Buffer, 01238 driverName.MaximumLength ); 01239 } 01240 01241 // 01242 // Call the driver initialization routine 01243 // 01244 01245 status = (*InitializationFunction)(driverObject, NULL); 01246 01247 if( !NT_SUCCESS( status )){ 01248 01249 errorFreeDriverObject: 01250 01251 // 01252 // If we were unsuccessful, we need to get rid of the driverObject 01253 // that we created. 01254 // 01255 01256 ObMakeTemporaryObject( driverObject ); 01257 ObDereferenceObject( driverObject ); 01258 } 01259 errorReturn: 01260 return status; 01261 }

VOID IoDeleteDriver IN PDRIVER_OBJECT  DriverObject  ) 
 

Definition at line 1264 of file pnpioapi.c.

References ObDereferenceObject.

Referenced by IopInitializePlugPlayServices().

01269 : 01270 01271 This routine deletes a driver object created explicitly through 01272 IoCreateDriver. 01273 01274 Parameters: 01275 01276 DriverObject - Supplies a pointer to the driver object to be deleted. 01277 01278 ReturnValue: 01279 01280 Status code that indicates whether or not the function was successful. 01281 01282 Notes: 01283 01284 --*/ 01285 { 01286 01287 ObDereferenceObject(DriverObject); 01288 }

NTSTATUS IoGetDeviceInterfaceAlias IN PUNICODE_STRING  SymbolicLinkName,
IN CONST GUID *  AliasInterfaceClassGuid,
OUT PUNICODE_STRING  AliasSymbolicLinkName
 

Definition at line 4946 of file pnpioapi.c.

References ExAcquireResourceExclusive, ExFreePool(), ExReleaseResource, IopBuildSymbolicLinkStrings(), IopConstStringSize, IopDeviceInterfaceKeysFromSymbolicLink(), IopFreeAllocatedUnicodeString(), IopGetRegistryValue(), IopParseSymbolicLinkName(), IopRegistryDataToUnicodeString, KeEnterCriticalRegion, KeLeaveCriticalRegion, KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PpRegistryDeviceResource, RtlFreeUnicodeString(), RtlStringFromGUID(), TRUE, and USER_SYMLINK_STRING_PREFIX.

04954 : 04955 04956 This API returns a symbolic link name (i.e., device interface) of a 04957 particular interface class that 'aliases' the specified device interface. 04958 Two device interfaces are considered aliases of each other if the 04959 following two criteria are met: 04960 04961 1. Both interfaces are exposed by the same PDO (devnode). 04962 2. Both interfaces share the same RefString. 04963 04964 Parameters: 04965 04966 SymbolicLinkName - Supplies the name of the device interface whose alias is 04967 to be retrieved. 04968 04969 AliasInterfaceClassGuid - Supplies a pointer to the GUID representing the interface 04970 class for which an alias is to be retrieved. 04971 04972 AliasSymbolicLinkName - Supplies a pointer to a string which, upon success, 04973 will contain the name of the device interface in the specified class that 04974 aliases the SymbolicLinkName interface. (This symbolic link name will be 04975 returned in either kernel-mode or user-mode form, depeding upon the form 04976 of the SymbolicLinkName path). 04977 04978 It is the caller's responsibility to free the buffer allocated for this 04979 string via ExFreePool(). 04980 04981 Return Value: 04982 04983 Status code that indicates whether or not the function was successful. 04984 04985 --*/ 04986 04987 { 04988 NTSTATUS status; 04989 HANDLE hKey; 04990 PKEY_VALUE_FULL_INFORMATION pDeviceInstanceInfo; 04991 UNICODE_STRING deviceInstanceString, refString, guidString, otherString; 04992 PUNICODE_STRING pUserString, pKernelString; 04993 BOOLEAN refStringPresent, userModeFormat; 04994 04995 PAGED_CODE(); 04996 04997 // 04998 // Convert the class guid into string form 04999 // 05000 05001 status = RtlStringFromGUID(AliasInterfaceClassGuid, &guidString); 05002 if( !NT_SUCCESS(status) ){ 05003 goto clean0; 05004 } 05005 05006 // 05007 // Enter critical section and acquire a lock on the registry. Both these 05008 // mechanisms are required to prevent deadlock in the case where an APC 05009 // routine calls this routine after the registry resource has been claimed 05010 // in this case it would wait blocking this thread so the registry would 05011 // never be released -> deadlock. Critical sectioning the registry manipulation 05012 // portion solves this problem 05013 // 05014 05015 KeEnterCriticalRegion(); 05016 ExAcquireResourceExclusive(&PpRegistryDeviceResource, TRUE); 05017 05018 // 05019 // Open the (parent) device interface key--not the refstring-specific one. 05020 // 05021 05022 status = IopDeviceInterfaceKeysFromSymbolicLink(SymbolicLinkName, 05023 KEY_READ, 05024 NULL, 05025 &hKey, 05026 NULL 05027 ); 05028 if(!NT_SUCCESS(status)) { 05029 goto clean1; 05030 } 05031 05032 // 05033 // Get the name of the device instance that 'owns' this interface. 05034 // 05035 05036 status = IopGetRegistryValue(hKey, REGSTR_VAL_DEVICE_INSTANCE, &pDeviceInstanceInfo); 05037 05038 ZwClose(hKey); 05039 05040 if(!NT_SUCCESS(status)) { 05041 goto clean1; 05042 } 05043 05044 if(pDeviceInstanceInfo->Type == REG_SZ) { 05045 05046 IopRegistryDataToUnicodeString(&deviceInstanceString, 05047 (PWSTR)KEY_VALUE_DATA(pDeviceInstanceInfo), 05048 pDeviceInstanceInfo->DataLength 05049 ); 05050 05051 } else { 05052 05053 status = STATUS_INVALID_PARAMETER_1; 05054 goto clean2; 05055 05056 } 05057 05058 // 05059 // Now parse out the refstring, so that we can construct the name of the interface device's 05060 // alias. (NOTE: we have not yet verified that the alias actually exists, we're only 05061 // constructing what its name would be, if it did exist.) 05062 // 05063 // Don't bother to check the return code. If this were a bad string, we'd have already 05064 // failed above when we called IopDeviceInterfaceKeysFromSymbolicLink. 05065 // 05066 IopParseSymbolicLinkName(SymbolicLinkName, 05067 NULL, 05068 NULL, 05069 NULL, 05070 &refString, 05071 &refStringPresent, 05072 NULL 05073 ); 05074 05075 // 05076 // Did the caller supply us with a user-mode or kernel-mode format path? 05077 // 05078 userModeFormat = (IopConstStringSize(USER_SYMLINK_STRING_PREFIX) == 05079 RtlCompareMemory(SymbolicLinkName->Buffer, 05080 USER_SYMLINK_STRING_PREFIX, 05081 IopConstStringSize(USER_SYMLINK_STRING_PREFIX) 05082 )); 05083 05084 if(userModeFormat) { 05085 pUserString = AliasSymbolicLinkName; 05086 pKernelString = &otherString; 05087 } else { 05088 pKernelString = AliasSymbolicLinkName; 05089 pUserString = &otherString; 05090 } 05091 05092 status = IopBuildSymbolicLinkStrings(&deviceInstanceString, 05093 &guidString, 05094 refStringPresent ? &refString : NULL, 05095 pUserString, 05096 pKernelString 05097 ); 05098 if (!NT_SUCCESS(status)) { 05099 goto clean2; 05100 } 05101 05102 // 05103 // OK, we now have the symbolic link name of the alias, but we don't yet know whether 05104 // it actually exists. Check this by attempting to open the associated registry key. 05105 // 05106 status = IopDeviceInterfaceKeysFromSymbolicLink(AliasSymbolicLinkName, 05107 KEY_READ, 05108 NULL, 05109 NULL, 05110 &hKey 05111 ); 05112 05113 if(NT_SUCCESS(status)) { 05114 // 05115 // Alias exists--close the key handle. 05116 // 05117 ZwClose(hKey); 05118 } else { 05119 IopFreeAllocatedUnicodeString(AliasSymbolicLinkName); 05120 } 05121 05122 IopFreeAllocatedUnicodeString(&otherString); 05123 05124 clean2: 05125 ExFreePool(pDeviceInstanceInfo); 05126 05127 clean1: 05128 ExReleaseResource(&PpRegistryDeviceResource); 05129 KeLeaveCriticalRegion(); 05130 RtlFreeUnicodeString(&guidString); 05131 05132 clean0: 05133 return status; 05134 }

NTSTATUS IoGetDeviceInterfaces IN CONST GUID *  InterfaceClassGuid,
IN PDEVICE_OBJECT PhysicalDeviceObject  OPTIONAL,
IN ULONG  Flags,
OUT PWSTR *  SymbolicLinkList
 

Definition at line 3419 of file pnpioapi.c.

References ASSERT_PDO, FALSE, _DEVICE_NODE::InstancePath, IopGetDeviceInterfaces(), NTSTATUS(), NULL, and PAGED_CODE.

Referenced by IopCreateArcNames(), and IoRegisterPlugPlayNotification().

03428 : 03429 03430 This API allows a WDM driver to get a list of paths that represent all 03431 device interfaces registered for the specified interface class. 03432 03433 Parameters: 03434 03435 InterfaceClassGuid - Supplies a pointer to a GUID representing the interface class 03436 for whom a list of members is to be retrieved 03437 03438 PhysicalDeviceObject - Optionally, supplies a pointer to the PDO for whom 03439 interfaces of the specified class are to be re-trieved. If this parameter 03440 is not supplied, then all interface devices (regardless of what physical 03441 device exposes them) will be returned. 03442 03443 Flags - Supplies flags that modify the behavior of list retrieval. 03444 The following flags are presently defined: 03445 03446 DEVICE_INTERFACE_INCLUDE_NONACTIVE -- If this flag is specified, then all 03447 device interfaces, whether currently active or not, will be returned 03448 (potentially filtered based on the PhysicalDeviceObject, if specified). 03449 03450 SymbolicLinkList - Supplies the address of a character pointer, that on 03451 success will contain a multi-sz list of \DosDevices\ symbolic link 03452 names that provide the requested functionality. The caller is 03453 responsible for freeing the memory via ExFreePool 03454 03455 Return Value: 03456 03457 Status code that indicates whether or not the function was successful. 03458 03459 --*/ 03460 03461 { 03462 NTSTATUS status; 03463 PUNICODE_STRING pDeviceName = NULL; 03464 PDEVICE_NODE pDeviceNode; 03465 03466 PAGED_CODE(); 03467 03468 // 03469 // Check we have a PDO and if so extract the instance path from it 03470 // 03471 03472 if (ARGUMENT_PRESENT(PhysicalDeviceObject)) { 03473 03474 ASSERT_PDO(PhysicalDeviceObject); 03475 pDeviceNode = (PDEVICE_NODE) PhysicalDeviceObject->DeviceObjectExtension->DeviceNode; 03476 pDeviceName = &pDeviceNode->InstancePath; 03477 } 03478 03479 status = IopGetDeviceInterfaces(InterfaceClassGuid, 03480 pDeviceName, 03481 Flags, 03482 FALSE, 03483 SymbolicLinkList, 03484 NULL 03485 ); 03486 return status; 03487 }

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

Definition at line 373 of file pnpioapi.c.

References _DEVICE_CAPABILITIES::Address, ASSERT, ASSERT_PDO, _DEVICE_NODE::ChildBusNumber, _DEVICE_NODE::ChildBusTypeIndex, _DEVICE_NODE::ChildInterfaceType, _BUS_TYPE_GUID_LIST::Count, DevicePropertyAddress, DevicePropertyBootConfiguration, DevicePropertyBootConfigurationTranslated, DevicePropertyBusNumber, DevicePropertyBusTypeGuid, DevicePropertyClassGuid, DevicePropertyClassName, DevicePropertyCompatibleIDs, DevicePropertyDeviceDescription, DevicePropertyDriverKeyName, DevicePropertyEnumeratorName, DevicePropertyFriendlyName, DevicePropertyHardwareID, DevicePropertyLegacyBusType, DevicePropertyLocationInformation, DevicePropertyManufacturer, DevicePropertyPhysicalDeviceObjectName, DevicePropertyUINumber, ExAcquireResourceExclusive, ExAllocatePool, ExFreePool(), ExReleaseResource, _BUS_TYPE_GUID_LIST::Guid, _DEVICE_NODE::InstancePath, IopBusTypeGuidList, IopDeviceObjectToDeviceInstance(), IopGetRegistryValue(), IopOpenRegistryKeyEx(), IopQueryDeviceCapabilities(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KEY_VALUE_DATA, L, NT_SUCCESS, NTSTATUS(), NULL, ObQueryNameString(), PAGED_CODE, PagedPool, PpRegistryDeviceResource, RtlInitUnicodeString(), and TRUE.

Referenced by ArbQueryConflict(), IoGetDmaAdapter(), and IopProcessSetInterfaceState().

00383 : 00384 00385 This routine lets drivers query the registry properties associated with the 00386 specified device. 00387 00388 Parameters: 00389 00390 DeviceObject - Supplies the device object whoes registry property is to be 00391 returned. This device object should be the one created by 00392 a bus driver. 00393 00394 DeviceProperty - Specifies what device property to get. 00395 00396 BufferLength - Specifies the length, in byte, of the PropertyBuffer. 00397 00398 PropertyBuffer - Supplies a pointer to a buffer to receive property data. 00399 00400 ResultLength - Supplies a pointer to a variable to receive the size of the 00401 property data returned. 00402 00403 ReturnValue: 00404 00405 Status code that indicates whether or not the function was successful. If 00406 PropertyBuffer is not big enough to hold requested data, STATUS_BUFFER_TOO_SMALL 00407 will be returned and ResultLength will be set to the number of bytes actually 00408 required. 00409 00410 --*/ 00411 00412 { 00413 PDEVICE_NODE deviceNode; 00414 DEVICE_CAPABILITIES capabilities; 00415 NTSTATUS status; 00416 HANDLE handle; 00417 PWSTR valueName, keyName = NULL; 00418 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 00419 ULONG valueType; 00420 ULONG length; 00421 POBJECT_NAME_INFORMATION deviceObjectName; 00422 PWSTR deviceInstanceName; 00423 PWCHAR enumeratorNameEnd; 00424 00425 PAGED_CODE(); 00426 00427 ASSERT_PDO(DeviceObject); 00428 00429 // 00430 // Initialize out parameters 00431 // 00432 00433 *ResultLength = 0; 00434 00435 // 00436 // Map Device Property to registry value name and value type. 00437 // 00438 00439 switch (DeviceProperty) { 00440 00441 case DevicePropertyDeviceDescription: 00442 valueName = REGSTR_VALUE_DEVICE_DESC; 00443 valueType = REG_SZ; 00444 break; 00445 00446 case DevicePropertyHardwareID: 00447 valueName = REGSTR_VAL_HARDWAREID; 00448 valueType = REG_MULTI_SZ; 00449 break; 00450 00451 case DevicePropertyCompatibleIDs: 00452 valueName = REGSTR_VAL_COMPATIBLEIDS; 00453 valueType = REG_MULTI_SZ; 00454 break; 00455 00456 case DevicePropertyBootConfiguration: 00457 keyName = REGSTR_KEY_LOG_CONF; 00458 valueName = REGSTR_VAL_BOOTCONFIG; 00459 valueType = REG_RESOURCE_LIST; 00460 break; 00461 00462 case DevicePropertyBootConfigurationTranslated: 00463 // 00464 // BUGBUG(andrewth) - support this! 00465 // 00466 return STATUS_NOT_SUPPORTED; 00467 break; 00468 00469 case DevicePropertyClassName: 00470 valueName = REGSTR_VALUE_CLASS; 00471 valueType = REG_SZ; 00472 break; 00473 00474 case DevicePropertyClassGuid: 00475 valueName = REGSTR_VALUE_CLASSGUID; 00476 valueType = REG_SZ; 00477 break; 00478 00479 case DevicePropertyDriverKeyName: 00480 valueName = REGSTR_VALUE_DRIVER; 00481 valueType = REG_SZ; 00482 break; 00483 00484 case DevicePropertyManufacturer: 00485 valueName = REGSTR_VAL_MFG; 00486 valueType = REG_SZ; 00487 break; 00488 00489 case DevicePropertyFriendlyName: 00490 valueName = REGSTR_VALUE_FRIENDLYNAME; 00491 valueType = REG_SZ; 00492 break; 00493 00494 case DevicePropertyLocationInformation: 00495 valueName = REGSTR_VAL_LOCATION_INFORMATION; 00496 valueType = REG_SZ; 00497 break; 00498 00499 case DevicePropertyUINumber: 00500 valueName = REGSTR_VAL_UI_NUMBER; 00501 valueType = REG_DWORD; 00502 break; 00503 00504 case DevicePropertyPhysicalDeviceObjectName: 00505 00506 ASSERT (0 == (1 & BufferLength)); // had better be an even length 00507 00508 // 00509 // Create a buffer for the Obj manager. 00510 // 00511 length = BufferLength + sizeof (OBJECT_NAME_INFORMATION); 00512 00513 deviceObjectName = (POBJECT_NAME_INFORMATION) 00514 ExAllocatePool(PagedPool, length); 00515 00516 if (NULL == deviceObjectName) { 00517 return STATUS_INSUFFICIENT_RESOURCES; 00518 } 00519 00520 status = ObQueryNameString (DeviceObject, 00521 deviceObjectName, 00522 length, 00523 ResultLength); 00524 00525 if (STATUS_INFO_LENGTH_MISMATCH == status) { 00526 status = STATUS_BUFFER_TOO_SMALL; 00527 } 00528 00529 if (NT_SUCCESS (status)) { 00530 00531 if (deviceObjectName->Name.Length == 0) { 00532 00533 // 00534 // PDO has no NAME, probably it's been deleted 00535 // 00536 *ResultLength = 0; 00537 00538 } else { 00539 00540 *ResultLength = deviceObjectName->Name.Length + sizeof(UNICODE_NULL); 00541 if (*ResultLength > BufferLength) { 00542 status = STATUS_BUFFER_TOO_SMALL; 00543 } else { 00544 00545 RtlCopyMemory(PropertyBuffer, 00546 deviceObjectName->Name.Buffer, 00547 deviceObjectName->Name.Length); 00548 *(PWCHAR) (((PUCHAR) PropertyBuffer) + deviceObjectName->Name.Length) = L'\0'; 00549 } 00550 } 00551 } else { 00552 *ResultLength -= sizeof(OBJECT_NAME_INFORMATION); 00553 } 00554 00555 ExFreePool (deviceObjectName); 00556 return status; 00557 00558 00559 case DevicePropertyBusTypeGuid: 00560 00561 deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 00562 if (deviceNode->ChildBusTypeIndex != 0xffff 00563 && deviceNode->ChildBusTypeIndex < IopBusTypeGuidList->Count) { 00564 00565 *ResultLength = sizeof(GUID); 00566 00567 if(*ResultLength <= BufferLength) { 00568 00569 RtlCopyMemory(PropertyBuffer, 00570 &(IopBusTypeGuidList->Guid[deviceNode->ChildBusTypeIndex]), 00571 sizeof(GUID)); 00572 00573 status = STATUS_SUCCESS; 00574 00575 } else { 00576 00577 status = STATUS_BUFFER_TOO_SMALL; 00578 00579 } 00580 00581 } else { 00582 status = STATUS_OBJECT_NAME_NOT_FOUND; 00583 } 00584 00585 return status; 00586 00587 case DevicePropertyLegacyBusType: 00588 00589 deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 00590 if (deviceNode->ChildInterfaceType != InterfaceTypeUndefined) { 00591 00592 *ResultLength = sizeof(INTERFACE_TYPE); 00593 00594 if(*ResultLength <= BufferLength) { 00595 00596 *(PINTERFACE_TYPE)PropertyBuffer = deviceNode->ChildInterfaceType; 00597 status = STATUS_SUCCESS; 00598 00599 } else { 00600 status = STATUS_BUFFER_TOO_SMALL; 00601 } 00602 00603 } else { 00604 status = STATUS_OBJECT_NAME_NOT_FOUND; 00605 } 00606 00607 return status; 00608 00609 case DevicePropertyBusNumber: 00610 00611 // 00612 // Retrieve the property from the parent's devnode field. 00613 // 00614 00615 deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 00616 if ((deviceNode->ChildBusNumber & 0x80000000) != 0x80000000) { 00617 00618 *ResultLength = sizeof(ULONG); 00619 00620 if(*ResultLength <= BufferLength) { 00621 00622 *(PULONG)PropertyBuffer = deviceNode->ChildBusNumber; 00623 status = STATUS_SUCCESS; 00624 00625 } else { 00626 status = STATUS_BUFFER_TOO_SMALL; 00627 } 00628 00629 } else { 00630 status = STATUS_OBJECT_NAME_NOT_FOUND; 00631 } 00632 00633 return status; 00634 00635 case DevicePropertyEnumeratorName: 00636 00637 ASSERT (0 == (1 & BufferLength)); // had better be an even length 00638 00639 deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 00640 deviceInstanceName = deviceNode->InstancePath.Buffer; 00641 00642 // 00643 // There should always be a string here, except for (possibly) 00644 // HTREE\Root\0, but no one should ever be calling us with that PDO 00645 // anyway. 00646 // 00647 ASSERT (deviceInstanceName); 00648 00649 // 00650 // We know we're going to find a separator character (\) in the string, 00651 // so the fact that unicode strings may not be null-terminated isn't 00652 // a problem. 00653 // 00654 enumeratorNameEnd = wcschr(deviceInstanceName, OBJ_NAME_PATH_SEPARATOR); 00655 ASSERT (enumeratorNameEnd); 00656 00657 // 00658 // Compute required length, minus null terminating character. 00659 // 00660 length = (ULONG)((PUCHAR)enumeratorNameEnd - (PUCHAR)deviceInstanceName); 00661 00662 // 00663 // Store required length in caller-supplied OUT parameter. 00664 // 00665 *ResultLength = length + sizeof(UNICODE_NULL); 00666 00667 if(*ResultLength > BufferLength) { 00668 status = STATUS_BUFFER_TOO_SMALL; 00669 } else { 00670 memcpy((PUCHAR)PropertyBuffer, (PUCHAR)deviceInstanceName, length); 00671 *(PWCHAR)((PUCHAR)PropertyBuffer + length) = UNICODE_NULL; 00672 status = STATUS_SUCCESS; 00673 } 00674 00675 return status; 00676 00677 case DevicePropertyAddress: 00678 00679 deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 00680 00681 status = IopQueryDeviceCapabilities(deviceNode, &capabilities); 00682 00683 if (NT_SUCCESS(status) && (capabilities.Address != 0xFFFFFFFF)) { 00684 00685 *ResultLength = sizeof(ULONG); 00686 00687 if(*ResultLength <= BufferLength) { 00688 00689 *(PULONG)PropertyBuffer = capabilities.Address; 00690 status = STATUS_SUCCESS; 00691 00692 } else { 00693 status = STATUS_BUFFER_TOO_SMALL; 00694 } 00695 00696 } else { 00697 status = STATUS_OBJECT_NAME_NOT_FOUND; 00698 } 00699 00700 return status; 00701 00702 default: 00703 status = STATUS_INVALID_PARAMETER_2; 00704 goto clean0; 00705 } 00706 00707 // 00708 // Enter critical section and acquire a lock on the registry. Both these 00709 // mechanisms are required to prevent deadlock in the case where an APC 00710 // routine calls this routine after the registry resource has been claimed 00711 // in this case it would wait blocking this thread so the registry would 00712 // never be released -> deadlock. Critical sectioning the registry manipulatio 00713 // portion solves this problem 00714 // 00715 00716 KeEnterCriticalRegion(); 00717 ExAcquireResourceExclusive(&PpRegistryDeviceResource, TRUE); 00718 00719 // 00720 // Based on the PDO specified by caller, find the handle of its device 00721 // instance registry key. 00722 // 00723 00724 status = IopDeviceObjectToDeviceInstance(DeviceObject, &handle, KEY_READ); 00725 if (!NT_SUCCESS(status)) { 00726 goto clean1; 00727 } 00728 00729 // 00730 // If the data is stored in a subkey then open this key and close the old one 00731 // 00732 00733 if (keyName) { 00734 HANDLE subKeyHandle; 00735 UNICODE_STRING unicodeKey; 00736 00737 RtlInitUnicodeString(&unicodeKey, keyName); 00738 status = IopOpenRegistryKeyEx( &subKeyHandle, 00739 handle, 00740 &unicodeKey, 00741 KEY_READ 00742 ); 00743 00744 if(NT_SUCCESS(status)){ 00745 ZwClose(handle); 00746 handle = subKeyHandle; 00747 } else { 00748 goto clean2; 00749 } 00750 00751 } 00752 00753 // 00754 // Read the registry value of the desired value name 00755 // 00756 00757 status = IopGetRegistryValue (handle, 00758 valueName, 00759 &keyValueInformation); 00760 00761 00762 // 00763 // We have finished using the registry so clean up and release our resources 00764 // 00765 00766 clean2: 00767 ZwClose(handle); 00768 clean1: 00769 ExReleaseResource(&PpRegistryDeviceResource); 00770 KeLeaveCriticalRegion(); 00771 00772 // 00773 // If we have been sucessful finding the info hand it back to the caller 00774 // 00775 00776 if (NT_SUCCESS(status)) { 00777 00778 // 00779 // Return the length of the data (or the required length if the buffer is too small) 00780 // 00781 00782 *ResultLength = keyValueInformation->DataLength; 00783 00784 // 00785 // Check that the buffer we have been given is big enough and that the value returned is 00786 // of the correct registry type 00787 // 00788 00789 if (keyValueInformation->DataLength <= BufferLength) { 00790 if (keyValueInformation->Type == valueType) { 00791 RtlCopyMemory(PropertyBuffer, 00792 KEY_VALUE_DATA(keyValueInformation), 00793 keyValueInformation->DataLength); 00794 00795 } else { 00796 status = STATUS_INVALID_PARAMETER_2; 00797 } 00798 } else { 00799 status = STATUS_BUFFER_TOO_SMALL; 00800 } 00801 00802 ExFreePool(keyValueInformation); 00803 } 00804 00805 clean0: 00806 return status; 00807 }

NTKERNELAPI PDMA_ADAPTER IoGetDmaAdapter IN PDEVICE_OBJECT PhysicalDeviceObject  OPTIONAL,
IN PDEVICE_DESCRIPTION  DeviceDescription,
IN OUT PULONG  NumberOfMapRegisters
 

Definition at line 8307 of file pnpioapi.c.

References ASSERT, ASSERT_PDO, BUS_INTERFACE_STANDARD, _BUS_INTERFACE_STANDARD::Context, DevicePropertyLegacyBusType, Executive, FALSE, _BUS_INTERFACE_STANDARD::GetDmaAdapter, HalGetDmaAdapter, _BUS_INTERFACE_STANDARD::InterfaceDereference, _DEVICE_DESCRIPTION::InterfaceType, IoBuildSynchronousFsdRequest(), IoCallDriver, IoGetAttachedDeviceReference(), IoGetDeviceProperty(), IoGetNextIrpStackLocation, _IRP::IoStatus, IRP_MJ_PNP, IRP_MN_QUERY_INTERFACE, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, PAGED_CODE, _IO_STACK_LOCATION::Parameters, and PnpDefaultInterfaceType.

08314 : 08315 08316 This function returns the appropriate DMA adapter object for the device 08317 defined in the device description structure. This code is a wrapper 08318 which queries the bus interface standard and then calls the returned 08319 get DMA adapter function. If an adapter object was not retrieved then 08320 a legecy function is attempted. 08321 08322 Arguments: 08323 08324 PhysicalDeviceObject - Optionally, supplies the PDO for the device 08325 requesting the DMA adapter. If not supplied, this routine performs the 08326 function of the non-PnP HalGetDmaAdapter routine. 08327 08328 DeviceDescriptor - Supplies a description of the deivce. 08329 08330 NumberOfMapRegisters - Returns the maximum number of map registers which 08331 may be allocated by the device driver. 08332 08333 Return Value: 08334 08335 A pointer to the requested adapter object or NULL if an adapter could not 08336 be created. 08337 08338 --*/ 08339 08340 { 08341 KEVENT event; 08342 NTSTATUS status; 08343 PIRP irp; 08344 IO_STATUS_BLOCK ioStatusBlock; 08345 PIO_STACK_LOCATION irpStack; 08346 BUS_INTERFACE_STANDARD busInterface; 08347 PDMA_ADAPTER dmaAdapter = NULL; 08348 PDEVICE_DESCRIPTION deviceDescriptionToUse; 08349 DEVICE_DESCRIPTION privateDeviceDescription; 08350 ULONG resultLength; 08351 PDEVICE_OBJECT targetDevice; 08352 08353 PAGED_CODE(); 08354 08355 if (PhysicalDeviceObject != NULL) { 08356 08357 ASSERT_PDO(PhysicalDeviceObject); 08358 08359 // 08360 // First off, determine whether or not the caller has requested that we 08361 // automatically fill in the proper InterfaceType value into the 08362 // DEVICE_DESCRIPTION structure used in retrieving the DMA adapter object. 08363 // If so, then retrieve that interface type value into our own copy of 08364 // the DEVICE_DESCRIPTION buffer. 08365 // 08366 if ((DeviceDescription->InterfaceType == InterfaceTypeUndefined) || 08367 (DeviceDescription->InterfaceType == PNPBus)) { 08368 // 08369 // Make a copy of the caller-supplied device description, so 08370 // we can modify it to fill in the correct interface type. 08371 // 08372 RtlCopyMemory(&privateDeviceDescription, 08373 DeviceDescription, 08374 sizeof(DEVICE_DESCRIPTION) 08375 ); 08376 08377 status = IoGetDeviceProperty(PhysicalDeviceObject, 08378 DevicePropertyLegacyBusType, 08379 sizeof(privateDeviceDescription.InterfaceType), 08380 (PVOID)&(privateDeviceDescription.InterfaceType), 08381 &resultLength 08382 ); 08383 08384 if (!NT_SUCCESS(status)) { 08385 08386 ASSERT(status == STATUS_OBJECT_NAME_NOT_FOUND); 08387 08388 // 08389 // Since the enumerator didn't tell us what interface type to 08390 // use for this PDO, we'll fall back to our default. This is 08391 // ISA for machines where the legacy bus is ISA or EISA, and it 08392 // is MCA for machines whose legacy bus is MicroChannel. 08393 // 08394 privateDeviceDescription.InterfaceType = PnpDefaultInterfaceType; 08395 } 08396 08397 // 08398 // Use our private device description buffer from now on. 08399 // 08400 deviceDescriptionToUse = &privateDeviceDescription; 08401 08402 } else { 08403 // 08404 // Use the caller-supplied device description. 08405 // 08406 deviceDescriptionToUse = DeviceDescription; 08407 } 08408 08409 // 08410 // Now, query for the BUS_INTERFACE_STANDARD interface from the PDO. 08411 // 08412 KeInitializeEvent( &event, NotificationEvent, FALSE ); 08413 08414 targetDevice = IoGetAttachedDeviceReference(PhysicalDeviceObject); 08415 08416 irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP, 08417 targetDevice, 08418 NULL, 08419 0, 08420 NULL, 08421 &event, 08422 &ioStatusBlock ); 08423 08424 if (irp == NULL) { 08425 return NULL; 08426 } 08427 08428 RtlZeroMemory( &busInterface, sizeof( BUS_INTERFACE_STANDARD )); 08429 08430 irpStack = IoGetNextIrpStackLocation( irp ); 08431 irpStack->MinorFunction = IRP_MN_QUERY_INTERFACE; 08432 irpStack->Parameters.QueryInterface.InterfaceType = (LPGUID) &GUID_BUS_INTERFACE_STANDARD; 08433 irpStack->Parameters.QueryInterface.Size = sizeof( BUS_INTERFACE_STANDARD ); 08434 irpStack->Parameters.QueryInterface.Version = 1; 08435 irpStack->Parameters.QueryInterface.Interface = (PINTERFACE) &busInterface; 08436 irpStack->Parameters.QueryInterface.InterfaceSpecificData = NULL; 08437 08438 // 08439 // Initialize the status to error in case the ACPI driver decides not to 08440 // set it correctly. 08441 // 08442 08443 irp->IoStatus.Status = STATUS_NOT_SUPPORTED; 08444 08445 status = IoCallDriver(targetDevice, irp); 08446 08447 if (status == STATUS_PENDING) { 08448 08449 KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL ); 08450 status = ioStatusBlock.Status; 08451 08452 } 08453 08454 ObDereferenceObject(targetDevice); 08455 08456 if (NT_SUCCESS( status)) { 08457 08458 if (busInterface.GetDmaAdapter != NULL) { 08459 08460 08461 dmaAdapter = busInterface.GetDmaAdapter( busInterface.Context, 08462 deviceDescriptionToUse, 08463 NumberOfMapRegisters ); 08464 08465 } 08466 08467 // 08468 // Dereference the interface 08469 // 08470 08471 busInterface.InterfaceDereference( busInterface.Context ); 08472 } 08473 08474 } else { 08475 // 08476 // The caller didn't specify the PDO, so we'll just use the device 08477 // description exactly as they specified it (i.e., we can't attempt to 08478 // make our own determination of what interface type to use). 08479 // 08480 deviceDescriptionToUse = DeviceDescription; 08481 } 08482 08483 #if !defined(NO_LEGACY_DRIVERS) 08484 // 08485 // If there is no DMA adapter, try the legacy mode code. 08486 // 08487 08488 if (dmaAdapter == NULL) { 08489 08490 dmaAdapter = HalGetDmaAdapter( PhysicalDeviceObject, 08491 deviceDescriptionToUse, 08492 NumberOfMapRegisters ); 08493 08494 } 08495 #endif // NO_LEGACY_DRIVERS 08496 08497 return( dmaAdapter ); 08498 }

NTSTATUS IoGetLegacyVetoList OUT PWSTR *VetoList  OPTIONAL,
OUT PPNP_VETO_TYPE  VetoType
 

Definition at line 9712 of file pnpioapi.c.

References ASSERT, ExFreePool(), FALSE, IopAcquireEnumerationLock, IopAppendLegacyVeto(), IopGetLegacyVetoListDeviceNode(), IopGetLegacyVetoListDrivers(), IopReleaseEnumerationLock, IopRootDeviceNode, L, NT_SUCCESS, NTSTATUS(), NULL, PnPInitialized, RtlInitUnicodeString(), IO_GET_LEGACY_VETO_LIST_CONTEXT::Status, Status, IO_GET_LEGACY_VETO_LIST_CONTEXT::VetoList, IO_GET_LEGACY_VETO_LIST_CONTEXT::VetoListLength, and IO_GET_LEGACY_VETO_LIST_CONTEXT::VetoType.

Referenced by ExpQueryLegacyDriverInformation().

09718 : 09719 09720 This routine is used by PNP and PO to determine whether legacy drivers and 09721 devices are installed in the system. This routine is conceptually a 09722 QUERY_REMOVE_DEVICE and QUERY_POWER-like interface for legacy drivers 09723 and devices. 09724 09725 Parameters: 09726 09727 VetoList - A pointer to a PWSTR. (Optional) If specified, 09728 IoGetLegacyVetoList will allocate a veto list, and return a 09729 pointer to the veto list in VetoList. 09730 09731 VetoType - A pointer to a PNP_VETO_TYPE. If no legacy drivers 09732 or devices are found in the system, VetoType is assigned 09733 PNP_VetoTypeUnknown. If one or more legacy drivers are installed, 09734 VetoType is assigned PNP_VetoLegacyDriver. If one or more 09735 legacy devices are installed, VetoType is assigned 09736 PNP_VetoLegacyDevice. VetoType is assigned independent of 09737 whether a VetoList is created. 09738 09739 ReturnValue: 09740 09741 An NTSTATUS value indicating whether the IoGetLegacyVetoList() operation 09742 was successful. 09743 09744 --*/ 09745 { 09746 NTSTATUS Status; 09747 IO_GET_LEGACY_VETO_LIST_CONTEXT Context; 09748 UNICODE_STRING UnicodeString; 09749 09750 // 09751 // Initialize the veto list. 09752 // 09753 09754 if (VetoList != NULL) { 09755 *VetoList = NULL; 09756 } 09757 09758 // 09759 // Initialize the veto type. 09760 // 09761 09762 ASSERT(VetoType != NULL); 09763 09764 *VetoType = PNP_VetoTypeUnknown; 09765 09766 // 09767 // Initialize the status. 09768 // 09769 09770 Status = STATUS_SUCCESS; 09771 09772 if (PnPInitialized == FALSE) { 09773 09774 // 09775 // Can't touch anything, but nothing is really started either. 09776 // 09777 return Status; 09778 } 09779 09780 // 09781 // Initialize our local context. 09782 // 09783 09784 Context.VetoList = VetoList; 09785 Context.VetoListLength = 0; 09786 Context.VetoType = VetoType; 09787 Context.Status = &Status; 09788 09789 // 09790 // Enumerate all driver objects. This process can: (1) modify 09791 // the veto list, (2) modify the veto type and/or (3) modify the 09792 // status. 09793 // 09794 09795 IopGetLegacyVetoListDrivers(&Context); 09796 09797 // 09798 // If the driver enumeration process was successful and no legacy 09799 // drivers were detected, enumerate all device nodes. The same 09800 // context values as above may be modified during device enumeration. 09801 // 09802 09803 if (NT_SUCCESS(Status)) { 09804 09805 if (*VetoType == PNP_VetoTypeUnknown) { 09806 09807 IopAcquireEnumerationLock(NULL); 09808 09809 IopGetLegacyVetoListDeviceNode( 09810 IopRootDeviceNode, 09811 &Context 09812 ); 09813 09814 IopReleaseEnumerationLock(NULL); 09815 09816 } 09817 09818 } 09819 09820 // 09821 // If the previous operation(s) was/were successful, and the caller 09822 // provided a veto list pointer and we have constructed a veto 09823 // list, terminate the veto list with an empty string, i.e. MULTI_SZ. 09824 // 09825 09826 if (NT_SUCCESS(Status)) { 09827 09828 if (*VetoType != PNP_VetoTypeUnknown) { 09829 09830 if (VetoList != NULL) { 09831 09832 RtlInitUnicodeString( 09833 &UnicodeString, 09834 L"" 09835 ); 09836 09837 IopAppendLegacyVeto( 09838 &Context, 09839 &UnicodeString 09840 ); 09841 09842 } 09843 09844 } 09845 09846 } 09847 09848 // 09849 // If a previous operation was unsuccessful, free any veto list we may have 09850 // allocated along the way. 09851 // 09852 09853 if (!NT_SUCCESS(Status)) { 09854 09855 if (VetoList != NULL && *VetoList != NULL) { 09856 ExFreePool(*VetoList); 09857 *VetoList = NULL; 09858 } 09859 09860 } 09861 09862 return Status; 09863 }

NTSTATUS IoGetRelatedTargetDevice IN PFILE_OBJECT  FileObject,
OUT PDEVICE_OBJECT DeviceObject
 

Definition at line 8120 of file pnpioapi.c.

References IopGetRelatedTargetDevice(), NT_SUCCESS, NTSTATUS(), NULL, and _DEVICE_NODE::PhysicalDeviceObject.

Referenced by FsRtlNotifyVolumeEvent(), and NtSetVolumeInformationFile().

08127 : 08128 08129 IoGetRelatedTargetDevice retrieves the device object associated with 08130 the specified file object and then sends a query device relations irp 08131 to that device object. 08132 08133 NOTE: The PDO associated with the returned device node has been referenced, 08134 and must be dereferenced when no longer needed. 08135 08136 Arguments: 08137 08138 FileObject - Specifies the file object that is associated with the device 08139 object that will receive the query device relations irp. 08140 08141 DeviceObject - Returns the related target device object. 08142 08143 ReturnValue 08144 08145 Returns an NTSTATUS value. 08146 08147 --*/ 08148 08149 { 08150 NTSTATUS status; 08151 PDEVICE_NODE deviceNode = NULL; 08152 08153 status = IopGetRelatedTargetDevice( FileObject, &deviceNode ); 08154 if (NT_SUCCESS(status) && deviceNode != NULL) { 08155 *DeviceObject = deviceNode->PhysicalDeviceObject; 08156 } 08157 return status; 08158 }

VOID IoInvalidateDeviceRelations PDEVICE_OBJECT  DeviceObject,
DEVICE_RELATION_TYPE  Type
 

Definition at line 1395 of file pnpioapi.c.

References ASSERT_PDO, BusRelations, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_BEING_ENUMERATED, DNF_ENUMERATION_REQUEST_QUEUED, DNF_IO_INVALIDATE_DEVICE_RELATIONS_PENDING, DNF_STARTED, EjectionRelations, _DEVICE_NODE::Flags, IopPnPSpinLock, IopRequestDeviceAction(), NULL, PoInvalidateDevicePowerRelations(), PowerRelations, and ReenumerateDeviceTree.

Referenced by IopProcessNewProfileStateCallback(), VideoPortCalloutThread(), and xxxUserPowerEventCalloutWorker().

01402 : 01403 01404 This API notifies the system that changes have occurred in the device 01405 relations of the specified type for the supplied DeviceObject. All 01406 cached information concerning the relationships must be invalidated, 01407 and if needed re-obtained via IRP_MN_QUERY_DEVICE_RELATIONS. 01408 01409 Parameters: 01410 01411 DeviceObject - the PDEVICE_OBJECT for which the specified relation type 01412 information has been invalidated. This pointer is valid 01413 for the duration of the call. 01414 01415 Type - specifies the type of the relation being invalidated. 01416 01417 ReturnValue: 01418 01419 none. 01420 01421 --*/ 01422 01423 { 01424 01425 PDEVICE_NODE deviceNode; 01426 KIRQL oldIrql; 01427 01428 ASSERT_PDO(DeviceObject); 01429 01430 switch (Type) { 01431 case BusRelations: 01432 01433 // 01434 // If the call was made before PnP completes device enumeration 01435 // we can safely ignore it. PnP manager will do it without 01436 // driver's request. 01437 // 01438 01439 deviceNode = (PDEVICE_NODE) DeviceObject->DeviceObjectExtension->DeviceNode; 01440 if (deviceNode) { 01441 01442 ExAcquireSpinLock(&IopPnPSpinLock, &oldIrql); 01443 if (deviceNode->Flags & DNF_BEING_ENUMERATED) { 01444 deviceNode->Flags |= DNF_IO_INVALIDATE_DEVICE_RELATIONS_PENDING; 01445 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 01446 } else if ((deviceNode->Flags & DNF_STARTED) && 01447 !(deviceNode->Flags & DNF_ENUMERATION_REQUEST_QUEUED)) { 01448 deviceNode->Flags |= DNF_ENUMERATION_REQUEST_QUEUED; 01449 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 01450 01451 IopRequestDeviceAction( DeviceObject, 01452 ReenumerateDeviceTree, 01453 NULL, 01454 NULL ); 01455 } else { 01456 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 01457 } 01458 } 01459 break; 01460 01461 case EjectionRelations: 01462 01463 // 01464 // For Ejection relation change, we will ignore it. We don't keep track 01465 // the Ejection relation. We will query the Ejection relation only when 01466 // we are requested to eject a device. 01467 01468 break; 01469 01470 case PowerRelations: 01471 01472 // 01473 // Call off to Po code, which will do the right thing 01474 // 01475 PoInvalidateDevicePowerRelations(DeviceObject); 01476 break; 01477 } 01478 }

VOID IoInvalidateDeviceState IN PDEVICE_OBJECT  PhysicalDeviceObject  ) 
 

Definition at line 6281 of file pnpioapi.c.

References ASSERT_PDO, DNF_REMOVE_PENDING_CLOSES, DNF_STARTED, _DEVICE_NODE::Flags, IopInvalidateDeviceStateWorker(), IopQueueDeviceWorkItem(), and NULL.

06287 : 06288 06289 This API will cause the PnP manager to send the specified PDO an IRP_MN_QUERY_PNP_DEVICE_STATE 06290 IRP. 06291 06292 Parameters: 06293 06294 PhysicalDeviceObject - Provides a pointer to the PDO who's state is to be invalidated. 06295 06296 Return Value: 06297 06298 none. 06299 06300 --*/ 06301 { 06302 PDEVICE_NODE deviceNode; 06303 06304 ASSERT_PDO(PhysicalDeviceObject); 06305 06306 // 06307 // If the call was made before PnP completes device enumeration 06308 // we can safely ignore it. PnP manager will do it without 06309 // driver's request. If the device was already removed or surprised 06310 // removed then ignore it as well since this is only valid for started 06311 // devices. 06312 // 06313 06314 deviceNode = (PDEVICE_NODE)PhysicalDeviceObject->DeviceObjectExtension->DeviceNode; 06315 06316 if ((deviceNode->Flags & (DNF_STARTED | DNF_REMOVE_PENDING_CLOSES)) != DNF_STARTED) { 06317 return; 06318 } 06319 06320 IopQueueDeviceWorkItem( PhysicalDeviceObject, 06321 IopInvalidateDeviceStateWorker, 06322 NULL); 06323 }

BOOLEAN IoIsWdmVersionAvailable IN UCHAR  MajorVersion,
IN UCHAR  MinorVersion
 

Definition at line 8275 of file pnpioapi.c.

References WDM_MAJORVERSION, and WDM_MINORVERSION.

08282 : 08283 08284 This routine reports whether WDM functionality is available that 08285 is greater than or equal to the specified major and minor version. 08286 08287 Parameters: 08288 08289 MajorVersion - Supplies the WDM major version that is required. 08290 08291 MinorVersion - Supplies the WDM minor version that is required. 08292 08293 Return Value: 08294 08295 If WDM support is available at _at least_ the requested level, the 08296 return value is TRUE, otherwise it is FALSE. 08297 08298 --*/ 08299 08300 { 08301 return ((MajorVersion < WDM_MAJORVERSION) || 08302 ((MajorVersion == WDM_MAJORVERSION) && (MinorVersion <= WDM_MINORVERSION))); 08303 }

NTSTATUS IoNotifyPowerOperationVetoed IN POWER_ACTION  VetoedPowerOperation,
IN PDEVICE_OBJECT TargetedDeviceObject  OPTIONAL,
IN PDEVICE_OBJECT  VetoingDeviceObject
 

Definition at line 9171 of file pnpioapi.c.

References _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, _DEVICE_NODE::InstancePath, IopRootDeviceNode, NULL, PAGED_CODE, _DEVICE_NODE::PhysicalDeviceObject, and PpSetPowerVetoEvent().

09179 { 09180 PDEVICE_NODE deviceNode, vetoingDeviceNode; 09181 PDEVICE_OBJECT deviceObject; 09182 09183 PAGED_CODE(); 09184 09185 // 09186 // We have to types of power events, system wide (standby) and device 09187 // targetted (warm eject). Rather than have two different veto mechanisms, 09188 // we just retarget the operation against the root device if none is 09189 // specified (hey, someone's gotta represent the system, right?). 09190 // 09191 if (TargetedDeviceObject) { 09192 09193 deviceObject = TargetedDeviceObject; 09194 09195 } else { 09196 09197 deviceObject = IopRootDeviceNode->PhysicalDeviceObject; 09198 } 09199 09200 deviceNode = (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode; 09201 if (!deviceNode) { 09202 return STATUS_INVALID_PARAMETER_2; 09203 } 09204 09205 vetoingDeviceNode = (PDEVICE_NODE)VetoingDeviceObject->DeviceObjectExtension->DeviceNode; 09206 if (!vetoingDeviceNode) { 09207 return STATUS_INVALID_PARAMETER_3; 09208 } 09209 09210 return PpSetPowerVetoEvent( 09211 VetoedPowerOperation, 09212 NULL, 09213 NULL, 09214 deviceObject, 09215 PNP_VetoDevice, 09216 &vetoingDeviceNode->InstancePath 09217 ); 09218 }

NTSTATUS IoOpenDeviceInterfaceRegistryKey IN PUNICODE_STRING  SymbolicLinkName,
IN ACCESS_MASK  DesiredAccess,
OUT PHANDLE  DeviceInterfaceKey
 

Definition at line 3624 of file pnpioapi.c.

References ExAcquireResourceExclusive, ExReleaseResource, IopCreateRegistryKeyEx(), IopDeviceInterfaceKeysFromSymbolicLink(), KeEnterCriticalRegion, KeLeaveCriticalRegion, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PpRegistryDeviceResource, and TRUE.

03632 : 03633 03634 This routine will open the registry key where the data associated with a 03635 specific device interface can be stored. 03636 03637 Parameters: 03638 03639 SymbolicLinkName - Supplies a pointer to the symbolic link name which was 03640 returned by IoRegisterDeviceInterface when the device class was registered. 03641 03642 DesiredAccess - Supplies the access privileges to the key the caller wants. 03643 03644 DeviceInterfaceKey - Supplies a pointer to a handle which on success will 03645 contain the handle to the requested registry key. 03646 03647 Return Value: 03648 03649 Status code that indicates whether or not the function was successful. 03650 03651 --*/ 03652 03653 { 03654 NTSTATUS status; 03655 HANDLE hKey; 03656 UNICODE_STRING unicodeString; 03657 03658 PAGED_CODE(); 03659 03660 // 03661 // Enter critical section and acquire a lock on the registry. Both these 03662 // mechanisms are required to prevent deadlock in the case where an APC 03663 // routine calls this routine after the registry resource has been claimed 03664 // in this case it would wait blocking this thread so the registry would 03665 // never be released -> deadlock. Critical sectioning the registry manipulation 03666 // portion solves this problem 03667 // 03668 03669 KeEnterCriticalRegion(); 03670 ExAcquireResourceExclusive(&PpRegistryDeviceResource, TRUE); 03671 03672 // 03673 // Open the interface device key 03674 // 03675 03676 status = IopDeviceInterfaceKeysFromSymbolicLink(SymbolicLinkName, 03677 KEY_READ, 03678 NULL, 03679 NULL, 03680 &hKey 03681 ); 03682 if(!NT_SUCCESS(status)) { 03683 goto clean0; 03684 } 03685 03686 // 03687 // Open the "Device Parameters" subkey. 03688 // 03689 03690 PiWstrToUnicodeString(&unicodeString, REGSTR_KEY_DEVICEPARAMETERS); 03691 status = IopCreateRegistryKeyEx( DeviceInterfaceKey, 03692 hKey, 03693 &unicodeString, 03694 DesiredAccess, 03695 REG_OPTION_NON_VOLATILE, 03696 NULL 03697 ); 03698 ZwClose(hKey); 03699 03700 clean0: 03701 ExReleaseResource(&PpRegistryDeviceResource); 03702 KeLeaveCriticalRegion(); 03703 03704 return status; 03705 }

NTSTATUS IoOpenDeviceRegistryKey IN PDEVICE_OBJECT  PhysicalDeviceObject,
IN ULONG  DevInstKeyType,
IN ACCESS_MASK  DesiredAccess,
OUT PHANDLE  DevInstRegKey
 

Definition at line 810 of file pnpioapi.c.

References ASSERT, ExAcquireResourceExclusive, ExAllocatePool, ExFreePool(), ExReleaseResource, _DEVICE_NODE::InstancePath, IopCreateRegistryKeyEx(), IopDeviceObjectToDeviceInstance(), IopGetRegistryValue(), IopOpenDeviceParametersSubkey(), IopOpenRegistryKeyEx(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KEY_VALUE_DATA, MAX_RESTPATH_BUF_LEN, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, PATH_CONTROL_CLASS, PATH_CURRENTCONTROLSET, PATH_CURRENTCONTROLSET_HW_PROFILE_CURRENT, PATH_ENUM, PLUGPLAY_REGKEY_CURRENT_HWPROFILE, PLUGPLAY_REGKEY_DEVICE, PLUGPLAY_REGKEY_DRIVER, PpRegistryDeviceResource, RtlAppendUnicodeStringToString(), RtlAppendUnicodeToString(), and TRUE.

00819 : 00820 00821 This routine returns a handle to an opened registry key that the driver 00822 may use to store/retrieve configuration information specific to a particular 00823 device instance. 00824 00825 The driver must call ZwClose to close the handle returned from this api 00826 when access is no longer required. 00827 00828 Parameters: 00829 00830 DeviceObject - Supples the device object of the physical device instance to 00831 open a registry storage key for. Normally it is a device object 00832 created by the hal bus extender. 00833 00834 DevInstKeyType - Supplies flags specifying which storage key associated with 00835 the device instance is to be opened. May be a combination of 00836 the following value: 00837 00838 PLUGPLAY_REGKEY_DEVICE - Open a key for storing device specific 00839 (driver-independent) information relating to the device instance. 00840 The flag may not be specified with PLUGPLAY_REGKEY_DRIVER. 00841 00842 PLUGPLAY_REGKEY_DRIVER - Open a key for storing driver-specific 00843 information relating to the device instance, This flag may 00844 not be specified with PLUGPLAY_REGKEY_DEVICE. 00845 00846 PLUGPLAY_REGKEY_CURRENT_HWPROFILE - If this flag is specified, 00847 then a key in the current hardware profile branch will be 00848 opened for the specified storage type. This allows the driver 00849 to access configuration information that is hardware profile 00850 specific. 00851 00852 DesiredAccess - Specifies the access mask for the key to be opened. 00853 00854 DevInstRegKey - Supplies the address of a variable that receives a handle to the 00855 opened key for the specified registry storage location. 00856 00857 Return Value: 00858 00859 Status code that indicates whether or not the function was successful. 00860 00861 --*/ 00862 00863 { 00864 00865 NTSTATUS status, appendStatus; 00866 HANDLE hBasePath; 00867 UNICODE_STRING unicodeBasePath, unicodeRestPath; 00868 00869 PAGED_CODE(); 00870 00871 // 00872 // Until SCSIPORT stops passing non PDOs allow the system to boot. 00873 // 00874 // ASSERT_PDO(PhysicalDeviceObject); 00875 // 00876 00877 // 00878 // Initialise out parameters 00879 // 00880 00881 *DevInstRegKey = NULL; 00882 00883 // 00884 // Allocate a buffer to build the RestPath string in 00885 // 00886 00887 if(!(unicodeRestPath.Buffer = ExAllocatePool(PagedPool, MAX_RESTPATH_BUF_LEN))) { 00888 status = STATUS_INSUFFICIENT_RESOURCES; 00889 goto clean0; 00890 } 00891 00892 unicodeRestPath.Length=0; 00893 unicodeRestPath.MaximumLength=MAX_RESTPATH_BUF_LEN; 00894 00895 // 00896 // Select the base path to the CurrentControlSet based on if we are dealing with 00897 // a hardware profile or not 00898 // 00899 00900 if(DevInstKeyType & PLUGPLAY_REGKEY_CURRENT_HWPROFILE) { 00901 PiWstrToUnicodeString(&unicodeBasePath, PATH_CURRENTCONTROLSET_HW_PROFILE_CURRENT); 00902 00903 } else { 00904 PiWstrToUnicodeString(&unicodeBasePath, PATH_CURRENTCONTROLSET); 00905 } 00906 00907 // 00908 // Enter critical section and acquire a lock on the registry. Both these 00909 // mechanisms are required to prevent deadlock in the case where an APC 00910 // routine calls this routine after the registry resource has been claimed 00911 // in this case it would wait blocking this thread so the registry would 00912 // never be released -> deadlock. Critical sectioning the registry manipulation 00913 // portion solves this problem 00914 // 00915 00916 KeEnterCriticalRegion(); 00917 ExAcquireResourceExclusive(&PpRegistryDeviceResource, TRUE); 00918 00919 // 00920 // Open the base registry key 00921 // 00922 00923 status = IopOpenRegistryKeyEx( &hBasePath, 00924 NULL, 00925 &unicodeBasePath, 00926 KEY_READ 00927 ); 00928 00929 if(!NT_SUCCESS(status)) { 00930 goto clean1; 00931 } 00932 00933 // 00934 // Build the RestPath string 00935 // 00936 00937 switch (DevInstKeyType) { 00938 00939 case PLUGPLAY_REGKEY_DEVICE: 00940 case PLUGPLAY_REGKEY_DEVICE + PLUGPLAY_REGKEY_CURRENT_HWPROFILE: 00941 { 00942 PDEVICE_NODE pDeviceNode; 00943 00944 // 00945 // Initialise the rest path with Enum\ 00946 // 00947 00948 appendStatus = RtlAppendUnicodeToString(&unicodeRestPath, PATH_ENUM); 00949 ASSERT(NT_SUCCESS( appendStatus )); 00950 // 00951 // Get the Enumerator\DeviceID\InstanceID path from the DeviceNode 00952 // 00953 00954 pDeviceNode = (PDEVICE_NODE) PhysicalDeviceObject->DeviceObjectExtension->DeviceNode; 00955 00956 // 00957 // Ensure this is a PDO and not an FDO (only PDO's have a DeviceNode) 00958 // 00959 00960 if (pDeviceNode) { 00961 appendStatus = RtlAppendUnicodeStringToString(&unicodeRestPath, &(pDeviceNode->InstancePath)); 00962 ASSERT(NT_SUCCESS( appendStatus )); 00963 } else { 00964 status = STATUS_INVALID_DEVICE_REQUEST; 00965 } 00966 00967 break; 00968 } 00969 00970 case PLUGPLAY_REGKEY_DRIVER: 00971 case PLUGPLAY_REGKEY_DRIVER + PLUGPLAY_REGKEY_CURRENT_HWPROFILE: 00972 { 00973 00974 HANDLE hDeviceKey; 00975 PKEY_VALUE_FULL_INFORMATION pDriverKeyInfo; 00976 00977 // 00978 // Initialise the rest path with Control\Class\ 00979 // 00980 00981 appendStatus = RtlAppendUnicodeToString(&unicodeRestPath, PATH_CONTROL_CLASS); 00982 ASSERT(NT_SUCCESS( appendStatus )); 00983 00984 // 00985 // Open the device instance key for this device 00986 // 00987 00988 status = IopDeviceObjectToDeviceInstance(PhysicalDeviceObject, &hDeviceKey, KEY_READ); 00989 00990 if(!NT_SUCCESS(status)){ 00991 goto clean1; 00992 } 00993 00994 // 00995 // See if we have a driver value 00996 // 00997 00998 status = IopGetRegistryValue(hDeviceKey, REGSTR_VALUE_DRIVER, &pDriverKeyInfo ); 00999 01000 if(NT_SUCCESS(status)){ 01001 01002 if(pDriverKeyInfo->Type == REG_SZ) { 01003 01004 // 01005 // Append <DevInstClass><ClassInstanceOrdinal> 01006 // 01007 01008 appendStatus = RtlAppendUnicodeToString(&unicodeRestPath, (PWSTR) KEY_VALUE_DATA(pDriverKeyInfo)); 01009 ASSERT(NT_SUCCESS( appendStatus )); 01010 01011 } else { 01012 // 01013 // We have a driver key with a non REG_SZ type - something is wrong - blame the PDO! 01014 // 01015 01016 status = STATUS_INVALID_PARAMETER_1; 01017 } 01018 01019 ExFreePool(pDriverKeyInfo); 01020 } 01021 01022 ZwClose(hDeviceKey); 01023 01024 break; 01025 } 01026 default: 01027 status = STATUS_INVALID_PARAMETER_3; 01028 goto clean2; 01029 } 01030 01031 01032 // 01033 // If we succeeded in building the rest path then open the key and hand it back to the caller 01034 // 01035 01036 if (NT_SUCCESS(status)){ 01037 if (DevInstKeyType == PLUGPLAY_REGKEY_DEVICE) { 01038 01039 status = IopOpenDeviceParametersSubkey(DevInstRegKey, 01040 hBasePath, 01041 &unicodeRestPath, 01042 DesiredAccess); 01043 } else { 01044 01045 status = IopCreateRegistryKeyEx( DevInstRegKey, 01046 hBasePath, 01047 &unicodeRestPath, 01048 DesiredAccess, 01049 REG_OPTION_NON_VOLATILE, 01050 NULL 01051 ); 01052 } 01053 } 01054 01055 // 01056 // Free up resources 01057 // 01058 01059 clean2: 01060 ZwClose(hBasePath); 01061 clean1: 01062 ExReleaseResource(&PpRegistryDeviceResource); 01063 KeLeaveCriticalRegion(); 01064 ExFreePool(unicodeRestPath.Buffer); 01065 clean0: 01066 return status; 01067 01068 }

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 }

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 IopAppendBuffer IN PBUFFER_INFO  Info,
IN PVOID  Data,
IN ULONG  DataSize
 

Definition at line 2575 of file pnpioapi.c.

References ASSERT, IopResizeBuffer(), NT_SUCCESS, NTSTATUS(), and TRUE.

Referenced by IopGetDeviceInterfaces().

02583 : 02584 02585 Copies the data to the end of the buffer, resizing if necessary. The current 02586 position is set to the end of the data just added. 02587 02588 Parameters: 02589 02590 Info - Pointer to a buffer info structure to be used to manage the buffer 02591 02592 Data - Pointer to the data to be added to the buffer 02593 02594 DataSize - The size of the data pointed to by Data in bytes 02595 02596 Return Value: 02597 02598 Status code that indicates whether or not the function was successful. 02599 02600 --*/ 02601 { 02602 02603 NTSTATUS status = STATUS_SUCCESS; 02604 ULONG free, used; 02605 02606 ASSERT(Info); 02607 02608 used = (ULONG)(Info->Current - Info->Buffer); 02609 free = Info->MaxSize - used; 02610 02611 if (free < DataSize) { 02612 status = IopResizeBuffer(Info, used + DataSize, TRUE); 02613 02614 if (!NT_SUCCESS(status)) { 02615 goto clean0; 02616 } 02617 02618 } 02619 02620 // 02621 // Copy the data into the buffer 02622 // 02623 02624 RtlCopyMemory(Info->Current, 02625 Data, 02626 DataSize); 02627 02628 // 02629 // Advance down the buffer 02630 // 02631 02632 Info->Current += DataSize; 02633 02634 clean0: 02635 return status; 02636 02637 }

BOOLEAN IopAppendLegacyVeto IN PIO_GET_LEGACY_VETO_LIST_CONTEXT  Context,
IN PUNICODE_STRING  VetoName
 

Definition at line 9357 of file pnpioapi.c.

References Buffer, ExAllocatePool, ExFreePool(), FALSE, L, NonPagedPool, NULL, and TRUE.

Referenced by IoGetLegacyVetoList(), IopGetLegacyVetoListDevice(), and IopGetLegacyVetoListDrivers().

09363 : 09364 09365 This routine appends a veto (driver name or device instance path) to the 09366 veto list. 09367 09368 Parameters: 09369 09370 Context - An IO_GET_LEGACY_VETO_LIST_CONTEXT pointer. 09371 09372 VetoName - The name of the driver/device to append to the veto list. 09373 09374 ReturnValue: 09375 09376 A BOOLEAN which indicates whether the append operation was successful. 09377 09378 --*/ 09379 { 09380 ULONG Length; 09381 PWSTR Buffer; 09382 09383 // 09384 // Compute the length of the (new) veto list. This is the length of 09385 // the old veto list + the size of the new veto + the size of the 09386 // terminating '\0'. 09387 // 09388 09389 Length = Context->VetoListLength + VetoName->Length + sizeof (WCHAR); 09390 09391 // 09392 // Allocate the new veto list. 09393 // 09394 09395 Buffer = ExAllocatePool( 09396 NonPagedPool, 09397 Length 09398 ); 09399 09400 // 09401 // If we succeeded in allocating the new veto list, copy the old 09402 // veto list to the new list, append the new veto, and finally, 09403 // append a terminating '\0'. Otherwise, update the status to 09404 // indicate an error; IopGetLegacyVetoList will free the veto list 09405 // before it returns. 09406 // 09407 09408 if (Buffer != NULL) { 09409 09410 if (*Context->VetoList != NULL) { 09411 09412 RtlMoveMemory( 09413 Buffer, 09414 *Context->VetoList, 09415 Context->VetoListLength 09416 ); 09417 09418 ExFreePool(*Context->VetoList); 09419 09420 } 09421 09422 RtlMoveMemory( 09423 &Buffer[Context->VetoListLength / sizeof (WCHAR)], 09424 VetoName->Buffer, 09425 VetoName->Length 09426 ); 09427 09428 Buffer[Length / sizeof (WCHAR) - 1] = L'\0'; 09429 09430 *Context->VetoList = Buffer; 09431 Context->VetoListLength = Length; 09432 09433 return TRUE; 09434 09435 } else { 09436 09437 *Context->Status = STATUS_INSUFFICIENT_RESOURCES; 09438 09439 return FALSE; 09440 09441 } 09442 }

NTSTATUS IopBuildSymbolicLinkStrings IN PUNICODE_STRING  DeviceString,
IN PUNICODE_STRING  GuidString,
IN PUNICODE_STRING ReferenceString  OPTIONAL,
OUT PUNICODE_STRING  UserString,
OUT PUNICODE_STRING  KernelString
 

Definition at line 5137 of file pnpioapi.c.

References ASSERT, IopAllocateUnicodeString(), IopConstStringSize, IopFreeAllocatedUnicodeString(), IopReplaceSeperatorWithPound(), KERNEL_SYMLINK_STRING_PREFIX, NT_SUCCESS, NTSTATUS(), PAGED_CODE, REPLACED_SEPERATOR_STRING, RtlAppendUnicodeStringToString(), RtlAppendUnicodeToString(), RtlCopyUnicodeString(), SEPERATOR_STRING, USER_SYMLINK_STRING_PREFIX, and USHORT.

Referenced by IoGetDeviceInterfaceAlias(), and IopRegisterDeviceInterface().

05146 : 05147 05148 This routine will construct various strings used in the registration of 05149 function device class associations (IoRegisterDeviceClassAssociation). 05150 The specific strings are detailed below 05151 05152 Parameters: 05153 05154 DeviceString - Supplies a pointer to the instance path of the device. 05155 It is of the form <Enumerator>\<Device>\<Instance>. 05156 05157 GuidString - Supplies a pointer to the string representation of the 05158 function class guid. 05159 05160 ReferenceString - Supplies a pointer to the reference string for the given 05161 device to exhibit the given function. This is optional 05162 05163 UserString - Supplies a pointer to an uninitialised string which on success 05164 will contain the string to be assigned to the "SymbolicLink" value under the 05165 KeyString. It is of the format \\?\<MungedDeviceString>\<GuidString>\<Reference> 05166 When no longer required it should be freed using IopFreeAllocatedUnicodeString. 05167 05168 KernelString - Supplies a pointer to an uninitialised string which on success 05169 will contain the kernel mode path of the device and is of the format 05170 \??\<MungedDeviceString>\<GuidString>\<Reference>. When no longer required it 05171 should be freed using IopFreeAllocatedUnicodeString. 05172 05173 Return Value: 05174 05175 Status code that indicates whether or not the function was successful. 05176 05177 --*/ 05178 05179 { 05180 NTSTATUS status; 05181 USHORT length, count; 05182 UNICODE_STRING mungedDeviceString; 05183 05184 PAGED_CODE(); 05185 05186 // 05187 // The code is optimised to use the fact that \\.\ and \??\ are the same size - if 05188 // these prefixes change then we need to change the code. 05189 // 05190 05191 ASSERT(IopConstStringSize(KERNEL_SYMLINK_STRING_PREFIX) == IopConstStringSize(USER_SYMLINK_STRING_PREFIX)); 05192 05193 // 05194 // Calculate the lengths of the strings 05195 // 05196 05197 length = IopConstStringSize(KERNEL_SYMLINK_STRING_PREFIX) + DeviceString->Length + 05198 IopConstStringSize(REPLACED_SEPERATOR_STRING) + GuidString->Length; 05199 05200 if(ARGUMENT_PRESENT(ReferenceString)) { 05201 length += IopConstStringSize(SEPERATOR_STRING) + ReferenceString->Length; 05202 } 05203 05204 // 05205 // Allocate space for the strings 05206 // 05207 05208 status = IopAllocateUnicodeString(KernelString, length); 05209 if (!NT_SUCCESS(status)) { 05210 goto clean0; 05211 } 05212 05213 status = IopAllocateUnicodeString(UserString, length); 05214 if (!NT_SUCCESS(status)) { 05215 goto clean1; 05216 } 05217 05218 // 05219 // Allocate a temporary string to hold the munged device string 05220 // 05221 05222 status = IopAllocateUnicodeString(&mungedDeviceString, DeviceString->Length); 05223 if (!NT_SUCCESS(status)) { 05224 goto clean2; 05225 } 05226 05227 // 05228 // Copy and munge the device string 05229 // 05230 05231 status = IopReplaceSeperatorWithPound(&mungedDeviceString, DeviceString); 05232 if (!NT_SUCCESS(status)) { 05233 goto clean3; 05234 } 05235 05236 // 05237 // Construct the user mode string 05238 // 05239 05240 RtlAppendUnicodeToString(UserString, USER_SYMLINK_STRING_PREFIX); 05241 RtlAppendUnicodeStringToString(UserString, &mungedDeviceString); 05242 RtlAppendUnicodeToString(UserString, REPLACED_SEPERATOR_STRING); 05243 RtlAppendUnicodeStringToString(UserString, GuidString); 05244 05245 if (ARGUMENT_PRESENT(ReferenceString)) { 05246 RtlAppendUnicodeToString(UserString, SEPERATOR_STRING); 05247 RtlAppendUnicodeStringToString(UserString, ReferenceString); 05248 } 05249 05250 ASSERT( UserString->Length == length ); 05251 05252 // 05253 // Construct the kernel mode string by replacing the prefix on the value string 05254 // 05255 05256 RtlCopyUnicodeString(KernelString, UserString); 05257 RtlCopyMemory(KernelString->Buffer, 05258 KERNEL_SYMLINK_STRING_PREFIX, 05259 IopConstStringSize(KERNEL_SYMLINK_STRING_PREFIX) 05260 ); 05261 05262 clean3: 05263 IopFreeAllocatedUnicodeString(&mungedDeviceString); 05264 05265 clean2: 05266 if (!NT_SUCCESS(status)) { 05267 IopFreeAllocatedUnicodeString(UserString); 05268 } 05269 05270 clean1: 05271 if (!NT_SUCCESS(status)) { 05272 IopFreeAllocatedUnicodeString(KernelString); 05273 } 05274 05275 clean0: 05276 return status; 05277 }

VOID IopDereferenceNotify PNOTIFY_ENTRY_HEADER  Notify  ) 
 

Definition at line 6600 of file pnpioapi.c.

References ASSERT, _NOTIFY_ENTRY_HEADER::DriverObject, _NOTIFY_ENTRY_HEADER::EventCategory, EventCategoryTargetDeviceChange, ExFreePool(), NULL, ObDereferenceObject, PAGED_CODE, _TARGET_DEVICE_NOTIFY_ENTRY::PhysicalDeviceObject, PTARGET_DEVICE_NOTIFY_ENTRY, _NOTIFY_ENTRY_HEADER::RefCount, and _NOTIFY_ENTRY_HEADER::Unregistered.

Referenced by IopNotifyDeviceClassChange(), IopNotifyHwProfileChange(), IopNotifyTargetDeviceChange(), IopProcessDeferredRegistrations(), and IoUnregisterPlugPlayNotification().

06606 : 06607 06608 This routine decrements the reference count for a notification entry, removing 06609 the entry from the list and freeing the associated memory if there are no 06610 outstanding reference counts. 06611 06612 Parameters: 06613 06614 Notify - Supplies a pointer to the notification entry to be referenced 06615 06616 Return Value: 06617 06618 None 06619 06620 Note: 06621 06622 The appropriate symchronization lock must be held on the notification 06623 list before this routine can be called 06624 06625 --*/ 06626 06627 { 06628 PAGED_CODE(); 06629 06630 ASSERT(Notify); 06631 ASSERT(Notify->RefCount > 0); 06632 06633 Notify->RefCount--; 06634 06635 if (Notify->RefCount == 0) { 06636 06637 // 06638 // If the refcount is zero then the node should have been deregisterd 06639 // and is no longer needs to be in the list so remove and free it 06640 // 06641 06642 ASSERT(Notify->Unregistered); 06643 06644 // 06645 // Dereference the driver object that registered for notifications 06646 // 06647 06648 ObDereferenceObject(Notify->DriverObject); 06649 06650 // 06651 // If this notification entry is for target device change, dereference 06652 // the PDO upon which this notification entry was hooked. 06653 // 06654 06655 if (Notify->EventCategory == EventCategoryTargetDeviceChange) { 06656 PTARGET_DEVICE_NOTIFY_ENTRY entry = (PTARGET_DEVICE_NOTIFY_ENTRY)Notify; 06657 06658 if (entry->PhysicalDeviceObject) { 06659 ObDereferenceObject(entry->PhysicalDeviceObject); 06660 entry->PhysicalDeviceObject = NULL; 06661 } 06662 } 06663 06664 RemoveEntryList((PLIST_ENTRY)Notify); 06665 06666 ExFreePool(Notify); 06667 06668 } 06669 }

NTSTATUS IopDeviceInterfaceKeysFromSymbolicLink IN PUNICODE_STRING  SymbolicLinkName,
IN ACCESS_MASK  DesiredAccess,
OUT PHANDLE DeviceInterfaceClassKey  OPTIONAL,
OUT PHANDLE DeviceInterfaceKey  OPTIONAL,
OUT PHANDLE DeviceInterfaceInstanceKey  OPTIONAL
 

Definition at line 3708 of file pnpioapi.c.

References ExAcquireResourceExclusive, ExReleaseResource, FALSE, IopOpenOrCreateDeviceInterfaceSubKeys(), IopOpenRegistryKeyEx(), IopParseSymbolicLinkName(), KeEnterCriticalRegion, KeLeaveCriticalRegion, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PpRegistryDeviceResource, and TRUE.

Referenced by IoGetDeviceInterfaceAlias(), IoOpenDeviceInterfaceRegistryKey(), IopProcessSetInterfaceState(), and IopUnregisterDeviceInterface().

03718 : 03719 03720 This routine will open the registry key where the data associated with the 03721 device pointed to by SymbolicLinkName is stored. If the path does not exist 03722 it will not be created. 03723 03724 Parameters: 03725 03726 SymbolicLinkName - Supplies a pointer to the symbolic link name. 03727 03728 DesiredAccess - Supplies the access privto the function class instance key the 03729 caller wants. 03730 03731 DeviceInterfaceClassKey - Optionally, supplies the address of a variable that 03732 receives a handle to the device class key for the interface. 03733 03734 DeviceInterfaceKey - Optionally, supplies the address of a variable that receives 03735 a handle to the device interface (parent) key. 03736 03737 DeviceInterfaceInstanceKey - Optionally, Supplies the address of a variable that 03738 receives a handle to the device interface instance key (i.e., the 03739 refstring-specific one). 03740 03741 Return Value: 03742 03743 Status code that indicates whether or not the function was successful. 03744 03745 03746 --*/ 03747 03748 { 03749 NTSTATUS status; 03750 UNICODE_STRING guidString, tempString; 03751 HANDLE hDeviceClasses, hFunctionClass; 03752 03753 PAGED_CODE(); 03754 03755 // 03756 // Get guid from symbolic link name 03757 // 03758 status = IopParseSymbolicLinkName(SymbolicLinkName, NULL, NULL, &guidString, NULL, NULL, NULL); 03759 03760 if(!NT_SUCCESS(status)){ 03761 goto clean0; 03762 } 03763 03764 // 03765 // Enter critical section and acquire a lock on the registry. Both these 03766 // mechanisms are required to prevent deadlock in the case where an APC 03767 // routine calls this routine after the registry resource has been claimed 03768 // in this case it would wait blocking this thread so the registry would 03769 // never be released -> deadlock. Critical sectioning the registry manipulation 03770 // portion solves this problem 03771 // 03772 03773 KeEnterCriticalRegion(); 03774 ExAcquireResourceExclusive(&PpRegistryDeviceResource, TRUE); 03775 03776 // 03777 // Open HKLM\System\CurrentControlSet\Control\DeviceClasses key 03778 // 03779 03780 PiWstrToUnicodeString(&tempString, REGSTR_FULL_PATH_DEVICE_CLASSES); 03781 status = IopOpenRegistryKeyEx( &hDeviceClasses, 03782 NULL, 03783 &tempString, 03784 KEY_READ 03785 ); 03786 03787 if( !NT_SUCCESS(status) ){ 03788 goto clean1; 03789 } 03790 03791 // 03792 // Open function class GUID key 03793 // 03794 03795 status = IopOpenRegistryKeyEx( &hFunctionClass, 03796 hDeviceClasses, 03797 &guidString, 03798 KEY_READ 03799 ); 03800 03801 if( !NT_SUCCESS(status) ){ 03802 goto clean2; 03803 } 03804 03805 // 03806 // Open device interface instance key 03807 // 03808 status = IopOpenOrCreateDeviceInterfaceSubKeys(DeviceInterfaceKey, 03809 NULL, 03810 DeviceInterfaceInstanceKey, 03811 NULL, 03812 hFunctionClass, 03813 SymbolicLinkName, 03814 DesiredAccess, 03815 FALSE 03816 ); 03817 03818 if((!NT_SUCCESS(status)) || (!ARGUMENT_PRESENT(DeviceInterfaceClassKey))) { 03819 ZwClose(hFunctionClass); 03820 } else { 03821 *DeviceInterfaceClassKey = hFunctionClass; 03822 } 03823 03824 clean2: 03825 ZwClose(hDeviceClasses); 03826 clean1: 03827 ExReleaseResource(&PpRegistryDeviceResource); 03828 KeLeaveCriticalRegion(); 03829 clean0: 03830 return status; 03831 03832 }

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 IopDropReferenceString OUT PUNICODE_STRING  OutString,
IN PUNICODE_STRING  InString
 

Definition at line 5353 of file pnpioapi.c.

References ASSERT, IopParseSymbolicLinkName(), NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

Referenced by IopProcessSetInterfaceState().

05360 : 05361 05362 This routine removes the reference string from a symbolic link name. No space 05363 is allocated for the out string so no attempt should be made to free the buffer 05364 of OutString. 05365 05366 Parameters: 05367 05368 SymbolicLinkName - Supplies a pointer to a symbolic link name string. 05369 Both the prefixed strings are valid. 05370 05371 GuidReferenceString - Supplies a pointer to an uninitialised string which on 05372 success will contain the symbolic link name without the reference string. 05373 See the note on storage allocation above. 05374 05375 Return Value: 05376 05377 Status code that indicates whether or not the function was successful. 05378 05379 Remarks: 05380 05381 The string returned in OutString is dependant on the buffer of 05382 InString and is only valid as long as InString is valid. 05383 05384 --*/ 05385 05386 { 05387 UNICODE_STRING refString; 05388 NTSTATUS status; 05389 BOOLEAN refStringPresent; 05390 05391 PAGED_CODE(); 05392 05393 ASSERT(InString); 05394 ASSERT(OutString); 05395 05396 OutString->Buffer = InString->Buffer; 05397 05398 status = IopParseSymbolicLinkName(InString, NULL, NULL, NULL, &refString, &refStringPresent, NULL); 05399 05400 if (NT_SUCCESS(status)) { 05401 // 05402 // If we have a refstring then subtract it's length 05403 // 05404 if (refStringPresent) { 05405 OutString->Length = InString->Length - (refString.Length + sizeof(WCHAR)); 05406 } else { 05407 OutString->Length = InString->Length; 05408 } 05409 05410 } else { 05411 // 05412 // Invalidate the returned string 05413 // 05414 OutString->Buffer = NULL; 05415 OutString->Length = 0; 05416 } 05417 05418 OutString->MaximumLength = OutString->Length; 05419 05420 return status; 05421 }

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 }

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 }

BOOLEAN IopGetLegacyVetoListDevice IN PDEVICE_NODE  DeviceNode,
IN PIO_GET_LEGACY_VETO_LIST_CONTEXT  Context
 

Definition at line 9445 of file pnpioapi.c.

References FALSE, IopAppendLegacyVeto(), IopDeviceNodeFlagsToCapabilities, _DEVICE_CAPABILITIES::NonDynamic, NULL, and TRUE.

Referenced by IopGetLegacyVetoListDeviceNode().

09451 : 09452 09453 This routine determines whether the specified device node should be added to 09454 the veto list, and if so, calls IopAppendLegacyVeto to add it. 09455 09456 Parameters: 09457 09458 DeviceNode - The device node to be added. 09459 09460 Context - An IO_GET_LEGACY_VETO_LIST_CONTEXT pointer. 09461 09462 ReturnValue: 09463 09464 A BOOLEAN value which indicates whether the device node enumeration 09465 process should be terminated or not. 09466 09467 --*/ 09468 { 09469 PDEVICE_CAPABILITIES DeviceCapabilities; 09470 09471 // 09472 // A device node should be added added to the veto list, if it has the 09473 // NonDynamic capability. 09474 // 09475 09476 DeviceCapabilities = IopDeviceNodeFlagsToCapabilities(DeviceNode); 09477 09478 if (DeviceCapabilities->NonDynamic) { 09479 09480 // 09481 // Update the veto type. If an error occurrs while adding the device 09482 // node to the veto list, or the caller did not provide a veto list 09483 // pointer, terminate the enumeration process now. 09484 // 09485 09486 *Context->VetoType = PNP_VetoLegacyDevice; 09487 09488 if (Context->VetoList != NULL) { 09489 09490 if (!IopAppendLegacyVeto(Context, &DeviceNode->InstancePath)) { 09491 return FALSE; 09492 } 09493 09494 } else { 09495 09496 return FALSE; 09497 09498 } 09499 09500 } 09501 09502 return TRUE; 09503 }

BOOLEAN IopGetLegacyVetoListDeviceNode IN PDEVICE_NODE  DeviceNode,
IN PIO_GET_LEGACY_VETO_LIST_CONTEXT  Context
 

Definition at line 9506 of file pnpioapi.c.

References _DEVICE_NODE::Child, FALSE, IopGetLegacyVetoListDevice(), NULL, _DEVICE_NODE::Sibling, and TRUE.

Referenced by IoGetLegacyVetoList().

09512 : 09513 09514 This routine recusively walks the device tree, invoking 09515 IopGetLegacyVetoListDevice to add device nodes to the veto list 09516 (as appropriate). 09517 09518 Parameters: 09519 09520 DeviceNode - The device node. 09521 09522 Context - An IO_GET_LEGACY_VETO_LIST_CONTEXT pointer. 09523 09524 09525 ReturnValue: 09526 09527 A BOOLEAN value which indicates whether the device tree enumeration 09528 process should be terminated or not. 09529 09530 --*/ 09531 { 09532 PDEVICE_NODE Child; 09533 09534 // 09535 // Determine whether the device node should be added to the veto 09536 // list and add it. If an operation is unsuccessful or we determine 09537 // the veto type but the caller doesn't need the veto list, then we 09538 // terminate our search now. 09539 // 09540 09541 if (!IopGetLegacyVetoListDevice(DeviceNode, Context)) { 09542 return FALSE; 09543 } 09544 09545 // 09546 // Call ourselves recursively to enumerate our children. If while 09547 // enumerating our children we determine we can terminate the search 09548 // prematurely, do so. 09549 // 09550 09551 for (Child = DeviceNode->Child; 09552 Child != NULL; 09553 Child = Child->Sibling) { 09554 09555 if (!IopGetLegacyVetoListDeviceNode(Child, Context)) { 09556 return FALSE; 09557 } 09558 09559 } 09560 09561 return TRUE; 09562 }

VOID IopGetLegacyVetoListDrivers IN PIO_GET_LEGACY_VETO_LIST_CONTEXT  Context  ) 
 

Definition at line 9565 of file pnpioapi.c.

References ASSERT, DRVO_LEGACY_RESOURCES, ExAllocatePool, ExFreePool(), FALSE, _DRIVER_OBJECT::Flags, IO_TYPE_DRIVER, IoDriverObjectType, IopAppendLegacyVeto(), KernelMode, L, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByName(), PagedPool, RtlInitUnicodeString(), TRUE, and _DRIVER_OBJECT::Type.

Referenced by IoGetLegacyVetoList().

09568 { 09569 PDRIVER_OBJECT driverObject; 09570 OBJECT_ATTRIBUTES attributes; 09571 UNICODE_STRING driverString; 09572 POBJECT_DIRECTORY_INFORMATION dirInfo; 09573 HANDLE directoryHandle; 09574 ULONG dirInfoLength, neededLength, dirContext; 09575 NTSTATUS status; 09576 BOOLEAN restartScan; 09577 09578 dirInfoLength = 0; 09579 dirInfo = NULL; 09580 restartScan = TRUE; 09581 09582 // 09583 // Get handle to \\Driver directory 09584 // 09585 09586 RtlInitUnicodeString(&driverString, L"\\Driver"); 09587 09588 InitializeObjectAttributes(&attributes, 09589 &driverString, 09590 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 09591 NULL, 09592 NULL 09593 ); 09594 09595 status = ZwOpenDirectoryObject(&directoryHandle, 09596 DIRECTORY_QUERY, 09597 &attributes 09598 ); 09599 if (!NT_SUCCESS(status)) { 09600 *Context->Status = status; 09601 return; 09602 } 09603 09604 for (;;) { 09605 09606 // 09607 // Get info on next object in directory. If the buffer is too 09608 // small, reallocate it and try again. Otherwise, any failure 09609 // including STATUS_NO_MORE_ENTRIES breaks us out. 09610 // 09611 09612 status = ZwQueryDirectoryObject(directoryHandle, 09613 dirInfo, 09614 dirInfoLength, 09615 TRUE, // force one at a time 09616 restartScan, 09617 &dirContext, 09618 &neededLength); 09619 if (status == STATUS_BUFFER_TOO_SMALL) { 09620 dirInfoLength = neededLength; 09621 if (dirInfo != NULL) { 09622 ExFreePool(dirInfo); 09623 } 09624 dirInfo = ExAllocatePool(PagedPool, dirInfoLength); 09625 if (dirInfo == NULL) { 09626 *Context->Status = STATUS_INSUFFICIENT_RESOURCES; 09627 break; 09628 } 09629 status = ZwQueryDirectoryObject(directoryHandle, 09630 dirInfo, 09631 dirInfoLength, 09632 TRUE, // force one at a time 09633 restartScan, 09634 &dirContext, 09635 &neededLength); 09636 } 09637 restartScan = FALSE; 09638 09639 if (!NT_SUCCESS(status)) { 09640 break; 09641 } 09642 09643 // 09644 // Have name of object. Create object path and use 09645 // ObReferenceObjectByName() to get DriverObject. This may 09646 // fail non-fatally if DriverObject has gone away in the interim. 09647 // 09648 09649 driverString.MaximumLength = sizeof(L"\\Driver\\") + 09650 dirInfo->Name.Length; 09651 driverString.Length = driverString.MaximumLength - sizeof(WCHAR); 09652 driverString.Buffer = ExAllocatePool(PagedPool, 09653 driverString.MaximumLength); 09654 if (driverString.Buffer == NULL) { 09655 *Context->Status = STATUS_INSUFFICIENT_RESOURCES; 09656 break; 09657 } 09658 09659 swprintf(driverString.Buffer, L"\\Driver\\%ws", dirInfo->Name.Buffer); 09660 status = ObReferenceObjectByName(&driverString, 09661 OBJ_CASE_INSENSITIVE, 09662 NULL, // access state 09663 0, // access mask 09664 IoDriverObjectType, 09665 KernelMode, 09666 NULL, // parse context 09667 &driverObject); 09668 09669 ExFreePool(driverString.Buffer); 09670 09671 if (NT_SUCCESS(status)) { 09672 ASSERT(driverObject->Type == IO_TYPE_DRIVER); 09673 if (driverObject->Flags & DRVO_LEGACY_RESOURCES) { 09674 // 09675 // Update the veto type. If the caller provided a 09676 // veto list pointer, add the driver to the veto list. 09677 // If an error occurs while adding the driver to the 09678 // veto list, or the caller did not provide a veto 09679 // list pointer, terminate the driver enumeration now. 09680 // 09681 // NOTE: Driver may be loaded but not running, 09682 // distinction is not made here. 09683 09684 09685 *Context->VetoType = PNP_VetoLegacyDriver; 09686 09687 if (Context->VetoList != NULL) { 09688 IopAppendLegacyVeto(Context, &dirInfo->Name); 09689 } 09690 } 09691 ObDereferenceObject(driverObject); 09692 09693 // 09694 // Early out if we have a veto and the caller didn't want a list or 09695 // we hit some error already 09696 // 09697 if (((*Context->VetoType == PNP_VetoLegacyDriver) && 09698 (Context->VetoList == NULL)) || 09699 !NT_SUCCESS(*Context->Status)) { 09700 break; 09701 } 09702 } 09703 } 09704 if (dirInfo != NULL) { 09705 ExFreePool(dirInfo); 09706 } 09707 09708 ZwClose(directoryHandle); 09709 }

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 }

VOID IopInitializePlugPlayNotification VOID   ) 
 

Definition at line 6511 of file pnpioapi.c.

References ExInitializeFastMutex, IopDeferredRegistrationList, IopDeferredRegistrationLock, IopDeviceClassNotifyList, IopDeviceClassNotifyLock, IopHwProfileNotifyLock, IopProfileNotifyList, IopTargetDeviceNotifyLock, NOTIFY_DEVICE_CLASS_HASH_BUCKETS, and PAGED_CODE.

06517 : 06518 06519 This routine performs initialization required before any of the notification 06520 APIs can be called. 06521 06522 Parameters: 06523 06524 None 06525 06526 Return Value: 06527 06528 None 06529 06530 --*/ 06531 06532 { 06533 ULONG count; 06534 06535 PAGED_CODE(); 06536 06537 // 06538 // Initialize the notification structures 06539 // 06540 06541 for (count = 0; count < NOTIFY_DEVICE_CLASS_HASH_BUCKETS; count++) { 06542 06543 InitializeListHead(&IopDeviceClassNotifyList[count]); 06544 06545 } 06546 06547 // 06548 // Initialize the profile notification list 06549 // 06550 InitializeListHead(&IopProfileNotifyList); 06551 06552 // 06553 // Initialize the deferred registration list 06554 // 06555 InitializeListHead(&IopDeferredRegistrationList); 06556 06557 ExInitializeFastMutex(&IopDeviceClassNotifyLock); 06558 ExInitializeFastMutex(&IopTargetDeviceNotifyLock); 06559 ExInitializeFastMutex(&IopHwProfileNotifyLock); 06560 ExInitializeFastMutex(&IopDeferredRegistrationLock); 06561 }

VOID IopInvalidateDeviceStateWorker PVOID  Context  ) 
 

Definition at line 6387 of file pnpioapi.c.

References _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_WORK_ITEM::DeviceObject, _DEVICE_OBJECT::DeviceObjectExtension, DNF_REMOVE_PENDING_CLOSES, DNF_STARTED, ExFreePool(), _DEVICE_NODE::Flags, IopQueryDeviceState(), IopUncacheInterfaceInformation(), ObDereferenceObject, and PDEVICE_WORK_ITEM.

Referenced by IoInvalidateDeviceState().

06393 : 06394 06395 This routine is the worker routine of IoInvalidateDeviceState. 06396 Its main purpose is to invoke IopSynchronousQueryDeviceState and release 06397 work item space. 06398 06399 Parameters: 06400 06401 Context - Supplies a pointer to the DEVICE_WORK_ITEM. 06402 06403 ReturnValue: 06404 06405 None. 06406 06407 --*/ 06408 06409 { 06410 PDEVICE_WORK_ITEM deviceWorkItem = (PDEVICE_WORK_ITEM)Context; 06411 PDEVICE_OBJECT deviceObject = deviceWorkItem->DeviceObject; 06412 PDEVICE_NODE deviceNode; 06413 06414 ExFreePool(deviceWorkItem); 06415 06416 // 06417 // If the device was removed or surprised removed while the work item was 06418 // queued then ignore it. 06419 // 06420 06421 deviceNode = (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode; 06422 06423 if ((deviceNode->Flags & (DNF_STARTED | DNF_REMOVE_PENDING_CLOSES)) == DNF_STARTED) { 06424 06425 IopQueryDeviceState(deviceObject); 06426 06427 // 06428 // PCMCIA driver uses this when switching between Cardbus and R2 cards. 06429 // 06430 IopUncacheInterfaceInformation(deviceObject); 06431 } 06432 06433 ObDereferenceObject(deviceObject); 06434 } //

BOOLEAN IopIsReportedAlready IN HANDLE  Handle,
IN PUNICODE_STRING  ServiceName,
IN PCM_RESOURCE_LIST  ResourceList
 

Definition at line 2286 of file pnpioapi.c.

References ExFreePool(), exit, FALSE, Handle, IopGetRegistryValue(), IopIsDuplicatedDevices(), IopOpenRegistryKeyEx(), KEY_VALUE_DATA, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, RtlEqualUnicodeString(), RtlInitUnicodeString(), TITLE_INDEX_VALUE, TRUE, and USHORT.

Referenced by IoReportDetectedDevice().

02294 : 02295 02296 This routine determines if the reported device instance is already reported 02297 or not. 02298 02299 Parameters: 02300 02301 Handle - Supplies a handle to the reported device instance key. 02302 02303 ServiceName - supplies a pointer to a the unicode service key name. 02304 02305 ResourceList - supplies a pointer to the reported Resource list. 02306 02307 Return Value: 02308 02309 Status code that indicates whether or not the function was successful. 02310 02311 --*/ 02312 02313 { 02314 PKEY_VALUE_FULL_INFORMATION keyValueInfo1 = NULL, keyValueInfo2 = NULL; 02315 NTSTATUS status; 02316 UNICODE_STRING unicodeName; 02317 HANDLE logConfHandle, controlHandle = NULL; 02318 BOOLEAN returnValue = FALSE; 02319 PCM_RESOURCE_LIST cmResource = NULL; 02320 ULONG tmpValue; 02321 02322 PAGED_CODE(); 02323 02324 // 02325 // If this registry key is for a device reported during the same boot 02326 // this is not a duplicate. 02327 // 02328 02329 RtlInitUnicodeString(&unicodeName, REGSTR_KEY_CONTROL); 02330 status = IopOpenRegistryKeyEx( &controlHandle, 02331 Handle, 02332 &unicodeName, 02333 KEY_ALL_ACCESS 02334 ); 02335 if (NT_SUCCESS(status)) { 02336 status = IopGetRegistryValue(controlHandle, 02337 REGSTR_VALUE_DEVICE_REPORTED, 02338 &keyValueInfo1); 02339 if (NT_SUCCESS(status)) { 02340 goto exit; 02341 } 02342 02343 // 02344 // Check if "Service" value matches what the caller passed in. 02345 // 02346 02347 status = IopGetRegistryValue(Handle, REGSTR_VALUE_SERVICE, &keyValueInfo1); 02348 if (NT_SUCCESS(status)) { 02349 if ((keyValueInfo1->Type == REG_SZ) && 02350 (keyValueInfo1->DataLength != 0)) { 02351 unicodeName.Buffer = (PWSTR)KEY_VALUE_DATA(keyValueInfo1); 02352 unicodeName.MaximumLength = unicodeName.Length = (USHORT)keyValueInfo1->DataLength; 02353 if (unicodeName.Buffer[(keyValueInfo1->DataLength / sizeof(WCHAR)) - 1] == UNICODE_NULL) { 02354 unicodeName.Length -= sizeof(WCHAR); 02355 } 02356 if (RtlEqualUnicodeString(ServiceName, &unicodeName, TRUE)) { 02357 02358 // 02359 // Next check if resources are the same 02360 // 02361 02362 RtlInitUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF); 02363 status = IopOpenRegistryKeyEx( &logConfHandle, 02364 Handle, 02365 &unicodeName, 02366 KEY_READ 02367 ); 02368 if (NT_SUCCESS(status)) { 02369 status = IopGetRegistryValue(logConfHandle, 02370 REGSTR_VAL_BOOTCONFIG, 02371 &keyValueInfo2); 02372 ZwClose(logConfHandle); 02373 if (NT_SUCCESS(status)) { 02374 if ((keyValueInfo2->Type == REG_RESOURCE_LIST) && 02375 (keyValueInfo2->DataLength != 0)) { 02376 cmResource = (PCM_RESOURCE_LIST)KEY_VALUE_DATA(keyValueInfo2); 02377 if (ResourceList && cmResource && 02378 IopIsDuplicatedDevices(ResourceList, cmResource, NULL, NULL)) { 02379 returnValue = TRUE; 02380 } 02381 } 02382 } 02383 } 02384 if (!ResourceList && !cmResource) { 02385 returnValue = TRUE; 02386 } 02387 } 02388 } 02389 } 02390 if (returnValue == TRUE) { 02391 02392 // 02393 // Mark this key has been used. 02394 // 02395 02396 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_DEVICE_REPORTED); 02397 tmpValue = 1; 02398 status = ZwSetValueKey(controlHandle, 02399 &unicodeName, 02400 TITLE_INDEX_VALUE, 02401 REG_DWORD, 02402 &tmpValue, 02403 sizeof(ULONG) 02404 ); 02405 if (!NT_SUCCESS(status)) { 02406 returnValue = FALSE; 02407 } 02408 } 02409 } 02410 02411 exit: 02412 if (controlHandle) { 02413 ZwClose(controlHandle); 02414 } 02415 02416 if (keyValueInfo1) { 02417 ExFreePool(keyValueInfo1); 02418 } 02419 if (keyValueInfo2) { 02420 ExFreePool(keyValueInfo2); 02421 } 02422 return returnValue; 02423 }

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, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Context, _NOTIFY_ENTRY_HEADER::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, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Context, _NOTIFY_ENTRY_HEADER::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, _HWPROFILE_NOTIFY_ENTRY::Unregistered, _NOTIFY_ENTRY_HEADER::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, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Context, _SETUP_NOTIFY_DATA::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, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Context, _NOTIFY_ENTRY_HEADER::Context, DbgPrint, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, _DRIVER_OBJECT::DriverName, _NOTIFY_ENTRY_HEADER::DriverObject, _TARGET_DEVICE_REMOVAL_NOTIFICATION::Event, _TARGET_DEVICE_CUSTOM_NOTIFICATION::FileObject, _TARGET_DEVICE_REMOVAL_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, _TARGET_DEVICE_NOTIFY_ENTRY::Unregistered, _NOTIFY_ENTRY_HEADER::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 }

ULONG IoPnPDeliverServicePowerNotification ULONG  PwrNotification,
BOOLEAN  Synchronous
 

Definition at line 9221 of file pnpioapi.c.

References ASSERT, ExAllocatePool, Executive, ExFreePool(), FALSE, IoRaiseInformationalHardError(), KeInitializeEvent, KernelMode, KeWaitForSingleObject(), MAX_VETO_NAME_LENGTH, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, and PpSetPowerEvent().

Referenced by xxxSendMessageBSM().

09225 { 09226 09227 NTSTATUS status = STATUS_SUCCESS; 09228 KEVENT completionEvent; 09229 NTSTATUS completionStatus=STATUS_SUCCESS; 09230 PNP_VETO_TYPE vetoType = PNP_VetoTypeUnknown; 09231 UNICODE_STRING vetoName; 09232 09233 PAGED_CODE(); 09234 09235 #define MAX_VETO_NAME_LENGTH 512 //From Revent.c make it common 09236 09237 if (Synchronous) { 09238 09239 09240 09241 vetoName.Buffer = ExAllocatePool (PagedPool,MAX_VETO_NAME_LENGTH*sizeof (WCHAR)); 09242 09243 if (vetoName.Buffer) { 09244 vetoName.MaximumLength = MAX_VETO_NAME_LENGTH; 09245 }else { 09246 vetoName.MaximumLength = 0; 09247 } 09248 vetoName.Length = 0; 09249 09250 KeInitializeEvent(&completionEvent, NotificationEvent, FALSE); 09251 09252 status = PpSetPowerEvent( 09253 PwrNotification, 09254 &completionEvent, 09255 &completionStatus, 09256 &vetoType,&vetoName 09257 ); 09258 09259 if (NT_SUCCESS(status)) { 09260 09261 KeWaitForSingleObject( &completionEvent, Executive, KernelMode, FALSE, NULL ); 09262 status = completionStatus; 09263 09264 if (vetoType == PNP_VetoWindowsService) { 09265 IoRaiseInformationalHardError (STATUS_DRIVER_FAILED_SLEEP,&vetoName,NULL); 09266 } 09267 09268 } 09269 if (vetoName.Buffer) { 09270 ExFreePool (vetoName.Buffer); 09271 } 09272 09273 } else { 09274 status = PpSetPowerEvent( 09275 PwrNotification, 09276 NULL, 09277 NULL, 09278 NULL, 09279 NULL 09280 ); 09281 } 09282 09283 ASSERT ((completionStatus == STATUS_SUCCESS) || 09284 (completionStatus == STATUS_UNSUCCESSFUL)); 09285 // 09286 // The private code in Win32k that calls this, assumes that 0 is failure, !0 is success 09287 // 09288 09289 return (completionStatus != STATUS_UNSUCCESSFUL); 09290 09291 }

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 IopOpenOrCreateDeviceInterfaceSubKeys OUT PHANDLE InterfaceKeyHandle  OPTIONAL,
OUT PULONG InterfaceKeyDisposition  OPTIONAL,
OUT PHANDLE InterfaceInstanceKeyHandle  OPTIONAL,
OUT PULONG InterfaceInstanceDisposition  OPTIONAL,
IN HANDLE  InterfaceClassKeyHandle,
IN PUNICODE_STRING  DeviceInterfaceName,
IN ACCESS_MASK  DesiredAccess,
IN BOOLEAN  Create
 

Definition at line 4741 of file pnpioapi.c.

References ASSERT, Create(), FALSE, IopAllocateUnicodeString(), IopConstStringSize, IopCreateRegistryKeyEx(), IopFreeAllocatedUnicodeString(), IopOpenRegistryKeyEx(), IopParseSymbolicLinkName(), IopReplaceSeperatorWithPound(), KEY_STRING_PREFIX, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, REFSTRING_PREFIX_CHAR, RtlCopyUnicodeString(), and USHORT.

Referenced by IopDeviceInterfaceKeysFromSymbolicLink(), IopGetDeviceInterfaces(), and IopRegisterDeviceInterface().

04754 : 04755 04756 This API opens or creates a two-level registry hierarchy underneath the 04757 specified interface class key for a particular device interface. The first 04758 level is the (munged) symbolic link name (sans RefString). The second level 04759 is the refstring, prepended with a '#' sign (if the device interface has no 04760 refstring, then this key name is simply '#'). 04761 04762 Parameters: 04763 04764 InterfaceKeyHandle - Optionally, supplies the address of a variable that 04765 receives a handle to the interface key (1st level in the hierarchy). 04766 04767 InterfaceKeyDisposition - Optionally, supplies the address of a variable that 04768 receives either REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY indicating 04769 whether the interface key was newly-created. 04770 04771 InterfaceInstanceKeyHandle - Optionally, supplies the address of a variable 04772 that receives a handle to the interface instance key (2nd level in the 04773 hierarchy). 04774 04775 InterfaceInstanceDisposition - Optionally, supplies the address of a variable 04776 that receives either REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY 04777 indicating whether the interface instance key was newly-created. 04778 04779 InterfaceClassKeyHandle - Supplies a handle to the interface class key under 04780 which the device interface keys are to be opened/created. 04781 04782 DeviceInterfaceName - Supplies the (user-mode or kernel-mode form) device 04783 interface name. 04784 04785 DesiredAccess - Specifies the desired access that the caller needs to the keys. 04786 04787 Create - Determines if the keys are to be created if they do not exist. 04788 04789 Return Value: 04790 04791 Status code that indicates whether or not the function was successful. 04792 04793 --*/ 04794 04795 { 04796 NTSTATUS status; 04797 UNICODE_STRING TempString, RefString; 04798 WCHAR PoundCharBuffer; 04799 HANDLE hTempInterface, hTempInterfaceInstance; 04800 ULONG TempInterfaceDisposition; 04801 BOOLEAN RefStringPresent=FALSE; 04802 04803 PAGED_CODE(); 04804 04805 // 04806 // Make a copy of the device interface name, since we're going to munge it. 04807 // 04808 status = IopAllocateUnicodeString(&TempString, DeviceInterfaceName->Length); 04809 04810 if(!NT_SUCCESS(status)) { 04811 goto clean0; 04812 } 04813 04814 RtlCopyUnicodeString(&TempString, DeviceInterfaceName); 04815 04816 // 04817 // Find the refstring component (if there is one). 04818 // 04819 status = IopParseSymbolicLinkName(&TempString, 04820 NULL, 04821 NULL, 04822 NULL, 04823 &RefString, 04824 &RefStringPresent, 04825 NULL 04826 ); 04827 ASSERT(NT_SUCCESS(status)); 04828 04829 if(RefStringPresent) { 04830 // 04831 // Truncate the device interface name before the refstring separator char. 04832 // 04833 RefString.Buffer--; 04834 RefString.Length += sizeof(WCHAR); 04835 RefString.MaximumLength += sizeof(WCHAR); 04836 TempString.MaximumLength = TempString.Length = (USHORT)((PUCHAR)RefString.Buffer - (PUCHAR)TempString.Buffer); 04837 } else { 04838 // 04839 // Set up refstring to point to a temporary character buffer that will hold 04840 // the single '#' used for the key name when no refstring is present. 04841 // 04842 RefString.Buffer = &PoundCharBuffer; 04843 RefString.Length = RefString.MaximumLength = sizeof(PoundCharBuffer); 04844 } 04845 04846 // 04847 // Replace the "\??\" or "\\?\" symbolic link name prefix with ##?# 04848 // 04849 RtlCopyMemory(TempString.Buffer, KEY_STRING_PREFIX, IopConstStringSize(KEY_STRING_PREFIX)); 04850 04851 // 04852 // Munge the string 04853 // 04854 IopReplaceSeperatorWithPound(&TempString, &TempString); 04855 04856 // 04857 // Now open/create this subkey under the interface class key. 04858 // 04859 04860 if (Create) { 04861 status = IopCreateRegistryKeyEx( &hTempInterface, 04862 InterfaceClassKeyHandle, 04863 &TempString, 04864 DesiredAccess, 04865 REG_OPTION_NON_VOLATILE, 04866 &TempInterfaceDisposition 04867 ); 04868 } else { 04869 status = IopOpenRegistryKeyEx( &hTempInterface, 04870 InterfaceClassKeyHandle, 04871 &TempString, 04872 DesiredAccess 04873 ); 04874 } 04875 04876 if(!NT_SUCCESS(status)) { 04877 goto clean1; 04878 } 04879 04880 // 04881 // Store a '#' as the first character of the RefString, and then we're ready to open the 04882 // refstring subkey. 04883 // 04884 *RefString.Buffer = REFSTRING_PREFIX_CHAR; 04885 04886 // 04887 // Now open/create the subkey under the interface key representing this interface instance 04888 // (i.e., differentiated by refstring). 04889 // 04890 04891 if (Create) { 04892 status = IopCreateRegistryKeyEx( &hTempInterfaceInstance, 04893 hTempInterface, 04894 &RefString, 04895 DesiredAccess, 04896 REG_OPTION_NON_VOLATILE, 04897 InterfaceInstanceDisposition 04898 ); 04899 } else { 04900 status = IopOpenRegistryKeyEx( &hTempInterfaceInstance, 04901 hTempInterface, 04902 &RefString, 04903 DesiredAccess 04904 ); 04905 } 04906 04907 if(NT_SUCCESS(status)) { 04908 // 04909 // Store any requested return values in the caller-supplied buffers. 04910 // 04911 if(InterfaceKeyHandle) { 04912 *InterfaceKeyHandle = hTempInterface; 04913 } else { 04914 ZwClose(hTempInterface); 04915 } 04916 if(InterfaceKeyDisposition) { 04917 *InterfaceKeyDisposition = TempInterfaceDisposition; 04918 } 04919 if(InterfaceInstanceKeyHandle) { 04920 *InterfaceInstanceKeyHandle = hTempInterfaceInstance; 04921 } else { 04922 ZwClose(hTempInterfaceInstance); 04923 } 04924 // 04925 // (no need to set InterfaceInstanceDisposition--we already set it above) 04926 // 04927 } else { 04928 // 04929 // If the interface key was newly-created above, then delete it. 04930 // 04931 if(TempInterfaceDisposition == REG_CREATED_NEW_KEY) { 04932 ZwDeleteKey(hTempInterface); 04933 } else { 04934 ZwClose(hTempInterface); 04935 } 04936 } 04937 04938 clean1: 04939 IopFreeAllocatedUnicodeString(&TempString); 04940 04941 clean0: 04942 return status; 04943 }

VOID IopOrphanNotification IN PDEVICE_NODE  TargetNode  ) 
 

Definition at line 9301 of file pnpioapi.c.

References _TARGET_DEVICE_NOTIFY_ENTRY::EventCategory, EventCategoryTargetDeviceChange, IopAcquireNotifyLock, IopReleaseNotifyLock, IopTargetDeviceNotifyLock, NULL, ObDereferenceObject, and _TARGET_DEVICE_NOTIFY_ENTRY::PhysicalDeviceObject.

09304 { 09305 PTARGET_DEVICE_NOTIFY_ENTRY entry; 09306 PFAST_MUTEX lock; 09307 09308 IopAcquireNotifyLock(&IopTargetDeviceNotifyLock); 09309 09310 while (!IsListEmpty(&TargetNode->TargetDeviceNotify)) { 09311 entry = (PTARGET_DEVICE_NOTIFY_ENTRY)RemoveHeadList(&TargetNode->TargetDeviceNotify); 09312 if (entry->EventCategory == EventCategoryTargetDeviceChange) { 09313 09314 if (entry->PhysicalDeviceObject) { 09315 ObDereferenceObject(entry->PhysicalDeviceObject); 09316 entry->PhysicalDeviceObject = NULL; 09317 } 09318 } 09319 } 09320 09321 IopReleaseNotifyLock(&IopTargetDeviceNotifyLock); 09322 }

NTSTATUS IopOverwriteBuffer IN PBUFFER_INFO  Info,
IN PVOID  Data,
IN ULONG  DataSize
 

Definition at line 2640 of file pnpioapi.c.

References ASSERT, FALSE, IopResizeBuffer(), NT_SUCCESS, and NTSTATUS().

02648 : 02649 02650 Copies data into the buffer, overwriting what is currently present, 02651 resising if necessary. The current position is set to the end of the 02652 data just added. 02653 02654 Parameters: 02655 02656 Info - Pointer to a buffer info structure to be used to manage the buffer 02657 02658 Data - Pointer to the data to be added to the buffer 02659 02660 DataSize - The size of the data pointed to by Data in bytes 02661 02662 Return Value: 02663 02664 Status code that indicates whether or not the function was successful. 02665 02666 --*/ 02667 02668 { 02669 NTSTATUS status = STATUS_SUCCESS; 02670 ULONG free; 02671 02672 ASSERT(Info); 02673 02674 free = Info->MaxSize; 02675 02676 02677 if (free < DataSize) { 02678 status = IopResizeBuffer(Info, DataSize, FALSE); 02679 02680 if (!NT_SUCCESS(status)) { 02681 goto clean0; 02682 } 02683 02684 } 02685 02686 // 02687 // Copy the data into the buffer 02688 // 02689 02690 RtlCopyMemory(Info->Buffer, 02691 Data, 02692 DataSize); 02693 02694 // 02695 // Advance down the buffer 02696 // 02697 02698 Info->Current += DataSize; 02699 02700 clean0: 02701 return status; 02702 }

NTSTATUS IopParseSymbolicLinkName IN PUNICODE_STRING  SymbolicLinkName,
OUT PUNICODE_STRING PrefixString  OPTIONAL,
OUT PUNICODE_STRING MungedPathString  OPTIONAL,
OUT PUNICODE_STRING GuidString  OPTIONAL,
OUT PUNICODE_STRING RefString  OPTIONAL,
OUT PBOOLEAN RefStringPresent  OPTIONAL,
OUT LPGUID Guid  OPTIONAL
 

Definition at line 5424 of file pnpioapi.c.

References ASSERT, FALSE, GUID_STRING_LENGTH, GUID_STRING_SIZE, IopConstStringLength, IopConstStringSize, KERNEL_SYMLINK_STRING_PREFIX, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, path, RtlGUIDFromString(), SEPERATOR_CHAR, TRUE, USER_SYMLINK_STRING_PREFIX, and USHORT.

Referenced by IoGetDeviceInterfaceAlias(), IopDeviceInterfaceKeysFromSymbolicLink(), IopDropReferenceString(), IopOpenOrCreateDeviceInterfaceSubKeys(), IopProcessSetInterfaceState(), and IopUnregisterDeviceInterface().

05436 : 05437 05438 This routine breaks apart a symbolic link name constructed by 05439 IopBuildSymbolicLinkNames. Both formats of name are valid - user 05440 mode \\?\ and kernel mode \??\. 05441 05442 Parameters: 05443 05444 SymbolicLinkName - Supplies a pointer to the symbolic link name to 05445 be analysed. 05446 05447 PrefixString - Optionally contains a pointer to a string which will contain 05448 the prefix of the string. 05449 05450 MungedPathString - Optionally contains a pointer to a string which will contain 05451 the enumeration path of the device with all occurences of '\' replaced with '#'. 05452 05453 GuidString - Optionally contains a pointer to a string which will contain 05454 the device class guid in string format from the string. 05455 05456 RefString - Optionally contains a pointer to a string which will contain 05457 the refstring of the string if one is present, otherwise it is undefined. 05458 05459 RefStringPresent - Optionally contains a pointer to a boolean value which will 05460 be set to true if a refstring is present. 05461 05462 Guid - Optionally contains a pointer to a guid which will contain 05463 the function class guid of the string. 05464 05465 Return Value: 05466 05467 Status code that indicates whether or not the function was successful. 05468 05469 --*/ 05470 05471 { 05472 NTSTATUS status = STATUS_SUCCESS; 05473 PWSTR pCurrent; 05474 USHORT last, current, path, guid, reference = 0; 05475 UNICODE_STRING tempString; 05476 GUID tempGuid; 05477 BOOLEAN haveRefString; 05478 05479 PAGED_CODE(); 05480 05481 ASSERT(IopConstStringSize(USER_SYMLINK_STRING_PREFIX) == IopConstStringSize(KERNEL_SYMLINK_STRING_PREFIX)); 05482 05483 // 05484 // Sanity check on the incoming string - if it does not have a \\?\ or \??\ prefix then fail 05485 // 05486 05487 if (!(RtlCompareMemory(SymbolicLinkName->Buffer, 05488 USER_SYMLINK_STRING_PREFIX, 05489 IopConstStringSize(USER_SYMLINK_STRING_PREFIX) 05490 ) != IopConstStringSize(USER_SYMLINK_STRING_PREFIX) 05491 || RtlCompareMemory(SymbolicLinkName->Buffer, 05492 KERNEL_SYMLINK_STRING_PREFIX, 05493 IopConstStringSize(KERNEL_SYMLINK_STRING_PREFIX) 05494 ) != IopConstStringSize(KERNEL_SYMLINK_STRING_PREFIX) 05495 )) { 05496 05497 status = STATUS_INVALID_PARAMETER; 05498 goto clean0; 05499 } 05500 05501 05502 // 05503 // check that the input buffer really is big enough 05504 // 05505 if (SymbolicLinkName->Length <(IopConstStringLength(KERNEL_SYMLINK_STRING_PREFIX)+GUID_STRING_SIZE+1)) { 05506 status = STATUS_INVALID_PARAMETER; 05507 goto clean0; 05508 05509 } 05510 05511 // 05512 // Break apart the string into it's constituent parts 05513 // 05514 05515 path = IopConstStringSize(USER_SYMLINK_STRING_PREFIX) + 1; 05516 05517 // 05518 // Find the '\' seperator 05519 // 05520 05521 pCurrent = SymbolicLinkName->Buffer + IopConstStringLength(KERNEL_SYMLINK_STRING_PREFIX); 05522 05523 for (current = 0; 05524 current < (SymbolicLinkName->Length / sizeof(WCHAR)) - IopConstStringLength(KERNEL_SYMLINK_STRING_PREFIX); 05525 current++, pCurrent++) { 05526 05527 if(*pCurrent == SEPERATOR_CHAR) { 05528 reference = current + 1 + IopConstStringLength(KERNEL_SYMLINK_STRING_PREFIX); 05529 break; 05530 } 05531 05532 } 05533 05534 // 05535 // If we don't have a reference string fake it to where it would have been 05536 // 05537 05538 if (reference == 0) { 05539 haveRefString = FALSE; 05540 reference = SymbolicLinkName->Length / sizeof(WCHAR) + 1; 05541 05542 } else { 05543 haveRefString = TRUE; 05544 } 05545 05546 // 05547 // Check the guid looks plausable 05548 // 05549 05550 tempString.Length = GUID_STRING_SIZE; 05551 tempString.MaximumLength = GUID_STRING_SIZE; 05552 tempString.Buffer = SymbolicLinkName->Buffer + reference - GUID_STRING_LENGTH - 1; 05553 05554 if (!NT_SUCCESS( RtlGUIDFromString(&tempString, &tempGuid) )) { 05555 status = STATUS_INVALID_PARAMETER; 05556 goto clean0; 05557 } 05558 05559 guid = reference - GUID_STRING_LENGTH - 1; 05560 05561 // 05562 // Setup return strings 05563 // 05564 05565 if (ARGUMENT_PRESENT(PrefixString)) { 05566 PrefixString->Length = IopConstStringSize(KERNEL_SYMLINK_STRING_PREFIX); 05567 PrefixString->MaximumLength = PrefixString->Length; 05568 PrefixString->Buffer = SymbolicLinkName->Buffer; 05569 } 05570 05571 if (ARGUMENT_PRESENT(MungedPathString)) { 05572 MungedPathString->Length = (reference - 1 - GUID_STRING_LENGTH - 1 - 05573 IopConstStringLength(KERNEL_SYMLINK_STRING_PREFIX)) * 05574 sizeof(WCHAR); 05575 MungedPathString->MaximumLength = MungedPathString->Length; 05576 MungedPathString->Buffer = SymbolicLinkName->Buffer + 05577 IopConstStringLength(KERNEL_SYMLINK_STRING_PREFIX); 05578 05579 } 05580 05581 if (ARGUMENT_PRESENT(GuidString)) { 05582 GuidString->Length = GUID_STRING_SIZE; 05583 GuidString->MaximumLength = GuidString->Length; 05584 GuidString->Buffer = SymbolicLinkName->Buffer + reference - 05585 GUID_STRING_LENGTH - 1; 05586 } 05587 05588 if (ARGUMENT_PRESENT(RefString)) { 05589 // 05590 // Check if we have a refstring 05591 // 05592 if (haveRefString) { 05593 RefString->Length = SymbolicLinkName->Length - 05594 (reference * sizeof(WCHAR)); 05595 RefString->MaximumLength = RefString->Length; 05596 RefString->Buffer = SymbolicLinkName->Buffer + reference; 05597 } else { 05598 RefString->Length = 0; 05599 RefString->MaximumLength = 0; 05600 RefString->Buffer = NULL; 05601 } 05602 } 05603 05604 if (ARGUMENT_PRESENT(RefStringPresent)) { 05605 *RefStringPresent = haveRefString; 05606 } 05607 05608 if(ARGUMENT_PRESENT(Guid)) { 05609 *Guid = tempGuid; 05610 } 05611 05612 clean0: 05613 05614 return status; 05615 05616 }

NTSTATUS IopPnPHydraCallback PVOID  CallbackParams  ) 
 

Definition at line 9333 of file pnpioapi.c.

References _NOTIFICATION_CALLBACK_PARAM_BLOCK::Callout, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Context, _NOTIFICATION_CALLBACK_PARAM_BLOCK::NotificationStructure, NTSTATUS(), and PNOTIFICATION_CALLBACK_PARAM_BLOCK.

Referenced by IopNotifyDeviceClassChange(), IopNotifyHwProfileChange(), IopNotifySetupDeviceArrival(), IopNotifyTargetDeviceChange(), and IoRegisterPlugPlayNotification().

09336 { 09337 PNOTIFICATION_CALLBACK_PARAM_BLOCK params=(PNOTIFICATION_CALLBACK_PARAM_BLOCK)CallbackParams; 09338 NTSTATUS status; 09339 09340 status = (params->Callout)(params->NotificationStructure,params->Context); 09341 09342 return status; 09343 }

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 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, _PENDING_SET_INTERFACE_STATE::List, 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 } }

NTSTATUS IopQueueDeviceWorkItem IN PDEVICE_OBJECT  PhysicalDeviceObject,
IN PVOID  WorkerRoutine,
IN PVOID  Context
 

Definition at line 6327 of file pnpioapi.c.

References _DEVICE_WORK_ITEM::Context, DelayedWorkQueue, _DEVICE_WORK_ITEM::DeviceObject, ExAllocatePool, ExInitializeWorkItem, ExQueueWorkItem(), NonPagedPool, NULL, ObReferenceObject, PDEVICE_WORK_ITEM, and _DEVICE_WORK_ITEM::WorkItem.

Referenced by IoInvalidateDeviceState(), and IoRequestDeviceEject().

06335 : 06336 06337 This API will cause the PnP manager to send the specified PDO an 06338 IRP_MN_QUERY_PNP_DEVICE_STATE IRP. 06339 06340 Parameters: 06341 06342 PhysicalDeviceObject - Provides a pointer to the PDO who's state is to be 06343 invalidated. 06344 06345 Return Value: 06346 06347 none. 06348 06349 --*/ 06350 06351 { 06352 PDEVICE_WORK_ITEM deviceWorkItem; 06353 06354 // 06355 // Since this routine can be called at DPC level we need to queue 06356 // a work item and process it when the irql drops. 06357 // 06358 06359 deviceWorkItem = ExAllocatePool(NonPagedPool, sizeof(DEVICE_WORK_ITEM)); 06360 if (deviceWorkItem == NULL) { 06361 06362 // 06363 // Failed to allocate memory for work item. Nothing we can do ... 06364 // 06365 06366 return STATUS_INSUFFICIENT_RESOURCES; 06367 } 06368 06369 ObReferenceObject(PhysicalDeviceObject); 06370 deviceWorkItem->DeviceObject = PhysicalDeviceObject; 06371 deviceWorkItem->Context = Context; 06372 06373 ExInitializeWorkItem( &deviceWorkItem->WorkItem, 06374 WorkerRoutine, 06375 deviceWorkItem); 06376 06377 // 06378 // Queue a work item to do the enumeration 06379 // 06380 06381 ExQueueWorkItem( &deviceWorkItem->WorkItem, DelayedWorkQueue ); 06382 06383 return STATUS_SUCCESS; 06384 }

NTSTATUS IopRealloc IN OUT PVOID *  Buffer,
IN ULONG  OldSize,
IN ULONG  NewSize
 

Definition at line 3491 of file pnpioapi.c.

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

03499 : 03500 03501 This implements a variation of the traditional C realloc routine. 03502 03503 Parameters: 03504 03505 Buffer - Supplies a pointer to a pointer to the buffer that is being 03506 reallocated. On sucessful completion it the pointer will be updated 03507 to point to the new buffer, on failure it will still point to the old 03508 buffer. 03509 03510 OldSize - The size in bytes of the memory block referenced by Buffer 03511 03512 NewSize - The desired new size in bytes of the buffer. This can be larger 03513 or smaller than the OldSize 03514 03515 Return Value: 03516 03517 Status code that indicates whether or not the function was successful. 03518 03519 --*/ 03520 03521 { 03522 03523 PVOID newBuffer; 03524 03525 PAGED_CODE(); 03526 03527 ASSERT(*Buffer); 03528 03529 // 03530 // Allocate a new buffer 03531 // 03532 03533 if (!(newBuffer = ExAllocatePool(PagedPool, NewSize))) { 03534 return STATUS_INSUFFICIENT_RESOURCES; 03535 } 03536 03537 // 03538 // Copy the contents of the old buffer 03539 // 03540 03541 if(OldSize <= NewSize) { 03542 RtlCopyMemory(newBuffer, *Buffer , OldSize); 03543 } else { 03544 RtlCopyMemory(newBuffer, *Buffer , NewSize); 03545 } 03546 // 03547 // Free up the old buffer 03548 // 03549 03550 ExFreePool(*Buffer); 03551 03552 // 03553 // Hand the new buffer back to the caller 03554 // 03555 03556 *Buffer = newBuffer; 03557 03558 return STATUS_SUCCESS; 03559 03560 }

VOID IopReferenceNotify PNOTIFY_ENTRY_HEADER  notify  ) 
 

Definition at line 6564 of file pnpioapi.c.

References ASSERT, PAGED_CODE, and _NOTIFY_ENTRY_HEADER::RefCount.

Referenced by IopNotifyDeviceClassChange(), IopNotifyHwProfileChange(), IopNotifyTargetDeviceChange(), and IoRegisterPlugPlayNotification().

06570 : 06571 06572 This routine increments the reference count for a notification entry. 06573 06574 Parameters: 06575 06576 Notify - Supplies a pointer to the notification entry to be referenced 06577 06578 Return Value: 06579 06580 None 06581 06582 Note: 06583 06584 The appropriate symchronization lock must be held on the notification 06585 list before this routine can be called 06586 06587 --*/ 06588 06589 { 06590 PAGED_CODE(); 06591 06592 ASSERT(Notify); 06593 ASSERT(Notify->RefCount > 0); 06594 06595 Notify->RefCount++; 06596 06597 }

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 IopRegisterTargetDeviceNotification IN ULONG  Flags,
IN PFILE_OBJECT  FileObject,
IN PDRIVER_OBJECT  DriverObject,
IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE  CallbackRoutine,
IN PVOID  Context,
IN BOOLEAN  AddLast,
OUT PVOID *  NotificationEntry
 

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 }

NTSTATUS IopReplaceSeperatorWithPound OUT PUNICODE_STRING  OutString,
IN PUNICODE_STRING  InString
 

Definition at line 5280 of file pnpioapi.c.

References ALT_SEPERATOR_CHAR, ASSERT, PAGED_CODE, REPLACED_SEPERATOR_CHAR, SEPERATOR_CHAR, and USHORT.

05287 : 05288 05289 This routine will copy a string from InString to OutString replacing any occurence of 05290 '\' or '/' with '#' as it goes. 05291 05292 Parameters: 05293 05294 OutString - Supplies a pointer to a string which has already been initialised to 05295 have a buffer large enough to accomodate the string. The contents of this 05296 string will be over written 05297 05298 InString - Supplies a pointer to the string to be munged 05299 05300 Return Value: 05301 05302 Status code that indicates whether or not the function was successful. 05303 05304 Remarks: 05305 05306 In place munging can be performed - ie. the In and Out strings can be the same. 05307 05308 --*/ 05309 05310 { 05311 PWSTR pInPosition, pOutPosition; 05312 USHORT count; 05313 05314 PAGED_CODE(); 05315 05316 ASSERT(InString); 05317 ASSERT(OutString); 05318 05319 // 05320 // Ensure we have enough space in the output string 05321 // 05322 05323 if(InString->Length > OutString->MaximumLength) { 05324 return STATUS_BUFFER_TOO_SMALL; 05325 } 05326 05327 pInPosition = InString->Buffer; 05328 pOutPosition = OutString->Buffer; 05329 count = InString->Length / sizeof(WCHAR); 05330 05331 // 05332 // Traverse the in string copying and replacing all occurences of '\' or '/' 05333 // with '#' 05334 // 05335 05336 while (count--) { 05337 if((*pInPosition == SEPERATOR_CHAR) || (*pInPosition == ALT_SEPERATOR_CHAR)) { 05338 *pOutPosition = REPLACED_SEPERATOR_CHAR; 05339 } else { 05340 *pOutPosition = *pInPosition; 05341 } 05342 pInPosition++; 05343 pOutPosition++; 05344 } 05345 05346 OutString->Length = InString->Length; 05347 05348 return STATUS_SUCCESS; 05349 05350 }

VOID IopReportTargetDeviceChangeAsyncWorker PVOID  Context  ) 
 

Definition at line 6242 of file pnpioapi.c.

References _ASYNC_TDC_WORK_ITEM::Callback, _ASYNC_TDC_WORK_ITEM::Context, _ASYNC_TDC_WORK_ITEM::DeviceObject, ExFreePool(), _ASYNC_TDC_WORK_ITEM::NotificationStructure, NULL, ObDereferenceObject, PASYNC_TDC_WORK_ITEM, and PpSetCustomTargetEvent().

Referenced by IoReportTargetDeviceChangeAsynchronous().

06248 : 06249 06250 This routine is the worker routine of IoInvalidateDeviceState. 06251 Its main purpose is to invoke IopSynchronousQueryDeviceState and release 06252 work item space. 06253 06254 Parameters: 06255 06256 Context - Supplies a pointer to the ASYNC_TDC_WORK_ITEM. 06257 06258 ReturnValue: 06259 06260 None. 06261 06262 --*/ 06263 06264 { 06265 PASYNC_TDC_WORK_ITEM asyncWorkItem = (PASYNC_TDC_WORK_ITEM)Context; 06266 06267 PpSetCustomTargetEvent( asyncWorkItem->DeviceObject, 06268 NULL, 06269 NULL, 06270 asyncWorkItem->Callback, 06271 asyncWorkItem->Context, 06272 asyncWorkItem->NotificationStructure); 06273 06274 ObDereferenceObject(asyncWorkItem->DeviceObject); 06275 ExFreePool(asyncWorkItem); 06276 }

VOID IopRequestDeviceEjectWorker PVOID  Context  ) 
 

Definition at line 1520 of file pnpioapi.c.

References _DEVICE_WORK_ITEM::DeviceObject, ExFreePool(), NULL, ObDereferenceObject, PDEVICE_WORK_ITEM, PpSetTargetDeviceRemove(), and TRUE.

Referenced by IoRequestDeviceEject().

01523 { 01524 PDEVICE_WORK_ITEM deviceWorkItem = (PDEVICE_WORK_ITEM)Context; 01525 PDEVICE_OBJECT deviceObject = deviceWorkItem->DeviceObject; 01526 01527 ExFreePool(deviceWorkItem); 01528 01529 // 01530 // Queue the event, we'll return immediately after it's queued. 01531 // 01532 01533 PpSetTargetDeviceRemove( deviceObject, 01534 TRUE, 01535 TRUE, 01536 TRUE, 01537 CM_PROB_DEVICE_NOT_THERE, 01538 NULL, 01539 NULL, 01540 NULL, 01541 NULL); 01542 01543 ObDereferenceObject(deviceObject); 01544 }

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 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 IopSetRegistryStringValue IN HANDLE  KeyHandle,
IN PUNICODE_STRING  ValueName,
IN PUNICODE_STRING  ValueData
 

Referenced by IopBootLog(), and IopRegisterDeviceInterface().

NTSTATUS IopSetSecurityObjectFromRegistry IN PVOID  Object,
IN HANDLE  Key
 

Definition at line 8959 of file pnpioapi.c.

References ExFreePool(), FALSE, IopGetRegistryValue(), Key, NT_SUCCESS, NTSTATUS(), NULL, ObSetSecurityObjectByPointer(), PagedPool, RtlGetDaclSecurityDescriptor(), RtlGetGroupSecurityDescriptor(), RtlGetOwnerSecurityDescriptor(), RtlGetSaclSecurityDescriptor(), RtlInitUnicodeString(), SeCaptureSecurityDescriptor(), SeReleaseSecurityDescriptor(), and UserMode.

08965 : 08966 08967 This routine will read in the security information stored in the specified 08968 registry key and assign that security to the specified object. If the 08969 registry key contains a SecurityDescriptor value it will be validated and 08970 assigned to the object if valid. 08971 08972 Arguments: 08973 08974 Object - the object to be secured. 08975 08976 Key - the registry key these values are saved in. 08977 08978 Return Value: 08979 08980 status 08981 08982 --*/ 08983 08984 { 08985 UNICODE_STRING valueName; 08986 08987 PKEY_VALUE_FULL_INFORMATION info = NULL; 08988 08989 PSECURITY_DESCRIPTOR descriptor; 08990 PSECURITY_DESCRIPTOR capturedDescriptor; 08991 08992 NTSTATUS status; 08993 08994 RtlInitUnicodeString(&valueName, REGSTR_VAL_DEVICE_SECURITY_DESCRIPTOR); 08995 08996 status = IopGetRegistryValue(Key, 08997 valueName.Buffer, 08998 &info); 08999 09000 if(!NT_SUCCESS(status)) { 09001 return status; 09002 } 09003 09004 descriptor = (((PUCHAR) info) + info->DataOffset); 09005 09006 status = SeCaptureSecurityDescriptor(descriptor, 09007 UserMode, 09008 PagedPool, 09009 FALSE, 09010 &capturedDescriptor); 09011 09012 ExFreePool(descriptor); 09013 09014 if(!NT_SUCCESS(status)) { 09015 return status; 09016 } 09017 09018 try { 09019 09020 SECURITY_INFORMATION securityInformation; 09021 09022 PSID sid; 09023 PACL acl; 09024 BOOLEAN present, tmp; 09025 09026 RtlZeroMemory(&securityInformation, sizeof(securityInformation)); 09027 09028 // 09029 // See what information is in the captured descriptor so we can build 09030 // up a securityInformation block to go with it. 09031 // 09032 09033 status = RtlGetOwnerSecurityDescriptor(capturedDescriptor, &sid, &tmp); 09034 09035 if(NT_SUCCESS(status) && (sid != NULL)) { 09036 securityInformation |= OWNER_SECURITY_INFORMATION; 09037 } 09038 09039 status = RtlGetGroupSecurityDescriptor(capturedDescriptor, &sid, &tmp); 09040 09041 if(NT_SUCCESS(status) && (sid != NULL)) { 09042 securityInformation |= GROUP_SECURITY_INFORMATION; 09043 } 09044 09045 status = RtlGetSaclSecurityDescriptor(capturedDescriptor, 09046 &present, 09047 &acl, 09048 &tmp); 09049 09050 if(NT_SUCCESS(status) && (present)) { 09051 securityInformation |= SACL_SECURITY_INFORMATION; 09052 } 09053 09054 status = RtlGetDaclSecurityDescriptor(capturedDescriptor, 09055 &present, 09056 &acl, 09057 &tmp); 09058 09059 if(NT_SUCCESS(status) && (present)) { 09060 securityInformation |= DACL_SECURITY_INFORMATION; 09061 } 09062 09063 status = ObSetSecurityObjectByPointer(Object, 09064 securityInformation, 09065 capturedDescriptor); 09066 } finally { 09067 SeReleaseSecurityDescriptor(capturedDescriptor, 09068 UserMode, 09069 FALSE); 09070 } 09071 09072 return status; 09073 }

NTSTATUS IopSetupDeviceObjectFromDeviceClass IN PDEVICE_OBJECT  Pdo,
IN HANDLE  InterfaceClassKey
 

Referenced by IopProcessSetInterfaceState().

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 IoRegisterDeviceInterface IN PDEVICE_OBJECT  PhysicalDeviceObject,
IN CONST GUID *  InterfaceClassGuid,
IN PUNICODE_STRING ReferenceString  OPTIONAL,
OUT PUNICODE_STRING  SymbolicLinkName
 

Definition at line 3835 of file pnpioapi.c.

References ALT_SEPERATOR_CHAR, FALSE, _DEVICE_NODE::InstancePath, IopRegisterDeviceInterface(), NTSTATUS(), PAGED_CODE, SEPERATOR_CHAR, and USHORT.

03844 : 03845 03846 This device driver interface allows a WDM driver to register a particular 03847 interface of its underlying hardware (ie PDO) as a member of a function class. 03848 03849 Parameters: 03850 03851 PhysicalDeviceObject - Supplies a pointer to the PDO for the P&P device 03852 instance associated with the functionality being registered 03853 03854 InterfaceClassGuid - Supplies a pointer to the GUID representring the functionality 03855 to be registered 03856 03857 ReferenceString - Optionally, supplies an additional context string which is 03858 appended to the enumeration path of the device 03859 03860 SymbolicLinkName - Supplies a pointer to a string which on success will contain the 03861 kernel mode path of the symbolic link used to open this device. 03862 03863 Return Value: 03864 03865 Status code that indicates whether or not the function was successful. 03866 03867 --*/ 03868 03869 { 03870 PDEVICE_NODE pDeviceNode; 03871 PUNICODE_STRING pDeviceString; 03872 NTSTATUS status; 03873 PWSTR pRefString; 03874 USHORT count; 03875 03876 PAGED_CODE(); 03877 03878 // 03879 // Until PartMgr/Disk stop registering non PDOs allow the system to boot. 03880 // 03881 // ASSERT_PDO(PhysicalDeviceObject); 03882 // 03883 03884 // 03885 // Ensure we have a PDO - only PDO's have a device node attached 03886 // 03887 03888 pDeviceNode = (PDEVICE_NODE) PhysicalDeviceObject->DeviceObjectExtension->DeviceNode; 03889 if (pDeviceNode) { 03890 03891 // 03892 // Get the instance path string 03893 // 03894 pDeviceString = &pDeviceNode->InstancePath; 03895 03896 if (pDeviceNode->InstancePath.Length == 0) { 03897 return STATUS_INVALID_DEVICE_REQUEST; 03898 } 03899 03900 // 03901 // Make sure the ReferenceString does not contain any path seperator characters 03902 // 03903 if (ReferenceString) { 03904 pRefString = ReferenceString->Buffer; 03905 count = ReferenceString->Length / sizeof(WCHAR); 03906 while (count--) { 03907 if((*pRefString == SEPERATOR_CHAR) || (*pRefString == ALT_SEPERATOR_CHAR)) { 03908 status = STATUS_INVALID_DEVICE_REQUEST; 03909 KdPrint(("IoRegisterDeviceInterface: Invalid RefString!! failed with status = %8.8X\n", status)); 03910 return status; 03911 } 03912 pRefString++; 03913 } 03914 } 03915 03916 return IopRegisterDeviceInterface(pDeviceString, 03917 InterfaceClassGuid, 03918 ReferenceString, 03919 FALSE, // kernel-mode format 03920 SymbolicLinkName 03921 ); 03922 } else { 03923 03924 return STATUS_INVALID_DEVICE_REQUEST; 03925 } 03926 }

NTSTATUS IoRegisterPlugPlayNotification IN IO_NOTIFICATION_EVENT_CATEGORY  EventCategory,
IN ULONG  EventCategoryFlags,
IN PVOID EventCategoryData  OPTIONAL,
IN PDRIVER_OBJECT  DriverObject,
IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE  CallbackRoutine,
IN PVOID  Context,
OUT PVOID *  NotificationEntry
 

Definition at line 7495 of file pnpioapi.c.

References ASSERT, _DEVICE_CLASS_NOTIFY_ENTRY::Callback, _TARGET_DEVICE_NOTIFY_ENTRY::Callback, _HWPROFILE_NOTIFY_ENTRY::Callback, _SETUP_NOTIFY_DATA::Callback, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Callout, _DEVICE_CLASS_NOTIFY_ENTRY::ClassGuid, _NOTIFICATION_CALLBACK_PARAM_BLOCK::Context, _DEVICE_CLASS_NOTIFY_ENTRY::Context, _TARGET_DEVICE_NOTIFY_ENTRY::Context, _HWPROFILE_NOTIFY_ENTRY::Context, _SETUP_NOTIFY_DATA::Context, DbgPrint, DEVICE_CLASS_NOTIFY_ENTRY, _DEVICE_CLASS_NOTIFY_ENTRY::DriverObject, _TARGET_DEVICE_NOTIFY_ENTRY::DriverObject, _HWPROFILE_NOTIFY_ENTRY::DriverObject, _SETUP_NOTIFY_DATA::DriverObject, _DEVICE_INTERFACE_CHANGE_NOTIFICATION::Event, _DEVICE_CLASS_NOTIFY_ENTRY::EventCategory, _TARGET_DEVICE_NOTIFY_ENTRY::EventCategory, _HWPROFILE_NOTIFY_ENTRY::EventCategory, _SETUP_NOTIFY_DATA::EventCategory, EventCategoryDeviceInterfaceChange, EventCategoryHardwareProfileChange, EventCategoryReserved, EventCategoryTargetDeviceChange, ExAllocatePool, ExFreePool(), FALSE, _TARGET_DEVICE_NOTIFY_ENTRY::FileObject, HWPROFILE_NOTIFY_ENTRY, _DEVICE_INTERFACE_CHANGE_NOTIFICATION::InterfaceClassGuid, IoDriverObjectType, IoGetDeviceInterfaces(), IopAcquireNotifyLock, IopDeferredRegistrationList, IopDeferredRegistrationLock, IopDeviceClassNotifyList, IopDeviceClassNotifyLock, IopGetRelatedTargetDevice(), IopHashGuid, IopHwProfileNotifyLock, IopPnPHydraCallback(), IopProfileNotifyList, IopReferenceNotify(), IopReleaseNotifyLock, IopSetupNotifyData, IopTargetDeviceNotifyLock, KeGetCurrentThread, KernelMode, _SETUP_NOTIFY_DATA::ListEntry, _DEVICE_CLASS_NOTIFY_ENTRY::Lock, _TARGET_DEVICE_NOTIFY_ENTRY::Lock, _HWPROFILE_NOTIFY_ENTRY::Lock, _SETUP_NOTIFY_DATA::Lock, MmDispatchWin32Callout(), _NOTIFICATION_CALLBACK_PARAM_BLOCK::NotificationStructure, _DEFERRED_REGISTRATION_ENTRY::NotifyEntry, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByPointer(), PAGED_CODE, PagedPool, PDEFERRED_REGISTRATION_ENTRY, _TARGET_DEVICE_NOTIFY_ENTRY::PhysicalDeviceObject, _DEVICE_NODE::PhysicalDeviceObject, PiNotificationInProgress, PiNotificationInProgressLock, PKWIN32_CALLOUT, PNP_NOTIFICATION_VERSION, PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, _DEVICE_CLASS_NOTIFY_ENTRY::RefCount, _TARGET_DEVICE_NOTIFY_ENTRY::RefCount, _HWPROFILE_NOTIFY_ENTRY::RefCount, _SETUP_NOTIFY_DATA::RefCount, RtlInitUnicodeString(), SETUP_NOTIFY_DATA, _DEVICE_INTERFACE_CHANGE_NOTIFICATION::Size, _DEVICE_INTERFACE_CHANGE_NOTIFICATION::SymbolicLinkName, TARGET_DEVICE_NOTIFY_ENTRY, _DEVICE_NODE::TargetDeviceNotify, TRUE, _DEVICE_CLASS_NOTIFY_ENTRY::Unregistered, _TARGET_DEVICE_NOTIFY_ENTRY::Unregistered, _HWPROFILE_NOTIFY_ENTRY::Unregistered, _SETUP_NOTIFY_DATA::Unregistered, and _DEVICE_INTERFACE_CHANGE_NOTIFICATION::Version.

Referenced by DeviceClassCDROMNotify(), RegisterForDeviceChangeNotifications(), and xxxRegisterForDeviceClassNotifications().

07506 : 07507 07508 IoRegisterPlugPlayNotification provides a mechanism by which WDM drivers may 07509 receive notification (via callback) for a variety of Plug&Play events. 07510 07511 Arguments: 07512 07513 EventCategory - Specifies the event category being registered for. WDM drivers 07514 may currently register for hard-ware profile changes, device class changes 07515 (instance arrivals and removals), and target device changes (query-removal, 07516 cancel-removal, removal-complete, as well as 3rd-party extensible events). 07517 07518 EventCategoryFlags - Supplies flags that modify the behavior of event registration. 07519 There is a separate group of flags defined for each event category. Presently, 07520 only the interface device change event category has any flags defined: 07521 07522 DEVICE_CLASS_NOTIFY_FOR_EXISTING_DEVICES -- Drivers wishing to retrieve a 07523 complete list of all interface devices presently available, and keep 07524 the list up-to-date (i.e., receive notification of interface device 07525 arrivals and removals), may specify this flag. This will cause the 07526 PnP manager to immediately notify the driver about every currently-existing 07527 device of the specified interface class. 07528 07529 EventCategoryData - Used to 'filter' events of the desired category based on the 07530 supplied criteria. Not all event categories will use this parameter. The 07531 event categories presently defined use this information as fol-lows: 07532 07533 EventCategoryHardwareProfileChange -- this parameter is unused, and should be NULL. 07534 EventCategoryDeviceClassChange -- LPGUID representing the interface class of interest 07535 EventCategoryTargetDeviceChange -- PFILE_OBJECT of interest 07536 07537 DriverObject - The caller must supply a reference to its driver object (obtained via 07538 ObReferenceObject), to prevent the driver from being unloaded while registered for 07539 notification. The PnP Manager will dereference the driver object when the driver 07540 unregisters for notification via IoUnregisterPlugPlayNotification). 07541 07542 CallbackRoutine - Entry point within the driver that the PnP manager should call 07543 whenever an applicable PnP event occurs. The entry point must have the 07544 following prototype: 07545 07546 typedef 07547 NTSTATUS 07548 (*PDRIVER_NOTIFICATION_CALLBACK_ROUTINE) ( 07549 IN PVOID NotificationStructure, 07550 IN PVOID Context 07551 ); 07552 07553 where NotificationStructure contains information about the event. Each event 07554 GUID within an event category may potentially have its own notification structure 07555 format, but the buffer must al-ways begin with a PLUGPLAY_NOTIFICATION_HEADER, 07556 which indicates the size and ver-sion of the structure, as well as the GUID for 07557 the event. 07558 07559 The Context parameter provides the callback with the same context data that the 07560 caller passed in during registration. 07561 07562 Context - Points to the context data passed to the callback upon event notification. 07563 07564 NotificationEntry - Upon success, receives a handle representing the notification 07565 registration. This handle may be used to unregister for notification via 07566 IoUnregisterPlugPlayNotification. 07567 07568 --*/ 07569 { 07570 07571 NTSTATUS status = STATUS_SUCCESS; 07572 #if DBG 07573 ULONG originalApcDisable; 07574 #endif 07575 07576 PAGED_CODE(); 07577 07578 ASSERT(NotificationEntry); 07579 07580 // 07581 // Initialize out parameters 07582 // 07583 07584 *NotificationEntry = NULL; 07585 07586 // 07587 // Reference the driver object so it doesn't go away while we still have 07588 // a pointer outstanding 07589 // 07590 status = ObReferenceObjectByPointer(DriverObject, 07591 0, 07592 IoDriverObjectType, 07593 KernelMode 07594 ); 07595 07596 if (!NT_SUCCESS(status)) { 07597 return status; 07598 } 07599 07600 switch (EventCategory) { 07601 07602 case EventCategoryReserved: 07603 { 07604 07605 PSETUP_NOTIFY_DATA setupData; 07606 07607 // 07608 // Allocate space for the setup data 07609 // 07610 07611 setupData = ExAllocatePool(PagedPool, sizeof(SETUP_NOTIFY_DATA)); 07612 if (!setupData) { 07613 status = STATUS_INSUFFICIENT_RESOURCES; 07614 goto clean0; 07615 } 07616 07617 // 07618 // Store the required information 07619 // 07620 InitializeListHead(&(setupData->ListEntry)); 07621 setupData->EventCategory = EventCategory; 07622 setupData->Callback = CallbackRoutine; 07623 setupData->Context = Context; 07624 setupData->RefCount = 1; 07625 setupData->Unregistered = FALSE; 07626 setupData->Lock = NULL; 07627 setupData->DriverObject = DriverObject; 07628 07629 // 07630 // Activate the notifications 07631 // 07632 07633 IopSetupNotifyData = setupData; 07634 07635 // 07636 // Explicitly NULL out the returned entry as you can *NOT* unregister 07637 // for setup notifications 07638 // 07639 07640 *NotificationEntry = NULL; 07641 07642 break; 07643 07644 } 07645 07646 case EventCategoryHardwareProfileChange: 07647 { 07648 PHWPROFILE_NOTIFY_ENTRY entry; 07649 07650 // 07651 // new entry 07652 // 07653 entry =ExAllocatePool (PagedPool,sizeof (HWPROFILE_NOTIFY_ENTRY)); 07654 if (!entry) { 07655 status = STATUS_INSUFFICIENT_RESOURCES; 07656 goto clean0; 07657 } 07658 07659 // 07660 // grab the fields 07661 // 07662 07663 entry->EventCategory = EventCategory; 07664 entry->Callback = CallbackRoutine; 07665 entry->Context = Context; 07666 entry->RefCount = 1; 07667 entry->Unregistered = FALSE; 07668 entry->Lock = &IopHwProfileNotifyLock; 07669 entry->DriverObject = DriverObject; 07670 07671 ExAcquireFastMutex(&PiNotificationInProgressLock); 07672 if (PiNotificationInProgress) { 07673 // 07674 // If a notification is in progress, mark the entry as 07675 // Unregistered until after the current notification is 07676 // complete. 07677 // 07678 07679 PDEFERRED_REGISTRATION_ENTRY deferredNode; 07680 07681 deferredNode = ExAllocatePool(PagedPool, sizeof(DEFERRED_REGISTRATION_ENTRY)); 07682 if (!deferredNode) { 07683 ExReleaseFastMutex(&PiNotificationInProgressLock); 07684 status = STATUS_INSUFFICIENT_RESOURCES; 07685 goto clean0; 07686 } 07687 07688 deferredNode->NotifyEntry = (PNOTIFY_ENTRY_HEADER)entry; 07689 07690 // 07691 // Consider this entry unregistered during the current 07692 // notification 07693 // 07694 entry->Unregistered = TRUE; 07695 07696 // 07697 // Reference the entry so that it doesn't go away until it has 07698 // been removed from the deferred registration list 07699 // 07700 IopReferenceNotify((PNOTIFY_ENTRY_HEADER)entry); 07701 07702 // 07703 // Add this entry to the deferred registration list 07704 // 07705 IopAcquireNotifyLock(&IopDeferredRegistrationLock); 07706 InsertTailList(&IopDeferredRegistrationList, (PLIST_ENTRY)deferredNode); 07707 IopReleaseNotifyLock(&IopDeferredRegistrationLock); 07708 } else { 07709 // 07710 // If there is currently no notification in progress, the deferred 07711 // registration list must be empty. 07712 // 07713 ASSERT(IsListEmpty(&IopDeferredRegistrationList)); 07714 } 07715 ExReleaseFastMutex(&PiNotificationInProgressLock); 07716 07717 // 07718 // Lock the list, insert the new entry, and unlock it. 07719 // 07720 07721 IopAcquireNotifyLock(&IopHwProfileNotifyLock); 07722 InsertTailList(&IopProfileNotifyList, (PLIST_ENTRY)entry); 07723 IopReleaseNotifyLock(&IopHwProfileNotifyLock); 07724 07725 *NotificationEntry = entry; 07726 07727 break; 07728 } 07729 case EventCategoryTargetDeviceChange: 07730 { 07731 PTARGET_DEVICE_NOTIFY_ENTRY entry; 07732 IO_STACK_LOCATION irpSp; 07733 PDEVICE_NODE deviceNode; 07734 07735 ASSERT(EventCategoryData); 07736 07737 // 07738 // Allocate a new list entry 07739 // 07740 07741 entry = ExAllocatePool(PagedPool, sizeof(TARGET_DEVICE_NOTIFY_ENTRY)); 07742 if (!entry) { 07743 status = STATUS_INSUFFICIENT_RESOURCES; 07744 goto clean0; 07745 } 07746 07747 // 07748 // Retrieve the device object associated with this file handle. 07749 // 07750 status = IopGetRelatedTargetDevice((PFILE_OBJECT)EventCategoryData, 07751 &deviceNode); 07752 if (!NT_SUCCESS(status)) { 07753 ExFreePool(entry); 07754 goto clean0; 07755 } 07756 07757 // 07758 // Fill out the entry 07759 // 07760 07761 entry->EventCategory = EventCategory; 07762 entry->Callback = CallbackRoutine; 07763 entry->Context = Context; 07764 entry->DriverObject = DriverObject; 07765 entry->RefCount = 1; 07766 entry->Unregistered = FALSE; 07767 entry->Lock = &IopTargetDeviceNotifyLock; 07768 entry->FileObject = (PFILE_OBJECT)EventCategoryData; 07769 07770 // 07771 // The PDO associated with the devnode we got back from 07772 // IopGetRelatedTargetDevice has already been referenced by that 07773 // routine. Store this reference away in the notification entry, 07774 // so we can deref it later when the notification entry is unregistered. 07775 // 07776 07777 ASSERT(deviceNode->PhysicalDeviceObject); 07778 entry->PhysicalDeviceObject = deviceNode->PhysicalDeviceObject; 07779 07780 ExAcquireFastMutex(&PiNotificationInProgressLock); 07781 if (PiNotificationInProgress) { 07782 // 07783 // If a notification is in progress, mark the entry as 07784 // Unregistered until after the current notification is 07785 // complete. 07786 // 07787 07788 PDEFERRED_REGISTRATION_ENTRY deferredNode; 07789 07790 deferredNode = ExAllocatePool(PagedPool, sizeof(DEFERRED_REGISTRATION_ENTRY)); 07791 if (!deferredNode) { 07792 ExReleaseFastMutex(&PiNotificationInProgressLock); 07793 status = STATUS_INSUFFICIENT_RESOURCES; 07794 goto clean0; 07795 } 07796 07797 deferredNode->NotifyEntry = (PNOTIFY_ENTRY_HEADER)entry; 07798 07799 // 07800 // Consider this entry unregistered during the current 07801 // notification 07802 // 07803 entry->Unregistered = TRUE; 07804 07805 // 07806 // Reference the entry so that it doesn't go away until it has 07807 // been removed from the deferred registration list 07808 // 07809 IopReferenceNotify((PNOTIFY_ENTRY_HEADER)entry); 07810 07811 // 07812 // Add this entry to the deferred registration list 07813 // 07814 IopAcquireNotifyLock(&IopDeferredRegistrationLock); 07815 InsertTailList(&IopDeferredRegistrationList, (PLIST_ENTRY)deferredNode); 07816 IopReleaseNotifyLock(&IopDeferredRegistrationLock); 07817 } else { 07818 // 07819 // If there is currently no notification in progress, the deferred 07820 // registration list must be empty. 07821 // 07822 ASSERT(IsListEmpty(&IopDeferredRegistrationList)); 07823 } 07824 ExReleaseFastMutex(&PiNotificationInProgressLock); 07825 07826 // 07827 // Lock the list, insert the new entry, and unlock it. 07828 // 07829 07830 IopAcquireNotifyLock(&IopTargetDeviceNotifyLock); 07831 InsertTailList(&deviceNode->TargetDeviceNotify, (PLIST_ENTRY)entry); 07832 IopReleaseNotifyLock(&IopTargetDeviceNotifyLock); 07833 07834 *NotificationEntry = entry; 07835 break; 07836 } 07837 07838 case EventCategoryDeviceInterfaceChange: 07839 { 07840 PDEVICE_CLASS_NOTIFY_ENTRY entry; 07841 07842 ASSERT(EventCategoryData); 07843 07844 // 07845 // Allocate a new list entry 07846 // 07847 07848 entry = ExAllocatePool(PagedPool, sizeof(DEVICE_CLASS_NOTIFY_ENTRY)); 07849 if (!entry) { 07850 status = STATUS_INSUFFICIENT_RESOURCES; 07851 goto clean0; 07852 } 07853 07854 // 07855 // Fill out the entry 07856 // 07857 07858 entry->EventCategory = EventCategory; 07859 entry->Callback = CallbackRoutine; 07860 entry->Context = Context; 07861 entry->ClassGuid = *((LPGUID) EventCategoryData); 07862 entry->RefCount = 1; 07863 entry->Unregistered = FALSE; 07864 entry->Lock = &IopDeviceClassNotifyLock; 07865 entry->DriverObject = DriverObject; 07866 07867 ExAcquireFastMutex(&PiNotificationInProgressLock); 07868 if (PiNotificationInProgress) { 07869 // 07870 // If a notification is in progress, mark the entry as 07871 // Unregistered until after the current notification is 07872 // complete. 07873 // 07874 07875 PDEFERRED_REGISTRATION_ENTRY deferredNode; 07876 07877 deferredNode = ExAllocatePool(PagedPool, sizeof(DEFERRED_REGISTRATION_ENTRY)); 07878 if (!deferredNode) { 07879 ExReleaseFastMutex(&PiNotificationInProgressLock); 07880 status = STATUS_INSUFFICIENT_RESOURCES; 07881 goto clean0; 07882 } 07883 07884 deferredNode->NotifyEntry = (PNOTIFY_ENTRY_HEADER)entry; 07885 07886 // 07887 // Consider this entry unregistered during the current 07888 // notification 07889 // 07890 entry->Unregistered = TRUE; 07891 07892 // 07893 // Reference the entry so that it doesn't go away until it has 07894 // been removed from the deferred registration list 07895 // 07896 IopReferenceNotify((PNOTIFY_ENTRY_HEADER)entry); 07897 07898 // 07899 // Add this entry to the deferred registration list 07900 // 07901 IopAcquireNotifyLock(&IopDeferredRegistrationLock); 07902 InsertTailList(&IopDeferredRegistrationList, (PLIST_ENTRY)deferredNode); 07903 IopReleaseNotifyLock(&IopDeferredRegistrationLock); 07904 } else { 07905 // 07906 // If there is currently no notification in progress, the deferred 07907 // registration list must be empty. 07908 // 07909 ASSERT(IsListEmpty(&IopDeferredRegistrationList)); 07910 } 07911 ExReleaseFastMutex(&PiNotificationInProgressLock); 07912 07913 // 07914 // Lock the list 07915 // 07916 07917 IopAcquireNotifyLock(&IopDeviceClassNotifyLock); 07918 07919 // 07920 // Insert it at the tail 07921 // 07922 07923 InsertTailList( (PLIST_ENTRY) &(IopDeviceClassNotifyList[ IopHashGuid(&(entry->ClassGuid)) ]), 07924 (PLIST_ENTRY) entry 07925 ); 07926 07927 // 07928 // Unlock the list 07929 // 07930 07931 IopReleaseNotifyLock(&IopDeviceClassNotifyLock); 07932 07933 // 07934 // See if we need to notify for all the device classes already present 07935 // 07936 07937 if (EventCategoryFlags & PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES) { 07938 07939 PWCHAR pSymbolicLinks, pCurrent; 07940 DEVICE_INTERFACE_CHANGE_NOTIFICATION notification; 07941 UNICODE_STRING unicodeString; 07942 07943 // 07944 // Fill in the notification structure 07945 // 07946 07947 notification.Version = PNP_NOTIFICATION_VERSION; 07948 notification.Size = sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION); 07949 notification.Event = GUID_DEVICE_INTERFACE_ARRIVAL; 07950 notification.InterfaceClassGuid = entry->ClassGuid; 07951 07952 // 07953 // Get the list of all the devices of this function class that are 07954 // already in the system 07955 // 07956 07957 status = IoGetDeviceInterfaces(&(entry->ClassGuid), 07958 NULL, 07959 0, 07960 &pSymbolicLinks 07961 ); 07962 if (!NT_SUCCESS(status)) { 07963 // 07964 // No buffer will have been returned so just return status 07965 // 07966 goto clean0; 07967 } 07968 07969 // 07970 // Callback for each device currently in the system 07971 // 07972 07973 pCurrent = pSymbolicLinks; 07974 while(*pCurrent != UNICODE_NULL) { 07975 NOTIFICATION_CALLBACK_PARAM_BLOCK callparams; 07976 ULONG Console=0; 07977 07978 RtlInitUnicodeString(&unicodeString, pCurrent); 07979 notification.SymbolicLinkName = &unicodeString; 07980 07981 #if DBG 07982 originalApcDisable = KeGetCurrentThread()->KernelApcDisable; 07983 #endif 07984 // 07985 // Call back on the registered notification routine 07986 // 07987 callparams.Callout=(*CallbackRoutine); 07988 callparams.NotificationStructure=&notification; 07989 callparams.Context=Context; 07990 07991 07992 // 07993 // Dispatch this function via the memory manager. 07994 // Win32K is a driver that can have multiple copies. If Hydra 07995 // is running, the Mem. manager will check if the callback exists 07996 // in "per session" space. If that is the case, it will attach to the 07997 // console (hence the 3rd param of PULONG containing 0) session and deliver 07998 // it. If either Hydra is not running, or the callback is outside session space 07999 // then the callback is called directly. 08000 // 08001 MmDispatchWin32Callout ((PKWIN32_CALLOUT)callparams.Callout,&IopPnPHydraCallback,&callparams,&Console); 08002 08003 #if DBG 08004 if (originalApcDisable != KeGetCurrentThread()->KernelApcDisable) { 08005 DbgPrint("IoRegisterPlugPlayNotification: Driver %Z, notification handler @ 0x%p returned with different KernelApcDisable = %d, original = %d\n", 08006 &entry->DriverObject->DriverName, entry->Callback, KeGetCurrentThread()->KernelApcDisable, originalApcDisable); 08007 DbgBreakPoint(); 08008 } 08009 #endif 08010 08011 pCurrent += (unicodeString.Length / sizeof(WCHAR)) + 1; 08012 08013 } 08014 08015 ExFreePool(pSymbolicLinks); 08016 08017 } 08018 08019 *NotificationEntry = entry; 08020 } 08021 08022 break; 08023 } 08024 08025 clean0: 08026 08027 if (!NT_SUCCESS(status)) { 08028 ObDereferenceObject(DriverObject); 08029 } 08030 08031 return status; 08032 }

NTSTATUS IoReportDetectedDevice IN PDRIVER_OBJECT  DriverObject,
IN INTERFACE_TYPE  LegacyBusType,
IN ULONG  BusNumber,
IN ULONG  SlotNumber,
IN PCM_RESOURCE_LIST  ResourceList,
IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements  OPTIONAL,
IN BOOLEAN  ResourceAssigned,
IN OUT PDEVICE_OBJECT DeviceObject
 

Definition at line 1548 of file pnpioapi.c.

References ArbiterRequestLegacyReported, ASSERT, BusNumber, CmRegistryMachineSystemCurrentControlSetEnumName, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_ADDED, DNF_ENUMERATED, DNF_HAS_PROBLEM, DNF_MADEUP, DNF_NEED_ENUMERATION_ONLY, DNF_NEED_QUERY_IDS, DNF_NO_RESOURCE_REQUIRED, DNF_PROCESSED, DNF_STARTED, DO_BUS_ENUMERATED_DEVICE, DRVO_BUILTIN_DRIVER, ExAcquireResourceShared, ExAllocatePool, ExFreePool(), exit, ExReleaseResource, FALSE, _DEVICE_OBJECT::Flags, _DEVICE_NODE::Flags, _DEVICE_NODE::InstancePath, IoCreateDevice(), IoDeleteDevice(), IopAllocateDeviceNode(), IopConcatenateUnicodeStrings(), IopCreateRegistryKeyEx(), IopDeleteLegacyKey(), IopDetermineResourceListSize(), IopDeviceObjectFromDeviceInstance(), IopDeviceObjectToDeviceInstance(), IopDoDeferredSetInterfaceState(), IopDoesDevNodeHaveProblem, IopDuplicateDetection(), IopInsertTreeDeviceNode(), IopIsReportedAlready(), IopNotifySetupDeviceArrival(), IoPnpDriverObject, IopNumberDeviceNodes, IopOpenRegistryKeyEx(), IopReleaseDeviceResources(), IopRootDeviceNode, IopSetDevNodeProblem, IopWriteAllocatedResourcesToRegistry(), IoReportResourceUsageInternal(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KeQueryTickCount(), L, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObject, PAGED_CODE, PagedPool, _DEVICE_NODE::PhysicalDeviceObject, PpCreateLegacyDeviceIds(), PpDeviceRegistration(), PpRegistryDeviceResource, _DEVICE_NODE::Problem, RtlInitUnicodeString(), _DEVICE_NODE::ServiceName, TITLE_INDEX_VALUE, TRUE, and USHORT.

01561 : 01562 01563 PnP device drivers call this API to report any device detected. This routine 01564 creates a Physical Device object, reference the Physical Device object and 01565 returns back to the callers. Once the detected device is reported, the Pnp manager 01566 considers the device has been fully controlled by the reporting drivers. Thus it 01567 will not invoke AddDevice entry and send StartDevice irp to the driver. 01568 01569 The driver needs to report the resources it used to detect this device such that 01570 pnp manager can perform duplicates detection on this device. 01571 01572 The caller must dereference the DeviceObject once it no longer needs it. 01573 01574 Parameters: 01575 01576 DriverObject - Supplies the driver object of the driver who detected 01577 this device. 01578 01579 ResourceList - Supplies a pointer to the resource list which the driver used 01580 to detect the device. 01581 01582 ResourceRequirements - supplies a pointer to the resource requirements list 01583 for the detected device. This is optional. 01584 01585 ResourceAssigned - if TRUE, the driver already called IoReportResourceUsage or 01586 IoAssignResource to get the ownership of the resources. Otherwise, 01587 the PnP manager will call IoReportResourceUsage to allocate the 01588 resources for the driver. 01589 01590 DeviceObject - if NULL, this routine will create a PDO and return it thru this variable. 01591 Otherwise, a PDO is already created and this routine will simply use the supplied 01592 PDO. 01593 01594 Return Value: 01595 01596 Status code that indicates whether or not the function was successful. 01597 01598 01599 --*/ 01600 01601 { 01602 WCHAR buffer[60]; 01603 NTSTATUS status; 01604 UNICODE_STRING deviceName, instanceName, unicodeName, *serviceName, driverName; 01605 PDEVICE_NODE deviceNode; 01606 ULONG length, i = 0, disposition, tmpValue, listSize = 0; 01607 HANDLE handle, handle1, logConfHandle, controlHandle, hTreeHandle, enumHandle; 01608 PCM_RESOURCE_LIST cmResource; 01609 PWSTR p; 01610 LARGE_INTEGER tickCount; 01611 PDEVICE_OBJECT deviceObject; 01612 BOOLEAN newlyCreated = FALSE; 01613 01614 PAGED_CODE(); 01615 01616 if (*DeviceObject) { 01617 01618 deviceObject = *DeviceObject; 01619 01620 // 01621 // The PDO is already known. simply handle the resourcelist and resreq list. 01622 // This is a hack for NDIS drivers. 01623 // 01624 deviceNode = (PDEVICE_NODE)(*DeviceObject)->DeviceObjectExtension->DeviceNode; 01625 if (!deviceNode) { 01626 return STATUS_NO_SUCH_DEVICE; 01627 } 01628 01629 KeEnterCriticalRegion(); 01630 ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE); 01631 01632 // 01633 // Write ResourceList and ResReq list to the device instance 01634 // 01635 01636 status = IopDeviceObjectToDeviceInstance (*DeviceObject, 01637 &handle, 01638 KEY_ALL_ACCESS 01639 ); 01640 if (!NT_SUCCESS(status)) { 01641 ExReleaseResource(&PpRegistryDeviceResource); 01642 KeLeaveCriticalRegion(); 01643 return status; 01644 } 01645 if (ResourceAssigned) { 01646 RtlInitUnicodeString(&unicodeName, REGSTR_VALUE_NO_RESOURCE_AT_INIT); 01647 tmpValue = 1; 01648 ZwSetValueKey(handle, 01649 &unicodeName, 01650 TITLE_INDEX_VALUE, 01651 REG_DWORD, 01652 &tmpValue, 01653 sizeof(tmpValue) 01654 ); 01655 } 01656 RtlInitUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF); 01657 status = IopCreateRegistryKeyEx( &logConfHandle, 01658 handle, 01659 &unicodeName, 01660 KEY_ALL_ACCESS, 01661 REG_OPTION_NON_VOLATILE, 01662 NULL 01663 ); 01664 ZwClose(handle); 01665 if (NT_SUCCESS(status)) { 01666 01667 // 01668 // Write the ResourceList and and ResourceRequirements to the logconf key under 01669 // device instance key. 01670 // 01671 01672 if (ResourceList) { 01673 RtlInitUnicodeString(&unicodeName, REGSTR_VAL_BOOTCONFIG); 01674 ZwSetValueKey( 01675 logConfHandle, 01676 &unicodeName, 01677 TITLE_INDEX_VALUE, 01678 REG_RESOURCE_LIST, 01679 ResourceList, 01680 listSize = IopDetermineResourceListSize(ResourceList) 01681 ); 01682 } 01683 if (ResourceRequirements) { 01684 RtlInitUnicodeString(&unicodeName, REGSTR_VALUE_BASIC_CONFIG_VECTOR); 01685 ZwSetValueKey( 01686 logConfHandle, 01687 &unicodeName, 01688 TITLE_INDEX_VALUE, 01689 REG_RESOURCE_REQUIREMENTS_LIST, 01690 ResourceRequirements, 01691 ResourceRequirements->ListSize 01692 ); 01693 } 01694 ZwClose(logConfHandle); 01695 } 01696 ExReleaseResource(&PpRegistryDeviceResource); 01697 KeLeaveCriticalRegion(); 01698 if (NT_SUCCESS(status)) { 01699 goto checkResource; 01700 } else { 01701 return status; 01702 } 01703 } 01704 01705 // 01706 // Normal case: *DeviceObject is NULL 01707 // 01708 01709 *DeviceObject = NULL; 01710 serviceName = &DriverObject->DriverExtension->ServiceKeyName; 01711 01712 // 01713 // Special handling for driver object created thru IoCreateDriver. 01714 // When a builtin driver calls IoReportDetectedDevice, the ServiceKeyName of 01715 // the driver object is set to \Driver\DriverName. To create a detected device 01716 // instance key, we will take only the DriverName. 01717 // 01718 01719 if (DriverObject->Flags & DRVO_BUILTIN_DRIVER) { 01720 p = serviceName->Buffer + (serviceName->Length / sizeof(WCHAR)) - 1; 01721 driverName.Length = 0; 01722 while (*p != '\\' && (p != serviceName->Buffer)) { 01723 p--; 01724 driverName.Length += sizeof(WCHAR); 01725 } 01726 if (p == serviceName->Buffer) { 01727 return STATUS_UNSUCCESSFUL; 01728 } else { 01729 p++; 01730 driverName.Buffer = p; 01731 driverName.MaximumLength = driverName.Length + sizeof(WCHAR); 01732 } 01733 } else { 01734 01735 // 01736 // Before doing anything first perform duplicate detection 01737 // 01738 01739 status = IopDuplicateDetection( 01740 LegacyBusType, 01741 BusNumber, 01742 SlotNumber, 01743 &deviceNode 01744 ); 01745 01746 if (NT_SUCCESS(status) && deviceNode) { 01747 deviceObject = deviceNode->PhysicalDeviceObject; 01748 if ((deviceNode->Flags & DNF_ADDED) || 01749 (IopDoesDevNodeHaveProblem(deviceNode) && 01750 deviceNode->Problem != CM_PROB_NOT_CONFIGURED && 01751 deviceNode->Problem != CM_PROB_REINSTALL && 01752 deviceNode->Problem != CM_PROB_FAILED_INSTALL)) { 01753 01754 // 01755 // BUGBUG: This assumption may not be true. 01756 // 01757 01758 ObDereferenceObject(deviceObject); 01759 01760 return STATUS_NO_SUCH_DEVICE; 01761 } 01762 01763 deviceNode->Flags &= ~DNF_HAS_PROBLEM; 01764 deviceNode->Problem = 0; 01765 01766 IopDeleteLegacyKey(DriverObject); 01767 goto checkResource; 01768 } 01769 01770 } 01771 01772 // 01773 // Create a PDO and its DeviceNode 01774 // 01775 01776 // 01777 // Madeup a name for the device object. 01778 // 01779 01780 KeQueryTickCount(&tickCount); 01781 length = _snwprintf(buffer, sizeof(buffer) / sizeof(WCHAR), L"\\Device\\%04u%x", IopNumberDeviceNodes, tickCount.LowPart); 01782 deviceName.MaximumLength = sizeof(buffer); 01783 deviceName.Length = (USHORT)(length * sizeof(WCHAR)); 01784 deviceName.Buffer = buffer; \ 01785 01786 status = IoCreateDevice( IoPnpDriverObject, 01787 sizeof(IOPNP_DEVICE_EXTENSION), 01788 &deviceName, 01789 FILE_DEVICE_CONTROLLER, 01790 0, 01791 FALSE, 01792 &deviceObject ); 01793 01794 if (NT_SUCCESS(status)) { 01795 deviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE; // Mark this is a PDO 01796 deviceNode = IopAllocateDeviceNode(deviceObject); 01797 if (deviceNode) { 01798 01799 // 01800 // First delete the Legacy_DriverName key and subkeys from Enum\Root, if exits. 01801 // 01802 01803 if (!(DriverObject->Flags & DRVO_BUILTIN_DRIVER)) { 01804 IopDeleteLegacyKey(DriverObject); 01805 } 01806 01807 // 01808 // Create the compatible id list we'll use for this made-up device. 01809 // 01810 01811 status = PpCreateLegacyDeviceIds( 01812 deviceObject, 01813 ((DriverObject->Flags & DRVO_BUILTIN_DRIVER) ? 01814 &driverName : serviceName), 01815 ResourceList); 01816 01817 if(!NT_SUCCESS(status)) { 01818 goto exit; 01819 } 01820 01821 // 01822 // Create/Open a registry key for the device instance and 01823 // write the addr of the device object to registry 01824 // 01825 01826 if (DriverObject->Flags & DRVO_BUILTIN_DRIVER) { 01827 length = _snwprintf(buffer, sizeof(buffer) / sizeof(WCHAR), L"ROOT\\%s", driverName.Buffer); 01828 } else { 01829 length = _snwprintf(buffer, sizeof(buffer) / sizeof(WCHAR), L"ROOT\\%s", serviceName->Buffer); 01830 } 01831 deviceName.MaximumLength = sizeof(buffer); 01832 ASSERT(length <= sizeof(buffer) - 10); 01833 deviceName.Length = (USHORT)(length * sizeof(WCHAR)); 01834 deviceName.Buffer = buffer; 01835 01836 KeEnterCriticalRegion(); 01837 ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE); 01838 01839 status = IopOpenRegistryKeyEx( &enumHandle, 01840 NULL, 01841 &CmRegistryMachineSystemCurrentControlSetEnumName, 01842 KEY_ALL_ACCESS 01843 ); 01844 if (!NT_SUCCESS(status)) { 01845 goto exit; 01846 } 01847 01848 status = IopCreateRegistryKeyEx( &handle1, 01849 enumHandle, 01850 &deviceName, 01851 KEY_ALL_ACCESS, 01852 REG_OPTION_NON_VOLATILE, 01853 &disposition 01854 ); 01855 01856 if (NT_SUCCESS(status)) { 01857 deviceName.Buffer[deviceName.Length / sizeof(WCHAR)] = 01858 OBJ_NAME_PATH_SEPARATOR; 01859 deviceName.Length += sizeof(WCHAR); 01860 if (disposition != REG_CREATED_NEW_KEY) { 01861 while (TRUE) { 01862 PiUlongToInstanceKeyUnicodeString(&instanceName, 01863 buffer + deviceName.Length / sizeof(WCHAR), 01864 sizeof(buffer) - deviceName.Length, 01865 i 01866 ); 01867 status = IopCreateRegistryKeyEx( &handle, 01868 handle1, 01869 &instanceName, 01870 KEY_ALL_ACCESS, 01871 REG_OPTION_NON_VOLATILE, 01872 &disposition 01873 ); 01874 if (NT_SUCCESS(status)) { 01875 if (disposition == REG_CREATED_NEW_KEY) { 01876 ZwClose(handle1); 01877 break; 01878 } else { 01879 if (IopIsReportedAlready(handle, serviceName, ResourceList)) { 01880 01881 // 01882 // Write the reported resources to registry in case the irq changed 01883 // 01884 01885 RtlInitUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF); 01886 status = IopCreateRegistryKeyEx( &logConfHandle, 01887 handle, 01888 &unicodeName, 01889 KEY_ALL_ACCESS, 01890 REG_OPTION_NON_VOLATILE, 01891 NULL 01892 ); 01893 if (NT_SUCCESS(status)) { 01894 01895 // 01896 // Write the ResourceList and and ResourceRequirements to the device instance key 01897 // 01898 01899 if (ResourceList) { 01900 RtlInitUnicodeString(&unicodeName, REGSTR_VAL_BOOTCONFIG); 01901 ZwSetValueKey( 01902 logConfHandle, 01903 &unicodeName, 01904 TITLE_INDEX_VALUE, 01905 REG_RESOURCE_LIST, 01906 ResourceList, 01907 listSize = IopDetermineResourceListSize(ResourceList) 01908 ); 01909 } 01910 if (ResourceRequirements) { 01911 RtlInitUnicodeString(&unicodeName, REGSTR_VALUE_BASIC_CONFIG_VECTOR); 01912 ZwSetValueKey( 01913 logConfHandle, 01914 &unicodeName, 01915 TITLE_INDEX_VALUE, 01916 REG_RESOURCE_REQUIREMENTS_LIST, 01917 ResourceRequirements, 01918 ResourceRequirements->ListSize 01919 ); 01920 } 01921 ZwClose(logConfHandle); 01922 } 01923 01924 ExReleaseResource(&PpRegistryDeviceResource); 01925 KeLeaveCriticalRegion(); 01926 IoDeleteDevice(deviceObject); 01927 ZwClose(handle1); 01928 deviceObject = IopDeviceObjectFromDeviceInstance ( 01929 handle, NULL); // Add a reference 01930 ZwClose(handle); 01931 ZwClose(enumHandle); 01932 ASSERT(deviceObject); 01933 if (deviceObject == NULL) { 01934 status = STATUS_UNSUCCESSFUL; 01935 return status; 01936 } 01937 deviceNode = (PDEVICE_NODE) 01938 deviceObject->DeviceObjectExtension->DeviceNode; 01939 goto checkResource; 01940 } else { 01941 i++; 01942 ZwClose(handle); 01943 continue; 01944 } 01945 } 01946 } else { 01947 ZwClose(handle1); 01948 ZwClose(enumHandle); 01949 goto exit; 01950 } 01951 } 01952 } else { 01953 01954 // 01955 // This is a new device key. So, instance is 0. Create it. 01956 // 01957 01958 PiUlongToInstanceKeyUnicodeString(&instanceName, 01959 buffer + deviceName.Length / sizeof(WCHAR), 01960 sizeof(buffer) - deviceName.Length, 01961 i 01962 ); 01963 status = IopCreateRegistryKeyEx( &handle, 01964 handle1, 01965 &instanceName, 01966 KEY_ALL_ACCESS, 01967 REG_OPTION_NON_VOLATILE, 01968 &disposition 01969 ); 01970 ZwClose(handle1); 01971 if (!NT_SUCCESS(status)) { 01972 ZwClose(enumHandle); 01973 goto exit; 01974 } 01975 ASSERT(disposition == REG_CREATED_NEW_KEY); 01976 } 01977 } else { 01978 ZwClose(enumHandle); 01979 goto exit; 01980 } 01981 01982 deviceName.Length += instanceName.Length; 01983 ASSERT(disposition == REG_CREATED_NEW_KEY); 01984 newlyCreated = TRUE; 01985 01986 // 01987 // Initialize new device instance registry key 01988 // 01989 01990 if (ResourceAssigned) { 01991 RtlInitUnicodeString(&unicodeName, REGSTR_VALUE_NO_RESOURCE_AT_INIT); 01992 tmpValue = 1; 01993 ZwSetValueKey(handle, 01994 &unicodeName, 01995 TITLE_INDEX_VALUE, 01996 REG_DWORD, 01997 &tmpValue, 01998 sizeof(tmpValue) 01999 ); 02000 } 02001 RtlInitUnicodeString(&unicodeName, REGSTR_KEY_LOG_CONF); 02002 logConfHandle = NULL; 02003 status = IopCreateRegistryKeyEx( &logConfHandle, 02004 handle, 02005 &unicodeName, 02006 KEY_ALL_ACCESS, 02007 REG_OPTION_NON_VOLATILE, 02008 NULL 02009 ); 02010 02011 ASSERT(status == STATUS_SUCCESS); 02012 02013 if (NT_SUCCESS(status)) { 02014 02015 // 02016 // Write the ResourceList and and ResourceRequirements to the logconf key under 02017 // device instance key. 02018 // 02019 02020 if (ResourceList) { 02021 RtlInitUnicodeString(&unicodeName, REGSTR_VAL_BOOTCONFIG); 02022 ZwSetValueKey( 02023 logConfHandle, 02024 &unicodeName, 02025 TITLE_INDEX_VALUE, 02026 REG_RESOURCE_LIST, 02027 ResourceList, 02028 listSize = IopDetermineResourceListSize(ResourceList) 02029 ); 02030 } 02031 if (ResourceRequirements) { 02032 RtlInitUnicodeString(&unicodeName, REGSTR_VALUE_BASIC_CONFIG_VECTOR); 02033 ZwSetValueKey( 02034 logConfHandle, 02035 &unicodeName, 02036 TITLE_INDEX_VALUE, 02037 REG_RESOURCE_REQUIREMENTS_LIST, 02038 ResourceRequirements, 02039 ResourceRequirements->ListSize 02040 ); 02041 } 02042 //ZwClose(logConfHandle); 02043 } 02044 02045 RtlInitUnicodeString(&unicodeName, REGSTR_VALUE_CONFIG_FLAGS); 02046 tmpValue = CONFIGFLAG_FINISH_INSTALL; 02047 ZwSetValueKey(handle, 02048 &unicodeName, 02049 TITLE_INDEX_VALUE, 02050 REG_DWORD, 02051 &tmpValue, 02052 sizeof(tmpValue) 02053 ); 02054 02055 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_LEGACY); 02056 tmpValue = 0; 02057 ZwSetValueKey( 02058 handle, 02059 &unicodeName, 02060 TITLE_INDEX_VALUE, 02061 REG_DWORD, 02062 &tmpValue, 02063 sizeof(ULONG) 02064 ); 02065 02066 RtlInitUnicodeString(&unicodeName, REGSTR_KEY_CONTROL); 02067 controlHandle = NULL; 02068 IopCreateRegistryKeyEx( &controlHandle, 02069 handle, 02070 &unicodeName, 02071 KEY_ALL_ACCESS, 02072 REG_OPTION_VOLATILE, 02073 NULL 02074 ); 02075 02076 ASSERT(status == STATUS_SUCCESS); 02077 02078 if (NT_SUCCESS(status)) { 02079 02080 // 02081 // Write DeviceObject reference ... 02082 // 02083 02084 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_DEVICE_REFERENCE); 02085 status = ZwSetValueKey(controlHandle, 02086 &unicodeName, 02087 TITLE_INDEX_VALUE, 02088 REG_DWORD, 02089 (PULONG_PTR)&deviceObject, 02090 sizeof(ULONG_PTR) 02091 ); 02092 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_DEVICE_REPORTED); 02093 tmpValue = 1; 02094 status = ZwSetValueKey(controlHandle, 02095 &unicodeName, 02096 TITLE_INDEX_VALUE, 02097 REG_DWORD, 02098 &tmpValue, 02099 sizeof(ULONG) 02100 ); 02101 status = ZwSetValueKey(handle, 02102 &unicodeName, 02103 TITLE_INDEX_VALUE, 02104 REG_DWORD, 02105 &tmpValue, 02106 sizeof(ULONG) 02107 ); 02108 02109 //ZwClose(controlHandle); 02110 } 02111 02112 ZwClose(enumHandle); 02113 02114 // 02115 // Create Service value name and set it to the calling driver's service 02116 // key name. 02117 // 02118 02119 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_SERVICE); 02120 p = (PWSTR)ExAllocatePool(PagedPool, serviceName->Length + sizeof(UNICODE_NULL)); 02121 if (!p) { 02122 goto CleanupRegistry; 02123 } 02124 RtlMoveMemory(p, serviceName->Buffer, serviceName->Length); 02125 p[serviceName->Length / sizeof (WCHAR)] = UNICODE_NULL; 02126 ZwSetValueKey( 02127 handle, 02128 &unicodeName, 02129 TITLE_INDEX_VALUE, 02130 REG_SZ, 02131 p, 02132 serviceName->Length + sizeof(UNICODE_NULL) 02133 ); 02134 if (DriverObject->Flags & DRVO_BUILTIN_DRIVER) { 02135 deviceNode->ServiceName = *serviceName; 02136 } else { 02137 ExFreePool(p); 02138 } 02139 02140 ExReleaseResource(&PpRegistryDeviceResource); 02141 KeLeaveCriticalRegion(); 02142 //ZwClose(logConfHandle); 02143 //ZwClose(controlHandle); 02144 //ZwClose(handle); 02145 02146 // 02147 // Register the device for the driver and save the device 02148 // instance path in device node. 02149 // 02150 02151 if (!(DriverObject->Flags & DRVO_BUILTIN_DRIVER)) { 02152 PpDeviceRegistration( &deviceName, 02153 TRUE, 02154 &deviceNode->ServiceName 02155 ); 02156 } 02157 02158 IopConcatenateUnicodeStrings(&deviceNode->InstancePath, &deviceName, NULL); 02159 02160 deviceNode->Flags = DNF_MADEUP + DNF_ENUMERATED + DNF_PROCESSED; 02161 02162 IopInsertTreeDeviceNode(IopRootDeviceNode, deviceNode); 02163 02164 // 02165 // Add a reference to the DeviceObject for ourself 02166 // 02167 02168 ObReferenceObject(deviceObject); 02169 02170 IopNotifySetupDeviceArrival(deviceObject, NULL, FALSE); 02171 02172 goto checkResource; 02173 } else { 02174 IoDeleteDevice(deviceObject); 02175 status = STATUS_INSUFFICIENT_RESOURCES; 02176 } 02177 } 02178 return status; 02179 checkResource: 02180 02181 02182 // 02183 // At this point the *DeviceObject is established. Check if we need to report resources for 02184 // the detected device. If we failed to 02185 // 02186 02187 if (ResourceAssigned) { 02188 //ASSERT(deviceNode->ResourceList == NULL); // make sure we have not reported resources yet. 02189 02190 // 02191 // If the driver specifies it already has acquired the resource. We will put a flag 02192 // in the device instance path to not to allocate resources at boot time. The Driver 02193 // may do detection and report it again. 02194 // 02195 02196 deviceNode->Flags |= DNF_NO_RESOURCE_REQUIRED; // do not need resources for this boot. 02197 if (ResourceList) { 02198 02199 // 02200 // Write the resource list to the reported device instance key. 02201 // 02202 02203 listSize = IopDetermineResourceListSize(ResourceList); 02204 IopWriteAllocatedResourcesToRegistry (deviceNode, ResourceList, listSize); 02205 } 02206 } else { 02207 BOOLEAN conflict; 02208 02209 if (ResourceList && ResourceList->Count && ResourceList->List[0].PartialResourceList.Count) { 02210 if (listSize == 0) { 02211 listSize = IopDetermineResourceListSize(ResourceList); 02212 } 02213 cmResource = (PCM_RESOURCE_LIST) ExAllocatePool(PagedPool, listSize); 02214 if (cmResource) { 02215 RtlCopyMemory(cmResource, ResourceList, listSize); 02216 RtlInitUnicodeString(&unicodeName, PNPMGR_STR_PNP_MANAGER); 02217 status = IoReportResourceUsageInternal( 02218 ArbiterRequestLegacyReported, 02219 &unicodeName, // DriverClassName OPTIONAL, 02220 IoPnpDriverObject, // DriverObject, 02221 NULL, // DriverList OPTIONAL, 02222 0, // DriverListSize OPTIONAL, 02223 deviceNode->PhysicalDeviceObject, 02224 // DeviceObject OPTIONAL, 02225 cmResource, // DeviceList OPTIONAL, 02226 listSize, // DeviceListSize OPTIONAL, 02227 FALSE, // OverrideConflict, 02228 &conflict // ConflictDetected 02229 ); 02230 ExFreePool(cmResource); 02231 if (!NT_SUCCESS(status) || conflict) { 02232 status = STATUS_CONFLICTING_ADDRESSES; 02233 IopSetDevNodeProblem(deviceNode, CM_PROB_NORMAL_CONFLICT); 02234 } 02235 } else { 02236 status = STATUS_INSUFFICIENT_RESOURCES; 02237 IopSetDevNodeProblem(deviceNode, CM_PROB_OUT_OF_MEMORY); 02238 } 02239 } else { 02240 ASSERT(ResourceRequirements == NULL); 02241 deviceNode->Flags |= DNF_NO_RESOURCE_REQUIRED; // do not need resources for this boot. 02242 } 02243 } 02244 02245 if (NT_SUCCESS(status)) { 02246 02247 IopDoDeferredSetInterfaceState(deviceNode); 02248 02249 deviceNode->Flags |= DNF_STARTED | DNF_ADDED | DNF_NEED_ENUMERATION_ONLY | DNF_NEED_QUERY_IDS; 02250 *DeviceObject = deviceObject; 02251 if (newlyCreated) { 02252 if (controlHandle) { 02253 ZwClose(controlHandle); 02254 } 02255 if (logConfHandle) { 02256 ZwClose(logConfHandle); 02257 } 02258 ZwClose(handle); 02259 } 02260 return status; 02261 02262 } 02263 CleanupRegistry: 02264 IopReleaseDeviceResources(deviceNode, FALSE); 02265 if (newlyCreated) { 02266 IoDeleteDevice(deviceObject); 02267 if (controlHandle) { 02268 ZwDeleteKey(controlHandle); 02269 } 02270 if (logConfHandle) { 02271 ZwDeleteKey(logConfHandle); 02272 } 02273 if (handle) { 02274 ZwDeleteKey(handle); 02275 } 02276 } 02277 return status; 02278 exit: 02279 ExReleaseResource(&PpRegistryDeviceResource); 02280 KeLeaveCriticalRegion(); 02281 IoDeleteDevice(*DeviceObject); 02282 return status; 02283 }

NTSTATUS IoReportTargetDeviceChange IN PDEVICE_OBJECT  PhysicalDeviceObject,
IN PVOID  NotificationStructure
 

Definition at line 6017 of file pnpioapi.c.

References ASSERT, ASSERT_PDO, DbgPrint, _TARGET_DEVICE_CUSTOM_NOTIFICATION::Event, Executive, FALSE, _TARGET_DEVICE_CUSTOM_NOTIFICATION::FileObject, IopCompareGuid, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), _TARGET_DEVICE_CUSTOM_NOTIFICATION::NameBufferOffset, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PpSetCustomTargetEvent(), and _TARGET_DEVICE_CUSTOM_NOTIFICATION::Size.

Referenced by FsRtlNotifyVolumeEvent(), and NtSetVolumeInformationFile().

06024 : 06025 06026 This routine may be used to give notification of 3rd-party target device 06027 change events. This API will notify every driver that has registered for 06028 notification on a file object associated with PhysicalDeviceObject about 06029 the event indicated in the NotificationStructure. 06030 06031 Parameters: 06032 06033 PhysicalDeviceObject - Provides a pointer to the PDO that the change begin 06034 reported is associated with. 06035 06036 NotificationStructure - Provides a pointer to the notification structure to be 06037 sent to all parties registered for notifications about changes to 06038 PhysicalDeviceObject. 06039 06040 Return Value: 06041 06042 Status code that indicates whether or not the function was successful. 06043 06044 Note: 06045 06046 This API may only be used to report non-PnP target device changes. In particular, 06047 it will fail if it's called with the NotificationStructure->Event field set to 06048 GUID_TARGET_DEVICE_QUERY_REMOVE, GUID_TARGET_DEVICE_REMOVE_CANCELLED, or 06049 GUID_TARGET_DEVICE_REMOVE_COMPLETE. 06050 06051 --*/ 06052 { 06053 06054 NTSTATUS status = STATUS_SUCCESS; 06055 KEVENT completionEvent; 06056 NTSTATUS completionStatus; 06057 PTARGET_DEVICE_CUSTOM_NOTIFICATION notifyStruct; 06058 LONG dataSize; 06059 06060 PAGED_CODE(); 06061 06062 notifyStruct = (PTARGET_DEVICE_CUSTOM_NOTIFICATION)NotificationStructure; 06063 06064 ASSERT(notifyStruct); 06065 06066 ASSERT_PDO(PhysicalDeviceObject); 06067 06068 ASSERT(NULL == notifyStruct->FileObject); 06069 06070 06071 if (IopCompareGuid(&notifyStruct->Event, &GUID_TARGET_DEVICE_QUERY_REMOVE) || 06072 IopCompareGuid(&notifyStruct->Event, &GUID_TARGET_DEVICE_REMOVE_CANCELLED) || 06073 IopCompareGuid(&notifyStruct->Event, &GUID_TARGET_DEVICE_REMOVE_COMPLETE)) { 06074 06075 // 06076 // Passed in an illegal value 06077 // 06078 06079 #if DBG 06080 DbgPrint("Illegal Event type passed as custom notification\n"); 06081 #endif 06082 return STATUS_INVALID_DEVICE_REQUEST; 06083 06084 } 06085 06086 if (notifyStruct->Size < FIELD_OFFSET(TARGET_DEVICE_CUSTOM_NOTIFICATION, CustomDataBuffer)) { 06087 06088 return STATUS_INVALID_DEVICE_REQUEST; 06089 } 06090 06091 dataSize = notifyStruct->Size - FIELD_OFFSET(TARGET_DEVICE_CUSTOM_NOTIFICATION, CustomDataBuffer); 06092 06093 if (notifyStruct->NameBufferOffset != -1 && notifyStruct->NameBufferOffset > dataSize) { 06094 06095 return STATUS_INVALID_DEVICE_REQUEST; 06096 } 06097 06098 KeInitializeEvent(&completionEvent, NotificationEvent, FALSE); 06099 06100 status = PpSetCustomTargetEvent( PhysicalDeviceObject, 06101 &completionEvent, 06102 &completionStatus, 06103 NULL, 06104 NULL, 06105 notifyStruct); 06106 06107 if (NT_SUCCESS(status)) { 06108 06109 KeWaitForSingleObject( &completionEvent, Executive, KernelMode, FALSE, NULL ); 06110 06111 status = completionStatus; 06112 } 06113 06114 return status; 06115 }

NTSTATUS IoReportTargetDeviceChangeAsynchronous IN PDEVICE_OBJECT  PhysicalDeviceObject,
IN PVOID  NotificationStructure,
IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback  OPTIONAL,
IN PVOID Context  OPTIONAL
 

Definition at line 6118 of file pnpioapi.c.

References ASSERT, ASSERT_PDO, ASYNC_TDC_WORK_ITEM, _ASYNC_TDC_WORK_ITEM::Callback, _ASYNC_TDC_WORK_ITEM::Context, DbgPrint, DelayedWorkQueue, _ASYNC_TDC_WORK_ITEM::DeviceObject, _TARGET_DEVICE_CUSTOM_NOTIFICATION::Event, ExAllocatePool, ExInitializeWorkItem, ExQueueWorkItem(), _TARGET_DEVICE_CUSTOM_NOTIFICATION::FileObject, IopCompareGuid, IopReportTargetDeviceChangeAsyncWorker(), _TARGET_DEVICE_CUSTOM_NOTIFICATION::NameBufferOffset, NonPagedPool, _ASYNC_TDC_WORK_ITEM::NotificationStructure, NTSTATUS(), NULL, ObReferenceObject, PASYNC_TDC_WORK_ITEM, _TARGET_DEVICE_CUSTOM_NOTIFICATION::Size, and _ASYNC_TDC_WORK_ITEM::WorkItem.

Referenced by FsRtlNotifyVolumeEvent().

06127 : 06128 06129 This routine may be used to give notification of 3rd-party target device 06130 change events. This API will notify every driver that has registered for 06131 notification on a file object associated with PhysicalDeviceObject about 06132 the event indicated in the NotificationStructure. 06133 06134 Parameters: 06135 06136 PhysicalDeviceObject - Provides a pointer to the PDO that the change begin 06137 reported is associated with. 06138 06139 NotificationStructure - Provides a pointer to the notification structure to be 06140 sent to all parties registered for notifications about changes to 06141 PhysicalDeviceObject. 06142 06143 Return Value: 06144 06145 Status code that indicates whether or not the function was successful. 06146 06147 Note: 06148 06149 This API may only be used to report non-PnP target device changes. In particular, 06150 it will fail if it's called with the NotificationStructure->Event field set to 06151 GUID_TARGET_DEVICE_QUERY_REMOVE, GUID_TARGET_DEVICE_REMOVE_CANCELLED, or 06152 GUID_TARGET_DEVICE_REMOVE_COMPLETE. 06153 06154 --*/ 06155 { 06156 PASYNC_TDC_WORK_ITEM asyncWorkItem; 06157 PWORK_QUEUE_ITEM workItem; 06158 NTSTATUS status; 06159 LONG dataSize; 06160 06161 PTARGET_DEVICE_CUSTOM_NOTIFICATION notifyStruct; 06162 06163 notifyStruct = (PTARGET_DEVICE_CUSTOM_NOTIFICATION)NotificationStructure; 06164 06165 ASSERT(notifyStruct); 06166 06167 ASSERT_PDO(PhysicalDeviceObject); 06168 06169 ASSERT(NULL == notifyStruct->FileObject); 06170 06171 if (IopCompareGuid(&notifyStruct->Event, &GUID_TARGET_DEVICE_QUERY_REMOVE) || 06172 IopCompareGuid(&notifyStruct->Event, &GUID_TARGET_DEVICE_REMOVE_CANCELLED) || 06173 IopCompareGuid(&notifyStruct->Event, &GUID_TARGET_DEVICE_REMOVE_COMPLETE)) { 06174 06175 // 06176 // Passed in an illegal value 06177 // 06178 06179 #if DBG 06180 DbgPrint("Illegal Event type passed as custom notification\n"); 06181 #endif 06182 return STATUS_INVALID_DEVICE_REQUEST; 06183 06184 } 06185 06186 if (notifyStruct->Size < FIELD_OFFSET(TARGET_DEVICE_CUSTOM_NOTIFICATION, CustomDataBuffer)) { 06187 06188 return STATUS_INVALID_DEVICE_REQUEST; 06189 } 06190 06191 dataSize = notifyStruct->Size - FIELD_OFFSET(TARGET_DEVICE_CUSTOM_NOTIFICATION, CustomDataBuffer); 06192 06193 if (notifyStruct->NameBufferOffset != -1 && notifyStruct->NameBufferOffset > dataSize) { 06194 06195 return STATUS_INVALID_DEVICE_REQUEST; 06196 } 06197 06198 // 06199 // Since this routine can be called at DPC level we need to queue 06200 // a work item and process it when the irql drops. 06201 // 06202 06203 asyncWorkItem = ExAllocatePool( NonPagedPool, 06204 sizeof(ASYNC_TDC_WORK_ITEM) + notifyStruct->Size); 06205 06206 if (asyncWorkItem != NULL) { 06207 06208 ObReferenceObject(PhysicalDeviceObject); 06209 06210 asyncWorkItem->DeviceObject = PhysicalDeviceObject; 06211 asyncWorkItem->NotificationStructure = 06212 (PTARGET_DEVICE_CUSTOM_NOTIFICATION)((PUCHAR)asyncWorkItem + sizeof(ASYNC_TDC_WORK_ITEM)); 06213 06214 RtlCopyMemory( asyncWorkItem->NotificationStructure, 06215 notifyStruct, 06216 notifyStruct->Size); 06217 06218 asyncWorkItem->Callback = Callback; 06219 asyncWorkItem->Context = Context; 06220 workItem = &asyncWorkItem->WorkItem; 06221 06222 ExInitializeWorkItem(workItem, IopReportTargetDeviceChangeAsyncWorker, asyncWorkItem); 06223 06224 // 06225 // Queue a work item to do the enumeration 06226 // 06227 06228 ExQueueWorkItem(workItem, DelayedWorkQueue); 06229 status = STATUS_PENDING; 06230 } else { 06231 // 06232 // Failed to allocate memory for work item. Nothing we can do ... 06233 // 06234 06235 status = STATUS_INSUFFICIENT_RESOURCES; 06236 } 06237 06238 return status; 06239 }

VOID IoRequestDeviceEject PDEVICE_OBJECT  DeviceObject  ) 
 

Definition at line 1481 of file pnpioapi.c.

References ASSERT_PDO, IopQueueDeviceWorkItem(), IopRequestDeviceEjectWorker(), and NULL.

Referenced by IopDeviceStartComplete().

01487 : 01488 01489 This API notifies that the device eject button has been pressed. This API must 01490 be called at IRQL <= DISPATCH_LEVEL. 01491 01492 This API informs PnP that a device eject has been requested, the device will 01493 not necessarily be ejected as a result of this API. The device will only be 01494 ejected if the drivers associated with it agree to stop and the device is 01495 successfully powered down. Note that eject in this context refers to device 01496 eject, not to media (floppies, cds, tapes) eject. For example, eject of a 01497 cd-rom disk drive, not ejection of a cd-rom disk. 01498 01499 Arguments: 01500 01501 DeviceObject - the PDEVICE_OBJECT for the device whose eject button has 01502 been pressed. This pointer is valid for the duration of 01503 the call, if the API wants to keep a copy of it, it 01504 should obtain its own reference to the object 01505 (ObReferenceObject). 01506 01507 ReturnValue: 01508 01509 None. 01510 01511 --*/ 01512 01513 { 01514 ASSERT_PDO(DeviceObject); 01515 01516 IopQueueDeviceWorkItem(DeviceObject, IopRequestDeviceEjectWorker, NULL); 01517 }

NTSTATUS IoSetDeviceInterfaceState IN PUNICODE_STRING  SymbolicLinkName,
IN BOOLEAN  Enable
 

Definition at line 3563 of file pnpioapi.c.

References ExAcquireResourceExclusive, ExReleaseResource, IopProcessSetInterfaceState(), KeEnterCriticalRegion, KeLeaveCriticalRegion, NT_SUCCESS, NTSTATUS(), PAGED_CODE, PpRegistryDeviceResource, and TRUE.

Referenced by IopUnregisterDeviceInterface().

03570 : 03571 03572 This DDI allows a device class to activate and deactivate an association 03573 previously registered using IoRegisterDeviceInterface 03574 03575 Parameters: 03576 03577 SymbolicLinkName - Supplies a pointer to the symbolic link name which was 03578 returned by IoRegisterDeviceInterface when the interface was registered, 03579 or as returned by IoGetDeviceInterfaces. 03580 03581 Enable - If TRUE (non-zero), the interface will be enabled. If FALSE, it 03582 will be disabled. 03583 03584 Return Value: 03585 03586 Status code that indicates whether or not the function was successful. 03587 03588 --*/ 03589 03590 { 03591 NTSTATUS status; 03592 03593 PAGED_CODE(); 03594 03595 // 03596 // Enter critical section and acquire a lock on the registry. Both these 03597 // mechanisms are required to prevent deadlock in the case where an APC 03598 // routine calls this routine after the registry resource has been claimed 03599 // in this case it would wait blocking this thread so the registry would 03600 // never be released -> deadlock. Critical sectioning the registry manipulation 03601 // portion solves this problem 03602 // 03603 03604 KeEnterCriticalRegion(); 03605 ExAcquireResourceExclusive(&PpRegistryDeviceResource, TRUE); 03606 03607 status = IopProcessSetInterfaceState(SymbolicLinkName, Enable, TRUE); 03608 03609 ExReleaseResource(&PpRegistryDeviceResource); 03610 KeLeaveCriticalRegion(); 03611 03612 if (!NT_SUCCESS(status) && !Enable) { 03613 // 03614 // If we failed to disable an interface (most likely because the 03615 // interface keys have already been deleted) report success. 03616 // 03617 status = STATUS_SUCCESS; 03618 } 03619 03620 return status; 03621 }

NTSTATUS IoSynchronousInvalidateDeviceRelations PDEVICE_OBJECT  DeviceObject,
DEVICE_RELATION_TYPE  Type
 

Definition at line 1291 of file pnpioapi.c.

References ASSERT_PDO, BusRelations, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_STARTED, EjectionRelations, Executive, FALSE, _DEVICE_NODE::Flags, IopRequestDeviceAction(), KeInitializeEvent, KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PnPInitialized, PoInvalidateDevicePowerRelations(), PowerRelations, and ReenumerateDeviceTree.

01298 : 01299 01300 This API notifies the system that changes have occurred in the device 01301 relations of the specified type for the supplied DeviceObject. All 01302 cached information concerning the relationships must be invalidated, 01303 and if needed re-obtained via IRP_MN_QUERY_DEVICE_RELATIONS. 01304 01305 This routine performs device enumeration synchronously. 01306 Note, A driver can NOT call this IO api while processing pnp irps AND 01307 A driver can NOT call this api from any system thread except the system 01308 threads created by the driver itself. 01309 01310 Parameters: 01311 01312 DeviceObject - the PDEVICE_OBJECT for which the specified relation type 01313 information has been invalidated. This pointer is valid 01314 for the duration of the call. 01315 01316 Type - specifies the type of the relation being invalidated. 01317 01318 ReturnValue: 01319 01320 Status code that indicates whether or not the function was successful. 01321 01322 --*/ 01323 01324 { 01325 PDEVICE_NODE deviceNode; 01326 NTSTATUS status = STATUS_SUCCESS; 01327 KEVENT completionEvent; 01328 01329 PAGED_CODE(); 01330 01331 ASSERT_PDO(DeviceObject); 01332 01333 switch (Type) { 01334 case BusRelations: 01335 01336 if (PnPInitialized) { 01337 01338 deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 01339 01340 if (deviceNode->Flags & DNF_STARTED) { 01341 01342 KeInitializeEvent( &completionEvent, NotificationEvent, FALSE ); 01343 01344 status = IopRequestDeviceAction( DeviceObject, 01345 ReenumerateDeviceTree, 01346 &completionEvent, 01347 NULL ); 01348 01349 if (NT_SUCCESS(status)) { 01350 01351 status = KeWaitForSingleObject( &completionEvent, 01352 Executive, 01353 KernelMode, 01354 FALSE, 01355 NULL); 01356 } 01357 } else { 01358 status = STATUS_UNSUCCESSFUL; 01359 } 01360 } else { 01361 // 01362 // BUGBUG - This check may be too much. For now ... 01363 // 01364 01365 status = STATUS_UNSUCCESSFUL; // BUGBUG- better status code 01366 } 01367 01368 01369 break; 01370 01371 case EjectionRelations: 01372 01373 // 01374 // For Ejection relation change, we will ignore it. We don't keep track 01375 // the Ejection relation. We will query the Ejection relation only when 01376 // we are requested to eject a device. 01377 // 01378 01379 status = STATUS_NOT_SUPPORTED; 01380 break; 01381 01382 case PowerRelations: 01383 01384 01385 // 01386 // Call off to Po code, which will do the right thing 01387 // 01388 PoInvalidateDevicePowerRelations(DeviceObject); 01389 break; 01390 } 01391 return status; 01392 }

NTSTATUS IoUnregisterPlugPlayNotification IN PVOID  NotificationEntry  ) 
 

Definition at line 5829 of file pnpioapi.c.

References ASSERT, ExFreePool(), FALSE, IopAcquireNotifyLock, IopDeferredRegistrationList, IopDeferredRegistrationLock, IopDereferenceNotify(), IopReleaseNotifyLock, _NOTIFY_ENTRY_HEADER::Lock, _DEFERRED_REGISTRATION_ENTRY::NotifyEntry, PAGED_CODE, PDEFERRED_REGISTRATION_ENTRY, PiNotificationInProgress, PiNotificationInProgressLock, TRUE, and _NOTIFY_ENTRY_HEADER::Unregistered.

Referenced by DeviceCDROMNotify(), and UnregisterForDeviceChangeNotifications().

05835 : 05836 05837 This routine unregisters a notification previously registered via 05838 IoRegisterPlugPlayNotification. A driver cannot be unloaded until it has 05839 unregistered all of its notification handles. 05840 05841 Parameters: 05842 05843 NotificationEntry - This provices the cookie returned by IoRegisterPlugPlayNotification 05844 which identifies the registration in question. 05845 05846 Return Value: 05847 05848 Status code that indicates whether or not the function was successful. 05849 05850 --*/ 05851 05852 { 05853 PNOTIFY_ENTRY_HEADER entry; 05854 PFAST_MUTEX lock; 05855 BOOLEAN wasDeferred = FALSE; 05856 05857 PAGED_CODE(); 05858 05859 ASSERT(NotificationEntry); 05860 05861 entry = (PNOTIFY_ENTRY_HEADER)NotificationEntry; 05862 05863 lock = entry->Lock; 05864 05865 ExAcquireFastMutex(&PiNotificationInProgressLock); 05866 if (PiNotificationInProgress) { 05867 // 05868 // Before unregistering the entry, we need to make sure that it's not sitting 05869 // around in the deferred registration list. 05870 // 05871 IopAcquireNotifyLock(&IopDeferredRegistrationLock); 05872 05873 if (!IsListEmpty(&IopDeferredRegistrationList)) { 05874 05875 PLIST_ENTRY link; 05876 PDEFERRED_REGISTRATION_ENTRY deferredNode; 05877 05878 link = IopDeferredRegistrationList.Flink; 05879 deferredNode = (PDEFERRED_REGISTRATION_ENTRY)link; 05880 05881 while (link != (PLIST_ENTRY)&IopDeferredRegistrationList) { 05882 ASSERT(deferredNode->NotifyEntry->Unregistered); 05883 if (deferredNode->NotifyEntry == entry) { 05884 wasDeferred = TRUE; 05885 if (lock) { 05886 IopAcquireNotifyLock(lock); 05887 } 05888 link = link->Flink; 05889 RemoveEntryList((PLIST_ENTRY)deferredNode); 05890 IopDereferenceNotify((PNOTIFY_ENTRY_HEADER)deferredNode->NotifyEntry); 05891 if (lock) { 05892 IopReleaseNotifyLock(lock); 05893 } 05894 ExFreePool(deferredNode); 05895 deferredNode = (PDEFERRED_REGISTRATION_ENTRY)link; 05896 } else { 05897 link = link->Flink; 05898 deferredNode = (PDEFERRED_REGISTRATION_ENTRY)link; 05899 } 05900 } 05901 } 05902 05903 IopReleaseNotifyLock(&IopDeferredRegistrationLock); 05904 } else { 05905 // 05906 // If there is currently no notification in progress, the deferred 05907 // registration list must be empty. 05908 // 05909 ASSERT(IsListEmpty(&IopDeferredRegistrationList)); 05910 } 05911 ExReleaseFastMutex(&PiNotificationInProgressLock); 05912 05913 // 05914 // Acquire lock 05915 // 05916 if (lock) { 05917 IopAcquireNotifyLock(lock); 05918 } 05919 05920 ASSERT(wasDeferred == entry->Unregistered); 05921 05922 if (!entry->Unregistered || wasDeferred) { 05923 // 05924 // Dereference the entry if it is currently registered, or had its 05925 // registration pending completion of the notification in progress. 05926 // 05927 05928 // 05929 // Mark the entry as unregistered so we don't notify on it 05930 // 05931 05932 entry->Unregistered = TRUE; 05933 05934 // 05935 // Dereference it thus deleting if no longer required 05936 // 05937 05938 IopDereferenceNotify(entry); 05939 } 05940 05941 // 05942 // Release the lock 05943 // 05944 05945 if (lock) { 05946 IopReleaseNotifyLock(lock); 05947 } 05948 05949 return STATUS_SUCCESS; 05950 05951 }

NTSTATUS PiNotifyUserMode PPNP_DEVICE_EVENT_ENTRY  DeviceEvent  ) 
 

Referenced by IopRequestHwProfileChangeNotification().

NTSTATUS PpCreateLegacyDeviceIds IN PDEVICE_OBJECT  DeviceObject,
IN PUNICODE_STRING  DriverName,
IN PCM_RESOURCE_LIST  Resources
 

Definition at line 9077 of file pnpioapi.c.

References _IOPNP_DEVICE_EXTENSION::CompatibleIdList, _IOPNP_DEVICE_EXTENSION::CompatibleIdListSize, ExAllocatePool, L, LEGACY_COMPATIBLE_ID_BASE, NULL, PAGED_CODE, and PagedPool.

Referenced by IoReportDetectedDevice().

09082 { 09083 PIOPNP_DEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension; 09084 PWCHAR buffer; 09085 09086 ULONG length = 0; 09087 09088 INTERFACE_TYPE interface; 09089 PWCHAR interfaceNames[] ={L"", 09090 L"Internal", 09091 L"Isa", 09092 L"Eisa", 09093 L"MicroChannel", 09094 L"TurboChannel", 09095 L"PCIBus", 09096 L"VMEBus", 09097 L"NuBus", 09098 L"PCMCIABus", 09099 L"CBus", 09100 L"MPIBus", 09101 L"MPSABus", 09102 L"ProcessorInternal", 09103 L"InternalPowerBus", 09104 L"PNPISABus", 09105 L"PNPBus", 09106 L"Other", 09107 L"Root"}; 09108 09109 09110 PAGED_CODE(); 09111 09112 if(Resources != NULL) { 09113 09114 interface = Resources->List[0].InterfaceType; 09115 09116 if((interface > MaximumInterfaceType) || 09117 (interface < InterfaceTypeUndefined)) { 09118 interface = MaximumInterfaceType; 09119 } 09120 } else { 09121 interface = Internal; 09122 } 09123 09124 interface++; 09125 09126 // 09127 // The compatible ID generated will be 09128 // DETECTED<InterfaceName><Driver Name> 09129 // 09130 09131 length = wcslen(LEGACY_COMPATIBLE_ID_BASE) * sizeof(WCHAR); 09132 length += wcslen(interfaceNames[interface]) * sizeof(WCHAR); 09133 length += sizeof(L'\\'); 09134 length += DriverName->Length; 09135 length += sizeof(UNICODE_NULL); 09136 09137 length += wcslen(LEGACY_COMPATIBLE_ID_BASE) * sizeof(WCHAR); 09138 length += sizeof(L'\\'); 09139 length += DriverName->Length; 09140 length += sizeof(UNICODE_NULL) * 2; 09141 09142 buffer = ExAllocatePool(PagedPool, length); 09143 deviceExtension->CompatibleIdList = buffer; 09144 09145 if(buffer == NULL) { 09146 return STATUS_INSUFFICIENT_RESOURCES; 09147 } 09148 09149 RtlZeroMemory(buffer, length); 09150 09151 swprintf(buffer, L"%ws%ws\\%wZ", LEGACY_COMPATIBLE_ID_BASE, 09152 interfaceNames[interface], 09153 DriverName); 09154 09155 // 09156 // Adjust the buffer to point to the end and generate the second 09157 // compatible id string. 09158 // 09159 09160 buffer += wcslen(buffer) + 1; 09161 09162 swprintf(buffer, L"%ws\\%wZ", LEGACY_COMPATIBLE_ID_BASE, DriverName); 09163 09164 deviceExtension->CompatibleIdListSize = length; 09165 09166 return STATUS_SUCCESS; 09167 }


Variable Documentation

LIST_ENTRY IopDeferredRegistrationList
 

Definition at line 199 of file pnpioapi.c.

Referenced by IopInitializePlugPlayNotification(), IopProcessDeferredRegistrations(), IoRegisterPlugPlayNotification(), and IoUnregisterPlugPlayNotification().

FAST_MUTEX IopDeferredRegistrationLock
 

Definition at line 200 of file pnpioapi.c.

Referenced by IopInitializePlugPlayNotification(), IopProcessDeferredRegistrations(), IoRegisterPlugPlayNotification(), and IoUnregisterPlugPlayNotification().

LIST_ENTRY IopDeviceClassNotifyList[NOTIFY_DEVICE_CLASS_HASH_BUCKETS]
 

Definition at line 183 of file pnpioapi.c.

Referenced by IopInitializePlugPlayNotification(), IopNotifyDeviceClassChange(), and IoRegisterPlugPlayNotification().

FAST_MUTEX IopDeviceClassNotifyLock
 

Definition at line 184 of file pnpioapi.c.

Referenced by IopInitializePlugPlayNotification(), IopNotifyDeviceClassChange(), and IoRegisterPlugPlayNotification().

FAST_MUTEX IopHwProfileNotifyLock
 

Definition at line 188 of file pnpioapi.c.

Referenced by IopInitializePlugPlayNotification(), IopNotifyHwProfileChange(), and IoRegisterPlugPlayNotification().

LIST_ENTRY IopProfileNotifyList
 

Definition at line 187 of file pnpioapi.c.

Referenced by IopInitializePlugPlayNotification(), IopNotifyHwProfileChange(), and IoRegisterPlugPlayNotification().

PSETUP_NOTIFY_DATA IopSetupNotifyData = NULL
 

Definition at line 185 of file pnpioapi.c.

Referenced by IopNotifySetupDeviceArrival(), and IoRegisterPlugPlayNotification().

FAST_MUTEX IopTargetDeviceNotifyLock
 

Definition at line 186 of file pnpioapi.c.

Referenced by IopInitializePlugPlayNotification(), IopNotifyTargetDeviceChange(), IopOrphanNotification(), and IoRegisterPlugPlayNotification().

BOOLEAN PiNotificationInProgress
 

Definition at line 189 of file pnpioapi.c.

Referenced by IopRequestHwProfileChangeNotification(), IoRegisterPlugPlayNotification(), and IoUnregisterPlugPlayNotification().

FAST_MUTEX PiNotificationInProgressLock
 

Definition at line 190 of file pnpioapi.c.

Referenced by IoRegisterPlugPlayNotification(), and IoUnregisterPlugPlayNotification().


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