四。目录对象结构(ObpLookupDirectoryEntry、ObpLookupObjectName) (一)

四。目录对象结构(ObpLookupDirectoryEntry、ObpLookupObjectName) (一)
2010年05月11日 星期二 14:31
第一篇在分析ObCreateObjectType函数中出现了ObpLookupDirectoryEntry。
这个函数的作用是查询指定的目录对象中是否包含某对象。

目录对象的数据结构是OBJECT_DIRECTORY
typedef struct _OBJECT_DIRECTORY {
   
struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[ NUMBER_HASH_BUCKETS ];
    EX_PUSH_LOCK Lock;
   
struct _DEVICE_MAP *DeviceMap;
   
ULONG SessionId;
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;

HashBuckets是一个根据哈希数组
哈希值是根据对象的名字计算出来的

typedef struct _OBJECT_DIRECTORY_ENTRY {
   
struct _OBJECT_DIRECTORY_ENTRY *ChainLink;
   
PVOID Object;
   
ULONG HashValue;
} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;

_OBJECT_DIRECTORY_ENTRY.ChainLink 把有相同哈希值的对象串联在一起


+-----------------------+
|    OBJECT_DIRECTORY   |
|        HashBuckets[37]+--+ (37个指针, 分别指向37个_OBJECT_DIRECTORY_ENTRY结构)
|                  Lock | | (HashValue相同的_OBJECT_DIRECTORY_ENTRY结构使用ChainLink串联起来)
+-----------------------+ | (这里只画出了一个指针)
+--------------------------+
V
+-----------------------+ +->+-----------------------+
|_OBJECT_DIRECTORY_ENTRY| | |_OBJECT_DIRECTORY_ENTRY|
|              ChainLink+--+ |              ChainLink+->.....
|                 Object|     |                 Object|
|              HashValue|     |              HashValue|
+-----------------------+     +-----------------------+

下面开始分析ObpLookupDirectoryEntry函数
PVOID
ObpLookupDirectoryEntry (
    IN POBJECT_DIRECTORY Directory,           
//目录对象
    IN PUNICODE_STRING Name,                   //搜索的名字
    IN ULONG Attributes,                       //指定是否区分大小写
    IN BOOLEAN SearchShadow,                   //是否搜索shadow directory
    OUT POBP_LOOKUP_CONTEXT LookupContext      //查询详细信息通过这个结构返回
    ) {
    ......
   
// 一些参数检测
    ......
   
   
// 根据名字计算一个哈希值, WcharLength是名字长度, Buffer指向Name->Buffer
    HashIndex = 0;
   
while (WcharLength--) {
        Wchar = *Buffer++;
        HashIndex += (HashIndex << 1) + (HashIndex >> 1);
       
if (Wchar < 'a') {
            HashIndex += Wchar;
        }
else if (Wchar > 'z') {
            HashIndex += RtlUpcaseUnicodeChar( (
WCHAR )Wchar );
        }
else {
            HashIndex += (Wchar - ('a'-'A'));
        }
    }
    HashValue = HashIndex;
    HashIndex %= NUMBER_HASH_BUCKETS;
    LookupContext->HashIndex = (
USHORT )HashIndex;
    LookupContext->HashValue = HashValue;
   
   
while (1) {
       
// 获取对应的哈希表项
        HeadDirectoryEntry = (POBJECT_DIRECTORY_ENTRY *)&Directory->HashBuckets[ HashIndex ];
        LookupBucket = HeadDirectoryEntry;

       
// 这个函数给目录上共享锁, _OBJECT_DIRECTORY.Lock 是共享锁数据结构
        if (!LookupContext->DirectoryLocked) {
            ObpLockDirectoryShared( Directory, LookupContext);
        }

// 遍历 _OBJECT_DIRECTORY_ENTRY.ChainLink 链表
        while ((DirectoryEntry = *HeadDirectoryEntry) != NULL ) {

           
if (DirectoryEntry->HashValue == HashValue) {
               
// 比较对象名称
                ObjectHeader = OBJECT_TO_OBJECT_HEADER( DirectoryEntry->Object );
                NameInfo = OBJECT_HEADER_TO_NAME_INFO_EXISTS( ObjectHeader );
               
if (RtlEqualUnicodeString( Name,
                                           &NameInfo->Name,
                                           CaseInSensitive )) {
                   
break ;
                }
            }

            HeadDirectoryEntry = &DirectoryEntry->ChainLink;
        }

       
if (DirectoryEntry) {
           
// 找到了对象所在的DirectoryEntry, 返回对应的OBJECT
            if (HeadDirectoryEntry != LookupBucket) {
               
if ( LookupContext->DirectoryLocked
                        ||
                     ExTryConvertPushLockSharedToExclusive(&Directory->Lock)) {

                    *HeadDirectoryEntry = DirectoryEntry->ChainLink;
                    DirectoryEntry->ChainLink = *LookupBucket;
                    *LookupBucket = DirectoryEntry;
                }
            }
            Object = DirectoryEntry->Object;
           
goto UPDATECONTEXT;
        }
else {
           
// 没有找到对象的DirectoryEntry
            if (!LookupContext->DirectoryLocked) {
                ObpUnlockDirectory( Directory, LookupContext );
            }
           
if (SearchShadow && Directory->DeviceMap != NULL ) {
                POBJECT_DIRECTORY NewDirectory;

                NewDirectory = ObpGetShadowDirectory (Directory);
               
if (NewDirectory != NULL ) {
                    Directory = NewDirectory;
                   
continue ;
                }
            }
           
goto UPDATECONTEXT;
        }
    }
UPDATECONTEXT:
    .....
   
return Object;
}

看过了查找指定目录下是否有指定名称的对象的函数后
再来看看一个功能更强大的函数ObpLookupObjectName
它可以根据路径来查找对象, 路径里还可以包含符号链接等。。。总之很复杂很强大。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值