redo boot around an explicit system volume and fixed kernel/HAL images, redo volumes and filesystem paths around capabilities instead of drive numbers and kernel CWD state, add a capability/security model with derived and revocable handles and security contexts, add port IPC and rssrv to manage the userspace resource namespace and publish the system volume, move process, dll and path loading to userspace and add process builder syscalls, init now supervises rssrv and the session process, redo the syscall ABI around request structs and four arguments, add a volume manager and proper partition arrival/removal handling so FAT and NTFS mount dynamically, clean up the HAL/DDK boundary so drivers don't depend on HAL internals, save fpu state properly now, the serial driver doesn't hang on a missing port, fix AHCI startup races, fix timeout accounting, fix shared mmap writeback, more smoke tests

This commit is contained in:
maksw committed 2026-08-20 12:33:17 +02:00
1 parent 4add6789ba
commit f882d339fb
232 files changed
+20934 -8898

No files matched your search

@@ -0,0 +1,129 @@
// Whole-process exit regression test. A blocked sibling must not keep the process alive.
#include <stdint.h>
#include <string.h>
#include <ntlite/syscall.h>
#include <ntlite/process_loader.h>
#define EVENT_AUTO_RESET 0u
#define READY_TIMEOUT_MS 1000u
#define BLOCK_SETTLE_MS 50u
#define CHILD_EXIT_TIMEOUT_MS 1000u
#define CHILD_EXIT_CODE 37
typedef struct WORKER_CONTEXT {
SYS_HANDLE ReadyEvent;
SYS_HANDLE BlockEvent;
} WORKER_CONTEXT;
static WORKER_CONTEXT gWorker;
// Writes one test message to the native console.
static void print(const char* text) {
SYS_WRITE_CONSOLE_REQUEST request = { sizeof(SYS_WRITE_CONSOLE_REQUEST), SysSvFromCstr(text) };
(void)SysWriteConsole(&request);
}
// Terminates the current test process after one failure.
static void fail(const char* message) {
print("process_exit_multithread_smoke: ");
print(message);
print("\n");
while (true) (void)SysExitProcess(1);
}
// Returns whether one string view exactly matches one NUL-terminated string.
static int view_equals_cstr(SYS_STRING_VIEW view, const char* text) {
size_t length = strlen(text);
return view.Data && view.Length == length && memcmp(view.Data, text, length) == 0;
}
// Blocks forever so only whole-process termination can remove this sibling promptly.
static void blocked_worker(uintptr_t argument) {
WORKER_CONTEXT* context = (WORKER_CONTEXT*)argument;
if (!context)
while (true) (void)SysExitProcess(2);
if (SysSignalEvent(context->ReadyEvent) != NTLSTATUS_SUCCESS)
while (true) (void)SysExitProcess(2);
(void)SysWaitSingle(context->BlockEvent, SYS_WAIT_FLAG_NONE, SYS_WAIT_TIMEOUT_INFINITE);
// A normal wait return is impossible in the test. If it happens, fail the process.
while (true) (void)SysExitProcess(2);
}
// Runs the child half that exits while one sibling is blocked indefinitely.
static void run_child(void) {
if (SysCreateEvent(EVENT_AUTO_RESET, 0, &gWorker.ReadyEvent) != NTLSTATUS_SUCCESS)
while (true) (void)SysExitProcess(2);
if (SysCreateEvent(EVENT_AUTO_RESET, 0, &gWorker.BlockEvent) != NTLSTATUS_SUCCESS)
while (true) (void)SysExitProcess(2);
SYS_HANDLE thread = SYS_HANDLE_INVALID;
SYS_CREATE_THREAD_REQUEST request = {
sizeof(SYS_CREATE_THREAD_REQUEST),
(uintptr_t)blocked_worker,
(uintptr_t)&gWorker,
1,
SYS_CREATE_THREAD_FLAG_NONE,
&thread,
(uint32_t*)0
};
if (SysCreateThread(&request) != NTLSTATUS_SUCCESS)
while (true) (void)SysExitProcess(2);
if (SysWaitSingle(gWorker.ReadyEvent, SYS_WAIT_FLAG_NONE, READY_TIMEOUT_MS) != NTLSTATUS_SUCCESS)
while (true) (void)SysExitProcess(2);
// Give the worker a scheduling window to enter its infinite wait before
// exercising whole-process exit. This avoids testing only the syscall gate.
if (SysSleep(BLOCK_SETTLE_MS) != NTLSTATUS_SUCCESS)
while (true) (void)SysExitProcess(2);
while (true) (void)SysExitProcess(CHILD_EXIT_CODE);
}
// Launches the child half and requires whole-process exit to finish promptly.
int main(void) {
SYS_PEB* peb = SysGetPeb();
if (!peb || peb->Magic != SYS_PEB_MAGIC || peb->Version != SYS_ENV_VERSION)
fail("invalid PEB");
if (view_equals_cstr(peb->CommandLine, "--child"))
run_child();
print("process_exit_multithread_smoke: begin\n");
SYS_HANDLE process = SYS_HANDLE_INVALID;
NTL_CREATE_SYSTEM_PROCESS_REQUEST request;
memset(&request, 0, sizeof(request));
request.Size = sizeof(request);
request.Flags = NTL_PROCESS_LOAD_FLAG_NONE;
request.Path = peb->ImagePath;
request.CommandLine = SysSvFromCstr("--child");
request.SecurityContext = SYS_SECURITY_CONTEXT_CURRENT;
request.ResolveModuleName = NtlResolveSystemModuleName;
request.ProcessHandleOut = &process;
KSTATUS status = NtlCreateSystemProcess(&request);
if (!KSUCCESS(status) || process == SYS_HANDLE_INVALID)
fail("child launch failed");
status = SysWaitSingle(process, SYS_WAIT_FLAG_NONE, CHILD_EXIT_TIMEOUT_MS);
if (status != NTLSTATUS_SUCCESS) {
(void)SysKillProcess(process, 1);
(void)SysWait(process, SYS_WAIT_FLAG_NONE);
(void)SysCloseHandle(process);
fail("child did not exit promptly");
}
int32_t exitCode = 0;
status = SysGetProcessExitCode(process, &exitCode);
(void)SysCloseHandle(process);
if (status != NTLSTATUS_SUCCESS || exitCode != CHILD_EXIT_CODE)
fail("child exit code mismatch");
print("process_exit_multithread_smoke: PASS\n");
while (true) (void)SysExitProcess(0);
}