Author: ion
Date: Thu May 25 00:06:13 2006
New Revision: 22015
URL:
http://svn.reactos.ru/svn/reactos?rev=22015&view=rev
Log:
- Rewrote the Object Directory implementation to follow the NT Structures in the NDK. This
got rid of the last remaining OBJECT_HEADER difference and switched over to
OBJECT_DIRECTORY.
- The low-level implementation is based on information from "Undocumented Windows
2000 Internals: A Programmer's Cookbook", with some modifications done by myself
to match the updated 2003 structures. This implementation was hackishly stuck into our
messed up high-level object lookup implementation, which now has 4 more band-aids. Still
needs a lot of work done to the upper echelons of object lookup, but at least this gets
rid of ROS-internal stuff.
Modified:
trunk/reactos/include/ndk/obtypes.h
trunk/reactos/ntoskrnl/cm/ntfunc.c
trunk/reactos/ntoskrnl/cm/registry.c
trunk/reactos/ntoskrnl/ex/win32k.c
trunk/reactos/ntoskrnl/include/internal/ob.h
trunk/reactos/ntoskrnl/ob/dirobj.c
trunk/reactos/ntoskrnl/ob/handle.c
trunk/reactos/ntoskrnl/ob/namespc.c
trunk/reactos/ntoskrnl/ob/ntobj.c
trunk/reactos/ntoskrnl/ob/object.c
trunk/reactos/subsystems/win32/win32k/include/winsta.h
trunk/reactos/subsystems/win32/win32k/main/dllmain.c
trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c
Modified: trunk/reactos/include/ndk/obtypes.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/include/ndk/obtypes.h?rev=2…
==============================================================================
--- trunk/reactos/include/ndk/obtypes.h (original)
+++ trunk/reactos/include/ndk/obtypes.h Thu May 25 00:06:13 2006
@@ -319,11 +319,43 @@
} OBJECT_TYPE;
//
+// Object Directory Structures
+//
+typedef struct _OBJECT_DIRECTORY_ENTRY
+{
+ struct _OBJECT_DIRECTORY_ENTRY *ChainLink;
+ PVOID Object;
+#if (NTDDI_VERSION >= NTDDI_WS03)
+ ULONG HashValue;
+#endif
+} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;
+
+typedef struct _OBJECT_DIRECTORY
+{
+ struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[NUMBER_HASH_BUCKETS];
+#if (NTDDI_VERSION < NTDDI_WINXP)
+ ERESOURCE Lock;
+#elif (NTDDI_VERSION >= NTDDI_WINXP)
+ ERESOURCE Lock; // FIXME: HACKHACK, SHOULD BE EX_PUSH_LOCK
+#endif
+#if (NTDDI_VERSION < NTDDI_WINXP)
+ BOOLEAN CurrentEntryValid;
+#else
+ struct _DEVICE_MAP *DeviceMap;
+#endif
+ ULONG SessionId;
+#if (NTDDI_VERSION == NTDDI_WINXP)
+ USHORT Reserved;
+ USHORT SymbolicLinkUsageCount;
+#endif
+} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;
+
+//
// Object Header Addon Information
//
typedef struct _OBJECT_HEADER_NAME_INFO
{
- struct _DIRECTORY_OBJECT *Directory;
+ POBJECT_DIRECTORY Directory;
UNICODE_STRING Name;
ULONG QueryReferences;
ULONG Reserved2;
@@ -385,47 +417,15 @@
} OBJECT_HEADER, *POBJECT_HEADER;
//
-// Object Directory Structures
-//
-typedef struct _OBJECT_DIRECTORY_ENTRY
-{
- struct _OBJECT_DIRECTORY_ENTRY *ChainLink;
- PVOID Object;
-#if (NTDDI_VERSION >= NTDDI_WS03)
- ULONG HashValue;
-#endif
-} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;
-
-typedef struct _OBJECT_DIRECTORY
-{
- struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[NUMBER_HASH_BUCKETS];
-#if (NTDDI_VERSION < NTDDI_WINXP)
- PERESOURCE Lock;
-#elif (NTDDI_VERSION >= NTDDI_WINXP)
- EX_PUSH_LOCK Lock;
-#endif
-#if (NTDDI_VERSION < NTDDI_WINXP)
- BOOLEAN CurrentEntryValid;
-#else
- struct _DEVICE_MAP *DeviceMap;
-#endif
- ULONG SessionId;
-#if (NTDDI_VERSION == NTDDI_WINXP)
- USHORT Reserved;
- USHORT SymbolicLinkUsageCount;
-#endif
-} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;
-
-//
// Device Map
//
typedef struct _DEVICE_MAP
{
- POBJECT_DIRECTORY DosDevicesDirectory;
- POBJECT_DIRECTORY GlobalDosDevicesDirectory;
- ULONG ReferenceCount;
- ULONG DriveMap;
- UCHAR DriveType[32];
+ POBJECT_DIRECTORY DosDevicesDirectory;
+ POBJECT_DIRECTORY GlobalDosDevicesDirectory;
+ ULONG ReferenceCount;
+ ULONG DriveMap;
+ UCHAR DriveType[32];
} DEVICE_MAP, *PDEVICE_MAP;
//
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/cm/ntfunc.c?rev=22…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/ntfunc.c (original)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c Thu May 25 00:06:13 2006
@@ -199,6 +199,7 @@
KPROCESSOR_MODE PreviousMode;
UNICODE_STRING CapturedClass = {0};
HANDLE hKey;
+ OBP_LOOKUP_CONTEXT Context;
PAGED_CODE();
@@ -262,7 +263,8 @@
&ObjectName,
(PVOID*)&Object,
&RemainingPath,
- CmiKeyType);
+ CmiKeyType,
+ &Context);
if (!NT_SUCCESS(Status))
{
PostCreateKeyInfo.Object = NULL;
@@ -1262,6 +1264,7 @@
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
REG_PRE_OPEN_KEY_INFORMATION PreOpenKeyInfo;
REG_POST_OPEN_KEY_INFORMATION PostOpenKeyInfo;
+ OBP_LOOKUP_CONTEXT Context;
PAGED_CODE();
@@ -1329,7 +1332,8 @@
&ObjectName,
(PVOID*)&Object,
&RemainingPath,
- CmiKeyType);
+ CmiKeyType,
+ &Context);
if (!NT_SUCCESS(Status))
{
DPRINT("CmpFindObject() returned 0x%08lx\n", Status);
Modified: trunk/reactos/ntoskrnl/cm/registry.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/cm/registry.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/registry.c (original)
+++ trunk/reactos/ntoskrnl/cm/registry.c Thu May 25 00:06:13 2006
@@ -704,6 +704,7 @@
PWSTR SubName;
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
+ OBP_LOOKUP_CONTEXT Context;
DPRINT("CmiConnectHive(%p, %p) called.\n",
KeyObjectAttributes, RegistryHive);
@@ -725,7 +726,8 @@
&ObjectName,
(PVOID*)&ParentKey,
&RemainingPath,
- CmiKeyType);
+ CmiKeyType,
+ &Context);
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
if (!NT_SUCCESS(Status))
Modified: trunk/reactos/ntoskrnl/ex/win32k.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ex/win32k.c?rev=22…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/win32k.c (original)
+++ trunk/reactos/ntoskrnl/ex/win32k.c Thu May 25 00:06:13 2006
@@ -86,14 +86,16 @@
PVOID *NextObject,
PUNICODE_STRING FullPath,
PWSTR *Path,
- ULONG Attributes)
+ ULONG Attributes,
+ POBP_LOOKUP_CONTEXT Context)
{
/* Call the Registered Callback */
return ExpWindowStationObjectParse(Object,
NextObject,
FullPath,
Path,
- Attributes);
+ Attributes,
+ Context);
}
NTSTATUS
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 Thu May 25 00:06:13 2006
@@ -11,21 +11,8 @@
struct _EPROCESS;
-typedef struct _DIRECTORY_OBJECT
-{
- CSHORT Type;
- CSHORT Size;
-
- /*
- * PURPOSE: Head of the list of our subdirectories
- */
- LIST_ENTRY head;
- KSPIN_LOCK Lock;
-} DIRECTORY_OBJECT, *PDIRECTORY_OBJECT;
-
typedef struct _ROS_OBJECT_HEADER
{
- LIST_ENTRY Entry;
LONG PointerCount;
union
{
@@ -46,6 +33,16 @@
QUAD Body;
} ROS_OBJECT_HEADER, *PROS_OBJECT_HEADER;
+typedef struct _OBP_LOOKUP_CONTEXT
+{
+ POBJECT_DIRECTORY Directory;
+ PVOID Object;
+ ULONG HashValue;
+ USHORT HashIndex;
+ BOOLEAN DirectoryLocked;
+ ULONG LockStateSignature;
+} OBP_LOOKUP_CONTEXT, *POBP_LOOKUP_CONTEXT;
+
#define BODY_TO_HEADER(objbdy) \
CONTAINING_RECORD((objbdy), ROS_OBJECT_HEADER, Body)
@@ -69,7 +66,7 @@
#define ObMarkHandleAsKernelHandle(Handle) \
(HANDLE)((ULONG_PTR)(Handle) | KERNEL_HANDLE_FLAG)
-extern PDIRECTORY_OBJECT NameSpaceRoot;
+extern POBJECT_DIRECTORY NameSpaceRoot;
extern POBJECT_TYPE ObSymbolicLinkType;
extern PHANDLE_TABLE ObpKernelHandleTable;
@@ -94,30 +91,27 @@
PVOID *NextObject,
PUNICODE_STRING FullPath,
PWSTR *Path,
- ULONG Attributes
-);
-
-VOID
-NTAPI
-ObpAddEntryDirectory(
- PDIRECTORY_OBJECT Parent,
- PROS_OBJECT_HEADER Header,
- 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);
+ ULONG Attributes,
+ POBP_LOOKUP_CONTEXT Context
+);
+
+BOOLEAN
+NTAPI
+ObpDeleteEntryDirectory(POBP_LOOKUP_CONTEXT Context);
+
+BOOLEAN
+NTAPI
+ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent,
+ IN POBP_LOOKUP_CONTEXT Context,
+ IN POBJECT_HEADER ObjectHeader);
+
+PVOID
+NTAPI
+ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory,
+ IN PUNICODE_STRING Name,
+ IN ULONG Attributes,
+ IN UCHAR SearchShadow,
+ IN POBP_LOOKUP_CONTEXT Context);
VOID
NTAPI
@@ -139,7 +133,8 @@
PVOID * NextObject,
PUNICODE_STRING FullPath,
PWSTR * Path,
- ULONG Attributes
+ ULONG Attributes,
+ POBP_LOOKUP_CONTEXT Context
);
VOID
@@ -157,7 +152,8 @@
PUNICODE_STRING ObjectName,
PVOID* ReturnedObject,
PUNICODE_STRING RemainingPath,
- POBJECT_TYPE ObjectType
+ POBJECT_TYPE ObjectType,
+ POBP_LOOKUP_CONTEXT Context
);
NTSTATUS
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 Thu May 25 00:06:13 2006
@@ -8,10 +8,12 @@
/* INCLUDES ***************************************************************/
+#define NTDDI_VERSION NTDDI_WS03
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
+#define OBP_PROFILE
#ifdef OBP_PROFILE
LARGE_INTEGER ObpProfileTime;
@@ -48,119 +50,228 @@
/* PRIVATE FUNCTIONS ******************************************************/
-VOID
+BOOLEAN
NTAPI
-ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
- PROS_OBJECT_HEADER Header,
- PWSTR Name)
+ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent,
+ IN POBP_LOOKUP_CONTEXT Context,
+ IN POBJECT_HEADER ObjectHeader)
{
- 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;
+ POBJECT_DIRECTORY_ENTRY *AllocatedEntry;
+ POBJECT_DIRECTORY_ENTRY NewEntry;
+ POBJECT_HEADER_NAME_INFO HeaderNameInfo;
+
+ /* 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'));
+ if (!NewEntry) return FALSE;
+
+ /* Save the hash */
+ NewEntry->HashValue = Context->HashValue;
+
+ /* Get the Object Name Information */
+ HeaderNameInfo = HEADER_TO_OBJECT_NAME(ObjectHeader);
+
+ /* 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;
+ *AllocatedEntry = NewEntry;
+
+ /* Associate the Object */
+ NewEntry->Object = &ObjectHeader->Body;
+
+ /* Associate the Directory */
+ HeaderNameInfo->Directory = Parent;
+ return TRUE;
}
PVOID
NTAPI
-ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
- PWSTR Name,
- ULONG Attributes)
+ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory,
+ IN PUNICODE_STRING Name,
+ IN ULONG Attributes,
+ IN UCHAR SearchShadow,
+ IN POBP_LOOKUP_CONTEXT Context)
{
- 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)
+ BOOLEAN CaseInsensitive = FALSE;
+ POBJECT_HEADER_NAME_INFO HeaderNameInfo;
+ 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();
+
+ /* Always disable this until we have LUID Device Maps */
+ SearchShadow = FALSE;
+
+ /* Fail the following cases */
+ TotalChars = Name->Length / sizeof(WCHAR);
+ if (!(Directory) || !(Name) || !(Name->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 */
+ 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'));
+ }
+
+ /* 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;
+ Context->HashIndex = HashIndex;
+
+ /* 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)
+ {
+ /* 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 */
+ ASSERT(BODY_TO_HEADER(CurrentEntry->Object)->NameInfoOffset != 0);
+
+ /* Get the name information */
+ 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 it %x\n",¤t_obj->Body);
- ObpEndProfile();
- return(¤t_obj->Body);
+ DPRINT("Found Name Match\n");
+ break;
}
}
- 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);
+
+ /* Move to the next entry */
+ AllocatedEntry = &CurrentEntry->ChainLink;
+ }
+
+ /* Check if we still have an entry */
+ if (CurrentEntry)
+ {
+ /* Set this entry as the first, to speed up incoming insertion */
+ if (AllocatedEntry != LookupBucket)
+ {
+ /* Set the Current Entry */
+ *AllocatedEntry = CurrentEntry->ChainLink;
+
+ /* Link to the old Hash Entry */
+ CurrentEntry->ChainLink = *LookupBucket;
+
+ /* Set the new Hash Entry */
+ *LookupBucket = CurrentEntry;
+ }
+
+ /* Save the found object */
+ FoundObject = CurrentEntry->Object;
+ if (!FoundObject) goto Quickie;
+
+ /* Add a reference to the object */
+ ObReferenceObject(FoundObject);
+ }
+
+ /* Check if the directory was unlocked (which means we locked it) */
+ if (!Context->DirectoryLocked)
+ {
+ /* 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;
+}
+
+BOOLEAN
+NTAPI
+ObpDeleteEntryDirectory(POBP_LOOKUP_CONTEXT Context)
+{
+ POBJECT_DIRECTORY Directory;
+ POBJECT_DIRECTORY_ENTRY *AllocatedEntry;
+ POBJECT_DIRECTORY_ENTRY CurrentEntry;
+
+ /* Get the Directory */
+ Directory = Context->Directory;
+ if (!Directory) return FALSE;
+
+ /* 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;
+ CurrentEntry->ChainLink = NULL;
+
+ /* Free it */
+ ExFreePool(CurrentEntry);
+
+ /* Return */
+ return TRUE;
}
NTSTATUS
@@ -169,22 +280,19 @@
PVOID * NextObject,
PUNICODE_STRING FullPath,
PWSTR * Path,
- ULONG Attributes)
+ ULONG Attributes,
+ POBP_LOOKUP_CONTEXT Context)
{
PWSTR Start;
PWSTR End;
PVOID FoundObject;
- KIRQL oldlvl;
-
- ObpStartProfile();
- DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n",
- Object,Path,*Path);
+ //KIRQL oldlvl;
+ UNICODE_STRING StartUs;
*NextObject = NULL;
if ((*Path) == NULL)
{
- ObpEndProfile();
return STATUS_UNSUCCESSFUL;
}
@@ -198,16 +306,18 @@
*End = 0;
}
- KeAcquireSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), &oldlvl);
- FoundObject = ObpFindEntryDirectory(Object, Start, Attributes);
+ //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);
+ //KeReleaseSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), oldlvl);
if (End != NULL)
{
*End = L'\\';
}
- ObpEndProfile();
return STATUS_UNSUCCESSFUL;
}
@@ -215,7 +325,7 @@
STANDARD_RIGHTS_REQUIRED,
NULL,
UserMode);
- KeReleaseSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), oldlvl);
+ //KeReleaseSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), oldlvl);
if (End != NULL)
{
*End = L'\\';
@@ -228,7 +338,6 @@
*NextObject = FoundObject;
- ObpEndProfile();
return STATUS_SUCCESS;
}
@@ -360,7 +469,7 @@
IN OUT PULONG Context,
OUT PULONG ReturnLength OPTIONAL)
{
- PDIRECTORY_OBJECT Directory;
+ POBJECT_DIRECTORY Directory;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
ULONG SkipEntries = 0;
NTSTATUS Status = STATUS_SUCCESS;
@@ -441,7 +550,7 @@
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes)
{
- PDIRECTORY_OBJECT Directory;
+ POBJECT_DIRECTORY Directory;
HANDLE hDirectory;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
@@ -475,7 +584,7 @@
ObjectAttributes,
PreviousMode,
NULL,
- sizeof(DIRECTORY_OBJECT),
+ sizeof(OBJECT_DIRECTORY),
0,
0,
(PVOID*)&Directory);
@@ -488,12 +597,6 @@
0,
NULL,
&hDirectory);
- if (!NT_SUCCESS(Status))
- {
- ObMakeTemporaryObject(Directory);
- }
- ObDereferenceObject(Directory);
-
if(NT_SUCCESS(Status))
{
_SEH_TRY
@@ -506,6 +609,8 @@
}
_SEH_END;
}
+
+ ObDereferenceObject(Directory);
}
return Status;
Modified: trunk/reactos/ntoskrnl/ob/handle.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/handle.c?rev=22…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/handle.c (original)
+++ trunk/reactos/ntoskrnl/ob/handle.c Thu May 25 00:06:13 2006
@@ -54,6 +54,7 @@
{
PROS_OBJECT_HEADER ObjectHeader = BODY_TO_HEADER(ObjectBody);
LONG NewHandleCount = InterlockedDecrement(&ObjectHeader->HandleCount);
+ OBP_LOOKUP_CONTEXT Context;
DPRINT("Header: %x\n", ObjectHeader);
DPRINT("NewHandleCount: %x\n", NewHandleCount);
DPRINT("HEADER_TO_OBJECT_NAME: %x\n", HEADER_TO_OBJECT_NAME(ObjectHeader));
@@ -75,7 +76,18 @@
/* delete the object from the namespace when the last handle got closed.
Only do this if it's actually been inserted into the namespace and
if it's not a permanent object. */
- ObpRemoveEntryDirectory((PROS_OBJECT_HEADER)ObjectHeader);
+
+ /* Make sure it's still inserted */
+ Context.Directory = HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory;
+ Context.DirectoryLocked = TRUE;
+ if (ObpLookupEntryDirectory(HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory,
+ &HEADER_TO_OBJECT_NAME(ObjectHeader)->Name,
+ 0,
+ FALSE,
+ &Context))
+ {
+ ObpDeleteEntryDirectory(&Context);
+ }
}
/* remove the keep-alive reference */
@@ -1150,6 +1162,7 @@
BOOLEAN ObjectAttached = FALSE;
PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
SECURITY_SUBJECT_CONTEXT SubjectContext;
+ OBP_LOOKUP_CONTEXT Context;
PAGED_CODE();
@@ -1167,7 +1180,8 @@
&ObjectNameInfo->Name,
&FoundObject,
&RemainingPath,
- NULL);
+ NULL,
+ &Context);
DPRINT("FoundObject: %x, Path: %wZ\n", FoundObject,
&RemainingPath);
if (!NT_SUCCESS(Status))
{
@@ -1202,10 +1216,7 @@
PVOID NewName;
PWSTR BufferPos = RemainingPath.Buffer;
ULONG Delta = 0;
-
- ObpAddEntryDirectory(FoundObject, (PROS_OBJECT_HEADER)Header, NULL);
- ObjectAttached = TRUE;
-
+
ObjectNameInfo = HEADER_TO_OBJECT_NAME(Header);
if (BufferPos[0] == L'\\')
@@ -1219,7 +1230,8 @@
ObjectNameInfo->Name.Buffer = NewName;
ObjectNameInfo->Name.Length = RemainingPath.Length - Delta;
ObjectNameInfo->Name.MaximumLength = RemainingPath.MaximumLength - Delta;
- DPRINT("Name: %S\n", ObjectNameInfo->Name.Buffer);
+ ObpInsertEntryDirectory(FoundObject, &Context, (POBJECT_HEADER)Header);
+ ObjectAttached = TRUE;
}
if ((Header->Type == IoFileObjectType) ||
@@ -1262,7 +1274,7 @@
DPRINT("Create Failed\n");
if (ObjectAttached == TRUE)
{
- ObpRemoveEntryDirectory((PROS_OBJECT_HEADER)Header);
+ ObpDeleteEntryDirectory(&Context);
}
if (FoundObject)
{
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 Thu May 25 00:06:13 2006
@@ -26,8 +26,8 @@
POBJECT_TYPE ObDirectoryType = NULL;
POBJECT_TYPE ObTypeObjectType = NULL;
-PDIRECTORY_OBJECT NameSpaceRoot = NULL;
-PDIRECTORY_OBJECT ObpTypeDirectoryObject = NULL;
+POBJECT_DIRECTORY NameSpaceRoot = NULL;
+POBJECT_DIRECTORY ObpTypeDirectoryObject = NULL;
/* FIXME: Move this somewhere else once devicemap support is in */
PDEVICE_MAP ObSystemDeviceMap = NULL;
KEVENT ObpDefaultObject;
@@ -72,6 +72,7 @@
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
NTSTATUS Status;
+ OBP_LOOKUP_CONTEXT Context;
PAGED_CODE();
@@ -95,7 +96,8 @@
&ObjectName,
&Object,
&RemainingPath,
- ObjectType);
+ ObjectType,
+ &Context);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
@@ -160,6 +162,7 @@
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
NTSTATUS Status;
+ OBP_LOOKUP_CONTEXT Context;
PAGED_CODE();
@@ -182,7 +185,8 @@
&ObjectName,
&Object,
&RemainingPath,
- ObjectType);
+ ObjectType,
+ &Context);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
if (!NT_SUCCESS(Status))
{
@@ -252,6 +256,7 @@
UNICODE_STRING Name;
SECURITY_DESCRIPTOR SecurityDescriptor;
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
+ OBP_LOOKUP_CONTEXT Context;
/* Initialize the security descriptor cache */
ObpInitSdCache();
@@ -279,11 +284,10 @@
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
ObjectTypeInitializer.UseDefaultObject = FALSE;
- ObjectTypeInitializer.OpenProcedure = ObpCreateDirectory;
ObjectTypeInitializer.ParseProcedure = (OB_PARSE_METHOD)ObpParseDirectory;
ObjectTypeInitializer.MaintainTypeList = FALSE;
ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
- ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DIRECTORY_OBJECT);
+ ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY);
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObDirectoryType);
/* Create security descriptor */
@@ -312,7 +316,7 @@
&ObjectAttributes,
KernelMode,
NULL,
- sizeof(DIRECTORY_OBJECT),
+ sizeof(OBJECT_DIRECTORY),
0,
0,
(PVOID*)&NameSpaceRoot);
@@ -335,7 +339,7 @@
&ObjectAttributes,
KernelMode,
NULL,
- sizeof(DIRECTORY_OBJECT),
+ sizeof(OBJECT_DIRECTORY),
0,
0,
(PVOID*)&ObpTypeDirectoryObject);
@@ -348,8 +352,24 @@
/* Insert the two objects we already created but couldn't add */
/* NOTE: Uses TypeList & Creator Info in OB 2.0 */
- ObpAddEntryDirectory(ObpTypeDirectoryObject,
(PROS_OBJECT_HEADER)BODY_TO_HEADER(ObTypeObjectType), NULL);
- ObpAddEntryDirectory(ObpTypeDirectoryObject,
(PROS_OBJECT_HEADER)BODY_TO_HEADER(ObDirectoryType), NULL);
+ Context.Directory = ObpTypeDirectoryObject;
+ Context.DirectoryLocked = TRUE;
+ if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
+
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObTypeObjectType))->Name,
+ OBJ_CASE_INSENSITIVE,
+ FALSE,
+ &Context))
+ {
+ ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context,
(POBJECT_HEADER)BODY_TO_HEADER(ObTypeObjectType));
+ }
+ if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
+
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObDirectoryType))->Name,
+ OBJ_CASE_INSENSITIVE,
+ FALSE,
+ &Context))
+ {
+ ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context,
(POBJECT_HEADER)BODY_TO_HEADER(ObDirectoryType));
+ }
/* Create 'symbolic link' object type */
ObInitSymbolicLinkImplementation();
@@ -471,7 +491,15 @@
/* Insert it into the Object Directory */
if (ObpTypeDirectoryObject)
{
- ObpAddEntryDirectory(ObpTypeDirectoryObject, Header, TypeName->Buffer);
+ OBP_LOOKUP_CONTEXT Context;
+ Context.Directory = ObpTypeDirectoryObject;
+ Context.DirectoryLocked = TRUE;
+ ObpLookupEntryDirectory(ObpTypeDirectoryObject,
+ TypeName,
+ OBJ_CASE_INSENSITIVE,
+ FALSE,
+ &Context);
+ ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context,
(POBJECT_HEADER)Header);
ObReferenceObject(ObpTypeDirectoryObject);
}
Modified: trunk/reactos/ntoskrnl/ob/ntobj.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/ntobj.c?rev=220…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/ntobj.c (original)
+++ trunk/reactos/ntoskrnl/ob/ntobj.c Thu May 25 00:06:13 2006
@@ -36,6 +36,7 @@
IN BOOLEAN Permanent)
{
PROS_OBJECT_HEADER ObjectHeader;
+ OBP_LOOKUP_CONTEXT Context;
ObjectHeader = BODY_TO_HEADER(ObjectBody);
ASSERT (ObjectHeader->PointerCount > 0);
@@ -49,8 +50,17 @@
if (ObjectHeader->HandleCount == 0 &&
HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory)
{
- /* Remove the object from the namespace */
- ObpRemoveEntryDirectory((PROS_OBJECT_HEADER)ObjectHeader);
+ /* Make sure it's still inserted */
+ Context.Directory = HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory;
+ Context.DirectoryLocked = TRUE;
+ if
(ObpLookupEntryDirectory(HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory,
+
&HEADER_TO_OBJECT_NAME(ObjectHeader)->Name,
+ 0,
+ FALSE,
+ &Context))
+ {
+ ObpDeleteEntryDirectory(&Context);
+ }
}
}
}
Modified: trunk/reactos/ntoskrnl/ob/object.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/object.c?rev=22…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/object.c (original)
+++ trunk/reactos/ntoskrnl/ob/object.c Thu May 25 00:06:13 2006
@@ -293,7 +293,8 @@
PUNICODE_STRING ObjectName,
PVOID* ReturnedObject,
PUNICODE_STRING RemainingPath,
- POBJECT_TYPE ObjectType)
+ POBJECT_TYPE ObjectType,
+ POBP_LOOKUP_CONTEXT Context)
{
PVOID NextObject;
PVOID CurrentObject;
@@ -388,7 +389,8 @@
&NextObject,
&PathString,
¤t,
- Attributes);
+ Attributes,
+ Context);
if (Status == STATUS_REPARSE)
{
/* reparse the object path */
@@ -442,7 +444,7 @@
{
POBJECT_HEADER_NAME_INFO LocalInfo;
PROS_OBJECT_HEADER ObjectHeader;
- PDIRECTORY_OBJECT ParentDirectory;
+ POBJECT_DIRECTORY ParentDirectory;
ULONG NameSize;
PWCH ObjectName;
NTSTATUS Status;
Modified: trunk/reactos/subsystems/win32/win32k/include/winsta.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/winsta.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/winsta.h Thu May 25 00:06:13 2006
@@ -74,7 +74,8 @@
PVOID *NextObject,
PUNICODE_STRING FullPath,
PWSTR *Path,
- ULONG Attributes);
+ ULONG Attributes,
+ PVOID Context);
NTSTATUS FASTCALL
IntValidateWindowStationHandle(
Modified: trunk/reactos/subsystems/win32/win32k/main/dllmain.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/mai…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/main/dllmain.c (original)
+++ trunk/reactos/subsystems/win32/win32k/main/dllmain.c Thu May 25 00:06:13 2006
@@ -382,7 +382,7 @@
* Register Object Manager Callbacks
*/
CalloutData.WinStaOpen = IntWinStaObjectOpen;
- CalloutData.WinStaParse = IntWinStaObjectParse;
+ CalloutData.WinStaParse = (OB_ROS_PARSE_METHOD)IntWinStaObjectParse;
CalloutData.WinStaDelete = IntWinStaObjectDelete;
CalloutData.WinStaFind = IntWinStaObjectFind;
CalloutData.DesktopCreate = IntDesktopObjectCreate;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c Thu May 25 00:06:13 2006
@@ -190,7 +190,8 @@
PVOID *NextObject,
PUNICODE_STRING FullPath,
PWSTR *Path,
- ULONG Attributes)
+ ULONG Attributes,
+ PVOID Context)
{
PVOID FoundObject;
NTSTATUS Status;