Author: ion
Date: Wed May 24 08:28:57 2006
New Revision: 22003
URL:
http://svn.reactos.ru/svn/reactos?rev=22003&view=rev
Log:
- Move all object directory stuff in dirobj.c and implement a simple profiler to measure
the time spent in those functions until the desktop appears. Enable with #define
OBP_PROFILE.
Modified:
trunk/reactos/ntoskrnl/include/internal/ob.h
trunk/reactos/ntoskrnl/ob/dirobj.c
trunk/reactos/ntoskrnl/ob/namespc.c
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/include/internal/o…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ob.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h Wed May 24 08:28:57 2006
@@ -105,6 +105,16 @@
PWSTR Name
);
+NTSTATUS
+NTAPI
+ObpCreateDirectory(
+ OB_OPEN_REASON Reason,
+ PEPROCESS Process,
+ PVOID ObjectBody,
+ ACCESS_MASK GrantedAccess,
+ ULONG HandleCount
+);
+
VOID
NTAPI
ObpRemoveEntryDirectory(PROS_OBJECT_HEADER Header);
@@ -120,6 +130,16 @@
ACCESS_MASK GrantedAccess,
ULONG HandleAttributes,
PHANDLE Handle
+);
+
+NTSTATUS
+NTAPI
+ObpParseDirectory(
+ PVOID Object,
+ PVOID * NextObject,
+ PUNICODE_STRING FullPath,
+ PWSTR * Path,
+ ULONG Attributes
);
VOID
Modified: trunk/reactos/ntoskrnl/ob/dirobj.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/dirobj.c?rev=22…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/dirobj.c (original)
+++ trunk/reactos/ntoskrnl/ob/dirobj.c Wed May 24 08:28:57 2006
@@ -11,6 +11,226 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
+
+#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
+
+/* PRIVATE FUNCTIONS ******************************************************/
+
+VOID
+NTAPI
+ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
+ PROS_OBJECT_HEADER Header,
+ PWSTR Name)
+{
+ KIRQL oldlvl;
+
+ ObpStartProfile();
+ ASSERT(HEADER_TO_OBJECT_NAME(Header));
+ HEADER_TO_OBJECT_NAME(Header)->Directory = Parent;
+
+ KeAcquireSpinLock(&Parent->Lock, &oldlvl);
+ InsertTailList(&Parent->head, &Header->Entry);
+ KeReleaseSpinLock(&Parent->Lock, oldlvl);
+ ObpEndProfile();
+}
+
+VOID
+NTAPI
+ObpRemoveEntryDirectory(PROS_OBJECT_HEADER Header)
+{
+ KIRQL oldlvl;
+
+ ObpStartProfile();
+ DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header);
+
+
KeAcquireSpinLock(&(HEADER_TO_OBJECT_NAME(Header)->Directory->Lock),&oldlvl);
+ if (Header->Entry.Flink && Header->Entry.Blink)
+ {
+ RemoveEntryList(&(Header->Entry));
+ Header->Entry.Flink = Header->Entry.Blink = NULL;
+ }
+
KeReleaseSpinLock(&(HEADER_TO_OBJECT_NAME(Header)->Directory->Lock),oldlvl);
+ ObpEndProfile();
+}
+
+NTSTATUS
+NTAPI
+ObpCreateDirectory(OB_OPEN_REASON Reason,
+ PEPROCESS Process,
+ PVOID ObjectBody,
+ ACCESS_MASK GrantedAccess,
+ ULONG HandleCount)
+{
+ PDIRECTORY_OBJECT Directory = ObjectBody;
+
+ ObpStartProfile();
+ if (Reason == ObCreateHandle)
+ {
+ InitializeListHead(&Directory->head);
+ KeInitializeSpinLock(&Directory->Lock);
+ }
+ ObpEndProfile();
+
+ return STATUS_SUCCESS;
+}
+
+PVOID
+NTAPI
+ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
+ PWSTR Name,
+ ULONG Attributes)
+{
+ PLIST_ENTRY current = DirectoryObject->head.Flink;
+ PROS_OBJECT_HEADER current_obj;
+
+ ObpStartProfile();
+ DPRINT("ObFindEntryDirectory(dir %x, name %S)\n",DirectoryObject, Name);
+ ObpCompleteProfile();
+
+ if (Name[0]==0)
+ {
+ ObpEndProfile();
+ return(DirectoryObject);
+ }
+ if (Name[0]=='.' && Name[1]==0)
+ {
+ ObpEndProfile();
+ return(DirectoryObject);
+ }
+ if (Name[0]=='.' && Name[1]=='.' && Name[2]==0)
+ {
+ ObpEndProfile();
+ return(HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(DirectoryObject))->Directory);
+ }
+ while (current!=(&(DirectoryObject->head)))
+ {
+ current_obj = CONTAINING_RECORD(current,ROS_OBJECT_HEADER,Entry);
+ DPRINT(" Scanning: %S for:
%S\n",HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name);
+ if (Attributes & OBJ_CASE_INSENSITIVE)
+ {
+ if (_wcsicmp(HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name)==0)
+ {
+ DPRINT("Found it %x\n",¤t_obj->Body);
+ ObpEndProfile();
+ return(¤t_obj->Body);
+ }
+ }
+ else
+ {
+ if ( wcscmp(HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name)==0)
+ {
+ DPRINT("Found it %x\n",¤t_obj->Body);
+ ObpEndProfile();
+ return(¤t_obj->Body);
+ }
+ }
+ current = current->Flink;
+ }
+ DPRINT(" Not Found: %s() = NULL\n",__FUNCTION__);
+ ObpEndProfile();
+ return(NULL);
+}
+
+NTSTATUS
+NTAPI
+ObpParseDirectory(PVOID Object,
+ PVOID * NextObject,
+ PUNICODE_STRING FullPath,
+ PWSTR * Path,
+ ULONG Attributes)
+{
+ PWSTR Start;
+ PWSTR End;
+ PVOID FoundObject;
+ KIRQL oldlvl;
+
+ ObpStartProfile();
+ DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n",
+ Object,Path,*Path);
+
+ *NextObject = NULL;
+
+ if ((*Path) == NULL)
+ {
+ ObpEndProfile();
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ Start = *Path;
+ if (*Start == L'\\')
+ Start++;
+
+ End = wcschr(Start, L'\\');
+ if (End != NULL)
+ {
+ *End = 0;
+ }
+
+ KeAcquireSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), &oldlvl);
+ FoundObject = ObpFindEntryDirectory(Object, Start, Attributes);
+ if (FoundObject == NULL)
+ {
+ KeReleaseSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), oldlvl);
+ if (End != NULL)
+ {
+ *End = L'\\';
+ }
+ ObpEndProfile();
+ 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;
+
+ ObpEndProfile();
+ return STATUS_SUCCESS;
+}
/* FUNCTIONS **************************************************************/
@@ -143,8 +363,6 @@
PDIRECTORY_OBJECT Directory;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
ULONG SkipEntries = 0;
- ULONG NextEntry = 0;
- ULONG CopyBytes = 0;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
@@ -191,201 +409,7 @@
NULL);
if(NT_SUCCESS(Status))
{
- PVOID TemporaryBuffer = ExAllocatePool(NonPagedPool, BufferLength);
- if(TemporaryBuffer != NULL)
- {
- PROS_OBJECT_HEADER EntryHeader;
- PLIST_ENTRY ListEntry;
- KIRQL OldLevel;
- ULONG RequiredSize = sizeof(OBJECT_DIRECTORY_INFORMATION);
- ULONG nDirectories = 0;
- POBJECT_DIRECTORY_INFORMATION DirInfo =
- (POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer;
-
- Status = STATUS_NO_MORE_ENTRIES;
-
- KeAcquireSpinLock(&Directory->Lock, &OldLevel);
-
- for(ListEntry = Directory->head.Flink;
- ListEntry != &Directory->head;
- ListEntry = ListEntry->Flink)
- {
- NextEntry++;
- if(SkipEntries == 0)
- {
- PUNICODE_STRING Name, Type;
- ULONG EntrySize;
-
- EntryHeader = CONTAINING_RECORD(ListEntry,
- ROS_OBJECT_HEADER,
- Entry);
-
- /* calculate the size of the required buffer space for this entry */
- Name = (HEADER_TO_OBJECT_NAME(EntryHeader)->Name.Length != 0 ?
- &HEADER_TO_OBJECT_NAME(EntryHeader)->Name : NULL);
- Type = &EntryHeader->Type->Name;
- EntrySize = sizeof(OBJECT_DIRECTORY_INFORMATION) +
- ((Name != NULL) ?
- ((ULONG)Name->Length + sizeof(WCHAR)) : 0) +
- (ULONG)EntryHeader->Type->Name.Length +
- sizeof(WCHAR);
-
- if(RequiredSize + EntrySize <= BufferLength)
- {
- /* the buffer is large enough to receive this entry. It
would've
- been much easier if the strings were directly appended to the
- OBJECT_DIRECTORY_INFORMATION structured written into the buffer
*/
- if(Name != NULL)
- DirInfo->ObjectName = *Name;
- else
- {
- DirInfo->ObjectName.Length =
- DirInfo->ObjectName.MaximumLength = 0;
- DirInfo->ObjectName.Buffer = NULL;
- }
- DirInfo->ObjectTypeName = *Type;
-
- nDirectories++;
- RequiredSize += EntrySize;
-
- Status = STATUS_SUCCESS;
-
- if(ReturnSingleEntry)
- {
- /* we're only supposed to query one entry, so bail and
copy the
- strings to the buffer */
- break;
- }
- DirInfo++;
- }
- else
- {
- if(ReturnSingleEntry)
- {
- /* the buffer is too small, so return the number of bytes
that
- would've been required for this query */
- RequiredSize += EntrySize;
- Status = STATUS_BUFFER_TOO_SMALL;
- }
-
- /* we couldn't query this entry, so leave the index that will
be stored
- in Context to this entry so the caller can query it the next
time
- he queries (hopefully with a buffer that is large enough then...)
*/
- NextEntry--;
-
- /* just copy the entries that fit into the buffer */
- break;
- }
- }
- else
- {
- /* skip the entry */
- SkipEntries--;
- }
- }
-
- if(!ReturnSingleEntry && ListEntry != &Directory->head)
- {
- /* there are more entries to enumerate but the buffer is already full.
- only tell this to the user if he queries multiple entries */
- Status = STATUS_MORE_ENTRIES;
- }
-
- if(NT_SUCCESS(Status) && nDirectories > 0)
- {
- PWSTR strbuf =
- (PWSTR)((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer +
- nDirectories + 1);
- PWSTR deststrbuf =
- (PWSTR)((POBJECT_DIRECTORY_INFORMATION)Buffer +
- nDirectories + 1);
-
- memset((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer +
- nDirectories,
- 0,
- sizeof(OBJECT_DIRECTORY_INFORMATION));
-
- CopyBytes = (nDirectories + 1) *
- sizeof(OBJECT_DIRECTORY_INFORMATION);
-
- /* copy the names from the objects and append them to the list of the
- objects. copy to the temporary buffer only because the directory
- lock can't be released and the buffer might be pagable memory! */
- for(DirInfo = (POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer;
- nDirectories > 0;
- nDirectories--, DirInfo++)
- {
- ULONG NameLength;
-
- if(DirInfo->ObjectName.Length > 0)
- {
- RtlCopyMemory(strbuf,
- DirInfo->ObjectName.Buffer,
- DirInfo->ObjectName.Length);
-
- /* change the buffer pointer to the buffer */
- DirInfo->ObjectName.Buffer = deststrbuf;
- NameLength = DirInfo->ObjectName.Length /
- sizeof(WCHAR);
-
- /* NULL-terminate the string */
- strbuf[NameLength] = L'\0';
- strbuf += NameLength + 1;
- deststrbuf += NameLength + 1;
-
- CopyBytes += (NameLength + 1) * sizeof(WCHAR);
- }
-
- RtlCopyMemory(strbuf,
- DirInfo->ObjectTypeName.Buffer,
- DirInfo->ObjectTypeName.Length);
-
- /* change the buffer pointer to the buffer */
- DirInfo->ObjectTypeName.Buffer = deststrbuf;
- NameLength = DirInfo->ObjectTypeName.Length /
- sizeof(WCHAR);
-
- /* NULL-terminate the string */
- strbuf[NameLength] = L'\0';
- strbuf += NameLength + 1;
- deststrbuf += NameLength + 1;
-
- CopyBytes += (NameLength + 1) * sizeof(WCHAR);
- }
- }
-
- KeReleaseSpinLock(&Directory->Lock, OldLevel);
- ObDereferenceObject(Directory);
-
- if(NT_SUCCESS(Status) || ReturnSingleEntry)
- {
- _SEH_TRY
- {
- if(CopyBytes != 0)
- {
- RtlCopyMemory(Buffer, TemporaryBuffer, CopyBytes);
- }
-
- *Context = NextEntry;
-
- if(ReturnLength != NULL)
- {
- *ReturnLength = RequiredSize;
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
- }
-
- ExFreePool(TemporaryBuffer);
- }
- else
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
+ Status = STATUS_INSUFFICIENT_RESOURCES;
}
return Status;
Modified: trunk/reactos/ntoskrnl/ob/namespc.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/namespc.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/namespc.c (original)
+++ trunk/reactos/ntoskrnl/ob/namespc.c Wed May 24 08:28:57 2006
@@ -242,184 +242,6 @@
/* FIXME: Release the DeviceMap Spinlock */
// KeReleasepinLock(DeviceMap->Lock, OldIrql);
-}
-
-VOID
-NTAPI
-ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
- PROS_OBJECT_HEADER Header,
- PWSTR Name)
-/*
- * FUNCTION: Add an entry to a namespace directory
- * ARGUMENTS:
- * Parent = directory to add in
- * Header = Header of the object to add the entry for
- * Name = Name to give the entry
- */
-{
- KIRQL oldlvl;
-
- ASSERT(HEADER_TO_OBJECT_NAME(Header));
- HEADER_TO_OBJECT_NAME(Header)->Directory = Parent;
-
- KeAcquireSpinLock(&Parent->Lock, &oldlvl);
- InsertTailList(&Parent->head, &Header->Entry);
- KeReleaseSpinLock(&Parent->Lock, oldlvl);
-}
-
-
-VOID
-NTAPI
-ObpRemoveEntryDirectory(PROS_OBJECT_HEADER Header)
-/*
- * FUNCTION: Remove an entry from a namespace directory
- * ARGUMENTS:
- * Header = Header of the object to remove
- */
-{
- KIRQL oldlvl;
-
- DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header);
-
-
KeAcquireSpinLock(&(HEADER_TO_OBJECT_NAME(Header)->Directory->Lock),&oldlvl);
- if (Header->Entry.Flink && Header->Entry.Blink)
- {
- RemoveEntryList(&(Header->Entry));
- Header->Entry.Flink = Header->Entry.Blink = NULL;
- }
- KeReleaseSpinLock(&(HEADER_TO_OBJECT_NAME(Header)->Directory->Lock),oldlvl);
-}
-
-NTSTATUS
-STDCALL
-ObpCreateDirectory(OB_OPEN_REASON Reason,
- PEPROCESS Process,
- PVOID ObjectBody,
- ACCESS_MASK GrantedAccess,
- ULONG HandleCount)
-{
- PDIRECTORY_OBJECT Directory = ObjectBody;
-
- if (Reason == ObCreateHandle)
- {
- InitializeListHead(&Directory->head);
- KeInitializeSpinLock(&Directory->Lock);
- }
-
- return STATUS_SUCCESS;
-}
-
-PVOID
-ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
- PWSTR Name,
- ULONG Attributes)
-{
- PLIST_ENTRY current = DirectoryObject->head.Flink;
- PROS_OBJECT_HEADER current_obj;
-
- DPRINT("ObFindEntryDirectory(dir %x, name %S)\n",DirectoryObject, Name);
-
- if (Name[0]==0)
- {
- return(DirectoryObject);
- }
- if (Name[0]=='.' && Name[1]==0)
- {
- return(DirectoryObject);
- }
- if (Name[0]=='.' && Name[1]=='.' && Name[2]==0)
- {
- return(HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(DirectoryObject))->Directory);
- }
- while (current!=(&(DirectoryObject->head)))
- {
- current_obj = CONTAINING_RECORD(current,ROS_OBJECT_HEADER,Entry);
- DPRINT(" Scanning: %S for:
%S\n",HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name);
- if (Attributes & OBJ_CASE_INSENSITIVE)
- {
- if (_wcsicmp(HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name)==0)
- {
- DPRINT("Found it %x\n",¤t_obj->Body);
- return(¤t_obj->Body);
- }
- }
- else
- {
- if ( wcscmp(HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name)==0)
- {
- DPRINT("Found it %x\n",¤t_obj->Body);
- return(¤t_obj->Body);
- }
- }
- current = current->Flink;
- }
- DPRINT(" Not Found: %s() = NULL\n",__FUNCTION__);
- return(NULL);
-}
-
-
-NTSTATUS STDCALL
-ObpParseDirectory(PVOID Object,
- PVOID * NextObject,
- PUNICODE_STRING FullPath,
- PWSTR * Path,
- ULONG Attributes)
-{
- PWSTR Start;
- PWSTR End;
- PVOID FoundObject;
- KIRQL oldlvl;
-
- DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n",
- Object,Path,*Path);
-
- *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);
- FoundObject = ObpFindEntryDirectory(Object, Start, Attributes);
- 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;
}
VOID