replace the VHD/diskpart disk image pipeline with a directory-based vvfat root, we'll see when it breaks, fix /O2, add an all_tests, generalize the fat32 driver into a fat 16+32 driver, change policy on volume drivers, collapse KCPU's fields into a single atomic KE_CPU_STATE state machine, move scheduler ticking to per-CPU LAPIC timers, gate verbose SMP topology logging behind selftest diagnostics and add SMP pool-checkpoint validation around AP admission, add checked intrusive list helpers behind a new KE_DEBUG_LIST_CHECKS flag, add ObInitializeObjectHeader/ObTryReferenceObject, add waitable display clock objects and a SYS_OPEN_DISPLAY_CLOCK syscall for vsync-style waits, refactor kernel input into a per-queue KE_INPUT_CONTEXT with its own key/mouse ring buffers and DPC-driven key repeat, add KeInputQueuePeekEvent/ReadEvent/WaitKey and a SYS_QUERY_GLOBAL_INPUT_STATE syscall, split the kernel pool allocator out of mm_virt, new video files!
This commit is contained in:
1 parent
485a6bbfe7
commit
8b254f84f4
74 files changed
+4488
-2503
No files matched your search
@@ -1,14 +1,13 @@
|
||||
// Native file metadata smoke test.
|
||||
// Verifies path stat, handle stat, directory metadata, missing paths, and invalid handles.
|
||||
// Verifies path stat, handle stat, directory metadata, missing paths, and invalid handles without mutating the filesystem.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
#define TEST_FILE_SIZE 1537u
|
||||
|
||||
static uint8_t gPattern[TEST_FILE_SIZE];
|
||||
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) {
|
||||
@@ -58,84 +57,77 @@ static void fail_status(const char* what, uint32_t status) {
|
||||
exit_now(1);
|
||||
}
|
||||
|
||||
// Removes a file path if it already exists.
|
||||
static void delete_file_path(const char* path) {
|
||||
SYS_PATH_REQUEST req = { SysSvFromCstr(path) };
|
||||
(void)SysDeleteFile(&req);
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Removes a directory path if it already exists.
|
||||
static void remove_dir_path(const char* path) {
|
||||
SYS_PATH_REQUEST req = { SysSvFromCstr(path) };
|
||||
(void)SysRemoveDir(&req);
|
||||
}
|
||||
|
||||
// Opens a new temporary file on the first writable path that works.
|
||||
static uint32_t create_temp_file(uint32_t* fileOut, const char** pathOut) {
|
||||
static const char* paths[] = {
|
||||
"file_stat_smoke.tmp",
|
||||
"/file_stat_smoke.tmp",
|
||||
"1:/file_stat_smoke.tmp",
|
||||
"0:/file_stat_smoke.tmp",
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i) {
|
||||
uint32_t h = 0;
|
||||
delete_file_path(paths[i]);
|
||||
SYS_OPEN_FILE_REQUEST req = SysMakeOpenFileRequest(SysSvFromCstr(paths[i]),
|
||||
SYS_FILE_ACCESS_READ | SYS_FILE_ACCESS_WRITE | SYS_FILE_ACCESS_QUERY,
|
||||
SYS_FILE_CREATE_NEW,
|
||||
SYS_FILE_FLAG_NONE,
|
||||
&h);
|
||||
uint32_t s = SysOpenFile(&req);
|
||||
if (s == NTLSTATUS_SUCCESS) {
|
||||
*fileOut = h;
|
||||
*pathOut = paths[i];
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
return NTLSTATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
// Creates a temporary directory on the first writable path that works.
|
||||
static uint32_t create_temp_dir(const char** pathOut) {
|
||||
static const char* paths[] = {
|
||||
"file_stat_smoke.dir",
|
||||
"/file_stat_smoke.dir",
|
||||
"1:/file_stat_smoke.dir",
|
||||
"0:/file_stat_smoke.dir",
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i) {
|
||||
remove_dir_path(paths[i]);
|
||||
SYS_PATH_REQUEST req = { SysSvFromCstr(paths[i]) };
|
||||
uint32_t s = SysCreateDir(&req);
|
||||
if (s == NTLSTATUS_SUCCESS) {
|
||||
*pathOut = paths[i];
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
if (slash == (size_t)-1) {
|
||||
if (outSize < 2) fail("parent directory buffer too small");
|
||||
out[0] = '.';
|
||||
out[1] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
return NTLSTATUS_NOT_FOUND;
|
||||
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';
|
||||
}
|
||||
|
||||
// Fills the write pattern used by the test file.
|
||||
static void fill_pattern(void) {
|
||||
for (size_t i = 0; i < sizeof(gPattern); ++i)
|
||||
gPattern[i] = (uint8_t)(0x31u + (uint8_t)(i * 17u + (i >> 3)));
|
||||
}
|
||||
// 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);
|
||||
|
||||
// Writes the test file contents and flushes them to the filesystem.
|
||||
static void write_test_file(uint32_t file) {
|
||||
size_t done = 0;
|
||||
SYS_FILE_IO_REQUEST writeReq = SysMakeFileIoRequest(file, gPattern, sizeof(gPattern), &done);
|
||||
uint32_t s = SysWriteFile(&writeReq);
|
||||
if (s != NTLSTATUS_SUCCESS) fail_status("write test file", s);
|
||||
if (done != sizeof(gPattern)) fail("short write");
|
||||
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;
|
||||
|
||||
s = SysFlushFile(file);
|
||||
if (s != NTLSTATUS_SUCCESS) fail_status("flush test file", 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.
|
||||
@@ -171,13 +163,13 @@ static void check_directory_stat(const SYS_FILE_STAT* stat) {
|
||||
if (stat->LinkCount == 0) fail("directory has zero links");
|
||||
}
|
||||
|
||||
// Exercises handle and path stat for one regular file.
|
||||
static void test_file_stat(uint32_t file, const char* path) {
|
||||
// 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, sizeof(gPattern), "handle stat");
|
||||
check_regular_stat(&byHandle, expectedSize, "handle stat");
|
||||
|
||||
uint64_t size = 0;
|
||||
s = SysGetFileSize(file, &size);
|
||||
@@ -186,10 +178,10 @@ static void test_file_stat(uint32_t file, const char* path) {
|
||||
|
||||
SYS_FILE_STAT byPath;
|
||||
memset(&byPath, 0x5A, sizeof(byPath));
|
||||
SYS_STAT_FILE_REQUEST statReq = { SysSvFromCstr(path), &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, sizeof(gPattern), "path stat");
|
||||
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");
|
||||
@@ -197,11 +189,11 @@ static void test_file_stat(uint32_t file, const char* path) {
|
||||
fail("handle and path file ids differ");
|
||||
}
|
||||
|
||||
// Exercises path stat for one directory.
|
||||
static void test_directory_stat(const char* path) {
|
||||
// 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(path), &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);
|
||||
@@ -226,30 +218,15 @@ static void test_failure_paths(void) {
|
||||
int main(void) {
|
||||
print("file_stat_smoke: start\n");
|
||||
|
||||
fill_pattern();
|
||||
|
||||
uint32_t file = 0;
|
||||
const char* filePath = 0;
|
||||
uint32_t s = create_temp_file(&file, &filePath);
|
||||
if (s != NTLSTATUS_SUCCESS) fail_status("create temp file", s);
|
||||
uint64_t size = 0;
|
||||
uint32_t s = open_self_image(&file, &size);
|
||||
if (s != NTLSTATUS_SUCCESS) fail_status("open self image", s);
|
||||
|
||||
write_test_file(file);
|
||||
test_file_stat(file, filePath);
|
||||
test_file_stat(file, size);
|
||||
SysCloseHandle(file);
|
||||
delete_file_path(filePath);
|
||||
|
||||
const char* dirPath = 0;
|
||||
s = create_temp_dir(&dirPath);
|
||||
if (s != NTLSTATUS_SUCCESS) fail_status("create temp dir", s);
|
||||
test_directory_stat(dirPath);
|
||||
remove_dir_path(dirPath);
|
||||
|
||||
SYS_PATH_REQUEST dirReq = { SysSvFromCstr(dirPath) };
|
||||
s = SysCreateDir(&dirReq);
|
||||
if (s != NTLSTATUS_SUCCESS) fail_status("recreate temp dir", s);
|
||||
test_directory_stat(dirPath);
|
||||
remove_dir_path(dirPath);
|
||||
|
||||
test_directory_stat();
|
||||
test_failure_paths();
|
||||
|
||||
print("file_stat_smoke: PASS\n");
|
||||
|
||||
Reference in new issue
Block a user