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

    技术2025-12-18  9

    四。目录对象结构(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它可以根据路径来查找对象, 路径里还可以包含符号链接等。。。总之很复杂很强大。。。
    最新回复(0)