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?re…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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.…
==============================================================================
--- 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=55…
==============================================================================
--- 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;