use tags for pool allocations, and reformat code

svn path=/trunk/; revision=14547
This commit is contained in:
Royce Mitchell III 2005-04-08 13:14:15 +00:00
parent 18cff7ccc9
commit 601ea5384b

View file

@ -1,10 +1,10 @@
/* $Id$ /* $Id$
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/job.c * FILE: ntoskrnl/ps/job.c
* PURPOSE: Job Native Functions * PURPOSE: Job Native Functions
* *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) (stubs) * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) (stubs)
* Thomas Weidenmueller <w3seek@reactos.com> * Thomas Weidenmueller <w3seek@reactos.com>
*/ */
@ -17,281 +17,293 @@
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
#define TAG_EJOB TAG('E', 'J', 'O', 'B') /* EJOB */
POBJECT_TYPE EXPORTED PsJobType = NULL; POBJECT_TYPE EXPORTED PsJobType = NULL;
LIST_ENTRY PsJobListHead; LIST_ENTRY PsJobListHead;
static FAST_MUTEX PsJobListLock; static FAST_MUTEX PsJobListLock;
static GENERIC_MAPPING PiJobMapping = {STANDARD_RIGHTS_READ | JOB_OBJECT_QUERY, static GENERIC_MAPPING PiJobMapping =
STANDARD_RIGHTS_WRITE | JOB_OBJECT_ASSIGN_PROCESS | JOB_OBJECT_SET_ATTRIBUTES | JOB_OBJECT_TERMINATE | JOB_OBJECT_SET_SECURITY_ATTRIBUTES, {
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, STANDARD_RIGHTS_READ | JOB_OBJECT_QUERY,
STANDARD_RIGHTS_ALL | JOB_OBJECT_ALL_ACCESS}; STANDARD_RIGHTS_WRITE | JOB_OBJECT_ASSIGN_PROCESS | JOB_OBJECT_SET_ATTRIBUTES | JOB_OBJECT_TERMINATE | JOB_OBJECT_SET_SECURITY_ATTRIBUTES,
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
STANDARD_RIGHTS_ALL | JOB_OBJECT_ALL_ACCESS
};
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
VOID STDCALL VOID STDCALL
PiDeleteJob(PVOID ObjectBody) PiDeleteJob ( PVOID ObjectBody )
{ {
PEJOB Job = (PEJOB)ObjectBody; PEJOB Job = (PEJOB)ObjectBody;
/* remove the reference to the completion port if associated */
if(Job->CompletionPort != NULL)
{
ObDereferenceObject(Job->CompletionPort);
}
/* unlink the job object */ /* remove the reference to the completion port if associated */
if(Job->JobLinks.Flink != NULL) if(Job->CompletionPort != NULL)
{ {
ExAcquireFastMutex(&PsJobListLock); ObDereferenceObject(Job->CompletionPort);
RemoveEntryList(&Job->JobLinks); }
ExReleaseFastMutex(&PsJobListLock);
} /* unlink the job object */
if(Job->JobLinks.Flink != NULL)
ExDeleteResource(&Job->JobLock); {
ExAcquireFastMutex(&PsJobListLock);
RemoveEntryList(&Job->JobLinks);
ExReleaseFastMutex(&PsJobListLock);
}
ExDeleteResource(&Job->JobLock);
} }
VOID INIT_FUNCTION VOID INIT_FUNCTION
PsInitJobManagment(VOID) PsInitJobManagment ( VOID )
{ {
PsJobType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); PsJobType = ExAllocatePoolWithTag (
NonPagedPool, sizeof(OBJECT_TYPE), TAG_EJOB );
PsJobType->Tag = TAG('E', 'J', 'O', 'B'); PsJobType->Tag = TAG_EJOB;
PsJobType->TotalObjects = 0; PsJobType->TotalObjects = 0;
PsJobType->TotalHandles = 0; PsJobType->TotalHandles = 0;
PsJobType->PeakObjects = 0; PsJobType->PeakObjects = 0;
PsJobType->PeakHandles = 0; PsJobType->PeakHandles = 0;
PsJobType->PagedPoolCharge = 0; PsJobType->PagedPoolCharge = 0;
PsJobType->NonpagedPoolCharge = sizeof(EJOB); PsJobType->NonpagedPoolCharge = sizeof(EJOB);
PsJobType->Mapping = &PiJobMapping; PsJobType->Mapping = &PiJobMapping;
PsJobType->Dump = NULL; PsJobType->Dump = NULL;
PsJobType->Open = NULL; PsJobType->Open = NULL;
PsJobType->Close = NULL; PsJobType->Close = NULL;
PsJobType->Delete = PiDeleteJob; PsJobType->Delete = PiDeleteJob;
PsJobType->Parse = NULL; PsJobType->Parse = NULL;
PsJobType->Security = NULL; PsJobType->Security = NULL;
PsJobType->QueryName = NULL; PsJobType->QueryName = NULL;
PsJobType->OkayToClose = NULL; PsJobType->OkayToClose = NULL;
PsJobType->Create = NULL; PsJobType->Create = NULL;
PsJobType->DuplicationNotify = NULL; PsJobType->DuplicationNotify = NULL;
RtlInitUnicodeString(&PsJobType->TypeName, L"Job"); RtlInitUnicodeString(&PsJobType->TypeName, L"Job");
ObpCreateTypeObject(PsJobType); ObpCreateTypeObject(PsJobType);
InitializeListHead(&PsJobListHead); InitializeListHead(&PsJobListHead);
ExInitializeFastMutex(&PsJobListLock); ExInitializeFastMutex(&PsJobListLock);
} }
NTSTATUS NTSTATUS
PspAssignProcessToJob(PEPROCESS Process, PspAssignProcessToJob (
PEJOB Job) PEPROCESS Process,
PEJOB Job)
{ {
DPRINT("PspAssignProcessToJob() is unimplemented!\n"); DPRINT("PspAssignProcessToJob() is unimplemented!\n");
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
} }
NTSTATUS NTSTATUS
PspTerminateJobObject(PEJOB Job, PspTerminateJobObject (
KPROCESSOR_MODE AccessMode, PEJOB Job,
NTSTATUS ExitStatus) KPROCESSOR_MODE AccessMode,
NTSTATUS ExitStatus )
{ {
DPRINT("PspTerminateJobObject() is unimplemented!\n"); DPRINT("PspTerminateJobObject() is unimplemented!\n");
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
} }
/* /*
* @unimplemented * @unimplemented
*/ */
NTSTATUS NTSTATUS
STDCALL STDCALL
NtAssignProcessToJobObject(HANDLE JobHandle, NtAssignProcessToJobObject (
HANDLE ProcessHandle) HANDLE JobHandle,
HANDLE ProcessHandle)
{ {
PEPROCESS Process; PEPROCESS Process;
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode;
NTSTATUS Status; NTSTATUS Status;
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
/* make sure we're having a handle with enough rights, especially the to
terminate the process. otherwise one could abuse the job objects to
terminate processes without having rights granted to do so! The reason
I open the process handle before the job handle is that a simple test showed
that it first complains about a invalid process handle! The other way around
would be simpler though... */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_TERMINATE,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if(NT_SUCCESS(Status))
{
if(Process->Job == NULL)
{
PEJOB Job;
Status = ObReferenceObjectByHandle(JobHandle,
JOB_OBJECT_ASSIGN_PROCESS,
PsJobType,
PreviousMode,
(PVOID*)&Job,
NULL);
if(NT_SUCCESS(Status))
{
/* lock the process so we can safely assign the process. Note that in the
meanwhile another thread could have assigned this process to a job! */
Status = PsLockProcess(Process, FALSE); PAGED_CODE();
if(NT_SUCCESS(Status))
PreviousMode = ExGetPreviousMode();
/* make sure we're having a handle with enough rights, especially the to
terminate the process. otherwise one could abuse the job objects to
terminate processes without having rights granted to do so! The reason
I open the process handle before the job handle is that a simple test showed
that it first complains about a invalid process handle! The other way around
would be simpler though... */
Status = ObReferenceObjectByHandle(
ProcessHandle,
PROCESS_TERMINATE,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if(NT_SUCCESS(Status))
{
if(Process->Job == NULL)
{
PEJOB Job;
Status = ObReferenceObjectByHandle(
JobHandle,
JOB_OBJECT_ASSIGN_PROCESS,
PsJobType,
PreviousMode,
(PVOID*)&Job,
NULL);
if(NT_SUCCESS(Status))
{
/* lock the process so we can safely assign the process. Note that in the
meanwhile another thread could have assigned this process to a job! */
Status = PsLockProcess(Process, FALSE);
if(NT_SUCCESS(Status))
{
if(Process->Job == NULL && Process->SessionId == Job->SessionId)
{
/* Just store the pointer to the job object in the process, we'll
assign it later. The reason we can't do this here is that locking
the job object might require it to wait, which is a bad thing
while holding the process lock! */
Process->Job = Job;
}
else
{
/* process is already assigned to a job or session id differs! */
Status = STATUS_ACCESS_DENIED;
}
PsUnlockProcess(Process);
if(NT_SUCCESS(Status))
{
/* let's actually assign the process to the job as we're not holding
the process lock anymore! */
Status = PspAssignProcessToJob(Process, Job);
}
}
ObDereferenceObject(Job);
}
}
else
{ {
if(Process->Job == NULL && Process->SessionId == Job->SessionId)
{
/* Just store the pointer to the job object in the process, we'll
assign it later. The reason we can't do this here is that locking
the job object might require it to wait, which is a bad thing
while holding the process lock! */
Process->Job = Job;
}
else
{
/* process is already assigned to a job or session id differs! */ /* process is already assigned to a job or session id differs! */
Status = STATUS_ACCESS_DENIED; Status = STATUS_ACCESS_DENIED;
}
PsUnlockProcess(Process);
if(NT_SUCCESS(Status))
{
/* let's actually assign the process to the job as we're not holding
the process lock anymore! */
Status = PspAssignProcessToJob(Process, Job);
}
} }
ObDereferenceObject(Job); ObDereferenceObject(Process);
}
} }
else
{
/* process is already assigned to a job or session id differs! */
Status = STATUS_ACCESS_DENIED;
}
ObDereferenceObject(Process);
}
return Status; return Status;
} }
/* /*
* @unimplemented * @unimplemented
*/ */
NTSTATUS NTSTATUS
STDCALL STDCALL
NtCreateJobObject(PHANDLE JobHandle, NtCreateJobObject (
ACCESS_MASK DesiredAccess, PHANDLE JobHandle,
POBJECT_ATTRIBUTES ObjectAttributes) ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes )
{ {
HANDLE hJob; HANDLE hJob;
PEJOB Job; PEJOB Job;
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode;
PEPROCESS CurrentProcess; PEPROCESS CurrentProcess;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
PreviousMode = ExGetPreviousMode(); PAGED_CODE();
CurrentProcess = PsGetCurrentProcess();
/* check for valid buffers */ PreviousMode = ExGetPreviousMode();
if(PreviousMode == UserMode) CurrentProcess = PsGetCurrentProcess();
{
_SEH_TRY
{
/* probe with 32bit alignment */
ProbeForWrite(JobHandle,
sizeof(HANDLE),
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status)) /* check for valid buffers */
if(PreviousMode == UserMode)
{ {
return Status; _SEH_TRY
{
/* probe with 32bit alignment */
ProbeForWrite(JobHandle,
sizeof(HANDLE),
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
return Status;
}
} }
}
Status = ObCreateObject(PreviousMode,
Status = ObCreateObject(PreviousMode, PsJobType,
PsJobType, ObjectAttributes,
ObjectAttributes, PreviousMode,
PreviousMode, NULL,
NULL, sizeof(EJOB),
sizeof(EJOB), 0,
0, 0,
0, (PVOID*)&Job);
(PVOID*)&Job);
if(NT_SUCCESS(Status))
{
/* FIXME - Zero all fields as we don't yet implement all of them */
RtlZeroMemory(Job, sizeof(EJOB));
/* make sure that early destruction doesn't attempt to remove the object from
the list before it even gets added! */
Job->JobLinks.Flink = NULL;
/* setup the job object */
InitializeListHead(&Job->ProcessListHead);
Job->SessionId = CurrentProcess->SessionId; /* inherit the session id from the caller */
Status = ExInitializeResource(&Job->JobLock);
if(!NT_SUCCESS(Status))
{
DPRINT1("Failed to initialize job lock!!!\n");
ObDereferenceObject(Job);
return Status;
}
KeInitializeEvent(&Job->Event, NotificationEvent, FALSE);
/* link the object into the global job list */
ExAcquireFastMutex(&PsJobListLock);
InsertTailList(&PsJobListHead, &Job->JobLinks);
ExReleaseFastMutex(&PsJobListLock);
Status = ObInsertObject(Job,
NULL,
DesiredAccess,
0,
NULL,
&hJob);
if(NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{ {
/* pass the handle back to the caller */ /* FIXME - Zero all fields as we don't yet implement all of them */
_SEH_TRY RtlZeroMemory(Job, sizeof(EJOB));
{
/* NOTE: if the caller passed invalid buffers to receive the handle it's his /* make sure that early destruction doesn't attempt to remove the object from
own fault! the object will still be created and live... It's possible the list before it even gets added! */
to find the handle using ObFindHandleForObject()! */ Job->JobLinks.Flink = NULL;
*JobHandle = hJob;
} /* setup the job object */
_SEH_HANDLE InitializeListHead(&Job->ProcessListHead);
{ Job->SessionId = CurrentProcess->SessionId; /* inherit the session id from the caller */
Status = _SEH_GetExceptionCode();
} Status = ExInitializeResource(&Job->JobLock);
_SEH_END; if(!NT_SUCCESS(Status))
{
DPRINT1("Failed to initialize job lock!!!\n");
ObDereferenceObject(Job);
return Status;
}
KeInitializeEvent(&Job->Event, NotificationEvent, FALSE);
/* link the object into the global job list */
ExAcquireFastMutex(&PsJobListLock);
InsertTailList(&PsJobListHead, &Job->JobLinks);
ExReleaseFastMutex(&PsJobListLock);
Status = ObInsertObject(Job,
NULL,
DesiredAccess,
0,
NULL,
&hJob);
if(NT_SUCCESS(Status))
{
/* pass the handle back to the caller */
_SEH_TRY
{
/* NOTE: if the caller passed invalid buffers to receive the handle it's his
own fault! the object will still be created and live... It's possible
to find the handle using ObFindHandleForObject()! */
*JobHandle = hJob;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
} }
}
return Status;
return Status;
} }
@ -300,207 +312,203 @@ NtCreateJobObject(PHANDLE JobHandle,
*/ */
NTSTATUS NTSTATUS
STDCALL STDCALL
NtIsProcessInJob(IN HANDLE ProcessHandle, NtIsProcessInJob (
IN HANDLE JobHandle OPTIONAL) IN HANDLE ProcessHandle,
IN HANDLE JobHandle OPTIONAL )
{ {
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode;
PEPROCESS Process; PEPROCESS Process;
NTSTATUS Status; NTSTATUS Status;
PreviousMode = ExGetPreviousMode();
PAGED_CODE();
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if(NT_SUCCESS(Status))
{
/* FIXME - make sure the job object doesn't get exchanged or deleted while trying to
reference it, e.g. by locking it somehow until it is referenced... */
PEJOB ProcessJob = Process->Job; PreviousMode = ExGetPreviousMode();
if(ProcessJob != NULL)
{
if(JobHandle == NULL)
{
/* the process is assigned to a job */
Status = STATUS_PROCESS_IN_JOB;
}
else /* JobHandle != NULL */
{
PEJOB JobObject;
/* get the job object and compare the object pointer with the one assigned to the process */ PAGED_CODE();
Status = ObReferenceObjectByHandle(JobHandle,
JOB_OBJECT_QUERY,
PsJobType,
PreviousMode,
(PVOID*)&JobObject,
NULL);
if(NT_SUCCESS(Status))
{
Status = ((ProcessJob == JobObject) ? STATUS_PROCESS_IN_JOB : STATUS_PROCESS_NOT_IN_JOB);
ObDereferenceObject(JobObject);
}
}
}
else
{
/* the process is not assigned to any job */
Status = STATUS_PROCESS_NOT_IN_JOB;
}
ObDereferenceObject(Process);
}
return Status; Status = ObReferenceObjectByHandle(
} ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
/* PreviousMode,
* @implemented (PVOID*)&Process,
*/ NULL);
NTSTATUS
STDCALL
NtOpenJobObject(PHANDLE JobHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes)
{
KPROCESSOR_MODE PreviousMode;
HANDLE hJob;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
/* check for valid buffers */
if(PreviousMode == UserMode)
{
_SEH_TRY
{
/* probe with 32bit alignment */
ProbeForWrite(JobHandle,
sizeof(HANDLE),
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
return Status;
}
}
if(NT_SUCCESS(Status))
{
Status = ObOpenObjectByName(ObjectAttributes,
PsJobType,
NULL,
PreviousMode,
DesiredAccess,
NULL,
&hJob);
if(NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{ {
_SEH_TRY /* FIXME - make sure the job object doesn't get exchanged or deleted while trying to
{ reference it, e.g. by locking it somehow until it is referenced... */
*JobHandle = hJob;
} PEJOB ProcessJob = Process->Job;
_SEH_HANDLE
{ if(ProcessJob != NULL)
Status = _SEH_GetExceptionCode(); {
} if(JobHandle == NULL)
_SEH_END; {
/* the process is assigned to a job */
Status = STATUS_PROCESS_IN_JOB;
}
else /* JobHandle != NULL */
{
PEJOB JobObject;
/* get the job object and compare the object pointer with the one assigned to the process */
Status = ObReferenceObjectByHandle(JobHandle,
JOB_OBJECT_QUERY,
PsJobType,
PreviousMode,
(PVOID*)&JobObject,
NULL);
if(NT_SUCCESS(Status))
{
Status = ((ProcessJob == JobObject) ? STATUS_PROCESS_IN_JOB : STATUS_PROCESS_NOT_IN_JOB);
ObDereferenceObject(JobObject);
}
}
}
else
{
/* the process is not assigned to any job */
Status = STATUS_PROCESS_NOT_IN_JOB;
}
ObDereferenceObject(Process);
} }
}
return Status;
}
return Status;
/*
* @unimplemented
*/
NTSTATUS
STDCALL
NtQueryInformationJobObject(HANDLE JobHandle,
JOBOBJECTINFOCLASS JobInformationClass,
PVOID JobInformation,
ULONG JobInformationLength,
PULONG ReturnLength)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
* @unimplemented
*/
NTSTATUS
STDCALL
NtSetInformationJobObject(HANDLE JobHandle,
JOBOBJECTINFOCLASS JobInformationClass,
PVOID JobInformation,
ULONG JobInformationLength)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
* @unimplemented
*/
NTSTATUS
STDCALL
NtTerminateJobObject(HANDLE JobHandle,
NTSTATUS ExitStatus)
{
KPROCESSOR_MODE PreviousMode;
PEJOB Job;
NTSTATUS Status;
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(JobHandle,
JOB_OBJECT_TERMINATE,
PsJobType,
PreviousMode,
(PVOID*)&Job,
NULL);
if(NT_SUCCESS(Status))
{
Status = PspTerminateJobObject(Job,
PreviousMode,
ExitStatus);
ObDereferenceObject(Job);
}
return Status;
} }
/* /*
* @implemented * @implemented
*/ */
PVOID NTSTATUS
STDCALL STDCALL
PsGetJobLock(PEJOB Job) NtOpenJobObject (
PHANDLE JobHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes)
{ {
ASSERT(Job); KPROCESSOR_MODE PreviousMode;
return (PVOID)&Job->JobLock; HANDLE hJob;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
/* check for valid buffers */
if(PreviousMode == UserMode)
{
_SEH_TRY
{
/* probe with 32bit alignment */
ProbeForWrite(JobHandle,
sizeof(HANDLE),
sizeof(ULONG));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
return Status;
}
}
if(NT_SUCCESS(Status))
{
Status = ObOpenObjectByName(ObjectAttributes,
PsJobType,
NULL,
PreviousMode,
DesiredAccess,
NULL,
&hJob);
if(NT_SUCCESS(Status))
{
_SEH_TRY
{
*JobHandle = hJob;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
}
return Status;
}
/*
* @unimplemented
*/
NTSTATUS
STDCALL
NtQueryInformationJobObject (
HANDLE JobHandle,
JOBOBJECTINFOCLASS JobInformationClass,
PVOID JobInformation,
ULONG JobInformationLength,
PULONG ReturnLength )
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
* @unimplemented
*/
NTSTATUS
STDCALL
NtSetInformationJobObject (
HANDLE JobHandle,
JOBOBJECTINFOCLASS JobInformationClass,
PVOID JobInformation,
ULONG JobInformationLength)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
* @unimplemented
*/
NTSTATUS
STDCALL
NtTerminateJobObject (
HANDLE JobHandle,
NTSTATUS ExitStatus )
{
KPROCESSOR_MODE PreviousMode;
PEJOB Job;
NTSTATUS Status;
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(
JobHandle,
JOB_OBJECT_TERMINATE,
PsJobType,
PreviousMode,
(PVOID*)&Job,
NULL);
if(NT_SUCCESS(Status))
{
Status = PspTerminateJobObject(
Job,
PreviousMode,
ExitStatus);
ObDereferenceObject(Job);
}
return Status;
} }
@ -509,10 +517,22 @@ PsGetJobLock(PEJOB Job)
*/ */
PVOID PVOID
STDCALL STDCALL
PsGetJobSessionId(PEJOB Job) PsGetJobLock ( PEJOB Job )
{ {
ASSERT(Job); ASSERT(Job);
return (PVOID)Job->SessionId; return (PVOID)&Job->JobLock;
}
/*
* @implemented
*/
PVOID
STDCALL
PsGetJobSessionId ( PEJOB Job )
{
ASSERT(Job);
return (PVOID)Job->SessionId;
} }
@ -521,10 +541,10 @@ PsGetJobSessionId(PEJOB Job)
*/ */
ULONG ULONG
STDCALL STDCALL
PsGetJobUIRestrictionsClass(PEJOB Job) PsGetJobUIRestrictionsClass ( PEJOB Job )
{ {
ASSERT(Job); ASSERT(Job);
return Job->UIRestrictionsClass; return Job->UIRestrictionsClass;
} }
@ -533,12 +553,13 @@ PsGetJobUIRestrictionsClass(PEJOB Job)
*/ */
VOID VOID
STDCALL STDCALL
PsSetJobUIRestrictionsClass(PEJOB Job, PsSetJobUIRestrictionsClass (
ULONG UIRestrictionsClass) PEJOB Job,
ULONG UIRestrictionsClass)
{ {
ASSERT(Job); ASSERT(Job);
InterlockedExchangeUL(&Job->UIRestrictionsClass, UIRestrictionsClass); InterlockedExchangeUL(&Job->UIRestrictionsClass, UIRestrictionsClass);
/* FIXME - walk through the job process list and update the restrictions? */ /* FIXME - walk through the job process list and update the restrictions? */
} }
/* EOF */ /* EOF */