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

svn path=/trunk/; revision=15395
This commit is contained in:
Alex Ionescu 2005-05-18 19:26:47 +00:00
parent dfedb99675
commit 00fe79ff10
23 changed files with 869 additions and 629 deletions

View file

@ -63,6 +63,15 @@ typedef NTSTATUS STDCALL_FUNC
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;

View file

@ -744,4 +744,11 @@ NTSTATUS
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*/

View file

@ -30,6 +30,138 @@ FAST_MUTEX CmiCallbackLock;
/* 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,
&current,
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 @@ NtCreateKey(OUT PHANDLE KeyHandle,
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 @@ NtDeleteKey(IN HANDLE KeyHandle)
PAGED_CODE();
DPRINT1("NtDeleteKey(KeyHandle %x) called\n", KeyHandle);
DPRINT("NtDeleteKey(KeyHandle %x) called\n", KeyHandle);
PreviousMode = ExGetPreviousMode();
@ -418,7 +550,7 @@ NtDeleteKey(IN HANDLE KeyHandle)
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 @@ NtOpenKey(OUT PHANDLE KeyHandle,
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;
}

View file

@ -702,7 +702,7 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
DPRINT("CmiConnectHive(%p, %p) called.\n",
KeyObjectAttributes, RegistryHive);
Status = ObFindObject(KeyObjectAttributes,
Status = CmpFindObject(KeyObjectAttributes,
(PVOID*)&ParentKey,
&RemainingPath,
CmiKeyType);
@ -746,6 +746,7 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
0,
0,
(PVOID*)&NewKey);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("ObCreateObject() failed (Status %lx)\n", Status);
@ -753,7 +754,14 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
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);

View file

@ -176,6 +176,15 @@ CmiObjectParse(PVOID ParsedObject,
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 @@ CmiObjectQueryName (PVOID ObjectBody,
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);

View file

@ -385,11 +385,6 @@ IoSecondStageCompletion(
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 @@ STDCALL
IopCreateFile(PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
POBJECT_ATTRIBUTES ObjectAttributes);
POBJECT_CREATE_INFORMATION ObjectAttributes);
VOID
STDCALL

View file

@ -29,14 +29,14 @@ typedef struct _OBJECT_HEADER
* 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 @@ NTSTATUS ObpCreateHandle(struct _EPROCESS* Process,
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 @@ ObpSetHandleAttributes(HANDLE Handle,
NTSTATUS
STDCALL
ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
ObpCreateTypeObject(struct _OBJECT_TYPE_INITIALIZER *ObjectTypeInitializer,
PUNICODE_STRING TypeName,
POBJECT_TYPE *ObjectType);
@ -224,18 +225,22 @@ typedef struct _CAPTURED_OBJECT_ATTRIBUTES
} 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 */

View file

@ -218,6 +218,17 @@ IopCreateDriverObject(
{
return Status;
}
Status = ObInsertObject(Object,
NULL,
FILE_ALL_ACCESS,
0,
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
return Status;
}
if (Status == STATUS_OBJECT_EXISTS)
{

View file

@ -47,7 +47,7 @@ STDCALL
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 @@ IopCreateFile(PVOID ObjectBody,
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 @@ IoCreateFile(OUT PHANDLE FileHandle,
if (CreateDisposition == FILE_OPEN ||
CreateDisposition == FILE_OPEN_IF)
{
Status = ObOpenObjectByName(ObjectAttributes,
NULL,
NULL,
@ -859,6 +860,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
DesiredAccess,
NULL,
&LocalHandle);
if (NT_SUCCESS(Status))
{
Status = ObReferenceObjectByHandle(LocalHandle,
@ -1012,7 +1014,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
*/
Status = IofCallDriver(FileObject->DeviceObject, Irp );
DPRINT("Status :%x\n", Status);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&FileObject->Event,

View file

@ -2099,6 +2099,16 @@ MmCreatePhysicalMemorySection(VOID)
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 @@ MmCreateDataFileSection(PSECTION_OBJECT *SectionObject,
{
return(Status);
}
/*
* Initialize it
*/
@ -3140,6 +3149,7 @@ MmCreateImageSection(PSECTION_OBJECT *SectionObject,
UserMode,
(PVOID*)(PVOID)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
return Status;

View file

@ -823,6 +823,7 @@ ObAssignSecurity@16
;ObCheckCreateObjectAccess@28
;ObCheckObjectAccess@20
ObCreateObject@36
ObpCreateHandle ; FIXME! See win32k/ntuser/csr.c!
ObFindHandleForObject@20
ObGetObjectPointerCount@4
ObGetObjectSecurity@12

View file

@ -253,7 +253,7 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
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 @@ NtCreateDirectoryObject (OUT PHANDLE DirectoryHandle,
PAGED_CODE();
DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, "
"DesiredAccess %x, ObjectAttributes %x\n",
DirectoryHandle, DesiredAccess, ObjectAttributes);
"DesiredAccess %x, ObjectAttributes %x\n",
DirectoryHandle, DesiredAccess, ObjectAttributes);
PreviousMode = ExGetPreviousMode();

View file

@ -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 @@ ObpDecrementHandleCount(PVOID ObjectBody)
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 @@ NtClose(IN HANDLE Handle)
/*
* @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;
}

View file

@ -40,7 +40,8 @@ static GENERIC_MAPPING ObpTypeMapping = {
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 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
{
PVOID Object = NULL;
UNICODE_STRING RemainingPath;
UNICODE_STRING ObjectName;
OBJECT_ATTRIBUTES ObjectAttributes;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
NTSTATUS Status;
PAGED_CODE();
@ -72,10 +75,26 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
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 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
{
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 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
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 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
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 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
ObDereferenceObject(Object);
RtlFreeUnicodeString(&RemainingPath);
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return Status;
}
@ -217,8 +259,7 @@ ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
{
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 @@ ObpRemoveEntryDirectory(POBJECT_HEADER Header)
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 @@ ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
}
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 @@ ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
}
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 @@ ObInit(VOID)
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 @@ ObInit(VOID)
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 @@ ObInit(VOID)
FALSE);
/* Create root directory */
DPRINT1("Creating Root Directory\n");
DPRINT("Creating Root Directory\n");
InitializeObjectAttributes(&ObjectAttributes,
NULL,
OBJ_PERMANENT,
@ -445,6 +486,12 @@ ObInit(VOID)
0,
0,
(PVOID*)&NameSpaceRoot);
ObInsertObject((PVOID)NameSpaceRoot,
NULL,
DIRECTORY_ALL_ACCESS,
0,
NULL,
NULL);
/* Create '\ObjectTypes' directory */
RtlInitUnicodeString(&Name, L"\\ObjectTypes");
@ -462,11 +509,17 @@ ObInit(VOID)
0,
0,
(PVOID*)&ObpTypeDirectoryObject);
ObInsertObject((PVOID)ObpTypeDirectoryObject,
NULL,
DIRECTORY_ALL_ACCESS,
0,
NULL,
NULL);
/* Insert the two objects we already created but couldn't add */
/* NOTE: Uses TypeList & Creator Info in OB 2.0 */
ObpAddEntryDirectory(ObpTypeDirectoryObject, BODY_TO_HEADER(ObTypeObjectType), L"Type");
ObpAddEntryDirectory(ObpTypeDirectoryObject, BODY_TO_HEADER(ObDirectoryType), L"Directory");
ObpAddEntryDirectory(ObpTypeDirectoryObject, BODY_TO_HEADER(ObTypeObjectType), NULL);
ObpAddEntryDirectory(ObpTypeDirectoryObject, BODY_TO_HEADER(ObDirectoryType), NULL);
/* Create 'symbolic link' object type */
ObInitSymbolicLinkImplementation();
@ -490,6 +543,7 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
/* Allocate the Object */
Status = ObpAllocateObject(NULL,
TypeName,
ObTypeObjectType,
OBJECT_ALLOC_SIZE(sizeof(OBJECT_TYPE)),
&Header);
@ -499,7 +553,7 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
return Status;
}
LocalObjectType = HEADER_TO_BODY(Header);
LocalObjectType = HEADER_TO_BODY(Header);
/* Check if this is the first Object Type */
if (!ObTypeObjectType)

View file

@ -225,7 +225,7 @@ ObpSetPermanentObject (IN PVOID ObjectBody, IN BOOLEAN Permanent)
ObjectHeader = BODY_TO_HEADER(ObjectBody);
ObjectHeader->Permanent = Permanent;
if (ObjectHeader->HandleCount == 0 && !Permanent && ObjectHeader->Parent != NULL)
if (ObjectHeader->HandleCount == 0 && !Permanent && ObjectHeader->NameInfo->Directory)
{
/* Remove the object from the namespace */
ObpRemoveEntryDirectory(ObjectHeader);

File diff suppressed because it is too large Load diff

View file

@ -139,7 +139,16 @@ RtlpCreateNlsSection(VOID)
DPRINT1("MmCreateSection() failed\n");
KEBUGCHECKEX(0x32, Status, 1, 1, 0);
}
Status = ObInsertObject(NlsSectionObject,
NULL,
SECTION_ALL_ACCESS,
0,
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(NlsSectionObject);
}
Status = MmMapViewInSystemSpace(NlsSectionObject,
&NlsSectionBase,
&NlsSectionViewSize);

View file

@ -604,6 +604,7 @@ SeCaptureSecurityDescriptor(
{
ULONG_PTR Offset = sizeof(SECURITY_DESCRIPTOR);
RtlZeroMemory(NewDescriptor, DescriptorSize);
NewDescriptor->Revision = DescriptorCopy.Revision;
NewDescriptor->Sbz1 = DescriptorCopy.Sbz1;
NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE;

View file

@ -362,9 +362,11 @@ SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
{
DPRINT("Use explicit owner sid!\n");
Owner = ExplicitDescriptor->Owner;
if (ExplicitDescriptor->Control & SE_SELF_RELATIVE)
{
Owner = (PSID)(((ULONG_PTR)Owner) + (ULONG_PTR)ExplicitDescriptor);
}
}
else

View file

@ -1808,6 +1808,12 @@ SepCreateSystemProcessToken(VOID)
{
return NULL;
}
Status = ObInsertObject(AccessToken,
NULL,
TOKEN_ALL_ACCESS,
0,
NULL,
NULL);
Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId);
if (!NT_SUCCESS(Status))

View file

@ -702,12 +702,13 @@ ScmStartUserModeService(PSERVICE Service)
ResumeThread(ProcessInformation.hThread);
/* Connect control pipe */
DPRINT1("Connect named pipe\n")
if (ConnectNamedPipe(Service->ControlPipeHandle, NULL))
{
DWORD dwProcessId = 0;
DWORD dwRead = 0;
DPRINT("Control pipe connected!\n");
DPRINT1("Control pipe connected!\n");
/* Read thread id from pipe */
if (!ReadFile(Service->ControlPipeHandle,
@ -731,7 +732,7 @@ ScmStartUserModeService(PSERVICE Service)
}
else
{
DPRINT("Connecting control pipe failed!\n");
DPRINT1("Connecting control pipe failed!\n");
/* Close control pipe */
CloseHandle(Service->ControlPipeHandle);

View file

@ -12,6 +12,13 @@
static HANDLE WindowsApiPort = NULL;
PEPROCESS CsrProcess = NULL;
NTSTATUS
ObpCreateHandle(PEPROCESS Process,
PVOID ObjectBody,
ACCESS_MASK GrantedAccess,
BOOLEAN Inherit,
PHANDLE HandleReturn);
NTSTATUS FASTCALL
CsrInit(void)
{
@ -94,12 +101,13 @@ CsrInsertObject(PVOID Object,
KeAttachProcess(CsrProcess);
}
Status = ObInsertObject(Object,
PassedAccessState,
DesiredAccess,
AdditionalReferences,
ReferencedObject,
Handle);
/* FIXME!!!!!!!!! SOMETHING HAS GOT TO BE DONE ABOUT THIS !!!!! */
Status = ObpCreateHandle(PsGetCurrentProcess(),
Object,
DesiredAccess,
BODY_TO_HEADER(Object)->Inherit,
Handle);
/* FIXME!!!!!!!!! SOMETHING HAS GOT TO BE DONE ABOUT ^^^^ THAT !!!!! */
if (CsrProcess != OldProcess)
{

View file

@ -8510,6 +8510,15 @@ typedef NTSTATUS
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;