#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 #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 */ // Windows-style flat command line, stored at launch by SysCreateProcess. // The initial thread receives this pointer as its UserArg so _start can // parse it into argc/argv without an extra syscall. char Cmdline[512]; char CurrentDirectory[512]; 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 command line buffer passed to the initial thread. */ uintptr_t UserCmdlineBase; size_t UserCmdlineSize; /* 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); 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);