Author: ion
Date: Thu May 25 03:20:50 2006
New Revision: 22029
URL:
http://svn.reactos.ru/svn/reactos?rev=22029&view=rev
Log:
- 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.
Modified:
trunk/reactos/ntoskrnl/include/internal/tag.h
trunk/reactos/ntoskrnl/ob/obdir.c
trunk/reactos/ntoskrnl/ob/obinit.c
trunk/reactos/ntoskrnl/ob/obname.c
Modified: trunk/reactos/ntoskrnl/include/internal/tag.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/include/internal/t…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/tag.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/tag.h Thu May 25 03:20:50 2006
@@ -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')
Modified: trunk/reactos/ntoskrnl/ob/obdir.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obdir.c?rev=220…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obdir.c (original)
+++ trunk/reactos/ntoskrnl/ob/obdir.c Thu May 25 03:20:50 2006
@@ -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 @@
/* 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 @@
/* 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 @@
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 @@
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 @@
/* 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 @@
/* 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 @@
/* 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 @@
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 @@
/* 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 @@
/* 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 @@
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 @@
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 @@
{
_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 @@
* @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 @@
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;
- }
- }
- else if(!RestartScan)
- {
+ /* Return the exception to caller if we failed */
+ if(!NT_SUCCESS(Status)) return Status;
+ }
+ 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 @@
NULL);
if(NT_SUCCESS(Status))
{
+ /* FIXME: TODO. UNIMPLEMENTED */
Status = STATUS_INSUFFICIENT_RESOURCES;
}
+ /* Return status to caller */
return Status;
}
@@ -535,7 +469,7 @@
* @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 @@
"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 @@
0,
0,
(PVOID*)&Directory);
-
if(NT_SUCCESS(Status))
{
+ /* Insert it into the handle table */
Status = ObInsertObject((PVOID)Directory,
NULL,
DesiredAccess,
@@ -608,18 +543,22 @@
{
_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;
}
Modified: trunk/reactos/ntoskrnl/ob/obinit.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obinit.c?rev=22…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obinit.c (original)
+++ trunk/reactos/ntoskrnl/ob/obinit.c Thu May 25 03:20:50 2006
@@ -77,7 +77,6 @@
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);
Modified: trunk/reactos/ntoskrnl/ob/obname.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obname.c?rev=22…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obname.c (original)
+++ trunk/reactos/ntoskrnl/ob/obname.c Thu May 25 03:20:50 2006
@@ -107,11 +107,62 @@
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)
{
@@ -135,6 +186,7 @@
NULL,
ObjectCreateInfo->ProbeMode);
}
+
if (NextObject == NULL)
{