Files
nt-lite/code/user/tests/cwd_peb_smoke/cwd_peb_smoke.c
T

109 lines
3.1 KiB
C

// Current-directory PEB cache smoke test.
// Verifies that SysSetCwd updates the user-visible PEB cache without a getter syscall.
#include <stddef.h>
#include <stdint.h>
#include <string.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 = { 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 = { SysSvFromParts(&c, 1) };
SysWriteConsole(&req);
}
}
// Terminates the current test process.
static void exit_now(int code) {
for (;;) SysExitProcess(code);
}
// Fails the test with one status value.
static void fail_status(const char* what, uint32_t status) {
print("cwd_peb_smoke: ");
print(what);
print(" status=");
print_u64(status);
print("\n");
exit_now(1);
}
// Fails the test with a simple message.
static void fail(const char* what) {
print("cwd_peb_smoke: ");
print(what);
print("\n");
exit_now(1);
}
// Sets the current directory to one native path.
static void set_cwd_or_fail(const char* path, const char* what) {
SYS_PATH_REQUEST req = { SysSvFromCstr(path) };
uint32_t status = SysSetCwd(&req);
if (status != NTLSTATUS_SUCCESS) fail_status(what, status);
}
// Verifies the current-directory PEB view against one native path.
static void expect_cwd(const char* expected) {
SYS_STRING_VIEW cwd = SysGetCurrentDirectoryView();
size_t expectedLen = strlen(expected);
if (cwd.Length != expectedLen) fail("cwd length mismatch");
if (cwd.Length && !cwd.Data) fail("cwd data missing");
if (cwd.Length && memcmp(cwd.Data, expected, cwd.Length) != 0) fail("cwd value mismatch");
}
// Program entry point.
int main(void) {
static const char rootPath[] = "0:/";
static const char tempDir[] = "0:/cwd_peb_smoke_dir";
print("cwd_peb_smoke: start\n");
SYS_PEB* peb = SysGetPeb();
if (!peb) fail("peb missing");
if (peb->Magic != SYS_PEB_MAGIC) fail("peb magic mismatch");
if (peb->Version != SYS_ENV_VERSION) fail("peb version mismatch");
set_cwd_or_fail(rootPath, "set root cwd");
expect_cwd(rootPath);
SYS_PATH_REQUEST dirReq = { SysSvFromCstr(tempDir) };
uint32_t status = SysRemoveDir(&dirReq);
if (status != NTLSTATUS_SUCCESS && status != NTLSTATUS_NOT_FOUND)
fail_status("remove stale temp dir", status);
status = SysCreateDir(&dirReq);
if (status != NTLSTATUS_SUCCESS) fail_status("create temp dir", status);
set_cwd_or_fail(tempDir, "set temp cwd");
expect_cwd(tempDir);
set_cwd_or_fail(rootPath, "restore root cwd");
expect_cwd(rootPath);
status = SysRemoveDir(&dirReq);
if (status != NTLSTATUS_SUCCESS) fail_status("remove temp dir", status);
print("cwd_peb_smoke: PASS\n");
exit_now(0);
return 0;
}