[ros-diffs] [ion] 22319: - Pretty much the last Ob implementation/optimization patch (Except for a minor fix by Thomas to fix handle sweeping), re-implemented the ObFindObject routine by using some code that I had written almost 2 years ago with help from Thomas and Filip, plus some fixes discovered today while testing. - Fixed symbolic link and desktop/winsta parse procedures to become NT-compatible now that ObFindObject is as well. Also fixed file/device parse routine for these changes. - ObFindObject now supports STATUS_REPARSE_OBJECT, and has an optimized path for parsing when a root directory is given, as well as is entirely unicode_string-based. - Cleaned up ob.h and added ob_x.h for the inlined functions. - Implemented new Ob tracing system.

ion at svn.reactos.org ion at svn.reactos.org
Mon Jun 12 07:58:10 CEST 2006


Author: ion
Date: Mon Jun 12 09:58:08 2006
New Revision: 22319

URL: http://svn.reactos.ru/svn/reactos?rev=22319&view=rev
Log:
- Pretty much the last Ob implementation/optimization patch (Except for a minor fix by Thomas to fix handle sweeping), re-implemented the ObFindObject routine by using some code that I had written almost 2 years ago with help from Thomas and Filip, plus some fixes discovered today while testing.
- Fixed symbolic link and desktop/winsta parse procedures to become NT-compatible now that ObFindObject is as well. Also fixed file/device parse routine for these changes.
- ObFindObject now supports STATUS_REPARSE_OBJECT, and has an optimized path for parsing when a root directory is given, as well as is entirely unicode_string-based.
- Cleaned up ob.h and added ob_x.h for the inlined functions.
- Implemented new Ob tracing system.

Added:
    trunk/reactos/ntoskrnl/include/internal/ob_x.h
Modified:
    trunk/reactos/ntoskrnl/include/internal/ob.h
    trunk/reactos/ntoskrnl/io/file.c
    trunk/reactos/ntoskrnl/ob/obhandle.c
    trunk/reactos/ntoskrnl/ob/obinit.c
    trunk/reactos/ntoskrnl/ob/obname.c
    trunk/reactos/ntoskrnl/ob/symlink.c
    trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c
    trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c

Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ob.h?rev=22319&r1=22318&r2=22319&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ob.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h Mon Jun 12 09:58:08 2006
@@ -1,53 +1,89 @@
 /*
- * COPYRIGHT:         See COPYING in the top level directory
- * PROJECT:           ReactOS kernel
- * FILE:              include/internal/objmgr.h
- * PURPOSE:           Object manager definitions
- * PROGRAMMER:        David Welch (welch at mcmail.com)
- */
-
-#ifndef __INCLUDE_INTERNAL_OBJMGR_H
-#define __INCLUDE_INTERNAL_OBJMGR_H
-
+* PROJECT:         ReactOS Kernel
+* LICENSE:         GPL - See COPYING in the top level directory
+* FILE:            ntoskrnl/include/ob.h
+* PURPOSE:         Internal header for the Object Manager
+* PROGRAMMERS:     Alex Ionescu (alex.ionescu at reactos.org)
+*/
+#include "ob_x.h"
+
+//
+// Define this if you want debugging support
+//
+#define _OB_DEBUG_                                      0x00
+
+//
+// These define the Debug Masks Supported
+//
+#define OB_HANDLE_DEBUG                                 0x01
+#define OB_NAMESPACE_DEBUG                              0x02
+#define OB_SECURITY_DEBUG                               0x04
+#define OB_REFERENCE_DEBUG                              0x08
+#define OB_CALLBACK_DEBUG                               0x10
+
+//
+// Debug/Tracing support
+//
+#if _OB_DEBUG_
+#ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
+#define OBTRACE DbgPrintEx
+#else
+#define OBTRACE(x, ...)                                 \
+    if (x & ObpTraceLevel) DbgPrint(__VA_ARGS__)
+#endif
+#else
+#define OBTRACE(x, ...) DPRINT(__VA_ARGS__)
+#endif
+
+//
+// Mask to detect GENERIC_XXX access masks being used
+//
+#define GENERIC_ACCESS                                  \
+    (GENERIC_READ    |                                  \
+     GENERIC_WRITE   |                                  \
+     GENERIC_EXECUTE |                                  \
+     GENERIC_ALL)
+
+//
+// Identifies a Kernel Handle
+//
+#define KERNEL_HANDLE_FLAG                              \
+    (1 << ((sizeof(HANDLE) * 8) - 1))
+#define ObIsKernelHandle(Handle, ProcessorMode)         \
+    (((ULONG_PTR)(Handle) & KERNEL_HANDLE_FLAG) &&      \
+    ((ProcessorMode) == KernelMode))
+
+//
+// Converts to and from a Kernel Handle to a normal handle
+//
+#define ObKernelHandleToHandle(Handle)                  \
+    (HANDLE)((ULONG_PTR)(Handle) & ~KERNEL_HANDLE_FLAG)
+#define ObMarkHandleAsKernelHandle(Handle)              \
+    (HANDLE)((ULONG_PTR)(Handle) | KERNEL_HANDLE_FLAG)
+
+//
+// Returns the number of handles in a handle table
+//
+#define ObpGetHandleCountByHandleTable(HandleTable)     \
+    ((PHANDLE_TABLE)HandleTable)->HandleCount
+
+//
+// Context Structures for Ex*Handle Callbacks
+//
 typedef struct _OBP_SET_HANDLE_ATTRIBUTES_CONTEXT
 {
     KPROCESSOR_MODE PreviousMode;
     OBJECT_HANDLE_ATTRIBUTE_INFORMATION Information;
 } OBP_SET_HANDLE_ATTRIBUTES_CONTEXT, *POBP_SET_HANDLE_ATTRIBUTES_CONTEXT;
-
 typedef struct _OBP_CLOSE_HANDLE_CONTEXT
 {
     PHANDLE_TABLE HandleTable;
     KPROCESSOR_MODE AccessMode;
 } OBP_CLOSE_HANDLE_CONTEXT, *POBP_CLOSE_HANDLE_CONTEXT;
 
-#define GENERIC_ACCESS (GENERIC_READ |      \
-                        GENERIC_WRITE |     \
-                        GENERIC_EXECUTE |   \
-                        GENERIC_ALL)
-
-#define KERNEL_HANDLE_FLAG (1 << ((sizeof(HANDLE) * 8) - 1))
-#define ObIsKernelHandle(Handle, ProcessorMode)                                \
-  (((ULONG_PTR)(Handle) & KERNEL_HANDLE_FLAG) &&                               \
-   ((ProcessorMode) == KernelMode))
-#define ObKernelHandleToHandle(Handle)                                         \
-  (HANDLE)((ULONG_PTR)(Handle) & ~KERNEL_HANDLE_FLAG)
-#define ObMarkHandleAsKernelHandle(Handle)                                     \
-  (HANDLE)((ULONG_PTR)(Handle) | KERNEL_HANDLE_FLAG)
-#define ObpGetHandleCountByHandleTable(HandleTable)                             \
-    ((PHANDLE_TABLE)HandleTable)->HandleCount
-
-extern KEVENT ObpDefaultObject;
-extern POBJECT_TYPE ObpTypeObjectType;
-extern POBJECT_TYPE ObSymbolicLinkType;
-extern POBJECT_TYPE ObTypeObjectType;
-extern POBJECT_DIRECTORY NameSpaceRoot;
-extern POBJECT_DIRECTORY ObpTypeDirectoryObject;
-extern PHANDLE_TABLE ObpKernelHandleTable;
-extern WORK_QUEUE_ITEM ObpReaperWorkItem;
-extern volatile PVOID ObpReaperList;
-extern NPAGED_LOOKASIDE_LIST ObpNmLookasideList, ObpCiLookasideList;
-
+//
+// Directory Namespace Functions
+//
 BOOLEAN
 NTAPI
 ObpDeleteEntryDirectory(
@@ -72,12 +108,33 @@
     IN POBP_LOOKUP_CONTEXT Context
 );
 
