// Kernel well-known system-service registry. This file intentionally owns only numeric service discovery. #include #include #include #include #include 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; } // Authority is an object capability, never a process privilege or service role. typedef struct KE_SERVICE_REGISTRATION_AUTHORITY { OBJECT Header; SYS_SERVICE_ID ServiceId; } KE_SERVICE_REGISTRATION_AUTHORITY; // Creates a capability to register one numeric service identity. KSTATUS KeSystemServiceCreateRegistrationAuthority(SYS_SERVICE_ID serviceId, OBJECT** authorityOut) { if (!authorityOut) return NTLSTATUS_INVALID_PARAMETER; *authorityOut = (OBJECT*)0; if (!KiSystemServiceIdValid(serviceId)) return NTLSTATUS_INVALID_PARAMETER; KE_SERVICE_REGISTRATION_AUTHORITY* authority = (KE_SERVICE_REGISTRATION_AUTHORITY*)ObAllocateObject(ObjectTypeServiceRegistration, sizeof(*authority)); if (!authority) return NTLSTATUS_NO_MEMORY; authority->ServiceId = serviceId; *authorityOut = &authority->Header; return NTLSTATUS_SUCCESS; } // Resolves an authority's registry identity without consulting process identity. KSTATUS KeSystemServiceRegistrationIdentity(const OBJECT* object, SYS_SERVICE_ID* serviceIdOut) { if (!object || !serviceIdOut || object->Type != ObjectTypeServiceRegistration) return NTLSTATUS_INVALID_PARAMETER; const KE_SERVICE_REGISTRATION_AUTHORITY* authority = (const KE_SERVICE_REGISTRATION_AUTHORITY*)object; if (!KiSystemServiceIdValid(authority->ServiceId)) return NTLSTATUS_INVALID_PARAMETER; *serviceIdOut = authority->ServiceId; return NTLSTATUS_SUCCESS; } // 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); }