307 lines
13 KiB
C
307 lines
13 KiB
C
// Internal RSSRV component model. One process owns the native resource plane, while each component owns its state.
|
|
|
|
#pragma once
|
|
|
|
#include <ntlite/resource.h>
|
|
#include <ntlite/input_service.h>
|
|
#include <ntlite/console_service.h>
|
|
#include <ntlite/syscall.h>
|
|
#include <stdint.h>
|
|
|
|
#define RSSRV_LISTENER_BACKLOG 16u
|
|
#define RSSRV_SYMBOLIC_LINK_MAX_DEPTH 16u
|
|
#define RSSRV_VOLUME_PATH_CAPACITY 48u
|
|
#define RSSRV_INPUT_KEY_QUEUE_SIZE 256u
|
|
#define RSSRV_INPUT_MOUSE_QUEUE_SIZE 128u
|
|
#define RSSRV_CONSOLE_KEY_QUEUE_SIZE 256u
|
|
|
|
typedef struct RSSRV_NODE RSSRV_NODE;
|
|
typedef struct RSSRV_VOLUME_PUBLICATION RSSRV_VOLUME_PUBLICATION;
|
|
typedef struct RSSRV_RESOURCE_SERVICE RSSRV_RESOURCE_SERVICE;
|
|
typedef struct RSSRV_SESSION_STATE RSSRV_SESSION_STATE;
|
|
typedef struct RSSRV_INPUT_TARGET RSSRV_INPUT_TARGET;
|
|
|
|
typedef void (*RSSRV_INPUT_TARGET_KEY_ROUTINE)(void* context, const INPUT_KEY_RECORD* record);
|
|
typedef void (*RSSRV_INPUT_TARGET_MOUSE_ROUTINE)(void* context, const INPUT_MOUSE_EVENT* event, int32_t x, int32_t y);
|
|
|
|
#define RSSRV_INPUT_TARGET_KIND_NONE 0u
|
|
#define RSSRV_INPUT_TARGET_KIND_CONSOLE 1u
|
|
#define RSSRV_INPUT_TARGET_KIND_DESKTOP 2u
|
|
|
|
struct RSSRV_INPUT_TARGET {
|
|
uint64_t Id;
|
|
uint32_t Kind;
|
|
uint32_t Flags;
|
|
RSSRV_SESSION_STATE* Session;
|
|
void* Context;
|
|
RSSRV_INPUT_TARGET_KEY_ROUTINE KeyRoutine;
|
|
RSSRV_INPUT_TARGET_MOUSE_ROUTINE MouseRoutine;
|
|
};
|
|
|
|
typedef struct RSSRV_NAMESPACE {
|
|
SYS_HANDLE Mutex;
|
|
RSSRV_NODE* Root;
|
|
} RSSRV_NAMESPACE;
|
|
|
|
typedef struct RSSRV_NAMESPACE_BINDING_VIEW {
|
|
RSSRV_NAMESPACE* Namespace;
|
|
SYS_HANDLE Handle;
|
|
uint32_t Kind;
|
|
SYS_RIGHTS ExportRights;
|
|
uint32_t ResolvedLength;
|
|
uint32_t Locked;
|
|
} RSSRV_NAMESPACE_BINDING_VIEW;
|
|
|
|
typedef struct RSSRV_NAMESPACE_ENTRY {
|
|
uint32_t Kind;
|
|
uint32_t NameLength;
|
|
char Name[NTL_RESOURCE_NAME_MAX + 1u];
|
|
} RSSRV_NAMESPACE_ENTRY;
|
|
|
|
typedef struct RSSRV_DISPLAY_STATE {
|
|
SYS_HANDLE Manager;
|
|
RSSRV_NAMESPACE* Namespace;
|
|
} RSSRV_DISPLAY_STATE;
|
|
|
|
struct RSSRV_SESSION_STATE {
|
|
SYS_HANDLE Mutex;
|
|
RSSRV_NAMESPACE* Namespace;
|
|
RSSRV_DISPLAY_STATE* Display;
|
|
uint32_t Id;
|
|
uint32_t Reserved;
|
|
uint64_t Generation;
|
|
uint64_t NextTargetId;
|
|
int32_t DisplayWidth;
|
|
int32_t DisplayHeight;
|
|
RSSRV_INPUT_TARGET* ActiveTarget;
|
|
RSSRV_INPUT_TARGET* KeyboardFocus;
|
|
RSSRV_INPUT_TARGET* PointerFocus;
|
|
RSSRV_INPUT_TARGET* PointerCapture;
|
|
SYS_HANDLE DwmListener;
|
|
SYS_HANDLE DwmEndpoint;
|
|
RSSRV_INPUT_TARGET DesktopTarget;
|
|
};
|
|
|
|
typedef struct RSSRV_INPUT_STATE {
|
|
SYS_HANDLE Manager;
|
|
SYS_HANDLE Mutex;
|
|
SYS_HANDLE KeyEvent;
|
|
SYS_HANDLE MouseEvent;
|
|
SYS_HANDLE RepeatTimer;
|
|
SYS_HANDLE Listener;
|
|
RSSRV_NAMESPACE* Namespace;
|
|
RSSRV_SESSION_STATE* Session;
|
|
|
|
uint8_t KeyDown[NTL_INPUT_KEY_BYTES];
|
|
uint32_t Modifiers;
|
|
INPUT_KEY RepeatKey;
|
|
uint64_t Generation;
|
|
INPUT_KEY_RECORD KeyQueue[RSSRV_INPUT_KEY_QUEUE_SIZE];
|
|
uint32_t KeyHead;
|
|
uint32_t KeyTail;
|
|
|
|
INPUT_MOUSE_EVENT MouseQueue[RSSRV_INPUT_MOUSE_QUEUE_SIZE];
|
|
uint32_t MouseHead;
|
|
uint32_t MouseTail;
|
|
int32_t MouseX;
|
|
int32_t MouseY;
|
|
int32_t MouseWheel;
|
|
uint32_t MouseButtons;
|
|
int32_t MouseWidth;
|
|
int32_t MouseHeight;
|
|
} RSSRV_INPUT_STATE;
|
|
|
|
typedef struct RSSRV_CONSOLE_STATE {
|
|
SYS_HANDLE Mutex;
|
|
SYS_HANDLE KeyEvent;
|
|
SYS_HANDLE Listener;
|
|
RSSRV_NAMESPACE* Namespace;
|
|
RSSRV_DISPLAY_STATE* Display;
|
|
RSSRV_SESSION_STATE* Session;
|
|
RSSRV_INPUT_TARGET InputTarget;
|
|
INPUT_KEY_RECORD KeyQueue[RSSRV_CONSOLE_KEY_QUEUE_SIZE];
|
|
uint32_t KeyHead;
|
|
uint32_t KeyTail;
|
|
uint64_t Generation;
|
|
} RSSRV_CONSOLE_STATE;
|
|
|
|
typedef struct RSSRV_VOLUME_STATE {
|
|
RSSRV_NAMESPACE* Namespace;
|
|
SYS_HANDLE Manager;
|
|
RSSRV_VOLUME_PUBLICATION* Published;
|
|
uint32_t NextHarddiskVolumeId;
|
|
} RSSRV_VOLUME_STATE;
|
|
|
|
typedef struct RSSRV_LISTENER_WORKER {
|
|
RSSRV_RESOURCE_SERVICE* Service;
|
|
SYS_HANDLE Listener;
|
|
uint32_t Administrative;
|
|
} RSSRV_LISTENER_WORKER;
|
|
|
|
struct RSSRV_RESOURCE_SERVICE {
|
|
RSSRV_NAMESPACE* Namespace;
|
|
SYS_HANDLE PublicListener;
|
|
SYS_HANDLE AdminListener;
|
|
RSSRV_LISTENER_WORKER PublicWorker;
|
|
RSSRV_LISTENER_WORKER AdminWorker;
|
|
};
|
|
|
|
typedef struct RSSRV_STATE {
|
|
RSSRV_NAMESPACE Namespace;
|
|
RSSRV_VOLUME_STATE Volumes;
|
|
RSSRV_DISPLAY_STATE Display;
|
|
RSSRV_SESSION_STATE Session;
|
|
RSSRV_INPUT_STATE Input;
|
|
RSSRV_CONSOLE_STATE Console;
|
|
RSSRV_RESOURCE_SERVICE Resource;
|
|
} RSSRV_STATE;
|
|
|
|
// Sets a best-effort diagnostic name for the current RSSRV thread.
|
|
void RssrvSetCurrentThreadName(const char* name);
|
|
|
|
// Terminates RSSRV without depending on a compiler runtime return path.
|
|
void RssrvExit(int code);
|
|
|
|
// Initializes the native namespace root and its synchronization object.
|
|
KSTATUS RssrvNamespaceInitialize(RSSRV_NAMESPACE* namespaceState);
|
|
|
|
// Validates one canonical absolute native resource path, including the root path "/".
|
|
KSTATUS RssrvNamespaceValidatePath(const char* path, uint32_t length);
|
|
|
|
// Creates one exact namespace directory. Its parent must already exist.
|
|
KSTATUS RssrvNamespaceCreateDirectory(RSSRV_NAMESPACE* namespaceState,
|
|
const char* path,
|
|
uint32_t length);
|
|
|
|
// Creates one absolute namespace symbolic link. Dangling targets are permitted.
|
|
KSTATUS RssrvNamespaceCreateSymbolicLink(RSSRV_NAMESPACE* namespaceState,
|
|
const char* path,
|
|
uint32_t length,
|
|
const char* target,
|
|
uint32_t targetLength);
|
|
|
|
// Takes ownership of one handle and binds it to a new exact resource name.
|
|
KSTATUS RssrvNamespaceBindOwned(RSSRV_NAMESPACE* namespaceState,
|
|
const char* path,
|
|
uint32_t length,
|
|
uint32_t kind,
|
|
SYS_HANDLE handle,
|
|
SYS_RIGHTS exportRights);
|
|
|
|
// Removes one exact namespace node. Namespace directories must be empty.
|
|
KSTATUS RssrvNamespaceUnbind(RSSRV_NAMESPACE* namespaceState,
|
|
const char* path,
|
|
uint32_t length);
|
|
|
|
// Queries one exact namespace node without following the final symbolic link.
|
|
KSTATUS RssrvNamespaceQuery(RSSRV_NAMESPACE* namespaceState,
|
|
const char* path,
|
|
uint32_t length,
|
|
uint32_t* kindOut);
|
|
|
|
// Returns the lexicographically next immediate child after one optional cursor name.
|
|
KSTATUS RssrvNamespaceEnumerate(RSSRV_NAMESPACE* namespaceState,
|
|
const char* path,
|
|
uint32_t length,
|
|
const char* after,
|
|
uint32_t afterLength,
|
|
RSSRV_NAMESPACE_ENTRY* entryOut);
|
|
|
|
// Opens a locked view of one exact bound object, following a final namespace symbolic link.
|
|
KSTATUS RssrvNamespaceBeginLookup(RSSRV_NAMESPACE* namespaceState,
|
|
const char* path,
|
|
uint32_t length,
|
|
RSSRV_NAMESPACE_BINDING_VIEW* viewOut,
|
|
uint32_t* kindOut);
|
|
|
|
// Opens a locked view of the first bound object reached while traversing one resource path.
|
|
KSTATUS RssrvNamespaceBeginResolve(RSSRV_NAMESPACE* namespaceState,
|
|
const char* path,
|
|
uint32_t length,
|
|
RSSRV_NAMESPACE_BINDING_VIEW* viewOut);
|
|
|
|
// Releases the namespace lock held by a successful binding view.
|
|
void RssrvNamespaceEndBinding(RSSRV_NAMESPACE_BINDING_VIEW* view);
|
|
|
|
// Initializes display authority around the kernel display-manager capability.
|
|
KSTATUS RssrvDisplayInitialize(RSSRV_DISPLAY_STATE* display, RSSRV_NAMESPACE* namespaceState, SYS_HANDLE manager);
|
|
// Publishes a query-only display device capability while retaining physical display authority inside RSSRV.
|
|
KSTATUS RssrvDisplayPublishDevice(RSSRV_DISPLAY_STATE* display);
|
|
KSTATUS RssrvDisplayQueryInfo(RSSRV_DISPLAY_STATE* display, SYS_DISPLAY_INFO* infoOut);
|
|
KSTATUS RssrvDisplayWriteConsole(RSSRV_DISPLAY_STATE* display, const char* data, size_t length);
|
|
KSTATUS RssrvDisplayQueryConsoleInfo(RSSRV_DISPLAY_STATE* display, SYS_CONSOLE_INFO* infoOut);
|
|
KSTATUS RssrvDisplaySetConsoleCursor(RSSRV_DISPLAY_STATE* display, int x, int y);
|
|
KSTATUS RssrvDisplayFillConsoleCharacter(RSSRV_DISPLAY_STATE* display, char character,
|
|
int x, int y, size_t length, size_t* writtenOut);
|
|
KSTATUS RssrvDisplayFillConsoleAttribute(RSSRV_DISPLAY_STATE* display, uint16_t attribute,
|
|
int x, int y, size_t length, size_t* writtenOut);
|
|
KSTATUS RssrvDisplayPutConsoleCharacter(RSSRV_DISPLAY_STATE* display, char character,
|
|
int x, int y, uint32_t foreground, uint32_t background);
|
|
KSTATUS RssrvDisplayClearConsole(RSSRV_DISPLAY_STATE* display, uint32_t color);
|
|
|
|
// Initializes Session 0, input routing, and display ownership.
|
|
KSTATUS RssrvSessionInitialize(RSSRV_SESSION_STATE* session,
|
|
RSSRV_NAMESPACE* namespaceState,
|
|
RSSRV_DISPLAY_STATE* display);
|
|
KSTATUS RssrvSessionRegisterInputTarget(RSSRV_SESSION_STATE* session,
|
|
RSSRV_INPUT_TARGET* target,
|
|
uint32_t kind,
|
|
void* context,
|
|
RSSRV_INPUT_TARGET_KEY_ROUTINE keyRoutine,
|
|
RSSRV_INPUT_TARGET_MOUSE_ROUTINE mouseRoutine);
|
|
KSTATUS RssrvSessionActivateInputTarget(RSSRV_SESSION_STATE* session, RSSRV_INPUT_TARGET* target);
|
|
KSTATUS RssrvSessionSetKeyboardFocus(RSSRV_SESSION_STATE* session, RSSRV_INPUT_TARGET* target);
|
|
KSTATUS RssrvSessionSetPointerFocus(RSSRV_SESSION_STATE* session, RSSRV_INPUT_TARGET* target);
|
|
KSTATUS RssrvSessionSetPointerCapture(RSSRV_SESSION_STATE* session, RSSRV_INPUT_TARGET* target);
|
|
KSTATUS RssrvSessionQueryDisplayBounds(RSSRV_SESSION_STATE* session, int32_t* widthOut, int32_t* heightOut);
|
|
void RssrvSessionObserveKey(RSSRV_SESSION_STATE* session, const INPUT_KEY_RECORD* record);
|
|
void RssrvSessionObserveMouse(RSSRV_SESSION_STATE* session, const INPUT_MOUSE_EVENT* event, int32_t x, int32_t y);
|
|
void RssrvSessionRouteKey(RSSRV_SESSION_STATE* session, const INPUT_KEY_RECORD* record);
|
|
void RssrvSessionRouteMouse(RSSRV_SESSION_STATE* session, const INPUT_MOUSE_EVENT* event, int32_t x, int32_t y);
|
|
KSTATUS RssrvSessionStart(RSSRV_SESSION_STATE* session, RSSRV_CONSOLE_STATE* console);
|
|
|
|
// Initializes and starts RSSRV-owned logical input over the kernel manager stream.
|
|
KSTATUS RssrvInputInitialize(RSSRV_INPUT_STATE* input,
|
|
RSSRV_NAMESPACE* namespaceState,
|
|
RSSRV_SESSION_STATE* session,
|
|
SYS_HANDLE manager);
|
|
KSTATUS RssrvInputStart(RSSRV_INPUT_STATE* input);
|
|
KSTATUS RssrvInputReadKeyRecord(RSSRV_INPUT_STATE* input, int peek,
|
|
uint64_t timeoutMilliseconds, INPUT_KEY_RECORD* recordOut);
|
|
KSTATUS RssrvInputFlushKeys(RSSRV_INPUT_STATE* input, uint32_t* discardedOut);
|
|
|
|
// Initializes and starts the one native logical console owned by RSSRV.
|
|
KSTATUS RssrvConsoleInitialize(RSSRV_CONSOLE_STATE* console,
|
|
RSSRV_NAMESPACE* namespaceState,
|
|
RSSRV_DISPLAY_STATE* display,
|
|
RSSRV_SESSION_STATE* session);
|
|
KSTATUS RssrvConsoleStart(RSSRV_CONSOLE_STATE* console);
|
|
|
|
// Initializes mounted-volume publication state against one volume-manager capability.
|
|
KSTATUS RssrvVolumesInitialize(RSSRV_VOLUME_STATE* volumes,
|
|
RSSRV_NAMESPACE* namespaceState,
|
|
SYS_HANDLE manager);
|
|
|
|
// Reconciles RSSRV volume bindings with the kernel's mounted-volume snapshot.
|
|
KSTATUS RssrvVolumesSynchronize(RSSRV_VOLUME_STATE* volumes, uint64_t* generationOut);
|
|
|
|
// Copies the namespace path assigned to one mounted kernel volume instance.
|
|
KSTATUS RssrvVolumesQueryPublishedPath(RSSRV_VOLUME_STATE* volumes,
|
|
uint32_t instanceId,
|
|
char* pathOut,
|
|
uint32_t capacity,
|
|
uint32_t* lengthOut);
|
|
|
|
// Starts the mounted-volume namespace publication worker.
|
|
KSTATUS RssrvVolumesStartWorker(RSSRV_VOLUME_STATE* volumes);
|
|
|
|
// Returns whether a path belongs to the RSSRV-owned automatic mounted-volume naming family.
|
|
int RssrvVolumesOwnPath(const char* path, uint32_t length);
|
|
|
|
// Initializes the public/admin resource protocol component around existing namespace state.
|
|
KSTATUS RssrvResourceInitialize(RSSRV_RESOURCE_SERVICE* service,
|
|
RSSRV_NAMESPACE* namespaceState);
|
|
|
|
// Creates the resource listeners and starts their accept workers.
|
|
KSTATUS RssrvResourceStart(RSSRV_RESOURCE_SERVICE* service);
|