The context structure was over-dereferenced

Hey , I’m working on a backup filter driver , my first time working with file contexts so I clearly do something wrong maybe you guys can help me identify it
Basically I want to have a context structure per-file (I filter “interesting” files to backup , doesnt matter tho ) that will not be per handle , so I will be able to tell if the file was ever backed up by the driver and if not back it on pre write.
The design mainly involves the post create routine:
check if file already has an allocated context , if not allocate it and init it
add a pointer to the context to a linked list of “contexts to release” on unload
for every get/set context I release it , the reason I think we need to release it once more on unload because docs suggest allocate = +1 on the refcount as well , and without it the filter hangs on unload

but… well, I get the BSOD suggested in the title with “context structure was over dereferenced” in unload when trying to release it , bit more info is " the context structure was dereferenced too many times, this means that the reference count on the Filter Manager’s CONTEXT_NODE structure went to 0 while it was still attached to its acossiated object"
any clear issues with my design ?

there’s the Post Create filter routine :
`FLT_POSTOP_CALLBACK_STATUS
BackupFilterPostCreate(
Inout PFLT_CALLBACK_DATA Data,
In PCFLT_RELATED_OBJECTS FltObjects,
In_opt PVOID CompletionContext,
In FLT_POST_OPERATION_FLAGS Flags
)

{
UNREFERENCED_PARAMETER(CompletionContext);
if (Flags & FLTFL_POST_OPERATION_DRAINING)
return FLT_POSTOP_FINISHED_PROCESSING;

const auto& params = Data->Iopb->Parameters.Create;
if (Data->RequestorMode == KernelMode
	|| (params.SecurityContext->DesiredAccess & FILE_WRITE_DATA) == 0
	|| Data->IoStatus.Information == FILE_DOES_NOT_EXIST) {
	// kernel caller, not write access or a new file - we do not care 
	return FLT_POSTOP_FINISHED_PROCESSING;
}

// get file name
FilterFileNameInformation fileNameInfo(Data);
if (!fileNameInfo) {
	return FLT_POSTOP_FINISHED_PROCESSING;
}

if (!NT_SUCCESS(fileNameInfo.Parse()))
	return FLT_POSTOP_FINISHED_PROCESSING;

if (!IsBackupDirectory(&fileNameInfo->ParentDir))
	return FLT_POSTOP_FINISHED_PROCESSING;

// if it's not the default stream, we don't care
if (fileNameInfo->Stream.Length > 0)
	return FLT_POSTOP_FINISHED_PROCESSING;

// if the file has a state already just return 
FileStateContext* CheckContext;   // if i change this to "FileStateContext CheckContext" clean unload, but the context is not useful and displaying blank info, which makes sense..
auto status = FltGetFileContext(FltObjects->Instance, FltObjects->FileObject, (PFLT_CONTEXT*)&CheckContext);
if (NT_SUCCESS(status)) {
	DbgPrint("[*] already allocated context for file :%wZ\n", CheckContext->FileName);
	FltReleaseContext((PFLT_CONTEXT)CheckContext);
	return FLT_POSTOP_FINISHED_PROCESSING;
}

// allocate and initialize a file context
FileStateContext* context;

 status = FltAllocateContext(FltObjects->Filter,
	FLT_FILE_CONTEXT, sizeof(FileStateContext), PagedPool,
	(PFLT_CONTEXT*)&context);
if (!NT_SUCCESS(status)) {
	DbgPrint("[*] failed to allocate file state context\n");
	return FLT_POSTOP_FINISHED_PROCESSING;
}
// for clean unload we need to keep track of those contexts as we dont release them on cleanup/close
SaveFileStateContextToDelete(context);
context->IsBacked = FALSE;
context->FileName.MaximumLength = fileNameInfo->Name.Length;
context->FileName.Buffer = (WCHAR*)ExAllocatePoolWithTag(PagedPool, fileNameInfo->Name.Length, TAG);
if (!context->FileName.Buffer) {
	FltReleaseContext(context);
	return FLT_POSTOP_FINISHED_PROCESSING;
}
RtlCopyUnicodeString(&context->FileName, &fileNameInfo->Name);
DbgPrint("[*] built context for file :%wZ\n", context->FileName);
context->Lock.Init();
status = FltSetFileContext(FltObjects->Instance,
	FltObjects->FileObject,
	FLT_SET_CONTEXT_KEEP_IF_EXISTS,
	context, nullptr);
if (!NT_SUCCESS(status)) {
	DbgPrint("[*] failed to set file context\n");
	ExFreePool(context->FileName.Buffer);
}
FltReleaseContext(context);

DbgPrint("[*] allocated and set file context for file\n");
return FLT_POSTOP_FINISHED_PROCESSING;

}`

and the unload called function that causes the BSOD (without it filter hangs)
`
void ReleaseFileStateContexts()
{
AutoLock locker(FileStateContextsMutex);
if (ContextsToDelete)
{
PContextToDelete current = ContextsToDelete;
while (current != nullptr)
{
FltReleaseContext((PFLT_CONTEXT)current->Context); // that is -1 on the refcount to make it 0
ExFreePoolWithTag(current, TAG);
current = (PContextToDelete)current->Next;
}
}

}`

solved , that was quick lol. I wrongly called the function before FltUnregisterFilter during unload, swapping the order and now unload is clean : )