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:
maksw committed 2026-07-12 00:10:21 +02:00
1 parent 485a6bbfe7
commit 8b254f84f4
74 files changed
+4488 -2503

No files matched your search

+100 -151
View File
@@ -6,7 +6,7 @@
// Compiler and linker flags stay in macros so they can be used in file-scope aggregate initializers.
// MSVC C rejects initializing a static object from another object, even when the source object is const.
// Drivers and user binaries do not inherit kernel include paths so private dependencies fail at compile time.
#define COMMON_CFLAGS_LITERAL "/nologo /W3 /WX /Od /GS- /Gs999999 /Gz /Gy /EHsc- /GR- /Oi- /Z7 /std:c17 /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS /Icode\\public /Icode\\common\\include"
#define COMMON_CFLAGS_LITERAL "/nologo /W3 /WX /O2 /GS- /Gs999999 /Gz /Gy /EHsc- /GR- /Oi- /Z7 /std:c17 /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS /Icode\\public /Icode\\common\\include"
#define KERNEL_CFLAGS_LITERAL COMMON_CFLAGS_LITERAL " /Icode\\kernel\\include"
#define DRIVER_CFLAGS_LITERAL COMMON_CFLAGS_LITERAL
#define USER_CFLAGS_LITERAL COMMON_CFLAGS_LITERAL
@@ -48,7 +48,7 @@ static const Driver_Target STANDALONE_DRIVERS[] = {
DRIVER_TARGET("serial", "obj\\drivers\\serial", "code\\drivers\\input\\serial\\serial.c"),
DRIVER_TARGET_LIBS("ata", "obj\\drivers\\ata", "code\\drivers\\storage\\ata\\ata.c", "bin\\pci.lib"),
DRIVER_TARGET_LIBS("ahci", "obj\\drivers\\ahci", "code\\drivers\\storage\\ahci\\ahci.c code\\drivers\\storage\\ahci\\ahci_port.c", "bin\\pci.lib"),
DRIVER_TARGET("fat32", "obj\\drivers\\fat32", "code\\drivers\\fs\\fat32\\fat32.c code\\drivers\\fs\\fat32\\fat32_mount.c"),
DRIVER_TARGET("fat", "obj\\drivers\\fat", "code\\drivers\\fs\\fat\\fat.c code\\drivers\\fs\\fat\\fat_mount.c"),
DRIVER_TARGET("ntfs", "obj\\drivers\\ntfs", "code\\drivers\\fs\\ntfs\\ntfs.c"),
DRIVER_TARGET_LIBS("vmwaresvga", "obj\\drivers\\vmwaresvga", "code\\drivers\\display\\vmwaresvga\\vmwaresvga.c", "bin\\pci.lib"),
DRIVER_TARGET_LIBS("usb", "obj\\drivers\\usb", "code\\drivers\\bus\\usb\\usb.c code\\drivers\\bus\\usb\\usb_bus.c code\\drivers\\bus\\usb\\usb_composite.c code\\drivers\\bus\\usb\\usb_core.c code\\drivers\\bus\\usb\\usb_xhci.c code\\drivers\\bus\\usb\\usb_hid.c code\\drivers\\bus\\usb\\usb_storage.c code\\drivers\\bus\\usb\\usb_hub.c", "bin\\pci.lib"),
@@ -66,7 +66,7 @@ void create_layout() {
"obj\\tcpserve", "obj\\udp", "obj\\resolve", "obj\\ping", "obj\\doom", "obj\\video", "obj\\memtop",
"obj\\file_stat_smoke", "obj\\handle_dup_smoke", "obj\\named_queue_lifetime_smoke", "obj\\input_api_smoke", "obj\\input_model_smoke", "obj\\timer_smoke", "obj\\stats_abi_smoke", "obj\\realpath_smoke", "obj\\file_lock_smoke", "obj\\process_protection_smoke", "obj\\socket_addr_smoke", "obj\\syscall_contract_smoke", "obj\\would_block_smoke", "obj\\cwd_peb_smoke", "obj\\mmap_smoke", "obj\\pcache_smoke", "obj\\pcache_pressure", "obj\\dirty_writeback", "obj\\shared_mmap",
"obj\\pcache_invalidate", "obj\\pcache_mmap_read_reuse", "obj\\pcache_multithread",
"obj\\surface_smoke", "obj\\surface_invalid_rect", "obj\\surface_multithread_present", "obj\\net_irp_smoke", "obj\\module_load_smoke", "obj\\posix_module_smoke", "obj\\exception_dispatcher_smoke", "obj\\native_exception_runtime_smoke", "obj\\native_raise_exception_smoke", "obj\\exception_smoke", "obj\\win32_exception_smoke", "obj\\win32_seh_smoke"
"obj\\all_tests", "obj\\surface_smoke", "obj\\surface_invalid_rect", "obj\\surface_multithread_present", "obj\\net_irp_smoke", "obj\\module_load_smoke", "obj\\posix_module_smoke", "obj\\exception_dispatcher_smoke", "obj\\native_exception_runtime_smoke", "obj\\native_raise_exception_smoke", "obj\\exception_smoke", "obj\\win32_exception_smoke", "obj\\win32_seh_smoke"
};
for (size_t i = 0; i < NOB_ARRAY_LEN(dirs); i++) nob_mkdir_if_not_exists(dirs[i]);
nob_mkdir_if_not_exists(PCI_BUS_DRIVER.obj_dir);
@@ -91,67 +91,32 @@ Nob_Proc run_async(const char *cmd_str) {
return proc;
}
// Deletes stale object files from a target directory before compiling into it.
// Link commands use directory wildcards, so removed translation units can otherwise
// survive as old .obj files and keep unresolved references alive.
bool clean_object_directory(const char *obj_dir) {
const char *cmd = nob_temp_sprintf("if exist %s\\*.obj del /q %s\\*.obj", obj_dir, obj_dir);
return run_sync(cmd);
// Cleans all object output by replacing obj/ as a whole.
// Only obj/ is disposable. fatroot/ and usbfatroot/ are developer-owned vvfat roots.
bool clean_build_object_directories(void) {
const char *cmd = "if exist obj rmdir /s /q obj";
if (!run_sync(cmd)) return false;
return nob_mkdir_if_not_exists("obj");
}
// Cleans object directories that are linked through wildcards.
// The build is intentionally simple and does not maintain per-file dependency state,
// so stale objects are more dangerous than recompiling a few extra files.
bool clean_build_object_directories(void) {
// Creates the FAT root layout used by QEMU vvfat without deleting existing files.
// The vvfat root is also a convenient developer workspace, so packaging must be non-destructive.
bool create_fatroot_layout(void) {
const char *dirs[] = {
"obj\\boot", "obj\\kernel", "obj\\lwip", "obj\\hal",
"obj\\syscall", "obj\\runtime", "obj\\win32", "obj\\posix",
"obj\\init", "obj\\shell_win32", "obj\\shell_posix", "obj\\shell_native",
"obj\\async_apc", "obj\\async_cancel", "obj\\apc_return_smoke", "obj\\edit", "obj\\httpget",
"obj\\tcpserve", "obj\\udp", "obj\\resolve", "obj\\ping",
"obj\\doom", "obj\\video", "obj\\memtop", "obj\\file_stat_smoke", "obj\\handle_dup_smoke", "obj\\named_queue_lifetime_smoke", "obj\\input_api_smoke", "obj\\input_model_smoke", "obj\\timer_smoke", "obj\\stats_abi_smoke", "obj\\realpath_smoke", "obj\\file_lock_smoke", "obj\\process_protection_smoke", "obj\\socket_addr_smoke", "obj\\syscall_contract_smoke", "obj\\would_block_smoke", "obj\\cwd_peb_smoke", "obj\\mmap_smoke", "obj\\pcache_smoke", "obj\\pcache_pressure", "obj\\dirty_writeback", "obj\\shared_mmap",
"obj\\pcache_invalidate", "obj\\pcache_mmap_read_reuse", "obj\\pcache_multithread",
"obj\\surface_smoke", "obj\\surface_invalid_rect", "obj\\surface_multithread_present", "obj\\net_irp_smoke", "obj\\module_load_smoke", "obj\\posix_module_smoke", "obj\\exception_dispatcher_smoke", "obj\\native_exception_runtime_smoke", "obj\\native_raise_exception_smoke", "obj\\exception_smoke", "obj\\win32_exception_smoke", "obj\\win32_seh_smoke"
"fatroot\\EFI", "fatroot\\EFI\\BOOT",
"fatroot\\system", "fatroot\\drivers", "fatroot\\apps", "fatroot\\tests"
};
for (size_t i = 0; i < NOB_ARRAY_LEN(dirs); i++) {
if (!clean_object_directory(dirs[i])) return false;
}
if (!clean_object_directory(PCI_BUS_DRIVER.obj_dir)) return false;
for (size_t i = 0; i < NOB_ARRAY_LEN(STANDALONE_DRIVERS); i++) {
if (!clean_object_directory(STANDALONE_DRIVERS[i].obj_dir)) return false;
if (!nob_mkdir_if_not_exists(dirs[i])) return false;
}
return true;
}
// Creates an empty USB image the first time the build sees a missing usb.vhd.
// The image is intentionally left unmounted and unpopulated after formatting so
// callers can use it as removable FAT32 storage without the build overwriting it.
bool create_usb_vhd_if_missing(void) {
if (nob_file_exists("usb.vhd")) return true;
char vhd_path[MAX_PATH];
GetFullPathNameA("usb.vhd", MAX_PATH, vhd_path, NULL);
const char *diskpart_script = nob_temp_sprintf(
"create vdisk file=\"%s\" maximum=256 type=fixed\n"
"select vdisk file=\"%s\"\n"
"attach vdisk\n"
"convert gpt\n"
"create partition primary\n"
"format fs=ntfs quick\n"
"detach vdisk\n"
"exit\n",
vhd_path, vhd_path
);
nob_log(NOB_INFO, "usb.vhd missing, creating empty 256 MB FAT32 GPT image...");
nob_write_entire_file("usb_mkimage.txt", diskpart_script, strlen(diskpart_script));
bool ok = run_sync("diskpart /s usb_mkimage.txt");
remove("usb_mkimage.txt");
return ok;
// Creates the USB vvfat root once and leaves its contents alone between builds.
bool create_usbfatroot_if_missing(void) {
return nob_mkdir_if_not_exists("usbfatroot");
}
// Runs the requested operation.
@@ -159,14 +124,9 @@ int main(int argc, char **argv) {
// The build tool rebuilds itself before doing any real work so the graph below matches the source.
NOB_GO_REBUILD_URSELF(argc, argv);
// The boot image must exist before the build can copy fresh binaries into it.
if (!nob_file_exists("disk.vhd")) {
nob_log(NOB_INFO, "disk.vhd missing, calling mkimage.bat...");
if (!run_sync("mkimage.bat")) return 1;
}
if (!create_usb_vhd_if_missing()) return 1;
create_layout();
if (!clean_build_object_directories()) return 1;
create_layout();
if (!create_usbfatroot_if_missing()) return 1;
// Core images build sequentially because later images link against earlier import libraries.
nob_log(NOB_INFO, "--- Building Core Subsystems ---");
@@ -250,6 +210,7 @@ int main(int argc, char **argv) {
const char *apps[][4] = {
// Folder, Libs, Name, Optional Extra Link Args.
{"system\\init", NATIVE_INIT_LIBS_LITERAL, "init", "/ENTRY:_start"},
{"tests\\all_tests", NATIVE_EXE_LIBS_LITERAL, "all_tests", NATIVE_EXE_ENTRY_LITERAL},
{"apps\\shell_win32", WIN32_EXE_LIBS_LITERAL, "shell_win32", NATIVE_EXE_ENTRY_LITERAL},
{"apps\\shell_posix", POSIX_EXE_LIBS_LITERAL, "shell_posix", "/ENTRY:PosixStart"},
{"apps\\shell_native", NATIVE_EXE_LIBS_LITERAL, "shell_native", NATIVE_EXE_ENTRY_LITERAL},
@@ -315,103 +276,91 @@ int main(int argc, char **argv) {
return 1;
}
// 4. Mounting & Packing Image.
nob_log(NOB_INFO, "--- Mounting disk.vhd ---");
// Resolve the absolute path to disk.vhd for diskpart.
char vhd_path[MAX_PATH];
GetFullPathNameA("disk.vhd", MAX_PATH, vhd_path, NULL);
const char *diskpart_mnt = nob_temp_sprintf(
"select vdisk file=\"%s\"\nattach vdisk\n"
"select partition 1\nformat fs=fat32 quick\nassign letter=Z\n"
"select partition 2\nformat fs=fat32 quick\nassign letter=Y\nexit\n",
vhd_path
);
nob_write_entire_file("mnt.txt", diskpart_mnt, strlen(diskpart_mnt));
if (!run_sync("diskpart /s mnt.txt")) return 1;
nob_log(NOB_INFO, "--- Assembling ESP ---");
_mkdir("Z:\\apps"); _mkdir("Y:\\apps");
_mkdir("Z:\\system"); _mkdir("Z:\\drivers");
_mkdir("Z:\\EFI"); _mkdir("Z:\\EFI\\BOOT");
// 4. Packing vvfat root.
nob_log(NOB_INFO, "--- Assembling fatroot ---");
if (!create_fatroot_layout()) return 1;
const char *copies[][2] = {
{"bin\\bootx64.efi", "Z:\\EFI\\BOOT\\bootx64.efi"}, {"bin\\kernel.exe", "Z:\\system\\colonel.exe"},
{"bin\\hal.dll", "Z:\\system\\hal.dll"}, {"bin\\syscall.dll", "Z:\\system\\syscall.dll"},
{"bin\\win32.dll", "Z:\\system\\win32.dll"}, {"bin\\posix.dll", "Z:\\system\\posix.dll"},
{"code\\settings.ini", "Z:\\system\\settings.ini"}, {"bin\\init.exe", "Z:\\system\\init.exe"},
{"bin\\pci.sys", "Z:\\drivers\\pci.sys"}, {"bin\\ps2.sys", "Z:\\drivers\\ps2.sys"},
{"bin\\serial.sys", "Z:\\drivers\\serial.sys"},
{"bin\\ata.sys", "Z:\\drivers\\ata.sys"}, {"bin\\ahci.sys", "Z:\\drivers\\ahci.sys"},
{"bin\\fat32.sys", "Z:\\drivers\\fat32.sys"}, {"bin\\ntfs.sys", "Z:\\drivers\\ntfs.sys"},
{"bin\\vmwaresvga.sys", "Z:\\drivers\\vmwaresvga.sys"},
{"bin\\lwip.sys", "Z:\\drivers\\lwip.sys"}, {"bin\\usb.sys", "Z:\\drivers\\usb.sys"},
{"bin\\rtl816x.sys", "Z:\\drivers\\rtl816x.sys"},
{"bin\\rtl8139.sys", "Z:\\drivers\\rtl8139.sys"}, {"code\\drivers\\drivers.ini", "Z:\\drivers\\drivers.ini"},
{"code\\boot.ini", "Z:\\boot.ini"},
{"bin\\bootx64.efi", "fatroot\\EFI\\BOOT\\bootx64.efi"},
{"bin\\kernel.exe", "fatroot\\system\\colonel.exe"},
{"bin\\hal.dll", "fatroot\\system\\hal.dll"},
{"bin\\syscall.dll", "fatroot\\system\\syscall.dll"},
{"bin\\win32.dll", "fatroot\\system\\win32.dll"},
{"bin\\posix.dll", "fatroot\\system\\posix.dll"},
{"code\\settings.ini", "fatroot\\system\\settings.ini"},
{"bin\\init.exe", "fatroot\\system\\init.exe"},
{"bin\\shell_win32.exe", "Z:\\apps\\shell_win32.exe"}, {"bin\\shell_posix.exe", "Z:\\apps\\shell_posix.exe"},
{"bin\\shell_native.exe", "Z:\\apps\\shell_native.exe"}, {"bin\\edit.exe", "Z:\\apps\\edit.exe"},
{"bin\\httpget.exe", "Z:\\apps\\httpget.exe"}, {"bin\\tcpserve.exe", "Z:\\apps\\tcpserve.exe"},
{"bin\\udp.exe", "Z:\\apps\\udp.exe"}, {"bin\\resolve.exe", "Z:\\apps\\resolve.exe"},
{"bin\\ping.exe", "Z:\\apps\\ping.exe"}, {"bin\\doom.exe", "Z:\\apps\\doom.exe"},
{"bin\\video.exe", "Z:\\apps\\video.exe"}, {"bin\\memtop.exe", "Z:\\apps\\memtop.exe"},
{"bin\\pci.sys", "fatroot\\drivers\\pci.sys"},
{"bin\\ps2.sys", "fatroot\\drivers\\ps2.sys"},
{"bin\\serial.sys", "fatroot\\drivers\\serial.sys"},
{"bin\\ata.sys", "fatroot\\drivers\\ata.sys"},
{"bin\\ahci.sys", "fatroot\\drivers\\ahci.sys"},
{"bin\\fat.sys", "fatroot\\drivers\\fat.sys"},
{"bin\\ntfs.sys", "fatroot\\drivers\\ntfs.sys"},
{"bin\\vmwaresvga.sys", "fatroot\\drivers\\vmwaresvga.sys"},
{"bin\\lwip.sys", "fatroot\\drivers\\lwip.sys"},
{"bin\\usb.sys", "fatroot\\drivers\\usb.sys"},
{"bin\\rtl816x.sys", "fatroot\\drivers\\rtl816x.sys"},
{"bin\\rtl8139.sys", "fatroot\\drivers\\rtl8139.sys"},
{"code\\drivers\\drivers.ini", "fatroot\\drivers\\drivers.ini"},
{"code\\boot.ini", "fatroot\\boot.ini"},
{"bin\\async_apc.exe", "Y:\\apps\\async_apc.exe"}, {"bin\\async_cancel.exe", "Y:\\apps\\async_cancel.exe"},
{"bin\\apc_return_smoke.exe", "Y:\\apps\\apc_return_smoke.exe"},
{"bin\\file_stat_smoke.exe", "Y:\\apps\\file_stat_smoke.exe"},
{"bin\\handle_dup_smoke.exe", "Y:\\apps\\handle_dup_smoke.exe"},
{"bin\\named_queue_lifetime_smoke.exe", "Y:\\apps\\named_queue_lifetime_smoke.exe"},
{"bin\\input_api_smoke.exe", "Y:\\apps\\input_api_smoke.exe"},
{"bin\\input_model_smoke.exe", "Y:\\apps\\input_model_smoke.exe"},
{"bin\\timer_smoke.exe", "Y:\\apps\\timer_smoke.exe"},
{"bin\\stats_abi_smoke.exe", "Y:\\apps\\stats_abi_smoke.exe"},
{"bin\\realpath_smoke.exe", "Y:\\apps\\realpath_smoke.exe"},
{"bin\\file_lock_smoke.exe", "Y:\\apps\\file_lock_smoke.exe"},
{"bin\\process_protection_smoke.exe", "Y:\\apps\\process_protection_smoke.exe"},
{"bin\\socket_addr_smoke.exe", "Y:\\apps\\socket_addr_smoke.exe"},
{"bin\\net_irp_smoke.exe", "Y:\\apps\\net_irp_smoke.exe"},
{"bin\\module_load_smoke.exe", "Y:\\apps\\module_load_smoke.exe"},
{"bin\\posix_module_smoke.exe", "Y:\\apps\\posix_module_smoke.exe"},
{"bin\\exception_dispatcher_smoke.exe", "Y:\\apps\\exception_dispatcher_smoke.exe"},
{"bin\\native_exception_runtime_smoke.exe", "Y:\\apps\\native_exception_runtime_smoke.exe"},
{"bin\\native_raise_exception_smoke.exe", "Y:\\apps\\native_raise_exception_smoke.exe"},
{"bin\\exception_smoke.exe", "Y:\\apps\\exception_smoke.exe"},
{"bin\\win32_exception_smoke.exe", "Y:\\apps\\win32_exception_smoke.exe"},
{"bin\\win32_seh_smoke.exe", "Y:\\apps\\win32_seh_smoke.exe"},
{"bin\\syscall_contract_smoke.exe", "Y:\\apps\\syscall_contract_smoke.exe"},
{"bin\\would_block_smoke.exe", "Y:\\apps\\would_block_smoke.exe"},
{"bin\\cwd_peb_smoke.exe", "Y:\\apps\\cwd_peb_smoke.exe"},
{"bin\\mmap_smoke.exe", "Y:\\apps\\mmap_smoke.exe"}, {"bin\\pcache_smoke.exe", "Y:\\apps\\pcache_smoke.exe"},
{"bin\\pcache_pressure.exe", "Y:\\apps\\pcache_pressure.exe"},
{"bin\\dirty_writeback.exe", "Y:\\apps\\dirty_writeback.exe"},
{"bin\\shared_mmap.exe", "Y:\\apps\\shared_mmap.exe"},
{"bin\\pcache_invalidate.exe", "Y:\\apps\\pcache_invalidate.exe"},
{"bin\\pcache_mmap_read_reuse.exe", "Y:\\apps\\pcache_mmap_read_reuse.exe"},
{"bin\\pcache_multithread.exe", "Y:\\apps\\pcache_multithread.exe"},
{"bin\\surface_smoke.exe", "Y:\\apps\\surface_smoke.exe"},
{"bin\\surface_invalid_rect.exe", "Y:\\apps\\surface_invalid_rect.exe"},
{"bin\\surface_multithread_present.exe", "Y:\\apps\\surface_multithread_present.exe"}
{"bin\\shell_win32.exe", "fatroot\\apps\\shell_win32.exe"},
{"bin\\shell_posix.exe", "fatroot\\apps\\shell_posix.exe"},
{"bin\\shell_native.exe", "fatroot\\apps\\shell_native.exe"},
{"bin\\edit.exe", "fatroot\\apps\\edit.exe"},
{"bin\\httpget.exe", "fatroot\\apps\\httpget.exe"},
{"bin\\tcpserve.exe", "fatroot\\apps\\tcpserve.exe"},
{"bin\\udp.exe", "fatroot\\apps\\udp.exe"},
{"bin\\resolve.exe", "fatroot\\apps\\resolve.exe"},
{"bin\\ping.exe", "fatroot\\apps\\ping.exe"},
{"bin\\doom.exe", "fatroot\\apps\\doom.exe"},
{"bin\\video.exe", "fatroot\\apps\\video.exe"},
{"bin\\memtop.exe", "fatroot\\apps\\memtop.exe"},
{"bin\\all_tests.exe", "fatroot\\tests\\all_tests.exe"},
{"bin\\async_apc.exe", "fatroot\\tests\\async_apc.exe"},
{"bin\\async_cancel.exe", "fatroot\\tests\\async_cancel.exe"},
{"bin\\apc_return_smoke.exe", "fatroot\\tests\\apc_return_smoke.exe"},
{"bin\\file_stat_smoke.exe", "fatroot\\tests\\file_stat_smoke.exe"},
{"bin\\handle_dup_smoke.exe", "fatroot\\tests\\handle_dup_smoke.exe"},
{"bin\\named_queue_lifetime_smoke.exe", "fatroot\\tests\\named_queue_lifetime_smoke.exe"},
{"bin\\input_api_smoke.exe", "fatroot\\tests\\input_api_smoke.exe"},
{"bin\\input_model_smoke.exe", "fatroot\\tests\\input_model_smoke.exe"},
{"bin\\timer_smoke.exe", "fatroot\\tests\\timer_smoke.exe"},
{"bin\\stats_abi_smoke.exe", "fatroot\\tests\\stats_abi_smoke.exe"},
{"bin\\realpath_smoke.exe", "fatroot\\tests\\realpath_smoke.exe"},
{"bin\\file_lock_smoke.exe", "fatroot\\tests\\file_lock_smoke.exe"},
{"bin\\process_protection_smoke.exe", "fatroot\\tests\\process_protection_smoke.exe"},
{"bin\\socket_addr_smoke.exe", "fatroot\\tests\\socket_addr_smoke.exe"},
{"bin\\net_irp_smoke.exe", "fatroot\\tests\\net_irp_smoke.exe"},
{"bin\\module_load_smoke.exe", "fatroot\\tests\\module_load_smoke.exe"},
{"bin\\posix_module_smoke.exe", "fatroot\\tests\\posix_module_smoke.exe"},
{"bin\\exception_dispatcher_smoke.exe", "fatroot\\tests\\exception_dispatcher_smoke.exe"},
{"bin\\native_exception_runtime_smoke.exe", "fatroot\\tests\\native_exception_runtime_smoke.exe"},
{"bin\\native_raise_exception_smoke.exe", "fatroot\\tests\\native_raise_exception_smoke.exe"},
{"bin\\exception_smoke.exe", "fatroot\\tests\\exception_smoke.exe"},
{"bin\\win32_exception_smoke.exe", "fatroot\\tests\\win32_exception_smoke.exe"},
{"bin\\win32_seh_smoke.exe", "fatroot\\tests\\win32_seh_smoke.exe"},
{"bin\\syscall_contract_smoke.exe", "fatroot\\tests\\syscall_contract_smoke.exe"},
{"bin\\would_block_smoke.exe", "fatroot\\tests\\would_block_smoke.exe"},
{"bin\\cwd_peb_smoke.exe", "fatroot\\tests\\cwd_peb_smoke.exe"},
{"bin\\mmap_smoke.exe", "fatroot\\tests\\mmap_smoke.exe"},
{"bin\\pcache_smoke.exe", "fatroot\\tests\\pcache_smoke.exe"},
{"bin\\pcache_pressure.exe", "fatroot\\tests\\pcache_pressure.exe"},
{"bin\\dirty_writeback.exe", "fatroot\\tests\\dirty_writeback.exe"},
{"bin\\shared_mmap.exe", "fatroot\\tests\\shared_mmap.exe"},
{"bin\\pcache_invalidate.exe", "fatroot\\tests\\pcache_invalidate.exe"},
{"bin\\pcache_mmap_read_reuse.exe", "fatroot\\tests\\pcache_mmap_read_reuse.exe"},
{"bin\\pcache_multithread.exe", "fatroot\\tests\\pcache_multithread.exe"},
{"bin\\surface_smoke.exe", "fatroot\\tests\\surface_smoke.exe"},
{"bin\\surface_invalid_rect.exe", "fatroot\\tests\\surface_invalid_rect.exe"},
{"bin\\surface_multithread_present.exe", "fatroot\\tests\\surface_multithread_present.exe"}
};
for (size_t i = 0; i < NOB_ARRAY_LEN(copies); i++) nob_copy_file(copies[i][0], copies[i][1]);
if (nob_file_exists("code\\user\\apps\\video\\bink2w64.dll")) nob_copy_file("code\\user\\apps\\video\\bink2w64.dll", "Z:\\apps\\bink2w64.dll");
if (nob_file_exists("code\\user\\apps\\video\\video.bk2")) nob_copy_file("code\\user\\apps\\video\\video.bk2", "Z:\\apps\\video.bk2");
if (nob_file_exists("code\\user\\apps\\doom\\doom1.wad")) nob_copy_file("code\\user\\apps\\doom\\doom1.wad", "Z:\\apps\\doom1.wad");
nob_log(NOB_INFO, "--- Unmounting disk.vhd ---");
const char *diskpart_umnt = nob_temp_sprintf(
"select vdisk file=\"%s\"\ndetach vdisk\nexit\n",
vhd_path
);
nob_write_entire_file("umnt.txt", diskpart_umnt, strlen(diskpart_umnt));
run_sync("diskpart /s umnt.txt");
remove("mnt.txt");
remove("umnt.txt");
for (size_t i = 0; i < NOB_ARRAY_LEN(copies); i++) {
if (!nob_copy_file(copies[i][0], copies[i][1])) return 1;
}
nob_log(NOB_INFO, "Build complete!");
return 0;