// Native file metadata smoke test. // Verifies path stat, handle stat, directory metadata, missing paths, and invalid handles without mutating the filesystem. #include #include #include #include static char gSelfPath[SYS_PATH_MAX]; static char gSelfDir[SYS_PATH_MAX]; // 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) { while (true) SysExitProcess(code); } // Fails the test with one plain message. static void fail(const char* msg) { print("file_stat_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("file_stat_smoke: "); print(what); print(" failed status="); print_u64(status); print("\n"); exit_now(1); } // Copies one string view into a fixed NUL-terminated buffer. static int copy_view(char* out, size_t outSize, SYS_STRING_VIEW view) { if (!out || outSize == 0 || !view.Data || view.Length + 1 > outSize) return 0; memcpy(out, view.Data, view.Length); out[view.Length] = '\0'; return 1; } // Builds the containing directory path for one process image path. static void build_parent_dir(char* out, size_t outSize, const char* path) { size_t len = strlen(path); size_t slash = (size_t)-1; for (size_t i = 0; i < len; ++i) { if (path[i] == '/' || path[i] == '\\') slash = i; } if (slash == (size_t)-1) { if (outSize < 2) fail("parent directory buffer too small"); out[0] = '.'; out[1] = '\0'; return; } if (slash == 0) { if (outSize < 2) fail("parent directory buffer too small"); out[0] = path[0]; out[1] = '\0'; return; } if (slash + 1 >= outSize) fail("parent directory path too long"); memcpy(out, path, slash); out[slash] = '\0'; } // Opens this process image for read/query metadata checks. static uint32_t open_self_image(uint32_t* fileOut, uint64_t* sizeOut) { SYS_PEB* peb = SysGetPeb(); if (!peb || peb->Magic != SYS_PEB_MAGIC || peb->Version != SYS_ENV_VERSION) return NTLSTATUS_INVALID_PARAMETER; if (!copy_view(gSelfPath, sizeof(gSelfPath), peb->ImagePath)) return NTLSTATUS_INVALID_PARAMETER; build_parent_dir(gSelfDir, sizeof(gSelfDir), gSelfPath); uint32_t h = 0; SYS_OPEN_FILE_REQUEST req = SysMakeOpenFileRequest(SysSvFromCstr(gSelfPath), SYS_FILE_ACCESS_READ | SYS_FILE_ACCESS_QUERY, SYS_FILE_OPEN_EXISTING, SYS_FILE_FLAG_NONE, &h); uint32_t s = SysOpenFile(&req); if (s != NTLSTATUS_SUCCESS) return s; uint64_t size = 0; s = SysGetFileSize(h, &size); if (s != NTLSTATUS_SUCCESS) { SysCloseHandle(h); return s; } if (size == 0) { SysCloseHandle(h); return NTLSTATUS_NOT_FOUND; } *fileOut = h; *sizeOut = size; return NTLSTATUS_SUCCESS; } // Checks one regular-file metadata result. static void check_regular_stat(const SYS_FILE_STAT* stat, uint64_t expectedSize, const char* what) { if (stat->Size != sizeof(*stat)) fail("stat abi size mismatch"); if (stat->Type != SYS_FILE_TYPE_REGULAR) { print("file_stat_smoke: "); print(what); print(" type="); print_u64(stat->Type); print("\n"); exit_now(1); } if ((stat->Attributes & SYS_FILE_ATTR_DIRECTORY) != 0) fail("regular file has directory attribute"); if (stat->LinkCount == 0) fail("regular file has zero links"); if (stat->FileSize != expectedSize) { print("file_stat_smoke: "); print(what); print(" size="); print_u64(stat->FileSize); print(" expected="); print_u64(expectedSize); print("\n"); exit_now(1); } } // Checks one directory metadata result. static void check_directory_stat(const SYS_FILE_STAT* stat) { if (stat->Size != sizeof(*stat)) fail("directory stat abi size mismatch"); if (stat->Type != SYS_FILE_TYPE_DIRECTORY) fail("directory stat type mismatch"); if ((stat->Attributes & SYS_FILE_ATTR_DIRECTORY) == 0) fail("directory attribute missing"); if (stat->LinkCount == 0) fail("directory has zero links"); } // Exercises handle and path stat for this process image. static void test_file_stat(uint32_t file, uint64_t expectedSize) { SYS_FILE_STAT byHandle; memset(&byHandle, 0xA5, sizeof(byHandle)); uint32_t s = SysGetFileStat(file, &byHandle); if (s != NTLSTATUS_SUCCESS) fail_status("get file stat", s); check_regular_stat(&byHandle, expectedSize, "handle stat"); uint64_t size = 0; s = SysGetFileSize(file, &size); if (s != NTLSTATUS_SUCCESS) fail_status("get file size", s); if (size != byHandle.FileSize) fail("file size and file stat disagree"); SYS_FILE_STAT byPath; memset(&byPath, 0x5A, sizeof(byPath)); SYS_STAT_FILE_REQUEST statReq = { SysSvFromCstr(gSelfPath), &byPath }; s = SysStatFile(&statReq); if (s != NTLSTATUS_SUCCESS) fail_status("path stat", s); check_regular_stat(&byPath, expectedSize, "path stat"); if (byHandle.VolumeId != 0 && byPath.VolumeId != 0 && byHandle.VolumeId != byPath.VolumeId) fail("handle and path volume ids differ"); if (byHandle.FileId != 0 && byPath.FileId != 0 && byHandle.FileId != byPath.FileId) fail("handle and path file ids differ"); } // Exercises path stat for the executable's containing directory. static void test_directory_stat(void) { SYS_FILE_STAT stat; memset(&stat, 0xCC, sizeof(stat)); SYS_STAT_FILE_REQUEST statReq = { SysSvFromCstr(gSelfDir), &stat }; uint32_t s = SysStatFile(&statReq); if (s != NTLSTATUS_SUCCESS) fail_status("directory stat", s); check_directory_stat(&stat); } // Checks failure status paths that stat callers depend on. static void test_failure_paths(void) { SYS_FILE_STAT stat; SYS_STAT_FILE_REQUEST missingReq = { SysSvFromCstr("file_stat_smoke_missing.nope"), &stat }; uint32_t s = SysStatFile(&missingReq); if (s != NTLSTATUS_NOT_FOUND) fail_status("missing path status", s); s = SysGetFileStat(0xFFFFFFFFu, &stat); if (s != NTLSTATUS_INVALID_HANDLE) fail_status("invalid handle status", s); SYS_STAT_FILE_REQUEST badReq = { SysSvFromCstr("file_stat_smoke_missing.nope"), 0 }; s = SysStatFile(&badReq); if (s != NTLSTATUS_INVALID_PARAMETER) fail_status("null stat output status", s); } // Runs the native file metadata smoke test. int main(void) { print("file_stat_smoke: start\n"); uint32_t file = 0; uint64_t size = 0; uint32_t s = open_self_image(&file, &size); if (s != NTLSTATUS_SUCCESS) fail_status("open self image", s); test_file_stat(file, size); SysCloseHandle(file); test_directory_stat(); test_failure_paths(); print("file_stat_smoke: PASS\n"); exit_now(0); return 0; }