mirror of
https://github.com/reactos/reactos.git
synced 2025-06-10 12:24:48 +00:00
[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. svn path=/trunk/; revision=55734
This commit is contained in:
parent
62930b0461
commit
1e172203a6
5 changed files with 291 additions and 15 deletions
|
@ -1504,6 +1504,46 @@ DbgkInitialize(VOID)
|
|||
&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 **********************************************************/
|
||||
|
||||
/*
|
||||
|
|
|
@ -134,6 +134,14 @@ DbgkClearProcessDebugObject(
|
|||
IN PDEBUG_OBJECT SourceDebugObject
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DbgkOpenProcessDebugPort(
|
||||
IN PEPROCESS Process,
|
||||
IN KPROCESSOR_MODE PreviousMode,
|
||||
OUT HANDLE *DebugHandle
|
||||
);
|
||||
|
||||
extern ULONG DbgkpTraceLevel;
|
||||
extern POBJECT_TYPE DbgkDebugObjectType;
|
||||
|
||||
|
|
|
@ -1507,6 +1507,10 @@ NTSTATUS
|
|||
NTAPI
|
||||
MmSetExecuteOptions(IN ULONG ExecuteOptions);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmGetExecuteOptions(IN PULONG ExecuteOptions);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmDeleteProcessPageDirectory(struct _EPROCESS *Process);
|
||||
|
|
|
@ -1094,11 +1094,52 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
|
|||
return Status;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -69,6 +69,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
|||
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 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
|||
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 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
|||
break;
|
||||
}
|
||||
|
||||
/* Set the return length */
|
||||
Length = ProcessInformationLength;
|
||||
|
||||
/* Reference the process */
|
||||
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||
PROCESS_QUERY_INFORMATION,
|
||||
|
@ -471,6 +470,10 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
|||
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 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
|||
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 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
|||
break;
|
||||
|
||||
case ProcessLUIDDeviceMapsEnabled:
|
||||
|
||||
/* Set the return length */
|
||||
Length = sizeof(ULONG);
|
||||
if (ProcessInformationLength != Length)
|
||||
|
@ -860,15 +898,118 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
|||
_SEH2_END;
|
||||
break;
|
||||
|
||||
case ProcessExecuteFlags:
|
||||
DPRINT1("No execute Not implemented: %lx\n", ProcessInformationClass);
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
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:
|
||||
|
||||
/* 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 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
|||
_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 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
|
|||
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 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
|
|||
/* 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 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
|
|||
case ProcessLdtInformation:
|
||||
case ProcessLdtSize:
|
||||
case ProcessIoPortHandlers:
|
||||
case ProcessWx86Information:
|
||||
DPRINT1("VDM/16-bit Request not implemented: %lx\n", ProcessInformationClass);
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue