Files
nt-lite/code/user/system/init/init.c
T
maksw 73abd6f90d isolate POSIX builds from the host UCRT, wire lwext4 and ntfs-3g as ext4.sys and ntfs.sys, split the FAT driver into directory/file/async/driver/mount units, add posixsrv and dwm plus input/console/desktop syscall clients and a pile of new smoke targets, rename serial.sys to cereal.sys, name HDA/USB/lwIP/AHCI workers, harden ATA probing/reset/removal around actual hardware deadlines, absent-channel detection, diagnostics and explicit worker lifetime, redo ACPI S5 shutdown around GAS/MMIO and HW-reduced firmware, scan SSDTs for _S5 and deal with Intel SMI sleep trapping, make serial and SMP timeouts use real monotonic deadlines, add thread names and fix terminal thread teardown, scheduler and APC prepare/commit races, make advisory file locks queryable and preserve split ranges and add mutable file append state, add shared-memory pipes with kernel-assisted wait/wake, introduce capability-scoped input and display managers, split surface map rights into read/write, add explicit unmap and replace present with commit/generation/damage tracking while keeping physical presentation under the display manager, decouple native exception classes from Win32 exception numbers and translate them in kernel32, add opaque process startup data, bump the resource protocol to v3 with namespace directories, symlinks and enumeration and service control to v2 with generic READY handle exports, add the new POSIX errno/status surface and rebuild fds around posixsrv-owned shared open descriptions, descriptor-local flags, exact inheritance snapshots, dup/fcntl/record locks and shared-ring pipes, add waitpid, POSIX credentials/groups/sessions/passwd/group lookups and move sockets onto stable open descriptions, port the shells and apps to the new console/input services and surface commit API, teach init to load services.ini and start/supervise RSSRV, DWM and generic services under restricted capabilities while publishing their endpoints through RSSRV, split RSSRV into namespace, volume, display, session, input, console and resource components and make /SystemRoot a real symlink to the independently published system volume, shift the syscall table again, expand lock/resource/surface/POSIX/service/thread smoke coverage, make docs scream ASK QUESTIONS and DISCUSS at LLMs, replace MIT No Attribution with WTFPL+.
2026-09-16 10:33:20 +02:00

1149 lines
51 KiB
C

