replace ad hoc driver loading with a proper driver manager, new DDK, new PnP manager with device matching, asynchronous startup, resource ownership and removal, add shared PCI capability helpers, replace typed, rigid services with a proper service manager, implement proper system shutdown and restart, shutting down unloads drivers and shuts down services, add simple power button, remove heavyweight boot self-tests and SMP stress runs, add monotonic timestamps to kernel debug output, fruitless USB and PS/2 fixes, make test builds opt in.
This commit is contained in:
1 parent
c0ad63c27f
commit
d36f19509c
160 files changed
+6563
-7366
No files matched your search
+69
-32
@@ -33,6 +33,7 @@
|
||||
#include <kernel/ke_cpu.h>
|
||||
#include <kernel/ke_sched.h>
|
||||
#include <kernel/ke_process.h>
|
||||
#include <kernel/ke_power.h>
|
||||
#include <kernel/se_security.h>
|
||||
#include <kernel/ke_mutex.h>
|
||||
#include <kernel/ke_semaphore.h>
|
||||
@@ -317,6 +318,40 @@ static size_t KiAlignUpSize(size_t value, size_t alignment) {
|
||||
|
||||
// Individual syscall handlers.
|
||||
|
||||
static uint64_t SyscallOpenPowerEvent(SYS_HANDLE* handleOut) {
|
||||
if (!handleOut) return NTLSTATUS_INVALID_PARAMETER;
|
||||
KSTATUS st = MmProbeUserWrite(handleOut, sizeof(*handleOut));
|
||||
if (!KSUCCESS(st)) return st;
|
||||
PROCESS* caller = KeGetCurrentProcess();
|
||||
EVENT* event = KePowerRequestEvent(caller);
|
||||
if (!event) return NTLSTATUS_ACCESS_DENIED;
|
||||
SYS_HANDLE handle = SYS_HANDLE_INVALID;
|
||||
st = KiAllocHandleForCurrentWithRights(&event->Header,
|
||||
SYS_RIGHT_WAIT | SYS_RIGHT_QUERY, &handle);
|
||||
if (!KSUCCESS(st)) return st;
|
||||
st = KiCopyHandleToUser(handleOut, handle);
|
||||
if (!KSUCCESS(st)) (void)KeCloseHandle(caller, handle);
|
||||
return st;
|
||||
}
|
||||
|
||||
static uint64_t SyscallRequestSystemPower(uint32_t action) {
|
||||
KSTATUS st = KiRequirePrivilege(SYS_PRIV_SYSTEM_POWER);
|
||||
return KSUCCESS(st) ? KePowerRequest(action) : st;
|
||||
}
|
||||
|
||||
static uint64_t SyscallQuerySystemPower(uint32_t* actionOut) {
|
||||
if (!actionOut) return NTLSTATUS_INVALID_PARAMETER;
|
||||
KSTATUS st = MmProbeUserWrite(actionOut, sizeof(*actionOut));
|
||||
if (!KSUCCESS(st)) return st;
|
||||
uint32_t action = 0;
|
||||
st = KePowerGetRequest(KeGetCurrentProcess(), &action);
|
||||
return KSUCCESS(st) ? KiCopyU32ToUser(actionOut, action) : st;
|
||||
}
|
||||
|
||||
static uint64_t SyscallCompleteSystemPower(uint32_t action) {
|
||||
return KePowerComplete(KeGetCurrentProcess(), action);
|
||||
}
|
||||
|
||||
// Implements SYS_EXIT_PROCESS.
|
||||
static uint64_t SyscallExitProcess(int32_t exitCode) {
|
||||
THREAD* t = KeGetCurrentThread();
|
||||
@@ -2873,12 +2908,12 @@ static uint64_t SyscallStartProcess(const SYS_START_PROCESS_REQUEST* request) {
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < req.StartupCapabilityCount && KSUCCESS(status); ++i) {
|
||||
if (!capabilities[i].Tag || capabilities[i].Handle == SYS_HANDLE_INVALID) {
|
||||
if (!SysStartupCapabilityNameValid(capabilities[i].Name) || capabilities[i].Handle == SYS_HANDLE_INVALID) {
|
||||
status = NTLSTATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
for (uint32_t j = 0; j < i; ++j) {
|
||||
if (capabilities[j].Tag == capabilities[i].Tag) {
|
||||
if (strcmp(capabilities[j].Name, capabilities[i].Name) == 0) {
|
||||
status = NTLSTATUS_OBJECT_NAME_COLLISION;
|
||||
break;
|
||||
}
|
||||
@@ -3414,48 +3449,48 @@ static uint64_t SyscallOpenPortPeerProcess(SYS_HANDLE endpointHandle,
|
||||
return status;
|
||||
}
|
||||
|
||||
// Implements SYS_REGISTER_SYSTEM_SERVICE.
|
||||
static uint64_t SyscallRegisterSystemService(SYS_SERVICE_ID serviceId, SYS_HANDLE listenerHandle) {
|
||||
if (serviceId == SYS_SERVICE_INVALID || serviceId > SYS_SERVICE_MAX)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
KSTATUS status = KiRequirePrivilege(SYS_PRIV_SYSTEM_SERVICE_REGISTER);
|
||||
// Implements SYS_REGISTER_SYSTEM_SERVICE using a typed, attenuable registration authority.
|
||||
static uint64_t SyscallRegisterSystemService(SYS_HANDLE registrationHandle, SYS_HANDLE listenerHandle) {
|
||||
PROCESS* process = KeGetCurrentProcess();
|
||||
if (!process) return NTLSTATUS_FAILURE;
|
||||
|
||||
OBJECT* authority = (OBJECT*)0;
|
||||
KSTATUS status = KeReferenceHandle(process, registrationHandle, ObjectTypeServiceRegistration,
|
||||
SYS_SERVICE_REGISTRATION_RIGHT_REGISTER, &authority);
|
||||
if (!KSUCCESS(status)) return status;
|
||||
|
||||
PROCESS* process = KeGetCurrentProcess();
|
||||
SYS_SERVICE_CLAIMS claim = KeSystemServiceRequiredClaim(serviceId);
|
||||
if (!process || !process->SecurityContext || claim == 0 ||
|
||||
!SeContextHasServiceClaims(process->SecurityContext, claim))
|
||||
return NTLSTATUS_ACCESS_DENIED;
|
||||
SYS_SERVICE_ID serviceId = SYS_SERVICE_INVALID;
|
||||
status = KeSystemServiceRegistrationIdentity(authority, &serviceId);
|
||||
ObDereferenceObject(authority);
|
||||
if (!KSUCCESS(status)) return status;
|
||||
|
||||
KSTATUS handleStatus = NTLSTATUS_SUCCESS;
|
||||
PORT* listener = (PORT*)KiHandleToObject(listenerHandle,
|
||||
ObjectTypePort,
|
||||
SYS_PORT_RIGHT_ACCEPT,
|
||||
&handleStatus);
|
||||
PORT* listener = (PORT*)KiHandleToObject(listenerHandle, ObjectTypePort,
|
||||
SYS_PORT_RIGHT_ACCEPT, &handleStatus);
|
||||
if (!listener) return handleStatus;
|
||||
status = KeSystemServiceRegister(serviceId, listener);
|
||||
ObDereferenceObject((OBJECT*)listener);
|
||||
return status;
|
||||
}
|
||||
|
||||
// Implements SYS_UNREGISTER_SYSTEM_SERVICE.
|
||||
static uint64_t SyscallUnregisterSystemService(SYS_SERVICE_ID serviceId, SYS_HANDLE listenerHandle) {
|
||||
if (serviceId == SYS_SERVICE_INVALID || serviceId > SYS_SERVICE_MAX)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
KSTATUS status = KiRequirePrivilege(SYS_PRIV_SYSTEM_SERVICE_REGISTER);
|
||||
// Implements SYS_UNREGISTER_SYSTEM_SERVICE using the same typed authority.
|
||||
static uint64_t SyscallUnregisterSystemService(SYS_HANDLE registrationHandle, SYS_HANDLE listenerHandle) {
|
||||
PROCESS* process = KeGetCurrentProcess();
|
||||
if (!process) return NTLSTATUS_FAILURE;
|
||||
|
||||
OBJECT* authority = (OBJECT*)0;
|
||||
KSTATUS status = KeReferenceHandle(process, registrationHandle, ObjectTypeServiceRegistration,
|
||||
SYS_SERVICE_REGISTRATION_RIGHT_UNREGISTER, &authority);
|
||||
if (!KSUCCESS(status)) return status;
|
||||
|
||||
PROCESS* process = KeGetCurrentProcess();
|
||||
SYS_SERVICE_CLAIMS claim = KeSystemServiceRequiredClaim(serviceId);
|
||||
if (!process || !process->SecurityContext || claim == 0 ||
|
||||
!SeContextHasServiceClaims(process->SecurityContext, claim))
|
||||
return NTLSTATUS_ACCESS_DENIED;
|
||||
SYS_SERVICE_ID serviceId = SYS_SERVICE_INVALID;
|
||||
status = KeSystemServiceRegistrationIdentity(authority, &serviceId);
|
||||
ObDereferenceObject(authority);
|
||||
if (!KSUCCESS(status)) return status;
|
||||
|
||||
KSTATUS handleStatus = NTLSTATUS_SUCCESS;
|
||||
PORT* listener = (PORT*)KiHandleToObject(listenerHandle,
|
||||
ObjectTypePort,
|
||||
SYS_PORT_RIGHT_ACCEPT,
|
||||
&handleStatus);
|
||||
PORT* listener = (PORT*)KiHandleToObject(listenerHandle, ObjectTypePort,
|
||||
SYS_PORT_RIGHT_ACCEPT, &handleStatus);
|
||||
if (!listener) return handleStatus;
|
||||
status = KeSystemServiceUnregister(serviceId, listener);
|
||||
ObDereferenceObject((OBJECT*)listener);
|
||||
@@ -3700,8 +3735,6 @@ static uint64_t SyscallDeriveSecurityContext(const SYS_DERIVE_SECURITY_CONTEXT_R
|
||||
status = SeDeriveSecurityContext(source,
|
||||
req.EffectivePrivileges,
|
||||
req.DelegablePrivileges,
|
||||
req.ServiceClaims,
|
||||
req.DelegableServiceClaims,
|
||||
&derived);
|
||||
ObDereferenceObject(&source->Header);
|
||||
if (!KSUCCESS(status)) return status;
|
||||
@@ -6197,6 +6230,10 @@ typedef struct SYSCALL_ENTRY {
|
||||
|
||||
static const SYSCALL_ENTRY gSyscallTable[SYS_MAX] = {
|
||||
// Process, threads, waits, APC, and exceptions.
|
||||
[SYS_OPEN_POWER_EVENT] = SYSCALL_ENTRY1(SyscallOpenPowerEvent),
|
||||
[SYS_REQUEST_SYSTEM_POWER] = SYSCALL_ENTRY1(SyscallRequestSystemPower),
|
||||
[SYS_QUERY_SYSTEM_POWER] = SYSCALL_ENTRY1(SyscallQuerySystemPower),
|
||||
[SYS_COMPLETE_SYSTEM_POWER] = SYSCALL_ENTRY1(SyscallCompleteSystemPower),
|
||||
[SYS_EXIT_PROCESS] = SYSCALL_ENTRY1(SyscallExitProcess),
|
||||
[SYS_EXIT_THREAD] = SYSCALL_ENTRY1(SyscallExitThread),
|
||||
[SYS_CREATE_PROCESS_OBJECT] = SYSCALL_ENTRY1(SyscallCreateProcessObject),
|
||||
|
||||
Reference in new issue
Block a user