+//
+// Symbolic Link Functions
+//
 VOID
 NTAPI
 ObInitSymbolicLinkImplementation(
     VOID
 );
 
+NTSTATUS
+NTAPI
+ObpParseSymbolicLink(
+    IN PVOID ParsedObject,
+    IN PVOID ObjectType,
+    IN OUT PACCESS_STATE AccessState,
+    IN KPROCESSOR_MODE AccessMode,
+    IN ULONG Attributes,
+    IN OUT PUNICODE_STRING FullPath,
+    IN OUT PUNICODE_STRING RemainingName,
+    IN OUT PVOID Context OPTIONAL,
+    IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
+    OUT PVOID *NextObject
+);
+
+//
+// Process/Handle Table Init/Rundown
+//
 NTSTATUS
 NTAPI
 ObpCreateHandleTable(
@@ -91,6 +148,9 @@
     IN PEPROCESS Process
 );
 
+//
+// Object Lookup Functions
+//
 NTSTATUS
 NTAPI
 ObFindObject(
@@ -107,6 +167,9 @@
     IN PVOID Insert
 );
 
+//
+// Object Attribute Functions
+//
 BOOLEAN
 NTAPI
 ObpSetHandleAttributes(
@@ -117,17 +180,26 @@
 
 VOID
 NTAPI
-ObpDeleteNameCheck(
-    IN PVOID Object
-);
-
-VOID
-NTAPI
 ObQueryDeviceMapInformation(
     IN PEPROCESS Process,
     OUT PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo
 );
 
+//
+// Object Lifetime Functions
+//
+VOID
+FASTCALL
+ObpDeleteObject(
+    IN PVOID Object
+);
+
+VOID
+NTAPI
+ObpReapObject(
+    IN PVOID Unused
+);
+
 VOID
 FASTCALL
 ObpSetPermanentObject(
@@ -136,22 +208,19 @@
 );
 
 VOID
-FASTCALL
-ObpDeleteObject(
-    IN PVOID Object
-);
-
-VOID
-NTAPI
-ObpReapObject(
-    IN PVOID Unused
-);
-
-/* Security descriptor cache functions */
-
-NTSTATUS
-NTAPI
-ObpInitSdCache(VOID);
+NTAPI
+ObpDeleteNameCheck(
+    IN PVOID Object
+);
+
+//
+// Security descriptor cache functions
+//
+NTSTATUS
+NTAPI
+ObpInitSdCache(
+    VOID
+);
 
 NTSTATUS
 NTAPI
@@ -162,7 +231,9 @@
 
 NTSTATUS
 NTAPI
-ObpRemoveSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
+ObpRemoveSecurityDescriptor(
+    IN PSECURITY_DESCRIPTOR SecurityDescriptor
+);
 
 PSECURITY_DESCRIPTOR
 NTAPI
@@ -172,37 +243,45 @@
 
 VOID
 NTAPI
-ObpDereferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
-
+ObpDereferenceCachedSecurityDescriptor(
+    IN PSECURITY_DESCRIPTOR SecurityDescriptor
+);
+
+//
+// Executive Fast Referencing Functions
+//
 VOID
 FASTCALL
 ObInitializeFastReference(
     IN PEX_FAST_REF FastRef,
-    PVOID Object
+    IN PVOID Object
 );
 
 PVOID
 FASTCALL
 ObFastReplaceObject(
     IN PEX_FAST_REF FastRef,
-    PVOID Object
+    IN PVOID Object
 );
 
 PVOID
 FASTCALL
-ObFastReferenceObject(IN PEX_FAST_REF FastRef);
+ObFastReferenceObject(
+    IN PEX_FAST_REF FastRef
+);
 
 VOID
 FASTCALL
 ObFastDereferenceObject(
     IN PEX_FAST_REF FastRef,
-    PVOID Object
-);
-
-/* Object Create and Object Name Capture Functions */
-
-NTSTATUS
-STDCALL
+    IN PVOID Object
+);
+
+//
+// Object Create and Object Name Capture Functions
+//
+NTSTATUS
+NTAPI
 ObpCaptureObjectName(
     IN PUNICODE_STRING CapturedName,
     IN PUNICODE_STRING ObjectName,
@@ -211,7 +290,7 @@
 );
 
 NTSTATUS
-STDCALL
+NTAPI
 ObpCaptureObjectAttributes(
     IN POBJECT_ATTRIBUTES ObjectAttributes,
     IN KPROCESSOR_MODE AccessMode,
@@ -220,119 +299,17 @@
     OUT PUNICODE_STRING ObjectName
 );
 
-VOID
-static __inline
-ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
-{
-    /* Check if we have a security descriptor */
-    if (ObjectCreateInfo->SecurityDescriptor)
-    {
-        /* Release it */
-        SeReleaseSecurityDescriptor(ObjectCreateInfo->SecurityDescriptor,
-                                    ObjectCreateInfo->ProbeMode,
-                                    TRUE);
-        ObjectCreateInfo->SecurityDescriptor = NULL;
-    }
-}
-
-PVOID
-static __inline
-ObpAllocateCapturedAttributes(IN PP_NPAGED_LOOKASIDE_NUMBER Type)
-{
-    PKPRCB Prcb = KeGetCurrentPrcb();
-    PVOID Buffer;
-    PNPAGED_LOOKASIDE_LIST List;
-
-    /* Get the P list first */
-    List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].P;
-
-    /* Attempt allocation */
-    List->L.TotalAllocates++;
-    Buffer = (PVOID)InterlockedPopEntrySList(&List->L.ListHead);
-    if (!Buffer)
-    {
-        /* Let the balancer know that the P list failed */
-        List->L.AllocateMisses++;
-
-        /* Try the L List */
-        List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].L;
-        List->L.TotalAllocates++;
-        Buffer = (PVOID)InterlockedPopEntrySList(&List->L.ListHead);
-        if (!Buffer)
-        {
-            /* Let the balancer know the L list failed too */
-            List->L.AllocateMisses++;
-
-            /* Allocate it */
-            Buffer = List->L.Allocate(List->L.Type, List->L.Size, List->L.Tag);
-        }
-    }
-
-    /* Return buffer */
-    return Buffer;
-}
-
-VOID
-static __inline
-ObpFreeCapturedAttributes(IN PVOID Buffer,
-                          IN PP_NPAGED_LOOKASIDE_NUMBER Type)
-{
-    PKPRCB Prcb = KeGetCurrentPrcb();
-    PNPAGED_LOOKASIDE_LIST List;
-
-    /* Use the P List */
-    List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].P;
-    List->L.TotalFrees++;
-
-    /* Check if the Free was within the Depth or not */
-    if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
-    {
-        /* Let the balancer know */
-        List->L.FreeMisses++;
-
-        /* Use the L List */
-        List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].L;
-        List->L.TotalFrees++;
-
-        /* Check if the Free was within the Depth or not */
-        if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
-        {
-            /* All lists failed, use the pool */
-            List->L.FreeMisses++;
-            List->L.Free(Buffer);
-        }
-    }
-    else
-    {
-        /* The free was within the Depth */
-        InterlockedPushEntrySList(&List->L.ListHead,
-                                  (PSINGLE_LIST_ENTRY)Buffer);
-    }
-}
-
-VOID
-static __inline
-ObpReleaseCapturedName(IN PUNICODE_STRING Name)
-{
-    /* We know this is a pool-allocation if the size doesn't match */
-    if (Name->MaximumLength != 248)
-    {
-        ExFreePool(Name->Buffer);
-    }
-    else
-    {
-        /* Otherwise, free from the lookaside */
-        ObpFreeCapturedAttributes(Name, LookasideNameBufferList);
-    }
-}
-
-VOID
-static __inline
-ObpFreeAndReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
-{
-    /* First release the attributes, then free them from the lookaside list */
-    ObpReleaseCapturedAttributes(ObjectCreateInfo);
-    ObpFreeCapturedAttributes(ObjectCreateInfo, LookasideCreateInfoList);
-}
-
-#endif /* __INCLUDE_INTERNAL_OBJMGR_H */
+//
+// Global data inside the Object Manager
+//
+extern ULONG ObpTraceLevel;
+extern KEVENT ObpDefaultObject;
+extern POBJECT_TYPE ObpTypeObjectType;
+extern POBJECT_TYPE ObSymbolicLinkType;
+extern POBJECT_TYPE ObTypeObjectType;
+extern POBJECT_DIRECTORY NameSpaceRoot;
+extern POBJECT_DIRECTORY ObpTypeDirectoryObject;
+extern PHANDLE_TABLE ObpKernelHandleTable;
+extern WORK_QUEUE_ITEM ObpReaperWorkItem;
+extern volatile PVOID ObpReaperList;
+extern NPAGED_LOOKASIDE_LIST ObpNmLookasideList, ObpCiLookasideList;

