📄 context.c
字号:
StreamContext->FileName.MaximumLength = FileName->Length;
status = CtxAllocateUnicodeString(&StreamContext->FileName);
if (NT_SUCCESS(status)) {
RtlCopyUnicodeString(&StreamContext->FileName, FileName);
}
return status;
}
NTSTATUS
CtxCreateOrReplaceStreamHandleContext (
IN PFLT_CALLBACK_DATA Cbd,
IN BOOLEAN ReplaceIfExists,
OUT PCTX_STREAMHANDLE_CONTEXT *StreamHandleContext,
OUT PBOOLEAN ContextReplaced OPTIONAL
)
/*++
Routine Description:
This routine creates a stream handle context for the target stream
handle. Optionally, if the context already exists, this routine
replaces it with the new context and releases the old context
Arguments:
Cbd - Supplies a pointer to the callbackData which
declares the requested operation.
ReplaceIfExists - Supplies if the stream handle context must be
replaced if already present
StreamContext - Returns the stream context
ContextReplaced - Returns if an existing context was replaced
Return Value:
Status
--*/
{
NTSTATUS status;
PCTX_STREAMHANDLE_CONTEXT streamHandleContext;
PCTX_STREAMHANDLE_CONTEXT oldStreamHandleContext;
PAGED_CODE();
*StreamHandleContext = NULL;
if (ContextReplaced != NULL) *ContextReplaced = FALSE;
//
// Create a stream context
//
DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
("[Ctx]: Creating stream handle context (FileObject = %p, Instance = %p)\n",
Cbd->Iopb->TargetFileObject,
Cbd->Iopb->TargetInstance) );
status = CtxCreateStreamHandleContext( &streamHandleContext );
if (!NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_STREAMHANDLE_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_STREAMHANDLE_CONTEXT_OPERATIONS,
("[Ctx]: Setting stream context %p (FileObject = %p, Instance = %p, ReplaceIfExists = %x)\n",
streamHandleContext,
Cbd->Iopb->TargetFileObject,
Cbd->Iopb->TargetInstance,
ReplaceIfExists) );
status = FltSetStreamHandleContext( Cbd->Iopb->TargetInstance,
Cbd->Iopb->TargetFileObject,
ReplaceIfExists ? FLT_SET_CONTEXT_REPLACE_IF_EXISTS : FLT_SET_CONTEXT_KEEP_IF_EXISTS,
streamHandleContext,
&oldStreamHandleContext );
if (!NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
("[Ctx]: Failed to set stream handle 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 handle context %p (FileObject = %p, Instance = %p)\n",
streamHandleContext,
Cbd->Iopb->TargetFileObject,
Cbd->Iopb->TargetInstance) );
FltReleaseContext( streamHandleContext );
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_STREAMHANDLE_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;
}
//
// We will reach here only if we have failed with STATUS_FLT_CONTEXT_ALREADY_DEFINED
// and we can fail with that code only if the context already exists and we have used
// the FLT_SET_CONTEXT_KEEP_IF_EXISTS flag
ASSERT( ReplaceIfExists == FALSE );
//
// Race condition. Someone has set a context after we queried it.
// Use the already set context instead
//
DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
("[Ctx]: Stream context already defined. Retaining old stream context %p (FileObject = %p, Instance = %p)\n",
oldStreamHandleContext,
Cbd->Iopb->TargetFileObject,
Cbd->Iopb->TargetInstance) );
//
// Return the existing context. Note that the new context that we allocated has already been
// realeased above.
//
streamHandleContext = oldStreamHandleContext;
} else {
//
// FltSetStreamContext has suceeded. The new context will be returned
// to the caller. The caller will use the context and then release it
// when he is done with the context.
//
// However, if we have replaced an existing context then we need to
// release the old context so as to decrement the ref count on it.
//
// Note that the memory allocated to the objects within the context
// will be freed in the context cleanup and must not be done here.
//
if ( ReplaceIfExists &&
oldStreamHandleContext != NULL) {
DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS,
("[Ctx]: Releasing old stream handle context %p (FileObject = %p, Instance = %p)\n",
oldStreamHandleContext,
Cbd->Iopb->TargetFileObject,
Cbd->Iopb->TargetInstance) );
FltReleaseContext( oldStreamHandleContext );
if (ContextReplaced != NULL) *ContextReplaced = TRUE;
}
}
*StreamHandleContext = streamHandleContext;
return status;
}
NTSTATUS
CtxCreateStreamHandleContext (
OUT PCTX_STREAMHANDLE_CONTEXT *StreamHandleContext
)
/*++
Routine Description:
This routine creates a new stream context
Arguments:
StreamContext - Returns the stream context
Return Value:
Status
--*/
{
NTSTATUS status;
PCTX_STREAMHANDLE_CONTEXT streamHandleContext;
PAGED_CODE();
//
// Allocate a stream context
//
DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS,
("[Ctx]: Allocating stream handle context \n") );
status = FltAllocateContext( Globals.Filter,
FLT_STREAMHANDLE_CONTEXT,
CTX_STREAMHANDLE_CONTEXT_SIZE,
PagedPool,
&streamHandleContext );
if (!NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
("[Ctx]: Failed to allocate stream handle context with status 0x%x \n",
status) );
return status;
}
//
// Initialize the newly created context
//
RtlZeroMemory( streamHandleContext, CTX_STREAMHANDLE_CONTEXT_SIZE );
streamHandleContext->Resource = CtxAllocateResource();
if(streamHandleContext->Resource == NULL) {
FltReleaseContext( streamHandleContext );
return STATUS_INSUFFICIENT_RESOURCES;
}
ExInitializeResourceLite( streamHandleContext->Resource );
*StreamHandleContext = streamHandleContext;
return STATUS_SUCCESS;
}
NTSTATUS
CtxUpdateNameInStreamHandleContext (
IN PUNICODE_STRING FileName,
OUT PCTX_STREAMHANDLE_CONTEXT StreamHandleContext
)
/*++
Routine Description:
This routine updates the name of the target in the supplied stream handle context
Arguments:
FileName - Supplies the directory name
StreamHandleContext - 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 (StreamHandleContext->FileName.Buffer != NULL) {
CtxFreeUnicodeString(&StreamHandleContext->FileName);
}
//
// Allocate and copy off the directory name
//
StreamHandleContext->FileName.MaximumLength = FileName->Length;
status = CtxAllocateUnicodeString(&StreamHandleContext->FileName);
if (NT_SUCCESS(status)) {
RtlCopyUnicodeString(&StreamHandleContext->FileName, FileName);
}
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -