View
234
Download
3
Category
Preview:
Citation preview
WindowsWindows®® Driver Model Driver ModelHistory And Architectural History And Architectural Overview Overview
Bob Rinne Bob Rinne DirectorDirectorWindows Operating System BaseWindows Operating System BaseMicrosoft Corporation Microsoft Corporation
Purpose Of This TalkPurpose Of This Talk
The WDM realityThe WDM reality Discuss what is covered in WDMDiscuss what is covered in WDM It has taken a long timeIt has taken a long time
Get an overview of its history Get an overview of its history and versionsand versions
Get an overview of the architecturesGet an overview of the architectures Basic information for navigating Basic information for navigating
through WDMthrough WDM
Technical OutlineTechnical Outline
Goals of WDMGoals of WDM History of WDMHistory of WDM Current stateCurrent state Overview of WDMOverview of WDM
Goals Of WDMGoals Of WDM
Common development environment Common development environment for Windows NTfor Windows NT®® and Windows 9x and Windows 9x family productsfamily products
Method of bringing Plug and Play and Method of bringing Plug and Play and Power Management to Windows NTPower Management to Windows NT
Binary compatibility between products Binary compatibility between products Broad coverage of new Broad coverage of new
technology bussestechnology busses
What Is WDMWhat Is WDM
NDIS/SCSINDIS/SCSI Pre-WDM, but satisfies goalsPre-WDM, but satisfies goals
System environmentSystem environment Bus supportBus support Device class supportDevice class support
History Of WDMHistory Of WDM
Introduced after Windows 95 launchIntroduced after Windows 95 launch First available in Windows 98First available in Windows 98 Now available in Windows 2000Now available in Windows 2000 Is present on Windows ME with Is present on Windows ME with
enhancements from Windows 98enhancements from Windows 98
History Of WDMHistory Of WDM
Windows 98 versionsWindows 98 versions Started from a device oriented Started from a device oriented
Plug and Play operating systemPlug and Play operating system Added portable abstractions and Added portable abstractions and
I/O subsystem from Windows NTI/O subsystem from Windows NT Provided definition for Plug and Play Provided definition for Plug and Play
and power management mapping to and power management mapping to Windows NTWindows NT
Work done as a mapper between WDM Work done as a mapper between WDM and Windows 95 coreand Windows 95 core
MS-DOS MS-DOS VMVM
Windows 98 And MeWindows 98 And Me
System VMSystem VM
MS-DOS MS-DOS VMVM
ApplicationsApplications
System servicesSystem services MS-DOS MS-DOS VMVM
Installable Installable file systemfile system Virtual Virtual
Memory Memory ManagerManager
ServicesServices
DriversDrivers
FSDFSD
Windows 95Windows 95I/O subsystemI/O subsystem
DeviceDevice driversdrivers
Device driversDevice driversHALHAL
FSDFSD
Windows NT Windows NT I/O ManagerI/O Manager
History Of WDMHistory Of WDM
Windows NT versionWindows NT version Started from non-Plug and Play, Started from non-Plug and Play,
“driver”-oriented operating system“driver”-oriented operating system Made WDM interfaces nativeMade WDM interfaces native Converted to Plug and Play/“device”- Converted to Plug and Play/“device”-
oriented operating systemoriented operating system
Windows NT Windows NT
DaemonsDaemons ServicesServices EnvironmentsEnvironments ApplicationsApplications
Security Security monitormonitor
PowerPowerManagementManagement
ExecutiveExecutive Process Process supportsupport
Memory Memory ManagementManagement
I/O managerI/O manager
Object management/executive run timeObject management/executive run time
Device driversDevice drivers KernelKernelHardware abstraction layerHardware abstraction layer
Platform interfacePlatform interface
Privileged Privileged architecturearchitecture
Interrupt Interrupt dispatchdispatch
I/OI/Odevicesdevices
DMADMAcontrolcontrol
Bus Bus mappingmapping
Clocks/ Clocks/ timerstimers
Cache Cache controlcontrol
LPCLPC LPCLPC LPCLPC LPCLPC
File systemsFile systems
Windows NT SystemWindows NT System
OtherOther OtherOther
SpoolerSpooler
File serverFile server
SecuritySecuritySession managerSession manager
ReplicatorReplicator
LogonLogon
AlerterAlerter
Event loggerEvent logger WindowsWindows
Current StateCurrent State
WDM is realWDM is real There now is a common There now is a common
development environmentdevelopment environment Binary compatibility is possibleBinary compatibility is possible
Unfortunately it is harder than we wantedUnfortunately it is harder than we wanted Requires extensive testing on all versions Requires extensive testing on all versions
of all operating systems of all operating systems
Current StateCurrent State
Busses coveredBusses covered Still have NDIS and SCSIStill have NDIS and SCSI USBUSB 13941394 New ones comingNew ones coming
Current StateCurrent State
Devices coveredDevices covered InputInput Cameras/ScannersCameras/Scanners AudioAudio WinModemWinModem Storage (*)Storage (*) Many moreMany more New ones comingNew ones coming
Current StateCurrent State
What’s not thereWhat’s not there VideoVideo Generic storageGeneric storage Super I/O chipSuper I/O chip
Overview Of WDMOverview Of WDM
Breakdown the componentsBreakdown the components What do those first two characters in What do those first two characters in
DDI calls mean?DDI calls mean? Definition of functionalityDefinition of functionality
Components In WDMComponents In WDM
wdm.hwdm.h Ke Ob Ex Io Mm Ps Rtl Po PnpKe Ob Ex Io Mm Ps Rtl Po Pnp Hal (platform support)Hal (platform support) Zw (magic)Zw (magic)
ks.hks.h KsKs
WmiWmi
Ke - KernelKe - Kernel
Minimal set of items exported here Minimal set of items exported here in WDMin WDM
Synchronization primitivesSynchronization primitives Performance counters and timersPerformance counters and timers Stall and Irq controlStall and Irq control
Ob - Object ManagerOb - Object Manager
Very minimal setVery minimal set Used only for object reference Used only for object reference
count maintenancecount maintenance
Ex - The System ExecutiveEx - The System Executive
Memory allocationsMemory allocations Interlocked operationsInterlocked operations List operationsList operations Work itemsWork items
There is a better set in the IO manager (Io*)There is a better set in the IO manager (Io*)
Io - I/O ManagerIo - I/O Manager
I/O Request Packet (IRP) HandlingI/O Request Packet (IRP) Handling The routines that pass IrpsThe routines that pass Irps Global locksGlobal locks
Device Object PlumbingDevice Object Plumbing The routines that set device relationshipsThe routines that set device relationships
Work itemsWork items Registry access routinesRegistry access routines System state notificationsSystem state notifications DMA assistanceDMA assistance Interrupt assistanceInterrupt assistance
Mm - Memory ManagerMm - Memory Manager
Virtual to Physical mappingVirtual to Physical mapping Physical memory commit/lockingPhysical memory commit/locking Driver image memory lockingDriver image memory locking Portable I/O space handlingPortable I/O space handling
Ps - Process ServicePs - Process Service
System thread supportSystem thread support Just creation and deletionJust creation and deletion
Rtl - Run-Time LibraryRtl - Run-Time Library
Bulk memory activity supportBulk memory activity support Unicode supportUnicode support Conversion supportConversion support
Unicode to AnsiUnicode to Ansi Integer to UnicodeInteger to Unicode Etc.Etc.
Po - Power ManagerPo - Power Manager
Power state change supportPower state change support Power Irp handlingPower Irp handling Device idle detection supportDevice idle detection support
PnP - Plug And Play PnP - Plug And Play SubsystemSubsystem There are no Plug and Play There are no Plug and Play
decorated routine namesdecorated routine names Exists as part of the I/O managerExists as part of the I/O manager Actually implemented as an entity in Actually implemented as an entity in
the systemthe system
Hal - Hardware Abstraction Hal - Hardware Abstraction LayerLayer Device manipulationDevice manipulation
I/O port access and usageI/O port access and usage Memory mapped device access Memory mapped device access
and usageand usage Platform abstractionPlatform abstraction
Component owner of interruptsComponent owner of interrupts
Zw - MagicZw - Magic
Kernel mode map to system APIsKernel mode map to system APIs Registry accessRegistry access
Open/Close keysOpen/Close keys Create/Delete keysCreate/Delete keys Query valuesQuery values
Minimal file accessMinimal file access
Ks - Kernel StreamingKs - Kernel Streaming
Separate component on both platformsSeparate component on both platforms Definitions of interfaces located in ks.hDefinitions of interfaces located in ks.h Provides plumbing for streaming data Provides plumbing for streaming data
device connectionsdevice connections
WMI - Windows WMI - Windows Management InfrastructureManagement Infrastructure Similar to Plug and Play as a Similar to Plug and Play as a
component of Iocomponent of Io GUID support - wmidata.hGUID support - wmidata.h Structure definitions - wmistr.hStructure definitions - wmistr.h Support library definitions - wmilib.hSupport library definitions - wmilib.h
ConclusionConclusion
Its taken awhileIts taken awhile Some of it is simple; Some of it isn’tSome of it is simple; Some of it isn’t Develop driver first under Develop driver first under
Windows 2000Windows 2000 Test, test, test, on all releases of all Test, test, test, on all releases of all
supported operating systemssupported operating systems
WDM Driver WDM Driver Implementation GuideImplementation Guide
Adrian J. OneyAdrian J. OneySoftware EngineerSoftware EngineerWindows Core OSWindows Core OSMicrosoft CorporationMicrosoft Corporation
PreviewPreview
Writing an Windows NT 4.0 skeleton Writing an Windows NT 4.0 skeleton driver required mastery of many driver required mastery of many conceptsconcepts SchedulingScheduling SynchronizationSynchronization DeviceObjects, DriverObjectsDeviceObjects, DriverObjects I/O theory (IRP handling, queuing, I/O theory (IRP handling, queuing,
asynchronous I/O)asynchronous I/O) SecuritySecurity DebuggingDebugging
PreviewPreview
Writing a WDM driver requires mastery Writing a WDM driver requires mastery of all of those concepts plus:of all of those concepts plus: Plug and Play Plug and Play Power ManagementPower Management WMI (WindowsWMI (Windows®® Management Interface) Management Interface) Windows 9x/Windows 2000 differencesWindows 9x/Windows 2000 differences
And don’t forget technology specific And don’t forget technology specific issuesissues Device class specific: Audio, Modem, …Device class specific: Audio, Modem, … Bus specific: USB, 1394, PCI, …Bus specific: USB, 1394, PCI, …
Scheduling BasicsScheduling Basics
WDM presents two types of schedulingWDM presents two types of scheduling Thread-based schedulingThread-based scheduling
Kernel support for semaphores, mutexes, event objectsKernel support for semaphores, mutexes, event objects Windows 2000 adds new high-level support for reader/writer Windows 2000 adds new high-level support for reader/writer
operations to WDMoperations to WDM (For instance ExAcquireSharedStarveExclusive)(For instance ExAcquireSharedStarveExclusive)
Interrupt Level-based schedulingInterrupt Level-based scheduling Code running at a higher IRQ Level (IRQL) immediately Code running at a higher IRQ Level (IRQL) immediately
preempts code running at a lower IRQLpreempts code running at a lower IRQL Code runs on same thread, no switching!Code runs on same thread, no switching!
The lowest three IRQL’s are scheduling constructs, unrelated The lowest three IRQL’s are scheduling constructs, unrelated to hardware:to hardware: PASSIVE_LEVEL, APC_LEVEL, DISPATCH_LEVELPASSIVE_LEVEL, APC_LEVEL, DISPATCH_LEVEL
Multiple processors can each run at a different IRQL!Multiple processors can each run at a different IRQL!
CallbacksCallbacks
PASSIVE_LEVEL (IRQL 0)PASSIVE_LEVEL (IRQL 0) ““Work Item”Work Item”
Queue-able from DISPATCH_LEVEL or lowerQueue-able from DISPATCH_LEVEL or lower Two types, Ex-WorkItems and Io-WorkItemsTwo types, Ex-WorkItems and Io-WorkItems
APC_LEVEL (IRQL 1)APC_LEVEL (IRQL 1) Asynchronous Procedure Call aka “APC”Asynchronous Procedure Call aka “APC”
Thread specificThread specific No WDM function to queue theseNo WDM function to queue these I/O Manager queues them to get back into correct I/O Manager queues them to get back into correct
process during I/Oprocess during I/O
DISPATCH_LEVEL (IRQL 2)DISPATCH_LEVEL (IRQL 2) Deferred Procedure Call aka “DPC”Deferred Procedure Call aka “DPC”
Queue-able anytime and anywhere, including ISRsQueue-able anytime and anywhere, including ISRs
Scheduling BasicsScheduling Basics
PASSIVE_LEVEL (IRQL 0)PASSIVE_LEVEL (IRQL 0) Drivers typically run at this levelDrivers typically run at this level Drivers can touch pageable memoryDrivers can touch pageable memory Drivers can do file I/ODrivers can do file I/O Blocking causes a processor to switch threadsBlocking causes a processor to switch threads
APC_LEVEL (IRQL 1)APC_LEVEL (IRQL 1) When switching into a new thread, the processor will When switching into a new thread, the processor will
run any pending APC’s at APC_LEVELrun any pending APC’s at APC_LEVEL Blocking lets other threads run at PASSIVE_LEVELBlocking lets other threads run at PASSIVE_LEVEL Restriction: Drivers cannot use file functionsRestriction: Drivers cannot use file functions
DISPATCH_LEVEL (IRQL 2)DISPATCH_LEVEL (IRQL 2) A processor never switches threads when running A processor never switches threads when running
driver code at DISPATCH_LEVELdriver code at DISPATCH_LEVEL Restrictions: A driver cannot touch pagable memory, Restrictions: A driver cannot touch pagable memory,
or use file functionsor use file functions
IRQs And IRQLs On 8259 PICIRQs And IRQLs On 8259 PIC
3131
Hardware Interrupt 0Hardware Interrupt 0
Hardware Interrupt 1Hardware Interrupt 1
……
Hardware Interrupt 14Hardware Interrupt 14
Hardware Interrupt 15Hardware Interrupt 15
2 – DISPATCH_LEVEL2 – DISPATCH_LEVEL
1 – APC_LEVEL1 – APC_LEVEL
0 – PASSIVE_LEVEL0 – PASSIVE_LEVEL
IDEIDE
CLOCKCLOCK
ISR queues DPCISR queues DPC
DPC DPC executesexecutes
Thread Thread SwitchesSwitches
IRQ
L
IRQ
L
IO-APIC ExampleIO-APIC Example
DeviceDevice IRQIRQ IRQLIRQLUSB ControllerUSB Controller 0xB40xB4 0xA0xASCSI ControllerSCSI Controller 0xA30xA3 9 9 Network AdapterNetwork Adapter 0xA40xA4 99SCSI ControllerSCSI Controller 0x930x93 88Network AdapterNetwork Adapter 0x940x94 88SCSI ControllerSCSI Controller 0x830x83 7 7 IDE ControllerIDE Controller 0x720x72 66SCSI ControllerSCSI Controller 0x730x73 66Floppy ControllerFloppy Controller 0x620x62 55Video ControllerVideo Controller 0x630x63 5 5 Com PortCom Port 0x510x51 44Network AdapterNetwork Adapter 0x530x53 44
From an 8-Way server machine down the hall, From an 8-Way server machine down the hall, other machines will be different!other machines will be different!
SynchronizationSynchronization
PASSIVE_LEVEL (IRQL 0)PASSIVE_LEVEL (IRQL 0) SemaphoresSemaphores EventsEvents Resources (a kind of Mutex)Resources (a kind of Mutex)
APC_LEVEL (IRQL 1)APC_LEVEL (IRQL 1) Fast Mutexes (automatically raises IRQL to APC_LEVEL)Fast Mutexes (automatically raises IRQL to APC_LEVEL) Semaphores, Events, Resources (note: none raise IRQL)Semaphores, Events, Resources (note: none raise IRQL)
DISPATCH_LEVEL (IRQL 2)DISPATCH_LEVEL (IRQL 2) SpinlocksSpinlocks No reentrant primitives (i.e., mutexes)No reentrant primitives (i.e., mutexes)
Hardware levels (IRQL > 2)Hardware levels (IRQL > 2) KeSynchronizeExecutionKeSynchronizeExecution
Security AttackSecurity Attack
A user mode application may choose to A user mode application may choose to “freeze” a thread. User mode does this “freeze” a thread. User mode does this by queuing an APC to the appropriate by queuing an APC to the appropriate thread. Security is compromised if your thread. Security is compromised if your driver gets frozen holding a sync objectdriver gets frozen holding a sync object Use synchronization objects that raise Use synchronization objects that raise
to APC_LEVEL or above, orto APC_LEVEL or above, or Move such operations into a system Move such operations into a system
thread, orthread, or Use KeEnterCriticalRegion and Use KeEnterCriticalRegion and
KeLeaveCriticalRegionKeLeaveCriticalRegion
Drivers And DevicesDrivers And Devices
Every driver has a DriverObject associated with itEvery driver has a DriverObject associated with it DriverObject(s) represent driver-specific informationDriverObject(s) represent driver-specific information
Dispatch tableDispatch table
Each driver creates one or more DeviceObject(s) via Each driver creates one or more DeviceObject(s) via IoCreateDevice(…)IoCreateDevice(…)
DeviceObject(s) contain per-device informationDeviceObject(s) contain per-device information DeviceExtensionDeviceExtension NameName Flags (e.g., DO_POWER_PAGABLE)Flags (e.g., DO_POWER_PAGABLE)
A WDM driver is typically unloaded when all it’s A WDM driver is typically unloaded when all it’s DeviceObject(s) have been deletedDeviceObject(s) have been deleted
Drivers And DevicesDrivers And Devices
DRIVER_OBJECTDRIVER_OBJECTScanner.sysScanner.sys
DEVICE_OBJECTDEVICE_OBJECT(Scanner #3)(Scanner #3)
DEVICE_OBJECTDEVICE_OBJECT(Scanner #2)(Scanner #2)
DEVICE_OBJECTDEVICE_OBJECT(Scanner #1)(Scanner #1)
DRIVER_OBJECTDRIVER_OBJECTToaster.sysToaster.sys
DEVICE_OBJECTDEVICE_OBJECT(Toaster #1)(Toaster #1)
DEVICE_OBJECTDEVICE_OBJECT(Scanner #2)(Scanner #2)
DEVICE_OBJECTDEVICE_OBJECT
DEVICE_OBJECTDEVICE_OBJECT
DEVICE_OBJECTDEVICE_OBJECT
Device StacksDevice Stacks
Doing an operation often requires Doing an operation often requires multiple drivers multiple drivers
DeviceObjects are arranged into DeviceObjects are arranged into chains called Device Stackchains called Device Stack
DRIVER_OBJECTDRIVER_OBJECTScanner.sysScanner.sys
DEVICE_OBJECTDEVICE_OBJECT
DEVICE_OBJECTDEVICE_OBJECT(Scanner #1)(Scanner #1)
I/O Request PacketsI/O Request Packets
The OS communicates with drivers The OS communicates with drivers by sending I/O Request Packets (IRPs) by sending I/O Request Packets (IRPs) to a device stackto a device stack
IRPs are WDM’s solutionIRPs are WDM’s solutionto asynchronous I/Oto asynchronous I/O
DEVICE_OBJECTDEVICE_OBJECT(Scanner #2)(Scanner #2)
DEVICE_OBJECTDEVICE_OBJECT
DEVICE_OBJECTDEVICE_OBJECT
DEVICE_OBJECTDEVICE_OBJECT
IRPIRP
Asynchronous I/OAsynchronous I/O
Goal: Let applications queue one or more Goal: Let applications queue one or more requests without blockingrequests without blocking Example: Decompressing GIF frames Example: Decompressing GIF frames
from a CDfrom a CD Two dedicated application threads Two dedicated application threads
is not an optimal solutionis not an optimal solution Thread switches are expensiveThread switches are expensive
Policy needs to be in the driver stackPolicy needs to be in the driver stack Only it knows whether a given request should be Only it knows whether a given request should be
handled synchronously or asynchronouslyhandled synchronously or asynchronously
Synchronous OS designSynchronous OS design
Driver ADriver A
Driver BDriver B
Driver CDriver C
AppApp Param for AParam for AParam for AParam for AReturn address to AppReturn address to App……Param for BParam for BParam for BParam for BReturn address to AReturn address to A……Param for CParam for CParam for CParam for CReturn address to BReturn address to B
Thread StackThread Stack
Stack PointerStack Pointer
Instruction PointerInstruction Pointer
User ModeUser Mode
Kernel ModeKernel Mode
I/O Request PacketsI/O Request Packets
Param for AParam for AParam for AParam for AReturn address to AppReturn address to App……Param for BParam for BParam for BParam for BReturn address to AReturn address to A……Param for CParam for CParam for CParam for CReturn address to BReturn address to B
Thread StackThread Stack
IRP HeaderIRP Header(Contains Status and Stack Pointer)(Contains Status and Stack Pointer)
Param AParam A Param AParam A Callback for InitatorCallback for Initator
Param BParam B Param BParam B Callback for ACallback for A
Param CParam C Param CParam C Callback for BCallback for B
IO_STACK_LOCATIONIO_STACK_LOCATION
IoGetCurrentIrpStackLocationIoGetCurrentIrpStackLocation (and IoGetNextIrpStackLocation) (and IoGetNextIrpStackLocation)
IoCallDriverIoCallDriver
IoCompleteRequestIoCompleteRequest
Completion routineCompletion routine (IoSetCompletionRoutine) (IoSetCompletionRoutine)
Irp->IoStatus.Status/InformationIrp->IoStatus.Status/Information
I/O Request PacketsI/O Request Packets
Stack FrameStack Frame
Stack PointerStack Pointer
Subroutine callSubroutine call
Return from subroutineReturn from subroutine
Return Address/CallbackReturn Address/Callback
Return ValueReturn Value
Thread Stack ConceptThread Stack Concept IRP Stack ConceptIRP Stack Concept
I/O Request PacketsI/O Request Packets
Each IRP must be targeted at a specific Each IRP must be targeted at a specific device stackdevice stack
IRPs typically have just enough stack IRPs typically have just enough stack locations to traverse the device stacklocations to traverse the device stack You must allocate a new IRP if you need to forward You must allocate a new IRP if you need to forward
the request to another stackthe request to another stack
IRP HeaderIRP Header(Contains Status and Stack Pointer)(Contains Status and Stack Pointer)
Param AParam A Param AParam A Callback for InitiatorCallback for Initiator
Param BParam B Param BParam B Callback for ACallback for A
Param CParam C Param CParam C Callback for BCallback for B
Device ADevice A
Device BDevice B
Device CDevice C
33
22
11
I/O Request PacketsI/O Request Packets
IRP HeaderIRP Header
ThreadThread UserIoStatusUserIoStatus UserEventUserEvent
Stack PointerStack Pointer IoStatusIoStatus CancelRoutineCancelRoutine
Major Major CodeCode
Minor Minor CodeCode
ParamParam ParamParam ParamParam ParamParam Completion Completion RoutineRoutine
Completion Completion ContextContext
IRP_MJ_IRP_MJ_ IRP_MN_IRP_MN_ …… …… …… …… func(…)func(…) PVOIDPVOID
DRIVER_OBJECTDRIVER_OBJECTDispatch TableDispatch Table
IRP_MJ_CREATEIRP_MJ_CREATE
IRP_MJ_CLOSEIRP_MJ_CLOSE
IRP_MJ_READIRP_MJ_READ
IRP_MJ_WRITEIRP_MJ_WRITE
IRP_MJ_DEVICE_CONTROLIRP_MJ_DEVICE_CONTROL
IRP_MJ_PNPIRP_MJ_PNP
IRP_MJ_POWERIRP_MJ_POWER
DEVICE_OBJECTDEVICE_OBJECT
What do I return from my dispatch What do I return from my dispatch routine?routine?
Return same value completion routine would Return same value completion routine would see, else return STATUS_PENDINGsee, else return STATUS_PENDING
Caller on thread stackCaller on thread stack
I/O Request PacketsI/O Request Packets
status = IoCallDriver(...); status = Irp->IoStatus.Status;
Callers completion routineCallers completion routine
I/O Request PacketsI/O Request Packets
Correct value returned from dispatch handler:Correct value returned from dispatch handler:
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;IoCompleteRequest( Irp, IO_NO_INCREMENT );IoCompleteRequest( Irp, IO_NO_INCREMENT );return STATUS_UNSUCCESSFUL;return STATUS_UNSUCCESSFUL;
Irp->IoStatus.Status = STATUS_SUCCESS;Irp->IoStatus.Status = STATUS_SUCCESS;IoSkipCurrentIrpStackLocation( Irp );IoSkipCurrentIrpStackLocation( Irp );return IoCallDriver( deviceBeneathMe, Irp );return IoCallDriver( deviceBeneathMe, Irp );
Incorrect value returned from dispatch handler:Incorrect value returned from dispatch handler:
Irp->IoStatus.Status = STATUS_SUCCESS;Irp->IoStatus.Status = STATUS_SUCCESS;IoSkipCurrentIrpStackLocation( Irp );IoSkipCurrentIrpStackLocation( Irp );IoCallDriver( deviceBeneathMe, Irp );IoCallDriver( deviceBeneathMe, Irp );return STATUS_SUCCESS;return STATUS_SUCCESS;
// Be extra careful when changing status in completion routines!// Be extra careful when changing status in completion routines!
The Two Types Of I/OThe Two Types Of I/O
Buffered I/OBuffered I/O Driver writes into Irp->AssociatedIrp.SystemBufferDriver writes into Irp->AssociatedIrp.SystemBuffer OS queues an APC in the requesting process OS queues an APC in the requesting process
context where it performs a copycontext where it performs a copy Direct I/ODirect I/O
Doesn’t require a copyDoesn’t require a copy Memory pages are locked during the duration Memory pages are locked during the duration
of the operationof the operation Pages are described by the IRPs Memory Pages are described by the IRPs Memory
Descriptor List (Irp->MdlAddress)Descriptor List (Irp->MdlAddress) Driver use DMA functions or get a kernel address Driver use DMA functions or get a kernel address
via via MmGetSystemAddressForMdlSafe(Irp->MdlAddress)MmGetSystemAddressForMdlSafe(Irp->MdlAddress)
WDM Device StacksWDM Device Stacks
A WDM driver stack can A WDM driver stack can contain several different contain several different kinds of device objects:kinds of device objects: Functional Device Object Functional Device Object
( “FDO” )( “FDO” ) Physical Device Object Physical Device Object
(“PDO”)(“PDO”) FiltersFilters
The stack and the OS data The stack and the OS data associated with it is called associated with it is called a “DevNode”a “DevNode”
Device NodeDevice Node(“DevNode”)(“DevNode”)
PDOPDOPhysical Device ObjectPhysical Device Object
FDOFDOFunctional Device ObjectFunctional Device Object
Upper Device FiltersUpper Device Filters
Lower Device FiltersLower Device Filters
Lower Class FiltersLower Class Filters
Upper Class FiltersUpper Class Filters
I/O IRPs are typically handled I/O IRPs are typically handled by the FDOby the FDO Create, Close, Read, Write, etc.Create, Close, Read, Write, etc. Drivers must fail any such IRP Drivers must fail any such IRP
explicitly if it’s not handledexplicitly if it’s not handled PnP and Power IRPs traverse PnP and Power IRPs traverse
the entire stack except if there the entire stack except if there is an erroris an error Drivers do not modify these Drivers do not modify these
IRPs if they do not implement IRPs if they do not implement the requestthe request
WMI IRPs are targeted at WMI IRPs are targeted at specific device objects in specific device objects in the stackthe stack Drivers do not modify Drivers do not modify
WMI IRPs if they do not WMI IRPs if they do not implement WMIimplement WMI
WDM Device StacksWDM Device Stacks
DevNodeDevNode
PDOPDOPhysical Device ObjectPhysical Device Object
FDOFDOFunctional Device ObjectFunctional Device Object
Upper Device FiltersUpper Device Filters
Lower Device FiltersLower Device Filters
Lower Class FiltersLower Class Filters
Upper Class FiltersUpper Class Filters
IRP
IRP
WDM Device StacksWDM Device Stacks
A PDO is created by the A PDO is created by the bus driverbus driver This is done in response to an This is done in response to an
OS enumeration requestOS enumeration request
Only the PDO has a name! Only the PDO has a name! More on this laterMore on this later
FDO’s and Filters are created FDO’s and Filters are created in AddDevice routines in AddDevice routines Drivers do not find their hardware, Drivers do not find their hardware,
rather their hardware finds themrather their hardware finds them Plug and Play passes the PDO Plug and Play passes the PDO
to AddDeviceto AddDevice Drivers attach new device objects Drivers attach new device objects
to the stack via to the stack via IoAttachDeviceToDeviceStackIoAttachDeviceToDeviceStack
DevNodeDevNode
PDOPDOPhysical Device ObjectPhysical Device Object
FDOFDOFunctional Device ObjectFunctional Device Object
Upper Device FiltersUpper Device Filters
Lower Device FiltersLower Device Filters
Lower Class FiltersLower Class Filters
Upper Class FiltersUpper Class Filters
USB Floppy DevNodeUSB Floppy DevNode
11 IoInvalidateDeviceRelationsIoInvalidateDeviceRelations
22 IRP_MN_QUERY_DEVICE_RELATIONSIRP_MN_QUERY_DEVICE_RELATIONS
IRPIRPInformationInformationPDOPDO
USBHUB.SYSUSBHUB.SYS
33
IRPIRPInformationInformation
IRP_MN_QUERY_IDIRP_MN_QUERY_ID
FDOFDOUSBFLOP.SYSUSBFLOP.SYS
Upper FiltersUpper Filters
Lower FiltersLower Filters
66 Load driversLoad drivers
44
[Version][Version]Signature =Signature =Provider Provider
Search INF FilesSearch INF Files
FDOFDOUSBHUB.SYSUSBHUB.SYS
PDOPDO
USB Hub DevNodeUSB Hub DevNode
PNP ManagerPNP Manager
RegistryRegistry
55 Call Class Installers Call Class Installers and Co-Installersand Co-Installers
Plug And PlayPlug And Play
The Plug and Play Manager queries the stack The Plug and Play Manager queries the stack to get a list of all possible resource solutions:to get a list of all possible resource solutions: The PDO responds to The PDO responds to
IRP_MN_QUERY_RESOURCE_REQUIREMENTSIRP_MN_QUERY_RESOURCE_REQUIREMENTS The FDO can adjust these requirements by The FDO can adjust these requirements by
responding to responding to IRP_MN_FILTER_RESOURCE_REQUIREMENTSIRP_MN_FILTER_RESOURCE_REQUIREMENTS
The Plug and Play Manager sends the best The Plug and Play Manager sends the best resource settings in IRP_MN_START_DEVICEresource settings in IRP_MN_START_DEVICE The card is configured to use the “Raw’ resource The card is configured to use the “Raw’ resource
setset The driver communicates with the card via the The driver communicates with the card via the
“Translated” resource set“Translated” resource set
Plug And PlayPlug And Play
FDO’s must respond to the following Plug and Play FDO’s must respond to the following Plug and Play events:events: ““Remove” events occur when a device is removed or disabled Remove” events occur when a device is removed or disabled
IRP_MN_REMOVE_DEVICEIRP_MN_REMOVE_DEVICE IRP_MN_SURPRISE_REMOVAL IRP_MN_SURPRISE_REMOVAL IRP_MN_QUERY_REMOVE_DEVICEIRP_MN_QUERY_REMOVE_DEVICE IRP_MN_CANCEL_REMOVE_DEVICEIRP_MN_CANCEL_REMOVE_DEVICE
““Stop” events occur when a device is to be paused for Stop” events occur when a device is to be paused for resource rebalancingresource rebalancing IRP_MN_QUERY_STOP_DEVICEIRP_MN_QUERY_STOP_DEVICE IRP_MN_STOP_DEVICEIRP_MN_STOP_DEVICE IRP_MN_CANCEL_STOP_DEVICEIRP_MN_CANCEL_STOP_DEVICE
Other Plug and Play events FDO’s typically respond to:Other Plug and Play events FDO’s typically respond to: IRP_MN_START_DEVICE (We hope)IRP_MN_START_DEVICE (We hope) IRP_MN_QUERY_CAPABILITIESIRP_MN_QUERY_CAPABILITIES
Plug And PlayPlug And Play
PDO’s must respond to even more messages:PDO’s must respond to even more messages: ““Who” are you, “What” are you? Who” are you, “What” are you?
IRP_MN_QUERY_IDIRP_MN_QUERY_ID IRP_MN_QUERY_DEVICE_TEXTIRP_MN_QUERY_DEVICE_TEXT
““Where are you, and where can you go today?”Where are you, and where can you go today?” IRP_MN_QUERY_RESOURCESIRP_MN_QUERY_RESOURCES IRP_MN_QUERY_RESOURCE_REQUIREMENTSIRP_MN_QUERY_RESOURCE_REQUIREMENTS
Settings, capabilities, and location:Settings, capabilities, and location: IRP_MN_QUERY_CAPABILITIESIRP_MN_QUERY_CAPABILITIES IRP_MN_QUERY_BUS_INFORMATIONIRP_MN_QUERY_BUS_INFORMATION
Misc.Misc. IRP_MN_QUERY_DEVICE_RELATIONS (TargetRelations) IRP_MN_QUERY_DEVICE_RELATIONS (TargetRelations)
““Finding” Plug And Play Finding” Plug And Play DevicesDevices Applications often need a list of devices to manipulate Applications often need a list of devices to manipulate
or display to the useror display to the user Printers, Scanners, etcPrinters, Scanners, etc
Using “well known names” (i.e., LptX) doesn’t Using “well known names” (i.e., LptX) doesn’t work well in a Plug and Play environmentwork well in a Plug and Play environment
Applications often need a list of devices that share a Applications often need a list of devices that share a given property, and properties can be hierarchicalgiven property, and properties can be hierarchical (E.g., all storage devices, just CDROMs, just Zip drives, etc.)(E.g., all storage devices, just CDROMs, just Zip drives, etc.)
WDM drivers expose one or more “Interfaces”, WDM drivers expose one or more “Interfaces”, identified via GUIDidentified via GUID Note: Only started devices can expose interfaces Note: Only started devices can expose interfaces
InterfacesInterfaces
Drivers register support for a given Interface Drivers register support for a given Interface by calling IoRegisterDeviceInterfaceby calling IoRegisterDeviceInterface
Drivers dynamically enable and disable an Drivers dynamically enable and disable an interface via IoSetDeviceInterfaceStateinterface via IoSetDeviceInterfaceState
IoSetDeviceInterfaceState creates a symbolic IoSetDeviceInterfaceState creates a symbolic link so that user mode applications can link so that user mode applications can communicate with the devicecommunicate with the device More on this laterMore on this later
Applications enumerate devices by passing an Applications enumerate devices by passing an interface GUID to various SetupApi functionsinterface GUID to various SetupApi functions
Kernel mode securityKernel mode security
User mode can attempt to open User mode can attempt to open a device with Read, Write, and a device with Read, Write, and Execute privileges Execute privileges
By default, all users get full By default, all users get full access to a WDM device stackaccess to a WDM device stack
Security checks are done at Security checks are done at Create/Open timeCreate/Open time
Access to a device can be Access to a device can be restricted via INFrestricted via INF Search DDK for “INF AddReg”, Search DDK for “INF AddReg”,
or stay tuned…or stay tuned…PDOPDO
Physical Device ObjectPhysical Device Object
FDOFDOFunctional Device ObjectFunctional Device Object
Upper Device FiltersUpper Device Filters
Lower Device FiltersLower Device Filters
Lower Class FiltersLower Class Filters
Upper Class FiltersUpper Class Filters
Kernel Mode SecurityKernel Mode Security
[MyDevice.NTx86][MyDevice.NTx86]CopyFiles = ...CopyFiles = ...
[MyDevice.NTx86.Services][MyDevice.NTx86.Services]AddService = ...AddService = ...
[MyDevice.NTx86.HW][MyDevice.NTx86.HW]AddReg = MyDevice.SecurityAddReg = MyDevice.Security
[MyDevice.Security][MyDevice.Security]HKR,,HKR,,DeviceCharacteristicsDeviceCharacteristics,0x10001,0x100,0x10001,0x100HKR,,HKR,,SecuritySecurity,,”,,”security-descriptor-stringsecurity-descriptor-string””
"D:P(A;;GA;;;SY)""D:P(A;;GA;;;SY)"
AllowAllow AllAll SystemSystem
"D:P( ;; ;;; ) (...)""D:P( ;; ;;; ) (...)"
A: AllowA: AllowD: DenyD: Deny
GA: AllGA: AllGR: ReadGR: ReadGW: WriteGW: Write
SY: SystemSY: SystemLA: Local AdministratorLA: Local AdministratorPU: Power userPU: Power userWD: WorldWD: World
(Example: System only access)(Example: System only access)
Security AttacksSecurity Attacks
Security constraints are applied Security constraints are applied to named device objectsto named device objects
In a WDM stack, only the PDO In a WDM stack, only the PDO should be namedshould be named If another device is named, it might If another device is named, it might
compromise system securitycompromise system security
A device doesn’t have to expose A device doesn’t have to expose a symbolic link to be opened!a symbolic link to be opened!
Be sure to pass in Be sure to pass in FILE_DEVICE_SECURE_OPEN FILE_DEVICE_SECURE_OPEN when creating PDO’swhen creating PDO’s
PDOPDOPhysical Device ObjectPhysical Device Object
FDOFDOFunctional Device ObjectFunctional Device Object
Upper Device FiltersUpper Device Filters
Lower Device FiltersLower Device Filters
Lower Class FiltersLower Class Filters
Upper Class FiltersUpper Class Filters
IOCTL SecurityIOCTL Security
Drivers encode the security requirements of Drivers encode the security requirements of Device IOCTLs in the 32bit code itself Device IOCTLs in the 32bit code itself
The Access mask can specify one of four The Access mask can specify one of four different privilege levels:different privilege levels: OpenableOpenable Opened with read accessOpened with read access Opened with write accessOpened with write access Opened with both read and write accessOpened with both read and write access
The IO Manager prevents applications from The IO Manager prevents applications from forming IOCTL codes their privileges don’t allowforming IOCTL codes their privileges don’t allow
MethodMethodFunctionFunctionAccessAccessDevice NumberDevice Number
3131 1515 1313 22
Security AttacksSecurity Attacks
Drivers should always check the full 32bit Ioctl code!Drivers should always check the full 32bit Ioctl code! Masking out the Access bits lets lower privileged Masking out the Access bits lets lower privileged
Ioctl’s succeedIoctl’s succeed Do not use the IoGetFunctionCodeFromCtlCode macroDo not use the IoGetFunctionCodeFromCtlCode macro
Drivers should always check the buffer size of Drivers should always check the buffer size of incoming Ioctl’sincoming Ioctl’s Malicious applications can attempt to crash the system via Malicious applications can attempt to crash the system via
malformed requestsmalformed requests Do Do notnot implement IOCTLs that allow an application to implement IOCTLs that allow an application to
read or write any piece of virtual or physical memoryread or write any piece of virtual or physical memory Don’t ship with debugging IOCTLs enabledDon’t ship with debugging IOCTLs enabled Don’t pass back “pointers” as handlesDon’t pass back “pointers” as handles
MethodMethodFunctionFunctionAccessAccessDevice NumberDevice Number
3131 1515 1313 22
Power ManagementPower Management
To implement power management, To implement power management, a driver needs code to:a driver needs code to: Save and restore the state of its hardwareSave and restore the state of its hardware Disable and enable the deviceDisable and enable the device Queue incoming requestsQueue incoming requests Convert System states to Device statesConvert System states to Device states
A driver must not touch it’s hardware A driver must not touch it’s hardware while it’s device is offwhile it’s device is off Memory and I/O typically return Memory and I/O typically return
0xFFFFFFFF when off, fooling badly written 0xFFFFFFFF when off, fooling badly written ISR’sISR’s
System StatesSystem States
S0: WorkingS0: Working Machine is fully powered and responsiveMachine is fully powered and responsive
S1: StandbyS1: Standby Processor and bus clocks are off, recovery time typically Processor and bus clocks are off, recovery time typically
two secondstwo seconds
S2: StandbyS2: Standby Greater power conservation, recovery time more Greater power conservation, recovery time more
than two secondsthan two seconds
S3: StandbyS3: Standby Typically only memory remains poweredTypically only memory remains powered
S4: HibernationS4: Hibernation Machine is off, memory is written to persistent storageMachine is off, memory is written to persistent storage
S5: OffS5: Off
Device StatesDevice States D0D0
Hardware is fully poweredHardware is fully powered D1D1
Less power consumption than D0Less power consumption than D0 Transition to fully powered happens quicklyTransition to fully powered happens quickly Driver cannot access device until powered upDriver cannot access device until powered up
D2D2 Less power consumption than D1Less power consumption than D1 Longer power-up time than D1Longer power-up time than D1 Driver cannot access device until powered upDriver cannot access device until powered up
D3: OffD3: Off Device is completely off (inaccessable)Device is completely off (inaccessable)
Converting S IRPs To D Converting S IRPs To D IRPsIRPs The WDM Power Manager sends S IRPs:The WDM Power Manager sends S IRPs:
IRP_MN_QUERY_POWERIRP_MN_QUERY_POWER IRP_MN_SET_POWERIRP_MN_SET_POWER
Each device stack has a “Power Policy Owner” who Each device stack has a “Power Policy Owner” who converts S IRPs to D IRPsconverts S IRPs to D IRPs The Power Policy Owner is typically the FDOThe Power Policy Owner is typically the FDO The mapping comes from the S The mapping comes from the S D array stored in the D array stored in the
IRP_MN_QUERY_CAPABILITIES structureIRP_MN_QUERY_CAPABILITIES structure Each entry calls out the lightest possible D state for Each entry calls out the lightest possible D state for
a given S statea given S state Mappings can be rounded down (deeper)Mappings can be rounded down (deeper)
The Power Policy Owner then uses The Power Policy Owner then uses PoRequestPowerIrp to request the appropriate D IRPPoRequestPowerIrp to request the appropriate D IRP
The conversion code is complicated, but most drivers The conversion code is complicated, but most drivers can use the boilerplate code in the WDM DDKcan use the boilerplate code in the WDM DDK
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYSPCI BusPCI BusS0 S0 D0 D0
PCIIDE.SYSPCIIDE.SYS
ATAPI.SYSATAPI.SYSIDE ChannelIDE Channel S0 S0 D0 D0
ATAPI.SYSATAPI.SYS
DISK.SYSDISK.SYS HDDHDDS0 S0 D0 D0
CDROMCDROMS0 S0 D0 D0
SCSIPORT.SYSSCSIPORT.SYS
CDROM.SYSCDROM.SYS
ACPI.SYSACPI.SYS
PCIIDE.SYSPCIIDE.SYSIDE ControllerIDE Controller S0 S0 D0 D0
PCI.SYSPCI.SYS
SCSI CardSCSI Card S0 S0 D0 D0
SCSIPORT.SYSSCSIPORT.SYS
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYS
Net CardNet CardS0 S0 D0 D0
NDIS.SYSNDIS.SYS
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYS
D0D0
D1D1D2D2
D3D3ModemModem
D0D0
D1D1D2D2
D3D3HDDHDD
D0D0
D1D1D2D2
D3D3CDROMCDROM
C0C0
D1D1D2D2
D3D3Net CardNet Card
D0D0
S0 S0 D0 D0
System State S0 – System State S0 –
WorkingWorking
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYSPCI BusPCI BusS1 S1 D1 D1
PCIIDE.SYSPCIIDE.SYS
ATAPI.SYSATAPI.SYSIDE ChannelIDE Channel S1 S1 D1 D1
ATAPI.SYSATAPI.SYS
DISK.SYSDISK.SYS HDDHDDS1 S1 D1 D1
CDROMCDROMS1 S1 D3 D3
SCSIPORT.SYSSCSIPORT.SYS
CDROM.SYSCDROM.SYS
ACPI.SYSACPI.SYS
PCIIDE.SYSPCIIDE.SYSIDE ControllerIDE Controller S1 S1 D1 D1
PCI.SYSPCI.SYS
SCSI CardSCSI Card S1 S1 D3 D3
SCSIPORT.SYSSCSIPORT.SYS
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYS
Net CardNet CardS1 S1 D3 D3
NDIS.SYSNDIS.SYS
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYS
D0D0
D1D1D2D2
D3D3ModemModem
D0D0
D1D1D2D2
D3D3HDDHDD
D0D0
D1D1D2D2
D3D3CDROMCDROM
C0C0
D1D1D2D2
D3D3Net CardNet Card
D0D0
S1 S1 D? D?
System State S1 – System State S1 – StandbyStandby
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYSPCI BusPCI BusS3 S3 D3 D3
PCIIDE.SYSPCIIDE.SYS
ATAPI.SYSATAPI.SYSIDE ChannelIDE Channel S3 S3 D3 D3
ATAPI.SYSATAPI.SYS
DISK.SYSDISK.SYS HDDHDDS3 S3 D3 D3
CDROMCDROMS3 S3 D3 D3
SCSIPORT.SYSSCSIPORT.SYS
CDROM.SYSCDROM.SYS
ACPI.SYSACPI.SYS
PCIIDE.SYSPCIIDE.SYSIDE ControllerIDE Controller S3 S3 D3 D3
PCI.SYSPCI.SYS
SCSI CardSCSI Card S3 S3 D3 D3
SCSIPORT.SYSSCSIPORT.SYS
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYS
Net CardNet CardS3 S3 D3 D3
NDIS.SYSNDIS.SYS
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYS
D0D0
D1D1D2D2
D3D3ModemModem
D0D0
D1D1D2D2
D3D3HDDHDD
D0D0
D1D1D2D2
D3D3CDROMCDROM
C0C0
D1D1D2D2
D3D3Net CardNet Card
D0D0
S3 S3 D? D?
System State S3 – System State S3 –
StandbyStandby
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYSPCI BusPCI BusS4 S4 D3 D3
PCIIDE.SYSPCIIDE.SYS
ATAPI.SYSATAPI.SYSIDE ChannelIDE Channel S4 S4 D3 D3
ATAPI.SYSATAPI.SYS
DISK.SYSDISK.SYS HDDHDDS4 S4 D3 D3
CDROMCDROMS4 S4 D3 D3
SCSIPORT.SYSSCSIPORT.SYS
CDROM.SYSCDROM.SYS
ACPI.SYSACPI.SYS
PCIIDE.SYSPCIIDE.SYSIDE ControllerIDE Controller S4 S4 D3 D3
PCI.SYSPCI.SYS
SCSI CardSCSI Card S4 S4 D3 D3
SCSIPORT.SYSSCSIPORT.SYS
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYS
Net CardNet CardS4 S4 D3 D3
NDIS.SYSNDIS.SYS
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYS
D0D0
D1D1D2D2
D3D3ModemModem
D0D0
D1D1D2D2
D3D3HDDHDD
D0D0
D1D1D2D2
D3D3CDROMCDROM
C0C0
D1D1D2D2
D3D3Net CardNet Card
D0D0
S4 S4 D3 D3
System State S4 – System State S4 – HibernateHibernate
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYSPCI BusPCI BusS5 S5 D3 D3
PCIIDE.SYSPCIIDE.SYS
ATAPI.SYSATAPI.SYSIDE ChannelIDE Channel S5 S5 D3 D3
ATAPI.SYSATAPI.SYS
DISK.SYSDISK.SYS HDDHDDS5 S5 D3 D3
CDROMCDROMS5 S5 D3 D3
SCSIPORT.SYSSCSIPORT.SYS
CDROM.SYSCDROM.SYS
ACPI.SYSACPI.SYS
PCIIDE.SYSPCIIDE.SYSIDE ControllerIDE Controller S5 S5 D3 D3
PCI.SYSPCI.SYS
SCSI CardSCSI Card S5 S5 D3 D3
SCSIPORT.SYSSCSIPORT.SYS
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYS
Net CardNet CardS5 S5 D3 D3
NDIS.SYSNDIS.SYS
ACPI.SYSACPI.SYS
PCI.SYSPCI.SYS
D0D0
D1D1D2D2
D3D3ModemModem
D0D0
D1D1D2D2
D3D3HDDHDD
D0D0
D1D1D2D2
D3D3CDROMCDROM
C0C0
D1D1D2D2
D3D3Net CardNet Card
D0D0
S5 S5 D3 D3
System State S5 – System State S5 – OffOff
Converting S IRPs To D Converting S IRPs To D IRPsIRPs
( Simplified from Toaster Sample in the WDM DDK )( Simplified from Toaster Sample in the WDM DDK )
NTSTATUSNTSTATUSToasterDispatchPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)ToasterDispatchPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){{
PIO_STACK_LOCATION stackLocation;PIO_STACK_LOCATION stackLocation;
////// Not shown: Are we deleted? If so, fail IRP.// Not shown: Are we deleted? If so, fail IRP.// Not shown: Are we started? If not, pass on IRP untouched.// Not shown: Are we started? If not, pass on IRP untouched.////stackLocation = IoGetCurrentIrpStackLocation( Irp );stackLocation = IoGetCurrentIrpStackLocation( Irp );switch(stackLocation->MinorFunction) {switch(stackLocation->MinorFunction) {
case IRP_MN_QUERY_POWER:case IRP_MN_QUERY_POWER: return ToasterQueryPowerState( DeviceObject, Irp );return ToasterQueryPowerState( DeviceObject, Irp );
case IRP_MN_SET_POWER: case IRP_MN_SET_POWER: return ToasterSetPowerState( DeviceObject, Irp );return ToasterSetPowerState( DeviceObject, Irp );
default:default: // Not shown: default logic// Not shown: default logic
}}}}
NTSTATUSNTSTATUS
ToasterQueryPowerState( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )ToasterQueryPowerState( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{{
PIO_STACK_LOCATION stackLocation;PIO_STACK_LOCATION stackLocation;
if (stackLocation->Parameters.Power.Type == SystemPowerState) { if (stackLocation->Parameters.Power.Type == SystemPowerState) {
return return HandleSystemPowerIrpHandleSystemPowerIrp( DeviceObject, Irp );( DeviceObject, Irp );
} }
return HandleDeviceQueryPower( DeviceObject, Irp );return HandleDeviceQueryPower( DeviceObject, Irp );
}}
Converting S IRPs To D Converting S IRPs To D IRPs IRPs
S S D routine D routine
NTSTATUSNTSTATUS
ToasterSetPowerState( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )ToasterSetPowerState( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{{
PIO_STACK_LOCATION stackLocation;PIO_STACK_LOCATION stackLocation;
if (stackLocation->Parameters.Power.Type == SystemPowerState) { if (stackLocation->Parameters.Power.Type == SystemPowerState) {
return return HandleSystemPowerIrpHandleSystemPowerIrp( DeviceObject, Irp );( DeviceObject, Irp );
} }
return HandleDeviceSetPower( DeviceObject, Irp );return HandleDeviceSetPower( DeviceObject, Irp );
}}
Converting S IRPs To D Converting S IRPs To D IRPs IRPs
S S D routine D routine
NTSTATUSNTSTATUS
HandleSystemPowerIrp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )HandleSystemPowerIrp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{{
////
// Forward IRP *asynchronously*, catch it on way up// Forward IRP *asynchronously*, catch it on way up
////
IoMarkIrpPending( Irp );IoMarkIrpPending( Irp );
IoCopyCurrentIrpStackLocationToNext( Irp );IoCopyCurrentIrpStackLocationToNext( Irp );
IoSetCompletionRoutine( Irp,IoSetCompletionRoutine( Irp,
(PIO_COMPLETION_ROUTINE) (PIO_COMPLETION_ROUTINE) OnFinishSystemPowerUpOnFinishSystemPowerUp,, NULL, TRUE, TRUE, TRUE); NULL, TRUE, TRUE, TRUE);
PoCallDriver( fdoData->NextLowerDriver, Irp );PoCallDriver( fdoData->NextLowerDriver, Irp );
return STATUS_PENDING;return STATUS_PENDING;
}}
Converting S IRPs To D Converting S IRPs To D IRPs IRPs
PPOPPO
S-I R
PS
-I RP
NTSTATUSNTSTATUSOnFinishSystemPowerUp(OnFinishSystemPowerUp( IN PDEVICE_OBJECT Fdo,IN PDEVICE_OBJECT Fdo, IN PIRP Irp,IN PIRP Irp, IN PVOID NotUsedIN PVOID NotUsed )){{ NTSTATUS status = Irp->IoStatus.Status;NTSTATUS status = Irp->IoStatus.Status;
if (!NT_SUCCESS(status)) {if (!NT_SUCCESS(status)) {
PoStartNextPowerIrp(Irp);PoStartNextPowerIrp(Irp); return STATUS_SUCCESS;return STATUS_SUCCESS; }}
QueueCorrespondingDeviceIrpQueueCorrespondingDeviceIrp( Irp, Fdo );( Irp, Fdo );
return STATUS_MORE_PROCESSING_REQUIRED;return STATUS_MORE_PROCESSING_REQUIRED;}}
Converting S IRPs To D Converting S IRPs To D IRPs IRPs
PPOPPO
S-I
RP
S-I
RP
VOIDVOIDQueueCorrespondingDeviceIrp( IN PIRP SIrp, IN PDEVICE_OBJECT DeviceObject )QueueCorrespondingDeviceIrp( IN PIRP SIrp, IN PDEVICE_OBJECT DeviceObject ){{ POWER_STATE dState;POWER_STATE dState; PFDO_DATA fdoData = (PFDO_DATA) DeviceObject->DeviceExtension;PFDO_DATA fdoData = (PFDO_DATA) DeviceObject->DeviceExtension; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(SIrp);PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(SIrp); SYSTEM_POWER_STATE sState = stack->Power.State.SystemState;SYSTEM_POWER_STATE sState = stack->Power.State.SystemState;
if ((sState == PowerSystemWorking) || (fdoData->ArmedForWake)) {if ((sState == PowerSystemWorking) || (fdoData->ArmedForWake)) { dState.DeviceState = fdoData->DeviceCaps.DeviceState[sState];dState.DeviceState = fdoData->DeviceCaps.DeviceState[sState]; } else {} else { dState.DeviceState = PowerDeviceD3;dState.DeviceState = PowerDeviceD3; }}
status = PoRequestPowerIrp(status = PoRequestPowerIrp( fdoData->UnderlyingPDO,fdoData->UnderlyingPDO,
stack->MinorFunction,stack->MinorFunction,
dState, dState, OnPowerRequestCompleteOnPowerRequestComplete,, SIrp, NULL);SIrp, NULL); }}
// Not shown: Handle case where PoRequestPowerIrp fails// Not shown: Handle case where PoRequestPowerIrp fails}}
Converting S IRPs To D Converting S IRPs To D IRPs IRPs
PPOPPO
S-I
RP
S-I
RP
D-IR
PD
-IRP
VOIDVOID
OnPowerRequestComplete(OnPowerRequestComplete(
IN PDEVICE_OBJECT DeviceObject,IN PDEVICE_OBJECT DeviceObject,
IN UCHAR MinorFunction,IN UCHAR MinorFunction,
IN POWER_STATE State,IN POWER_STATE State,
IN PVOID PowerContext,IN PVOID PowerContext,
IN PIO_STATUS_BLOCK IoStatusIN PIO_STATUS_BLOCK IoStatus ))
{{
PIRP sIrp = (PIRP) PowerContext;PIRP sIrp = (PIRP) PowerContext;
////
// Copy status from D IRP to S IRP// Copy status from D IRP to S IRP
////
sIrp->IoStatus.Status = IoStatus->Status;sIrp->IoStatus.Status = IoStatus->Status;
PoStartNextPowerIrp( sIrp );PoStartNextPowerIrp( sIrp );
IoCompleteRequest( sIrp, IO_NO_INCREMENT );IoCompleteRequest( sIrp, IO_NO_INCREMENT );
}}
Converting S IRPs To D Converting S IRPs To D IRPs IRPs
PPOPPO
S-I
RP
S-I
RP
D-I
RP
D- I
RP
VOIDVOIDOnPowerRequestComplete(OnPowerRequestComplete( IN PDEVICE_OBJECT DeviceObject,IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction,IN UCHAR MinorFunction, IN POWER_STATE State,IN POWER_STATE State, IN PVOID PowerContext,IN PVOID PowerContext, IN PIO_STATUS_BLOCK IoStatusIN PIO_STATUS_BLOCK IoStatus )){{ PIRP sIrp = (PIRP) PowerContext;PIRP sIrp = (PIRP) PowerContext;
//// // Copy status from D IRP to S IRP// Copy status from D IRP to S IRP //// sIrp->IoStatus.Status = IoStatus->Status;sIrp->IoStatus.Status = IoStatus->Status;
PoStartNextPowerIrp( sIrp );PoStartNextPowerIrp( sIrp ); IoCompleteRequest( sIrp, IO_NO_INCREMENT );IoCompleteRequest( sIrp, IO_NO_INCREMENT );}}
Converting S IRPs To D Converting S IRPs To D IRPs IRPs
PPOPPO
S-I
RP
S-I
RP
Power Management Power Management Gotcha’s Gotcha’s Drivers cannot block a thread and wait for a Drivers cannot block a thread and wait for a
power IRP to complete on Windows 2000power IRP to complete on Windows 2000 S S D state mapping for non-power manageable D state mapping for non-power manageable
PCI devices may contain invalid D states on PCI devices may contain invalid D states on Windows 2000Windows 2000
Drivers cannot safely complete power IRPs at Drivers cannot safely complete power IRPs at DISPATCH_LEVEL on Windows 9xDISPATCH_LEVEL on Windows 9x
Drivers cannot safely do “idle time” power Drivers cannot safely do “idle time” power management on Windows 9xmanagement on Windows 9x
PCI supports two types of D3 which WDM PCI supports two types of D3 which WDM doesn’t distinguishdoesn’t distinguish
WDM And Hardware – DSPWDM And Hardware – DSP
Bad design:Bad design:1.1. OS loads DSP driver OS loads DSP driver
against “DSP device”against “DSP device”
2.2. Driver uploads software Driver uploads software into volatile DSP RAMinto volatile DSP RAM
3.3. ““DSP device” DSP device” disappears from busdisappears from bus
4.4. New device appears in New device appears in it’s placeit’s place
Problem: What happens Problem: What happens when the device is when the device is turned off?turned off?
Correct design:Correct design:1.1. OS loads DSP bus driver OS loads DSP bus driver
against “DSP device”against “DSP device”2.2. DSP bus driver uploads DSP bus driver uploads
DSP software into DSP software into volatile DSP RAMvolatile DSP RAM
3.3. Bus driver exposes new Bus driver exposes new functionality by creating functionality by creating a child devicea child device
4.4. Bus driver reprograms Bus driver reprograms DSP when appropriateDSP when appropriate
Recommended