Added: trunk/reactos/ntoskrnl/include/internal/ob_x.h
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ob_x.h?rev=22319&view=auto
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ob_x.h (added)
+++ trunk/reactos/ntoskrnl/include/internal/ob_x.h Mon Jun 12 09:58:08 2006
@@ -1,0 +1,123 @@
+/*
+* PROJECT:         ReactOS Kernel
+* LICENSE:         GPL - See COPYING in the top level directory
+* FILE:            ntoskrnl/include/ob_x.h
+* PURPOSE:         Intenral Inlined Functions for the Object Manager
+* PROGRAMMERS:     Alex Ionescu (alex.ionescu at reactos.org)
+*/
+
+VOID
+static __inline
+ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
+{
+    /* Check if we have a security descriptor */
+    if (ObjectCreateInfo->SecurityDescriptor)
+    {
+        /* Release it */
+        SeReleaseSecurityDescriptor(ObjectCreateInfo->SecurityDescriptor,
+                                    ObjectCreateInfo->ProbeMode,
+                                    TRUE);
+        ObjectCreateInfo->SecurityDescriptor = NULL;
+    }
+}
+
+PVOID
+static __inline
+ObpAllocateCapturedAttributes(IN PP_NPAGED_LOOKASIDE_NUMBER Type)
+{
+    PKPRCB Prcb = KeGetCurrentPrcb();
+    PVOID Buffer;
+    PNPAGED_LOOKASIDE_LIST List;
+
+    /* Get the P list first */
+    List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].P;
+
+    /* Attempt allocation */
+    List->L.TotalAllocates++;
+    Buffer = (PVOID)InterlockedPopEntrySList(&List->L.ListHead);
+    if (!Buffer)
+    {
+        /* Let the balancer know that the P list failed */
+        List->L.AllocateMisses++;
+
+        /* Try the L List */
+        List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].L;
+        List->L.TotalAllocates++;
+        Buffer = (PVOID)InterlockedPopEntrySList(&List->L.ListHead);
+        if (!Buffer)
+        {
+            /* Let the balancer know the L list failed too */
+            List->L.AllocateMisses++;
+
+            /* Allocate it */
+            Buffer = List->L.Allocate(List->L.Type, List->L.Size, List->L.Tag);
+        }
+    }
+
+    /* Return buffer */
+    return Buffer;
+}
+
+VOID
+static __inline
+ObpFreeCapturedAttributes(IN PVOID Buffer,
+                          IN PP_NPAGED_LOOKASIDE_NUMBER Type)
+{
+    PKPRCB Prcb = KeGetCurrentPrcb();
+    PNPAGED_LOOKASIDE_LIST List;
+
+    /* Use the P List */
+    List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].P;
+    List->L.TotalFrees++;
+
+    /* Check if the Free was within the Depth or not */
+    if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
+    {
+        /* Let the balancer know */
+        List->L.FreeMisses++;
+
+        /* Use the L List */
+        List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].L;
+        List->L.TotalFrees++;
+
+        /* Check if the Free was within the Depth or not */
+        if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
+        {
+            /* All lists failed, use the pool */
+            List->L.FreeMisses++;
+            List->L.Free(Buffer);
+        }
+    }
+    else
+    {
+        /* The free was within the Depth */
+        InterlockedPushEntrySList(&List->L.ListHead,
+                                  (PSINGLE_LIST_ENTRY)Buffer);
+    }
+}
+
+VOID
+static __inline
+ObpReleaseCapturedName(IN PUNICODE_STRING Name)
+{
+    /* We know this is a pool-allocation if the size doesn't match */
+    if (Name->MaximumLength != 248)
+    {
+        ExFreePool(Name->Buffer);
+    }
+    else
+    {
+        /* Otherwise, free from the lookaside */
+        ObpFreeCapturedAttributes(Name, LookasideNameBufferList);
+    }
+}
+
+VOID
+static __inline
+ObpFreeAndReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
+{
+    /* First release the attributes, then free them from the lookaside list */
+    ObpReleaseCapturedAttributes(ObjectCreateInfo);
+    ObpFreeCapturedAttributes(ObjectCreateInfo, LookasideCreateInfoList);
+}
+

Modified: trunk/reactos/ntoskrnl/io/file.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/io/file.c?rev=22319&r1=22318&r2=22319&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/file.c (original)
+++ trunk/reactos/ntoskrnl/io/file.c Mon Jun 12 09:58:08 2006
@@ -44,19 +44,15 @@
     NTSTATUS Status;
     PFILE_OBJECT FileObject;
     DPRINT("IopParseDevice:\n"
-            "DeviceObject : %p, Type : %p, TypeName : %wZ\n"
-            "FileObject : %p, Type : %p, TypeName : %wZ\n"
-            "CompleteName : %wZ, RemainingName : %wZ\n",
-            ParseObject,
-            ObjectType,
-            &ObjectType->Name,
-            Context,
-            Context ? OBJECT_TO_OBJECT_HEADER(Context)->Type : NULL,
-            Context ? &OBJECT_TO_OBJECT_HEADER(Context)->Type->Name: NULL,
-            CompleteName,
-            RemainingName);
-
-    if (!RemainingName || !RemainingName->Buffer)
+           "DeviceObject : %p\n"
+           "RelatedFileObject : %p\n"
+           "CompleteName : %wZ, RemainingName : %wZ\n",
+           ParseObject,
+           Context,
+           CompleteName,
+           RemainingName);
+
+    if (!*RemainingName->Buffer)
     {
         DeviceObject = ParseObject;
 
@@ -71,6 +67,7 @@
                                 (PVOID*)&FileObject);
         /* Set File Object Data */
         FileObject->DeviceObject = IoGetAttachedDevice(DeviceObject);
+        DPRINT("DO. DRV Name: %p %wZ\n", DeviceObject, &DeviceObject->DriverObject->DriverName);
 
         /* HACK */
         FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
