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
@@ -1416,36 +1416,158 @@ static void cmd_write(const char* args) {
|
||||
print("File written successfully.\n");
|
||||
}
|
||||
|
||||
#define SHELL_DIR_INITIAL_CAPACITY 64u
|
||||
|
||||
// Returns an ASCII lower-case value for case-insensitive directory sorting.
|
||||
static char shellAsciiLower(char c) {
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return (char)(c - 'A' + 'a');
|
||||
return c;
|
||||
}
|
||||
|
||||
// Compares two names using case-insensitive order with a stable case tie-breaker.
|
||||
static int shellCompareNames(const char* a, const char* b) {
|
||||
size_t i = 0;
|
||||
if (!a) a = "";
|
||||
if (!b) b = "";
|
||||
|
||||
for (;;) {
|
||||
char ca = shellAsciiLower(a[i]);
|
||||
char cb = shellAsciiLower(b[i]);
|
||||
if (ca != cb)
|
||||
return (ca < cb) ? -1 : 1;
|
||||
if (ca == '\0')
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
return strcmp(a, b);
|
||||
}
|
||||
|
||||
// Compares two directory entries by display name.
|
||||
static int shellCompareDirEntries(const SYS_DIR_ENTRY* a, const SYS_DIR_ENTRY* b) {
|
||||
return shellCompareNames(a->Name, b->Name);
|
||||
}
|
||||
|
||||
// Allocates a directory-entry array from VM so large listings do not consume stack.
|
||||
static uint32_t shellAllocDirEntries(uint32_t capacity, SYS_DIR_ENTRY** entriesOut) {
|
||||
void* base = 0;
|
||||
size_t bytes = (size_t)capacity * sizeof(SYS_DIR_ENTRY);
|
||||
size_t pages = (bytes + 4095u) / 4096u;
|
||||
if (pages == 0) pages = 1;
|
||||
|
||||
SYS_ALLOC_VM_REQUEST req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.Size = sizeof(req);
|
||||
req.Protect = SYS_VM_READWRITE;
|
||||
req.Flags = SYS_VM_FLAG_NONE;
|
||||
req.PageCount = pages;
|
||||
req.BaseOut = &base;
|
||||
|
||||
uint32_t status = SysAllocVm(&req);
|
||||
if (status != 0 || !base) {
|
||||
*entriesOut = 0;
|
||||
return status ? status : 1;
|
||||
}
|
||||
|
||||
*entriesOut = (SYS_DIR_ENTRY*)base;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Grows a directory-entry array while preserving already-read entries.
|
||||
static uint32_t shellGrowDirEntries(SYS_DIR_ENTRY** entries, uint32_t* capacity, uint32_t count) {
|
||||
uint32_t oldCapacity = *capacity;
|
||||
uint32_t newCapacity = oldCapacity ? oldCapacity * 2u : SHELL_DIR_INITIAL_CAPACITY;
|
||||
SYS_DIR_ENTRY* next = 0;
|
||||
uint32_t status = shellAllocDirEntries(newCapacity, &next);
|
||||
if (status != 0)
|
||||
return status;
|
||||
|
||||
if (*entries && count)
|
||||
memcpy(next, *entries, (size_t)count * sizeof(SYS_DIR_ENTRY));
|
||||
if (*entries)
|
||||
SysFreeVm(*entries);
|
||||
|
||||
*entries = next;
|
||||
*capacity = newCapacity;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Sorts directory entries alphabetically.
|
||||
static void shellSortDirEntries(SYS_DIR_ENTRY* entries, uint32_t count) {
|
||||
for (uint32_t i = 1; i < count; i++) {
|
||||
SYS_DIR_ENTRY current = entries[i];
|
||||
uint32_t j = i;
|
||||
while (j > 0 && shellCompareDirEntries(¤t, &entries[j - 1]) < 0) {
|
||||
entries[j] = entries[j - 1];
|
||||
j--;
|
||||
}
|
||||
entries[j] = current;
|
||||
}
|
||||
}
|
||||
|
||||
// Prints one directory entry in cmd dir format.
|
||||
static void shellPrintDirEntry(const SYS_DIR_ENTRY* ke) {
|
||||
printDirTime(&ke->LastWriteTime);
|
||||
|
||||
if (ke->Attr & 0x10) {
|
||||
print("<DIR> ");
|
||||
print(ke->Name);
|
||||
} else {
|
||||
print(" ");
|
||||
print(ke->Name);
|
||||
print(" (");
|
||||
printUInt64(ke->FileSize);
|
||||
print(" bytes)");
|
||||
}
|
||||
print("\n");
|
||||
}
|
||||
|
||||
// Implements the cmd dir operation.
|
||||
static void cmd_dir(const char* path) {
|
||||
uint32_t hDir;
|
||||
const char* target = (path && *path != '\0') ? path : ".";
|
||||
|
||||
|
||||
uint32_t st = open_dir(target, &hDir);
|
||||
if (st != 0) {
|
||||
if (st != 0) {
|
||||
print("dir: failed to open directory, status=0x");
|
||||
printHex32(st);
|
||||
print("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
SYS_DIR_ENTRY ke;
|
||||
while (SysReadDir(hDir, &ke) == 0) {
|
||||
printDirTime(&ke.LastWriteTime);
|
||||
|
||||
if (ke.Attr & 0x10) {
|
||||
print("<DIR> ");
|
||||
print(ke.Name);
|
||||
} else {
|
||||
print(" ");
|
||||
print(ke.Name);
|
||||
print(" (");
|
||||
printUInt64(ke.FileSize);
|
||||
print(" bytes)");
|
||||
}
|
||||
print("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
SYS_DIR_ENTRY* entries = 0;
|
||||
uint32_t count = 0;
|
||||
uint32_t capacity = 0;
|
||||
|
||||
for (;;) {
|
||||
SYS_DIR_ENTRY ke;
|
||||
st = SysReadDir(hDir, &ke);
|
||||
if (st != 0)
|
||||
break;
|
||||
|
||||
if (count == capacity) {
|
||||
st = shellGrowDirEntries(&entries, &capacity, count);
|
||||
if (st != 0) {
|
||||
print("dir: out of memory, status=0x");
|
||||
printHex32(st);
|
||||
print("\n");
|
||||
SysCloseHandle(hDir);
|
||||
if (entries) SysFreeVm(entries);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
entries[count++] = ke;
|
||||
}
|
||||
|
||||
SysCloseHandle(hDir);
|
||||
shellSortDirEntries(entries, count);
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
shellPrintDirEntry(&entries[i]);
|
||||
|
||||
if (entries)
|
||||
SysFreeVm(entries);
|
||||
}
|
||||
|
||||
// Implements the cmd type operation.
|
||||
|
||||
Reference in new issue
Block a user