// Console-service smoke test. Verifies RSSRV publication, query, write, and cursor operations. #include #include #include #include #include static void exit_test(int code) { for (;;) SysExitProcess(code); } static void print(const char* text) { SYS_WRITE_CONSOLE_REQUEST request = { sizeof(request), SysSvFromCstr(text) }; (void)SysWriteConsole(&request); } static void print_status(KSTATUS status) { static const char digits[] = "0123456789ABCDEF"; char buffer[11] = "0x00000000"; for (uint32_t i = 0; i < 8u; ++i) buffer[2u + i] = digits[(status >> ((7u - i) * 4u)) & 0xFu]; print(buffer); } // Reports one failed console-service operation with its native status. static void fail_status(const char* operation, KSTATUS status, int code) { print("console_service_smoke: "); print(operation); print(" failed status="); print_status(status); print("\n"); exit_test(code); } // Reports one failed console-service invariant. static void fail(const char* message, int code) { print("console_service_smoke: "); print(message); print("\n"); exit_test(code); } // Runs the console-service smoke contract. int main(void) { SYS_HANDLE resources = SYS_HANDLE_INVALID; KSTATUS status = NtlResourceConnect(&resources); if (!KSUCCESS(status)) fail_status("connect resource service", status, 1); uint32_t kind = NTL_RESOURCE_KIND_INVALID; status = NtlResourceQuery(resources, SYS_SV_LITERAL("/Sessions/0"), &kind); if (!KSUCCESS(status)) fail_status("query /Sessions/0", status, 2); if (kind != NTL_RESOURCE_KIND_NAMESPACE_DIRECTORY) fail("/Sessions/0 has wrong resource kind", 2); // DWM is noncritical, so the console contract must not depend on the desktop endpoint being published. status = NtlResourceQuery(resources, SYS_SV_LITERAL("/Sessions/0/Console"), &kind); if (!KSUCCESS(status)) fail_status("query /Sessions/0/Console", status, 3); if (kind != NTL_RESOURCE_KIND_CAPABILITY) fail("/Sessions/0/Console has wrong resource kind", 3); status = NtlResourceQuery(resources, SYS_SV_LITERAL("/Console"), &kind); if (!KSUCCESS(status)) fail_status("query /Console", status, 4); if (kind != NTL_RESOURCE_KIND_SYMBOLIC_LINK) fail("/Console has wrong resource kind", 4); SYS_HANDLE alias = SYS_HANDLE_INVALID; status = NtlResourceLookup(resources, SYS_SV_LITERAL("/Console"), SYS_RIGHT_QUERY | SYS_PORT_RIGHT_CONNECT, &alias); if (!KSUCCESS(status)) fail_status("lookup /Console", status, 5); if (alias == SYS_HANDLE_INVALID) fail("lookup /Console returned invalid handle", 5); (void)SysCloseHandle(alias); (void)NtlResourceClose(resources); SYS_HANDLE session = SYS_HANDLE_INVALID; status = NtlConsoleConnect(&session); if (!KSUCCESS(status)) fail_status("connect console", status, 6); NTL_CONSOLE_INFO before; memset(&before, 0, sizeof(before)); status = NtlConsoleQueryInfo(session, &before); if (!KSUCCESS(status)) fail_status("query console info", status, 7); if (before.Size != sizeof(before) || before.Flags != NTL_CONSOLE_FLAG_NONE || before.Columns == 0 || before.Rows == 0 || before.PixelWidth == 0 || before.PixelHeight == 0) fail("initial console info is invalid", 7); static const char message[] = "[console_service_smoke] PASS\n"; size_t written = 0; status = NtlConsoleWrite(session, message, sizeof(message) - 1u, &written); if (!KSUCCESS(status)) fail_status("write console", status, 8); if (written != sizeof(message) - 1u) fail("console write returned short byte count", 8); NTL_CONSOLE_INFO after; memset(&after, 0, sizeof(after)); status = NtlConsoleQueryInfo(session, &after); if (!KSUCCESS(status)) fail_status("query console info after write", status, 9); if (after.Generation <= before.Generation) fail("console generation did not advance", 9); status = NtlConsoleSetCursor(session, (int)after.CursorX, (int)after.CursorY); if (!KSUCCESS(status)) fail_status("set console cursor", status, 10); (void)NtlConsoleClose(session); exit_test(0); return 0; }