?? filemon.c
字號:
//
// 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 it matches the exclusion string, do not log it
//
Wait_Semaphore( FilterMutex, BLOCK_SVC_INTS );
for( i = 0; i < NumExcludeFilters; i++ ) {
if( MatchWithPattern( ExcludeFilters[i], Text ) ) {
Signal_Semaphore( FilterMutex );
return FALSE;
}
}
//
// If it matches an include filter then log it
//
for( i = 0; i < NumIncludeFilters; i++ ) {
if( MatchWithPattern( IncludeFilters[i], Text )) {
Signal_Semaphore( FilterMutex );
return TRUE;
}
}
//
// It didn't match any include filters so don't log
//
Signal_Semaphore( FilterMutex );
return FALSE;
}
//----------------------------------------------------------------------
// P A T H P A R S I N G
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//
// FilemonConvertUnparsedPath
//
// Converts an unparsed unicode path to ANSI. This is only used for
// UNC paths except for the special cases of renames and findopens.
//
//----------------------------------------------------------------------
VOID
FilemonConvertUnparsedPath(
pioreq pir,
PCHAR fullpathname
)
{
_QWORD result;
UniToBCS( fullpathname, pir->ir_upath, wstrlen( pir->ir_upath ),
MAXPATHLEN, BCS_WANSI, &result );
fullpathname[ result.ddLower ] = 0;
}
//----------------------------------------------------------------------
//
// FilemonConvertParsedPath
//
// Converts a parsed unicode path to ANSI.
//
//----------------------------------------------------------------------
VOID
FilemonConvertParsedPath(
int drive,
path_t ppath,
int codepage,
PCHAR fullpathname
)
{
int i = 0;
_QWORD result;
if( drive != 0xFF ) {
//
// Its a volume-based path
//
fullpathname[0] = drive+'A'-1;
fullpathname[1] = ':';
i = 2;
}
fullpathname[i] = 0;
UniToBCSPath( &fullpathname[i], ppath->pp_elements,
MAXPATHLEN-1, codepage, &result );
fullpathname[ i + result.ddLower ] = 0;
}
//----------------------------------------------------------------------
//
// FilemonConvertMixedPath
//
// This converts a mix of unparsed and parsed paths to ANSI. The
// unparsed path is used for server/share, whereas the parsed
// path is used for the directory/file. Only UNC rename and findopen
// use this.
//
//----------------------------------------------------------------------
VOID
FilemonConvertMixedPath(
pioreq pir,
path_t ppath,
int codepage,
PCHAR fullpathname
)
{
int i, slashes;
_QWORD result;
UniToBCS( fullpathname, pir->ir_upath, wstrlen( pir->ir_upath ), MAXPATHLEN-1,
codepage, &result );
fullpathname[ result.ddLower ] = 0;
slashes = 0;
for( i = 0; i < result.ddLower; i++ ) {
//
// We find the 4th slash: \\Server\share\...
//
if( fullpathname[i] == '\\' && ++slashes == 4 ) break;
}
if( slashes == 4 ) {
FilemonConvertParsedPath( 0xFF, ppath, codepage, &fullpathname[i]);
}
}
//----------------------------------------------------------------------
//
// FilemonConvertPath
//
// Converts a unicode path name to ANSI.
//
//----------------------------------------------------------------------
PCHAR
FilemonConvertPath(
CONVERT_TYPE converttype,
int drive,
pioreq pir,
int codepage,
PCHAR fullpathname
)
{
if( drive != 0xFF ) {
//
// Its a volume-based path
//
switch( converttype ) {
case CONVERT_RENAME_TARGET:
FilemonConvertParsedPath( drive, pir->ir_ppath2, codepage, fullpathname );
break;
default:
FilemonConvertParsedPath( drive, pir->ir_ppath, codepage, fullpathname );
break;
}
} else {
//
// Its a UNC path. The parsed path doesn't include the
// server/share, so we get that from the unparsed path.
//
switch( converttype ) {
case CONVERT_STANDARD:
FilemonConvertUnparsedPath( pir, fullpathname );
break;
case CONVERT_FINDOPEN:
case CONVERT_RENAME_SOURCE:
FilemonConvertMixedPath( pir, pir->ir_ppath, codepage, fullpathname );
break;
case CONVERT_RENAME_TARGET:
FilemonConvertMixedPath( pir, pir->ir_ppath2, codepage, fullpathname );
break;
}
}
return fullpathname;
}
//----------------------------------------------------------------------
//
// FilemonGetFullPath
//
// Returns the full pathname of a file, if we can obtain one, else
// returns a handle.
//
//----------------------------------------------------------------------
PCHAR
FilemonGetFullPath(
fh_t filenumber,
PCHAR fullname,
int Drive,
int ResType,
int CodePage,
pioreq pir
)
{
PHASH_ENTRY hashEntry;
pIFSFunc enumFunc;
ifsreq ifsr;
path_t uniFullName;
int retval;
//
// See if we find the key in the hash table.
//
Wait_Semaphore( HashMutex, BLOCK_SVC_INTS );
hashEntry = HashTable[ HASHOBJECT( filenumber ) ];
while( hashEntry &&
hashEntry->filenumber != filenumber &&
hashEntry->drive != (Drive & 0xFF)) {
hashEntry = hashEntry->Next;
}
Signal_Semaphore( HashMutex );
fullname[0] = 0;
if( hashEntry ) {
strcpy( fullname, hashEntry->FullName );
} else {
//
// File name isn't in the table, so ask the
// underlying file system
//
sprintf( fullname, "0x%X", filenumber );
uniFullName = IFSMgr_GetHeap( MAXPATHLEN * sizeof(WCHAR) + sizeof( path_t));
if( uniFullName ) {
//
// Send a query file name request
//
memcpy( &ifsr, pir, sizeof( ifsreq ));
ifsr.ifsir.ir_flags = ENUMH_GETFILENAME;
ifsr.ifsir.ir_ppath = uniFullName;
enumFunc = ifsr.ifs_hndl->hf_misc->hm_func[HM_ENUMHANDLE];
retval = (*PrevIFSHookProc)(enumFunc, IFSFN_ENUMHANDLE,
Drive, ResType, CodePage,
(pioreq) &ifsr);
if( retval == ERROR_SUCCESS ) {
FilemonConvertParsedPath( Drive, uniFullName, CodePage, fullname );
FilemonLogHash( Drive, filenumber, fullname );
}
IFSMgr_RetHeap( (void *) uniFullName );
}
}
return fullname;
}
//----------------------------------------------------------------------
// H O O K R O U T I N E
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//
// FilemonHookProc
//
// All (most) IFS functions come through this routine for us to look
// at.
//
//----------------------------------------------------------------------
#pragma optimize("", off)
int
_cdecl
FilemonHookProc(
pIFSFunc pfn,
int fn,
int Drive,
int ResType,
int CodePage,
pioreq pir
)
{
int retval;
char fullpathname[MAXPATHLEN];
char processname[64];
char data[MAXPATHLEN];
char drivestring[4];
ifsreq origifsr;
pioreq origir;
_WIN32_FIND_DATA *finddata;
struct srch_entry *search;
BOOLEAN log;
_QWORD result;
DWORD timelo, timehi;
DWORD timelo1, timehi1;
DWORD dostime, dosdate;
DWORD datetimelo, datetimehi;
int i, j;
//
// Inititlize default data.
//
data[0] = 0;
//
// Save original iorequest because some entries get modified.
//
origir = (pioreq) &origifsr;
memcpy( &origifsr, pir, sizeof( ifsreq ));
//
// Get the current process name.
//
FilemonGetProcess( processname );
//
// Get the time
//
VTD_Get_Real_Time( &timehi, &timelo );
datetimehi = IFSMgr_Get_DOSTime( &datetimelo );
dostime = VTD_Get_Date_And_Time( &dosdate );
datetimelo = dostime - ((datetimehi >> 11)& 0x1F)*60*60*1000 -
((datetimehi >> 5) & 0x3F)*60*1000 -
((datetimehi & 0x1F)*2000);
//
// Special case for close call, since after the file's closed
// we can't query its name
//
if( fn == IFSFN_CLOSE ) {
FilemonGetFullPath( origir->ir_fh, fullpathname, Drive, ResType, CodePage, origir );
}
//
// Call the previous hooker first, to get the return code.
//
retval = (*PrevIFSHookProc)(pfn, fn, Drive, ResType, CodePage, pir);
//
// Now extract parameters based on the function type.
//
dprintf("%d: %d\n", fn, pir->ir_fh );
switch( fn ) {
case IFSFN_OPEN:
FilemonConvertPath( CONVERT_STANDARD, Drive, origir, CodePage, fullpathname );
TIME_DIFF();
sprintf(data,"");
if( origir->ir_options & ACTION_CREATENEW ) strcat(data,"CREATENEW ");
if( origir->ir_options & ACTION_OPENEXISTING ) strcat(data,"OPENEXISTING ");
if( origir->ir_options & ACTION_REPLACEEXISTING ) strcat(data,"REPLACEEXISTING ");
switch (origir->ir_flags & ACCESS_MODE_MASK) {
case ACCESS_READONLY:
strcat(data,"READONLY ");
break;
case ACCESS_WRITEONLY:
strcat(data,"WRITEONLY ");
break;
case ACCESS_READWRITE:
strcat(data,"READWRITE ");
break;
case ACCESS_EXECUTE:
strcat(data,"EXECUTE ");
break;
default:
break;
}
switch (origir->ir_flags & SHARE_MODE_MASK) {
case SHARE_COMPATIBILITY:
strcat(data,"COMPATIBILITY ");
break;
case SHARE_DENYREADWRITE:
strcat(data,"DENYREADWRITE ");
break;
case SHARE_DENYWRITE:
strcat(data,"DENYWRITE ");
break;
case SHARE_DENYREAD:
strcat(data,"DENYREAD ");
break;
case SHARE_DENYNONE:
strcat(data,"DENYNONE ");
break;
default:
break;
}
LogRecord( timelo, datetimelo, datetimehi, "%s\tOpen\t%s\t%s\t%s",
processname, fullpathname,
data, ErrorString( retval ));
FilemonLogHash( Drive, pir->ir_fh, fullpathname );
break;
case IFSFN_READ:
case IFSFN_WRITE:
FilemonGetFullPath( origir->ir_fh, fullpathname, Drive, ResType, CodePage, origir );
if( ((fn == IFSFN_READ && FilterDef.logreads ) ||
(fn == IFSFN_WRITE && FilterDef.logwrites )) ) {
TIME_DIFF();
sprintf( data, "Offset: %ld Length: %ld", origir->ir_pos, origir->ir_length );
LogRecord( timelo, datetimelo, datetimehi, "%s\t%s\t%s\t%s\t%s",
processname, fn == IFSFN_READ? "Read" : "Write",
fullpathname,
data, ErrorString( retval ));
}
break;
case IFSFN_CLOSE:
if( FilterDef.logreads ) {
TIME_DIFF();
switch( origir->ir_flags ) {
case CLOSE_HANDLE: sprintf(data, "CLOSE_HANDLE"); break;
case CLOSE_FOR_PROCESS: sprintf(data, "CLOSE_FOR_PROCESS"); break;
case CLOSE_FINAL: sprintf(data, "CLOSE_FINAL"); break;
default: sprintf(data,"0x%02X",origir->ir_flags); break;
}
LogRecord( timelo, datetimelo, datetimehi, "%s\tClose\t%s\t%s\t%s", processname,
fullpathname, data, ErrorString( retval ));
}
if( origir->ir_flags == CLOSE_FINAL ) FilemonFreeHashEntry( Drive, origir->ir_fh);
break;
case IFSFN_DIR:
//
// This works around a special case I've seen when hiting the "browse" button in the
// "have disk" dialog of the hardware wizard
//
if( origir->ir_flags != 0xFF ) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -