add ntfs.sys standalone driver target, change default usb vhd layout formatting to ntfs, implement Fat32CreateDir for directory creation support in the fat32 file system driver, add a dedicated HAL serial output endpoint for COM1 writes in hal_serial.c and subscribe serial to HAL text streams, introduce waitable kernel timers with KeTimerCreate, KeTimerSet, and KeTimerCancel alongside spinlock-protected global timer list initialization and scheduler tick tracking, implement SyscallWriteFileAsync system call for asynchronous non-blocking file writes, refactor NetSocketConnect and NetSocketSendTo to use generic SYS_SOCKET_ADDRESS_K structures instead of being hardcoded to IPv4, update gethostbyname and DNS name resolution to support IPv6 parsing via ResolveNameFamily, update tcpserve.exe with -4 and -6 command-line flags to accept and display IPv6 addresses, append size and version headers to all kernel telemetry and statistics structures including SYS_PMM_STATS, SYS_CPU_STATS, and SYS_SCHEDULER_STATS, update winmm timeGetTime to look up high-resolution hardware frequencies via SysGetTickFrequency, integrate 14 native smoke test applications.
This commit is contained in:
1 parent
2c4a68a75f
commit
ed3d065abd
156 files changed
+10509
-2643
No files matched your search
@@ -18,14 +18,22 @@ static void print(const char* s) { SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCs
|
||||
|
||||
// Opens file.
|
||||
static uint32_t open_file(const char* path, uint32_t* handleOut) {
|
||||
SYS_PATH_HANDLE_REQUEST req = { SysSvFromCstr(path), handleOut };
|
||||
SYS_OPEN_FILE_REQUEST req = SysMakeOpenFileRequest(SysSvFromCstr(path),
|
||||
SYS_FILE_ACCESS_READ | SYS_FILE_ACCESS_QUERY,
|
||||
SYS_FILE_OPEN_EXISTING,
|
||||
SYS_FILE_FLAG_NONE,
|
||||
handleOut);
|
||||
return SysOpenFile(&req);
|
||||
}
|
||||
|
||||
// Creates file.
|
||||
static uint32_t create_file(const char* path, uint32_t* handleOut) {
|
||||
SYS_PATH_HANDLE_REQUEST req = { SysSvFromCstr(path), handleOut };
|
||||
return SysCreateFile(&req);
|
||||
SYS_OPEN_FILE_REQUEST req = SysMakeOpenFileRequest(SysSvFromCstr(path),
|
||||
SYS_FILE_ACCESS_WRITE | SYS_FILE_ACCESS_QUERY,
|
||||
SYS_FILE_CREATE_ALWAYS,
|
||||
SYS_FILE_FLAG_NONE,
|
||||
handleOut);
|
||||
return SysOpenFile(&req);
|
||||
}
|
||||
|
||||
// Opens dir.
|
||||
@@ -513,7 +521,13 @@ static bool readLine(char* buf, int len) {
|
||||
|
||||
while (true) {
|
||||
INPUT_KEY_RECORD input;
|
||||
if (SysReadInputEvent(&input) != 0) { SysYield(); continue; }
|
||||
SYS_INPUT_EVENT_REQUEST inputReq;
|
||||
inputReq.Size = sizeof(inputReq);
|
||||
inputReq.QueueHandle = 0;
|
||||
inputReq.Flags = SYS_INPUT_EVENT_FLAG_NONE;
|
||||
inputReq.TimeoutMilliseconds = SYS_WAIT_TIMEOUT_INFINITE;
|
||||
inputReq.RecordOut = &input;
|
||||
if (SysReadInputEvent(&inputReq) != STATUS_SUCCESS) { SysYield(); continue; }
|
||||
|
||||
INPUT_KEY key = input.Key;
|
||||
if (key == INPUT_KEY_NONE) { SysYield(); continue; }
|
||||
@@ -609,7 +623,6 @@ static void printSizeKiB(uint64_t bytes) {
|
||||
print(" KiB");
|
||||
}
|
||||
|
||||
|
||||
// Prints pages Ki B.
|
||||
static void printPagesKiB(uint64_t pages) {
|
||||
printUInt64(pages * 4u);
|
||||
@@ -630,7 +643,8 @@ static void printCpuFlags(uint32_t flags) {
|
||||
static void cmd_stats(void) {
|
||||
SYS_SCHEDULER_STATS sched;
|
||||
SYS_PMM_STATS pmm;
|
||||
SYS_CPU_STATS cpu;
|
||||
SYS_CPU_STATS* cpu = 0;
|
||||
void* cpuBuffer = 0;
|
||||
SYS_PFN_STATS pfn;
|
||||
SYS_VAD_STATS vad;
|
||||
SYS_SWAP_STATS swap;
|
||||
@@ -657,11 +671,32 @@ static void cmd_stats(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
status = SysQueryKernelStats(SYS_KERNEL_STATS_CPU, &cpu, sizeof(cpu), NULL);
|
||||
size_t cpuSize = 0;
|
||||
status = SysQueryKernelStats(SYS_KERNEL_STATS_CPU, 0, 0, &cpuSize);
|
||||
if (status != 0 || cpuSize < sizeof(SYS_CPU_STATS)) {
|
||||
print("stats: cpu size query failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t cpuPages = (cpuSize + 4095u) / 4096u;
|
||||
if (cpuPages == 0) cpuPages = 1;
|
||||
status = SysAllocVm(0, cpuPages, SYS_VM_READWRITE, SYS_VM_FLAG_NONE, &cpuBuffer);
|
||||
if (status != 0 || !cpuBuffer) {
|
||||
print("stats: cpu buffer allocation failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cpu = (SYS_CPU_STATS*)cpuBuffer;
|
||||
status = SysQueryKernelStats(SYS_KERNEL_STATS_CPU, cpu, cpuPages * 4096u, NULL);
|
||||
if (status != 0) {
|
||||
print("stats: cpu query failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
SysFreeVm(cpuBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -670,6 +705,7 @@ static void cmd_stats(void) {
|
||||
print("stats: pfn query failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
SysFreeVm(cpuBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -678,6 +714,7 @@ static void cmd_stats(void) {
|
||||
print("stats: vad query failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
SysFreeVm(cpuBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -686,6 +723,7 @@ static void cmd_stats(void) {
|
||||
print("stats: swap query failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
SysFreeVm(cpuBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -694,6 +732,7 @@ static void cmd_stats(void) {
|
||||
print("stats: file cache query failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
SysFreeVm(cpuBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -702,6 +741,7 @@ static void cmd_stats(void) {
|
||||
print("stats: filesystem query failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
SysFreeVm(cpuBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -710,6 +750,7 @@ static void cmd_stats(void) {
|
||||
print("stats: disk query failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
SysFreeVm(cpuBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -718,6 +759,7 @@ static void cmd_stats(void) {
|
||||
print("stats: pte query failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
SysFreeVm(cpuBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -726,6 +768,7 @@ static void cmd_stats(void) {
|
||||
print("stats: surface query failed: ");
|
||||
printUInt(status);
|
||||
print("\n");
|
||||
SysFreeVm(cpuBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -743,11 +786,10 @@ static void cmd_stats(void) {
|
||||
print(" SMT primary pokes: "); printUInt64(sched.SmtPrimaryPokes); print("\n");
|
||||
|
||||
print("CPUs:\n");
|
||||
uint32_t n = cpu.CpuCount;
|
||||
if (n > SYS_KERNEL_STATS_MAX_CPUS)
|
||||
n = SYS_KERNEL_STATS_MAX_CPUS;
|
||||
const SYS_CPU_STAT* cpuRecords = SYS_CPU_STATS_CONST_RECORDS(cpu);
|
||||
uint32_t n = cpu->RecordCount;
|
||||
for (uint32_t i = 0; i < n; i++) {
|
||||
SYS_CPU_STAT* c = &cpu.Cpu[i];
|
||||
const SYS_CPU_STAT* c = &cpuRecords[i];
|
||||
print(" cpu"); printUInt(c->CpuIndex);
|
||||
print(" lapic="); printUInt(c->LapicId);
|
||||
print(" current=");
|
||||
@@ -929,14 +971,8 @@ static void cmd_stats(void) {
|
||||
print(" invalidation: count="); printUInt64(filesystem.PathCacheInvalidations);
|
||||
print(" generation="); printUInt64(filesystem.PathCacheGeneration); print("\n");
|
||||
print(" directory search: searches="); printUInt64(filesystem.DirectorySearches);
|
||||
print(" clusters="); printUInt64(filesystem.DirectoryClustersRead);
|
||||
print(" blocks="); printUInt64(filesystem.DirectoryBlocksRead);
|
||||
print(" entries="); printUInt64(filesystem.DirectoryEntriesScanned); print("\n");
|
||||
print(" FAT chain cache: lookups="); printUInt64(filesystem.FatChainCacheLookups);
|
||||
print(" hits="); printUInt64(filesystem.FatChainCacheHits);
|
||||
print(" misses="); printUInt64(filesystem.FatChainCacheMisses);
|
||||
print(" stores="); printUInt64(filesystem.FatChainCacheStores); print("\n");
|
||||
print(" FAT chain work: invalidations="); printUInt64(filesystem.FatChainCacheInvalidations);
|
||||
print(" fat-steps="); printUInt64(filesystem.FatChainWalkSteps); print("\n");
|
||||
print(" data read spans: runs="); printUInt64(filesystem.DataReadRuns);
|
||||
print(" sectors="); printUInt64(filesystem.DataReadSectors);
|
||||
print(" merges="); printUInt64(filesystem.DataReadRunMerges);
|
||||
@@ -988,18 +1024,18 @@ static void cmd_stats(void) {
|
||||
print(" query: total="); printUInt64(pte.QueryCalls);
|
||||
print(" failed="); printUInt64(pte.QueryFailures);
|
||||
print(" translate="); printUInt64(pte.TranslateCalls); print("\n");
|
||||
print(" generic: "); printUInt64(pte.QueryByPurpose[0]);
|
||||
print(" failed="); printUInt64(pte.QueryFailuresByPurpose[0]); print("\n");
|
||||
print(" user-probe: "); printUInt64(pte.QueryByPurpose[1]);
|
||||
print(" failed="); printUInt64(pte.QueryFailuresByPurpose[1]); print("\n");
|
||||
print(" heap: "); printUInt64(pte.QueryByPurpose[2]);
|
||||
print(" failed="); printUInt64(pte.QueryFailuresByPurpose[2]); print("\n");
|
||||
print(" vad: "); printUInt64(pte.QueryByPurpose[3]);
|
||||
print(" failed="); printUInt64(pte.QueryFailuresByPurpose[3]); print("\n");
|
||||
print(" debug: "); printUInt64(pte.QueryByPurpose[4]);
|
||||
print(" failed="); printUInt64(pte.QueryFailuresByPurpose[4]); print("\n");
|
||||
print(" self-test: "); printUInt64(pte.QueryByPurpose[5]);
|
||||
print(" failed="); printUInt64(pte.QueryFailuresByPurpose[5]); print("\n");
|
||||
print(" generic: "); printUInt64(pte.QueryByPurpose[SYS_PTE_QUERY_GENERIC]);
|
||||
print(" failed="); printUInt64(pte.QueryFailuresByPurpose[SYS_PTE_QUERY_GENERIC]); print("\n");
|
||||
print(" user-probe: "); printUInt64(pte.QueryByPurpose[SYS_PTE_QUERY_USER_PROBE]);
|
||||
print(" failed="); printUInt64(pte.QueryFailuresByPurpose[SYS_PTE_QUERY_USER_PROBE]); print("\n");
|
||||
print(" heap: "); printUInt64(pte.QueryByPurpose[SYS_PTE_QUERY_HEAP]);
|
||||
print(" failed="); printUInt64(pte.QueryFailuresByPurpose[SYS_PTE_QUERY_HEAP]); print("\n");
|
||||
print(" vad: "); printUInt64(pte.QueryByPurpose[SYS_PTE_QUERY_VAD]);
|
||||
print(" failed="); printUInt64(pte.QueryFailuresByPurpose[SYS_PTE_QUERY_VAD]); print("\n");
|
||||
print(" debug: "); printUInt64(pte.QueryByPurpose[SYS_PTE_QUERY_DEBUG]);
|
||||
print(" failed="); printUInt64(pte.QueryFailuresByPurpose[SYS_PTE_QUERY_DEBUG]); print("\n");
|
||||
print(" self-test: "); printUInt64(pte.QueryByPurpose[SYS_PTE_QUERY_SELF_TEST]);
|
||||
print(" failed="); printUInt64(pte.QueryFailuresByPurpose[SYS_PTE_QUERY_SELF_TEST]); print("\n");
|
||||
print(" tlb: local="); printUInt64(pte.LocalFlushes);
|
||||
print(" global="); printUInt64(pte.GlobalFlushes);
|
||||
print(" new-map-skip="); printUInt64(pte.NewMappingNoFlushes);
|
||||
@@ -1009,9 +1045,9 @@ static void cmd_stats(void) {
|
||||
print(" skipped="); printUInt64(pte.ShootdownSkippedNoTargets);
|
||||
print(" acks="); printUInt64(pte.ShootdownAcks);
|
||||
print(" timeouts="); printUInt64(pte.ShootdownTimeouts); print("\n");
|
||||
SysFreeVm(cpuBuffer);
|
||||
}
|
||||
|
||||
|
||||
// Implements the cmd time operation.
|
||||
static void cmd_time(void) {
|
||||
SYS_SYSTEM_TIME t;
|
||||
@@ -1197,16 +1233,17 @@ static void cmd_ps(void) {
|
||||
printUInt((uint32_t)count);
|
||||
print("):\n");
|
||||
print(" PID State Thr Hnd Mod UserKiB ImageKiB Flags Name\n");
|
||||
print(" Flags: S=system I=idle *=current T=terminating X=exited.\n");
|
||||
print(" Flags: S=system I=idle P=protected *=current T=terminating X=exited.\n");
|
||||
|
||||
size_t displayCount = count < MAX_PROCS ? count : MAX_PROCS;
|
||||
for (size_t i = 0; i < displayCount; i++) {
|
||||
SYS_PROCESS_INFO* p = &procs[i];
|
||||
char flags[6];
|
||||
char flags[7];
|
||||
size_t flagLen = 0;
|
||||
|
||||
if (p->Flags & SYS_PROCESS_FLAG_SYSTEM) flags[flagLen++] = 'S';
|
||||
if (p->Flags & SYS_PROCESS_FLAG_IDLE) flags[flagLen++] = 'I';
|
||||
if (p->Flags & SYS_PROCESS_FLAG_TERMINATION_PROTECTED) flags[flagLen++] = 'P';
|
||||
if (p->Flags & SYS_PROCESS_FLAG_CURRENT) flags[flagLen++] = '*';
|
||||
if (p->Flags & SYS_PROCESS_FLAG_TERMINATING) flags[flagLen++] = 'T';
|
||||
if (p->Flags & SYS_PROCESS_FLAG_EXITED) flags[flagLen++] = 'X';
|
||||
@@ -1310,9 +1347,20 @@ static void cmd_threads(const char* args) {
|
||||
|
||||
static void cmd_kill(const char* args) {
|
||||
uint32_t pid = 0;
|
||||
if (!parseUInt(args, &pid) || pid == 0) { print("kill: usage: kill <pid>\n"); return; }
|
||||
uint32_t status = SysKillProcess(pid, (int)STATUS_PROCESS_KILLED);
|
||||
if (status != 0) {
|
||||
if (!parseUInt(args, &pid)) { print("kill: usage: kill <pid>\n"); return; }
|
||||
|
||||
uint32_t hProc = 0;
|
||||
uint32_t status = SysOpenProcess(pid, &hProc);
|
||||
if (status == 0) {
|
||||
status = SysKillProcess(hProc, (int32_t)STATUS_PROCESS_KILLED);
|
||||
SysCloseHandle(hProc);
|
||||
}
|
||||
|
||||
if (status == STATUS_ACCESS_DENIED) {
|
||||
print("kill: process ");
|
||||
printUInt(pid);
|
||||
print(" is termination-protected.\n");
|
||||
} else if (status != 0) {
|
||||
print("shell: failed to kill process ");
|
||||
printUInt(pid);
|
||||
print(", error code: ");
|
||||
@@ -1347,8 +1395,11 @@ static void cmd_dir(const char* path) {
|
||||
uint32_t hDir;
|
||||
const char* target = (path && *path != '\0') ? path : ".";
|
||||
|
||||
if (open_dir(target, &hDir) != 0) {
|
||||
print("dir: failed to open directory\n");
|
||||
uint32_t st = open_dir(target, &hDir);
|
||||
if (st != 0) {
|
||||
print("dir: failed to open directory, status=0x");
|
||||
printHex32(st);
|
||||
print("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1384,7 +1435,6 @@ static void cmd_type(const char* filename) {
|
||||
SysCloseHandle(hFile); print("\n");
|
||||
}
|
||||
|
||||
|
||||
// Implements the extract Program Path operation.
|
||||
static bool extractProgramPath(const char* cmdline, char* out, size_t outSize) {
|
||||
if (!cmdline || !out || outSize == 0) return false;
|
||||
@@ -1410,15 +1460,21 @@ static bool extractProgramPath(const char* cmdline, char* out, size_t outSize) {
|
||||
static bool shellConsumeQueuedCtrlC(void) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
INPUT_KEY_RECORD input;
|
||||
if (SysPeekInputEvent(&input) != 0) return false;
|
||||
SYS_INPUT_EVENT_REQUEST inputReq;
|
||||
inputReq.Size = sizeof(inputReq);
|
||||
inputReq.QueueHandle = 0;
|
||||
inputReq.Flags = SYS_INPUT_EVENT_FLAG_NONE;
|
||||
inputReq.TimeoutMilliseconds = 0;
|
||||
inputReq.RecordOut = &input;
|
||||
if (SysPeekInputEvent(&inputReq) != STATUS_SUCCESS) return false;
|
||||
|
||||
if ((input.Modifiers & INPUT_MOD_CTRL) && input.Key == INPUT_KEY_C) {
|
||||
(void)SysReadInputEvent(&input);
|
||||
(void)SysReadInputEvent(&inputReq);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (input.Key == INPUT_KEY_LEFT_CTRL || input.Key == INPUT_KEY_RIGHT_CTRL) {
|
||||
(void)SysReadInputEvent(&input);
|
||||
(void)SysReadInputEvent(&inputReq);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1428,10 +1484,14 @@ static bool shellConsumeQueuedCtrlC(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns whether one input key is currently held.
|
||||
static bool shellIsKeyDown(INPUT_KEY key) {
|
||||
bool down = false;
|
||||
return SysIsKeyDown(key, &down) == STATUS_SUCCESS && down;
|
||||
}
|
||||
|
||||
// Waits for a foreground process while watching Ctrl-C without stealing ordinary stdin.
|
||||
static uint32_t waitForegroundProcess(uint32_t hProc) {
|
||||
uint32_t pid = 0;
|
||||
bool havePid = SysGetProcessPid(hProc, &pid) == 0 && pid != 0;
|
||||
bool sentBreak = false;
|
||||
|
||||
uint32_t inputQueue = 0;
|
||||
@@ -1451,7 +1511,7 @@ static uint32_t waitForegroundProcess(uint32_t hProc) {
|
||||
for (;;) {
|
||||
index = 0;
|
||||
uint32_t status = SysWaitMany(&waitReq);
|
||||
if (status != SYS_STATUS_SUCCESS) {
|
||||
if (status != STATUS_SUCCESS) {
|
||||
SysCloseHandle(inputQueue);
|
||||
return status;
|
||||
}
|
||||
@@ -1462,10 +1522,10 @@ static uint32_t waitForegroundProcess(uint32_t hProc) {
|
||||
}
|
||||
|
||||
uint32_t modifiers = SysGetKeyModifiers();
|
||||
if (((modifiers & INPUT_MOD_CTRL) && SysIsKeyDown(INPUT_KEY_C)) || shellConsumeQueuedCtrlC()) {
|
||||
if (((modifiers & INPUT_MOD_CTRL) && shellIsKeyDown(INPUT_KEY_C)) || shellConsumeQueuedCtrlC()) {
|
||||
if (!sentBreak) {
|
||||
print("^C\n");
|
||||
if (havePid) (void)SysKillProcess(pid, (int)STATUS_PROCESS_KILLED);
|
||||
(void)SysKillProcess(hProc, (int32_t)STATUS_PROCESS_KILLED);
|
||||
sentBreak = true;
|
||||
}
|
||||
}
|
||||
@@ -1564,13 +1624,13 @@ static int runCommand(const char* cmd) {
|
||||
} else {
|
||||
// Foreground mode: Wait for completion and flush standard keyboard stream.
|
||||
uint32_t waitStatus = waitForegroundProcess(hProc);
|
||||
if (waitStatus != SYS_STATUS_SUCCESS) {
|
||||
if (waitStatus != STATUS_SUCCESS) {
|
||||
print("shell: wait failed: ");
|
||||
printUInt(waitStatus);
|
||||
print("\n");
|
||||
}
|
||||
print("Process exited with code: ");
|
||||
int exitCode;
|
||||
int32_t exitCode;
|
||||
SysGetProcessExitCode(hProc, &exitCode);
|
||||
printInt(exitCode);
|
||||
const char* exitName = processExitStatusName((uint32_t)exitCode);
|
||||
@@ -1583,7 +1643,8 @@ static int runCommand(const char* cmd) {
|
||||
}
|
||||
print("\n");
|
||||
SysCloseHandle(hProc);
|
||||
while (SysPollKeyboard()) (void)SysReadKey();
|
||||
INPUT_KEY drainedKey;
|
||||
while (SysPollKeyboard(&drainedKey) == STATUS_SUCCESS) (void)SysReadKey(&drainedKey);
|
||||
}
|
||||
} else {
|
||||
print("shell: launch failed\n");
|
||||
|
||||
Reference in new issue
Block a user