Hi
I’ve investigated the problem and here my code because of which the minifilter can’t be loaded:
I have the following functions for IRP_MJ_DIRECTORY_CONTROL:
{ IRP_MJ_DIRECTORY_CONTROL,
0,
PreOperationPassThrough,
PostOperationPassThrough
},
ULONG_PTR OperationStatusCtx = 1;
and the functions:
/*************************************************************************
MiniFilter callback routines.
*************************************************************************/
FLT_PREOP_CALLBACK_STATUS
PreOperationPassThrough (
IN OUT PFLT_CALLBACK_DATA Data,
IN PCFLT_RELATED_OBJECTS FltObjects,
OUT PVOID *CompletionContext
)
/*++
Routine Description:
This routine is the main pre-operation dispatch routine for this
miniFilter. Since this is just a simple passThrough miniFilter it
does not do anything with the callbackData but rather return
FLT_PREOP_SUCCESS_WITH_CALLBACK thereby passing it down to the next
miniFilter in the chain.
This is non-pageable because it could be called on the paging path
Arguments:
Data - Pointer to the filter callbackData that is passed to us.
FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
opaque handles to this filter, instance, its associated volume and
file object.
CompletionContext - The context for the completion routine for this
operation.
Return Value:
The return value is the status of the operation.
–*/
{
NTSTATUS status;
UNREFERENCED_PARAMETER( FltObjects );
UNREFERENCED_PARAMETER( CompletionContext );
DbgPrint(“PassThrough!PtPreOperationPassThrough: Entered\n”);
//
// See if this is an operation we would like the operation status
// for. If so request it.
//
// NOTE: most filters do NOT need to do this. You only need to make
// this call if, for example, you need to know if the oplock was
// actually granted.
//
if (DoRequestOperationStatus( Data )) {
DbgBreakPoint();
status = FltRequestOperationStatusCallback( Data,
OperationStatusCallback,
(PVOID)(++OperationStatusCtx) );
if (!NT_SUCCESS(status)) {
DbgPrint((“PassThrough!PtPreOperationPassThrough: FltRequestOperationStatusCallback Failed, status=%08x\n”,
status) );
}
}
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
BOOLEAN
DoRequestOperationStatus(
IN PFLT_CALLBACK_DATA Data
)
/*++
Routine Description:
This identifies those operations we want the operation status for. These
are typically operations that return STATUS_PENDING as a normal completion
status.
Arguments:
Return Value:
TRUE - If we want the operation status
FALSE - If we don’t
–*/
{
PFLT_IO_PARAMETER_BLOCK iopb = Data->Iopb;
//
// return boolean state based on which operations we are interested in
//
return (BOOLEAN)
//
// Check for oplock operations
//
FLT_IS_IRP_OPERATION(Data) &&
(((iopb->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
((iopb->Parameters.FileSystemControl.Common.FsControlCode == FSCTL_REQUEST_FILTER_OPLOCK) ||
(iopb->Parameters.FileSystemControl.Common.FsControlCode == FSCTL_REQUEST_BATCH_OPLOCK) ||
(iopb->Parameters.FileSystemControl.Common.FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_1) ||
(iopb->Parameters.FileSystemControl.Common.FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_2)))
||
//
// Check for directy change notification
//
((iopb->MajorFunction == IRP_MJ_DIRECTORY_CONTROL) &&
(iopb->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY))
);
}
VOID
OperationStatusCallback (
IN PCFLT_RELATED_OBJECTS FltObjects,
IN PFLT_IO_PARAMETER_BLOCK IopbSnapshot,
IN NTSTATUS OperationStatus,
IN PVOID RequesterContext
)
/*++
Routine Description:
This routine is called when the given operation returns from the call
to IoCallDriver. This is useful for operations where STATUS_PENDING
means the operation was successfully queued. This is useful for OpLocks
and directory change notification operations.
This callback is called in the context of the originating thread and will
never be called at DPC level. The file object has been correctly
referenced so that you can access it. It will be automatically
dereferenced upon return.
This is non-pageable because it could be called on the paging path
Arguments:
FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
opaque handles to this filter, instance, its associated volume and
file object.
RequesterContext - The context for the completion routine for this
operation.
OperationStatus -
Return Value:
The return value is the status of the operation.
–*/
{
DbgPrint(“PassThrough!PtOperationStatusCallback: Entered\n”) );
DbgPrint(“PassThrough!PtOperationStatusCallback: Status=%08x ctx=%p IrpMj=%02x.%02x "%s"\n”,
OperationStatus,
RequesterContext,
IopbSnapshot->MajorFunction,
IopbSnapshot->MinorFunction,
FltGetIrpName(IopbSnapshot->MajorFunction)) );
}
if the IRP_MJ_DIRECTORY_CONTROL with IRP_MN_NOTIFY_CHANGE_DIRECTORY arrives I can’t unload the minifilter anymore.
There is no context referenced so there should be no problem. Also in the DDK is nothing that mentions a neccessary call to unreference a certain object.
Can maybe someone from MS take a look on it.
thanks
horatiu