clean up and standardize types across the codebase, unify atomic operations, improve UTF-8 handling throughout the system, remove obsolete input and named queue interfaces, redesign process preparation and creation, tighten IPC and service boundaries, improve error handling and reliability, minor documentation cleanup, fix doom surfaces, fix panic in ini parsing.
This commit is contained in:
1 parent
899225f551
commit
c0ad63c27f
226 files changed
+6562
-4147
No files matched your search
@@ -1,197 +0,0 @@
|
||||
// Native named queue lifetime smoke test.
|
||||
// Verifies explicit name withdrawal and automatic withdrawal on owner handle close.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
#define TEST_MESSAGE_TYPE 0x71756575u
|
||||
#define TEST_MESSAGE_VALUE 0x123456789abcdef0ull
|
||||
|
||||
typedef struct TEST_QUEUE_MESSAGE {
|
||||
uint32_t Type;
|
||||
uint32_t Flags;
|
||||
uint64_t Param[6];
|
||||
} TEST_QUEUE_MESSAGE;
|
||||
|
||||
typedef char TEST_QUEUE_MESSAGE_SIZE_CHECK[
|
||||
(sizeof(TEST_QUEUE_MESSAGE) == SYS_QUEUE_MESSAGE_SIZE) ? 1 : -1
|
||||
];
|
||||
|
||||
// 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 plain message.
|
||||
static void fail(const char* msg) {
|
||||
print("named_queue_lifetime_smoke: ");
|
||||
print(msg);
|
||||
print("\n");
|
||||
exit_now(1);
|
||||
}
|
||||
|
||||
// Fails the test with one status value.
|
||||
static void fail_status(const char* what, uint32_t status) {
|
||||
print("named_queue_lifetime_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("named_queue_lifetime_smoke: ");
|
||||
print(what);
|
||||
print(" got=");
|
||||
print_u64(got);
|
||||
print(" expected=");
|
||||
print_u64(expected);
|
||||
print("\n");
|
||||
exit_now(1);
|
||||
}
|
||||
|
||||
// Publishes one queue under a short test name.
|
||||
static uint32_t publish_queue(const char* name, uint32_t queue) {
|
||||
SYS_PUBLISH_QUEUE_REQUEST req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.Size = sizeof(req);
|
||||
req.Name = SysSvFromCstr(name);
|
||||
req.QueueHandle = queue;
|
||||
return SysPublishQueue(&req);
|
||||
}
|
||||
|
||||
// Withdraws one named queue publication.
|
||||
static uint32_t unpublish_queue(const char* name) {
|
||||
SYS_UNPUBLISH_QUEUE_REQUEST req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.Size = sizeof(req);
|
||||
req.Name = SysSvFromCstr(name);
|
||||
return SysUnpublishQueue(&req);
|
||||
}
|
||||
|
||||
// Opens one named queue publication.
|
||||
static uint32_t open_named_queue(const char* name, uint32_t* out) {
|
||||
SYS_OPEN_NAMED_QUEUE_REQUEST req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.Size = sizeof(req);
|
||||
req.Name = SysSvFromCstr(name);
|
||||
req.HandleOut = out;
|
||||
return SysOpenNamedQueue(&req);
|
||||
}
|
||||
|
||||
// Sends one fixed-size queue message.
|
||||
static uint32_t send_message(uint32_t queue, const TEST_QUEUE_MESSAGE* message) {
|
||||
SYS_QUEUE_SEND_REQUEST req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.Size = sizeof(req);
|
||||
req.QueueHandle = queue;
|
||||
req.Flags = SYS_QUEUE_FLAG_NONE;
|
||||
req.TimeoutMilliseconds = 0;
|
||||
req.Message = message;
|
||||
return SysSendQueue(&req);
|
||||
}
|
||||
|
||||
// Receives one fixed-size queue message.
|
||||
static uint32_t recv_message(uint32_t queue, TEST_QUEUE_MESSAGE* message) {
|
||||
SYS_QUEUE_RECV_REQUEST req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.Size = sizeof(req);
|
||||
req.QueueHandle = queue;
|
||||
req.Flags = SYS_QUEUE_FLAG_NONE;
|
||||
req.TimeoutMilliseconds = 0;
|
||||
req.MessageOut = message;
|
||||
return SysRecvQueue(&req);
|
||||
}
|
||||
|
||||
// Verifies explicit unpublish removes only the name, not existing handles.
|
||||
static void check_explicit_unpublish(void) {
|
||||
uint32_t queue = 0;
|
||||
uint32_t opened = 0;
|
||||
uint32_t status = SysCreateQueue(&queue);
|
||||
if (status != NTLSTATUS_SUCCESS) fail_status("create queue", status);
|
||||
|
||||
status = publish_queue("ntl.queue.explicit", queue);
|
||||
if (status != NTLSTATUS_SUCCESS) fail_status("publish queue", status);
|
||||
|
||||
status = open_named_queue("ntl.queue.explicit", &opened);
|
||||
if (status != NTLSTATUS_SUCCESS) fail_status("open published queue", status);
|
||||
if (!opened) fail("opened handle is zero");
|
||||
|
||||
status = unpublish_queue("ntl.queue.explicit");
|
||||
if (status != NTLSTATUS_SUCCESS) fail_status("unpublish queue", status);
|
||||
|
||||
uint32_t missing = 0;
|
||||
status = open_named_queue("ntl.queue.explicit", &missing);
|
||||
expect_status("open withdrawn name", status, NTLSTATUS_NOT_FOUND);
|
||||
|
||||
TEST_QUEUE_MESSAGE out;
|
||||
TEST_QUEUE_MESSAGE in;
|
||||
memset(&out, 0, sizeof(out));
|
||||
memset(&in, 0, sizeof(in));
|
||||
out.Type = TEST_MESSAGE_TYPE;
|
||||
out.Param[0] = TEST_MESSAGE_VALUE;
|
||||
status = send_message(queue, &out);
|
||||
if (status != NTLSTATUS_SUCCESS) fail_status("send after unpublish", status);
|
||||
status = recv_message(opened, &in);
|
||||
if (status != NTLSTATUS_SUCCESS) fail_status("recv after unpublish", status);
|
||||
if (in.Type != TEST_MESSAGE_TYPE || in.Param[0] != TEST_MESSAGE_VALUE)
|
||||
fail("message mismatch after unpublish");
|
||||
|
||||
SysCloseHandle(opened);
|
||||
SysCloseHandle(queue);
|
||||
}
|
||||
|
||||
// Verifies closing the publishing handle withdraws its names.
|
||||
static void check_close_withdraws_name(void) {
|
||||
uint32_t queue = 0;
|
||||
uint32_t status = SysCreateQueue(&queue);
|
||||
if (status != NTLSTATUS_SUCCESS) fail_status("create close queue", status);
|
||||
|
||||
status = publish_queue("ntl.queue.close", queue);
|
||||
if (status != NTLSTATUS_SUCCESS) fail_status("publish close queue", status);
|
||||
|
||||
SysCloseHandle(queue);
|
||||
|
||||
uint32_t opened = 0;
|
||||
status = open_named_queue("ntl.queue.close", &opened);
|
||||
expect_status("open close-withdrawn name", status, NTLSTATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Runs the named queue lifetime smoke test.
|
||||
int main(void) {
|
||||
print("named_queue_lifetime_smoke: start\n");
|
||||
check_explicit_unpublish();
|
||||
check_close_withdraws_name();
|
||||
print("named_queue_lifetime_smoke: PASS\n");
|
||||
exit_now(0);
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user