POBJECT_HEADER ObjectHeader;
} RETENTION_CHECK_PARAMS, *PRETENTION_CHECK_PARAMS;
-/* TEMPORARY HACK. DO NOT REMOVE -- Alex */
-NTSTATUS
-STDCALL
-ExpDesktopCreate(PVOID ObjectBody,
- PVOID Parent,
- PWSTR RemainingPath,
- struct _OBJECT_ATTRIBUTES* ObjectAttributes);
/* FUNCTIONS ************************************************************/
NTSTATUS
-ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
- IN KPROCESSOR_MODE AccessMode,
- IN POOL_TYPE PoolType,
- IN BOOLEAN CaptureIfKernel,
- OUT PCAPTURED_OBJECT_ATTRIBUTES CapturedObjectAttributes OPTIONAL,
- OUT PUNICODE_STRING ObjectName OPTIONAL)
+STDCALL
+ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName,
+ IN PUNICODE_STRING ObjectName,
+ IN KPROCESSOR_MODE AccessMode)
{
- OBJECT_ATTRIBUTES AttributesCopy;
- NTSTATUS Status = STATUS_SUCCESS;
-
- /* at least one output parameter must be != NULL! */
- ASSERT(CapturedObjectAttributes != NULL || ObjectName != NULL);
-
- if(ObjectAttributes == NULL)
- {
- /* we're going to return STATUS_SUCCESS! */
- goto failbasiccleanup;
- }
-
- if(AccessMode != KernelMode)
- {
- RtlZeroMemory(&AttributesCopy, sizeof(AttributesCopy));
-
- _SEH_TRY
- {
- ProbeForRead(ObjectAttributes,
- sizeof(ObjectAttributes),
- sizeof(ULONG));
- /* make a copy on the stack */
- AttributesCopy = *ObjectAttributes;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
+ NTSTATUS Status = STATUS_SUCCESS;
+ UNICODE_STRING LocalName;
+
+ /* First Probe the String */
+ DPRINT("ObpCaptureObjectName: %wZ\n", ObjectName);
+ if (AccessMode != KernelMode)
{
- DPRINT1("ObpCaptureObjectAttributes failed to probe object attributes\n");
- goto failbasiccleanup;
- }
- }
- else if(!CaptureIfKernel)
- {
- if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
- {
- if(ObjectName != NULL)
- {
- /* we don't have to capture any memory, the caller considers the passed data
- as valid */
- if(ObjectAttributes->ObjectName != NULL)
+ DPRINT("Probing Struct\n");
+ _SEH_TRY
{
- *ObjectName = *ObjectAttributes->ObjectName;
+ /* FIXME: Explorer or win32 broken I think */
+ #if 0
+ ProbeForRead(ObjectName,
+ sizeof(UNICODE_STRING),
+ sizeof(USHORT));
+ #endif
+ LocalName = *ObjectName;
}
- else
+ _SEH_HANDLE
{
- ObjectName->Length = ObjectName->MaximumLength = 0;
- ObjectName->Buffer = NULL;
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (NT_SUCCESS(Status))
+ {
+ DPRINT("Probing OK\n");
+ _SEH_TRY
+ {
+ #if 0
+ DPRINT("Probing buffer\n");
+ ProbeForRead(LocalName.Buffer,
+ LocalName.Length,
+ sizeof(USHORT));
+ #endif
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+
+ /* Fail if anything up to here died */
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Probing failed\n");
+ return Status;
}
- }
- if(CapturedObjectAttributes != NULL)
- {
- CapturedObjectAttributes->RootDirectory = ObjectAttributes->RootDirectory;
- CapturedObjectAttributes->Attributes = ObjectAttributes->Attributes;
- CapturedObjectAttributes->SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
- CapturedObjectAttributes->SecurityQualityOfService = ObjectAttributes->SecurityQualityOfService;
- }
-
- return STATUS_SUCCESS;
- }
- else
- {
- Status = STATUS_INVALID_PARAMETER;
- goto failbasiccleanup;
- }
- }
- else
- {
- AttributesCopy = *ObjectAttributes;
- }
-
- /* if Length isn't as expected, bail with an invalid parameter status code so
- the caller knows he passed garbage... */
- if(AttributesCopy.Length != sizeof(OBJECT_ATTRIBUTES))
- {
- Status = STATUS_INVALID_PARAMETER;
- goto failbasiccleanup;
- }
-
- if(CapturedObjectAttributes != NULL)
- {
- CapturedObjectAttributes->RootDirectory = AttributesCopy.RootDirectory;
- CapturedObjectAttributes->Attributes = AttributesCopy.Attributes;
-
- if(AttributesCopy.SecurityDescriptor != NULL)
- {
- Status = SeCaptureSecurityDescriptor(AttributesCopy.SecurityDescriptor,
- AccessMode,
- PoolType,
- TRUE,
- &CapturedObjectAttributes->SecurityDescriptor);
- if(!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to capture the security descriptor!!!\n");
- goto failbasiccleanup;
- }
}
else
{
- CapturedObjectAttributes->SecurityDescriptor = NULL;
- }
-
- if(AttributesCopy.SecurityQualityOfService != NULL)
- {
- SECURITY_QUALITY_OF_SERVICE SafeQoS;
-
- RtlZeroMemory(&SafeQoS, sizeof(SafeQoS));
-
- _SEH_TRY
- {
- ProbeForRead(AttributesCopy.SecurityQualityOfService,
- sizeof(SECURITY_QUALITY_OF_SERVICE),
- sizeof(ULONG));
- SafeQoS = *(PSECURITY_QUALITY_OF_SERVICE)AttributesCopy.SecurityQualityOfService;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to capture QoS!!!\n");
- goto failcleanupsdescriptor;
- }
-
- if(SafeQoS.Length != sizeof(SECURITY_QUALITY_OF_SERVICE))
- {
- DPRINT1("Unable to capture QoS, wrong size!!!\n");
- Status = STATUS_INVALID_PARAMETER;
- goto failcleanupsdescriptor;
- }
-
- CapturedObjectAttributes->SecurityQualityOfService = ExAllocatePool(PoolType,
- sizeof(SECURITY_QUALITY_OF_SERVICE));
- if(CapturedObjectAttributes->SecurityQualityOfService != NULL)
- {
- *CapturedObjectAttributes->SecurityQualityOfService = SafeQoS;
- }
- else
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto failcleanupsdescriptor;
- }
+ LocalName = *ObjectName;
}
- else
+
+ /* Make sure there really is a string */
+ DPRINT("Probing OK\n");
+ if (LocalName.Length)
{
- CapturedObjectAttributes->SecurityQualityOfService = NULL;
+ /* Allocate a non-paged buffer for this string */
+ DPRINT("Capturing String\n");
+ CapturedName->Length = LocalName.Length;
+ CapturedName->MaximumLength = LocalName.Length + sizeof(WCHAR);
+ CapturedName->Buffer = ExAllocatePoolWithTag(NonPagedPool,
+ CapturedName->MaximumLength,
+ TAG('O','b','N','m'));
+
+ /* Copy the string and null-terminate it */
+ RtlMoveMemory(CapturedName->Buffer, LocalName.Buffer, LocalName.Length);
+ CapturedName->Buffer[LocalName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ DPRINT("String Captured: %p, %wZ\n", CapturedName, CapturedName);
}
- }
+
+ return Status;
+}
- if(ObjectName != NULL)
- {
- if(AttributesCopy.ObjectName != NULL)
+NTSTATUS
+STDCALL
+ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN KPROCESSOR_MODE AccessMode,
+ IN POBJECT_TYPE ObjectType,
+ IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
+ OUT PUNICODE_STRING ObjectName)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ PSECURITY_DESCRIPTOR SecurityDescriptor;
+ PSECURITY_QUALITY_OF_SERVICE SecurityQos;
+ PUNICODE_STRING LocalObjectName = NULL;
+
+ /* Zero out the Capture Data */
+ DPRINT("ObpCaptureObjectAttributes\n");
+ RtlZeroMemory(ObjectCreateInfo, sizeof(OBJECT_CREATE_INFORMATION));
+
+ /* Check if we got Oba */
+ if (ObjectAttributes)
{
- UNICODE_STRING OriginalCopy;
-
- if(AccessMode != KernelMode)
- {
- RtlZeroMemory(&OriginalCopy, sizeof(OriginalCopy));
-
- _SEH_TRY
- {
- /* probe the ObjectName structure and make a local stack copy of it */
- ProbeForRead(AttributesCopy.ObjectName,
- sizeof(UNICODE_STRING),
- sizeof(ULONG));
- OriginalCopy = *AttributesCopy.ObjectName;
- if(OriginalCopy.Length > 0)
- {
- ProbeForRead(OriginalCopy.Buffer,
- OriginalCopy.Length,
- sizeof(WCHAR));
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(NT_SUCCESS(Status))
+ if (AccessMode != KernelMode)
{
- if(OriginalCopy.Length > 0)
- {
- ObjectName->MaximumLength = OriginalCopy.Length + sizeof(WCHAR);
- ObjectName->Buffer = ExAllocatePool(PoolType,
- ObjectName->MaximumLength);
- if(ObjectName->Buffer != NULL)
+ DPRINT("Probing OBA\n");
+ _SEH_TRY
{
- _SEH_TRY
- {
- /* no need to probe OriginalCopy.Buffer again, we already did that
- when capturing the UNICODE_STRING structure itself */
- RtlCopyMemory(ObjectName->Buffer, OriginalCopy.Buffer, OriginalCopy.Length);
- ObjectName->Buffer[OriginalCopy.Length / sizeof(WCHAR)] = L'\0';
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- DPRINT1("ObpCaptureObjectAttributes failed to copy the unicode string!\n");
- }
+ /* FIXME: SMSS SENDS BULLSHIT. */
+ #if 0
+ ProbeForRead(ObjectAttributes,
+ sizeof(ObjectAttributes),
+ sizeof(ULONG));
+ #endif
}
- else
+ _SEH_HANDLE
{
- Status = STATUS_INSUFFICIENT_RESOURCES;
+ Status = _SEH_GetExceptionCode();
}
- }
- else if(AttributesCopy.RootDirectory != NULL /* && OriginalCopy.Length == 0 */)
- {
- /* if the caller specified a root directory, there must be an object name! */
- Status = STATUS_OBJECT_NAME_INVALID;
- }
+ _SEH_END;
}
- else
+
+ /* Validate the Size */
+ DPRINT("Validating OBA\n");
+ if (ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES))
{
- DPRINT1("ObpCaptureObjectAttributes failed to probe the object name UNICODE_STRING structure!\n");
+ Status = STATUS_INVALID_PARAMETER;
}
- }
- else /* AccessMode == KernelMode */
- {
- OriginalCopy = *AttributesCopy.ObjectName;
- if(OriginalCopy.Length > 0)
+ /* Fail if SEH or Size Validation failed */
+ if(!NT_SUCCESS(Status))
{
- ObjectName->MaximumLength = OriginalCopy.Length + sizeof(WCHAR);
- ObjectName->Buffer = ExAllocatePool(PoolType,
- ObjectName->MaximumLength);
- if(ObjectName->Buffer != NULL)
- {
- RtlCopyMemory(ObjectName->Buffer, OriginalCopy.Buffer, OriginalCopy.Length);
- ObjectName->Buffer[OriginalCopy.Length / sizeof(WCHAR)] = L'\0';
- }
- else
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
+ DPRINT1("ObpCaptureObjectAttributes failed to probe object attributes\n");
+ goto fail;
}
- else if(AttributesCopy.RootDirectory != NULL /* && OriginalCopy.Length == 0 */)
+
+ /* Set some Create Info */
+ DPRINT("Creating OBCI\n");
+ ObjectCreateInfo->RootDirectory = ObjectAttributes->RootDirectory;
+ ObjectCreateInfo->Attributes = ObjectAttributes->Attributes;
+ LocalObjectName = ObjectAttributes->ObjectName;
+ SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
+ SecurityQos = ObjectAttributes->SecurityQualityOfService;
+
+ /* Validate the SD */
+ if (SecurityDescriptor)
{
- /* if the caller specified a root directory, there must be an object name! */
- Status = STATUS_OBJECT_NAME_INVALID;
+ DPRINT("Probing SD: %x\n", SecurityDescriptor);
+ Status = SeCaptureSecurityDescriptor(SecurityDescriptor,
+ AccessMode,
+ NonPagedPool,
+ TRUE,
+ &ObjectCreateInfo->SecurityDescriptor);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Unable to capture the security descriptor!!!\n");
+ ObjectCreateInfo->SecurityDescriptor = NULL;
+ goto fail;
+ }
+
+ DPRINT("Probe done\n");
+ ObjectCreateInfo->SecurityDescriptorCharge = 0; /* FIXME */
+ ObjectCreateInfo->ProbeMode = AccessMode;
}
- }
- }
- else
- {
- ObjectName->Length = ObjectName->MaximumLength = 0;
- ObjectName->Buffer = NULL;
- }
- }
+
+ /* Validate the QoS */
+ if (SecurityQos)
+ {
+ if (AccessMode != KernelMode)
+ {
+ DPRINT("Probing QoS\n");
+ _SEH_TRY
+ {
+ ProbeForRead(SecurityQos,
+ sizeof(SECURITY_QUALITY_OF_SERVICE),
+ sizeof(ULONG));
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
- if(!NT_SUCCESS(Status))
- {
- if(ObjectName->Buffer)
- {
- ExFreePool(ObjectName->Buffer);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Unable to capture QoS!!!\n");
+ goto fail;
+ }
+
+ ObjectCreateInfo->SecurityQualityOfService = *SecurityQos;
+ ObjectCreateInfo->SecurityQos = &ObjectCreateInfo->SecurityQualityOfService;
+ }
}
-
-failcleanupsdescriptor:
- if(CapturedObjectAttributes != NULL)
+
+ /* Clear Local Object Name */
+ DPRINT("Clearing name\n");
+ RtlZeroMemory(ObjectName, sizeof(UNICODE_STRING));
+
+ /* Now check if the Object Attributes had an Object Name */
+ if (LocalObjectName)
{
- /* cleanup allocated resources */
- SeReleaseSecurityDescriptor(CapturedObjectAttributes->SecurityDescriptor,
- AccessMode,
- TRUE);
+ DPRINT("Name Buffer: %x\n", LocalObjectName->Buffer);
+ Status = ObpCaptureObjectName(ObjectName,
+ LocalObjectName,
+ AccessMode);
}
-
-failbasiccleanup:
- if(ObjectName != NULL)
+ else
{
- ObjectName->Length = ObjectName->MaximumLength = 0;
- ObjectName->Buffer = NULL;
+ /* He can't have specified a Root Directory */
+ if (ObjectCreateInfo->RootDirectory)
+ {
+ DPRINT1("Invalid name\n");
+ Status = STATUS_OBJECT_NAME_INVALID;
+ }
}
- if(CapturedObjectAttributes != NULL)
+
+fail:
+ if (!NT_SUCCESS(Status))
{
- RtlZeroMemory(CapturedObjectAttributes, sizeof(CAPTURED_OBJECT_ATTRIBUTES));
+ DPRINT1("Failed to capture, cleaning up\n");
+ ObpReleaseCapturedAttributes(ObjectCreateInfo);
}
- }
-
- return Status;
+
+ DPRINT("Return to caller\n");
+ return Status;
}
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)
{
- /* WARNING - You need to pass the same parameters to this function as you passed
- to ObpCaptureObjectAttributes() to avoid memory leaks */
- if(AccessMode != KernelMode || CaptureIfKernel)
- {
- if(CapturedObjectAttributes != NULL)
- {
- if(CapturedObjectAttributes->SecurityDescriptor != NULL)
- {
- ExFreePool(CapturedObjectAttributes->SecurityDescriptor);
- CapturedObjectAttributes->SecurityDescriptor = NULL;
- }
- if(CapturedObjectAttributes->SecurityQualityOfService != NULL)
- {
- ExFreePool(CapturedObjectAttributes->SecurityQualityOfService);
- CapturedObjectAttributes->SecurityQualityOfService = NULL;
- }
- }
- if(ObjectName != NULL &&
- ObjectName->Length > 0)
+ /* Release the SD, it's the only thing we allocated */
+ if (ObjectCreateInfo->SecurityDescriptor)
{
- ExFreePool(ObjectName->Buffer);
+ SeReleaseSecurityDescriptor(ObjectCreateInfo->SecurityDescriptor,
+ ObjectCreateInfo->ProbeMode,
+ TRUE);
+ ObjectCreateInfo->SecurityDescriptor = NULL;
}
- }
}
* RETURN VALUE
*/
NTSTATUS
-ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
+ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
+ PUNICODE_STRING ObjectName,
PVOID* ReturnedObject,
PUNICODE_STRING RemainingPath,
POBJECT_TYPE ObjectType)
PWSTR current;
UNICODE_STRING PathString;
ULONG Attributes;
- PUNICODE_STRING ObjectName;
PAGED_CODE();
- DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
- "RemainingPath %x)\n",ObjectAttributes,ReturnedObject,RemainingPath);
- DPRINT("ObjectAttributes->ObjectName %wZ\n",
- ObjectAttributes->ObjectName);
+ DPRINT("ObFindObject(ObjectCreateInfo %x, ReturnedObject %x, "
+ "RemainingPath %x)\n",ObjectCreateInfo,ReturnedObject,RemainingPath);
RtlInitUnicodeString (RemainingPath, NULL);
- if (ObjectAttributes->RootDirectory == NULL)
+ if (ObjectCreateInfo->RootDirectory == NULL)
{
ObReferenceObjectByPointer(NameSpaceRoot,
DIRECTORY_TRAVERSE,
}
else
{
- Status = ObReferenceObjectByHandle(ObjectAttributes->RootDirectory,
+ Status = ObReferenceObjectByHandle(ObjectCreateInfo->RootDirectory,
0,
NULL,
UserMode,
}
}
- ObjectName = ObjectAttributes->ObjectName;
if (ObjectName->Length == 0 ||
ObjectName->Buffer[0] == UNICODE_NULL)
{
return STATUS_SUCCESS;
}
- if (ObjectAttributes->RootDirectory == NULL &&
+ if (ObjectCreateInfo->RootDirectory == NULL &&
ObjectName->Buffer[0] != L'\\')
{
ObDereferenceObject (CurrentObject);
+ DPRINT1("failed\n");
return STATUS_UNSUCCESSFUL;
}
current = PathString.Buffer;
RootObject = CurrentObject;
- Attributes = ObjectAttributes->Attributes;
+ Attributes = ObjectCreateInfo->Attributes;
if (ObjectType == ObSymbolicLinkType)
Attributes |= OBJ_OPENLINK;
CurrentHeader = BODY_TO_HEADER(CurrentObject);
DPRINT("Current ObjectType %wZ\n",
- &CurrentHeader->ObjectType->TypeName);
+ &CurrentHeader->ObjectType->Name);
- if (CurrentHeader->ObjectType->Parse == NULL)
+ if (CurrentHeader->ObjectType->TypeInfo.ParseProcedure == NULL)
{
DPRINT("Current object can't parse\n");
break;
}
- Status = CurrentHeader->ObjectType->Parse(CurrentObject,
+ Status = CurrentHeader->ObjectType->TypeInfo.ParseProcedure(CurrentObject,
&NextObject,
&PathString,
¤t,
}
if (current)
+ {
RtlpCreateUnicodeString (RemainingPath, current, NonPagedPool);
+ }
+
RtlFreeUnicodeString (&PathString);
*ReturnedObject = CurrentObject;
ObjectHeader = BODY_TO_HEADER(Object);
if (ObjectHeader->ObjectType != NULL &&
- ObjectHeader->ObjectType->QueryName != NULL)
+ ObjectHeader->ObjectType->TypeInfo.QueryNameProcedure != NULL)
{
- DPRINT ("Calling %x\n", ObjectHeader->ObjectType->QueryName);
- Status = ObjectHeader->ObjectType->QueryName (Object,
+ DPRINT ("Calling %x\n", ObjectHeader->ObjectType->TypeInfo.QueryNameProcedure);
+ Status = ObjectHeader->ObjectType->TypeInfo.QueryNameProcedure (Object,
ObjectNameInfo,
Length,
ReturnLength);
}
- else if (ObjectHeader->Name.Length > 0 && ObjectHeader->Name.Buffer != NULL)
+ else if (ObjectHeader->NameInfo->Name.Length > 0 && ObjectHeader->NameInfo->Name.Buffer != NULL)
{
DPRINT ("Object does not have a 'QueryName' function\n");
- if (ObjectHeader->Parent == NameSpaceRoot)
+ if (ObjectHeader->NameInfo->Directory == NameSpaceRoot)
{
DPRINT ("Reached the root directory\n");
ObjectNameInfo->Name.Length = 0;
ObjectNameInfo->Name.Buffer[0] = 0;
Status = STATUS_SUCCESS;
}
- else if (ObjectHeader->Parent != NULL)
+ else if (ObjectHeader->NameInfo->Directory != NULL)
{
LocalInfo = ExAllocatePool (NonPagedPool,
sizeof(OBJECT_NAME_INFORMATION) +
if (LocalInfo == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
- Status = ObQueryNameString (ObjectHeader->Parent,
+ Status = ObQueryNameString (ObjectHeader->NameInfo->Directory,
LocalInfo,
MAX_PATH * sizeof(WCHAR),
&LocalReturnLength);
return Status;
}
- DPRINT ("Object path %wZ\n", &ObjectHeader->Name);
+ DPRINT ("Object path %wZ\n", &ObjectHeader->NameInfo->Name);
Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name,
L"\\");
if (!NT_SUCCESS (Status))
return Status;
Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
- &ObjectHeader->Name);
+ &ObjectHeader->NameInfo->Name);
}
else
{
return Status;
}
+NTSTATUS
+STDCALL
+ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
+ PUNICODE_STRING ObjectName,
+ POBJECT_TYPE ObjectType,
+ ULONG ObjectSize,
+ POBJECT_HEADER *ObjectHeader)
+{
+ POBJECT_HEADER Header;
+ POBJECT_HEADER_NAME_INFO ObjectNameInfo;
+ POOL_TYPE PoolType;
+ ULONG Tag;
+
+ /* If we don't have an Object Type yet, force NonPaged */
+ DPRINT("ObpAllocateObject\n");
+ if (!ObjectType)
+ {
+ PoolType = NonPagedPool;
+ Tag = TAG('O', 'b', 'j', 'T');
+ }
+ else
+ {
+ PoolType = ObjectType->TypeInfo.PoolType;
+ Tag = ObjectType->Key;
+ }
+
+ /* Allocate memory for the Object */
+ Header = ExAllocatePoolWithTag(PoolType, ObjectSize, Tag);
+ if (!Header) {
+ DPRINT1("Not enough memory!\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Initialize the object header */
+ RtlZeroMemory(Header, ObjectSize);
+ DPRINT("Initalizing header %p\n", Header);
+ Header->HandleCount = 0;
+ Header->RefCount = 1;
+ Header->ObjectType = ObjectType;
+ if (ObjectCreateInfo && ObjectCreateInfo->Attributes & OBJ_PERMANENT)
+ {
+ Header->Permanent = TRUE;
+ }
+ if (ObjectCreateInfo && ObjectCreateInfo->Attributes & OBJ_INHERIT)
+ {
+ Header->Inherit = TRUE;
+ }
+
+ /* Initialize the Object Name Info [part of header in OB 2.0] */
+ ObjectNameInfo = ExAllocatePool(PoolType, ObjectSize);
+ ObjectNameInfo->Name = *ObjectName;
+ ObjectNameInfo->Directory = NULL;
+
+ /* Link stuff to Object Header */
+ Header->NameInfo = ObjectNameInfo;
+ Header->ObjectCreateInfo = ObjectCreateInfo;
+
+ /* Return Header */
+ *ObjectHeader = Header;
+ return STATUS_SUCCESS;
+}
/**********************************************************************
* NAME EXPORTED
*
* @implemented
*/
-NTSTATUS STDCALL
-ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
- IN POBJECT_TYPE Type,
- IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
- IN KPROCESSOR_MODE AccessMode,
- IN OUT PVOID ParseContext OPTIONAL,
- IN ULONG ObjectSize,
- IN ULONG PagedPoolCharge OPTIONAL,
- IN ULONG NonPagedPoolCharge OPTIONAL,
- OUT PVOID *Object)
+NTSTATUS
+STDCALL
+ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
+ IN POBJECT_TYPE Type,
+ IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
+ IN KPROCESSOR_MODE AccessMode,
+ IN OUT PVOID ParseContext OPTIONAL,
+ IN ULONG ObjectSize,
+ IN ULONG PagedPoolCharge OPTIONAL,
+ IN ULONG NonPagedPoolCharge OPTIONAL,
+ OUT PVOID *Object)
{
- PVOID Parent = NULL;
- UNICODE_STRING RemainingPath;
- POBJECT_HEADER Header;
- POBJECT_HEADER ParentHeader = NULL;
- NTSTATUS Status = 0;
- BOOLEAN ObjectAttached = FALSE;
- PWCHAR NamePtr;
- PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
- SECURITY_SUBJECT_CONTEXT SubjectContext;
-
- PAGED_CODE();
-
- if(ObjectAttributesAccessMode == UserMode && ObjectAttributes != NULL)
- {
- Status = STATUS_SUCCESS;
- _SEH_TRY
- {
- ProbeForRead(ObjectAttributes,
- sizeof(OBJECT_ATTRIBUTES),
- sizeof(ULONG));
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- return Status;
- }
- }
-
- DPRINT("ObCreateObject(Type %p ObjectAttributes %p, Object %p)\n",
- Type, ObjectAttributes, Object);
-
- if (Type == NULL)
+ NTSTATUS Status;
+ POBJECT_CREATE_INFORMATION ObjectCreateInfo;
+ UNICODE_STRING ObjectName;
+ POBJECT_HEADER Header;
+
+ DPRINT("ObCreateObject(Type %p ObjectAttributes %p, Object %p)\n",
+ Type, ObjectAttributes, Object);
+
+ /* Allocate a Buffer for the Object Create Info */
+ DPRINT("Allocating Create Buffer\n");
+ ObjectCreateInfo = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(*ObjectCreateInfo),
+ TAG('O','b','C', 'I'));
+
+ /* Capture all the info */
+ DPRINT("Capturing Create Info\n");
+ Status = ObpCaptureObjectAttributes(ObjectAttributes,
+ AccessMode,
+ Type,
+ ObjectCreateInfo,
+ &ObjectName);
+
+ if (NT_SUCCESS(Status))
{
- DPRINT1("Invalid object type!\n");
- return STATUS_INVALID_PARAMETER;
- }
-
- if (ObjectAttributes != NULL &&
- ObjectAttributes->ObjectName != NULL &&
- ObjectAttributes->ObjectName->Buffer != NULL)
- {
- Status = ObFindObject(ObjectAttributes,
- &Parent,
- &RemainingPath,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("ObFindObject() failed! (Status 0x%x)\n", Status);
- return Status;
- }
- if (Parent != NULL)
+ /* Allocate the Object */
+ DPRINT("Allocating: %wZ\n", &ObjectName);
+ Status = ObpAllocateObject(ObjectCreateInfo,
+ &ObjectName,
+ Type,
+ OBJECT_ALLOC_SIZE(ObjectSize),
+ &Header);
+
+ if (NT_SUCCESS(Status))
{
- ParentHeader = BODY_TO_HEADER(Parent);
+ /* Return the Object */
+ DPRINT("Returning Object\n");
+ *Object = HEADER_TO_BODY(Header);
+
+ /* Return to caller, leave the Capture Info Alive for ObInsert */
+ return Status;
}
- if (ParentHeader &&
- RemainingPath.Buffer == NULL)
- {
- if (ParentHeader->ObjectType != Type
- || !(ObjectAttributes->Attributes & OBJ_OPENIF))
- {
- ObDereferenceObject(Parent);
- return STATUS_OBJECT_NAME_COLLISION;
- }
- *Object = Parent;
- return STATUS_OBJECT_EXISTS;
- }
- }
- else
- {
- RtlInitUnicodeString(&RemainingPath, NULL);
- }
-
- DPRINT("Allocating memory\n");
- Header = (POBJECT_HEADER)ExAllocatePoolWithTag(NonPagedPool,
- OBJECT_ALLOC_SIZE(ObjectSize),
- Type->Tag);
- if (Header == NULL) {
- DPRINT1("Not enough memory!\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- RtlZeroMemory(Header, OBJECT_ALLOC_SIZE(ObjectSize));
-
- /* Initialize the object header */
- DPRINT("Initalizing header 0x%x (%wZ)\n", Header, &Type->TypeName);
- Header->HandleCount = 0;
- Header->RefCount = 1;
- Header->ObjectType = Type;
- if (ObjectAttributes != NULL &&
- ObjectAttributes->Attributes & OBJ_PERMANENT)
- {
- Header->Permanent = TRUE;
- }
- else
- {
- Header->Permanent = FALSE;
- }
-
- if (ObjectAttributes != NULL &&
- ObjectAttributes->Attributes & OBJ_INHERIT)
- {
- Header->Inherit = TRUE;
- }
- else
- {
- Header->Inherit = FALSE;
- }
-
- RtlInitUnicodeString(&(Header->Name),NULL);
-
- DPRINT("Getting Parent and adding entry\n");
- if (ParentHeader != NULL &&
- ParentHeader->ObjectType == ObDirectoryType &&
- RemainingPath.Buffer != NULL)
- {
- NamePtr = RemainingPath.Buffer;
- if (*NamePtr == L'\\')
- NamePtr++;
-
- ObpAddEntryDirectory(Parent,
- Header,
- NamePtr);
-
- ObjectAttached = TRUE;
- }
-
- if ((Header->ObjectType == IoFileObjectType) ||
- (Header->ObjectType == ExDesktopObjectType) ||
- (Header->ObjectType->Open != NULL))
- {
- DPRINT("About to call Open Routine\n");
- if (Header->ObjectType == IoFileObjectType)
- {
- /* TEMPORARY HACK. DO NOT TOUCH -- Alex */
- DPRINT("Calling IopCreateFile\n");
- Status = IopCreateFile(HEADER_TO_BODY(Header),
- Parent,
- RemainingPath.Buffer,
- ObjectAttributes);
- }
- else if (Header->ObjectType == ExDesktopObjectType)
- {
- /* TEMPORARY HACK. DO NOT TOUCH -- Alex */
- DPRINT("Calling ExpDesktopCreate\n");
- Status = ExpDesktopCreate(HEADER_TO_BODY(Header),
- Parent,
- RemainingPath.Buffer,
- ObjectAttributes);
- }
- else if (Header->ObjectType->Open != NULL)
- {
- DPRINT("Calling %x\n", Header->ObjectType->Open);
- Status = Header->ObjectType->Open(ObCreateHandle,
- HEADER_TO_BODY(Header),
- NULL,
- 0,
- 0);
- }
-
- if (!NT_SUCCESS(Status))
- {
- if (ObjectAttached == TRUE)
- {
- ObpRemoveEntryDirectory(Header);
- }
- if (Parent)
- {
- ObDereferenceObject(Parent);
- }
- RtlFreeUnicodeString(&Header->Name);
- RtlFreeUnicodeString(&RemainingPath);
- ExFreePool(Header);
- DPRINT("Create Failed\n");
- return Status;
- }
- }
-
- RtlFreeUnicodeString(&RemainingPath);
-
- SeCaptureSubjectContext(&SubjectContext);
-
- DPRINT("Security Assignment in progress\n");
- /* Build the new security descriptor */
- Status = SeAssignSecurity((ParentHeader != NULL) ? ParentHeader->SecurityDescriptor : NULL,
- (ObjectAttributes != NULL) ? ObjectAttributes->SecurityDescriptor : NULL,
- &NewSecurityDescriptor,
- (Header->ObjectType == ObDirectoryType),
- &SubjectContext,
- Header->ObjectType->Mapping,
- PagedPool);
- if (NT_SUCCESS(Status))
- {
- DPRINT("NewSecurityDescriptor %p\n", NewSecurityDescriptor);
-
- if (Header->ObjectType->Security != NULL)
- {
- /* Call the security method */
- Status = Header->ObjectType->Security(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);
+
+ /* Release the Capture Info, we don't need it */
+ DPRINT1("Allocation failed\n");
+ ObpReleaseCapturedAttributes(ObjectCreateInfo);
+ if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
}
-
- DPRINT("Security Complete\n");
- SeReleaseSubjectContext(&SubjectContext);
-
- if (Object != NULL)
- {
- *Object = HEADER_TO_BODY(Header);
- }
-
- DPRINT("Sucess!\n");
- return STATUS_SUCCESS;
+
+ /* We failed, so release the Buffer */
+ DPRINT1("Capture failed\n");
+ ExFreePool(ObjectCreateInfo);
+ return Status;
}
-
/*
* FUNCTION: Increments the pointer reference count for a given object
* ARGUMENTS:
KEBUGCHECK(0);
}
+ if (Header->ObjectType != NULL &&
+ Header->ObjectType->TypeInfo.DeleteProcedure != NULL)
+ {
+ Header->ObjectType->TypeInfo.DeleteProcedure(HEADER_TO_BODY(Header));
+ }
+
if (Header->SecurityDescriptor != NULL)
{
ObpRemoveSecurityDescriptor(Header->SecurityDescriptor);
}
-
- if (Header->ObjectType != NULL &&
- Header->ObjectType->Delete != NULL)
+
+ if (Header->NameInfo)
{
- Header->ObjectType->Delete(HEADER_TO_BODY(Header));
+ if(Header->NameInfo->Name.Buffer)
+ {
+ ExFreePool(Header->NameInfo->Name.Buffer);
+ }
+ ExFreePool(Header->NameInfo);
}
-
- if (Header->Name.Buffer != NULL)
+ if (Header->ObjectCreateInfo)
{
- ObpRemoveEntryDirectory(Header);
- RtlFreeUnicodeString(&Header->Name);
+ ObpReleaseCapturedAttributes(Header->ObjectCreateInfo);
+ ExFreePool(Header->ObjectCreateInfo);
}
DPRINT("ObPerformRetentionChecks() = Freeing object\n");
Params = (PRETENTION_CHECK_PARAMS)
ExAllocatePoolWithTag(NonPagedPoolMustSucceed,
sizeof(RETENTION_CHECK_PARAMS),
- ObjectHeader->ObjectType->Tag);
+ ObjectHeader->ObjectType->Key);
Params->ObjectHeader = ObjectHeader;
ExInitializeWorkItem(&Params->WorkItem,
ObpDeleteObjectWorkRoutine,
last reference.
*/
NewRefCount = InterlockedDecrement(&Header->RefCount);
- DPRINT("ObfDereferenceObject(0x%x)==%d (%wZ)\n", Object, NewRefCount, &Header->ObjectType->TypeName);
+ DPRINT("ObfDereferenceObject(0x%x)==%d\n", Object, NewRefCount);
ASSERT(NewRefCount >= 0);
/* Check whether the object can now be deleted. */