📄 filemon.c
字号:
//
// Matched
//
return TRUE;
}
//----------------------------------------------------------------------
//
// MatchWithPatternCore
//
// Performs nifty wildcard comparison.
//
//----------------------------------------------------------------------
BOOLEAN MatchWithPatternCore( PCHAR Pattern, PCHAR Name )
{
//
// End of pattern?
//
if( !*Pattern ) {
return FALSE;
}
//
// If we hit a wild card, do recursion
//
if( *Pattern == '*' ) {
Pattern++;
while( *Name && *Pattern ) {
//
// See if this substring matches
//
if( *Pattern == *Name || *Name == '*' ) {
if( MatchWithPatternCore( Pattern+1, Name+1 )) {
return TRUE;
}
}
//
// Try the next substring
//
Name++;
}
//
// See if match condition was met
//
return MatchOkay( Pattern );
}
//
// Do straight compare until we hit a wild card
//
while( *Name && *Pattern != '*' ) {
if( *Pattern == *Name ) {
Pattern++;
Name++;
} else {
return FALSE;
}
}
//
// If not done, recurse
//
if( *Name ) {
return MatchWithPatternCore( Pattern, Name );
}
//
// Make sure its a match
//
return MatchOkay( Pattern );
}
//----------------------------------------------------------------------
//
// MatchWithPattern
//
// Converts strings to upper-case before calling core comparison routine.
//
//----------------------------------------------------------------------
BOOLEAN MatchWithPattern( PCHAR Pattern, PCHAR Name )
{
PCHAR Upname;
int i;
BOOLEAN isMatch;
//
// Allocate space for up-cased version of the name
//
Upname = MemAllocatePool( NonPagedPool, strlen( Name ) + 1);
if ( !Upname ) return FALSE;
//
// Make the name upcased
//
i = 0;
while( *Name ) {
if( *Name >= 'a' && *Name <= 'z' )
Upname[i++] = *Name - 'a' + 'A';
else
Upname[i++] = *Name;
Name++;
}
Upname[i] = 0;
//
// Now do the comparison
//
isMatch = MatchWithPatternCore( Pattern, Upname );
MemFreePool( Upname );
return isMatch;
}
//----------------------------------------------------------------------
// B U F F E R M A N A G E M E N T
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//
// FilemonFreeStore
//
// Frees all the data output buffers that we have currently allocated.
//
//----------------------------------------------------------------------
VOID FilemonFreeStore()
{
PSTORE_BUF prev;
//
// Just traverse the list of allocated output buffers
//
while( Store ) {
prev = Store->Next;
MemFreePool( Store );
Store = prev;
}
}
//----------------------------------------------------------------------
//
// FilemonNewStore
//
// Called when the current buffer has filled up. This allocates a new
// buffer and stick it at the head (newest) entry of our buffer list.
//
//----------------------------------------------------------------------
void FilemonNewStore( void )
{
PSTORE_BUF prev = Store, newstore;
//
// If we've already allocated the allowed number of buffers, just
// reuse the current one. This will result in output records being
// lost, but it takes ALOT of file system activity to cause this.
//
if( MaxStore == NumStore ) {
Store->Len = 0;
return;
}
//
// If the output buffer we currently are using is empty, just
// use it.
//
if( !Store->Len )
return;
//
// Allocate a new output buffer
//
newstore = MemAllocatePool( NonPagedPool, sizeof(*Store) );
if( newstore ) {
//
// Allocation was successful so add the buffer to the list
// of allocated buffers and increment the buffer count.
//
Store = newstore;
Store->Len = 0;
Store->Next = prev;
NumStore++;
} else {
//
// The allocation failed - just reuse the current buffer
//
Store->Len = 0;
}
}
//----------------------------------------------------------------------
//
// FilemonOldestStore
//
// Traverse the list of allocated buffers to find the last one, which
// will be the oldest (as we want to return the oldest data to the GUI
// first).
//
//----------------------------------------------------------------------
PSTORE_BUF FilemonOldestStore( void )
{
PSTORE_BUF ptr = Store, prev = NULL;
//
// Traverse the list
//
while ( ptr->Next ) {
ptr = (prev = ptr)->Next;
}
//
// Remove the buffer from the list
//
if ( prev ) {
prev->Next = NULL;
}
NumStore--;
return ptr;
}
//----------------------------------------------------------------------
//
// FilemonResetStore
//
// When a GUI instance has close communication (exited), but the driver
// can't unload due to oustdanding IRPs, all the output buffers except
// one are all deallocated so that the memory footprint is shrunk as much
// as possible.
//
//----------------------------------------------------------------------
VOID FilemonResetStore()
{
PSTORE_BUF current, next;
//
// Traverse the list of output buffers
//
current = Store->Next;
while( current ) {
//
// Free the buffer
//
next = current->Next;
MemFreePool( current );
current = next;
}
//
// Move the output pointer in the buffer that's being kept
// the start of the buffer.
//
Store->Len = 0;
Store->Next = NULL;
}
//----------------------------------------------------------------------
//
// UpdateStore
//
// This "printfs" a string into an output buffer.
//
//----------------------------------------------------------------------
void UpdateStore( ULONG seq, PLARGE_INTEGER time, const CHAR * format, ... )
{
PENTRY Entry;
int len;
va_list arg_ptr;
KIRQL oldirql;
PCHAR text;
//
// If no GUI is there to receive the output or if no filtering is desired, don't bother
//
if( !FilterOn ) {
return;
}
//
// Allocate a buffer
//
text = MemAllocateFromNPagedLookasideList( &PathLookaside );
if( !text ) {
return;
}
//
// Send text out as debug output This is x86 specific.
//
#define A (&format)
DbgPrint(( (char *)format, A[1], A[2], A[3], A[4], A[5], A[6] ));
DbgPrint(( "\n" ));
#undef A
//
// Lock the output buffer.
//
KeAcquireSpinLock( &StoreMutex, &oldirql );
//
// Vsprintf to determine the length of the buffer
//
va_start( arg_ptr, format );
len = vsprintf( text, format, arg_ptr );
va_end( arg_ptr );
//
// ULONG align for Alpha
//
len += 4; len &= 0xFFFFFFFC; // +1 to include null terminator and +3 to allign on 32 bit
//
// If the current output buffer is near capacity, move to a new
// output buffer
//
if ( Store->Len + len + sizeof(ENTRY) +1 >= MAX_STORE ) {
FilemonNewStore();
}
//
// Extract the sequence number and store it
//
Entry = (void *)(Store->Data+Store->Len);
Entry->seq = seq;
Entry->time = *time;
memcpy( Entry->text, text, len );
//
// Store the length of the string, plus 1 for the terminating
// NULL
//
Store->Len += (Entry->text - (PCHAR) Entry ) + len;
//
// Release the output buffer lock
//
KeReleaseSpinLock( &StoreMutex, oldirql );
//
// Free the buffer
//
MemFreePool( text );
}
//----------------------------------------------------------------------
// 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()
{
PHASH_ENTRY hashEntry, nextEntry;
ULONG i;
//
// First, free the hash table entries
//
for( i = 0; i < NUMHASH; i++ ) {
hashEntry = HashTable[i];
while( hashEntry ) {
nextEntry = hashEntry->Next;
MemFreePool( hashEntry->FullPathName );
MemFreeToNPagedLookasideList( &HashLookaside, hashEntry );
hashEntry = nextEntry;
}
HashTable[i] = NULL;
}
}
//----------------------------------------------------------------------
//
// 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;
KIRQL oldirql;
KeAcquireSpinLock( &HashMutex, &oldirql );
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -