161

Click here to load reader

How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Embed Size (px)

Citation preview

Page 1: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

How to Develop a UMDF DriverPart 1

Page 2: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

OutlineOutline

Architectural Goals

Architectural DescriptionCore components

Driver Manager, Reflector, Host Process, and Drivers

Driver startup and teardown

I/O flow

Layered drivers

Driver Programming ModelWDF object model

COM-lite

UMDF DDIs

Page 3: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

GoalsGoals

An understanding of UMDF infrastructure

An understanding of the UMDF DDIs and how they are structured

Page 4: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Architectural Goals Architectural Goals

StabilityDriver failures should NOT bring down the system

Build on Windows NT I/O modelApplications are transparent to driver runtime environment – User or Kernel mode

Asynchronous, layered drivers, and packet based

Integrate into PnP for device installs, driver load/unload

SecurityDriver failures should NOT compromise the system

Driver runs in “LocalService” account

Shared model between KMDF and UMDFShared model != same DDIs or data structures

Page 5: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device StackDevice Stack

Architectural Block DiagramArchitectural Block Diagram

Provided by:Provided by:

MicrosoftMicrosoft

ISVISV

IHVIHV

Windows Kernel(I/O Mgr, PnP)

Reflector

Driver Manager

Kernel Driver(e.g., WinUSB)

Application(s)

Kernel Driver 2

User

Kernel

Host Process

UM Driver

Host Process

WinSock

Reflector

UM Driver

Page 6: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF ComponentsUMDF Components

Driver managerGlobal, system-wide Windows Service

Responsible for host process lifetime

Responds to messages from reflector

Always running

Started during installation of the first UMDF device

Reflector

Driver Manager

Host ProcessUM

Driver

Page 7: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF ComponentsUMDF Components

ReflectorNucleus of UMDF

Installed with each device stack

Proxy for UM device stack in kernel

Forwards I/O, Power, and PnP messages from kernel to host process

Ties the UM device stack to KM side

Ensures “good behavior” of UM drivers

Proper responses to messages

Timely completion of critical system messages

Tracks all outstanding kernel resources

Reflector

Driver Manager

Host ProcessUM

Driver

Page 8: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF Components : Host ProcessUMDF Components : Host Process

Child process of the UM Driver ManagerUnit of isolation for the device stack

Driver crash will not affect other device stacks

Container for Framework and UM driver(s)

Runtime environment for framework and driverI/O dispatching, driver loading, driver layering, thread pool

Handles messages from reflector and driver manager

Reflector

Driver Manager

UM Driver

Runtime FrameworkDDI

Page 9: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Host Process - FrameworkHost Process - Framework

Implements all of the WDF modelQueues, Request, I/O target, etc

Implements default behaviorReduces vendor written code

Exposes DDI

Implemented as DLL

UM Driver

Runtime Framework DDI

Page 10: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

IPC : Message PassingIPC : Message Passing

RequirementsPacket-based and asynchronous

Cancelable

Fail-safe

Efficient data transfer

Secure

Several potential solutionPending I/O, synchronous message passing

Windows codenamed “Longhorn” solution: ALPCStandard Windows OS Component

Page 11: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Processing MessagesProcessing Messages

KM drivers handle I/O in caller’s threadObviously not a option for UMDF

Host has a thread pool processing messagesDedicated thread for “critical” operations

To ensure I/O doesn’t block them

e.g., PnP/PM, Cancellation, Cleanup, and Close

Shared threads for non-critical operations like I/OPool could grow or shrink as load changes

Fixed at 2 threads for Beta 1

For long operations the driver should consider using work-items

Page 12: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Driver Loading Driver Loading

Windows Kernel(I/O Mgr, PnP)

Driver Manager

Host Runtime

Reflector

Kernel Driver

1

3

Add Device

Framework6 UM

Driver

5

2 IPC Channel4

Provided by:Provided by:

MicrosoftMicrosoft

IHVIHV

Page 13: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Host Runtime

IPC Channel

Driver Loading (Layered UM Drivers)Driver Loading (Layered UM Drivers)

Windows Kernel(I/O Mgr, PnP)

Driver Manager

Reflector

Kernel Driver

2

3

Add Device

Framework6 UM Driver

5

4

UM FilterDriver

7

Framework8

1

Provided by:Provided by:

MicrosoftMicrosoft

IHVIHV

Page 14: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Driver Loading (Host Process)Driver Loading (Host Process)

UM DriverHost

Runtime Framework

Add Device

Driver creates WDF Device

Add Device

Add Device

Driver creates WDF Queue

Driver creates WDF Queue

Provided by:Provided by:

MicrosoftMicrosoft

IHVIHV

Page 15: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Host Process

I/O Data FlowI/O Data Flow

Kernel driver

Windows Kernel“Up” Device

Object

ApplicationUM Filter

DriverUM I/O Mgr

“Down” Device Object

Reflector

Device Stack

FrameworkUM Driver

IRP2

IPC Message

3

47

8

12

6

5

9

Framework

Win32 I/O API

1

1011

Provided by:Provided by:

MicrosoftMicrosoft

ISVISV

IHVIHV

Page 16: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

I/O in Host ProcessI/O in Host Process

UM Driver

Run-time

Framework

Device Stack

Invoke driver callbackpassing in I/O request

UM Irp

Host File Object returned as context to the reflector.

IPC Message

Host File Object

UMIRP

Driver can return without completing i/o (asynch)

Driver eventuallycompletes i/o.

Provided by:Provided by:

MicrosoftMicrosoft

ISVISV

IHVIHV

Page 17: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device Removal and CleanupDevice Removal and Cleanup

UM DriverRun-time Framework

Device Remove

Message path similar to “add device” pathDriver gets several PnP notifications for remove

UM driver may unload when remove finishes

Host process may exit when all drivers are unloaded

Host lifetime controlled by the driver manager

Page 18: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

When Driver or Application CrashesWhen Driver or Application Crashes

When the UM driver crashes:Reflector gets notification from OS

Reflector tracks outstanding I/O in the host. Completed with STATUS_DRIVER_PROCESS_TERMINATED

Win32 apps will see ERROR_DRIVER_PROCESS_TERMINATED

The kernel drivers for the device stack are unloaded

Device is disabled (yellow bang in device manager)

When the application crashes:Reflectors gets IRP_MJ_CLEANUP

Sent to host on the “cancel” IPC channel

Host/UM driver complete pending I/O requests

Page 19: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Timeout PolicyTimeout Policy

UMDF enforces timeouts on “critical” operationsOperations that run under system wide locks

Operations that affect user experience

If operations do not complete on time Host is forcibly terminated and error report is generated

Critical operations includePnP and PM operations

These run under a system-wide PnP lock

Blocks other PnP operations

I/O CancellationLong term operations must be cancelable

Adversely affects user experience (application hangs)

In WinHEC release, time out = 1 minuteWill adjust based on feedback & failure report data for RTM

Page 20: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

ImpersonationImpersonation

Driver runs in LocalService security context

Drivers can impersonate the client processOnly for I/O requests

Not for PnP or other system messages

typedef enum _SECURITY_IMPERSONATION_LEVEL { SecurityAnonymous, SecurityIdentification, SecurityImpersonation, SecurityDelegation } SECURITY_IMPERSONATION_LEVEL;

Page 21: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Using ImpersonationUsing Impersonation

Application controls the allowed levelSpecified in QOS settings in CreateFile API

See dwFlagsAndAttributes parameter in MSDN

INF sets the driver’s maximum desired levelStored in registry during device installation

Set this as low as possible for your driver

Reduces chance of “elevation of privilege” attack

Driver requests impersonation for given requestSpecifies desired level and a callback

Isolate impersonated code Do minimal work to reduce the attack surface

Page 22: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF VerifierUMDF Verifier

Built-in verificationChecks for problems in framework code

Checks for problems in device driver code

Always enabled & always fatalUnless you have a debugger attached

DDI misusage result in verifier failurePassing incorrect parameters, including NULL, in DDI

Incorrect DDI call sequence

More aggressive checks planned for Beta 2

Verifier failure causes a UMDF “Bugcheck”Generates Memory Dump

Generates Error Report

Sends Error Report to Microsoft (opt-in)

Page 23: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF Verifier FailuresUMDF Verifier Failures

Driver failures will “Bugcheck” the hostBugcheck is NOT the “Blue Screen of Death”

We will pick a less scary name in Beta 2

Bugcheck will:Save memory dump to log file directory

%windir%\System32\LogFiles\WUDF\xxx.dmp

Create an error report to report to Microsoft (opt-in)

Break into debugger if presentPrints out error message

Developer can continue…but that may lead to another crash

Terminate the host process and disable the device

Page 24: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF Error ReportingUMDF Error Reporting

Current driver failure reports are hard to analyzeToo much information in the running kernelNot enough fits into a minidump

User-Mode Drivers reports can be betterCompartmentalized – less information to collectSpecialized – not mixed with irrelevant stateBetter collection – we’re not limited by crash dump

UMDF reports problems through Windows Error Reporting (WER)

UMDF queues reports for later approval and uploadWER provides for a global “opt-in” to upload quicker

No modal crash dialogsBubble on the task bar indicating an incident has occurred

Please upload error reports for Beta 1Even if you think it’s your driverWe need data to refine what we’re collecting

Page 25: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Types of Error ReportsTypes of Error Reports

UMDF will report the following problems :UM Driver Verifier failureUnhandled Exception in host processUnexpected Host TerminationFailure or Timeout of “Critical” Operation

Error Report may contain:Memory dump of the host processCopy of UMDF’s internal trace logConfiguration information about the device

Device name, manufacturer, drivers installedDriver binary versions

Internal analysis of the problemAddress of the last driver to framework call (or vice versa)Problem code, exception info, etc...

Report contents depend on the problem detected

Page 26: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device Driver Interfaces (DDI)and Programming Patterns

Page 27: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Framework objects have a hierarchical relationship

WDF Driver is the root object

Child lifetime scoped by parent

Every WDF object is defined byMethods: actions on objects

Properties: are object attributes

Events: notifications from Framework objects to the driver

Framework Object ModelFramework Object Model

WDF Driver

WDF Device

WDF Queue

WDF Queue

Page 28: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Key Framework ObjectsKey Framework Objects

Object DescriptionDriver Supports one or more devices

One per driver per host processDevice Tracks PnP/PM state changes and

notifies driverI/O Request Represents application’s I/O requestI/O Queue Controls I/O request flow into driverFile Provides per-handle context for driverI/O Target Represents next lower device in stack

Encapsulates driver to driver communication

Page 29: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Parent-Child Object HierarchyParent-Child Object Hierarchy

Device

I/O Queue

I/O Request

I/O Target

Driver

File

Applies to lifetime managementLifetime of child is scoped within that of the parent

Child is cleaned up when the parent goes away

Page 30: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Framework Object Model Framework Object Model

WDF Driver

WDF Device

WDF Queue

WDF Queue

MyDriver

MyRead Queue MyWrite

Queue

Framework Driver

Driver implemented Callback Objects

WDF Objects

MyDevice

Provided by:Provided by:

MicrosoftMicrosoft

IHVIHV

Page 31: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Framework Object Model Framework Object Model

MyDriver1

MyDevice1

MyRead Queue1MyWrite

Queue1

Framework Driver 1

WDF Driver

WDF Device

WDF Queue WDF Queue

WDF Driver

WDF Queue

WDF Device

WDF Queue

Driver 2

MyDevice2 MyDriver2

MyWrite Queue2MyRead

Queue2Device Stack

Each driver in the stack has its own set of framework objects

Page 32: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

DDI DesignDDI Design

Common object model with KMDFDriver writers familiar with KMDF can quickly come up to speed with UMDF

Interface based programming modelUM developers are familiar with C++ and OOP

Interfaces allow logical grouping of functions making it easy to navigate through the DDI

Facilitates opt-in programming

Built-in extensibility

C++ is the supported language in the first version

Uses a small subset of COM (COM-Lite)COM complexity is in COM RTL features

Threading Model, Automation, etc...

UMDF doesn’t depend on COM RTL

Page 33: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

DDI : COM InterfacesDDI : COM Interfaces

Problems solved by InterfacesAllows us to evolve the DDI without changing exported functions

Older drivers do not need to be rebuilt

No C++ name mangling

No C++ fragile base class problem

COM facilitates thisWell understood

Existing tools like ATL

We don’t want to invent another model

C++ facilitates thisInterfaces are just abstract base classes

With only pure virtual functions

Compiler implements interface as function pointer table (V-Table)

Page 34: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

All You Need to Know about COM …All You Need to Know about COM …

COM interfaces, by convention, start with “I”e.g., IUnknown

All COM interfaces are derived from IUknownQueryInterface, AddRef, Release

Lifetime management of COM objectsAddRef: takes a reference on Framework object

WDF object model simplifies ref-counting

Release: drops ref-count on Framework objectDriver should release interfaces retrieved from Fx when done

Query Interface (QI): allows discovery of “interfaces” supported by the driver

Page 35: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device Driver Interfaces (DDI)Device Driver Interfaces (DDI)

UMDF DDI is in wudfddi.idlinterface IWDFObject : IUnknown{ HRESULT DeleteWdfObject(); ... VOID AcquireLock(); VOID ReleaseLock();};

Simplified C++ equivalent generated by MIDLstruct IWDFObject : public IUnknown{ virtual HRESULT DeleteWdfObject() = 0; ... virtual VOID AcquireLock() = 0; virtual VOID ReleaseLock() = 0;};

IWDFObject is base interface for all WDF objects

Page 36: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device Driver Interfaces (DDI)Device Driver Interfaces (DDI)

DDIs are grouped into 2 types of interfacesFunctionality exported by Framework

By convention these begin with IWDF

E.g., IWDFDriver, IWDFDevice, IWDFIoQueue

Callbacks exported by DriverThese are of the form I<WdfObject><Function>

e.g., IQueueCallbackRead, IRequestCallbackCancel

Methods on callback interfaces begin with “On”

interface IQueueCallbackRead : IUnknown{ void OnRead ( IWDFIoQueue* pWdfQueue, IWDFIoRequest* pWdfRequest, SIZE_T NumOfBytesToRead );};

Page 37: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device Driver Interfaces (DDI)Device Driver Interfaces (DDI)

KMDF and UMDF DDI are similarTuned to language and runtime environment

KMDF NTSTATUS WdfDeviceConfigureRequestDispatching( WDFDEVICE Device, WDFQUEUE Queue, WDF_REQUEST_TYPE RequestType, BOOLEAN Forward );

UMDF HRESULT IWDFDevice::ConfigureRequestDispatching( IWDFIoQueue * pQueue, WDF_REQUEST_TYPE RequestType, BOOL Forward );

Device parameter is implicit in C++

Page 38: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Driver EntryDriver Entry

IDriverEntry is the top driver-exported interface interface IDriverEntry::IUnknown {

HRESULT OnInitialize( IWDFDriver* pWdfDriver );

HRESULT OnDeviceAdd(

IWDFDriver* pWdfDriver,

IWDFDeviceInitialize* pWdfDeviceInit

);

VOID OnDeinitialize();

};

OnInitialize and OnDeinitializeDo driver-wide initialization and cleanup

OnDeviceAddInvoked once for each new device detected by Windows

Page 39: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Callback objects = Callbacks + ContextExample: Creating Device Object

