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=22... ============================================================================== --- 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=220... ============================================================================== --- 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=2... ============================================================================== --- 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=220... ============================================================================== --- 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/ob... ============================================================================== --- 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=220... ============================================================================== --- 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=220... ============================================================================== --- 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=22... ============================================================================== --- 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=2201... ============================================================================== --- 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=220... ============================================================================== --- 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/incl... ============================================================================== --- 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/main... ============================================================================== --- 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/ntus... ============================================================================== --- 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;