/* $Id$
*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/ob/object.c
- * PURPOSE: Implements generic object managment functions
- * PROGRAMMERS David Welch (welch@cwcom.net), Skywing (skywing@valhallalegends.com)
- * UPDATE HISTORY:
- * 10/06/98: Created
- * 09/13/03: Fixed various ObXxx routines to not call retention
- * checks directly at a raised IRQL.
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/ob/object.c
+ * PURPOSE: Implements generic object managment functions
+ *
+ * PROGRAMMERS: David Welch (welch@cwcom.net)
+ * Skywing (skywing@valhallalegends.com)
*/
/* INCLUDES *****************************************************************/
{
OBJECT_ATTRIBUTES AttributesCopy;
NTSTATUS Status = STATUS_SUCCESS;
-
+
/* at least one output parameter must be != NULL! */
- ASSERT((ULONG_PTR)CapturedObjectAttributes ^ (ULONG_PTR)ObjectName != 0);
-
+ ASSERT(CapturedObjectAttributes != NULL || ObjectName != NULL);
+
if(ObjectAttributes == NULL)
{
-failbasiccleanup:
- if(ObjectName != NULL)
- {
- RtlInitUnicodeString(ObjectName, NULL);
- }
- if(CapturedObjectAttributes != NULL)
- {
- RtlZeroMemory(CapturedObjectAttributes, sizeof(CAPTURED_OBJECT_ATTRIBUTES));
- }
- return Status; /* STATUS_SUCCESS */
+ /* we're going to return STATUS_SUCCESS! */
+ goto failbasiccleanup;
}
-
+
if(AccessMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
- return Status;
+ DPRINT1("ObpCaptureObjectAttributes failed to probe object attributes\n");
+ goto failbasiccleanup;
}
}
- else if(AccessMode == KernelMode && !CaptureIfKernel)
+ else if(!CaptureIfKernel)
{
- if(ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES))
+ if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
{
- /* we don't have to capture any memory, the caller considers the passed data
- as valid */
if(ObjectName != NULL)
{
- *ObjectName = *ObjectAttributes->ObjectName;
+ /* we don't have to capture any memory, the caller considers the passed data
+ as valid */
+ if(ObjectAttributes->ObjectName != NULL)
+ {
+ *ObjectName = *ObjectAttributes->ObjectName;
+ }
+ else
+ {
+ ObjectName->Length = ObjectName->MaximumLength = 0;
+ ObjectName->Buffer = NULL;
+ }
}
if(CapturedObjectAttributes != NULL)
{
CapturedObjectAttributes->RootDirectory = ObjectAttributes->RootDirectory;
CapturedObjectAttributes->Attributes = ObjectAttributes->Attributes;
CapturedObjectAttributes->SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
+ CapturedObjectAttributes->SecurityQualityOfService = ObjectAttributes->SecurityQualityOfService;
}
return STATUS_SUCCESS;
{
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->SecurityDescriptor = NULL;
}
+
+ if(AttributesCopy.SecurityQualityOfService != NULL)
+ {
+ SECURITY_QUALITY_OF_SERVICE 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;
+ }
+ }
+ else
+ {
+ CapturedObjectAttributes->SecurityQualityOfService = NULL;
+ }
}
-
+
if(ObjectName != NULL)
{
if(AttributesCopy.ObjectName != NULL)
{
UNICODE_STRING OriginalCopy;
-
+
if(AccessMode != KernelMode)
{
_SEH_TRY
{
ProbeForRead(OriginalCopy.Buffer,
OriginalCopy.Length,
- sizeof(ULONG));
+ sizeof(WCHAR));
}
}
_SEH_HANDLE
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(NT_SUCCESS(Status))
{
if(OriginalCopy.Length > 0)
Status = _SEH_GetExceptionCode();
}
_SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("ObpCaptureObjectAttributes failed to copy the unicode string!\n");
+ }
}
else
{
Status = STATUS_OBJECT_NAME_INVALID;
}
}
-
- /* handle failure */
- if(!NT_SUCCESS(Status))
+ else
{
-failallocatedcleanup:
- if(ObjectName->Buffer)
- {
- ExFreePool(ObjectName->Buffer);
- }
- if(CapturedObjectAttributes != NULL)
- {
- /* cleanup allocated resources */
- SeReleaseSecurityDescriptor(CapturedObjectAttributes->SecurityDescriptor,
- AccessMode,
- TRUE);
- }
- goto failbasiccleanup;
+ DPRINT1("ObpCaptureObjectAttributes failed to probe the object name UNICODE_STRING structure!\n");
}
}
else /* AccessMode == KernelMode */
{
OriginalCopy = *AttributesCopy.ObjectName;
-
+
if(OriginalCopy.Length > 0)
{
ObjectName->MaximumLength = OriginalCopy.Length + sizeof(WCHAR);
/* if the caller specified a root directory, there must be an object name! */
Status = STATUS_OBJECT_NAME_INVALID;
}
-
- if(!NT_SUCCESS(Status))
- {
- goto failallocatedcleanup;
- }
}
}
else
{
- RtlInitUnicodeString(ObjectName, NULL);
+ ObjectName->Length = ObjectName->MaximumLength = 0;
+ ObjectName->Buffer = NULL;
}
}
-
+
+ if(!NT_SUCCESS(Status))
+ {
+ if(ObjectName->Buffer)
+ {
+ ExFreePool(ObjectName->Buffer);
+ }
+
+failcleanupsdescriptor:
+ if(CapturedObjectAttributes != NULL)
+ {
+ /* cleanup allocated resources */
+ SeReleaseSecurityDescriptor(CapturedObjectAttributes->SecurityDescriptor,
+ AccessMode,
+ TRUE);
+ }
+
+failbasiccleanup:
+ if(ObjectName != NULL)
+ {
+ ObjectName->Length = ObjectName->MaximumLength = 0;
+ ObjectName->Buffer = NULL;
+ }
+ if(CapturedObjectAttributes != NULL)
+ {
+ RtlZeroMemory(CapturedObjectAttributes, sizeof(CAPTURED_OBJECT_ATTRIBUTES));
+ }
+ }
+
return Status;
}
+
VOID
ObpReleaseObjectAttributes(IN PCAPTURED_OBJECT_ATTRIBUTES CapturedObjectAttributes OPTIONAL,
IN PUNICODE_STRING ObjectName OPTIONAL,
{
/* WARNING - You need to pass the same parameters to this function as you passed
to ObpCaptureObjectAttributes() to avoid memory leaks */
- if(AccessMode != KernelMode ||
- (AccessMode == KernelMode && CaptureIfKernel))
+ if(AccessMode != KernelMode || CaptureIfKernel)
{
- if(CapturedObjectAttributes != NULL &&
- CapturedObjectAttributes->SecurityDescriptor != NULL)
+ if(CapturedObjectAttributes != NULL)
{
- ExFreePool(CapturedObjectAttributes->SecurityDescriptor);
- CapturedObjectAttributes->SecurityDescriptor = 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)
UNICODE_STRING PathString;
ULONG Attributes;
PUNICODE_STRING ObjectName;
+
+ PAGED_CODE();
DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
"RemainingPath %x)\n",ObjectAttributes,ReturnedObject,RemainingPath);
}
if (current)
- RtlCreateUnicodeString (RemainingPath, current);
+ RtlpCreateUnicodeString (RemainingPath, current, NonPagedPool);
RtlFreeUnicodeString (&PathString);
*ReturnedObject = CurrentObject;
POBJECT_HEADER ObjectHeader;
ULONG LocalReturnLength;
NTSTATUS Status;
+
+ PAGED_CODE();
*ReturnLength = 0;
PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
SECURITY_SUBJECT_CONTEXT SubjectContext;
- ASSERT_IRQL(APC_LEVEL);
+ PAGED_CODE();
- if(AccessMode == UserMode)
+ if(ObjectAttributesAccessMode == UserMode && ObjectAttributes != NULL)
{
Status = STATUS_SUCCESS;
_SEH_TRY
IN KPROCESSOR_MODE AccessMode)
{
POBJECT_HEADER Header;
+
+ /* NOTE: should be possible to reference an object above APC_LEVEL! */
DPRINT("ObReferenceObjectByPointer(Object %x, ObjectType %x)\n",
Object,ObjectType);
{
NTSTATUS Status;
+ PAGED_CODE();
+
DPRINT("ObOpenObjectByPointer()\n");
Status = ObReferenceObjectByPointer(Object,
ObGetObjectPointerCount(PVOID Object)
{
POBJECT_HEADER Header;
+
+ PAGED_CODE();
ASSERT(Object);
Header = BODY_TO_HEADER(Object);
ObGetObjectHandleCount(PVOID Object)
{
POBJECT_HEADER Header;
+
+ PAGED_CODE();
ASSERT(Object);
Header = BODY_TO_HEADER(Object);