@@ -88,7 +85,7 @@
                         0,
                         (PVOID*)&FileObject);
 
-    if (ObjectType == IoDeviceObjectType)
+    if (!Context)
     {
         /* Parent is a device object */
         DeviceObject = IoGetAttachedDevice((PDEVICE_OBJECT)ParseObject);
@@ -110,7 +107,6 @@
     RtlCreateUnicodeString(&FileObject->FileName, RemainingName->Buffer);
     FileObject->DeviceObject = DeviceObject;
     *Object = FileObject;
-    RemainingName->Buffer = NULL; // ros hack
     return STATUS_SUCCESS;
 }
 

Modified: trunk/reactos/ntoskrnl/ob/obhandle.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev=22319&r1=22318&r2=22319&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obhandle.c (original)
+++ trunk/reactos/ntoskrnl/ob/obhandle.c Mon Jun 12 09:58:08 2006
@@ -19,12 +19,6 @@
 
 PHANDLE_TABLE ObpKernelHandleTable = NULL;
 
-#ifdef _OBDEBUG_
-#define OBTRACE DPRINT1
-#else
-#define OBTRACE DPRINT
-#endif
-
 /* PRIVATE FUNCTIONS *********************************************************/
 
 NTSTATUS
@@ -103,7 +97,8 @@
     /* Get the object type and header */
     ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
     ObjectType = ObjectHeader->Type;
