Object Manager Patch. This patch continues the work done in the previous
patch and makes the following changes in order to support OB 2.0 (it
basically temporarily fixes a highly incorrect implementation so that
caller code will be ready to work with the OB 2.0 without change):
1) The documented Object Create Information Structure and semantics
implemented. All Object Attributes and passed data from user-mode is now
probed and saved into this object create structure when ObCreateObject
is called.
2) ObCreateObject does NOT PERFORM ANY OTHER OPERATION EXCEPT CREATING
THE OBJECT ANYMORE. ObCreateObject will NOT insert the Object into the
tree and other operations. These are now done correctly by
ObInsertObject. Therefore, the biggest hurdle was changing pieces of
code which assumed ObCreateObject would be enough.
3) ObInsertObject uses the captured create info for all operations
isntead of the Object Attributes.
4) ObFindObject now uses the captured info as well.
5) The OBject name and directory are now stored in the documented Object
Name Information, always allocated and freed from non paged pool.
HACKS:
5) Because the registry code is horribly broken and doesn't use
ObFindObjectByName, the old ObFindObject had to be temporarily
duplicated into CmpFindObject.
7) Win32k used ObInsertObject in CsrInsertObject as a way to create a
handle inside csrss. However, OBInsertObject now does more then this. As
a temporary hack, ObpCreateHandle is exported from the kernel and called
from win32k. A fix needs to be done for this, but I don't know the
design of win32k+csrss well enough to find a solution.
8) SEH has been commented out in some places of the new probing code
because it breaks smss and explorer. These need to be investigated (seh
did not exist in the previous code, so this is not really a hack)
9) Named objects with a parent directory are NOT allowed. However
because of bugs in kernel32, the new check has been temporarily
disabled. (this check did not exist in the previous code, so this is not
really a hack)
The next patch will add a proper ObFindObject which will support a more
complete Parse Procedure with context and security information. This is
needed for proper registry access (requested by Eric Kohl) and for
proper functionality of the Desktop/File creation, which should use the
Parse routine, and not the Create Handle Routine. This will also make it
possible to remove some previous hacks and pave the way for a fixed
Iop/IoCreateFile
Modified: trunk/reactos/include/ddk/obfuncs.h
Modified: trunk/reactos/ntoskrnl/cm/cm.h
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
Modified: trunk/reactos/ntoskrnl/cm/registry.c
Modified: trunk/reactos/ntoskrnl/cm/regobj.c
Modified: trunk/reactos/ntoskrnl/include/internal/io.h
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
Modified: trunk/reactos/ntoskrnl/io/driver.c
Modified: trunk/reactos/ntoskrnl/io/file.c
Modified: trunk/reactos/ntoskrnl/mm/section.c
Modified: trunk/reactos/ntoskrnl/ntoskrnl.def
Modified: trunk/reactos/ntoskrnl/ob/dirobj.c
Modified: trunk/reactos/ntoskrnl/ob/handle.c
Modified: trunk/reactos/ntoskrnl/ob/namespc.c
Modified: trunk/reactos/ntoskrnl/ob/ntobj.c
Modified: trunk/reactos/ntoskrnl/ob/object.c
Modified: trunk/reactos/ntoskrnl/rtl/nls.c
Modified: trunk/reactos/ntoskrnl/se/sd.c
Modified: trunk/reactos/ntoskrnl/se/semgr.c
Modified: trunk/reactos/ntoskrnl/se/token.c
Modified: trunk/reactos/subsys/system/services/database.c
Modified: trunk/reactos/subsys/win32k/ntuser/csr.c
Modified: trunk/reactos/w32api/include/ddk/winddk.h
_____
Modified: trunk/reactos/include/ddk/obfuncs.h
--- trunk/reactos/include/ddk/obfuncs.h 2005-05-18 19:08:00 UTC (rev
15394)
+++ trunk/reactos/include/ddk/obfuncs.h 2005-05-18 19:26:47 UTC (rev
15395)
@@ -63,6 +63,15 @@
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG BufferLength);
+typedef struct _OBJECT_HEADER_NAME_INFO
+{
+ struct _DIRECTORY_OBJECT *Directory;
+ UNICODE_STRING Name;
+ ULONG QueryReferences;
+ ULONG Reserved2;
+ ULONG DbgReferenceCount;
+} OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
+
typedef struct _OBJECT_CREATE_INFORMATION
{
ULONG Attributes;
_____
Modified: trunk/reactos/ntoskrnl/cm/cm.h
--- trunk/reactos/ntoskrnl/cm/cm.h 2005-05-18 19:08:00 UTC (rev
15394)
+++ trunk/reactos/ntoskrnl/cm/cm.h 2005-05-18 19:26:47 UTC (rev
15395)
@@ -744,4 +744,11 @@
CmiSaveTempHive (PREGISTRY_HIVE Hive,
HANDLE FileHandle);
+/* TEMPORARY HACK UNTIL PROPER PARSE ROUTINES SOON. DO NOT REMOVE --
Alex */
+NTSTATUS
+CmpFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
+ PVOID* ReturnedObject,
+ PUNICODE_STRING RemainingPath,
+ POBJECT_TYPE ObjectType);
+
#endif /*__INCLUDE_CM_H*/
_____
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
--- trunk/reactos/ntoskrnl/cm/ntfunc.c 2005-05-18 19:08:00 UTC (rev
15394)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c 2005-05-18 19:26:47 UTC (rev
15395)
@@ -30,6 +30,138 @@
/* FUNCTIONS
****************************************************************/
+/* TEMPORARY HACK UNTIL PROPER PARSE ROUTINES SOON. DO NOT REMOVE --
Alex */
+NTSTATUS
+CmpFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
+ PVOID* ReturnedObject,
+ PUNICODE_STRING RemainingPath,
+ POBJECT_TYPE ObjectType)
+{
+ PVOID NextObject;
+ PVOID CurrentObject;
+ PVOID RootObject;
+ POBJECT_HEADER CurrentHeader;
+ NTSTATUS Status;
+ PWSTR current;
+ UNICODE_STRING PathString;
+ ULONG Attributes;
+ PUNICODE_STRING ObjectName;
+
+ PAGED_CODE();
+
+ DPRINT("CmpFindObject(ObjectAttributes %x, ReturnedObject %x, "
+ "RemainingPath
%x)\n",ObjectAttributes,ReturnedObject,RemainingPath);
+ DPRINT("ObjectAttributes->ObjectName %wZ\n",
+ ObjectAttributes->ObjectName);
+
+ RtlInitUnicodeString (RemainingPath, NULL);
+
+ if (ObjectAttributes->RootDirectory == NULL)
+ {
+ ObReferenceObjectByPointer(NameSpaceRoot,
+ DIRECTORY_TRAVERSE,
+ NULL,
+ UserMode);
+ CurrentObject = NameSpaceRoot;
+ }
+ else
+ {
+ Status =
ObReferenceObjectByHandle(ObjectAttributes->RootDirectory,
+ 0,
+ NULL,
+ UserMode,
+ &CurrentObject,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+
+ ObjectName = ObjectAttributes->ObjectName;
+ if (ObjectName->Length == 0 ||
+ ObjectName->Buffer[0] == UNICODE_NULL)
+ {
+ *ReturnedObject = CurrentObject;
+ return STATUS_SUCCESS;
+ }
+
+ if (ObjectAttributes->RootDirectory == NULL &&
+ ObjectName->Buffer[0] != L'\\')
+ {
+ ObDereferenceObject (CurrentObject);
+ 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;
+ Attributes = ObjectAttributes->Attributes;
+ if (ObjectType == ObSymbolicLinkType)
+ Attributes |= OBJ_OPENLINK;
+
+ while (TRUE)
+ {
+ DPRINT("current %S\n",current);
+ CurrentHeader = BODY_TO_HEADER(CurrentObject);
+
+ DPRINT("Current ObjectType %wZ\n",
+ &CurrentHeader->ObjectType->TypeName);
+
+ if (CurrentHeader->ObjectType->TypeInfo.ParseProcedure == NULL)
+ {
+ DPRINT("Current object can't parse\n");
+ break;
+ }
+ Status =
CurrentHeader->ObjectType->TypeInfo.ParseProcedure(CurrentObject,
+ &NextObject,
+ &PathString,
+ ¤t,
+ Attributes);
+ if (Status == STATUS_REPARSE)
+ {
+ /* reparse the object path */
+ NextObject = NameSpaceRoot;
+ current = PathString.Buffer;
+
+ ObReferenceObjectByPointer(NextObject,
+ DIRECTORY_TRAVERSE,
+ NULL,
+ UserMode);
+ }
+
+ if (NextObject == NULL)
+ {
+ break;
+ }
+ ObDereferenceObject(CurrentObject);
+ CurrentObject = NextObject;
+ }
+
+ if (current)
+ RtlpCreateUnicodeString (RemainingPath, current, NonPagedPool);
+ RtlFreeUnicodeString (&PathString);
+ *ReturnedObject = CurrentObject;
+
+ return STATUS_SUCCESS;
+}
+
/*
* @implemented
*/
@@ -199,13 +331,13 @@
KeyHandle,
ObjectAttributes->RootDirectory);
- Status = ObFindObject(ObjectAttributes,
+ Status = CmpFindObject(ObjectAttributes,
&Object,
&RemainingPath,
CmiKeyType);
if (!NT_SUCCESS(Status))
{
- DPRINT("ObFindObject failed, Status: 0x%x\n", Status);
+ DPRINT("CmpFindObject failed, Status: 0x%x\n", Status);
return(Status);
}
@@ -379,7 +511,7 @@
PAGED_CODE();
- DPRINT1("NtDeleteKey(KeyHandle %x) called\n", KeyHandle);
+ DPRINT("NtDeleteKey(KeyHandle %x) called\n", KeyHandle);
PreviousMode = ExGetPreviousMode();
@@ -418,7 +550,7 @@
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
- DPRINT1("PointerCount %lu\n",
ObGetObjectPointerCount((PVOID)KeyObject));
+ DPRINT("PointerCount %lu\n",
ObGetObjectPointerCount((PVOID)KeyObject));
/* Dereference the object */
ObDereferenceObject(KeyObject);
@@ -1146,14 +1278,14 @@
return(STATUS_BUFFER_OVERFLOW);*/
RemainingPath.Buffer = NULL;
- Status = ObFindObject(ObjectAttributes,
+ Status = CmpFindObject(ObjectAttributes,
&Object,
&RemainingPath,
CmiKeyType);
if (!NT_SUCCESS(Status))
{
- DPRINT("ObFindObject() returned 0x%08lx\n", Status);
- Status = STATUS_INVALID_HANDLE; /* Because ObFindObject
returns STATUS_UNSUCCESSFUL */
+ DPRINT("CmpFindObject() returned 0x%08lx\n", Status);
+ Status = STATUS_INVALID_HANDLE; /* Because CmpFindObject
returns STATUS_UNSUCCESSFUL */
hKey = *KeyHandle; /* Preserve hkResult value */
goto openkey_cleanup;
}
_____
Modified: trunk/reactos/ntoskrnl/cm/registry.c
--- trunk/reactos/ntoskrnl/cm/registry.c 2005-05-18 19:08:00 UTC
(rev 15394)
+++ trunk/reactos/ntoskrnl/cm/registry.c 2005-05-18 19:26:47 UTC
(rev 15395)
@@ -702,7 +702,7 @@
DPRINT("CmiConnectHive(%p, %p) called.\n",
KeyObjectAttributes, RegistryHive);
- Status = ObFindObject(KeyObjectAttributes,
+ Status = CmpFindObject(KeyObjectAttributes,
(PVOID*)&ParentKey,
&RemainingPath,
CmiKeyType);
@@ -746,6 +746,7 @@
0,
0,
(PVOID*)&NewKey);
+
if (!NT_SUCCESS(Status))
{
DPRINT1 ("ObCreateObject() failed (Status %lx)\n", Status);
@@ -753,7 +754,14 @@
RtlFreeUnicodeString(&RemainingPath);
return Status;
}
-
+ DPRINT("Inserting Key into Object Tree\n");
+ Status = ObInsertObject((PVOID)NewKey,
+ NULL,
+ KEY_ALL_ACCESS,
+ 0,
+ NULL,
+ NULL);
+DPRINT("Status %x\n", Status);
NewKey->RegistryHive = RegistryHive;
NewKey->KeyCellOffset = RegistryHive->HiveHeader->RootKeyOffset;
NewKey->KeyCell = CmiGetCell (RegistryHive, NewKey->KeyCellOffset,
NULL);
_____
Modified: trunk/reactos/ntoskrnl/cm/regobj.c
--- trunk/reactos/ntoskrnl/cm/regobj.c 2005-05-18 19:08:00 UTC (rev
15394)
+++ trunk/reactos/ntoskrnl/cm/regobj.c 2005-05-18 19:26:47 UTC (rev
15395)
@@ -176,6 +176,15 @@
RtlFreeUnicodeString(&KeyName);
return(Status);
}
+ DPRINT("Inserting Key into Object Tree\n");
+ Status = ObInsertObject((PVOID)FoundObject,
+ NULL,
+ KEY_ALL_ACCESS,
+ 0,
+ NULL,
+ NULL);
+ DPRINT("Status %x\n", Status);
+
/* Add the keep-alive reference */
ObReferenceObject(FoundObject);
@@ -503,7 +512,7 @@
else
{
/* KeyObject is the root key */
- Status = ObQueryNameString (BODY_TO_HEADER(KeyObject)->Parent,
+ Status = ObQueryNameString
(BODY_TO_HEADER(KeyObject)->NameInfo->Directory,
LocalInfo,
MAX_PATH * sizeof(WCHAR),
&LocalReturnLength);
_____
Modified: trunk/reactos/ntoskrnl/include/internal/io.h
--- trunk/reactos/ntoskrnl/include/internal/io.h 2005-05-18
19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/include/internal/io.h 2005-05-18
19:26:47 UTC (rev 15395)
@@ -385,11 +385,6 @@
PVOID* SystemArgument2);
NTSTATUS STDCALL
-IopCreateFile(PVOID ObjectBody,
- PVOID Parent,
- PWSTR RemainingPath,
- POBJECT_ATTRIBUTES ObjectAttributes);
-NTSTATUS STDCALL
IopCreateDevice(PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
@@ -553,7 +548,7 @@
IopCreateFile(PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
- POBJECT_ATTRIBUTES ObjectAttributes);
+ POBJECT_CREATE_INFORMATION ObjectAttributes);
VOID
STDCALL
_____
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
--- trunk/reactos/ntoskrnl/include/internal/ob.h 2005-05-18
19:08:00 UTC (rev 15394)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h 2005-05-18
19:26:47 UTC (rev 15395)
@@ -29,14 +29,14 @@
* PURPOSE: Header for every object managed by the object manager
*/
{
- UNICODE_STRING Name;
+ POBJECT_HEADER_NAME_INFO NameInfo;
LIST_ENTRY Entry;
LONG RefCount;
LONG HandleCount;
BOOLEAN Permanent;
BOOLEAN Inherit;
- struct _DIRECTORY_OBJECT* Parent;
POBJECT_TYPE ObjectType;
+ POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PSECURITY_DESCRIPTOR SecurityDescriptor;
/*
@@ -133,7 +133,8 @@
VOID ObCreateHandleTable(struct _EPROCESS* Parent,
BOOLEAN Inherit,
struct _EPROCESS* Process);
-NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
+NTSTATUS ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
+ PUNICODE_STRING ObjectName,
PVOID* ReturnedObject,
PUNICODE_STRING RemainingPath,
POBJECT_TYPE ObjectType);
@@ -148,7 +149,7 @@
NTSTATUS
STDCALL
-ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
+ObpCreateTypeObject(struct _OBJECT_TYPE_INITIALIZER
*ObjectTypeInitializer,
PUNICODE_STRING TypeName,
POBJECT_TYPE *ObjectType);
@@ -224,18 +225,22 @@
} CAPTURED_OBJECT_ATTRIBUTES, *PCAPTURED_OBJECT_ATTRIBUTES;
NTSTATUS
-ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes
OPTIONAL,
+STDCALL
+ObpCaptureObjectName(IN PUNICODE_STRING CapturedName,
+ IN PUNICODE_STRING ObjectName,
+ IN KPROCESSOR_MODE AccessMode);
+
+NTSTATUS
+STDCALL
+ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
IN KPROCESSOR_MODE AccessMode,
- IN POOL_TYPE PoolType,
- IN BOOLEAN CaptureIfKernel,
- OUT PCAPTURED_OBJECT_ATTRIBUTES
CapturedObjectAttributes OPTIONAL,
- OUT PUNICODE_STRING ObjectName OPTIONAL);
+ IN POBJECT_TYPE ObjectType,
+ IN POBJECT_CREATE_INFORMATION
ObjectCreateInfo,
+ OUT PUNICODE_STRING ObjectName);
VOID
-ObpReleaseObjectAttributes(IN PCAPTURED_OBJECT_ATTRIBUTES
CapturedObjectAttributes OPTIONAL,
- IN PUNICODE_STRING ObjectName OPTIONAL,
- IN KPROCESSOR_MODE AccessMode,
- IN BOOLEAN CaptureIfKernel);
+STDCALL
+ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION
ObjectCreateInfo);
/* object information classes */
_____
Modified: trunk/reactos/ntoskrnl/io/driver.c
--- trunk/reactos/ntoskrnl/io/driver.c 2005-05-18 19:08:00 UTC (rev
15394)
+++ trunk/reactos/ntoskrnl/io/driver.c 2005-05-18 19:26:47 UTC (rev
15395)
@@ -218,6 +218,17 @@
{
return Status;
}
+
+ Status = ObInsertObject(Object,
+ NULL,
+ FILE_ALL_ACCESS,
+ 0,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
if (Status == STATUS_OBJECT_EXISTS)
{
_____
Modified: trunk/reactos/ntoskrnl/io/file.c
--- trunk/reactos/ntoskrnl/io/file.c 2005-05-18 19:08:00 UTC (rev
15394)
+++ trunk/reactos/ntoskrnl/io/file.c 2005-05-18 19:26:47 UTC (rev
15395)
@@ -47,7 +47,7 @@
IopCreateFile(PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
- POBJECT_ATTRIBUTES ObjectAttributes)
+ POBJECT_CREATE_INFORMATION ObjectCreateInfo)
{
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject = (PFILE_OBJECT) ObjectBody;
@@ -73,8 +73,8 @@
ParentObjectType != IoFileObjectType)
{
DPRINT("Parent [%wZ] is a %S which is neither a file type nor a
device type ; remaining path = %S\n",
- &BODY_TO_HEADER(Parent)->Name,
- BODY_TO_HEADER(Parent)->ObjectType->TypeName.Buffer,
+ &BODY_TO_HEADER(Parent)->NameInfo->Name,
+ BODY_TO_HEADER(Parent)->ObjectType->Name.Buffer,
RemainingPath);
return(STATUS_UNSUCCESSFUL);
}
@@ -852,6 +852,7 @@
if (CreateDisposition == FILE_OPEN ||
CreateDisposition == FILE_OPEN_IF)
{
+
Status = ObOpenObjectByName(ObjectAttributes,
NULL,
NULL,
@@ -859,6 +860,7 @@
DesiredAccess,
NULL,
&LocalHandle);
+
if (NT_SUCCESS(Status))
{
Status = ObReferenceObjectByHandle(LocalHandle,
@@ -1012,7 +1014,7 @@
*/
Status = IofCallDriver(FileObject->DeviceObject, Irp );
DPRINT("Status :%x\n", Status);
-
+
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&FileObject->Event,
_____
Modified: trunk/reactos/ntoskrnl/mm/section.c
--- trunk/reactos/ntoskrnl/mm/section.c 2005-05-18 19:08:00 UTC (rev
15394)
+++ trunk/reactos/ntoskrnl/mm/section.c 2005-05-18 19:26:47 UTC (rev
15395)
@@ -2099,6 +2099,16 @@
DbgPrint("Failed to create PhysicalMemory section\n");
KEBUGCHECK(0);
}
+ Status = ObInsertObject(PhysSection,
+ NULL,
+ SECTION_ALL_ACCESS,
+ 0,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject(PhysSection);
+ }
PhysSection->AllocationAttributes |= SEC_PHYSICALMEMORY;
return(STATUS_SUCCESS);
@@ -2239,7 +2249,6 @@
{
return(Status);
}
-
/*
* Initialize it
*/
@@ -3140,6 +3149,7 @@
UserMode,
(PVOID*)(PVOID)&FileObject,
NULL);
+
if (!NT_SUCCESS(Status))
{
return Status;
_____
Modified: trunk/reactos/ntoskrnl/ntoskrnl.def
--- trunk/reactos/ntoskrnl/ntoskrnl.def 2005-05-18 19:08:00 UTC (rev
15394)
+++ trunk/reactos/ntoskrnl/ntoskrnl.def 2005-05-18 19:26:47 UTC (rev
15395)
@@ -823,6 +823,7 @@
;ObCheckCreateObjectAccess@28
;ObCheckObjectAccess@20
ObCreateObject@36
+ObpCreateHandle ; FIXME! See win32k/ntuser/csr.c!
ObFindHandleForObject@20
ObGetObjectPointerCount@4
ObGetObjectSecurity@12
_____
Modified: trunk/reactos/ntoskrnl/ob/dirobj.c
--- trunk/reactos/ntoskrnl/ob/dirobj.c 2005-05-18 19:08:00 UTC (rev
15394)
+++ trunk/reactos/ntoskrnl/ob/dirobj.c 2005-05-18 19:26:47 UTC (rev
15395)
@@ -253,7 +253,7 @@
EntryHeader = CONTAINING_RECORD(ListEntry, OBJECT_HEADER,
Entry);
/* calculate the size of the required buffer space for this
entry */
- Name = (EntryHeader->Name.Length != 0 ? &EntryHeader->Name :
NULL);
+ Name = (EntryHeader->NameInfo->Name.Length != 0 ?
&EntryHeader->NameInfo->Name : NULL);
Type = &EntryHeader->ObjectType->Name;
EntrySize = sizeof(OBJECT_DIRECTORY_INFORMATION) +
((Name != NULL) ? ((ULONG)Name->Length +
sizeof(WCHAR)) : 0) +
@@ -440,8 +440,8 @@
PAGED_CODE();
DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, "
- "DesiredAccess %x, ObjectAttributes %x\n",
- DirectoryHandle, DesiredAccess, ObjectAttributes);
+ "DesiredAccess %x, ObjectAttributes %x\n",
+ DirectoryHandle, DesiredAccess, ObjectAttributes);
PreviousMode = ExGetPreviousMode();
_____
Modified: trunk/reactos/ntoskrnl/ob/handle.c
--- trunk/reactos/ntoskrnl/ob/handle.c 2005-05-18 19:08:00 UTC (rev
15394)
+++ trunk/reactos/ntoskrnl/ob/handle.c 2005-05-18 19:26:47 UTC (rev
15395)
@@ -46,6 +46,14 @@
PHANDLE_TABLE ObpKernelHandleTable = NULL;
+/* TEMPORARY HACK. DO NOT REMOVE -- Alex */
+NTSTATUS
+STDCALL
+ExpDesktopCreate(PVOID ObjectBody,
+ PVOID Parent,
+ PWSTR RemainingPath,
+ POBJECT_CREATE_INFORMATION ObjectCreateInformation);
+
/* FUNCTIONS
***************************************************************/
static VOID
@@ -64,7 +72,7 @@
if(NewHandleCount == 0)
{
- if(ObjectHeader->Parent != NULL && !ObjectHeader->Permanent)
+ if(ObjectHeader->NameInfo->Directory != NULL &&
!ObjectHeader->Permanent)
{
/* delete the object from the namespace when the last handle got
closed.
Only do this if it's actually been inserted into the namespace
and
@@ -925,27 +933,221 @@
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS
+STDCALL
ObInsertObject(IN PVOID Object,
- IN PACCESS_STATE PassedAccessState OPTIONAL,
- IN ACCESS_MASK DesiredAccess,
- IN ULONG AdditionalReferences,
- OUT PVOID* ReferencedObject OPTIONAL,
- OUT PHANDLE Handle)
+ IN PACCESS_STATE PassedAccessState OPTIONAL,
+ IN ACCESS_MASK DesiredAccess,
+ IN ULONG AdditionalReferences,
+ OUT PVOID* ReferencedObject OPTIONAL,
+ OUT PHANDLE Handle)
{
- POBJECT_HEADER ObjectHeader;
- ACCESS_MASK Access;
+ POBJECT_CREATE_INFORMATION ObjectCreateInfo;
+ POBJECT_HEADER Header;
+ POBJECT_HEADER_NAME_INFO ObjectNameInfo;
+ PVOID FoundObject = NULL;
+ POBJECT_HEADER FoundHeader = NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
+ UNICODE_STRING RemainingPath;
+ BOOLEAN ObjectAttached = FALSE;
+ PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
+ SECURITY_SUBJECT_CONTEXT SubjectContext;
- PAGED_CODE();
+ PAGED_CODE();
+
+ /* Get the Header and Create Info */
+ DPRINT("ObInsertObject: %x\n", Object);
+ Header = BODY_TO_HEADER(Object);
+ ObjectCreateInfo = Header->ObjectCreateInfo;
+ ObjectNameInfo = Header->NameInfo;
+
+ /* First try to find the Object */
+ if (ObjectNameInfo && ObjectNameInfo->Name.Buffer)
+ {
+ DPRINT("Object has a name. Trying to find it: %wZ.\n",
&ObjectNameInfo->Name);
+ Status = ObFindObject(ObjectCreateInfo,
+ &ObjectNameInfo->Name,
+ &FoundObject,
+ &RemainingPath,
+ NULL);
+ DPRINT("FoundObject: %x, Path: %wZ\n", FoundObject,
&RemainingPath);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ObFindObject() failed! (Status 0x%x)\n", Status);
+ return Status;
+ }
+
+ if (FoundObject)
+ {
+ DPRINT("Getting header: %x\n", FoundObject);
+ FoundHeader = BODY_TO_HEADER(FoundObject);
+ }
+
+ if (FoundHeader && RemainingPath.Buffer == NULL)
+ {
+ DPRINT("Object exists\n");
+ if (FoundHeader->ObjectType != Header->ObjectType
+ || !(ObjectCreateInfo->Attributes & OBJ_OPENIF))
+ {
+ ObDereferenceObject(FoundObject);
+ return STATUS_OBJECT_NAME_COLLISION;
+ }
+ return STATUS_OBJECT_EXISTS;
+ }
+ }
+ else
+ {
+ DPRINT("No name, empty remaining path\n");
+ RtlInitUnicodeString(&RemainingPath, NULL);
+ }
- Access = DesiredAccess;
- ObjectHeader = BODY_TO_HEADER(Object);
+ if (FoundHeader && FoundHeader->ObjectType == ObDirectoryType &&
+ RemainingPath.Buffer)
+ {
+ DPRINT("Adding to Object Directory\n");
+ ObpAddEntryDirectory(FoundObject, Header, NULL);
+ ObjectAttached = TRUE;
+
+ /* The name was changed so let's update it */
+ /* FIXME: TEMPORARY HACK This will go in ObFindObject in the
next commit */
+ PVOID NewName;
+ PWSTR BufferPos = RemainingPath.Buffer;
+
+ NewName = ExAllocatePool(NonPagedPool,
RemainingPath.MaximumLength);
+ ObjectNameInfo = Header->NameInfo;
+
+ if (BufferPos[0] == L'\\')
+ {
+ BufferPos++;
+ }
+
+ RtlMoveMemory(NewName, BufferPos, RemainingPath.MaximumLength);
+ if (ObjectNameInfo->Name.Buffer)
ExFreePool(ObjectNameInfo->Name.Buffer);
+ ObjectNameInfo->Name.Buffer = NewName;
+ ObjectNameInfo->Name.Length = RemainingPath.Length;
+ ObjectNameInfo->Name.MaximumLength =
RemainingPath.MaximumLength;
+ DPRINT("Name: %S\n", ObjectNameInfo->Name.Buffer);
+ }
- return(ObpCreateHandle(PsGetCurrentProcess(),
- Object,
- Access,
- ObjectHeader->Inherit,
- Handle));
+ if ((Header->ObjectType == IoFileObjectType) ||
+ (Header->ObjectType == ExDesktopObjectType) ||
+ (Header->ObjectType->TypeInfo.OpenProcedure != NULL))
+ {
+ DPRINT("About to call Open Routine\n");
+ if (Header->ObjectType == IoFileObjectType)
+ {
+ /* TEMPORARY HACK. DO NOT TOUCH -- Alex */
+ DPRINT("Calling IopCreateFile: %x\n", FoundObject);
+ Status = IopCreateFile(HEADER_TO_BODY(Header),
+ FoundObject,
+ RemainingPath.Buffer,
+ ObjectCreateInfo);
+ DPRINT("Called IopCreateFile: %x\n", Status);
+
+ }
+ else if (Header->ObjectType == ExDesktopObjectType)
+ {
+ /* TEMPORARY HACK. DO NOT TOUCH -- Alex */
+ DPRINT("Calling ExpDesktopCreate\n");
+ Status = ExpDesktopCreate(HEADER_TO_BODY(Header),
+ FoundObject,
+ RemainingPath.Buffer,
+ ObjectCreateInfo);
+ }
+ else if (Header->ObjectType->TypeInfo.OpenProcedure != NULL)
+ {
+ DPRINT("Calling %x\n",
Header->ObjectType->TypeInfo.OpenProcedure);
+ Status =
Header->ObjectType->TypeInfo.OpenProcedure(ObCreateHandle,
+
HEADER_TO_BODY(Header),
+ NULL,
+ 0,
+ 0);
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Create Failed\n");
+ if (ObjectAttached == TRUE)
+ {
+ ObpRemoveEntryDirectory(Header);
+ }
+ if (FoundObject)
+ {
+ ObDereferenceObject(FoundObject);
+ }
+ RtlFreeUnicodeString(&RemainingPath);
+ return Status;
+ }
+ }
+
+ RtlFreeUnicodeString(&RemainingPath);
+
+ DPRINT("Security Assignment in progress\n");
+ SeCaptureSubjectContext(&SubjectContext);
+
+ /* Build the new security descriptor */
+ Status = SeAssignSecurity((FoundHeader != NULL) ?
FoundHeader->SecurityDescriptor : NULL,
+ (ObjectCreateInfo != NULL) ?
ObjectCreateInfo->SecurityDescriptor : NULL,
+ &NewSecurityDescriptor,
+ (Header->ObjectType == ObDirectoryType),
+ &SubjectContext,
+
&Header->ObjectType->TypeInfo.GenericMapping,
+ PagedPool);
+
+ if (NT_SUCCESS(Status))
+ {
+ DPRINT("NewSecurityDescriptor %p\n", NewSecurityDescriptor);
+
+ if (Header->ObjectType->TypeInfo.SecurityProcedure != NULL)
+ {
+ /* Call the security method */
+ Status =
Header->ObjectType->TypeInfo.SecurityProcedure(HEADER_TO_BODY(Header),
+
AssignSecurityDescriptor,
+ 0,
+
NewSecurityDescriptor,
+
NULL);
+ }
+ else
+ {
+ /* Assign the security descriptor to the object header */
+ Status = ObpAddSecurityDescriptor(NewSecurityDescriptor,
+
&Header->SecurityDescriptor);
+ DPRINT("Object security descriptor %p\n",
Header->SecurityDescriptor);
+ }
+
+ /* Release the new security descriptor */
+ SeDeassignSecurity(&NewSecurityDescriptor);
+ }
+
+ DPRINT("Security Complete\n");
+ SeReleaseSubjectContext(&SubjectContext);
+
+ /* We can delete the Create Info now */
+ Header->ObjectCreateInfo = NULL;
+ ObpReleaseCapturedAttributes(ObjectCreateInfo);
+ ExFreePool(ObjectCreateInfo);
+
+ /* Create the Handle */
+ /* HACKHACK: Because of ROS's incorrect startup, this can be called
+ * without a valid Process until I finalize the startup patch,
+ * so don't create a handle if this is the case. We also don't
create
+ * a handle if Handle is NULL when the Registry Code calls it,
because
+ * the registry code totally bastardizes the Ob and needs to be
fixed
+ */
+ DPRINT("Creating handle\n");
+ if (Handle != NULL)
+ {
+ Status = ObpCreateHandle(PsGetCurrentProcess(),
+ HEADER_TO_BODY(Header),
+ DesiredAccess,
+ Header->Inherit,
+ Handle);
+ DPRINT("handle Created: %d. refcount. handlecount %d %d\n",
+ *Handle, Header->RefCount, Header->HandleCount);
+ }
+
+ DPRINT("Status %x\n", Status);
+ return Status;
}
_____
Modified: trunk/reactos/ntoskrnl/ob/namespc.c
--- trunk/reactos/ntoskrnl/ob/namespc.c 2005-05-18 19:08:00 UTC (rev
15394)
+++ trunk/reactos/ntoskrnl/ob/namespc.c 2005-05-18 19:26:47 UTC (rev
15395)
@@ -40,7 +40,8 @@
NTSTATUS
STDCALL
-ObpAllocateObject(POBJECT_ATTRIBUTES ObjectAttributes,
+ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
+ PUNICODE_STRING ObjectName,
POBJECT_TYPE ObjectType,
ULONG ObjectSize,
POBJECT_HEADER *ObjectHeader);
@@ -62,7 +63,9 @@
{
PVOID Object = NULL;
UNICODE_STRING RemainingPath;
+ UNICODE_STRING ObjectName;
OBJECT_ATTRIBUTES ObjectAttributes;
+ OBJECT_CREATE_INFORMATION ObjectCreateInfo;
NTSTATUS Status;
PAGED_CODE();
@@ -72,10 +75,26 @@
Attributes | OBJ_OPENIF,
NULL,
NULL);
- Status = ObFindObject(&ObjectAttributes,
+
+ /* Capture all the info */
+ DPRINT("Capturing Create Info\n");
+ Status = ObpCaptureObjectAttributes(&ObjectAttributes,
+ AccessMode,
+ ObjectType,
+ &ObjectCreateInfo,
+ &ObjectName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n",
Status);
+ return Status;
+ }
+
+ Status = ObFindObject(&ObjectCreateInfo,
+ &ObjectName,
&Object,
&RemainingPath,
ObjectType);
+
if (!NT_SUCCESS(Status))
{
return(Status);
@@ -136,13 +155,29 @@
{
UNICODE_STRING RemainingPath;
PVOID Object = NULL;
+ UNICODE_STRING ObjectName;
+ OBJECT_CREATE_INFORMATION ObjectCreateInfo;
NTSTATUS Status;
PAGED_CODE();
DPRINT("ObOpenObjectByName(...)\n");
- Status = ObFindObject(ObjectAttributes,
+ /* Capture all the info */
+ DPRINT("Capturing Create Info\n");
+ Status = ObpCaptureObjectAttributes(ObjectAttributes,
+ AccessMode,
+ ObjectType,
+ &ObjectCreateInfo,
+ &ObjectName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n",
Status);
+ return Status;
+ }
+
+ Status = ObFindObject(&ObjectCreateInfo,
+ &ObjectName,
&Object,
&RemainingPath,
ObjectType);
@@ -152,9 +187,12 @@
return Status;
}
+ DPRINT("OBject: %x, Remaining Path: %wZ\n", Object,
&RemainingPath);
if (Object == NULL)
{
RtlFreeUnicodeString(&RemainingPath);
+ ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+ if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return STATUS_UNSUCCESSFUL;
}
if (RemainingPath.Buffer != NULL)
@@ -165,9 +203,11 @@
Status =STATUS_OBJECT_PATH_NOT_FOUND;
RtlFreeUnicodeString(&RemainingPath);
ObDereferenceObject(Object);
+ ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+ if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return Status;
}
-
+
Status = ObpCreateHandle(PsGetCurrentProcess(),
Object,
DesiredAccess,
@@ -176,6 +216,8 @@
ObDereferenceObject(Object);
RtlFreeUnicodeString(&RemainingPath);
+ ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+ if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return Status;
}
@@ -217,8 +259,7 @@
{
KIRQL oldlvl;
- RtlpCreateUnicodeString(&Header->Name, Name, NonPagedPool);
- Header->Parent = Parent;
+ Header->NameInfo->Directory = Parent;
KeAcquireSpinLock(&Parent->Lock, &oldlvl);
InsertTailList(&Parent->head, &Header->Entry);
@@ -238,13 +279,13 @@
DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header);
- KeAcquireSpinLock(&(Header->Parent->Lock),&oldlvl);
+ KeAcquireSpinLock(&(Header->NameInfo->Directory->Lock),&oldlvl);
if (Header->Entry.Flink && Header->Entry.Blink)
{
RemoveEntryList(&(Header->Entry));
Header->Entry.Flink = Header->Entry.Blink = NULL;
}
- KeReleaseSpinLock(&(Header->Parent->Lock),oldlvl);
+ KeReleaseSpinLock(&(Header->NameInfo->Directory->Lock),oldlvl);
}
NTSTATUS
@@ -286,15 +327,15 @@
}
if (Name[0]=='.' && Name[1]=='.' && Name[2]==0)
{
- return(BODY_TO_HEADER(DirectoryObject)->Parent);
+ return(BODY_TO_HEADER(DirectoryObject)->NameInfo->Directory);
}
while (current!=(&(DirectoryObject->head)))
{
current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry);
- DPRINT(" Scanning: %S for: %S\n",current_obj->Name.Buffer,
Name);
+ DPRINT(" Scanning: %S for:
%S\n",current_obj->NameInfo->Name.Buffer, Name);
if (Attributes & OBJ_CASE_INSENSITIVE)
{
- if (_wcsicmp(current_obj->Name.Buffer, Name)==0)
+ if (_wcsicmp(current_obj->NameInfo->Name.Buffer, Name)==0)
{
DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
return(HEADER_TO_BODY(current_obj));
@@ -302,7 +343,7 @@
}
else
{
- if ( wcscmp(current_obj->Name.Buffer, Name)==0)
+ if ( wcscmp(current_obj->NameInfo->Name.Buffer, Name)==0)
{
DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
return(HEADER_TO_BODY(current_obj));
@@ -389,7 +430,7 @@
ObpInitSdCache();
/* Create the Type Type */
- DPRINT1("Creating Type Type\n");
+ DPRINT("Creating Type Type\n");
RtlZeroMemory(&ObjectTypeInitializer,
sizeof(ObjectTypeInitializer));
RtlInitUnicodeString(&Name, L"Type");
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
@@ -402,7 +443,7 @@
ObpCreateTypeObject(&ObjectTypeInitializer, &Name,
&ObTypeObjectType);
/* Create the Directory Type */
- DPRINT1("Creating Directory Type\n");
+ DPRINT("Creating Directory Type\n");
RtlZeroMemory(&ObjectTypeInitializer,
sizeof(ObjectTypeInitializer));
RtlInitUnicodeString(&Name, L"Directory");
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
@@ -430,7 +471,7 @@
FALSE);
/* Create root directory */
- DPRINT1("Creating Root Directory\n");
+ DPRINT("Creating Root Directory\n");
[truncated at 1000 lines; 1272 more skipped]