mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 09:11:42 +00:00
- Cleanup profiling and debugging code, add function comment headers and comment the functions in obdir.c
- Remove directory object parsing. Directory objects don't have parse routines. Instead, inline the lookup in ObFindObject (this hasn't been optimized yet, a lot of the code is now setting a = b, c = a, c = b. svn path=/trunk/; revision=22029
This commit is contained in:
parent
ab775b4798
commit
766bb1c7a8
4 changed files with 164 additions and 173 deletions
|
@ -118,8 +118,9 @@
|
|||
#define TAG_SYMLINK_TTARGET TAG('S', 'Y', 'T', 'T')
|
||||
#define TAG_SYMLINK_TARGET TAG('S', 'Y', 'M', 'T')
|
||||
|
||||
/* Object Name Tag */
|
||||
#define OB_NAME_TAG TAG('O','b','N','m')
|
||||
/* Object Manager Tags */
|
||||
#define OB_NAME_TAG TAG('O', 'b', 'N', 'm')
|
||||
#define OB_DIR_TAG TAG('O', 'b', 'D', 'i')
|
||||
|
||||
/* formerly located in ps/cid.c */
|
||||
#define TAG_CIDOBJECT TAG('C', 'I', 'D', 'O')
|
||||
|
|
|
@ -18,45 +18,29 @@
|
|||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#define OBP_PROFILE
|
||||
#ifdef OBP_PROFILE
|
||||
|
||||
LARGE_INTEGER ObpProfileTime;
|
||||
BOOLEAN ObpProfileComplete;
|
||||
|
||||
#define ObpStartProfile() \
|
||||
LARGE_INTEGER StartTime; \
|
||||
LARGE_INTEGER EndTime; \
|
||||
StartTime = KeQueryPerformanceCounter(NULL);
|
||||
|
||||
#define ObpEndProfile() \
|
||||
EndTime = KeQueryPerformanceCounter(NULL); \
|
||||
ObpProfileTime.QuadPart += (EndTime.QuadPart - \
|
||||
StartTime.QuadPart);
|
||||
|
||||
#define ObpCompleteProfile() \
|
||||
if (!wcscmp(Name, L"NlsSectionCP1252") && \
|
||||
!ObpProfileComplete) \
|
||||
{ \
|
||||
DPRINT1("******************************\n");\
|
||||
DPRINT1("Obp Profiling1 Complete: %I64d\n", \
|
||||
ObpProfileTime.QuadPart); \
|
||||
DPRINT1("******************************\n");\
|
||||
ObpProfileComplete = TRUE; \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define ObpStartProfile()
|
||||
#define ObpEndProfile()
|
||||
#define ObpCompleteProfile()
|
||||
|
||||
#endif
|
||||
|
||||
POBJECT_TYPE ObDirectoryType = NULL;
|
||||
|
||||
/* PRIVATE FUNCTIONS ******************************************************/
|
||||
|
||||
/*++
|
||||
* @name ObpInsertEntryDirectory
|
||||
*
|
||||
* The ObpInsertEntryDirectory routine <FILLMEIN>.
|
||||
*
|
||||
* @param Parent
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @param Context
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @param ObjectHeader
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @return TRUE if the object was inserted, FALSE otherwise.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent,
|
||||
|
@ -70,19 +54,10 @@ ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent,
|
|||
/* Make sure we have a name */
|
||||
ASSERT(ObjectHeader->NameInfoOffset != 0);
|
||||
|
||||
/* Validate the context */
|
||||
if ((Context->Object) || !(Context->DirectoryLocked) || !Parent)
|
||||
{
|
||||
DbgPrint("OB: ObpInsertEntryDirectory - invalid context %p %ld\n",
|
||||
Context, Context->DirectoryLocked);
|
||||
DbgBreakPoint();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Allocate a new Directory Entry */
|
||||
NewEntry = ExAllocatePoolWithTag(PagedPool,
|
||||
sizeof(OBJECT_DIRECTORY_ENTRY),
|
||||
TAG('O', 'b', 'D', 'i'));
|
||||
OB_DIR_TAG);
|
||||
if (!NewEntry) return FALSE;
|
||||
|
||||
/* Save the hash */
|
||||
|
@ -93,12 +68,6 @@ ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent,
|
|||
|
||||
/* Get the Allocated entry */
|
||||
AllocatedEntry = &Parent->HashBuckets[Context->HashIndex];
|
||||
DPRINT("ADD: Allocated Entry: %p. NewEntry: %p\n", AllocatedEntry, NewEntry);
|
||||
DPRINT("ADD: Name: %wZ, Hash: %lx\n", &HeaderNameInfo->Name, Context->HashIndex);
|
||||
DPRINT("ADD: Parent: %p. Name: %wZ\n",
|
||||
Parent,
|
||||
HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(Parent)) ?
|
||||
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(Parent))->Name : NULL);
|
||||
|
||||
/* Set it */
|
||||
NewEntry->ChainLink = *AllocatedEntry;
|
||||
|
@ -112,6 +81,31 @@ ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name ObpLookupEntryDirectory
|
||||
*
|
||||
* The ObpLookupEntryDirectory routine <FILLMEIN>.
|
||||
*
|
||||
* @param Directory
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @param Name
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @param Attributes
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @param SearchShadow
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @param Context
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @return Pointer to the object which was found, or NULL otherwise.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
PVOID
|
||||
NTAPI
|
||||
ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory,
|
||||
|
@ -133,21 +127,23 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory,
|
|||
PWSTR Buffer;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Always disable this until we have LUID Device Maps */
|
||||
/* Always disable this until we have DOS Device Maps */
|
||||
SearchShadow = FALSE;
|
||||
|
||||
/* Fail the following cases */
|
||||
/* Fail if we don't have a directory or name */
|
||||
if (!(Directory) || !(Name)) goto Quickie;
|
||||
|
||||
/* Get name information */
|
||||
TotalChars = Name->Length / sizeof(WCHAR);
|
||||
if (!(Directory) || !(Name) || !(Name->Buffer) || !(TotalChars))
|
||||
{
|
||||
goto Quickie;
|
||||
}
|
||||
Buffer = Name->Buffer;
|
||||
|
||||
/* Fail if the name is empty */
|
||||
if (!(Buffer) || !(TotalChars)) goto Quickie;
|
||||
|
||||
/* Set up case-sensitivity */
|
||||
if (Attributes & OBJ_CASE_INSENSITIVE) CaseInsensitive = TRUE;
|
||||
|
||||
/* Create the Hash */
|
||||
Buffer = Name->Buffer;
|
||||
for (HashValue = 0; TotalChars; TotalChars--)
|
||||
{
|
||||
/* Go to the next Character */
|
||||
|
@ -164,8 +160,6 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory,
|
|||
|
||||
/* Merge it with our number of hash buckets */
|
||||
HashIndex = HashValue % 37;
|
||||
DPRINT("LOOKUP: ObjectName: %wZ\n", Name);
|
||||
DPRINT("LOOKUP: Generated Hash: 0x%x. Generated Id: 0x%x\n", HashValue, HashIndex);
|
||||
|
||||
/* Save the result */
|
||||
Context->HashValue = HashValue;
|
||||
|
@ -174,7 +168,6 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory,
|
|||
/* Get the root entry and set it as our lookup bucket */
|
||||
AllocatedEntry = &Directory->HashBuckets[HashIndex];
|
||||
LookupBucket = AllocatedEntry;
|
||||
DPRINT("LOOKUP: Allocated Entry: %p. LookupBucket: %p\n", AllocatedEntry, LookupBucket);
|
||||
|
||||
/* Check if the directory is already locked */
|
||||
if (!Context->DirectoryLocked)
|
||||
|
@ -182,14 +175,12 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory,
|
|||
/* Lock it */
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceSharedLite(&Directory->Lock, TRUE);
|
||||
Context->LockStateSignature = 0xDDDD1234;
|
||||
}
|
||||
|
||||
/* Start looping */
|
||||
while ((CurrentEntry = *AllocatedEntry))
|
||||
{
|
||||
/* Do the hashes match? */
|
||||
DPRINT("CurrentEntry: %p. CurrentHash: %lx\n", CurrentEntry, CurrentEntry->HashValue);
|
||||
if (CurrentEntry->HashValue == HashValue)
|
||||
{
|
||||
/* Make sure that it has a name */
|
||||
|
@ -199,11 +190,9 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory,
|
|||
HeaderNameInfo = HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(CurrentEntry->Object));
|
||||
|
||||
/* Do the names match? */
|
||||
DPRINT("NameCheck: %wZ, %wZ\n", Name, &HeaderNameInfo->Name);
|
||||
if ((Name->Length == HeaderNameInfo->Name.Length) &&
|
||||
(RtlEqualUnicodeString(Name, &HeaderNameInfo->Name, CaseInsensitive)))
|
||||
{
|
||||
DPRINT("Found Name Match\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -242,16 +231,27 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory,
|
|||
/* Lock it */
|
||||
ExReleaseResourceLite(&Directory->Lock);
|
||||
KeLeaveCriticalRegion();
|
||||
Context->LockStateSignature = 0xEEEE1234;
|
||||
}
|
||||
|
||||
Quickie:
|
||||
/* Return the object we found */
|
||||
DPRINT("Object Found: %p Context: %p\n", FoundObject, Context);
|
||||
Context->Object = FoundObject;
|
||||
return FoundObject;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name ObpDeleteEntryDirectory
|
||||
*
|
||||
* The ObpDeleteEntryDirectory routine <FILLMEIN>.
|
||||
*
|
||||
* @param Context
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @return TRUE if the object was deleted, FALSE otherwise.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
ObpDeleteEntryDirectory(POBP_LOOKUP_CONTEXT Context)
|
||||
|
@ -267,8 +267,6 @@ ObpDeleteEntryDirectory(POBP_LOOKUP_CONTEXT Context)
|
|||
/* Get the Entry */
|
||||
AllocatedEntry = &Directory->HashBuckets[Context->HashIndex];
|
||||
CurrentEntry = *AllocatedEntry;
|
||||
DPRINT("DEL: Parent: %p, Hash: %lx, AllocatedEntry: %p, CurrentEntry: %p\n",
|
||||
Directory, Context->HashIndex, AllocatedEntry, CurrentEntry);
|
||||
|
||||
/* Unlink the Entry */
|
||||
*AllocatedEntry = CurrentEntry->ChainLink;
|
||||
|
@ -281,80 +279,13 @@ ObpDeleteEntryDirectory(POBP_LOOKUP_CONTEXT Context)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ObpParseDirectory(PVOID Object,
|
||||
PVOID * NextObject,
|
||||
PUNICODE_STRING FullPath,
|
||||
PWSTR * Path,
|
||||
ULONG Attributes,
|
||||
POBP_LOOKUP_CONTEXT Context)
|
||||
{
|
||||
PWSTR Start;
|
||||
PWSTR End;
|
||||
PVOID FoundObject;
|
||||
//KIRQL oldlvl;
|
||||
UNICODE_STRING StartUs;
|
||||
|
||||
*NextObject = NULL;
|
||||
|
||||
if ((*Path) == NULL)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
Start = *Path;
|
||||
if (*Start == L'\\')
|
||||
Start++;
|
||||
|
||||
End = wcschr(Start, L'\\');
|
||||
if (End != NULL)
|
||||
{
|
||||
*End = 0;
|
||||
}
|
||||
|
||||
//KeAcquireSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), &oldlvl);
|
||||
RtlInitUnicodeString(&StartUs, Start);
|
||||
Context->DirectoryLocked = TRUE;
|
||||
Context->Directory = Object;
|
||||
FoundObject = ObpLookupEntryDirectory(Object, &StartUs, Attributes, FALSE, Context);
|
||||
if (FoundObject == NULL)
|
||||
{
|
||||
//KeReleaseSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), oldlvl);
|
||||
if (End != NULL)
|
||||
{
|
||||
*End = L'\\';
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
ObReferenceObjectByPointer(FoundObject,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
UserMode);
|
||||
//KeReleaseSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), oldlvl);
|
||||
if (End != NULL)
|
||||
{
|
||||
*End = L'\\';
|
||||
*Path = End;
|
||||
}
|
||||
else
|
||||
{
|
||||
*Path = NULL;
|
||||
}
|
||||
|
||||
*NextObject = FoundObject;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* FUNCTIONS **************************************************************/
|
||||
|
||||
/*++
|
||||
* @name NtOpenDirectoryObject
|
||||
* @implemented NT4
|
||||
*
|
||||
* The NtOpenDirectoryObject opens a namespace directory object.
|
||||
* The NtOpenDirectoryObject routine opens a namespace directory object.
|
||||
*
|
||||
* @param DirectoryHandle
|
||||
* Variable which receives the directory handle.
|
||||
|
@ -381,25 +312,26 @@ NtOpenDirectoryObject (OUT PHANDLE DirectoryHandle,
|
|||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Check if we need to do any probing */
|
||||
if(PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
/* Probe the return handle */
|
||||
ProbeForWriteHandle(DirectoryHandle);
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
/* Get the error code */
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtOpenDirectoryObject failed, Status: 0x%x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
/* If we failed, return the error */
|
||||
if(!NT_SUCCESS(Status)) return Status;
|
||||
}
|
||||
|
||||
/* Open the directory object */
|
||||
Status = ObOpenObjectByName(ObjectAttributes,
|
||||
ObDirectoryType,
|
||||
NULL,
|
||||
|
@ -411,15 +343,18 @@ NtOpenDirectoryObject (OUT PHANDLE DirectoryHandle,
|
|||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
/* Write back the handle to the caller */
|
||||
*DirectoryHandle = hDirectory;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
/* Get the exception code */
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
|
||||
/* Return the status to the caller */
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -427,7 +362,7 @@ NtOpenDirectoryObject (OUT PHANDLE DirectoryHandle,
|
|||
* @name NtQueryDirectoryObject
|
||||
* @implemented NT4
|
||||
*
|
||||
* The NtQueryDirectoryObject Reads information from a directory in
|
||||
* The NtQueryDirectoryObject routine reads information from a directory in
|
||||
* the system namespace.
|
||||
*
|
||||
* @param DirectoryHandle
|
||||
|
@ -482,41 +417,38 @@ NtQueryDirectoryObject(IN HANDLE DirectoryHandle,
|
|||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Check if we need to do any probing */
|
||||
if(PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
/* a test showed that the Buffer pointer just has to be 16 bit aligned,
|
||||
propably due to the fact that most information that needs to be copied
|
||||
is unicode strings */
|
||||
/* Probe the buffer (assuming it will hold Unicode characters) */
|
||||
ProbeForWrite(Buffer, BufferLength, sizeof(WCHAR));
|
||||
|
||||
/* Probe the context and copy it unless scan-restart was requested */
|
||||
ProbeForWriteUlong(Context);
|
||||
if(!RestartScan)
|
||||
{
|
||||
SkipEntries = *Context;
|
||||
}
|
||||
if(ReturnLength != NULL)
|
||||
{
|
||||
ProbeForWriteUlong(ReturnLength);
|
||||
}
|
||||
if (!RestartScan) SkipEntries = *Context;
|
||||
|
||||
/* Probe the return length if the caller specified one */
|
||||
if(ReturnLength) ProbeForWriteUlong(ReturnLength);
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
/* Get the exception code */
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtQueryDirectoryObject failed, Status: 0x%x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
/* Return the exception to caller if we failed */
|
||||
if(!NT_SUCCESS(Status)) return Status;
|
||||
}
|
||||
else if(!RestartScan)
|
||||
else if (!RestartScan)
|
||||
{
|
||||
/* This is kernel mode, save the context without probing, if needed */
|
||||
SkipEntries = *Context;
|
||||
}
|
||||
|
||||
/* Get a reference to directory */
|
||||
Status = ObReferenceObjectByHandle(DirectoryHandle,
|
||||
DIRECTORY_QUERY,
|
||||
ObDirectoryType,
|
||||
|
@ -525,9 +457,11 @@ NtQueryDirectoryObject(IN HANDLE DirectoryHandle,
|
|||
NULL);
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: TODO. UNIMPLEMENTED */
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Return status to caller */
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -535,7 +469,7 @@ NtQueryDirectoryObject(IN HANDLE DirectoryHandle,
|
|||
* @name NtCreateDirectoryObject
|
||||
* @implemented NT4
|
||||
*
|
||||
* The NtOpenDirectoryObject creates or opens a directory object.
|
||||
* The NtOpenDirectoryObject routine creates or opens a directory object.
|
||||
*
|
||||
* @param DirectoryHandle
|
||||
* Variable which receives the directory handle.
|
||||
|
@ -567,25 +501,26 @@ NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle,
|
|||
"DesiredAccess %x, ObjectAttributes %x\n",
|
||||
DirectoryHandle, DesiredAccess, ObjectAttributes);
|
||||
|
||||
/* Check if we need to do any probing */
|
||||
if(PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
/* Probe the return handle */
|
||||
ProbeForWriteHandle(DirectoryHandle);
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
/* Get the error code */
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtCreateDirectoryObject failed, Status: 0x%x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
/* If we failed, return the error */
|
||||
if(!NT_SUCCESS(Status)) return Status;
|
||||
}
|
||||
|
||||
/* Create the object */
|
||||
Status = ObCreateObject(PreviousMode,
|
||||
ObDirectoryType,
|
||||
ObjectAttributes,
|
||||
|
@ -595,9 +530,9 @@ NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle,
|
|||
0,
|
||||
0,
|
||||
(PVOID*)&Directory);
|
||||
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
/* Insert it into the handle table */
|
||||
Status = ObInsertObject((PVOID)Directory,
|
||||
NULL,
|
||||
DesiredAccess,
|
||||
|
@ -608,18 +543,22 @@ NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle,
|
|||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
/* Return the handle back to the caller */
|
||||
*DirectoryHandle = hDirectory;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
/* Get the exception code */
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
|
||||
/* ReactOS HACK: ObInsertObject double-references */
|
||||
ObDereferenceObject(Directory);
|
||||
}
|
||||
|
||||
/* Return status to caller */
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,6 @@ ObInit(VOID)
|
|||
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
|
||||
ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
|
||||
ObjectTypeInitializer.UseDefaultObject = FALSE;
|
||||
ObjectTypeInitializer.ParseProcedure = (OB_PARSE_METHOD)ObpParseDirectory;
|
||||
ObjectTypeInitializer.MaintainTypeList = FALSE;
|
||||
ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
|
||||
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY);
|
||||
|
|
|
@ -107,11 +107,62 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
|||
|
||||
while (TRUE)
|
||||
{
|
||||
DPRINT("current %S\n",current);
|
||||
CurrentHeader = BODY_TO_HEADER(CurrentObject);
|
||||
|
||||
DPRINT("Current ObjectType %wZ\n",
|
||||
&CurrentHeader->Type->Name);
|
||||
/* Loop as long as we're dealing with a directory */
|
||||
while (CurrentHeader->Type == ObDirectoryType)
|
||||
{
|
||||
PWSTR Start, End;
|
||||
PVOID FoundObject;
|
||||
UNICODE_STRING StartUs;
|
||||
NextObject = NULL;
|
||||
|
||||
if (!current) goto Next;
|
||||
|
||||
Start = current;
|
||||
if (*Start == L'\\') Start++;
|
||||
|
||||
End = wcschr(Start, L'\\');
|
||||
if (End != NULL) *End = 0;
|
||||
|
||||
RtlInitUnicodeString(&StartUs, Start);
|
||||
Context->DirectoryLocked = TRUE;
|
||||
Context->Directory = CurrentObject;
|
||||
FoundObject = ObpLookupEntryDirectory(CurrentObject, &StartUs, Attributes, FALSE, Context);
|
||||
if (FoundObject == NULL)
|
||||
{
|
||||
if (End != NULL)
|
||||
{
|
||||
*End = L'\\';
|
||||
}
|
||||
goto Next;
|
||||
}
|
||||
|
||||
ObReferenceObjectByPointer(FoundObject,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
UserMode);
|
||||
if (End != NULL)
|
||||
{
|
||||
*End = L'\\';
|
||||
current = End;
|
||||
}
|
||||
else
|
||||
{
|
||||
current = NULL;
|
||||
}
|
||||
|
||||
NextObject = FoundObject;
|
||||
|
||||
Next:
|
||||
if (NextObject == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
ObDereferenceObject(CurrentObject);
|
||||
CurrentObject = NextObject;
|
||||
CurrentHeader = BODY_TO_HEADER(CurrentObject);
|
||||
}
|
||||
|
||||
if (CurrentHeader->Type->TypeInfo.ParseProcedure == NULL)
|
||||
{
|
||||
|
@ -136,6 +187,7 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
|||
ObjectCreateInfo->ProbeMode);
|
||||
}
|
||||
|
||||
|
||||
if (NextObject == NULL)
|
||||
{
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue