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
@@ -0,0 +1,135 @@
|
||||
// Input model smoke test.
|
||||
// Verifies that input queue handles and request-based reads target one keyboard queue.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
// Prints one NUL-terminated string to the kernel console.
|
||||
static void print(const char* s) {
|
||||
SYS_WRITE_CONSOLE_REQUEST req = { sizeof(SYS_WRITE_CONSOLE_REQUEST), SysSvFromCstr(s) };
|
||||
SysWriteConsole(&req);
|
||||
}
|
||||
|
||||
// Prints one unsigned integer to the kernel console.
|
||||
static void print_u64(uint64_t v) {
|
||||
char buf[32];
|
||||
int i = 0;
|
||||
if (v == 0) {
|
||||
print("0");
|
||||
return;
|
||||
}
|
||||
while (v && i < (int)sizeof(buf)) {
|
||||
buf[i++] = (char)('0' + (v % 10));
|
||||
v /= 10;
|
||||
}
|
||||
while (i--) {
|
||||
char c = buf[i];
|
||||
SYS_WRITE_CONSOLE_REQUEST req = { sizeof(SYS_WRITE_CONSOLE_REQUEST), SysSvFromParts(&c, 1) };
|
||||
SysWriteConsole(&req);
|
||||
}
|
||||
}
|
||||
|
||||
// Terminates the current test process.
|
||||
static void exit_now(int code) {
|
||||
while (true) SysExitProcess(code);
|
||||
}
|
||||
|
||||
// Fails the test with one status value.
|
||||
static void fail_status(const char* what, uint32_t status) {
|
||||
print("input_model_smoke: ");
|
||||
print(what);
|
||||
print(" status=");
|
||||
print_u64(status);
|
||||
print("\n");
|
||||
exit_now(1);
|
||||
}
|
||||
|
||||
// Requires one exact status value.
|
||||
static void expect_status(const char* what, uint32_t got, uint32_t expected) {
|
||||
if (got == expected) return;
|
||||
print("input_model_smoke: ");
|
||||
print(what);
|
||||
print(" got=");
|
||||
print_u64(got);
|
||||
print(" expected=");
|
||||
print_u64(expected);
|
||||
print("\n");
|
||||
exit_now(1);
|
||||
}
|
||||
|
||||
// Program entry point.
|
||||
int main(void) {
|
||||
print("input_model_smoke: start\n");
|
||||
|
||||
uint32_t inputQueue = 0;
|
||||
expect_status("open input queue null", SysOpenInputQueue(SYS_INPUT_QUEUE_FLAG_NONE, (uint32_t*)0), NTLSTATUS_INVALID_PARAMETER);
|
||||
expect_status("open input queue bad flags", SysOpenInputQueue(1, &inputQueue), NTLSTATUS_INVALID_PARAMETER);
|
||||
|
||||
uint32_t status = SysOpenInputQueue(SYS_INPUT_QUEUE_FLAG_NONE, &inputQueue);
|
||||
if (status != NTLSTATUS_SUCCESS)
|
||||
fail_status("open input queue", status);
|
||||
|
||||
INPUT_KEY_RECORD record;
|
||||
SYS_INPUT_EVENT_REQUEST req;
|
||||
req.Size = sizeof(req);
|
||||
req.QueueHandle = inputQueue;
|
||||
req.Flags = SYS_INPUT_EVENT_FLAG_NONE;
|
||||
req.TimeoutMilliseconds = 0;
|
||||
req.RecordOut = &record;
|
||||
|
||||
SYS_INPUT_EVENT_REQUEST badReq = req;
|
||||
badReq.Size = 0;
|
||||
expect_status("read input bad size", SysReadInputEvent(&badReq), NTLSTATUS_INVALID_PARAMETER);
|
||||
|
||||
badReq = req;
|
||||
badReq.RecordOut = (INPUT_KEY_RECORD*)0;
|
||||
expect_status("peek input null out", SysPeekInputEvent(&badReq), NTLSTATUS_INVALID_PARAMETER);
|
||||
|
||||
badReq = req;
|
||||
badReq.QueueHandle = 0xdeadbeefu;
|
||||
expect_status("read input bad handle", SysReadInputEvent(&badReq), NTLSTATUS_INVALID_HANDLE);
|
||||
|
||||
SYS_GLOBAL_INPUT_STATE state;
|
||||
state.Size = sizeof(state);
|
||||
state.Flags = SYS_GLOBAL_INPUT_STATE_FLAG_NONE;
|
||||
expect_status("query global input null", SysQueryGlobalInputState((SYS_GLOBAL_INPUT_STATE*)0), NTLSTATUS_INVALID_PARAMETER);
|
||||
|
||||
SYS_GLOBAL_INPUT_STATE badState = state;
|
||||
badState.Size = 0;
|
||||
expect_status("query global input bad size", SysQueryGlobalInputState(&badState), NTLSTATUS_INVALID_PARAMETER);
|
||||
|
||||
badState = state;
|
||||
badState.Flags = 1;
|
||||
expect_status("query global input bad flags", SysQueryGlobalInputState(&badState), NTLSTATUS_INVALID_PARAMETER);
|
||||
|
||||
status = SysQueryGlobalInputState(&state);
|
||||
if (status != NTLSTATUS_SUCCESS)
|
||||
fail_status("query global input", status);
|
||||
if (state.Size != sizeof(state))
|
||||
fail_status("query global input size", state.Size);
|
||||
if (state.Flags != SYS_GLOBAL_INPUT_STATE_FLAG_NONE)
|
||||
fail_status("query global input flags", state.Flags);
|
||||
|
||||
status = SysPeekInputEvent(&req);
|
||||
if (status != NTLSTATUS_SUCCESS && status != NTLSTATUS_WOULD_BLOCK)
|
||||
fail_status("peek input immediate", status);
|
||||
|
||||
uint32_t waitStatus = SysWaitSingle(inputQueue, SYS_WAIT_FLAG_NONE, 0);
|
||||
if (status == NTLSTATUS_SUCCESS) {
|
||||
if (waitStatus != NTLSTATUS_SUCCESS)
|
||||
fail_status("wait input after readable peek", waitStatus);
|
||||
} else if (waitStatus != NTLSTATUS_TIMEOUT) {
|
||||
fail_status("wait empty input immediate", waitStatus);
|
||||
}
|
||||
|
||||
req.TimeoutMilliseconds = 1;
|
||||
status = SysReadInputEvent(&req);
|
||||
if (status != NTLSTATUS_SUCCESS && status != NTLSTATUS_TIMEOUT)
|
||||
fail_status("read input finite timeout", status);
|
||||
|
||||
SysCloseHandle(inputQueue);
|
||||
|
||||
print("input_model_smoke: PASS\n");
|
||||
exit_now(0);
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user