📄 context.c
字号:
/*++
Copyright (c) 1999 - 2002 Microsoft Corporation
Module Name:
context.c
Abstract:
This is the stream nd stream handle context module of the kernel mode
context sample filter driver
Environment:
Kernel mode
--*/
#include "pch.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, CtxFindOrCreateStreamContext)
#pragma alloc_text(PAGE, CtxCreateStreamContext)
#pragma alloc_text(PAGE, CtxUpdateNameInStreamContext)
#pragma alloc_text(PAGE, CtxCreateOrReplaceStreamHandleContext)
#pragma alloc_text(PAGE, CtxCreateStreamHandleContext)
#pragma alloc_text(PAGE, CtxUpdateNameInStreamHandleContext)
#endif
NTSTATUS
CtxFindOrCreateStreamContext (
IN PFLT_CALLBACK_DATA Cbd,
IN BOOLEAN CreateIfNotFound,
OUT PCTX_STREAM_CONTEXT *StreamContext,
OUT PBOOLEAN ContextCreated OPTIONAL
)
/*++
Routine Description:
This routine finds the stream context for the target stream.
Optionally, if the context does not exist this routing creates
a new one and attaches the context to the stream.
Arguments:
Cbd - Supplies a pointer to the callbackData which
declares the requested operation.
CreateIfNotFound - Supplies if the stream must be created if missing
StreamContext - Returns the stream context
ContextCreated - Returns if a new context was created
Return Value:
Status
--*/
{
NTSTATUS status;
PCTX_STREAM_CONTEXT streamContext;
PCTX_STREAM_CONTEXT oldStreamContext;
PAGED_CODE();
*StreamContext = NULL;
if (ContextCreated != NULL) *ContextCreated = FALSE;
//
// First try to get the stream context.
//
DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: Trying to get stream context (FileObject = %p, Instance = %p)\n",
Cbd->Iopb->TargetFileObject,
Cbd->Iopb->TargetInstance) );
status = FltGetStreamContext( Cbd->Iopb->TargetInstance,
Cbd->Iopb->TargetFileObject,
&streamContext );
//
// 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 stream context
//
DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: Creating stream context (FileObject = %p, Instance = %p)\n",
Cbd->Iopb->TargetFileObject,
Cbd->Iopb->TargetInstance) );
status = CtxCreateStreamContext( &streamContext );
if (!NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: Failed to create stream 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_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: Setting stream context %p (FileObject = %p, Instance = %p)\n",
streamContext,
Cbd->Iopb->TargetFileObject,
Cbd->Iopb->TargetInstance) );
status = FltSetStreamContext( Cbd->Iopb->TargetInstance,
Cbd->Iopb->TargetFileObject,
FLT_SET_CONTEXT_KEEP_IF_EXISTS,
streamContext,
&oldStreamContext );
if (!NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: Failed to set stream context with status 0x%x. (FileObject = %p, Instance = %p)\n",
status,
Cbd->Iopb->TargetFileObject,
Cbd->Iopb->TargetInstance) );
//
// We release the context here because FltSetStreamContext failed
//
// If FltSetStreamContext 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_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: Releasing stream context %p (FileObject = %p, Instance = %p)\n",
streamContext,
Cbd->Iopb->TargetFileObject,
Cbd->Iopb->TargetInstance) );
FltReleaseContext( streamContext );
if (status != STATUS_FLT_CONTEXT_ALREADY_DEFINED) {
//
// FltSetStreamContext failed for a reason other than the context already
// existing on the stream. 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_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: Failed to set stream 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_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: Stream context already defined. Retaining old stream context %p (FileObject = %p, Instance = %p)\n",
oldStreamContext,
Cbd->Iopb->TargetFileObject,
Cbd->Iopb->TargetInstance) );
//
// Return the existing context. Note that the new context that we allocated has already been
// realeased above.
//
streamContext = oldStreamContext;
} else {
if (ContextCreated != NULL) *ContextCreated = TRUE;
}
}
*StreamContext = streamContext;
return status;
}
NTSTATUS
CtxCreateStreamContext (
OUT PCTX_STREAM_CONTEXT *StreamContext
)
/*++
Routine Description:
This routine creates a new stream context
Arguments:
StreamContext - Returns the stream context
Return Value:
Status
--*/
{
NTSTATUS status;
PCTX_STREAM_CONTEXT streamContext;
PAGED_CODE();
//
// Allocate a stream context
//
DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: Allocating stream context \n") );
status = FltAllocateContext( Globals.Filter,
FLT_STREAM_CONTEXT,
CTX_STREAM_CONTEXT_SIZE,
PagedPool,
&streamContext );
if (!NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
("[Ctx]: Failed to allocate stream context with status 0x%x \n",
status) );
return status;
}
//
// Initialize the newly created context
//
RtlZeroMemory( streamContext, CTX_STREAM_CONTEXT_SIZE );
streamContext->Resource = CtxAllocateResource();
if(streamContext->Resource == NULL) {
FltReleaseContext( streamContext );
return STATUS_INSUFFICIENT_RESOURCES;
}
ExInitializeResourceLite( streamContext->Resource );
*StreamContext = streamContext;
return STATUS_SUCCESS;
}
NTSTATUS
CtxUpdateNameInStreamContext (
IN PUNICODE_STRING FileName,
OUT PCTX_STREAM_CONTEXT StreamContext
)
/*++
Routine Description:
This routine updates the name of the target in the supplied stream context
Arguments:
FileName - Supplies the directory name
StreamContext - Returns the updated name in the stream context
Return Value:
Status
Note:
The caller must synchronize access to the context. This routine does no
synchronization
--*/
{
NTSTATUS status;
//
// Free any existing name
//
if (StreamContext->FileName.Buffer != NULL) {
CtxFreeUnicodeString(&StreamContext->FileName);
}
//
// Allocate and copy off the directory name
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -