Filemon中的HASH TABLE

本文介绍了一个从Filemon中提取的代码片段,该片段用于通过FILE_OBJECT获取文件名等信息,适用于IO密集型操作如IRP_MJ_READ/IRP_MJ_WRITE的监控。文中详细描述了如何使用哈希表来高效地存储和检索文件名。

这段代码是从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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值