// 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 loader 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 { char Name[SYS_STARTUP_CAPABILITY_NAME_MAX + 1u]; SYS_HANDLE SourceHandle; SYS_RIGHTS DesiredRights; uint32_t DuplicateFlags; } NTL_PROCESS_STARTUP_CAPABILITY; // Opaque preparation owned by the userspace process loader. A successful // prepare returns one allocation consumed by Start or Abort; never copy it. typedef struct NTL_PROCESS_PREPARATION NTL_PROCESS_PREPARATION; // 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_PREPARE_PROCESS_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_PREPARE_PROCESS_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 // Allocates and prepares an inert child, including image, dependencies, inherited // capabilities, and bootstrap data. On failure *preparationOut is NULL and no // prepared process or child handle is retained. imageFile may be invalid to // open request->Path relative to RootHandle. NTL_PROCESS_LOADER_API KSTATUS NtlPrepareProcess(const NTL_PREPARE_PROCESS_REQUEST* request, SYS_HANDLE imageFile, NTL_PROCESS_PREPARATION** preparationOut); // Borrows the native process capability without transferring ownership. This // handle must not be closed by the caller and is valid only until Start/Abort. NTL_PROCESS_LOADER_API KSTATUS NtlPreparedProcessGetHandle( const NTL_PROCESS_PREPARATION* preparation, SYS_HANDLE* processHandleOut); // Consumes one valid preparation on both success and ordinary start failure. // On success returns the caller-owned native process capability. On failure // the inert child is discarded and *processHandleOut is invalid. NTL_PROCESS_LOADER_API KSTATUS NtlStartPreparedProcess( NTL_PROCESS_PREPARATION* preparation, SYS_HANDLE* processHandleOut); // Consumes one prepared child without starting it. NULL is accepted. NTL_PROCESS_LOADER_API void NtlAbortPreparedProcess(NTL_PROCESS_PREPARATION* preparation); 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 at process construction. 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