// Native userspace process-loader declarations. #pragma once #include #include #include #include #include #include #include #define NTL_PROCESS_LOAD_FLAG_NONE 0x00000000u #define NTL_PROCESS_STARTUP_DATA_MAX 1024u // Generic userspace process vectors. The builder copies every view into the // child loader block; callers retain ownership of the source arrays/strings. typedef struct NTL_PROCESS_STRING_VECTOR { const SYS_STRING_VIEW* Entries; uint32_t Count; } NTL_PROCESS_STRING_VECTOR; // Describes one source capability to duplicate into a constructing child. typedef struct NTL_PROCESS_STARTUP_CAPABILITY { uint32_t Tag; SYS_HANDLE SourceHandle; SYS_RIGHTS DesiredRights; uint32_t DuplicateFlags; } NTL_PROCESS_STARTUP_CAPABILITY; // Reusable inert-process builder used by policy services such as posixsrv. // The storage is opaque to callers; initialize it to zero before first use. #define NTL_PROCESS_BUILDER_OPAQUE_WORDS 160u typedef struct NTL_PROCESS_BUILDER { uintptr_t Opaque[NTL_PROCESS_BUILDER_OPAQUE_WORDS]; } NTL_PROCESS_BUILDER; // Describes construction of an inert child. Unlike NTL_CREATE_PROCESS_AT_REQUEST, // preparation does not start the process and therefore has no output handle field. typedef struct NTL_PROCESS_BUILDER_REQUEST { uint32_t Size; uint32_t Flags; SYS_HANDLE RootHandle; SYS_STRING_VIEW Path; SYS_STRING_VIEW CommandLine; SYS_STRING_VIEW CurrentDirectory; SYS_HANDLE SecurityContext; SYS_HANDLE ModuleRootHandle; SYS_STRING_VIEW ModuleDirectory; NTL_MODULE_NAME_RESOLVER ResolveModuleName; void* ResolveContext; const NTL_PROCESS_STARTUP_CAPABILITY* StartupCapabilities; uint32_t StartupCapabilityCount; NTL_PROCESS_STRING_VECTOR Arguments; NTL_PROCESS_STRING_VECTOR Environment; const void* StartupData; size_t StartupDataSize; } NTL_PROCESS_BUILDER_REQUEST; // Creates and starts one PE32+ process entirely through the userspace image loader. typedef struct NTL_CREATE_PROCESS_AT_REQUEST { uint32_t Size; uint32_t Flags; SYS_HANDLE RootHandle; SYS_STRING_VIEW Path; SYS_STRING_VIEW CommandLine; // Empty inherits the caller's userspace CWD; non-empty is normalized as a native resource path. SYS_STRING_VIEW CurrentDirectory; SYS_HANDLE SecurityContext; SYS_HANDLE ModuleRootHandle; SYS_STRING_VIEW ModuleDirectory; NTL_MODULE_NAME_RESOLVER ResolveModuleName; void* ResolveContext; const NTL_PROCESS_STARTUP_CAPABILITY* StartupCapabilities; uint32_t StartupCapabilityCount; NTL_PROCESS_STRING_VECTOR Arguments; NTL_PROCESS_STRING_VECTOR Environment; // Optional opaque userspace bootstrap data copied into the child's read-only loader block. const void* StartupData; size_t StartupDataSize; SYS_HANDLE* ProcessHandleOut; } NTL_CREATE_PROCESS_AT_REQUEST; // Creates one process beneath the globally published /SystemRoot volume. Path remains a // canonical volume-relative native path; RSSRV is used only to obtain the volume capability. typedef struct NTL_CREATE_SYSTEM_PROCESS_REQUEST { uint32_t Size; uint32_t Flags; // Optional pre-opened executable file. When supplied, Path is diagnostic/PEB identity only. SYS_HANDLE ImageFile; SYS_STRING_VIEW Path; SYS_STRING_VIEW CommandLine; // Empty inherits the caller's userspace CWD; non-empty is normalized as a native resource path. SYS_STRING_VIEW CurrentDirectory; SYS_HANDLE SecurityContext; NTL_MODULE_NAME_RESOLVER ResolveModuleName; void* ResolveContext; const NTL_PROCESS_STARTUP_CAPABILITY* StartupCapabilities; uint32_t StartupCapabilityCount; NTL_PROCESS_STRING_VECTOR Arguments; NTL_PROCESS_STRING_VECTOR Environment; // Optional opaque userspace bootstrap data copied into the child's read-only loader block. const void* StartupData; size_t StartupDataSize; SYS_HANDLE* ProcessHandleOut; } NTL_CREATE_SYSTEM_PROCESS_REQUEST; #if defined(NTL_SYSCALL_STATIC) #define NTL_PROCESS_LOADER_API #elif defined(NTL_SYSCALL_BUILD) #define NTL_PROCESS_LOADER_API __declspec(dllexport) #else #define NTL_PROCESS_LOADER_API #endif // Prepares an inert child and materializes its image/dependencies/bootstrap data. // imageFile may be SYS_HANDLE_INVALID to open request->Path relative to RootHandle. NTL_PROCESS_LOADER_API KSTATUS NtlProcessBuilderPrepare(NTL_PROCESS_BUILDER* builder, const NTL_PROCESS_BUILDER_REQUEST* request, SYS_HANDLE imageFile); // Returns the prepared process capability without transferring ownership from the builder. // The borrowed handle remains valid only until Start or Abort consumes the builder. NTL_PROCESS_LOADER_API KSTATUS NtlProcessBuilderGetProcessHandle(NTL_PROCESS_BUILDER* builder, SYS_HANDLE* processHandleOut); // Starts a prepared child and returns the retained process capability to the caller. // On success the builder is consumed and reset to the empty state. NTL_PROCESS_LOADER_API KSTATUS NtlProcessBuilderStart(NTL_PROCESS_BUILDER* builder, SYS_HANDLE* processHandleOut); // Aborts a prepared child, terminating the inert native process and releasing loader state. NTL_PROCESS_LOADER_API void NtlProcessBuilderAbort(NTL_PROCESS_BUILDER* builder); NTL_PROCESS_LOADER_API KSTATUS NtlCreateProcessAt(const NTL_CREATE_PROCESS_AT_REQUEST* request); NTL_PROCESS_LOADER_API KSTATUS NtlCreateSystemProcess(const NTL_CREATE_SYSTEM_PROCESS_REQUEST* request); // Copies the optional opaque startup data supplied by the userspace process builder. NTL_PROCESS_LOADER_API KSTATUS NtlGetProcessStartupData(void* buffer, size_t bufferSize, size_t* sizeOut); // Returns one immutable argument/environment entry from the current loader block. NTL_PROCESS_LOADER_API KSTATUS NtlGetProcessArgumentCount(uint32_t* countOut); NTL_PROCESS_LOADER_API KSTATUS NtlGetProcessArgument(uint32_t index, SYS_STRING_VIEW* argumentOut); NTL_PROCESS_LOADER_API KSTATUS NtlGetProcessEnvironmentCount(uint32_t* countOut); NTL_PROCESS_LOADER_API KSTATUS NtlGetProcessEnvironment(uint32_t index, SYS_STRING_VIEW* entryOut); #undef NTL_PROCESS_LOADER_API