I'm trying to rewrite my driver to the OOP architecture and I'm faced with the problem of calling a method like callback when I don't have any std::XXXX, as well as when arguments to the function itself are passed by a template.
So I have the following class:
class Log {
public:
/*static*/ VOID LogNotifyUsermodeCallback(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
NTSTATUS LogRegisterIrpBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS LogRegisterEventBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp);
};
Also I have the following code:
NTSTATUS Log::LogRegisterIrpBasedNotification(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
//Some line of code....
KeInitializeDpc(&NotifyRecord->Dpc, // Dpc
LogNotifyUsermodeCallback, // DeferredRoutine
NotifyRecord // DeferredContext
);
//Some line of code....
}
DeferredRoutine has the following pattern of calling arguments:
VOID Log::LogNotifyUsermodeCallback(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
I can't call the LogNotifyUsermodeCallback method as static, because arguments are passed there by template, and other methods of the Log class are also called in this method itself, and I don't have other ideas. So, the main question is: how, under all these conditions, can I call LogNotifyUsermodeCallback as a callback method?
As I said earlier, arguments are passed to my function by windows itself => I can't let my arguments go there, since they will violate the order of the arguments being passed.
My solution:
I'm creating a C callback + global variable.
namespace Cwrapper {
Log* GLogPtr = nullptr;
void Callback(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
{
if (GLogPtr) { return GLogPtr->LogNotifyUsermodeCallback(Dpc, DeferredContext, SystemArgument1, SystemArgument2); }
}
};
Next, I pass the this pointer to my specific class to GLogPtr
Cwrapper::GLogPtr = this;
KeInitializeDpc(&NotifyRecord->Dpc, // Dpc
Cwrapper::Callback, // DeferredRoutine
NotifyRecord // DeferredContext
);
From the information I have read, this method is also called a "trampoline"
Some information: https://web.archive.org/web/20230822094216/https://codeyarns.com/tech/2015-09-01-how-to-register-class-method-as-c-callback.html