📄 minispy.c
字号:
ASSERT(retryStatus == status);
}
#endif
}
//
// Store the name
//
SpySetRecordName( &(recordList->LogRecord), nameToUse );
//
// Release the name information structure (if defined)
//
if (NULL != nameInfo) {
FltReleaseFileNameInformation( nameInfo );
}
//
// Set all of the operation information into the record
//
SpyLogPreOperationData( Data, FltObjects, recordList );
//
// Pass the record to our completions routine and return that
// we want our completion routine called.
//
if (Data->Iopb->MajorFunction == IRP_MJ_SHUTDOWN) {
//
// Since completion callbacks are not supported for
// this operation, do the completion processing now
//
SpyPostOperationCallback( Data,
FltObjects,
recordList,
0 );
returnStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
} else {
*CompletionContext = recordList;
returnStatus = FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
}
return returnStatus;
}
FLT_POSTOP_CALLBACK_STATUS
SpyPostOperationCallback (
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__in PVOID CompletionContext,
__in FLT_POST_OPERATION_FLAGS Flags
)
/*++
Routine Description:
This routine receives ALL post-operation callbacks. This will take
the log record passed in the context parameter and update it with
the completion information. It will then insert it on a list to be
sent to the usermode component.
NOTE: This routine must be NON-PAGED because it can be called at DPC level
Arguments:
Data - Contains information about the given operation.
FltObjects - Contains pointers to the various objects that are pertinent
to this operation.
CompletionContext - Pointer to the RECORD_LIST structure in which we
store the information we are logging. This was passed from the
pre-operation callback
Flags - Contains information as to why this routine was called.
Return Value:
Identifies how processing should continue for this operation
--*/
{
PRECORD_LIST recordList;
PRECORD_LIST reparseRecordList = NULL;
PLOG_RECORD reparseLogRecord;
PFLT_TAG_DATA_BUFFER tagData;
ULONG copyLength;
UNREFERENCED_PARAMETER( FltObjects );
recordList = (PRECORD_LIST)CompletionContext;
//
// If our instance is in the process of being torn down don't bother to
// log this record, free it now.
//
if (FlagOn(Flags,FLTFL_POST_OPERATION_DRAINING)) {
SpyFreeRecord( recordList );
return FLT_POSTOP_FINISHED_PROCESSING;
}
//
// Set completion information into the record
//
SpyLogPostOperationData( Data, recordList );
//
// Log reparse tag information if specified.
//
if (tagData = Data->TagData) {
reparseRecordList = SpyNewRecord();
if (reparseRecordList) {
//
// only copy the DATA portion of the information
//
RtlCopyMemory( &reparseRecordList->LogRecord.Data,
&recordList->LogRecord.Data,
sizeof(RECORD_DATA) );
reparseLogRecord = &reparseRecordList->LogRecord;
copyLength = FLT_TAG_DATA_BUFFER_HEADER_SIZE + tagData->TagDataLength;
if(copyLength > MAX_NAME_SPACE) {
copyLength = MAX_NAME_SPACE;
}
//
// Copy reparse data
//
RtlCopyMemory(
&reparseRecordList->LogRecord.Name[0],
tagData,
copyLength
);
reparseLogRecord->RecordType |= RECORD_TYPE_FILETAG;
reparseLogRecord->Length += (ULONG) ROUND_TO_SIZE( copyLength, sizeof( PVOID ) );
}
}
//
// Send the logged information to the user service.
//
SpyLog( recordList );
if (reparseRecordList) {
SpyLog( reparseRecordList );
}
//
// For creates within a transaction enlist in the transaction
// if we haven't already done.
//
if ((FltObjects->Transaction != NULL) &&
(Data->Iopb->MajorFunction == IRP_MJ_CREATE) &&
(Data->IoStatus.Status == STATUS_SUCCESS)) {
//
// Enlist in the transaction.
//
SpyEnlistInTransaction( FltObjects );
}
return FLT_POSTOP_FINISHED_PROCESSING;
}
NTSTATUS
SpyEnlistInTransaction (
__in PCFLT_RELATED_OBJECTS FltObjects
)
{
#if MINISPY_LONGHORN
PMINISPY_TRANSACTION_CONTEXT transactionContext=NULL;
PRECORD_LIST recordList;
NTSTATUS status;
static ULONG Sequence=1;
//
// This code is only built in the Longhorn environment, but
// we need to ensure this binary still runs down-level. Return
// at this point if the transaction dynamic imports were not found.
//
// If we find FltGetTransactionContext, we assume the other
// transaction APIs are also present.
//
if (NULL == MiniSpyData.PFltGetTransactionContext) {
return STATUS_SUCCESS;
}
//
// Try to get our context for this transaction. If we get
// one we have already enlisted in this transaction.
//
status = (*MiniSpyData.PFltGetTransactionContext)( FltObjects->Instance,
FltObjects->Transaction,
&transactionContext );
if (NT_SUCCESS( status )) {
FltReleaseContext( transactionContext );
return STATUS_SUCCESS;
}
//
// If the context does not exist create a new one, else return the error
// status to the caller.
//
if (status != STATUS_NOT_FOUND) {
return status;
}
//
// Allocate a transaction context.
//
status = FltAllocateContext( FltObjects->Filter,
FLT_TRANSACTION_CONTEXT,
sizeof(MINISPY_TRANSACTION_CONTEXT),
PagedPool,
&transactionContext );
if (!NT_SUCCESS( status )) {
return status;
}
//
// Set the context into the transaction
//
RtlZeroMemory(transactionContext, sizeof(MINISPY_TRANSACTION_CONTEXT));
transactionContext->Count = Sequence++;
ASSERT( MiniSpyData.PFltSetTransactionContext );
status = (*MiniSpyData.PFltSetTransactionContext)( FltObjects->Instance,
FltObjects->Transaction,
FLT_SET_CONTEXT_KEEP_IF_EXISTS,
transactionContext,
NULL );
if (!NT_SUCCESS( status )) {
FltReleaseContext( transactionContext ); //this will free the context
return status;
}
//
// Enlist on this transaction for notifications.
//
ASSERT( MiniSpyData.PFltEnlistInTransaction );
status = (*MiniSpyData.PFltEnlistInTransaction)( FltObjects->Instance,
FltObjects->Transaction,
transactionContext,
FLT_MAX_TRANSACTION_NOTIFICATIONS );
//
// If the enlistment failed we need to delete the context and remove
// our count
//
if (!NT_SUCCESS( status )) {
FltDeleteContext( transactionContext );
FltReleaseContext( transactionContext );
return status;
}
//
// The operation succeeded, remove our count
//
FltReleaseContext( transactionContext );
//
// Log a record that a new transaction has started.
//
recordList = SpyNewRecord();
if (recordList) {
SpyLogTransactionNotify( FltObjects, recordList, 0 );
//
// Send the logged information to the user service.
//
SpyLog( recordList );
}
#endif // MINISPY_LONGHORN
return STATUS_SUCCESS;
}
#if MINISPY_LONGHORN
NTSTATUS
SpyKtmNotificationCallback (
__in PCFLT_RELATED_OBJECTS FltObjects,
__in PFLT_CONTEXT TransactionContext,
__in ULONG TransactionNotification
)
{
PRECORD_LIST recordList;
//
// Try and get a log record
//
recordList = SpyNewRecord();
if (recordList) {
SpyLogTransactionNotify( FltObjects, recordList, TransactionNotification );
//
// Send the logged information to the user service.
//
SpyLog( recordList );
}
return STATUS_SUCCESS;
}
#endif // MINISPY_LONGHORN
VOID
SpyDeleteTxfContext (
__inout PMINISPY_TRANSACTION_CONTEXT Context,
__in FLT_CONTEXT_TYPE ContextType
)
{
UNREFERENCED_PARAMETER( Context );
UNREFERENCED_PARAMETER( ContextType );
ASSERT(FLT_TRANSACTION_CONTEXT == ContextType);
ASSERT(Context->Count != 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -