I have a USB driver that fetches and sends data to an audio hardware device. I also have a WDM audio driver based on the SimpleAudioSample example.
The USB driver creates a child, and the INF of the audio driver matches on the hardware id of the child. When the child is created I pass a WDF_OBJECT_ATTRIBUTES
to allocate some context space. I then allocate an object of type Foo
in the context space. When the audio driver is started I retrieve the context space, cast it to the AudioDriverPdoContext
struct and then call methods on the object allocated in the USB driver. I also pass object to the USB driver and callback into the audio driver from the USB driver.
The classes that are shared (in the example it’s IBar
, Bar
and Foo
) are built into a separate library, and I link to this library from both the USB and the audio driver. All object are deleted in the same driver that made the allocation.
I wonder if it is ok to share pointers to allocated objectes like this, and call back and fourth between two different drivers using pointer to the objects?
I have looked at using Driver Defined Intefaces, which takes care of versioning and provides a recognisable way of sharing interfaces between drivers, which is of course something good.
class IBar {
public:
virtual ~IBar() = default;
virtual void callback() = 0;
};
class Foo {
public:
void doThings() {
// ...
}
void doOtherThings(IBar* ptr) {
ptr->callback();
}
};
class Bar : public IBar {
public:
void callback() override {
// ...
}
};
struct AudioDriverPdoContext {
Foo* foo = nullptr;
};
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(AudioDriverPdoContext, getAudioDriverPdoContext)
When the child is created:
WDF_OBJECT_ATTRIBUTES pdoAttributes{};
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&pdoAttributes, AudioDriverPdoContext);
WDFDEVICE hChild = nullptr;
if (const auto status = WdfDeviceCreate(&DeviceInit, &pdoAttributes, &hChild);
!NT_SUCCESS(status)) {
return status;
}
// new is implemented to return non-pagable memory
getAudioDriverPdoContext(hChild)->foo = new Foo();
In the StartDevice
function of the WDM audio driver
auto bar = new Bar();
if (PDEVICE_OBJECT pdo = nullptr;
NT_SUCCESS(PcGetPhysicalDeviceObject(DeviceObject, &pdo)) && pdo) {
if (auto* const audioDriverPdoContext =
static_cast<AudioDriverPdoContext*>(pdo->DeviceExtension);) {
audioDriverPdoContext->doThings(); // Is this ok?
audioDriverPdoContext->doOtherThings(bar); // Is this ok?
}
}