⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 operations.c

📁 miniFilter.rar所有框架代码以及对应的PPT资料,可以直接拿来进行修改即可完成各种驱动,是你开发微软新过滤构架驱动所必下资料
💻 C
📖 第 1 页 / 共 3 页
字号:

            status = FmmReacquireMetadataFileReferences( Cbd );

            if (!NT_SUCCESS( status )) {

                DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
                            ("[Fmm]: Failed to re-open metadata with status 0x%x after a successful unlock.\n",
                             status) );

                //
                //  Sanity - we are now in a bad state. The volume was unlocked
                //  but we have not been able to re-acquire references to
                //  our metadata file
                //
                //  Ntfs dismounts and remounts the volume after an unlock. So we ignore
                //  failures to open the metadata with STATUS_INVALID_DEVICE_OBJECT_PARAMETER
                //  because the volume should have been remounted and the metadata file
                //  should have been opened on the newly mounted instance of that volume
                //
                //  Note however, that if this is an implicit lock (used by autoXXX.exe) then
                //  ntfs will not automatically dismount the volume. It relies on the application
                //  to restart the system if it has made any changes to the volume. If the
                //  application has not made any changes then ntfs will simply continue on
                //  after the unlock without dismounting the volume. Hence we cannot assume
                //  that ntfs always dismounts the volume. We need to try to re-acquire
                //  a handle to our metadata file and ignore failure with error
                //  STATUS_INVALID_DEVICE_OBJECT_PARAMETER which indicates that the
                //  volume has dismounted
                //
                //  Also it is always possible to fail with STATUS_INSUFFICIENT_RESOURCES
                //  so we should ignore that as well.
                //
                //  It is also possible to fail if the instance context was in a transition state
                //  so we should ignore STATUS_FILE_LOCK_CONFLICT too.
                //

                ASSERT( (status == STATUS_INVALID_DEVICE_OBJECT_PARAMETER) ||
                        (status == STATUS_INSUFFICIENT_RESOURCES) ||
                        (status == STATUS_FILE_LOCK_CONFLICT) );

                //
                //  There is little use updating the return status since it already has a
                //  failure code from the failed dismount
                //
            }
        }

        //
        //  We don't need to process a volume CleanUp any further
        //

        goto FmmPostCleanupCleanup;
    }


    //
    //  Here the filter can do any further processing it may want to do
    //  in the PostCleanUp Callback
    //

FmmPostCleanupCleanup:

    if (!NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_ERROR,
                    ("[Fmm]: FmmPostCleanup -> Failed with status 0x%x \n",
                    status) );

        //
        //  It does not make sense to fail in the the post op, since the operation has completed
        //

    }


    DebugTrace( DEBUG_TRACE_ALL_IO,
                ("[Fmm]: FmmPostCleanup -> Exit (Cbd = %p, FileObject = %p)\n",
                 Cbd,
                 FltObjects->FileObject) );

    return FLT_POSTOP_FINISHED_PROCESSING;
}


FLT_PREOP_CALLBACK_STATUS
FmmPreFSControl (
    __inout PFLT_CALLBACK_DATA Cbd,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
    )
{

    NTSTATUS status;
    FLT_PREOP_CALLBACK_STATUS callbackStatus;

    UNREFERENCED_PARAMETER( CompletionContext );
    UNREFERENCED_PARAMETER( FltObjects );

    PAGED_CODE();

    DebugTrace( DEBUG_TRACE_ALL_IO,
                ("[Fmm]: FmmPreFsCtl -> Enter (FsControlCode = 0x%x, Cbd = %p, FileObject = %p)\n",
                 Cbd->Iopb->Parameters.FileSystemControl.Common.FsControlCode,
                 Cbd,
                 FltObjects->FileObject) );


    //
    //  default to no post-op callback
    //

    callbackStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;


    if (Cbd->Iopb->MinorFunction != IRP_MN_USER_FS_REQUEST) {

        goto FmmPreFSControlCleanup;
    }


    switch (Cbd->Iopb->Parameters.FileSystemControl.Common.FsControlCode) {

    //
    //  System FSCTLs that we are interested in
    //

    case FSCTL_DISMOUNT_VOLUME:
    case FSCTL_LOCK_VOLUME:


        if (FmmTargetIsVolumeOpen( Cbd )) {

            //
            //  Give up the metadata file handle and the metadata file object
            //

            status = FmmReleaseMetadataFileReferences( Cbd );

            if ( NT_SUCCESS( status )) {

                //
                //  Continue with the lock/dismount - we need to check if the
                //  lock operation suceeded in the post-op
                //

                callbackStatus = FLT_PREOP_SYNCHRONIZE;
            } else {

                //
                //  Fail the lock/dismount
                //

                DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
                            ("[Fmm]: Failed to release metadata file references with status 0x%x for a volume lock/dismount\n",
                             status) );

                Cbd->IoStatus.Status = status;
                callbackStatus = FLT_PREOP_COMPLETE;
            }
        }
        break;

    case FSCTL_UNLOCK_VOLUME:

        //
        //  We need to handle unlock in the post-op
        //

        callbackStatus = FLT_PREOP_SYNCHRONIZE;
        break;

    }

