diff --git a/reactos/include/ndk/psfuncs.h b/reactos/include/ndk/psfuncs.h index ac2c8992b15..ff33730d2f8 100644 --- a/reactos/include/ndk/psfuncs.h +++ b/reactos/include/ndk/psfuncs.h @@ -137,6 +137,13 @@ PsReturnProcessNonPagedPoolQuota( IN SIZE_T Amount ); +NTKERNELAPI +ULONG +NTAPI +PsGetCurrentProcessSessionId( + VOID +); + // // Process Impersonation Functions // diff --git a/reactos/ntoskrnl/ob/oblife.c b/reactos/ntoskrnl/ob/oblife.c index 5b4727483f9..a95b6f21462 100644 --- a/reactos/ntoskrnl/ob/oblife.c +++ b/reactos/ntoskrnl/ob/oblife.c @@ -1605,7 +1605,7 @@ NtQueryObject(IN HANDLE ObjectHandle, _SEH2_END; /* Dereference the object if we had referenced it */ - if (Object) ObDereferenceObject (Object); + if (Object) ObDereferenceObject(Object); /* Return status */ return Status; @@ -1645,91 +1645,128 @@ NtSetInformationObject(IN HANDLE ObjectHandle, 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; + } + + /* 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 this is a kernel handle */ + if (ObIsKernelHandle(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; + } + + /* 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; } - /* Validate the length */ - if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION)) - { - /* Invalid length */ - return STATUS_INFO_LENGTH_MISMATCH; - } - - /* 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 this is a kernel handle */ - if (ObIsKernelHandle(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; - } - - /* 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); return Status; } diff --git a/reactos/ntoskrnl/ps/query.c b/reactos/ntoskrnl/ps/query.c index 1fbf36a4be1..d9d9b97fbf0 100644 --- a/reactos/ntoskrnl/ps/query.c +++ b/reactos/ntoskrnl/ps/query.c @@ -835,8 +835,29 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle, break; case ProcessLUIDDeviceMapsEnabled: - DPRINT1("LUID Device Maps Not implemented: %lx\n", ProcessInformationClass); - Status = STATUS_NOT_IMPLEMENTED; + /* Set the return length */ + Length = sizeof(ULONG); + if (ProcessInformationLength != Length) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + /* Indicate success */ + Status = STATUS_SUCCESS; + + /* Protect write in SEH */ + _SEH2_TRY + { + /* Return the count of handles */ + *(PULONG)ProcessInformation = FALSE; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; break; case ProcessExecuteFlags: