四。目录对象结构(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它可以根据路径来查找对象, 路径里还可以包含符号链接等。。。总之很复杂很强大。。。
转载请注明原文地址: https://ibbs.8miu.com/read-2271284.html