📄 datastore.c
字号:
/*++
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
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -