?? filemon.c
字號(hào):
//======================================================================
//
// FILEMON.c - main module for VxD FILEMON
//
// SysInternals - www.sysinternals.com
// Copyright (C) 1996-2000 Mark Russinovich and Bryce Cogswell
//
//======================================================================
#define DEVICE_MAIN
#include <vtoolsc.h>
#include "..\exe\ioctlcmd.h"
#include "filemon.h"
#undef DEVICE_MAIN
//----------------------------------------------------------------------
// G L O B A L D A T A
//----------------------------------------------------------------------
//
// Indicates if the GUI wants activity to be logged
//
BOOLEAN FilterOn = FALSE;
//
// Global filter (sent to us by the GUI)
//
FILTER FilterDef;
//
// Array of process and path filters
//
ULONG NumIncludeFilters = 0;
PCHAR IncludeFilters[MAXFILTERS];
ULONG NumExcludeFilters = 0;
PCHAR ExcludeFilters[MAXFILTERS];
//
// Real service pointers with the hook thunks
//
ppIFSFileHookFunc PrevIFSHookProc;
//
// Hash table data
//
PHASH_ENTRY HashTable[NUMHASH];
//
// Buffer data
//
PLOG_BUF Log = NULL;
ULONG Sequence = 0;
//
// Maximum amount of buffers we will grab for buffered unread data
//
ULONG NumLog = 0;
ULONG MaxLog = 5;
//
// Semaphore for critical sections
//
SEMHANDLE LogMutex, HashMutex, FilterMutex;
//
// Unknown error string
//
CHAR errstring[32];
//----------------------------------------------------------------------
// F O R W A R D S
//----------------------------------------------------------------------
BOOLEAN
ApplyFilters(
PCHAR Text
);
//----------------------------------------------------------------------
// V X D C O N T R O L
//----------------------------------------------------------------------
//
// Device declaration
//
Declare_Virtual_Device(FILEMON)
//
// Message handlers - we only care about dynamic loading and unloading
//
DefineControlHandler(SYS_DYNAMIC_DEVICE_INIT, OnSysDynamicDeviceInit);
DefineControlHandler(SYS_DYNAMIC_DEVICE_EXIT, OnSysDynamicDeviceExit);
DefineControlHandler(W32_DEVICEIOCONTROL, OnW32Deviceiocontrol);
//----------------------------------------------------------------------
//
// ControlDispatcher
//
// Multiplexes incoming VxD messages from Windows to their handlers.
//
//----------------------------------------------------------------------
BOOL
__cdecl ControlDispatcher(
DWORD dwControlMessage,
DWORD EBX,
DWORD EDX,
DWORD ESI,
DWORD EDI,
DWORD ECX
)
{
START_CONTROL_DISPATCH
ON_W32_DEVICEIOCONTROL(OnW32Deviceiocontrol);
ON_SYS_DYNAMIC_DEVICE_INIT(OnSysDynamicDeviceInit);
ON_SYS_DYNAMIC_DEVICE_EXIT(OnSysDynamicDeviceExit);
END_CONTROL_DISPATCH
return TRUE;
}
//----------------------------------------------------------------------
// P A T T E R N M A T C H I N G R O U T I N E S
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//
// MatchOkay
//
// Only thing left after compare is more mask. This routine makes
// sure that its a valid wild card ending so that its really a match.
//
//----------------------------------------------------------------------
BOOLEAN
MatchOkay(
PCHAR Pattern
)
{
//
// If pattern isn't empty, it must be a wildcard
//
if( *Pattern && *Pattern != '*' ) {
return FALSE;
}
//
// Matched
//
return TRUE;
}
//----------------------------------------------------------------------
//
// MatchWithPattern
//
// Performs nifty wildcard comparison.
//
//----------------------------------------------------------------------
BOOLEAN
MatchWithPattern(
PCHAR Pattern,
PCHAR Name
)
{
CHAR upcase;
//
// End of pattern?
//
if( !*Pattern ) {
return FALSE;
}
//
// If we hit a wild card, do recursion
//
if( *Pattern == '*' ) {
Pattern++;
while( *Name && *Pattern ) {
if( *Name >= 'a' && *Name <= 'z' )
upcase = *Name - 'a' + 'A';
else
upcase = *Name;
//
// See if this substring matches
//
if( *Pattern == upcase || *Name == '*' ) {
if( MatchWithPattern( 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( *Name >= 'a' && *Name <= 'z' )
upcase = *Name - 'a' + 'A';
else
upcase = *Name;
if( *Pattern == upcase ) {
Pattern++;
Name++;
} else {
return FALSE;
}
}
//
// If not done, recurse
//
if( *Name ) {
return MatchWithPattern( Pattern, Name );
}
//
// Make sure its a match
//
return MatchOkay( Pattern );
}
//----------------------------------------------------------------------
// B U F F E R M A N A G E M E N T
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//
// FilemonFreeLog
//
// Frees all the data output buffers that we have currently allocated.
//
//----------------------------------------------------------------------
VOID
FilemonFreeLog(
VOID
)
{
PLOG_BUF prev;
//
// Just traverse the list of allocated output buffers
//
while( Log ) {
prev = Log->Next;
PageFree( Log->Handle, 0 );
Log = prev;
}
}
//----------------------------------------------------------------------
//
// FilemonNewLog
//
// Called when the current buffer has filled up. This moves us to the
// pre-allocated buffer and then allocates another buffer.
//
// Returns FALSE if another thread is already allocating a buffer.
//
//----------------------------------------------------------------------
BOOLEAN
FilemonNewLog( VOID
)
{
PLOG_BUF prev = Log, newLog;
static busyAllocating = FALSE;
MEMHANDLE hNewLog;
//
// If we have maxed out or haven't accessed the current Log
// just return.
//
if( MaxLog == NumLog ) {
Log->Len = 0;
return TRUE;
}
//
// If the output buffer we currently are using is empty, just
// use it, or if we are busy already allocating a buffer, return
//
if( !Log->Len || busyAllocating ) {
return !busyAllocating;
}
//
// Allocate a new output buffer. Release lock to prevent deadlock
// on reentrance (allocating memory can result in file I/O)
//
busyAllocating = TRUE;
dprintf("Pageallocate: num:%d\n", NumLog );
Signal_Semaphore( LogMutex );
PageAllocate(LOGBUFPAGES, PG_SYS, 0, 0, 0, 0, NULL, PAGELOCKED,
(PMEMHANDLE) &hNewLog, (PVOID) &newLog );
Wait_Semaphore( LogMutex, BLOCK_SVC_INTS );
dprintf("Pageallocate done: num:%d\n", NumLog );
busyAllocating = FALSE;
if( newLog ) {
//
// Allocation was successful so add the buffer to the list
// of allocated buffers and increment the buffer count.
//
Log = newLog;
Log->Handle = hNewLog;
Log->Len = 0;
Log->Next = prev;
NumLog++;
} else {
//
// The allocation failed - just reuse the current buffer
//
Log->Len = 0;
}
return TRUE;
}
//----------------------------------------------------------------------
//
// FilemonOldestLog
//
// Goes through the linked list of storage buffers and returns the
// oldest one.
//
//----------------------------------------------------------------------
PLOG_BUF
FilemonOldestLog(
VOID
)
{
PLOG_BUF ptr = Log, prev = NULL;
//
// Traverse the list
//
while ( ptr->Next ) {
ptr = (prev = ptr)->Next;
}
//
// Remove the buffer from the list
//
if ( prev ) {
prev->Next = NULL;
}
NumLog--;
return ptr;
}
//----------------------------------------------------------------------
//
// FilemonResetLog
//
// When a GUI is no longer communicating with us, but we can't unload,
// we reset the storage buffers.
//
//----------------------------------------------------------------------
VOID
FilemonResetLog(
VOID
)
{
PLOG_BUF current, next;
//
// Traverse the list of output buffers
//
current = Log->Next;
while( current ) {
//
// Free the buffer
//
next = current->Next;
PageFree( current->Handle, 0 );
current = next;
}
//
// Move the output pointer in the buffer that's being kept
// the start of the buffer.
//
Log->Len = 0;
Log->Next = NULL;
}
//----------------------------------------------------------------------
//
// LogRecord
//
// Add a new string to Log, if it fits.
//
//----------------------------------------------------------------------
VOID
LogRecord(
ULONG time,
ULONG datetimelo,
ULONG datetimehi,
const char *format,
...
)
{
PENTRY Entry;
ULONG len;
va_list arg_ptr;
static CHAR text[MAXPATHLEN*3];
//
// If no filtering is desired, don't bother
//
if( !FilterOn ) {
return;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -