Hi,
My driver filter registry calls for specific process. Problem is that CmUnRegisterCallback don’t call cleanup callbacks for object context so my driver leak resources.
Thanks for your help.
NTSTATUS
DriverEntry (
In PDRIVER_OBJECT DriverObject,
In PUNICODE_STRING RegistryPath
)
{
// other initialization routines
…
//
CmRegisterCallbackEx(EsuregCallback,
&RegistryAltitude,
EsuData.DriverObject,
NULL,
&RegistryCookie,
NULL);
}
NTSTATUS
EsuregCallback(
In PVOID CallbackContext,
In_opt PVOID Argument1,
In_opt PVOID Argument2
)
{
NTSTATUS status = STATUS_SUCCESS;
REG_NOTIFY_CLASS notifyClass;
UNREFERENCED_PARAMETER(CallbackContext);
notifyClass = (REG_NOTIFY_CLASS)(ULONG_PTR)Argument1;
switch(notifyClass) {
case RegNtPreOpenKeyEx:
status = EsuregPreOpenKeyEx( (PREG_OPEN_KEY_INFORMATION) Argument2);
break;
case RegNtPostOpenKeyEx:
status = EsuregPostOpenKeyEx((PREG_POST_OPERATION_INFORMATION) Argument2);
break;
default:
break;
}
return status;
}
NTSTATUS
EsuregPreOpenKeyEx(
In PREG_OPEN_KEY_INFORMATION PreOpenInfo
)
{
PESU_REGISTRY_CONTEXT regContext = NULL;
// my context structure
regContext = ExAllocatePoolWithTag(PagedPool, sizeof(ESU_REGISTRY_CONTEXT), ESU_REG_CONTEXT_TAG);
PreOpenInfo->CallContext = regContext;
return STATUS_SUCCESS;
}
NTSTATUS
EsuregPostOpenKeyEx(
In PREG_POST_OPERATION_INFORMATION PostOpenInfo
)
{
NTSTATUS status = STATUS_SUCCESS;
if (PostOpenInfo->CallContext != NULL) {
if (PostOpenInfo->Status == STATUS_SUCCESS) {
status = CmSetCallbackObjectContext(
PostOpenInfo->Object,
&RegistryCookie,
PostOpenInfo->CallContext,
NULL);
if (!NT_SUCCESS(status)) {
ExFreePoolWithTag(PostOpenInfo->CallContext, ESU_REG_CONTEXT_TAG);
}
else {
InterlockedIncrement(&callbackCounts); // 0 when driver loads
}
}
else {
ExFreePoolWithTag(PostOpenInfo->CallContext, ESU_REG_CONTEXT_TAG);
}
}
return status;
}
NTSTATUS
EsuregObjectContextCleanup(
In PREG_CALLBACK_CONTEXT_CLEANUP_INFORMATION RegCallbackContextCleanupInf
)
{
if (RegCallbackContextCleanupInf->ObjectContext != NULL) {
ExFreePoolWithTag(RegCallbackContextCleanupInf->ObjectContext, ESU_REG_CONTEXT_TAG);
}
InterlockedDecrement(&callbackCounts);
return STATUS_SUCCESS;
}
VOID
EsudrvPortDisconnect(
In_opt PVOID ConnectionCookie
)
{
UNREFERENCED_PARAMETER(ConnectionCookie);
// close client port and other details
…
//
// Unregister registry filter
if (NT_SUCCESS(CmUnRegisterCallback(RegistryCookie))) {
// callbackCounts = number of leaked context structures
DbgPrint(“Context Cleanup Callbacks %d \n”, callbackCounts );
}
}