📄 operations.c
字号:
/*++
Copyright (c) 1999 - 2002 Microsoft Corporation
Module Name:
operations.c
Abstract:
This is the i/o operations module of the kernel mode filter driver implementing
context sample
Environment:
Kernel mode
--*/
#include "pch.h"
//
// Assign text sections for each routine.
//
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, CtxPreCreate)
#pragma alloc_text(PAGE, CtxPostCreate)
#pragma alloc_text(PAGE, CtxPreCleanup)
#pragma alloc_text(PAGE, CtxPreClose)
#pragma alloc_text(PAGE, CtxPreSetInfo)
#pragma alloc_text(PAGE, CtxPostSetInfo)
#endif
FLT_PREOP_CALLBACK_STATUS
CtxPreCreate (
__inout PFLT_CALLBACK_DATA Cbd,
__in PCFLT_RELATED_OBJECTS FltObjects,
__deref_out_opt PVOID *CompletionContext
)
{
UNREFERENCED_PARAMETER( Cbd );
UNREFERENCED_PARAMETER( FltObjects );
UNREFERENCED_PARAMETER( CompletionContext );
PAGED_CODE();
DebugTrace( DEBUG_TRACE_ALL_IO,
("[Ctx]: CtxPreCreate -> Enter (Cbd = %p, FileObject = %p)\n",
Cbd,
FltObjects->FileObject) );
DebugTrace( DEBUG_TRACE_ALL_IO,
("[Ctx]: CtxPreCreate -> Exit (Cbd = %p, FileObject = %p)\n",
Cbd,
FltObjects->FileObject) );
//
// Force a post-op callback so we can add our contexts to the opened
// objects
//
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
FLT_POSTOP_CALLBACK_STATUS
CtxPostCreate (
__inout PFLT_CALLBACK_DATA Cbd,
__in PCFLT_RELATED_OBJECTS FltObjects,
__inout_opt PVOID CbdContext,
__in FLT_POST_OPERATION_FLAGS Flags
)
{
PCTX_STREAM_CONTEXT streamContext = NULL;
PCTX_STREAMHANDLE_CONTEXT streamHandleContext = NULL;
PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
NTSTATUS status;
BOOLEAN streamContextCreated, streamHandleContextReplaced;
UNREFERENCED_PARAMETER( FltObjects );
UNREFERENCED_PARAMETER( Flags );
UNREFERENCED_PARAMETER( CbdContext );
PAGED_CODE();
DebugTrace( DEBUG_TRACE_ALL_IO,
("[Ctx]: CtxPostCreate -> Enter (Cbd = %p, FileObject = %p)\n",
Cbd,
FltObjects->FileObject) );
//
// Initialize defaults
//
status = STATUS_SUCCESS;
//
// If the Create has failed, do nothing
//
if (!NT_SUCCESS( Cbd->IoStatus.Status )) {
goto CtxPostCreateCleanup;
}
//
// Get the file name
//
status = FltGetFileNameInformation( Cbd,
FLT_FILE_NAME_NORMALIZED |
FLT_FILE_NAME_QUERY_DEFAULT,
&nameInfo );
if (!NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
("[Ctx]: CtxPostCreate -> Failed to get name information (Cbd = %p, FileObject = %p)\n",
Cbd,
FltObjects->FileObject) );
goto CtxPostCreateCleanup;
}
//
// Find or create a stream context
//
status = CtxFindOrCreateStreamContext(Cbd,
TRUE,
&streamContext,
&streamContextCreated);
if (!NT_SUCCESS( status )) {
//
// This failure will most likely be because stream contexts are not supported
// on the object we are trying to assign a context to or the object is being
// deleted
//
DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: CtxPostCreate -> Failed to find or create stream context (Cbd = %p, FileObject = %p)\n",
Cbd,
FltObjects->FileObject) );
goto CtxPostCreateCleanup;
}
DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: CtxPostCreate -> Getting/Creating stream context for file %wZ (Cbd = %p, FileObject = %p, StreamContext = %p. StreamContextCreated = %x)\n",
&nameInfo->Name,
Cbd,
FltObjects->FileObject,
streamContext,
streamContextCreated) );
//
// Acquire write acccess to the context
//
CtxAcquireResourceExclusive(streamContext->Resource);
//
// Increment the create count
//
streamContext->CreateCount++;
//
// Update the file name in the context
//
status = CtxUpdateNameInStreamContext( &nameInfo->Name,
streamContext);
DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: CtxPostCreate -> Stream context info for file %wZ (Cbd = %p, FileObject = %p, StreamContext = %p) \n\tName = %wZ \n\tCreateCount = %x \n\tCleanupCount = %x, \n\tCloseCount = %x\n",
&nameInfo->Name,
Cbd,
FltObjects->FileObject,
streamContext,
&streamContext->FileName,
streamContext->CreateCount,
streamContext->CleanupCount,
streamContext->CloseCount) );
//
// Relinquish write acccess to the context
//
CtxReleaseResource(streamContext->Resource);
//
// Quit on failure after we have given up
// the resource
//
if (!NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: CtxPostCreate -> Failed to update name in stream context for file %wZ (Cbd = %p, FileObject = %p)\n",
&nameInfo->Name,
Cbd,
FltObjects->FileObject) );
goto CtxPostCreateCleanup;
}
//
// Create or replace a stream handle context
//
status = CtxCreateOrReplaceStreamHandleContext(Cbd,
TRUE,
&streamHandleContext,
&streamHandleContextReplaced);
if (!NT_SUCCESS( status )) {
//
// This failure will most likely be because stream contexts are not supported
// on the object we are trying to assign a context to or the object is being
// deleted
//
DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
("[Ctx]: CtxPostCreate -> Failed to find or create stream handle context (Cbd = %p, FileObject = %p)\n",
Cbd,
FltObjects->FileObject) );
goto CtxPostCreateCleanup;
}
DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
("[Ctx]: CtxPostCreate -> Creating/Replacing stream handle context for file %wZ (Cbd = %p, FileObject = %p StreamHandleContext = %p, StreamHandleContextReplaced = %x)\n",
&nameInfo->Name,
Cbd,
FltObjects->FileObject,
streamHandleContext,
streamHandleContextReplaced) );
//
// Acquire write acccess to the context
//
CtxAcquireResourceExclusive( streamHandleContext->Resource );
//
// Update the file name in the context
//
status = CtxUpdateNameInStreamHandleContext( &nameInfo->Name,
streamHandleContext);
DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
("[Ctx]: CtxPostCreate -> Stream handle context info for file %wZ (Cbd = %p, FileObject = %p, StreamHandleContext = %p) \n\tName = %wZ\n",
&nameInfo->Name,
Cbd,
FltObjects->FileObject,
streamHandleContext,
&streamHandleContext->FileName) );
//
// Relinquish write acccess to the context
//
CtxReleaseResource(streamHandleContext->Resource);
//
// Quit on failure after we have given up
// the resource
//
if (!NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
("[Ctx]: CtxPostCreate -> Failed to update name in stream handle context for file %wZ (Cbd = %p, FileObject = %p)\n",
&nameInfo->Name,
Cbd,
FltObjects->FileObject) );
goto CtxPostCreateCleanup;
}
CtxPostCreateCleanup:
//
// Release the references we have acquired
//
if (nameInfo != NULL) {
FltReleaseFileNameInformation( nameInfo );
}
if (streamContext != NULL) {
FltReleaseContext( streamContext );
}
if (streamHandleContext != NULL) {
FltReleaseContext( streamHandleContext );
}
if (!NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_ERROR,
("[Ctx]: CtxPostCreate -> Failed with status 0x%x \n",
status) );
//
// It doesn't make sense to udate Cbd->IoStatus.Status on failure since the
// file system has successfully completed the operation
//
}
DebugTrace( DEBUG_TRACE_ALL_IO,
("[Ctx]: CtxPostCreate -> Exit (Cbd = %p, FileObject = %p, Status = 0x%x)\n",
Cbd,
FltObjects->FileObject,
Cbd->IoStatus.Status) );
return FLT_POSTOP_FINISHED_PROCESSING;
}
FLT_PREOP_CALLBACK_STATUS
CtxPreCleanup (
__inout PFLT_CALLBACK_DATA Cbd,
__in PCFLT_RELATED_OBJECTS FltObjects,
__deref_out_opt PVOID *CompletionContext
)
{
PCTX_STREAM_CONTEXT streamContext = NULL;
NTSTATUS status;
BOOLEAN streamContextCreated;
UNREFERENCED_PARAMETER( FltObjects );
UNREFERENCED_PARAMETER( CompletionContext );
PAGED_CODE();
DebugTrace( DEBUG_TRACE_ALL_IO,
("[Ctx]: CtxPreCleanup -> Enter (Cbd = %p, FileObject = %p)\n",
Cbd,
FltObjects->FileObject) );
//
// Get the stream context
//
status = CtxFindOrCreateStreamContext(Cbd,
FALSE, // do not create if one does not exist
&streamContext,
&streamContextCreated);
if (!NT_SUCCESS( status )) {
//
// This failure will most likely be because stream contexts are not supported
// on the object we are trying to assign a context to or the object is being
// deleted
//
DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: CtxPreCleanup -> Failed to find stream context (Cbd = %p, FileObject = %p)\n",
Cbd,
FltObjects->FileObject) );
goto CtxPreCleanupCleanup;
}
DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: CtxPreCleanup -> Getting stream context for file (Cbd = %p, FileObject = %p, StreamContext = %p. StreamContextCreated = %x)\n",
Cbd,
FltObjects->FileObject,
streamContext,
streamContextCreated) );
//
// Acquire write acccess to the context
//
CtxAcquireResourceExclusive(streamContext->Resource);
DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: CtxPreCleanup -> Old info in stream context for file(Cbd = %p, FileObject = %p, StreamContext = %p) \n\tName = %wZ \n\tCreateCount = %x \n\tCleanupCount = %x, \n\tCloseCount = %x\n",
Cbd,
FltObjects->FileObject,
streamContext,
&streamContext->FileName,
streamContext->CreateCount,
streamContext->CleanupCount,
streamContext->CloseCount) );
//
// Update the cleanup count in the context
//
streamContext->CleanupCount++;
DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: CtxPreCleanup -> New info in stream context for file (Cbd = %p, FileObject = %p, StreamContext = %p) \n\tName = %wZ \n\tCreateCount = %x \n\tCleanupCount = %x, \n\tCloseCount = %x\n",
Cbd,
FltObjects->FileObject,
streamContext,
&streamContext->FileName,
streamContext->CreateCount,
streamContext->CleanupCount,
streamContext->CloseCount) );
//
// Relinquish write acccess to the context
//
CtxReleaseResource(streamContext->Resource);
CtxPreCleanupCleanup:
//
// Release the references we have acquired
//
if (streamContext != NULL) {
FltReleaseContext( streamContext );
}
DebugTrace( DEBUG_TRACE_ALL_IO,
("[Ctx]: CtxPreCleanup -> Exit (Cbd = %p, FileObject = %p)\n",
Cbd,
FltObjects->FileObject) );
//
// It doesn't make sense to fail the cleanup - so ignore any errors we may
// encounter and return success
//
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
FLT_PREOP_CALLBACK_STATUS
CtxPreClose (
__inout PFLT_CALLBACK_DATA Cbd,
__in PCFLT_RELATED_OBJECTS FltObjects,
__deref_out_opt PVOID *CompletionContext
)
{
PCTX_STREAM_CONTEXT streamContext = NULL;
NTSTATUS status;
BOOLEAN streamContextCreated;
UNREFERENCED_PARAMETER( FltObjects );
UNREFERENCED_PARAMETER( CompletionContext );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -