/* FIXME: From winbase.h... what to do? */
#define SEM_NOALIGNMENTFAULTEXCEPT 0x04
-/* Include Information Class Tables */
-#include "internal/ps_i.h"
-
/* Debugging Level */
ULONG PspTraceLevel = 0;
_SEH2_END;
}
- if((ProcessInformationClass == ProcessCookie) &&
+ if (((ProcessInformationClass == ProcessCookie) ||
+ (ProcessInformationClass == ProcessImageInformation)) &&
(ProcessHandle != NtCurrentProcess()))
{
/*
ProcessBasicInfo->UniqueProcessId = (ULONG_PTR)Process->
UniqueProcessId;
ProcessBasicInfo->InheritedFromUniqueProcessId =
- (ULONG)Process->InheritedFromUniqueProcessId;
+ (ULONG_PTR)Process->InheritedFromUniqueProcessId;
ProcessBasicInfo->BasePriority = Process->Pcb.BasePriority;
}
_SEH2_TRY
{
/* Write back the Session ID */
- SessionInfo->SessionId = PtrToUlong(PsGetProcessSessionId(Process));
+ SessionInfo->SessionId = PsGetProcessSessionId(Process);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
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;
}
}
/* Free the image path */
- ExFreePool(ImageName);
+ ExFreePoolWithTag(ImageName, TAG_SEPA);
}
/* Dereference the process */
ObDereferenceObject(Process);
break;
case ProcessImageInformation:
- DPRINT1("Image Information Query Not implemented: %lx\n", ProcessInformationClass);
- Status = STATUS_NOT_IMPLEMENTED;
+
+ /* Set the length required and validate it */
+ Length = sizeof(SECTION_IMAGE_INFORMATION);
+ if (ProcessInformationLength != Length)
+ {
+ /* Break out */
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ /* Enter SEH to protect write */
+ _SEH2_TRY
+ {
+ MmGetImageInformation((PSECTION_IMAGE_INFORMATION)ProcessInformation);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Get the exception code */
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ /* Indicate success */
+ Status = STATUS_SUCCESS;
break;
case ProcessDebugObjectHandle:
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
-
+
/* Indicate success */
Status = STATUS_SUCCESS;
-
+
/* Protect write in SEH */
_SEH2_TRY
{
{
/* Get the WOW64 process structure */
#ifdef _WIN64
- Wow64 = Process->Wow64Process;
+ Wow64 = (ULONG_PTR)Process->Wow64Process;
#else
Wow64 = 0;
#endif
/* Release the lock */
ExReleaseRundownProtection(&Process->RundownProtect);
}
-
+
/* Protect write with SEH */
_SEH2_TRY
{
/* Dereference the process */
ObDereferenceObject(Process);
break;
-
+
case ProcessExecuteFlags:
-
+
/* Set return length */
Length = sizeof(ULONG);
if (ProcessInformationLength != Length)
/* Getting VDM powers requires the SeTcbPrivilege */
if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
{
- /* Bail out */
+ /* We don't hold the privilege, bail out */
Status = STATUS_PRIVILEGE_NOT_HELD;
DPRINT1("Need TCB privilege\n");
break;
/* Setting the error port requires the SeTcbPrivilege */
if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
{
- /* Can't set the session ID, bail out. */
+ /* We don't hold the privilege, bail out */
Status = STATUS_PRIVILEGE_NOT_HELD;
break;
}
/* Setting the session id requires the SeTcbPrivilege */
if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
{
- /* Can't set the session ID, bail out. */
+ /* We don't hold the privilege, bail out */
Status = STATUS_PRIVILEGE_NOT_HELD;
break;
}
+#if 0 // OLD AND DEPRECATED CODE!!!!
+
/* FIXME - update the session id for the process token */
//Status = PsLockProcess(Process, FALSE);
if (!NT_SUCCESS(Status)) break;
/* Write the session ID in the EPROCESS */
- Process->Session = SessionInfo.SessionId;
+ Process->Session = UlongToPtr(SessionInfo.SessionId); // HACK!!!
/* Check if the process also has a PEB */
if (Process->Peb)
/* Unlock the process */
//PsUnlockProcess(Process);
+
+#endif
+
+ /*
+ * Since we cannot change the session ID of the given
+ * process anymore because it is set once and for all
+ * at process creation time and because it is stored
+ * inside the Process->Session structure managed by MM,
+ * we fake changing it: we just return success if the
+ * user-defined value is the same as the session ID of
+ * the process, and otherwise we fail.
+ */
+ if (SessionInfo.SessionId == PsGetProcessSessionId(Process))
+ {
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ Status = STATUS_ACCESS_DENIED;
+ }
+
break;
case ProcessPriorityClass:
/* Setting 'break on termination' requires the SeDebugPrivilege */
if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode))
{
+ /* We don't hold the privilege, bail out */
Status = STATUS_PRIVILEGE_NOT_HELD;
break;
}
KeSetAutoAlignmentProcess(&Process->Pcb, FALSE);
Status = STATUS_SUCCESS;
break;
-
+
case ProcessUserModeIOPL:
/* Only TCB can do this */
- if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
+ if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
{
- /* Fail */
+ /* We don't hold the privilege, bail out */
DPRINT1("Need TCB to set IOPL\n");
Status = STATUS_PRIVILEGE_NOT_HELD;
break;
/* Call Mm for the update */
Status = MmSetExecuteOptions(NoExecute);
break;
-
+
/* We currently don't implement any of these */
case ProcessLdtInformation:
case ProcessLdtSize:
break;
case ProcessQuotaLimits:
- DPRINT1("Quota Limits not implemented\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
+
+ return PspSetQuotaLimits(ProcessHandle,
+ 1,
+ ProcessInformation,
+ ProcessInformationLength,
+ PreviousMode);
case ProcessWorkingSetWatch:
DPRINT1("WS watch not implemented\n");
/* All done */
break;
-
+
case ThreadBreakOnTermination:
/* Check buffer length */
/* Setting 'break on termination' requires the SeDebugPrivilege */
if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode))
{
+ /* We don't hold the privilege, bail out */
Status = STATUS_PRIVILEGE_NOT_HELD;
break;
}
(PTHREAD_BASIC_INFORMATION)ThreadInformation;
PKERNEL_USER_TIMES ThreadTime = (PKERNEL_USER_TIMES)ThreadInformation;
KIRQL OldIrql;
+ ULONG ThreadTerminated;
PAGED_CODE();
/* Check if we were called from user mode */
_SEH2_END;
break;
+ case ThreadIsTerminated:
+
+ /* Set the return length*/
+ Length = sizeof(ThreadTerminated);
+
+ if (ThreadInformationLength != Length)
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ ThreadTerminated = PsIsThreadTerminating(Thread);
+
+ _SEH2_TRY
+ {
+ *(PULONG)ThreadInformation = ThreadTerminated ? 1 : 0;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
+
/* Anything else */
default: