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/o…
==============================================================================
--- 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(a)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(a)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/o…
==============================================================================
--- 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(a)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=2231…
==============================================================================
--- 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=…
==============================================================================
--- 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=22…
==============================================================================
--- 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=22…
==============================================================================
--- 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=2…
==============================================================================
--- 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/ntu…
==============================================================================
--- 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/ntu…
==============================================================================
--- 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,