#pragma once // ke_process.h - process model // A process owns a handle table and a list of threads. // There is one shared address space - processes do not own one. #include #include #include #include #include #include #define PROCESS_NAME_MAX 64 #define HANDLE_TABLE_SIZE 256 #define PROCESS_MODULE_MAX 16 typedef struct PROCESS_MODULE { char Name[32]; uintptr_t Base; size_t Size; } PROCESS_MODULE; typedef struct PROCESS { OBJECT Header; /* must be first */ uint32_t ProcessId; char Name[PROCESS_NAME_MAX]; /* UTF-8 */ char CurrentDirectory[512]; uint8_t CurrentDrive; SPINLOCK CwdLock; /* Thread list. */ LIST_ENTRY ThreadList; /* links THREAD.ProcessLink */ uint32_t ThreadCount; /* Handle table. Index 0 is always NULL (the invalid handle). Entries are OBJECT pointers, each holding a reference. */ OBJECT* Handles[HANDLE_TABLE_SIZE]; SPINLOCK HandleLock; int ExitCode; /* Main executable image. Used for cleanup. */ uintptr_t ImageBase; size_t ImageSize; /* User-mode process environment. The initial thread sees this through GS->TEB->PEB. */ uintptr_t UserPebBase; size_t UserPebSize; uintptr_t UserImagePathBase; size_t UserImagePathSize; uintptr_t UserCmdlineBase; size_t UserCmdlineSize; uintptr_t UserCwdBase; size_t UserCwdSize; /* Per-process loaded modules (user processes only). */ PROCESS_MODULE Modules[PROCESS_MODULE_MAX]; uint32_t ModuleCount; /* Signaled (manual-reset) when the process exits. Waiters block on this via KeWaitForEvent. */ EVENT* ExitEvent; LIST_ENTRY GlobalLink; /* node in the global process list */ } PROCESS; KSTATUS KeCreateProcess(const char* name, PROCESS **out); KSTATUS KeSetupUserProcessEnvironment(PROCESS* process, const char* imagePath, const char* commandLine, const char* currentDirectory); void KeExitProcess(PROCESS* process, int exitCode); KSTATUS KeGetProcessExitCode(PROCESS* process, int* exitCodeOut); /* Handle table operations. */ KSTATUS KeAllocateHandle(PROCESS* process, OBJECT* object, uint32_t* handleOut); void KeCloseHandle(PROCESS* process, uint32_t handle); OBJECT* KeLookupHandle(PROCESS* process, uint32_t handle); /* Return the global process list head (kernel-internal). */ LIST_ENTRY* KeGetProcessList(void); PROCESS* KeGetCurrentProcess(void); /* Copy a snapshot of process IDs into caller-provided storage. */ size_t KeCopyProcessIds(uint32_t* pidsOut, size_t maxCount); /* Find a live process by its ProcessId. Bumps refcount; caller must ObDereferenceObject. */ PROCESS* KeGetProcessById(uint32_t pid);