-    OBTRACE("OBTRACE - %s - Decrementing count for: %p. HC LC %lx %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Decrementing count for: %p. HC LC %lx %lx\n",
             __FUNCTION__,
             ObjectBody,
             ObjectHeader->HandleCount,
@@ -132,7 +127,8 @@
 
     /* Decrease the total number of handles for this type */
     ObjectType->TotalNumberOfHandles--;
-    OBTRACE("OBTRACE - %s - Decremented count for: %p. HC LC %lx %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Decremented count for: %p. HC LC %lx %lx\n",
             __FUNCTION__,
             ObjectBody,
             ObjectHeader->HandleCount,
@@ -183,7 +179,8 @@
     ObjectType = ObjectHeader->Type;
     Body = &ObjectHeader->Body;
     GrantedAccess = HandleEntry->GrantedAccess;
-    OBTRACE("OBTRACE - %s - Closing handle: %lx for %p. HC LC %lx %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Closing handle: %lx for %p. HC LC %lx %lx\n",
             __FUNCTION__,
             Handle,
             Body,
@@ -243,7 +240,8 @@
     //ObDereferenceObject(Body); // FIXME: Needs sync changes in other code
 
     /* Return to caller */
-    OBTRACE("OBTRACE - %s - Closed handle: %lx for %p. HC LC %lx %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Closed handle: %lx for %p. HC LC %lx %lx\n",
             __FUNCTION__,
             Handle,
             Body,
@@ -297,7 +295,8 @@
     /* Get the object header and type */
     ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
     ObjectType = ObjectHeader->Type;
-    OBTRACE("OBTRACE - %s - Incrementing count for: %p. Reason: %lx. HC LC %lx %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Incrementing count for: %p. Reason: %lx. HC LC %lx %lx\n",
             __FUNCTION__,
             Object,
             OpenReason,
@@ -376,7 +375,8 @@
 
     /* Increase total number of handles */
     ObjectType->TotalNumberOfHandles++;
-    OBTRACE("OBTRACE - %s - Incremented count for: %p. Reason: %lx HC LC %lx %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Incremented count for: %p. Reason: %lx HC LC %lx %lx\n",
             __FUNCTION__,
             Object,
             OpenReason,
@@ -429,7 +429,8 @@
     /* Get the object header and type */
     ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
     ObjectType = ObjectHeader->Type;
-    OBTRACE("OBTRACE - %s - Incrementing count for: %p. UNNAMED. HC LC %lx %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Incrementing count for: %p. UNNAMED. HC LC %lx %lx\n",
             __FUNCTION__,
             Object,
             ObjectHeader->HandleCount,
@@ -486,7 +487,8 @@
 
     /* Increase total number of handles */
     ObjectType->TotalNumberOfHandles++;
-    OBTRACE("OBTRACE - %s - Incremented count for: %p. UNNAMED HC LC %lx %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Incremented count for: %p. UNNAMED HC LC %lx %lx\n",
             __FUNCTION__,
             Object,
             ObjectHeader->HandleCount,
@@ -546,7 +548,8 @@
 
     /* Get the object header and type */
     ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
-    OBTRACE("OBTRACE - %s - Creating handle for: %p. UNNAMED. HC LC %lx %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Creating handle for: %p. UNNAMED. HC LC %lx %lx\n",
             __FUNCTION__,
             Object,
             ObjectHeader->HandleCount,
@@ -606,7 +609,8 @@
      * ObpIncrementHandleCount to make sure that Object Security is valid
      * (specified in Gl00my documentation on Ob)
      */
-    OBTRACE("OBTRACE - %s - Handle Properties: [%p-%lx-%lx]\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Handle Properties: [%p-%lx-%lx]\n",
             __FUNCTION__,
             NewEntry.Object, NewEntry.ObAttributes & 3, NewEntry.GrantedAccess);
     Handle = ExCreateHandle(HandleTable, &NewEntry);
@@ -634,7 +638,8 @@
         /* Return handle and object */
         *ReturnedHandle = Handle;
         if (ReturnedObject) *ReturnedObject = Object;
-        OBTRACE("OBTRACE - %s - Returning Handle: %lx HC LC %lx %lx\n",
+        OBTRACE(OB_HANDLE_DEBUG,
+                "%s %s - Returning Handle: %lx HC LC %lx %lx\n",
                 __FUNCTION__,
                 Handle,
                 ObjectHeader->HandleCount,
@@ -716,7 +721,8 @@
     /* Get the object header and type */
     ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
     ObjectType = ObjectHeader->Type;
-    OBTRACE("OBTRACE - %s - Creating handle for: %p. Reason: %lx. HC LC %lx %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Creating handle for: %p. Reason: %lx. HC LC %lx %lx\n",
             __FUNCTION__,
             Object,
             OpenReason,
@@ -787,7 +793,8 @@
      * ObpIncrementHandleCount to make sure that Object Security is valid
      * (specified in Gl00my documentation on Ob)
      */
-    OBTRACE("OBTRACE - %s - Handle Properties: [%p-%lx-%lx]\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Handle Properties: [%p-%lx-%lx]\n",
             __FUNCTION__,
             NewEntry.Object, NewEntry.ObAttributes & 3, NewEntry.GrantedAccess);
     Handle = ExCreateHandle(HandleTable, &NewEntry);
@@ -815,7 +822,8 @@
         /* Return handle and object */
         *ReturnedHandle = Handle;
         if (ReturnedObject) *ReturnedObject = Object;
-        OBTRACE("OBTRACE - %s - Returning Handle: %lx HC LC %lx %lx\n",
+        OBTRACE(OB_HANDLE_DEBUG,
+                "%s - Returning Handle: %lx HC LC %lx %lx\n",
                 __FUNCTION__,
                 Handle,
                 ObjectHeader->HandleCount,
@@ -857,7 +865,8 @@
     PHANDLE_TABLE_ENTRY HandleTableEntry;
     NTSTATUS Status;
     PAGED_CODE();
-    OBTRACE("OBTRACE - %s - Closing handle: %lx\n", __FUNCTION__, Handle);
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Closing handle: %lx\n", __FUNCTION__, Handle);
 
     /* Check if we're dealing with a kernel handle */
     if (ObIsKernelHandle(Handle, AccessMode))
@@ -924,7 +933,8 @@
     }
 
     /* Return status */
-    OBTRACE("OBTRACE - %s - Closed handle: %lx S: %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Closed handle: %lx S: %lx\n",
             __FUNCTION__, Handle, Status);
     return Status;
 }
@@ -1213,7 +1223,8 @@
     PHANDLE_TABLE HandleTable = NULL;
     OBJECT_HANDLE_INFORMATION HandleInformation;
     PAGED_CODE();
-    OBTRACE("OBTRACE - %s - Duplicating handle: %lx for %p into %p\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Duplicating handle: %lx for %p into %p\n",
             __FUNCTION__,
             SourceHandle,
             SourceProcess,
@@ -1376,7 +1387,8 @@
     if (TargetHandle) *TargetHandle = NewHandle;
 
     /* Return status */
-    OBTRACE("OBTRACE - %s - Duplicated handle: %lx for %p into %p. Source: %p HC PC %lx %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Duplicated handle: %lx for %p into %p. Source: %p HC PC %lx %lx\n",
             __FUNCTION__,
             NewHandle,
             SourceProcess,
@@ -1534,7 +1546,8 @@
 Quickie:
     ObpReleaseCapturedAttributes(&ObjectCreateInfo);
     if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName);
-    OBTRACE("OBTRACE: %s returning Object with PC S: %lx %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s returning Object with PC S: %lx %lx\n",
             __FUNCTION__,
             OBJECT_TO_OBJECT_HEADER(Object)->PointerCount,
             Status);
@@ -1633,7 +1646,8 @@
     ObDereferenceObject(Object);
 
     /* Return */
-    OBTRACE("OBTRACE: %s returning Object with PC S: %lx %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - returning Object with PC S: %lx %lx\n",
             __FUNCTION__,
             OBJECT_TO_OBJECT_HEADER(Object)->PointerCount,
             Status);
@@ -1993,11 +2007,12 @@
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
     PAGED_CODE();
-    OBTRACE("OBTRACE - %s - Duplicating handle: %lx for %lx into %lx.\n",
-        __FUNCTION__,
-        SourceHandle,
-        SourceProcessHandle,
-        TargetProcessHandle);
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Duplicating handle: %lx for %lx into %lx.\n",
+            __FUNCTION__,
+            SourceHandle,
+            SourceProcessHandle,
+            TargetProcessHandle);
 
     if((TargetHandle) && (PreviousMode != KernelMode))
     {
@@ -2083,7 +2098,8 @@
     }
 
     /* Dereference the processes */
-    OBTRACE("OBTRACE - %s - Duplicated handle: %lx into %lx S %lx\n",
+    OBTRACE(OB_HANDLE_DEBUG,
+            "%s - Duplicated handle: %lx into %lx S %lx\n",
             __FUNCTION__,
             hTarget,
             TargetProcessHandle,

Modified: trunk/reactos/ntoskrnl/ob/obinit.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obinit.c?rev=22319&r1=22318&r2=22319&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obinit.c (original)
+++ trunk/reactos/ntoskrnl/ob/obinit.c Mon Jun 12 09:58:08 2006
@@ -38,6 +38,7 @@
 };
 
 PDEVICE_MAP ObSystemDeviceMap = NULL;
+ULONG ObpTraceLevel = OB_NAMESPACE_DEBUG;
 
 /* PRIVATE FUNCTIONS *********************************************************/
 

Modified: trunk/reactos/ntoskrnl/ob/obname.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obname.c?rev=22319&r1=22318&r2=22319&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obname.c (original)
+++ trunk/reactos/ntoskrnl/ob/obname.c Mon Jun 12 09:58:08 2006
@@ -106,280 +106,433 @@
 ObFindObject(IN HANDLE RootHandle,
              IN PUNICODE_STRING ObjectName,
              IN ULONG Attributes,
-             IN KPROCESSOR_MODE PreviousMode,
+             IN KPROCESSOR_MODE AccessMode,
              IN PVOID *ReturnedObject,
              IN POBJECT_TYPE ObjectType,
              IN POBP_LOOKUP_CONTEXT Context,
              IN PACCESS_STATE AccessState,
              IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
              IN PVOID ParseContext,
-             IN PVOID Insert)
+             OUT PVOID ExpectedObject)
 {
-    PVOID NextObject;
-    PVOID CurrentObject;
-    PVOID RootObject;
+    PVOID RootDirectory;
+    PVOID CurrentDirectory = NULL;
+    PVOID CurrentObject = NULL;
     POBJECT_HEADER CurrentHeader;
     NTSTATUS Status = STATUS_SUCCESS;
-    PWSTR current;
-    UNICODE_STRING PathString;
-    UNICODE_STRING CurrentUs;
-    UNICODE_STRING Path;
-    PUNICODE_STRING RemainingPath = &Path;
-
+    PVOID NewName;
+    POBJECT_HEADER_NAME_INFO ObjectNameInfo;
+    UNICODE_STRING RemainingPath, PartName;
+    BOOLEAN InsideRoot = FALSE;
+    OB_PARSE_METHOD ParseRoutine;
     PAGED_CODE();
 
-    DPRINT("ObFindObject(ObjectCreateInfo %x, ReturnedObject %x, "
-        "RemainingPath %x)\n",ObjectCreateInfo,ReturnedObject,RemainingPath);
-
-    RtlInitUnicodeString (RemainingPath, NULL);
-
-    if (RootHandle == NULL)
-    {
-        ObReferenceObjectByPointer(NameSpaceRoot,
-            DIRECTORY_TRAVERSE,
-            NULL,
-            PreviousMode);
-        CurrentObject = NameSpaceRoot;
+    /* Assume failure */
+    OBTRACE(OB_NAMESPACE_DEBUG,
+            "%s - Finding Object: %wZ. Expecting: %p\n",
+            __FUNCTION__,
+            ObjectName,
+            ExpectedObject);
+    *ReturnedObject = NULL;
+
+    /* Check if we got a Root Directory */
+    if (RootHandle)
+    {
+        /* We did. Reference it */
+        Status = ObReferenceObjectByHandle(RootHandle,
+                                           0,
+                                           NULL,
+                                           AccessMode,
+                                           &RootDirectory,
+                                           NULL);
+        if (!NT_SUCCESS(Status)) return Status;
+
+        /* Get the header */
+        CurrentHeader = OBJECT_TO_OBJECT_HEADER(RootDirectory);
+
+        /* The name cannot start with a separator, unless this is a file */
+        if ((ObjectName->Buffer) &&
+            (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR) &&
+            (CurrentHeader->Type != IoFileObjectType))
+        {
+            /* The syntax is bad, so fail this request */
+            ObDereferenceObject(RootDirectory);
+            return STATUS_OBJECT_PATH_SYNTAX_BAD;
+        }
+
+        /* Don't parse a Directory */
+        if (CurrentHeader->Type != ObDirectoryType)
+        {
+            /* Make sure the Object Type has a parse routine */
+            ParseRoutine = CurrentHeader->Type->TypeInfo.ParseProcedure;
+            if (!ParseRoutine)
+            {
+                /* We can't parse a name if we don't have a parse routine */
+                ObDereferenceObject(RootDirectory);
+                return STATUS_INVALID_HANDLE;
+            }
+
+            /* Now parse */
+            while (TRUE)
+            {
+                /* Start with the full name */
+                RemainingPath = *ObjectName;
+
+                /* Call the Parse Procedure */
+                Status = ParseRoutine(RootDirectory,
+                                      ObjectType,
+                                      AccessState,
+                                      AccessMode,
+                                      Attributes,
+                                      ObjectName,
+                                      &RemainingPath,
+                                      ParseContext,
+                                      SecurityQos,
+                                      &CurrentObject);
+
+                /* Check for success or failure, so not reparse */
+                if ((Status != STATUS_REPARSE) &&
+                    (Status != STATUS_REPARSE_OBJECT))
+                {
+                    /* Check for failure */
+                    if (!NT_SUCCESS(Status))
+                    {
+                        /* Parse routine might not have cleared this, do it */
+                        CurrentObject = NULL;
+                    }
+                    else if (!CurrentObject)
+                    {
+                        /* Modify status to reflect failure inside Ob */
+                        Status = STATUS_OBJECT_NAME_NOT_FOUND;
+                    }
+
+                    /* We're done, return the status and object */
+                    *ReturnedObject = CurrentObject;
+                    ObDereferenceObject(RootDirectory);
+                    return Status;
+                }
+                else if ((!ObjectName->Length) ||
+                         (!ObjectName->Buffer) ||
+                         (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
+                {
+                    /* Reparsed to the root directory, so start over */
+                    ObDereferenceObject(RootDirectory);
+                    RootDirectory = NameSpaceRoot;
+
+                    /* Don't use this anymore, since we're starting at root */
+                    RootHandle = NULL;
+                    break;
+                }
+            }
+        }
+        else if (!(ObjectName->Length) || !(ObjectName->Buffer))
+        {
+            /* Just return the Root Directory if we didn't get a name*/
+            Status = ObReferenceObjectByPointer(RootDirectory,
+                                                0,
+                                                ObjectType,
+                                                AccessMode);
+            if (NT_SUCCESS(Status)) *ReturnedObject = RootDirectory;
+            ObDereferenceObject(RootDirectory);
+            return Status;
+        }
     }
     else
     {
-        Status = ObReferenceObjectByHandle(RootHandle,
-            0,
-            NULL,
-            PreviousMode,
-            &CurrentObject,
-            NULL);
-        if (!NT_SUCCESS(Status))
-        {
-            return Status;
-        }
-    }
-
-    if (ObjectName->Length == 0 ||
-        ObjectName->Buffer[0] == UNICODE_NULL)
-    {
-        *ReturnedObject = CurrentObject;
-        return STATUS_SUCCESS;
-    }
-
-    if (RootHandle == NULL &&
-        ObjectName->Buffer[0] != L'\\')
-    {
-        ObDereferenceObject (CurrentObject);
-        DPRINT1("failed\n");
-        return STATUS_UNSUCCESSFUL;
-    }
-
-    /* Create a zero-terminated copy of the object name */
-    PathString.Length = ObjectName->Length;
-    PathString.MaximumLength = ObjectName->Length + sizeof(WCHAR);
-    PathString.Buffer = ExAllocatePool (NonPagedPool,
-        PathString.MaximumLength);
-    if (PathString.Buffer == NULL)
-    {
-        ObDereferenceObject (CurrentObject);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    RtlCopyMemory (PathString.Buffer,
-        ObjectName->Buffer,
-        ObjectName->Length);
-    PathString.Buffer[PathString.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
-    current = PathString.Buffer;
-
-    RootObject = CurrentObject;
-    if (ObjectType == ObSymbolicLinkType)
-        Attributes |= OBJ_OPENLINK;
-
+        /* We did not get a Root Directory, so use the root */
+        RootDirectory = NameSpaceRoot;
+
+        /* It must start with a path separator */
+        if (!(ObjectName->Length) ||
+            !(ObjectName->Buffer) ||
+            (ObjectName->Buffer[0] != OBJ_NAME_PATH_SEPARATOR))
+        {
+            /* This name is invalid, so fail */
+            return STATUS_OBJECT_PATH_SYNTAX_BAD;
+        }
+
+        /* Check if the name is only the path separator */
+        if (ObjectName->Length == sizeof(OBJ_NAME_PATH_SEPARATOR))
+        {
+            /* So the caller only wants the root directory; do we have one? */
+            if (!RootDirectory)
+            {
+                /* This must be the first time we're creating it... right? */
+                if (ExpectedObject)
+                {
+                    /* Yes, so return it to ObInsert so that it can create it */
+                    Status = ObReferenceObjectByPointer(ExpectedObject,
+                                                        0,
+                                                        ObjectType,
+                                                        AccessMode);
+                    if (NT_SUCCESS(Status)) *ReturnedObject = ExpectedObject;
+                    return Status;
+                }
+                else
+                {
+                    /* This should never really happen */
+                    ASSERT(FALSE);
+                    return STATUS_INVALID_PARAMETER;
+                }
+            }
+            else
+            {
+                /* We do have the root directory, so just return it */
+                Status = ObReferenceObjectByPointer(RootDirectory,
+                                                    0,
+                                                    ObjectType,
+                                                    AccessMode);
+                if (NT_SUCCESS(Status)) *ReturnedObject = RootDirectory;
+                return Status;
+            }
+        }
+    }
+
+    /* Save the name */
+ReparseNewDir:
+    RemainingPath = *ObjectName;
+
+    /* Reparse */
     while (TRUE)
     {
+        /* Check if we should use the Root Directory */
+        if (!InsideRoot)
+        {
+            /* Yes, use the root directory and remember that */
+            CurrentDirectory = RootDirectory;
+            InsideRoot = TRUE;
+        }
+
+        /* Check if the name starts with a path separator */
+        if ((RemainingPath.Length) &&
+            (RemainingPath.Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
+        {
+            /* Skip the path separator */
+            RemainingPath.Buffer++;
+            RemainingPath.Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
+        }
+
+        /* Find the next Part Name */
+        PartName = RemainingPath;
+        while (RemainingPath.Length)
+        {
+            /* Break if we found the \ ending */
+            if (RemainingPath.Buffer[0] == OBJ_NAME_PATH_SEPARATOR) break;
+
+            /* Move on */
+            RemainingPath.Buffer++;
+            RemainingPath.Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
+        }
+
+        /* Get its size and make sure it's valid */
+        if (!(PartName.Length -= RemainingPath.Length))
+        {
+            Status = STATUS_OBJECT_NAME_INVALID;
+            break;
+        }
+
+        /* Do the look up */
+        Context->DirectoryLocked = TRUE;
+        Context->Directory = CurrentDirectory;
+        CurrentObject = ObpLookupEntryDirectory(CurrentDirectory,
+                                                &PartName,
+                                                Attributes,
+                                                FALSE,
+                                                Context);
+        if (!CurrentObject)
+        {
+            /* We didn't find it... do we still have a path? */
+            if (RemainingPath.Length)
+            {
+                /* Then tell the caller the path wasn't found */
+                Status = STATUS_OBJECT_PATH_NOT_FOUND;
+                break;
+            }
+            else if (!ExpectedObject)
+            {
+                /* Otherwise, we have a path, but the name isn't valid */
+                Status = STATUS_OBJECT_NAME_NOT_FOUND;
+                break;
+            }
+
+            /* Reference newly to be inserted object */
+            ObReferenceObject(ExpectedObject);
+            CurrentHeader = OBJECT_TO_OBJECT_HEADER(ExpectedObject);
+
+            /* Create Object Name */
+            NewName = ExAllocatePoolWithTag(NonPagedPool,
+                                            PartName.MaximumLength,
+                                            OB_NAME_TAG);
+            ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(CurrentHeader);
+
+            /* Copy the Name */
+            RtlMoveMemory(NewName, PartName.Buffer, PartName.MaximumLength);
+
+            /* Free old name */
+            if (ObjectNameInfo->Name.Buffer) ExFreePool(ObjectNameInfo->Name.Buffer);
+
+            /* Write new one */
+            ObjectNameInfo->Name.Buffer = NewName;
+            ObjectNameInfo->Name.Length = PartName.Length;
+            ObjectNameInfo->Name.MaximumLength = PartName.MaximumLength;
+
+            /* Rereference the Directory and insert */
+            ObReferenceObject(CurrentDirectory);
+            ObpInsertEntryDirectory(CurrentDirectory, Context, CurrentHeader);
+
+            /* Return Status and the Expected Object */
+            Status = STATUS_SUCCESS;
+            CurrentObject = ExpectedObject;
+
+            /* Get out of here */
+            break;
+        }
+
+Reparse:
+        /* We found it, so now get its header */
         CurrentHeader = OBJECT_TO_OBJECT_HEADER(CurrentObject);
 
-        /* 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;
+        /* 
+         * Check for a parse Procedure, but don't bother to parse for an insert
+         * unless it's a Symbolic Link, in which case we MUST parse
+         */
+        ParseRoutine = CurrentHeader->Type->TypeInfo.ParseProcedure;
+        if (ParseRoutine &&
+            (!ExpectedObject || ParseRoutine == ObpParseSymbolicLink))
+        {
+            /* Use the Root Directory next time */
+            InsideRoot = FALSE;
+
+            /* Call the Parse Procedure */
+            Status = ParseRoutine(CurrentObject,
+                                  ObjectType,
+                                  AccessState,
+                                  AccessMode,
+                                  Attributes,
+                                  ObjectName,
+                                  &RemainingPath,
+                                  ParseContext,
+                                  SecurityQos,
+                                  &CurrentObject);
+
+            /* Check if we have to reparse */
+            if ((Status == STATUS_REPARSE) ||
+                (Status == STATUS_REPARSE_OBJECT))
+            {
+                /* Start over from root if we got sent back there */
+                if ((Status == STATUS_REPARSE_OBJECT) ||
+                    (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
+                {
+                    /* Check if we got a root directory */
+                    if (RootHandle)
+                    {
+                        /* Stop using it, because we have a new directory now */
+                        ObDereferenceObject(RootDirectory);
+                        RootHandle = NULL;
+                    }
+
+                    /* Start at Root */
+                    RootDirectory = NameSpaceRoot;
+
+                    /* Check for reparse status */
+                    if (Status == STATUS_REPARSE_OBJECT)
+                    {
+                        /* Did we actually get an object to which to reparse? */
+                        if (!CurrentObject)
+                        {
+                            /* We didn't, so set a failure status */
+                            Status = STATUS_OBJECT_NAME_NOT_FOUND;
+                        }
+                        else
+                        {
+                            /* We did, so we're free to parse the new object */
+                            InsideRoot = TRUE;
+                            goto Reparse;
+                        }
+                    }
+
+                    /* Restart the search */
+                    goto ReparseNewDir;
+                }
+                else if (RootDirectory == NameSpaceRoot)
+                {
+                    /* We got STATUS_REPARSE but are at the Root Directory */
+                    CurrentObject = NULL;
+                    Status = STATUS_OBJECT_NAME_NOT_FOUND;
+                }
+            }
+            else if (!NT_SUCCESS(Status))
+            {
+                /* Total failure */
+                CurrentObject = NULL;
+            }
+            else if (!CurrentObject)
+            {
+                /* We didn't reparse but we didn't find the Object Either */
+                Status = STATUS_OBJECT_NAME_NOT_FOUND;
+            }
+
+            /* Break out of the loop */
+            break;
+        }
+        else
+        {
+            /* No parse routine...do we still have a remaining name? */
+            if (!RemainingPath.Length)
+            {
+                /* Are we creating an object? */
+                if (!ExpectedObject)
+                {
+                    /* We don't... reference the Object */
+                    Status = ObReferenceObjectByPointer(CurrentObject,
+                                                        0,
+                                                        ObjectType,
+                                                        AccessMode);
+                    if (!NT_SUCCESS(Status)) CurrentObject = NULL;
+                }
+
+                /* And get out of the reparse loop */
+                break;
             }
             else
             {
-                current = NULL;
-            }
-
-            NextObject = FoundObject;
-
-Next:
-            if (NextObject == NULL)
-            {
-                break;
-            }
-            ObDereferenceObject(CurrentObject);
-            CurrentObject = NextObject;
-            CurrentHeader = OBJECT_TO_OBJECT_HEADER(CurrentObject);
-        }
-
-        if (CurrentHeader->Type->TypeInfo.ParseProcedure == NULL)
-        {
-            DPRINT("Current object can't parse\n");
-            break;
-        }
-
-        RtlInitUnicodeString(&CurrentUs, current);
-        Status = CurrentHeader->Type->TypeInfo.ParseProcedure(CurrentObject,
-            CurrentHeader->Type,
-            AccessState,
-            PreviousMode,
-            Attributes,
-            &PathString,
-            &CurrentUs,
-            ParseContext,
-            SecurityQos,
-            &NextObject);
-        current = CurrentUs.Buffer;
-        if (Status == STATUS_REPARSE)
-        {
-            /* reparse the object path */
-            NextObject = NameSpaceRoot;
-            current = PathString.Buffer;
-
-            ObReferenceObjectByPointer(NextObject,
-                DIRECTORY_TRAVERSE,
-                NULL,
-                PreviousMode);
-        }
-
-
-        if (NextObject == NULL)
-        {
-            break;
-        }
-        ObDereferenceObject(CurrentObject);
-        CurrentObject = NextObject;
-        if (!current) break;
-    }
-
-    if (current)
-    {
-        RtlpCreateUnicodeString (RemainingPath, current, NonPagedPool);
-    }
-
-    RtlFreeUnicodeString (&PathString);
-    *ReturnedObject = CurrentObject;
-
-    /*
-     * Icky hack: put the code that was in ObInsertObject here so that
-     * we can get rid of the "RemainingPath" stuff, which shouldn't
-     * be exposed outside of here.
-     * Also makes the interface closer to NT parsing, and will make the
-     * eventual changes easier to deal with
-     */
-    if (Insert)
-    {
-        PVOID FoundObject = NULL;
-        POBJECT_HEADER Header = OBJECT_TO_OBJECT_HEADER(Insert);
-        POBJECT_HEADER FoundHeader = NULL;
-        FoundObject = *ReturnedObject;
-        if (FoundObject)
-        {
-            FoundHeader = OBJECT_TO_OBJECT_HEADER(FoundObject);
-        }
-
-        if (FoundHeader && RemainingPath->Buffer == NULL)
-        {
-            DPRINT("Object exists\n");
-            ObDereferenceObject(FoundObject);
-            return STATUS_OBJECT_NAME_COLLISION;
-        }
-
-        /*
-         * MiniHack
-         * If we still have a remaining path on a directory object, but we are
-         * a file object, then fail, because this means the file doesn't exist
-         */
-        if ((RemainingPath->Buffer) &&
-            (FoundHeader && FoundHeader->Type == ObDirectoryType) &&
-            (Header->Type == IoFileObjectType))
-        {
-            /* Hack */
-            RtlFreeUnicodeString(RemainingPath);
-            *ReturnedObject = NULL;
-            return STATUS_OBJECT_PATH_NOT_FOUND;
-        }
-
-        if (FoundHeader && FoundHeader->Type == ObDirectoryType &&
-            RemainingPath->Buffer)
-        {
-            /* The name was changed so let's update it */
-            PVOID NewName;
-            PWSTR BufferPos = RemainingPath->Buffer;
-            ULONG Delta = 0;
-            POBJECT_HEADER_NAME_INFO ObjectNameInfo;
-
-            ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(Header);
-
-            if (BufferPos[0] == L'\\')
-            {
-                BufferPos++;
-                Delta = sizeof(WCHAR);
-            }
-            NewName = ExAllocatePool(NonPagedPool, RemainingPath->MaximumLength - Delta);
-            RtlMoveMemory(NewName, BufferPos, RemainingPath->MaximumLength - Delta);
-            if (ObjectNameInfo->Name.Buffer) ExFreePool(ObjectNameInfo->Name.Buffer);
-            ObjectNameInfo->Name.Buffer = NewName;
-            ObjectNameInfo->Name.Length = RemainingPath->Length - Delta;
-            ObjectNameInfo->Name.MaximumLength = RemainingPath->MaximumLength - Delta;
-            ObpInsertEntryDirectory(FoundObject, Context, Header);
-        }
-
-        RtlFreeUnicodeString(RemainingPath);
-        *ReturnedObject = Insert;
-    }
-    else
-    {
-        /* ROS Hack */
-        DPRINT("REmaining path: %wZ\n", RemainingPath);
-        if (RemainingPath->Buffer != NULL)
-        {
-            if (wcschr(RemainingPath->Buffer + 1, L'\\') == NULL)
-                Status = STATUS_OBJECT_NAME_NOT_FOUND;
-            else
-                Status =STATUS_OBJECT_PATH_NOT_FOUND;
-        }
-    }
-
+                /* We still have a name; check if this is a directory object */
+                if (CurrentHeader->Type == ObDirectoryType)
+                {
+                    /* Restart from this directory */
+                    CurrentDirectory = CurrentObject;
+                }
+                else
+                {
+                    /* We still have a name, but no parse routine for it */
+                    Status = STATUS_OBJECT_TYPE_MISMATCH;
+                    CurrentObject = NULL;
+                    break;
+                }
+            }
+        }
+    }
+
+    /* Write what we found, and if it's null, check if we got success */
+    if (!(*ReturnedObject = CurrentObject) && (NT_SUCCESS(Status)))
+    {
+        /* Nothing found... but we have success. Correct the status code */
+        Status = STATUS_OBJECT_NAME_NOT_FOUND;
+    }
+
+    /* Check if we had a root directory */
+    if (RootHandle)
+    {
+        /* Dereference it */
+        ObDereferenceObject(RootDirectory);
+    }
+
+    /* Return status to caller */
+    OBTRACE(OB_NAMESPACE_DEBUG,
+            "%s - Found Object: %p. Expected: %p\n",
+            __FUNCTION__,
+            *ReturnedObject,
+            ExpectedObject);
     return Status;
 }
 

Modified: trunk/reactos/ntoskrnl/ob/symlink.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/symlink.c?rev=22319&r1=22318&r2=22319&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ob/symlink.c (original)
+++ trunk/reactos/ntoskrnl/ob/symlink.c Mon Jun 12 09:58:08 2006
@@ -100,24 +100,45 @@
     POBJECT_SYMBOLIC_LINK SymlinkObject = (POBJECT_SYMBOLIC_LINK)ParsedObject;
     PUNICODE_STRING TargetPath;
     PWSTR NewTargetPath;
-    ULONG LengthUsed, MaximumLength, RemainLength;
-    PWSTR *RemainingPath = &RemainingName->Buffer;
-
-    /*
-    * Stop parsing if the entire path has been parsed and
-    * the desired object is a symbolic link object.
-    */
-    if (((*RemainingPath == NULL) || (**RemainingPath == 0)) &&
-        (Attributes & OBJ_OPENLINK))
-    {
-        *NextObject = NULL;
-        return(STATUS_SUCCESS);
+    ULONG LengthUsed, MaximumLength;
+    NTSTATUS Status;
+
+    /* Assume failure */
+    *NextObject = NULL;
+
+    /* Check if we're out of name to parse */
+    if (!RemainingName->Length)
+    {
+        /* Check if we got an object type */
+        if (ObjectType)
+        {
+            /* Reference the object only */
+            Status = ObReferenceObjectByPointer(ParsedObject,
+                                                0,
+                                                ObjectType,
+                                                AccessMode);
+            if (NT_SUCCESS(Status))
+            {
+                /* Return it */
+                *NextObject = ParsedObject;
+            }
+
+            if ((NT_SUCCESS(Status)) || (Status != STATUS_OBJECT_TYPE_MISMATCH))
+            {
+                /* Fail */
+                return Status;
+            }
+        }
+    }
+    else if (RemainingName->Buffer[0] != OBJ_NAME_PATH_SEPARATOR)
+    {
+        /* Symbolic links must start with a backslash */
+        return STATUS_OBJECT_TYPE_MISMATCH;
     }
 
     /* Set the target path and length */
     TargetPath = &SymlinkObject->LinkTarget;
-    RemainLength = *RemainingPath ? wcslen(*RemainingPath) * sizeof(WCHAR) : 0;
-    LengthUsed = TargetPath->Length + RemainLength;
+    LengthUsed = TargetPath->Length + RemainingName->Length;
 
     /* Optimization: check if the new name is shorter */
     if (FullPath->MaximumLength <= LengthUsed)
@@ -136,12 +157,12 @@
     }
 
     /* Make sure we have a length */
-    if (RemainLength)
+    if (RemainingName->Length)
     {
         /* Copy the new path */
         RtlMoveMemory((PVOID)((ULONG_PTR)NewTargetPath + TargetPath->Length),
-                      *RemainingPath,
-                      RemainLength);
+                      RemainingName->Buffer,
+                      RemainingName->Length);
     }
 
     /* Copy the target path and null-terminate it */
@@ -156,10 +177,7 @@
     FullPath->MaximumLength = MaximumLength;
     FullPath->Buffer = NewTargetPath;
 
-    /* Reinitialize RemainingPath for reparsing */
-    *RemainingPath = FullPath->Buffer;
-
-    *NextObject = NULL;
+    /* Tell the parse routine to start reparsing */
     return STATUS_REPARSE;
 }
 

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c?rev=22319&r1=22318&r2=22319&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c Mon Jun 12 09:58:08 2006
@@ -133,7 +133,6 @@
                 /* Reference the desktop and return it */
                 ObReferenceObject(Desktop);
                 *Object = Desktop;
-                RemainingName->Buffer = NULL; // => ROS Parse routines need to do this
                 return Status;
             }
         }
@@ -168,7 +167,6 @@
 
     /* Set the desktop object and return success */
     *Object = Desktop;
-    RemainingName->Buffer = NULL; // => ROS Parse routines need to do this
     return STATUS_SUCCESS;
 }
 

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c
URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c?rev=22319&r1=22318&r2=22319&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c Mon Jun 12 09:58:08 2006
@@ -126,8 +126,8 @@
         }
 
         /* Reference the window station and return */
-        //ObReferenceObject(Object);
-        //*NextObject = Object; => ROS Parse routines don't need to do this
+        ObReferenceObject(Parameters->ParseObject);
+        *Parameters->Object = Parameters->ParseObject;
         return STATUS_SUCCESS;
     }
 
@@ -149,10 +149,8 @@
 
     /*
      * Check if we are parsing a desktop.
-     * FIXME: ROS Sends the wrong Object Type. The parsed object's type
-     * should be sent, not the parsed parent's.
      */
-    if (Parameters->ObjectType == ExWindowStationObjectType)
+    if (Parameters->ObjectType == ExDesktopObjectType)
     {
         /* Then call the desktop parse routine */
         return IntDesktopObjectParse(Parameters->ParseObject,




More information about the Ros-diffs mailing list