KMDF Rules for SDV


KMDF rules for SDV are divided into the following categories, as described in the following sections:

This rule category

Analyzes these types of DDI functions

DDI order rules

Dependent DDI functions

Device initialization rules

Device object initialization DDI functions

Control device cleanup rules

DDI functions for creation and disposal of device objects

Request-completion rules

Queue and request object DDI functions

Request-cancellation rules

Request object DDI functions

Request buffer, MDL, and memory rules

Request object memory access DDI functions

Power policy owner rules

DDI functions for drivers that are power policy owners

 Note  This is preview information to introduce KMDF rules. See the WDK documentation for comprehensive documentation of KMDF rules for SDV.

DDI Order Rules for KMDF

These rules specify that certain DDI functions must be called before other dependent DDI functions. For example, the FileObjectConfigured rule specifies that a file object is cnfigured in the driver by calling WdfDeviceInitSetFileObjectConfig before calling WdfRequestGetFileObject for the same file object.

  • DriverCreate Rule

    Specifies that a KMDF driver calls WdfDriverCreate from within its DriverEntry function.

  • FileObjectConfigured Rule

    Specifies that a call to WdfRequestGetFileObject is preceded by a call to WdfDeviceInitSetFileObjectConfig.

  • CtlDeviceFinishInitDeviceAdd Rule

    Specifies, for a Plug and Play driver, that if the driver creates a control device object in an EvtDriverDeviceAdd callback function, it must call WdfControlFinishInitializing after the control device object has been created and before exiting from EvtDriverDeviceAdd. This rule does not apply for non-Plug and Play drivers.

  • CtlDeviceFinishInitDrEntry Rule

    Specifies, for a Plug and Play driver, that if the driver creates a control device object in the DriverEntry function, it must call WdfControlFinishInitializing after the control device object has been created and before exiting from DriverEntry. This rule does not apply for non-Plug and Play drivers.

Device Initialization Rules for KMDF

In general, these rules check that DDI functions for device object initialization are always called before the device object is created. For example, the DeviceInitAllocate rule specifies that, for either a PDO or a control device object, the WdfPdoInitAllocate or WdfControlDeviceInitAllocate framework device object initialization method must be called before the driver calls WdfDeviceCreate for the PDO or control device object.

  • DeviceInitAllocate Rule

    Specifies, for a PDO or a control device object, that the WdfPdoDeviceInitAllocate or WdfControlDeviceInitAllocate framework device object initialization method must be called before the driver calls WdfDeviceCreate.

  • DeviceInitAPI Rule

    Specifies, for an FDO, that the WdfDeviceInitXxx and the WdfFdoInitXxx framework FDO initialization methods must be called before the driver calls the WdfDeviceCreate method for the device object.

  • ControlDeviceInitAPI Rule

    Specifies, for a control device object, that the WdfDeviceInitXxx and WdfControlDeviceInitSetShutdownNotification framework device object initialization methods must be called before the driver calls WdfDeviceCreate.

  • PdoDeviceInitAPI Rule

    Specifies, for a PDO, that the WdfDeviceInitXxx framework device object initialization methods and the WdfPdoInitXxx framework PDO initialization methods must be called before the driver calls WdfDeviceCreate.

Control Device Cleanup Rules for KMDF

These rules specify that the control device object that the driver created is properly disposed of at a correct point. For example, the ControlDeviceDeleted rule specifies that any Plug and Play driver that creates a control device object must delete the control device object before the driver unloads, within one of the cleanup callback functions for the device.

  • Cleanup4CtlDeviceRegistered Rule

    Specifies that if a Plug and Play driver creates a control device object, it must register either the EvtCleanupCallback or the EvtDestroyCallback function in the WDF_OBJECT_ATTRIBUTES structure for the control device object or register the EvtDeviceSelfManagedIoCleanup callback in the WDF_PNPPOWER_EVENT_CALLBACKS structure.

  • ControlDeviceDeleted Rule

    Specifies that, if a Plug and Play driver creates a control device object, the driver must delete the control device object in one of the cleanup callback functions before the driver unloads.

Request-Completion Rules for KMDF

