ACX WDF driver lifetime management

This topic provides a summary of the ACX WDF driver lifetime management and proper memory cleanup. For a general overview of ACX, see ACX audio class extensions overview.

ACX WDF initialization and startup

Proper ACX initialization, needs to occur, to allow proper clean up of ACX, WDF and memory resources. More detail on the major phases of device enumeration summarized here, is available in ACX device enumeration.

  • WDM Driver Entry
  • WDF Device Add
  • WDF Prepare Hardware
  • WDF Device D0 Entry
  • ACX Circuit Creation Process (ACX Pins and Jacks objects are associated with the Circuit)
  • ACX Stream Creation Process

ACX WDF object cleanup

This topic describes the clean up of ACX WDF objects in this order.

  • ACX Stream Close Process
  • ACX Circuit Removal Process
  • WDF Device Release Hardware
  • WDF Driver Unload

There are multiple valid approaches to creating and cleaning up WDF and ACX objects, this topic covers some key elements of managing the lifetime of ACX/WDF objects.

PnP Power events and object destruction

PnP Power events can cause object creation and destruction. For more information on PnP power events, see ACX power management and WDF PnP and Power Management Callback Sequences.

WDF object reference lifetime management

WDF uses reference counts to help track the lifetime of objects. It may be appropriate in a cleanup call back function, to dereference object references. The framework call this cleanup call back function, so that the driver can call WdfObjectDereference if it had previously called WdfObjectReference for the object that is being deleted. For more information, see WdfObjectReference and WdfObjectDereference.

Surface Team driver development best practices

For a description of common mistakes that are made in driver code with memory and object lifetime management, see those sections in Surface Team driver development best practices.

ACX Stream Close Process

When the client closes the stream, the driver needs to work to close and clean up the resources that were associated with the stream. For more details, see ACX Streaming - Stream close process. It is important that the driver does not clean up resources that support the stream, and that the clean up process be aware of impacts on the client.

ACX Circuit Removal Process

ACX can create a dynamic circuit on demand. To do this, the driver allocates a WDFDEVICE_INIT structure by calling WdfPdoInitAllocate. The driver then specifies any PnP/power callbacks it wants to receive and creates the device. The driver invokes AcxDeviceRemoveCircuitDevice to remove the audio device from the device list.

For more information, see ACX circuit dynamic removal in ACX Circuits.

WDF Device Release Hardware

The EVT_WDF_DEVICE_RELEASE_HARDWARE callback function is used to in a driver's EvtDeviceReleaseHardware event callback function to perform operations that are needed when a device is no longer accessible.

WDF Device Context Cleanup

This code from the AudioCodec sample shows use of an WDF_OBJECT_ATTRIBUTES structure to set a EvtCleanupCallback.

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CODEC_DEVICE_CONTEXT);
    attributes.EvtCleanupCallback = Codec_EvtDeviceContextCleanup;

This example callback given a WdfDevice cleans up device context.

VOID
Codec_EvtDeviceContextCleanup(
    _In_ WDFOBJECT      WdfDevice
)

{
    WDFDEVICE               device;
    PCODEC_DEVICE_CONTEXT   devCtx;

    device = (WDFDEVICE)WdfDevice;
    devCtx = GetCodecDeviceContext(device);
    ASSERT(devCtx != nullptr);

    if (devCtx->Capture)
    {
        CodecC_CircuitCleanup(devCtx->Capture);
    }
}

WDF Driver Unload

When the driver is unloaded, it should release all remaining resources. For more information, see Releasing Driver-Allocated Resources.

A driver registers an EvtDriverUnload callback function when it calls WdfDriverCreate. The EvtDriverUnload callback function must deallocate any non-device-specific system resources that the driver's DriverEntry routine allocated. For more information, see EVT_WDF_DRIVER_UNLOAD callback function.

This code from the AudioCodec sample shows the structure of a driver unload callback.

EVT_WDF_DRIVER_UNLOAD               AudioCodecDriverUnload;

void AudioCodecDriverUnload(
    _In_ WDFDRIVER Driver
)
{
    PAGED_CODE();

    if (!Driver)
    {
        ASSERT(FALSE);
        return;
    }

    WPP_CLEANUP(WdfDriverWdmGetDriverObject(Driver));

// Here is where you would cleanup any allocated resources associated with the driver.

    return;
}

See also

ACX device enumeration

ACX power management

PnP and Power Management Callback Sequences

Summary of ACX objects

ACX audio class extensions overview

ACX reference documentation