ObpLookupEntryDirectory(Windows内核学习笔记)
日期: 2020-04-08 分类: 个人收藏 368次阅读
PVOID
NTAPI
ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory,
IN PUNICODE_STRING Name,
IN ULONG Attributes,
IN UCHAR SearchShadow,
IN POBP_LOOKUP_CONTEXT Context)
{
BOOLEAN CaseInsensitive = FALSE;
POBJECT_HEADER_NAME_INFO HeaderNameInfo;
POBJECT_HEADER ObjectHeader;
ULONG HashValue;
ULONG HashIndex;
LONG TotalChars;
WCHAR CurrentChar;
POBJECT_DIRECTORY_ENTRY *AllocatedEntry;
POBJECT_DIRECTORY_ENTRY *LookupBucket;
POBJECT_DIRECTORY_ENTRY CurrentEntry;
PVOID FoundObject = NULL;
PWSTR Buffer;
PAGED_CODE();
if (!ObpLUIDDeviceMapsEnabled)
SearchShadow = FALSE;
/*检查输入的两个关键指针是否有效*/
if (!(Directory) || !(Name))
goto Quickie;
/* Get name information */
TotalChars = Name->Length / sizeof(WCHAR);//按照双字大小,计算对象名的字节数
Buffer = Name->Buffer;//得Name名称
/* Set up case-sensitivity */
if (Attributes & OBJ_CASE_INSENSITIVE)
CaseInsensitive = TRUE;//大小写不敏感
/*不是一个命名的对象*/
if (!(Buffer) || !(TotalChars))
goto Quickie;
/*计算hash值*/
for (HashValue = 0; TotalChars; TotalChars--)
{
/* Go to the next Character */
CurrentChar = *Buffer++;
/* Prepare the Hash */
HashValue += (HashValue << 1) + (HashValue >> 1);
/* Create the rest based on the name */
if (CurrentChar < 'a') HashValue += CurrentChar;
else if (CurrentChar > 'z') HashValue += RtlUpcaseUnicodeChar(CurrentChar);
else HashValue += (CurrentChar - ('a'-'A'));
}
/*计算hash索引*/
HashIndex = HashValue % 37;//Hash数组的大小为37
/*保存Hash值和Hash索引在Context中*/
Context->HashValue = HashValue;
Context->HashIndex = (USHORT)HashIndex;
/*得到当前HashIndex对应在Hash列表中的首地址*/
AllocatedEntry = &Directory->HashBuckets[HashIndex];
LookupBucket = AllocatedEntry;
/* Check if the directory is already locked */
if (!Context->DirectoryLocked)
{
/*申请共享锁*/
ObpAcquireDirectoryLockShared(Directory, Context);
}
/* Start looping */
while ((CurrentEntry = *AllocatedEntry))
{
/*Hash匹配*/
if (CurrentEntry->HashValue == HashValue)
{
/*对象体向对象头的转换*/
ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentEntry->Object);
/* Get the name information */
ASSERT(ObjectHeader->NameInfoOffset != 0);
HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
/*如果名字相同,长度相同*/
if ((Name->Length == HeaderNameInfo->Name.Length) &&
(RtlEqualUnicodeString(Name, &HeaderNameInfo->Name, CaseInsensitive)))
{
break;//发现目标,对象名相同
}
}
/*否则继续向下遍历*/
AllocatedEntry = &CurrentEntry->ChainLink;
}
/*若CurrentEntry非空,则说明找到了目标对象所在的节点 */
if (CurrentEntry)
{
/*设置当前节点到队列的最前面,为了下次查找效率的提高*/
if (AllocatedEntry != LookupBucket)
{
/* Check if the directory was locked or convert the lock */
if ((Context->DirectoryLocked) ||
(ExConvertPushLockSharedToExclusive(&Directory->Lock)))
{
/*当前目录项的值修改为当前目录项的下一个,因为当前目录项的内容要被放到最前面去*/
*AllocatedEntry = CurrentEntry->ChainLink;
/*连接之前的Hash表 */
CurrentEntry->ChainLink = *LookupBucket;
/*构建新的HashEntry*/
*LookupBucket = CurrentEntry;
}
}
/* 找到目标对象 */
FoundObject = CurrentEntry->Object;
goto Quickie;
}
else
{
/* Check if the directory was locked */
if (!Context->DirectoryLocked)
{
/* Release the lock */
ObpReleaseDirectoryLock(Directory, Context);
}
/* Check if we should scan the shadow directory */
if ((SearchShadow) && (Directory->DeviceMap))
{
/* FIXME: We don't support this yet */
ASSERT(FALSE);
}
}
Quickie:
/* Check if we inserted an object */
if (FoundObject)
{
/* Get the object name information */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(FoundObject);
ObpReferenceNameInfo(ObjectHeader);
/* Reference the object being looked up */
ObReferenceObject(FoundObject);
/* Check if the directory was locked */
if (!Context->DirectoryLocked)
{
/* Release the lock */
ObpReleaseDirectoryLock(Directory, Context);
}
}
/* Check if we found an object already */
if (Context->Object)
{
/* We already did a lookup, so remove this object's query reference */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Context->Object);
HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
ObpDereferenceNameInfo(HeaderNameInfo);
/* Also dereference the object itself */
ObDereferenceObject(Context->Object);
}
/* Return the object we found */
Context->Object = FoundObject;
return FoundObject;
}
“You’re never really done for, as long as you’ve got a good story and someone to tell it to.”
参考资料:
《Windows内核情景分析》
《Reactos》
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
上一篇: 计算机网络知识框架总结(复习)
下一篇: @程序员,一文让你掌握Python爬虫!
精华推荐