Author: ion Date: Mon Feb 20 06:42:02 2012 New Revision: 55734
URL: http://svn.reactos.org/svn/reactos?rev=55734&view=rev Log: [NTOSKRNL]: Implement ProcessDebugObjectHandle and a bunch more query/set process classes. Fixes Winetests. [NTOSKRNL]: We should not be setting *ReturnLength in most failure cases, so no longer do so. Fixes Winetests.
Modified: trunk/reactos/ntoskrnl/dbgk/dbgkobj.c trunk/reactos/ntoskrnl/include/internal/dbgk.h trunk/reactos/ntoskrnl/include/internal/mm.h trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c trunk/reactos/ntoskrnl/ps/query.c
Modified: trunk/reactos/ntoskrnl/dbgk/dbgkobj.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/dbgk/dbgkobj.c?rev... ============================================================================== --- trunk/reactos/ntoskrnl/dbgk/dbgkobj.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/dbgk/dbgkobj.c [iso-8859-1] Mon Feb 20 06:42:02 2012 @@ -1504,6 +1504,46 @@ &DbgkDebugObjectType); }
+NTSTATUS +NTAPI +DbgkOpenProcessDebugPort(IN PEPROCESS Process, + IN KPROCESSOR_MODE PreviousMode, + OUT HANDLE *DebugHandle) +{ + PDEBUG_OBJECT DebugObject; + NTSTATUS Status; + PAGED_CODE(); + + /* If there's no debug port, just exit */ + if (!Process->DebugPort) return STATUS_PORT_NOT_SET; + + /* Otherwise, acquire the lock while we grab the port */ + ExAcquireFastMutex(&DbgkpProcessDebugPortMutex); + + /* Grab it and reference it if it exists */ + DebugObject = Process->DebugPort; + if (DebugObject) ObReferenceObject(DebugObject); + + /* Release the lock now */ + ExReleaseFastMutex(&DbgkpProcessDebugPortMutex); + + /* Bail out if it doesn't exist */ + if (!DebugObject) return STATUS_PORT_NOT_SET; + + /* Now get a handle to it */ + Status = ObOpenObjectByPointer(DebugObject, + 0, + NULL, + MAXIMUM_ALLOWED, + DbgkDebugObjectType, + PreviousMode, + DebugHandle); + if (!NT_SUCCESS(Status)) ObDereferenceObject(DebugObject); + + /* Return status */ + return Status; +} + /* PUBLIC FUNCTIONS **********************************************************/
/*
Modified: trunk/reactos/ntoskrnl/include/internal/dbgk.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/d... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/dbgk.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/dbgk.h [iso-8859-1] Mon Feb 20 06:42:02 2012 @@ -134,6 +134,14 @@ IN PDEBUG_OBJECT SourceDebugObject );
+NTSTATUS +NTAPI +DbgkOpenProcessDebugPort( + IN PEPROCESS Process, + IN KPROCESSOR_MODE PreviousMode, + OUT HANDLE *DebugHandle +); + extern ULONG DbgkpTraceLevel; extern POBJECT_TYPE DbgkDebugObjectType;
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/m... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/mm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/mm.h [iso-8859-1] Mon Feb 20 06:42:02 2012 @@ -1507,6 +1507,10 @@ NTAPI MmSetExecuteOptions(IN ULONG ExecuteOptions);
+NTSTATUS +NTAPI +MmGetExecuteOptions(IN PULONG ExecuteOptions); + VOID NTAPI MmDeleteProcessPageDirectory(struct _EPROCESS *Process);
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Mon Feb 20 06:42:02 2012 @@ -1096,9 +1096,50 @@
NTSTATUS NTAPI +MmGetExecuteOptions(IN PULONG ExecuteOptions) +{ + PKPROCESS CurrentProcess = &PsGetCurrentProcess()->Pcb; + ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); + + *ExecuteOptions = 0; + + if (CurrentProcess->Flags.ExecuteDisable) + { + *ExecuteOptions |= MEM_EXECUTE_OPTION_DISABLE; + } + + if (CurrentProcess->Flags.ExecuteEnable) + { + *ExecuteOptions |= MEM_EXECUTE_OPTION_ENABLE; + } + + if (CurrentProcess->Flags.DisableThunkEmulation) + { + *ExecuteOptions |= MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION; + } + + if (CurrentProcess->Flags.Permanent) + { + *ExecuteOptions |= MEM_EXECUTE_OPTION_PERMANENT; + } + + if (CurrentProcess->Flags.ExecuteDispatchEnable) + { + *ExecuteOptions |= MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE; + } + + if (CurrentProcess->Flags.ImageDispatchEnable) + { + *ExecuteOptions |= MEM_EXECUTE_OPTION_IMAGE_DISPATCH_ENABLE; + } + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI MmSetExecuteOptions(IN ULONG ExecuteOptions) { - PKPROCESS CurrentProcess = &PsGetCurrentProcess()->Pcb; KLOCK_QUEUE_HANDLE ProcessLock; NTSTATUS Status = STATUS_ACCESS_DENIED;
Modified: trunk/reactos/ntoskrnl/ps/query.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/query.c?rev=557... ============================================================================== --- trunk/reactos/ntoskrnl/ps/query.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ps/query.c [iso-8859-1] Mon Feb 20 06:42:02 2012 @@ -69,6 +69,7 @@ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); NTSTATUS Status; ULONG Length = 0; + HANDLE DebugPort = 0; PPROCESS_BASIC_INFORMATION ProcessBasicInfo = (PPROCESS_BASIC_INFORMATION)ProcessInformation; PKERNEL_USER_TIMES ProcessTime = (PKERNEL_USER_TIMES)ProcessInformation; @@ -81,7 +82,8 @@ PQUOTA_LIMITS QuotaLimits = (PQUOTA_LIMITS)ProcessInformation; PROCESS_DEVICEMAP_INFORMATION DeviceMap; PUNICODE_STRING ImageName; - ULONG Cookie; + ULONG Cookie, ExecuteOptions = 0; + ULONG_PTR Wow64 = 0; PAGED_CODE();
/* Check for user-mode caller */ @@ -443,9 +445,6 @@ break; }
- /* Set the return length */ - Length = ProcessInformationLength; - /* Reference the process */ Status = ObReferenceObjectByHandle(ProcessHandle, PROCESS_QUERY_INFORMATION, @@ -471,6 +470,10 @@ VmCounters->PagefileUsage = Process->QuotaUsage[2] << PAGE_SHIFT; VmCounters->PeakPagefileUsage = Process->QuotaPeak[2] << PAGE_SHIFT; //VmCounters->PrivateUsage = Process->CommitCharge << PAGE_SHIFT; + // + + /* Set the return length */ + Length = ProcessInformationLength; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -825,8 +828,42 @@ break;
case ProcessDebugObjectHandle: - DPRINT1("Debug Object Query Not implemented: %lx\n", ProcessInformationClass); - Status = STATUS_NOT_IMPLEMENTED; + + /* Set the return length */ + Length = sizeof(HANDLE); + if (ProcessInformationLength != Length) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + /* Reference the process */ + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_QUERY_INFORMATION, + PsProcessType, + PreviousMode, + (PVOID*)&Process, + NULL); + if (!NT_SUCCESS(Status)) break; + + /* Get the debug port */ + Status = DbgkOpenProcessDebugPort(Process, PreviousMode, &DebugPort); + + /* Let go of the process */ + ObDereferenceObject(Process); + + /* Protect write in SEH */ + _SEH2_TRY + { + /* Return the count of handles */ + *(PHANDLE)ProcessInformation = DebugPort; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; break;
case ProcessHandleTracing: @@ -835,6 +872,7 @@ break;
case ProcessLUIDDeviceMapsEnabled: + /* Set the return length */ Length = sizeof(ULONG); if (ProcessInformationLength != Length) @@ -860,15 +898,118 @@ _SEH2_END; break;
+ case ProcessWx86Information: + + /* 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 if the flag is set */ + *(PULONG)ProcessInformation = (ULONG)Process->VdmAllowed; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + break; + + case ProcessWow64Information: + + /* Set return length */ + Length = sizeof(ULONG_PTR); + if (ProcessInformationLength != Length) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + /* Reference the process */ + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_QUERY_INFORMATION, + PsProcessType, + PreviousMode, + (PVOID*)&Process, + NULL); + if (!NT_SUCCESS(Status)) break; + + /* Make sure the process isn't dying */ + if (ExAcquireRundownProtection(&Process->RundownProtect)) + { + /* Get the WOW64 process structure */ +#ifdef _WIN64 + Wow64 = Process->Wow64Process; +#else + Wow64 = 0; +#endif + /* Release the lock */ + ExReleaseRundownProtection(&Process->RundownProtect); + } + + /* Protect write with SEH */ + _SEH2_TRY + { + /* Return whether or not we have a debug port */ + *(PULONG_PTR)ProcessInformation = Wow64; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + /* Dereference the process */ + ObDereferenceObject(Process); + break; + case ProcessExecuteFlags: - DPRINT1("No execute Not implemented: %lx\n", ProcessInformationClass); - Status = STATUS_NOT_IMPLEMENTED; - break; - - case ProcessWow64Information: + + /* Set return length */ + Length = sizeof(ULONG); + if (ProcessInformationLength != Length) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + if (ProcessHandle != NtCurrentProcess()) + { + return STATUS_INVALID_PARAMETER; + } + + /* Get the options */ + Status = MmGetExecuteOptions(&ExecuteOptions); + if (NT_SUCCESS(Status)) + { + /* Protect write with SEH */ + _SEH2_TRY + { + /* Return them */ + *(PULONG)ProcessInformation = ExecuteOptions; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + break; + case ProcessLdtInformation: - case ProcessWx86Information: - DPRINT1("VDM/16-bit implemented: %lx\n", ProcessInformationClass); + DPRINT1("VDM/16-bit not implemented: %lx\n", ProcessInformationClass); Status = STATUS_NOT_IMPLEMENTED; break;
@@ -892,7 +1033,7 @@ _SEH2_TRY { /* Check if caller wanted return length */ - if (ReturnLength) *ReturnLength = Length; + if ((ReturnLength) && (Length)) *ReturnLength = Length; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -928,7 +1069,7 @@ KAFFINITY ValidAffinity, Affinity = 0; ULONG DefaultHardErrorMode = 0, BasePriority = 0, MemoryPriority = 0; ULONG DisableBoost = 0, DebugFlags = 0, EnableFixup = 0, Boost = 0; - ULONG NoExecute = 0; + ULONG NoExecute = 0, VdmPower = 0; BOOLEAN HasPrivilege; PLIST_ENTRY Next; PETHREAD Thread; @@ -970,6 +1111,49 @@ /* Check what kind of information class this is */ switch (ProcessInformationClass) { + case ProcessWx86Information: + + /* Check buffer length */ + if (ProcessInformationLength != sizeof(HANDLE)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + /* Use SEH for capture */ + _SEH2_TRY + { + /* Capture the boolean */ + VdmPower = *(PULONG)ProcessInformation; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); + } + _SEH2_END; + + /* Getting VDM powers requires the SeTcbPrivilege */ + if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) + { + /* Bail out */ + Status = STATUS_PRIVILEGE_NOT_HELD; + DPRINT1("Need TCB privilege\n"); + break; + } + + /* Set or clear the flag */ + if (VdmPower) + { + PspSetProcessFlag(Process, PSF_VDM_ALLOWED_BIT); + } + else + { + PspClearProcessFlag(Process, PSF_VDM_ALLOWED_BIT); + } + break; + /* Error/Exception Port */ case ProcessExceptionPort:
@@ -1670,7 +1854,6 @@ case ProcessLdtInformation: case ProcessLdtSize: case ProcessIoPortHandlers: - case ProcessWx86Information: DPRINT1("VDM/16-bit Request not implemented: %lx\n", ProcessInformationClass); Status = STATUS_NOT_IMPLEMENTED; break;