static
_fileContext*
    _getOrSetContext
    (
        PFLT_CALLBACK_DATA Data
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    _fileContext* context = NULL;
    _fileContext* oldContext = NULL;

    status = FltGetFileContext( Data->Iopb->TargetInstance,
                                Data->Iopb->TargetFileObject,
                                &context );

    if( STATUS_NOT_FOUND == status )
    {
        status = FltAllocateContext( g_filter,
                                     FLT_FILE_CONTEXT,
                                     sizeof( _fileContext ),
                                     NonPagedPool,
                                     (PFLT_CONTEXT*)&context );
        
        if( STATUS_SUCCESS == status )
        {
            context->isNew = FALSE;
            context->isDelete = FALSE;
            context->isChanged = FALSE;
            context->isRead = FALSE;
            context->lastWritePid = 0;
            context->lastReadPid = 0;

            status = FltSetFileContext( Data->Iopb->TargetInstance,
                                        Data->Iopb->TargetFileObject,
                                        FLT_SET_CONTEXT_KEEP_IF_EXISTS,
                                        context,
                                        &oldContext );

            if( STATUS_FLT_CONTEXT_ALREADY_DEFINED == status )
            {
                FltReleaseContext( (PFLT_CONTEXT)context );
                context = oldContext;
            }
            else if( STATUS_SUCCESS != status )
            {
                FltReleaseContext( (PFLT_CONTEXT)context );
                context = NULL;
            }
        }
    }

    if( NULL_CONTEXT == context )
    {
        context = NULL;
    }

    return context;
}
示例#2
0
static NTSTATUS
UcaSetContext(_In_ PFLT_INSTANCE Instance,
              _In_ PVOID Target,
              _In_ FLT_CONTEXT_TYPE ContextType,
              _In_ PFLT_CONTEXT NewContext,
              _Outptr_opt_result_maybenull_ PFLT_CONTEXT *OldContext)
{
    NTSTATUS Status;

    PAGED_CODE();

    switch (ContextType)
    {
        case FLT_STREAM_CONTEXT:

            Status = FltSetStreamContext(Instance,
                                         (PFILE_OBJECT)Target,
                                         FLT_SET_CONTEXT_KEEP_IF_EXISTS,
                                         NewContext,
                                         OldContext);
            break;

        case FLT_FILE_CONTEXT:

            Status = FltSetFileContext(Instance,
                                       (PFILE_OBJECT)Target,
                                       FLT_SET_CONTEXT_KEEP_IF_EXISTS,
                                       NewContext,
                                       OldContext);
            break;

        case FLT_TRANSACTION_CONTEXT:

            Status = FltSetTransactionContext(Instance,
                                              (PKTRANSACTION)Target,
                                              FLT_SET_CONTEXT_KEEP_IF_EXISTS,
                                              NewContext,
                                              OldContext);
            break;

        case FLT_INSTANCE_CONTEXT:

            Status = FltSetInstanceContext(Instance,
                                           FLT_SET_CONTEXT_KEEP_IF_EXISTS,
                                           NewContext,
                                           OldContext);
            break;

        default:

            Status = STATUS_INVALID_PARAMETER;
            break;
    }

    return Status;
}
示例#3
0
/*++

Routine Description:

	这个函数找到目标文件的文件上下文。
	如果上下文不存在,这个函数创建一个新的文件上下文附加在该文件上。
    This routine finds the file context for the target file.
    Optionally, if the context does not exist this routing creates
    a new one and attaches the context to the file.

Arguments:

    Cbd                   - Supplies a pointer to the callbackData which
                            declares the requested operation.
    CreateIfNotFound      - Supplies if the file context must be created if missing
    FileName              - Supplies the file name
    FileContext           - Returns the file context
    ContextCreated        - Returns if a new context was created

Return Value:

    Status

--*/
NTSTATUS
CtxFindOrCreateFileContext (
    __in PFLT_CALLBACK_DATA Cbd,
    __in BOOLEAN CreateIfNotFound,
    __in_opt PUNICODE_STRING FileName,
    __deref_out PCTX_FILE_CONTEXT *FileContext,
    __out_opt PBOOLEAN ContextCreated
    )
{
    NTSTATUS status;
    PCTX_FILE_CONTEXT fileContext;
    PCTX_FILE_CONTEXT oldFileContext;

    PAGED_CODE();

    *FileContext = NULL;
    if (ContextCreated != NULL) *ContextCreated = FALSE;

    //  首先,尝试获取文件上下文。
    //  First try to get the file context.
    DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                ("[Ctx]: Trying to get file context (FileObject = %p, Instance = %p)\n",
                 Cbd->Iopb->TargetFileObject,
                 Cbd->Iopb->TargetInstance) );

    status = FltGetFileContext( Cbd->Iopb->TargetInstance, Cbd->Iopb->TargetFileObject, &fileContext );

    //  如果调用失败是因为上下文不存在,并且用户想创建一个新的话,那么就创建一个
    //  If the call failed because the context does not exist
    //  and the user wants to creat a new one, the create a
    //  new context
    if (!NT_SUCCESS( status ) && (status == STATUS_NOT_FOUND) && CreateIfNotFound) 
	{
        //  创建一个文件上下文
        //  Create a file context
        DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                    ("[Ctx]: Creating file context (FileObject = %p, Instance = %p)\n",
                     Cbd->Iopb->TargetFileObject,
                     Cbd->Iopb->TargetInstance) );

        status = CtxCreateFileContext( FileName, &fileContext );

        if (!NT_SUCCESS( status )) 
		{
            DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                        ("[Ctx]: Failed to create file context with status 0x%x. (FileObject = %p, Instance = %p)\n",
                        status,
                        Cbd->Iopb->TargetFileObject,
                        Cbd->Iopb->TargetInstance) );

            return status;
        }

        //  将新建的上下文设置到文件对象上
        //  Set the new context we just allocated on the file object
        DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                    ("[Ctx]: Setting file context %p (FileObject = %p, Instance = %p)\n",
                     fileContext,
                     Cbd->Iopb->TargetFileObject,
                     Cbd->Iopb->TargetInstance) );

        status = FltSetFileContext( Cbd->Iopb->TargetInstance,
                                      Cbd->Iopb->TargetFileObject,
                                      FLT_SET_CONTEXT_KEEP_IF_EXISTS,
                                      fileContext,
                                      &oldFileContext );

        if (!NT_SUCCESS( status ))
		{
            DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                        ("[Ctx]: Failed to set file context with status 0x%x. (FileObject = %p, Instance = %p)\n",
                        status,
                        Cbd->Iopb->TargetFileObject,
                        Cbd->Iopb->TargetInstance) );

            //  由于FltSetFileContext()调用失败,释放上下文
            //  We release the context here because FltSetFileContext failed
            //
			//  如果FltSetFileContext()成功,这个上下文会返回给调用者。
			//  调用者使用这个上下文,当使用完毕之后释放它。
            //  If FltSetFileContext succeeded then the context will be returned
            //  to the caller. The caller will use the context and then release it
            //  when he is done with the context.
            DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                        ("[Ctx]: Releasing file context %p (FileObject = %p, Instance = %p)\n",
                         fileContext,
                         Cbd->Iopb->TargetFileObject,
                         Cbd->Iopb->TargetInstance) );

            FltReleaseContext( fileContext );

            if (status != STATUS_FLT_CONTEXT_ALREADY_DEFINED)
			{
                //  
                //  FltSetFileContext failed for a reason other than the context already
                //  existing on the file. So the object now does not have any context set
                //  on it. So we return failure to the caller.
                DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                            ("[Ctx]: Failed to set file context with status 0x%x != STATUS_FLT_CONTEXT_ALREADY_DEFINED. (FileObject = %p, Instance = %p)\n",
                            status,
                            Cbd->Iopb->TargetFileObject,
                            Cbd->Iopb->TargetInstance) );

                return status;
            }

            //  竞争条件。
            //  Race condition. Someone has set a context after we queried it.
            //  Use the already set context instead
            DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                        ("[Ctx]: File context already defined. Retaining old file context %p (FileObject = %p, Instance = %p)\n",
                         oldFileContext,
                         Cbd->Iopb->TargetFileObject,
                         Cbd->Iopb->TargetInstance) );

            //
            //  Return the existing context. Note that the new context that we allocated has already been
            //  realeased above.
            fileContext = oldFileContext;
            status = STATUS_SUCCESS;
        } 
		else
		{
            if (ContextCreated != NULL) 
				*ContextCreated = TRUE;
        }
    }

    *FileContext = fileContext;

    return status;
}
示例#4
0
NTSTATUS
CtxFindOrCreateFileContext (
    __in PFLT_CALLBACK_DATA Cbd,
    __in BOOLEAN CreateIfNotFound,
    __in_opt PUNICODE_STRING FileName,
    __deref_out PCTX_FILE_CONTEXT *FileContext,
    __out_opt PBOOLEAN ContextCreated
    )
/*++

Routine Description:

    This routine finds the file context for the target file.
    Optionally, if the context does not exist this routing creates
    a new one and attaches the context to the file.

Arguments:

    Cbd                   - Supplies a pointer to the callbackData which
                            declares the requested operation.
    CreateIfNotFound      - Supplies if the file context must be created if missing
    FileName              - Supplies the file name
    FileContext           - Returns the file context
    ContextCreated        - Returns if a new context was created

Return Value:

    Status

--*/
{
    NTSTATUS status;
    PCTX_FILE_CONTEXT fileContext;
    PCTX_FILE_CONTEXT oldFileContext;

    PAGED_CODE();

    *FileContext = NULL;
    if (ContextCreated != NULL) *ContextCreated = FALSE;

    //
    //  First try to get the file context.
    //

    DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                ("[Ctx]: Trying to get file context (FileObject = %p, Instance = %p)\n",
                 Cbd->Iopb->TargetFileObject,
                 Cbd->Iopb->TargetInstance) );

    status = FltGetFileContext( Cbd->Iopb->TargetInstance,
                                  Cbd->Iopb->TargetFileObject,
                                  &fileContext );

    //
    //  If the call failed because the context does not exist
    //  and the user wants to creat a new one, the create a
    //  new context
    //

    if (!NT_SUCCESS( status ) &&
        (status == STATUS_NOT_FOUND) &&
        CreateIfNotFound) {


        //
        //  Create a file context
        //

        DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                    ("[Ctx]: Creating file context (FileObject = %p, Instance = %p)\n",
                     Cbd->Iopb->TargetFileObject,
                     Cbd->Iopb->TargetInstance) );

        status = CtxCreateFileContext( FileName, &fileContext );

        if (!NT_SUCCESS( status )) {

            DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                        ("[Ctx]: Failed to create file context with status 0x%x. (FileObject = %p, Instance = %p)\n",
                        status,
                        Cbd->Iopb->TargetFileObject,
                        Cbd->Iopb->TargetInstance) );

            return status;
        }


        //
        //  Set the new context we just allocated on the file object
        //

        DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                    ("[Ctx]: Setting file context %p (FileObject = %p, Instance = %p)\n",
                     fileContext,
                     Cbd->Iopb->TargetFileObject,
                     Cbd->Iopb->TargetInstance) );

        status = FltSetFileContext( Cbd->Iopb->TargetInstance,
                                      Cbd->Iopb->TargetFileObject,
                                      FLT_SET_CONTEXT_KEEP_IF_EXISTS,
                                      fileContext,
                                      &oldFileContext );

        if (!NT_SUCCESS( status )) {

            DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                        ("[Ctx]: Failed to set file context with status 0x%x. (FileObject = %p, Instance = %p)\n",
                        status,
                        Cbd->Iopb->TargetFileObject,
                        Cbd->Iopb->TargetInstance) );
            //
            //  We release the context here because FltSetFileContext failed
            //
            //  If FltSetFileContext succeeded then the context will be returned
            //  to the caller. The caller will use the context and then release it
            //  when he is done with the context.
            //

            DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                        ("[Ctx]: Releasing file context %p (FileObject = %p, Instance = %p)\n",
                         fileContext,
                         Cbd->Iopb->TargetFileObject,
                         Cbd->Iopb->TargetInstance) );

            FltReleaseContext( fileContext );

            if (status != STATUS_FLT_CONTEXT_ALREADY_DEFINED) {

                //
                //  FltSetFileContext failed for a reason other than the context already
                //  existing on the file. So the object now does not have any context set
                //  on it. So we return failure to the caller.
                //

                DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                            ("[Ctx]: Failed to set file context with status 0x%x != STATUS_FLT_CONTEXT_ALREADY_DEFINED. (FileObject = %p, Instance = %p)\n",
                            status,
                            Cbd->Iopb->TargetFileObject,
                            Cbd->Iopb->TargetInstance) );

                return status;
            }

            //
            //  Race condition. Someone has set a context after we queried it.
            //  Use the already set context instead
            //

            DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS,
                        ("[Ctx]: File context already defined. Retaining old file context %p (FileObject = %p, Instance = %p)\n",
                         oldFileContext,
                         Cbd->Iopb->TargetFileObject,
                         Cbd->Iopb->TargetInstance) );

            //
            //  Return the existing context. Note that the new context that we allocated has already been
            //  realeased above.
            //

            fileContext = oldFileContext;
            status = STATUS_SUCCESS;

        } else {

            if (ContextCreated != NULL) *ContextCreated = TRUE;
        }
    }

    *FileContext = fileContext;

    return status;
}