clean up and standardize types across the codebase, unify atomic operations, improve UTF-8 handling throughout the system, remove obsolete input and named queue interfaces, redesign process preparation and creation, tighten IPC and service boundaries, improve error handling and reliability, minor documentation cleanup, fix doom surfaces, fix panic in ini parsing.
This commit is contained in:
1 parent
899225f551
commit
c0ad63c27f
226 files changed
+6562
-4147
No files matched your search
@@ -1,8 +1,10 @@
|
||||
// Userspace process-builder smoke test for inert construction inputs and child bootstrap vectors.
|
||||
// Userspace prepared-process smoke test for inert construction and child bootstrap vectors.
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <ntlite/syscall.h>
|
||||
#include <ntlite/path.h>
|
||||
#include <ntlite/process_loader.h>
|
||||
#include <ntlite/resource.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
@@ -16,13 +18,13 @@ static void exit_now(int code) {
|
||||
}
|
||||
|
||||
// Compares one native string view with a C string.
|
||||
static int view_equals_cstr(SYS_STRING_VIEW view, const char* text) {
|
||||
static bool view_equals_cstr(SYS_STRING_VIEW view, const char* text) {
|
||||
size_t length = strlen(text);
|
||||
return view.Length == length && (!length || memcmp(view.Data, text, length) == 0);
|
||||
}
|
||||
|
||||
// Detects the child instance through the diagnostic command line.
|
||||
static int is_child(void) {
|
||||
static bool is_child(void) {
|
||||
SYS_PEB* peb = SysGetPeb();
|
||||
static const char marker[] = "process-builder-child";
|
||||
return peb && peb->CommandLine.Length == sizeof(marker) - 1u &&
|
||||
@@ -63,7 +65,7 @@ static void run_child(void) {
|
||||
exit_now(0);
|
||||
}
|
||||
|
||||
// Runs the parent half through the reusable userspace process builder wrapper.
|
||||
// Runs the parent half through prepared-process and convenience construction paths.
|
||||
static int run_parent(void) {
|
||||
SYS_PEB* peb = SysGetPeb();
|
||||
if (!peb || peb->Magic != SYS_PEB_MAGIC || peb->Version != SYS_ENV_VERSION)
|
||||
@@ -121,6 +123,109 @@ static int run_parent(void) {
|
||||
request.StartupData = &startupWord;
|
||||
request.StartupDataSize = sizeof(startupWord);
|
||||
request.ProcessHandleOut = &child;
|
||||
// Exercise the public opaque preparation lifecycle without starting the child.
|
||||
SYS_HANDLE systemRoot = SYS_HANDLE_INVALID;
|
||||
status = NtlResourceOpenSystemRoot(SYS_RIGHT_QUERY | SYS_VOLUME_RIGHT_OPEN, &systemRoot);
|
||||
if (!KSUCCESS(status)) {
|
||||
(void)SysCloseHandle(imageFile);
|
||||
(void)SysCloseHandle(event);
|
||||
return 8;
|
||||
}
|
||||
NTL_PREPARE_PROCESS_REQUEST prepare;
|
||||
memset(&prepare, 0, sizeof(prepare));
|
||||
prepare.Size = sizeof(prepare);
|
||||
prepare.Flags = NTL_PROCESS_LOAD_FLAG_NONE;
|
||||
prepare.RootHandle = systemRoot;
|
||||
prepare.Path = peb->ImagePath;
|
||||
prepare.CommandLine = request.CommandLine;
|
||||
prepare.SecurityContext = request.SecurityContext;
|
||||
prepare.ModuleRootHandle = systemRoot;
|
||||
prepare.ModuleDirectory = SYS_SV_LITERAL("system");
|
||||
prepare.ResolveModuleName = request.ResolveModuleName;
|
||||
prepare.StartupCapabilities = request.StartupCapabilities;
|
||||
prepare.StartupCapabilityCount = request.StartupCapabilityCount;
|
||||
prepare.Arguments = request.Arguments;
|
||||
prepare.Environment = request.Environment;
|
||||
prepare.StartupData = request.StartupData;
|
||||
prepare.StartupDataSize = request.StartupDataSize;
|
||||
|
||||
// Invalid requests never publish a partially constructed preparation.
|
||||
NTL_PROCESS_PREPARATION* preparation = 0;
|
||||
uint32_t savedSize = prepare.Size;
|
||||
prepare.Size = 0;
|
||||
status = NtlPrepareProcess(&prepare, imageFile, &preparation);
|
||||
prepare.Size = savedSize;
|
||||
if (status != NTLSTATUS_INVALID_PARAMETER || preparation != 0) {
|
||||
(void)SysCloseHandle(systemRoot);
|
||||
(void)SysCloseHandle(imageFile);
|
||||
(void)SysCloseHandle(event);
|
||||
return 16;
|
||||
}
|
||||
status = NtlPrepareProcess(&prepare, imageFile, &preparation);
|
||||
if (!KSUCCESS(status) || !preparation) {
|
||||
(void)SysCloseHandle(systemRoot);
|
||||
(void)SysCloseHandle(imageFile);
|
||||
(void)SysCloseHandle(event);
|
||||
return 9;
|
||||
}
|
||||
SYS_HANDLE borrowed = SYS_HANDLE_INVALID;
|
||||
uint32_t nativePid = 0;
|
||||
status = NtlPreparedProcessGetHandle(preparation, &borrowed);
|
||||
if (!KSUCCESS(status) || borrowed == SYS_HANDLE_INVALID ||
|
||||
!KSUCCESS(SysGetProcessPid(borrowed, &nativePid)) || nativePid == 0) {
|
||||
NtlAbortPreparedProcess(preparation);
|
||||
(void)SysCloseHandle(systemRoot);
|
||||
(void)SysCloseHandle(imageFile);
|
||||
(void)SysCloseHandle(event);
|
||||
return 10;
|
||||
}
|
||||
NtlAbortPreparedProcess(preparation);
|
||||
|
||||
// A second preparation starts the child. Start consumes its allocation;
|
||||
// callers must not also abort or close the previously borrowed handle.
|
||||
preparation = 0;
|
||||
status = NtlPrepareProcess(&prepare, imageFile, &preparation);
|
||||
if (!KSUCCESS(status) || !preparation) {
|
||||
(void)SysCloseHandle(systemRoot);
|
||||
(void)SysCloseHandle(imageFile);
|
||||
(void)SysCloseHandle(event);
|
||||
return 11;
|
||||
}
|
||||
status = NtlStartPreparedProcess(preparation, &child);
|
||||
(void)SysCloseHandle(systemRoot);
|
||||
if (!KSUCCESS(status) || child == SYS_HANDLE_INVALID) {
|
||||
(void)SysCloseHandle(imageFile);
|
||||
(void)SysCloseHandle(event);
|
||||
return 12;
|
||||
}
|
||||
status = SysWait(event, SYS_WAIT_FLAG_NONE);
|
||||
if (!KSUCCESS(status)) {
|
||||
(void)SysKillProcess(child, (int32_t)NTLSTATUS_PROCESS_KILLED);
|
||||
(void)SysCloseHandle(child);
|
||||
(void)SysCloseHandle(imageFile);
|
||||
(void)SysCloseHandle(event);
|
||||
return 13;
|
||||
}
|
||||
status = SysWait(child, SYS_WAIT_FLAG_NONE);
|
||||
int32_t directExitCode = -1;
|
||||
if (KSUCCESS(status)) status = SysGetProcessExitCode(child, &directExitCode);
|
||||
(void)SysCloseHandle(child);
|
||||
child = SYS_HANDLE_INVALID;
|
||||
if (!KSUCCESS(status) || directExitCode != 0) {
|
||||
(void)SysCloseHandle(imageFile);
|
||||
(void)SysCloseHandle(event);
|
||||
return 14;
|
||||
}
|
||||
|
||||
// Preserve coverage for NtlCreateSystemProcess's convenience wrapper.
|
||||
(void)SysCloseHandle(event);
|
||||
status = SysCreateEvent(0, 0, &event);
|
||||
if (!KSUCCESS(status)) {
|
||||
(void)SysCloseHandle(imageFile);
|
||||
return 15;
|
||||
}
|
||||
startupCapability.SourceHandle = event;
|
||||
request.ProcessHandleOut = &child;
|
||||
status = NtlCreateSystemProcess(&request);
|
||||
(void)SysCloseHandle(imageFile);
|
||||
if (!KSUCCESS(status)) {
|
||||
|
||||
Reference in new issue
Block a user