These rules specify that each request presented to the driver in one of the default queue callbacks (EvTimerFunc, EvtDpcFunc, EvtInterruptDpc, EvtInterruptEnable, EvtInterruptDisable, EvtWorkItem) must be completed only once. For example, the DeferredRequestCompleted rule specifies that if a request is not completed in a default queue callback function but is deferred for later processing, the request must be completed in a deferred processing callback, unless the request is forwarded and delivered to the framework or if WdfRequestStopAcknowledge is called.

  • DoubleCompletion Rule

    Specifies that drivers do not complete a request twice.

  • DoubleCompletionLocal Rule

    Specifies that drivers do not complete a request twice. This is the same rule as the DoubleCompletion rule except that the check is performed only within the default I/O queue request handlers, for the sake of optimization.

  • RequestCompleted Rule

    Specifies that each request presented to the driver's default I/O queue must be completed unless the driver defers or forwards the request or calls WdfRequestStopAcknowledge for the request. This rule gives a Not Applicable result for drivers that do not register for any of the following:

    • Any relevant cleanup or destroy callback functions for the device object, queue object, or file object.

    • Plug and Play and power callback functions such as EvtDeviceSelfManagedIoCleanup or EvtDeviceShutdownNotification.

    • The EvtDriverUnload callback.

  • RequestCompletedLocal Rule

    Warns of a possible defect if a request is not completed in any of the default I/O queue callback functions and if the request is not marked as "cancelable" in those functions. This rule is intended only for drivers for which the RequestCompleted rule is Not Applicable.

  • DeferredRequestCompleted Rule

    Specifies that if a request presented to a driver's default I/O queue callback function is not completed in the callback function but is deferred for later processing, the request must be completed in a deferred processing callback function, unless the request is forwarded and delivered to the framework or if the WdfRequestStopAcknowledge method was called.

Request-Cancellation Rules for KMDF

These rules specify the correct coding pattern for canceling a request that was presented to the driver in one of the default I/O queue callback functions and marked as Cancelable by WdfRequestMarkCancelable. For example, the ReqNotCanceled rule specifies that if a driver marked a request Cancelable and then completed it in a deferred processing callback, then the driver must call WdfRequestUnmarkCancelable on the request before it completes the request and the request should be completed only if it was not already canceled.

  • ReqNotCanceled Rule

    Specifies that if a request marked as Cancelable is completed in a deferred processing callback, then WdfRequestUnmarkCancelable must be called on the request before the request is completed. The request should be completed only if it was not already canceled.

  • ReqNotCanceledLocal Rule

    Specifies that if a request marked as Cancelable is completed in a default I/O queue callback function, then WdfRequestUnmarkCancelable must be called on the request before the request is completed and the request should be completed only if it was not already canceled. This rule differs from the ReqNotCanceled rule in that it specifies the check within default I/O queue request handlers.

  • ReqIsNotCancelable Rule

    Specifies that only cancelable deferred requests are made noncancelable before completion. In other words, if the driver calls WdfRequestUnmarkCancelable on a request, the driver must previously have called of WdfRequestMarkCancelable on the request.

  • MarkCancOnCancReq Rule

    Specifies that WdfRequestMarkCancelable cannot be called twice consecutively on the same request.

  • MarkCancOnCancReqLocal Rule

    Specifies that WdfRequestMarkCancelable cannot be called twice consecutively on the same request. This rule specifies the check only within default I/O queue callback functions.

  • ReqIsCancOnCancReq Rule

    Specifies that WdfRequestIsCanceled can be called only on a request that has not been marked as cancelable.

Request Buffer, MDL, and Memory Rules

These rules specify that after a request is completed, its buffer, MDL, or memory object cannot be accessed. For example, the BufAfterReqCompletedRead rule specifies this check for the cases when the buffer is accessed from the EvtIoRead callback function.

 Note  For this set of KMDF rules, SDV considers 14 DDI functions as possible buffer access functions, 15 DDI functions as possible MDL access functions, and 10 DDI functions as possible memory access functions. In addition to those listed in this example, the BufAfterReqCompletedReadA rule specifies the check for 10 other DDI functions that access the buffer.

  • InputBufferAPI Rule

    Specifies that correct DDI functions for buffer or MDL or memory object retrieval are used in the EvtIoRead function. Specifically, these DDI functions cannot be called in this case: WdfRequestRetrieveInputBuffer, WdfRequestRetrieveUnsafeUserInputBuffer, WdfRequestRetrieveInputWdmMdl, and WdfRequestRetrieveInputMemory.

  • OutputBufferAPI Rule

    Specifies that correct DDI functions for buffer or MDL or memory object retrieval are used in the EvtIoWrite function. Specifically, these DDI functions cannot be called in this case: WdfRequestRetrieveOutputBuffer, WdfRequestRetrieveUnsafeUserOutputBuffer, WdfRequestRetrieveOutputWdmMdl, and WdfRequestRetrieveOutputMemory.

Request Buffer Rules

  • BufAfterReqCompletedRead and BufAfterReqCompletedReadA Rules

    Specify that, within the EvtIoRead function, the buffer cannot be accessed after the request is completed. The buffer is retrieved by calling WdfRequestRetrieveOutputBuffer or WdfRequestRetrieveUnsafeUserOutputBuffer.

  • BufAfterReqCompletedWrite and BufAfterReqCompletedWriteA Rules

    Specify that, within the EvtIoWrite function, the buffer cannot be accessed after the request is completed. The buffer is retrieved by calling WdfRequestRetrieveInputBuffer or WdfRequestRetrieveUnsafeUserInputBuffer.

  • BufAfterReqCompletedIoctl and BufAfterReqCompletedIoctlA Rules

    Specify that, within the EvtIoDeviceControl function, the buffer cannot be accessed after the request is completed. The buffer is retrieved by calling WdfRequestRetrieveOutputBuffer, WdfRequestRetrieveUnsafeUserOutputBuffer, WdfRequestRetrieveInputBuffer, or WdfRequestRetrieveUnsafeUserInputBuffer.

  • BufAfterReqCompletedIntIoctl and BufAfterReqCompletedIntIoctlA Rules

    Specify that, within the EvtIoInternalDeviceControl function, the buffer cannot be accessed after the request is completed. The buffer is retrieved by calling WdfRequestRetrieveOutputBuffer, WdfRequestRetrieveUnsafeUserOutputBuffer, WdfRequestRetrieveInputBuffer, or WdfRequestRetrieveUnsafeUserInputBuffer.

Request MDL Rules

  • MdlAfterReqCompletedRead and MdlAfterReqCompletedReadA Rules

    Specify that, within the EvtIoRead function, the MDL object cannot be accessed after the request is completed. The MDL is retrieved by calling WdfRequestRetrieveOutputWdmMdl.

  • MdlAfterReqCompletedWrite and MdlAfterReqCompletedWriteA Rules

    Specify that, within the EvtIoWrite request handler, the MDL object cannot be accessed after the request is completed. The MDL is retrieved by calling WdfRequestRetrieveInputWdmMdl.

  • MdlAfterReqCompletedIoctl and MdlAfterReqCompletedIoctlA Rules

    Specify that, within the EvtIoDeviceControl request handler, the MDL cannot be accessed after the request is completed. The MDL is retrieved by calling WdfRequestRetrieveInputWdmMdl or WdfRequestRetrieveOutputWdmMdl.

  • MdlAfterReqCompletedIntIoctl and MdlAfterReqCompletedIntIoctlA Rules

    Specify that, within the EvtIoInternalDeviceControl request handler, the MDL cannot be accessed after the request is completed. The MDL is retrieved by calling WdfRequestRetrieveInputWdmMdl or WdfRequestRetrieveOutputWdmMdl.

Request Memory Rules

  • MemAfterReqCompletedRead and MemAfterReqCompletedReadA Rules

    Specify that, within the EvtIoRead request handler, the memory object cannot be accessed after the request is completed. The memory object is retrieved by calling WdfRequestRetrieveOutputMemory.

  • MemAfterReqCompletedWrite and MemAfterReqCompletedWriteA Rules

    Specify that, within the EvtIoWrite request handler, the memory object cannot be accessed after the request is completed. The memory object is retrieved by calling WdfRequestRetrieveInputMemory.

  • MemAfterReqCompletedIoctl and MemAfterReqCompletedIoctlA Rules

    Specify that, within the EvtIoDeviceControl request handler, the memory object cannot be accessed after the request is completed. The memory object is retrieved by calling WdfRequestRetrieveInputMemory or WdfRequestRetrieveOutputMemory.

  • MemAfterReqCompletedIntIoctl and MemAfterReqCompletedIntIoctlA Rules

    Specify that, within the EvtIoInternalDeviceControl request handler, the memory object cannot be accessed after the request is completed. The memory object is retrieved by calling WdfRequestRetrieveInputMemory or WdfRequestRetrieveOutputMemory.

Power Policy Owner DDI Rules

These rules specify that a driver that is not a power policy owner cannot call the following three power management DDI functions: WdfDeviceInitSetPowerPolicyEventCallbacks, WdfDeviceAssignS0IdleSettings, and WdfDeviceAssignSxWakeSettings.

For example, the NonPnPDrvPowerPolicyOwner rule specifies that a non-Plug and Play driver cannot call these three DDI functions.

This set of rules includes two precondition rules: FDODriver and NotPowerPolicyOwner. Table 24-1 shows the rules that depend on the precondition rules, plus the precondition rule results that determine whether the dependent rule applies to a driver. If a rule depends on more than one precondition, both results should be present for the rule to apply for the driver.

Table 24-1: Precondition Rules for PowerPolicyOwner Rules
Open table as spreadsheet

