// Init service manager. The kernel bootstraps only init; init starts and supervises user-mode system services. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "service_config.h" #include "restart_budget.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; static INIT_SERVICE_CONFIG gServiceConfig; static INIT_SERVICE gServices[INIT_SERVICE_MAX_COUNT]; // Capability sources are referenced by name; the catalog owns READY handles // and borrows kernel-provided bootstrap handles for the lifetime of init. typedef struct INIT_GRANT_SOURCE { char Name[SYS_STARTUP_CAPABILITY_NAME_MAX + 1u]; SYS_HANDLE Handle; SYS_RIGHTS RightsCeiling; const INIT_SERVICE_DESCRIPTOR* Provider; bool OwnsHandle; } INIT_GRANT_SOURCE; #define INIT_GRANT_SOURCE_MAX (8u + INIT_SERVICE_MAX_COUNT * SYS_PORT_MAX_TRANSFER_HANDLES) static INIT_GRANT_SOURCE gGrantSources[INIT_GRANT_SOURCE_MAX]; static uint32_t gGrantSourceCount; // Records one source and its strict rights ceiling without granting any authority. static KSTATUS add_grant_source(const char* name, SYS_HANDLE handle, SYS_RIGHTS rights, const INIT_SERVICE_DESCRIPTOR* provider, bool ownsHandle) { if (!name || !name[0] || handle == SYS_HANDLE_INVALID || !rights || gGrantSourceCount >= INIT_GRANT_SOURCE_MAX) return NTLSTATUS_INVALID_PARAMETER; size_t length = strlen(name); if (length > SYS_STARTUP_CAPABILITY_NAME_MAX) return NTLSTATUS_NAME_TOO_LONG; for (uint32_t i = 0; i < gGrantSourceCount; ++i) if (strcmp(gGrantSources[i].Name, name) == 0) return NTLSTATUS_OBJECT_NAME_COLLISION; INIT_GRANT_SOURCE* source = &gGrantSources[gGrantSourceCount++]; memset(source, 0, sizeof(*source)); memcpy(source->Name, name, length + 1u); source->Handle = handle; source->RightsCeiling = rights; source->Provider = provider; source->OwnsHandle = ownsHandle; return NTLSTATUS_SUCCESS; } // Drops all sources exported by a service generation before its handles expire. static void forget_service_grants(const INIT_SERVICE_DESCRIPTOR* provider) { if (!provider) return; for (uint32_t i = 0; i < gGrantSourceCount;) { INIT_GRANT_SOURCE* source = &gGrantSources[i]; if (source->Provider != provider) { ++i; continue; } if (source->OwnsHandle && source->Handle != SYS_HANDLE_INVALID) (void)SysCloseHandle(source->Handle); gGrantSources[i] = gGrantSources[--gGrantSourceCount]; memset(&gGrantSources[gGrantSourceCount], 0, sizeof(gGrantSources[0])); } } // Keeps the named READY exports for subsequent dependent services. Ownership of // an export handle passes to the catalog only when retainHandles is true. static KSTATUS register_ready_exports(const INIT_SERVICE_DESCRIPTOR* provider, const NTL_SERVICE_CONTROL_MESSAGE* message, const SYS_HANDLE* handles, uint32_t count, bool retainHandles) { if (!provider || !message || count != message->ExportCount) return NTLSTATUS_INVALID_PARAMETER; if (gGrantSourceCount + count > INIT_GRANT_SOURCE_MAX) return NTLSTATUS_LIMIT_REACHED; char names[SYS_PORT_MAX_TRANSFER_HANDLES][SYS_STARTUP_CAPABILITY_NAME_MAX + 1u]; for (uint32_t i = 0; i < count; ++i) { size_t left = strlen(provider->Id), right = strlen(message->ExportNames[i]); if (left + right + 1u > SYS_STARTUP_CAPABILITY_NAME_MAX || handles[i] == SYS_HANDLE_INVALID) return NTLSTATUS_INVALID_PARAMETER; memcpy(names[i], provider->Id, left); names[i][left] = '.'; memcpy(names[i] + left + 1u, message->ExportNames[i], right + 1u); for (uint32_t j = 0; j < gGrantSourceCount; ++j) if (strcmp(names[i], gGrantSources[j].Name) == 0) return NTLSTATUS_OBJECT_NAME_COLLISION; } for (uint32_t i = 0; i < count; ++i) { KSTATUS status = add_grant_source(names[i], handles[i], SYS_RIGHT_QUERY | SYS_PORT_RIGHT_CONNECT, provider, retainHandles); if (!KSUCCESS(status)) { // All names and available capacity were validated before mutation. forget_service_grants(provider); return status; } } return NTLSTATUS_SUCCESS; } // Populates the trusted bootstrap catalog from kernel-issued, init-owned handles. static KSTATUS initialize_boot_grants(SYS_HANDLE namespaceVolume, SYS_HANDLE volumeManager, SYS_HANDLE inputManager, SYS_HANDLE displayManager, SYS_HANDLE registrationAuthority) { gGrantSourceCount = 0; KSTATUS status; #define ADD_BOOT(name, handle, rights) \ do { status = add_grant_source(name, handle, rights, (const INIT_SERVICE_DESCRIPTOR*)0, false); \ if (!KSUCCESS(status)) return status; } while (0) ADD_BOOT(NTL_BOOT_CAP_NAMESPACE_ROOT, namespaceVolume, SYS_RIGHT_QUERY | SYS_RIGHT_TRANSFER | SYS_VOLUME_RIGHT_OPEN | SYS_VOLUME_RIGHT_MODIFY); ADD_BOOT(NTL_BOOT_CAP_VOLUME_MANAGER, volumeManager, SYS_RIGHT_QUERY | SYS_VOLUME_MANAGER_RIGHT_ENUMERATE | SYS_VOLUME_MANAGER_RIGHT_OPEN | SYS_VOLUME_MANAGER_RIGHT_WAIT); ADD_BOOT(NTL_BOOT_CAP_INPUT_MANAGER, inputManager, SYS_RIGHT_QUERY | SYS_INPUT_MANAGER_RIGHT_READ); ADD_BOOT(NTL_BOOT_CAP_DISPLAY_POLICY, displayManager, SYS_RIGHT_DERIVE | SYS_RIGHT_TRANSFER | SYS_RIGHT_QUERY | SYS_DISPLAY_MANAGER_RIGHT_ENUMERATE | SYS_DISPLAY_MANAGER_RIGHT_MODESET | SYS_DISPLAY_MANAGER_RIGHT_CONSOLE); ADD_BOOT(NTL_BOOT_CAP_DISPLAY_PRESENT, displayManager, SYS_RIGHT_QUERY | SYS_DISPLAY_MANAGER_RIGHT_ENUMERATE | SYS_DISPLAY_MANAGER_RIGHT_PRESENT | SYS_DISPLAY_MANAGER_RIGHT_CURSOR); ADD_BOOT(NTL_BOOT_CAP_RESOURCE_REGISTRATION, registrationAuthority, SYS_RIGHT_QUERY | SYS_SERVICE_REGISTRATION_RIGHT_REGISTER | SYS_SERVICE_REGISTRATION_RIGHT_UNREGISTER); #undef ADD_BOOT return NTLSTATUS_SUCCESS; } // Resolves configured names into attenuated child capabilities before creation. static KSTATUS resolve_service_grants(const INIT_SERVICE_DESCRIPTOR* descriptor, NTL_PROCESS_STARTUP_CAPABILITY* resolved, uint32_t* countOut) { if (!descriptor || !resolved || !countOut || descriptor->GrantCount >= SYS_STARTUP_CAPABILITY_MAX) return NTLSTATUS_INVALID_PARAMETER; *countOut = 0; for (uint32_t i = 0; i < descriptor->GrantCount; ++i) { const INIT_GRANT_SOURCE* found = (const INIT_GRANT_SOURCE*)0; for (uint32_t j = 0; j < gGrantSourceCount; ++j) if (strcmp(descriptor->Grants[i], gGrantSources[j].Name) == 0) { found = &gGrantSources[j]; break; } if (!found) return NTLSTATUS_NOT_FOUND; NTL_PROCESS_STARTUP_CAPABILITY* destination = &resolved[i]; memset(destination, 0, sizeof(*destination)); memcpy(destination->Name, found->Name, strlen(found->Name) + 1u); destination->SourceHandle = found->Handle; destination->DesiredRights = found->RightsCeiling; destination->DuplicateFlags = SYS_DUPLICATE_HANDLE_FLAG_NONE; ++*countOut; } return NTLSTATUS_SUCCESS; } // 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 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.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; forget_service_grants(service->Descriptor); 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, INIT_SERVICE* service) { if (!service || !service->Descriptor || service->Descriptor->ImagePath[0] == '\0' || service->Descriptor->GrantCount > SYS_STARTUP_CAPABILITY_MAX - 1u) 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)); uint32_t startupCapabilityCount = 0; status = resolve_service_grants(service->Descriptor, startup, &startupCapabilityCount); if (!KSUCCESS(status)) { (void)SysCloseHandle(controlListener); service->State = InitServiceFailed; return status; } memcpy(startup[startupCapabilityCount].Name, "service.control", sizeof("service.control")); startup[startupCapabilityCount].SourceHandle = controlListener; startup[startupCapabilityCount].DesiredRights = SYS_RIGHT_QUERY | SYS_PORT_RIGHT_ACCEPT; startup[startupCapabilityCount].DuplicateFlags = SYS_DUPLICATE_HANDLE_FLAG_NONE; uint32_t capabilityCount = startupCapabilityCount + 1u; 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 = capabilityCount; 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, NTL_SERVICE_CONTROL_MESSAGE* messageOut) { if (!service || !service->Descriptor || !exportCountOut || !messageOut || 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) && info.HandleCount <= exportCapacity && NtlServiceControlValid(&message, NTL_SERVICE_CONTROL_READY, info.HandleCount); 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; *messageOut = message; return NTLSTATUS_SUCCESS; } // Every service uses the same process, READY, export and failure path. static KSTATUS start_managed_service(SYS_HANDLE systemVolume, SYS_HANDLE securityContext, INIT_SERVICE* service) { KSTATUS status = start_service_process(systemVolume, securityContext, service); if (!KSUCCESS(status)) { debug_print("[init] process or startup grant creation failed for "); debug_print(service->Descriptor->Id); debug_print(": "); debug_status(status); debug_print("\n"); return status; } SYS_HANDLE handles[SYS_PORT_MAX_TRANSFER_HANDLES]; uint32_t count = 0; NTL_SERVICE_CONTROL_MESSAGE ready; status = wait_service_ready(service, handles, SYS_PORT_MAX_TRANSFER_HANDLES, &count, &ready); if (!KSUCCESS(status)) { debug_print("[init] READY receive failed for "); debug_print(service->Descriptor->Id); debug_print(": "); debug_status(status); debug_print("\n"); } if (KSUCCESS(status)) { const INIT_SERVICE_DESCRIPTOR* descriptor = service->Descriptor; if (count != descriptor->ExportCount) status = NTLSTATUS_INVALID_PARAMETER; for (uint32_t i = 0; KSUCCESS(status) && i < count; ++i) { bool declared = false; for (uint32_t j = 0; j < descriptor->ExportCount; ++j) if (strcmp(ready.ExportNames[i], descriptor->Exports[j]) == 0) declared = true; if (!declared || handles[i] == SYS_HANDLE_INVALID) status = NTLSTATUS_INVALID_PARAMETER; } if (KSUCCESS(status)) { status = register_ready_exports(descriptor, &ready, handles, count, true); if (KSUCCESS(status)) for (uint32_t i = 0; i < count; ++i) handles[i] = SYS_HANDLE_INVALID; } } for (uint32_t i = 0; i < count; ++i) if (handles[i] != SYS_HANDLE_INVALID) (void)SysCloseHandle(handles[i]); 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 STOP and bounds the fallback termination of any service. static void stop_service(INIT_SERVICE* service) { if (!service || service->Process == SYS_HANDLE_INVALID) return; service->State = InitServiceStopping; NTL_SERVICE_CONTROL_MESSAGE message = {0}; message.Size = sizeof(message); message.Version = NTL_SERVICE_CONTROL_VERSION; message.Operation = NTL_SERVICE_CONTROL_STOP; SYS_SEND_PORT_REQUEST send = {0}; send.Size = sizeof(send); send.EndpointHandle = service->ControlEndpoint; 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); status = SysWaitSingle(service->Process, SYS_WAIT_FLAG_NONE, 2000u); if (!KSUCCESS(status)) debug_print("[init] service termination timed out\n"); } close_service_handles(service); service->State = InitServiceStopped; } // Shuts down the declared graph in reverse dependency order. static void stop_all_services(void) { for (uint32_t order = gServiceConfig.StartupCount; order > 0; --order) stop_service(&gServices[gServiceConfig.StartupOrder[order - 1u]]); } // Tests a transitive hard dependency in the validated acyclic service graph. static bool service_depends_on(uint16_t serviceIndex, uint16_t providerIndex) { const INIT_SERVICE_DESCRIPTOR* desc = &gServiceConfig.Services[serviceIndex]; for (uint32_t i = 0; i < desc->DependencyCount; ++i) { uint16_t dep = desc->Dependencies[i]; if (dep == providerIndex || service_depends_on(dep, providerIndex)) return true; } return false; } // Before restarting a provider, quiesce every transitive consumer in reverse order. static void stop_service_dependents(uint16_t providerIndex) { for (uint32_t order = gServiceConfig.StartupCount; order > 0; --order) { uint16_t index = gServiceConfig.StartupOrder[order - 1u]; if (index != providerIndex && service_depends_on(index, providerIndex)) stop_service(&gServices[index]); } } // Starts eligible descendants again using the dependency-first startup order. static KSTATUS restart_service_dependents(uint16_t providerIndex, SYS_HANDLE volume, SYS_HANDLE context) { for (uint32_t order = 0; order < gServiceConfig.StartupCount; ++order) { uint16_t index = gServiceConfig.StartupOrder[order]; if (!service_depends_on(index, providerIndex)) continue; KSTATUS status = start_managed_service(volume, context, &gServices[index]); if (!KSUCCESS(status)) return status; } return NTLSTATUS_SUCCESS; } // 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(NTL_BOOT_CAP_SYSTEM_VOLUME); SYS_HANDLE namespaceVolume = SysGetStartupCapability(NTL_BOOT_CAP_NAMESPACE_ROOT); SYS_HANDLE volumeManager = SysGetStartupCapability(NTL_BOOT_CAP_VOLUME_MANAGER); SYS_HANDLE inputManager = SysGetStartupCapability(NTL_BOOT_CAP_INPUT_MANAGER); SYS_HANDLE displayManager = SysGetStartupCapability(NTL_BOOT_CAP_DISPLAY_POLICY); SYS_HANDLE registrationAuthority = SysGetStartupCapability(NTL_BOOT_CAP_RESOURCE_REGISTRATION); SYS_HANDLE powerEvent = SYS_HANDLE_INVALID; status = SysOpenPowerEvent(&powerEvent); if (!KSUCCESS(status)) { debug_print("[init] FATAL: power coordinator unavailable\n"); exit_now(1); } // Report the missing name so bootstrap ABI mismatches can be diagnosed directly. const struct { const char* Name; SYS_HANDLE Handle; } requiredBootstrap[] = { { NTL_BOOT_CAP_SYSTEM_VOLUME, systemVolume }, { NTL_BOOT_CAP_NAMESPACE_ROOT, namespaceVolume }, { NTL_BOOT_CAP_VOLUME_MANAGER, volumeManager }, { NTL_BOOT_CAP_INPUT_MANAGER, inputManager }, { NTL_BOOT_CAP_DISPLAY_POLICY, displayManager }, { NTL_BOOT_CAP_RESOURCE_REGISTRATION, registrationAuthority }, }; for (uint32_t i = 0; i < sizeof(requiredBootstrap) / sizeof(requiredBootstrap[0]); ++i) { if (requiredBootstrap[i].Handle != SYS_HANDLE_INVALID) continue; debug_print("[init] FATAL: missing bootstrap capability: "); debug_print(requiredBootstrap[i].Name); debug_print("\n"); exit_now(1); } status = initialize_boot_grants(namespaceVolume, volumeManager, inputManager, displayManager, registrationAuthority); if (!KSUCCESS(status)) { debug_print("[init] FATAL: bootstrap grant catalog initialization failed\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 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"); 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); exit_now(1); } uint32_t autoCount = gServiceConfig.StartupCount; if (autoCount + 2u > SYS_WAIT_MANY_MAX_HANDLES) { debug_print("[init] FATAL: service graph exceeds supervision wait capacity\n"); exit_now(1); } for (uint32_t i = 0; i < gServiceConfig.ServiceCount; ++i) initialize_service(&gServices[i], &gServiceConfig.Services[i]); for (uint32_t order = 0; order < gServiceConfig.StartupCount; ++order) { uint16_t index = gServiceConfig.StartupOrder[order]; INIT_SERVICE* service = &gServices[index]; status = start_managed_service(systemVolume, unprivilegedServiceContext, service); debug_print("[init] service "); debug_print(service->Descriptor->Id); if (KSUCCESS(status)) debug_print(" READY\n"); else { debug_print(" startup failed: "); debug_status(status); debug_print("\n"); if (service->Descriptor->Critical) { stop_all_services(); exit_now(1); } } } INIT_RESTART_BUDGET restartBudgets[INIT_SERVICE_MAX_COUNT] = {0}; uint64_t tickFrequency = 0; status = SysGetTickFrequency(&tickFrequency); if (!KSUCCESS(status) || tickFrequency == 0u) { debug_print("[init] FATAL: monotonic clock unavailable for supervision\n"); stop_all_services(); exit_now(1); } for (;;) { SYS_HANDLE child = SYS_HANDLE_INVALID; status = start_configured_child(systemVolume, childPath, &child); if (!KSUCCESS(status)) { debug_print("[init] FATAL: session start failed: "); debug_status(status); debug_print("\n"); stop_all_services(); 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] = powerEvent; kinds[waitCount++] = UINT32_MAX; waits[waitCount] = child; kinds[waitCount++] = UINT32_MAX - 1u; for (uint32_t i = 0; i < gServiceConfig.ServiceCount; ++i) { if (gServices[i].State != InitServiceReady || gServices[i].Process == SYS_HANDLE_INVALID) continue; waits[waitCount] = gServices[i].Process; kinds[waitCount++] = i; } uint32_t signaled = 0; SYS_WAIT_MANY_REQUEST wait = {0}; wait.Size = sizeof(wait); wait.Handles = waits; wait.Count = waitCount; wait.SignaledIndexOut = &signaled; wait.TimeoutMilliseconds = SYS_WAIT_TIMEOUT_INFINITE; status = SysWaitMany(&wait); if (!KSUCCESS(status)) { debug_print("[init] FATAL: service supervision wait failed\n"); (void)SysKillProcess(child, 1); (void)SysWait(child, SYS_WAIT_FLAG_NONE); (void)SysCloseHandle(child); stop_all_services(); exit_now(1); } if (kinds[signaled] == UINT32_MAX) { uint32_t action = 0; status = SysQuerySystemPower(&action); if (!KSUCCESS(status) || !action) { debug_print("[init] FATAL: invalid power request\n"); exit_now(1); } (void)SysKillProcess(child, 0); (void)SysWaitSingle(child, SYS_WAIT_FLAG_NONE, 3000u); (void)SysCloseHandle(child); stop_all_services(); (void)SysCloseHandle(unprivilegedServiceContext); (void)SysCloseHandle(powerEvent); status = SysCompleteSystemPower(action); if (!KSUCCESS(status)) { debug_print("[init] FATAL: power commit rejected\n"); exit_now(1); } exit_now(0); } if (kinds[signaled] == UINT32_MAX - 1u) { int32_t exitCode = 1; (void)SysGetProcessExitCode(child, &exitCode); (void)SysCloseHandle(child); if (exitCode == 0) debug_print("[init] session ended; restarting\n"); else debug_print("[init] session crashed; restarting\n"); restartChild = true; break; } uint16_t failedIndex = (uint16_t)kinds[signaled]; INIT_SERVICE* failed = &gServices[failedIndex]; int32_t exitCode = -1; (void)SysGetProcessExitCode(failed->Process, &exitCode); debug_print("[init] service exited: "); debug_print(failed->Descriptor->Id); debug_print(" code="); debug_i32(exitCode); debug_print("\n"); stop_service_dependents(failedIndex); close_service_handles(failed); failed->State = InitServiceFailed; if (failed->Descriptor->RestartPolicy == InitServiceRestartOnFailure && InitConsumeRestartBudget(&restartBudgets[failedIndex], SysGetTick(), tickFrequency)) { status = start_managed_service(systemVolume, unprivilegedServiceContext, failed); if (KSUCCESS(status)) status = restart_service_dependents(failedIndex, systemVolume, unprivilegedServiceContext); if (KSUCCESS(status)) continue; debug_print("[init] service restart failed\n"); } // Any affected critical service is a fatal dependency loss. bool fatal = failed->Descriptor->Critical; for (uint32_t i = 0; i < gServiceConfig.ServiceCount; ++i) if (gServices[i].Descriptor->Critical && service_depends_on((uint16_t)i, failedIndex)) fatal = true; if (fatal) { (void)SysKillProcess(child, 1); (void)SysWait(child, SYS_WAIT_FLAG_NONE); (void)SysCloseHandle(child); stop_all_services(); debug_print("[init] FATAL: critical service dependency lost\n"); exit_now(1); } } if (!restartChild) break; } exit_now(1); }