这段代码是从Filemon中提取出来的,适合做监控的朋友使用
主要是为了在IO比较频繁的例程比如IRP_MJ_READ/IRP_MJ_WRITE里通过FILE_OBJECT得到文件名等信息。这种方法比其他方法相对更加高效一些。比如FILEMON,TDI_FW都采用HASH TABLE来保存文件名或者其他信息。
//
// Structure for the fileobject/name hash table
//
typedef struct _nameentry {
PFILE_OBJECT FileObject;
struct _nameentry *Next;
CHAR FullPathName[];
} HASH_ENTRY, *PHASH_ENTRY;
//
// Number of hash buckets in the hash table
//
#define NUMHASH 0x100
//
// Hash function. Basically chops the low few bits of the file object
//
#if defined(_IA64_)
#define HASHOBJECT(_fileobject) (((ULONG_PTR)_fileobject)>>5)%NUMHASH
#else
#define HASHOBJECT(_fileobject) (((ULONG)_fileobject)>>5)%NUMHASH
#endif
//
// Hash table for keeping names around. This is necessary because
// at any time the name information in the fileobjects that we
// see can be deallocated and reused. If we want to print accurate
// names, we need to keep them around ourselves.
//
PHASH_ENTRY HashTable[NUMHASH];
//----------------------------------------------------------------------
// 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();
}
//----------------------------------------------------------------------
//
// FilemonGetFullPath
//
// Takes a fileobject and filename and returns a canonical path,
// nicely formatted, in fullpathname.
//
//----------------------------------------------------------------------
VOID
FilemonGetFullPath(
PFILE_OBJECT fileObject,
PCHAR fullPathName
)
{
PHASH_ENTRY hashEntry, newEntry;
//
// Lookup the object in the hash table to see if a name
// has already been generated for it
//
KeEnterCriticalRegion();
ExAcquireResourceSharedLite( &HashResource, TRUE );
hashEntry = HashTable[ HASHOBJECT( fileObject ) ];
while( hashEntry && hashEntry->FileObject != fileObject ) {
hashEntry = hashEntry->Next;
}
//
// Did we find an entry?
//
if( hashEntry ) {
//
// Yes, so get the name from the entry.
//
strcpy( fullPathName, hashEntry->FullPathName );
ExReleaseResourceLite( &HashResource );
KeLeaveCriticalRegion();
return;
}
ExReleaseResourceLite( &HashResource );
KeLeaveCriticalRegion();
//
// Allocate a hash entry
//
newEntry = ExAllocatePool( NonPagedPool,
sizeof(HASH_ENTRY ) + strlen( fullPathName ) + 1);
//
// If no memory for a new entry, oh well.
//
if( newEntry ) {
//
// Fill in the new entry
//
newEntry->FileObject = fileObject;
strcpy( newEntry->FullPathName, fullPathName );
//
// Put it in the hash table
//
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite( &HashResource, TRUE );
newEntry->Next = HashTable[ HASHOBJECT(fileObject) ];
HashTable[ HASHOBJECT(fileObject) ] = newEntry;
ExReleaseResourceLite( &HashResource );
KeLeaveCriticalRegion();
}
}
转自: http://hi.baidu.com/dongyang_sec/blog/item/22ef64127f1b19c8c2fd788a.html