// Init service manager. The kernel bootstraps only init; init starts and supervises user-mode system services.
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <ntlite/exception.h>
#include <ntlite/input_service.h>
#include <ntlite/console_service.h>
#include <ntlite/desktop.h>
#include <ntlite/process_loader.h>
#include <ntlite/resource.h>
#include <ntlite/security.h>
#include <ntlite/service_control.h>
#include <ntlite/syscall.h>
#include "service_config.h"
typedef enum INIT_SERVICE_STATE {
InitServiceStopped = 0,
InitServiceStarting,
InitServiceReady,
InitServiceStopping,
InitServiceFailed,
} INIT_SERVICE_STATE;
typedef struct INIT_SERVICE {
const INIT_SERVICE_DESCRIPTOR* Descriptor;
SYS_HANDLE Process;
SYS_HANDLE ControlEndpoint;
INIT_SERVICE_STATE State;
} INIT_SERVICE;
typedef struct INIT_RESOURCE_SERVICE {
INIT_SERVICE Service;
SYS_HANDLE AdminListener;
SYS_HANDLE SessionControlListener;
} INIT_RESOURCE_SERVICE;
static INIT_SERVICE_CONFIG gServiceConfig;
// Writes one string through the privileged kernel debug channel.
static void debug_print(const char* text) {
SYS_PRINT_DEBUG_REQUEST request = { sizeof(request), SysSvFromCstr(text) };
(void)SysPrintDebug(&request);
}
// Writes one status value in hexadecimal without pulling in a formatting runtime.
static void debug_status(KSTATUS status) {
static const char digits[] = "0123456789ABCDEF";
char buffer[11] = "0x00000000";
for (uint32_t i = 0; i < 8; ++i)
buffer[2 + i] = digits[(status >> ((7u - i) * 4u)) & 0xFu];
debug_print(buffer);
}
// Writes one unsigned decimal value without pulling in a formatting runtime.
static void debug_u32(uint32_t value) {
char buffer[11];
uint32_t length = 0;
do {
buffer[length++] = (char)('0' + value % 10u);
value /= 10u;
} while (value != 0u);
for (uint32_t i = 0; i < length / 2u; ++i) {
char temporary = buffer[i];
buffer[i] = buffer[length - 1u - i];
buffer[length - 1u - i] = temporary;
}
buffer[length] = '\0';
debug_print(buffer);
}
// Writes one signed decimal value without pulling in a formatting runtime.
static void debug_i32(int32_t value) {
if (value < 0) debug_print("-");
uint32_t magnitude = value < 0 ? (uint32_t)(-(int64_t)value) : (uint32_t)value;
debug_u32(magnitude);
}
// Reports a managed service that terminated before completing its READY contract.
static void debug_early_service_exit(const INIT_SERVICE* service) {
if (!service || !service->Descriptor || service->Process == SYS_HANDLE_INVALID) return;
KSTATUS waitStatus = SysWaitSingle(service->Process, SYS_WAIT_FLAG_NONE, 0);
if (waitStatus != NTLSTATUS_SUCCESS) return;
int32_t exitCode = -1;
if (SysGetProcessExitCode(service->Process, &exitCode) != NTLSTATUS_SUCCESS) return;
debug_print("[init] service ");
debug_print(service->Descriptor->Id);
debug_print(" exited during startup with code ");
debug_i32(exitCode);
debug_print("\n");
}
// Exits init without relying on a compiler runtime return path.
static void exit_now(int code) {
for (;;) SysExitProcess(code);
}
// Initializes one managed-service runtime record in the stopped state.
static void initialize_service(INIT_SERVICE* service, const INIT_SERVICE_DESCRIPTOR* descriptor) {
memset(service, 0, sizeof(*service));
service->Descriptor = descriptor;
service->Process = SYS_HANDLE_INVALID;
service->ControlEndpoint = SYS_HANDLE_INVALID;
service->State = InitServiceStopped;
}
// Derives the least-privileged security context required by RSSRV.
static KSTATUS derive_resource_service_context(SYS_HANDLE* contextOut) {
if (!contextOut) return NTLSTATUS_INVALID_PARAMETER;
*contextOut = SYS_HANDLE_INVALID;
SYS_DERIVE_SECURITY_CONTEXT_REQUEST request;
memset(&request, 0, sizeof(request));
request.Size = sizeof(request);
request.SourceContext = SYS_SECURITY_CONTEXT_CURRENT;
request.EffectivePrivileges = SYS_PRIV_SYSTEM_SERVICE_REGISTER;
request.DelegablePrivileges = 0;
request.ServiceClaims = SYS_SERVICE_CLAIM_RESOURCE;
request.DelegableServiceClaims = 0;
request.Flags = SYS_SECURITY_CONTEXT_FLAG_NONE;
request.ContextHandleOut = contextOut;
return SysDeriveSecurityContext(&request);
}
// Derives the unprivileged security context used by replaceable user-mode services.
static KSTATUS derive_unprivileged_service_context(SYS_HANDLE* contextOut) {
if (!contextOut) return NTLSTATUS_INVALID_PARAMETER;
*contextOut = SYS_HANDLE_INVALID;
SYS_DERIVE_SECURITY_CONTEXT_REQUEST request;
memset(&request, 0, sizeof(request));
request.Size = sizeof(request);
request.SourceContext = SYS_SECURITY_CONTEXT_CURRENT;
request.EffectivePrivileges = 0;
request.DelegablePrivileges = 0;
request.ServiceClaims = 0;
request.DelegableServiceClaims = 0;
request.Flags = SYS_SECURITY_CONTEXT_FLAG_NONE;
request.ContextHandleOut = contextOut;
return SysDeriveSecurityContext(&request);
}
// Creates one private Port listener used only between init and a managed service.
static KSTATUS create_control_listener(SYS_HANDLE* listenerOut) {
SYS_CREATE_PORT_REQUEST request;
memset(&request, 0, sizeof(request));
request.Size = sizeof(request);
request.Flags = SYS_PORT_FLAG_NONE;
request.Backlog = 1;
request.HandleOut = listenerOut;
return SysCreatePort(&request);
}
// Connects init to the private control listener delegated to the child.
static KSTATUS connect_control_listener(SYS_HANDLE listener, SYS_HANDLE* endpointOut) {
SYS_CONNECT_PORT_REQUEST request;
memset(&request, 0, sizeof(request));
request.Size = sizeof(request);
request.ListenerHandle = listener;
request.Flags = SYS_PORT_CONNECT_FLAG_NONE;
request.EndpointHandleOut = endpointOut;
return SysConnectPort(&request);
}
// Closes the generic parent-side handles retained for one managed service.
static void close_service_handles(INIT_SERVICE* service) {
if (!service) return;
if (service->ControlEndpoint != SYS_HANDLE_INVALID) {
(void)SysDisconnectPort(service->ControlEndpoint);
(void)SysCloseHandle(service->ControlEndpoint);
}
if (service->Process != SYS_HANDLE_INVALID)
(void)SysCloseHandle(service->Process);
service->Process = SYS_HANDLE_INVALID;
service->ControlEndpoint = SYS_HANDLE_INVALID;
}
// Starts one managed service process and establishes its private control connection.
static KSTATUS start_service_process(SYS_HANDLE systemVolume,
SYS_HANDLE securityContext,
const NTL_PROCESS_STARTUP_CAPABILITY* startupCapabilities,
uint32_t startupCapabilityCount,
INIT_SERVICE* service) {
if (!service || !service->Descriptor || service->Descriptor->ImagePath[0] == '\0' ||
startupCapabilityCount > SYS_STARTUP_CAPABILITY_MAX - 1u ||
(startupCapabilityCount && !startupCapabilities))
return NTLSTATUS_INVALID_PARAMETER;
if (service->Process != SYS_HANDLE_INVALID || service->ControlEndpoint != SYS_HANDLE_INVALID ||
(service->State != InitServiceStopped && service->State != InitServiceFailed))
return NTLSTATUS_FAILURE;
service->State = InitServiceStarting;
SYS_HANDLE controlListener = SYS_HANDLE_INVALID;
KSTATUS status = create_control_listener(&controlListener);
if (!KSUCCESS(status)) {
service->State = InitServiceFailed;
return status;
}
NTL_PROCESS_STARTUP_CAPABILITY startup[SYS_STARTUP_CAPABILITY_MAX];
memset(startup, 0, sizeof(startup));
for (uint32_t i = 0; i < startupCapabilityCount; ++i)
startup[i] = startupCapabilities[i];
startup[startupCapabilityCount].Tag = SYS_STARTUP_CAP_SERVICE_CONTROL;
startup[startupCapabilityCount].SourceHandle = controlListener;
startup[startupCapabilityCount].DesiredRights = SYS_RIGHT_QUERY | SYS_PORT_RIGHT_ACCEPT;
startup[startupCapabilityCount].DuplicateFlags = SYS_DUPLICATE_HANDLE_FLAG_NONE;
SYS_HANDLE process = SYS_HANDLE_INVALID;
SYS_STRING_VIEW imagePath = SysSvFromCstr(service->Descriptor->ImagePath);
NTL_CREATE_PROCESS_AT_REQUEST create;
memset(&create, 0, sizeof(create));
create.Size = sizeof(create);
create.Flags = NTL_PROCESS_LOAD_FLAG_NONE;
create.RootHandle = systemVolume;
create.Path = imagePath;
create.CommandLine = imagePath;
create.SecurityContext = securityContext;
create.ModuleRootHandle = systemVolume;
create.ModuleDirectory = SYS_SV_LITERAL("system");
create.ResolveModuleName = NtlResolveModuleNameIdentity;
create.ResolveContext = (void*)0;
create.StartupCapabilities = startup;
create.StartupCapabilityCount = startupCapabilityCount + 1u;
create.ProcessHandleOut = &process;
status = NtlCreateProcessAt(&create);
if (!KSUCCESS(status)) {
(void)SysCloseHandle(controlListener);
service->State = InitServiceFailed;
return status;
}
SYS_HANDLE controlEndpoint = SYS_HANDLE_INVALID;
status = connect_control_listener(controlListener, &controlEndpoint);
(void)SysCloseHandle(controlListener);
if (!KSUCCESS(status)) {
(void)SysKillProcess(process, 1);
(void)SysCloseHandle(process);
service->State = InitServiceFailed;
return status;
}
service->Process = process;
service->ControlEndpoint = controlEndpoint;
return NTLSTATUS_SUCCESS;
}
// Waits for one service READY notification and receives its service-defined export handles.
static KSTATUS wait_service_ready(INIT_SERVICE* service,
SYS_HANDLE* exportsOut,
uint32_t exportCapacity,
uint32_t* exportCountOut) {
if (!service || !service->Descriptor || !exportCountOut ||
exportCapacity > SYS_PORT_MAX_TRANSFER_HANDLES || (exportCapacity && !exportsOut))
return NTLSTATUS_INVALID_PARAMETER;
for (uint32_t i = 0; i < exportCapacity; ++i) exportsOut[i] = SYS_HANDLE_INVALID;
*exportCountOut = 0;
NTL_SERVICE_CONTROL_MESSAGE message;
SYS_PORT_MESSAGE_INFO info;
memset(&message, 0, sizeof(message));
memset(&info, 0, sizeof(info));
info.Size = sizeof(info);
SYS_RECEIVE_PORT_REQUEST receive;
memset(&receive, 0, sizeof(receive));
receive.Size = sizeof(receive);
receive.EndpointHandle = service->ControlEndpoint;
receive.Flags = SYS_PORT_FLAG_NONE;
receive.Payload = &message;
receive.PayloadCapacity = sizeof(message);
receive.HandlesOut = exportsOut;
receive.HandleCapacity = exportCapacity;
receive.InfoOut = &info;
receive.TimeoutMilliseconds = service->Descriptor->ReadyTimeoutMilliseconds;
KSTATUS status = SysReceivePort(&receive);
if (!KSUCCESS(status)) return status;
bool valid = info.Type == SYS_PORT_MESSAGE_NOTIFICATION &&
info.PayloadLength == sizeof(message) &&
message.Size == sizeof(message) &&
message.Version == NTL_SERVICE_CONTROL_VERSION &&
message.Operation == NTL_SERVICE_CONTROL_READY &&
message.ExportCount == info.HandleCount &&
message.ExportCount <= exportCapacity &&
message.Reserved[0] == 0 && message.Reserved[1] == 0 && message.Reserved[2] == 0;
if (!valid || !KSUCCESS(message.Status)) {
for (uint32_t i = 0; i < info.HandleCount && i < exportCapacity; ++i) {
if (exportsOut[i] != SYS_HANDLE_INVALID) {
(void)SysCloseHandle(exportsOut[i]);
exportsOut[i] = SYS_HANDLE_INVALID;
}
}
return valid ? message.Status : NTLSTATUS_FAILURE;
}
*exportCountOut = info.HandleCount;
return NTLSTATUS_SUCCESS;
}
// Waits for RSSRV readiness and receives init-only namespace and DWM-session bootstrap exports.
static KSTATUS wait_resource_service_ready(INIT_SERVICE* service,
SYS_HANDLE* adminListenerOut,
SYS_HANDLE* sessionControlListenerOut) {
if (!adminListenerOut || !sessionControlListenerOut) return NTLSTATUS_INVALID_PARAMETER;
*adminListenerOut = SYS_HANDLE_INVALID;
*sessionControlListenerOut = SYS_HANDLE_INVALID;
SYS_HANDLE exports[2] = { SYS_HANDLE_INVALID, SYS_HANDLE_INVALID };
uint32_t exportCount = 0;
KSTATUS status = wait_service_ready(service, exports, 2u, &exportCount);
if (!KSUCCESS(status)) return status;
if (exportCount != 2u || exports[0] == SYS_HANDLE_INVALID || exports[1] == SYS_HANDLE_INVALID) {
for (uint32_t i = 0; i < 2u; ++i)
if (exports[i] != SYS_HANDLE_INVALID) (void)SysCloseHandle(exports[i]);
return NTLSTATUS_FAILURE;
}
*adminListenerOut = exports[0];
*sessionControlListenerOut = exports[1];
return NTLSTATUS_SUCCESS;
}
// Verifies namespace structure, administration, symbolic links, enumeration, and public capability lookup.
static KSTATUS verify_resource_service(SYS_HANDLE adminListener, SYS_HANDLE namespaceVolume) {
SYS_HANDLE admin = SYS_HANDLE_INVALID;
SYS_HANDLE publicSession = SYS_HANDLE_INVALID;
SYS_HANDLE volume = SYS_HANDLE_INVALID;
SYS_HANDLE displayDevice = SYS_HANDLE_INVALID;
SYS_HANDLE consoleAlias = SYS_HANDLE_INVALID;
uint32_t initDirectoryCreated = 0;
uint32_t aliasCreated = 0;
uint32_t probeBound = 0;
NTL_RESOURCE_ENUM_CURSOR cursor;
uint32_t sawAlias = 0;
uint32_t sawProbe = 0;
memset(&cursor, 0, sizeof(cursor));
KSTATUS status = NtlResourceConnectListener(adminListener, &admin);
if (!KSUCCESS(status)) return status;
uint32_t kind = NTL_RESOURCE_KIND_INVALID;
status = NtlResourceQuery(admin, SYS_SV_LITERAL("/"), &kind);
if (!KSUCCESS(status) || kind != NTL_RESOURCE_KIND_NAMESPACE_DIRECTORY) {
status = KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
goto cleanup;
}
status = NtlResourceQuery(admin, SYS_SV_LITERAL("/SystemRoot"), &kind);
if (!KSUCCESS(status) || kind != NTL_RESOURCE_KIND_SYMBOLIC_LINK) {
status = KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
goto cleanup;
}
status = NtlResourceQuery(admin, SYS_SV_LITERAL("/Device/Display0"), &kind);
if (!KSUCCESS(status) || kind != NTL_RESOURCE_KIND_DEVICE) {
status = KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
goto cleanup;
}
status = NtlResourceLookup(admin, SYS_SV_LITERAL("/Device/Display0"),
SYS_RIGHT_QUERY | SYS_DISPLAY_MANAGER_RIGHT_ENUMERATE, &displayDevice);
if (!KSUCCESS(status)) goto cleanup;
SYS_DISPLAY_INFO displayInfo;
memset(&displayInfo, 0, sizeof(displayInfo));
status = SysQueryDisplayManagerInfo(displayDevice, &displayInfo);
(void)SysCloseHandle(displayDevice);
displayDevice = SYS_HANDLE_INVALID;
if (!KSUCCESS(status) || displayInfo.Mode.Width == 0 || displayInfo.Mode.Height == 0) {
status = KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
goto cleanup;
}
status = NtlResourceQuery(admin, SYS_SV_LITERAL("/Sessions/0"), &kind);
if (!KSUCCESS(status) || kind != NTL_RESOURCE_KIND_NAMESPACE_DIRECTORY) {
status = KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
goto cleanup;
}
status = NtlResourceQuery(admin, SYS_SV_LITERAL("/Sessions/0/Desktop"), &kind);
if (status != NTLSTATUS_NOT_FOUND) {
status = KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
goto cleanup;
}
status = NtlResourceQuery(admin, SYS_SV_LITERAL("/Sessions/0/Console"), &kind);
if (!KSUCCESS(status) || kind != NTL_RESOURCE_KIND_CAPABILITY) {
status = KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
goto cleanup;
}
status = NtlResourceQuery(admin, SYS_SV_LITERAL("/Console"), &kind);
if (!KSUCCESS(status) || kind != NTL_RESOURCE_KIND_SYMBOLIC_LINK) {
status = KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
goto cleanup;
}
status = NtlResourceLookup(admin, SYS_SV_LITERAL("/Console"),
SYS_RIGHT_QUERY | SYS_PORT_RIGHT_CONNECT, &consoleAlias);
if (!KSUCCESS(status)) goto cleanup;
(void)SysCloseHandle(consoleAlias);
consoleAlias = SYS_HANDLE_INVALID;
status = NtlResourceQuery(admin, SYS_SV_LITERAL(NTL_INPUT_SERVICE_PATH), &kind);
if (!KSUCCESS(status) || kind != NTL_RESOURCE_KIND_CAPABILITY) {
status = KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
goto cleanup;
}
SYS_HANDLE inputSession = SYS_HANDLE_INVALID;
status = NtlInputConnect(&inputSession);
if (!KSUCCESS(status)) goto cleanup;
NTL_INPUT_STATE inputState;
status = NtlInputQueryState(inputSession, &inputState);
(void)NtlInputClose(inputSession);
if (!KSUCCESS(status) || inputState.Size != sizeof(inputState) ||
inputState.Flags != NTL_INPUT_STATE_FLAG_NONE) {
status = KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
goto cleanup;
}
status = NtlResourceQuery(admin, SYS_SV_LITERAL(NTL_CONSOLE_SERVICE_PATH), &kind);
if (!KSUCCESS(status) || kind != NTL_RESOURCE_KIND_CAPABILITY) {
status = KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
goto cleanup;
}
SYS_HANDLE consoleSession = SYS_HANDLE_INVALID;
status = NtlConsoleConnect(&consoleSession);
if (!KSUCCESS(status)) goto cleanup;
NTL_CONSOLE_INFO consoleInfo;
memset(&consoleInfo, 0, sizeof(consoleInfo));
status = NtlConsoleQueryInfo(consoleSession, &consoleInfo);
(void)NtlConsoleClose(consoleSession);
if (!KSUCCESS(status) || consoleInfo.Size != sizeof(consoleInfo) ||
consoleInfo.Flags != NTL_CONSOLE_FLAG_NONE || consoleInfo.Columns == 0 ||
consoleInfo.Rows == 0 || consoleInfo.PixelWidth == 0 || consoleInfo.PixelHeight == 0) {
status = KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
goto cleanup;
}
// Exercise explicit parent creation rather than allowing bind to manufacture namespace directories.
status = NtlResourceCreateDirectory(admin, SYS_SV_LITERAL("/Init"));
if (!KSUCCESS(status)) goto cleanup;
initDirectoryCreated = 1;
// Exercise a symbolic-link chain: /Init/SystemRoot -> /SystemRoot -> /Device/HarddiskVolumeN.
status = NtlResourceCreateSymbolicLink(admin, SYS_SV_LITERAL("/Init/SystemRoot"),
SYS_SV_LITERAL("/SystemRoot"));
if (!KSUCCESS(status)) goto cleanup;
aliasCreated = 1;
status = NtlResourceBind(admin, SYS_SV_LITERAL("/Init/BootstrapProbe"),
NTL_RESOURCE_KIND_VOLUME, namespaceVolume,
SYS_RIGHT_TRANSFER | SYS_RIGHT_QUERY | SYS_VOLUME_RIGHT_OPEN,
SYS_RIGHT_QUERY | SYS_VOLUME_RIGHT_OPEN);
if (!KSUCCESS(status)) goto cleanup;
probeBound = 1;
status = NtlResourceConnect(&publicSession);
if (!KSUCCESS(status)) goto cleanup;
status = NtlResourceLookup(publicSession, SYS_SV_LITERAL("/SystemRoot"),
SYS_RIGHT_QUERY | SYS_VOLUME_RIGHT_OPEN, &volume);
if (!KSUCCESS(status)) goto cleanup;
(void)SysCloseHandle(volume);
volume = SYS_HANDLE_INVALID;
status = NtlResourceLookup(publicSession, SYS_SV_LITERAL("/Init/SystemRoot"),
SYS_RIGHT_QUERY | SYS_VOLUME_RIGHT_OPEN, &volume);
if (!KSUCCESS(status)) goto cleanup;
(void)SysCloseHandle(volume);
volume = SYS_HANDLE_INVALID;
kind = NTL_RESOURCE_KIND_INVALID;
status = NtlResourceQuery(publicSession, SYS_SV_LITERAL("/Init/BootstrapProbe"), &kind);
if (!KSUCCESS(status) || kind != NTL_RESOURCE_KIND_VOLUME) {
status = KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
goto cleanup;
}
for (;;) {
NTL_RESOURCE_ENUM_ENTRY entry;
status = NtlResourceEnumerate(publicSession, SYS_SV_LITERAL("/Init"), &cursor, &entry);
if (status == NTLSTATUS_NO_MORE_FILES) {
status = NTLSTATUS_SUCCESS;
break;
}
if (!KSUCCESS(status)) goto cleanup;
if (strcmp(entry.Name, "SystemRoot") == 0 && entry.Kind == NTL_RESOURCE_KIND_SYMBOLIC_LINK)
sawAlias = 1;
if (strcmp(entry.Name, "BootstrapProbe") == 0 && entry.Kind == NTL_RESOURCE_KIND_VOLUME)
sawProbe = 1;
}
if (!sawAlias || !sawProbe) {
status = NTLSTATUS_FAILURE;
goto cleanup;
}
status = NtlResourceUnbind(admin, SYS_SV_LITERAL("/Init/BootstrapProbe"));
if (!KSUCCESS(status)) goto cleanup;
probeBound = 0;
kind = NTL_RESOURCE_KIND_INVALID;
if (NtlResourceQuery(publicSession, SYS_SV_LITERAL("/Init/BootstrapProbe"), &kind) != NTLSTATUS_NOT_FOUND) {
status = NTLSTATUS_FAILURE;
goto cleanup;
}
cleanup:
if (consoleAlias != SYS_HANDLE_INVALID) (void)SysCloseHandle(consoleAlias);
if (displayDevice != SYS_HANDLE_INVALID) (void)SysCloseHandle(displayDevice);
if (volume != SYS_HANDLE_INVALID) (void)SysCloseHandle(volume);
if (publicSession != SYS_HANDLE_INVALID) (void)NtlResourceClose(publicSession);
if (probeBound) (void)NtlResourceUnbind(admin, SYS_SV_LITERAL("/Init/BootstrapProbe"));
if (aliasCreated) {
KSTATUS cleanupStatus = NtlResourceUnbind(admin, SYS_SV_LITERAL("/Init/SystemRoot"));
if (KSUCCESS(status) && !KSUCCESS(cleanupStatus)) status = cleanupStatus;
}
if (initDirectoryCreated) {
KSTATUS cleanupStatus = NtlResourceUnbind(admin, SYS_SV_LITERAL("/Init"));
if (KSUCCESS(status) && !KSUCCESS(cleanupStatus)) status = cleanupStatus;
}
(void)NtlResourceClose(admin);
return status;
}
// Tears down retained RSSRV-specific and generic handles without sending a stop message.
static void close_resource_service(INIT_RESOURCE_SERVICE* resourceService) {
if (!resourceService) return;
if (resourceService->AdminListener != SYS_HANDLE_INVALID)
(void)SysCloseHandle(resourceService->AdminListener);
if (resourceService->SessionControlListener != SYS_HANDLE_INVALID)
(void)SysCloseHandle(resourceService->SessionControlListener);
resourceService->AdminListener = SYS_HANDLE_INVALID;
resourceService->SessionControlListener = SYS_HANDLE_INVALID;
close_service_handles(&resourceService->Service);
}
// Initializes the RSSRV-specific extension of one managed-service runtime.
static void initialize_resource_service(INIT_RESOURCE_SERVICE* resourceService,
const INIT_SERVICE_DESCRIPTOR* descriptor) {
memset(resourceService, 0, sizeof(*resourceService));
initialize_service(&resourceService->Service, descriptor);
resourceService->AdminListener = SYS_HANDLE_INVALID;
resourceService->SessionControlListener = SYS_HANDLE_INVALID;
}
// Starts one restricted RSSRV instance through the generic managed-service process path.
static KSTATUS start_resource_service(SYS_HANDLE systemVolume,
SYS_HANDLE namespaceVolume,
SYS_HANDLE volumeManager,
SYS_HANDLE inputManager,
SYS_HANDLE displayManager,
SYS_HANDLE resourceContext,
INIT_RESOURCE_SERVICE* resourceService) {
if (!resourceService || !resourceService->Service.Descriptor ||
resourceService->Service.Descriptor->Type != InitServiceTypeResource ||
resourceService->AdminListener != SYS_HANDLE_INVALID)
return NTLSTATUS_INVALID_PARAMETER;
NTL_PROCESS_STARTUP_CAPABILITY startup[4];
memset(startup, 0, sizeof(startup));
startup[0].Tag = SYS_STARTUP_CAP_SYSTEM_VOLUME_NAMESPACE;
startup[0].SourceHandle = namespaceVolume;
startup[0].DesiredRights = SYS_RIGHT_QUERY | SYS_RIGHT_TRANSFER |
SYS_VOLUME_RIGHT_OPEN | SYS_VOLUME_RIGHT_MODIFY;
startup[0].DuplicateFlags = SYS_DUPLICATE_HANDLE_FLAG_NONE;
startup[1].Tag = SYS_STARTUP_CAP_VOLUME_MANAGER;
startup[1].SourceHandle = volumeManager;
startup[1].DesiredRights = SYS_RIGHT_QUERY |
SYS_VOLUME_MANAGER_RIGHT_ENUMERATE | SYS_VOLUME_MANAGER_RIGHT_OPEN |
SYS_VOLUME_MANAGER_RIGHT_WAIT;
startup[1].DuplicateFlags = SYS_DUPLICATE_HANDLE_FLAG_NONE;
startup[2].Tag = SYS_STARTUP_CAP_INPUT_MANAGER;
startup[2].SourceHandle = inputManager;
startup[2].DesiredRights = SYS_RIGHT_QUERY | SYS_INPUT_MANAGER_RIGHT_READ;
startup[2].DuplicateFlags = SYS_DUPLICATE_HANDLE_FLAG_NONE;
startup[3].Tag = SYS_STARTUP_CAP_DISPLAY_MANAGER;
startup[3].SourceHandle = displayManager;
startup[3].DesiredRights = SYS_RIGHT_DERIVE | SYS_RIGHT_TRANSFER | SYS_RIGHT_QUERY | SYS_DISPLAY_MANAGER_RIGHT_ENUMERATE |
SYS_DISPLAY_MANAGER_RIGHT_MODESET | SYS_DISPLAY_MANAGER_RIGHT_CONSOLE;
startup[3].DuplicateFlags = SYS_DUPLICATE_HANDLE_FLAG_NONE;
KSTATUS status = start_service_process(systemVolume, resourceContext, startup, 4,
&resourceService->Service);
if (!KSUCCESS(status)) return status;
SYS_HANDLE adminListener = SYS_HANDLE_INVALID;
SYS_HANDLE sessionControlListener = SYS_HANDLE_INVALID;
status = wait_resource_service_ready(&resourceService->Service, &adminListener, &sessionControlListener);
if (KSUCCESS(status))
status = verify_resource_service(adminListener, namespaceVolume);
if (!KSUCCESS(status)) {
if (adminListener != SYS_HANDLE_INVALID) (void)SysCloseHandle(adminListener);
if (sessionControlListener != SYS_HANDLE_INVALID) (void)SysCloseHandle(sessionControlListener);
debug_early_service_exit(&resourceService->Service);
(void)SysKillProcess(resourceService->Service.Process, 1);
(void)SysWait(resourceService->Service.Process, SYS_WAIT_FLAG_NONE);
close_service_handles(&resourceService->Service);
resourceService->Service.State = InitServiceFailed;
return status;
}
resourceService->AdminListener = adminListener;
resourceService->SessionControlListener = sessionControlListener;
resourceService->Service.State = InitServiceReady;
return NTLSTATUS_SUCCESS;
}
// Publishes DWM's desktop listener at the stable Session 0 desktop resource path.
static KSTATUS publish_dwm_desktop(SYS_HANDLE adminListener, SYS_HANDLE desktopListener) {
if (adminListener == SYS_HANDLE_INVALID || desktopListener == SYS_HANDLE_INVALID)
return NTLSTATUS_INVALID_PARAMETER;
SYS_HANDLE admin = SYS_HANDLE_INVALID;
KSTATUS status = NtlResourceConnectListener(adminListener, &admin);
if (!KSUCCESS(status)) return status;
status = NtlResourceBind(admin, SYS_SV_LITERAL(NTL_DESKTOP_SERVICE_PATH),
NTL_RESOURCE_KIND_CAPABILITY, desktopListener,
SYS_RIGHT_TRANSFER | SYS_RIGHT_QUERY | SYS_PORT_RIGHT_CONNECT,
SYS_RIGHT_QUERY | SYS_PORT_RIGHT_CONNECT);
(void)NtlResourceClose(admin);
return status;
}
// Removes DWM's public desktop endpoint while retaining Session 0 itself inside RSSRV.
static void unpublish_dwm_desktop(SYS_HANDLE adminListener) {
if (adminListener == SYS_HANDLE_INVALID) return;
SYS_HANDLE admin = SYS_HANDLE_INVALID;
if (!KSUCCESS(NtlResourceConnectListener(adminListener, &admin))) return;
(void)NtlResourceUnbind(admin, SYS_SV_LITERAL(NTL_DESKTOP_SERVICE_PATH));
(void)NtlResourceClose(admin);
}
// Starts one DWM instance with physical presentation, cursor policy, and attenuated Session 0 authority.
static KSTATUS start_dwm_service(SYS_HANDLE systemVolume,
SYS_HANDLE displayManager,
SYS_HANDLE securityContext,
const INIT_RESOURCE_SERVICE* resourceService,
INIT_SERVICE* service) {
if (!resourceService || !service || !service->Descriptor || service->Descriptor->Type != InitServiceTypeDwm ||
displayManager == SYS_HANDLE_INVALID || securityContext == SYS_HANDLE_INVALID ||
resourceService->AdminListener == SYS_HANDLE_INVALID ||
resourceService->SessionControlListener == SYS_HANDLE_INVALID)
return NTLSTATUS_INVALID_PARAMETER;
NTL_PROCESS_STARTUP_CAPABILITY startup[2];
memset(startup, 0, sizeof(startup));
startup[0].Tag = SYS_STARTUP_CAP_DISPLAY_MANAGER;
startup[0].SourceHandle = displayManager;
startup[0].DesiredRights = SYS_RIGHT_QUERY | SYS_DISPLAY_MANAGER_RIGHT_ENUMERATE |
SYS_DISPLAY_MANAGER_RIGHT_PRESENT | SYS_DISPLAY_MANAGER_RIGHT_CURSOR;
startup[0].DuplicateFlags = SYS_DUPLICATE_HANDLE_FLAG_NONE;
startup[1].Tag = SYS_STARTUP_CAP_SESSION_CONTROL;
startup[1].SourceHandle = resourceService->SessionControlListener;
startup[1].DesiredRights = SYS_RIGHT_QUERY | SYS_PORT_RIGHT_CONNECT;
startup[1].DuplicateFlags = SYS_DUPLICATE_HANDLE_FLAG_NONE;
KSTATUS status = start_service_process(systemVolume, securityContext, startup, 2u, service);
if (!KSUCCESS(status)) {
debug_print("[init] DWM spawn/delegation failed: ");
debug_status(status);
debug_print("\n");
return status;
}
SYS_HANDLE exports[1] = { SYS_HANDLE_INVALID };
uint32_t exportCount = 0;
status = wait_service_ready(service, exports, 1u, &exportCount);
if (!KSUCCESS(status)) {
debug_print("[init] DWM READY wait failed: ");
debug_status(status);
debug_print("\n");
} else if (exportCount != 1u || exports[0] == SYS_HANDLE_INVALID) {
debug_print("[init] DWM READY contract invalid\n");
status = NTLSTATUS_FAILURE;
} else {
status = publish_dwm_desktop(resourceService->AdminListener, exports[0]);
if (!KSUCCESS(status)) {
debug_print("[init] DWM desktop publication failed: ");
debug_status(status);
debug_print("\n");
}
}
if (exports[0] != SYS_HANDLE_INVALID) (void)SysCloseHandle(exports[0]);
if (!KSUCCESS(status)) {
debug_early_service_exit(service);
(void)SysKillProcess(service->Process, 1);
(void)SysWait(service->Process, SYS_WAIT_FLAG_NONE);
close_service_handles(service);
service->State = InitServiceFailed;
return status;
}
service->State = InitServiceReady;
return NTLSTATUS_SUCCESS;
}
// Builds the canonical RSSRV publication path for one generic service identifier.
static KSTATUS build_generic_service_path(const INIT_SERVICE_DESCRIPTOR* descriptor,
char* pathOut,
size_t pathCapacity) {
static const char prefix[] = "/Services/";
if (!descriptor || !pathOut || pathCapacity == 0) return NTLSTATUS_INVALID_PARAMETER;
size_t prefixLength = sizeof(prefix) - 1u;
size_t idLength = strlen(descriptor->Id);
if (idLength == 0 || prefixLength + idLength + 1u > pathCapacity)
return NTLSTATUS_NAME_TOO_LONG;
memcpy(pathOut, prefix, prefixLength);
memcpy(pathOut + prefixLength, descriptor->Id, idLength + 1u);
return NTLSTATUS_SUCCESS;
}
// Publishes one generic service listener through RSSRV rather than the kernel service registry.
static KSTATUS publish_generic_service(SYS_HANDLE adminListener,
const INIT_SERVICE_DESCRIPTOR* descriptor,
SYS_HANDLE publicListener) {
if (adminListener == SYS_HANDLE_INVALID || !descriptor || publicListener == SYS_HANDLE_INVALID)
return NTLSTATUS_INVALID_PARAMETER;
char path[64];
KSTATUS status = build_generic_service_path(descriptor, path, sizeof(path));
if (!KSUCCESS(status)) return status;
SYS_HANDLE admin = SYS_HANDLE_INVALID;
status = NtlResourceConnectListener(adminListener, &admin);
if (!KSUCCESS(status)) return status;
status = NtlResourceBind(admin, SysSvFromCstr(path), NTL_RESOURCE_KIND_CAPABILITY,
publicListener,
SYS_RIGHT_TRANSFER | SYS_RIGHT_QUERY | SYS_PORT_RIGHT_CONNECT,
SYS_RIGHT_QUERY | SYS_PORT_RIGHT_CONNECT);
(void)NtlResourceClose(admin);
return status;
}
// Removes one generic service publication before its process is stopped or forgotten.
static void unpublish_generic_service(SYS_HANDLE adminListener,
const INIT_SERVICE_DESCRIPTOR* descriptor) {
if (adminListener == SYS_HANDLE_INVALID || !descriptor) return;
char path[64];
if (!KSUCCESS(build_generic_service_path(descriptor, path, sizeof(path)))) return;
SYS_HANDLE admin = SYS_HANDLE_INVALID;
if (!KSUCCESS(NtlResourceConnectListener(adminListener, &admin))) return;
(void)NtlResourceUnbind(admin, SysSvFromCstr(path));
(void)NtlResourceClose(admin);
}
// Starts one generic service, validates its READY listener export, and publishes it through RSSRV.
static KSTATUS start_generic_service(SYS_HANDLE systemVolume,
SYS_HANDLE securityContext,
const INIT_RESOURCE_SERVICE* resourceService,
INIT_SERVICE* service) {
if (!resourceService || !service || !service->Descriptor ||
service->Descriptor->Type != InitServiceTypeGeneric ||
resourceService->AdminListener == SYS_HANDLE_INVALID)
return NTLSTATUS_INVALID_PARAMETER;
KSTATUS status = start_service_process(systemVolume, securityContext, (const NTL_PROCESS_STARTUP_CAPABILITY*)0,
0u, service);
if (!KSUCCESS(status)) return status;
SYS_HANDLE exports[1] = { SYS_HANDLE_INVALID };
uint32_t exportCount = 0;
status = wait_service_ready(service, exports, 1u, &exportCount);
if (KSUCCESS(status) && (exportCount != 1u || exports[0] == SYS_HANDLE_INVALID))
status = NTLSTATUS_FAILURE;
if (KSUCCESS(status))
status = publish_generic_service(resourceService->AdminListener, service->Descriptor, exports[0]);
if (exports[0] != SYS_HANDLE_INVALID) (void)SysCloseHandle(exports[0]);
if (!KSUCCESS(status)) {
debug_early_service_exit(service);
(void)SysKillProcess(service->Process, 1);
(void)SysWait(service->Process, SYS_WAIT_FLAG_NONE);
close_service_handles(service);
service->State = InitServiceFailed;
return status;
}
service->State = InitServiceReady;
return NTLSTATUS_SUCCESS;
}
// Requests graceful shutdown of one managed service, falling back to process termination.
static void stop_service(INIT_SERVICE* service) {
if (!service || service->Process == SYS_HANDLE_INVALID) return;
service->State = InitServiceStopping;
NTL_SERVICE_CONTROL_MESSAGE message;
memset(&message, 0, sizeof(message));
message.Size = sizeof(message);
message.Version = NTL_SERVICE_CONTROL_VERSION;
message.Operation = NTL_SERVICE_CONTROL_STOP;
message.ExportCount = 0;
SYS_SEND_PORT_REQUEST send;
memset(&send, 0, sizeof(send));
send.Size = sizeof(send);
send.EndpointHandle = service->ControlEndpoint;
send.Flags = SYS_PORT_FLAG_NONE;
send.Payload = &message;
send.PayloadLength = sizeof(message);
send.TimeoutMilliseconds = service->Descriptor->StopTimeoutMilliseconds;
(void)SysSendPort(&send);
KSTATUS status = SysWaitSingle(service->Process, SYS_WAIT_FLAG_NONE,
service->Descriptor->StopTimeoutMilliseconds);
if (!KSUCCESS(status)) {
(void)SysKillProcess(service->Process, 1);
(void)SysWait(service->Process, SYS_WAIT_FLAG_NONE);
}
close_service_handles(service);
service->State = InitServiceStopped;
}
// Unpublishes and stops DWM so new desktop connections cannot race service teardown.
static void stop_dwm_service(INIT_RESOURCE_SERVICE* resourceService, INIT_SERVICE* service) {
if (!resourceService || !service || service->State != InitServiceReady) return;
unpublish_dwm_desktop(resourceService->AdminListener);
stop_service(service);
}
// Unpublishes and stops one generic service before RSSRV namespace teardown.
static void stop_generic_service(const INIT_RESOURCE_SERVICE* resourceService, INIT_SERVICE* service) {
if (!resourceService || !service || service->State != InitServiceReady) return;
unpublish_generic_service(resourceService->AdminListener, service->Descriptor);
stop_service(service);
}
// Stops ready generic services in reverse dependency order.
static void stop_generic_services(const INIT_RESOURCE_SERVICE* resourceService,
INIT_SERVICE* services) {
if (!resourceService || !services) return;
for (uint32_t order = gServiceConfig.StartupCount; order > 0; --order) {
uint16_t index = gServiceConfig.StartupOrder[order - 1u];
if (gServiceConfig.Services[index].Type == InitServiceTypeGeneric)
stop_generic_service(resourceService, &services[index]);
}
}
// Requests graceful RSSRV shutdown and releases its private administrative export.
static void stop_resource_service(INIT_RESOURCE_SERVICE* resourceService) {
if (!resourceService) return;
stop_service(&resourceService->Service);
if (resourceService->AdminListener != SYS_HANDLE_INVALID)
(void)SysCloseHandle(resourceService->AdminListener);
if (resourceService->SessionControlListener != SYS_HANDLE_INVALID)
(void)SysCloseHandle(resourceService->SessionControlListener);
resourceService->AdminListener = SYS_HANDLE_INVALID;
resourceService->SessionControlListener = SYS_HANDLE_INVALID;
}
// Starts the configured native session process from the system-volume capability.
static KSTATUS start_configured_child(SYS_HANDLE systemVolume, SYS_STRING_VIEW path, SYS_HANDLE* processOut) {
NTL_CREATE_PROCESS_AT_REQUEST create;
memset(&create, 0, sizeof(create));
create.Size = sizeof(create);
create.Flags = NTL_PROCESS_LOAD_FLAG_NONE;
create.RootHandle = systemVolume;
create.Path = path;
create.CommandLine = path;
create.SecurityContext = SYS_SECURITY_CONTEXT_CURRENT;
create.ModuleRootHandle = systemVolume;
create.ModuleDirectory = SYS_SV_LITERAL("system");
create.ResolveModuleName = NtlResolveSystemModuleName;
create.ProcessHandleOut = processOut;
return NtlCreateProcessAt(&create);
}
// Best-effort diagnostic name for init's current thread.
static void init_set_current_thread_name(const char* name) {
SYS_SET_THREAD_NAME_REQUEST request;
memset(&request, 0, sizeof(request));
request.Size = sizeof(request);
request.ThreadHandle = SYS_HANDLE_INVALID;
request.Name = SysSvFromCstr(name);
(void)SysSetThreadName(&request);
}
// Initializes init state and supervises configured services plus the native session process.
void _start(void) {
KSTATUS status = NtlInitializeExceptionRuntime();
if (!KSUCCESS(status)) exit_now((int)status);
init_set_current_thread_name("init.main");
SYS_HANDLE systemVolume = SysGetStartupCapability(SYS_STARTUP_CAP_SYSTEM_VOLUME);
SYS_HANDLE namespaceVolume = SysGetStartupCapability(SYS_STARTUP_CAP_SYSTEM_VOLUME_NAMESPACE);
SYS_HANDLE volumeManager = SysGetStartupCapability(SYS_STARTUP_CAP_VOLUME_MANAGER);
SYS_HANDLE inputManager = SysGetStartupCapability(SYS_STARTUP_CAP_INPUT_MANAGER);
SYS_HANDLE displayManager = SysGetStartupCapability(SYS_STARTUP_CAP_DISPLAY_MANAGER);
if (systemVolume == SYS_HANDLE_INVALID || namespaceVolume == SYS_HANDLE_INVALID ||
volumeManager == SYS_HANDLE_INVALID || inputManager == SYS_HANDLE_INVALID ||
displayManager == SYS_HANDLE_INVALID) {
debug_print("[init] FATAL: bootstrap resource-plane capability missing\n");
exit_now(1);
}
uint32_t configErrorLine = 0;
status = InitLoadServiceConfig(systemVolume, &gServiceConfig, &configErrorLine);
if (!KSUCCESS(status)) {
debug_print("[init] FATAL: invalid or unreadable services.ini");
if (configErrorLine != 0u) {
debug_print(" at line ");
debug_u32(configErrorLine);
}
debug_print(": ");
debug_status(status);
debug_print("\n");
exit_now(1);
}
SYS_HANDLE resourceContext = SYS_HANDLE_INVALID;
status = derive_resource_service_context(&resourceContext);
if (!KSUCCESS(status)) {
debug_print("[init] FATAL: cannot derive RSSRV security context: ");
debug_status(status);
debug_print("\n");
exit_now(1);
}
SYS_HANDLE unprivilegedServiceContext = SYS_HANDLE_INVALID;
status = derive_unprivileged_service_context(&unprivilegedServiceContext);
if (!KSUCCESS(status)) {
debug_print("[init] FATAL: cannot derive unprivileged service context: ");
debug_status(status);
debug_print("\n");
(void)SysCloseHandle(resourceContext);
exit_now(1);
}
SYS_STRING_VIEW childPath = SysGetPeb()->CommandLine;
if (!childPath.Data || childPath.Length == 0) {
debug_print("[init] FATAL: no configured session process\n");
if (unprivilegedServiceContext != SYS_HANDLE_INVALID) (void)SysCloseHandle(unprivilegedServiceContext);
(void)SysCloseHandle(resourceContext);
exit_now(1);
}
INIT_RESOURCE_SERVICE resourceService;
initialize_resource_service(&resourceService,
&gServiceConfig.Services[gServiceConfig.ResourceServiceIndex]);
INIT_SERVICE dwmService;
memset(&dwmService, 0, sizeof(dwmService));
if (gServiceConfig.DwmServiceIndex != UINT16_MAX)
initialize_service(&dwmService, &gServiceConfig.Services[gServiceConfig.DwmServiceIndex]);
else {
dwmService.Process = SYS_HANDLE_INVALID;
dwmService.ControlEndpoint = SYS_HANDLE_INVALID;
dwmService.State = InitServiceStopped;
}
INIT_SERVICE genericServices[INIT_SERVICE_MAX_COUNT];
memset(genericServices, 0, sizeof(genericServices));
uint32_t automaticGenericCount = 0;
for (uint32_t i = 0; i < gServiceConfig.ServiceCount; ++i) {
if (gServiceConfig.Services[i].Type != InitServiceTypeGeneric) continue;
initialize_service(&genericServices[i], &gServiceConfig.Services[i]);
if (gServiceConfig.Services[i].StartPolicy == InitServiceStartAuto) ++automaticGenericCount;
}
if (automaticGenericCount + 3u > SYS_WAIT_MANY_MAX_HANDLES) {
debug_print("[init] FATAL: too many automatic generic services for supervision wait set\n");
(void)SysCloseHandle(unprivilegedServiceContext);
(void)SysCloseHandle(resourceContext);
exit_now(1);
}
for (uint32_t order = 0; order < gServiceConfig.StartupCount; ++order) {
uint16_t index = gServiceConfig.StartupOrder[order];
const INIT_SERVICE_DESCRIPTOR* descriptor = &gServiceConfig.Services[index];
if (descriptor->Type == InitServiceTypeResource) {
status = start_resource_service(systemVolume, namespaceVolume, volumeManager, inputManager,
displayManager, resourceContext, &resourceService);
if (!KSUCCESS(status)) {
debug_print("[init] FATAL: RSSRV startup failed: ");
debug_status(status);
debug_print("\n");
if (unprivilegedServiceContext != SYS_HANDLE_INVALID) (void)SysCloseHandle(unprivilegedServiceContext);
(void)SysCloseHandle(resourceContext);
exit_now(1);
}
debug_print("[init] RSSRV ready\n");
} else if (descriptor->Type == InitServiceTypeDwm) {
status = start_dwm_service(systemVolume, displayManager, unprivilegedServiceContext, &resourceService, &dwmService);
if (!KSUCCESS(status)) {
debug_print("[init] noncritical DWM startup failed: ");
debug_status(status);
debug_print("\n");
} else {
debug_print("[init] DWM ready\n");
}
} else if (descriptor->Type == InitServiceTypeGeneric) {
status = start_generic_service(systemVolume, unprivilegedServiceContext, &resourceService,
&genericServices[index]);
if (!KSUCCESS(status)) {
debug_print("[init] noncritical generic service startup failed: ");
debug_print(descriptor->Id);
debug_print(" status=");
debug_status(status);
debug_print("\n");
} else {
debug_print("[init] generic service ready: ");
debug_print(descriptor->Id);
debug_print("\n");
}
}
}
if (resourceService.Service.State != InitServiceReady) {
debug_print("[init] FATAL: configured resource service was not started\n");
if (dwmService.State == InitServiceReady) stop_dwm_service(&resourceService, &dwmService);
stop_generic_services(&resourceService, genericServices);
if (unprivilegedServiceContext != SYS_HANDLE_INVALID) (void)SysCloseHandle(unprivilegedServiceContext);
(void)SysCloseHandle(resourceContext);
exit_now(1);
}
for (;;) {
SYS_HANDLE child = SYS_HANDLE_INVALID;
status = start_configured_child(systemVolume, childPath, &child);
if (!KSUCCESS(status)) {
debug_print("[init] FATAL: failed to start configured child: ");
debug_status(status);
debug_print("\n");
if (dwmService.State == InitServiceReady) stop_dwm_service(&resourceService, &dwmService);
stop_generic_services(&resourceService, genericServices);
stop_resource_service(&resourceService);
if (unprivilegedServiceContext != SYS_HANDLE_INVALID) (void)SysCloseHandle(unprivilegedServiceContext);
(void)SysCloseHandle(resourceContext);
exit_now(1);
}
debug_print("[init] session process started\n");
bool restartChild = false;
for (;;) {
SYS_HANDLE waits[SYS_WAIT_MANY_MAX_HANDLES];
uint32_t kinds[SYS_WAIT_MANY_MAX_HANDLES];
uint32_t waitCount = 0;
waits[waitCount] = resourceService.Service.Process;
kinds[waitCount++] = 0u;
if (dwmService.State == InitServiceReady && dwmService.Process != SYS_HANDLE_INVALID) {
waits[waitCount] = dwmService.Process;
kinds[waitCount++] = 1u;
}
waits[waitCount] = child;
kinds[waitCount++] = 2u;
for (uint32_t i = 0; i < gServiceConfig.ServiceCount; ++i) {
if (gServiceConfig.Services[i].Type != InitServiceTypeGeneric ||
genericServices[i].State != InitServiceReady ||
genericServices[i].Process == SYS_HANDLE_INVALID)
continue;
waits[waitCount] = genericServices[i].Process;
kinds[waitCount++] = 3u + i;
}
uint32_t signaled = 0;
SYS_WAIT_MANY_REQUEST wait;
memset(&wait, 0, sizeof(wait));
wait.Size = sizeof(wait);
wait.Flags = SYS_WAIT_FLAG_NONE;
wait.Handles = waits;
wait.Count = waitCount;
wait.SignaledIndexOut = &signaled;
wait.TimeoutMilliseconds = SYS_WAIT_TIMEOUT_INFINITE;
status = SysWaitMany(&wait);
if (!KSUCCESS(status)) {
(void)SysKillProcess(child, 1);
(void)SysWait(child, SYS_WAIT_FLAG_NONE);
(void)SysCloseHandle(child);
if (dwmService.State == InitServiceReady) stop_dwm_service(&resourceService, &dwmService);
stop_generic_services(&resourceService, genericServices);
stop_resource_service(&resourceService);
if (unprivilegedServiceContext != SYS_HANDLE_INVALID) (void)SysCloseHandle(unprivilegedServiceContext);
(void)SysCloseHandle(resourceContext);
debug_print("[init] FATAL: service wait failed\n");
exit_now(1);
}
if (kinds[signaled] == 0u) {
int32_t serviceExit = -1;
(void)SysGetProcessExitCode(resourceService.Service.Process, &serviceExit);
resourceService.Service.State = InitServiceFailed;
debug_print("[init] FATAL: critical RSSRV exited unexpectedly: ");
debug_i32(serviceExit);
debug_print("\n");
(void)SysKillProcess(child, 1);
(void)SysWait(child, SYS_WAIT_FLAG_NONE);
(void)SysCloseHandle(child);
if (dwmService.State == InitServiceReady) stop_dwm_service(&resourceService, &dwmService);
for (uint32_t i = 0; i < gServiceConfig.ServiceCount; ++i) {
if (gServiceConfig.Services[i].Type == InitServiceTypeGeneric &&
genericServices[i].Process != SYS_HANDLE_INVALID) {
(void)SysKillProcess(genericServices[i].Process, 1);
(void)SysWait(genericServices[i].Process, SYS_WAIT_FLAG_NONE);
close_service_handles(&genericServices[i]);
genericServices[i].State = InitServiceFailed;
}
}
close_resource_service(&resourceService);
if (unprivilegedServiceContext != SYS_HANDLE_INVALID) (void)SysCloseHandle(unprivilegedServiceContext);
(void)SysCloseHandle(resourceContext);
exit_now(1);
}
if (kinds[signaled] == 1u) {
int32_t serviceExit = -1;
(void)SysGetProcessExitCode(dwmService.Process, &serviceExit);
debug_print("[init] noncritical DWM exited unexpectedly: ");
debug_i32(serviceExit);
debug_print("\n");
unpublish_dwm_desktop(resourceService.AdminListener);
close_service_handles(&dwmService);
dwmService.State = InitServiceFailed;
continue;
}
if (kinds[signaled] >= 3u) {
uint32_t index = kinds[signaled] - 3u;
INIT_SERVICE* generic = &genericServices[index];
int32_t serviceExit = -1;
(void)SysGetProcessExitCode(generic->Process, &serviceExit);
debug_print("[init] noncritical generic service exited unexpectedly: ");
debug_print(generic->Descriptor->Id);
debug_print(" code=");
debug_i32(serviceExit);
debug_print("\n");
unpublish_generic_service(resourceService.AdminListener, generic->Descriptor);
close_service_handles(generic);
generic->State = InitServiceFailed;
continue;
}
int32_t exitCode = -1;
status = SysGetProcessExitCode(child, &exitCode);
(void)SysCloseHandle(child);
child = SYS_HANDLE_INVALID;
if (!KSUCCESS(status)) exitCode = 1;
if (exitCode == 0) {
if (dwmService.State == InitServiceReady) stop_dwm_service(&resourceService, &dwmService);
stop_generic_services(&resourceService, genericServices);
stop_resource_service(&resourceService);
debug_print("[init] done\n");
if (unprivilegedServiceContext != SYS_HANDLE_INVALID) (void)SysCloseHandle(unprivilegedServiceContext);
(void)SysCloseHandle(resourceContext);
exit_now(0);
}
debug_print("[init] session process crashed; restarting\n");
restartChild = true;
break;
}
if (!restartChild) break;
}
exit_now(1);
}