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

📄 datastore.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 2002 - 2003  Microsoft Corporation

Module Name:

    datastore.c

Abstract:

    This module contains routines that provide support for storage and
    retrieval of the filter metadata manager filter metadata.


Environment:

    Kernel mode


--*/

#include "pch.h"

//
//  Assign text sections for each routine.
//

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FmmOpenMetadata)
#pragma alloc_text(PAGE, FmmCloseMetadata)
#pragma alloc_text(PAGE, FmmReleaseMetadataFileReferences)
#pragma alloc_text(PAGE, FmmReacquireMetadataFileReferences)
#pragma alloc_text(PAGE, FmmSetMetadataOpenTriggerFileObject)
#pragma alloc_text(PAGE, FmmBeginFileSystemOperation)
#pragma alloc_text(PAGE, FmmEndFileSystemOperation)
#endif

NTSTATUS
FmmOpenMetadata (
    __in PFMM_INSTANCE_CONTEXT InstanceContext,
    __in BOOLEAN CreateIfNotPresent
    )
/*++

Routine Description:

    This routine opens or creates the Fmm metadata on the specified instance.

Arguments:

    InstanceContext     - Supplies the instance context for this instance.
    CreateIfNotPresent  - Supplies if the directory entry must be created if it is not present

Return Value:

    Returns the status of this operation.

Note:

    The caller must hold the instance context resource exclusive when this routine is called.

--*/
{
    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK ioStatus;
    UNICODE_STRING fileName;
    NTSTATUS status;
    ULONG length;

    PAGED_CODE();

    DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS,
                ("[Fmm]: Opening metadata file ... (Volume = %p, CreateIfNotPresent = %X)\n",
                 InstanceContext->Volume,
                 CreateIfNotPresent) );

    status = STATUS_SUCCESS;
    fileName.Buffer = NULL;

    //
    //  Get the volume name and construct the full metadata filename.
    //


    length = FMM_DEFAULT_VOLUME_NAME_LENGTH + FMM_METADATA_FILE_NAME_LENGTH;

    while (TRUE) {

        fileName.MaximumLength = (USHORT)length;

        status = FmmAllocateUnicodeString( &fileName );

        if (!NT_SUCCESS( status )) {

            goto FmmOpenMetadataCleanup;
        }

        status = FltGetVolumeName( InstanceContext->Volume, &fileName, &length );

        if (NT_SUCCESS( status )) {

            status = RtlAppendUnicodeToString( &fileName, FMM_METADATA_FILE_NAME );

            if (NT_SUCCESS( status )) {

                break;
            }
        } else {

            DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS | DEBUG_TRACE_ERROR,
                        ("[Fmm]: Failed to get volume name (Volume = %p, Status = 0x%x)\n",
                         InstanceContext->Volume,
                         status) );
        }


        if (status != STATUS_BUFFER_TOO_SMALL) {

            goto FmmOpenMetadataCleanup;;
        }

        //
        //  Free the filename buffer since a bigger one will be allocated
        //  above
        //

        FmmFreeUnicodeString( &fileName );

        length += FMM_METADATA_FILE_NAME_LENGTH;
    }


    //
    //  Initialize the object attributes and open the file.
    //

    InitializeObjectAttributes( &objectAttributes,
                                &fileName,
                                OBJ_KERNEL_HANDLE,
                                NULL,
                                NULL );




RetryFltCreateFile:


    DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS,
                ("[Fmm]: Calling FltCreateFile for metadata file %wZ (Volume = %p, Status = 0x%x)\n",
                 &fileName,
                 InstanceContext->Volume,
                 status) );


    //
    //  Mark the beginning of a file system operation
    //

    FmmBeginFileSystemOperation( InstanceContext );

    status = FltCreateFile( Globals.Filter,
                            InstanceContext->Instance,
                            &InstanceContext->MetadataHandle,
                            FILE_ALL_ACCESS,
                            &objectAttributes,
                            &ioStatus,
                            (PLARGE_INTEGER) NULL,
                            FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN,
                            FILE_SHARE_READ,
                            (CreateIfNotPresent ? FILE_OPEN_IF : FILE_OPEN),
                            0L,
                            NULL,
                            0L,
                            0 );

    //
    //  Mark the end of a file system operation
    //

    FmmEndFileSystemOperation( InstanceContext );


    if (!NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS | DEBUG_TRACE_ERROR,
                    ("[Fmm]: FltCreateFile failure for metadata file %wZ (Volume = %p, Status = 0x%x)\n",
                     &fileName,
                     InstanceContext->Volume,
                     status) );

        if (CreateIfNotPresent && (status == STATUS_OBJECT_PATH_NOT_FOUND)) {

            //
            //  We need to create the metadata file and the creation failed
            //  because the SystemVolumeInformation folder does not exist.
            //  So, create the folder and try again.
            //

            DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS,
                        ("[Fmm]: Creating SystemVolumeInformation folder for metadata file %wZ (Volume = %p, Status = 0x%x)\n",
                         &fileName,
                         InstanceContext->Volume,
                         status) );


            //
            //  Mark the beginning of a file system operation
            //

            FmmBeginFileSystemOperation( InstanceContext );

            status = FltCreateSystemVolumeInformationFolder( InstanceContext->Instance );

            //
            //  Mark the end of a file system operation
            //

            FmmEndFileSystemOperation( InstanceContext );



            if (NT_SUCCESS( status )) {

                //
                //  We have sucessfully created the SystemVolumeInformation folder
                //  Try to create the metadata file again
                //

                goto RetryFltCreateFile;
            } else {

                DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS | DEBUG_TRACE_ERROR,
                            ("[Fmm]: FltCreateSystemVolumeInformationFolder failure for metadata file %wZ (Volume = %p, Status = 0x%x)\n",
                             &fileName,
                             InstanceContext->Volume,
                             status) );
            }
        }

        goto FmmOpenMetadataCleanup;
    }

    //
    //  Retrieve the FileObject from the handle created
    //

    status = ObReferenceObjectByHandle( InstanceContext->MetadataHandle,
                                        STANDARD_RIGHTS_REQUIRED,
                                        *IoFileObjectType,
                                        KernelMode,
                                        &InstanceContext->MetadataFileObject,
                                        NULL );
    if (!NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS | DEBUG_TRACE_ERROR,
                    ("[Fmm]: Failure to get file object from handle for metadata file %wZ (Volume = %p, Status = 0x%x)\n",
                     &fileName,
                     InstanceContext->Volume,
                     status) );

        goto FmmOpenMetadataCleanup;
    }

    if (ioStatus.Information == FILE_CREATED) {

        //
        //  New metadata was created
        //

        DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS,
                    ("[Fmm]: Created new metadata file %wZ (Volume = %p, Status = 0x%x)\n",
                     &fileName,
                     InstanceContext->Volume,
                     status) );

        //
        //  The filter may want to do some initialization on the newly created
        //  metadata file here like adding a header to the file
        //

    }
    else {

        //
        //  Existing metadata was opened
        //

        DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS,
                    ("[Fmm]: Opened existing metadata file %wZ (Volume = %p, Status = 0x%x)\n",
                     &fileName,
                     InstanceContext->Volume,
                     status) );

        //
        //  The filter may want to do some sanity checks on the metadata file here
        //  like validating the header of the file
        //

    }

    //
    //  Here the filter may read the metadata contents and initialize
    //  its in memory data structures with the data from the metadata
    //  file
    //


FmmOpenMetadataCleanup:

    if (!NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS | DEBUG_TRACE_ERROR,
                    ("[Fmm]: Failed to open metadata (Volume = %p, Status = 0x%x)\n",
                     InstanceContext->Volume,
                     status) );

        //
        //  CLose the handle and dereference the file object
        //

        if (InstanceContext->MetadataHandle) {


            //
            //  Mark the beginning of a file system operation
            //

            FmmBeginFileSystemOperation( InstanceContext );

            FltClose( InstanceContext->MetadataHandle );

            //
            //  Mark the end of a file system operation
            //

            FmmEndFileSystemOperation( InstanceContext );

            InstanceContext->MetadataHandle = NULL;

            if (InstanceContext->MetadataFileObject) {

                ObDereferenceObject( InstanceContext->MetadataFileObject );
                InstanceContext->MetadataFileObject = NULL;
            }
        }
    } else {

        DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS,
                    ("[Fmm]: Metadata successfully opened (Volume = %p)\n",
                     InstanceContext->Volume) );

        //
        //  Set flags to indicate successful open of filter metadata
        //

        SetFlag( InstanceContext->Flags, INSTANCE_CONTEXT_F_METADATA_OPENED );

    }

    if (fileName.Buffer != NULL) {

        FmmFreeUnicodeString( &fileName );
    }

    return status;
}


VOID
FmmCloseMetadata (
    __in PFMM_INSTANCE_CONTEXT InstanceContext
    )
/*++

Routine Description:

    This routine closes the filters handle to the metadata file.

Arguments:

    InstanceContext - Instance context for this instance.

Return Value:

    Void.

Note:

    The caller must hold the instance context resource when this routine is called.


--*/
{
    PAGED_CODE();

    ASSERT( InstanceContext->MetadataHandle );
    ASSERT( InstanceContext->MetadataFileObject );

    DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS,
                ("[Fmm]: Closing metadata file ... (Volume = %p)\n",
                 InstanceContext->Volume ) );

    //
    //  Dereference the file object and close the file handle.
    //

    ObDereferenceObject( InstanceContext->MetadataFileObject );

    InstanceContext->MetadataFileObject = NULL;


    //
    //  Mark the beginning of a file system operation
    //

    FmmBeginFileSystemOperation( InstanceContext );

    FltClose( InstanceContext->MetadataHandle );

    //
    //  Mark the end of a file system operation
    //

    FmmEndFileSystemOperation( InstanceContext );


    InstanceContext->MetadataHandle = NULL;

    //
    //  Reset flag to indicate filter metadata is closed
    //

    ClearFlag( InstanceContext->Flags, INSTANCE_CONTEXT_F_METADATA_OPENED );

}

NTSTATUS
FmmReleaseMetadataFileReferences (
    __inout PFLT_CALLBACK_DATA Cbd
    )
/*++

Routine Description:

    This routine releases all references to the metadata file on the specified instance.

Arguments:

    Cbd                 - Supplies a pointer to the callbackData which
                          declares the requested operation.

Return Value:

    Status

Note:

    This routine takes care of the synchronization needed to access the metadata
    file object and handle

    This routine will also set the MetadataOpenTriggerFileObject in the instance context
    to the file object of the volume that triggered the release of the metadata file
    references.

--*/
{
    NTSTATUS status = STATUS_SUCCESS;
    PFMM_INSTANCE_CONTEXT instanceContext = NULL;

⌨️ 快捷键说明

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