FmmPreFSControlCleanup:


    DebugTrace( DEBUG_TRACE_ALL_IO,
                ("[Fmm]: FmmPreFsCtl -> Exit (FsControlCode = 0x%x, Cbd = %p, FileObject = %p)\n",
                 Cbd->Iopb->Parameters.FileSystemControl.Common.FsControlCode,
                 Cbd,
                 FltObjects->FileObject) );

    return callbackStatus;

}


FLT_POSTOP_CALLBACK_STATUS
FmmPostFSControl (
    __inout PFLT_CALLBACK_DATA Cbd,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in PVOID CompletionContext,
    __in FLT_POST_OPERATION_FLAGS Flags
    )
{

    NTSTATUS status;

    UNREFERENCED_PARAMETER( CompletionContext );
    UNREFERENCED_PARAMETER( Flags );

    PAGED_CODE();

    DebugTrace( DEBUG_TRACE_ALL_IO,
                ("[Fmm]: FmmPostFsCtl -> Enter (FsControlCode = 0x%x, Cbd = %p, FileObject = %p)\n",
                 Cbd->Iopb->Parameters.FileSystemControl.Common.FsControlCode,
                 Cbd,
                 FltObjects->FileObject) );


    if (!FlagOn(Flags,FLTFL_POST_OPERATION_DRAINING)) {

        switch (Cbd->Iopb->Parameters.FileSystemControl.Common.FsControlCode) {

        //
        //  System FSCTLs that we are interested in
        //

        case FSCTL_DISMOUNT_VOLUME:

            if (FmmTargetIsVolumeOpen( Cbd )) {

                if (NT_SUCCESS( Cbd->IoStatus.Status )) {

                    //
                    //  Dismount succeeded - teardown our instance because its no longer valid.
                    //  If we do not tear down this instance, it will stay around until the
                    //  last handle for that volume is closed. This will cause the instance
                    //  enumeration APIs to see multiple instances
                    //

                    status = FltDetachVolume( Globals.Filter, FltObjects->Volume, NULL );

                    if (!NT_SUCCESS( status )) {

                        DebugTrace( DEBUG_TRACE_ERROR,
                                    ("[Fmm]: Failed to detach instance with status 0x%x after a volume dismount\n",
                                     status) );

                        //
                        //  Doesn't make sense to update the status code in the post-op with a
                        //  failure code since the operation has already been performed by the
                        //  file system
                        //
                    }

                } else {

                    //
                    //  The dismount failed - reaquire our references to the metadata file
                    //  handle and the metadata file object
                    //

                    status = FmmReacquireMetadataFileReferences( Cbd );

                    if (!NT_SUCCESS( status )) {

                        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
                                    ("[Fmm]: Failed to re-open metadata with status 0x%x after a failed dismount with status 0x%x\n",
                                     status,
                                     Cbd->IoStatus.Status) );

                        //
                        //  Sanity - we are now in a bad state. The dismount has failed
                        //  but we have not been able to re-acquire references to
                        //  our metadata file
                        //
                        //  It is always possible to fail with STATUS_INSUFFICIENT_RESOURCES
                        //  so we should ignore that.
                        //
                        //  It is also possible to fail if the instance context was in a transition state
                        //  so we should ignore STATUS_FILE_LOCK_CONFLICT too.
                        //

                        ASSERT( (status == STATUS_INSUFFICIENT_RESOURCES) ||
                                (status == STATUS_FILE_LOCK_CONFLICT) );

                        //
                        //  There is little use updating the return status since it already has a
                        //  failure code from the failed dismount
                        //
                    }
                }
            }

            break;

        case FSCTL_LOCK_VOLUME:


            if (FmmTargetIsVolumeOpen( Cbd )) {

                if (!NT_SUCCESS( Cbd->IoStatus.Status )) {

                    //
                    //  The lock failed - reaquired our references to the metadata file
                    //  handle and the metadata file object
                    //

                    status = FmmReacquireMetadataFileReferences( Cbd );

                    if (!NT_SUCCESS( status )) {

                        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
                                    ("[Fmm]: Failed to re-open metadata with status 0x%x after a failed lock with status 0x%x\n",
                                     status,
                                     Cbd->IoStatus.Status) );

                        //
                        //  Sanity - we are now in a bad state. The lock has failed
                        //  but we have not been able to re-acquire references to
                        //  our metadata file
                        //
                        //  It is always possible to fail with STATUS_INSUFFICIENT_RESOURCES
                        //  so we should ignore that.
                        //
                        //  It is also possible to fail if the instance context was in a transition state
                        //  so we should ignore STATUS_FILE_LOCK_CONFLICT too.
                        //

                        ASSERT( (status == STATUS_INSUFFICIENT_RESOURCES) ||
                                (status == STATUS_FILE_LOCK_CONFLICT) );

                        //
                        //  There is little use updating the return status since it already has a
                        //  failure code from the failed lock
                        //

                    }
                } else {

                    //
                    //  The lock operation suceeded - update the MetadataOpenTriggerFileObject in the
                    //  instance context to the File Object on the lock operation suceeded because this
                    //  the file object on close/unlock of which, we need to reacquire our metadata file
                    //  references
                    //

                    status = FmmSetMetadataOpenTriggerFileObject( Cbd );

                    if (!NT_SUCCESS( status )) {

                        DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
                                    ("[Fmm]: Failed to update MetadataOpenTriggerFileObject in the instance context with status 0x%x after a successful lock.\n",
                                     status,
                                     Cbd->IoStatus.Status) );

                        //
                        //  Sanity - we are now in a bad state. We have failed to
                        //  set the TriggerFileObject We may not be able to detect
                        //  an unlock operation on which we need to re-acquire our
                        //  metadata file references
                        //

                        ASSERT( status == STATUS_FILE_LOCK_CONFLICT );

                        //
                        //  Doesn't make sense to update the status code in the
                        //  post-op with a failure code since the operation has
                        //  already been performed by the file system
                        //
                    }

                }
            }

            break;

        case FSCTL_UNLOCK_VOLUME:

            if (NT_SUCCESS( Cbd->IoStatus.Status )) {

                //
                //  The unlock suceeded - reaquired our references to the metadata file
                //  handle and the metadata file object
                //

                status = FmmReacquireMetadataFileReferences( Cbd );

                if (!NT_SUCCESS( status )) {

                    DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS,
                                ("[Fmm]: Failed to re-open metadata with status 0x%x after a successful unlock.\n",
                                 status) );

                    //
                    //  Sanity - we are now in a bad state. The volume was unlocked
                    //  but we have not been able to re-acquire references to
                    //  our metadata file
                    //
                    //  Ntfs dismounts and remounts the volume after an unlock. So we ignore
                    //  failures to open the metadata with STATUS_INVALID_DEVICE_OBJECT_PARAMETER
                    //  because the volume should have been remounted and the metadata file
                    //  should have been opened on the newly mounted instance of that volume
                    //
                    //  Note however, that if this is an implicit lock (used by autoXXX.exe) then
                    //  ntfs will not automatically dismount the volume. It relies on the application
                    //  to restart the system if it has made any changes to the volume. If the
                    //  application has not made any changes then ntfs will simply continue on
                    //  after the unlock without dismounting the volume. Hence we cannot assume
                    //  that ntfs always dismounts the volume. We need to try to re-acquire
                    //  a handle to our metadata file and ignore failure with error
                    //  STATUS_INVALID_DEVICE_OBJECT_PARAMETER which indicates that the
                    //  volume has dismounted
                    //
                    //  Also it is always possible to fail with STATUS_INSUFFICIENT_RESOURCES
                    //  so we should ignore that as well.
                    //
                    //  It is also possible to fail if the instance context was in a transition state
                    //  so we should ignore STATUS_FILE_LOCK_CONFLICT too.
                    //

                    ASSERT( (status == STATUS_INVALID_DEVICE_OBJECT_PARAMETER) ||
                            (status == STATUS_INSUFFICIENT_RESOURCES) ||
                            (status == STATUS_FILE_LOCK_CONFLICT) );

                    //
                    //  There is little use updating the return status since it already has a
                    //  failure code from the failed dismount
                    //
                }
            }


            break;

        }
    }

    DebugTrace( DEBUG_TRACE_ALL_IO,
                ("[Fmm]: FmmPostFsCtl -> Exit (FsControlCode = 0x%x, Cbd = %p, FileObject = %p)\n",
                 Cbd->Iopb->Parameters.FileSystemControl.Common.FsControlCode,
                 Cbd,
                 FltObjects->FileObject) );


    return FLT_POSTOP_FINISHED_PROCESSING;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -