i think it works
This commit is contained in:
commit
0e1479b168
167 files changed
+27008
No files matched your search
@@ -0,0 +1,143 @@
|
||||
// ke_process.c - process model
|
||||
#include "ke_process.h"
|
||||
#include "ke_thread.h" // KeExitThread (forward declared below)
|
||||
#include "mm_virt.h"
|
||||
#include "ob_object.h"
|
||||
#include <string.h>
|
||||
#include <intrin.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Global process list
|
||||
// ---------------------------------------------------------------------------
|
||||
static LIST_ENTRY gProcessList;
|
||||
static SPINLOCK gProcessListLock;
|
||||
static uint32_t gNextProcessId = 1;
|
||||
|
||||
static void ProcessInit(void) {
|
||||
static int inited = 0;
|
||||
if (!inited) {
|
||||
LIST_INIT(&gProcessList);
|
||||
gProcessListLock = (SPINLOCK)SPINLOCK_INIT;
|
||||
inited = 1;
|
||||
}
|
||||
}
|
||||
|
||||
LIST_ENTRY* KeGetProcessList(void) {
|
||||
return &gProcessList;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Destructor (called by ObDereferenceObject when RefCount hits zero)
|
||||
// ---------------------------------------------------------------------------
|
||||
static void ProcessDestroy(OBJECT* obj) {
|
||||
PROCESS* proc = CONTAINING_RECORD(obj, PROCESS, Header);
|
||||
|
||||
// Release all remaining handles.
|
||||
for (int i = 1; i < HANDLE_TABLE_SIZE; i++) {
|
||||
if (proc->Handles[i]) {
|
||||
ObDereferenceObject(proc->Handles[i]);
|
||||
proc->Handles[i] = (OBJECT *)0;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove from global list.
|
||||
KeAcquireSpinlock(&gProcessListLock);
|
||||
ListRemove(&proc->GlobalLink);
|
||||
KeReleaseSpinlock(&gProcessListLock);
|
||||
|
||||
// Memory for the struct itself is freed by ObDereferenceObject after
|
||||
// Destroy returns.
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// KeCreateProcess
|
||||
// ---------------------------------------------------------------------------
|
||||
KSTATUS KeCreateProcess(const char* name, PROCESS **out) {
|
||||
ProcessInit();
|
||||
|
||||
if (!name || !out) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
PROCESS* proc = (PROCESS *)ObAllocateObject(ObjectTypeProcess, sizeof(PROCESS));
|
||||
if (!proc) return STATUS_NO_MEMORY;
|
||||
|
||||
proc->Header.Destroy = ProcessDestroy;
|
||||
|
||||
proc->ProcessId = _InterlockedExchangeAdd((volatile long *)&gNextProcessId, 1);
|
||||
strncpy(proc->Name, name, PROCESS_NAME_MAX - 1);
|
||||
proc->Name[PROCESS_NAME_MAX - 1] = '\0';
|
||||
|
||||
LIST_INIT(&proc->ThreadList);
|
||||
proc->ThreadCount = 0;
|
||||
proc->HandleLock = (SPINLOCK)SPINLOCK_INIT;
|
||||
proc->ExitCode = 0;
|
||||
|
||||
// Slot 0 is the invalid handle - leave it NULL.
|
||||
memset(proc->Handles, 0, sizeof(proc->Handles));
|
||||
|
||||
LIST_INIT(&proc->GlobalLink);
|
||||
|
||||
KeAcquireSpinlock(&gProcessListLock);
|
||||
ListInsertTail(&gProcessList, &proc->GlobalLink);
|
||||
KeReleaseSpinlock(&gProcessListLock);
|
||||
|
||||
*out = proc;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// KeExitProcess
|
||||
// ---------------------------------------------------------------------------
|
||||
void KeExitProcess(PROCESS* process, int exitCode) {
|
||||
if (!process) return;
|
||||
process->ExitCode = exitCode;
|
||||
// The last thread exiting via KeExitThread will drop the process refcount.
|
||||
// This function is a policy hook; actual cleanup is in ProcessDestroy.
|
||||
ObDereferenceObject(&process->Header);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Handle table
|
||||
// ---------------------------------------------------------------------------
|
||||
KSTATUS KeAllocateHandle(PROCESS* process, OBJECT* object, uint32_t* handleOut) {
|
||||
if (!process || !object || !handleOut) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
KeAcquireSpinlock(&process->HandleLock);
|
||||
|
||||
for (int i = 1; i < HANDLE_TABLE_SIZE; i++) {
|
||||
if (!process->Handles[i]) {
|
||||
ObReferenceObject(object);
|
||||
process->Handles[i] = object;
|
||||
*handleOut = (uint32_t)i;
|
||||
KeReleaseSpinlock(&process->HandleLock);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
KeReleaseSpinlock(&process->HandleLock);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
void KeCloseHandle(PROCESS* process, uint32_t handle) {
|
||||
if (!process || handle == 0 || handle >= HANDLE_TABLE_SIZE) return;
|
||||
|
||||
KeAcquireSpinlock(&process->HandleLock);
|
||||
OBJECT* obj = process->Handles[handle];
|
||||
if (obj) {
|
||||
process->Handles[handle] = (OBJECT *)0;
|
||||
KeReleaseSpinlock(&process->HandleLock);
|
||||
ObDereferenceObject(obj);
|
||||
return;
|
||||
}
|
||||
KeReleaseSpinlock(&process->HandleLock);
|
||||
}
|
||||
|
||||
OBJECT* KeLookupHandle(PROCESS* process, uint32_t handle) {
|
||||
if (!process || handle == 0 || handle >= HANDLE_TABLE_SIZE)
|
||||
return (OBJECT *)0;
|
||||
|
||||
KeAcquireSpinlock(&process->HandleLock);
|
||||
OBJECT* obj = process->Handles[handle];
|
||||
if (obj) ObReferenceObject(obj);
|
||||
KeReleaseSpinlock(&process->HandleLock);
|
||||
return obj;
|
||||
}
|
||||
Reference in new issue
Block a user