redo boot around an explicit system volume and fixed kernel/HAL images, redo volumes and filesystem paths around capabilities instead of drive numbers and kernel CWD state, add a capability/security model with derived and revocable handles and security contexts, add port IPC and rssrv to manage the userspace resource namespace and publish the system volume, move process, dll and path loading to userspace and add process builder syscalls, init now supervises rssrv and the session process, redo the syscall ABI around request structs and four arguments, add a volume manager and proper partition arrival/removal handling so FAT and NTFS mount dynamically, clean up the HAL/DDK boundary so drivers don't depend on HAL internals, save fpu state properly now, the serial driver doesn't hang on a missing port, fix AHCI startup races, fix timeout accounting, fix shared mmap writeback, more smoke tests

This commit is contained in:
maksw committed 2026-08-20 12:33:17 +02:00
1 parent 4add6789ba
commit f882d339fb
232 files changed
+20934 -8898

No files matched your search

+399 -81
View File
@@ -1,103 +1,421 @@
// Init support.
// 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/process_loader.h>
#include <ntlite/resource.h>
#include <ntlite/security.h>
#include <ntlite/service_control.h>
#include <ntlite/syscall.h>
// Implements the itoa operation.
void itoa(int num, char* str) {
int i = 0;
int is_negative = 0;
#define INIT_SERVICE_READY_TIMEOUT_MS 5000u
#define INIT_SERVICE_STOP_TIMEOUT_MS 5000u
// Handle 0 explicitly.
if (num == 0) {
str[i++] = '0';
str[i] = '\0';
return;
}
typedef struct INIT_RESOURCE_SERVICE {
SYS_HANDLE Process;
SYS_HANDLE ControlEndpoint;
SYS_HANDLE AdminListener;
} INIT_RESOURCE_SERVICE;
// Handle negative numbers.
if (num < 0) {
is_negative = 1;
num = -num;
}
// Process individual digits (result is in reverse).
while (num != 0) {
int rem = num % 10;
str[i++] = rem + '0';
num = num / 10;
}
if (is_negative) {
str[i++] = '-';
}
str[i] = '\0'; // Null terminate
// Reverse the string.
int start = 0;
int end = i - 1;
while (start < end) {
char temp = str[start];
str[start] = str[end];
str[end] = temp;
start++;
end--;
}
// 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);
}
// Implements the debug print operation.
static void debug_print(const char* s) {
SYS_PRINT_DEBUG_REQUEST req = { SysSvFromCstr(s) };
(void)SysPrintDebug(&req);
// 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);
}
// Initializes init process state and supervises the configured child process.
void _start(void)
{
uint32_t runtimeStatus = NtlInitializeExceptionRuntime();
if (runtimeStatus != NTLSTATUS_SUCCESS)
SysExitProcess((int32_t)runtimeStatus);
// Exits init without relying on a compiler runtime return path.
static void exit_now(int code) {
for (;;) SysExitProcess(code);
}
SYS_STRING_VIEW args = SysGetPeb()->CommandLine;
uint32_t h = 0;
uint32_t s = 0;
// 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);
}
while (true) {
debug_print("[init] starting\n");
SYS_CREATE_PROCESS_REQUEST cp = { args, SysSvFromParts(0, 0), &h };
s = SysCreateProcess(&cp);
if (s != NTLSTATUS_SUCCESS) {
debug_print("[init] FATAL: failed to start!\n");
char buffer[12];
itoa(s, buffer);
debug_print(buffer);
// 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);
}
// Waits for RSSRV readiness and receives its private administrative namespace listener.
static KSTATUS wait_resource_service_ready(SYS_HANDLE controlEndpoint, SYS_HANDLE* adminListenerOut) {
if (!adminListenerOut) return NTLSTATUS_INVALID_PARAMETER;
*adminListenerOut = SYS_HANDLE_INVALID;
NTL_SERVICE_CONTROL_MESSAGE message;
SYS_PORT_MESSAGE_INFO info;
SYS_HANDLE adminListener = SYS_HANDLE_INVALID;
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 = controlEndpoint;
receive.Flags = SYS_PORT_FLAG_NONE;
receive.Payload = &message;
receive.PayloadCapacity = sizeof(message);
receive.HandlesOut = &adminListener;
receive.HandleCapacity = 1;
receive.InfoOut = &info;
receive.TimeoutMilliseconds = INIT_SERVICE_READY_TIMEOUT_MS;
KSTATUS status = SysReceivePort(&receive);
if (!KSUCCESS(status)) return status;
if (info.Type != SYS_PORT_MESSAGE_NOTIFICATION || info.PayloadLength != sizeof(message) ||
info.HandleCount != 1 || adminListener == SYS_HANDLE_INVALID ||
message.Size != sizeof(message) || message.Version != NTL_SERVICE_CONTROL_VERSION ||
message.Operation != NTL_SERVICE_CONTROL_READY ||
message.Flags != NTL_SERVICE_READY_FLAG_RESOURCE_ADMIN_LISTENER ||
!KSUCCESS(message.Status)) {
if (adminListener != SYS_HANDLE_INVALID) (void)SysCloseHandle(adminListener);
return NTLSTATUS_FAILURE;
}
*adminListenerOut = adminListener;
return NTLSTATUS_SUCCESS;
}
// Verifies private namespace administration and public /SystemRoot lookup before declaring RSSRV usable.
static KSTATUS verify_resource_service(SYS_HANDLE adminListener, SYS_HANDLE namespaceVolume) {
SYS_HANDLE admin = SYS_HANDLE_INVALID;
KSTATUS status = NtlResourceConnectListener(adminListener, &admin);
if (!KSUCCESS(status)) return status;
uint32_t kind = NTL_RESOURCE_KIND_INVALID;
status = NtlResourceQuery(admin, SYS_SV_LITERAL("/SystemRoot"), &kind);
if (!KSUCCESS(status) || kind != NTL_RESOURCE_KIND_VOLUME) {
(void)NtlResourceClose(admin);
return KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
}
// Exercise capability-based administration without leaving a bootstrap-only namespace entry behind.
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)) {
(void)NtlResourceClose(admin);
return status;
}
SYS_HANDLE publicSession = SYS_HANDLE_INVALID;
status = NtlResourceConnect(&publicSession);
if (!KSUCCESS(status)) {
(void)NtlResourceUnbind(admin, SYS_SV_LITERAL("/Init/BootstrapProbe"));
(void)NtlResourceClose(admin);
return status;
}
SYS_HANDLE volume = SYS_HANDLE_INVALID;
status = NtlResourceLookup(publicSession, SYS_SV_LITERAL("/SystemRoot"),
SYS_RIGHT_QUERY | SYS_VOLUME_RIGHT_OPEN, &volume);
if (KSUCCESS(status)) (void)SysCloseHandle(volume);
if (!KSUCCESS(status)) {
(void)NtlResourceClose(publicSession);
(void)NtlResourceUnbind(admin, SYS_SV_LITERAL("/Init/BootstrapProbe"));
(void)NtlResourceClose(admin);
return status;
}
kind = NTL_RESOURCE_KIND_INVALID;
status = NtlResourceQuery(publicSession, SYS_SV_LITERAL("/Init/BootstrapProbe"), &kind);
if (!KSUCCESS(status) || kind != NTL_RESOURCE_KIND_VOLUME) {
(void)NtlResourceClose(publicSession);
(void)NtlResourceUnbind(admin, SYS_SV_LITERAL("/Init/BootstrapProbe"));
(void)NtlResourceClose(admin);
return KSUCCESS(status) ? NTLSTATUS_FAILURE : status;
}
status = NtlResourceUnbind(admin, SYS_SV_LITERAL("/Init/BootstrapProbe"));
if (KSUCCESS(status)) {
kind = NTL_RESOURCE_KIND_INVALID;
KSTATUS queryStatus = NtlResourceQuery(publicSession, SYS_SV_LITERAL("/Init/BootstrapProbe"), &kind);
if (queryStatus != NTLSTATUS_NOT_FOUND) status = NTLSTATUS_FAILURE;
}
(void)NtlResourceClose(publicSession);
(void)NtlResourceClose(admin);
return status;
}
// Tears down retained parent-side service handles without sending a stop message.
static void close_resource_service(INIT_RESOURCE_SERVICE* service) {
if (!service) return;
if (service->ControlEndpoint != SYS_HANDLE_INVALID) {
(void)SysDisconnectPort(service->ControlEndpoint);
(void)SysCloseHandle(service->ControlEndpoint);
}
if (service->AdminListener != SYS_HANDLE_INVALID)
(void)SysCloseHandle(service->AdminListener);
if (service->Process != SYS_HANDLE_INVALID)
(void)SysCloseHandle(service->Process);
service->Process = SYS_HANDLE_INVALID;
service->ControlEndpoint = SYS_HANDLE_INVALID;
service->AdminListener = SYS_HANDLE_INVALID;
}
// Starts one restricted, import-free RSSRV instance through the userspace process loader.
static KSTATUS start_resource_service(SYS_HANDLE systemVolume,
SYS_HANDLE namespaceVolume,
SYS_HANDLE volumeManager,
SYS_HANDLE resourceContext,
INIT_RESOURCE_SERVICE* serviceOut) {
if (!serviceOut) return NTLSTATUS_INVALID_PARAMETER;
memset(serviceOut, 0, sizeof(*serviceOut));
SYS_HANDLE controlListener = SYS_HANDLE_INVALID;
KSTATUS status = create_control_listener(&controlListener);
if (!KSUCCESS(status)) return status;
NTL_PROCESS_STARTUP_CAPABILITY startup[3];
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_SERVICE_CONTROL;
startup[1].SourceHandle = controlListener;
startup[1].DesiredRights = SYS_RIGHT_QUERY | SYS_PORT_RIGHT_ACCEPT;
startup[1].DuplicateFlags = SYS_DUPLICATE_HANDLE_FLAG_NONE;
startup[2].Tag = SYS_STARTUP_CAP_VOLUME_MANAGER;
startup[2].SourceHandle = volumeManager;
startup[2].DesiredRights = SYS_RIGHT_QUERY |
SYS_VOLUME_MANAGER_RIGHT_ENUMERATE | SYS_VOLUME_MANAGER_RIGHT_OPEN |
SYS_VOLUME_MANAGER_RIGHT_WAIT;
startup[2].DuplicateFlags = SYS_DUPLICATE_HANDLE_FLAG_NONE;
SYS_HANDLE process = SYS_HANDLE_INVALID;
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 = SYS_SV_LITERAL("system/rssrv.exe");
create.CommandLine = SYS_SV_LITERAL("system/rssrv.exe");
create.SecurityContext = resourceContext;
create.ModuleRootHandle = systemVolume;
create.ModuleDirectory = SYS_SV_LITERAL("system");
create.ResolveModuleName = NtlResolveModuleNameIdentity;
create.ResolveContext = (void*)0;
create.StartupCapabilities = startup;
create.StartupCapabilityCount = 3;
create.ProcessHandleOut = &process;
status = NtlCreateProcessAt(&create);
if (!KSUCCESS(status)) {
(void)SysCloseHandle(controlListener);
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);
return status;
}
SYS_HANDLE adminListener = SYS_HANDLE_INVALID;
status = wait_resource_service_ready(controlEndpoint, &adminListener);
if (KSUCCESS(status))
status = verify_resource_service(adminListener, namespaceVolume);
if (!KSUCCESS(status)) {
if (adminListener != SYS_HANDLE_INVALID) (void)SysCloseHandle(adminListener);
(void)SysDisconnectPort(controlEndpoint);
(void)SysCloseHandle(controlEndpoint);
(void)SysKillProcess(process, 1);
(void)SysCloseHandle(process);
return status;
}
serviceOut->Process = process;
serviceOut->ControlEndpoint = controlEndpoint;
serviceOut->AdminListener = adminListener;
return NTLSTATUS_SUCCESS;
}
// Requests graceful RSSRV shutdown, falling back to process termination if it stops responding.
static void stop_resource_service(INIT_RESOURCE_SERVICE* service) {
if (!service || service->Process == SYS_HANDLE_INVALID) return;
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;
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 = INIT_SERVICE_STOP_TIMEOUT_MS;
(void)SysSendPort(&send);
KSTATUS status = SysWaitSingle(service->Process, SYS_WAIT_FLAG_NONE, INIT_SERVICE_STOP_TIMEOUT_MS);
if (!KSUCCESS(status)) {
(void)SysKillProcess(service->Process, 1);
(void)SysWait(service->Process, SYS_WAIT_FLAG_NONE);
}
close_resource_service(service);
}
// Starts the configured native session child directly beneath 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);
}
// Initializes init state and supervises RSSRV plus the configured session process.
void _start(void) {
KSTATUS status = NtlInitializeExceptionRuntime();
if (!KSUCCESS(status)) exit_now((int)status);
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);
if (systemVolume == SYS_HANDLE_INVALID || namespaceVolume == SYS_HANDLE_INVALID ||
volumeManager == SYS_HANDLE_INVALID) {
debug_print("[init] FATAL: bootstrap storage capability missing\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_STRING_VIEW childPath = SysGetPeb()->CommandLine;
if (!childPath.Data || childPath.Length == 0) {
debug_print("[init] FATAL: no configured session process\n");
exit_now(1);
}
for (;;) {
INIT_RESOURCE_SERVICE resourceService;
status = start_resource_service(systemVolume, namespaceVolume, volumeManager, resourceContext, &resourceService);
if (!KSUCCESS(status)) {
debug_print("[init] FATAL: RSSRV startup failed: ");
debug_status(status);
debug_print("\n");
SysExitProcess(1);
exit_now(1);
}
debug_print("[init] RSSRV ready\n");
debug_print("[init] waiting\n");
s = SysWait(h, SYS_WAIT_FLAG_NONE);
if (s != NTLSTATUS_SUCCESS)
debug_print("[init] WARNING: SysWait returned error\n");
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");
stop_resource_service(&resourceService);
exit_now(1);
}
debug_print("[init] session process started\n");
int32_t exitCode = 0;
if (SysGetProcessExitCode(h, &exitCode) != NTLSTATUS_SUCCESS) {
debug_print("[init] WARNING: failed to read exit code\n");
exitCode = 1;
SYS_HANDLE waits[2] = { resourceService.Process, child };
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 = 2;
wait.SignaledIndexOut = &signaled;
wait.TimeoutMilliseconds = SYS_WAIT_TIMEOUT_INFINITE;
status = SysWaitMany(&wait);
if (!KSUCCESS(status)) {
(void)SysKillProcess(child, 1);
(void)SysCloseHandle(child);
stop_resource_service(&resourceService);
debug_print("[init] FATAL: service wait failed\n");
exit_now(1);
}
if (signaled == 0) {
int32_t serviceExit = -1;
(void)SysGetProcessExitCode(resourceService.Process, &serviceExit);
debug_print("[init] RSSRV exited unexpectedly; restarting service plane\n");
(void)SysKillProcess(child, 1);
(void)SysWait(child, SYS_WAIT_FLAG_NONE);
(void)SysCloseHandle(child);
close_resource_service(&resourceService);
break;
}
int32_t exitCode = -1;
status = SysGetProcessExitCode(child, &exitCode);
(void)SysCloseHandle(child);
if (!KSUCCESS(status)) exitCode = 1;
if (exitCode == 0) {
stop_resource_service(&resourceService);
debug_print("[init] done\n");
(void)SysCloseHandle(resourceContext);
exit_now(0);
}
debug_print("[init] session process crashed; restarting\n");
}
SysCloseHandle(h);
if (exitCode == 0)
break;
debug_print("[init] child crashed, restarting\n");
}
debug_print("[init] done\n");
SysExitProcess(0);
}
+947
View File
@@ -0,0 +1,947 @@
// Native resource namespace service. RSSRV owns global names and transfers capabilities; it is not a file data path.
#include <ntlite/exception.h>
#include <ntlite/resource.h>
#include <ntlite/service.h>
#include <ntlite/service_control.h>
#include <ntlite/syscall.h>
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#define RSSRV_LISTENER_BACKLOG 16u
// One namespace binding. Path storage follows the fixed header in the same allocation.
typedef struct RSSRV_ENTRY {
struct RSSRV_ENTRY* Next;
SYS_HANDLE Handle;
uint32_t Kind;
SYS_RIGHTS ExportRights;
uint32_t PathLength;
char Path[1];
} RSSRV_ENTRY;
typedef struct RSSRV_SESSION {
SYS_HANDLE Endpoint;
uint32_t Administrative;
} RSSRV_SESSION;
typedef struct RSSRV_LISTENER_WORKER {
SYS_HANDLE Listener;
uint32_t Administrative;
} RSSRV_LISTENER_WORKER;
typedef struct RSSRV_VOLUME_PUBLICATION {
struct RSSRV_VOLUME_PUBLICATION* Next;
uint32_t InstanceId;
uint32_t NamespaceId;
uint32_t PathLength;
char Path[48];
} RSSRV_VOLUME_PUBLICATION;
static SYS_HANDLE gNamespaceMutex = SYS_HANDLE_INVALID;
static RSSRV_ENTRY* gNamespace = (RSSRV_ENTRY*)0;
static SYS_HANDLE gPublicListener = SYS_HANDLE_INVALID;
static SYS_HANDLE gAdminListener = SYS_HANDLE_INVALID;
static RSSRV_LISTENER_WORKER gPublicWorker;
static RSSRV_LISTENER_WORKER gAdminWorker;
static RSSRV_VOLUME_PUBLICATION* gPublishedVolumes = (RSSRV_VOLUME_PUBLICATION*)0;
static uint32_t gNextHarddiskVolumeId = 1u;
// Exits without depending on a compiler runtime return path.
static void RssrvExit(int code) {
for (;;) SysExitProcess(code);
}
// Acquires the namespace mutex.
static KSTATUS RssrvLockNamespace(void) {
return SysWait(gNamespaceMutex, SYS_WAIT_FLAG_NONE);
}
// Releases the namespace mutex.
static void RssrvUnlockNamespace(void) {
(void)SysReleaseMutex(gNamespaceMutex);
}
// Validates one canonical absolute native resource path.
static KSTATUS RssrvValidatePath(const char* path, uint32_t length) {
if (!path || length < 2 || length > NTL_RESOURCE_PATH_MAX || path[0] != '/' || path[length - 1] == '/')
return NTLSTATUS_INVALID_PARAMETER;
uint32_t componentStart = 1;
for (uint32_t i = 1; i <= length; ++i) {
if (i < length) {
char c = path[i];
if (c == '\\' || c == '\0')
return NTLSTATUS_INVALID_PARAMETER;
if (c != '/')
continue;
}
uint32_t componentLength = i - componentStart;
if (componentLength == 0 ||
(componentLength == 1 && path[componentStart] == '.') ||
(componentLength == 2 && path[componentStart] == '.' && path[componentStart + 1] == '.'))
return NTLSTATUS_INVALID_PARAMETER;
componentStart = i + 1;
}
return NTLSTATUS_SUCCESS;
}
// Returns whether a path belongs to the RSSRV-owned automatic mounted-volume naming family.
static int RssrvIsManagedVolumePath(const char* path, uint32_t length) {
static const char prefix[] = "/Device/HarddiskVolume";
uint32_t prefixLength = (uint32_t)(sizeof(prefix) - 1u);
return path && length >= prefixLength && memcmp(path, prefix, prefixLength) == 0;
}
// Finds one exact binding while the namespace mutex is held.
static RSSRV_ENTRY* RssrvFindLocked(const char* path, uint32_t length, RSSRV_ENTRY*** linkOut) {
RSSRV_ENTRY** link = &gNamespace;
while (*link) {
RSSRV_ENTRY* entry = *link;
if (entry->PathLength == length && memcmp(entry->Path, path, length) == 0) {
if (linkOut) *linkOut = link;
return entry;
}
link = &entry->Next;
}
if (linkOut) *linkOut = link;
return (RSSRV_ENTRY*)0;
}
// Finds the longest namespace binding that is an exact component prefix of path.
static RSSRV_ENTRY* RssrvFindPrefixLocked(const char* path, uint32_t length) {
RSSRV_ENTRY* best = (RSSRV_ENTRY*)0;
for (RSSRV_ENTRY* entry = gNamespace; entry; entry = entry->Next) {
if (entry->PathLength > length)
continue;
if (memcmp(entry->Path, path, entry->PathLength) != 0)
continue;
if (entry->PathLength != length && path[entry->PathLength] != '/')
continue;
if (!best || entry->PathLength > best->PathLength)
best = entry;
}
return best;
}
// Takes ownership of one handle and binds it to a new exact resource name.
static KSTATUS RssrvBindOwned(const char* path,
uint32_t length,
uint32_t kind,
SYS_HANDLE handle,
SYS_RIGHTS exportRights) {
if (kind == NTL_RESOURCE_KIND_INVALID || handle == SYS_HANDLE_INVALID || !exportRights)
return NTLSTATUS_INVALID_PARAMETER;
KSTATUS status = RssrvValidatePath(path, length);
if (!KSUCCESS(status)) return status;
size_t bytes = offsetof(RSSRV_ENTRY, Path) + (size_t)length + 1u;
RSSRV_ENTRY* entry = (RSSRV_ENTRY*)malloc(bytes);
if (!entry) return NTLSTATUS_NO_MEMORY;
memset(entry, 0, bytes);
entry->Handle = handle;
entry->Kind = kind;
entry->ExportRights = exportRights;
entry->PathLength = length;
memcpy(entry->Path, path, length);
entry->Path[length] = '\0';
status = RssrvLockNamespace();
if (!KSUCCESS(status)) {
free(entry);
return status;
}
if (RssrvFindLocked(path, length, (RSSRV_ENTRY***)0)) {
RssrvUnlockNamespace();
free(entry);
return NTLSTATUS_OBJECT_NAME_COLLISION;
}
entry->Next = gNamespace;
gNamespace = entry;
RssrvUnlockNamespace();
return NTLSTATUS_SUCCESS;
}
// Removes one binding and closes the namespace's retained handle.
static KSTATUS RssrvUnbind(const char* path, uint32_t length) {
KSTATUS status = RssrvValidatePath(path, length);
if (!KSUCCESS(status)) return status;
status = RssrvLockNamespace();
if (!KSUCCESS(status)) return status;
RSSRV_ENTRY** link = (RSSRV_ENTRY**)0;
RSSRV_ENTRY* entry = RssrvFindLocked(path, length, &link);
if (!entry) {
RssrvUnlockNamespace();
return NTLSTATUS_NOT_FOUND;
}
*link = entry->Next;
RssrvUnlockNamespace();
(void)SysCloseHandle(entry->Handle);
free(entry);
return NTLSTATUS_SUCCESS;
}
// Finds one published mounted volume by kernel instance identity.
static RSSRV_VOLUME_PUBLICATION* RssrvFindPublishedVolume(uint32_t instanceId) {
for (RSSRV_VOLUME_PUBLICATION* publication = gPublishedVolumes; publication; publication = publication->Next) {
if (publication->InstanceId == instanceId)
return publication;
}
return (RSSRV_VOLUME_PUBLICATION*)0;
}
// Returns whether one kernel volume instance is present in the current manager snapshot.
static int RssrvSnapshotContainsVolume(const SYS_VOLUME_INFO* volumes, uint32_t count, uint32_t instanceId) {
for (uint32_t i = 0; i < count; ++i) {
if (volumes[i].InstanceId == instanceId)
return 1;
}
return 0;
}
// Builds one RSSRV-local /Device/HarddiskVolumeN name without introducing a formatting-runtime dependency.
static KSTATUS RssrvBuildHarddiskVolumePath(uint32_t namespaceId, char* path, uint32_t capacity, uint32_t* lengthOut) {
static const char prefix[] = "/Device/HarddiskVolume";
if (!namespaceId || !path || !lengthOut)
return NTLSTATUS_INVALID_PARAMETER;
uint32_t prefixLength = (uint32_t)(sizeof(prefix) - 1u);
char digits[10];
uint32_t digitCount = 0;
uint32_t value = namespaceId;
do {
digits[digitCount++] = (char)('0' + (value % 10u));
value /= 10u;
} while (value && digitCount < (uint32_t)sizeof(digits));
if (prefixLength + digitCount + 1u > capacity)
return NTLSTATUS_BUFFER_TOO_SMALL;
memcpy(path, prefix, prefixLength);
for (uint32_t i = 0; i < digitCount; ++i)
path[prefixLength + i] = digits[digitCount - 1u - i];
path[prefixLength + digitCount] = '\0';
*lengthOut = prefixLength + digitCount;
return NTLSTATUS_SUCCESS;
}
// Takes a stable manager snapshot, growing the userspace buffer if the mounted-volume count changes.
static KSTATUS RssrvQueryVolumes(SYS_HANDLE manager,
SYS_VOLUME_INFO** volumesOut,
uint32_t* countOut,
uint64_t* generationOut) {
if (!volumesOut || !countOut || !generationOut)
return NTLSTATUS_INVALID_PARAMETER;
*volumesOut = (SYS_VOLUME_INFO*)0;
*countOut = 0;
*generationOut = 0;
SYS_VOLUME_INFO* volumes = (SYS_VOLUME_INFO*)0;
uint32_t capacity = 0;
for (;;) {
uint32_t count = 0;
uint64_t generation = 0;
SYS_QUERY_VOLUMES_REQUEST query;
memset(&query, 0, sizeof(query));
query.Size = sizeof(query);
query.ManagerHandle = manager;
query.Flags = SYS_VOLUME_QUERY_FLAG_NONE;
query.Capacity = capacity;
query.Volumes = volumes;
query.CountOut = &count;
query.GenerationOut = &generation;
KSTATUS status = SysQueryVolumes(&query);
if (status == NTLSTATUS_BUFFER_TOO_SMALL) {
if (volumes) free(volumes);
volumes = (SYS_VOLUME_INFO*)0;
capacity = count;
if (capacity) {
volumes = (SYS_VOLUME_INFO*)malloc((size_t)capacity * sizeof(*volumes));
if (!volumes)
return NTLSTATUS_NO_MEMORY;
memset(volumes, 0, (size_t)capacity * sizeof(*volumes));
}
continue;
}
if (!KSUCCESS(status)) {
if (volumes) free(volumes);
return status;
}
for (uint32_t i = 0; i < count; ++i) {
if (volumes[i].Size != sizeof(SYS_VOLUME_INFO) ||
volumes[i].Version != SYS_VOLUME_ENUM_VERSION || !volumes[i].InstanceId ||
volumes[i].Flags != 0) {
if (volumes) free(volumes);
return NTLSTATUS_INVALID_PARAMETER;
}
}
*volumesOut = volumes;
*countOut = count;
*generationOut = generation;
return NTLSTATUS_SUCCESS;
}
}
// Reconciles the RSSRV object namespace with the kernel's mounted-volume snapshot.
static KSTATUS RssrvSyncVolumes(SYS_HANDLE manager, uint64_t* generationOut) {
if (!generationOut)
return NTLSTATUS_INVALID_PARAMETER;
SYS_VOLUME_INFO* volumes = (SYS_VOLUME_INFO*)0;
uint32_t count = 0;
uint64_t generation = 0;
KSTATUS status = RssrvQueryVolumes(manager, &volumes, &count, &generation);
if (!KSUCCESS(status))
return status;
RSSRV_VOLUME_PUBLICATION** link = &gPublishedVolumes;
while (*link) {
RSSRV_VOLUME_PUBLICATION* publication = *link;
if (RssrvSnapshotContainsVolume(volumes, count, publication->InstanceId)) {
link = &publication->Next;
continue;
}
status = RssrvUnbind(publication->Path, publication->PathLength);
if (!KSUCCESS(status) && status != NTLSTATUS_NOT_FOUND) {
free(volumes);
return status;
}
*link = publication->Next;
free(publication);
}
for (uint32_t i = 0; i < count; ++i) {
if (RssrvFindPublishedVolume(volumes[i].InstanceId))
continue;
SYS_HANDLE volume = SYS_HANDLE_INVALID;
status = SysOpenVolume(manager, volumes[i].InstanceId,
SYS_RIGHT_QUERY | SYS_RIGHT_TRANSFER |
SYS_VOLUME_RIGHT_OPEN | SYS_VOLUME_RIGHT_MODIFY,
&volume);
if (status == NTLSTATUS_NOT_FOUND || status == NTLSTATUS_OBJECT_DEAD)
continue;
if (!KSUCCESS(status)) {
free(volumes);
return status;
}
RSSRV_VOLUME_PUBLICATION* publication =
(RSSRV_VOLUME_PUBLICATION*)malloc(sizeof(*publication));
if (!publication) {
(void)SysCloseHandle(volume);
free(volumes);
return NTLSTATUS_NO_MEMORY;
}
memset(publication, 0, sizeof(*publication));
publication->InstanceId = volumes[i].InstanceId;
publication->NamespaceId = gNextHarddiskVolumeId;
status = RssrvBuildHarddiskVolumePath(publication->NamespaceId,
publication->Path,
(uint32_t)sizeof(publication->Path),
&publication->PathLength);
if (!KSUCCESS(status)) {
free(publication);
(void)SysCloseHandle(volume);
free(volumes);
return status;
}
status = RssrvBindOwned(publication->Path, publication->PathLength,
NTL_RESOURCE_KIND_VOLUME, volume,
SYS_RIGHT_QUERY | SYS_VOLUME_RIGHT_OPEN | SYS_VOLUME_RIGHT_MODIFY);
if (!KSUCCESS(status)) {
free(publication);
(void)SysCloseHandle(volume);
free(volumes);
return status;
}
publication->Next = gPublishedVolumes;
gPublishedVolumes = publication;
gNextHarddiskVolumeId++;
if (!gNextHarddiskVolumeId) {
free(volumes);
return NTLSTATUS_LIMIT_REACHED;
}
}
if (volumes) free(volumes);
*generationOut = generation;
return NTLSTATUS_SUCCESS;
}
// Keeps automatic /Device/HarddiskVolumeN bindings synchronized with mounted IO_VOLUME instances.
static void RssrvVolumeWorker(uintptr_t argument) {
SYS_HANDLE manager = (SYS_HANDLE)argument;
for (;;) {
uint64_t generation = 0;
KSTATUS status = RssrvSyncVolumes(manager, &generation);
if (!KSUCCESS(status))
RssrvExit(12);
status = SysWaitVolumeChange(manager, generation, SYS_WAIT_TIMEOUT_INFINITE);
if (!KSUCCESS(status))
RssrvExit(12);
}
}
// Starts the mounted-volume namespace publication worker.
static KSTATUS RssrvStartVolumeWorker(SYS_HANDLE manager) {
uint32_t threadId = 0;
SYS_CREATE_THREAD_REQUEST create;
memset(&create, 0, sizeof(create));
create.Size = sizeof(create);
create.Entry = (uintptr_t)RssrvVolumeWorker;
create.Argument = (uintptr_t)manager;
create.Priority = 1;
create.Flags = SYS_CREATE_THREAD_FLAG_NONE;
create.ThreadIdOut = &threadId;
return SysCreateThread(&create);
}
// Replies with one fixed resource-protocol reply and no handle transfer.
static KSTATUS RssrvReplyStatus(SYS_HANDLE endpoint,
uint32_t messageId,
uint32_t operation,
KSTATUS status,
uint32_t kind) {
NTL_RESOURCE_REPLY reply;
memset(&reply, 0, sizeof(reply));
reply.Size = sizeof(reply);
reply.Version = NTL_RESOURCE_PROTOCOL_VERSION;
reply.Operation = operation;
reply.Flags = NTL_RESOURCE_FLAG_NONE;
reply.Status = status;
reply.Kind = kind;
SYS_REPLY_PORT_REQUEST request;
memset(&request, 0, sizeof(request));
request.Size = sizeof(request);
request.EndpointHandle = endpoint;
request.MessageId = messageId;
request.Flags = SYS_PORT_FLAG_NONE;
request.Payload = &reply;
request.PayloadLength = sizeof(reply);
return SysReplyPort(&request);
}
// Handles one lookup while retaining the namespace mutex through capability transfer.
static KSTATUS RssrvHandleLookup(SYS_HANDLE endpoint,
uint32_t messageId,
const NTL_RESOURCE_REQUEST* request,
const char* path) {
if (!request->Rights)
return RssrvReplyStatus(endpoint, messageId, request->Operation,
NTLSTATUS_INVALID_PARAMETER, NTL_RESOURCE_KIND_INVALID);
KSTATUS status = RssrvLockNamespace();
if (!KSUCCESS(status))
return RssrvReplyStatus(endpoint, messageId, request->Operation, status, NTL_RESOURCE_KIND_INVALID);
RSSRV_ENTRY* entry = RssrvFindLocked(path, request->PathLength, (RSSRV_ENTRY***)0);
if (!entry) {
RssrvUnlockNamespace();
return RssrvReplyStatus(endpoint, messageId, request->Operation,
NTLSTATUS_NOT_FOUND, NTL_RESOURCE_KIND_INVALID);
}
uint32_t kind = entry->Kind;
NTL_RESOURCE_REPLY reply;
memset(&reply, 0, sizeof(reply));
reply.Size = sizeof(reply);
reply.Version = NTL_RESOURCE_PROTOCOL_VERSION;
reply.Operation = NTL_RESOURCE_OP_LOOKUP;
reply.Status = NTLSTATUS_SUCCESS;
reply.Kind = kind;
SYS_PORT_HANDLE_TRANSFER transfer;
transfer.Handle = entry->Handle;
if ((request->Rights & ~entry->ExportRights) != 0) {
RssrvUnlockNamespace();
return RssrvReplyStatus(endpoint, messageId, request->Operation,
NTLSTATUS_ACCESS_DENIED, kind);
}
transfer.DesiredRights = request->Rights;
transfer.Flags = SYS_PORT_TRANSFER_FLAG_NONE;
SYS_REPLY_PORT_REQUEST out;
memset(&out, 0, sizeof(out));
out.Size = sizeof(out);
out.EndpointHandle = endpoint;
out.MessageId = messageId;
out.Flags = SYS_PORT_FLAG_NONE;
out.Payload = &reply;
out.PayloadLength = sizeof(reply);
out.Handles = &transfer;
out.HandleCount = 1;
status = SysReplyPort(&out);
RssrvUnlockNamespace();
// A rights mismatch leaves the synchronous call pending, so return the precise error without a handle.
if (!KSUCCESS(status))
return RssrvReplyStatus(endpoint, messageId, request->Operation, status, kind);
return NTLSTATUS_SUCCESS;
}
// Resolves the longest bound resource prefix and transfers traversal authority.
static KSTATUS RssrvHandleResolve(SYS_HANDLE endpoint,
uint32_t messageId,
const NTL_RESOURCE_REQUEST* request,
const char* path) {
if ((request->Flags & ~NTL_RESOURCE_RESOLVE_FLAG_MODIFY) != 0)
return RssrvReplyStatus(endpoint, messageId, request->Operation,
NTLSTATUS_INVALID_PARAMETER, NTL_RESOURCE_KIND_INVALID);
KSTATUS status = RssrvLockNamespace();
if (!KSUCCESS(status))
return RssrvReplyStatus(endpoint, messageId, request->Operation, status, NTL_RESOURCE_KIND_INVALID);
RSSRV_ENTRY* entry = RssrvFindPrefixLocked(path, request->PathLength);
if (!entry) {
RssrvUnlockNamespace();
return RssrvReplyStatus(endpoint, messageId, request->Operation,
NTLSTATUS_NOT_FOUND, NTL_RESOURCE_KIND_INVALID);
}
SYS_RIGHTS desiredRights = 0;
if (entry->Kind == NTL_RESOURCE_KIND_VOLUME) {
desiredRights = SYS_VOLUME_RIGHT_OPEN;
if (request->Flags & NTL_RESOURCE_RESOLVE_FLAG_MODIFY)
desiredRights |= SYS_VOLUME_RIGHT_MODIFY;
} else if (entry->Kind == NTL_RESOURCE_KIND_DIRECTORY) {
desiredRights = SYS_DIR_RIGHT_OPEN;
if (request->Flags & NTL_RESOURCE_RESOLVE_FLAG_MODIFY)
desiredRights |= SYS_DIR_RIGHT_MODIFY;
} else {
uint32_t kind = entry->Kind;
RssrvUnlockNamespace();
return RssrvReplyStatus(endpoint, messageId, request->Operation,
NTLSTATUS_NOT_SUPPORTED, kind);
}
if ((desiredRights & ~entry->ExportRights) != 0) {
uint32_t kind = entry->Kind;
RssrvUnlockNamespace();
return RssrvReplyStatus(endpoint, messageId, request->Operation,
NTLSTATUS_ACCESS_DENIED, kind);
}
uint32_t kind = entry->Kind;
NTL_RESOURCE_REPLY reply;
memset(&reply, 0, sizeof(reply));
reply.Size = sizeof(reply);
reply.Version = NTL_RESOURCE_PROTOCOL_VERSION;
reply.Operation = NTL_RESOURCE_OP_RESOLVE;
reply.Flags = request->Flags;
reply.Status = NTLSTATUS_SUCCESS;
reply.Kind = kind;
reply.ResolvedLength = entry->PathLength;
SYS_PORT_HANDLE_TRANSFER transfer;
transfer.Handle = entry->Handle;
transfer.DesiredRights = desiredRights;
transfer.Flags = SYS_PORT_TRANSFER_FLAG_NONE;
SYS_REPLY_PORT_REQUEST out;
memset(&out, 0, sizeof(out));
out.Size = sizeof(out);
out.EndpointHandle = endpoint;
out.MessageId = messageId;
out.Flags = SYS_PORT_FLAG_NONE;
out.Payload = &reply;
out.PayloadLength = sizeof(reply);
out.Handles = &transfer;
out.HandleCount = 1;
status = SysReplyPort(&out);
RssrvUnlockNamespace();
if (!KSUCCESS(status))
return RssrvReplyStatus(endpoint, messageId, request->Operation, status, kind);
return NTLSTATUS_SUCCESS;
}
// Handles one metadata query.
static KSTATUS RssrvHandleQuery(SYS_HANDLE endpoint,
uint32_t messageId,
const NTL_RESOURCE_REQUEST* request,
const char* path) {
KSTATUS status = RssrvLockNamespace();
if (!KSUCCESS(status))
return RssrvReplyStatus(endpoint, messageId, request->Operation, status, NTL_RESOURCE_KIND_INVALID);
RSSRV_ENTRY* entry = RssrvFindLocked(path, request->PathLength, (RSSRV_ENTRY***)0);
uint32_t found = entry != (RSSRV_ENTRY*)0;
uint32_t kind = found ? entry->Kind : NTL_RESOURCE_KIND_INVALID;
RssrvUnlockNamespace();
return RssrvReplyStatus(endpoint, messageId, request->Operation,
found ? NTLSTATUS_SUCCESS : NTLSTATUS_NOT_FOUND, kind);
}
// Handles one administrative bind. On success the namespace takes ownership of receivedHandle.
static KSTATUS RssrvHandleBind(SYS_HANDLE endpoint,
uint32_t messageId,
const NTL_RESOURCE_REQUEST* request,
const char* path,
uint32_t administrative,
SYS_HANDLE receivedHandle,
uint32_t* consumedOut) {
if (!consumedOut) return NTLSTATUS_INVALID_PARAMETER;
*consumedOut = 0;
if (!administrative || RssrvIsManagedVolumePath(path, request->PathLength))
return RssrvReplyStatus(endpoint, messageId, request->Operation,
NTLSTATUS_ACCESS_DENIED, NTL_RESOURCE_KIND_INVALID);
KSTATUS bindStatus = RssrvBindOwned(path, request->PathLength, request->Kind, receivedHandle, request->ExportRights);
if (KSUCCESS(bindStatus)) *consumedOut = 1;
KSTATUS replyStatus = RssrvReplyStatus(endpoint, messageId, request->Operation, bindStatus,
KSUCCESS(bindStatus) ? request->Kind : NTL_RESOURCE_KIND_INVALID);
return KSUCCESS(replyStatus) ? bindStatus : replyStatus;
}
// Dispatches one received resource request and returns whether a received handle was consumed.
static uint32_t RssrvDispatchRequest(SYS_HANDLE endpoint,
uint32_t administrative,
const uint8_t* payload,
uint32_t payloadLength,
const SYS_PORT_MESSAGE_INFO* info,
SYS_HANDLE receivedHandle) {
uint32_t operation = 0;
if (payloadLength < sizeof(NTL_RESOURCE_REQUEST)) {
(void)RssrvReplyStatus(endpoint, info->MessageId, operation,
NTLSTATUS_INVALID_PARAMETER, NTL_RESOURCE_KIND_INVALID);
return 0;
}
NTL_RESOURCE_REQUEST request;
memcpy(&request, payload, sizeof(request));
operation = request.Operation;
if (request.Size != sizeof(request) || request.Version != NTL_RESOURCE_PROTOCOL_VERSION ||
request.PathLength == 0 || payloadLength != sizeof(request) + request.PathLength) {
(void)RssrvReplyStatus(endpoint, info->MessageId, operation,
NTLSTATUS_INVALID_PARAMETER, NTL_RESOURCE_KIND_INVALID);
return 0;
}
const char* path = (const char*)(payload + sizeof(request));
KSTATUS status = RssrvValidatePath(path, request.PathLength);
if (!KSUCCESS(status)) {
(void)RssrvReplyStatus(endpoint, info->MessageId, operation, status, NTL_RESOURCE_KIND_INVALID);
return 0;
}
switch (operation) {
case NTL_RESOURCE_OP_LOOKUP:
if (request.Flags != NTL_RESOURCE_FLAG_NONE || info->HandleCount != 0 ||
request.ExportRights != 0 || request.Kind != NTL_RESOURCE_KIND_INVALID) {
(void)RssrvReplyStatus(endpoint, info->MessageId, operation,
NTLSTATUS_INVALID_PARAMETER, NTL_RESOURCE_KIND_INVALID);
return 0;
}
(void)RssrvHandleLookup(endpoint, info->MessageId, &request, path);
return 0;
case NTL_RESOURCE_OP_QUERY:
if (request.Flags != NTL_RESOURCE_FLAG_NONE || info->HandleCount != 0 || request.Rights != 0 ||
request.ExportRights != 0 || request.Kind != NTL_RESOURCE_KIND_INVALID) {
(void)RssrvReplyStatus(endpoint, info->MessageId, operation,
NTLSTATUS_INVALID_PARAMETER, NTL_RESOURCE_KIND_INVALID);
return 0;
}
(void)RssrvHandleQuery(endpoint, info->MessageId, &request, path);
return 0;
case NTL_RESOURCE_OP_RESOLVE:
if (info->HandleCount != 0 || request.Rights != 0 || request.ExportRights != 0 ||
request.Kind != NTL_RESOURCE_KIND_INVALID ||
(request.Flags & ~NTL_RESOURCE_RESOLVE_FLAG_MODIFY) != 0) {
(void)RssrvReplyStatus(endpoint, info->MessageId, operation,
NTLSTATUS_INVALID_PARAMETER, NTL_RESOURCE_KIND_INVALID);
return 0;
}
(void)RssrvHandleResolve(endpoint, info->MessageId, &request, path);
return 0;
case NTL_RESOURCE_OP_BIND:
if (request.Flags != NTL_RESOURCE_FLAG_NONE || info->HandleCount != 1 ||
!(request.Rights & SYS_RIGHT_TRANSFER) ||
request.ExportRights == 0 || (request.ExportRights & ~request.Rights) != 0 ||
request.Kind == NTL_RESOURCE_KIND_INVALID || receivedHandle == SYS_HANDLE_INVALID) {
(void)RssrvReplyStatus(endpoint, info->MessageId, operation,
NTLSTATUS_INVALID_PARAMETER, NTL_RESOURCE_KIND_INVALID);
return 0;
}
{
uint32_t consumed = 0;
(void)RssrvHandleBind(endpoint, info->MessageId, &request, path, administrative,
receivedHandle, &consumed);
return consumed;
}
case NTL_RESOURCE_OP_UNBIND:
if (request.Flags != NTL_RESOURCE_FLAG_NONE || info->HandleCount != 0 || request.Rights != 0 ||
request.ExportRights != 0 || request.Kind != NTL_RESOURCE_KIND_INVALID) {
(void)RssrvReplyStatus(endpoint, info->MessageId, operation,
NTLSTATUS_INVALID_PARAMETER, NTL_RESOURCE_KIND_INVALID);
return 0;
}
status = administrative && !RssrvIsManagedVolumePath(path, request.PathLength)
? RssrvUnbind(path, request.PathLength)
: NTLSTATUS_ACCESS_DENIED;
(void)RssrvReplyStatus(endpoint, info->MessageId, operation, status, NTL_RESOURCE_KIND_INVALID);
return 0;
default:
(void)RssrvReplyStatus(endpoint, info->MessageId, operation,
NTLSTATUS_NOT_SUPPORTED, NTL_RESOURCE_KIND_INVALID);
return 0;
}
}
// Serves one connected resource session until the peer disconnects.
static void RssrvSessionThread(uintptr_t argument) {
RSSRV_SESSION* session = (RSSRV_SESSION*)argument;
if (!session) {
SysExitThread(1);
return;
}
SYS_HANDLE endpoint = session->Endpoint;
uint32_t administrative = session->Administrative;
free(session);
uint8_t payload[SYS_PORT_MAX_INLINE_BYTES];
SYS_HANDLE handles[SYS_PORT_MAX_TRANSFER_HANDLES];
for (;;) {
memset(handles, 0, sizeof(handles));
SYS_PORT_MESSAGE_INFO info;
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 = endpoint;
receive.Flags = SYS_PORT_FLAG_NONE;
receive.Payload = payload;
receive.PayloadCapacity = sizeof(payload);
receive.HandlesOut = handles;
receive.HandleCapacity = SYS_PORT_MAX_TRANSFER_HANDLES;
receive.InfoOut = &info;
receive.TimeoutMilliseconds = SYS_PORT_TIMEOUT_INFINITE;
KSTATUS status = SysReceivePort(&receive);
if (status == NTLSTATUS_PORT_DISCONNECTED)
break;
if (!KSUCCESS(status))
break;
uint32_t consumed = 0;
if (info.Type == SYS_PORT_MESSAGE_REQUEST)
consumed = RssrvDispatchRequest(endpoint, administrative, payload, info.PayloadLength,
&info, info.HandleCount == 1 ? handles[0] : SYS_HANDLE_INVALID);
for (uint32_t i = consumed ? 1u : 0u; i < info.HandleCount; ++i) {
if (handles[i] != SYS_HANDLE_INVALID) (void)SysCloseHandle(handles[i]);
}
}
(void)SysCloseHandle(endpoint);
SysExitThread(0);
}
// Accepts sessions from one listener and gives every connection its own worker thread.
static void RssrvListenerThread(uintptr_t argument) {
RSSRV_LISTENER_WORKER* worker = (RSSRV_LISTENER_WORKER*)argument;
if (!worker) {
SysExitThread(1);
return;
}
for (;;) {
SYS_HANDLE endpoint = SYS_HANDLE_INVALID;
SYS_ACCEPT_PORT_REQUEST accept;
memset(&accept, 0, sizeof(accept));
accept.Size = sizeof(accept);
accept.ListenerHandle = worker->Listener;
accept.Flags = SYS_PORT_ACCEPT_FLAG_NONE;
accept.TimeoutMilliseconds = SYS_PORT_TIMEOUT_INFINITE;
accept.EndpointHandleOut = &endpoint;
KSTATUS status = SysAcceptPort(&accept);
if (!KSUCCESS(status))
break;
RSSRV_SESSION* session = (RSSRV_SESSION*)malloc(sizeof(*session));
if (!session) {
(void)SysDisconnectPort(endpoint);
(void)SysCloseHandle(endpoint);
continue;
}
session->Endpoint = endpoint;
session->Administrative = worker->Administrative;
uint32_t threadId = 0;
SYS_CREATE_THREAD_REQUEST create;
memset(&create, 0, sizeof(create));
create.Size = sizeof(create);
create.Entry = (uintptr_t)RssrvSessionThread;
create.Argument = (uintptr_t)session;
create.Priority = 1;
create.Flags = SYS_CREATE_THREAD_FLAG_NONE;
create.ThreadIdOut = &threadId;
status = SysCreateThread(&create);
if (!KSUCCESS(status)) {
free(session);
(void)SysDisconnectPort(endpoint);
(void)SysCloseHandle(endpoint);
}
}
SysExitThread(0);
}
// Starts one resource listener worker thread.
static KSTATUS RssrvStartListenerWorker(RSSRV_LISTENER_WORKER* worker,
SYS_HANDLE listener,
uint32_t administrative) {
worker->Listener = listener;
worker->Administrative = administrative;
uint32_t threadId = 0;
SYS_CREATE_THREAD_REQUEST create;
memset(&create, 0, sizeof(create));
create.Size = sizeof(create);
create.Entry = (uintptr_t)RssrvListenerThread;
create.Argument = (uintptr_t)worker;
create.Priority = 1;
create.Flags = SYS_CREATE_THREAD_FLAG_NONE;
create.ThreadIdOut = &threadId;
return SysCreateThread(&create);
}
// Creates one listener using the service's bounded default backlog.
static KSTATUS RssrvCreateListener(SYS_HANDLE* listenerOut) {
SYS_CREATE_PORT_REQUEST create;
memset(&create, 0, sizeof(create));
create.Size = sizeof(create);
create.Flags = SYS_PORT_FLAG_NONE;
create.Backlog = RSSRV_LISTENER_BACKLOG;
create.HandleOut = listenerOut;
return SysCreatePort(&create);
}
// Accepts the one private service-manager control connection.
static KSTATUS RssrvAcceptControl(SYS_HANDLE controlListener, SYS_HANDLE* endpointOut) {
SYS_ACCEPT_PORT_REQUEST accept;
memset(&accept, 0, sizeof(accept));
accept.Size = sizeof(accept);
accept.ListenerHandle = controlListener;
accept.Flags = SYS_PORT_ACCEPT_FLAG_NONE;
accept.TimeoutMilliseconds = SYS_PORT_TIMEOUT_INFINITE;
accept.EndpointHandleOut = endpointOut;
return SysAcceptPort(&accept);
}
// Sends service readiness and delegates the private administrative resource listener to init.
static KSTATUS RssrvSendReady(SYS_HANDLE controlEndpoint) {
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_READY;
message.Flags = NTL_SERVICE_READY_FLAG_RESOURCE_ADMIN_LISTENER;
message.Status = NTLSTATUS_SUCCESS;
SYS_PORT_HANDLE_TRANSFER transfer;
transfer.Handle = gAdminListener;
transfer.DesiredRights = SYS_RIGHT_QUERY | SYS_PORT_RIGHT_CONNECT;
transfer.Flags = SYS_PORT_TRANSFER_FLAG_NONE;
SYS_SEND_PORT_REQUEST send;
memset(&send, 0, sizeof(send));
send.Size = sizeof(send);
send.EndpointHandle = controlEndpoint;
send.Flags = SYS_PORT_FLAG_NONE;
send.Payload = &message;
send.PayloadLength = sizeof(message);
send.Handles = &transfer;
send.HandleCount = 1;
send.TimeoutMilliseconds = SYS_PORT_TIMEOUT_INFINITE;
return SysSendPort(&send);
}
// Waits for the service manager's stop notification or control-port disconnect.
static void RssrvControlLoop(SYS_HANDLE controlEndpoint) {
for (;;) {
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 = controlEndpoint;
receive.Payload = &message;
receive.PayloadCapacity = sizeof(message);
receive.InfoOut = &info;
receive.TimeoutMilliseconds = SYS_PORT_TIMEOUT_INFINITE;
KSTATUS status = SysReceivePort(&receive);
if (status == NTLSTATUS_PORT_DISCONNECTED)
return;
if (!KSUCCESS(status))
return;
if (info.Type != SYS_PORT_MESSAGE_NOTIFICATION || info.HandleCount != 0 ||
info.PayloadLength != sizeof(message) || message.Size != sizeof(message) ||
message.Version != NTL_SERVICE_CONTROL_VERSION)
continue;
if (message.Operation == NTL_SERVICE_CONTROL_STOP)
return;
}
}
// Starts RSSRV and owns the global native resource namespace until init requests shutdown.
void _start(void) {
KSTATUS status = NtlInitializeExceptionRuntime();
if (!KSUCCESS(status)) RssrvExit(1);
SYS_SECURITY_CONTEXT_INFO security;
memset(&security, 0, sizeof(security));
security.Size = sizeof(security);
status = SysQuerySecurityContext(SYS_SECURITY_CONTEXT_CURRENT, &security);
if (!KSUCCESS(status) || security.EffectivePrivileges != SYS_PRIV_SYSTEM_SERVICE_REGISTER ||
security.DelegablePrivileges != 0 || security.ServiceClaims != SYS_SERVICE_CLAIM_RESOURCE ||
security.DelegableServiceClaims != 0)
RssrvExit(2);
SYS_HANDLE systemVolume = SysGetStartupCapability(SYS_STARTUP_CAP_SYSTEM_VOLUME_NAMESPACE);
SYS_HANDLE controlListener = SysGetStartupCapability(SYS_STARTUP_CAP_SERVICE_CONTROL);
SYS_HANDLE volumeManager = SysGetStartupCapability(SYS_STARTUP_CAP_VOLUME_MANAGER);
if (systemVolume == SYS_HANDLE_INVALID || controlListener == SYS_HANDLE_INVALID ||
volumeManager == SYS_HANDLE_INVALID)
RssrvExit(3);
status = SysCreateMutex(&gNamespaceMutex);
if (!KSUCCESS(status)) RssrvExit(3);
// RSSRV takes ownership of its startup system-volume handle as the first namespace binding.
static const char systemRoot[] = "/SystemRoot";
status = RssrvBindOwned(systemRoot, sizeof(systemRoot) - 1, NTL_RESOURCE_KIND_VOLUME, systemVolume,
SYS_RIGHT_QUERY | SYS_VOLUME_RIGHT_OPEN | SYS_VOLUME_RIGHT_MODIFY);
if (!KSUCCESS(status)) RssrvExit(4);
SYS_HANDLE controlEndpoint = SYS_HANDLE_INVALID;
status = RssrvAcceptControl(controlListener, &controlEndpoint);
(void)SysCloseHandle(controlListener);
if (!KSUCCESS(status)) RssrvExit(5);
status = RssrvCreateListener(&gPublicListener);
if (!KSUCCESS(status)) RssrvExit(6);
status = RssrvCreateListener(&gAdminListener);
if (!KSUCCESS(status)) RssrvExit(7);
status = RssrvStartListenerWorker(&gPublicWorker, gPublicListener, 0);
if (!KSUCCESS(status)) RssrvExit(8);
status = RssrvStartListenerWorker(&gAdminWorker, gAdminListener, 1);
if (!KSUCCESS(status)) RssrvExit(9);
uint64_t volumeGeneration = 0;
status = RssrvSyncVolumes(volumeManager, &volumeGeneration);
if (!KSUCCESS(status)) RssrvExit(10);
status = RssrvStartVolumeWorker(volumeManager);
if (!KSUCCESS(status)) RssrvExit(11);
status = SysRegisterSystemService(SYS_SERVICE_RESOURCE, gPublicListener);
if (!KSUCCESS(status)) RssrvExit(12);
status = RssrvSendReady(controlEndpoint);
if (!KSUCCESS(status)) RssrvExit(13);
RssrvControlLoop(controlEndpoint);
(void)SysUnregisterSystemService(SYS_SERVICE_RESOURCE, gPublicListener);
(void)SysDisconnectPort(controlEndpoint);
(void)SysCloseHandle(controlEndpoint);
RssrvExit(0);
}