📄 filemon.c
字号:
//
passedFilters = !ProcessFilters || ApplyFilters( text );
if( passedFilters ) {
//
// Assign a sequence number if we weren't passed one
//
if( !SeqNum || (SeqNum && *SeqNum == (ULONG) -1)) {
recordSequence = InterlockedIncrement( &Sequence );
if( SeqNum ) *SeqNum = recordSequence;
} else {
recordSequence = *SeqNum;
}
//
// If the current output buffer is near capacity, move to a new
// output buffer
//
if( CurrentLog->Len + len + sizeof(ENTRY) +1 >= LOGBUFSIZE ) {
FilemonAllocateLog();
}
//
// Log the entry
//
Entry = (void *)(CurrentLog->Data+CurrentLog->Len);
Entry->seq = recordSequence;
Entry->datetime.QuadPart = 0;
Entry->perftime.QuadPart = 0;
if( dateTime ) Entry->datetime = *dateTime;
if( perfTime ) Entry->perftime = *perfTime;
memcpy( Entry->text, text, len );
//
// Log the length of the string, plus 1 for the terminating
// NULL
//
CurrentLog->Len += ((ULONG) (Entry->text - (PCHAR) Entry )) + len;
}
//
// Release the output buffer lock
//
ExReleaseFastMutex( &LogMutex );
return passedFilters;
}
//----------------------------------------------------------------------
// H A S H T A B L E M A N A G E M E N T
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//
// FilemonHashCleanup
//
// Called when we are unloading to free any memory that we have
// in our possession.
//
//----------------------------------------------------------------------
VOID
FilemonHashCleanup(
VOID
)
{
PHASH_ENTRY hashEntry, nextEntry;
ULONG i;
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite( &HashResource, TRUE );
//
// Free the hash table entries
//
for( i = 0; i < NUMHASH; i++ ) {
hashEntry = HashTable[i];
while( hashEntry ) {
nextEntry = hashEntry->Next;
ExFreePool( hashEntry );
hashEntry = nextEntry;
}
HashTable[i] = NULL;
}
ExReleaseResourceLite( &HashResource );
KeLeaveCriticalRegion();
}
//----------------------------------------------------------------------
//
// FilemonFreeHashEntry
//
// When we see a file close, we can free the string we had associated
// with the fileobject being closed since we know it won't be used
// again.
//
//----------------------------------------------------------------------
VOID
FilemonFreeHashEntry(
PFILE_OBJECT fileObject
)
{
PHASH_ENTRY hashEntry, prevEntry;
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite( &HashResource, TRUE );
//
// Look-up the entry
//
hashEntry = HashTable[ HASHOBJECT( fileObject ) ];
prevEntry = NULL;
while( hashEntry && hashEntry->FileObject != fileObject ) {
prevEntry = hashEntry;
hashEntry = hashEntry->Next;
}
//
// If we fall of the hash list without finding what we're looking
// for, just return.
//
if( !hashEntry ) {
ExReleaseResourceLite( &HashResource );
KeLeaveCriticalRegion();
return;
}
//
// Got it! Remove it from the list
//
if( prevEntry ) {
prevEntry->Next = hashEntry->Next;
} else {
HashTable[ HASHOBJECT( fileObject )] = hashEntry->Next;
}
//
// Free the entry's memory
//
ExFreePool( hashEntry );
ExReleaseResourceLite( &HashResource );
KeLeaveCriticalRegion();
}
//----------------------------------------------------------------------
// P A T H A N D P R O C E S S N A M E R O U T I N E S
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//
// FilemonFreeFilters
//
// Fress storage we allocated for filter strings.
//
//----------------------------------------------------------------------
VOID
FilemonFreeFilters(
VOID
)
{
ULONG i;
for( i = 0; i < NumIncludeFilters; i++ ) {
ExFreePool( IncludeFilters[i] );
}
for( i = 0; i < NumExcludeFilters; i++ ) {
ExFreePool( ExcludeFilters[i] );
}
NumIncludeFilters = 0;
NumExcludeFilters = 0;
}
//----------------------------------------------------------------------
//
// MakeFilterArray
//
// Takes a filter string and splits into components (a component
// is seperated with a ';')
//
//----------------------------------------------------------------------
VOID
MakeFilterArray(
PCHAR FilterString,
PCHAR FilterArray[],
PULONG NumFilters
)
{
PCHAR filterStart;
ULONG filterLength;
CHAR saveChar;
//
// Scan through the process filters
//
filterStart = FilterString;
while( *filterStart ) {
filterLength = 0;
while( filterStart[filterLength] &&
filterStart[filterLength] != ';' ) {
filterLength++;
}
//
// Ignore zero-length components
//
if( filterLength ) {
//
// Conservatively allocate so that we can prepend and append
// wildcards
//
FilterArray[ *NumFilters ] =
ExAllocatePool( PagedPool, filterLength + 1 + 2*sizeof('*') );
//
// Only fill this in if there's enough memory
//
if( FilterArray[ *NumFilters] ) {
saveChar = *(filterStart + filterLength );
*(filterStart + filterLength) = 0;
sprintf( FilterArray[ *NumFilters ], "%s%s%s",
*filterStart == '*' ? "" : "*",
filterStart,
*(filterStart + filterLength - 1 ) == '*' ? "" : "*" );
*(filterStart + filterLength) = saveChar;
(*NumFilters)++;
}
}
//
// Are we done?
//
if( !filterStart[filterLength] ) break;
//
// Move to the next component (skip over ';')
//
filterStart += filterLength + 1;
}
}
//----------------------------------------------------------------------
//
// FilemonUpdateFilters
//
// Takes a new filter specification and updates the filter
// arrays with them.
//
//----------------------------------------------------------------------
VOID
FilemonUpdateFilters(
VOID
)
{
//
// Free old filters (if any)
//
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite( &FilterResource, TRUE );
FilemonFreeFilters();
//
// Create new filter arrays
//
MakeFilterArray( FilterDef.includefilter,
IncludeFilters, &NumIncludeFilters );
MakeFilterArray( FilterDef.excludefilter,
ExcludeFilters, &NumExcludeFilters );
ExReleaseResourceLite( &FilterResource );
KeLeaveCriticalRegion();
}
//----------------------------------------------------------------------
//
// ApplyFilters
//
// If the name matches the exclusion mask, we do not log it. Else if
// it doesn't match the inclusion mask we do not log it.
//
//----------------------------------------------------------------------
BOOLEAN
ApplyFilters(
PCHAR Text
)
{
ULONG i;
//
// If no GUI or no filename return FALSE
//
if( !Text ) return FALSE;
//
// If it matches the exclusion string, do not log it
//
KeEnterCriticalRegion();
ExAcquireResourceSharedLite( &FilterResource, TRUE );
for( i = 0; i < NumExcludeFilters; i++ ) {
if( MatchWithPattern( ExcludeFilters[i], Text ) ) {
ExReleaseResourceLite( &FilterResource );
KeLeaveCriticalRegion();
return FALSE;
}
}
//
// If it matches an include filter then log it
//
for( i = 0; i < NumIncludeFilters; i++ ) {
if( MatchWithPattern( IncludeFilters[i], Text )) {
ExReleaseResourceLite( &FilterResource );
KeLeaveCriticalRegion();
return TRUE;
}
}
//
// It didn't match any include filters so don't log
//
ExReleaseResourceLite( &FilterResource );
KeLeaveCriticalRegion();
return FALSE;
}
//----------------------------------------------------------------------
//
// FilemonQueryFileComplete
//
// This routine is used to handle I/O completion for our self-generated
// IRP that is used to query a file's name or number.
//
//----------------------------------------------------------------------
NTSTATUS
FilemonQueryFileComplete(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
)
{
//
// Copy the status information back into the "user" IOSB.
//
*Irp->UserIosb = Irp->IoStatus;
if( !NT_SUCCESS(Irp->IoStatus.Status) ) {
DbgPrint((" ERROR ON IRP: %x\n", Irp->IoStatus.Status ));
}
//
// Set the user event - wakes up the mainline code doing this.
//
KeSetEvent(Irp->UserEvent, 0, FALSE);
//
// Free the IRP now that we are done with it.
//
IoFreeIrp(Irp);
//
// We return STATUS_MORE_PROCESSING_REQUIRED because this "magic" return value
// tells the I/O Manager that additional processing will be done by this driver
// to the IRP - in fact, it might (as it is in this case) already BE done - and
// the IRP cannot be completed.
//
return STATUS_MORE_PROCESSING_REQUIRED;
}
//----------------------------------------------------------------------
//
// FilemonQueryFile
//
// This function retrieves the "standard" information for the
// underlying file system, asking for the filename in particular.
//
//----------------------------------------------------------------------
BOOLEAN
FilemonQueryFile(
PDEVICE_OBJECT DeviceObject,
PFILE_OBJECT FileObject,
FILE_INFORMATION_CLASS FileInformationClass,
PVOID FileQueryBuffer,
ULONG FileQueryBufferLength
)
{
PIRP irp;
KEVENT event;
IO_STATUS_BLOCK IoStatusBlock;
PIO_STACK_LOCATION ioStackLocation;
DbgPrint(("Getting file name for %x\n", FileObject));
//
// Initialize the event
//
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
//
// Allocate an irp for this request. This could also come from a
// private pool, for instance.
//
irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if(!irp) {
//
// Failure!
//
return FALSE;
}
//
// Build the IRP's main body
//
irp->AssociatedIrp.SystemBuffer = FileQueryBuffer;
irp->UserEvent = &event;
irp->UserIosb = &IoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->RequestorMode = KernelMode;
irp->Flags = 0;
//
// Set up the I/O stack location.
//
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_QUERY_INFORMATION;
ioStackLocation->DeviceObject = DeviceObject;
ioStackLocation->FileObject = FileObject;
ioStackLocation->Parameters.QueryFile.Length = FileQueryBufferLength;
ioStackLocation->Parameters.QueryFile.FileInformationClass = FileInformationClass;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -