Skip to content

WDF resource classes

Raymond Chen edited this page Aug 24, 2020 · 1 revision

WIL defines a number of classes specific to WDF resources. They are defined in wil/resource.h as part of the RAII resource wrappers library.

unique_wdf_any

The wil::unique_wdf_any<T> template class is a specialization of the unique_any template class for managing WDF objects that need to be deleted using WdfObjectDelete. wil::unique_wdf_any<T> can hold any WDF object T, but specializations are provided for common WDF object types, such as wil::unique_wdf_collection, wil::unique_wdf_memory, etc.

unique_wdf_spin_lock and unique_wdf_wait_lock

wil::unique_wdf_spin_lock and wil::unique_wdf_wait_lock provide additional methods:

  • A create(...) method that calls the appropriate construction function (WdfSpinLockCreate or WdfWaitLockCreate). The method optionally takes a WDF_OBJECT_ATTRIBUTES structure.
  • An acquire() method that acquires the lock and returns a RAII lock guard object that releases the lock when it goes out of scope. The lock guard objects are themselves unique_any objects with all the associated functionality.
  • wil::unique_wdf_wait_lock additionally has a try_acquire() method that returns immediately if the lock is already held (note that WDF wait locks cannot be acquired recursively).
wil::unique_wdf_wait_lock waitLock;
if (NT_SUCCESS(waitLock.create()))
{
    auto lockGuard = waitLock.acquire();
}

wil::wdf_spin_lock_release_scope_exit lockGuard;
wil::unique_wdf_spin_lock spinLock;
if (NT_SUCCESS(spinLock.create()))
{
    lockGuard = spinLock.acquire();
}

lockGuard.reset();

unique_wdf_object_reference

wil::unique_wdf_object_reference<T> is a unique_any specialization used to manage a WDF object reference that needs to be released using WdfObjectDereferenceWithTag. The macro WI_WdfObjectReferenceIncrement can be used to acquire a reference on a WDF object using WdfObjectReferenceActual and wrap it into a wil::unique_wdf_object_reference<T>, automatically deducing the type of the WDF object. The macro captures the source file and line number for use with the WDF tag tracker (if enabled). Alternatively, if the source file and line number information has already been captured from elsewhere, you may use wil::wdf_object_reference_increment directly.

WDFDRIVER driver = WdfGetDriver();

auto wdfObjectRef = WI_WdfObjectReferenceIncrement(driver, "Tag string");

// "Detach" the reference.
auto referenceAndTag = wdfObjectRef.release();

// "Attach" it to a new RAII object.
wil::unique_wdf_object_reference<WDFDRIVER> wdfObjectRef2{ referenceAndTag };

wdfObjectRef2.reset();