implement proper IRQL, DPCs, kernel and user APCs, alertable waits, async file I/O with cancellation, trap frames, selftests, a real driver/device model, native async FAT32, VFAT dotfile fixes, syscall ABI cleanup, async_apc and async_cancel tests, POSIX multi-volume paths, and pimp the readme.
This commit is contained in:
1 parent
f5fd7bdd75
commit
529f816166
75 files changed
+9969
-5675
No files matched your search
+47
-27
@@ -16,7 +16,7 @@ static LIST_ENTRY gProcessList;
|
||||
static SPINLOCK gProcessListLock;
|
||||
static uint32_t gNextProcessId = 1;
|
||||
|
||||
static void ProcessInit(void) {
|
||||
static void KiProcessInit(void) {
|
||||
static int inited = 0;
|
||||
if (!inited) {
|
||||
LIST_INIT(&gProcessList);
|
||||
@@ -26,7 +26,7 @@ static void ProcessInit(void) {
|
||||
}
|
||||
|
||||
LIST_ENTRY* KeGetProcessList(void) {
|
||||
ProcessInit();
|
||||
KiProcessInit();
|
||||
return &gProcessList;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ PROCESS* KeGetCurrentProcess(void) {
|
||||
}
|
||||
|
||||
size_t KeCopyProcessIds(uint32_t* pidsOut, size_t maxCount) {
|
||||
ProcessInit();
|
||||
KiProcessInit();
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gProcessListLock);
|
||||
size_t count = 0;
|
||||
@@ -56,7 +56,7 @@ size_t KeCopyProcessIds(uint32_t* pidsOut, size_t maxCount) {
|
||||
// ---------------------------------------------------------------------------
|
||||
// Destructor (called by ObDereferenceObject when RefCount hits zero)
|
||||
// ---------------------------------------------------------------------------
|
||||
static void ProcessDestroy(OBJECT* obj) {
|
||||
static void KiProcessDestroy(OBJECT* obj) {
|
||||
PROCESS* proc = CONTAINING_RECORD(obj, PROCESS, Header);
|
||||
|
||||
// Release all remaining handles.
|
||||
@@ -69,7 +69,7 @@ static void ProcessDestroy(OBJECT* obj) {
|
||||
|
||||
// Release the main executable image.
|
||||
if (proc->ImageBase && proc->ImageSize) {
|
||||
MmFreeUserMemory((void *)proc->ImageBase, proc->ImageSize);
|
||||
MmFreeUserMemory((void *)proc->ImageBase);
|
||||
proc->ImageBase = 0;
|
||||
proc->ImageSize = 0;
|
||||
}
|
||||
@@ -77,7 +77,7 @@ static void ProcessDestroy(OBJECT* obj) {
|
||||
// Release per-process modules.
|
||||
for (uint32_t i = 0; i < proc->ModuleCount; i++) {
|
||||
if (proc->Modules[i].Base && proc->Modules[i].Size) {
|
||||
MmFreeUserMemory((void *)proc->Modules[i].Base, proc->Modules[i].Size);
|
||||
MmFreeUserMemory((void *)proc->Modules[i].Base);
|
||||
}
|
||||
proc->Modules[i].Base = 0;
|
||||
proc->Modules[i].Size = 0;
|
||||
@@ -87,22 +87,22 @@ static void ProcessDestroy(OBJECT* obj) {
|
||||
|
||||
// Release the user-mode process environment.
|
||||
if (proc->UserPebBase && proc->UserPebSize) {
|
||||
MmFreeUserMemory((void *)proc->UserPebBase, proc->UserPebSize);
|
||||
MmFreeUserMemory((void *)proc->UserPebBase);
|
||||
proc->UserPebBase = 0;
|
||||
proc->UserPebSize = 0;
|
||||
}
|
||||
if (proc->UserImagePathBase && proc->UserImagePathSize) {
|
||||
MmFreeUserMemory((void *)proc->UserImagePathBase, proc->UserImagePathSize);
|
||||
MmFreeUserMemory((void *)proc->UserImagePathBase);
|
||||
proc->UserImagePathBase = 0;
|
||||
proc->UserImagePathSize = 0;
|
||||
}
|
||||
if (proc->UserCmdlineBase && proc->UserCmdlineSize) {
|
||||
MmFreeUserMemory((void *)proc->UserCmdlineBase, proc->UserCmdlineSize);
|
||||
MmFreeUserMemory((void *)proc->UserCmdlineBase);
|
||||
proc->UserCmdlineBase = 0;
|
||||
proc->UserCmdlineSize = 0;
|
||||
}
|
||||
if (proc->UserCwdBase && proc->UserCwdSize) {
|
||||
MmFreeUserMemory((void *)proc->UserCwdBase, proc->UserCwdSize);
|
||||
MmFreeUserMemory((void *)proc->UserCwdBase);
|
||||
proc->UserCwdBase = 0;
|
||||
proc->UserCwdSize = 0;
|
||||
}
|
||||
@@ -126,14 +126,14 @@ static void ProcessDestroy(OBJECT* obj) {
|
||||
// KeCreateProcess
|
||||
// ---------------------------------------------------------------------------
|
||||
KSTATUS KeCreateProcess(const char* name, PROCESS **out) {
|
||||
ProcessInit();
|
||||
KiProcessInit();
|
||||
|
||||
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->Header.Destroy = KiProcessDestroy;
|
||||
|
||||
proc->ProcessId = _InterlockedExchangeAdd((volatile long *)&gNextProcessId, 1);
|
||||
strncpy(proc->Name, name, PROCESS_NAME_MAX - 1);
|
||||
@@ -155,6 +155,7 @@ KSTATUS KeCreateProcess(const char* name, PROCESS **out) {
|
||||
proc->UserCwdSize = 0;
|
||||
proc->ModuleCount = 0;
|
||||
proc->CurrentDirectory[0] = '\0';
|
||||
proc->CurrentDrive = 0;
|
||||
proc->CwdLock = (SPINLOCK)SPINLOCK_INIT;
|
||||
|
||||
// Slot 0 is the invalid handle - leave it NULL.
|
||||
@@ -180,7 +181,7 @@ KSTATUS KeCreateProcess(const char* name, PROCESS **out) {
|
||||
// ---------------------------------------------------------------------------
|
||||
// KeSetupUserProcessEnvironment
|
||||
// ---------------------------------------------------------------------------
|
||||
static KSTATUS CopyEnvironmentString(const char* src, uintptr_t* baseOut, size_t* sizeOut) {
|
||||
static KSTATUS KiCopyEnvironmentString(const char* src, uintptr_t* baseOut, size_t* sizeOut) {
|
||||
if (!baseOut || !sizeOut) return STATUS_INVALID_PARAMETER;
|
||||
if (!src) src = "";
|
||||
|
||||
@@ -194,7 +195,7 @@ static KSTATUS CopyEnvironmentString(const char* src, uintptr_t* baseOut, size_t
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static KSTATUS CopyEnvironmentStringFixed(const char* src, size_t capacity,
|
||||
static KSTATUS KiCopyEnvironmentStringFixed(const char* src, size_t capacity,
|
||||
uintptr_t* baseOut, size_t* sizeOut) {
|
||||
if (!baseOut || !sizeOut || capacity == 0) return STATUS_INVALID_PARAMETER;
|
||||
if (!src) src = "";
|
||||
@@ -213,31 +214,48 @@ static KSTATUS CopyEnvironmentStringFixed(const char* src, size_t capacity,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void FreePartialProcessEnvironment(PROCESS* proc) {
|
||||
static void KiFreePartialProcessEnvironment(PROCESS* proc) {
|
||||
if (!proc) return;
|
||||
|
||||
if (proc->UserPebBase && proc->UserPebSize) {
|
||||
MmFreeUserMemory((void*)proc->UserPebBase, proc->UserPebSize);
|
||||
MmFreeUserMemory((void*)proc->UserPebBase);
|
||||
proc->UserPebBase = 0;
|
||||
proc->UserPebSize = 0;
|
||||
}
|
||||
if (proc->UserImagePathBase && proc->UserImagePathSize) {
|
||||
MmFreeUserMemory((void*)proc->UserImagePathBase, proc->UserImagePathSize);
|
||||
MmFreeUserMemory((void*)proc->UserImagePathBase);
|
||||
proc->UserImagePathBase = 0;
|
||||
proc->UserImagePathSize = 0;
|
||||
}
|
||||
if (proc->UserCmdlineBase && proc->UserCmdlineSize) {
|
||||
MmFreeUserMemory((void*)proc->UserCmdlineBase, proc->UserCmdlineSize);
|
||||
MmFreeUserMemory((void*)proc->UserCmdlineBase);
|
||||
proc->UserCmdlineBase = 0;
|
||||
proc->UserCmdlineSize = 0;
|
||||
}
|
||||
if (proc->UserCwdBase && proc->UserCwdSize) {
|
||||
MmFreeUserMemory((void*)proc->UserCwdBase, proc->UserCwdSize);
|
||||
MmFreeUserMemory((void*)proc->UserCwdBase);
|
||||
proc->UserCwdBase = 0;
|
||||
proc->UserCwdSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void KiFormatNativeCwd(const PROCESS* proc, const char* currentDirectory,
|
||||
char* out, size_t outSize) {
|
||||
if (!out || outSize == 0) return;
|
||||
const char* rel = currentDirectory ? currentDirectory : "";
|
||||
uint8_t drive = proc ? proc->CurrentDrive : 0;
|
||||
if (drive > 7) drive = 0;
|
||||
|
||||
if (outSize < 4) { out[0] = '\0'; return; }
|
||||
out[0] = (char)('0' + drive);
|
||||
out[1] = ':';
|
||||
out[2] = '/';
|
||||
size_t len = strlen(rel);
|
||||
if (len + 4 > outSize) len = outSize - 4;
|
||||
memcpy(out + 3, rel, len);
|
||||
out[3 + len] = '\0';
|
||||
}
|
||||
|
||||
KSTATUS KeSetupUserProcessEnvironment(PROCESS* proc,
|
||||
const char* imagePath,
|
||||
const char* commandLine,
|
||||
@@ -245,17 +263,19 @@ KSTATUS KeSetupUserProcessEnvironment(PROCESS* proc,
|
||||
if (!proc || !imagePath) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
const char* finalCommandLine = (commandLine && commandLine[0]) ? commandLine : imagePath;
|
||||
const char* finalCwd = currentDirectory ? currentDirectory : proc->CurrentDirectory;
|
||||
const char* finalCwdRel = currentDirectory ? currentDirectory : proc->CurrentDirectory;
|
||||
char finalCwd[SYS_CWD_MAX];
|
||||
KiFormatNativeCwd(proc, finalCwdRel, finalCwd, sizeof(finalCwd));
|
||||
|
||||
FreePartialProcessEnvironment(proc);
|
||||
KiFreePartialProcessEnvironment(proc);
|
||||
|
||||
KSTATUS s = CopyEnvironmentString(imagePath, &proc->UserImagePathBase, &proc->UserImagePathSize);
|
||||
KSTATUS s = KiCopyEnvironmentString(imagePath, &proc->UserImagePathBase, &proc->UserImagePathSize);
|
||||
if (!KSUCCESS(s)) goto fail;
|
||||
|
||||
s = CopyEnvironmentString(finalCommandLine, &proc->UserCmdlineBase, &proc->UserCmdlineSize);
|
||||
s = KiCopyEnvironmentString(finalCommandLine, &proc->UserCmdlineBase, &proc->UserCmdlineSize);
|
||||
if (!KSUCCESS(s)) goto fail;
|
||||
|
||||
s = CopyEnvironmentStringFixed(finalCwd, SYS_CWD_MAX, &proc->UserCwdBase, &proc->UserCwdSize);
|
||||
s = KiCopyEnvironmentStringFixed(finalCwd, SYS_CWD_MAX, &proc->UserCwdBase, &proc->UserCwdSize);
|
||||
if (!KSUCCESS(s)) goto fail;
|
||||
|
||||
SYS_PEB* peb = (SYS_PEB*)MmAllocateUserMemory(sizeof(SYS_PEB));
|
||||
@@ -277,7 +297,7 @@ KSTATUS KeSetupUserProcessEnvironment(PROCESS* proc,
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
FreePartialProcessEnvironment(proc);
|
||||
KiFreePartialProcessEnvironment(proc);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -290,7 +310,7 @@ void KeExitProcess(PROCESS* process, int exitCode) {
|
||||
// Wake any threads waiting for this process to finish.
|
||||
if (process->ExitEvent) KeSignalEvent(process->ExitEvent);
|
||||
// The last thread exiting via KeExitThread will drop the process refcount.
|
||||
// This function is a policy hook; actual cleanup is in ProcessDestroy.
|
||||
// This function is a policy hook; actual cleanup is in KiProcessDestroy.
|
||||
ObDereferenceObject(&process->Header);
|
||||
}
|
||||
|
||||
@@ -351,7 +371,7 @@ OBJECT* KeLookupHandle(PROCESS* process, uint32_t handle) {
|
||||
}
|
||||
|
||||
PROCESS* KeGetProcessById(uint32_t pid) {
|
||||
ProcessInit();
|
||||
KiProcessInit();
|
||||
uintptr_t flags = KeAcquireSpinlock(&gProcessListLock);
|
||||
LIST_ENTRY* head = &gProcessList;
|
||||
LIST_ENTRY* node = head->Fwd;
|
||||
|
||||
Reference in new issue
Block a user