POBJECT_TYPE ObpTypeObjectType = NULL;
KEVENT ObpDefaultObject;
+KGUARDED_MUTEX ObpDeviceMapLock;
GENERAL_LOOKASIDE ObpNameBufferLookasideList, ObpCreateInfoLookasideList;
/* Add the SD charge too */
if (Header->Flags & OB_FLAG_SECURITY) PagedPoolCharge += 2048;
}
-
+
/* Return the quota */
DPRINT("FIXME: Should return quotas: %lx %lx\n", PagedPoolCharge, NonPagedPoolCharge);
#if 0
PagedPoolCharge,
NonPagedPoolCharge);
#endif
-
+
}
}
NTSTATUS
NTAPI
ObpCaptureObjectCreateInformation(IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN KPROCESSOR_MODE AccessMode,
- IN BOOLEAN AllocateFromLookaside,
- IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
- OUT PUNICODE_STRING ObjectName)
+ IN KPROCESSOR_MODE AccessMode,
+ IN KPROCESSOR_MODE CreatorMode,
+ IN BOOLEAN AllocateFromLookaside,
+ IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
+ OUT PUNICODE_STRING ObjectName)
{
NTSTATUS Status = STATUS_SUCCESS;
PSECURITY_DESCRIPTOR SecurityDescriptor;
_SEH2_YIELD(return STATUS_INVALID_PARAMETER);
}
- /* Set some Create Info */
+ /* Set some Create Info and do not allow user-mode kernel handles */
ObjectCreateInfo->RootDirectory = ObjectAttributes->RootDirectory;
- ObjectCreateInfo->Attributes = ObjectAttributes->Attributes;
+ ObjectCreateInfo->Attributes = ObjectAttributes->Attributes & OBJ_VALID_ATTRIBUTES;
+ if (CreatorMode != KernelMode) ObjectCreateInfo->Attributes &= ~OBJ_KERNEL_HANDLE;
LocalObjectName = ObjectAttributes->ObjectName;
SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
SecurityQos = ObjectAttributes->SecurityQualityOfService;
/* Capture all the info */
Status = ObpCaptureObjectCreateInformation(ObjectAttributes,
ProbeMode,
+ AccessMode,
FALSE,
ObjectCreateInfo,
&ObjectName);
POBJECT_TYPE LocalObjectType;
ULONG HeaderSize;
NTSTATUS Status;
- CHAR Tag[4];
OBP_LOOKUP_CONTEXT Context;
PWCHAR p;
ULONG i;
UNICODE_STRING ObjectName;
+ ANSI_STRING AnsiName;
POBJECT_HEADER_CREATOR_INFO CreatorInfo;
/* Verify parameters */
ObpTypeObjectType,
sizeof(OBJECT_TYPE),
KernelMode,
- (POBJECT_HEADER*)&Header);
+ &Header);
if (!NT_SUCCESS(Status))
{
/* Free the name and fail */
}
else
{
- /* Set Tag */
- Tag[0] = (CHAR)TypeName->Buffer[0];
- Tag[1] = (CHAR)TypeName->Buffer[1];
- Tag[2] = (CHAR)TypeName->Buffer[2];
- Tag[3] = (CHAR)TypeName->Buffer[3];
- LocalObjectType->Key = *(PULONG)Tag;
+ /* Convert the tag to ASCII */
+ Status = RtlUnicodeStringToAnsiString(&AnsiName, TypeName, TRUE);
+ if (NT_SUCCESS(Status))
+ {
+ /* For every missing character, use a space */
+ for (i = 3; i >= AnsiName.Length; i--) AnsiName.Buffer[i] = ' ';
+
+ /* Set the key and free the converted name */
+ LocalObjectType->Key = *(PULONG)AnsiName.Buffer;
+ RtlFreeAnsiString(&AnsiName);
+ }
+ else
+ {
+ /* Just copy the characters */
+ LocalObjectType->Key = *(PULONG)TypeName->Buffer;
+ }
}
/* Set up the type information */
InitializeListHead(&LocalObjectType->TypeList);
/* Lock the object type */
- ObpEnterObjectTypeMutex(LocalObjectType);
+ ObpEnterObjectTypeMutex(ObpTypeObjectType);
/* Get creator info and insert it into the type list */
CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(Header);
- if (CreatorInfo) InsertTailList(&ObpTypeObjectType->TypeList,
- &CreatorInfo->TypeList);
+ if (CreatorInfo)
+ {
+ InsertTailList(&ObpTypeObjectType->TypeList,
+ &CreatorInfo->TypeList);
+
+ /* CORE-8423: Avoid inserting this a second time if someone creates a
+ * handle to the object type (bug in Windows 2003) */
+ Header->Flags &= ~OB_FLAG_CREATE_INFO;
+ }
/* Set the index and the entry into the object type array */
LocalObjectType->Index = ObpTypeObjectType->TotalNumberOfObjects;
+
+ NT_ASSERT(LocalObjectType->Index != 0);
+
if (LocalObjectType->Index < 32)
{
/* It fits, insert it */
}
/* Release the object type */
- ObpLeaveObjectTypeMutex(LocalObjectType);
+ ObpLeaveObjectTypeMutex(ObpTypeObjectType);
/* Check if we're actually creating the directory object itself */
if (!(ObpTypeDirectoryObject) ||
return STATUS_INSUFFICIENT_RESOURCES;
}
+VOID
+NTAPI
+ObDeleteCapturedInsertInfo(IN PVOID Object)
+{
+ POBJECT_HEADER ObjectHeader;
+ PAGED_CODE();
+
+ /* Check if there is anything to free */
+ ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
+ if ((ObjectHeader->Flags & OB_FLAG_CREATE_INFO) &&
+ (ObjectHeader->ObjectCreateInfo != NULL))
+ {
+ /* Free the create info */
+ ObpFreeObjectCreateInformation(ObjectHeader->ObjectCreateInfo);
+ ObjectHeader->ObjectCreateInfo = NULL;
+ }
+}
+
VOID
NTAPI
ObpDeleteObjectType(IN PVOID Object)
{
ULONG i;
POBJECT_TYPE ObjectType = (PVOID)Object;
-
+
/* Loop our locks */
for (i = 0; i < 4; i++)
{
/* Delete each one */
ExDeleteResourceLite(&ObjectType->ObjectLocks[i]);
}
-
+
/* Delete our main mutex */
ExDeleteResourceLite(&ObjectType->Mutex);
}
POBJECT_HEADER ObjectHeader = NULL;
POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags;
POBJECT_BASIC_INFORMATION BasicInfo;
- ULONG InfoLength;
+ ULONG InfoLength = 0;
PVOID Object = NULL;
NTSTATUS Status;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
_SEH2_END;
/* Dereference the object if we had referenced it */
- if (Object) ObDereferenceObject (Object);
+ if (Object) ObDereferenceObject(Object);
/* Return status */
return Status;
OBP_SET_HANDLE_ATTRIBUTES_CONTEXT Context;
PVOID ObjectTable;
KAPC_STATE ApcState;
+ POBJECT_DIRECTORY Directory;
+ KPROCESSOR_MODE PreviousMode;
BOOLEAN AttachedToProcess = FALSE;
PAGED_CODE();
/* Validate the information class */
- if (ObjectInformationClass != ObjectHandleFlagInformation)
+ switch (ObjectInformationClass)
{
- /* Invalid class */
- return STATUS_INVALID_INFO_CLASS;
- }
+ case ObjectHandleFlagInformation:
- /* Validate the length */
- if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION))
- {
- /* Invalid length */
- return STATUS_INFO_LENGTH_MISMATCH;
- }
+ /* Validate the length */
+ if (Length != sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION))
+ {
+ /* Invalid length */
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
- /* Save the previous mode */
- Context.PreviousMode = ExGetPreviousMode();
+ /* Save the previous mode */
+ Context.PreviousMode = ExGetPreviousMode();
- /* Check if we were called from user mode */
- if (Context.PreviousMode != KernelMode)
- {
- /* Enter SEH */
- _SEH2_TRY
- {
- /* Probe and capture the attribute buffer */
- ProbeForRead(ObjectInformation,
- sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION),
- sizeof(BOOLEAN));
- Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
- ObjectInformation;
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* Return the exception code */
- _SEH2_YIELD(return _SEH2_GetExceptionCode());
- }
- _SEH2_END;
- }
- else
- {
- /* Just copy the buffer directly */
- Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
- ObjectInformation;
- }
+ /* Check if we were called from user mode */
+ if (Context.PreviousMode != KernelMode)
+ {
+ /* Enter SEH */
+ _SEH2_TRY
+ {
+ /* Probe and capture the attribute buffer */
+ ProbeForRead(ObjectInformation,
+ sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION),
+ sizeof(BOOLEAN));
+ Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
+ ObjectInformation;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ /* Just copy the buffer directly */
+ Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
+ ObjectInformation;
+ }
- /* Check if this is a kernel handle */
- if (ObIsKernelHandle(ObjectHandle, Context.PreviousMode))
- {
- /* Get the actual handle */
- ObjectHandle = ObKernelHandleToHandle(ObjectHandle);
- ObjectTable = ObpKernelHandleTable;
+ /* Check if this is a kernel handle */
+ if (ObpIsKernelHandle(ObjectHandle, Context.PreviousMode))
+ {
+ /* Get the actual handle */
+ ObjectHandle = ObKernelHandleToHandle(ObjectHandle);
+ ObjectTable = ObpKernelHandleTable;
- /* Check if we're not in the system process */
- if (PsGetCurrentProcess() != PsInitialSystemProcess)
- {
- /* Attach to it */
- KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState);
- AttachedToProcess = TRUE;
- }
- }
- else
- {
- /* Use the current table */
- ObjectTable = PsGetCurrentProcess()->ObjectTable;
- }
+ /* Check if we're not in the system process */
+ if (PsGetCurrentProcess() != PsInitialSystemProcess)
+ {
+ /* Attach to it */
+ KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState);
+ AttachedToProcess = TRUE;
+ }
+ }
+ else
+ {
+ /* Use the current table */
+ ObjectTable = PsGetCurrentProcess()->ObjectTable;
+ }
- /* Change the handle attributes */
- if (!ExChangeHandle(ObjectTable,
- ObjectHandle,
- ObpSetHandleAttributes,
- (ULONG_PTR)&Context))
- {
- /* Some failure */
- Status = STATUS_ACCESS_DENIED;
- }
- else
- {
- /* We are done */
- Status = STATUS_SUCCESS;
+ /* Change the handle attributes */
+ if (!ExChangeHandle(ObjectTable,
+ ObjectHandle,
+ ObpSetHandleAttributes,
+ (ULONG_PTR)&Context))
+ {
+ /* Some failure */
+ Status = STATUS_ACCESS_DENIED;
+ }
+ else
+ {
+ /* We are done */
+ Status = STATUS_SUCCESS;
+ }
+
+ /* De-attach if we were attached, and return status */
+ if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
+ break;
+
+ case ObjectSessionInformation:
+
+ /* Only a system process can do this */
+ PreviousMode = ExGetPreviousMode();
+ if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
+ {
+ /* Fail */
+ DPRINT1("Privilege not held\n");
+ Status = STATUS_PRIVILEGE_NOT_HELD;
+ }
+ else
+ {
+ /* Get the object directory */
+ Status = ObReferenceObjectByHandle(ObjectHandle,
+ 0,
+ ObDirectoryType,
+ PreviousMode,
+ (PVOID*)&Directory,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ /* FIXME: Missng locks */
+ /* Set its session ID */
+ Directory->SessionId = PsGetCurrentProcessSessionId();
+ ObDereferenceObject(Directory);
+ }
+ }
+ break;
+
+ default:
+ /* Unsupported class */
+ Status = STATUS_INVALID_INFO_CLASS;
+ break;
}
- /* De-attach if we were attached, and return status */
- if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
return Status;
}