HRESULT CMyDriver::OnDeviceAdd( IWDFDriver* pDriver,

IWDFDeviceInitialize* pDeviceInit ) { IUnknown *pDeviceCallback = NULL; ... // Create callback object hr = CMyDevice::CreateInstance( &pDeviceCallback, pDeviceInit, completionPort ); ... // Create WDF Device hr = pDriver->CreateDevice( pDeviceInit, pDeviceCallback, &pIWDFDevice ); ... }

Callback ObjectsCallback Objects

1

2

Page 40: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Callback Objects (con’t)Callback Objects (con’t)class CMyDevice : public IDevicePnpHardware // Callback interface exposed to // framework.{private: HANDLE m_CompletionPort; WINUSB_INTERFACE HANDLE m_UsbHandle; UCHAR m_BulkOutPipe; ULONG m_BulkOutMaxPacket; ...public: virtual HRESULT stdcall OnPrepareHardware( IWDFDevice* pDevice ); STDMETHOD( OnReleaseHardware )( IWDFDevice *pDevice );

// Factory method static HRESULT CreateInstance( IUnknown *pUnknown, IWDFDeviceInitialize *pDeviceInit, HANDLE CompletionPort ); ...};

Context

Callback

Page 41: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Callback Objects (con’t)Callback Objects (con’t)static HRESULT CreateInstance(

IUnknown **ppUnknown,

IWDFDeviceInitialize *pDeviceInit,

HANDLE CompletionPort

) {

...

// Allocate our callback context

CMyDevice *pMyDevice = new CMyDevice();

...

// Get our callback interface

hr = pMyDevice->QueryInterface(

__uuidof(IUnknown),

(void **) ppUnknown

);

...

return hr;

}

1

2

Page 42: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Callback Objects (con’t) Callback Objects (con’t)

WDF Driver

WDF Device

Framework Driver

IDriverEntryOnDeviceAdd1

IWDFDriver::CreateDevice( … ) 3

4QueryInterface for• IDevicePnP• IDevicePnPHardware

- - - -

5

MyDeviceIUnknown

IDevicePnpHardware

2

Callback Object

Provided by:Provided by:

MicrosoftMicrosoft

IHVIHV

Page 43: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

SummarySummary

Discussed driver loading/unloading, I/O data flowDriver installation and setup are same as WDM drivers

Keep in the mind the “timeout” polices in reflector

Built-in verifier checks

Error reporting via WER

Discussed driver programming modelKMDF and UMDF share same model

UMDF DDI is based on C++ and COM-lite

Callback objects = Context + Callbacks

Page 44: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

How to Develop a UMDF DriverPart 2

Page 45: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

OutlineOutline

Goals

Getting StartedWriting your Driver

Installing your Driver

Debugging the Driver

Plug and Play / Power ManagementDesign goals

Design overview

Device Driver Interface (DDI)

PnP/PM driver callback example

Page 46: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

GoalsGoals

How to start writing and debugging a UMDF driver

How to interact with UMDF’s Plug And Play and Power Management support

The basics of creating and configuring a device driver

Page 47: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Writing Your Driver

Page 48: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

What is a User-Mode Driver?What is a User-Mode Driver?

User-Mode (UM) Drivers are DLLsProvide driver’s “callback object” classes

Use COM programming pattern, not runtimeAt least, not very much of the runtime

Expose standard COM entry pointsDllGetClassObject, DllRegisterServer, DllUnregisterServer

Can write UM Drivers in C or C++Implementing COM objects is easier in C++

Can use ATL with C++ for additional COM support

WDF Supplement CD contains several examplesThis talk references the “Skeleton” driver

Page 49: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF Driver DLL ExportsUMDF Driver DLL Exports

DllMainCalled when DLL loads (and unloads)

Construct global objects, initialize tracing

Dll[Un]RegisterServerCalled by CoInstaller during device installation

Skeleton sample uses ATLRather than write another implementation

DllGetClassObjectCalled on device arrival by COM to get “class factory”

DllCanUnloadNowJust return S_FALSE

Page 50: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Common Driver ClassesCommon Driver Classes

COM objects must implement IUnknownIndependently, or with help from CUnknown base class

UMDF driver implements these classesCClassFactory

Instantiates your driver event handler

CMyDriverYour Driver-Callback Class

Must implement IDriverEntry

Paired with an IWDFDriver object

CMyDeviceYour Device-Callback Class

May implement IDevicePnpHardware and/or IDevicePnp

Paired with an IWDFDevice object

Page 51: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF Skeleton DriverUMDF Skeleton Driver

Example code based on UMDF Skeleton sampleCode in slides should not be used as-is

UMDF Skeleton does just enough to get loadedBoilerplate code found in all UM DriversMinimal callback objects for driver and device

Description of filesComSup.h & ComSup.cpp

COM Support code – provides classes for IUnknown & IClassFactoryDllSup.h & DllSup.cpp

DLL Support code – provides implementation of required exportsDepends on COM support code

Driver.h & Driver.cppDriver-Callback Class

Device.h & Device.cppDevice-Callback Class

“TODO” comments mark where to add your driver codeCOM and DLL support files require no changesThe driver and device files you’ll need to modify for your driver

Page 52: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Example: CMyDriver Definition (Driver.h)Example: CMyDriver Definition (Driver.h)

class CMyDriver: public CUnknown, public IDriverEntry {

IDriverEntry *QueryIDriverEntry();

HRESULT Initialize();

public:

static HRESULT CreateInstance( PCMyDriver *Driver );

HRESULT OnInitialize( IWDFDriver *FxDriver ){

return S_OK;

}

HRESULT OnDeviceAdd(IWDFDriver *FxDriver,

IWDFDeviceInitialize *FxDeviceInit);

HRESULT OnDeinitialize( IWDFDriver *FxDriver ) {

return S_OK;

}

... // IUnknown methods, etc...

};

Page 53: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Example: CMyDriver ImplementationExample: CMyDriver Implementation (Driver.cpp)(Driver.cpp)

HRESULT CMyDriver::CreateInstance( CMyDriver **Driver ) {

CMyDriver *driver = new CMyDriver();

if (driver == NULL) { return E_OUTOFMEMORY; }

HRESULT hr = driver->Initialize();

if (S_OK == hr) {

*Driver = driver;

} else {

driver->Release();

}

return hr;

}

HRESULT CMyDriver::Initialize() {

HRESULT hr = S_OK;

... // Do any initialization that could fail here

return hr;

}

Page 54: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Example: CMyDriver Implementation Example: CMyDriver Implementation (con’t)(con’t)HRESULT CMyDriver::OnDeviceAdd(...) {

CMyDevice *deviceCallback; IWDFDevice *fxDevice;

HRESULT hr = CMyDevice::CreateInstance( FxDeviceInit,

&device );

if (S_OK == hr) {

... // Call SetLockingModel(), SetFilter(), etc...

hr = FxWdfDevice->CreateDevice(

FxDeviceInit,

deviceCallback->QueryIUnknown(),

&fxDevice

);

// Release Reference from QueryIUnknown()

deviceCallback->Release();

}

if (S_OK == hr) {fxDevice->Release();}

if (NULL != deviceCallback) {deviceCallback->Release();}

return hr;

}

Page 55: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Example: CMyDevice Definition (Device.h)Example: CMyDevice Definition (Device.h)class CMyDevice : public CUnknown {

HRESULT Initialize( IWDFDeviceInitialize *DeviceInit ) { return S_OK; }

static HRESULT CreateInstance( IWdfDeviceInitialize *FxDeviceInit, CMyDevice **Device ); // Add IUnknown methods here}

Page 56: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Writing Your Driver (Summary)Writing Your Driver (Summary)

Create the common codeRequired DLL ExportsCOM support classesCopy from skeleton, use existing ones (ATL), or write your own

Implement CMyDriver classIncluding the OnDeviceAdd() method

Allocate and initialize a CMyDevice objectCreate IWDFDevice object & connect to CMyDevice callbacks

Implement CMyDevice classAdd Device-Callback interfaces later

Your driver should now loadBut can’t talk to your device or do I/ONext two talks will address that

Page 57: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Installing Your DriverInstalling Your Driver

INF Based InstallationJust like WDM and kernel-mode WDF drivers

Device Matching, Driver Signing, etc... work normally

User-Mode Driver’s INF does extra workUse UMDF CoInstaller

Register Driver DLLs

Configure the Driver List

Setup UM Driver Key

Add the Reflector driver

We plan to simplify the installation for Beta 2Still INF based, but more support from CoInstaller

Page 58: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Registry LocationsRegistry Locations

UMDF keeps information in several registry keysWe’ll refer to them using these names as we go

Defined in the [Strings] section of the Skeleton INF

Key Name Location%UMDF_Software% HKLM \

Software \Microsoft \

Windows NT \CurrentVersion \

WUDF

%UMDF_Services% %UMDF_Software% \Services

%UMDF_Host% %UMDF_Services% \ {193a1820-d9ac-4997-8c55-be817523f6aa}

Page 59: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

System provided CoInstallerSets Driver Manager to start automatically

WUDFCoInstaller.dll is already installedNo need to copy the file

Driver’s INF must reference this CoInstaller

[Skeleton.CoInstallers]AddReg = Skeleton.CoInstallers_AddReg

[Skeleton.CoInstallers_AddReg]HKR,,CoInstallers32,0x00010000,“WUDFCoInstaller.dll”

Without the CoInstaller your driver may not startDriver can’t start if the Driver Manager isn’t running

Problem code 37 in device manager

Use UMDF CoInstallerUse UMDF CoInstaller

Page 60: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF uses CoCreateInstance to load driversThis requires the driver to be “registered”

INF must register any user-mode drivers it copiesDo this in the [DDInstall] section

[Skeleton]CopyFiles=DriverCopyRegisterDlls=Skeleton.RegisterDlls

[Skeleton.RegisterDlls]11,,WUDFSkeleton.dll,1

Unregistered drivers will not loadProblem code 43 in the device manager

Register Driver DLLsRegister Driver DLLs

Page 61: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF loads drivers by “Driver Name”We recommend the binary name (without extension)

UMDF Maintains its own driver listLists drivers in order of attachment to the stack

Drivers are listed by “Driver Name”

User-Mode drivers load above kernel-mode drivers

MultiString stored under the device node’s key[Skeleton_AddReg]

HKR, “WUDF”, “DriverList”, 0x00010000, “WUDFSkeleton”

If this is missingProblem 43 in device manager

Configure the Driver ListConfigure the Driver List

Page 62: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Setup UM Driver KeySetup UM Driver Key

Create an entry under UMDF Services KeyOne for each driver installed

Key name is the Device Name

Contains UMDF-Specific Driver Information:The Driver’s CLSID

Configure this in the INF

Replace CLSID with your driver’s class ID.[Skeleton_AddReg]

HKLM, %WUDF_Services%\WUDFSkeleton, “ComCLSID”, 0, “{CLSID}”

Without this:Problem 43 in device manager

Page 63: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Reflector driver is WUDFRd.sysAlready installed on the system

Your INF must make this the top-most kernel driver

If you’re writing a UM function driverAssign reflector as service with AddService directive

You’ll need a service install section too

If you’re writing a UM Upper-Level filter driverAssign reflector as top-most Upper Device Filter

Without this UMDF is never loadedDevice may start, but no host process

Adding the Reflector DriverAdding the Reflector Driver

Page 64: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Installing Your Driver (Summary)Installing Your Driver (Summary)

Use the UMDF CoInstaller

Register your Driver DLLs with COM

Configure the Driver List

Setup UM Driver KeyRecord your driver’s CLSID

Add Reflector driver to the kernel drivers

If it doesn’t work:Is Driver Manager started?

Does device manager show a problem code?

Is WUDFHost.exe (host process) running ?

Page 65: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Debugging Your Driver

Page 66: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Debugging OverviewDebugging Overview

Similar to service debuggingUM Drivers cannot be started by the debugger

No Just-In-Time debugging

Host process starts when device is installedPlug & Replug the device to restart

Or disable & re-enable in device manager

Each device stack runs in host processWUDFHost.exe

Child of Driver Manager service

One stack per host-process for now

Page 67: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Debugger OptionsDebugger Options

WinDbgGUI Debugger

Source and/or Assembly level debugging

UMDF debugger extension available

Can work as user-mode or kernel-mode debugger

See resources slide to find download location

Visual Studio DebuggerWDK and Visual Studio aren’t currently integrated

UMDF Debugger extension not available

Must copy mspdb71.dll from WDK to use it

We’re concentrating support on WinDbg

CDB & KDIf you prefer command line debugging, these work

Page 68: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

User-Mode or Kernel-Mode DebuggingUser-Mode or Kernel-Mode Debugging

Can debug UMDF with UM or KM debuggerYou can use WinDbg to debug either way

UM DebuggerSimpler and more familiarHave to attach to each host process when it starts

KM DebuggingRequires a second computer to run debuggerMore complex, but quite powerful

Stops entire computer – no UMDF timeouts

Can be always runningCatch UMDF Verifier problems like JIT debugger

Can debug and set breakpoints in host processUse “.process /i <process object address>” to break into running host

See additional slides for KM Debugging tips

Page 69: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Host process started by Driver Manager serviceYou can’t attach debugger until after initialization

Host Process supports an “initial breakpoint” (IB)Host waits N seconds for debugger to attach

Breaks into debugger once detected

Continues running once N seconds elapse

Timeout (in seconds) configured under UMDF_Host key

HostProcessDbgBreakOnStart = N

Enabling IB disables other UMDF timeoutsLike those on PnP operations

Initial Breakpoint is for UM Debugger (by default)Can be configured to watch for both UM & KM debugger

Set high-bit in the timeout value0x8000000 attempts once to break into either debugger

Enabling the DebuggerEnabling the Debugger

Page 70: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Cannot connect UM Debugger until host starts

Enable the Initial Breakpoint

Attach the device to the systemOr enable it in the device manager

If you have a single device attachedRun “windbg –pn WUDFHost.exe”

Repeat until it finds a host process to debug

If you have multiple devices attachedFind out process ID (PID) of the new host

Use tasklist.exe before & after to find new host process

Run “windbg –p PID”

Attaching the UM DebuggerAttaching the UM Debugger

Page 71: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF Debugger ExtensionUMDF Debugger Extension

WudfExt.dllCopy into your path

“!load WudfExt.dll” debugger command loads the extension

Names are case sensitive

Command Description!devstack Shows device stacks in the host process

!dumpirps Shows UM IRPs in the host process

!umirp Shows a host IRP

!wdfdriverinfo Shows info about a UM driver

!wdfdevicequeue Shows the I/O queues for a device

!wdfqueue Shows an IoQueue

!wdfrequest Shows an IoRequest

!wdfitf2obj Converts an interface pointer to an object address for above extensions.

Page 72: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Interesting UMDF Breakpoints (BP)Interesting UMDF Breakpoints (BP)

Event to debug Breakpoint (BP)

Host attempts to load driver

OLE32!CoCreateInstance

Watch for your CLSID

Driver Load MyDriver!DllMain

Invoked first time when your DLL is loadedCalled after that too, so clear the BP once it hits

Creation of CMyDriver

MyDriver!DllGetClassObject

Invoked to get your class factory

MyDriver!CMyDriver::CMyDriver

Invoked when the factory calls new

Driver attaches device to stack

MyDriver!CMyDriver::OnDeviceAdd

Driver creates a device to attach to the stack

Hopefully, this will get you started

Page 73: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Tracing in Your UM DriverTracing in Your UM Driver

Recommend using WPP tracing for debug outputLightweight & always available, printf-style tracing

Easily captured to disk, screen or (kernel) debugger

Skeleton contains some basic tracing codeSee MSDN documentation on Event Tracing

Collect output with tracelog.exe or traceview.exeTracelog comes with Windows

Traceview comes with WDK

For more information see:“Collecting & Viewing Traces” in additional slides

MSDN & DDK documentation

Page 74: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

What Do I Do When It Crashes? (Summary)What Do I Do When It Crashes? (Summary)

Check for configuration problemsIs there a PNP problem code?

Is there a host process running?

Is there a .dmp file WUDF log file directory?%SystemRoot%\LogFiles\WUDF\*.dmp

Attach a debugger to the host as it startsOr always enable the kernel debugger

Watch for UMDF Verifier failures

Walk through initializationUse list of interesting breakpoints

Get debug output with WPP tracing

Page 75: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Plug and Play / Power Management

Page 76: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF Design Goals for PnP/PMUMDF Design Goals for PnP/PM

Coordinate I/O delivery to driver with PnP/PM events

The framework handles complexities of PnP/PMAllow drivers to participate with optional callbacks

Support FDO and filter driver scenariosNo bus driver support for version 1

Same design as kernel mode WDF PnP/PM

Page 77: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and
Page 78: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF PnP/PM DesignUMDF PnP/PM Design

Implemented with a state machineConsumes PnP/Power messages from the reflector

Suspends and resumes I/O queues as needed

Calls the driver if desired through a set of driver provided callback functions

Driver callbacks are logically grouped into interfacesIDevicePnpHardware

IDevicePnp

IDevicePnpSelfManagedIo

Driver “opts-in” by implementing one or more callback interfaces

Software-only drivers generally don’t need any of these interfaces

Most drivers will only need IDevicePnpHardware

Page 79: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF PnP/PM InterfacesUMDF PnP/PM Interfaces

IDevicePnpHardwareFirst time hardware initialization / de-initialization

OnPrepareHardware()OnReleaseHardware()

IDevicePnpDevice state change notifications

OnD0Entry()OnD0Exit()OnSurpriseRemoval()OnQueryRemove()OnQueryStop()

IDevicePnpSelfManagedIoCustom I/O processing notifications

OnSelfManagedIoCleanup()OnSelfManagedIoFlush()OnSelfManagedIoInit()OnSelfManagedIoSuspend()OnSelfManagedIoRestart()

Page 80: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device Driver Interface (DDI)Device Driver Interface (DDI)

IDriverEntry::OnDeviceAddDriver must implement this interfaceCalled when framework receives “Add Device” messageDriver should perform initialization that does not require access to hardware or lower level driversDriver also creates a device object and device callback object (beyond the scope of this talk)

HRESULT CMyDriver::OnDeviceAdd( IWDFDriver* pDriver, IWDFDeviceInitialize* pDeviceInit ) { // Read in driver properties

INamedPropertyStore * pPropStore = NULL; hr = pDeviceInit->GetDevicePropertyStore( &pPropStore ); ...}

Page 81: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

IDevicePnpHardwareIDevicePnpHardware

OnPrepareHardwareCalled when device is first startedDriver establishes connection to the device and performs one-time initialization

HRESULT CMyDevice::OnPrepareHardware( IWDFDevice* pDevice ) { ... // Open the device

hr = pDevice->GetDeviceName( pDeviceName, … ) m_Handle = CreateFile( pDeviceName, … ) ... // Initialize the device and look for endpoints

if (WinUsb_Initialize( m_Handle, &m_UsbHandle )) { return DiscoverBulkEndpoints(); }

Page 82: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

IDevicePnpHardwareIDevicePnpHardware

OnReleaseHardwareCalled when device is removed or stoppedDriver should essentially undo anything it did in OnPrepareHardware

HRESULT CDevice::OnReleaseHardware( IWDFDevice* pDevice ) { // Close the USB handle and the device’s file // handle

if ( m_UsbHandle ) { WinUsb_Free( m_UsbHandle ); } if ( m_Handle ) { CloseHandle( m_Handle ); } return S_OK; }

Page 83: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

IDevicePnpIDevicePnpOnD0Exit

Called each time device should power downAlso called before the device is removed

Stop device’s I/O target with “leave pending I/O” flag hr = m_pIoTarget->

Stop( WdfIoTargetLeaveSentIoPending );

Save device stateSet the device into low power state

OnD0EntryCalled each time device should power upAlso called when the device starts up

Set the device into working power stateRestore any previously saved stateRestart device’s I/O target

hr = m_pIoTarget->Start();

Page 84: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

IDevicePnpIDevicePnpOnSurpriseRemoval

Called when the device has unexpectedly detached from the PCStop device’s I/O target with cancel flag

hr = m_pIoTarget->Stop( WdfIoTargetCancelSentIo )

OnQueryRemoveAllows driver to veto a device removal request

HRESULT CDevice::OnQueryRemove( IWDFDevice* pDevice ) {

return S_OK; // Allow device removal}

OnQueryStopAllows driver to veto a device stop request

HRESULT CDevice::OnQueryStop( IWDFDevice* pDevice ) { return E_FAIL; // Disallow device stop}

Page 85: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

IDevicePnpSelfManagedIoIDevicePnpSelfManagedIo

Notifications to drivers that perform I/O dispatching unmanaged by the framework

OnSelfManagedIoInit()Start I/O dispatching

OnSelfManagedIoSuspend()Pause I/O dispatching

OnSelfManagedIoRestart()Resume I/O dispatching

OnSelfManagedIoFlush()Cancel or complete all pending I/O

OnSelfManagedIoCleanup()Free I/O dispatching mechanisms

Page 86: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

PnP/PM Driver Callback Example

Page 87: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device Driver

OffOnOff

Framework

Start Device

Start DeviceStart Device

OnPrepareHardware()

Page 88: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device Driver

OffOnOff

Framework

Start Device

OnD0Entry()

Start DeviceStart Device

Page 89: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device Driver

OffOnOn

Device OperationalDevice Operational

Framework

Page 90: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device Driver

OffOnOn

OnD0Exit()

Suspend DeviceSuspend Device

Framework

Power Down

Page 91: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device Driver

OffOnOn

OnD0Entry()

Resume DeviceResume Device

Framework

Power Up

Page 92: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device Driver

OffOnOn

OnD0Exit()

Remove DeviceRemove Device

Framework

Remove Device

Page 93: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device Driver

OffOnOn

OnReleaseHardware()

Remove DeviceRemove Device

Framework

Remove Device

Page 94: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

WDM Message to UMDF Callback MappingWDM Message to UMDF Callback Mapping

Start -> Query Remove -> RemoveIRP_MN_START_DEVICE:

OnPrepareHardware()

OnD0Entry()

OnSelfManagedIoInit()

IRP_MN_QUERY_REMOVE_DEVICE:OnQueryRemove()

IRP_MN_REMOVE_DEVICE:OnSelfManagedIoSuspend()

OnD0Exit()

OnSelfManagedIoFlush()

OnReleaseHardware()

OnSelfManagedIoCleanup()

Page 95: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

WDM Message to UMDF Callback MappingWDM Message to UMDF Callback Mapping

Start -> Surprise Removal -> RemoveIRP_MN_START_DEVICE:

OnPrepareHardware()

OnD0Entry()

OnSelfManagedIoInit()

IRP_MN_SURPRISE_REMOVAL:OnSurpriseRemoval()

OnSelfManagedIoSuspend()

OnReleaseHardware()

OnSelfManagedIoFlush()

IRP_MN_REMOVE_DEVICE:OnSelfManagedIoCleanup()

Page 96: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

PnP/PM TimeoutsPnP/PM Timeouts

Each WDM PnP/PM message has a timeoutCurrently, this timeout is set to 1 minute

The reflector will abort the host process if this timeout is exceeded

Each WDM Pnp/PM message can produce multiple driver callbacks, for example:

“AddDevice” results in:OnInitialize

OnDeviceAdd

IRP_MN_START results in:OnPrepareHardware

OnD0Entry

OnSelfManagedIoInit

1 minute

1 minute

Page 97: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Supplemental Slides

Page 98: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Example: DllMainExample: DllMain

BOOL DllMain(

HINSTANCE ModuleHandle, DWORD Reason, PVOID Reserved

)

{

if (DLL_PROCESS_ATTACH == Reason) {

WPP_INIT_TRACING(“Microsoft\\UMDF\\UMDFSkeleton”);

g_ModuleHandle = ModuleHandle;

} else if (DLL_PROCESS_DETACH) == Reason) {

WPP_CLEANUP();

}

return TRUE;

}

See Skeleton\Host.cpp

Page 99: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Example: DllGetClassObjectExample: DllGetClassObjectHRESULT DllGetClassObject( REFCLSID ClassId, REFIID InterfaceId, PVOID *Interface ){ PCClassFactory factory; HRESULT hr; *Interface = NULL; if (!IsEqualCLSID( ClassId, __uuidof(MyDriverCoClass) )) { return CLASS_E_NOTAVAILABLE; } hr = CClassFactory::CreateInstance(&factory);

if (S_OK == hr) { hr = factory->QueryInterface(InterfaceId, Interface); factory->Release(); } return hr;}

Page 100: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Example: DllRegisterServer & DllCanUnloadNowExample: DllRegisterServer & DllCanUnloadNow

HRESULT DllRegisterServer() { return UpdateCOMRegistration( g_ModuleHandle, IDR_MYDRIVER_CLASSINFO, true, __uuidof( MyDriverCoClass ), L“UMDF Skeleton Sample Driver” );}

HRESULT DllUnregisterServer() { return UpdateCOMRegistration(..., false, ...)}

HRESULT DllCanUnloadNow() { return S_FALSE;}

Page 101: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Example: CUnknown DefinitionExample: CUnknown Definitionclass CUnknown : public IUnknown { LONG m_RefCount;public: CUnknown() { m_RefCount = 1; } virtual ~CUnknown() { return; } IUnknown *QueryIUnknown(){ AddRef(); return (IUnknown *)this; }

ULONG AddRef(); ULONG Release(); HRESULT QueryInterface( REFIID InterfaceId, PVOID *Interface );};

Page 102: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Example: CUnknown ImplementationExample: CUnknown ImplementationULONG CUnknown::AddRef(){ return InterlockedIncrement(&m_RefCount);}

ULONG CUnknown::Release() { ULONG count = InterlockedIncrement(&m_RefCount); if (count == 0) { delete this; } return count;}

HRESULT CUnknown:QueryInterface(...) { if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) { *Interface = QueryIUnknown(); return S_OK; } *Interface = NULL; return E_NOINTERFACE;}

Page 103: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Example: CClassFactory DefinitionExample: CClassFactory Definitionclass CClassFactory : public CUnknown, public IClassFactory {public: IClassFactory *QueryIClassFactory() {...}

// IUnknown AddRef() {return __super::AddRef()} Release() {return __super::Release()} QueryInterface(...);

// IClassFactory HRESULT CreateInstance( IUnknown *Outer, REFIID InterfaceId, PVOID *Object ); HRESULT LockServer(BOOL Lock) { return S_OK; }};

Page 104: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Example: CClassFactory ImplementationExample: CClassFactory ImplementationHRESULT CClassFactory::QueryInterface(...) {

if(IsEqualIID(Interface, __uuidof(IClassFactory)) {

*Object = QueryIClassFactory();

return S_OK;

} else {

return CUnknown::QueryInterface(...);

}

}

HRESULT CClassFactory::CreateInstance(...) {

PCMyDriver driver;

HRESULT hr = CMyDriver::CreateInstance(&driver);

if (S_OK == hr) {

hr = driver->QueryInterface(InterfaceId, Object);

driver->Release();

}

return hr;

}

Page 105: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Debugging with WinDbgDebugging with WinDbgSource Level GUI debugger(Most) commands work on addresses or symbols

ModuleName!FunctionNameModuleName!ClassName::MethodName

Best to always use fully resolved names

Setting Breakpoints“bp <addr>” sets an excution breakpoint

Use bu if the function’s module isn’t loaded yet‘ba [w|r] [1|2|4|8] <addr>’ sets a watchpoint

ba r 4 MyDriver!g_MyArrayLength

Dumping Memoryd<type> [address] [L<length>]

type = byte, word, char, unicode, dword, quadword, stringdd MyMyDriver!g_MyArrayLength L1

dv dumps local variable namesDumping Types

dt <variable name> dumps a specific localdt <addr> <typename> dumps an address or symbol as a type

dt ??? MyDriver!CMyDevice

See the WinDbg help for more details

Page 106: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Debugging with a Kernel DebuggerDebugging with a Kernel Debugger

WinDbg can be used as a kernel debuggerMust point Kernel debugger to host process

Automatic if the process requests a kernel break-inManually through the .process command

“!process 0 0” will list all process object addresses

Must reload user-mode symbols after attaching“.reload /user”

Or the stack trace won’t have any symbols

Can set breakpoints on user-mode addressesMust load user symbols first

Cannot break into a running host processMust wait for a breakpoint

UMDF “Verifier” will break into KD if attachedLast chance to debug before process termination

Page 107: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Collecting & Viewing TracesCollecting & Viewing Traces

TraceLog.exe lets you control trace sessionsTo start a session

Tracelog.exe -start MyLogger -guid MyDriver.ctl -level 255 -flag 65535 -f MyLogFile.etl

To end a sessionTracelog.exe -stop MyLogger

To print a sessionTraceFmt –o MyLogFile.txt -p symbols.pri/TraceFormat MyLogFile.etl

Or use the GUI “TraceView” toolUse in place of TraceLog or TraceFmt

Resources:“WPP Software Tracing” page in DDK documentation

MSDN online page for these tools:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ddtools/hh/ddtools/tracetools_8eccb8f7-6f29-4683-87bd-fa83618c32eb.xml.asp

Page 108: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

How to Develop a UMDF Driver: How to Develop a UMDF Driver: Part 3Part 3

Page 109: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

OutlineOutline

I/O Processing Overview

I/O Queues

File Objects

Driver Layering

I/O Targets

Cancellation

Page 110: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

GoalsGoals

A better understanding of: How to incorporate I/O processing in a UMDF driver

Framework objects involved with I/O Request processing

Knowledge of where to find resources for UMDF

Page 111: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

I/O Request Processing OverviewI/O Request Processing Overview

Page 112: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

I/O Request Processing in UMDFI/O Request Processing in UMDF

You’ve seen WDF Driver and Device objectsThese are used to configure a device stack

I/O processing involves many more objects for:Flow control and internal request routing

Per request context and callbacks

Connections to other drivers in the stack and/or system

And some concepts that span across objects:Driver Layering

Cancellation

Page 113: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Request

Framework ObjectsFramework Objects

Device

Queue

I/O Target

Memory (Input)

Memory (Output)

Driver

File

Page 114: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Framework ObjectsFramework Objects

Object Description

Device The information associated with a single layer in a device stack

Request An I/O operation

Either sent to the driver or initiated by the driver to a lower device

Queue A flow control mechanism for Requests

File An open handle to the device and any context the driver needs to store with it

I/O Target Another driver to which the Driver can send Requests

Either another user-mode layer in the device stack, the kernel-mode portion of the device stack, or the top of another device stack entirely.

Memory A buffer associated with a request

These objects are associated with request processingAll derive from IWDFObject

Page 115: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

I/O Request Processing – A Bird’s Eye viewI/O Request Processing – A Bird’s Eye view

Request

I/O Queue

Driver

I/O Target

Complete

Page 116: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

I/O Request ObjectI/O Request Object

I/O Queue

Driver

I/O Target

Complete

Request

Page 117: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

I/O Request ObjectI/O Request Object

Represents a requestSent to the driver by a client

An application or another UM driver

Generated by a driver

Types of Requests presented to driverCreate

Read / Write / DeviceIoControl

Cleanup

Close

Request Parameters can be obtained from IWDFIoRequest interface

Page 118: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

I/O QueuesI/O Queues

Page 119: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

I/O QueuesI/O Queues

I/O Queue

Driver

I/O Target

Complete

Request

Page 120: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

I/O QueuesI/O Queues

Queues provide flow control for I/O RequestsAll requests dispatched to driver through I/O Queues

Driver can configure I/O routing for a deviceCreate one or more queues for a device

Configure routing for a type of I/O to a particular queue

“Default queue” handles any remaining I/O types

Page 121: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

I/O Queue Dispatch TypesI/O Queue Dispatch Types

Dispatch Type controls how requests are presented to driver

Queues allow following modes of dispatching:Automatic: Queue presents requests via callbacks (Push Model)

Manual: Requests are retrieved by driver (Pull Model)

Dispatch type is set at Queue creation timeIt is a per-Queue property

Page 122: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Automatic DispatchAutomatic Dispatch

Queue presents request through driver implemented callback interfaces

IQueueCallbackCreateClose

IQueueCallback[Read | Write | DeviceIoControl]

Automatic Dispatch TypesSequential: allows at most one outstanding request at a time

New Request not presented until current request is completed

Parallel: allows multiple outstanding requestsNew Request can be presented even when previously presented requests are not completed

The number of parallel requests presented is boundedDriver should minimize blocking in presentation callbacks

Page 123: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Manual DispatchManual Dispatch

Driver pulls requests from the queueTypically starts in response to Queue callback IQueueCallbackStateChange

Empty to non-empty transition

Continues to pump I/O until “done”No more I/O, bookmark request retrieved, error, etc...

Starts again on next Queue state changeHRESULT RetrieveNextRequest(

OUT IWDFIoRequest** ppRequest

);

It is possible for driver to pull requests from an Automatic Queue

Page 124: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Callback ConstraintsCallback Constraints

Callback constraints specify locking model for Queue callbacks

Callback constraints optionsDevice Level: Callbacks invoked with device level lock held

None: Callbacks invoked with no lock held

Specified at device creation time via IWDFDeviceInitialize::SetLockingConstraint

Set before creating the WDF Device object

Per device property – applies to all queues

Page 125: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Callback Constraints (con’t)Callback Constraints (con’t)

Constraints apply only to Queue Callbacks

Queue callbacks includeAutomatic Dispatch Callbacks

Queue state change callback

Request cancellation callback

If Device Level locking is used:The above callbacks are synchronized

Request Completion is a not a Queue Callback – not synchronized

Unsynchronized code can call IWDFObject::AcquireLock

Call on object that matches your synchronization scope

Page 126: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Sequential Queue

Device Level Locking

Parallel Queue

Device Level Locking

Parallel Queue

No Locking

Dispatch Type vs. Locking ModelDispatch Type vs. Locking Model

Request1

Req1 Complete

Request2

Req2 Complete

Request1

Req1 Complete

Request2

Req2 Complete

Request1

Req1 Complete

Req2 Complete

Request2

Combining Dispatch Type and Locking Model provides several modes of operation

For example:

Page 127: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF OSR USB Sample Walk-throughUMDF OSR USB Sample Walk-through

Requests and Queue Usage in the sample driver (src\umdf\usb\driver)

Callback locking constraint used(CMyDevice::Initialize in Device.cpp)

Dispatch type used(CMyQueue::Initialize in Queue.cpp)

Queue callbacks used(CMyQueue in Queue.h and Queue.cpp)

Page 128: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

File ObjectsFile Objects

Page 129: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

File ObjectFile Object

File Object represents open connection to device

It is the session context for I/O

All requests associated with a File Object in UMDF

KMDF and WDM requests sometimes don’t have one

File object for a request obtained using IWDFIoRequest::GetFileObject

Trailing name used by client while opening connection is available via IWDFFile::GetFileName

Page 130: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

File Object (con’t)File Object (con’t)

Device

File1

Request1

Request2

File2

Request1

Request2

Page 131: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

File Object LifetimeFile Object Lifetime

File Object’s lifetime spansCreate: File Object gets created in response to a connection being opened

Cleanup: Notification of connection being torn down and that Close is pending

Close: All I/O pertaining to this File Object has now ceased. File Object is now disposed.

File Object is created and destroyed by the Framework

All I/O operations happen in the context of File object

i.e., they happen between Create and Close

These operations are: Read / Write / DeviceIoControl

Page 132: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

File Object Lifetime IllustratedFile Object Lifetime Illustrated

Close

Any remaining Requests drain

CleanupCloseHandle(hFile);

… …Read/Write/IoCtl RequestsAsync/Sync Read/Write/IoCtl

… …Create RequesthFile = CreateFile(…

DriverApplication

Example of I/O sequence between App and Driver

Page 133: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Cleanup Handling in DriverCleanup Handling in Driver

Cleanup received when client closes connectionNotification for driver to flush I/O for File Object

Cancel or complete outstanding I/O as soon as possibleClose will not come until all I/O is finishedCleanup is a “critical” operation in UMDF

Cannot fail, subject to timeout

Cleanup is not the end of I/O operationsThat’s the Close RequestI/O received after a Cleanup should be cancelled/completed immediately

Page 134: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF OSR USB Sample Walk-throughUMDF OSR USB Sample Walk-through

File usage in the sample driver (src\umdf\usb\driver) (Queue.cpp)

CMyQueue::OnRead

CMyQueue::OnCreateFile

CMyQueue::OnCleanupFile

CMyQueue::OnCloseFile

Page 135: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Driver LayeringDriver Layering

Page 136: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Driver LayeringDriver Layering

UMDF supports driver layeringMultiple drivers build a device stack

“Function” driver provides core device behavior

“Filter” drivers modify aspects of device behavior

Filter is a property set at device creation time

All Framework Objects are per layerEach layer works only with its own objects

e.g., each layer gets a Request object to complete

Driver sends request to next layer using I/O Target

Represents the next driver in the stack

That driver may be in user mode or kernel mode

Page 137: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Driver Layering DiagramDriver Layering Diagram

Device Queue File Request

Device Queue File Request

Device Queue File Request

Device Stack

Framework

Framework

Framework

Page 138: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Request CompletionRequest Completion

When Driver receives a Request it canComplete the Request synchronously

Forward it to an I/O Target or an I/O Queue

Hold on to it to complete later

Driver must complete a Request it receivese.g., while forwarding request to I/O Target

Driver must register request-completion-callback object

Framework invokes callback when target completes request

Callback must complete request or arrange for completion

UM IRP not complete until all layers complete their Request objects

Completion callback is not a device level eventRuns outside driver’s callback locking constraints

Page 139: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Request Completion IllustratedRequest Completion Illustrated

Request Completion Routine

Request Completion Routine

Request

Page 140: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

I/O TargetI/O Target

Page 141: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

I/O TargetI/O Target

I/O Queue

Driver

I/O Target

Complete

Request

Page 142: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

I/O Target Framework ObjectI/O Target Framework Object

Provides a way to send requests to another device

Local I/O Target represents:The next device in the stack

Another UM Driver, or the KM portion of the stack

Driver doesn’t need to care which it is

Remote I/O Target representsSome other UM or KM device stack

Need feedback to prioritize this for Longhorn

I/O Target is responsible forSending I/O request to lower device

Detecting completion and invoking callback interface

Page 143: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Device Stack

I/O Target

I/O Target

I/O Target

Device

Device

Device

Local I/O TargetLocal I/O Target

User Mode

Kernel Mode

Device

Device

Down Device

Application

ReflectorUp Device

Page 144: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

I/O Target FunctionalityI/O Target Functionality

State based I/O handlingDriver can start and stop the I/O target

In Response to a PnP Transition

For any driver specific reason (e.g., reconfigure after reset)

Supports two I/O modes:Synchronous for short-term operations

Asynchronous with callback for long-term operations

Supports request timeoutOutstanding request is cancelled when timeout expires

Tracks sent requests for the driverAllows automatic purge or flush on I/O target stop

Coordinates completion and cancellation

Page 145: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Bridging UM and KM stacksBridging UM and KM stacks

I/O Target provides bridge between KM and UM driversBottom-most I/O Target sends requests to kernel-mode stack

Driver could also “escape” to the Platform APISend I/O using Win32 File I/O API directly

Advantages of using I/O TargetHandles complexity of coordinating completion, cancellation and cleanup

Allows for filtering and layered stacks transparently

Allows routing of request to kernel mode in mode neutral way

Offers rich functionality

In Beta 1Bottom-most I/O Target uses Win32 File I/O API internally

No way to use specific API (e.g., WinUSB)Makes the escape necessary in such cases

Page 146: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF OSR USB Sample Walk-throughUMDF OSR USB Sample Walk-through

I/O Target usage in the sample filter (src\umdf\usb\filter)

Obtaining default I/O Target(CMyQueue::Initialize in Queue.cpp)

Forwarding request down the stack(CMyQueue::OnWrite in Queue.cpp)

(CMyQueue::ForwardRequest in Queue.cpp)

Page 147: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Request CancellationRequest Cancellation

Page 148: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Request CancellationRequest Cancellation

Application can cancel a request at any time byUsing CancelIo[Ex] API

Exiting application, etc.

Higher layer driver can cancel sent requests

Cancel tells driver to complete request soonBut not necessarily immediately

Driver should abort any long operationsShort synchronous requests can just be allowed to complete normally

Cancel is a critical operationCannot be failed, subject to timeout, etc…

Cancellation is part of good user experience

Page 149: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Cancellation OverviewCancellation Overview

Request Owner can register a cancel callback

Cancel callback follows locking constraints

On Cancel:Request’s internal state is marked as cancelled

Any callback registered after this will run immediately

Registered cancel callback is cleared then invoked

In the cancellation callbackOwner arranges to cancel and complete request

Remove callback before transferring ownershipe.g., when forwarding or completing the Request

Page 150: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Request OwnershipRequest Ownership

Request ownership starts with I/O Queue

Request ownership moves from:Queue to Driver – Driver receives the Request

Driver to Queue – Driver forwards Request to Queue

Driver to I/O Target – Driver forwards Request to I/O Target

Queue or I/O Target handle cancellation when they own request

I/O Target notifies you through completion callback

Driver must handle cancel when it owns requestIf it holds on to the request for a long time

Page 151: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Cancellation Handling in DriverCancellation Handling in Driver

When driver receives a Request, it may:Complete it soon

Shortly send it to I/O Target

Queue it back to Framework I/O Queue

Hold on to it (not using Framework I/O Queue)

Do (potentially) lengthy sync/asynch processing

Driver needs to handle cancellation only in the last two cases

Page 152: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Cancellation Handling in Driver (con’t)Cancellation Handling in Driver (con’t)

Driver may register a cancel notification callbackvoid IWDFIoRequest::MarkCancelable(

IRequestCallbackCancel* pCancelCallback

);

In callback it should cancel/complete the requestAs soon as possible

Unregister callback when transferring ownershipBefore sending request to I/O target or completing it

HRESULT IWdfIoRequest::UnmarkCancelable();

Failure return value indicates request has been canceledCancel routine has run or will run soon

Owner must ensure Request is completed only once

Page 153: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Cancellation IllustratedCancellation IllustratedLet us take the example of OSR USB Driver

This driver uses device level locking

It submits I/O requests to WinUSB

The internal completion routine manually uses device level lock

Request state is stored in Request context

There are the following possibilities:1. Request completes without cancellation

2. Request is cancelled2a. Cancel callback runs before completion callback

2b. Cancel callback runs after completion callback

The driver makes sure that:Request is completed only once

Request is not completed until both completion and cancellation callback are done with it

Page 154: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

OnRead*OnRead*

ctx->state = RequestCompleted;

DeviceLock->ReleaseLock();

}

Cancellation Illustrated (1)Cancellation Illustrated (1)

WinUSB_ReadPipe

Req->MarkCancelable

… …

OnUSBReadComplete

}

else {

DeviceLock->ReleaseLock();

CompleteRequest

}

if (ctx->state == CancelInvoked) {else {

DeviceLock->ReleaseLock();

CompleteRequest

}

if (Req->UnmarkCancelable()) {

DeviceLock->AcquireLock();

OnCancel*

if (ctx->state == RequestCompleted) {

CompleteRequest

}

else {

CancelIoEx

ctx->state = CancelInvoked;

}

OnUSBReadComplete

* Invoked under DeviceLock

Page 155: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

OnCancel*OnCancel*

OnRead*

}

Cancellation Illustrated (2a)Cancellation Illustrated (2a)

WinUSB_ReadPipe

Req->MarkCancelable

… …

OnUSBReadComplete

if (Req->UnmarkCancelable()) {

DeviceLock->AcquireLock();

}

ctx->state = CancelInvoked;

CancelIoEx

else {

}

CompleteRequest

if (ctx->state == RequestCompleted) {

OnUSBReadComplete

ctx->state = RequestCompleted;

DeviceLock->ReleaseLock();

}

DeviceLock->ReleaseLock();

CompleteRequest

}

if (ctx->state == CancelInvoked) {else {

DeviceLock->ReleaseLock();

CompleteRequest

}

else {

* Invoked under DeviceLock

Page 156: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

OnCancel*OnCancel*

}

Cancellation Illustrated (2b)Cancellation Illustrated (2b)

WinUSB_ReadPipe

Req->MarkCancelable

OnRead*

OnUSBReadComplete

if (Req->UnmarkCancelable()) {

DeviceLock->AcquireLock();

}

ctx->state = CancelInvoked;

CancelIoEx

else {

}

CompleteRequest

if (ctx->state == RequestCompleted) {

OnUSBReadComplete

ctx->state = RequestCompleted;

DeviceLock->ReleaseLock();

}

DeviceLock->ReleaseLock();

CompleteRequest

}

if (ctx->state == CancelInvoked) {else {

DeviceLock->ReleaseLock();

CompleteRequest

}

else {

* Invoked under DeviceLock

Page 157: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

UMDF OSR USB Sample Walk-throughUMDF OSR USB Sample Walk-through

Cancellation walk-through in the sample driver (src\umdf\usb\driver) (Queue.cpp)

CMyQueue::OnRead

CMyQueue::OnCancel

CMyQueue::CompletionThread

Page 158: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Putting It TogetherPutting It Together

You’ve seen the following portions of the sample:Driver (Driver.cpp)

CMyDriver::OnDeviceAdd

Device (Device.cpp)CMyDevice::OnPrepareHardware

CMyDevice::OnReleaseHardware

Queue (Queue.cpp)CMyQueue::OnCreateFile

CMyQueue::OnCleanupFile

CMyQueue::OnRead / CQueue::OnWrite

CMyQueue::OnCancel

CMyQueue::CompletionThread

Page 159: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Call to ActionCall to Action

Install the Windows Driver Kit

Join the WDF Beta ProgramAt http://beta.microsoft.com

Guest ID: Guest4WDF

Evaluate UMDF for your driver projectsConsider development time, customer support for system crashes, etc.

Send Us Feedback – We want to knowIf UMDF will meet your needs

What stops you from writing your drivers with UMDF

Page 160: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

Additional ResourcesAdditional Resources

Emailumdffdbk @ microsoft.com

Web Resources:WDF Information:

http://www.microsoft.com/whdc/driver/wdf/default.mspx

Windows Debugger:http://www.microsoft.com/whdc/devtools/debugging/default.mspx

External Resources“Introduction to the Windows Driver Foundation: How To Develop Device Drivers Using the Kernel Mode Driver Framework” from OSR Press

Release date is September 2005Focuses on KMDF but provides general WDF information as well

Page 161: How to Develop a UMDF Driver Part 1. Outline Architectural Goals Architectural Description Core components Driver Manager, Reflector, Host Process, and

© 2005 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.