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:
1 parent
4add6789ba
commit
f882d339fb
232 files changed
+20934
-8898
No files matched your search
@@ -0,0 +1,92 @@
|
||||
// Kernel well-known system-service registry. This file intentionally owns only numeric service discovery.
|
||||
|
||||
#include <kernel/ke_system_service.h>
|
||||
#include <kernel/ke_port.h>
|
||||
#include <kernel/ke_spinlock.h>
|
||||
#include <kernel/ob_object.h>
|
||||
#include <ntlite/security.h>
|
||||
|
||||
static SPINLOCK gSystemServiceLock = SPINLOCK_INIT;
|
||||
static PORT* gSystemServices[SYS_SERVICE_MAX + 1u];
|
||||
|
||||
// Returns whether one numeric service identifier is valid for the current ABI.
|
||||
static bool KiSystemServiceIdValid(SYS_SERVICE_ID serviceId) {
|
||||
return serviceId > SYS_SERVICE_INVALID && serviceId <= SYS_SERVICE_MAX;
|
||||
}
|
||||
|
||||
// Returns the security claim that authorizes publication of one well-known service.
|
||||
SYS_SERVICE_CLAIMS KeSystemServiceRequiredClaim(SYS_SERVICE_ID serviceId) {
|
||||
switch (serviceId) {
|
||||
case SYS_SERVICE_RESOURCE:
|
||||
return SYS_SERVICE_CLAIM_RESOURCE;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Registers one weak listener reference without creating a string or pathname namespace.
|
||||
KSTATUS KeSystemServiceRegister(SYS_SERVICE_ID serviceId, PORT* listener) {
|
||||
if (!KiSystemServiceIdValid(serviceId) || !listener || !KePortIsListener(listener))
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gSystemServiceLock);
|
||||
if (gSystemServices[serviceId]) {
|
||||
KeReleaseSpinlock(&gSystemServiceLock, flags);
|
||||
return NTLSTATUS_ALREADY_EXISTS;
|
||||
}
|
||||
gSystemServices[serviceId] = listener;
|
||||
KeReleaseSpinlock(&gSystemServiceLock, flags);
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Removes one registration only when the caller still names the registered listener object.
|
||||
KSTATUS KeSystemServiceUnregister(SYS_SERVICE_ID serviceId, PORT* listener) {
|
||||
if (!KiSystemServiceIdValid(serviceId) || !listener || !KePortIsListener(listener))
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gSystemServiceLock);
|
||||
if (!gSystemServices[serviceId]) {
|
||||
KeReleaseSpinlock(&gSystemServiceLock, flags);
|
||||
return NTLSTATUS_NOT_FOUND;
|
||||
}
|
||||
if (gSystemServices[serviceId] != listener) {
|
||||
KeReleaseSpinlock(&gSystemServiceLock, flags);
|
||||
return NTLSTATUS_ACCESS_DENIED;
|
||||
}
|
||||
gSystemServices[serviceId] = (PORT*)0;
|
||||
KeReleaseSpinlock(&gSystemServiceLock, flags);
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// References one currently registered listener for a connect operation.
|
||||
KSTATUS KeSystemServiceReference(SYS_SERVICE_ID serviceId, PORT** listenerOut) {
|
||||
if (!listenerOut)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
*listenerOut = (PORT*)0;
|
||||
if (!KiSystemServiceIdValid(serviceId))
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gSystemServiceLock);
|
||||
PORT* listener = gSystemServices[serviceId];
|
||||
if (!listener || !ObTryReferenceObject((OBJECT*)listener)) {
|
||||
KeReleaseSpinlock(&gSystemServiceLock, flags);
|
||||
return NTLSTATUS_NOT_FOUND;
|
||||
}
|
||||
KeReleaseSpinlock(&gSystemServiceLock, flags);
|
||||
|
||||
*listenerOut = listener;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Removes any weak registration whose listener is entering terminal object destruction.
|
||||
void KeSystemServiceUnregisterListener(PORT* listener) {
|
||||
if (!listener)
|
||||
return;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gSystemServiceLock);
|
||||
for (SYS_SERVICE_ID id = 1; id <= SYS_SERVICE_MAX; ++id) {
|
||||
if (gSystemServices[id] == listener)
|
||||
gSystemServices[id] = (PORT*)0;
|
||||
}
|
||||
KeReleaseSpinlock(&gSystemServiceLock, flags);
|
||||
}
|
||||
Reference in new issue
Block a user