PowerPolicyOwner rules

Precondition rules

 

FDODriver

NotPowerPolicyOwner

NonFDONotPowerPolicyOwnerAPI

Fail

Pass

FDOPowerPolicyOwnerAPI

Pass

Not a precondition

  • FDODriver (Precondition) Rule

    Specifies which driver is a function driver: if the driver calls WdfFdoInitSetFilter before returning from its EvtDriverDeviceAdd callback, the driver is not a function driver-in fact, it's a filter driver. If the rule presents a Pass result, the driver is a function driver; if the rule presents a Fail result or a Not Applicable result, the driver is not a function driver. For example, this rule presents a Not Applicable result for any non-Plug and Play driver- that is, any driver that does not provide an EvtDriverDeviceAdd callback.

    This is a precondition rule for the NonFDONotPowerPolicyOwnerAPI and FDOPowerPolicyOwnerAPI rules. Any "defect" identified by the rule actually indicates that the NonFDONotPowerPolicyOwnerAPI rule applies to the driver; any Pass result identified by the rule actually indicates that the FDOPowerPolicyOwnerAPI rule applies to the driver.

  • NotPowerPolicyOwner (Precondition) Rule

    Specifies which driver is considered a power policy owner. That is:

    • If EvtDriverDeviceAdd is called but WdfFdoInitSetFilter is not, then the driver is a function driver and therefore is the power policy owner.

    • If the driver calls WdfPdoInitAssignRawDevice, then it is a raw PDO driver and therefore is the power policy owner.

    If the driver is not a power policy owner, this rule passes.

    If the driver is a power policy owner, SDV reports a Fail result or the rule is Not Appicable.

    This rule is a precondition for the NonFDONotPowerPolicyOwnerAPI rule. Any Fail result that this rule identifies actually indicates that the NonFDONotPowerPolicyOwnerAPI rule applies to the driver.

  • NonFDONotPowerPolicyOwnerAPI Rule

    Specifies that if a non-FDO driver is not a power policy owner, then the three power management-related DDI functions cannot be called. For this rule to apply, the following two preconditions must be met:

    • The FDODriver rule should produce a Fail result.

    • The NotPowerPolicyOwner rule should produce a Pass result.

  • NonPnPDrvPowerPolicyOwnerAPI Rule

    Specifies that a non-Plug and Play driver cannot call the three power management-related DDI functions. For Plug and Play drivers and non-Plug and Play drivers that have no defect, this rule gives a Not Applicable result.

  • FDOPowerPolicyOwnerAPI Rule

    Warns if an FDO driver relinquishes power policy ownership and the driver calls the three power management-related DDI functions because these DDI functions can be called only on those execution paths for which the driver is a power policy owner. For this rule to apply, a precondition must be met: the FDODriver rule should "pass."

image from book
Rule Hierarchies and Preconditions-Solving the Problem of Complicated Rules

When I started working on the project in 2004, KMDF was still in the development phase and SDV was already being used for WDM drivers. I saw the advantage of the new framework, because it introduced a higher level of abstraction that would allow driver writers to save on routine coding and concentrate more on device-specific issues. This not only reduces the size of the driver but also makes it easier to debug it. At the same time, KMDF imposes quite non-trivial DDI usage rules. It was clear that some way of automatically checking a KMDF driver against DDI usage rules would be very valuable for driver writers in helping them to adopt the new framework.

SDV is very good at checking rules for DDI usage, as the experience of applying it to WDM drivers demonstrated. This was the motivation for me to develop SDV rules for KMDF. Writing SDV rules for KMDF presented challenges and required further development of SDV rule-writing techniques.

Because of the higher level of KMDF DDI functions (as compared to WDM), many KMDF rules turned out to be more complex than the majority of the rules for WDM. In KMDF rules, it is common that more DDI functions are involved in a single rule and that more complicated dependencies between them need to be expressed. On the other hand, for performance purposes, it is highly desirable to make each rule as simple as possible. This was solved by splitting a complicated rule into several simpler rules, which is in essence the task of splitting a state machine into a set of simpler state machines. Additionally, some rules are applicable only for drivers with specific properties. This was solved by introducing rule hierarchy and precondition rules-a new idea for SDV.

This project gave me a unique opportunity to work with two great teams-the KMDF team and the SDV team-and to participate in the development of new state-of-the-art technology for driver development.
-Ella Bounimova, Static Analysis Tools for Drivers, Microsoft

image from book




Developing Drivers with the Microsoft Windows Driver Foundation
Developing Drivers with the Windows Driver Foundation (Pro Developer)
ISBN: 0735623740
EAN: 2147483647
Year: 2007
Pages: 224

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net