diff --git a/OVMF/OVMF_VARS_4M_d.fd b/OVMF/OVMF_VARS_4M_d.fd index efc24ae..8905bfc 100644 Binary files a/OVMF/OVMF_VARS_4M_d.fd and b/OVMF/OVMF_VARS_4M_d.fd differ diff --git a/code/build/build.c b/code/build/build.c index 0f57097..4057a78 100644 --- a/code/build/build.c +++ b/code/build/build.c @@ -6,6 +6,13 @@ // 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. #define 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 /Icode\\kernel\\include" +#define USER_HEAP_OBJS_LITERAL "obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj" +#define NATIVE_RUNTIME_OBJS_LITERAL "obj\\runtime\\native_exception.obj obj\\runtime\\native_start.obj" +#define NATIVE_EXE_LIBS_LITERAL "bin\\syscall.lib obj\\libc.obj " USER_HEAP_OBJS_LITERAL " " NATIVE_RUNTIME_OBJS_LITERAL +#define NATIVE_INIT_LIBS_LITERAL "bin\\syscall.lib obj\\libc.obj " USER_HEAP_OBJS_LITERAL " obj\\runtime\\native_exception.obj" +#define WIN32_EXE_LIBS_LITERAL "bin\\win32.lib bin\\syscall.lib obj\\libc.obj obj\\runtime\\native_start.obj" +#define POSIX_EXE_LIBS_LITERAL "bin\\posix.lib bin\\syscall.lib obj\\libc.obj obj\\runtime\\posix_start.obj obj\\runtime\\native_exception.obj" +#define NATIVE_EXE_ENTRY_LITERAL "/ENTRY:NtlNativeStart" #define LWIP_CFLAGS_LITERAL CFLAGS_LITERAL " /Icode\\drivers\\net\\lwip\\include /Icode\\third_party\\lwip\\src\\include /wd4005 /wd4100 /wd4103 /wd4127 /wd4244 /wd4267 /wd4706" #define LFLAGS_LITERAL "/nologo /NODEFAULTLIB /DEBUG" @@ -49,9 +56,9 @@ void create_layout() { "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\\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\\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\\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); @@ -94,9 +101,9 @@ bool clean_build_object_directories(void) { "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\\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\\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\\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++) { @@ -167,6 +174,8 @@ int main(int argc, char **argv) { "cl /nologo /c /Foobj\\libc.obj code\\common\\libc.c", nob_temp_sprintf("cl %s /c /Foobj\\runtime\\user_heap.obj code\\user\\runtime\\heap.c", CFLAGS), nob_temp_sprintf("cl %s /c /Foobj\\runtime\\user_heap_exports.obj code\\user\\runtime\\heap_exports.c", CFLAGS), + nob_temp_sprintf("cl %s /c /Foobj\\runtime\\native_exception.obj code\\user\\runtime\\native_exception.c", CFLAGS), + nob_temp_sprintf("cl %s /c /Foobj\\runtime\\native_start.obj code\\user\\runtime\\native_start.c", CFLAGS), nob_temp_sprintf("cl %s /c /Foobj\\runtime\\posix_start.obj code\\user\\runtime\\posix_start.c", CFLAGS), // Bootloader. @@ -180,7 +189,7 @@ int main(int argc, char **argv) { // Subsystem DLLs. "link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL /OUT:bin\\syscall.dll obj\\syscall\\stubs.obj", - nob_temp_sprintf("cl %s /DUSER_HEAP_EXPORTS /MP /c /Foobj\\win32\\ code\\user\\runtime\\heap.c code\\user\\runtime\\heap_exports.c code\\user\\personalities\\win32\\*.c && link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL /OUT:bin\\win32.dll bin\\syscall.lib obj\\libc.obj obj\\win32\\*.obj", CFLAGS), + nob_temp_sprintf("cl %s /DUSER_HEAP_EXPORTS /DNTL_EXCEPTION_EXPORTS /MP /c /Foobj\\win32\\ code\\user\\runtime\\heap.c code\\user\\runtime\\heap_exports.c code\\user\\runtime\\native_exception.c code\\user\\personalities\\win32\\*.c && link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL /OUT:bin\\win32.dll bin\\syscall.lib obj\\libc.obj obj\\win32\\*.obj", CFLAGS), nob_temp_sprintf("cl %s /DUSER_HEAP_EXPORTS /MP /c /Foobj\\posix\\ code\\user\\runtime\\heap.c code\\user\\runtime\\heap_exports.c code\\user\\personalities\\posix\\*.c && link /nologo /SUBSYSTEM:NATIVE /NODEFAULTLIB /DLL /OUT:bin\\posix.dll bin\\syscall.lib obj\\libc.obj obj\\posix\\*.obj", CFLAGS) }; @@ -232,49 +241,56 @@ int main(int argc, char **argv) { // Queue Subsystem Applications. const char *apps[][4] = { // Folder, Libs, Name, Optional Extra Link Args. - {"system\\init", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "init", "/ENTRY:_start"}, - {"apps\\shell_win32", "bin\\win32.lib obj\\libc.obj", "shell_win32", "/ENTRY:main"}, - {"apps\\shell_posix", "bin\\posix.lib obj\\libc.obj obj\\runtime\\posix_start.obj", "shell_posix", "/ENTRY:PosixStart"}, - {"apps\\shell_native", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "shell_native", "/ENTRY:main"}, - {"tests\\async_apc", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "async_apc", "/ENTRY:main"}, - {"tests\\apc_return_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "apc_return_smoke", "/ENTRY:main"}, - {"tests\\async_cancel", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "async_cancel", "/ENTRY:main"}, - {"tests\\file_stat_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "file_stat_smoke", "/ENTRY:main"}, - {"tests\\handle_dup_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "handle_dup_smoke", "/ENTRY:main"}, - {"tests\\input_api_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "input_api_smoke", "/ENTRY:main"}, - {"tests\\input_model_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "input_model_smoke", "/ENTRY:main"}, - {"tests\\timer_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "timer_smoke", "/ENTRY:main"}, - {"tests\\stats_abi_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "stats_abi_smoke", "/ENTRY:main"}, - {"tests\\realpath_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "realpath_smoke", "/ENTRY:main"}, - {"tests\\file_lock_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "file_lock_smoke", "/ENTRY:main"}, - {"tests\\process_protection_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "process_protection_smoke", "/ENTRY:main"}, - {"tests\\socket_addr_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "socket_addr_smoke", "/ENTRY:main"}, - {"tests\\net_irp_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "net_irp_smoke", "/ENTRY:main"}, - {"tests\\module_load_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "module_load_smoke", "/ENTRY:main"}, - {"tests\\posix_module_smoke", "bin\\posix.lib obj\\libc.obj obj\\runtime\\posix_start.obj", "posix_module_smoke", "/ENTRY:PosixStart"}, - {"tests\\syscall_contract_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "syscall_contract_smoke", "/ENTRY:main"}, - {"tests\\would_block_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "would_block_smoke", "/ENTRY:main"}, - {"tests\\cwd_peb_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "cwd_peb_smoke", "/ENTRY:main"}, - {"tests\\mmap_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "mmap_smoke", "/ENTRY:main"}, - {"tests\\pcache_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "pcache_smoke", "/ENTRY:main"}, - {"tests\\pcache_pressure", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "pcache_pressure", "/ENTRY:main"}, - {"tests\\dirty_writeback", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "dirty_writeback", "/ENTRY:main"}, - {"tests\\shared_mmap", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "shared_mmap", "/ENTRY:main"}, - {"tests\\pcache_invalidate", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "pcache_invalidate", "/ENTRY:main"}, - {"tests\\pcache_mmap_read_reuse", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "pcache_mmap_read_reuse", "/ENTRY:main"}, - {"tests\\pcache_multithread", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "pcache_multithread", "/ENTRY:main"}, - {"tests\\surface_smoke", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "surface_smoke", "/ENTRY:main"}, - {"tests\\surface_invalid_rect", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "surface_invalid_rect", "/ENTRY:main"}, - {"tests\\surface_multithread_present", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "surface_multithread_present", "/ENTRY:main"}, - {"apps\\edit", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "edit", "/ENTRY:main"}, - {"apps\\httpget", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "httpget", "/ENTRY:main"}, - {"apps\\tcpserve", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "tcpserve", "/ENTRY:main"}, - {"apps\\udp", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "udp", "/ENTRY:main"}, - {"apps\\resolve", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "resolve", "/ENTRY:main"}, - {"apps\\ping", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "ping", "/ENTRY:main"}, - {"apps\\doom", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "doom", "/ENTRY:main"}, - {"apps\\video", "bin\\syscall.lib obj\\libc.obj code\\user\\apps\\video\\bink2w64.lib", "video", "/ENTRY:main"}, - {"apps\\memtop", "bin\\syscall.lib obj\\libc.obj obj\\runtime\\user_heap.obj obj\\runtime\\user_heap_exports.obj", "memtop", "/ENTRY:main"} + {"system\\init", NATIVE_INIT_LIBS_LITERAL, "init", "/ENTRY:_start"}, + {"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}, + {"tests\\async_apc", NATIVE_EXE_LIBS_LITERAL, "async_apc", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\apc_return_smoke", NATIVE_EXE_LIBS_LITERAL, "apc_return_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\async_cancel", NATIVE_EXE_LIBS_LITERAL, "async_cancel", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\file_stat_smoke", NATIVE_EXE_LIBS_LITERAL, "file_stat_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\handle_dup_smoke", NATIVE_EXE_LIBS_LITERAL, "handle_dup_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\named_queue_lifetime_smoke", NATIVE_EXE_LIBS_LITERAL, "named_queue_lifetime_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\input_api_smoke", NATIVE_EXE_LIBS_LITERAL, "input_api_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\input_model_smoke", NATIVE_EXE_LIBS_LITERAL, "input_model_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\timer_smoke", NATIVE_EXE_LIBS_LITERAL, "timer_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\stats_abi_smoke", NATIVE_EXE_LIBS_LITERAL, "stats_abi_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\realpath_smoke", NATIVE_EXE_LIBS_LITERAL, "realpath_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\file_lock_smoke", NATIVE_EXE_LIBS_LITERAL, "file_lock_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\process_protection_smoke", NATIVE_EXE_LIBS_LITERAL, "process_protection_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\socket_addr_smoke", NATIVE_EXE_LIBS_LITERAL, "socket_addr_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\net_irp_smoke", NATIVE_EXE_LIBS_LITERAL, "net_irp_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\module_load_smoke", NATIVE_EXE_LIBS_LITERAL, "module_load_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\posix_module_smoke", POSIX_EXE_LIBS_LITERAL, "posix_module_smoke", "/ENTRY:PosixStart"}, + {"tests\\exception_dispatcher_smoke", NATIVE_EXE_LIBS_LITERAL, "exception_dispatcher_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\native_exception_runtime_smoke", NATIVE_EXE_LIBS_LITERAL, "native_exception_runtime_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\native_raise_exception_smoke", NATIVE_EXE_LIBS_LITERAL, "native_raise_exception_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\exception_smoke", NATIVE_EXE_LIBS_LITERAL, "exception_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\win32_exception_smoke", WIN32_EXE_LIBS_LITERAL, "win32_exception_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\win32_seh_smoke", WIN32_EXE_LIBS_LITERAL, "win32_seh_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\syscall_contract_smoke", NATIVE_EXE_LIBS_LITERAL, "syscall_contract_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\would_block_smoke", NATIVE_EXE_LIBS_LITERAL, "would_block_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\cwd_peb_smoke", NATIVE_EXE_LIBS_LITERAL, "cwd_peb_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\mmap_smoke", NATIVE_EXE_LIBS_LITERAL, "mmap_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\pcache_smoke", NATIVE_EXE_LIBS_LITERAL, "pcache_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\pcache_pressure", NATIVE_EXE_LIBS_LITERAL, "pcache_pressure", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\dirty_writeback", NATIVE_EXE_LIBS_LITERAL, "dirty_writeback", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\shared_mmap", NATIVE_EXE_LIBS_LITERAL, "shared_mmap", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\pcache_invalidate", NATIVE_EXE_LIBS_LITERAL, "pcache_invalidate", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\pcache_mmap_read_reuse", NATIVE_EXE_LIBS_LITERAL, "pcache_mmap_read_reuse", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\pcache_multithread", NATIVE_EXE_LIBS_LITERAL, "pcache_multithread", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\surface_smoke", NATIVE_EXE_LIBS_LITERAL, "surface_smoke", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\surface_invalid_rect", NATIVE_EXE_LIBS_LITERAL, "surface_invalid_rect", NATIVE_EXE_ENTRY_LITERAL}, + {"tests\\surface_multithread_present", NATIVE_EXE_LIBS_LITERAL, "surface_multithread_present", NATIVE_EXE_ENTRY_LITERAL}, + {"apps\\edit", NATIVE_EXE_LIBS_LITERAL, "edit", NATIVE_EXE_ENTRY_LITERAL}, + {"apps\\httpget", NATIVE_EXE_LIBS_LITERAL, "httpget", NATIVE_EXE_ENTRY_LITERAL}, + {"apps\\tcpserve", NATIVE_EXE_LIBS_LITERAL, "tcpserve", NATIVE_EXE_ENTRY_LITERAL}, + {"apps\\udp", NATIVE_EXE_LIBS_LITERAL, "udp", NATIVE_EXE_ENTRY_LITERAL}, + {"apps\\resolve", NATIVE_EXE_LIBS_LITERAL, "resolve", NATIVE_EXE_ENTRY_LITERAL}, + {"apps\\ping", NATIVE_EXE_LIBS_LITERAL, "ping", NATIVE_EXE_ENTRY_LITERAL}, + {"apps\\doom", NATIVE_EXE_LIBS_LITERAL, "doom", NATIVE_EXE_ENTRY_LITERAL}, + {"apps\\video", "bin\\syscall.lib obj\\libc.obj " NATIVE_RUNTIME_OBJS_LITERAL " code\\user\\apps\\video\\bink2w64.lib", "video", NATIVE_EXE_ENTRY_LITERAL}, + {"apps\\memtop", NATIVE_EXE_LIBS_LITERAL, "memtop", NATIVE_EXE_ENTRY_LITERAL} }; for (size_t i = 0; i < NOB_ARRAY_LEN(apps); i++) { @@ -339,6 +355,7 @@ int main(int argc, char **argv) { {"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"}, @@ -350,6 +367,12 @@ int main(int argc, char **argv) { {"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"}, diff --git a/code/drivers/bus/pci/pci.c b/code/drivers/bus/pci/pci.c index 8ecc854..77d6212 100644 --- a/code/drivers/bus/pci/pci.c +++ b/code/drivers/bus/pci/pci.c @@ -44,18 +44,18 @@ static uint64_t PciDefaultMmioFlags(void) { // Creates mmio Va. static KSTATUS PciAllocateMmioVa(uint64_t length, uintptr_t* outVa) { if (!outVa || !length) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint64_t alignedLength = PciAlignUp64(length, PAGE_SIZE); uintptr_t va = (uintptr_t)PciAlignUp64((uint64_t)gPciMmioNext, PAGE_SIZE); if (va < PCI_MMIO_VA_BASE || va >= PCI_MMIO_VA_LIMIT) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; if (alignedLength > (uint64_t)(PCI_MMIO_VA_LIMIT - va)) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; gPciMmioNext = va + (uintptr_t)alignedLength; *outVa = va; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Checks whether pdo. @@ -332,7 +332,7 @@ static KSTATUS PciCreatePdo(uint8_t bus, uint8_t dev, uint8_t fn) { uint32_t id = PciRawRead32(bus, dev, fn, PCI_REG_VENDOR_DEVICE); uint16_t vendor = (uint16_t)(id & 0xFFFFu); if (vendor == PCI_VENDOR_INVALID) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; uint32_t classReg = PciRawRead32(bus, dev, fn, PCI_REG_REVISION_CLASS); uint32_t hdrReg = PciRawRead32(bus, dev, fn, PCI_REG_HEADER_TYPE); @@ -399,7 +399,7 @@ static KSTATUS PciCreatePdo(uint8_t bus, uint8_t dev, uint8_t fn) { info.Subclass, info.ProgIf, info.InterruptLine); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the enumerate Bus operation. @@ -415,7 +415,7 @@ static void PciEnumerateBus(void) { for (uint8_t fn = 0; fn < fnLimit; fn++) { KSTATUS st = PciCreatePdo((uint8_t)bus, (uint8_t)dev, fn); - if (!KSUCCESS(st) && st != STATUS_NOT_FOUND) { + if (!KSUCCESS(st) && st != NTLSTATUS_NOT_FOUND) { DbgPrint("pci: failed to create PDO for %02x:%02x.%u st=0x%x\n", bus, dev, fn, st); } @@ -426,21 +426,21 @@ static void PciEnumerateBus(void) { // Dispatches pnp. static KSTATUS PciDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { - if (!device || !irp) return STATUS_INVALID_PARAMETER; + if (!device || !irp) return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); - if (!ios || ios->MajorFunction != IRP_MJ_PNP) return STATUS_INVALID_PARAMETER; + if (!ios || ios->MajorFunction != IRP_MJ_PNP) return NTLSTATUS_INVALID_PARAMETER; switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) { case IRP_MN_START_DEVICE: device->PnpState = DevicePnpStarted; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE: case IRP_MN_SURPRISE_REMOVAL: case IRP_MN_REMOVE_DEVICE: - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; default: - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } } @@ -452,81 +452,81 @@ __declspec(dllexport) uint32_t PciDriverAbiVersion(void) { // Returns device Info. __declspec(dllexport) KSTATUS PciGetDeviceInfo(DEVICE_OBJECT* pdo, PCI_DEVICE_INFO* outInfo) { PCI_PDO_EXTENSION* ext; - if (!outInfo || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER; + if (!outInfo || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER; *outInfo = ext->Info; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns config8. __declspec(dllexport) KSTATUS PciReadConfig8(DEVICE_OBJECT* pdo, uint16_t offset, uint8_t* outValue) { PCI_PDO_EXTENSION* ext; - if (!outValue || offset > 0xFFu || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER; + if (!outValue || offset > 0xFFu || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER; *outValue = PciRawRead8(ext->Info.Address.Bus, ext->Info.Address.Device, ext->Info.Address.Function, offset); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns config16. __declspec(dllexport) KSTATUS PciReadConfig16(DEVICE_OBJECT* pdo, uint16_t offset, uint16_t* outValue) { PCI_PDO_EXTENSION* ext; - if (!outValue || offset > 0xFEu || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER; + if (!outValue || offset > 0xFEu || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER; *outValue = PciRawRead16(ext->Info.Address.Bus, ext->Info.Address.Device, ext->Info.Address.Function, offset); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns config32. __declspec(dllexport) KSTATUS PciReadConfig32(DEVICE_OBJECT* pdo, uint16_t offset, uint32_t* outValue) { PCI_PDO_EXTENSION* ext; - if (!outValue || offset > 0xFCu || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER; + if (!outValue || offset > 0xFCu || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER; *outValue = PciRawRead32(ext->Info.Address.Bus, ext->Info.Address.Device, ext->Info.Address.Function, offset); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Updates config8. __declspec(dllexport) KSTATUS PciWriteConfig8(DEVICE_OBJECT* pdo, uint16_t offset, uint8_t value) { PCI_PDO_EXTENSION* ext; - if (offset > 0xFFu || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER; + if (offset > 0xFFu || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER; PciRawWrite8(ext->Info.Address.Bus, ext->Info.Address.Device, ext->Info.Address.Function, offset, value); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Updates config16. __declspec(dllexport) KSTATUS PciWriteConfig16(DEVICE_OBJECT* pdo, uint16_t offset, uint16_t value) { PCI_PDO_EXTENSION* ext; - if (offset > 0xFEu || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER; + if (offset > 0xFEu || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER; PciRawWrite16(ext->Info.Address.Bus, ext->Info.Address.Device, ext->Info.Address.Function, offset, value); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Updates config32. __declspec(dllexport) KSTATUS PciWriteConfig32(DEVICE_OBJECT* pdo, uint16_t offset, uint32_t value) { PCI_PDO_EXTENSION* ext; - if (offset > 0xFCu || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER; + if (offset > 0xFCu || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER; PciRawWrite32(ext->Info.Address.Bus, ext->Info.Address.Device, ext->Info.Address.Function, offset, value); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns bar. __declspec(dllexport) KSTATUS PciGetBar(DEVICE_OBJECT* pdo, uint8_t index, PCI_BAR* outBar) { PCI_PDO_EXTENSION* ext; - if (!outBar || index >= PCI_MAX_BARS || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER; - if (ext->Bars[index].Type == PciBarUnused) return STATUS_NOT_FOUND; + if (!outBar || index >= PCI_MAX_BARS || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER; + if (ext->Bars[index].Type == PciBarUnused) return NTLSTATUS_NOT_FOUND; *outBar = ext->Bars[index]; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Maps a PCI BAR through the private MMIO aperture with explicit cache attributes. __declspec(dllexport) KSTATUS PciMapBar(DEVICE_OBJECT* pdo, uint8_t index, uint64_t pageFlags, void** outVirtual, uint64_t* outLength) { PCI_BAR bar; - if (!outVirtual) return STATUS_INVALID_PARAMETER; + if (!outVirtual) return NTLSTATUS_INVALID_PARAMETER; *outVirtual = NULL; KSTATUS st = PciGetBar(pdo, index, &bar); if (!KSUCCESS(st)) return st; if (bar.Type != PciBarMemory32 && bar.Type != PciBarMemory64) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (!bar.Length) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; if (bar.Base + bar.Length < bar.Base) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint64_t flags = pageFlags ? pageFlags : PciDefaultMmioFlags(); flags |= PAGE_PRESENT; @@ -548,13 +548,13 @@ __declspec(dllexport) KSTATUS PciMapBar(DEVICE_OBJECT* pdo, uint8_t index, uint6 *outVirtual = (void*)(virtBase + (uintptr_t)physOffset); if (outLength) *outLength = bar.Length; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Enables device. __declspec(dllexport) KSTATUS PciEnableDevice(DEVICE_OBJECT* pdo, uint32_t flags) { PCI_PDO_EXTENSION* ext; - if (!PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER; + if (!PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER; uint16_t cmd = PciRawRead16(ext->Info.Address.Bus, ext->Info.Address.Device, @@ -571,16 +571,16 @@ __declspec(dllexport) KSTATUS PciEnableDevice(DEVICE_OBJECT* pdo, uint32_t flags ext->Info.Address.Function, PCI_REG_COMMAND_STATUS, cmd); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns interrupt. __declspec(dllexport) KSTATUS PciGetInterrupt(DEVICE_OBJECT* pdo, uint8_t* outIrq) { PCI_PDO_EXTENSION* ext; - if (!outIrq || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER; - if (ext->Info.InterruptLine == 0xFFu) return STATUS_NOT_FOUND; + if (!outIrq || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER; + if (ext->Info.InterruptLine == 0xFFu) return NTLSTATUS_NOT_FOUND; *outIrq = ext->Info.InterruptLine; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns capability. @@ -608,20 +608,20 @@ static uint8_t PciFindCapability(PCI_PDO_EXTENSION* ext, uint8_t capId) { __declspec(dllexport) KSTATUS PciEnableMsi(DEVICE_OBJECT* pdo, uint8_t irqSlot) { PCI_PDO_EXTENSION* ext; if (!PciIsPdo(pdo, &ext)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (irqSlot >= 24u) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint8_t cap = PciFindCapability(ext, PCI_CAP_ID_MSI); if (!cap) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; uint32_t bspLapic = HalGetBspLapicId(); if (!HalApicUsingX2Apic() && bspLapic >= 256u) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (HalApicUsingX2Apic() && bspLapic >= 256u) { // Extended x2APIC MSI destinations need interrupt-remapping awareness. - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } uint8_t bus = ext->Info.Address.Bus; @@ -657,17 +657,17 @@ __declspec(dllexport) KSTATUS PciEnableMsi(DEVICE_OBJECT* pdo, uint8_t irqSlot) DbgPrint("pci: MSI enabled %02x:%02x.%u cap=0x%02x vector=0x%02x irqslot=%u dest=%u %s\n", bus, dev, fn, cap, vector, irqSlot, bspLapic, is64 ? "64-bit" : "32-bit"); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Enables a single MSI vector, allocating the nt-lite IRQ slot internally. __declspec(dllexport) KSTATUS PciEnableMsiAuto(DEVICE_OBJECT* pdo, uint8_t* outIrqSlot) { PCI_PDO_EXTENSION* ext; if (!outIrqSlot || !PciIsPdo(pdo, &ext)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!PciFindCapability(ext, PCI_CAP_ID_MSI)) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; uint8_t irq = 0xFFu; KSTATUS st = KeIrqAllocateMsiVector(&irq); @@ -679,12 +679,12 @@ __declspec(dllexport) KSTATUS PciEnableMsiAuto(DEVICE_OBJECT* pdo, uint8_t* outI return st; *outIrqSlot = irq; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the driver Entry operation. KSTATUS DriverEntry(const HAL_API* hal) { - if (!hal) return STATUS_INVALID_PARAMETER; + if (!hal) return NTLSTATUS_INVALID_PARAMETER; gHal = hal; gPciDeviceCount = 0; @@ -697,5 +697,5 @@ KSTATUS DriverEntry(const HAL_API* hal) { DbgPrint("pci: DriverEntry ABI=%u\n", PciDriverAbiVersion()); PciEnumerateBus(); DbgPrint("pci: enumeration complete, devices=%u\n", gPciDeviceCount); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } diff --git a/code/drivers/bus/usb/usb.c b/code/drivers/bus/usb/usb.c index a81fd37..db79df4 100644 --- a/code/drivers/bus/usb/usb.c +++ b/code/drivers/bus/usb/usb.c @@ -36,7 +36,7 @@ static KSTATUS UsbInitializeXhciDriver(void) { // Implements the driver Entry operation. KSTATUS DriverEntry(const HAL_API* hal) { - if (!hal) return STATUS_INVALID_PARAMETER; + if (!hal) return NTLSTATUS_INVALID_PARAMETER; DbgPrint("usb: driver loading\n"); gUsbHal = hal; @@ -77,5 +77,5 @@ KSTATUS DriverEntry(const HAL_API* hal) { } DbgPrint("usb: driver initialized\n"); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } diff --git a/code/drivers/bus/usb/usb_bus.c b/code/drivers/bus/usb/usb_bus.c index bd22e27..617736b 100644 --- a/code/drivers/bus/usb/usb_bus.c +++ b/code/drivers/bus/usb/usb_bus.c @@ -81,10 +81,10 @@ KSTATUS UsbCreatePipe(USB_DEVICE* dev, uint16_t maxPacketSize, uint8_t interval, USB_PIPE** outPipe) { - if (!dev || !outPipe) return STATUS_INVALID_PARAMETER; + if (!dev || !outPipe) return NTLSTATUS_INVALID_PARAMETER; USB_PIPE* pipe = (USB_PIPE*)ObAllocateObject(ObjectTypeUsbPipe, sizeof(USB_PIPE)); - if (!pipe) return STATUS_NO_MEMORY; + if (!pipe) return NTLSTATUS_NO_MEMORY; pipe->Header.Destroy = UsbPipeDestroy; pipe->Device = dev; UsbReferenceDevice(dev); @@ -95,7 +95,7 @@ KSTATUS UsbCreatePipe(USB_DEVICE* dev, pipe->Interval = interval; pipe->Open = true; *outPipe = pipe; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the id From Buffer operation. @@ -255,7 +255,7 @@ static void UsbMakeInterfaceIds(const XHCI_DEVICE* xdev, // Initializes bus Model. KSTATUS UsbInitializeBusModel(void) { if (gUsbBusModelReady) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; memset(&gUsbBusDriver, 0, sizeof(gUsbBusDriver)); IoInitializeDriverObject(&gUsbBusDriver, SYS_SV_LITERAL("usb-bus")); @@ -266,7 +266,7 @@ KSTATUS UsbInitializeBusModel(void) { if (!KSUCCESS(st)) return st; gUsbBusModelReady = true; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } void UsbInitializeHcd(USB_HCD* hcd, @@ -285,8 +285,8 @@ void UsbInitializeHcd(USB_HCD* hcd, // Creates root Hub Pdo. KSTATUS UsbCreateRootHubPdo(USB_HCD* hcd) { - if (!hcd) return STATUS_INVALID_PARAMETER; - if (hcd->RootHubPdo) return STATUS_ALREADY_EXISTS; + if (!hcd) return NTLSTATUS_INVALID_PARAMETER; + if (hcd->RootHubPdo) return NTLSTATUS_ALREADY_EXISTS; IO_DEVICE_ID ids[2]; char idbuf[2][USB_MAX_DEVICE_ID_TEXT]; @@ -312,20 +312,20 @@ KSTATUS UsbCreateRootHubPdo(USB_HCD* hcd) { hcd->RootHubPdo = pdo; st = IoRegisterPhysicalDevice(pdo); - if (!KSUCCESS(st) && st != STATUS_ALREADY_EXISTS) + if (!KSUCCESS(st) && st != NTLSTATUS_ALREADY_EXISTS) return st; DbgPrint("usb: created root hub PDO ports=%u\n", hcd->MaxRootPorts); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Creates device Pdo. KSTATUS UsbCreateDevicePdo(USB_HCD* hcd, XHCI_DEVICE* xdev, DEVICE_OBJECT* parent) { - if (!hcd || !xdev) return STATUS_INVALID_PARAMETER; - if (xdev->UsbPdo) return STATUS_ALREADY_EXISTS; + if (!hcd || !xdev) return NTLSTATUS_INVALID_PARAMETER; + if (xdev->UsbPdo) return NTLSTATUS_ALREADY_EXISTS; USB_DEVICE* udev = UsbAllocateDevice(); - if (!udev) return STATUS_NO_MEMORY; + if (!udev) return NTLSTATUS_NO_MEMORY; udev->Hcd = hcd; udev->HcdDeviceContext = xdev; @@ -379,19 +379,19 @@ KSTATUS UsbCreateDevicePdo(USB_HCD* hcd, XHCI_DEVICE* xdev, DEVICE_OBJECT* paren xdev->UsbPdo = pdo; st = IoRegisterPhysicalDevice(pdo); - if (!KSUCCESS(st) && st != STATUS_ALREADY_EXISTS) + if (!KSUCCESS(st) && st != NTLSTATUS_ALREADY_EXISTS) return st; DbgPrint("usb: created device PDO slot=%u vid=%04x pid=%04x ids=%llu\n", xdev->SlotId, xdev->VendorId, xdev->ProductId, (unsigned long long)idCount); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Creates interface Pdos. KSTATUS UsbCreateInterfacePdos(USB_HCD* hcd, XHCI_DEVICE* xdev, DEVICE_OBJECT* parent) { - if (!hcd || !xdev || !xdev->UsbDevice) return STATUS_INVALID_PARAMETER; + if (!hcd || !xdev || !xdev->UsbDevice) return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* deviceParent = parent ? parent : xdev->UsbPdo; - if (!deviceParent) return STATUS_INVALID_PARAMETER; + if (!deviceParent) return NTLSTATUS_INVALID_PARAMETER; for (uint8_t i = 0; i < xdev->InterfaceCount; i++) { USB_TRACKED_INTERFACE* iface = &xdev->Interfaces[i]; @@ -428,7 +428,7 @@ KSTATUS UsbCreateInterfacePdos(USB_HCD* hcd, XHCI_DEVICE* xdev, DEVICE_OBJECT* p memcpy(&ext->Endpoints[ep], &iface->Endpoints[ep], sizeof(USB_ENDPOINT_DESCRIPTOR)); st = IoRegisterPhysicalDevice(pdo); - if (!KSUCCESS(st) && st != STATUS_ALREADY_EXISTS) + if (!KSUCCESS(st) && st != NTLSTATUS_ALREADY_EXISTS) return st; DbgPrint("usb: created interface PDO slot=%u if=%u class=%02x subclass=%02x proto=%02x\n", @@ -438,7 +438,7 @@ KSTATUS UsbCreateInterfacePdos(USB_HCD* hcd, XHCI_DEVICE* xdev, DEVICE_OBJECT* p iface->Descriptor.bInterfaceSubClass, iface->Descriptor.bInterfaceProtocol); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the reference First Child operation. @@ -462,7 +462,7 @@ static void UsbSendPnpIfAlive(DEVICE_OBJECT* pdo, IO_PNP_MINOR_FUNCTION minor) { // Releases device Object Children. KSTATUS UsbRemoveDeviceObjectChildren(DEVICE_OBJECT* parent, bool surprise) { if (!parent) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; for (;;) { DEVICE_OBJECT* child = UsbReferenceFirstChild(parent); @@ -476,13 +476,13 @@ KSTATUS UsbRemoveDeviceObjectChildren(DEVICE_OBJECT* parent, bool surprise) { IoDereferenceDeviceObject(child); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Releases pdo Subtree. KSTATUS UsbRemovePdoSubtree(DEVICE_OBJECT* pdo, bool surprise) { if (!pdo || pdo->Type != DeviceObjectPhysical) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; // Child PDOs may be owned either directly by the PDO or by an attached FDO // such as usb-composite or usb-hub. The attached driver's PnP handler is @@ -494,20 +494,20 @@ KSTATUS UsbRemovePdoSubtree(DEVICE_OBJECT* pdo, bool surprise) { UsbSendPnpIfAlive(pdo, IRP_MN_SURPRISE_REMOVAL); UsbSendPnpIfAlive(pdo, IRP_MN_REMOVE_DEVICE); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Submits urb To Hcd. static KSTATUS UsbSubmitUrbToHcd(USB_PDO_EXTENSION* ext, USB_URB* urb) { - if (!ext || !urb) return STATUS_INVALID_PARAMETER; + if (!ext || !urb) return NTLSTATUS_INVALID_PARAMETER; USB_HCD* hcd = ext->Hcd; if (!hcd || !hcd->Operations || !hcd->Operations->SubmitUrb) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (!urb->Device) urb->Device = ext->Device; if (!urb->Device) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; return hcd->Operations->SubmitUrb(hcd, urb); } @@ -515,16 +515,16 @@ static KSTATUS UsbSubmitUrbToHcd(USB_PDO_EXTENSION* ext, USB_URB* urb) { // Cancels urb. KSTATUS UsbCancelUrb(USB_URB* urb) { if (!urb || !urb->Device || !urb->Device->Hcd) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_HCD* hcd = urb->Device->Hcd; if (!hcd->Operations || !hcd->Operations->CancelUrb) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; return hcd->Operations->CancelUrb(hcd, urb); } // Submits urb Sync. KSTATUS UsbSubmitUrbSync(DEVICE_OBJECT* target, USB_URB* urb) { - if (!target || !urb) return STATUS_INVALID_PARAMETER; + if (!target || !urb) return NTLSTATUS_INVALID_PARAMETER; IRP irp; IoInitializeIrp(&irp, 1); @@ -547,7 +547,7 @@ static void UsbAsyncUrbIrpComplete(IRP* irp, void* context) { // Submits urb Async. KSTATUS UsbSubmitUrbAsync(DEVICE_OBJECT* target, USB_URB* urb) { - if (!target || !urb) return STATUS_INVALID_PARAMETER; + if (!target || !urb) return NTLSTATUS_INVALID_PARAMETER; IRP* irp = (IRP*)0; KSTATUS st = IoAllocateIrp(1, &irp); @@ -563,7 +563,7 @@ KSTATUS UsbSubmitUrbAsync(DEVICE_OBJECT* target, USB_URB* urb) { IoSetCompletionRoutine(irp, UsbAsyncUrbIrpComplete, (void*)0); st = IoSubmitIrp(target, irp); - if (st != STATUS_PENDING && !(irp->Flags & IRP_FLAG_COMPLETED)) { + if (st != NTLSTATUS_PENDING && !(irp->Flags & IRP_FLAG_COMPLETED)) { IoFreeIrp(irp); return st; } @@ -572,18 +572,18 @@ KSTATUS UsbSubmitUrbAsync(DEVICE_OBJECT* target, USB_URB* urb) { // Dispatches internal Device Control. KSTATUS UsbDispatchInternalDeviceControl(DEVICE_OBJECT* device, IRP* irp) { - if (!device || !irp) return STATUS_INVALID_PARAMETER; + if (!device || !irp) return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); - if (!ios) return STATUS_INVALID_PARAMETER; + if (!ios) return NTLSTATUS_INVALID_PARAMETER; if (ios->Parameters.DeviceIoControl.IoControlCode != USB_IOCTL_SUBMIT_URB) { - IoCompleteRequest(irp, STATUS_NOT_SUPPORTED, 0); - return STATUS_PENDING; + IoCompleteRequest(irp, NTLSTATUS_NOT_SUPPORTED, 0); + return NTLSTATUS_PENDING; } if (ios->Parameters.DeviceIoControl.InputLength < sizeof(USB_URB) || !ios->Parameters.DeviceIoControl.InputBuffer) { - IoCompleteRequest(irp, STATUS_INVALID_PARAMETER, 0); - return STATUS_PENDING; + IoCompleteRequest(irp, NTLSTATUS_INVALID_PARAMETER, 0); + return NTLSTATUS_PENDING; } USB_URB* urb = (USB_URB*)ios->Parameters.DeviceIoControl.InputBuffer; @@ -592,25 +592,25 @@ KSTATUS UsbDispatchInternalDeviceControl(DEVICE_OBJECT* device, IRP* irp) { KSTATUS st = UsbSubmitUrbToHcd(ext, urb); urb->Status = st; - if (st == STATUS_PENDING) { + if (st == NTLSTATUS_PENDING) { urb->Pending = true; - return STATUS_PENDING; + return NTLSTATUS_PENDING; } urb->Pending = false; IoCompleteRequest(irp, st, KSUCCESS(st) ? urb->ActualLength : 0); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } // Dispatches pdo Pnp. KSTATUS UsbDispatchPdoPnp(DEVICE_OBJECT* device, IRP* irp) { - if (!device || !irp) return STATUS_INVALID_PARAMETER; + if (!device || !irp) return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios || ios->MajorFunction != IRP_MJ_PNP) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_PDO_EXTENSION* ext = (USB_PDO_EXTENSION*)device->DeviceExtension; - KSTATUS st = STATUS_SUCCESS; + KSTATUS st = NTLSTATUS_SUCCESS; switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) { case IRP_MN_START_DEVICE: @@ -636,12 +636,12 @@ KSTATUS UsbDispatchPdoPnp(DEVICE_OBJECT* device, IRP* irp) { IoDeleteDevice(device); break; default: - st = STATUS_NOT_SUPPORTED; + st = NTLSTATUS_NOT_SUPPORTED; break; } - if (st == STATUS_NOT_SUPPORTED) + if (st == NTLSTATUS_NOT_SUPPORTED) return st; IoCompleteRequest(irp, st, 0); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } diff --git a/code/drivers/bus/usb/usb_composite.c b/code/drivers/bus/usb/usb_composite.c index f63d256..cad8bbb 100644 --- a/code/drivers/bus/usb/usb_composite.c +++ b/code/drivers/bus/usb/usb_composite.c @@ -16,11 +16,11 @@ static const IO_DRIVER_ID_TABLE gUsbCompositeIdTable = { // Implements the composite Create Interfaces operation. static KSTATUS UsbCompositeCreateInterfaces(USB_COMPOSITE_EXTENSION* ext) { if (!ext || !ext->Device || ext->InterfacesCreated) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; XHCI_DEVICE* xdev = (XHCI_DEVICE*)ext->Device->HcdDeviceContext; if (!xdev) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS st = UsbCreateInterfacePdos(ext->Device->Hcd, xdev, ext->Self); if (KSUCCESS(st)) @@ -32,7 +32,7 @@ static KSTATUS UsbCompositeCreateInterfaces(USB_COMPOSITE_EXTENSION* ext) { static KSTATUS UsbCompositeForwardPnp(DEVICE_OBJECT* device, IRP* irp, KSTATUS localStatus) { if (!KSUCCESS(localStatus)) { IoCompleteRequest(irp, localStatus, 0); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } return IoForwardIrpToLower(device, irp); } @@ -40,7 +40,7 @@ static KSTATUS UsbCompositeForwardPnp(DEVICE_OBJECT* device, IRP* irp, KSTATUS l // Implements the composite Dispatch Pnp operation. KSTATUS UsbCompositeDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { if (!device || !irp) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; // The composite driver owns two different device-object roles: // * an FDO attached above a USB device PDO, and @@ -53,10 +53,10 @@ KSTATUS UsbCompositeDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios || ios->MajorFunction != IRP_MJ_PNP) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_COMPOSITE_EXTENSION* ext = (USB_COMPOSITE_EXTENSION*)device->DeviceExtension; - KSTATUS st = STATUS_SUCCESS; + KSTATUS st = NTLSTATUS_SUCCESS; switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) { case IRP_MN_START_DEVICE: @@ -94,20 +94,20 @@ KSTATUS UsbCompositeDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { IoDetachDevice(device); ext->LowerDevice = (DEVICE_OBJECT*)0; IoDeleteDevice(device); - if (lower == STATUS_NOT_SUPPORTED) { - IoCompleteRequest(irp, STATUS_SUCCESS, 0); - return STATUS_PENDING; + if (lower == NTLSTATUS_NOT_SUPPORTED) { + IoCompleteRequest(irp, NTLSTATUS_SUCCESS, 0); + return NTLSTATUS_PENDING; } - if (lower != STATUS_PENDING && !KSUCCESS(lower)) { + if (lower != NTLSTATUS_PENDING && !KSUCCESS(lower)) { IoCompleteRequest(irp, lower, 0); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } return lower; } } IoDeleteDevice(device); - IoCompleteRequest(irp, STATUS_SUCCESS, 0); - return STATUS_PENDING; + IoCompleteRequest(irp, NTLSTATUS_SUCCESS, 0); + return NTLSTATUS_PENDING; default: return IoForwardIrpToLower(device, irp); @@ -117,11 +117,11 @@ KSTATUS UsbCompositeDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { // Implements the composite Add Device operation. KSTATUS UsbCompositeAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) { if (!driver || !physicalDeviceObject || physicalDeviceObject->Type != DeviceObjectPhysical) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_PDO_EXTENSION* pdoExt = (USB_PDO_EXTENSION*)physicalDeviceObject->DeviceExtension; if (!pdoExt || pdoExt->Kind != UsbPdoDevice || !pdoExt->Device) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* fdo = (DEVICE_OBJECT*)0; KSTATUS st = IoCreateDevice(driver, sizeof(USB_COMPOSITE_EXTENSION), &fdo); @@ -137,11 +137,11 @@ KSTATUS UsbCompositeAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDevi ext->LowerDevice = IoAttachDeviceToDeviceStack(fdo, physicalDeviceObject); if (!ext->LowerDevice) { IoDeleteDevice(fdo); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } DbgPrint("usb: composite attached slot=%u\n", ext->Device->SlotId); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Initializes composite Driver. diff --git a/code/drivers/bus/usb/usb_core.c b/code/drivers/bus/usb/usb_core.c index 429f6bc..fb0e562 100644 --- a/code/drivers/bus/usb/usb_core.c +++ b/code/drivers/bus/usb/usb_core.c @@ -22,7 +22,7 @@ KSTATUS XhciSetConfiguration(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, dev->Configured = true; UsbTrace("usb: SET_CONFIGURATION slot=%u value=%u complete\n", dev->SlotId, configurationValue); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns tracked Interface By Number. @@ -214,7 +214,7 @@ KSTATUS XhciDiscoverAndSetConfiguration(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, const USB_DEVICE_DESCRIPTOR* devDesc) { if (devDesc->bNumConfigurations == 0) { DbgPrint("usb: slot=%u has no configurations\n", dev->SlotId); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } USB_CONFIGURATION_DESCRIPTOR config; @@ -232,7 +232,7 @@ KSTATUS XhciDiscoverAndSetConfiguration(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, if (config.bConfigurationValue == 0) { DbgPrint("usb: slot=%u configuration value 0 is invalid for SET_CONFIGURATION\n", dev->SlotId); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } st = XhciSetConfiguration(xhci, dev, config.bConfigurationValue); @@ -248,7 +248,7 @@ KSTATUS XhciDiscoverAndSetConfiguration(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, } } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the rollback Enumerated Slot operation. @@ -283,7 +283,7 @@ static KSTATUS XhciEnumeratePathEx(XHCI_CONTROLLER* xhci, uint8_t* outSlotId) { if (outSlotId) *outSlotId = 0; if (!xhci || !path || path->RootPort == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint8_t slotId = 0; KSTATUS st = XhciEnableSlot(xhci, &slotId); @@ -372,7 +372,7 @@ static KSTATUS XhciEnumeratePathEx(XHCI_CONTROLLER* xhci, } if (outSlotId) *outSlotId = slotId; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the enumerate Port Ex operation. @@ -401,18 +401,18 @@ KSTATUS XhciEnumerateHubPortEx(XHCI_CONTROLLER* xhci, uint8_t* outSlotId) { if (outSlotId) *outSlotId = 0; if (!xhci || !hub || !hub->Device || !hub->Self || hubPort == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_DEVICE* parent = hub->Device; if (parent->Path.Depth >= 5u) { DbgPrint("usb-hub: hub slot=%u port=%u exceeds xHCI route depth\n", parent->SlotId, hubPort); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } if (hubPort > 15u) { DbgPrint("usb-hub: hub slot=%u port=%u cannot be represented in xHCI route string yet\n", parent->SlotId, hubPort); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } USB_PORT_PATH path = parent->Path; diff --git a/code/drivers/bus/usb/usb_hid.c b/code/drivers/bus/usb/usb_hid.c index b8d050c..37bb02f 100644 --- a/code/drivers/bus/usb/usb_hid.c +++ b/code/drivers/bus/usb/usb_hid.c @@ -87,7 +87,7 @@ void XhciProcessBootMouseReport(XHCI_DEVICE* dev, const uint8_t* report, uint16_ // Implements the arm Hid Interrupt In operation. KSTATUS XhciArmHidInterruptIn(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) { if (!dev->HidActive || dev->HidArmed || !dev->HidRing || !dev->HidBuffer) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; memset(dev->HidBuffer, 0, dev->HidReportLength); @@ -109,7 +109,7 @@ KSTATUS XhciArmHidInterruptIn(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) { dev->HidArmed = true; XhciBarrier(); XhciWrite32(xhci->Doorbells, (uint32_t)dev->SlotId * 4u, dev->HidEndpointId); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the arm All Hid operation. @@ -159,10 +159,10 @@ static void XhciHandleLegacyHidTransferEvent(XHCI_CONTROLLER* xhci, uint64_t trb // Starts hid Interrupts. KSTATUS XhciStartHidInterrupts(XHCI_CONTROLLER* xhci) { if (!xhci || xhci->HidDeviceCount == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; DbgPrint("usb: HID interrupt URBs active devices=%u\n", xhci->HidDeviceCount); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Updates hid Boot Protocol. @@ -193,17 +193,17 @@ KSTATUS XhciSetHidBootProtocol(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) { DbgPrint("usb: HID boot protocol selected slot=%u if=%u proto=%u\n", dev->SlotId, dev->HidInterface, dev->HidProtocol); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Creates hid Memory. KSTATUS XhciAllocateHidMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) { - if (dev->HidRing && dev->HidBuffer) return STATUS_SUCCESS; + if (dev->HidRing && dev->HidBuffer) return NTLSTATUS_SUCCESS; dev->HidRing = (XHCI_TRB*)UsbDmaAllocPages(xhci, 1, &dev->HidRingPhys); dev->HidBuffer = (uint8_t*)UsbDmaAllocPages(xhci, 1, &dev->HidBufferPhys); if (!dev->HidRing || !dev->HidBuffer) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; dev->HidEnqueue = 0; dev->HidCycle = 1; @@ -219,20 +219,20 @@ KSTATUS XhciAllocateHidMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) { memset(dev->HidLastKeys, 0, sizeof(dev->HidLastKeys)); dev->HidLastModifiers = 0; dev->HidLastButtons = 0; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the configure Hid Endpoint operation. KSTATUS XhciConfigureHidEndpoint(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) { if (!dev->HidCandidate) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; KSTATUS st = XhciAllocateHidMemory(xhci, dev); if (!KSUCCESS(st)) return st; uint8_t dci = dev->HidEndpointId; if (dci < 2 || dci > 31) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; memset(dev->InputContext, 0, PAGE_SIZE); uint32_t* icc = XhciInputControlContext(xhci, dev); @@ -294,7 +294,7 @@ KSTATUS XhciConfigureHidEndpoint(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) { maxPacket, dev->HidInterval, inputId); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // PDO/FDO boot HID function driver path. @@ -436,7 +436,7 @@ static void UsbHidInterruptComplete(USB_URB* urb, void* context) { UsbHidProcessQemuTabletReport(ext, ext->ReportBuffer, length); else if (ext->Mouse) UsbHidProcessBootMouseReport(ext, ext->ReportBuffer, length); - } else if (urb->Status != STATUS_CANCELLED) { + } else if (urb->Status != NTLSTATUS_CANCELLED) { DbgPrint("usb: HID interrupt URB failed slot=%u if=%u ep=%02x st=0x%x cc=%u actual=%u/%u\n", ext->Device ? ext->Device->SlotId : 0, ext->InterfaceNumber, @@ -454,7 +454,7 @@ static void UsbHidInterruptComplete(USB_URB* urb, void* context) { // Implements the hid Send Boot Protocol operation. static KSTATUS UsbHidSendBootProtocol(USB_HID_EXTENSION* ext) { if (!ext || !ext->LowerDevice || !ext->Device) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_URB urb; memset(&urb, 0, sizeof(urb)); @@ -492,17 +492,17 @@ static KSTATUS UsbHidSendBootProtocol(USB_HID_EXTENSION* ext) { DbgPrint("usb: HID boot protocol selected slot=%u if=%u proto=%u\n", ext->Device->SlotId, ext->InterfaceNumber, ext->Protocol); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the hid Arm Interrupt operation. static KSTATUS UsbHidArmInterrupt(USB_HID_EXTENSION* ext) { if (!ext || !ext->Started || ext->SurpriseRemoved || ext->Removed) - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; if (!ext->LowerDevice || !ext->InterruptPipe || !ext->ReportBuffer || !ext->ReportBufferPhys) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (ext->InterruptPending) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; memset(ext->ReportBuffer, 0, ext->ReportLength); memset(&ext->InterruptUrb, 0, sizeof(ext->InterruptUrb)); @@ -517,31 +517,31 @@ static KSTATUS UsbHidArmInterrupt(USB_HID_EXTENSION* ext) { ext->InterruptUrb.CompleteContext = ext; KSTATUS st = UsbSubmitUrbAsync(ext->LowerDevice, &ext->InterruptUrb); - if (st != STATUS_PENDING && !KSUCCESS(st)) + if (st != NTLSTATUS_PENDING && !KSUCCESS(st)) return st; - if (ext->InterruptUrb.Status != STATUS_PENDING && ext->InterruptUrb.Status != STATUS_SUCCESS) + if (ext->InterruptUrb.Status != NTLSTATUS_PENDING && ext->InterruptUrb.Status != NTLSTATUS_SUCCESS) return ext->InterruptUrb.Status; ext->InterruptPending = true; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the hid Start Device operation. static KSTATUS UsbHidStartDevice(DEVICE_OBJECT* device, USB_HID_EXTENSION* ext) { if (!device || !ext || !ext->Device || !ext->InterfacePdo) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (ext->Started) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (ext->SurpriseRemoved || ext->Removed) - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; USB_PDO_EXTENSION* pdoExt = (USB_PDO_EXTENSION*)ext->InterfacePdo->DeviceExtension; if (!pdoExt || pdoExt->Kind != UsbPdoInterface) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; const USB_ENDPOINT_DESCRIPTOR* ep = UsbHidFindInterruptInPdo(pdoExt); if (!ep) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; ext->Keyboard = (pdoExt->InterfaceDescriptor.bInterfaceSubClass == USB_HID_SUBCLASS_BOOT && pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_KEYBOARD); @@ -567,7 +567,7 @@ static KSTATUS UsbHidStartDevice(DEVICE_OBJECT* device, USB_HID_EXTENSION* ext) ext->ReportBuffer = (uint8_t*)UsbAllocateDmaBuffer(ext->Device, 1, &ext->ReportBufferPhys); if (!ext->ReportBuffer) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; KSTATUS st = UsbCreatePipe(ext->Device, UsbPipeInterrupt, @@ -613,27 +613,27 @@ static KSTATUS UsbHidStartDevice(DEVICE_OBJECT* device, USB_HID_EXTENSION* ext) ext->MaxPacketSize, ext->Interval, ext->InputDeviceId); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the hid Dispatch Pnp operation. KSTATUS UsbHidDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { if (!device || !irp) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios || ios->MajorFunction != IRP_MJ_PNP) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_HID_EXTENSION* ext = (USB_HID_EXTENSION*)device->DeviceExtension; - KSTATUS st = STATUS_SUCCESS; + KSTATUS st = NTLSTATUS_SUCCESS; switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) { case IRP_MN_START_DEVICE: st = UsbHidStartDevice(device, ext); if (!KSUCCESS(st)) { IoCompleteRequest(irp, st, 0); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } return IoForwardIrpToLower(device, irp); @@ -680,19 +680,19 @@ KSTATUS UsbHidDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { } } - KSTATUS lower = ext && ext->LowerDevice ? IoForwardIrpToLower(device, irp) : STATUS_SUCCESS; + KSTATUS lower = ext && ext->LowerDevice ? IoForwardIrpToLower(device, irp) : NTLSTATUS_SUCCESS; if (ext && ext->LowerDevice) { IoDetachDevice(device); ext->LowerDevice = (DEVICE_OBJECT*)0; } IoDeleteDevice(device); - if (lower == STATUS_NOT_SUPPORTED) { - IoCompleteRequest(irp, STATUS_SUCCESS, 0); - return STATUS_PENDING; + if (lower == NTLSTATUS_NOT_SUPPORTED) { + IoCompleteRequest(irp, NTLSTATUS_SUCCESS, 0); + return NTLSTATUS_PENDING; } - if (lower != STATUS_PENDING && !KSUCCESS(lower)) { + if (lower != NTLSTATUS_PENDING && !KSUCCESS(lower)) { IoCompleteRequest(irp, lower, 0); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } return lower; } @@ -705,17 +705,17 @@ KSTATUS UsbHidDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { // Implements the hid Add Device operation. KSTATUS UsbHidAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) { if (!driver || !physicalDeviceObject || physicalDeviceObject->Type != DeviceObjectPhysical) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_PDO_EXTENSION* pdoExt = (USB_PDO_EXTENSION*)physicalDeviceObject->DeviceExtension; if (!pdoExt || pdoExt->Kind != UsbPdoInterface || !pdoExt->Device) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (pdoExt->InterfaceDescriptor.bInterfaceClass != USB_CLASS_HID) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; const USB_ENDPOINT_DESCRIPTOR* ep = UsbHidFindInterruptInPdo(pdoExt); if (!ep) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; bool bootKeyboard = pdoExt->InterfaceDescriptor.bInterfaceSubClass == USB_HID_SUBCLASS_BOOT && pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_KEYBOARD; @@ -723,7 +723,7 @@ KSTATUS UsbHidAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObje pdoExt->InterfaceDescriptor.bInterfaceProtocol == USB_HID_PROTOCOL_MOUSE; bool qemuTablet = UsbHidIsQemuAbsoluteTabletPdo(pdoExt, ep); if (!bootKeyboard && !bootMouse && !qemuTablet) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* fdo = (DEVICE_OBJECT*)0; KSTATUS st = IoCreateDevice(driver, sizeof(USB_HID_EXTENSION), &fdo); @@ -752,7 +752,7 @@ KSTATUS UsbHidAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObje IoDestroyRemoveLock(&ext->RemoveLock); ext->RemoveLockReady = false; IoDeleteDevice(fdo); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } DbgPrint("usb: HID FDO attached slot=%u if=%u proto=%u kind=%s\n", @@ -760,7 +760,7 @@ KSTATUS UsbHidAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObje pdoExt->InterfaceDescriptor.bInterfaceNumber, pdoExt->InterfaceDescriptor.bInterfaceProtocol, qemuTablet ? "qemu-tablet" : (bootKeyboard ? "keyboard" : "mouse")); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Initializes hid Driver. diff --git a/code/drivers/bus/usb/usb_hub.c b/code/drivers/bus/usb/usb_hub.c index 055d3ae..05e8ac2 100644 --- a/code/drivers/bus/usb/usb_hub.c +++ b/code/drivers/bus/usb/usb_hub.c @@ -54,15 +54,15 @@ static KSTATUS UsbHubEnumerateRootPortWithRetries(USB_HUB_EXTENSION* hub, uint8_t* outSlot) { if (outSlot) *outSlot = 0; if (!hub || !xhci || port == 0 || port > USB_ROOT_HUB_MAX_PORTS) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; - KSTATUS last = STATUS_DEVICE_ERROR; + KSTATUS last = NTLSTATUS_DEVICE_ERROR; uint8_t maxAttempts = USB_ROOT_PORT_ENUM_RETRIES; if (maxAttempts == 0) maxAttempts = 1; for (uint8_t attempt = 1; attempt <= maxAttempts; attempt++) { if (!UsbHubRootPortConnected(xhci, port)) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; uint8_t slot = 0; last = XhciEnumeratePortEx(xhci, port, &slot); @@ -70,7 +70,7 @@ static KSTATUS UsbHubEnumerateRootPortWithRetries(USB_HUB_EXTENSION* hub, if (outSlot) *outSlot = slot; hub->RootPortFailCount[port] = 0; hub->RootPortState[port] = UsbHubPortChildPresent; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } hub->RootPortFailCount[port] = attempt; @@ -82,7 +82,7 @@ static KSTATUS UsbHubEnumerateRootPortWithRetries(USB_HUB_EXTENSION* hub, // enumerations. Descriptor/control timeouts are not retried here; they // are usually dead/firmware-owned ports and retrying them stalls boot. - if (last != STATUS_DEVICE_ERROR || attempt == maxAttempts) + if (last != NTLSTATUS_DEVICE_ERROR || attempt == maxAttempts) break; DbgPrint("usb-hub: root port %u enumeration attempt %u failed st=0x%x; retrying\n", @@ -219,7 +219,7 @@ static KSTATUS UsbHubControlIn(USB_HUB_EXTENSION* hub, PHYSICAL_ADDRESS bufferPhys, uint16_t length) { if (!hub || !hub->LowerDevice || !buffer || !bufferPhys || !length) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_URB urb; memset(&urb, 0, sizeof(urb)); @@ -243,7 +243,7 @@ static KSTATUS UsbHubControlNoData(USB_HUB_EXTENSION* hub, uint16_t value, uint16_t index) { if (!hub || !hub->LowerDevice) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_URB urb; memset(&urb, 0, sizeof(urb)); @@ -261,7 +261,7 @@ static KSTATUS UsbHubControlNoData(USB_HUB_EXTENSION* hub, // Implements the hub Read Descriptor operation. static KSTATUS UsbHubReadDescriptor(USB_HUB_EXTENSION* hub, USB_HUB_DESCRIPTOR* outDesc) { if (!hub || !outDesc || !hub->ChangeBitmap || !hub->ChangeBitmapPhys) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; memset(hub->ChangeBitmap, 0, USB_HUB_CHANGE_BITMAP_BYTES); KSTATUS st = UsbHubControlIn(hub, @@ -277,14 +277,14 @@ static KSTATUS UsbHubReadDescriptor(USB_HUB_EXTENSION* hub, USB_HUB_DESCRIPTOR* memcpy(outDesc, hub->ChangeBitmap, sizeof(USB_HUB_DESCRIPTOR)); if (outDesc->bDescriptorType != USB_DESC_HUB || outDesc->bNbrPorts == 0) - return STATUS_DEVICE_ERROR; - return STATUS_SUCCESS; + return NTLSTATUS_DEVICE_ERROR; + return NTLSTATUS_SUCCESS; } // Implements the hub Get Port Status operation. static KSTATUS UsbHubGetPortStatus(USB_HUB_EXTENSION* hub, uint8_t port, USB_HUB_PORT_STATUS* outStatus) { if (!hub || !outStatus || port == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; memset(hub->ChangeBitmap, 0, USB_HUB_CHANGE_BITMAP_BYTES); KSTATUS st = UsbHubControlIn(hub, @@ -299,7 +299,7 @@ static KSTATUS UsbHubGetPortStatus(USB_HUB_EXTENSION* hub, uint8_t port, USB_HUB return st; memcpy(outStatus, hub->ChangeBitmap, sizeof(USB_HUB_PORT_STATUS)); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the hub Set Port Feature operation. @@ -333,7 +333,7 @@ static uint8_t UsbHubSpeedFromPortStatus(uint16_t status) { static KSTATUS UsbHubResetExternalPort(USB_HUB_EXTENSION* hub, uint8_t port, uint8_t* outSpeed) { if (outSpeed) *outSpeed = 0; if (!hub || port == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; (void)UsbHubClearPortFeature(hub, port, USB_HUB_PORT_FEAT_C_CONNECTION); (void)UsbHubClearPortFeature(hub, port, USB_HUB_PORT_FEAT_C_ENABLE); @@ -361,13 +361,13 @@ static KSTATUS UsbHubResetExternalPort(USB_HUB_EXTENSION* hub, uint8_t port, uin if (!KSUCCESS(st)) return st; if (!(ps.Status & USB_HUB_PORT_STATUS_CONNECTION)) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; if (!(ps.Status & USB_HUB_PORT_STATUS_ENABLE)) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; if (outSpeed) *outSpeed = UsbHubSpeedFromPortStatus(ps.Status); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the hub Handle External Port Change operation. @@ -568,17 +568,17 @@ static void UsbHubWorker(void* arg) { // Implements the hub Do Root Port Scan operation. static KSTATUS UsbHubDoRootPortScan(USB_HCD* hcd) { if (!hcd || !hcd->RootHubContext) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_HUB_EXTENSION* hub = (USB_HUB_EXTENSION*)hcd->RootHubContext; if (!hub->Started) - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; uint32_t attempted = 0; uint32_t configured = 0; XHCI_CONTROLLER* xhci = (XHCI_CONTROLLER*)hcd->ControllerContext; if (!xhci || !xhci->Op) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; for (uint8_t port = 1; port <= hub->PortCount; port++) { uint32_t portsc = XhciRead32(xhci->Op, XhciPortReg(port)); @@ -609,16 +609,16 @@ static KSTATUS UsbHubDoRootPortScan(USB_HCD* hcd) { DbgPrint("usb-hub: root-port scan complete; attempted=%u configured=%u\n", attempted, configured); hub->InitialScanComplete = true; hub->InitialScanInProgress = false; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the hub Schedule Root Scan operation. KSTATUS UsbHubScheduleRootScan(USB_HCD* hcd) { if (!hcd || !hcd->RootHubContext) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_HUB_EXTENSION* hub = (USB_HUB_EXTENSION*)hcd->RootHubContext; if (hub->Kind != UsbHubKindRoot || !hub->Started) - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; uintptr_t flags = KeAcquireSpinlock(&hub->PendingLock); if (!hub->InitialScanComplete && !hub->InitialScanInProgress) @@ -627,7 +627,7 @@ KSTATUS UsbHubScheduleRootScan(USB_HCD* hcd) { if (hub->WorkerSemaphore) KeSignalSemaphore(hub->WorkerSemaphore); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the hub Queue Root Port Change operation. @@ -641,7 +641,7 @@ void UsbHubQueueRootPortChange(USB_HCD* hcd, uint8_t port) { // Implements the hub Scan External Ports operation. static KSTATUS UsbHubScanExternalPorts(USB_HUB_EXTENSION* hub) { if (!hub || hub->Kind != UsbHubKindExternal) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t attempted = 0; uint32_t configured = 0; @@ -663,7 +663,7 @@ static KSTATUS UsbHubScanExternalPorts(USB_HUB_EXTENSION* hub) { } DbgPrint("usb-hub: external hub slot=%u scan complete; attempted=%u configured=%u\n", hub->Device ? hub->Device->SlotId : 0, attempted, configured); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the hub Find Interrupt In operation. @@ -742,7 +742,7 @@ static void UsbHubArmExternalInterrupt(USB_HUB_EXTENSION* hub) { hub->ChangeUrb.CompleteContext = hub; KSTATUS st = UsbSubmitUrbAsync(hub->LowerDevice, &hub->ChangeUrb); - if (st == STATUS_PENDING) { + if (st == NTLSTATUS_PENDING) { hub->ChangeUrbPending = true; } else if (!KSUCCESS(st)) { DbgPrint("usb-hub: slot=%u interrupt arm failed st=0x%x\n", @@ -776,17 +776,17 @@ static KSTATUS UsbHubStartRootDevice(DEVICE_OBJECT* device, USB_HUB_EXTENSION* h hub->HubPdo->PnpState = DevicePnpStarted; DbgPrint("usb-hub: root hub started ports=%u\n", hub->PortCount); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the hub Start External Device operation. static KSTATUS UsbHubStartExternalDevice(DEVICE_OBJECT* device, USB_HUB_EXTENSION* hub) { if (!hub || !hub->Device) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; hub->ChangeBitmap = (uint8_t*)UsbAllocateDmaBuffer(hub->Device, 1, &hub->ChangeBitmapPhys); if (!hub->ChangeBitmap) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; USB_HUB_DESCRIPTOR desc; memset(&desc, 0, sizeof(desc)); @@ -846,13 +846,13 @@ static KSTATUS UsbHubStartExternalDevice(DEVICE_OBJECT* device, USB_HUB_EXTENSIO (void)UsbHubScanExternalPorts(hub); UsbHubArmExternalInterrupt(hub); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the hub Start Device operation. static KSTATUS UsbHubStartDevice(DEVICE_OBJECT* device, USB_HUB_EXTENSION* hub) { if (!device || !hub || hub->Started) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (hub->Kind == UsbHubKindRoot) return UsbHubStartRootDevice(device, hub); @@ -862,20 +862,20 @@ static KSTATUS UsbHubStartDevice(DEVICE_OBJECT* device, USB_HUB_EXTENSION* hub) // Implements the hub Dispatch Pnp operation. KSTATUS UsbHubDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { if (!device || !irp) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios || ios->MajorFunction != IRP_MJ_PNP) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_HUB_EXTENSION* hub = (USB_HUB_EXTENSION*)device->DeviceExtension; - KSTATUS st = STATUS_SUCCESS; + KSTATUS st = NTLSTATUS_SUCCESS; switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) { case IRP_MN_START_DEVICE: st = UsbHubStartDevice(device, hub); if (!KSUCCESS(st)) { IoCompleteRequest(irp, st, 0); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } return IoForwardIrpToLower(device, irp); @@ -940,19 +940,19 @@ KSTATUS UsbHubDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { } } - KSTATUS lower = hub && hub->LowerDevice ? IoForwardIrpToLower(device, irp) : STATUS_SUCCESS; + KSTATUS lower = hub && hub->LowerDevice ? IoForwardIrpToLower(device, irp) : NTLSTATUS_SUCCESS; if (hub && hub->LowerDevice) { IoDetachDevice(device); hub->LowerDevice = (DEVICE_OBJECT*)0; } IoDeleteDevice(device); - if (lower == STATUS_NOT_SUPPORTED) { - IoCompleteRequest(irp, STATUS_SUCCESS, 0); - return STATUS_PENDING; + if (lower == NTLSTATUS_NOT_SUPPORTED) { + IoCompleteRequest(irp, NTLSTATUS_SUCCESS, 0); + return NTLSTATUS_PENDING; } - if (lower != STATUS_PENDING && !KSUCCESS(lower)) { + if (lower != NTLSTATUS_PENDING && !KSUCCESS(lower)) { IoCompleteRequest(irp, lower, 0); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } return lower; } @@ -965,11 +965,11 @@ KSTATUS UsbHubDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { // Implements the hub Add Device operation. KSTATUS UsbHubAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) { if (!driver || !physicalDeviceObject || physicalDeviceObject->Type != DeviceObjectPhysical) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_PDO_EXTENSION* pdoExt = (USB_PDO_EXTENSION*)physicalDeviceObject->DeviceExtension; if (!pdoExt) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_HUB_KIND kind; USB_DEVICE* usbDevice = (USB_DEVICE*)0; @@ -983,16 +983,16 @@ KSTATUS UsbHubAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObje usbDevice = pdoExt->Device; intr = UsbHubFindInterruptIn(pdoExt); if (!intr) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } else if (pdoExt->Kind == UsbPdoInterface && pdoExt->Device && pdoExt->InterfaceDescriptor.bInterfaceClass == USB_CLASS_HUB) { kind = UsbHubKindExternal; usbDevice = pdoExt->Device; intr = UsbHubFindInterruptIn(pdoExt); if (!intr) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } else { - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } DEVICE_OBJECT* fdo = (DEVICE_OBJECT*)0; @@ -1034,7 +1034,7 @@ KSTATUS UsbHubAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObje IoDestroyRemoveLock(&hub->RemoveLock); hub->RemoveLockReady = false; IoDeleteDevice(fdo); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } if (kind == UsbHubKindRoot) { @@ -1045,7 +1045,7 @@ KSTATUS UsbHubAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObje hub->Device ? hub->Device->SlotId : 0, hub->InterruptEndpointAddress); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Initializes hub Driver. diff --git a/code/drivers/bus/usb/usb_storage.c b/code/drivers/bus/usb/usb_storage.c index 85e0a61..184a76b 100644 --- a/code/drivers/bus/usb/usb_storage.c +++ b/code/drivers/bus/usb/usb_storage.c @@ -60,11 +60,11 @@ static KSTATUS UsbStorageSubmitBulk(USB_STORAGE_EXTENSION* storage, uint32_t length, uint32_t* outActual) { if (!storage || !storage->LowerDevice || !storage->Device || !phys || length == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_PIPE* pipe = dataIn ? storage->BulkInPipe : storage->BulkOutPipe; if (!pipe || !pipe->Open) - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; USB_URB urb; memset(&urb, 0, sizeof(urb)); @@ -104,9 +104,9 @@ KSTATUS UsbStorageBotCommand(USB_STORAGE_EXTENSION* storage, uint32_t dataLength, bool dataIn) { if (!storage || !storage->XhciDevice || !cdb || cdbLen == 0 || cdbLen > 16) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (dataLength && (!data || !dataPhys)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; XHCI_DEVICE* dev = storage->XhciDevice; USB_MASS_CBW* cbw = (USB_MASS_CBW*)dev->DescriptorBuffer; @@ -122,7 +122,7 @@ KSTATUS UsbStorageBotCommand(USB_STORAGE_EXTENSION* storage, uint32_t actual = 0; KSTATUS st = UsbStorageBulkOut(storage, dev->DescriptorPhys, sizeof(*cbw), &actual); if (!KSUCCESS(st) || actual != sizeof(*cbw)) - return KSUCCESS(st) ? STATUS_DEVICE_ERROR : st; + return KSUCCESS(st) ? NTLSTATUS_DEVICE_ERROR : st; if (dataLength) { actual = 0; @@ -137,20 +137,20 @@ KSTATUS UsbStorageBotCommand(USB_STORAGE_EXTENSION* storage, actual = 0; st = UsbStorageBulkIn(storage, dev->DescriptorPhys, sizeof(*csw), &actual); if (!KSUCCESS(st) || actual != sizeof(*csw)) - return KSUCCESS(st) ? STATUS_DEVICE_ERROR : st; + return KSUCCESS(st) ? NTLSTATUS_DEVICE_ERROR : st; if (csw->Signature != USB_MASS_BOT_CSW_SIGNATURE || csw->Tag != storage->Tag) { DbgPrint("usb-storage: invalid CSW slot=%u sig=%08x tag=%08x expected=%08x\n", dev->SlotId, csw->Signature, csw->Tag, storage->Tag); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } if (csw->Status != USB_MASS_BOT_CSW_PASSED) { DbgPrint("usb-storage: command %02x failed slot=%u csw_status=%u residue=%u\n", cdb[0], dev->SlotId, csw->Status, csw->DataResidue); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the be32 operation. @@ -176,7 +176,7 @@ void UsbStoreBe16(uint8_t* p, uint16_t v) { // Implements the storage Inquiry operation. KSTATUS UsbStorageInquiry(USB_STORAGE_EXTENSION* storage) { if (!storage || !storage->XhciDevice) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; XHCI_DEVICE* dev = storage->XhciDevice; uint8_t cdb[6] = { SCSI_INQUIRY, 0, 0, 0, 36, 0 }; @@ -192,13 +192,13 @@ KSTATUS UsbStorageInquiry(USB_STORAGE_EXTENSION* storage) { memcpy(product, dev->MassBuffer + 16, 16); product[16] = 0; DbgPrint("usb-storage: INQUIRY slot=%u vendor='%s' product='%s'\n", dev->SlotId, vendor, product); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the storage Request Sense operation. KSTATUS UsbStorageRequestSense(USB_STORAGE_EXTENSION* storage) { if (!storage || !storage->XhciDevice) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; XHCI_DEVICE* dev = storage->XhciDevice; uint8_t rs[6] = { SCSI_REQUEST_SENSE, 0, 0, 0, 18, 0 }; @@ -210,16 +210,16 @@ KSTATUS UsbStorageRequestSense(USB_STORAGE_EXTENSION* storage) { // Implements the storage Test Unit Ready operation. KSTATUS UsbStorageTestUnitReady(USB_STORAGE_EXTENSION* storage) { if (!storage || !storage->XhciDevice) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint8_t cdb[6] = { SCSI_TEST_UNIT_READY, 0, 0, 0, 0, 0 }; - KSTATUS last = STATUS_DEVICE_ERROR; + KSTATUS last = NTLSTATUS_DEVICE_ERROR; XHCI_CONTROLLER* xhci = (XHCI_CONTROLLER*)storage->Device->Hcd->ControllerContext; for (uint32_t attempt = 0; attempt < 10; attempt++) { KSTATUS st = UsbStorageBotCommand(storage, cdb, sizeof(cdb), (void*)0, 0, 0, false); - if (KSUCCESS(st)) return STATUS_SUCCESS; + if (KSUCCESS(st)) return NTLSTATUS_SUCCESS; last = st; (void)UsbStorageRequestSense(storage); @@ -232,7 +232,7 @@ KSTATUS UsbStorageTestUnitReady(USB_STORAGE_EXTENSION* storage) { // Implements the storage Read Capacity operation. KSTATUS UsbStorageReadCapacity(USB_STORAGE_EXTENSION* storage) { if (!storage || !storage->XhciDevice) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; XHCI_DEVICE* dev = storage->XhciDevice; uint8_t cdb[10] = { SCSI_READ_CAPACITY_10, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -245,7 +245,7 @@ KSTATUS UsbStorageReadCapacity(USB_STORAGE_EXTENSION* storage) { uint32_t lastLba = UsbBe32(dev->MassBuffer + 0); uint32_t blockSize = UsbBe32(dev->MassBuffer + 4); if (blockSize == 0) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; storage->BlockSize = blockSize; storage->BlockCount = (uint64_t)lastLba + 1ull; @@ -258,7 +258,7 @@ KSTATUS UsbStorageReadCapacity(USB_STORAGE_EXTENSION* storage) { (unsigned long long)storage->BlockCount, storage->BlockSize, (unsigned long long)((storage->BlockCount * (uint64_t)storage->BlockSize) / (1024ull * 1024ull))); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KSTATUS UsbStorageReadWriteSectors(USB_STORAGE_EXTENSION* storage, @@ -267,16 +267,16 @@ KSTATUS UsbStorageReadWriteSectors(USB_STORAGE_EXTENSION* storage, uint32_t sectors, void* buffer) { if (!storage || !storage->XhciDevice || !buffer || sectors == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (storage->BlockSize != USB_STORAGE_SECTOR_SIZE) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (lba > 0xFFFFFFFFull || sectors > 0xFFFFu) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; XHCI_DEVICE* dev = storage->XhciDevice; uint32_t bytes = sectors * USB_STORAGE_SECTOR_SIZE; if (bytes > USB_STORAGE_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint8_t cdb[10]; memset(cdb, 0, sizeof(cdb)); @@ -294,7 +294,7 @@ KSTATUS UsbStorageReadWriteSectors(USB_STORAGE_EXTENSION* storage, if (!write) memcpy(buffer, dev->MassBuffer, bytes); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the storage Acquire Io operation. @@ -314,11 +314,11 @@ void UsbStorageReleaseIo(USB_STORAGE_EXTENSION* storage) { // Implements the storage Dispatch Read Write operation. KSTATUS UsbStorageDispatchReadWrite(DEVICE_OBJECT* device, IRP* irp) { if (!device || !irp) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_STORAGE_EXTENSION* storage = UsbStorageFromDiskDevice(device); if (!storage || !storage->RemoveLockReady) - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; KSTATUS st = IoAcquireRemoveLock(&storage->RemoveLock, irp); if (!KSUCCESS(st)) @@ -327,25 +327,25 @@ KSTATUS UsbStorageDispatchReadWrite(DEVICE_OBJECT* device, IRP* irp) { IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios) { IoReleaseRemoveLock(&storage->RemoveLock, irp); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (ios->MajorFunction != IRP_MJ_READ && ios->MajorFunction != IRP_MJ_WRITE) { IoReleaseRemoveLock(&storage->RemoveLock, irp); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if ((ios->Parameters.ReadWrite.ByteOffset & 511ull) || (ios->Parameters.ReadWrite.Length & 511u) || ios->Parameters.ReadWrite.Length == 0 || !irp->UserBuffer) { IoReleaseRemoveLock(&storage->RemoveLock, irp); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (!storage->Started || storage->SurpriseRemoved || storage->Removed || storage->BlockSize != USB_STORAGE_SECTOR_SIZE) { IoReleaseRemoveLock(&storage->RemoveLock, irp); - IoCompleteRequest(irp, STATUS_OBJECT_DEAD, 0); - return STATUS_PENDING; + IoCompleteRequest(irp, NTLSTATUS_OBJECT_DEAD, 0); + return NTLSTATUS_PENDING; } uint8_t* buffer = (uint8_t*)irp->UserBuffer; @@ -355,7 +355,7 @@ KSTATUS UsbStorageDispatchReadWrite(DEVICE_OBJECT* device, IRP* irp) { bool write = (ios->MajorFunction == IRP_MJ_WRITE); uint32_t maxSectors = USB_STORAGE_MAX_BYTES / USB_STORAGE_SECTOR_SIZE; - st = STATUS_SUCCESS; + st = NTLSTATUS_SUCCESS; UsbStorageAcquireIo(storage); while (remaining) { uint32_t chunk = remaining; @@ -372,19 +372,19 @@ KSTATUS UsbStorageDispatchReadWrite(DEVICE_OBJECT* device, IRP* irp) { IoReleaseRemoveLock(&storage->RemoveLock, irp); IoCompleteRequest(irp, st, KSUCCESS(st) ? (size_t)done * USB_STORAGE_SECTOR_SIZE : 0); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } // Creates mass Storage Memory. KSTATUS XhciAllocateMassStorageMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) { if (dev->MassInRing && dev->MassOutRing && dev->MassBuffer) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; dev->MassInRing = (XHCI_TRB*)UsbDmaAllocPages(xhci, 1, &dev->MassInRingPhys); dev->MassOutRing = (XHCI_TRB*)UsbDmaAllocPages(xhci, 1, &dev->MassOutRingPhys); dev->MassBuffer = (uint8_t*)UsbDmaAllocPages(xhci, USB_STORAGE_DMA_PAGES, &dev->MassBufferPhys); if (!dev->MassInRing || !dev->MassOutRing || !dev->MassBuffer) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; dev->MassInEnqueue = 0; dev->MassInCycle = 1; @@ -393,13 +393,13 @@ KSTATUS XhciAllocateMassStorageMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) { dev->MassTag = 0x1000u + dev->SlotId; XhciInitialiseTransferRing(dev->MassInRing, dev->MassInRingPhys, XHCI_BULK_RING_TRBS, dev->MassInCycle); XhciInitialiseTransferRing(dev->MassOutRing, dev->MassOutRingPhys, XHCI_BULK_RING_TRBS, dev->MassOutCycle); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the configure Mass Storage Endpoints operation. KSTATUS XhciConfigureMassStorageEndpoints(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) { if (!dev->MassCandidate) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; KSTATUS st = XhciAllocateMassStorageMemory(xhci, dev); if (!KSUCCESS(st)) return st; @@ -407,7 +407,7 @@ KSTATUS XhciConfigureMassStorageEndpoints(XHCI_CONTROLLER* xhci, XHCI_DEVICE* de uint8_t inDci = dev->MassBulkInEndpointId; uint8_t outDci = dev->MassBulkOutEndpointId; if (inDci < 2 || inDci > 31 || outDci < 2 || outDci > 31) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; memset(dev->InputContext, 0, PAGE_SIZE); uint32_t* icc = XhciInputControlContext(xhci, dev); @@ -463,7 +463,7 @@ KSTATUS XhciConfigureMassStorageEndpoints(XHCI_CONTROLLER* xhci, XHCI_DEVICE* de inDci, dev->MassBulkOutAddress, outDci); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns free Disk Index. @@ -478,9 +478,9 @@ uint8_t UsbFindFreeDiskIndex(void) { // Implements the storage Register Disk operation. KSTATUS UsbStorageRegisterDisk(USB_STORAGE_EXTENSION* storage) { if (!storage || storage->BlockSize != USB_STORAGE_SECTOR_SIZE || storage->BlockCount == 0) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (storage->DiskDevice) - return STATUS_ALREADY_EXISTS; + return NTLSTATUS_ALREADY_EXISTS; DEVICE_OBJECT* disk = (DEVICE_OBJECT*)0; KSTATUS st = IoCreateDevice(&gUsbStorageDriver, sizeof(USB_STORAGE_DISK_EXTENSION), &disk); @@ -499,7 +499,7 @@ KSTATUS UsbStorageRegisterDisk(USB_STORAGE_EXTENSION* storage) { uint8_t index = UsbFindFreeDiskIndex(); if (index == 0xFFu) { IoDeleteDevice(disk); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } st = IoRegisterDiskDevice(index, disk); @@ -516,31 +516,31 @@ KSTATUS UsbStorageRegisterDisk(USB_STORAGE_EXTENSION* storage) { index, storage->Device ? storage->Device->SlotId : 0, (unsigned long long)storage->BlockCount); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the storage Start Device operation. static KSTATUS UsbStorageStartDevice(DEVICE_OBJECT* device, USB_STORAGE_EXTENSION* storage) { if (!device || !storage || !storage->InterfacePdo || !storage->Device) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (storage->Started) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (storage->SurpriseRemoved || storage->Removed) - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; USB_PDO_EXTENSION* pdoExt = (USB_PDO_EXTENSION*)storage->InterfacePdo->DeviceExtension; if (!pdoExt || pdoExt->Kind != UsbPdoInterface) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; const USB_ENDPOINT_DESCRIPTOR* bulkIn = UsbStorageFindBulkEndpoint(pdoExt, true); const USB_ENDPOINT_DESCRIPTOR* bulkOut = UsbStorageFindBulkEndpoint(pdoExt, false); if (!bulkIn || !bulkOut) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; XHCI_CONTROLLER* xhci = (XHCI_CONTROLLER*)storage->Device->Hcd->ControllerContext; XHCI_DEVICE* xdev = (XHCI_DEVICE*)storage->Device->HcdDeviceContext; if (!xhci || !xdev) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; storage->XhciDevice = xdev; storage->InterfaceNumber = pdoExt->InterfaceDescriptor.bInterfaceNumber; @@ -592,7 +592,7 @@ static KSTATUS UsbStorageStartDevice(DEVICE_OBJECT* device, USB_STORAGE_EXTENSIO if (storage->BlockSize != USB_STORAGE_SECTOR_SIZE) { DbgPrint("usb-storage: unsupported block size slot=%u size=%u\n", storage->Device->SlotId, storage->BlockSize); - st = STATUS_NOT_SUPPORTED; + st = NTLSTATUS_NOT_SUPPORTED; goto fail; } @@ -616,7 +616,7 @@ static KSTATUS UsbStorageStartDevice(DEVICE_OBJECT* device, USB_STORAGE_EXTENSIO DbgPrint("usb-storage: FDO bound slot=%u if=%u disk-ready\n", storage->Device->SlotId, storage->InterfaceNumber); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; fail: xdev->MassCandidate = false; @@ -639,23 +639,23 @@ fail: // Implements the storage Disk Pnp operation. static KSTATUS UsbStorageDiskPnp(DEVICE_OBJECT* device, IRP* irp, USB_STORAGE_EXTENSION* storage, IO_PNP_MINOR_FUNCTION minor) { if (!device || !irp || !storage) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; switch (minor) { case IRP_MN_START_DEVICE: device->PnpState = DevicePnpStarted; - IoCompleteRequest(irp, STATUS_SUCCESS, 0); - return STATUS_PENDING; + IoCompleteRequest(irp, NTLSTATUS_SUCCESS, 0); + return NTLSTATUS_PENDING; case IRP_MN_QUERY_REMOVE_DEVICE: device->PnpState = DevicePnpRemovePending; - IoCompleteRequest(irp, STATUS_SUCCESS, 0); - return STATUS_PENDING; + IoCompleteRequest(irp, NTLSTATUS_SUCCESS, 0); + return NTLSTATUS_PENDING; case IRP_MN_CANCEL_REMOVE_DEVICE: device->PnpState = DevicePnpStarted; - IoCompleteRequest(irp, STATUS_SUCCESS, 0); - return STATUS_PENDING; + IoCompleteRequest(irp, NTLSTATUS_SUCCESS, 0); + return NTLSTATUS_PENDING; case IRP_MN_SURPRISE_REMOVAL: storage->SurpriseRemoved = true; @@ -664,8 +664,8 @@ static KSTATUS UsbStorageDiskPnp(DEVICE_OBJECT* device, IRP* irp, USB_STORAGE_EX storage->XhciDevice->MassActive = false; } device->PnpState = DevicePnpSurpriseRemoved; - IoCompleteRequest(irp, STATUS_SUCCESS, 0); - return STATUS_PENDING; + IoCompleteRequest(irp, NTLSTATUS_SUCCESS, 0); + return NTLSTATUS_PENDING; case IRP_MN_REMOVE_DEVICE: storage->Removed = true; @@ -679,26 +679,26 @@ static KSTATUS UsbStorageDiskPnp(DEVICE_OBJECT* device, IRP* irp, USB_STORAGE_EX if (storage->DiskDevice == device) storage->DiskDevice = (DEVICE_OBJECT*)0; IoDeleteDevice(device); - IoCompleteRequest(irp, STATUS_SUCCESS, 0); - return STATUS_PENDING; + IoCompleteRequest(irp, NTLSTATUS_SUCCESS, 0); + return NTLSTATUS_PENDING; default: - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } } // Implements the storage Interface Pnp operation. static KSTATUS UsbStorageInterfacePnp(DEVICE_OBJECT* device, IRP* irp, USB_STORAGE_EXTENSION* storage, IO_PNP_MINOR_FUNCTION minor) { if (!device || !irp || !storage) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; - KSTATUS st = STATUS_SUCCESS; + KSTATUS st = NTLSTATUS_SUCCESS; switch (minor) { case IRP_MN_START_DEVICE: st = UsbStorageStartDevice(device, storage); if (!KSUCCESS(st)) { IoCompleteRequest(irp, st, 0); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } return IoForwardIrpToLower(device, irp); @@ -743,19 +743,19 @@ static KSTATUS UsbStorageInterfacePnp(DEVICE_OBJECT* device, IRP* irp, USB_STORA } device->PnpState = DevicePnpDeleted; - KSTATUS lower = storage->LowerDevice ? IoForwardIrpToLower(device, irp) : STATUS_SUCCESS; + KSTATUS lower = storage->LowerDevice ? IoForwardIrpToLower(device, irp) : NTLSTATUS_SUCCESS; if (storage->LowerDevice) { IoDetachDevice(device); storage->LowerDevice = (DEVICE_OBJECT*)0; } IoDeleteDevice(device); - if (lower == STATUS_NOT_SUPPORTED) { - IoCompleteRequest(irp, STATUS_SUCCESS, 0); - return STATUS_PENDING; + if (lower == NTLSTATUS_NOT_SUPPORTED) { + IoCompleteRequest(irp, NTLSTATUS_SUCCESS, 0); + return NTLSTATUS_PENDING; } - if (lower != STATUS_PENDING && !KSUCCESS(lower)) { + if (lower != NTLSTATUS_PENDING && !KSUCCESS(lower)) { IoCompleteRequest(irp, lower, 0); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } return lower; } @@ -768,11 +768,11 @@ static KSTATUS UsbStorageInterfacePnp(DEVICE_OBJECT* device, IRP* irp, USB_STORA // Implements the storage Dispatch Pnp operation. KSTATUS UsbStorageDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { if (!device || !irp) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios || ios->MajorFunction != IRP_MJ_PNP) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_STORAGE_EXTENSION* iface = UsbStorageFromInterfaceDevice(device); if (iface) @@ -782,23 +782,23 @@ KSTATUS UsbStorageDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { if (disk) return UsbStorageDiskPnp(device, irp, disk, (IO_PNP_MINOR_FUNCTION)ios->MinorFunction); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } // Implements the storage Add Device operation. KSTATUS UsbStorageAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) { if (!driver || !physicalDeviceObject || physicalDeviceObject->Type != DeviceObjectPhysical) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; USB_PDO_EXTENSION* pdoExt = (USB_PDO_EXTENSION*)physicalDeviceObject->DeviceExtension; if (!pdoExt || pdoExt->Kind != UsbPdoInterface || !pdoExt->Device) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (pdoExt->InterfaceDescriptor.bInterfaceClass != USB_CLASS_MASS_STORAGE || pdoExt->InterfaceDescriptor.bInterfaceSubClass != USB_MASS_SUBCLASS_SCSI || pdoExt->InterfaceDescriptor.bInterfaceProtocol != USB_MASS_PROTOCOL_BOT) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!UsbStorageFindBulkEndpoint(pdoExt, true) || !UsbStorageFindBulkEndpoint(pdoExt, false)) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; DEVICE_OBJECT* fdo = (DEVICE_OBJECT*)0; KSTATUS st = IoCreateDevice(driver, sizeof(USB_STORAGE_EXTENSION), &fdo); @@ -827,13 +827,13 @@ KSTATUS UsbStorageAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDevice IoDestroyRemoveLock(&ext->RemoveLock); ext->RemoveLockReady = false; IoDeleteDevice(fdo); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } DbgPrint("usb-storage: FDO attached slot=%u if=%u\n", ext->Device->SlotId, pdoExt->InterfaceDescriptor.bInterfaceNumber); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Initializes storage Driver. diff --git a/code/drivers/bus/usb/usb_xhci.c b/code/drivers/bus/usb/usb_xhci.c index 9824be5..7a24fe9 100644 --- a/code/drivers/bus/usb/usb_xhci.c +++ b/code/drivers/bus/usb/usb_xhci.c @@ -499,12 +499,12 @@ void XhciUnregisterWaitTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target) { KSTATUS XhciWaitForArmedTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target, uint32_t timeoutUs) { if (!xhci || !target) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; for (uint32_t i = 0; i < timeoutUs; i++) { if (XhciWaitTargetComplete(target)) { XhciUnregisterWaitTarget(xhci, target); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // The IRQ/DPC path normally owns the event ring after enumeration, but @@ -522,13 +522,13 @@ KSTATUS XhciWaitForArmedTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target, } XhciUnregisterWaitTarget(xhci, target); - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } KSTATUS XhciWaitForTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target, uint32_t timeoutUs) { if (!xhci || !target) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; XhciRegisterWaitTarget(xhci, target); return XhciWaitForArmedTarget(xhci, target, timeoutUs); } @@ -557,15 +557,15 @@ static uint32_t gXhciControllerCount; // Registers controller. static KSTATUS XhciRegisterController(XHCI_CONTROLLER* xhci) { - if (!xhci) return STATUS_INVALID_PARAMETER; + if (!xhci) return NTLSTATUS_INVALID_PARAMETER; for (uint32_t i = 0; i < gXhciControllerCount; i++) { if (gXhciControllers[i] == xhci) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (gXhciControllerCount >= XHCI_MAX_CONTROLLERS) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; gXhciControllers[gXhciControllerCount++] = xhci; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the isr operation. @@ -589,7 +589,7 @@ void XhciIsr(void) { // Implements the bios Handoff operation. KSTATUS XhciBiosHandoff(XHCI_CONTROLLER* xhci) { uint32_t xecp = (xhci->Hcc1 >> 16) & 0xFFFFu; - if (!xecp) return STATUS_SUCCESS; + if (!xecp) return NTLSTATUS_SUCCESS; for (uint32_t guard = 0; xecp && guard < 64; guard++) { uint32_t off = xecp << 2; @@ -621,13 +621,13 @@ KSTATUS XhciBiosHandoff(XHCI_CONTROLLER* xhci) { // Clear legacy SMI enables/status. RW1C status bits tolerate this. XhciWrite32(xhci->Mmio, off + 4u, 0xFFFFFFFFu); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } xecp = next; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the stop And Reset operation. @@ -639,7 +639,7 @@ KSTATUS XhciStopAndReset(XHCI_CONTROLLER* xhci) { XHCI_USBSTS_HCH, 1000000u)) { DbgPrint("usb: xHCI stop timeout usbsts=%08x\n", XhciRead32(xhci->Op, XHCI_OP_USBSTS)); - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } } @@ -648,35 +648,35 @@ KSTATUS XhciStopAndReset(XHCI_CONTROLLER* xhci) { XHCI_USBCMD_HCRST, 1000000u)) { DbgPrint("usb: xHCI reset timeout usbcmd=%08x\n", XhciRead32(xhci->Op, XHCI_OP_USBCMD)); - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } if (!UsbWaitClear32(xhci->Hal, xhci->Op, XHCI_OP_USBSTS, XHCI_USBSTS_CNR, 1000000u)) { DbgPrint("usb: xHCI controller-not-ready timeout usbsts=%08x\n", XhciRead32(xhci->Op, XHCI_OP_USBSTS)); - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } XhciWrite32(xhci->Op, XHCI_OP_USBSTS, XhciRead32(xhci->Op, XHCI_OP_USBSTS) & XHCI_USBSTS_CLEAR_MASK); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Creates scratchpads. KSTATUS XhciAllocateScratchpads(XHCI_CONTROLLER* xhci) { - if (xhci->ScratchpadCount == 0) return STATUS_SUCCESS; + if (xhci->ScratchpadCount == 0) return NTLSTATUS_SUCCESS; if (xhci->ScratchpadCount > XHCI_MAX_SCRATCHPADS) { DbgPrint("usb: xHCI wants %u scratchpads, capped driver supports %u\n", xhci->ScratchpadCount, XHCI_MAX_SCRATCHPADS); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } xhci->ScratchpadArray = (uint64_t*)UsbDmaAllocPages(xhci, 1, &xhci->ScratchpadArrayPhys); if (!xhci->ScratchpadArray) { DbgPrint("usb: xHCI scratchpad pointer-array allocation failed count=%u\n", xhci->ScratchpadCount); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } for (uint16_t i = 0; i < xhci->ScratchpadCount; i++) { @@ -684,7 +684,7 @@ KSTATUS XhciAllocateScratchpads(XHCI_CONTROLLER* xhci) { if (!page) { DbgPrint("usb: xHCI scratchpad buffer allocation failed index=%u/%u\n", i, xhci->ScratchpadCount); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } (void)page; xhci->ScratchpadArray[i] = xhci->ScratchpadPhys[i]; @@ -694,7 +694,7 @@ KSTATUS XhciAllocateScratchpads(XHCI_CONTROLLER* xhci) { UsbTrace("usb: xHCI allocated %u scratchpad buffer(s) array=0x%016llX\n", xhci->ScratchpadCount, (unsigned long long)xhci->ScratchpadArrayPhys); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Creates runtime Memory. @@ -707,7 +707,7 @@ KSTATUS XhciAllocateRuntimeMemory(XHCI_CONTROLLER* xhci) { if (!xhci->Dcbaa || !xhci->CommandRing || !xhci->EventRing || !xhci->Erst) { DbgPrint("usb: xHCI runtime DMA allocation failed dcbaa=0x%016llX cmd=0x%016llX event=0x%016llX erst=0x%016llX\n", xhci->Dcbaa, xhci->CommandRing, xhci->EventRing, xhci->Erst); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } xhci->CommandEnqueue = 0; @@ -735,13 +735,13 @@ KSTATUS XhciAllocateRuntimeMemory(XHCI_CONTROLLER* xhci) { (unsigned long long)xhci->CommandRingPhys, (unsigned long long)xhci->EventRingPhys, (unsigned long long)xhci->ErstPhys); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the program Runtime operation. KSTATUS XhciProgramRuntime(XHCI_CONTROLLER* xhci) { uint8_t slots = xhci->MaxSlots; - if (slots == 0) return STATUS_DEVICE_ERROR; + if (slots == 0) return NTLSTATUS_DEVICE_ERROR; XhciWrite64(xhci->Op, XHCI_OP_DCBAAP, xhci->DcbaaPhys); XhciWrite64(xhci->Op, XHCI_OP_CRCR, xhci->CommandRingPhys | xhci->CommandCycle); @@ -756,7 +756,7 @@ KSTATUS XhciProgramRuntime(XHCI_CONTROLLER* xhci) { XhciWrite64(ir0, 0x18u, xhci->EventRingPhys); XhciBarrier(); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the command Trb Phys operation. @@ -770,7 +770,7 @@ static KSTATUS XhciCommandRingAppend(XHCI_CONTROLLER* xhci, uint32_t controlWithoutCycle, uint64_t* outPhys) { if (!xhci || !xhci->CommandRing) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (xhci->CommandEnqueue >= XHCI_RING_TRBS - 1u) { XHCI_TRB* link = &xhci->CommandRing[XHCI_RING_TRBS - 1u]; @@ -796,7 +796,7 @@ static KSTATUS XhciCommandRingAppend(XHCI_CONTROLLER* xhci, trb->Control = controlWithoutCycle | xhci->CommandCycle; if (outPhys) *outPhys = trbPhys; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KSTATUS XhciSubmitCommand(XHCI_CONTROLLER* xhci, @@ -805,7 +805,7 @@ KSTATUS XhciSubmitCommand(XHCI_CONTROLLER* xhci, uint32_t controlWithoutCycle, XHCI_COMMAND_RESULT* outResult) { if (!xhci) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; XHCI_WAIT_TARGET target; memset(&target, 0, sizeof(target)); @@ -829,8 +829,8 @@ KSTATUS XhciSubmitCommand(XHCI_CONTROLLER* xhci, if (KSUCCESS(waitStatus) && target.CommandMatched) { if (outResult) *outResult = target.Command; return (target.Command.CompletionCode == XHCI_CC_SUCCESS) - ? STATUS_SUCCESS - : STATUS_DEVICE_ERROR; + ? NTLSTATUS_SUCCESS + : NTLSTATUS_DEVICE_ERROR; } DbgPrint("usb: xHCI command timeout type=%u usbsts=%08x crcr=0x%016llX\n", @@ -852,7 +852,7 @@ KSTATUS XhciSubmitNoopCommand(XHCI_CONTROLLER* xhci) { if (KSUCCESS(st)) { UsbTrace("usb: xHCI No-Op command completed successfully\n"); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } DbgPrint("usb: xHCI No-Op command failed st=0x%x cc=%u\n", @@ -877,17 +877,17 @@ KSTATUS XhciEnableSlot(XHCI_CONTROLLER* xhci, uint8_t* outSlotId) { } if (result.SlotId == 0 || result.SlotId > XHCI_MAX_TRACKED_SLOTS) { DbgPrint("usb: xHCI Enable Slot returned unsupported slot=%u\n", result.SlotId); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } *outSlotId = result.SlotId; UsbTrace("usb: xHCI Enable Slot -> slot %u\n", result.SlotId); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Disables slot. KSTATUS XhciDisableSlot(XHCI_CONTROLLER* xhci, uint8_t slotId) { if (!xhci || slotId == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; XHCI_COMMAND_RESULT res; memset(&res, 0, sizeof(res)); @@ -901,9 +901,9 @@ KSTATUS XhciDisableSlot(XHCI_CONTROLLER* xhci, uint8_t slotId) { return st; if (res.CompletionCode != XHCI_CC_SUCCESS) { DbgPrint("usb: Disable Slot slot=%u failed cc=%u\n", slotId, res.CompletionCode); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the address Device operation. @@ -923,7 +923,7 @@ KSTATUS XhciAddressDevice(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) { return st; } UsbTrace("usb: xHCI Address Device slot=%u complete\n", dev->SlotId); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Starts the requested operation. @@ -936,11 +936,11 @@ KSTATUS XhciStart(XHCI_CONTROLLER* xhci) { XHCI_USBSTS_HCH, 1000000u)) { DbgPrint("usb: xHCI start timeout usbsts=%08x\n", XhciRead32(xhci->Op, XHCI_OP_USBSTS)); - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } xhci->Running = true; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Enables interrupts. @@ -979,7 +979,7 @@ KSTATUS XhciResetPort(XHCI_CONTROLLER* xhci, uint8_t port, uint8_t* outSpeed) { uint32_t off = XhciPortReg(port); uint32_t portsc = XhciRead32(xhci->Op, off); if (!(portsc & XHCI_PORTSC_CCS)) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; uint32_t speed = (portsc & XHCI_PORTSC_SPEED_MASK) >> XHCI_PORTSC_SPEED_SHIFT; uint8_t protocol = XhciPortProtocolMajor(xhci, port, portsc); @@ -1018,8 +1018,8 @@ KSTATUS XhciResetPort(XHCI_CONTROLLER* xhci, uint8_t port, uint8_t* outSpeed) { protocol, XhciPortSpeedName(speed), speed); if (!enabled || !(portsc & XHCI_PORTSC_CCS) || !(portsc & XHCI_PORTSC_PED)) - return STATUS_DEVICE_ERROR; - return STATUS_SUCCESS; + return NTLSTATUS_DEVICE_ERROR; + return NTLSTATUS_SUCCESS; } uint32_t reset = (portsc & XHCI_PORTSC_PP) | XHCI_PORTSC_PR; @@ -1038,7 +1038,7 @@ KSTATUS XhciResetPort(XHCI_CONTROLLER* xhci, uint8_t port, uint8_t* outSpeed) { if (!resetDone) { DbgPrint("usb: xHCI port %u reset timeout portsc=%08x\n", port, portsc); - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } XhciClearPortChanges(xhci, port); @@ -1052,9 +1052,9 @@ KSTATUS XhciResetPort(XHCI_CONTROLLER* xhci, uint8_t port, uint8_t* outSpeed) { protocol, XhciPortSpeedName(speed), speed); if (!(portsc & XHCI_PORTSC_CCS) || !(portsc & XHCI_PORTSC_PED)) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Creates device Memory. @@ -1065,7 +1065,7 @@ KSTATUS XhciAllocateDeviceMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) { dev->DescriptorBuffer = (uint8_t*)UsbDmaAllocPages(xhci, 1, &dev->DescriptorPhys); if (!dev->InputContext || !dev->DeviceContext || !dev->Ep0Ring || !dev->DescriptorBuffer) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; dev->Ep0Enqueue = 0; dev->Ep0Cycle = 1; @@ -1078,7 +1078,7 @@ KSTATUS XhciAllocateDeviceMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev) { XHCI_TRB_LINK_TC | dev->Ep0Cycle; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Builds default Control Context. @@ -1135,7 +1135,7 @@ KSTATUS XhciEp0AppendTrb(XHCI_DEVICE* dev, uint32_t controlWithoutCycle, uint64_t* outPhys) { if (!dev || !dev->Ep0Ring) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (dev->Ep0Enqueue >= XHCI_EP0_RING_TRBS - 1u) { XHCI_TRB* link = &dev->Ep0Ring[XHCI_EP0_RING_TRBS - 1u]; @@ -1161,7 +1161,7 @@ KSTATUS XhciEp0AppendTrb(XHCI_DEVICE* dev, trb->Control = controlWithoutCycle | dev->Ep0Cycle; if (outPhys) *outPhys = phys; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KSTATUS XhciControlInTimeout(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, @@ -1171,7 +1171,7 @@ KSTATUS XhciControlInTimeout(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, uint16_t length, uint32_t timeoutUs) { if (!buffer || length == 0 || length > PAGE_SIZE) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; memset(buffer, 0, length); @@ -1223,13 +1223,13 @@ KSTATUS XhciControlInTimeout(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, return st; } if (target.Transfer.CompletionCode == XHCI_CC_SUCCESS) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; DbgPrint("usb: xHCI control IN failed slot=%u cc=%u residue=%u\n", dev->SlotId, target.Transfer.CompletionCode, target.Transfer.Residue); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } KSTATUS XhciControlIn(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, @@ -1282,13 +1282,13 @@ KSTATUS XhciControlNoData(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, return st; } if (target.Transfer.CompletionCode == XHCI_CC_SUCCESS) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; DbgPrint("usb: xHCI control no-data failed slot=%u cc=%u residue=%u\n", dev->SlotId, target.Transfer.CompletionCode, target.Transfer.Residue); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } KSTATUS XhciGetDeviceDescriptorTimeout(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, @@ -1314,10 +1314,10 @@ KSTATUS XhciGetDeviceDescriptorTimeout(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, outDesc->bDescriptorType != USB_DESC_DEVICE) { DbgPrint("usb: invalid device descriptor slot=%u len=%u type=%u\n", dev->SlotId, outDesc->bLength, outDesc->bDescriptorType); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KSTATUS XhciGetDeviceDescriptor(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, @@ -1353,7 +1353,7 @@ KSTATUS XhciGetConfigurationDescriptor(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, outConfig->bLength, outConfig->bDescriptorType, outConfig->wTotalLength); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } uint16_t total = outConfig->wTotalLength; @@ -1378,11 +1378,11 @@ KSTATUS XhciGetConfigurationDescriptor(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, configurationIndex, outConfig->bLength, outConfig->bDescriptorType); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } if (outTotalLength) *outTotalLength = total; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the endpoint Id From Address operation. @@ -1420,7 +1420,7 @@ KSTATUS XhciRingAppend(XHCI_TRB* ring, PHYSICAL_ADDRESS ringPhys, uint64_t parameter, uint32_t status, uint32_t controlWithoutCycle, uint64_t* outPhys) { if (!ring || !enqueue || !cycle || trbCount < 2) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (*enqueue >= trbCount - 1u) { XHCI_TRB* link = &ring[trbCount - 1u]; @@ -1446,7 +1446,7 @@ KSTATUS XhciRingAppend(XHCI_TRB* ring, PHYSICAL_ADDRESS ringPhys, trb->Control = controlWithoutCycle | *cycle; if (outPhys) *outPhys = phys; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } void XhciInitialiseTransferRing(XHCI_TRB* ring, PHYSICAL_ADDRESS ringPhys, @@ -1471,9 +1471,9 @@ KSTATUS XhciBulkTransfer(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, uint32_t length, uint32_t* outActual) { if (!xhci || !dev || !ring || !enqueue || !cycle || !bufferPhys || length == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (length > USB_STORAGE_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint64_t trbPhys = 0; KSTATUS st = XhciRingAppend(ring, @@ -1511,36 +1511,36 @@ KSTATUS XhciBulkTransfer(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, endpointId, target.Transfer.CompletionCode, target.Transfer.Residue); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } if (outActual) *outActual = length - target.Transfer.Residue; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the configure Pipe Endpoint operation. KSTATUS XhciConfigurePipeEndpoint(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, USB_PIPE* pipe) { if (!xhci || !dev || !pipe || !pipe->Open) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint8_t dci = pipe->EndpointId; if (dci < 2 || dci > 31) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (pipe->HcdPipeContext) { XHCI_PIPE_CONTEXT* ctx = (XHCI_PIPE_CONTEXT*)pipe->HcdPipeContext; - return ctx->Configured ? STATUS_SUCCESS : STATUS_DEVICE_ERROR; + return ctx->Configured ? NTLSTATUS_SUCCESS : NTLSTATUS_DEVICE_ERROR; } XHCI_PIPE_CONTEXT* ctx = (XHCI_PIPE_CONTEXT*)MmAllocatePool(sizeof(XHCI_PIPE_CONTEXT)); - if (!ctx) return STATUS_NO_MEMORY; + if (!ctx) return NTLSTATUS_NO_MEMORY; memset(ctx, 0, sizeof(*ctx)); ctx->Ring = (XHCI_TRB*)UsbDmaAllocPages(xhci, 1, &ctx->RingPhys); if (!ctx->Ring) { MmFreePool(ctx); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } ctx->Enqueue = 0; ctx->Cycle = 1; @@ -1575,7 +1575,7 @@ KSTATUS XhciConfigurePipeEndpoint(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, USB_P endpointType = XHCI_EP_TYPE_BULK_OUT; } else { MmFreePool(ctx); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } ep[0] = (uint32_t)interval << 16; @@ -1597,31 +1597,31 @@ KSTATUS XhciConfigurePipeEndpoint(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, USB_P DbgPrint("usb: Configure pipe endpoint failed slot=%u ep=%u type=%u st=0x%x cc=%u\n", dev->SlotId, dci, pipe->Type, st, result.CompletionCode); MmFreePool(ctx); - return KSUCCESS(st) ? STATUS_DEVICE_ERROR : st; + return KSUCCESS(st) ? NTLSTATUS_DEVICE_ERROR : st; } ctx->Configured = true; pipe->HcdPipeContext = ctx; dev->EndpointPipes[dci] = pipe; UsbReferencePipe(pipe); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the hcd Submit Interrupt Urb operation. static KSTATUS XhciHcdSubmitInterruptUrb(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, USB_URB* urb) { if (!xhci || !dev || !urb || !urb->Pipe || !urb->BufferPhys || urb->Length == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (urb->Pipe->Type != UsbPipeInterrupt || !(urb->Pipe->EndpointAddress & USB_ENDPOINT_DIR_IN)) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; KSTATUS st = XhciConfigurePipeEndpoint(xhci, dev, urb->Pipe); if (!KSUCCESS(st)) return st; XHCI_PIPE_CONTEXT* ctx = (XHCI_PIPE_CONTEXT*)urb->Pipe->HcdPipeContext; if (!ctx || !ctx->Configured) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; if (ctx->ActiveTransfer) - return STATUS_QUEUE_FULL; + return NTLSTATUS_QUEUE_FULL; uint64_t trbPhys = 0; st = XhciRingAppend(ctx->Ring, @@ -1642,13 +1642,13 @@ static KSTATUS XhciHcdSubmitInterruptUrb(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev ctx->ActiveUrb = urb; urb->Pending = true; urb->Cancelled = false; - urb->Status = STATUS_PENDING; + urb->Status = NTLSTATUS_PENDING; urb->ActualLength = 0; urb->HcdCompletionCode = 0; XhciBarrier(); XhciWrite32(xhci->Doorbells, (uint32_t)dev->SlotId * 4u, ctx->EndpointId); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } void XhciHandleAsyncTransferEvent(XHCI_CONTROLLER* xhci, uint64_t trbPhys, @@ -1674,12 +1674,12 @@ void XhciHandleAsyncTransferEvent(XHCI_CONTROLLER* xhci, uint64_t trbPhys, if (!urb) return; - KSTATUS st = STATUS_SUCCESS; + KSTATUS st = NTLSTATUS_SUCCESS; if (urb->Cancelled) { - st = STATUS_CANCELLED; + st = NTLSTATUS_CANCELLED; } else if (completionCode != XHCI_CC_SUCCESS && completionCode != XHCI_CC_SHORT_PACKET) { - st = STATUS_DEVICE_ERROR; + st = NTLSTATUS_DEVICE_ERROR; } uint32_t actual = 0; @@ -1705,7 +1705,7 @@ void XhciHandleAsyncTransferEvent(XHCI_CONTROLLER* xhci, uint64_t trbPhys, // Implements the hcd Submit Bulk Urb operation. static KSTATUS XhciHcdSubmitBulkUrb(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, USB_URB* urb) { if (!xhci || !dev || !urb || !urb->Pipe || !urb->BufferPhys || urb->Length == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint8_t endpointId = urb->Pipe->EndpointId; XHCI_TRB* ring = (XHCI_TRB*)0; @@ -1724,7 +1724,7 @@ static KSTATUS XhciHcdSubmitBulkUrb(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, USB enqueue = &dev->MassOutEnqueue; cycle = &dev->MassOutCycle; } else { - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } uint32_t actual = 0; @@ -1745,12 +1745,12 @@ static KSTATUS XhciHcdSubmitBulkUrb(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, USB // Implements the hcd Submit Urb operation. static KSTATUS XhciHcdSubmitUrb(USB_HCD* hcd, USB_URB* urb) { if (!hcd || !urb || !urb->Device) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; XHCI_CONTROLLER* xhci = (XHCI_CONTROLLER*)hcd->ControllerContext; XHCI_DEVICE* dev = (XHCI_DEVICE*)urb->Device->HcdDeviceContext; if (!xhci || !dev || !dev->Allocated) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS st; switch (urb->Function) { @@ -1762,7 +1762,7 @@ static KSTATUS XhciHcdSubmitUrb(USB_HCD* hcd, USB_URB* urb) { st = XhciControlIn(xhci, dev, &urb->Setup, urb->Buffer, urb->BufferPhys, (uint16_t)urb->Length); urb->ActualLength = KSUCCESS(st) ? urb->Length : 0; } else { - st = STATUS_NOT_SUPPORTED; + st = NTLSTATUS_NOT_SUPPORTED; urb->ActualLength = 0; } break; @@ -1776,7 +1776,7 @@ static KSTATUS XhciHcdSubmitUrb(USB_HCD* hcd, USB_URB* urb) { break; default: - st = STATUS_NOT_SUPPORTED; + st = NTLSTATUS_NOT_SUPPORTED; urb->ActualLength = 0; break; } @@ -1788,11 +1788,11 @@ static KSTATUS XhciHcdSubmitUrb(USB_HCD* hcd, USB_URB* urb) { // Implements the hcd Cancel Urb operation. static KSTATUS XhciHcdCancelUrb(USB_HCD* hcd, USB_URB* urb) { (void)hcd; - if (!urb) return STATUS_INVALID_PARAMETER; + if (!urb) return NTLSTATUS_INVALID_PARAMETER; urb->Cancelled = true; if (!urb->Pending) - urb->Status = STATUS_CANCELLED; - return STATUS_SUCCESS; + urb->Status = NTLSTATUS_CANCELLED; + return NTLSTATUS_SUCCESS; } // Implements the hcd Allocate Dma operation. @@ -1803,15 +1803,15 @@ static void* XhciHcdAllocateDma(USB_HCD* hcd, size_t pages, PHYSICAL_ADDRESS* ou // Implements the hcd Reset Root Port operation. static KSTATUS XhciHcdResetRootPort(USB_HCD* hcd, uint8_t port, uint8_t* outSpeed) { - if (!hcd) return STATUS_INVALID_PARAMETER; + if (!hcd) return NTLSTATUS_INVALID_PARAMETER; return XhciResetPort((XHCI_CONTROLLER*)hcd->ControllerContext, port, outSpeed); } // Implements the hcd Clear Root Port Changes operation. static KSTATUS XhciHcdClearRootPortChanges(USB_HCD* hcd, uint8_t port) { - if (!hcd) return STATUS_INVALID_PARAMETER; + if (!hcd) return NTLSTATUS_INVALID_PARAMETER; XhciClearPortChanges((XHCI_CONTROLLER*)hcd->ControllerContext, port); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } const USB_HCD_OPERATIONS gXhciHcdOperations = { @@ -1825,9 +1825,9 @@ const USB_HCD_OPERATIONS gXhciHcdOperations = { // Starts controller. KSTATUS XhciStartController(XHCI_CONTROLLER* xhci) { if (!xhci || xhci->Magic != XHCI_CONTROLLER_MAGIC || !xhci->Pdo || !xhci->Fdo) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (xhci->Running) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; KSTATUS st = PciGetDeviceInfo(xhci->Pdo, &xhci->PciInfo); if (!KSUCCESS(st)) { @@ -1848,7 +1848,7 @@ KSTATUS XhciStartController(XHCI_CONTROLLER* xhci) { if (xhci->MmioBar.Type != PciBarMemory32 && xhci->MmioBar.Type != PciBarMemory64) { DbgPrint("usb: xHCI PCI %02x:%02x.%x BAR0 is not MMIO type=%u\n", xhci->Bus, xhci->Dev, xhci->Fn, xhci->MmioBar.Type); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } xhci->Irq = 0xFFu; @@ -1914,7 +1914,7 @@ KSTATUS XhciStartController(XHCI_CONTROLLER* xhci) { xhci->MaxSlots == 0 || xhci->MaxPorts == 0) { DbgPrint("usb: xHCI invalid caps caplen=%u dboff=0x%x rtsoff=0x%x hcs1=%08x\n", xhci->CapLength, xhci->DbOff, xhci->RtsOff, xhci->Hcs1); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } uint32_t portEnd = xhci->CapLength + XHCI_OP_PORT_BASE + @@ -1926,7 +1926,7 @@ KSTATUS XhciStartController(XHCI_CONTROLLER* xhci) { if (xhci->MmioBytes < needBytes) { DbgPrint("usb: xHCI BAR0 too small length=0x%x need=0x%x dboff=0x%x rtsoff=0x%x ports=%u\n", xhci->MmioBytes, needBytes, xhci->DbOff, xhci->RtsOff, xhci->MaxPorts); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } xhci->Op = xhci->Mmio + xhci->CapLength; @@ -1957,7 +1957,7 @@ KSTATUS XhciStartController(XHCI_CONTROLLER* xhci) { uint32_t pageSize = XhciRead32(xhci->Op, XHCI_OP_PAGESIZE); if ((pageSize & 1u) == 0) { DbgPrint("usb: xHCI does not advertise 4K pages pagesize=%08x\n", pageSize); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } st = XhciAllocateRuntimeMemory(xhci); @@ -1976,7 +1976,7 @@ KSTATUS XhciStartController(XHCI_CONTROLLER* xhci) { XhciLogPortStatus(xhci); st = UsbCreateRootHubPdo(&xhci->Hcd); - if (!KSUCCESS(st) && st != STATUS_ALREADY_EXISTS) { + if (!KSUCCESS(st) && st != NTLSTATUS_ALREADY_EXISTS) { DbgPrint("usb: root hub PDO creation failed st=0x%x\n", st); return st; } @@ -2008,20 +2008,20 @@ KSTATUS XhciStartController(XHCI_CONTROLLER* xhci) { DbgPrint("usb: xHCI host controller initialised; HID boot input active=%u mass-storage will arrive through hotplug\n", xhci->HidDeviceCount); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Dispatches pnp. KSTATUS XhciDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { if (!device || !irp || !device->DeviceExtension) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; XHCI_CONTROLLER* xhci = (XHCI_CONTROLLER*)device->DeviceExtension; if (xhci->Magic != XHCI_CONTROLLER_MAGIC) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); - if (!ios) return STATUS_INVALID_PARAMETER; + if (!ios) return NTLSTATUS_INVALID_PARAMETER; switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) { case IRP_MN_START_DEVICE: @@ -2029,11 +2029,11 @@ KSTATUS XhciDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { case IRP_MN_QUERY_REMOVE_DEVICE: device->PnpState = DevicePnpRemovePending; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_CANCEL_REMOVE_DEVICE: device->PnpState = xhci->Running ? DevicePnpStarted : DevicePnpNotStarted; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_SURPRISE_REMOVAL: device->PnpState = DevicePnpSurpriseRemoved; @@ -2045,7 +2045,7 @@ KSTATUS XhciDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { } if (xhci->Hcd.RootHubPdo) (void)UsbRemovePdoSubtree(xhci->Hcd.RootHubPdo, true); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_REMOVE_DEVICE: device->PnpState = DevicePnpDeleted; @@ -2055,7 +2055,7 @@ KSTATUS XhciDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { (void)UsbRemovePdoSubtree(xhci->Hcd.RootHubPdo, true); IoDetachDevice(device); IoDeleteDevice(device); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; default: return IoForwardIrpToLower(device, irp); @@ -2065,7 +2065,7 @@ KSTATUS XhciDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { // Implements the add Device operation. KSTATUS XhciAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) { if (!driver || !physicalDeviceObject || physicalDeviceObject->Type != DeviceObjectPhysical) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* fdo = (DEVICE_OBJECT*)0; KSTATUS st = IoCreateDevice(driver, sizeof(XHCI_CONTROLLER), &fdo); @@ -2085,9 +2085,9 @@ KSTATUS XhciAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject xhci->LowerDevice = IoAttachDeviceToDeviceStack(fdo, physicalDeviceObject); if (!xhci->LowerDevice) { IoDeleteDevice(fdo); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } DbgPrint("usb: xHCI FDO attached to %v\n", physicalDeviceObject->Name); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } diff --git a/code/drivers/display/vmwaresvga/vmwaresvga.c b/code/drivers/display/vmwaresvga/vmwaresvga.c index d7b8740..482649f 100644 --- a/code/drivers/display/vmwaresvga/vmwaresvga.c +++ b/code/drivers/display/vmwaresvga/vmwaresvga.c @@ -46,7 +46,7 @@ static uint32_t VmwSvgaProbeId(VMWSVGA_DEVICE* v) { // Chooses the runtime display mode, preferring the current boot framebuffer size. static KSTATUS VmwSvgaChooseMode(uint32_t* outWidth, uint32_t* outHeight) { if (!outWidth || !outHeight) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DISPLAY_MODE current; memset(¤t, 0, sizeof(current)); @@ -55,12 +55,12 @@ static KSTATUS VmwSvgaChooseMode(uint32_t* outWidth, uint32_t* outHeight) { current.Width > 0 && current.Height > 0) { *outWidth = current.Width; *outHeight = current.Height; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } *outWidth = 1024; *outHeight = 768; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Programs the visible guest display rectangle used by the legacy framebuffer path. @@ -81,7 +81,7 @@ static void VmwSvgaProgramLegacyDisplayTopology(VMWSVGA_DEVICE* v, uint32_t widt // Programs the SVGA device mode before FIFO and framebuffer use. static KSTATUS VmwSvgaSetMode(VMWSVGA_DEVICE* v) { if (!v) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t desiredWidth = 0; uint32_t desiredHeight = 0; @@ -97,7 +97,7 @@ static KSTATUS VmwSvgaSetMode(VMWSVGA_DEVICE* v) { if (maxHeight && desiredHeight > maxHeight) desiredHeight = maxHeight; if (desiredWidth == 0 || desiredHeight == 0) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; VmwSvgaWriteReg(v, SVGA_REG_CONFIG_DONE, 0u); VmwSvgaWriteReg(v, SVGA_REG_ENABLE, 0u); @@ -116,7 +116,7 @@ static KSTATUS VmwSvgaSetMode(VMWSVGA_DEVICE* v) { DbgPrint("VMWSVGA: requested mode %ux%u max=%ux%u caps=0x%x\n", desiredWidth, desiredHeight, maxWidth, maxHeight, caps); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Clips a display rectangle to the current framebuffer bounds. @@ -156,18 +156,18 @@ static uint32_t VmwSvgaFifoNext(VMWSVGA_DEVICE* v, uint32_t offset) { // Writes one command dword into the SVGA FIFO and waits for space if needed. static KSTATUS VmwSvgaFifoWrite(VMWSVGA_DEVICE* v, uint32_t value) { if (!v || !v->FifoReady || !v->Fifo) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; uint32_t min = v->Fifo[SVGA_FIFO_MIN]; uint32_t max = v->Fifo[SVGA_FIFO_MAX]; if (min < SVGA_FIFO_NUM_LEGACY_REGS * sizeof(uint32_t) || max > v->FifoBytes || min >= max) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; for (uint32_t guard = 0; guard < VMWSVGA_MAX_WAIT_ITERS; guard++) { uint32_t next = v->Fifo[SVGA_FIFO_NEXT_CMD]; uint32_t stop = v->Fifo[SVGA_FIFO_STOP]; if (next < min || next >= max || stop < min || stop >= max) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; uint32_t nextAfter = VmwSvgaFifoNext(v, next); if (nextAfter != stop) { @@ -175,7 +175,7 @@ static KSTATUS VmwSvgaFifoWrite(VMWSVGA_DEVICE* v, uint32_t value) { _ReadWriteBarrier(); v->Fifo[SVGA_FIFO_NEXT_CMD] = nextAfter; _ReadWriteBarrier(); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KSTATUS syncSt = VmwSvgaSyncDevice(v); @@ -183,7 +183,7 @@ static KSTATUS VmwSvgaFifoWrite(VMWSVGA_DEVICE* v, uint32_t value) { return syncSt; } - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } // Checks whether an extended FIFO register is valid for this device. @@ -406,14 +406,14 @@ static KSTATUS VmwSvgaDefineClassicCursor(VMWSVGA_DEVICE* v, int width, int heig size_t pixelCount = (size_t)encodedWidth * (size_t)height; if (encodedWidth > 256 || pixelCount > 256u * 256u) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint8_t* andBits = (uint8_t*)MmAllocatePool(pixelCount); uint8_t* xorBits = (uint8_t*)MmAllocatePool(pixelCount); if (!andBits || !xorBits) { if (andBits) MmFreePool(andBits); if (xorBits) MmFreePool(xorBits); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } VmwSvgaBuildMonoCursorBits(argbPixels, width, encodedWidth, height, andBits, xorBits); @@ -463,9 +463,9 @@ done: // Implements the upload Cursor Image operation. static KSTATUS VmwSvgaUploadCursorImage(VMWSVGA_DEVICE* v, int width, int height, int hotX, int hotY, const uint32_t* argbPixels) { if (!v || !v->HardwareCursor || !argbPixels || width <= 0 || height <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (width > 256 || height > 256 || hotX < 0 || hotY < 0 || hotX >= width || hotY >= height) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS st; if (v->AlphaCursor) @@ -481,14 +481,14 @@ static KSTATUS VmwSvgaUploadCursorImage(VMWSVGA_DEVICE* v, int width, int height // Implements the define Cursor Image operation. static KSTATUS VmwSvgaDefineCursorImage(VMWSVGA_DEVICE* v, int width, int height, int hotX, int hotY, const uint32_t* argbPixels) { if (!v || !v->HardwareCursor || !argbPixels || width <= 0 || height <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (width > 256 || height > 256 || hotX < 0 || hotY < 0 || hotX >= width || hotY >= height) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; size_t bytes = (size_t)width * (size_t)height * sizeof(uint32_t); uint32_t* copy = (uint32_t*)MmAllocatePool(bytes); if (!copy) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; memcpy(copy, argbPixels, bytes); KSTATUS st = VmwSvgaUploadCursorImage(v, width, height, hotX, hotY, copy); @@ -506,7 +506,7 @@ static KSTATUS VmwSvgaDefineCursorImage(VMWSVGA_DEVICE* v, int width, int height v->CursorHotX = hotX; v->CursorHotY = hotY; v->CursorImageDefined = true; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the align Up32 operation. @@ -517,7 +517,7 @@ static uint32_t VmwSvgaAlignUp32(uint32_t value, uint32_t alignment) { // Implements the define Screen Object operation. static KSTATUS VmwSvgaDefineScreenObject(VMWSVGA_DEVICE* v) { if (!v || !v->FifoReady || !v->UseScreenObject) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS st = VmwSvgaFifoWrite(v, SVGA_CMD_DEFINE_SCREEN); if (!KSUCCESS(st)) return st; @@ -552,7 +552,7 @@ static KSTATUS VmwSvgaDefineScreenObject(VMWSVGA_DEVICE* v) { // Implements the define Gmrfb operation. static KSTATUS VmwSvgaDefineGmrfb(VMWSVGA_DEVICE* v) { if (!v || !v->FifoReady || !v->UseScreenObject) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS st = VmwSvgaFifoWrite(v, SVGA_CMD_DEFINE_GMRFB); if (!KSUCCESS(st)) return st; @@ -564,14 +564,14 @@ static KSTATUS VmwSvgaDefineGmrfb(VMWSVGA_DEVICE* v) { if (!KSUCCESS(st)) return st; st = VmwSvgaFifoWrite(v, SVGA_GMRFB_FORMAT_32BPP_24DEPTH); if (!KSUCCESS(st)) return st; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Blits gmrfb To Screen. static KSTATUS VmwSvgaBlitGmrfbToScreen(VMWSVGA_DEVICE* v, int x, int y, int w, int h) { DISPLAY_RECT r = { x, y, w, h }; if (!VmwSvgaClipRect(v, &r)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; KSTATUS st = VmwSvgaFifoWrite(v, SVGA_CMD_BLIT_GMRFB_TO_SCREEN); if (!KSUCCESS(st)) return st; @@ -591,13 +591,13 @@ static KSTATUS VmwSvgaBlitGmrfbToScreen(VMWSVGA_DEVICE* v, int x, int y, int w, if (!KSUCCESS(st)) return st; VmwSvgaWakeFifo(v); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Initializes screen Object. static KSTATUS VmwSvgaInitializeScreenObject(VMWSVGA_DEVICE* v) { if (!v || !v->FifoReady) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DbgPrint("VMWSVGA: screen object probe caps=0x%x fifoCaps=0x%x\n", v->Capabilities, v->FifoCaps); @@ -616,7 +616,7 @@ static KSTATUS VmwSvgaInitializeScreenObject(VMWSVGA_DEVICE* v) { hasScreenObject2 ? 1u : 0u, v->Capabilities, v->FifoCaps); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } DbgPrint("VMWSVGA: using screen object generation %u\n", hasScreenObject2 ? 2u : 1u); @@ -630,7 +630,7 @@ static KSTATUS VmwSvgaInitializeScreenObject(VMWSVGA_DEVICE* v) { (uint64_t)backingOffset + backingBytes > v->FramebufferBytes) { DbgPrint("VMWSVGA: screen object disabled; insufficient GFB source=0x%x backing=0x%x fbLen=0x%llx\n", sourceBytes, backingBytes, (unsigned long long)v->FramebufferBytes); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } v->ScreenId = SVGA_SCREEN_OBJECT_ID_PRIMARY; @@ -655,14 +655,14 @@ static KSTATUS VmwSvgaInitializeScreenObject(VMWSVGA_DEVICE* v) { DbgPrint("VMWSVGA: screen object enabled id=%u sourceOff=0x%x backingOff=0x%x bytes=0x%x\n", v->ScreenId, v->ScreenSourceOffset, v->ScreenBackingOffset, v->ScreenSourceBytes); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the legacy Update operation. static KSTATUS VmwSvgaLegacyUpdate(VMWSVGA_DEVICE* v, int x, int y, int w, int h) { DISPLAY_RECT r = { x, y, w, h }; if (!VmwSvgaClipRect(v, &r)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; KSTATUS st = VmwSvgaFifoWrite(v, SVGA_CMD_UPDATE); if (!KSUCCESS(st)) return st; @@ -676,14 +676,14 @@ static KSTATUS VmwSvgaLegacyUpdate(VMWSVGA_DEVICE* v, int x, int y, int w, int h if (!KSUCCESS(st)) return st; VmwSvgaWakeFifo(v); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Updates the requested value. static KSTATUS VmwSvgaUpdate(VMWSVGA_DEVICE* v, int x, int y, int w, int h) { DISPLAY_RECT r = { x, y, w, h }; if (!VmwSvgaClipRect(v, &r)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; v->Stats.DirtyRectCount++; @@ -699,17 +699,17 @@ static KSTATUS VmwSvgaUpdate(VMWSVGA_DEVICE* v, int x, int y, int w, int h) { // Waits until the SVGA host has consumed the queued FIFO work. static KSTATUS VmwSvgaSyncDevice(VMWSVGA_DEVICE* v) { if (!v) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; v->Stats.SyncCount++; VmwSvgaWriteReg(v, SVGA_REG_SYNC, 1u); for (uint32_t guard = 0; guard < VMWSVGA_MAX_WAIT_ITERS; guard++) { if (VmwSvgaReadReg(v, SVGA_REG_BUSY) == 0) { if (VmwSvgaHasFifoRegister(v, SVGA_FIFO_BUSY)) v->Fifo[SVGA_FIFO_BUSY] = 0u; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } // Implements the blend Pixel operation. @@ -740,23 +740,23 @@ static VMWSVGA_DEVICE* VmwSvgaFromDisplay(DISPLAY_DEVICE* device) { static KSTATUS VmwSvgaDisplayGetMode(DISPLAY_DEVICE* device, DISPLAY_MODE* outMode) { VMWSVGA_DEVICE* v = VmwSvgaFromDisplay(device); if (!v || !outMode || !v->Framebuffer) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; outMode->Width = v->Width; outMode->Height = v->Height; outMode->Stride = v->Stride; outMode->Format = DisplayPixelFormatX8R8G8B8; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the display Blit operation. static KSTATUS VmwSvgaDisplayBlit(DISPLAY_DEVICE* device, int x, int y, int w, int h, const uint32_t* pixels) { VMWSVGA_DEVICE* v = VmwSvgaFromDisplay(device); if (!v || !v->Backbuffer || !pixels || w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DISPLAY_RECT r = { x, y, w, h }; if (!VmwSvgaClipRect(v, &r)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; v->Stats.BlitCount++; v->Stats.BytesCopied += (uint64_t)(uint32_t)r.W * (uint64_t)(uint32_t)r.H * sizeof(uint32_t); @@ -769,18 +769,18 @@ static KSTATUS VmwSvgaDisplayBlit(DISPLAY_DEVICE* device, int x, int y, int w, i const uint32_t* src = pixels + ((size_t)(srcOffsetY + row) * (size_t)w) + srcOffsetX; memcpy(dst, src, bytesPerRow); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the display Fill Rect operation. static KSTATUS VmwSvgaDisplayFillRect(DISPLAY_DEVICE* device, int x, int y, int w, int h, uint32_t color) { VMWSVGA_DEVICE* v = VmwSvgaFromDisplay(device); if (!v || !v->Backbuffer || w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DISPLAY_RECT r = { x, y, w, h }; if (!VmwSvgaClipRect(v, &r)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; v->Stats.FillRectCount++; v->Stats.BytesCopied += (uint64_t)(uint32_t)r.W * (uint64_t)(uint32_t)r.H * sizeof(uint32_t); @@ -790,14 +790,14 @@ static KSTATUS VmwSvgaDisplayFillRect(DISPLAY_DEVICE* device, int x, int y, int for (int xx = 0; xx < r.W; xx++) *dst++ = color; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the display Copy Rect operation. static KSTATUS VmwSvgaDisplayCopyRect(DISPLAY_DEVICE* device, int dstX, int dstY, int srcX, int srcY, int w, int h) { VMWSVGA_DEVICE* v = VmwSvgaFromDisplay(device); if (!v || !v->Backbuffer || w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (srcX < 0) { int d = -srcX; srcX = 0; dstX += d; w -= d; } if (srcY < 0) { int d = -srcY; srcY = 0; dstY += d; h -= d; } @@ -808,7 +808,7 @@ static KSTATUS VmwSvgaDisplayCopyRect(DISPLAY_DEVICE* device, int dstX, int dstY if (srcY + h > (int)v->Height) h = (int)v->Height - srcY; if (dstY + h > (int)v->Height) h = (int)v->Height - dstY; if (w <= 0 || h <= 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; v->Stats.CopyRectCount++; v->Stats.BytesCopied += (uint64_t)(uint32_t)w * (uint64_t)(uint32_t)h * sizeof(uint32_t); @@ -827,18 +827,18 @@ static KSTATUS VmwSvgaDisplayCopyRect(DISPLAY_DEVICE* device, int dstX, int dstY memmove(dst, src, rowBytes); } } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the display Read Rect operation. static KSTATUS VmwSvgaDisplayReadRect(DISPLAY_DEVICE* device, int x, int y, int w, int h, uint32_t* outPixels, uint32_t outStride) { VMWSVGA_DEVICE* v = VmwSvgaFromDisplay(device); if (!v || !v->Backbuffer || !outPixels || outStride == 0 || w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DISPLAY_RECT r = { x, y, w, h }; if (!VmwSvgaClipRect(v, &r)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; v->Stats.ReadRectCount++; v->Stats.BytesCopied += (uint64_t)(uint32_t)r.W * (uint64_t)(uint32_t)r.H * sizeof(uint32_t); @@ -850,21 +850,21 @@ static KSTATUS VmwSvgaDisplayReadRect(DISPLAY_DEVICE* device, int x, int y, int uint32_t* dst = outPixels + ((size_t)(dstOffsetY + row) * outStride) + dstOffsetX; memcpy(dst, src, (size_t)r.W * sizeof(uint32_t)); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the display Present operation. static KSTATUS VmwSvgaDisplayPresent(DISPLAY_DEVICE* device, const DISPLAY_RECT* rects, size_t rectCount) { VMWSVGA_DEVICE* v = VmwSvgaFromDisplay(device); if (!v || !v->Framebuffer || !v->Backbuffer) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!rects || rectCount == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; v->Stats.PresentCount++; v->Stats.PresentRectCount += rectCount; - KSTATUS result = STATUS_SUCCESS; + KSTATUS result = NTLSTATUS_SUCCESS; for (size_t i = 0; i < rectCount; i++) { DISPLAY_RECT r = rects[i]; if (!VmwSvgaClipRect(v, &r)) @@ -902,7 +902,7 @@ static KSTATUS VmwSvgaDisplaySync(DISPLAY_DEVICE* device) { static KSTATUS VmwSvgaDisplaySetCursorImage(DISPLAY_DEVICE* device, int width, int height, int hotX, int hotY, const uint32_t* argbPixels) { VMWSVGA_DEVICE* v = VmwSvgaFromDisplay(device); if (!v || !v->HardwareCursor) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; return VmwSvgaDefineCursorImage(v, width, height, hotX, hotY, argbPixels); } @@ -910,13 +910,13 @@ static KSTATUS VmwSvgaDisplaySetCursorImage(DISPLAY_DEVICE* device, int width, i static KSTATUS VmwSvgaDisplaySetCursorPosition(DISPLAY_DEVICE* device, int x, int y) { VMWSVGA_DEVICE* v = VmwSvgaFromDisplay(device); if (!v) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; v->CursorX = x; v->CursorY = y; v->Stats.CursorMoveCount++; if (v->HardwareCursor && v->CursorImageDefined) VmwSvgaCursorSetPosition(v, x, y); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the restore Cursor operation. @@ -976,11 +976,11 @@ static void VmwSvgaDrawCursor(VMWSVGA_DEVICE* v) { static KSTATUS VmwSvgaDisplayShowCursor(DISPLAY_DEVICE* device, bool show) { VMWSVGA_DEVICE* v = VmwSvgaFromDisplay(device); if (!v) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (v->HardwareCursor) { if (!v->CursorImageDefined) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (show) { v->Stats.CursorShowCount++; VmwSvgaCursorSetPosition(v, v->CursorX, v->CursorY); @@ -989,11 +989,11 @@ static KSTATUS VmwSvgaDisplayShowCursor(DISPLAY_DEVICE* device, bool show) { v->Stats.CursorHideCount++; VmwSvgaCursorSetVisible(v, false); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (!v->Framebuffer || !v->Backbuffer) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (show) { v->Stats.CursorShowCount++; @@ -1004,16 +1004,16 @@ static KSTATUS VmwSvgaDisplayShowCursor(DISPLAY_DEVICE* device, bool show) { v->Stats.CursorHideCount++; VmwSvgaRestoreCursor(v); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the display Query Stats operation. static KSTATUS VmwSvgaDisplayQueryStats(DISPLAY_DEVICE* device, DISPLAY_STATS* outStats) { VMWSVGA_DEVICE* v = VmwSvgaFromDisplay(device); if (!v || !outStats) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *outStats = v->Stats; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static const DISPLAY_DEVICE_OPS gVmwSvgaDisplayOps = { @@ -1039,7 +1039,7 @@ static KSTATUS VmwSvgaSelectBars(VMWSVGA_DEVICE* v) { if (!KSUCCESS(st) || bar.Type != PciBarIo || bar.Base > 0xFFFFu) { DbgPrint("VMWSVGA: BAR0 is not a usable I/O register BAR st=0x%x type=%u base=0x%llx\n", st, bar.Type, (unsigned long long)bar.Base); - return KSUCCESS(st) ? STATUS_NOT_SUPPORTED : st; + return KSUCCESS(st) ? NTLSTATUS_NOT_SUPPORTED : st; } v->IoBar = bar; v->IoBase = (uint16_t)bar.Base; @@ -1047,17 +1047,17 @@ static KSTATUS VmwSvgaSelectBars(VMWSVGA_DEVICE* v) { st = PciGetBar(v->Pdo, 1, &bar); if (!KSUCCESS(st) || (bar.Type != PciBarMemory32 && bar.Type != PciBarMemory64)) { DbgPrint("VMWSVGA: BAR1 is not a usable framebuffer BAR st=0x%x type=%u\n", st, bar.Type); - return KSUCCESS(st) ? STATUS_NOT_SUPPORTED : st; + return KSUCCESS(st) ? NTLSTATUS_NOT_SUPPORTED : st; } v->FramebufferBar = bar; st = PciGetBar(v->Pdo, 2, &bar); if (!KSUCCESS(st) || (bar.Type != PciBarMemory32 && bar.Type != PciBarMemory64)) { DbgPrint("VMWSVGA: BAR2 is not a usable FIFO BAR st=0x%x type=%u\n", st, bar.Type); - return KSUCCESS(st) ? STATUS_NOT_SUPPORTED : st; + return KSUCCESS(st) ? NTLSTATUS_NOT_SUPPORTED : st; } v->FifoBar = bar; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the mmio Page Flags operation. @@ -1076,7 +1076,7 @@ static KSTATUS VmwSvgaMapBars(VMWSVGA_DEVICE* v) { (unsigned long long)(uintptr_t)v->FramebufferMapping, (unsigned long long)v->FramebufferBar.Base, (unsigned long long)v->FramebufferBar.Length); - return KSUCCESS(st) ? STATUS_DEVICE_ERROR : st; + return KSUCCESS(st) ? NTLSTATUS_DEVICE_ERROR : st; } st = PciMapBar(v->Pdo, 2, mmioFlags, @@ -1087,7 +1087,7 @@ static KSTATUS VmwSvgaMapBars(VMWSVGA_DEVICE* v) { (unsigned long long)(uintptr_t)v->Fifo, (unsigned long long)v->FifoBar.Base, (unsigned long long)v->FifoBar.Length); - return KSUCCESS(st) ? STATUS_DEVICE_ERROR : st; + return KSUCCESS(st) ? NTLSTATUS_DEVICE_ERROR : st; } DbgPrint("VMWSVGA: BARs io=0x%04x fbBase=0x%llx fbLen=0x%llx fbVirt=0x%llx fifoBase=0x%llx fifoLen=0x%llx fifoVirt=0x%llx\n", @@ -1098,7 +1098,7 @@ static KSTATUS VmwSvgaMapBars(VMWSVGA_DEVICE* v) { (unsigned long long)v->FifoBar.Base, (unsigned long long)v->FifoBar.Length, (unsigned long long)(uintptr_t)v->Fifo); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns mode. @@ -1120,29 +1120,29 @@ static KSTATUS VmwSvgaReadMode(VMWSVGA_DEVICE* v) { if (v->Width == 0 || v->Height == 0 || v->BytesPerLine == 0) { DbgPrint("VMWSVGA: invalid mode %ux%u pitch=%u\n", v->Width, v->Height, v->BytesPerLine); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } if (v->BitsPerPixel != 32) { DbgPrint("VMWSVGA: unsupported bpp=%u\n", v->BitsPerPixel); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } if ((v->BytesPerLine & 3u) != 0) { DbgPrint("VMWSVGA: unsupported non-dword pitch=%u\n", v->BytesPerLine); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } v->Stride = v->BytesPerLine / sizeof(uint32_t); if (v->Stride < v->Width) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; if (!v->FramebufferMapping) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; uint64_t needed = (uint64_t)v->BytesPerLine * (uint64_t)v->Height; if (fbSize && needed > fbSize) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; if ((uint64_t)fbOffset > v->FramebufferBytes || needed > v->FramebufferBytes - (uint64_t)fbOffset) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; v->FramebufferOffset = fbOffset; v->Framebuffer = v->FramebufferMapping + fbOffset; @@ -1150,7 +1150,7 @@ static KSTATUS VmwSvgaReadMode(VMWSVGA_DEVICE* v) { v->BackbufferBytes = (size_t)needed; v->Backbuffer = (uint32_t*)MmAllocatePool(v->BackbufferBytes); if (!v->Backbuffer) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; memset(v->Backbuffer, 0, v->BackbufferBytes); @@ -1164,7 +1164,7 @@ static KSTATUS VmwSvgaReadMode(VMWSVGA_DEVICE* v) { fbStart, fifoSize, v->Capabilities); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns the active FIFO size reported by the device, not the larger PCI BAR aperture. @@ -1180,7 +1180,7 @@ static uint32_t VmwSvgaGetFifoMaxBytes(VMWSVGA_DEVICE* v) { // Initializes fifo. static KSTATUS VmwSvgaInitializeFifo(VMWSVGA_DEVICE* v) { if (!v->Fifo || v->FifoBytes < 4096u) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; VmwSvgaWriteReg(v, SVGA_REG_CONFIG_DONE, 0u); @@ -1195,7 +1195,7 @@ static KSTATUS VmwSvgaInitializeFifo(VMWSVGA_DEVICE* v) { min = SVGA_FIFO_NUM_LEGACY_REGS * sizeof(uint32_t); if (max <= min + 32u) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; v->FifoRegCount = min / sizeof(uint32_t); @@ -1221,15 +1221,15 @@ static KSTATUS VmwSvgaInitializeFifo(VMWSVGA_DEVICE* v) { v->FifoCaps, v->FifoDeviceBytes, (unsigned long long)v->FifoBytes); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Starts device. static KSTATUS VmwSvgaStartDevice(VMWSVGA_DEVICE* v) { if (!v || v->Magic != VMWSVGA_DEVICE_MAGIC || !v->Fdo || !v->Pdo) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (v->Started) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; KSTATUS st = PciGetDeviceInfo(v->Pdo, &v->PciInfo); if (!KSUCCESS(st)) @@ -1253,7 +1253,7 @@ static KSTATUS VmwSvgaStartDevice(VMWSVGA_DEVICE* v) { v->DeviceId = VmwSvgaProbeId(v); if (v->DeviceId == SVGA_ID_INVALID) { DbgPrint("VMWSVGA: SVGA ID probe failed\n"); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } VmwSvgaWriteReg(v, SVGA_REG_GUEST_ID, 0u); @@ -1284,7 +1284,7 @@ static KSTATUS VmwSvgaStartDevice(VMWSVGA_DEVICE* v) { #if VMWSVGA_ENABLE_SCREEN_OBJECTS KSTATUS screenSt = VmwSvgaInitializeScreenObject(v); - if (!KSUCCESS(screenSt) && screenSt != STATUS_NOT_SUPPORTED) + if (!KSUCCESS(screenSt) && screenSt != NTLSTATUS_NOT_SUPPORTED) DbgPrint("VMWSVGA: screen object init failed st=0x%x; using legacy GFB UPDATE\n", screenSt); #else v->UseScreenObject = false; @@ -1340,7 +1340,7 @@ static KSTATUS VmwSvgaStartDevice(VMWSVGA_DEVICE* v) { } st = KeDisplayRegisterDevice(&v->DisplayDevice); - if (!KSUCCESS(st) && st != STATUS_ALREADY_EXISTS) { + if (!KSUCCESS(st) && st != NTLSTATUS_ALREADY_EXISTS) { KeDisplaySuspendConsole(false); return st; } @@ -1356,21 +1356,21 @@ static KSTATUS VmwSvgaStartDevice(VMWSVGA_DEVICE* v) { (void)VmwSvgaDisplaySync(&v->DisplayDevice); DbgPrint("VMWSVGA: initialized as primary display id=0x%x io=0x%04x\n", v->DeviceId, v->IoBase); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Dispatches pnp. KSTATUS VmwSvgaDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { if (!device || !irp || !device->DeviceExtension) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; VMWSVGA_DEVICE* v = (VMWSVGA_DEVICE*)device->DeviceExtension; if (v->Magic != VMWSVGA_DEVICE_MAGIC) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios || ios->MajorFunction != IRP_MJ_PNP) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) { case IRP_MN_START_DEVICE: @@ -1378,12 +1378,12 @@ KSTATUS VmwSvgaDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE: - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_SURPRISE_REMOVAL: v->SurpriseRemoved = true; device->PnpState = DevicePnpSurpriseRemoved; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_REMOVE_DEVICE: v->Removed = true; @@ -1399,7 +1399,7 @@ KSTATUS VmwSvgaDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { } IoDetachDevice(device); IoDeleteDevice(device); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; default: return IoForwardIrpToLower(device, irp); @@ -1409,7 +1409,7 @@ KSTATUS VmwSvgaDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { // Implements the add Device operation. KSTATUS VmwSvgaAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) { if (!driver || !physicalDeviceObject || physicalDeviceObject->Type != DeviceObjectPhysical) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* fdo = NULL; KSTATUS st = IoCreateDevice(driver, sizeof(VMWSVGA_DEVICE), &fdo); @@ -1428,17 +1428,17 @@ KSTATUS VmwSvgaAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObj v->LowerDevice = IoAttachDeviceToDeviceStack(fdo, physicalDeviceObject); if (!v->LowerDevice) { IoDeleteDevice(fdo); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } DbgPrint("VMWSVGA: FDO attached to %v\n", physicalDeviceObject->Name); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the driver Entry operation. KSTATUS DriverEntry(const HAL_API* hal) { if (!hal) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DbgPrint("VMWSVGA: driver loading...\n"); gVmwSvgaHal = hal; diff --git a/code/drivers/fs/fat32/fat32.c b/code/drivers/fs/fat32/fat32.c index 2ca4980..3b3de6b 100644 --- a/code/drivers/fs/fat32/fat32.c +++ b/code/drivers/fs/fat32/fat32.c @@ -208,7 +208,7 @@ static KSTATUS FatCacheRead(FAT32_VOL *v, uint64_t lba, uint8_t **out) { if (e->valid && e->vol == v && e->lba == lba) { *out = e->data; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Evict current occupant: single-copy writeback on collision. @@ -226,7 +226,7 @@ static KSTATUS FatCacheRead(FAT32_VOL *v, uint64_t lba, uint8_t **out) { e->valid = true; e->dirty = false; *out = e->data; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the fat Cache Mark Dirty operation. @@ -285,13 +285,13 @@ typedef struct { // Raw sector I/O (bypasses FAT cache; used for file data and cache eviction). static KSTATUS ReadSectorsRaw(FAT32_VOL *v, uint64_t lba, uint32_t count, void *buf) { - if (!v) return STATUS_INVALID_PARAMETER; + if (!v) return NTLSTATUS_INVALID_PARAMETER; return IoReadDiskSectors(v->DriveIndex, lba, count, buf); } static KSTATUS WriteSectorsRaw(FAT32_VOL *v, uint64_t lba, uint32_t count, const void *buf) { - if (!v) return STATUS_INVALID_PARAMETER; + if (!v) return NTLSTATUS_INVALID_PARAMETER; return IoWriteDiskSectors(v->DriveIndex, lba, count, buf); } @@ -366,7 +366,7 @@ static KSTATUS WriteFatEntry(FAT32_VOL *v, uint32_t cluster, uint32_t value) { | (value & 0x0FFFFFFFu); FatCacheMarkDirty(v, sector); FatCacheRelease(held); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Cluster allocation (fix #3: next-free hint + two-phase wrap-around scan). @@ -535,7 +535,7 @@ static uint8_t FatEncodeCreateTimeTenth(const SYS_SYSTEM_TIME* t) { static void FatQueryEncodedTime(FAT32_ENCODED_TIME* out) { SYS_SYSTEM_TIME now; memset(&now, 0, sizeof(now)); - if (KeQuerySystemTime(&now) != STATUS_SUCCESS) { + if (KeQuerySystemTime(&now) != NTLSTATUS_SUCCESS) { now.Year = 1980; now.Month = 1; now.Day = 1; @@ -584,9 +584,9 @@ static void FatDecodeAccessDate(uint16_t date, SYS_SYSTEM_TIME* out) { static KSTATUS DirentUpdateMetadata(FAT32_VOL *v, uint64_t lba, uint32_t offset, const FAT32_DIRENT_UPDATE* update) { - if (!v || !update || !update->Flags) return STATUS_INVALID_PARAMETER; + if (!v || !update || !update->Flags) return NTLSTATUS_INVALID_PARAMETER; uint8_t *sec = (uint8_t *)MmAllocatePool(v->BytesPerSector); - if (!sec) return STATUS_NO_MEMORY; + if (!sec) return NTLSTATUS_NO_MEMORY; KSTATUS s = ReadSectors(v, lba, 1, sec); if (KSUCCESS(s)) { DIRENT *d = (DIRENT *)(sec + offset); @@ -967,13 +967,13 @@ static void MakeLegacyBrokenDot83V(SYS_STRING_VIEW src, char name8[8], char ext3 static KSTATUS DeleteLegacyBrokenDotAliasV(FAT32_VOL *v, uint32_t dirCluster, SYS_STRING_VIEW longName) { - if (!SysSvIsValid(longName) || longName.Length < 2 || longName.Data[0] != '.') return STATUS_SUCCESS; + if (!SysSvIsValid(longName) || longName.Length < 2 || longName.Data[0] != '.') return NTLSTATUS_SUCCESS; char badName[8], badExt[3]; MakeLegacyBrokenDot83V(longName, badName, badExt); uint8_t *clusterBuf = (uint8_t *)MmAllocatePool(v->BytesPerCluster); - if (!clusterBuf) return STATUS_NO_MEMORY; + if (!clusterBuf) return NTLSTATUS_NO_MEMORY; uint32_t cluster = dirCluster; while (cluster >= 2 && cluster < FAT32_EOC) { @@ -984,7 +984,7 @@ static KSTATUS DeleteLegacyBrokenDotAliasV(FAT32_VOL *v, uint32_t dirCluster, uint32_t entries = v->BytesPerCluster / sizeof(DIRENT); DIRENT *dir = (DIRENT *)clusterBuf; for (uint32_t i = 0; i < entries; i++) { - if (dir[i].Name[0] == 0x00) { MmFreePool(clusterBuf); return STATUS_SUCCESS; } + if (dir[i].Name[0] == 0x00) { MmFreePool(clusterBuf); return NTLSTATUS_SUCCESS; } if ((uint8_t)dir[i].Name[0] == 0xE5 || dir[i].Attr == ATTR_LFN) continue; if (MatchRaw83(dir[i].Name, dir[i].Ext, badName, badExt)) { int emptyBase = 1; @@ -1005,7 +1005,7 @@ static KSTATUS DeleteLegacyBrokenDotAliasV(FAT32_VOL *v, uint32_t dirCluster, } MmFreePool(clusterBuf); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the lfn Append operation. @@ -1419,9 +1419,9 @@ static KSTATUS Fat32LookupPathV(FAT32_VOL *v, SYS_STRING_VIEW path, uint8_t *outAttr, uint64_t *outDirentLba, uint32_t *outDirentOffset) { if (!v || !outCluster || !outSize || !SysSvIsValid(path)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (SysSvContainsByte(path, '\0')) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t cluster = v->RootCluster, size = 0; uint8_t attr = ATTR_DIRECTORY; @@ -1433,21 +1433,21 @@ static KSTATUS Fat32LookupPathV(FAT32_VOL *v, SYS_STRING_VIEW path, if (Fat32PathCacheLookup(v, path, outCluster, outSize, &attr, outDirentLba, outDirentOffset)) { if (outAttr) *outAttr = attr; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } size_t cursor = 0; SYS_STRING_VIEW component; while (Fat32PathNextComponent(path, &cursor, &component)) { - if (component.Length >= MAX_LFN) return STATUS_BUFFER_TOO_SMALL; - if (!Fat32NameViewIsValid(component)) return STATUS_INVALID_PARAMETER; - if (!(attr & ATTR_DIRECTORY)) return STATUS_NOT_FOUND; + if (component.Length >= MAX_LFN) return NTLSTATUS_BUFFER_TOO_SMALL; + if (!Fat32NameViewIsValid(component)) return NTLSTATUS_INVALID_PARAMETER; + if (!(attr & ATTR_DIRECTORY)) return NTLSTATUS_NOT_FOUND; uint32_t childCluster, childSize; uint8_t childAttr; uint64_t childLba = 0; uint32_t childOffset = 0; if (!SearchDirV(v, cluster, component, &childCluster, &childSize, &childAttr, &childLba, &childOffset)) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; cluster = childCluster; size = childSize; attr = childAttr; finalDirentLba = childLba; @@ -1461,7 +1461,7 @@ static KSTATUS Fat32LookupPathV(FAT32_VOL *v, SYS_STRING_VIEW path, if (outAttr) *outAttr = attr; Fat32PathCacheStore(v, path, cluster, size, attr, finalDirentLba, finalDirentOffset); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS TraverseV(FAT32_VOL *v, SYS_STRING_VIEW path, @@ -1471,15 +1471,15 @@ static KSTATUS TraverseV(FAT32_VOL *v, SYS_STRING_VIEW path, static KSTATUS SplitPathV(SYS_STRING_VIEW path, SYS_STRING_VIEW* parent, SYS_STRING_VIEW* name) { - if (!parent || !name || !SysSvIsValid(path)) return STATUS_INVALID_PARAMETER; + if (!parent || !name || !SysSvIsValid(path)) return NTLSTATUS_INVALID_PARAMETER; *parent = SYS_SV_NULL; *name = SYS_SV_NULL; while (path.Length && Fat32IsPathSep(path.Data[path.Length - 1])) path.Length--; - if (path.Length == 0) return STATUS_INVALID_PARAMETER; + if (path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; - if (SysSvContainsByte(path, '\0')) return STATUS_INVALID_PARAMETER; + if (SysSvContainsByte(path, '\0')) return NTLSTATUS_INVALID_PARAMETER; size_t lastSep = (size_t)-1; for (size_t i = 0; i < path.Length; i++) { @@ -1494,8 +1494,8 @@ static KSTATUS SplitPathV(SYS_STRING_VIEW path, SYS_STRING_VIEW* parent, *name = SysSvFromParts(path.Data + lastSep + 1, path.Length - lastSep - 1); } - if (!Fat32NameViewIsValid(*name)) return STATUS_INVALID_PARAMETER; - return STATUS_SUCCESS; + if (!Fat32NameViewIsValid(*name)) return NTLSTATUS_INVALID_PARAMETER; + return NTLSTATUS_SUCCESS; } // Find a free DIRENT slot. @@ -1593,7 +1593,7 @@ static KSTATUS Fat32ResolveParentForMutation(FAT32_VOL *v, SYS_STRING_VIEW path, uint32_t *parentClusterOut, SYS_STRING_VIEW *filenameOut) { if (!v || !parentClusterOut || !filenameOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; SYS_STRING_VIEW parentPath; SYS_STRING_VIEW filenameView; @@ -1606,11 +1606,11 @@ static KSTATUS Fat32ResolveParentForMutation(FAT32_VOL *v, SYS_STRING_VIEW path, s = Fat32LookupPathV(v, parentPath, &parentCluster, &parentSize, &parentAttr, NULL, NULL); if (!KSUCCESS(s)) return s; - if (!(parentAttr & ATTR_DIRECTORY)) return STATUS_NOT_FOUND; + if (!(parentAttr & ATTR_DIRECTORY)) return NTLSTATUS_NOT_FOUND; *parentClusterOut = parentCluster; *filenameOut = filenameView; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Creates a FAT directory entry run for a new file or directory. @@ -1620,7 +1620,7 @@ static KSTATUS Fat32CreateDirent(FAT32_VOL *v, SYS_STRING_VIEW path, uint64_t *direntLbaOut, uint32_t *direntOffsetOut) { if (!v || !SysSvIsValid(path) || path.Length == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t parentCluster = 0; SYS_STRING_VIEW filenameView; @@ -1634,7 +1634,7 @@ static KSTATUS Fat32CreateDirent(FAT32_VOL *v, SYS_STRING_VIEW path, uint32_t existingOffset = 0; if (SearchDirV(v, parentCluster, filenameView, &ec, &es, &ea, &existingLba, &existingOffset)) { - return STATUS_OBJECT_NAME_COLLISION; + return NTLSTATUS_OBJECT_NAME_COLLISION; } } @@ -1644,22 +1644,22 @@ static KSTATUS Fat32CreateDirent(FAT32_VOL *v, SYS_STRING_VIEW path, s = DeleteLegacyBrokenDotAliasV(v, parentCluster, filenameView); if (!KSUCCESS(s)) return s; if (!MakeUniqueShortAliasV(v, parentCluster, filenameView, shortName, shortExt)) - return STATUS_OBJECT_NAME_COLLISION; + return NTLSTATUS_OBJECT_NAME_COLLISION; } else { Make83NameV(filenameView, shortName, shortExt); } size_t nameLen = filenameView.Length; - if (nameLen == 0 || nameLen >= MAX_LFN) return STATUS_INVALID_PARAMETER; + if (nameLen == 0 || nameLen >= MAX_LFN) return NTLSTATUS_INVALID_PARAMETER; uint32_t lfnCount = useLfn ? (uint32_t)((nameLen + 12u) / 13u) : 0; uint32_t neededEntries = lfnCount + 1u; uint32_t entryCluster, firstIndex; if (!FindFreeDirentRun(v, parentCluster, neededEntries, &entryCluster, &firstIndex)) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; uint8_t *clusterBuf = (uint8_t *)MmAllocatePool(v->BytesPerCluster); - if (!clusterBuf) return STATUS_NO_MEMORY; + if (!clusterBuf) return NTLSTATUS_NO_MEMORY; uint64_t clusterLba = ClusterToLba(v, entryCluster); s = ReadSectors(v, clusterLba, v->SectorsPerCluster, clusterBuf); @@ -1708,7 +1708,7 @@ static KSTATUS Fat32CreateDirent(FAT32_VOL *v, SYS_STRING_VIEW path, if (direntOffsetOut) *direntOffsetOut = direntOffset; Fat32PathCacheInvalidate(v); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Initializes one dot entry in a new directory cluster. @@ -1735,10 +1735,10 @@ static void Fat32InitDotEntry(DIRENT *d, const char *name, static KSTATUS Fat32InitializeDirectoryCluster(FAT32_VOL *v, uint32_t dirCluster, uint32_t parentCluster) { if (!v || dirCluster < 2) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint8_t *clusterBuf = (uint8_t *)MmAllocatePool(v->BytesPerCluster); - if (!clusterBuf) return STATUS_NO_MEMORY; + if (!clusterBuf) return NTLSTATUS_NO_MEMORY; memset(clusterBuf, 0, v->BytesPerCluster); FAT32_ENCODED_TIME now; @@ -1766,10 +1766,10 @@ static int Fat32IsDotEntry(const DIRENT *d) { static KSTATUS Fat32DirectoryIsEmpty(FAT32_VOL *v, uint32_t dirCluster, int *emptyOut) { if (!v || !emptyOut || dirCluster < 2) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint8_t *clusterBuf = (uint8_t *)MmAllocatePool(v->BytesPerCluster); - if (!clusterBuf) return STATUS_NO_MEMORY; + if (!clusterBuf) return NTLSTATUS_NO_MEMORY; uint32_t cluster = dirCluster; while (cluster >= 2 && cluster < FAT32_EOC) { @@ -1781,14 +1781,14 @@ static KSTATUS Fat32DirectoryIsEmpty(FAT32_VOL *v, uint32_t dirCluster, DIRENT *dir = (DIRENT *)clusterBuf; for (uint32_t i = 0; i < entries; i++) { uint8_t first = (uint8_t)dir[i].Name[0]; - if (first == 0x00) { MmFreePool(clusterBuf); *emptyOut = 1; return STATUS_SUCCESS; } + if (first == 0x00) { MmFreePool(clusterBuf); *emptyOut = 1; return NTLSTATUS_SUCCESS; } if (first == 0xE5 || dir[i].Attr == ATTR_LFN) continue; if ((dir[i].Attr & ATTR_VOLUME_ID) && !(dir[i].Attr & ATTR_DIRECTORY)) continue; if (Fat32IsDotEntry(&dir[i])) continue; MmFreePool(clusterBuf); *emptyOut = 0; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } cluster = FatEntry(v, cluster); @@ -1796,17 +1796,17 @@ static KSTATUS Fat32DirectoryIsEmpty(FAT32_VOL *v, uint32_t dirCluster, MmFreePool(clusterBuf); *emptyOut = 1; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Deletes the directory-entry run for one child name from a parent directory. static KSTATUS Fat32DeleteDirentRunV(FAT32_VOL *v, uint32_t parentCluster, SYS_STRING_VIEW name) { if (!v || !Fat32NameViewIsValid(name)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint8_t *clusterBuf = (uint8_t *)MmAllocatePool(v->BytesPerCluster); - if (!clusterBuf) return STATUS_NO_MEMORY; + if (!clusterBuf) return NTLSTATUS_NO_MEMORY; char lfn[MAX_LFN]; int hasLfn = 0; @@ -1829,7 +1829,7 @@ static KSTATUS Fat32DeleteDirentRunV(FAT32_VOL *v, uint32_t parentCluster, memset(lfn, 0, sizeof(lfn)); for (uint32_t i = 0; i < entries; i++) { uint8_t first = (uint8_t)dir[i].Name[0]; - if (first == 0x00) { MmFreePool(clusterBuf); return STATUS_NOT_FOUND; } + if (first == 0x00) { MmFreePool(clusterBuf); return NTLSTATUS_NOT_FOUND; } if (first == 0xE5) { hasLfn = 0; memset(lfn, 0, sizeof(lfn)); continue; } if (dir[i].Attr == ATTR_LFN) { if (!hasLfn) lfnStart = i; @@ -1863,13 +1863,13 @@ static KSTATUS Fat32DeleteDirentRunV(FAT32_VOL *v, uint32_t parentCluster, } MmFreePool(clusterBuf); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } // Open / Close. KSTATUS Fat32Open(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileCtx) { if (!fs || !fileCtx || !SysSvIsValid(path) || path.Length == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; FAT32_VOL *v = (FAT32_VOL *)fs->DriverCtx; uint32_t cluster, size; uint64_t direntLba; uint32_t direntOffset; @@ -1877,12 +1877,12 @@ KSTATUS Fat32Open(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileCtx) { if (!KSUCCESS(s)) return s; FAT32_FILE *f = (FAT32_FILE *)MmAllocatePool(sizeof(FAT32_FILE)); - if (!f) return STATUS_NO_MEMORY; + if (!f) return NTLSTATUS_NO_MEMORY; f->StartCluster = cluster; f->FileSize = size; f->Vol = v; f->DirentLba = direntLba; f->DirentOffset = direntOffset; Fat32FileInitChainCache(f); *fileCtx = f; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Releases the requested object. @@ -1902,13 +1902,13 @@ KSTATUS Fat32Read(IO_FILESYSTEM *fs, void *fileCtx, uint64_t offset, void *buf, size_t size, size_t *bytesRead) { (void)fs; - if (!bytesRead) return STATUS_INVALID_PARAMETER; + if (!bytesRead) return NTLSTATUS_INVALID_PARAMETER; *bytesRead = 0; - if (!fileCtx || !buf) return STATUS_INVALID_PARAMETER; + if (!fileCtx || !buf) return NTLSTATUS_INVALID_PARAMETER; FAT32_FILE *f = (FAT32_FILE *)fileCtx; FAT32_VOL *v = f->Vol; - if (offset >= f->FileSize || size == 0) return STATUS_SUCCESS; + if (offset >= f->FileSize || size == 0) return NTLSTATUS_SUCCESS; if (size > (size_t)(f->FileSize - offset)) size = (size_t)(f->FileSize - offset); size_t wanted = size; @@ -1920,11 +1920,11 @@ KSTATUS Fat32Read(IO_FILESYSTEM *fs, void *fileCtx, maxUsefulSectors = FAT32_READ_RUN_MAX_SECTORS; uint8_t *runBuf = (uint8_t *)MmAllocatePool((size_t)maxUsefulSectors * 512u); - if (!runBuf) return STATUS_NO_MEMORY; + if (!runBuf) return NTLSTATUS_NO_MEMORY; size_t totalRead = 0; uint8_t *out = (uint8_t *)buf; - KSTATUS readStatus = STATUS_SUCCESS; + KSTATUS readStatus = NTLSTATUS_SUCCESS; uint32_t logicalCluster = (uint32_t)(offset / v->BytesPerCluster); uint32_t offsetInCluster = (uint32_t)(offset % v->BytesPerCluster); uint32_t cluster = Fat32ResolveFileCluster(f, logicalCluster); @@ -1941,7 +1941,7 @@ KSTATUS Fat32Read(IO_FILESYSTEM *fs, void *fileCtx, uint32_t next = 0; if (!Fat32BuildReadRun(f, logicalCluster, cluster, usefulSectors, &runSectors, &next)) { - readStatus = STATUS_DEVICE_ERROR; + readStatus = NTLSTATUS_DEVICE_ERROR; break; } @@ -1977,8 +1977,8 @@ KSTATUS Fat32Read(IO_FILESYSTEM *fs, void *fileCtx, MmFreePool(runBuf); *bytesRead = totalRead; if (totalRead != wanted) - return KSUCCESS(readStatus) ? STATUS_DEVICE_ERROR : readStatus; - return STATUS_SUCCESS; + return KSUCCESS(readStatus) ? NTLSTATUS_DEVICE_ERROR : readStatus; + return NTLSTATUS_SUCCESS; } // Write (fix #4: contiguous-run coalescing) @@ -1989,7 +1989,7 @@ KSTATUS Fat32Write(IO_FILESYSTEM *fs, void *fileCtx, uint64_t offset, const void *buf, size_t size, size_t *bytesWritten) { (void)fs; - if (!size) { *bytesWritten = 0; return STATUS_SUCCESS; } + if (!size) { *bytesWritten = 0; return NTLSTATUS_SUCCESS; } FAT32_FILE *f = (FAT32_FILE *)fileCtx; FAT32_VOL *v = f->Vol; @@ -1999,7 +1999,7 @@ KSTATUS Fat32Write(IO_FILESYSTEM *fs, void *fileCtx, // Ensure at least one cluster exists. if (f->StartCluster < 2) { uint32_t first = AllocCluster(v); - if (!first) { *bytesWritten = 0; return STATUS_NO_MEMORY; } + if (!first) { *bytesWritten = 0; return NTLSTATUS_NO_MEMORY; } f->StartCluster = first; DirentUpdateFirstCluster(v, f->DirentLba, f->DirentOffset, first); } @@ -2013,13 +2013,13 @@ KSTATUS Fat32Write(IO_FILESYSTEM *fs, void *fileCtx, uint32_t next = FatEntry(v, cluster); if (next < 2 || next >= FAT32_EOC) { next = AppendCluster(v, cluster); - if (!next) { *bytesWritten = 0; return STATUS_NO_MEMORY; } + if (!next) { *bytesWritten = 0; return NTLSTATUS_NO_MEMORY; } } cluster = next; } uint8_t *runBuf = (uint8_t *)MmAllocatePool(FAT32_WRITE_RUN_MAX_SECTORS * 512u); - if (!runBuf) { *bytesWritten = 0; return STATUS_NO_MEMORY; } + if (!runBuf) { *bytesWritten = 0; return NTLSTATUS_NO_MEMORY; } size_t written = 0, remaining = size; @@ -2095,14 +2095,14 @@ KSTATUS Fat32Write(IO_FILESYSTEM *fs, void *fileCtx, } *bytesWritten = written; - return (written == size) ? STATUS_SUCCESS : STATUS_DEVICE_ERROR; + return (written == size) ? NTLSTATUS_SUCCESS : NTLSTATUS_DEVICE_ERROR; } // Create. // Creates the requested file and fails if the name already exists. KSTATUS Fat32Create(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileCtx) { if (!fs || !fileCtx || !SysSvIsValid(path) || path.Length == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; FAT32_VOL *v = (FAT32_VOL *)fs->DriverCtx; uint64_t direntLba = 0; @@ -2112,7 +2112,7 @@ KSTATUS Fat32Create(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileCtx) { if (!KSUCCESS(s)) return s; FAT32_FILE *f = (FAT32_FILE *)MmAllocatePool(sizeof(FAT32_FILE)); - if (!f) return STATUS_NO_MEMORY; + if (!f) return NTLSTATUS_NO_MEMORY; f->StartCluster = 0; f->FileSize = 0; f->Vol = v; @@ -2120,13 +2120,13 @@ KSTATUS Fat32Create(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileCtx) { f->DirentOffset = direntOffset; Fat32FileInitChainCache(f); *fileCtx = f; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Creates a directory and initializes its dot entries. KSTATUS Fat32CreateDir(IO_FILESYSTEM *fs, SYS_STRING_VIEW path) { if (!fs || !SysSvIsValid(path) || path.Length == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; FAT32_VOL *v = (FAT32_VOL *)fs->DriverCtx; uint32_t parentCluster = 0; @@ -2136,7 +2136,7 @@ KSTATUS Fat32CreateDir(IO_FILESYSTEM *fs, SYS_STRING_VIEW path) { (void)filenameView; uint32_t dirCluster = AllocCluster(v); - if (!dirCluster) return STATUS_NO_MEMORY; + if (!dirCluster) return NTLSTATUS_NO_MEMORY; s = Fat32InitializeDirectoryCluster(v, dirCluster, parentCluster); if (!KSUCCESS(s)) { @@ -2153,13 +2153,13 @@ KSTATUS Fat32CreateDir(IO_FILESYSTEM *fs, SYS_STRING_VIEW path) { } FlushFatCache(v); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Removes an empty directory. KSTATUS Fat32RemoveDir(IO_FILESYSTEM *fs, SYS_STRING_VIEW path) { if (!fs || !SysSvIsValid(path) || path.Length == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; FAT32_VOL *v = (FAT32_VOL *)fs->DriverCtx; uint32_t cluster = 0; @@ -2170,13 +2170,13 @@ KSTATUS Fat32RemoveDir(IO_FILESYSTEM *fs, SYS_STRING_VIEW path) { KSTATUS s = Fat32LookupPathV(v, path, &cluster, &size, &attr, &direntLba, &direntOffset); if (!KSUCCESS(s)) return s; - if (!direntLba) return STATUS_ACCESS_DENIED; - if (!(attr & ATTR_DIRECTORY)) return STATUS_ACCESS_DENIED; + if (!direntLba) return NTLSTATUS_ACCESS_DENIED; + if (!(attr & ATTR_DIRECTORY)) return NTLSTATUS_ACCESS_DENIED; int empty = 0; s = Fat32DirectoryIsEmpty(v, cluster, &empty); if (!KSUCCESS(s)) return s; - if (!empty) return STATUS_ACCESS_DENIED; + if (!empty) return NTLSTATUS_ACCESS_DENIED; uint32_t parentCluster = 0; SYS_STRING_VIEW filenameView; @@ -2189,7 +2189,7 @@ KSTATUS Fat32RemoveDir(IO_FILESYSTEM *fs, SYS_STRING_VIEW path) { if (cluster >= 2) FreeClusterChain(v, cluster); FlushFatCache(v); Fat32PathCacheInvalidate(v); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Truncate. @@ -2240,7 +2240,7 @@ KSTATUS Fat32Truncate(IO_FILESYSTEM *fs, void *fileCtx, uint64_t newSize, uint32 uint32_t lastCluster = 0; if (f->StartCluster < 2) { uint32_t first = AllocClusterEx(v, zeroNewClusters); - if (!first) return STATUS_NO_MEMORY; + if (!first) return NTLSTATUS_NO_MEMORY; f->StartCluster = first; DirentUpdateFirstCluster(v, f->DirentLba, f->DirentOffset, first); lastCluster = first; curClusters = 1; @@ -2249,7 +2249,7 @@ KSTATUS Fat32Truncate(IO_FILESYSTEM *fs, void *fileCtx, uint64_t newSize, uint32 } for (uint32_t i = curClusters; i < newClusters; i++) { uint32_t next = AppendClusterEx(v, lastCluster, zeroNewClusters); - if (!next) return STATUS_NO_MEMORY; + if (!next) return NTLSTATUS_NO_MEMORY; lastCluster = next; } } @@ -2265,16 +2265,16 @@ update_size: // Delete. KSTATUS Fat32Delete(IO_FILESYSTEM *fs, SYS_STRING_VIEW path) { if (!fs || !SysSvIsValid(path) || path.Length == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; FAT32_VOL *v = (FAT32_VOL *)fs->DriverCtx; uint32_t cluster, size; uint64_t direntLba; uint32_t direntOffset; KSTATUS s = Fat32LookupPathV(v, path, &cluster, &size, NULL, &direntLba, &direntOffset); if (!KSUCCESS(s)) return s; - if (!direntLba) return STATUS_ACCESS_DENIED; + if (!direntLba) return NTLSTATUS_ACCESS_DENIED; uint8_t *sec = (uint8_t *)MmAllocatePool(v->BytesPerSector); - if (!sec) return STATUS_NO_MEMORY; + if (!sec) return NTLSTATUS_NO_MEMORY; s = ReadSectors(v, direntLba, 1, sec); if (KSUCCESS(s)) { sec[direntOffset] = 0xE5; s = WriteSectors(v, direntLba, 1, sec); } MmFreePool(sec); @@ -2283,7 +2283,7 @@ KSTATUS Fat32Delete(IO_FILESYSTEM *fs, SYS_STRING_VIEW path) { if (cluster >= 2) FreeClusterChain(v, cluster); FlushFatCache(v); Fat32PathCacheInvalidate(v); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns size. @@ -2343,11 +2343,11 @@ static void Fat32FillRootStat(FAT32_VOL *v, SYS_FILE_STAT *out) { // Queries metadata for an open FAT32 file. KSTATUS Fat32QueryInfo(IO_FILESYSTEM *fs, void *fileCtx, SYS_FILE_STAT *out) { (void)fs; - if (!fileCtx || !out) return STATUS_INVALID_PARAMETER; + if (!fileCtx || !out) return NTLSTATUS_INVALID_PARAMETER; FAT32_FILE *f = (FAT32_FILE *)fileCtx; FAT32_VOL *v = f->Vol; - if (!v) return STATUS_INVALID_PARAMETER; + if (!v) return NTLSTATUS_INVALID_PARAMETER; if (f->DirentLba == 0) { if (f->StartCluster == v->RootCluster && f->FileSize == 0) { @@ -2362,11 +2362,11 @@ KSTATUS Fat32QueryInfo(IO_FILESYSTEM *fs, void *fileCtx, SYS_FILE_STAT *out) { out->VolumeId = Fat32VolumeIdentity(v); out->FileId = ((uint64_t)f->StartCluster << 1); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } uint8_t *sec = (uint8_t *)MmAllocatePool(v->BytesPerSector); - if (!sec) return STATUS_NO_MEMORY; + if (!sec) return NTLSTATUS_NO_MEMORY; KSTATUS s = ReadSectors(v, f->DirentLba, 1, sec); if (!KSUCCESS(s)) { MmFreePool(sec); return s; } @@ -2374,22 +2374,22 @@ KSTATUS Fat32QueryInfo(IO_FILESYSTEM *fs, void *fileCtx, SYS_FILE_STAT *out) { DIRENT *d = (DIRENT *)(sec + f->DirentOffset); if ((uint8_t)d->Name[0] == 0x00 || (uint8_t)d->Name[0] == 0xE5) { MmFreePool(sec); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } Fat32FillStatFromDirent(v, d, f->DirentLba, f->DirentOffset, out); f->StartCluster = ((uint32_t)d->FirstClusterHi << 16) | d->FirstClusterLo; f->FileSize = d->FileSize; MmFreePool(sec); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Queries metadata for a FAT32 path. KSTATUS Fat32Stat(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, SYS_FILE_STAT *out) { - if (!fs || !out || !SysSvIsValid(path)) return STATUS_INVALID_PARAMETER; + if (!fs || !out || !SysSvIsValid(path)) return NTLSTATUS_INVALID_PARAMETER; FAT32_VOL *v = (FAT32_VOL *)fs->DriverCtx; - if (!v) return STATUS_INVALID_PARAMETER; + if (!v) return NTLSTATUS_INVALID_PARAMETER; uint32_t cluster = 0; uint32_t size = 0; @@ -2402,11 +2402,11 @@ KSTATUS Fat32Stat(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, SYS_FILE_STAT *out) { if (direntLba == 0) { Fat32FillRootStat(v, out); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } uint8_t *sec = (uint8_t *)MmAllocatePool(v->BytesPerSector); - if (!sec) return STATUS_NO_MEMORY; + if (!sec) return NTLSTATUS_NO_MEMORY; s = ReadSectors(v, direntLba, 1, sec); if (!KSUCCESS(s)) { MmFreePool(sec); return s; } @@ -2414,14 +2414,14 @@ KSTATUS Fat32Stat(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, SYS_FILE_STAT *out) { DIRENT *d = (DIRENT *)(sec + direntOffset); if ((uint8_t)d->Name[0] == 0x00 || (uint8_t)d->Name[0] == 0xE5) { MmFreePool(sec); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } Fat32FillStatFromDirent(v, d, direntLba, direntOffset, out); out->Type = Fat32FileTypeFromAttr(attr); out->FileSize = size; MmFreePool(sec); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Mixes FAT directory metadata into a per-file content generation. @@ -2446,12 +2446,12 @@ static uint64_t Fat32DirentGeneration(const DIRENT *d) { KSTATUS Fat32QueryIdentity(IO_FILESYSTEM *fs, void *fileCtx, IO_FILE_IDENTITY *out) { (void)fs; if (!fileCtx || !out) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; FAT32_FILE *f = (FAT32_FILE *)fileCtx; FAT32_VOL *v = f->Vol; if (!v) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t startCluster = f->StartCluster; uint32_t fileSize = f->FileSize; @@ -2461,7 +2461,7 @@ KSTATUS Fat32QueryIdentity(IO_FILESYSTEM *fs, void *fileCtx, IO_FILE_IDENTITY *o if (f->DirentLba != 0) { uint8_t *sec = (uint8_t *)MmAllocatePool(v->BytesPerSector); if (!sec) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; KSTATUS s = ReadSectors(v, f->DirentLba, 1, sec); if (!KSUCCESS(s)) { @@ -2472,7 +2472,7 @@ KSTATUS Fat32QueryIdentity(IO_FILESYSTEM *fs, void *fileCtx, IO_FILE_IDENTITY *o DIRENT *d = (DIRENT *)(sec + f->DirentOffset); if ((uint8_t)d->Name[0] == 0x00 || (uint8_t)d->Name[0] == 0xE5) { MmFreePool(sec); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } startCluster = ((uint32_t)d->FirstClusterHi << 16) | d->FirstClusterLo; @@ -2487,7 +2487,7 @@ KSTATUS Fat32QueryIdentity(IO_FILESYSTEM *fs, void *fileCtx, IO_FILE_IDENTITY *o ((uint64_t)startCluster << 1); out->Generation = generation ? generation : 1; out->Size = fileSize; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Directory enumeration (fix #2: cluster buffer cached in context) @@ -2509,7 +2509,7 @@ typedef struct { // Opens dir. KSTATUS Fat32OpenDir(IO_FILESYSTEM *fs, SYS_STRING_VIEW dirPath, void **dirCtx) { if (!fs || !dirCtx || !SysSvIsValid(dirPath)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; FAT32_VOL *v = (FAT32_VOL *)fs->DriverCtx; uint32_t cluster; @@ -2522,10 +2522,10 @@ KSTATUS Fat32OpenDir(IO_FILESYSTEM *fs, SYS_STRING_VIEW dirPath, void **dirCtx) } FAT32_DIR_CTX *ctx = (FAT32_DIR_CTX *)MmAllocatePool(sizeof(FAT32_DIR_CTX)); - if (!ctx) return STATUS_NO_MEMORY; + if (!ctx) return NTLSTATUS_NO_MEMORY; ctx->ClusterBuf = (uint8_t *)MmAllocatePool(v->BytesPerCluster); - if (!ctx->ClusterBuf) { MmFreePool(ctx); return STATUS_NO_MEMORY; } + if (!ctx->ClusterBuf) { MmFreePool(ctx); return NTLSTATUS_NO_MEMORY; } ctx->Vol = v; ctx->DirCluster = cluster; @@ -2535,7 +2535,7 @@ KSTATUS Fat32OpenDir(IO_FILESYSTEM *fs, SYS_STRING_VIEW dirPath, void **dirCtx) ctx->HasLfn = 0; memset(ctx->LfnBuf, 0, sizeof(ctx->LfnBuf)); *dirCtx = ctx; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns dir. @@ -2558,7 +2558,7 @@ KSTATUS Fat32ReadDir(IO_FILESYSTEM *fs, void *dirCtx, KDIR_ENTRY *out) { while (ctx->EntryIndex < epc) { DIRENT *e = &dir[ctx->EntryIndex++]; - if (e->Name[0] == 0x00) { ctx->CurCluster = FAT32_EOC; return STATUS_NO_MORE_FILES; } + if (e->Name[0] == 0x00) { ctx->CurCluster = FAT32_EOC; return NTLSTATUS_NO_MORE_FILES; } if ((uint8_t)e->Name[0] == 0xE5) { ctx->HasLfn = 0; memset(ctx->LfnBuf, 0, sizeof(ctx->LfnBuf)); continue; } if (e->Attr == ATTR_LFN) { LfnAppend(ctx->LfnBuf, (LFN_ENTRY *)e); ctx->HasLfn = 1; continue; } if (e->Attr & 0x08 && !(e->Attr & ATTR_DIRECTORY)) { ctx->HasLfn = 0; memset(ctx->LfnBuf, 0, sizeof(ctx->LfnBuf)); continue; } @@ -2589,14 +2589,14 @@ KSTATUS Fat32ReadDir(IO_FILESYSTEM *fs, void *dirCtx, KDIR_ENTRY *out) { FatDecodeAccessDate(e->LastAccDate, &out->LastAccessTime); FatDecodeDateTime(e->WrtDate, e->WrtTime, 0, &out->LastWriteTime); ctx->HasLfn = 0; memset(ctx->LfnBuf, 0, sizeof(ctx->LfnBuf)); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } ctx->CurCluster = FatEntry(v, ctx->CurCluster); ctx->EntryIndex = 0; } - return STATUS_NO_MORE_FILES; + return NTLSTATUS_NO_MORE_FILES; } // Releases dir. @@ -2855,13 +2855,13 @@ static KSTATUS Fat32EnsureAsyncWorkerStarted(void) { uintptr_t flags = KeAcquireSpinlock(&gFat32AsyncLock); if (gFat32AsyncInitState == 2) { KeReleaseSpinlock(&gFat32AsyncLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (gFat32AsyncInitState == 1) { KeReleaseSpinlock(&gFat32AsyncLock, flags); while (gFat32AsyncInitState == 1) KeYield(); - return gFat32AsyncInitState == 2 ? STATUS_SUCCESS : STATUS_FAILURE; + return gFat32AsyncInitState == 2 ? NTLSTATUS_SUCCESS : NTLSTATUS_FAILURE; } gFat32AsyncInitState = 1; @@ -2939,14 +2939,14 @@ static void Fat32AsyncReadIrpComplete(IRP* irp, void* completeCtx) { // Implements the async Read Submit Next operation. static void Fat32AsyncReadSubmitNext(FAT32_ASYNC_RW* ctx) { if (ctx->Remaining == 0) { - Fat32AsyncFinish(ctx, STATUS_SUCCESS, ctx->Done); + Fat32AsyncFinish(ctx, NTLSTATUS_SUCCESS, ctx->Done); return; } if (ctx->Cluster < 2 || ctx->Cluster >= FAT32_EOC) { if (ctx->Done < ctx->Requested) memset(ctx->Dst, 0, ctx->Requested - ctx->Done); - Fat32AsyncFinish(ctx, STATUS_DEVICE_ERROR, ctx->Done); + Fat32AsyncFinish(ctx, NTLSTATUS_DEVICE_ERROR, ctx->Done); return; } @@ -2956,7 +2956,7 @@ static void Fat32AsyncReadSubmitNext(FAT32_ASYNC_RW* ctx) { uint32_t next = 0; if (!Fat32BuildReadRun(ctx->File, ctx->LogicalCluster, ctx->Cluster, FAT32_READ_RUN_MAX_SECTORS, &runSectors, &next)) { - Fat32AsyncFinish(ctx, STATUS_DEVICE_ERROR, ctx->Done); + Fat32AsyncFinish(ctx, NTLSTATUS_DEVICE_ERROR, ctx->Done); return; } @@ -2972,7 +2972,7 @@ static void Fat32AsyncReadSubmitNext(FAT32_ASYNC_RW* ctx) { ctx->CurrentDevice = IoReferenceDiskDevice(v->DriveIndex); if (!ctx->CurrentDevice) { - Fat32AsyncFinish(ctx, STATUS_NOT_FOUND, ctx->Done); + Fat32AsyncFinish(ctx, NTLSTATUS_NOT_FOUND, ctx->Done); return; } @@ -2984,7 +2984,7 @@ static void Fat32AsyncReadSubmitNext(FAT32_ASYNC_RW* ctx) { ctx->Irp.CompletionCtx = ctx; KSTATUS s = IoSubmitIrp(ctx->CurrentDevice, &ctx->Irp); - if (s != STATUS_PENDING) { + if (s != NTLSTATUS_PENDING) { IoDereferenceDeviceObject(ctx->CurrentDevice); ctx->CurrentDevice = (DEVICE_OBJECT*)0; Fat32AsyncFinish(ctx, s, ctx->Done); @@ -2996,17 +2996,17 @@ KSTATUS Fat32ReadAsync(IO_FILESYSTEM *fs, void *fileCtx, IO_FS_ASYNC_COMPLETE complete, void *completeContext) { (void)fs; - if (!complete) return STATUS_INVALID_PARAMETER; + if (!complete) return NTLSTATUS_INVALID_PARAMETER; if (!fileCtx || (!buf && size)) { - complete(completeContext, STATUS_INVALID_PARAMETER, 0); - return STATUS_PENDING; + complete(completeContext, NTLSTATUS_INVALID_PARAMETER, 0); + return NTLSTATUS_PENDING; } FAT32_FILE* f = (FAT32_FILE*)fileCtx; FAT32_VOL* v = f->Vol; if (offset >= f->FileSize || size == 0) { - complete(completeContext, STATUS_SUCCESS, 0); - return STATUS_PENDING; + complete(completeContext, NTLSTATUS_SUCCESS, 0); + return NTLSTATUS_PENDING; } if (offset + size > f->FileSize) size = (size_t)(f->FileSize - offset); @@ -3014,13 +3014,13 @@ KSTATUS Fat32ReadAsync(IO_FILESYSTEM *fs, void *fileCtx, KSTATUS ws = Fat32EnsureAsyncWorkerStarted(); if (!KSUCCESS(ws)) { complete(completeContext, ws, 0); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } FAT32_ASYNC_RW* ctx = (FAT32_ASYNC_RW*)MmAllocatePool(sizeof(FAT32_ASYNC_RW)); if (!ctx) { - complete(completeContext, STATUS_NO_MEMORY, 0); - return STATUS_PENDING; + complete(completeContext, NTLSTATUS_NO_MEMORY, 0); + return NTLSTATUS_PENDING; } memset(ctx, 0, sizeof(*ctx)); LIST_INIT(&ctx->Link); @@ -3028,8 +3028,8 @@ KSTATUS Fat32ReadAsync(IO_FILESYSTEM *fs, void *fileCtx, ctx->RunBuf = (uint8_t*)MmAllocatePool(FAT32_READ_RUN_MAX_SECTORS * 512u); if (!ctx->RunBuf) { MmFreePool(ctx); - complete(completeContext, STATUS_NO_MEMORY, 0); - return STATUS_PENDING; + complete(completeContext, NTLSTATUS_NO_MEMORY, 0); + return NTLSTATUS_PENDING; } ctx->Vol = v; @@ -3046,7 +3046,7 @@ KSTATUS Fat32ReadAsync(IO_FILESYSTEM *fs, void *fileCtx, ctx->CompleteContext = completeContext; Fat32AsyncQueueContinuation(ctx); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } // Implements the async Write Irp Complete operation. @@ -3089,7 +3089,7 @@ static void Fat32AsyncWriteSubmitNext(FAT32_ASYNC_RW* ctx) { DirentUpdateMetadata(ctx->Vol, ctx->File->DirentLba, ctx->File->DirentOffset, &u); } - Fat32AsyncFinish(ctx, STATUS_SUCCESS, ctx->Done); + Fat32AsyncFinish(ctx, NTLSTATUS_SUCCESS, ctx->Done); return; } @@ -3098,11 +3098,11 @@ static void Fat32AsyncWriteSubmitNext(FAT32_ASYNC_RW* ctx) { if (ctx->CurrentLast >= 2 && ctx->CurrentLast < FAT32_EOC) { ctx->Cluster = AppendCluster(v, ctx->CurrentLast); if (!ctx->Cluster) { - Fat32AsyncFinish(ctx, STATUS_NO_MEMORY, ctx->Done); + Fat32AsyncFinish(ctx, NTLSTATUS_NO_MEMORY, ctx->Done); return; } } else { - Fat32AsyncFinish(ctx, STATUS_DEVICE_ERROR, ctx->Done); + Fat32AsyncFinish(ctx, NTLSTATUS_DEVICE_ERROR, ctx->Done); return; } } @@ -3143,7 +3143,7 @@ static void Fat32AsyncWriteSubmitNext(FAT32_ASYNC_RW* ctx) { ctx->CurrentDevice = IoReferenceDiskDevice(v->DriveIndex); if (!ctx->CurrentDevice) { - Fat32AsyncFinish(ctx, STATUS_NOT_FOUND, ctx->Done); + Fat32AsyncFinish(ctx, NTLSTATUS_NOT_FOUND, ctx->Done); return; } @@ -3155,7 +3155,7 @@ static void Fat32AsyncWriteSubmitNext(FAT32_ASYNC_RW* ctx) { ctx->Irp.CompletionCtx = ctx; KSTATUS s = IoSubmitIrp(ctx->CurrentDevice, &ctx->Irp); - if (s != STATUS_PENDING) { + if (s != NTLSTATUS_PENDING) { IoDereferenceDeviceObject(ctx->CurrentDevice); ctx->CurrentDevice = (DEVICE_OBJECT*)0; Fat32AsyncFinish(ctx, s, ctx->Done); @@ -3167,20 +3167,20 @@ KSTATUS Fat32WriteAsync(IO_FILESYSTEM *fs, void *fileCtx, IO_FS_ASYNC_COMPLETE complete, void *completeContext) { (void)fs; - if (!complete) return STATUS_INVALID_PARAMETER; + if (!complete) return NTLSTATUS_INVALID_PARAMETER; if (!fileCtx || (!buf && size)) { - complete(completeContext, STATUS_INVALID_PARAMETER, 0); - return STATUS_PENDING; + complete(completeContext, NTLSTATUS_INVALID_PARAMETER, 0); + return NTLSTATUS_PENDING; } if (size == 0) { - complete(completeContext, STATUS_SUCCESS, 0); - return STATUS_PENDING; + complete(completeContext, NTLSTATUS_SUCCESS, 0); + return NTLSTATUS_PENDING; } KSTATUS ws = Fat32EnsureAsyncWorkerStarted(); if (!KSUCCESS(ws)) { complete(completeContext, ws, 0); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } FAT32_FILE* f = (FAT32_FILE*)fileCtx; @@ -3190,8 +3190,8 @@ KSTATUS Fat32WriteAsync(IO_FILESYSTEM *fs, void *fileCtx, if (f->StartCluster < 2) { uint32_t first = AllocCluster(v); if (!first) { - complete(completeContext, STATUS_NO_MEMORY, 0); - return STATUS_PENDING; + complete(completeContext, NTLSTATUS_NO_MEMORY, 0); + return NTLSTATUS_PENDING; } f->StartCluster = first; DirentUpdateFirstCluster(v, f->DirentLba, f->DirentOffset, first); @@ -3204,8 +3204,8 @@ KSTATUS Fat32WriteAsync(IO_FILESYSTEM *fs, void *fileCtx, if (next < 2 || next >= FAT32_EOC) { next = AppendCluster(v, cluster); if (!next) { - complete(completeContext, STATUS_NO_MEMORY, 0); - return STATUS_PENDING; + complete(completeContext, NTLSTATUS_NO_MEMORY, 0); + return NTLSTATUS_PENDING; } } cluster = next; @@ -3213,8 +3213,8 @@ KSTATUS Fat32WriteAsync(IO_FILESYSTEM *fs, void *fileCtx, FAT32_ASYNC_RW* ctx = (FAT32_ASYNC_RW*)MmAllocatePool(sizeof(FAT32_ASYNC_RW)); if (!ctx) { - complete(completeContext, STATUS_NO_MEMORY, 0); - return STATUS_PENDING; + complete(completeContext, NTLSTATUS_NO_MEMORY, 0); + return NTLSTATUS_PENDING; } memset(ctx, 0, sizeof(*ctx)); LIST_INIT(&ctx->Link); @@ -3222,8 +3222,8 @@ KSTATUS Fat32WriteAsync(IO_FILESYSTEM *fs, void *fileCtx, ctx->RunBuf = (uint8_t*)MmAllocatePool(FAT32_WRITE_RUN_MAX_SECTORS * 512u); if (!ctx->RunBuf) { MmFreePool(ctx); - complete(completeContext, STATUS_NO_MEMORY, 0); - return STATUS_PENDING; + complete(completeContext, NTLSTATUS_NO_MEMORY, 0); + return NTLSTATUS_PENDING; } ctx->Vol = v; @@ -3239,7 +3239,7 @@ KSTATUS Fat32WriteAsync(IO_FILESYSTEM *fs, void *fileCtx, ctx->CompleteContext = completeContext; Fat32AsyncQueueContinuation(ctx); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } // DriverEntry. @@ -3431,7 +3431,7 @@ static void Fat32DiskChange(uint8_t driveIndex, // Implements the driver Entry operation. KSTATUS DriverEntry(const HAL_API *hal) { DbgPrint("FAT32: Init\n"); - if (!hal) return STATUS_INVALID_PARAMETER; + if (!hal) return NTLSTATUS_INVALID_PARAMETER; FatCacheInvalidate(); (void)hal; @@ -3450,9 +3450,9 @@ KSTATUS DriverEntry(const HAL_API *hal) { if (!gMountedCount) { DbgPrint("FAT32: no mountable FAT32 volumes found.\n"); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } DbgPrint("FAT32: Init complete; mounted %u volume(s).\n", gMountedCount); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } diff --git a/code/drivers/fs/ntfs/ntfs.c b/code/drivers/fs/ntfs/ntfs.c index 4a7a3ff..bac8d7a 100644 --- a/code/drivers/fs/ntfs/ntfs.c +++ b/code/drivers/fs/ntfs/ntfs.c @@ -382,37 +382,37 @@ static void NtfsDebugDumpRuns(const char* tag, const LIST_ENTRY* runs) { } static KSTATUS NtfsReadSectors(NTFS_VOLUME* vol, uint64_t lba, uint32_t count, void* buffer) { - if (!vol || !buffer || count == 0) return STATUS_INVALID_PARAMETER; - if (vol->PartitionSize && lba >= vol->PartitionSize) return STATUS_DEVICE_ERROR; - if (vol->PartitionSize && (uint64_t)count > vol->PartitionSize - lba) return STATUS_DEVICE_ERROR; + if (!vol || !buffer || count == 0) return NTLSTATUS_INVALID_PARAMETER; + if (vol->PartitionSize && lba >= vol->PartitionSize) return NTLSTATUS_DEVICE_ERROR; + if (vol->PartitionSize && (uint64_t)count > vol->PartitionSize - lba) return NTLSTATUS_DEVICE_ERROR; return IoReadDiskSectors(vol->DriveIndex, vol->PartitionLba + lba, count, buffer); } static KSTATUS NtfsReadBytesDirect(NTFS_VOLUME* vol, uint64_t byteOffset, uint64_t byteCount, void* buffer) { - if (!vol || !buffer) return STATUS_INVALID_PARAMETER; + if (!vol || !buffer) return NTLSTATUS_INVALID_PARAMETER; if ((byteOffset % vol->BytesPerSector) != 0 || (byteCount % vol->BytesPerSector) != 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint64_t lba = byteOffset / vol->BytesPerSector; uint64_t sectors = byteCount / vol->BytesPerSector; - if (sectors > 0xffffffffull) return STATUS_INVALID_PARAMETER; + if (sectors > 0xffffffffull) return NTLSTATUS_INVALID_PARAMETER; return NtfsReadSectors(vol, lba, (uint32_t)sectors, buffer); } static KSTATUS NtfsProcessFixups(NTFS_MULTI_SECTOR_HEADER* header, uint64_t length, uint32_t sectorSize) { - if (!header || sectorSize == 0 || length < sectorSize) return STATUS_INVALID_PARAMETER; + if (!header || sectorSize == 0 || length < sectorSize) return NTLSTATUS_INVALID_PARAMETER; uint64_t sectors = length / sectorSize; - if (header->UpdateSequenceArraySize < sectors + 1) return STATUS_INVALID_PARAMETER; + if (header->UpdateSequenceArraySize < sectors + 1) return NTLSTATUS_INVALID_PARAMETER; if (header->UpdateSequenceArrayOffset + (uint64_t)header->UpdateSequenceArraySize * sizeof(uint16_t) > length) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint16_t* seq = (uint16_t*)((uint8_t*)header + header->UpdateSequenceArrayOffset); uint8_t* ptr = (uint8_t*)header + sectorSize - sizeof(uint16_t); for (uint64_t i = 0; i < sectors; i++) { - if (*(uint16_t*)ptr != seq[0]) return STATUS_CHECKSUM_MISMATCH; + if (*(uint16_t*)ptr != seq[0]) return NTLSTATUS_CHECKSUM_MISMATCH; *(uint16_t*)ptr = seq[i + 1u]; ptr += sectorSize; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static int64_t NtfsReadSignedLe(const uint8_t* p, uint8_t bytes) { @@ -442,19 +442,19 @@ static uint32_t NtfsAttributeMinimumLength(uint8_t formCode) { } static KSTATUS NtfsReadMappings(NTFS_VOLUME* vol, const NTFS_ATTRIBUTE_RECORD_HEADER* attr, LIST_ENTRY* runs) { - if (!vol || !attr || !runs) return STATUS_INVALID_PARAMETER; - if (attr->FormCode != NTFS_FORM_NONRESIDENT) return STATUS_INVALID_PARAMETER; - if (attr->Flags & NTFS_ATTRIBUTE_FLAG_ENCRYPTED) return STATUS_NOT_SUPPORTED; - if (attr->Flags & NTFS_ATTRIBUTE_FLAG_COMPRESSION_MASK) return STATUS_NOT_SUPPORTED; + if (!vol || !attr || !runs) return NTLSTATUS_INVALID_PARAMETER; + if (attr->FormCode != NTFS_FORM_NONRESIDENT) return NTLSTATUS_INVALID_PARAMETER; + if (attr->Flags & NTFS_ATTRIBUTE_FLAG_ENCRYPTED) return NTLSTATUS_NOT_SUPPORTED; + if (attr->Flags & NTFS_ATTRIBUTE_FLAG_COMPRESSION_MASK) return NTLSTATUS_NOT_SUPPORTED; uint32_t attrLen = NtfsAttributeRecordLength(attr); - if (attrLen < NtfsAttributeMinimumLength(NTFS_FORM_NONRESIDENT)) return STATUS_INVALID_PARAMETER; - if (attr->Form.Nonresident.MappingPairsOffset >= attrLen) return STATUS_INVALID_PARAMETER; + if (attrLen < NtfsAttributeMinimumLength(NTFS_FORM_NONRESIDENT)) return NTLSTATUS_INVALID_PARAMETER; + if (attr->Form.Nonresident.MappingPairsOffset >= attrLen) return NTLSTATUS_INVALID_PARAMETER; uint64_t limitBytes = attr->Form.Nonresident.AllocatedLength; if (limitBytes == 0) limitBytes = attr->Form.Nonresident.FileSize; if (limitBytes == 0) limitBytes = attr->Form.Nonresident.ValidDataLength; uint64_t maxCluster = NtfsAlignUp(limitBytes, vol->BytesPerCluster) / vol->BytesPerCluster; - if (maxCluster == 0) return STATUS_SUCCESS; + if (maxCluster == 0) return NTLSTATUS_SUCCESS; const uint8_t* stream = (const uint8_t*)attr + attr->Form.Nonresident.MappingPairsOffset; const uint8_t* end = (const uint8_t*)attr + attrLen; @@ -465,18 +465,18 @@ static KSTATUS NtfsReadMappings(NTFS_VOLUME* vol, const NTFS_ATTRIBUTE_RECORD_HE uint8_t header = *stream++; uint8_t lenBytes = header & 0x0fu; uint8_t lcnBytes = header >> 4; - if (lenBytes == 0 || lenBytes > 8 || lcnBytes > 8) return STATUS_INVALID_PARAMETER; - if ((size_t)(end - stream) < (size_t)lenBytes + (size_t)lcnBytes) return STATUS_INVALID_PARAMETER; + if (lenBytes == 0 || lenBytes > 8 || lcnBytes > 8) return NTLSTATUS_INVALID_PARAMETER; + if ((size_t)(end - stream) < (size_t)lenBytes + (size_t)lcnBytes) return NTLSTATUS_INVALID_PARAMETER; int64_t runClustersSigned = NtfsReadSignedLe(stream, lenBytes); stream += lenBytes; - if (runClustersSigned <= 0) return STATUS_INVALID_PARAMETER; + if (runClustersSigned <= 0) return NTLSTATUS_INVALID_PARAMETER; uint64_t currentVcn = nextVcn; nextVcn += (uint64_t)runClustersSigned; if (nextVcn > maxCluster) nextVcn = maxCluster; NTFS_RUN* run = (NTFS_RUN*)MmAllocatePool(sizeof(NTFS_RUN)); - if (!run) return STATUS_NO_MEMORY; + if (!run) return NTLSTATUS_NO_MEMORY; memset(run, 0, sizeof(*run)); run->Vcn = currentVcn; run->Length = nextVcn - currentVcn; @@ -486,7 +486,7 @@ static KSTATUS NtfsReadMappings(NTFS_VOLUME* vol, const NTFS_ATTRIBUTE_RECORD_HE } else { currentLcn += NtfsReadSignedLe(stream, lcnBytes); stream += lcnBytes; - if (currentLcn < 0) { MmFreePool(run); return STATUS_INVALID_PARAMETER; } + if (currentLcn < 0) { MmFreePool(run); return NTLSTATUS_INVALID_PARAMETER; } run->Sparse = false; run->Lcn = (uint64_t)currentLcn; } @@ -494,12 +494,12 @@ static KSTATUS NtfsReadMappings(NTFS_VOLUME* vol, const NTFS_ATTRIBUTE_RECORD_HE if (nextVcn >= maxCluster) break; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS NtfsReadFromRuns(NTFS_VOLUME* vol, const LIST_ENTRY* runs, uint64_t offset, void* buffer, uint64_t size) { - if (!vol || !runs || (!buffer && size)) return STATUS_INVALID_PARAMETER; - if (size == 0) return STATUS_SUCCESS; + if (!vol || !runs || (!buffer && size)) return NTLSTATUS_INVALID_PARAMETER; + if (size == 0) return NTLSTATUS_SUCCESS; uint8_t* out = (uint8_t*)buffer; uint64_t clusterSize = vol->BytesPerCluster; @@ -545,7 +545,7 @@ static KSTATUS NtfsReadFromRuns(NTFS_VOLUME* vol, const LIST_ENTRY* runs, uint64 } if (size) memset(out, 0, (size_t)size); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static bool NtfsAttrNameEqualsAscii(const NTFS_ATTRIBUTE_RECORD_HEADER* attr, const char* ascii) { @@ -571,7 +571,7 @@ static KSTATUS NtfsForEachRecordAttribute(NTFS_VOLUME* vol, const NTFS_FILE_RECORD_SEGMENT_HEADER* record, bool (*callback)(const NTFS_ATTR_VIEW* view, void* ctx), void* ctx) { - if (!vol || !record || !callback) return STATUS_INVALID_PARAMETER; + if (!vol || !record || !callback) return NTLSTATUS_INVALID_PARAMETER; uint32_t offset = record->FirstAttributeOffset; uint32_t recordBytes = record->EntryUsedSize ? record->EntryUsedSize : record->EntryAllocatedSize; if (recordBytes == 0 || recordBytes > vol->FileRecordSize) recordBytes = (uint32_t)vol->FileRecordSize; @@ -579,7 +579,7 @@ static KSTATUS NtfsForEachRecordAttribute(NTFS_VOLUME* vol, if (offset >= recordBytes || offset < sizeof(NTFS_FILE_RECORD_SEGMENT_HEADER)) { NtfsTrace("NTFS: attrs: inode=%llu bad firstAttr=%u recordBytes=%u fileRecordSize=%llu\n", (unsigned long long)inode, offset, recordBytes, (unsigned long long)vol->FileRecordSize); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } while (offset + offsetof(NTFS_ATTRIBUTE_RECORD_HEADER, Form) <= recordBytes) { @@ -590,13 +590,13 @@ static KSTATUS NtfsForEachRecordAttribute(NTFS_VOLUME* vol, if (attrLen < minAttrLen || attrLen == 0) { NtfsTrace("NTFS: attrs: inode=%llu bad attr off=%u type=0x%x len=%u form=%u min=%u\n", (unsigned long long)inode, offset, attr->TypeCode, attrLen, attr->FormCode, minAttrLen); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (offset + attrLen > recordBytes) { NtfsTrace("NTFS: attrs: inode=%llu attr overruns off=%u type=0x%x len=%u recordBytes=%u used=%u alloc=%u\n", (unsigned long long)inode, offset, attr->TypeCode, attrLen, recordBytes, record->EntryUsedSize, record->EntryAllocatedSize); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } NTFS_ATTR_VIEW view; @@ -608,20 +608,20 @@ static KSTATUS NtfsForEachRecordAttribute(NTFS_VOLUME* vol, NtfsTrace("NTFS: attrs: inode=%llu resident bounds off=%u type=0x%x attrLen=%u valueOff=%u valueLen=%u\n", (unsigned long long)inode, offset, attr->TypeCode, attrLen, attr->Form.Resident.ValueOffset, attr->Form.Resident.ValueLength); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } view.ResidentData = (const uint8_t*)attr + attr->Form.Resident.ValueOffset; view.ResidentSize = attr->Form.Resident.ValueLength; } else if (attr->FormCode != NTFS_FORM_NONRESIDENT) { NtfsTrace("NTFS: attrs: inode=%llu unsupported form=%u off=%u type=0x%x\n", (unsigned long long)inode, attr->FormCode, offset, attr->TypeCode); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (!callback(&view, ctx)) break; offset += attrLen; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS NtfsValidateFileRecord(NTFS_VOLUME* vol, uint64_t inode, void* record, const char* source) { @@ -631,7 +631,7 @@ static KSTATUS NtfsValidateFileRecord(NTFS_VOLUME* vol, uint64_t inode, void* re NtfsTrace("NTFS: record: inode=%llu %s bad signature=0x%x bytes=%02x %02x %02x %02x mftOff=%llu\n", (unsigned long long)inode, source ? source : "?", fr->MultiSectorHeader.Signature, b[0], b[1], b[2], b[3], (unsigned long long)(inode * vol->FileRecordSize)); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } KSTATUS s = NtfsProcessFixups(&fr->MultiSectorHeader, vol->FileRecordSize, vol->BytesPerSector); @@ -643,11 +643,11 @@ static KSTATUS NtfsValidateFileRecord(NTFS_VOLUME* vol, uint64_t inode, void* re (unsigned long long)vol->FileRecordSize, vol->BytesPerSector); return s; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS NtfsReadRecord(NTFS_VOLUME* vol, uint64_t inode, void* record) { - if (!vol || !record) return STATUS_INVALID_PARAMETER; + if (!vol || !record) return NTLSTATUS_INVALID_PARAMETER; uint64_t mftOffset = inode * vol->FileRecordSize; KSTATUS s = NtfsReadFromRuns(vol, &vol->MftRuns, mftOffset, record, vol->FileRecordSize); if (!KSUCCESS(s)) { @@ -678,7 +678,7 @@ static KSTATUS NtfsReadRecord(NTFS_VOLUME* vol, uint64_t inode, void* record) { (unsigned long long)inode); NtfsDebugDumpRuns("mft", &vol->MftRuns); MmFreePool(direct); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } MmFreePool(direct); return s; @@ -739,7 +739,7 @@ static bool NtfsLoadFileAttributeCallback(const NTFS_ATTR_VIEW* view, void* rawC file->PhysicalSize = view->ResidentSize; if (view->ResidentSize) { file->ResidentData = (uint8_t*)MmAllocatePool(view->ResidentSize); - if (!file->ResidentData) { ctx->Status = STATUS_NO_MEMORY; return false; } + if (!file->ResidentData) { ctx->Status = NTLSTATUS_NO_MEMORY; return false; } memcpy(file->ResidentData, view->ResidentData, view->ResidentSize); file->ResidentDataSize = view->ResidentSize; } @@ -755,7 +755,7 @@ static bool NtfsLoadFileAttributeCallback(const NTFS_ATTR_VIEW* view, void* rawC case NTFS_ATTR_INDEX_ROOT: { if (NtfsAttrNameEqualsAscii(attr, "$I30") && attr->FormCode == NTFS_FORM_RESIDENT && view->ResidentSize) { file->IndexRoot = (NTFS_INDEX_ROOT*)MmAllocatePool(view->ResidentSize); - if (!file->IndexRoot) { ctx->Status = STATUS_NO_MEMORY; return false; } + if (!file->IndexRoot) { ctx->Status = NTLSTATUS_NO_MEMORY; return false; } memcpy(file->IndexRoot, view->ResidentData, view->ResidentSize); file->IndexRootSize = view->ResidentSize; file->IsDirectory = true; @@ -780,30 +780,30 @@ static bool NtfsLoadFileAttributeCallback(const NTFS_ATTR_VIEW* view, void* rawC } static KSTATUS NtfsLoadFile(NTFS_VOLUME* vol, uint64_t inode, NTFS_FILE* file) { - if (!vol || !file) return STATUS_INVALID_PARAMETER; + if (!vol || !file) return NTLSTATUS_INVALID_PARAMETER; NtfsInitFile(file, vol, inode); void* record = MmAllocatePool((size_t)vol->FileRecordSize); - if (!record) return STATUS_NO_MEMORY; + if (!record) return NTLSTATUS_NO_MEMORY; KSTATUS s = NtfsReadRecord(vol, inode, record); if (!KSUCCESS(s)) { MmFreePool(record); NtfsCleanupFile(file); return s; } NTFS_LOAD_FILE_CTX ctx; ctx.File = file; - ctx.Status = STATUS_SUCCESS; + ctx.Status = NTLSTATUS_SUCCESS; s = NtfsForEachRecordAttribute(vol, inode, (const NTFS_FILE_RECORD_SEGMENT_HEADER*)record, NtfsLoadFileAttributeCallback, &ctx); MmFreePool(record); if (!KSUCCESS(s)) { NtfsCleanupFile(file); return s; } if (!KSUCCESS(ctx.Status)) { NtfsCleanupFile(file); return ctx.Status; } if (file->ValidDataLength == 0 && file->ResidentDataSize) file->ValidDataLength = file->ResidentDataSize; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS NtfsReadFileData(NTFS_FILE* file, uint64_t offset, void* buffer, size_t size, size_t* bytesRead) { if (bytesRead) *bytesRead = 0; - if (!file || !buffer || !bytesRead) return STATUS_INVALID_PARAMETER; - if (file->IsDirectory) return STATUS_ACCESS_DENIED; - if (offset >= file->Size || size == 0) return STATUS_SUCCESS; + if (!file || !buffer || !bytesRead) return NTLSTATUS_INVALID_PARAMETER; + if (file->IsDirectory) return NTLSTATUS_ACCESS_DENIED; + if (offset >= file->Size || size == 0) return NTLSTATUS_SUCCESS; uint64_t remaining = file->Size - offset; if ((uint64_t)size > remaining) size = (size_t)remaining; @@ -818,7 +818,7 @@ static KSTATUS NtfsReadFileData(NTFS_FILE* file, uint64_t offset, void* buffer, if (copy < size) memset((uint8_t*)buffer + copy, 0, size - copy); } *bytesRead = size; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } uint64_t validEnd = offset + size; @@ -826,7 +826,7 @@ static KSTATUS NtfsReadFileData(NTFS_FILE* file, uint64_t offset, void* buffer, if (offset >= file->ValidDataLength) { memset(buffer, 0, size); *bytesRead = size; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } uint64_t sectorSize = file->Vol->BytesPerSector; @@ -838,7 +838,7 @@ static KSTATUS NtfsReadFileData(NTFS_FILE* file, uint64_t offset, void* buffer, if (startAligned != offset || endAligned != validEnd) { tmp = (uint8_t*)MmAllocatePool((size_t)ioSize); - if (!tmp) return STATUS_NO_MEMORY; + if (!tmp) return NTLSTATUS_NO_MEMORY; ioBuffer = tmp; } @@ -853,7 +853,7 @@ static KSTATUS NtfsReadFileData(NTFS_FILE* file, uint64_t offset, void* buffer, memset((uint8_t*)buffer + (validEnd - offset), 0, (size_t)(offset + size - validEnd)); } *bytesRead = size; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static uint16_t NtfsUpcaseChar(NTFS_VOLUME* vol, uint16_t c) { @@ -956,12 +956,12 @@ static KSTATUS NtfsWalkIndexBuffer(NTFS_VOLUME* vol, NTFS_INDEX_ENTRY_CALLBACK callback, void* ctx, uint32_t depth) { - if (!vol || !root || !nodeHeader || !nodeBase || !callback) return STATUS_INVALID_PARAMETER; - if (depth > 16u) return STATUS_INVALID_PARAMETER; + if (!vol || !root || !nodeHeader || !nodeBase || !callback) return NTLSTATUS_INVALID_PARAMETER; + if (depth > 16u) return NTLSTATUS_INVALID_PARAMETER; if (nodeHeader->FirstEntry > nodeBytes) { NtfsTrace("NTFS: index walk: firstEntry=%u nodeBytes=%llu depth=%u\n", nodeHeader->FirstEntry, (unsigned long long)nodeBytes, depth); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } uint32_t offset = nodeHeader->FirstEntry; @@ -973,23 +973,23 @@ static KSTATUS NtfsWalkIndexBuffer(NTFS_VOLUME* vol, if (ent->EntryLength < sizeof(NTFS_INDEX_ENTRY) || offset + ent->EntryLength > limit) { NtfsTrace("NTFS: index walk: bad entry off=%u len=%u limit=%u flags=0x%x depth=%u\n", offset, ent->EntryLength, limit, ent->Flags, depth); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (!(ent->Flags & NTFS_INDEX_ENTRY_LAST) && ent->StreamLength >= offsetof(NTFS_FILE_NAME_ATTR, FileName)) { const NTFS_FILE_NAME_ATTR* fn = (const NTFS_FILE_NAME_ATTR*)((const uint8_t*)ent + sizeof(NTFS_INDEX_ENTRY)); size_t needed = offsetof(NTFS_FILE_NAME_ATTR, FileName) + (size_t)fn->FileNameLength * sizeof(uint16_t); if (needed <= ent->StreamLength && fn->Namespace != NTFS_FILE_NAME_DOS) { - if (!callback(fn, NtfsFileReferenceNumber(ent->FileReference), ctx)) return STATUS_SUCCESS; + if (!callback(fn, NtfsFileReferenceNumber(ent->FileReference), ctx)) return NTLSTATUS_SUCCESS; } } if (ent->Flags & NTFS_INDEX_ENTRY_SUBNODE) { - if (ent->EntryLength < sizeof(NTFS_INDEX_ENTRY) + sizeof(uint64_t)) return STATUS_INVALID_PARAMETER; + if (ent->EntryLength < sizeof(NTFS_INDEX_ENTRY) + sizeof(uint64_t)) return NTLSTATUS_INVALID_PARAMETER; if (!indexRuns || LIST_IS_EMPTY(indexRuns)) { NtfsTrace("NTFS: index walk: subnode present but no $INDEX_ALLOCATION runs depth=%u off=%u\n", depth, offset); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } uint64_t childVcn = *(const uint64_t*)((const uint8_t*)ent + ent->EntryLength - sizeof(uint64_t)); uint64_t childOffset; @@ -997,7 +997,7 @@ static KSTATUS NtfsWalkIndexBuffer(NTFS_VOLUME* vol, else childOffset = childVcn * (uint64_t)vol->BytesPerCluster; uint8_t* record = (uint8_t*)MmAllocatePool(root->BytesPerIndexRecord); - if (!record) return STATUS_NO_MEMORY; + if (!record) return NTLSTATUS_NO_MEMORY; KSTATUS s = NtfsReadFromRuns(vol, indexRuns, childOffset, record, root->BytesPerIndexRecord); if (KSUCCESS(s)) { NTFS_INDEX_RECORD* ir = (NTFS_INDEX_RECORD*)record; @@ -1006,7 +1006,7 @@ static KSTATUS NtfsWalkIndexBuffer(NTFS_VOLUME* vol, (unsigned long long)childVcn, (unsigned long long)childOffset, ir->MultiSectorHeader.Signature); - s = STATUS_INVALID_PARAMETER; + s = NTLSTATUS_INVALID_PARAMETER; } else s = NtfsProcessFixups(&ir->MultiSectorHeader, root->BytesPerIndexRecord, vol->BytesPerSector); if (KSUCCESS(s)) { @@ -1027,12 +1027,12 @@ static KSTATUS NtfsWalkIndexBuffer(NTFS_VOLUME* vol, offset += ent->EntryLength; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS NtfsWalkDirectory(NTFS_FILE* dir, NTFS_INDEX_ENTRY_CALLBACK callback, void* ctx) { - if (!dir || !dir->IsDirectory || !dir->IndexRoot || !callback) return STATUS_INVALID_PARAMETER; - if (dir->IndexRootSize < sizeof(NTFS_INDEX_ROOT)) return STATUS_INVALID_PARAMETER; + if (!dir || !dir->IsDirectory || !dir->IndexRoot || !callback) return NTLSTATUS_INVALID_PARAMETER; + if (dir->IndexRootSize < sizeof(NTFS_INDEX_ROOT)) return NTLSTATUS_INVALID_PARAMETER; const uint8_t* nodeBase = (const uint8_t*)&dir->IndexRoot->NodeHeader; size_t nodeBytes = dir->IndexRootSize - offsetof(NTFS_INDEX_ROOT, NodeHeader); return NtfsWalkIndexBuffer(dir->Vol, dir->IndexRoot, &dir->IndexRuns, @@ -1051,11 +1051,11 @@ static bool NtfsFindEntryCallback(const NTFS_FILE_NAME_ATTR* fn, uint64_t inode, } static KSTATUS NtfsFindInDirectory(NTFS_VOLUME* vol, uint64_t dirInode, const uint16_t* name, size_t nameLength, uint64_t* outInode) { - if (!vol || !name || !nameLength || !outInode) return STATUS_INVALID_PARAMETER; + if (!vol || !name || !nameLength || !outInode) return NTLSTATUS_INVALID_PARAMETER; NTFS_FILE dir; KSTATUS s = NtfsLoadFile(vol, dirInode, &dir); if (!KSUCCESS(s)) return s; - if (!dir.IsDirectory) { NtfsCleanupFile(&dir); return STATUS_NOT_FOUND; } + if (!dir.IsDirectory) { NtfsCleanupFile(&dir); return NTLSTATUS_NOT_FOUND; } NTFS_FIND_CTX ctx; memset(&ctx, 0, sizeof(ctx)); @@ -1065,18 +1065,18 @@ static KSTATUS NtfsFindInDirectory(NTFS_VOLUME* vol, uint64_t dirInode, const ui s = NtfsWalkDirectory(&dir, NtfsFindEntryCallback, &ctx); NtfsCleanupFile(&dir); if (!KSUCCESS(s)) return s; - if (!ctx.Found) return STATUS_NOT_FOUND; + if (!ctx.Found) return NTLSTATUS_NOT_FOUND; *outInode = ctx.Inode; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS NtfsLookupPath(NTFS_VOLUME* vol, SYS_STRING_VIEW path, uint64_t* outInode) { - if (!vol || !outInode || !SysSvIsValid(path)) return STATUS_INVALID_PARAMETER; + if (!vol || !outInode || !SysSvIsValid(path)) return NTLSTATUS_INVALID_PARAMETER; uint64_t inode = NTFS_ROOT_DIR_INODE; size_t pos = 0; while (pos < path.Length && (path.Data[pos] == '\\' || path.Data[pos] == '/')) pos++; - if (pos >= path.Length) { *outInode = inode; return STATUS_SUCCESS; } + if (pos >= path.Length) { *outInode = inode; return NTLSTATUS_SUCCESS; } while (pos < path.Length) { while (pos < path.Length && (path.Data[pos] == '\\' || path.Data[pos] == '/')) pos++; @@ -1086,8 +1086,8 @@ static KSTATUS NtfsLookupPath(NTFS_VOLUME* vol, SYS_STRING_VIEW path, uint64_t* size_t len = pos - start; if (len == 0) continue; if (len == 1 && path.Data[start] == '.') continue; - if (len == 2 && path.Data[start] == '.' && path.Data[start + 1u] == '.') return STATUS_INVALID_PARAMETER; - if (len > 255u) return STATUS_INVALID_PARAMETER; + if (len == 2 && path.Data[start] == '.' && path.Data[start + 1u] == '.') return NTLSTATUS_INVALID_PARAMETER; + if (len > 255u) return NTLSTATUS_INVALID_PARAMETER; uint16_t segment[260]; for (size_t i = 0; i < len; i++) segment[i] = (uint16_t)(uint8_t)path.Data[start + i]; @@ -1096,7 +1096,7 @@ static KSTATUS NtfsLookupPath(NTFS_VOLUME* vol, SYS_STRING_VIEW path, uint64_t* } *outInode = inode; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static bool NtfsShouldHideDirectoryEntry(const NTFS_FILE_NAME_ATTR* fn, bool hideNtfsMetadata) { @@ -1118,9 +1118,9 @@ static bool NtfsCollectEntryCallback(const NTFS_FILE_NAME_ATTR* fn, uint64_t ino if (NtfsShouldHideDirectoryEntry(fn, ctx->HideNtfsMetadata)) return true; if (dir->Count == dir->Capacity) { uint32_t newCap = dir->Capacity ? dir->Capacity * 2u : 32u; - if (newCap < dir->Capacity) { ctx->Status = STATUS_NO_MEMORY; return false; } + if (newCap < dir->Capacity) { ctx->Status = NTLSTATUS_NO_MEMORY; return false; } NTFS_DIRENT_CACHE* newer = (NTFS_DIRENT_CACHE*)MmReallocatePool(dir->Entries, (size_t)newCap * sizeof(NTFS_DIRENT_CACHE)); - if (!newer) { ctx->Status = STATUS_NO_MEMORY; return false; } + if (!newer) { ctx->Status = NTLSTATUS_NO_MEMORY; return false; } dir->Entries = newer; dir->Capacity = newCap; } @@ -1135,25 +1135,25 @@ static bool NtfsCollectEntryCallback(const NTFS_FILE_NAME_ATTR* fn, uint64_t ino e->LastAccessTime = fn->LastAccessTime; e->LastWriteTime = fn->LastWriteTime; NtfsUtf16ToAscii(fn->FileName, fn->FileNameLength, e->Name, sizeof(e->Name)); - ctx->Status = STATUS_SUCCESS; + ctx->Status = NTLSTATUS_SUCCESS; return true; } static KSTATUS NtfsOpen(IO_FILESYSTEM* fs, SYS_STRING_VIEW path, void** fileCtx) { - if (!fs || !fileCtx || !SysSvIsValid(path)) return STATUS_INVALID_PARAMETER; + if (!fs || !fileCtx || !SysSvIsValid(path)) return NTLSTATUS_INVALID_PARAMETER; NTFS_VOLUME* vol = (NTFS_VOLUME*)fs->DriverCtx; - if (!vol) return STATUS_INVALID_PARAMETER; + if (!vol) return NTLSTATUS_INVALID_PARAMETER; uint64_t inode; KSTATUS s = NtfsLookupPath(vol, path, &inode); if (!KSUCCESS(s)) return s; NTFS_FILE* file = (NTFS_FILE*)MmAllocatePool(sizeof(NTFS_FILE)); - if (!file) return STATUS_NO_MEMORY; + if (!file) return NTLSTATUS_NO_MEMORY; s = NtfsLoadFile(vol, inode, file); if (!KSUCCESS(s)) { MmFreePool(file); return s; } *fileCtx = file; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static void NtfsClose(IO_FILESYSTEM* fs, void* fileCtx) { @@ -1172,22 +1172,22 @@ static KSTATUS NtfsRead(IO_FILESYSTEM* fs, void* fileCtx, uint64_t offset, void* static KSTATUS NtfsWrite(IO_FILESYSTEM* fs, void* fileCtx, uint64_t offset, const void* buf, size_t size, size_t* bytesWritten) { (void)fs; (void)fileCtx; (void)offset; (void)buf; (void)size; if (bytesWritten) *bytesWritten = 0; - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } static KSTATUS NtfsCreate(IO_FILESYSTEM* fs, SYS_STRING_VIEW path, void** fileCtx) { (void)fs; (void)path; (void)fileCtx; - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } static KSTATUS NtfsDelete(IO_FILESYSTEM* fs, SYS_STRING_VIEW path) { (void)fs; (void)path; - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } static KSTATUS NtfsTruncate(IO_FILESYSTEM* fs, void* fileCtx, uint64_t newSize, uint32_t fileFlags) { (void)fs; (void)fileCtx; (void)newSize; (void)fileFlags; - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } static uint64_t NtfsGetSize(IO_FILESYSTEM* fs, void* fileCtx) { @@ -1198,13 +1198,13 @@ static uint64_t NtfsGetSize(IO_FILESYSTEM* fs, void* fileCtx) { static KSTATUS NtfsQueryInfo(IO_FILESYSTEM* fs, void* fileCtx, SYS_FILE_STAT* out) { (void)fs; - if (!fileCtx || !out) return STATUS_INVALID_PARAMETER; + if (!fileCtx || !out) return NTLSTATUS_INVALID_PARAMETER; NtfsFillStat((NTFS_FILE*)fileCtx, out); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS NtfsStat(IO_FILESYSTEM* fs, SYS_STRING_VIEW path, SYS_FILE_STAT* out) { - if (!fs || !out || !SysSvIsValid(path)) return STATUS_INVALID_PARAMETER; + if (!fs || !out || !SysSvIsValid(path)) return NTLSTATUS_INVALID_PARAMETER; void* ctx = NULL; KSTATUS s = NtfsOpen(fs, path, &ctx); if (!KSUCCESS(s)) return s; @@ -1215,19 +1215,19 @@ static KSTATUS NtfsStat(IO_FILESYSTEM* fs, SYS_STRING_VIEW path, SYS_FILE_STAT* static KSTATUS NtfsQueryIdentity(IO_FILESYSTEM* fs, void* fileCtx, IO_FILE_IDENTITY* out) { (void)fs; - if (!fileCtx || !out) return STATUS_INVALID_PARAMETER; + if (!fileCtx || !out) return NTLSTATUS_INVALID_PARAMETER; NTFS_FILE* file = (NTFS_FILE*)fileCtx; out->VolumeId = file->Vol->SerialNumber; out->FileId = file->Inode; out->Generation = (uint64_t)file->StandardInfo.LastWriteTime ^ ((uint64_t)file->StandardInfo.ChangeTime << 1u); out->Size = file->Size; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS NtfsOpenDir(IO_FILESYSTEM* fs, SYS_STRING_VIEW dirPath, void** dirCtx) { - if (!fs || !dirCtx || !SysSvIsValid(dirPath)) return STATUS_INVALID_PARAMETER; + if (!fs || !dirCtx || !SysSvIsValid(dirPath)) return NTLSTATUS_INVALID_PARAMETER; NTFS_VOLUME* vol = (NTFS_VOLUME*)fs->DriverCtx; - if (!vol) return STATUS_INVALID_PARAMETER; + if (!vol) return NTLSTATUS_INVALID_PARAMETER; uint64_t inode; KSTATUS s = NtfsLookupPath(vol, dirPath, &inode); @@ -1245,10 +1245,10 @@ static KSTATUS NtfsOpenDir(IO_FILESYSTEM* fs, SYS_STRING_VIEW dirPath, void** di return s; } if (!dir.IsDirectory) { - NtfsTrace("NTFS: opendir: inode=%llu is not directory attr=0x%x indexRoot=%p\n", + NtfsTrace("NTFS: opendir: inode=%llu is not directory attr=0x%x indexRoot=0x%016llX\n", (unsigned long long)inode, dir.Attributes, dir.IndexRoot); NtfsCleanupFile(&dir); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } if (!dir.IndexRoot) { NtfsTrace("NTFS: opendir: inode=%llu has no $I30 $INDEX_ROOT\n", @@ -1262,14 +1262,14 @@ static KSTATUS NtfsOpenDir(IO_FILESYSTEM* fs, SYS_STRING_VIEW dirPath, void** di } NTFS_DIR_CTX* ctx = (NTFS_DIR_CTX*)MmAllocatePool(sizeof(NTFS_DIR_CTX)); - if (!ctx) { NtfsCleanupFile(&dir); return STATUS_NO_MEMORY; } + if (!ctx) { NtfsCleanupFile(&dir); return NTLSTATUS_NO_MEMORY; } memset(ctx, 0, sizeof(*ctx)); NTFS_COLLECT_CTX collect; memset(&collect, 0, sizeof(collect)); collect.Vol = vol; collect.Dir = ctx; - collect.Status = STATUS_SUCCESS; + collect.Status = NTLSTATUS_SUCCESS; collect.HideNtfsMetadata = (inode == NTFS_ROOT_DIR_INODE); s = NtfsWalkDirectory(&dir, NtfsCollectEntryCallback, &collect); NtfsCleanupFile(&dir); @@ -1292,14 +1292,14 @@ static KSTATUS NtfsOpenDir(IO_FILESYSTEM* fs, SYS_STRING_VIEW dirPath, void** di (unsigned long long)inode, ctx->Count); *dirCtx = ctx; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS NtfsReadDir(IO_FILESYSTEM* fs, void* dirCtx, KDIR_ENTRY* out) { (void)fs; - if (!dirCtx || !out) return STATUS_INVALID_PARAMETER; + if (!dirCtx || !out) return NTLSTATUS_INVALID_PARAMETER; NTFS_DIR_CTX* ctx = (NTFS_DIR_CTX*)dirCtx; - if (ctx->Position >= ctx->Count) return STATUS_NO_MORE_FILES; + if (ctx->Position >= ctx->Count) return NTLSTATUS_NO_MORE_FILES; NTFS_DIRENT_CACHE* e = &ctx->Entries[ctx->Position++]; memset(out, 0, sizeof(*out)); strncpy(out->Name, e->Name, sizeof(out->Name) - 1u); @@ -1308,7 +1308,7 @@ static KSTATUS NtfsReadDir(IO_FILESYSTEM* fs, void* dirCtx, KDIR_ENTRY* out) { NtfsWinTimeToSystemTime(e->CreationTime, &out->CreateTime); NtfsWinTimeToSystemTime(e->LastAccessTime, &out->LastAccessTime); NtfsWinTimeToSystemTime(e->LastWriteTime, &out->LastWriteTime); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static void NtfsCloseDir(IO_FILESYSTEM* fs, void* dirCtx) { @@ -1384,36 +1384,36 @@ static bool NtfsMftAttributeCallback(const NTFS_ATTR_VIEW* view, void* rawCtx) { static KSTATUS NtfsReadMftRuns(NTFS_VOLUME* vol) { void* record = MmAllocatePool((size_t)vol->FileRecordSize); - if (!record) return STATUS_NO_MEMORY; + if (!record) return NTLSTATUS_NO_MEMORY; uint64_t mftByte = vol->MftStartCluster * vol->BytesPerCluster; KSTATUS s = NtfsReadBytesDirect(vol, mftByte, vol->FileRecordSize, record); if (KSUCCESS(s)) { NTFS_FILE_RECORD_SEGMENT_HEADER* fr = (NTFS_FILE_RECORD_SEGMENT_HEADER*)record; - if (fr->MultiSectorHeader.Signature != NTFS_FILE_SIGNATURE) s = STATUS_INVALID_PARAMETER; + if (fr->MultiSectorHeader.Signature != NTFS_FILE_SIGNATURE) s = NTLSTATUS_INVALID_PARAMETER; else s = NtfsProcessFixups(&fr->MultiSectorHeader, vol->FileRecordSize, vol->BytesPerSector); } if (!KSUCCESS(s)) { MmFreePool(record); return s; } NTFS_MFT_CTX ctx; ctx.Vol = vol; - ctx.Status = STATUS_NOT_FOUND; + ctx.Status = NTLSTATUS_NOT_FOUND; ctx.Found = false; s = NtfsForEachRecordAttribute(vol, NTFS_MFT_INODE, (const NTFS_FILE_RECORD_SEGMENT_HEADER*)record, NtfsMftAttributeCallback, &ctx); MmFreePool(record); if (!KSUCCESS(s)) return s; - if (!ctx.Found) return STATUS_NOT_FOUND; + if (!ctx.Found) return NTLSTATUS_NOT_FOUND; if (KSUCCESS(ctx.Status)) NtfsDebugDumpRuns("mft", &vol->MftRuns); return ctx.Status; } static KSTATUS NtfsInitUpcaseIdentity(NTFS_VOLUME* vol) { - if (!vol) return STATUS_INVALID_PARAMETER; + if (!vol) return NTLSTATUS_INVALID_PARAMETER; vol->Upcase = (uint16_t*)MmAllocatePool(NTFS_UPCASE_TABLE_BYTES); - if (!vol->Upcase) return STATUS_NO_MEMORY; + if (!vol->Upcase) return NTLSTATUS_NO_MEMORY; for (uint32_t i = 0; i < NTFS_UPCASE_TABLE_CHARS; i++) vol->Upcase[i] = (uint16_t)i; for (uint16_t c = (uint16_t)'a'; c <= (uint16_t)'z'; c++) vol->Upcase[c] = (uint16_t)(c - 32u); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static void NtfsCleanupVolume(NTFS_VOLUME* vol) { @@ -1436,7 +1436,7 @@ static void NtfsTryLoadUpcase(NTFS_VOLUME* vol) { } static KSTATUS NtfsProbeAndPrepareVolume(NTFS_VOLUME* vol, uint8_t disk, uint64_t startLba, uint64_t sectors) { - if (!vol) return STATUS_INVALID_PARAMETER; + if (!vol) return NTLSTATUS_INVALID_PARAMETER; memset(vol, 0, sizeof(*vol)); vol->DriveIndex = disk; vol->PartitionLba = startLba; @@ -1450,7 +1450,7 @@ static KSTATUS NtfsProbeAndPrepareVolume(NTFS_VOLUME* vol, uint8_t disk, uint64_ if (!KSUCCESS(s)) return s; const NTFS_BOOT_SECTOR* bs = (const NTFS_BOOT_SECTOR*)sector; - if (!NtfsIsValidBootSector(bs)) return STATUS_NOT_SUPPORTED; + if (!NtfsIsValidBootSector(bs)) return NTLSTATUS_NOT_SUPPORTED; vol->BytesPerSector = bs->BytesPerSector; vol->SectorsPerCluster = bs->SectorsPerCluster; @@ -1462,14 +1462,14 @@ static KSTATUS NtfsProbeAndPrepareVolume(NTFS_VOLUME* vol, uint8_t disk, uint64_ vol->MftStartCluster = bs->MFT; vol->FileRecordSize = NtfsDecodeRecordSize(bs->ClustersPerMFTRecord, vol->BytesPerCluster); if (vol->FileRecordSize == 0 || vol->FileRecordSize > 65536ull || (vol->FileRecordSize % vol->BytesPerSector) != 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; s = NtfsInitUpcaseIdentity(vol); if (!KSUCCESS(s)) return s; s = NtfsReadMftRuns(vol); if (!KSUCCESS(s)) { NtfsCleanupVolume(vol); return s; } NtfsTryLoadUpcase(vol); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static uint32_t NtfsEnumerateDiskPartitions(uint8_t disk, NTFS_PARTITION_CANDIDATE* parts, uint32_t maxParts, bool* mediaReadable) { @@ -1692,7 +1692,7 @@ static void NtfsDiskChange(uint8_t driveIndex, DEVICE_OBJECT* device, IO_DEVICE_ KSTATUS DriverEntry(const HAL_API* hal) { DbgPrint("NTFS: Init\n"); - if (!hal) return STATUS_INVALID_PARAMETER; + if (!hal) return NTLSTATUS_INVALID_PARAMETER; (void)hal; memset(gVolumes, 0, sizeof(gVolumes)); memset(gFilesystems, 0, sizeof(gFilesystems)); @@ -1708,8 +1708,8 @@ KSTATUS DriverEntry(const HAL_API* hal) { if (!gMountedCount) { DbgPrint("NTFS: no mountable NTFS volumes found.\n"); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } DbgPrint("NTFS: Init complete; mounted %u volume(s).\n", gMountedCount); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } diff --git a/code/drivers/input/ps2/ps2.c b/code/drivers/input/ps2/ps2.c index b1d45bf..293cb31 100644 --- a/code/drivers/input/ps2/ps2.c +++ b/code/drivers/input/ps2/ps2.c @@ -305,5 +305,5 @@ KSTATUS DriverEntry(const HAL_API* hal) { Ps2ControllerEnableInterrupts(); DbgPrint("ps2: initialized keyboard=%u mouse=%u\n", keyboardId, mouseId); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } diff --git a/code/drivers/input/serial/serial.c b/code/drivers/input/serial/serial.c index 853dc3f..583d26a 100644 --- a/code/drivers/input/serial/serial.c +++ b/code/drivers/input/serial/serial.c @@ -339,5 +339,5 @@ KSTATUS DriverEntry(const HAL_API* hal) { KeIrqRegister(SERIAL_COM1_IRQ, SerialIsr); DbgPrint("serial: initialized COM1 input device=%u irq=%u\n", deviceId, SERIAL_COM1_IRQ); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } diff --git a/code/drivers/net/lwip/lwip_stack.c b/code/drivers/net/lwip/lwip_stack.c index d9d7617..16fb1a7 100644 --- a/code/drivers/net/lwip/lwip_stack.c +++ b/code/drivers/net/lwip/lwip_stack.c @@ -134,21 +134,21 @@ static NET_STACK_PROVIDER gLwipProvider = { // Implements the err To Status operation. static KSTATUS LwipErrToStatus(err_t err) { switch (err) { - case ERR_OK: return STATUS_SUCCESS; - case ERR_MEM: return STATUS_NO_MEMORY; - case ERR_BUF: return STATUS_BUFFER_TOO_SMALL; - case ERR_TIMEOUT: return STATUS_TIMEOUT; - case ERR_WOULDBLOCK:return STATUS_WOULD_BLOCK; - case ERR_RTE: return STATUS_NOT_FOUND; - case ERR_VAL: return STATUS_INVALID_PARAMETER; - case ERR_ARG: return STATUS_INVALID_PARAMETER; - case ERR_USE: return STATUS_ALREADY_EXISTS; - case ERR_ISCONN: return STATUS_ALREADY_EXISTS; - case ERR_CONN: return STATUS_OBJECT_DEAD; - case ERR_CLSD: return STATUS_OBJECT_DEAD; - case ERR_ABRT: return STATUS_OBJECT_DEAD; - case ERR_RST: return STATUS_OBJECT_DEAD; - default: return STATUS_FAILURE; + case ERR_OK: return NTLSTATUS_SUCCESS; + case ERR_MEM: return NTLSTATUS_NO_MEMORY; + case ERR_BUF: return NTLSTATUS_BUFFER_TOO_SMALL; + case ERR_TIMEOUT: return NTLSTATUS_TIMEOUT; + case ERR_WOULDBLOCK:return NTLSTATUS_WOULD_BLOCK; + case ERR_RTE: return NTLSTATUS_NOT_FOUND; + case ERR_VAL: return NTLSTATUS_INVALID_PARAMETER; + case ERR_ARG: return NTLSTATUS_INVALID_PARAMETER; + case ERR_USE: return NTLSTATUS_ALREADY_EXISTS; + case ERR_ISCONN: return NTLSTATUS_ALREADY_EXISTS; + case ERR_CONN: return NTLSTATUS_OBJECT_DEAD; + case ERR_CLSD: return NTLSTATUS_OBJECT_DEAD; + case ERR_ABRT: return NTLSTATUS_OBJECT_DEAD; + case ERR_RST: return NTLSTATUS_OBJECT_DEAD; + default: return NTLSTATUS_FAILURE; } } @@ -199,36 +199,36 @@ static KSTATUS LwipGetSettingIpv4(const char* section, const char* key, ip4_addr_t* out, int required) { char value[LWIP_SETTINGS_VALUE_MAX]; KSTATUS st = KeGetSettingString(section, key, value, sizeof(value)); - if (st == STATUS_NOT_FOUND && !required) - return STATUS_NOT_FOUND; + if (st == NTLSTATUS_NOT_FOUND && !required) + return NTLSTATUS_NOT_FOUND; if (!KSUCCESS(st)) return st; if (!LwipParseIpv4(value, out)) { DbgPrint("lwIP: invalid IPv4 setting [%s] %s=%s\n", section, key, value); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS LwipGetSettingIpv6(const char* section, const char* key, ip6_addr_t* out, int required) { char value[LWIP_SETTINGS_VALUE_MAX]; KSTATUS st = KeGetSettingString(section, key, value, sizeof(value)); - if (st == STATUS_NOT_FOUND && !required) - return STATUS_NOT_FOUND; + if (st == NTLSTATUS_NOT_FOUND && !required) + return NTLSTATUS_NOT_FOUND; if (!KSUCCESS(st)) return st; if (!ip6addr_aton(value, out)) { DbgPrint("lwIP: invalid IPv6 setting [%s] %s=%s\n", section, key, value); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS LwipLoadIpv6Config(const char* section, LWIP_NETIF_CONFIG* cfg) { char mode[LWIP_SETTINGS_VALUE_MAX]; KSTATUS st = KeGetSettingString(section, "ipv6", mode, sizeof(mode)); - if (st == STATUS_NOT_FOUND) { + if (st == NTLSTATUS_NOT_FOUND) { cfg->EnableIpv6 = 1; cfg->Ipv6Autoconfig = 1; } else if (!KSUCCESS(st)) { @@ -246,40 +246,40 @@ static KSTATUS LwipLoadIpv6Config(const char* section, LWIP_NETIF_CONFIG* cfg) { return st; } else { DbgPrint("lwIP: invalid IPv6 mode [%s] ipv6=%s\n", section, mode); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (!cfg->EnableIpv6) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; st = LwipGetSettingIpv6(section, "dns6", &cfg->Dns6, 0); if (KSUCCESS(st)) cfg->HasDns6 = 1; - else if (st != STATUS_NOT_FOUND) + else if (st != NTLSTATUS_NOT_FOUND) return st; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Copies section Name. static KSTATUS LwipCopySectionName(char* out, size_t outSize, const char* prefix, const char* name) { if (!out || !outSize || !prefix || !name) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; size_t prefixLen = strlen(prefix); size_t nameLen = strlen(name); if (prefixLen + nameLen + 1 > outSize) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; memcpy(out, prefix, prefixLen); memcpy(out + prefixLen, name, nameLen + 1); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Loads config From Section. static KSTATUS LwipLoadConfigFromSection(const char* section, LWIP_NETIF_CONFIG* cfg) { if (!section || !cfg) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; char mode[LWIP_SETTINGS_VALUE_MAX]; KSTATUS st = KeGetSettingString(section, "mode", mode, sizeof(mode)); @@ -289,7 +289,7 @@ static KSTATUS LwipLoadConfigFromSection(const char* section, LWIP_NETIF_CONFIG* memset(cfg, 0, sizeof(*cfg)); size_t sectionLen = strlen(section); if (sectionLen >= sizeof(cfg->Section)) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; memcpy(cfg->Section, section, sectionLen + 1); if (strcmp(mode, "static") == 0) { @@ -311,19 +311,19 @@ static KSTATUS LwipLoadConfigFromSection(const char* section, LWIP_NETIF_CONFIG* st = LwipGetSettingIpv4(section, "dns", &cfg->Dns4, 0); if (KSUCCESS(st)) cfg->HasDns4 = 1; - else if (st != STATUS_NOT_FOUND) + else if (st != NTLSTATUS_NOT_FOUND) return st; return LwipLoadIpv6Config(section, cfg); } DbgPrint("lwIP: invalid network mode [%s] mode=%s\n", section, mode); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } // Loads netif Config. static KSTATUS LwipLoadNetifConfig(const NET_DEVICE* device, LWIP_NETIF_CONFIG* cfg) { if (!device || !cfg) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; char section[64]; KSTATUS st = LwipCopySectionName(section, sizeof(section), @@ -333,9 +333,9 @@ static KSTATUS LwipLoadNetifConfig(const NET_DEVICE* device, LWIP_NETIF_CONFIG* st = LwipLoadConfigFromSection(section, cfg); if (KSUCCESS(st)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; - if (st != STATUS_NOT_FOUND) { + if (st != NTLSTATUS_NOT_FOUND) { DbgPrint("lwIP: invalid settings for [%s] (0x%x)\n", section, st); return st; } @@ -347,13 +347,13 @@ static KSTATUS LwipLoadNetifConfig(const NET_DEVICE* device, LWIP_NETIF_CONFIG* return st; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the socket Lock operation. static KSTATUS LwipSocketLock(LWIP_PROVIDER_SOCKET* s) { if (!s || !s->Lock) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; return KeWaitSemaphore(s->Lock); } @@ -407,12 +407,12 @@ static void LwipSocketCallback(struct netconn* conn, enum netconn_evt evt, u16_t static KSTATUS LwipSocketAllocateWithConn(uint32_t domain, uint32_t type, uint32_t protocol, struct netconn* conn, LWIP_PROVIDER_SOCKET** out) { if (!conn || !out) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *out = NULL; LWIP_PROVIDER_SOCKET* s = (LWIP_PROVIDER_SOCKET*)MmAllocatePool(sizeof(*s)); if (!s) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; memset(s, 0, sizeof(*s)); KSTATUS st = KeSemaphoreCreate(1, 1, &s->Lock); @@ -430,7 +430,7 @@ static KSTATUS LwipSocketAllocateWithConn(uint32_t domain, uint32_t type, uint32 netconn_set_recvtimeout(conn, 0); netconn_set_sendtimeout(conn, 0); *out = s; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } @@ -452,13 +452,13 @@ static KSTATUS LwipSocketWaitRecvNetbuf(LWIP_PROVIDER_SOCKET* s, volatile uint8_t* cancelRequested, err_t* errOut) { if (!s || !s->Conn || !bufferOut || !errOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *bufferOut = NULL; *errOut = ERR_OK; if (!cancelRequested || s->NonBlocking) { *errOut = netconn_recv(s->Conn, bufferOut); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } uint32_t originalTimeout = s->ReceiveTimeoutMs; @@ -466,7 +466,7 @@ static KSTATUS LwipSocketWaitRecvNetbuf(LWIP_PROVIDER_SOCKET* s, for (;;) { if (LwipSocketCancelRequested(cancelRequested)) { netconn_set_recvtimeout(s->Conn, originalTimeout); - return STATUS_CANCELLED; + return NTLSTATUS_CANCELLED; } uint32_t remaining = 0; @@ -474,7 +474,7 @@ static KSTATUS LwipSocketWaitRecvNetbuf(LWIP_PROVIDER_SOCKET* s, if (elapsed >= originalTimeout) { netconn_set_recvtimeout(s->Conn, originalTimeout); *errOut = ERR_TIMEOUT; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } remaining = originalTimeout - elapsed; } @@ -485,7 +485,7 @@ static KSTATUS LwipSocketWaitRecvNetbuf(LWIP_PROVIDER_SOCKET* s, if (err != ERR_TIMEOUT) { netconn_set_recvtimeout(s->Conn, originalTimeout); *errOut = err; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } elapsed += slice; @@ -498,13 +498,13 @@ static KSTATUS LwipSocketWaitAccept(LWIP_PROVIDER_SOCKET* s, volatile uint8_t* cancelRequested, err_t* errOut) { if (!s || !s->Conn || !acceptedOut || !errOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *acceptedOut = NULL; *errOut = ERR_OK; if (!cancelRequested || s->NonBlocking) { *errOut = netconn_accept(s->Conn, acceptedOut); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } uint32_t originalTimeout = s->ReceiveTimeoutMs; @@ -512,7 +512,7 @@ static KSTATUS LwipSocketWaitAccept(LWIP_PROVIDER_SOCKET* s, for (;;) { if (LwipSocketCancelRequested(cancelRequested)) { netconn_set_recvtimeout(s->Conn, originalTimeout); - return STATUS_CANCELLED; + return NTLSTATUS_CANCELLED; } uint32_t remaining = 0; @@ -520,7 +520,7 @@ static KSTATUS LwipSocketWaitAccept(LWIP_PROVIDER_SOCKET* s, if (elapsed >= originalTimeout) { netconn_set_recvtimeout(s->Conn, originalTimeout); *errOut = ERR_TIMEOUT; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } remaining = originalTimeout - elapsed; } @@ -531,7 +531,7 @@ static KSTATUS LwipSocketWaitAccept(LWIP_PROVIDER_SOCKET* s, if (err != ERR_TIMEOUT) { netconn_set_recvtimeout(s->Conn, originalTimeout); *errOut = err; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } elapsed += slice; @@ -539,9 +539,9 @@ static KSTATUS LwipSocketWaitAccept(LWIP_PROVIDER_SOCKET* s, } static int LwipSocketAddressValid(const SYS_SOCKET_ADDRESS_K* address, size_t addressSize) { - if (!address || addressSize < sizeof(SYS_SOCKET_ADDRESS_K)) + if (!address || addressSize != sizeof(SYS_SOCKET_ADDRESS_K)) return 0; - if (address->Size < sizeof(SYS_SOCKET_ADDRESS_K)) + if (address->Size != sizeof(SYS_SOCKET_ADDRESS_K)) return 0; return address->Family == SYS_AF_INET || address->Family == SYS_AF_INET6; } @@ -559,10 +559,10 @@ static int LwipSocketFamilyMatches(const LWIP_PROVIDER_SOCKET* s, const SYS_SOCK // Implements the socket Make Ip operation. static KSTATUS LwipSocketMakeIp(const SYS_SOCKET_ADDRESS_K* address, ip_addr_t* out) { if (!address || !out) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (address->Family == SYS_AF_INET) { IP_ADDR4(out, address->Address[0], address->Address[1], address->Address[2], address->Address[3]); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (address->Family == SYS_AF_INET6) { uint32_t a0 = ((uint32_t)address->Address[0] << 24) | ((uint32_t)address->Address[1] << 16) | @@ -575,9 +575,9 @@ static KSTATUS LwipSocketMakeIp(const SYS_SOCKET_ADDRESS_K* address, ip_addr_t* ((uint32_t)address->Address[14] << 8) | (uint32_t)address->Address[15]; IP_ADDR6_HOST(out, a0, a1, a2, a3); ip6_addr_set_zone(ip_2_ip6(out), (u8_t)address->ScopeId); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } // Implements the socket Fill Address operation. @@ -756,9 +756,9 @@ static void LwipInitDone(void* arg) { // Implements the stack Initialize operation. static KSTATUS LwipStackInitialize(const HAL_API* hal) { if (gLwipInitialized) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (!hal || !hal->Timer.QueryTicks) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; LwipPortSetTimerQuery(hal->Timer.QueryTicks); @@ -775,24 +775,24 @@ static KSTATUS LwipStackInitialize(const HAL_API* hal) { gLwipInitialized = 1; DbgPrint("lwIP: tcpip thread initialized\n"); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the provider Attach Device operation. static KSTATUS LwipProviderAttachDevice(NET_DEVICE* device) { if (!gLwipInitialized) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (!device || device->Index >= LWIP_MAX_NETIFS) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (device->HardwareAddressLength != NET_ETHERNET_ADDRESS_LENGTH) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (gBindings[device->Index]) - return STATUS_ALREADY_EXISTS; + return NTLSTATUS_ALREADY_EXISTS; LWIP_BINDING* b = (LWIP_BINDING*)MmAllocatePool(sizeof(*b)); if (!b) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; memset(b, 0, sizeof(*b)); b->Device = device; @@ -818,13 +818,13 @@ static KSTATUS LwipProviderAttachDevice(NET_DEVICE* device) { if (err == ERR_OK) st = KeWaitSemaphore(done); else - st = STATUS_FAILURE; + st = NTLSTATUS_FAILURE; ObDereferenceObject(&done->Header); if (!KSUCCESS(st) || ctx.Result != ERR_OK) { MmFreePool(b); - return KSUCCESS(st) ? STATUS_FAILURE : st; + return KSUCCESS(st) ? NTLSTATUS_FAILURE : st; } gBindings[device->Index] = b; @@ -834,79 +834,79 @@ static KSTATUS LwipProviderAttachDevice(NET_DEVICE* device) { b->Config.Section, b->Config.UseDhcp ? "dhcp" : "static", b->Config.EnableIpv6 ? (b->Config.HasStaticIpv6 ? "static" : "auto") : "off"); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the provider Receive Frame operation. static KSTATUS LwipProviderReceiveFrame(NET_DEVICE* device, const void* frame, size_t length) { if (!gLwipInitialized) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (!device || device->Index >= LWIP_MAX_NETIFS || !frame) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; LWIP_BINDING* b = gBindings[device->Index]; if (!b || !b->Attached) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; if (length < NET_ETHERNET_HEADER_LENGTH || length > NET_ETHERNET_MAX_FRAME) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; struct pbuf* p = pbuf_alloc(PBUF_RAW, (u16_t)length, PBUF_POOL); if (!p) p = pbuf_alloc(PBUF_RAW, (u16_t)length, PBUF_RAM); if (!p) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; if (pbuf_take(p, frame, (u16_t)length) != ERR_OK) { pbuf_free(p); - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; } err_t err = b->Netif.input(p, &b->Netif); if (err != ERR_OK) { pbuf_free(p); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the provider Socket Create operation. static KSTATUS LwipProviderSocketCreate(uint32_t domain, uint32_t type, uint32_t protocol, void** outSocket) { if (!outSocket) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *outSocket = NULL; if (!gLwipInitialized) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (domain != SYS_AF_INET && domain != SYS_AF_INET6) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; int ipv6 = domain == SYS_AF_INET6; enum netconn_type netconnType; u8_t rawProtocol = 0; if (type == SYS_SOCK_STREAM) { if (protocol != 0 && protocol != SYS_IPPROTO_TCP) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; netconnType = ipv6 ? NETCONN_TCP_IPV6 : NETCONN_TCP; protocol = SYS_IPPROTO_TCP; } else if (type == SYS_SOCK_DGRAM) { if (protocol != 0 && protocol != SYS_IPPROTO_UDP) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; netconnType = ipv6 ? NETCONN_UDP_IPV6 : NETCONN_UDP; protocol = SYS_IPPROTO_UDP; } else if (type == SYS_SOCK_RAW) { if ((!ipv6 && protocol != SYS_IPPROTO_ICMP) || (ipv6 && protocol != SYS_IPPROTO_ICMPV6)) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; netconnType = ipv6 ? NETCONN_RAW_IPV6 : NETCONN_RAW; rawProtocol = ipv6 ? IP6_NEXTH_ICMP6 : IP_PROTO_ICMP; } else { - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } struct netconn* conn = netconn_new_with_proto_and_callback(netconnType, rawProtocol, NULL); if (!conn) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; LWIP_PROVIDER_SOCKET* s = NULL; KSTATUS st = LwipSocketAllocateWithConn(domain, type, protocol, conn, &s); @@ -916,7 +916,7 @@ static KSTATUS LwipProviderSocketCreate(uint32_t domain, uint32_t type, uint32_t } *outSocket = s; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the provider Socket Close operation. @@ -950,13 +950,13 @@ static void LwipProviderSocketClose(void* socket) { static KSTATUS LwipProviderBind(void* socket, const SYS_SOCKET_ADDRESS_K* address, size_t addressSize) { LWIP_PROVIDER_SOCKET* s = (LWIP_PROVIDER_SOCKET*)socket; if (!s || !address) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!LwipSocketAddressValid(address, addressSize)) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; if ((s->Type != SYS_SOCK_STREAM && s->Type != SYS_SOCK_DGRAM) || !s->Conn) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!LwipSocketFamilyMatches(s, address)) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; KSTATUS st = LwipSocketLock(s); if (!KSUCCESS(st)) @@ -964,7 +964,7 @@ static KSTATUS LwipProviderBind(void* socket, const SYS_SOCKET_ADDRESS_K* addres if (s->Connected || s->Listening || s->ShutdownRead || s->ShutdownWrite) { LwipSocketUnlock(s); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } ip_addr_t ip; @@ -985,9 +985,9 @@ static KSTATUS LwipProviderBind(void* socket, const SYS_SOCKET_ADDRESS_K* addres static KSTATUS LwipProviderListen(void* socket, uint32_t backlog) { LWIP_PROVIDER_SOCKET* s = (LWIP_PROVIDER_SOCKET*)socket; if (!s) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (s->Type != SYS_SOCK_STREAM || !s->Conn) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (backlog > 255u) backlog = 255u; @@ -997,7 +997,7 @@ static KSTATUS LwipProviderListen(void* socket, uint32_t backlog) { if (s->Connected || s->ShutdownRead || s->ShutdownWrite) { LwipSocketUnlock(s); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } err_t err = netconn_listen_with_backlog(s->Conn, (u8_t)backlog); @@ -1014,13 +1014,13 @@ static KSTATUS LwipProviderListen(void* socket, uint32_t backlog) { static KSTATUS LwipProviderAccept(void* socket, void** acceptedOut, SYS_SOCKET_ADDRESS_K* remoteOut, volatile uint8_t* cancelRequested) { LWIP_PROVIDER_SOCKET* s = (LWIP_PROVIDER_SOCKET*)socket; if (!s || !acceptedOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *acceptedOut = NULL; if (remoteOut) memset(remoteOut, 0, sizeof(*remoteOut)); if (s->Type != SYS_SOCK_STREAM || !s->Conn) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS st = LwipSocketLock(s); if (!KSUCCESS(st)) @@ -1028,7 +1028,7 @@ static KSTATUS LwipProviderAccept(void* socket, void** acceptedOut, SYS_SOCKET_A if (!s->Listening || s->ShutdownRead || s->ShutdownWrite) { LwipSocketUnlock(s); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } struct netconn* acceptedConn = NULL; @@ -1041,7 +1041,7 @@ static KSTATUS LwipProviderAccept(void* socket, void** acceptedOut, SYS_SOCKET_A if (err != ERR_OK) return LwipErrToStatus(err); if (!acceptedConn) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; LWIP_PROVIDER_SOCKET* accepted = NULL; st = LwipSocketAllocateWithConn(s->Domain, s->Type, s->Protocol, acceptedConn, &accepted); @@ -1066,20 +1066,20 @@ static KSTATUS LwipProviderAccept(void* socket, void** acceptedOut, SYS_SOCKET_A } *acceptedOut = accepted; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the provider Connect operation. static KSTATUS LwipProviderConnect(void* socket, const SYS_SOCKET_ADDRESS_K* address, size_t addressSize, volatile uint8_t* cancelRequested) { LWIP_PROVIDER_SOCKET* s = (LWIP_PROVIDER_SOCKET*)socket; if (!s || !address) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!LwipSocketAddressValid(address, addressSize)) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; if ((s->Type != SYS_SOCK_STREAM && s->Type != SYS_SOCK_DGRAM) || !s->Conn) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!LwipSocketFamilyMatches(s, address)) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; KSTATUS st = LwipSocketLock(s); if (!KSUCCESS(st)) @@ -1087,11 +1087,11 @@ static KSTATUS LwipProviderConnect(void* socket, const SYS_SOCKET_ADDRESS_K* add if (s->Listening) { LwipSocketUnlock(s); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (s->ShutdownRead || s->ShutdownWrite) { LwipSocketUnlock(s); - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; } ip_addr_t ip; @@ -1117,7 +1117,7 @@ static KSTATUS LwipProviderConnect(void* socket, const SYS_SOCKET_ADDRESS_K* add netconn_set_nonblocking(s->Conn, wasNonBlocking || s->NonBlocking); s->Connected = 1; LwipSocketUnlock(s); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (err != ERR_INPROGRESS) { netconn_set_nonblocking(s->Conn, wasNonBlocking || s->NonBlocking); @@ -1132,7 +1132,7 @@ static KSTATUS LwipProviderConnect(void* socket, const SYS_SOCKET_ADDRESS_K* add s->ShutdownWrite = 1; netconn_set_nonblocking(s->Conn, wasNonBlocking || s->NonBlocking); LwipSocketUnlock(s); - return STATUS_CANCELLED; + return NTLSTATUS_CANCELLED; } if (s->Conn->state != NETCONN_CONNECT) { @@ -1141,7 +1141,7 @@ static KSTATUS LwipProviderConnect(void* socket, const SYS_SOCKET_ADDRESS_K* add if (err == ERR_OK) { s->Connected = 1; LwipSocketUnlock(s); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } LwipSocketUnlock(s); return LwipErrToStatus(err); @@ -1161,15 +1161,15 @@ static KSTATUS LwipProviderSend(void* socket, const void* buffer, size_t length, if (sentOut) *sentOut = 0; if (!s || (!buffer && length)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (flags != 0) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (length > LWIP_PROVIDER_SOCKET_IO_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (length == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (s->Type != SYS_SOCK_STREAM || !s->Conn) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS st = LwipSocketLock(s); if (!KSUCCESS(st)) @@ -1177,11 +1177,11 @@ static KSTATUS LwipProviderSend(void* socket, const void* buffer, size_t length, if (s->Listening) { LwipSocketUnlock(s); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (s->ShutdownWrite) { LwipSocketUnlock(s); - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; } size_t written = 0; @@ -1236,7 +1236,7 @@ static KSTATUS LwipReceiveFromBuffered(LWIP_PROVIDER_SOCKET* s, uint8_t* out, if (copiedOut) *copiedOut = copied; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the provider Receive operation. @@ -1245,15 +1245,15 @@ static KSTATUS LwipProviderReceive(void* socket, void* buffer, size_t length, ui if (receivedOut) *receivedOut = 0; if (!s || (!buffer && length)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (flags != 0) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (length > LWIP_PROVIDER_SOCKET_IO_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (length == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (s->Type != SYS_SOCK_STREAM || !s->Conn) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS st = LwipSocketLock(s); if (!KSUCCESS(st)) @@ -1261,11 +1261,11 @@ static KSTATUS LwipProviderReceive(void* socket, void* buffer, size_t length, ui if (s->Listening) { LwipSocketUnlock(s); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (s->ShutdownRead) { LwipSocketUnlock(s); - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; } size_t copied = 0; @@ -1288,7 +1288,7 @@ static KSTATUS LwipProviderReceive(void* socket, void* buffer, size_t length, ui if (receivedOut) *receivedOut = 0; LwipSocketUnlock(s); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (err != ERR_OK) { LwipSocketUnlock(s); @@ -1308,7 +1308,7 @@ static KSTATUS LwipProviderReceive(void* socket, void* buffer, size_t length, ui *receivedOut = copied; LwipSocketUnlock(s); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS LwipProviderSendTo(void* socket, const void* buffer, size_t length, uint32_t flags, @@ -1317,21 +1317,21 @@ static KSTATUS LwipProviderSendTo(void* socket, const void* buffer, size_t lengt if (sentOut) *sentOut = 0; if (!s || (!buffer && length) || !remote) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!LwipSocketAddressValid(remote, remoteSize)) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; if (flags != 0) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (s->Type == SYS_SOCK_DGRAM && length > LWIP_PROVIDER_SOCKET_UDP_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (s->Type == SYS_SOCK_RAW && length > LWIP_PROVIDER_SOCKET_RAW_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!LwipSocketFamilyMatches(s, remote)) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (length == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if ((s->Type != SYS_SOCK_DGRAM && s->Type != SYS_SOCK_RAW) || !s->Conn) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS st = LwipSocketLock(s); if (!KSUCCESS(st)) @@ -1339,13 +1339,13 @@ static KSTATUS LwipProviderSendTo(void* socket, const void* buffer, size_t lengt if (s->ShutdownWrite) { LwipSocketUnlock(s); - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; } struct netbuf* nb = netbuf_new(); if (!nb) { LwipSocketUnlock(s); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } err_t err = netbuf_ref(nb, buffer, (u16_t)length); @@ -1372,17 +1372,17 @@ static KSTATUS LwipProviderReceiveFrom(void* socket, void* buffer, size_t length if (receivedOut) *receivedOut = 0; if (!s || (!buffer && length)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (flags != 0) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (s->Type == SYS_SOCK_DGRAM && length > LWIP_PROVIDER_SOCKET_UDP_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (s->Type == SYS_SOCK_RAW && length > LWIP_PROVIDER_SOCKET_RAW_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (length == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if ((s->Type != SYS_SOCK_DGRAM && s->Type != SYS_SOCK_RAW) || !s->Conn) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS st = LwipSocketLock(s); if (!KSUCCESS(st)) @@ -1390,7 +1390,7 @@ static KSTATUS LwipProviderReceiveFrom(void* socket, void* buffer, size_t length if (s->ShutdownRead) { LwipSocketUnlock(s); - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; } struct netbuf* nb = NULL; @@ -1406,7 +1406,7 @@ static KSTATUS LwipProviderReceiveFrom(void* socket, void* buffer, size_t length } if (!nb) { LwipSocketUnlock(s); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } size_t copied = 0; @@ -1448,11 +1448,11 @@ static KSTATUS LwipProviderReceiveFrom(void* socket, void* buffer, size_t length static KSTATUS LwipProviderSetOption(void* socket, uint32_t option, const void* value, size_t valueSize) { LWIP_PROVIDER_SOCKET* s = (LWIP_PROVIDER_SOCKET*)socket; if (!s || !value) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (valueSize != sizeof(uint32_t)) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; if (!s->Conn) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t v = 0; memcpy(&v, value, sizeof(v)); @@ -1476,11 +1476,11 @@ static KSTATUS LwipProviderSetOption(void* socket, uint32_t option, const void* break; default: LwipSocketUnlock(s); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } LwipSocketUnlock(s); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the provider Get Option operation. @@ -1489,11 +1489,11 @@ static KSTATUS LwipProviderGetOption(void* socket, uint32_t option, void* value, if (actualSizeOut) *actualSizeOut = sizeof(uint32_t); if (!s || !value) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (valueSize < sizeof(uint32_t)) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; if (!s->Conn) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS st = LwipSocketLock(s); if (!KSUCCESS(st)) @@ -1512,19 +1512,19 @@ static KSTATUS LwipProviderGetOption(void* socket, uint32_t option, void* value, break; default: LwipSocketUnlock(s); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } memcpy(value, &v, sizeof(v)); LwipSocketUnlock(s); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the provider Poll operation. static KSTATUS LwipProviderPoll(void* socket, uint32_t events, uint32_t* returnedEventsOut) { LWIP_PROVIDER_SOCKET* s = (LWIP_PROVIDER_SOCKET*)socket; if (!s || !returnedEventsOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t revents = 0; KSTATUS st = LwipSocketLock(s); @@ -1534,7 +1534,7 @@ static KSTATUS LwipProviderPoll(void* socket, uint32_t events, uint32_t* returne if (!s->Conn) { *returnedEventsOut = SYS_POLL_INVALID; LwipSocketUnlock(s); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } err_t lastErr = netconn_err(s->Conn); @@ -1556,18 +1556,18 @@ static KSTATUS LwipProviderPoll(void* socket, uint32_t events, uint32_t* returne *returnedEventsOut = revents; LwipSocketUnlock(s); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the provider Shutdown operation. static KSTATUS LwipProviderShutdown(void* socket, uint32_t how) { LWIP_PROVIDER_SOCKET* s = (LWIP_PROVIDER_SOCKET*)socket; if (!s) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (how != SYS_SHUTDOWN_READ && how != SYS_SHUTDOWN_WRITE && how != SYS_SHUTDOWN_BOTH) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!s->Conn) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS st = LwipSocketLock(s); if (!KSUCCESS(st)) @@ -1588,9 +1588,9 @@ static KSTATUS LwipProviderShutdown(void* socket, uint32_t how) { // Implements the provider Resolve Host operation. static KSTATUS LwipProviderResolveHost(const char* name, uint32_t family, SYS_SOCKET_ADDRESS_K* addressOut) { if (!name || !addressOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!gLwipInitialized) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; u8_t dnsType; if (family == SYS_AF_INET) @@ -1598,7 +1598,7 @@ static KSTATUS LwipProviderResolveHost(const char* name, uint32_t family, SYS_SO else if (family == SYS_AF_INET6) dnsType = NETCONN_DNS_IPV6; else - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; ip_addr_t resolved; err_t err = netconn_gethostbyname_addrtype(name, &resolved, dnsType); @@ -1606,17 +1606,17 @@ static KSTATUS LwipProviderResolveHost(const char* name, uint32_t family, SYS_SO return LwipErrToStatus(err); if ((family == SYS_AF_INET && !IP_IS_V4(&resolved)) || (family == SYS_AF_INET6 && !IP_IS_V6(&resolved))) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; LwipSocketFillAddress(addressOut, &resolved, 0); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Dispatches a provider-private socket request carried by an IRP. static KSTATUS LwipDispatchSocketRequest(NET_SOCKET_IRP_REQUEST* request) { if (!request || request->Size != sizeof(*request)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; switch (request->Operation) { case NetSocketIrpCreate: @@ -1626,7 +1626,7 @@ static KSTATUS LwipDispatchSocketRequest(NET_SOCKET_IRP_REQUEST* request) { request->u.Create.ProviderSocketOut); case NetSocketIrpClose: LwipProviderSocketClose(request->u.Close.Socket); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case NetSocketIrpBind: return LwipProviderBind(request->u.Bind.Socket, request->u.Bind.Address, @@ -1696,7 +1696,7 @@ static KSTATUS LwipDispatchSocketRequest(NET_SOCKET_IRP_REQUEST* request) { request->u.ResolveHost.Family, request->u.ResolveHost.AddressOut); default: - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } } @@ -1705,11 +1705,11 @@ static KSTATUS LwipDispatchInternalDeviceControl(DEVICE_OBJECT* device, IRP* irp (void)device; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (ios->Parameters.DeviceIoControl.IoControlCode != NET_IOCTL_SOCKET) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (ios->Parameters.DeviceIoControl.InputLength < sizeof(NET_SOCKET_IRP_REQUEST)) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; NET_SOCKET_IRP_REQUEST* request = (NET_SOCKET_IRP_REQUEST*)ios->Parameters.DeviceIoControl.InputBuffer; return LwipDispatchSocketRequest(request); @@ -1757,5 +1757,5 @@ KSTATUS DriverEntry(const HAL_API* hal) { } DbgPrint("lwIP: driver initialized\n"); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } diff --git a/code/drivers/net/rtl8139/rtl8139.c b/code/drivers/net/rtl8139/rtl8139.c index 15e8a7c..e846e3e 100644 --- a/code/drivers/net/rtl8139/rtl8139.c +++ b/code/drivers/net/rtl8139/rtl8139.c @@ -68,11 +68,11 @@ static KSTATUS Rtl8139Reset(RTL8139_DEVICE* r) { Rtl8139Write8(r, RTL8139_REG_CMD, RTL8139_CMD_RST); for (uint32_t i = 0; i < 1000; i++) { if ((Rtl8139Read8(r, RTL8139_REG_CMD) & RTL8139_CMD_RST) == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (gHal->Timer.Stall) gHal->Timer.Stall(1000); } - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } // Returns mac. @@ -87,14 +87,14 @@ static KSTATUS Rtl8139AllocateDma(RTL8139_DEVICE* r) { r->RxPhys = MmPfnAllocateContiguous(RTL8139_RX_PAGES, MmPfnUseDma); r->TxPhys = MmPfnAllocateContiguous(RTL8139_TX_PAGES, MmPfnUseDma); if (!r->RxPhys || !r->TxPhys) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; // RTL8139 has 32-bit DMA address registers. This is fine for typical QEMU // and low-memory hobby OS configs, but make failure explicit. if ((r->RxPhys + RTL8139_RX_ALLOC_SIZE - 1) > 0xFFFFFFFFULL || (r->TxPhys + RTL8139_TX_SLOTS * RTL8139_TX_BUF_SIZE - 1) > 0xFFFFFFFFULL) { DbgPrint("RTL8139: DMA allocation above 4GiB is not supported by this NIC\n"); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } r->RxBuffer = (uint8_t*)gHal->PhysToVirt(r->RxPhys); @@ -105,7 +105,7 @@ static KSTATUS Rtl8139AllocateDma(RTL8139_DEVICE* r) { DbgPrint("RTL8139: rx=0x%016llX tx=0x%016llX\n", (unsigned long long)r->RxPhys, (unsigned long long)r->TxPhys); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the rx Read16 operation. @@ -226,24 +226,24 @@ static void Rtl8139DpcRoutine(KDPC* dpc, void* context, void* systemArgument1, v // Registers device. static KSTATUS Rtl8139RegisterDevice(RTL8139_DEVICE* r) { - if (!r) return STATUS_INVALID_PARAMETER; + if (!r) return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&gRtl8139RegistryLock); for (uint32_t i = 0; i < gRtl8139DeviceCount; i++) { if (gRtl8139Devices[i] == r) { KeReleaseSpinlock(&gRtl8139RegistryLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } if (gRtl8139DeviceCount >= RTL8139_MAX_DEVICES) { KeReleaseSpinlock(&gRtl8139RegistryLock, flags); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } gRtl8139Devices[gRtl8139DeviceCount++] = r; KeReleaseSpinlock(&gRtl8139RegistryLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the unregister Device operation. @@ -294,15 +294,15 @@ static void Rtl8139Isr(void) { // Implements the send Frame operation. static KSTATUS Rtl8139SendFrame(NET_DEVICE* device, const void* frame, size_t length) { if (!device || !frame) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (length > NET_ETHERNET_MAX_FRAME) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; if (length < NET_ETHERNET_HEADER_LENGTH) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; RTL8139_DEVICE* r = (RTL8139_DEVICE*)device->DriverContext; if (!r) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&r->TxLock); uint32_t slot = r->TxSlot; @@ -311,7 +311,7 @@ static KSTATUS Rtl8139SendFrame(NET_DEVICE* device, const void* frame, size_t le // Writing a command with OWN cleared hands the slot to the NIC. if (!(tsd & RTL8139_TSD_OWN)) { KeReleaseSpinlock(&r->TxLock, flags); - return STATUS_QUEUE_FULL; + return NTLSTATUS_QUEUE_FULL; } size_t wireLength = length < NET_ETHERNET_MIN_FRAME ? NET_ETHERNET_MIN_FRAME : length; @@ -325,13 +325,13 @@ static KSTATUS Rtl8139SendFrame(NET_DEVICE* device, const void* frame, size_t le r->TxSlot = (slot + 1u) % RTL8139_TX_SLOTS; KeReleaseSpinlock(&r->TxLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the select Register Bar operation. static KSTATUS Rtl8139SelectRegisterBar(RTL8139_DEVICE* r) { if (!r || !r->Pdo) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; PCI_BAR best; PCI_BAR fallback; @@ -373,12 +373,12 @@ static KSTATUS Rtl8139SelectRegisterBar(RTL8139_DEVICE* r) { (unsigned long long)best.Base, (unsigned long long)r->RegisterBytes, r->Mmio); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (best.Type == PciBarIo) { if (best.Base > 0xFFFFu) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; r->RegisterBar = best; r->RegisterBytes = best.Length; @@ -388,18 +388,18 @@ static KSTATUS Rtl8139SelectRegisterBar(RTL8139_DEVICE* r) { best.Index, r->IoBase, (unsigned long long)r->RegisterBytes); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } // Starts device. static KSTATUS Rtl8139StartDevice(RTL8139_DEVICE* r) { if (!r || r->Magic != RTL8139_DEVICE_MAGIC || !r->Pdo || !r->Fdo) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (r->Started) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; KSTATUS st = PciGetDeviceInfo(r->Pdo, &r->PciInfo); if (!KSUCCESS(st)) { @@ -432,7 +432,7 @@ static KSTATUS Rtl8139StartDevice(RTL8139_DEVICE* r) { st = PciGetInterrupt(r->Pdo, &r->Irq); if (!KSUCCESS(st) || r->Irq == 0xFFu) { DbgPrint("RTL8139: no legacy PCI IRQ line wired\n"); - return KSUCCESS(st) ? STATUS_NOT_SUPPORTED : st; + return KSUCCESS(st) ? NTLSTATUS_NOT_SUPPORTED : st; } Rtl8139Write8(r, RTL8139_REG_CONFIG1, 0x00); @@ -477,21 +477,21 @@ static KSTATUS Rtl8139StartDevice(RTL8139_DEVICE* r) { } DbgPrint("RTL8139: initialized; RX/TX enabled on IRQ %u\n", r->Irq); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Dispatches pnp. KSTATUS Rtl8139DispatchPnp(DEVICE_OBJECT* device, IRP* irp) { if (!device || !irp || !device->DeviceExtension) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; RTL8139_DEVICE* r = (RTL8139_DEVICE*)device->DeviceExtension; if (r->Magic != RTL8139_DEVICE_MAGIC) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios || ios->MajorFunction != IRP_MJ_PNP) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) { case IRP_MN_START_DEVICE: @@ -499,14 +499,14 @@ KSTATUS Rtl8139DispatchPnp(DEVICE_OBJECT* device, IRP* irp) { case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE: - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_SURPRISE_REMOVAL: r->SurpriseRemoved = true; device->PnpState = DevicePnpSurpriseRemoved; if (r->Started) Rtl8139Write16(r, RTL8139_REG_IMR, 0); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_REMOVE_DEVICE: r->Removed = true; @@ -516,7 +516,7 @@ KSTATUS Rtl8139DispatchPnp(DEVICE_OBJECT* device, IRP* irp) { Rtl8139UnregisterDevice(r); IoDetachDevice(device); IoDeleteDevice(device); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; default: return IoForwardIrpToLower(device, irp); @@ -526,7 +526,7 @@ KSTATUS Rtl8139DispatchPnp(DEVICE_OBJECT* device, IRP* irp) { // Implements the add Device operation. KSTATUS Rtl8139AddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) { if (!driver || !physicalDeviceObject || physicalDeviceObject->Type != DeviceObjectPhysical) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* fdo = (DEVICE_OBJECT*)0; KSTATUS st = IoCreateDevice(driver, sizeof(RTL8139_DEVICE), &fdo); @@ -545,17 +545,17 @@ KSTATUS Rtl8139AddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObj r->LowerDevice = IoAttachDeviceToDeviceStack(fdo, physicalDeviceObject); if (!r->LowerDevice) { IoDeleteDevice(fdo); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } DbgPrint("RTL8139: FDO attached to %v\n", physicalDeviceObject->Name); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the driver Entry operation. KSTATUS DriverEntry(const HAL_API* hal) { if (!hal) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DbgPrint("RTL8139: driver loading...\n"); gHal = hal; diff --git a/code/drivers/net/rtl816x/rtl816x.c b/code/drivers/net/rtl816x/rtl816x.c index cd8d27b..427efab 100644 --- a/code/drivers/net/rtl816x/rtl816x.c +++ b/code/drivers/net/rtl816x/rtl816x.c @@ -69,11 +69,11 @@ static KSTATUS RtlReset(RTL816X_DEVICE* r) { RtlWrite8(r, RTL_REG_CHIP_CMD, RTL_CMD_RESET); for (uint32_t i = 0; i < 1000; i++) { if ((RtlRead8(r, RTL_REG_CHIP_CMD) & RTL_CMD_RESET) == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (gHal->Timer.Stall) gHal->Timer.Stall(1000); } - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } // Implements the rtl Read Mac operation. @@ -91,7 +91,7 @@ static KSTATUS RtlAllocateDma(RTL816X_DEVICE* r) { r->TxBuffersPhys = MmPfnAllocateContiguous(RTL_TXBUF_PAGES, MmPfnUseDma); if (!r->RxRingPhys || !r->TxRingPhys || !r->RxBuffersPhys || !r->TxBuffersPhys) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; r->RxRing = (RTL_DESC*)gHal->PhysToVirt(r->RxRingPhys); r->TxRing = (RTL_DESC*)gHal->PhysToVirt(r->TxRingPhys); @@ -108,7 +108,7 @@ static KSTATUS RtlAllocateDma(RTL816X_DEVICE* r) { (unsigned long long)r->TxRingPhys, (unsigned long long)r->RxBuffersPhys, (unsigned long long)r->TxBuffersPhys); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the rtl Init Descriptors operation. @@ -229,24 +229,24 @@ static void RtlDpcRoutine(KDPC* dpc, void* context, void* systemArgument1, void* // Implements the rtl Register Device operation. static KSTATUS RtlRegisterDevice(RTL816X_DEVICE* r) { - if (!r) return STATUS_INVALID_PARAMETER; + if (!r) return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&gRtl816xRegistryLock); for (uint32_t i = 0; i < gRtl816xDeviceCount; i++) { if (gRtl816xDevices[i] == r) { KeReleaseSpinlock(&gRtl816xRegistryLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } if (gRtl816xDeviceCount >= RTL816X_MAX_DEVICES) { KeReleaseSpinlock(&gRtl816xRegistryLock, flags); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } gRtl816xDevices[gRtl816xDeviceCount++] = r; KeReleaseSpinlock(&gRtl816xRegistryLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the rtl Unregister Device operation. @@ -297,15 +297,15 @@ static void RtlIsr(void) { // Implements the rtl Send Frame operation. static KSTATUS RtlSendFrame(NET_DEVICE* device, const void* frame, size_t length) { if (!device || !frame) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (length > NET_ETHERNET_MAX_FRAME) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; if (length < NET_ETHERNET_HEADER_LENGTH) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; RTL816X_DEVICE* r = (RTL816X_DEVICE*)device->DriverContext; if (!r || !r->Started || r->Removed || r->SurpriseRemoved) - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; uintptr_t flags = KeAcquireSpinlock(&r->TxLock); uint32_t index = r->TxIndex; @@ -313,7 +313,7 @@ static KSTATUS RtlSendFrame(NET_DEVICE* device, const void* frame, size_t length uint32_t opts = d->opts1; if (opts & RTL_DESC_OWN) { KeReleaseSpinlock(&r->TxLock, flags); - return STATUS_QUEUE_FULL; + return NTLSTATUS_QUEUE_FULL; } size_t wireLength = length < NET_ETHERNET_MIN_FRAME ? NET_ETHERNET_MIN_FRAME : length; @@ -331,13 +331,13 @@ static KSTATUS RtlSendFrame(NET_DEVICE* device, const void* frame, size_t length r->TxIndex = (index + 1) % RTL_TX_COUNT; KeReleaseSpinlock(&r->TxLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the rtl Select Register Bar operation. static KSTATUS RtlSelectRegisterBar(RTL816X_DEVICE* r) { if (!r || !r->Pdo) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; PCI_BAR best; PCI_BAR fallback; @@ -379,12 +379,12 @@ static KSTATUS RtlSelectRegisterBar(RTL816X_DEVICE* r) { (unsigned long long)best.Base, (unsigned long long)r->RegisterBytes, r->Mmio); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (best.Type == PciBarIo) { if (best.Base > 0xFFFFu) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; r->RegisterBar = best; r->RegisterBytes = best.Length; @@ -394,18 +394,18 @@ static KSTATUS RtlSelectRegisterBar(RTL816X_DEVICE* r) { best.Index, r->IoBase, (unsigned long long)r->RegisterBytes); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } // Implements the rtl Start Device operation. static KSTATUS RtlStartDevice(RTL816X_DEVICE* r) { if (!r || r->Magic != RTL816X_DEVICE_MAGIC || !r->Pdo || !r->Fdo) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (r->Started) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; KSTATUS st = PciGetDeviceInfo(r->Pdo, &r->PciInfo); if (!KSUCCESS(st)) { @@ -438,7 +438,7 @@ static KSTATUS RtlStartDevice(RTL816X_DEVICE* r) { st = PciGetInterrupt(r->Pdo, &r->Irq); if (!KSUCCESS(st) || r->Irq == 0xFFu) { DbgPrint("RTL816X: no legacy PCI IRQ line wired\n"); - return KSUCCESS(st) ? STATUS_NOT_SUPPORTED : st; + return KSUCCESS(st) ? NTLSTATUS_NOT_SUPPORTED : st; } st = RtlReset(r); @@ -483,21 +483,21 @@ static KSTATUS RtlStartDevice(RTL816X_DEVICE* r) { } DbgPrint("RTL816X: initialized; RX/TX enabled on IRQ %u\n", r->Irq); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Dispatches pnp. KSTATUS Rtl816xDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { if (!device || !irp || !device->DeviceExtension) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; RTL816X_DEVICE* r = (RTL816X_DEVICE*)device->DeviceExtension; if (r->Magic != RTL816X_DEVICE_MAGIC) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios || ios->MajorFunction != IRP_MJ_PNP) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) { case IRP_MN_START_DEVICE: @@ -505,14 +505,14 @@ KSTATUS Rtl816xDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE: - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_SURPRISE_REMOVAL: r->SurpriseRemoved = true; device->PnpState = DevicePnpSurpriseRemoved; if (r->Started) RtlWrite16(r, RTL_REG_INTR_MASK, 0); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_REMOVE_DEVICE: r->Removed = true; @@ -522,7 +522,7 @@ KSTATUS Rtl816xDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { RtlUnregisterDevice(r); IoDetachDevice(device); IoDeleteDevice(device); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; default: return IoForwardIrpToLower(device, irp); @@ -532,7 +532,7 @@ KSTATUS Rtl816xDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { // Implements the add Device operation. KSTATUS Rtl816xAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) { if (!driver || !physicalDeviceObject || physicalDeviceObject->Type != DeviceObjectPhysical) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* fdo = (DEVICE_OBJECT*)0; KSTATUS st = IoCreateDevice(driver, sizeof(RTL816X_DEVICE), &fdo); @@ -551,17 +551,17 @@ KSTATUS Rtl816xAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObj r->LowerDevice = IoAttachDeviceToDeviceStack(fdo, physicalDeviceObject); if (!r->LowerDevice) { IoDeleteDevice(fdo); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } DbgPrint("RTL816X: FDO attached to %v\n", physicalDeviceObject->Name); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the driver Entry operation. KSTATUS DriverEntry(const HAL_API* hal) { if (!hal) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DbgPrint("RTL816X: driver loading...\n"); gHal = hal; diff --git a/code/drivers/storage/ahci/ahci.c b/code/drivers/storage/ahci/ahci.c index 311df21..e1c6380 100644 --- a/code/drivers/storage/ahci/ahci.c +++ b/code/drivers/storage/ahci/ahci.c @@ -57,7 +57,7 @@ static KSTATUS port_init_memory(AHCI_DRIVE *drv) { uint64_t flags = PAGE_PRESENT | PAGE_WRITE | PAGE_NOCACHE; drv->structPhys = MmPfnAllocateContiguous(PORT_PAGES_STRUCT, MmPfnUseDma); - if (!drv->structPhys) return STATUS_NO_MEMORY; + if (!drv->structPhys) return NTLSTATUS_NO_MEMORY; drv->structVirt = g_hal->PhysToVirt(drv->structPhys); // Force NOCACHE on DMA descriptor memory. MmPteProtectRange((uintptr_t)drv->structVirt, @@ -65,7 +65,7 @@ static KSTATUS port_init_memory(AHCI_DRIVE *drv) { memset(drv->structVirt, 0, PORT_PAGES_STRUCT * 4096); drv->bouncePhys = MmPfnAllocateContiguous(BOUNCE_PAGES, MmPfnUseDma); - if (!drv->bouncePhys) return STATUS_NO_MEMORY; + if (!drv->bouncePhys) return NTLSTATUS_NO_MEMORY; drv->bounceVirt = g_hal->PhysToVirt(drv->bouncePhys); // Bounce buffer: NOCACHE to ensure CPU writes reach physical memory // before the HBA's DMA engine reads them. @@ -100,12 +100,12 @@ static KSTATUS port_init_memory(AHCI_DRIVE *drv) { port_start(port); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Issue a command - polling fallback (used during early init / IDENTIFY only, // before the scheduler and interrupt handler are live). -// Returns STATUS_SUCCESS, STATUS_DEVICE_ERROR, or STATUS_TIMEOUT. +// Returns NTLSTATUS_SUCCESS, NTLSTATUS_DEVICE_ERROR, or NTLSTATUS_TIMEOUT. static KSTATUS port_issue_cmd_poll(AHCI_DRIVE *drv) { HBA_PORT *port = drv->port; @@ -119,7 +119,7 @@ static KSTATUS port_issue_cmd_poll(AHCI_DRIVE *drv) { spin++; if (spin == POLL_TIMEOUT) { DbgPrint("AHCI: port hung (pre-issue)\n"); - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } // Issue slot 0. @@ -133,17 +133,17 @@ static KSTATUS port_issue_cmd_poll(AHCI_DRIVE *drv) { port->is, port->tfd, port->serr); port->serr = (uint32_t)-1; port->is = (uint32_t)-1; - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } } if (port->is & PORT_IS_TFES) { DbgPrint("AHCI: TFES after completion TFD=0x%x\n", port->tfd); port->is = (uint32_t)-1; - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Interrupt bottom half. The ISR owns hardware acknowledgement and status @@ -217,7 +217,7 @@ static KSTATUS port_issue_cmd(AHCI_DRIVE *drv) { spin++; if (spin == POLL_TIMEOUT) { DbgPrint("AHCI: port hung (pre-issue)\n"); - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } // Issue slot 0, then block on the event. @@ -230,10 +230,10 @@ static KSTATUS port_issue_cmd(AHCI_DRIVE *drv) { DbgPrint("AHCI: error IS=0x%x TFD=0x%x SERR=0x%x\n", is, port->tfd, port->serr); port->serr = (uint32_t)-1; - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Build a standard DMA read or write command in slot 0. @@ -336,7 +336,7 @@ static KSTATUS port_identify(AHCI_DRIVE *drv) { | ((uint64_t)id[ATA_IDENT_W60 + 1] << 16); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Core read logic. @@ -356,7 +356,7 @@ static KSTATUS do_read(AHCI_DRIVE *drv, uint64_t lba, lba += batch; count -= batch; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Core write logic. @@ -376,7 +376,7 @@ static KSTATUS do_write(AHCI_DRIVE *drv, uint64_t lba, lba += batch; count -= batch; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Async IRP dispatch. @@ -384,22 +384,22 @@ static KSTATUS do_write(AHCI_DRIVE *drv, uint64_t lba, static KSTATUS AhciGetIrpReadWrite(IRP* irp, bool* outWrite, uint64_t* outLba, uint32_t* outSectors, void** outBuffer) { if (!irp || !outWrite || !outLba || !outSectors || !outBuffer) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); - if (!ios) return STATUS_INVALID_PARAMETER; + if (!ios) return NTLSTATUS_INVALID_PARAMETER; if (ios->MajorFunction != IRP_MJ_READ && ios->MajorFunction != IRP_MJ_WRITE) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if ((ios->Parameters.ReadWrite.ByteOffset & 511ull) || (ios->Parameters.ReadWrite.Length & 511u)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!irp->UserBuffer || ios->Parameters.ReadWrite.Length == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *outWrite = (ios->MajorFunction == IRP_MJ_WRITE); *outLba = ios->Parameters.ReadWrite.ByteOffset >> 9; *outSectors = ios->Parameters.ReadWrite.Length >> 9; *outBuffer = irp->UserBuffer; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // AhciDispatchReadWrite - DEVICE_OBJECT dispatch entry for disk IRPs. @@ -407,9 +407,9 @@ static KSTATUS AhciGetIrpReadWrite(IRP* irp, bool* outWrite, uint64_t* outLba, // IoCompleteRequest(). Rejected IRPs are returned synchronously and are not // completed. static KSTATUS AhciDispatchReadWrite(DEVICE_OBJECT *device, IRP *irp) { - if (!device || !irp) return STATUS_INVALID_PARAMETER; + if (!device || !irp) return NTLSTATUS_INVALID_PARAMETER; AHCI_DRIVE *drv = (AHCI_DRIVE *)device->DeviceExtension; - if (!drv) return STATUS_INVALID_PARAMETER; + if (!drv) return NTLSTATUS_INVALID_PARAMETER; KSTATUS st = IoAcquireRemoveLock(&drv->removeLock, irp); if (!KSUCCESS(st)) @@ -424,13 +424,13 @@ static KSTATUS AhciDispatchReadWrite(DEVICE_OBJECT *device, IRP *irp) { (void)buffer; if (!KSUCCESS(st) || lba + sectors > drv->sectorCount) { IoReleaseRemoveLock(&drv->removeLock, irp); - return KSUCCESS(st) ? STATUS_INVALID_PARAMETER : st; + return KSUCCESS(st) ? NTLSTATUS_INVALID_PARAMETER : st; } - irp->Status = STATUS_FAILURE; + irp->Status = NTLSTATUS_FAILURE; irp->Information = 0; IrpQueueEnqueue(&drv->irpQueue, irp); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } // Cancels release Remove Lock. @@ -442,68 +442,68 @@ static void AhciCancelReleaseRemoveLock(IRP* irp, void* context) { // Dispatches drive Pnp. static KSTATUS AhciDispatchDrivePnp(DEVICE_OBJECT* device, IRP* irp) { - if (!device || !irp) return STATUS_INVALID_PARAMETER; + if (!device || !irp) return NTLSTATUS_INVALID_PARAMETER; AHCI_DRIVE* drv = (AHCI_DRIVE*)device->DeviceExtension; - if (!drv) return STATUS_INVALID_PARAMETER; + if (!drv) return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios || ios->MajorFunction != IRP_MJ_PNP) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) { case IRP_MN_START_DEVICE: device->PnpState = DevicePnpStarted; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_QUERY_REMOVE_DEVICE: device->PnpState = DevicePnpRemovePending; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_CANCEL_REMOVE_DEVICE: device->PnpState = DevicePnpStarted; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_SURPRISE_REMOVAL: drv->surpriseRemoved = true; device->PnpState = DevicePnpSurpriseRemoved; - IrpQueueCancelAllEx(&drv->irpQueue, STATUS_OBJECT_DEAD, AhciCancelReleaseRemoveLock, drv); - return STATUS_SUCCESS; + IrpQueueCancelAllEx(&drv->irpQueue, NTLSTATUS_OBJECT_DEAD, AhciCancelReleaseRemoveLock, drv); + return NTLSTATUS_SUCCESS; case IRP_MN_REMOVE_DEVICE: drv->removed = true; device->PnpState = DevicePnpDeleted; - IrpQueueCancelAllEx(&drv->irpQueue, STATUS_OBJECT_DEAD, AhciCancelReleaseRemoveLock, drv); + IrpQueueCancelAllEx(&drv->irpQueue, NTLSTATUS_OBJECT_DEAD, AhciCancelReleaseRemoveLock, drv); IoReleaseRemoveLockAndWait(&drv->removeLock, irp); IoDeleteDevice(device); drv->deviceObject = (DEVICE_OBJECT*)0; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; default: - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } } // Dispatches controller Pnp. static KSTATUS AhciDispatchControllerPnp(DEVICE_OBJECT* device, IRP* irp) { - if (!device || !irp) return STATUS_INVALID_PARAMETER; + if (!device || !irp) return NTLSTATUS_INVALID_PARAMETER; AHCI_CONTROLLER* ctl = (AHCI_CONTROLLER*)device->DeviceExtension; if (!ctl || ctl->magic != AHCI_CONTROLLER_MAGIC) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios || ios->MajorFunction != IRP_MJ_PNP) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) { case IRP_MN_START_DEVICE: if (ctl->started) { device->PnpState = DevicePnpStarted; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } return AhciStartController(ctl); case IRP_MN_QUERY_REMOVE_DEVICE: device->PnpState = DevicePnpRemovePending; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_CANCEL_REMOVE_DEVICE: device->PnpState = DevicePnpStarted; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_SURPRISE_REMOVAL: ctl->surpriseRemoved = true; @@ -511,9 +511,9 @@ static KSTATUS AhciDispatchControllerPnp(DEVICE_OBJECT* device, IRP* irp) { for (int i = 0; i < ctl->driveCount; i++) { AHCI_DRIVE* drv = &ctl->drives[i]; drv->surpriseRemoved = true; - IrpQueueCancelAllEx(&drv->irpQueue, STATUS_OBJECT_DEAD, AhciCancelReleaseRemoveLock, drv); + IrpQueueCancelAllEx(&drv->irpQueue, NTLSTATUS_OBJECT_DEAD, AhciCancelReleaseRemoveLock, drv); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_REMOVE_DEVICE: ctl->removed = true; @@ -521,28 +521,28 @@ static KSTATUS AhciDispatchControllerPnp(DEVICE_OBJECT* device, IRP* irp) { for (int i = 0; i < ctl->driveCount; i++) { AHCI_DRIVE* drv = &ctl->drives[i]; drv->removed = true; - IrpQueueCancelAllEx(&drv->irpQueue, STATUS_OBJECT_DEAD, AhciCancelReleaseRemoveLock, drv); + IrpQueueCancelAllEx(&drv->irpQueue, NTLSTATUS_OBJECT_DEAD, AhciCancelReleaseRemoveLock, drv); } IoDetachDevice(device); IoDeleteDevice(device); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; default: - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } } // Dispatches pnp. static KSTATUS AhciDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { if (!device || !device->DeviceExtension) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t magic = *(uint32_t*)device->DeviceExtension; if (magic == AHCI_CONTROLLER_MAGIC) return AhciDispatchControllerPnp(device, irp); if (magic == AHCI_DRIVE_MAGIC) return AhciDispatchDrivePnp(device, irp); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } // AhciWorker - kernel thread, one per drive. @@ -612,24 +612,24 @@ static void AhciWorker(uintptr_t arg) { // Registers controller. static KSTATUS AhciRegisterController(AHCI_CONTROLLER* ctl) { - if (!ctl) return STATUS_INVALID_PARAMETER; + if (!ctl) return NTLSTATUS_INVALID_PARAMETER; for (int i = 0; i < g_controllerCount; i++) { if (g_controllers[i] == ctl) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (g_controllerCount >= MAX_AHCI_CONTROLLERS) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; g_controllers[g_controllerCount++] = ctl; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Starts controller. static KSTATUS AhciStartController(AHCI_CONTROLLER* ctl) { if (!ctl || ctl->magic != AHCI_CONTROLLER_MAGIC || !ctl->pdo || !ctl->fdo) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (ctl->started) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; KSTATUS st = PciGetDeviceInfo(ctl->pdo, &ctl->pciInfo); if (!KSUCCESS(st)) { @@ -671,7 +671,7 @@ static KSTATUS AhciStartController(AHCI_CONTROLLER* ctl) { } if (ctl->abar.Type != PciBarMemory32 && ctl->abar.Type != PciBarMemory64) { DbgPrint("AHCI: BAR5/ABAR is not MMIO (type=%u)\n", ctl->abar.Type); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } st = PciMapBar(ctl->pdo, @@ -855,13 +855,13 @@ static KSTATUS AhciStartController(AHCI_CONTROLLER* ctl) { ctl->started = true; ctl->fdo->PnpState = DevicePnpStarted; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the add Device operation. static KSTATUS AhciAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) { if (!driver || !physicalDeviceObject || physicalDeviceObject->Type != DeviceObjectPhysical) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* fdo = (DEVICE_OBJECT*)0; KSTATUS st = IoCreateDevice(driver, sizeof(AHCI_CONTROLLER), &fdo); @@ -879,11 +879,11 @@ static KSTATUS AhciAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDevic ctl->lowerDevice = IoAttachDeviceToDeviceStack(fdo, physicalDeviceObject); if (!ctl->lowerDevice) { IoDeleteDevice(fdo); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } DbgPrint("AHCI: FDO attached to %v\n", physicalDeviceObject->Name); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the driver Entry operation. diff --git a/code/drivers/storage/ahci/ahci_port.c b/code/drivers/storage/ahci/ahci_port.c index 428b3d3..50db132 100644 --- a/code/drivers/storage/ahci/ahci_port.c +++ b/code/drivers/storage/ahci/ahci_port.c @@ -13,10 +13,10 @@ KSTATUS ahci_map_mmio(uint64_t physBase, uint64_t length) { uintptr_t virt = (uintptr_t)g_hal->PhysToVirt(phys); uint64_t flags = PAGE_PRESENT | PAGE_WRITE | PAGE_NOCACHE; KSTATUS st = MmPteMapPage(virt, phys, flags, MmPteMapFailIfPresent); - // Ignore STATUS_ALREADY_EXISTS - a prior mapping with different flags + // Ignore NTLSTATUS_ALREADY_EXISTS - a prior mapping with different flags // is possible for the first page if the bootloader was overly generous. // Use MmPteProtectRange to force NOCACHE in that case. - if (st == STATUS_ALREADY_EXISTS) { + if (st == NTLSTATUS_ALREADY_EXISTS) { st = MmPteProtectRange(virt, 4096, flags); } if (!KSUCCESS(st)) { @@ -25,7 +25,7 @@ KSTATUS ahci_map_mmio(uint64_t physBase, uint64_t length) { return st; } } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the port stop operation. @@ -79,13 +79,13 @@ KSTATUS hba_reset(HBA_MEM *hba) { } if (hba->ghc & GHC_HR) { DbgPrint("AHCI: HBA reset timed out\n"); - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } // Re-enable AHCI mode (reset cleared it), then enable global interrupts. // GHC.IE lets the HBA assert its PCI interrupt line when a port fires. hba->ghc |= GHC_AE | GHC_IE; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the port link up operation. @@ -129,7 +129,7 @@ KSTATUS port_comreset(AHCI_DRIVE *drv) { } if (!link_ok) { DbgPrint("AHCI: COMRESET: link did not come back (ssts=0x%x)\n", port->ssts); - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } port->serr = (uint32_t)-1; @@ -145,5 +145,5 @@ KSTATUS port_comreset(AHCI_DRIVE *drv) { DbgPrint("AHCI: port COMRESET done: sig=0x%08x ssts=0x%08x\n", port->sig, port->ssts); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } diff --git a/code/drivers/storage/ata/ata.c b/code/drivers/storage/ata/ata.c index be99d06..e898424 100644 --- a/code/drivers/storage/ata/ata.c +++ b/code/drivers/storage/ata/ata.c @@ -58,10 +58,10 @@ static void AtaDelay400ns(ATA_CHANNEL* ch) { static KSTATUS AtaWaitNotBusy(ATA_CHANNEL* ch) { for (uint32_t i = 0; i < ATA_POLL_LIMIT; i++) { if (!(AtaIn8(ch, ATA_REG_STATUS) & ATA_STATUS_BSY)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; KeYield(); } - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } // Waits for drq. @@ -69,14 +69,14 @@ static KSTATUS AtaWaitDrq(ATA_CHANNEL* ch) { for (uint32_t i = 0; i < ATA_POLL_LIMIT; i++) { uint8_t st = AtaIn8(ch, ATA_REG_STATUS); if (st & ATA_STATUS_ERR) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; if (st & ATA_STATUS_DF) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; if (!(st & ATA_STATUS_BSY) && (st & ATA_STATUS_DRQ)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; KeYield(); } - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } // Implements the select Drive operation. @@ -107,7 +107,7 @@ static KSTATUS AtaIdentify(ATA_DEVICE* dev) { uint8_t status = AtaIn8(ch, ATA_REG_STATUS); if (status == 0) { KeSignalSemaphore(ch->Lock); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } st = AtaWaitNotBusy(ch); @@ -118,7 +118,7 @@ static KSTATUS AtaIdentify(ATA_DEVICE* dev) { if (AtaIn8(ch, ATA_REG_LBA1) != 0 || AtaIn8(ch, ATA_REG_LBA2) != 0) { KeSignalSemaphore(ch->Lock); - return STATUS_NOT_SUPPORTED; // ATAPI or non-ATA signature. + return NTLSTATUS_NOT_SUPPORTED; // ATAPI or non-ATA signature. } st = AtaWaitDrq(ch); @@ -133,7 +133,7 @@ static KSTATUS AtaIdentify(ATA_DEVICE* dev) { KeSignalSemaphore(ch->Lock); if (!(ident[ATA_IDENT_CAPABILITIES] & ATA_IDENT_LBA_SUPPORTED)) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; dev->SupportsLba48 = (ident[ATA_IDENT_COMMAND_SETS] & ATA_IDENT_LBA48_SUPPORTED) != 0; if (dev->SupportsLba48) { @@ -148,7 +148,7 @@ static KSTATUS AtaIdentify(ATA_DEVICE* dev) { ident[ATA_IDENT_LBA28_SECTORS_LO]; } - return dev->SectorCount ? STATUS_SUCCESS : STATUS_NOT_FOUND; + return dev->SectorCount ? NTLSTATUS_SUCCESS : NTLSTATUS_NOT_FOUND; } // Implements the program Lba operation. @@ -166,11 +166,11 @@ static KSTATUS AtaProgramLba(ATA_DEVICE* dev, uint64_t lba, uint16_t count, bool AtaOut8(ch, ATA_REG_LBA1, (uint8_t)(lba >> 8)); AtaOut8(ch, ATA_REG_LBA2, (uint8_t)(lba >> 16)); AtaOut8(ch, ATA_REG_COMMAND, write ? ATA_CMD_WRITE_SECTORS_EXT : ATA_CMD_READ_SECTORS_EXT); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (lba > 0x0FFFFFFFULL || count > 256) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; AtaOut8(ch, ATA_REG_DRIVE_HEAD, (uint8_t)(0xE0u | (dev->Drive ? 0x10u : 0u) | ((lba >> 24) & 0x0Fu))); AtaOut8(ch, ATA_REG_SECTOR_COUNT, (uint8_t)count); @@ -178,17 +178,17 @@ static KSTATUS AtaProgramLba(ATA_DEVICE* dev, uint64_t lba, uint16_t count, bool AtaOut8(ch, ATA_REG_LBA1, (uint8_t)(lba >> 8)); AtaOut8(ch, ATA_REG_LBA2, (uint8_t)(lba >> 16)); AtaOut8(ch, ATA_REG_COMMAND, write ? ATA_CMD_WRITE_SECTORS : ATA_CMD_READ_SECTORS); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns pio. static KSTATUS AtaReadPio(ATA_DEVICE* dev, uint64_t lba, uint32_t count, void* buffer) { if (!dev || !buffer) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (count == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (lba + count > dev->SectorCount) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; ATA_CHANNEL* ch = dev->Channel; uint16_t* out = (uint16_t*)buffer; @@ -237,11 +237,11 @@ static KSTATUS AtaFlush(ATA_DEVICE* dev) { // Updates pio. static KSTATUS AtaWritePio(ATA_DEVICE* dev, uint64_t lba, uint32_t count, const void* buffer) { if (!dev || !buffer) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (count == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (lba + count > dev->SectorCount) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; ATA_CHANNEL* ch = dev->Channel; const uint16_t* in = (const uint16_t*)buffer; @@ -283,22 +283,22 @@ static KSTATUS AtaWritePio(ATA_DEVICE* dev, uint64_t lba, uint32_t count, const static KSTATUS AtaGetIrpReadWrite(IRP* irp, bool* outWrite, uint64_t* outLba, uint32_t* outSectors, void** outBuffer) { if (!irp || !outWrite || !outLba || !outSectors || !outBuffer) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); - if (!ios) return STATUS_INVALID_PARAMETER; + if (!ios) return NTLSTATUS_INVALID_PARAMETER; if (ios->MajorFunction != IRP_MJ_READ && ios->MajorFunction != IRP_MJ_WRITE) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if ((ios->Parameters.ReadWrite.ByteOffset & 511ull) || (ios->Parameters.ReadWrite.Length & 511u)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!irp->UserBuffer || ios->Parameters.ReadWrite.Length == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *outWrite = (ios->MajorFunction == IRP_MJ_WRITE); *outLba = ios->Parameters.ReadWrite.ByteOffset >> 9; *outSectors = ios->Parameters.ReadWrite.Length >> 9; *outBuffer = irp->UserBuffer; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the worker operation. @@ -321,7 +321,7 @@ static void AtaWorker(uintptr_t arg) { KSTATUS st = AtaGetIrpReadWrite(irp, &write, &lba, §ors, &buffer); if (KSUCCESS(st)) { if (lba + sectors > dev->SectorCount) - st = STATUS_INVALID_PARAMETER; + st = NTLSTATUS_INVALID_PARAMETER; else st = write ? AtaWritePio(dev, lba, sectors, buffer) : AtaReadPio(dev, lba, sectors, buffer); @@ -335,11 +335,11 @@ static void AtaWorker(uintptr_t arg) { // Dispatches read Write. KSTATUS AtaDispatchReadWrite(DEVICE_OBJECT* device, IRP* irp) { if (!device || !irp || !device->DeviceExtension) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; ATA_DEVICE* dev = (ATA_DEVICE*)device->DeviceExtension; if (dev->Magic != ATA_DEVICE_MAGIC || !dev->Present) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS st = IoAcquireRemoveLock(&dev->RemoveLock, irp); if (!KSUCCESS(st)) @@ -354,13 +354,13 @@ KSTATUS AtaDispatchReadWrite(DEVICE_OBJECT* device, IRP* irp) { (void)buffer; if (!KSUCCESS(st) || lba + sectors > dev->SectorCount) { IoReleaseRemoveLock(&dev->RemoveLock, irp); - return KSUCCESS(st) ? STATUS_INVALID_PARAMETER : st; + return KSUCCESS(st) ? NTLSTATUS_INVALID_PARAMETER : st; } - irp->Status = STATUS_FAILURE; + irp->Status = NTLSTATUS_FAILURE; irp->Information = 0; IrpQueueEnqueue(&dev->IrpQueue, irp); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } // Returns free Disk Index. @@ -416,7 +416,7 @@ static KSTATUS AtaInitChannel(ATA_CONTROLLER* ctl, uint8_t index) { ch->ControlBase, ch->Irq, ch->NativeMode ? "native" : "compat"); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Registers disk. @@ -435,7 +435,7 @@ static KSTATUS AtaRegisterDisk(ATA_DEVICE* dev) { uint8_t index = AtaFindFreeDiskIndex(); if (index == 0xFFu) { IoDeleteDevice(disk); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } st = IoRegisterDiskDevice(index, disk); @@ -452,7 +452,7 @@ static KSTATUS AtaRegisterDisk(ATA_DEVICE* dev) { dev->Drive ? "slave" : "master", (unsigned long long)dev->SectorCount, (unsigned long long)(dev->SectorCount / 2048)); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Probes drive. @@ -490,28 +490,28 @@ static KSTATUS AtaProbeDrive(ATA_CONTROLLER* ctl, ATA_CHANNEL* ch, uint8_t drive PriorityHigh, &dev->WorkerThread); if (!KSUCCESS(st)) DbgPrint("ATA: drive %u worker thread create failed (0x%x)\n", dev->DiskIndex, st); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Registers controller. static KSTATUS AtaRegisterController(ATA_CONTROLLER* ctl) { - if (!ctl) return STATUS_INVALID_PARAMETER; + if (!ctl) return NTLSTATUS_INVALID_PARAMETER; for (uint32_t i = 0; i < gAtaControllerCount; i++) { if (gAtaControllers[i] == ctl) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (gAtaControllerCount >= ATA_MAX_CONTROLLERS) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; gAtaControllers[gAtaControllerCount++] = ctl; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Starts controller. static KSTATUS AtaStartController(ATA_CONTROLLER* ctl) { if (!ctl || ctl->Magic != ATA_CONTROLLER_MAGIC || !ctl->Pdo || !ctl->Fdo) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (ctl->Started) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; KSTATUS st = PciGetDeviceInfo(ctl->Pdo, &ctl->PciInfo); if (!KSUCCESS(st)) { @@ -560,7 +560,7 @@ static KSTATUS AtaStartController(ATA_CONTROLLER* ctl) { ctl->Started = true; ctl->Fdo->PnpState = DevicePnpStarted; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Cancels release Remove Lock. @@ -580,7 +580,7 @@ static void AtaRemoveControllerDevices(ATA_CONTROLLER* ctl, IO_DEVICE_CHANGE cha if (!dev->Present) continue; - IrpQueueCancelAllEx(&dev->IrpQueue, STATUS_OBJECT_DEAD, AtaCancelReleaseRemoveLock, dev); + IrpQueueCancelAllEx(&dev->IrpQueue, NTLSTATUS_OBJECT_DEAD, AtaCancelReleaseRemoveLock, dev); if (dev->DiskIndex != 0xFFu) { if (change == IoDeviceSurpriseRemoved) IoNotifyDiskSurpriseRemoved(dev->DiskIndex); @@ -596,13 +596,13 @@ static void AtaRemoveControllerDevices(ATA_CONTROLLER* ctl, IO_DEVICE_CHANGE cha // Dispatches pnp. KSTATUS AtaDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { if (!device || !irp || !device->DeviceExtension) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; ATA_CONTROLLER* ctl = (ATA_CONTROLLER*)device->DeviceExtension; if (ctl->Magic == ATA_CONTROLLER_MAGIC) { IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios || ios->MajorFunction != IRP_MJ_PNP) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) { case IRP_MN_START_DEVICE: @@ -610,13 +610,13 @@ KSTATUS AtaDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE: - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_SURPRISE_REMOVAL: ctl->SurpriseRemoved = true; device->PnpState = DevicePnpSurpriseRemoved; AtaRemoveControllerDevices(ctl, IoDeviceSurpriseRemoved); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_REMOVE_DEVICE: ctl->Removed = true; @@ -624,7 +624,7 @@ KSTATUS AtaDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { AtaRemoveControllerDevices(ctl, IoDeviceRemoved); IoDetachDevice(device); IoDeleteDevice(device); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; default: return IoForwardIrpToLower(device, irp); @@ -635,40 +635,40 @@ KSTATUS AtaDispatchPnp(DEVICE_OBJECT* device, IRP* irp) { if (dev->Magic == ATA_DEVICE_MAGIC) { IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios || ios->MajorFunction != IRP_MJ_PNP) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) { case IRP_MN_START_DEVICE: device->PnpState = DevicePnpStarted; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE: - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case IRP_MN_SURPRISE_REMOVAL: device->PnpState = DevicePnpSurpriseRemoved; dev->Present = false; - IrpQueueCancelAllEx(&dev->IrpQueue, STATUS_OBJECT_DEAD, AtaCancelReleaseRemoveLock, dev); - return STATUS_SUCCESS; + IrpQueueCancelAllEx(&dev->IrpQueue, NTLSTATUS_OBJECT_DEAD, AtaCancelReleaseRemoveLock, dev); + return NTLSTATUS_SUCCESS; case IRP_MN_REMOVE_DEVICE: device->PnpState = DevicePnpDeleted; dev->Present = false; - IrpQueueCancelAllEx(&dev->IrpQueue, STATUS_OBJECT_DEAD, AtaCancelReleaseRemoveLock, dev); + IrpQueueCancelAllEx(&dev->IrpQueue, NTLSTATUS_OBJECT_DEAD, AtaCancelReleaseRemoveLock, dev); IoReleaseRemoveLockAndWait(&dev->RemoveLock, irp); IoDeleteDevice(device); dev->DeviceObject = (DEVICE_OBJECT*)0; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; default: - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } } - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } // Implements the add Device operation. KSTATUS AtaAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) { if (!driver || !physicalDeviceObject || physicalDeviceObject->Type != DeviceObjectPhysical) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* fdo = (DEVICE_OBJECT*)0; KSTATUS st = IoCreateDevice(driver, sizeof(ATA_CONTROLLER), &fdo); @@ -685,17 +685,17 @@ KSTATUS AtaAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) ctl->LowerDevice = IoAttachDeviceToDeviceStack(fdo, physicalDeviceObject); if (!ctl->LowerDevice) { IoDeleteDevice(fdo); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } DbgPrint("ATA: FDO attached to %v\n", physicalDeviceObject->Name); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the driver Entry operation. KSTATUS DriverEntry(const HAL_API* hal) { if (!hal) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DbgPrint("ATA: driver loading...\n"); gAtaHal = hal; diff --git a/code/kernel/hal/hal_apic.c b/code/kernel/hal/hal_apic.c index 8da818f..6408924 100644 --- a/code/kernel/hal/hal_apic.c +++ b/code/kernel/hal/hal_apic.c @@ -166,9 +166,9 @@ __declspec(dllexport) void HalApicSendTlbShootdownIpi(uint32_t lapicId) { // Starts application Processor. __declspec(dllexport) KSTATUS HalStartApplicationProcessor(uint32_t lapicId, uint8_t startupVector) { if ((!gLapic && !gX2ApicEnabled) || !startupVector || lapicId == gBspLapicId) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!HalApicCanAddressId(lapicId)) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; // INIT assert/deassert, then two SIPIs. The target begins at startupVector << 12. HalApicSendIpi(lapicId, 0x0000C500u); // INIT, level assert, level-triggered @@ -179,7 +179,7 @@ __declspec(dllexport) KSTATUS HalStartApplicationProcessor(uint32_t lapicId, uin HalApicStallUs(200); HalApicSendIpi(lapicId, 0x00000600u | startupVector); // SIPI retry HalApicStallUs(200); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the apic Route Irq operation. diff --git a/code/kernel/hal/hal_main.c b/code/kernel/hal/hal_main.c index 041a85d..2ceda33 100644 --- a/code/kernel/hal/hal_main.c +++ b/code/kernel/hal/hal_main.c @@ -513,7 +513,7 @@ static void HalShutdown(void) { } __declspec(dllexport) KSTATUS HalGetProcessorTopology(HAL_CPU_TOPOLOGY* out) { - if (!out) return STATUS_INVALID_PARAMETER; + if (!out) return NTLSTATUS_INVALID_PARAMETER; memset(out, 0, sizeof(*out)); *out = gCpuTopology; @@ -526,7 +526,7 @@ __declspec(dllexport) KSTATUS HalGetProcessorTopology(HAL_CPU_TOPOLOGY* out) { out->Cpus[0].Flags = 1; out->Cpus[0].Enabled = 1; out->Cpus[0].IsBsp = 1; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } uint32_t bsp = HalGetBspLapicId(); @@ -546,11 +546,11 @@ __declspec(dllexport) KSTATUS HalGetProcessorTopology(HAL_CPU_TOPOLOGY* out) { cpu->Enabled = 1; cpu->IsBsp = 1; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } __declspec(dllexport) KSTATUS HalInitialize(const HAL_INIT_PARAMS* initParams) { - if (gInitialised) return STATUS_ALREADY_EXISTS; + if (gInitialised) return NTLSTATUS_ALREADY_EXISTS; gPhysBase = initParams->PhysicalWindowBase; gApi.PhysToVirt = HalPhysToVirt; debugEnabled = initParams->Debug; @@ -606,7 +606,7 @@ __declspec(dllexport) KSTATUS HalInitialize(const HAL_INIT_PARAMS* initParams) { } HalDbgPrint("HAL: initialisation complete.\n"); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Registers scheduler. diff --git a/code/kernel/hal/hal_output.c b/code/kernel/hal/hal_output.c index 2dd31b2..4e2b1b2 100644 --- a/code/kernel/hal/hal_output.c +++ b/code/kernel/hal/hal_output.c @@ -36,9 +36,9 @@ static void HalOutputReleaseRegistrationLock(void) { static KSTATUS HalOutputRegisterEndpoint(const HAL_OUTPUT_ENDPOINT* endpoint, uint32_t* endpointIdOut) { if (!endpoint || !endpointIdOut || !endpoint->Name || !endpoint->Write || endpoint->StreamMask == 0 || (endpoint->StreamMask & ~HAL_OUTPUT_STREAM_ALL) != 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; - KSTATUS status = STATUS_NO_MEMORY; + KSTATUS status = NTLSTATUS_NO_MEMORY; HalOutputAcquireRegistrationLock(); for (uint32_t i = 0; i < HAL_OUTPUT_ENDPOINT_CAPACITY; i++) { HAL_OUTPUT_SLOT* slot = &gOutputSlots[i]; @@ -50,7 +50,7 @@ static KSTATUS HalOutputRegisterEndpoint(const HAL_OUTPUT_ENDPOINT* endpoint, ui _InterlockedExchange(&slot->Published, 1); _InterlockedIncrement(&gOutputEndpointCount); *endpointIdOut = i; - status = STATUS_SUCCESS; + status = NTLSTATUS_SUCCESS; break; } HalOutputReleaseRegistrationLock(); @@ -61,14 +61,14 @@ static KSTATUS HalOutputRegisterEndpoint(const HAL_OUTPUT_ENDPOINT* endpoint, ui static KSTATUS HalOutputSetEndpointStreams(uint32_t endpointId, uint32_t streamMask) { if (endpointId >= HAL_OUTPUT_ENDPOINT_CAPACITY || (streamMask & ~HAL_OUTPUT_STREAM_ALL) != 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; HAL_OUTPUT_SLOT* slot = &gOutputSlots[endpointId]; if (_InterlockedCompareExchange(&slot->Published, 0, 0) == 0) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; _InterlockedExchange((volatile long*)&slot->Endpoint.StreamMask, (long)streamMask); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Fans one text record out to every subscribed endpoint. diff --git a/code/kernel/hal/hal_rtc.c b/code/kernel/hal/hal_rtc.c index 2408939..8c370f8 100644 --- a/code/kernel/hal/hal_rtc.c +++ b/code/kernel/hal/hal_rtc.c @@ -142,15 +142,15 @@ static bool RtcValid(const HAL_RTC_TIME* t) { // Implements the rtc Query Time operation. static KSTATUS HalRtcQueryTime(HAL_RTC_TIME* outTime) { - if (!outTime) return STATUS_INVALID_PARAMETER; + if (!outTime) return NTLSTATUS_INVALID_PARAMETER; HAL_RTC_TIME t; memset(&t, 0, sizeof(t)); if (!RtcReadStable(&t) || !RtcValid(&t)) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; *outTime = t; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the rtc Set Century Register operation. @@ -164,7 +164,7 @@ void HalRtcInitialize(HAL_RTC* out) { out->QueryTime = HalRtcQueryTime; HAL_RTC_TIME t; - if (HalRtcQueryTime(&t) == STATUS_SUCCESS) { + if (HalRtcQueryTime(&t) == NTLSTATUS_SUCCESS) { HalDbgPrint("HAL: RTC %04u-%02u-%02u %02u:%02u:%02u century-reg=0x%02x\n", t.Year, t.Month, t.Day, t.Hour, t.Minute, t.Second, gCenturyRegister); diff --git a/code/kernel/hal/hal_screen.c b/code/kernel/hal/hal_screen.c index eb695f0..6574c1b 100644 --- a/code/kernel/hal/hal_screen.c +++ b/code/kernel/hal/hal_screen.c @@ -117,14 +117,14 @@ static void ScreenGetSize(int* w, int* h) { *w = gWidth; *h = gHeight; } // Implements the screen Get Framebuffer operation. static KSTATUS ScreenGetFramebuffer(HAL_FRAMEBUFFER_INFO* outInfo) { if (!outInfo || !gFb || gWidth <= 0 || gHeight <= 0 || gStride <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; outInfo->Base = (uintptr_t)gFb; outInfo->Width = (uint32_t)gWidth; outInfo->Height = (uint32_t)gHeight; outInfo->Stride = (uint32_t)gStride; outInfo->Format = 1; // X8R8G8B8 - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the screen Scroll operation. diff --git a/code/kernel/hal/hal_timer.c b/code/kernel/hal/hal_timer.c index b2d4467..8e08d48 100644 --- a/code/kernel/hal/hal_timer.c +++ b/code/kernel/hal/hal_timer.c @@ -210,7 +210,7 @@ KSTATUS HalTimerInitialize(uintptr_t lapicPhys, uintptr_t hpetPhys, HAL_TIMER *o } if (!ticksPerMs) { HalDbgPrint("HAL: APIC calibration failed. How?\n"); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } gApicTicksPerUs = ticksPerMs / 1000; @@ -234,5 +234,5 @@ KSTATUS HalTimerInitialize(uintptr_t lapicPhys, uintptr_t hpetPhys, HAL_TIMER *o out->Stall = Stall; out->Isr = TimerIsr; out->IrqNumber = 0; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } diff --git a/code/kernel/include/kernel/io_file.h b/code/kernel/include/kernel/io_file.h index 0cd58b2..56a1686 100644 --- a/code/kernel/include/kernel/io_file.h +++ b/code/kernel/include/kernel/io_file.h @@ -20,7 +20,7 @@ typedef SYS_DIR_ENTRY KDIR_ENTRY; #define KDIR_NAME_MAX SYS_DIR_NAME_MAX // Native asynchronous filesystem completion. Filesystems that provide -// ReadAsync/WriteAsync accept the operation, return STATUS_PENDING, and later +// ReadAsync/WriteAsync accept the operation, return NTLSTATUS_PENDING, and later // call Complete(CompleteContext, status, information). Filesystems without // these callbacks fall back to the generic VFS async worker. typedef void (*IO_FS_ASYNC_COMPLETE)(void* completeContext, @@ -130,7 +130,7 @@ typedef struct IO_FILESYSTEM { // Advance to the next entry. // Fills 'out' with name, attributes, and size. - // Returns STATUS_NO_MORE_FILES when the directory is exhausted. + // Returns NTLSTATUS_NO_MORE_FILES when the directory is exhausted. KSTATUS (*ReadDir)(struct IO_FILESYSTEM* fs, void* dirCtx, KDIR_ENTRY* out); diff --git a/code/kernel/include/kernel/ke_debug.h b/code/kernel/include/kernel/ke_debug.h index c5e6619..14ad813 100644 --- a/code/kernel/include/kernel/ke_debug.h +++ b/code/kernel/include/kernel/ke_debug.h @@ -78,7 +78,7 @@ typedef struct KFAULT_FRAME { uint64_t R15; } KFAULT_FRAME; -__declspec(dllexport) KSTATUS KeFaultDispatchFrame(const KFAULT_FRAME* frame); +__declspec(dllexport) KSTATUS KeFaultDispatchFrame(KFAULT_FRAME* frame); // Compatibility wrapper for any older assembly/object still calling this. __declspec(dllexport) _Noreturn void KeFaultDispatch(int vector, uintptr_t rip, diff --git a/code/kernel/include/kernel/ke_exception.h b/code/kernel/include/kernel/ke_exception.h new file mode 100644 index 0000000..a68ef18 --- /dev/null +++ b/code/kernel/include/kernel/ke_exception.h @@ -0,0 +1,26 @@ +// Kernel exception classification shared by trap and crash-report paths. + +#pragma once + +#include +#include +#include +#include +#include + +#define KFAULT_FRAME_MAGIC_VALUE 0x3146544C5541464BULL + +bool KeFaultFrameIsValid(const KFAULT_FRAME* frame); +bool KeFaultFrameFromUser(const KFAULT_FRAME* frame); +const char* KeExceptionVectorName(uint32_t vector); +bool KeExceptionVectorHasErrorCode(uint32_t vector); +KSTATUS KeExceptionProcessExitStatus(uint32_t vector); +KSTATUS KeExceptionResolveRecoverableFault(const KFAULT_FRAME* frame); + +struct PROCESS; + +KSTATUS KeSetExceptionDispatcher(struct PROCESS* process, const SYS_EXCEPTION_DISPATCHER_REQUEST* request); +KSTATUS KeGetExceptionDispatcher(struct PROCESS* process, SYS_EXCEPTION_DISPATCHER_REQUEST* request); +KSTATUS KeDeliverUserException(KFAULT_FRAME* frame); +uint64_t KeContinueException(const SYS_CONTINUE_EXCEPTION_REQUEST* request); +uint64_t KeRaiseUserException(const SYS_RAISE_EXCEPTION_REQUEST* request, const uint64_t* parameters); diff --git a/code/kernel/include/kernel/ke_named_queue.h b/code/kernel/include/kernel/ke_named_queue.h new file mode 100644 index 0000000..1434662 --- /dev/null +++ b/code/kernel/include/kernel/ke_named_queue.h @@ -0,0 +1,11 @@ +// Named queue registry hooks shared by process handle cleanup and syscalls. + +#pragma once + +#include + +struct PROCESS; +struct OBJECT; + +// Removes registry entries owned by the given process handle/object pair. +void KeNamedQueueUnpublishHandle(struct PROCESS* process, uint32_t handle, struct OBJECT* object); diff --git a/code/kernel/include/kernel/ke_process.h b/code/kernel/include/kernel/ke_process.h index 88a69b4..495df82 100644 --- a/code/kernel/include/kernel/ke_process.h +++ b/code/kernel/include/kernel/ke_process.h @@ -32,6 +32,8 @@ #define HANDLE_RIGHT_LOCK 0x00000080u #define HANDLE_RIGHT_ALL 0xFFFFFFFFu +struct SYS_EXCEPTION_STATS; + typedef struct HANDLE_ENTRY { OBJECT* Object; uint32_t Rights; @@ -100,6 +102,24 @@ typedef struct PROCESS { uint32_t ModuleCount; SPINLOCK ModuleLock; + // Native structured-exception dispatcher registration. The user-mode + // personality owns VEH, SEH, signal, and unwind policy behind this hook. + uintptr_t ExceptionDispatcher; + uintptr_t ExceptionDispatcherContext; + uintptr_t ExceptionStackBase; + size_t ExceptionStackSize; + uint32_t ExceptionDispatchFlags; + uint64_t ExceptionDeliveredCount; + uint64_t ExceptionUserRaisedCount; + uint64_t ExceptionContinuedCount; + uint64_t ExceptionUnhandledCount; + uint64_t ExceptionInvalidContinueCount; + uint32_t ExceptionMaxNestedDispatch; + uint32_t LastExceptionCode; + uintptr_t LastExceptionAddress; + uintptr_t LastExceptionFaultAddress; + SPINLOCK ExceptionLock; + // Signaled (manual-reset) when the process exits. // Waiters block on this via KeWaitForEvent. EVENT* ExitEvent; @@ -119,6 +139,7 @@ void KeCompleteProcessExitIfLastThread(PROCESS* process); int KeIsProcessTerminating(PROCESS* process); int KeIsProcessTerminationProtected(PROCESS* process); KSTATUS KeGetProcessExitCode(PROCESS* process, int32_t* exitCodeOut); +void KeQueryExceptionStats(struct SYS_EXCEPTION_STATS* statsOut); // Handle table operations. KSTATUS KeAllocateHandle(PROCESS* process, OBJECT* object, uint32_t* handleOut); diff --git a/code/kernel/include/kernel/ke_thread.h b/code/kernel/include/kernel/ke_thread.h index ccdfff3..d44ccb7 100644 --- a/code/kernel/include/kernel/ke_thread.h +++ b/code/kernel/include/kernel/ke_thread.h @@ -13,6 +13,7 @@ #define KSTACK_SIZE (64 * 1024) // 64 KB kernel stack #define USTACK_SIZE (512 * 1024) // 512 KB user stack +#define KE_USER_EXCEPTION_MAX_DEPTH 8u typedef struct THREAD THREAD; @@ -153,6 +154,14 @@ struct THREAD { uint64_t UserApcSavedRsp; uint64_t UserApcSavedRflags; uint64_t UserApcSavedRax; + + // User exception dispatch state. The kernel tracks delivery nesting, + // continuability, and the process status to use if user policy declines + // the active exception. User-mode personalities own handler policy. + uint32_t UserExceptionDepth; + uint32_t UserExceptionNoncontinuableMask; + uintptr_t UserExceptionFrameUserAddress; + KSTATUS UserExceptionExitStatus[KE_USER_EXCEPTION_MAX_DEPTH]; }; // Creates and queues a user thread. On success, *out receives a referenced diff --git a/code/kernel/include/kernel/syscall_nr.h b/code/kernel/include/kernel/syscall_nr.h index fb8e67c..c7f83b5 100644 --- a/code/kernel/include/kernel/syscall_nr.h +++ b/code/kernel/include/kernel/syscall_nr.h @@ -7,141 +7,146 @@ // R10 and R11 carry args 4-5 and are loaded by six-argument stubs. // RAX carries the return value. -// Process, threads, modules, waits, and APC. -#define SYS_EXIT_PROCESS 0 -#define SYS_EXIT_THREAD 1 -#define SYS_CREATE_PROCESS 2 -#define SYS_OPEN_PROCESS 3 -#define SYS_GET_PROCESS_EXIT_CODE 4 -#define SYS_KILL_PROCESS 5 -#define SYS_GET_PROCESS_LIST 6 -#define SYS_GET_PROCESS_PID 7 -#define SYS_CREATE_THREAD 8 -#define SYS_GET_THREAD_LIST 9 -#define SYS_LOAD_MODULE 10 -#define SYS_UNLOAD_MODULE 11 -#define SYS_GET_MODULE_INFO 12 -#define SYS_GET_MODULE_EXPORT 13 -#define SYS_GET_MODULE_LIST 14 -#define SYS_GET_CURRENT_TID 15 -#define SYS_GET_CURRENT_PID 16 -#define SYS_SET_THREAD_PRIORITY 17 -#define SYS_YIELD 18 -#define SYS_SLEEP 19 -#define SYS_WAIT_SINGLE 20 -#define SYS_WAIT_MANY 21 -#define SYS_SET_USER_APC_DISPATCHER 22 -#define SYS_APC_RETURN 23 +// Process, threads, modules, waits, APC, and exceptions. +#define SYS_EXIT_PROCESS 0 +#define SYS_EXIT_THREAD 1 +#define SYS_CREATE_PROCESS 2 +#define SYS_OPEN_PROCESS 3 +#define SYS_GET_PROCESS_EXIT_CODE 4 +#define SYS_KILL_PROCESS 5 +#define SYS_GET_PROCESS_LIST 6 +#define SYS_GET_PROCESS_PID 7 +#define SYS_CREATE_THREAD 8 +#define SYS_GET_THREAD_LIST 9 +#define SYS_LOAD_MODULE 10 +#define SYS_UNLOAD_MODULE 11 +#define SYS_GET_MODULE_INFO 12 +#define SYS_GET_MODULE_EXPORT 13 +#define SYS_GET_MODULE_LIST 14 +#define SYS_GET_CURRENT_TID 15 +#define SYS_GET_CURRENT_PID 16 +#define SYS_SET_THREAD_PRIORITY 17 +#define SYS_YIELD 18 +#define SYS_SLEEP 19 +#define SYS_WAIT_SINGLE 20 +#define SYS_WAIT_MANY 21 +#define SYS_SET_USER_APC_DISPATCHER 22 +#define SYS_APC_RETURN 23 +#define SYS_SET_EXCEPTION_DISPATCHER 24 +#define SYS_GET_EXCEPTION_DISPATCHER 25 +#define SYS_CONTINUE_EXCEPTION 26 +#define SYS_RAISE_EXCEPTION 27 // Virtual memory, mappings, and handles. -#define SYS_ALLOC_VM 24 -#define SYS_FREE_VM 25 -#define SYS_PROTECT_VM 26 -#define SYS_QUERY_VM 27 -#define SYS_CLOSE_HANDLE 28 -#define SYS_DUPLICATE_HANDLE 29 -#define SYS_CREATE_FILE_MAPPING 30 -#define SYS_MAP_FILE 31 +#define SYS_ALLOC_VM 28 +#define SYS_FREE_VM 29 +#define SYS_PROTECT_VM 30 +#define SYS_QUERY_VM 31 +#define SYS_CLOSE_HANDLE 32 +#define SYS_DUPLICATE_HANDLE 33 +#define SYS_CREATE_FILE_MAPPING 34 +#define SYS_MAP_FILE 35 // Synchronization objects. -#define SYS_CREATE_MUTEX 32 -#define SYS_TRY_ACQUIRE_MUTEX 33 -#define SYS_RELEASE_MUTEX 34 -#define SYS_CREATE_SEM 35 -#define SYS_TRY_WAIT_SEM 36 -#define SYS_SIGNAL_SEM 37 -#define SYS_CREATE_EVENT 38 -#define SYS_SIGNAL_EVENT 39 -#define SYS_CLEAR_EVENT 40 +#define SYS_CREATE_MUTEX 36 +#define SYS_TRY_ACQUIRE_MUTEX 37 +#define SYS_RELEASE_MUTEX 38 +#define SYS_CREATE_SEM 39 +#define SYS_TRY_WAIT_SEM 40 +#define SYS_SIGNAL_SEM 41 +#define SYS_CREATE_EVENT 42 +#define SYS_SIGNAL_EVENT 43 +#define SYS_CLEAR_EVENT 44 // Queues and named queues. -#define SYS_CREATE_QUEUE 41 -#define SYS_SEND_QUEUE 42 -#define SYS_RECV_QUEUE 43 -#define SYS_PUBLISH_QUEUE 44 -#define SYS_OPEN_NAMED_QUEUE 45 -#define SYS_OPEN_NAMED_QUEUE_OWNER_PROCESS 46 +#define SYS_CREATE_QUEUE 45 +#define SYS_SEND_QUEUE 46 +#define SYS_RECV_QUEUE 47 +#define SYS_PUBLISH_QUEUE 48 +#define SYS_OPEN_NAMED_QUEUE 49 +#define SYS_OPEN_NAMED_QUEUE_OWNER_PROCESS 50 // Files, directories, and current directory. -#define SYS_OPEN_FILE 47 -#define SYS_READ_FILE 48 -#define SYS_WRITE_FILE 49 -#define SYS_READ_FILE_ASYNC 50 -#define SYS_WRITE_FILE_ASYNC 51 -#define SYS_CANCEL_IO 52 -#define SYS_SEEK_FILE 53 -#define SYS_GET_FILE_POS 54 -#define SYS_GET_FILE_SIZE 55 -#define SYS_GET_FILE_STAT 56 -#define SYS_STAT_FILE 57 -#define SYS_TRUNCATE_FILE 58 -#define SYS_FLUSH_FILE 59 -#define SYS_DELETE_FILE 60 -#define SYS_RENAME_FILE 61 -#define SYS_LOCK_FILE 62 -#define SYS_UNLOCK_FILE 63 -#define SYS_OPEN_DIR 64 -#define SYS_READ_DIR 65 -#define SYS_CREATE_DIR 66 -#define SYS_REMOVE_DIR 67 -#define SYS_SET_CWD 68 -#define SYS_REAL_PATH 69 +#define SYS_OPEN_FILE 51 +#define SYS_READ_FILE 52 +#define SYS_WRITE_FILE 53 +#define SYS_READ_FILE_ASYNC 54 +#define SYS_WRITE_FILE_ASYNC 55 +#define SYS_CANCEL_IO 56 +#define SYS_SEEK_FILE 57 +#define SYS_GET_FILE_POS 58 +#define SYS_GET_FILE_SIZE 59 +#define SYS_GET_FILE_STAT 60 +#define SYS_STAT_FILE 61 +#define SYS_TRUNCATE_FILE 62 +#define SYS_FLUSH_FILE 63 +#define SYS_DELETE_FILE 64 +#define SYS_RENAME_FILE 65 +#define SYS_LOCK_FILE 66 +#define SYS_UNLOCK_FILE 67 +#define SYS_OPEN_DIR 68 +#define SYS_READ_DIR 69 +#define SYS_CREATE_DIR 70 +#define SYS_REMOVE_DIR 71 +#define SYS_SET_CWD 72 +#define SYS_REAL_PATH 73 // Console, display, and surfaces. -#define SYS_WRITE_CONSOLE 70 -#define SYS_GET_CONSOLE_INFO 71 -#define SYS_SET_CONSOLE_CURSOR 72 -#define SYS_FILL_CONSOLE_CHARACTER 73 -#define SYS_FILL_CONSOLE_ATTRIBUTE 74 -#define SYS_PUT_SCREEN_CHAR 75 -#define SYS_CLEAR_SCREEN 76 -#define SYS_GET_SCREEN_SIZE 77 -#define SYS_QUERY_DISPLAY_INFO 78 -#define SYS_CREATE_SURFACE 79 -#define SYS_MAP_SURFACE 80 -#define SYS_QUERY_SURFACE 81 -#define SYS_PRESENT_SURFACE 82 +#define SYS_WRITE_CONSOLE 74 +#define SYS_GET_CONSOLE_INFO 75 +#define SYS_SET_CONSOLE_CURSOR 76 +#define SYS_FILL_CONSOLE_CHARACTER 77 +#define SYS_FILL_CONSOLE_ATTRIBUTE 78 +#define SYS_PUT_SCREEN_CHAR 79 +#define SYS_CLEAR_SCREEN 80 +#define SYS_GET_SCREEN_SIZE 81 +#define SYS_QUERY_DISPLAY_INFO 82 +#define SYS_CREATE_SURFACE 83 +#define SYS_MAP_SURFACE 84 +#define SYS_QUERY_SURFACE 85 +#define SYS_PRESENT_SURFACE 86 // Input. -#define SYS_POLL_KEYBOARD 83 -#define SYS_IS_KEY_DOWN 84 -#define SYS_READ_KEYBOARD_CHAR 85 -#define SYS_READ_KEY 86 -#define SYS_GET_KEY_MODIFIERS 87 -#define SYS_OPEN_INPUT_QUEUE 88 -#define SYS_READ_INPUT_EVENT 89 -#define SYS_PEEK_INPUT_EVENT 90 -#define SYS_PEEK_MOUSE 91 -#define SYS_READ_MOUSE 92 -#define SYS_GET_MOUSE_POS 93 +#define SYS_POLL_KEYBOARD 87 +#define SYS_IS_KEY_DOWN 88 +#define SYS_READ_KEYBOARD_CHAR 89 +#define SYS_READ_KEY 90 +#define SYS_GET_KEY_MODIFIERS 91 +#define SYS_OPEN_INPUT_QUEUE 92 +#define SYS_READ_INPUT_EVENT 93 +#define SYS_PEEK_INPUT_EVENT 94 +#define SYS_PEEK_MOUSE 95 +#define SYS_READ_MOUSE 96 +#define SYS_GET_MOUSE_POS 97 // Time, debug, and system information. -#define SYS_CREATE_TIMER 94 -#define SYS_SET_TIMER 95 -#define SYS_CANCEL_TIMER 96 -#define SYS_GET_TICK 97 -#define SYS_GET_TICK_FREQUENCY 98 -#define SYS_GET_SYSTEM_TIME 99 -#define SYS_PRINT_DEBUG 100 -#define SYS_QUERY_TRAP_FRAME 101 -#define SYS_GET_MEMORY_STATUS 102 -#define SYS_QUERY_KERNEL_STATS 103 +#define SYS_CREATE_TIMER 98 +#define SYS_SET_TIMER 99 +#define SYS_CANCEL_TIMER 100 +#define SYS_GET_TICK 101 +#define SYS_GET_TICK_FREQUENCY 102 +#define SYS_GET_SYSTEM_TIME 103 +#define SYS_PRINT_DEBUG 104 +#define SYS_QUERY_TRAP_FRAME 105 +#define SYS_GET_MEMORY_STATUS 106 +#define SYS_QUERY_KERNEL_STATS 107 // Native sockets and polling. -#define SYS_CREATE_SOCKET 104 -#define SYS_SOCKET_IO_ASYNC 105 -#define SYS_BIND_SOCKET 106 -#define SYS_LISTEN_SOCKET 107 -#define SYS_ACCEPT_SOCKET 108 -#define SYS_CONNECT_SOCKET 109 -#define SYS_SEND_SOCKET 110 -#define SYS_RECV_SOCKET 111 -#define SYS_SHUTDOWN_SOCKET 112 -#define SYS_SEND_TO_SOCKET 113 -#define SYS_RECV_FROM_SOCKET 114 -#define SYS_RESOLVE_HOST 115 -#define SYS_SET_SOCKET_OPTION 116 -#define SYS_GET_SOCKET_OPTION 117 -#define SYS_POLL 118 +#define SYS_CREATE_SOCKET 108 +#define SYS_SOCKET_IO_ASYNC 109 +#define SYS_BIND_SOCKET 110 +#define SYS_LISTEN_SOCKET 111 +#define SYS_ACCEPT_SOCKET 112 +#define SYS_CONNECT_SOCKET 113 +#define SYS_SEND_SOCKET 114 +#define SYS_RECV_SOCKET 115 +#define SYS_SHUTDOWN_SOCKET 116 +#define SYS_SEND_TO_SOCKET 117 +#define SYS_RECV_FROM_SOCKET 118 +#define SYS_RESOLVE_HOST 119 +#define SYS_SET_SOCKET_OPTION 120 +#define SYS_GET_SOCKET_OPTION 121 +#define SYS_POLL 122 +#define SYS_UNPUBLISH_QUEUE 123 -#define SYS_MAX 119 +#define SYS_MAX 124 diff --git a/code/kernel/io_async.c b/code/kernel/io_async.c index d80fdb3..0b4f23d 100644 --- a/code/kernel/io_async.c +++ b/code/kernel/io_async.c @@ -42,19 +42,19 @@ __declspec(dllexport) KSTATUS IoCreateAsyncRequest(size_t objectSize, IO_ASYNC_REQUEST_CANCEL_ROUTINE cancelRoutine, void* cancelContext, IO_ASYNC_REQUEST_OBJECT** requestOut) { - if (!requestOut) return STATUS_INVALID_PARAMETER; + if (!requestOut) return NTLSTATUS_INVALID_PARAMETER; *requestOut = (IO_ASYNC_REQUEST_OBJECT*)0; - if (objectSize < sizeof(IO_ASYNC_REQUEST_OBJECT)) return STATUS_INVALID_PARAMETER; + if (objectSize < sizeof(IO_ASYNC_REQUEST_OBJECT)) return NTLSTATUS_INVALID_PARAMETER; IO_ASYNC_REQUEST_OBJECT* request = (IO_ASYNC_REQUEST_OBJECT*)ObAllocateObject(ObjectTypeAsyncIo, objectSize); - if (!request) return STATUS_NO_MEMORY; + if (!request) return NTLSTATUS_NO_MEMORY; request->Header.Destroy = KiIoAsyncRequestDestroy; LIST_INIT(&request->Link); request->State = IoAsyncRequestQueued; request->CancelRequested = 0; - request->IosbSnapshot.Status = STATUS_PENDING; + request->IosbSnapshot.Status = NTLSTATUS_PENDING; request->IosbSnapshot.Information = 0; request->CleanupRoutine = cleanupRoutine; request->CleanupContext = cleanupContext; @@ -68,7 +68,7 @@ __declspec(dllexport) KSTATUS IoCreateAsyncRequest(size_t objectSize, } *requestOut = request; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns the object header embedded in an async request. @@ -90,11 +90,11 @@ __declspec(dllexport) void IoInitializeAsyncRequestCompletion(IO_ASYNC_REQUEST_O request->Iosb = iosb; request->LockedBuffer = lockedBuffer; request->LockedIosb = lockedIosb; - request->IosbSnapshot.Status = STATUS_PENDING; + request->IosbSnapshot.Status = NTLSTATUS_PENDING; request->IosbSnapshot.Information = 0; if (iosb) { - iosb->Status = STATUS_PENDING; + iosb->Status = NTLSTATUS_PENDING; iosb->Information = 0; } if (completionEvent) @@ -130,34 +130,34 @@ __declspec(dllexport) EVENT* IoGetAsyncRequestWaitEvent(IO_ASYNC_REQUEST_OBJECT* // Waits for an async request to complete according to wait flags. __declspec(dllexport) KSTATUS IoWaitAsyncRequest(IO_ASYNC_REQUEST_OBJECT* request, uint32_t flags) { - if (!request || !request->WaitEvent) return STATUS_INVALID_PARAMETER; - if (flags & ~SYS_WAIT_FLAG_ALERTABLE) return STATUS_INVALID_PARAMETER; + if (!request || !request->WaitEvent) return NTLSTATUS_INVALID_PARAMETER; + if (flags & ~SYS_WAIT_FLAG_ALERTABLE) return NTLSTATUS_INVALID_PARAMETER; return KeWaitForEvent(request->WaitEvent, (flags & SYS_WAIT_FLAG_ALERTABLE) ? 1 : 0); } // Cancels an async request through its operation-family cancel routine. __declspec(dllexport) KSTATUS IoCancelAsyncRequest(IO_ASYNC_REQUEST_OBJECT* request) { - if (!request) return STATUS_INVALID_PARAMETER; + if (!request) return NTLSTATUS_INVALID_PARAMETER; if (request->CancelRoutine) return request->CancelRoutine(request, request->CancelContext); request->CancelRequested = 1; if (request->State == IoAsyncRequestCompleted || request->State == IoAsyncRequestCancelled) - return STATUS_OBJECT_DEAD; - return STATUS_PENDING; + return NTLSTATUS_OBJECT_DEAD; + return NTLSTATUS_PENDING; } // Completes an async request and publishes all caller-visible completion state. __declspec(dllexport) KSTATUS IoCompleteAsyncRequest(IO_ASYNC_REQUEST_OBJECT* request, KSTATUS status, size_t information) { - if (!request) return STATUS_INVALID_PARAMETER; + if (!request) return NTLSTATUS_INVALID_PARAMETER; request->IosbSnapshot.Status = status; request->IosbSnapshot.Information = information; - request->State = (status == STATUS_CANCELLED) ? IoAsyncRequestCancelled + request->State = (status == NTLSTATUS_CANCELLED) ? IoAsyncRequestCancelled : IoAsyncRequestCompleted; if (request->Iosb) { @@ -189,14 +189,14 @@ __declspec(dllexport) KSTATUS IoCompleteAsyncRequest(IO_ASYNC_REQUEST_OBJECT* re request->LockedIosb = (MM_LOCKED_USER_BUFFER*)0; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Copies the last completion snapshot out of an async request. __declspec(dllexport) KSTATUS IoQueryAsyncRequest(IO_ASYNC_REQUEST_OBJECT* request, IO_STATUS_BLOCK* iosbOut) { - if (!request || !iosbOut) return STATUS_INVALID_PARAMETER; + if (!request || !iosbOut) return NTLSTATUS_INVALID_PARAMETER; iosbOut->Status = request->IosbSnapshot.Status; iosbOut->Information = request->IosbSnapshot.Information; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } diff --git a/code/kernel/io_device.c b/code/kernel/io_device.c index 52c2527..33897be 100644 --- a/code/kernel/io_device.c +++ b/code/kernel/io_device.c @@ -63,7 +63,7 @@ static bool IoTryAddDeviceForDriver(DRIVER_OBJECT* driver, DEVICE_OBJECT* pdo) { IoSvOrUnnamed(driver->Name), IoSvOrUnnamed(pdo->Name), IoBusTypeName(pdo->u.Pdo.BusType)); KSTATUS start = IoSendPnpIrpSync(pdo, IRP_MN_START_DEVICE); - if (!KSUCCESS(start) && start != STATUS_NOT_SUPPORTED) { + if (!KSUCCESS(start) && start != NTLSTATUS_NOT_SUPPORTED) { DbgPrint("io: START_DEVICE failed driver=%v pdo=%v st=0x%x\n", IoSvOrUnnamed(driver->Name), IoSvOrUnnamed(pdo->Name), start); } @@ -87,9 +87,9 @@ __declspec(dllexport) void IoInitializeDriverObject(DRIVER_OBJECT* driver, // Registers driver Object. __declspec(dllexport) KSTATUS IoRegisterDriverObject(DRIVER_OBJECT* driver) { - if (!driver) return STATUS_INVALID_PARAMETER; + if (!driver) return NTLSTATUS_INVALID_PARAMETER; if (gDriverObjectCount >= MAX_DRIVER_OBJECTS) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; if (driver->Header.Type != ObjectTypeDriver) { driver->Header.Type = ObjectTypeDriver; @@ -102,7 +102,7 @@ __declspec(dllexport) KSTATUS IoRegisterDriverObject(DRIVER_OBJECT* driver) { for (uint32_t i = 0; i < gPhysicalDeviceCount; i++) (void)IoTryAddDeviceForDriver(driver, gPhysicalDevices[i]); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Device object lifetime. @@ -144,11 +144,11 @@ static KSTATUS IoCreateDeviceInternal(DRIVER_OBJECT* driver, DEVICE_OBJECT_TYPE type, size_t extensionSize, DEVICE_OBJECT** outDevice) { - if (!driver || !outDevice) return STATUS_INVALID_PARAMETER; + if (!driver || !outDevice) return NTLSTATUS_INVALID_PARAMETER; size_t total = sizeof(DEVICE_OBJECT) + extensionSize; DEVICE_OBJECT* dev = (DEVICE_OBJECT*)ObAllocateObject(ObjectTypeDevice, total); - if (!dev) return STATUS_NO_MEMORY; + if (!dev) return NTLSTATUS_NO_MEMORY; dev->Header.Destroy = IoDeviceDestroy; dev->DriverObject = driver; @@ -169,7 +169,7 @@ static KSTATUS IoCreateDeviceInternal(DRIVER_OBJECT* driver, dev->DeviceExtension = (void*)((uint8_t*)dev + sizeof(DEVICE_OBJECT)); *outDevice = dev; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } __declspec(dllexport) KSTATUS IoCreateDevice(DRIVER_OBJECT* driver, @@ -184,8 +184,8 @@ __declspec(dllexport) KSTATUS IoCreatePhysicalDevice(DRIVER_OBJECT* busDriver, size_t idCount, size_t extensionSize, DEVICE_OBJECT** outPdo) { - if (!busDriver || !outPdo) return STATUS_INVALID_PARAMETER; - if (idCount > IO_MAX_DEVICE_IDS) return STATUS_INVALID_PARAMETER; + if (!busDriver || !outPdo) return NTLSTATUS_INVALID_PARAMETER; + if (idCount > IO_MAX_DEVICE_IDS) return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* pdo = (DEVICE_OBJECT*)0; KSTATUS st = IoCreateDeviceInternal(busDriver, DeviceObjectPhysical, extensionSize, &pdo); @@ -195,7 +195,7 @@ __declspec(dllexport) KSTATUS IoCreatePhysicalDevice(DRIVER_OBJECT* busDriver, for (size_t i = 0; i < idCount; i++) { if (!SysSvIsValid(ids[i].Id) || ids[i].Id.Length >= IO_MAX_DEVICE_ID_CHARS) { IoDeleteDevice(pdo); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } char* dst = pdo->u.Pdo.IdStorage[i]; @@ -221,21 +221,21 @@ __declspec(dllexport) KSTATUS IoCreatePhysicalDevice(DRIVER_OBJECT* busDriver, } *outPdo = pdo; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Registers physical Device. __declspec(dllexport) KSTATUS IoRegisterPhysicalDevice(DEVICE_OBJECT* pdo) { if (!pdo || pdo->Type != DeviceObjectPhysical) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; for (uint32_t i = 0; i < gPhysicalDeviceCount; i++) { if (gPhysicalDevices[i] == pdo) - return STATUS_ALREADY_EXISTS; + return NTLSTATUS_ALREADY_EXISTS; } if (gPhysicalDeviceCount >= MAX_PDO_OBJECTS) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; gPhysicalDevices[gPhysicalDeviceCount++] = pdo; @@ -250,21 +250,21 @@ __declspec(dllexport) KSTATUS IoRegisterPhysicalDevice(DEVICE_OBJECT* pdo) { DbgPrint("io: no function driver for pdo=%v id=%v bus=%s\n", IoSvOrUnnamed(pdo->Name), id, IoBusTypeName(pdo->u.Pdo.BusType)); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } __declspec(dllexport) KSTATUS IoSetDeviceName(DEVICE_OBJECT* device, SYS_STRING_VIEW name) { if (!device || !SysSvIsValid(name)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (name.Length >= IO_MAX_DEVICE_NAME_CHARS) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; if (name.Length) memcpy(device->NameStorage, name.Data, name.Length); device->NameStorage[name.Length] = '\0'; device->Name = SysSvFromParts(device->NameStorage, name.Length); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the reference Device Object operation. @@ -378,12 +378,12 @@ __declspec(dllexport) uint8_t IoGetDeviceStackSize(DEVICE_OBJECT* device) { // Implements the forward Irp To Lower operation. __declspec(dllexport) KSTATUS IoForwardIrpToLower(DEVICE_OBJECT* device, IRP* irp) { if (!device || !irp || !device->LowerDevice) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; IO_STACK_LOCATION* cur = IoGetCurrentIrpStackLocation(irp); IO_STACK_LOCATION* next = IoGetNextIrpStackLocation(irp); if (!cur || !next) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* currentDevice = cur->DeviceObject; memcpy(next, cur, sizeof(*next)); @@ -400,10 +400,10 @@ __declspec(dllexport) KSTATUS IoForwardIrpToLower(DEVICE_OBJECT* device, IRP* ir __declspec(dllexport) KSTATUS IoSendPnpIrpSync(DEVICE_OBJECT* device, IO_PNP_MINOR_FUNCTION minor) { - if (!device) return STATUS_INVALID_PARAMETER; + if (!device) return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* top = IoGetAttachedDeviceReference(device); - if (!top) return STATUS_INVALID_PARAMETER; + if (!top) return NTLSTATUS_INVALID_PARAMETER; uint8_t stackCount = IoGetDeviceStackSize(top); IRP* irp = (IRP*)0; @@ -611,14 +611,28 @@ static void IoDiskReadAheadNoteWrite(uint8_t driveIndex, uint32_t count) { static void IoNotifyDiskChange(uint8_t driveIndex, DEVICE_OBJECT* device, IO_DEVICE_CHANGE change) { for (uint32_t i = 0; i < gDiskChangeCallbackCount; i++) { IO_DISK_CHANGE_CALLBACK_ENTRY* entry = &gDiskChangeCallbacks[i]; - if (entry->Used && entry->Callback) - entry->Callback(driveIndex, device, change, entry->Context); + IO_DISK_CHANGE_CALLBACK callback = entry->Callback; + void* context = entry->Context; + if (entry->Used && callback) { + callback(driveIndex, device, change, context); + } else if (entry->Used) { + KePanic(KE_PANIC_CODE_DRIVER, + "io: disk change callback entry has null callback index=%u ctx=0x%016llX change=%u drive=%u dev=0x%016llX\n", + i, context, (uint32_t)change, driveIndex, device); + } } if (change == IoDeviceArrived) { for (uint32_t i = 0; i < gDiskArrivalCallbackCount; i++) { IO_DISK_ARRIVAL_CALLBACK_ENTRY* entry = &gDiskArrivalCallbacks[i]; - if (entry->Used && entry->Callback) - entry->Callback(driveIndex, device, entry->Context); + IO_DISK_ARRIVAL_CALLBACK callback = entry->Callback; + void* context = entry->Context; + if (entry->Used && callback) { + callback(driveIndex, device, context); + } else if (entry->Used) { + KePanic(KE_PANIC_CODE_DRIVER, + "io: disk arrival callback entry has null callback index=%u ctx=0x%016llX drive=%u dev=0x%016llX\n", + i, context, driveIndex, device); + } } } } @@ -626,9 +640,9 @@ static void IoNotifyDiskChange(uint8_t driveIndex, DEVICE_OBJECT* device, IO_DEV __declspec(dllexport) KSTATUS IoRegisterDiskDevice(uint8_t driveIndex, DEVICE_OBJECT* device) { if (driveIndex >= MAX_DISK_DEVICES || !device || !device->DriverObject) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (gDiskDevices[driveIndex]) - return STATUS_ALREADY_EXISTS; + return NTLSTATUS_ALREADY_EXISTS; device->Flags |= DEVICE_OBJECT_DISK; device->u.Disk.DiskIndex = driveIndex; @@ -636,9 +650,9 @@ __declspec(dllexport) KSTATUS IoRegisterDiskDevice(uint8_t driveIndex, device->u.Disk.SectorSize = 512; KSTATUS pnpStatus = IoSendPnpIrpSync(device, IRP_MN_START_DEVICE); - if (!KSUCCESS(pnpStatus) && pnpStatus != STATUS_NOT_SUPPORTED) + if (!KSUCCESS(pnpStatus) && pnpStatus != NTLSTATUS_NOT_SUPPORTED) return pnpStatus; - if (pnpStatus == STATUS_NOT_SUPPORTED) + if (pnpStatus == NTLSTATUS_NOT_SUPPORTED) device->PnpState = DevicePnpStarted; IoDiskReadAheadPrepare(driveIndex); @@ -646,35 +660,35 @@ __declspec(dllexport) KSTATUS IoRegisterDiskDevice(uint8_t driveIndex, IoReferenceDeviceObject(device); gDiskDevices[driveIndex] = device; IoNotifyDiskChange(driveIndex, device, IoDeviceArrived); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the notify Disk Surprise Removed operation. __declspec(dllexport) KSTATUS IoNotifyDiskSurpriseRemoved(uint8_t driveIndex) { if (driveIndex >= MAX_DISK_DEVICES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* dev = gDiskDevices[driveIndex]; - if (!dev) return STATUS_NOT_FOUND; + if (!dev) return NTLSTATUS_NOT_FOUND; IoDiskReadAheadInvalidate(driveIndex); dev->PnpState = DevicePnpSurpriseRemoved; IoNotifyDiskChange(driveIndex, dev, IoDeviceSurpriseRemoved); (void)IoSendPnpIrpSync(dev, IRP_MN_SURPRISE_REMOVAL); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the unregister Disk Device operation. __declspec(dllexport) KSTATUS IoUnregisterDiskDevice(uint8_t driveIndex) { if (driveIndex >= MAX_DISK_DEVICES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* dev = gDiskDevices[driveIndex]; - if (!dev) return STATUS_NOT_FOUND; + if (!dev) return NTLSTATUS_NOT_FOUND; if (dev->PnpState != DevicePnpSurpriseRemoved) { IoNotifyDiskChange(driveIndex, dev, IoDeviceQueryRemove); KSTATUS queryStatus = IoSendPnpIrpSync(dev, IRP_MN_QUERY_REMOVE_DEVICE); - if (!KSUCCESS(queryStatus) && queryStatus != STATUS_NOT_SUPPORTED) + if (!KSUCCESS(queryStatus) && queryStatus != NTLSTATUS_NOT_SUPPORTED) return queryStatus; dev->PnpState = DevicePnpSurpriseRemoved; @@ -689,54 +703,58 @@ __declspec(dllexport) KSTATUS IoUnregisterDiskDevice(uint8_t driveIndex) { IoDiskReadAheadRelease(driveIndex); IoNotifyDiskChange(driveIndex, dev, IoDeviceRemoved); IoDereferenceDeviceObject(dev); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } __declspec(dllexport) KSTATUS IoRegisterDiskArrivalCallback(IO_DISK_ARRIVAL_CALLBACK callback, void* context) { if (!callback) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (gDiskArrivalCallbackCount >= MAX_DISK_CALLBACKS) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; IO_DISK_ARRIVAL_CALLBACK_ENTRY* entry = &gDiskArrivalCallbacks[gDiskArrivalCallbackCount++]; memset(entry, 0, sizeof(*entry)); entry->Used = true; entry->Callback = callback; entry->Context = context; + DbgPrint("io: registered disk arrival callback index=%u cb=0x%016llX ctx=0x%016llX\n", + gDiskArrivalCallbackCount - 1u, callback, context); for (uint8_t i = 0; i < MAX_DISK_DEVICES; i++) { if (gDiskDevices[i]) callback(i, gDiskDevices[i], context); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } __declspec(dllexport) KSTATUS IoRegisterDiskChangeCallback(IO_DISK_CHANGE_CALLBACK callback, void* context) { if (!callback) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (gDiskChangeCallbackCount >= MAX_DISK_CALLBACKS) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; IO_DISK_CHANGE_CALLBACK_ENTRY* entry = &gDiskChangeCallbacks[gDiskChangeCallbackCount++]; memset(entry, 0, sizeof(*entry)); entry->Used = true; entry->Callback = callback; entry->Context = context; - return STATUS_SUCCESS; + DbgPrint("io: registered disk change callback index=%u cb=0x%016llX ctx=0x%016llX\n", + gDiskChangeCallbackCount - 1u, callback, context); + return NTLSTATUS_SUCCESS; } __declspec(dllexport) KSTATUS IoEnumerateDiskDevices(IO_DISK_ARRIVAL_CALLBACK callback, void* context) { if (!callback) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; for (uint8_t i = 0; i < MAX_DISK_DEVICES; i++) { if (gDiskDevices[i]) callback(i, gDiskDevices[i], context); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns disk Device. @@ -767,31 +785,31 @@ __declspec(dllexport) uint64_t IoDiskSectorCount(uint8_t driveIndex) { __declspec(dllexport) KSTATUS IoCallDriver(DEVICE_OBJECT* device, IRP* irp) { if (!device || !device->DriverObject || !irp) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp); if (!ios) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; IO_MAJOR_FUNCTION major = ios->MajorFunction; if (major >= IRP_MJ_MAXIMUM_FUNCTION) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (major != IRP_MJ_PNP && (device->DeletePending || device->PnpState == DevicePnpSurpriseRemoved || device->PnpState == DevicePnpRemovePending || device->PnpState == DevicePnpDeleted)) - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; PDRIVER_DISPATCH dispatch = device->DriverObject->MajorFunction[major]; if (!dispatch) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; ios->DeviceObject = device; IoReferenceDeviceObject(device); _InterlockedIncrement(&device->OutstandingIrps); KSTATUS st = dispatch(device, irp); - if (st != STATUS_PENDING) { + if (st != NTLSTATUS_PENDING) { if (ios->DeviceObject == device) { ios->DeviceObject = (DEVICE_OBJECT*)0; _InterlockedDecrement(&device->OutstandingIrps); @@ -803,17 +821,17 @@ __declspec(dllexport) KSTATUS IoCallDriver(DEVICE_OBJECT* device, IRP* irp) { // Validates that a sector range fits the disk and IRP byte length. static KSTATUS IoValidateDiskSectorRange(DEVICE_OBJECT* dev, uint64_t lba, uint32_t count) { - if (!dev || count == 0) return STATUS_INVALID_PARAMETER; - if (count > (0xffffffffu / IO_DISK_SECTOR_BYTES)) return STATUS_INVALID_PARAMETER; - if (lba > dev->u.Disk.SectorCount) return STATUS_INVALID_PARAMETER; - if ((uint64_t)count > dev->u.Disk.SectorCount - lba) return STATUS_INVALID_PARAMETER; - return STATUS_SUCCESS; + if (!dev || count == 0) return NTLSTATUS_INVALID_PARAMETER; + if (count > (0xffffffffu / IO_DISK_SECTOR_BYTES)) return NTLSTATUS_INVALID_PARAMETER; + if (lba > dev->u.Disk.SectorCount) return NTLSTATUS_INVALID_PARAMETER; + if ((uint64_t)count > dev->u.Disk.SectorCount - lba) return NTLSTATUS_INVALID_PARAMETER; + return NTLSTATUS_SUCCESS; } // Submits one raw disk read IRP. static KSTATUS IoReadDiskSectorsRaw(DEVICE_OBJECT* dev, uint64_t lba, uint32_t count, void* buffer) { - if (!dev || !buffer || count == 0) return STATUS_INVALID_PARAMETER; + if (!dev || !buffer || count == 0) return NTLSTATUS_INVALID_PARAMETER; IRP irp; IoBuildReadWriteIrp(&irp, IRP_MJ_READ, lba * 512ull, count * 512u, buffer); @@ -823,7 +841,7 @@ static KSTATUS IoReadDiskSectorsRaw(DEVICE_OBJECT* dev, uint64_t lba, // Submits one raw disk write IRP. static KSTATUS IoWriteDiskSectorsRaw(DEVICE_OBJECT* dev, uint64_t lba, uint32_t count, void* buffer) { - if (!dev || !buffer || count == 0) return STATUS_INVALID_PARAMETER; + if (!dev || !buffer || count == 0) return NTLSTATUS_INVALID_PARAMETER; IRP irp; IoBuildReadWriteIrp(&irp, IRP_MJ_WRITE, lba * 512ull, count * 512u, buffer); @@ -911,10 +929,10 @@ __declspec(dllexport) KSTATUS IoReadDiskSectors(uint8_t driveIndex, uint64_t lba, uint32_t count, void* buffer) { - if (!buffer || count == 0) return STATUS_INVALID_PARAMETER; + if (!buffer || count == 0) return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* dev = IoReferenceDiskDevice(driveIndex); - if (!dev) return STATUS_NOT_FOUND; + if (!dev) return NTLSTATUS_NOT_FOUND; KSTATUS rangeStatus = IoValidateDiskSectorRange(dev, lba, count); if (!KSUCCESS(rangeStatus)) { @@ -926,7 +944,7 @@ __declspec(dllexport) KSTATUS IoReadDiskSectors(uint8_t driveIndex, uint32_t score = IoDiskReadAheadNoteRead(driveIndex, lba, count); IoDiskMaybeReadAhead(driveIndex, dev, lba + count, count, score); IoDereferenceDeviceObject(dev); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KSTATUS st = IoReadDiskSectorsRaw(dev, lba, count, buffer); @@ -942,10 +960,10 @@ __declspec(dllexport) KSTATUS IoWriteDiskSectors(uint8_t driveIndex, uint64_t lba, uint32_t count, const void* buffer) { - if (!buffer || count == 0) return STATUS_INVALID_PARAMETER; + if (!buffer || count == 0) return NTLSTATUS_INVALID_PARAMETER; DEVICE_OBJECT* dev = IoReferenceDiskDevice(driveIndex); - if (!dev) return STATUS_NOT_FOUND; + if (!dev) return NTLSTATUS_NOT_FOUND; KSTATUS rangeStatus = IoValidateDiskSectorRange(dev, lba, count); if (!KSUCCESS(rangeStatus)) { diff --git a/code/kernel/io_file.c b/code/kernel/io_file.c index 016c0f1..9e22e98 100644 --- a/code/kernel/io_file.c +++ b/code/kernel/io_file.c @@ -183,13 +183,13 @@ static uint64_t KiIoFileLockRemainingMilliseconds(uint64_t deadlineTick) { // Waits for a file-lock conflict to change. static KSTATUS KiIoWaitForFileLockChange(EVENT* event, uint64_t timeoutMilliseconds, uint64_t deadlineTick) { if (!event) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint64_t waitMilliseconds = timeoutMilliseconds; if (timeoutMilliseconds != SYS_WAIT_TIMEOUT_INFINITE) { waitMilliseconds = KiIoFileLockRemainingMilliseconds(deadlineTick); if (waitMilliseconds == 0) - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } EVENT* events[1] = { event }; @@ -224,7 +224,7 @@ static void KiIoAsyncFileRequestCleanup(IO_ASYNC_REQUEST_OBJECT* async, void* co // Cancels an async file request from the common async request surface. static KSTATUS KiIoCancelAsyncFileRequest(IO_ASYNC_REQUEST_OBJECT* async, void* context) { (void)context; - if (!async) return STATUS_INVALID_PARAMETER; + if (!async) return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&gAsyncFileQueueLock); IO_ASYNC_REQUEST_STATE state = IoAsyncRequestGetState(async); @@ -235,19 +235,19 @@ static KSTATUS KiIoCancelAsyncFileRequest(IO_ASYNC_REQUEST_OBJECT* async, void* IoAsyncRequestSetState(async, IoAsyncRequestCancelled); KeReleaseSpinlock(&gAsyncFileQueueLock, flags); - IoCompleteAsyncRequest(async, STATUS_CANCELLED, 0); + IoCompleteAsyncRequest(async, NTLSTATUS_CANCELLED, 0); ObDereferenceObject(&async->Header); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (state == IoAsyncRequestRunning) { IoAsyncRequestRequestCancel(async); KeReleaseSpinlock(&gAsyncFileQueueLock, flags); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } KeReleaseSpinlock(&gAsyncFileQueueLock, flags); - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; } // Implements the io Async File Dequeue operation. @@ -286,7 +286,7 @@ static void KiIoAsyncFileWorker(void* arg) { if (!req) continue; if (IoAsyncRequestIsCancelRequested(&req->Async) || IoAsyncRequestGetState(&req->Async) == IoAsyncRequestCancelled) { - IoCompleteAsyncRequest(&req->Async, STATUS_CANCELLED, 0); + IoCompleteAsyncRequest(&req->Async, NTLSTATUS_CANCELLED, 0); ObDereferenceObject(&req->Async.Header); // queue/worker reference continue; } @@ -304,7 +304,7 @@ static void KiIoAsyncFileWorker(void* arg) { // The operation may already have reached the filesystem. The // completion contract still reports cancellation so waiters/APCs do // not mistake a cancelled request for useful data. - s = STATUS_CANCELLED; + s = NTLSTATUS_CANCELLED; done = 0; } @@ -318,13 +318,13 @@ static KSTATUS KiIoEnsureAsyncFileIoStarted(void) { uintptr_t flags = KeAcquireSpinlock(&gAsyncFileInitLock); if (gAsyncFileInitState == 2) { KeReleaseSpinlock(&gAsyncFileInitLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (gAsyncFileInitState == 1) { KeReleaseSpinlock(&gAsyncFileInitLock, flags); while (gAsyncFileInitState == 1) KeYield(); - return (gAsyncFileInitState == 2) ? STATUS_SUCCESS : STATUS_FAILURE; + return (gAsyncFileInitState == 2) ? NTLSTATUS_SUCCESS : NTLSTATUS_FAILURE; } gAsyncFileInitState = 1; @@ -359,7 +359,7 @@ static void KiIoNativeFsAsyncComplete(void* completeContext, if (!req) return; if (IoAsyncRequestIsCancelRequested(&req->Async)) { - status = STATUS_CANCELLED; + status = NTLSTATUS_CANCELLED; information = 0; } @@ -381,20 +381,20 @@ static KSTATUS KiIoSubmitAsyncFileRequest(IO_ASYNC_FILE_OP op, if (!file || !iosb) { MmUnlockUserBuffer(lockedBuffer); MmUnlockUserBuffer(lockedIosb); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (!buffer && size) { MmUnlockUserBuffer(lockedBuffer); MmUnlockUserBuffer(lockedIosb); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (!KeCanWait()) { MmUnlockUserBuffer(lockedBuffer); MmUnlockUserBuffer(lockedIosb); - return STATUS_INVALID_IRQL; + return NTLSTATUS_INVALID_IRQL; } - iosb->Status = STATUS_PENDING; + iosb->Status = NTLSTATUS_PENDING; iosb->Information = 0; IO_ASYNC_REQUEST_OBJECT* async = (IO_ASYNC_REQUEST_OBJECT*)0; @@ -423,7 +423,7 @@ static KSTATUS KiIoSubmitAsyncFileRequest(IO_ASYNC_FILE_OP op, ObReferenceObject(&file->Header); IO_FS_ASYNC_COMPLETE complete = KiIoNativeFsAsyncComplete; - KSTATUS ns = STATUS_NOT_SUPPORTED; + KSTATUS ns = NTLSTATUS_NOT_SUPPORTED; bool hasNative = (op == IoAsyncFileRead) ? (file->Fs->ReadAsync != 0) : (file->Fs->WriteAsync != 0); @@ -440,13 +440,13 @@ static KSTATUS KiIoSubmitAsyncFileRequest(IO_ASYNC_FILE_OP op, ns = file->Fs->WriteAsync(file->Fs, file->FileCtx, offset, buffer, size, complete, req); } - if (ns == STATUS_PENDING) { + if (ns == NTLSTATUS_PENDING) { if (requestOut) { *requestOut = req; } else { ObDereferenceObject(&req->Async.Header); } - return STATUS_PENDING; + return NTLSTATUS_PENDING; } ObDereferenceObject(&req->Async.Header); // provider rejected synchronously @@ -482,7 +482,7 @@ static KSTATUS KiIoSubmitAsyncFileRequest(IO_ASYNC_FILE_OP op, ObDereferenceObject(&req->Async.Header); } - return STATUS_PENDING; + return NTLSTATUS_PENDING; } __declspec(dllexport) KSTATUS IoReadFileAsyncKernel(FILE_OBJECT* file, void* buf, @@ -607,12 +607,12 @@ static void KiPopComponent(char* work, size_t* workLen) { // Resolve a possibly-relative string view against the CWD. // The returned view is backed by out->Storage and remains valid while 'out' lives. static KSTATUS KiResolvePathV(SYS_STRING_VIEW input, KRESOLVED_PATH* out) { - if (!out) return STATUS_INVALID_PARAMETER; + if (!out) return NTLSTATUS_INVALID_PARAMETER; memset(out, 0, sizeof(*out)); - if (!SysSvIsValid(input)) return STATUS_INVALID_PARAMETER; - if (SysSvContainsByte(input, '\0')) return STATUS_INVALID_PARAMETER; - if (input.Length >= CWD_MAX) return STATUS_BUFFER_TOO_SMALL; + if (!SysSvIsValid(input)) return NTLSTATUS_INVALID_PARAMETER; + if (SysSvContainsByte(input, '\0')) return NTLSTATUS_INVALID_PARAMETER; + if (input.Length >= CWD_MAX) return NTLSTATUS_BUFFER_TOO_SMALL; uint8_t drive = 0; PROCESS* proc = KeGetCurrentProcess(); @@ -662,25 +662,25 @@ static KSTATUS KiResolvePathV(SYS_STRING_VIEW input, KRESOLVED_PATH* out) { KiPopComponent(work, &workLen); continue; } - if (compLen >= 256) return STATUS_BUFFER_TOO_SMALL; + if (compLen >= 256) return NTLSTATUS_BUFFER_TOO_SMALL; if (!KiAppendComponent(work, &workLen, sizeof(work), input.Data + compStart, compLen)) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; } - if (workLen + 1 > sizeof(out->Storage)) return STATUS_BUFFER_TOO_SMALL; + if (workLen + 1 > sizeof(out->Storage)) return NTLSTATUS_BUFFER_TOO_SMALL; memcpy(out->Storage, work, workLen); out->Storage[workLen] = '\0'; out->Drive = drive; out->Path = SysSvFromParts(out->Storage, workLen); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Builds a canonical native path using the kernel-owned process CWD. __declspec(dllexport) KSTATUS IoRealPath(SYS_STRING_VIEW path, char* buffer, size_t bufferSize, size_t* requiredSizeOut) { if (requiredSizeOut) *requiredSizeOut = 0; - if (path.Length && !path.Data) return STATUS_INVALID_PARAMETER; - if (path.Length == 0) return STATUS_INVALID_PARAMETER; - if (!buffer && bufferSize != 0) return STATUS_INVALID_PARAMETER; + if (path.Length && !path.Data) return NTLSTATUS_INVALID_PARAMETER; + if (path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; + if (!buffer && bufferSize != 0) return NTLSTATUS_INVALID_PARAMETER; KRESOLVED_PATH resolved; KSTATUS s = KiResolvePathV(path, &resolved); @@ -688,38 +688,38 @@ __declspec(dllexport) KSTATUS IoRealPath(SYS_STRING_VIEW path, char* buffer, siz char formatted[SYS_CWD_MAX]; size_t required = KiFormatCwd(resolved.Drive, resolved.Path, formatted, sizeof(formatted)); - if (!required || required > sizeof(formatted)) return STATUS_BUFFER_TOO_SMALL; + if (!required || required > sizeof(formatted)) return NTLSTATUS_BUFFER_TOO_SMALL; if (requiredSizeOut) *requiredSizeOut = required; - if (!buffer) return STATUS_SUCCESS; - if (bufferSize < required) return STATUS_BUFFER_TOO_SMALL; + if (!buffer) return NTLSTATUS_SUCCESS; + if (bufferSize < required) return NTLSTATUS_BUFFER_TOO_SMALL; memcpy(buffer, formatted, required); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Updates cwd. __declspec(dllexport) KSTATUS IoSetCwd(SYS_STRING_VIEW path) { - if (path.Length && !path.Data) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; + if (path.Length && !path.Data) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; PROCESS* proc = KeGetCurrentProcess(); - if (!proc) return STATUS_ACCESS_DENIED; + if (!proc) return NTLSTATUS_ACCESS_DENIED; KRESOLVED_PATH resolved; KSTATUS s = KiResolvePathV(path, &resolved); if (!KSUCCESS(s)) return s; IO_FILESYSTEM* fs = gVolumes[resolved.Drive].Fs; - if (!fs) return STATUS_NOT_FOUND; - if (!fs->OpenDir) return STATUS_NOT_SUPPORTED; + if (!fs) return NTLSTATUS_NOT_FOUND; + if (!fs->OpenDir) return NTLSTATUS_NOT_SUPPORTED; void* dirCtx = NULL; s = fs->OpenDir(fs, resolved.Path, &dirCtx); if (!KSUCCESS(s)) return s; fs->CloseDir(fs, dirCtx); - if (resolved.Path.Length + 1 > sizeof(proc->CurrentDirectory)) return STATUS_BUFFER_TOO_SMALL; + if (resolved.Path.Length + 1 > sizeof(proc->CurrentDirectory)) return NTLSTATUS_BUFFER_TOO_SMALL; uintptr_t flags = KeAcquireSpinlock(&proc->CwdLock); proc->CurrentDrive = resolved.Drive; @@ -738,7 +738,7 @@ __declspec(dllexport) KSTATUS IoSetCwd(SYS_STRING_VIEW path) { } KeReleaseSpinlock(&proc->CwdLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Registration. @@ -746,32 +746,32 @@ __declspec(dllexport) KSTATUS IoRegisterFilesystem(uint8_t volumeIndex, IO_FILESYSTEM *fs, const IO_VOLUME_PARAMS *vol) { if (volumeIndex >= MAX_DRIVES || !fs || !vol) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (gVolumes[volumeIndex].Fs) - return STATUS_ALREADY_EXISTS; + return NTLSTATUS_ALREADY_EXISTS; gVolumes[volumeIndex].Fs = fs; gVolumes[volumeIndex].Vol = *vol; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the unregister Filesystem operation. __declspec(dllexport) KSTATUS IoUnregisterFilesystem(uint8_t volumeIndex) { if (volumeIndex >= MAX_DRIVES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!gVolumes[volumeIndex].Fs) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; memset(&gVolumes[volumeIndex], 0, sizeof(gVolumes[volumeIndex])); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the unregister Filesystems For Disk operation. __declspec(dllexport) KSTATUS IoUnregisterFilesystemsForDisk(uint8_t diskIndex) { - KSTATUS last = STATUS_NOT_FOUND; + KSTATUS last = NTLSTATUS_NOT_FOUND; for (uint8_t i = 0; i < MAX_DRIVES; i++) { if (gVolumes[i].Fs && gVolumes[i].Vol.DiskIndex == diskIndex) { memset(&gVolumes[i], 0, sizeof(gVolumes[i])); - last = STATUS_SUCCESS; + last = NTLSTATUS_SUCCESS; } } return last; @@ -827,16 +827,16 @@ static void KiFileDestroy(OBJECT* obj) { // IoOpenFile. __declspec(dllexport) KSTATUS IoOpenFile(SYS_STRING_VIEW path, FILE_OBJECT **out) { - if ((!path.Data && path.Length) || !out) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; - if (path.Length == 0) return STATUS_INVALID_PARAMETER; + if ((!path.Data && path.Length) || !out) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; + if (path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; KRESOLVED_PATH resolved; KSTATUS s = KiResolvePathV(path, &resolved); if (!KSUCCESS(s)) return s; IO_FILESYSTEM* fs = gVolumes[resolved.Drive].Fs; - if (!fs) return STATUS_NOT_FOUND; + if (!fs) return NTLSTATUS_NOT_FOUND; void* fileCtx; s = fs->Open(fs, resolved.Path, &fileCtx); @@ -845,7 +845,7 @@ __declspec(dllexport) KSTATUS IoOpenFile(SYS_STRING_VIEW path, FILE_OBJECT **out // File objects reuse the generic object slot because the handle table only needs the shared header contract here. FILE_OBJECT* f = (FILE_OBJECT *)ObAllocateObject(ObjectTypeFile, sizeof(FILE_OBJECT)); - if (!f) { fs->Close(fs, fileCtx); return STATUS_NO_MEMORY; } + if (!f) { fs->Close(fs, fileCtx); return NTLSTATUS_NO_MEMORY; } f->Header.Destroy = KiFileDestroy; f->Fs = fs; f->FileCtx = fileCtx; @@ -859,7 +859,7 @@ __declspec(dllexport) KSTATUS IoOpenFile(SYS_STRING_VIEW path, FILE_OBJECT **out f->ReadaheadSuppressedUntil = 0; *out = f; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static uint64_t KiAlignUpPage64(uint64_t value) { @@ -906,7 +906,7 @@ static void KiIoMaybeScheduleReadAhead(FILE_OBJECT* file, uint64_t offset, size_ if (pages) { KSTATUS ras = MmFileCacheScheduleReadAhead(file, start, pages); - if (ras == STATUS_QUEUE_FULL) { + if (ras == NTLSTATUS_QUEUE_FULL) { flags = KeAcquireSpinlock(&file->Lock); uint64_t suppressUntil = end + (1024u * 1024u); if (suppressUntil < end || suppressUntil > fileSize) @@ -924,15 +924,15 @@ __declspec(dllexport) KSTATUS IoReadFileAt(FILE_OBJECT* file, uint64_t offset, void* buf, size_t size, size_t* bytesRead) { if (bytesRead) *bytesRead = 0; - if (!file || !buf || !bytesRead) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; - if (size == 0) return STATUS_SUCCESS; + if (!file || !buf || !bytesRead) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; + if (size == 0) return NTLSTATUS_SUCCESS; uintptr_t flags = KeAcquireSpinlock(&file->Lock); uint64_t fileSize = file->Size; KeReleaseSpinlock(&file->Lock, flags); - if (offset >= fileSize) return STATUS_SUCCESS; + if (offset >= fileSize) return NTLSTATUS_SUCCESS; size_t remaining = (size_t)(fileSize - offset); if (size > remaining) size = remaining; @@ -954,7 +954,7 @@ __declspec(dllexport) KSTATUS IoReadFileAt(FILE_OBJECT* file, uint64_t offset, if (!KSUCCESS(s)) { if (total) { *bytesRead = total; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } return s; } @@ -969,7 +969,7 @@ __declspec(dllexport) KSTATUS IoReadFileAt(FILE_OBJECT* file, uint64_t offset, void* srcPage = MmPfnToVirtual(page.Frame); if (!srcPage) { MmFileCacheReleasePage(&page); - return total ? STATUS_SUCCESS : STATUS_FAILURE; + return total ? NTLSTATUS_SUCCESS : NTLSTATUS_FAILURE; } memcpy(dst + total, (const uint8_t*)srcPage + inPage, chunk); MmFileCacheReleasePage(&page); @@ -980,17 +980,17 @@ __declspec(dllexport) KSTATUS IoReadFileAt(FILE_OBJECT* file, uint64_t offset, *bytesRead = total; KiIoMaybeScheduleReadAhead(file, offset, total, fileSize); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } __declspec(dllexport) KSTATUS IoWriteFileAt(FILE_OBJECT* file, uint64_t offset, const void* buf, size_t size, size_t* bytesWritten) { if (bytesWritten) *bytesWritten = 0; - if (!file || !buf || !bytesWritten) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; - if (!file->Fs->Write) return STATUS_NOT_SUPPORTED; - if (size == 0) return STATUS_SUCCESS; + if (!file || !buf || !bytesWritten) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; + if (!file->Fs->Write) return NTLSTATUS_NOT_SUPPORTED; + if (size == 0) return NTLSTATUS_SUCCESS; uintptr_t flags = KeAcquireSpinlock(&file->Lock); uint64_t oldSize = file->Size; @@ -1018,8 +1018,8 @@ __declspec(dllexport) KSTATUS IoWriteFileAt(FILE_OBJECT* file, uint64_t offset, // Flushes dirty mapped and cached pages for one file object. __declspec(dllexport) KSTATUS IoFlushFile(FILE_OBJECT* file) { - if (!file) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; + if (!file) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; KSTATUS sync = MmVadSyncFileMappings(file); KSTATUS flush = MmFileCacheFlushFile(file); @@ -1030,7 +1030,7 @@ __declspec(dllexport) KSTATUS IoFlushFile(FILE_OBJECT* file) { __declspec(dllexport) KSTATUS IoReadFile(FILE_OBJECT* file, void* buf, size_t size, size_t* bytesRead) { if (bytesRead) *bytesRead = 0; - if (!file || !buf || !bytesRead) return STATUS_INVALID_PARAMETER; + if (!file || !buf || !bytesRead) return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&file->Lock); uint64_t offset = file->Offset; @@ -1049,7 +1049,7 @@ __declspec(dllexport) KSTATUS IoReadFile(FILE_OBJECT* file, void* buf, __declspec(dllexport) KSTATUS IoWriteFile(FILE_OBJECT* file, const void* buf, size_t size, size_t* bytesWritten) { if (bytesWritten) *bytesWritten = 0; - if (!file || !buf || !bytesWritten) return STATUS_INVALID_PARAMETER; + if (!file || !buf || !bytesWritten) return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&file->Lock); uint64_t offset = (file->Flags & IO_FILE_FLAG_APPEND) ? file->Size : file->Offset; @@ -1066,16 +1066,16 @@ __declspec(dllexport) KSTATUS IoWriteFile(FILE_OBJECT* file, const void* buf, // IoCreateFile - create a new file and return it open for writing. __declspec(dllexport) KSTATUS IoCreateFile(SYS_STRING_VIEW path, FILE_OBJECT** out) { - if ((!path.Data && path.Length) || !out || path.Length == 0) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; + if ((!path.Data && path.Length) || !out || path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; KRESOLVED_PATH resolved; KSTATUS s = KiResolvePathV(path, &resolved); if (!KSUCCESS(s)) return s; IO_FILESYSTEM* fs = gVolumes[resolved.Drive].Fs; - if (!fs) return STATUS_NOT_FOUND; - if (!fs->Create) return STATUS_NOT_SUPPORTED; + if (!fs) return NTLSTATUS_NOT_FOUND; + if (!fs->Create) return NTLSTATUS_NOT_SUPPORTED; void* fileCtx; s = fs->Create(fs, resolved.Path, &fileCtx); @@ -1083,7 +1083,7 @@ __declspec(dllexport) KSTATUS IoCreateFile(SYS_STRING_VIEW path, FILE_OBJECT** o FILE_OBJECT* f = (FILE_OBJECT*)ObAllocateObject(ObjectTypeFile, sizeof(FILE_OBJECT)); - if (!f) { fs->Close(fs, fileCtx); return STATUS_NO_MEMORY; } + if (!f) { fs->Close(fs, fileCtx); return NTLSTATUS_NO_MEMORY; } f->Header.Destroy = KiFileDestroy; f->Fs = fs; f->FileCtx = fileCtx; @@ -1097,21 +1097,21 @@ __declspec(dllexport) KSTATUS IoCreateFile(SYS_STRING_VIEW path, FILE_OBJECT** o f->ReadaheadSuppressedUntil = 0; *out = f; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // IoDeleteFile - delete a file by path (does not require an open handle). __declspec(dllexport) KSTATUS IoDeleteFile(SYS_STRING_VIEW path) { - if ((!path.Data && path.Length) || path.Length == 0) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; + if ((!path.Data && path.Length) || path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; KRESOLVED_PATH resolved; KSTATUS s = KiResolvePathV(path, &resolved); if (!KSUCCESS(s)) return s; IO_FILESYSTEM* fs = gVolumes[resolved.Drive].Fs; - if (!fs) return STATUS_NOT_FOUND; - if (!fs->Delete) return STATUS_NOT_SUPPORTED; + if (!fs) return NTLSTATUS_NOT_FOUND; + if (!fs->Delete) return NTLSTATUS_NOT_SUPPORTED; return fs->Delete(fs, resolved.Path); } @@ -1119,8 +1119,8 @@ __declspec(dllexport) KSTATUS IoDeleteFile(SYS_STRING_VIEW path) { // Implements the rename File operation. __declspec(dllexport) KSTATUS IoRenameFile(SYS_STRING_VIEW oldPath, SYS_STRING_VIEW newPath) { if ((!oldPath.Data && oldPath.Length) || (!newPath.Data && newPath.Length) || - oldPath.Length == 0 || newPath.Length == 0) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; + oldPath.Length == 0 || newPath.Length == 0) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; KRESOLVED_PATH oldResolved; KRESOLVED_PATH newResolved; @@ -1128,52 +1128,52 @@ __declspec(dllexport) KSTATUS IoRenameFile(SYS_STRING_VIEW oldPath, SYS_STRING_V if (!KSUCCESS(s)) return s; s = KiResolvePathV(newPath, &newResolved); if (!KSUCCESS(s)) return s; - if (oldResolved.Drive != newResolved.Drive) return STATUS_NOT_SUPPORTED; + if (oldResolved.Drive != newResolved.Drive) return NTLSTATUS_NOT_SUPPORTED; IO_FILESYSTEM* fs = gVolumes[oldResolved.Drive].Fs; - if (!fs) return STATUS_NOT_FOUND; - if (!fs->Rename) return STATUS_NOT_SUPPORTED; + if (!fs) return NTLSTATUS_NOT_FOUND; + if (!fs->Rename) return NTLSTATUS_NOT_SUPPORTED; return fs->Rename(fs, oldResolved.Path, newResolved.Path); } // Creates dir. __declspec(dllexport) KSTATUS IoCreateDir(SYS_STRING_VIEW path) { - if ((!path.Data && path.Length) || path.Length == 0) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; + if ((!path.Data && path.Length) || path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; KRESOLVED_PATH resolved; KSTATUS s = KiResolvePathV(path, &resolved); if (!KSUCCESS(s)) return s; IO_FILESYSTEM* fs = gVolumes[resolved.Drive].Fs; - if (!fs) return STATUS_NOT_FOUND; - if (!fs->CreateDir) return STATUS_NOT_SUPPORTED; + if (!fs) return NTLSTATUS_NOT_FOUND; + if (!fs->CreateDir) return NTLSTATUS_NOT_SUPPORTED; return fs->CreateDir(fs, resolved.Path); } // Releases dir. __declspec(dllexport) KSTATUS IoRemoveDir(SYS_STRING_VIEW path) { - if ((!path.Data && path.Length) || path.Length == 0) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; + if ((!path.Data && path.Length) || path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; KRESOLVED_PATH resolved; KSTATUS s = KiResolvePathV(path, &resolved); if (!KSUCCESS(s)) return s; IO_FILESYSTEM* fs = gVolumes[resolved.Drive].Fs; - if (!fs) return STATUS_NOT_FOUND; - if (!fs->RemoveDir) return STATUS_NOT_SUPPORTED; + if (!fs) return NTLSTATUS_NOT_FOUND; + if (!fs->RemoveDir) return NTLSTATUS_NOT_SUPPORTED; return fs->RemoveDir(fs, resolved.Path); } // IoTruncateFile - resize the file; updates the cached Size on success. __declspec(dllexport) KSTATUS IoTruncateFile(FILE_OBJECT* file, uint64_t newSize) { - if (!file) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; - if (!file->Fs->Truncate) return STATUS_NOT_SUPPORTED; + if (!file) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; + if (!file->Fs->Truncate) return NTLSTATUS_NOT_SUPPORTED; KSTATUS flush = IoFlushFile(file); if (!KSUCCESS(flush)) return flush; @@ -1190,11 +1190,11 @@ __declspec(dllexport) KSTATUS IoTruncateFile(FILE_OBJECT* file, uint64_t newSize } __declspec(dllexport) KSTATUS IoSeekFile(FILE_OBJECT* file, uint64_t offset) { - if (!file) return STATUS_INVALID_PARAMETER; + if (!file) return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&file->Lock); file->Offset = offset; KeReleaseSpinlock(&file->Lock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns file Size. @@ -1208,7 +1208,7 @@ __declspec(dllexport) uint64_t IoGetFileSize(FILE_OBJECT* file) { // Queries metadata for an open file object. __declspec(dllexport) KSTATUS IoGetFileStat(FILE_OBJECT* file, SYS_FILE_STAT* out) { - if (!file || !out) return STATUS_INVALID_PARAMETER; + if (!file || !out) return NTLSTATUS_INVALID_PARAMETER; memset(out, 0, sizeof(*out)); out->Size = sizeof(*out); out->Type = SYS_FILE_TYPE_REGULAR; @@ -1216,7 +1216,7 @@ __declspec(dllexport) KSTATUS IoGetFileStat(FILE_OBJECT* file, SYS_FILE_STAT* ou out->FileSize = IoGetFileSize(file); if (!file->Fs || !file->Fs->QueryInfo) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; KSTATUS s = file->Fs->QueryInfo(file->Fs, file->FileCtx, out); if (KSUCCESS(s)) { @@ -1229,16 +1229,16 @@ __declspec(dllexport) KSTATUS IoGetFileStat(FILE_OBJECT* file, SYS_FILE_STAT* ou // Queries metadata for a filesystem path. __declspec(dllexport) KSTATUS IoStatFile(SYS_STRING_VIEW path, SYS_FILE_STAT* out) { - if ((!path.Data && path.Length) || path.Length == 0 || !out) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; + if ((!path.Data && path.Length) || path.Length == 0 || !out) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; KRESOLVED_PATH resolved; KSTATUS s = KiResolvePathV(path, &resolved); if (!KSUCCESS(s)) return s; IO_FILESYSTEM* fs = gVolumes[resolved.Drive].Fs; - if (!fs) return STATUS_NOT_FOUND; - if (!fs->Stat) return STATUS_NOT_SUPPORTED; + if (!fs) return NTLSTATUS_NOT_FOUND; + if (!fs->Stat) return NTLSTATUS_NOT_SUPPORTED; memset(out, 0, sizeof(*out)); out->Size = sizeof(*out); @@ -1248,10 +1248,10 @@ __declspec(dllexport) KSTATUS IoStatFile(SYS_STRING_VIEW path, SYS_FILE_STAT* ou // Queries the filesystem identity for a file object. __declspec(dllexport) KSTATUS IoQueryFileIdentity(FILE_OBJECT* file, IO_FILE_IDENTITY* out) { if (!file || !out) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; memset(out, 0, sizeof(*out)); if (!file->Fs || !file->Fs->QueryIdentity) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; return file->Fs->QueryIdentity(file->Fs, file->FileCtx, out); } @@ -1259,10 +1259,10 @@ __declspec(dllexport) KSTATUS IoQueryFileIdentity(FILE_OBJECT* file, IO_FILE_IDE __declspec(dllexport) KSTATUS IoLockFile(FILE_OBJECT* file, PROCESS* owner, uint32_t mode, uint64_t offset, uint64_t length, uint64_t timeoutMilliseconds) { - if (!file || !owner) return STATUS_INVALID_PARAMETER; - if (mode != SYS_FILE_LOCK_SHARED && mode != SYS_FILE_LOCK_EXCLUSIVE) return STATUS_INVALID_PARAMETER; - if (length == 0) return STATUS_INVALID_PARAMETER; - if (timeoutMilliseconds != 0 && !KeCanWait()) return STATUS_INVALID_IRQL; + if (!file || !owner) return NTLSTATUS_INVALID_PARAMETER; + if (mode != SYS_FILE_LOCK_SHARED && mode != SYS_FILE_LOCK_EXCLUSIVE) return NTLSTATUS_INVALID_PARAMETER; + if (length == 0) return NTLSTATUS_INVALID_PARAMETER; + if (timeoutMilliseconds != 0 && !KeCanWait()) return NTLSTATUS_INVALID_IRQL; IO_FILE_IDENTITY identity; KSTATUS s = IoQueryFileIdentity(file, &identity); @@ -1282,7 +1282,7 @@ __declspec(dllexport) KSTATUS IoLockFile(FILE_OBJECT* file, PROCESS* owner, uint IO_FILE_LOCK_ENTRY* entry = (IO_FILE_LOCK_ENTRY*)MmAllocatePoolTag(sizeof(*entry), MM_POOL_TAG('f', 'l', 'c', 'k')); if (!entry) { if (waitEvent) ObDereferenceObject(&waitEvent->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } uintptr_t flags = KeAcquireSpinlock(&gFileLockLock); @@ -1296,14 +1296,14 @@ __declspec(dllexport) KSTATUS IoLockFile(FILE_OBJECT* file, PROCESS* owner, uint ListInsertTail(&gFileLocks, &entry->Link); KeReleaseSpinlock(&gFileLockLock, flags); if (waitEvent) ObDereferenceObject(&waitEvent->Header); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KeReleaseSpinlock(&gFileLockLock, flags); MmFreePool(entry); if (timeoutMilliseconds == 0) { if (waitEvent) ObDereferenceObject(&waitEvent->Header); - return STATUS_WOULD_BLOCK; + return NTLSTATUS_WOULD_BLOCK; } if (!waitEvent) { @@ -1347,7 +1347,7 @@ __declspec(dllexport) KSTATUS IoLockFile(FILE_OBJECT* file, PROCESS* owner, uint // Releases this process's overlapping advisory locks for one file identity. __declspec(dllexport) KSTATUS IoUnlockFile(FILE_OBJECT* file, PROCESS* owner, uint64_t offset, uint64_t length) { - if (!file || !owner || length == 0) return STATUS_INVALID_PARAMETER; + if (!file || !owner || length == 0) return NTLSTATUS_INVALID_PARAMETER; IO_FILE_IDENTITY identity; KSTATUS s = IoQueryFileIdentity(file, &identity); @@ -1375,7 +1375,7 @@ __declspec(dllexport) KSTATUS IoUnlockFile(FILE_OBJECT* file, PROCESS* owner, ui KiIoSignalFileLockWaitersLocked(&identity); KeReleaseSpinlock(&gFileLockLock, flags); - return released ? STATUS_SUCCESS : STATUS_NOT_FOUND; + return released ? NTLSTATUS_SUCCESS : NTLSTATUS_NOT_FOUND; } // Releases every advisory file lock owned by one exiting process. @@ -1424,22 +1424,22 @@ static void KiDirDestroy(OBJECT* obj) { // Opens dir. __declspec(dllexport) KSTATUS IoOpenDir(SYS_STRING_VIEW dirPath, DIR_OBJECT** out) { - if (!out) return STATUS_INVALID_PARAMETER; - if (dirPath.Length && !dirPath.Data) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; + if (!out) return NTLSTATUS_INVALID_PARAMETER; + if (dirPath.Length && !dirPath.Data) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; KRESOLVED_PATH resolved; KSTATUS s; if (dirPath.Length == 0) { PROCESS* proc = KeGetCurrentProcess(); - if (!proc) return STATUS_ACCESS_DENIED; + if (!proc) return NTLSTATUS_ACCESS_DENIED; uintptr_t flags = KeAcquireSpinlock(&proc->CwdLock); size_t cwdLen = proc->CurrentDirectoryLength; if (cwdLen + 1 > sizeof(resolved.Storage)) { KeReleaseSpinlock(&proc->CwdLock, flags); - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; } memcpy(resolved.Storage, proc->CurrentDirectory, cwdLen + 1); resolved.Drive = proc->CurrentDrive; @@ -1451,29 +1451,29 @@ __declspec(dllexport) KSTATUS IoOpenDir(SYS_STRING_VIEW dirPath, DIR_OBJECT** ou } IO_FILESYSTEM* fs = gVolumes[resolved.Drive].Fs; - if (!fs) return STATUS_NOT_FOUND; - if (!fs->OpenDir) return STATUS_NOT_SUPPORTED; + if (!fs) return NTLSTATUS_NOT_FOUND; + if (!fs->OpenDir) return NTLSTATUS_NOT_SUPPORTED; void* dirCtx = NULL; s = fs->OpenDir(fs, resolved.Path, &dirCtx); if (!KSUCCESS(s)) return s; DIR_OBJECT* d = (DIR_OBJECT*)ObAllocateObject(ObjectTypeDir, sizeof(DIR_OBJECT)); - if (!d) { fs->CloseDir(fs, dirCtx); return STATUS_NO_MEMORY; } + if (!d) { fs->CloseDir(fs, dirCtx); return NTLSTATUS_NO_MEMORY; } d->Header.Destroy = KiDirDestroy; d->Fs = fs; d->DirCtx = dirCtx; *out = d; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns dir. __declspec(dllexport) KSTATUS IoReadDir(DIR_OBJECT* dir, KDIR_ENTRY* entryOut) { - if (!dir || !entryOut) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; - if (!dir->Fs->ReadDir) return STATUS_NOT_SUPPORTED; + if (!dir || !entryOut) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; + if (!dir->Fs->ReadDir) return NTLSTATUS_NOT_SUPPORTED; return dir->Fs->ReadDir(dir->Fs, dir->DirCtx, entryOut); } diff --git a/code/kernel/ke_apc.c b/code/kernel/ke_apc.c index 4387247..9c561f8 100644 --- a/code/kernel/ke_apc.c +++ b/code/kernel/ke_apc.c @@ -38,12 +38,12 @@ static bool KiUserRflagsValid(uint64_t rflags) { static KSTATUS KiValidateUserApcResumeState(uint64_t rip, uint64_t rsp, uint64_t rflags, uint64_t cs, uint64_t ss) { if (!KiUserAddressValid(rip) || !KiUserAddressValid(rsp)) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; if (cs != KI_USER_CS || ss != KI_USER_SS) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; if (!KiUserRflagsValid(rflags)) - return STATUS_ACCESS_DENIED; - return STATUS_SUCCESS; + return NTLSTATUS_ACCESS_DENIED; + return NTLSTATUS_SUCCESS; } // Allocates a nonzero token for one active user APC return frame. @@ -128,7 +128,7 @@ __declspec(dllexport) bool KeInsertQueueApc(KAPC* apc, // If the target opted into an alertable wait, make the APC itself the // wait completion. The target thread will deliver the APC before - // KeWaitForEvent(..., true) returns STATUS_KERNEL_APC. + // KeWaitForEvent(..., true) returns NTLSTATUS_KERNEL_APC. if (wakeAlertable) KiWakeThreadForKernelApc(thread); @@ -238,15 +238,15 @@ void KiDeliverKernelApcs(void) { // Updates user Apc Dispatcher. __declspec(dllexport) KSTATUS KeSetUserApcDispatcher(void* dispatcher) { THREAD* thread = KeGetCurrentThread(); - if (!thread) return STATUS_FAILURE; - if (!dispatcher) return STATUS_INVALID_PARAMETER; - if (!KiUserAddressValid((uint64_t)(uintptr_t)dispatcher)) return STATUS_ACCESS_DENIED; + if (!thread) return NTLSTATUS_FAILURE; + if (!dispatcher) return NTLSTATUS_INVALID_PARAMETER; + if (!KiUserAddressValid((uint64_t)(uintptr_t)dispatcher)) return NTLSTATUS_ACCESS_DENIED; KSTATUS s = MmProbeUserRead(dispatcher, 1); if (!KSUCCESS(s)) return s; thread->UserApcDispatcher = (uintptr_t)dispatcher; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } __declspec(dllexport) KSTATUS KeQueueUserApc(THREAD* thread, @@ -255,15 +255,15 @@ __declspec(dllexport) KSTATUS KeQueueUserApc(THREAD* thread, void* systemArgument1, void* systemArgument2) { if (!thread || !routine) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!KiUserAddressValid((uint64_t)(uintptr_t)routine)) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; if (thread->State == ThreadDead) - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; KUSER_APC* apc = (KUSER_APC*)MmAllocatePoolTag(sizeof(KUSER_APC), MM_POOL_TAG('a', 'p', 'c', ' ')); if (!apc) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; memset(apc, 0, sizeof(*apc)); LIST_INIT(&apc->Link); @@ -283,7 +283,7 @@ __declspec(dllexport) KSTATUS KeQueueUserApc(THREAD* thread, if (wakeAlertable) KiWakeThreadForUserApc(thread); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the pop User Apc operation. @@ -359,11 +359,11 @@ void KiCheckForUserApcDelivery(KTRAP_FRAME* frame) { thread->UserApcSavedRip = frame->Rip; thread->UserApcSavedRsp = frame->Rsp; thread->UserApcSavedRflags = frame->Rflags; - thread->UserApcSavedRax = STATUS_USER_APC; + thread->UserApcSavedRax = NTLSTATUS_USER_APC; frame->Rip = thread->UserApcDispatcher; frame->Rsp = newRsp; - frame->Rax = STATUS_USER_APC; + frame->Rax = NTLSTATUS_USER_APC; thread->UserApcDeliverable = 0; thread->UserApcDeliveryActive = 1; @@ -416,10 +416,10 @@ void KiRundownApcState(THREAD* thread) { __declspec(dllexport) uint64_t KeUserApcReturn(const SYS_USER_APC_FRAME_K* userFrame) { THREAD* thread = KeGetCurrentThread(); if (!thread) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; if (!thread->UserApcDeliveryActive || !userFrame) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; SYS_USER_APC_FRAME_K frameCopy; KSTATUS s = CopyFromUser(&frameCopy, userFrame, sizeof(frameCopy)); @@ -434,12 +434,12 @@ __declspec(dllexport) uint64_t KeUserApcReturn(const SYS_USER_APC_FRAME_K* userF (uint64_t)thread->UserApcFrameUserAddress, frameCopy.ReturnToken, thread->UserApcReturnToken); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } KTRAP_FRAME* frame = KeGetCurrentTrapFrame(); if (!frame || !KeTrapFrameFromUser(frame) || frame->Kind != KTRAP_KIND_SYSCALL) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; s = KiValidateUserApcResumeState(thread->UserApcSavedRip, thread->UserApcSavedRsp, diff --git a/code/kernel/ke_debug.c b/code/kernel/ke_debug.c index 88f98a1..40a0b86 100644 --- a/code/kernel/ke_debug.c +++ b/code/kernel/ke_debug.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -220,12 +221,12 @@ __declspec(dllexport) void DbgPrint(const char* fmt, ...) { // Flushes debug Log To File. __declspec(dllexport) KSTATUS KeFlushDebugLogToFile(SYS_STRING_VIEW path) { if (!gDebugLogBuffer || gDebugLogSize == 0 || !SysSvIsValid(path) || path.Length == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!KeCanWait()) - return STATUS_INVALID_IRQL; + return NTLSTATUS_INVALID_IRQL; if (_InterlockedCompareExchange((volatile long*)&gDebugLogFlushing, 1, 0) != 0) - return STATUS_PENDING; + return NTLSTATUS_PENDING; size_t used; size_t start; @@ -236,7 +237,7 @@ __declspec(dllexport) KSTATUS KeFlushDebugLogToFile(SYS_STRING_VIEW path) { if (used == 0) { _InterlockedExchange((volatile long*)&gDebugLogFlushing, 0); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } (void)IoDeleteFile(path); @@ -264,7 +265,7 @@ __declspec(dllexport) KSTATUS KeFlushDebugLogToFile(SYS_STRING_VIEW path) { IoCloseFile(file); _InterlockedExchange((volatile long*)&gDebugLogFlushing, 0); - return (KSUCCESS(st) && totalWritten == used) ? STATUS_SUCCESS : st; + return (KSUCCESS(st) && totalWritten == used) ? NTLSTATUS_SUCCESS : st; } // Attempts to persist the debug log during a panic when the filesystem is usable. @@ -348,73 +349,6 @@ static void KiFaultPrintf(const char* format, ...) { va_end(args); } -// KeBugCheckProcess - user-mode fault handler - -// Resolves the faulting RIP to a module name, prints a yellow crash banner, -// kills the offending process, then exits the current thread so the scheduler -// can continue running everything else. - -// Return the short exception name for a CPU exception vector. -// Keep this table complete for vectors 0..31 so faults never collapse into -// a vague "general protection" bucket just because the IDT entry existed -// first or the crash printer lacked a name. -static const char* KiFaultVectorName(int vector) { - switch (vector) { - case 0: return "#DE Divide Error"; - case 1: return "#DB Debug"; - case 2: return "NMI Interrupt"; - case 3: return "#BP Breakpoint"; - case 4: return "#OF Overflow"; - case 5: return "#BR Bound Range Exceeded"; - case 6: return "#UD Invalid Opcode"; - case 7: return "#NM Device Not Available"; - case 8: return "#DF Double Fault"; - case 9: return "Coprocessor Segment Overrun"; - case 10: return "#TS Invalid TSS"; - case 11: return "#NP Segment Not Present"; - case 12: return "#SS Stack-Segment Fault"; - case 13: return "#GP General Protection"; - case 14: return "#PF Page Fault"; - case 15: return "Reserved Exception 15"; - case 16: return "#MF x87 Floating-Point Exception"; - case 17: return "#AC Alignment Check"; - case 18: return "#MC Machine Check"; - case 19: return "#XM SIMD Floating-Point Exception"; - case 20: return "#VE Virtualization Exception"; - case 21: return "#CP Control Protection Exception"; - case 22: return "Reserved Exception 22"; - case 23: return "Reserved Exception 23"; - case 24: return "Reserved Exception 24"; - case 25: return "Reserved Exception 25"; - case 26: return "Reserved Exception 26"; - case 27: return "Reserved Exception 27"; - case 28: return "#HV Hypervisor Injection Exception"; - case 29: return "#VC VMM Communication Exception"; - case 30: return "#SX Security Exception"; - case 31: return "Reserved Exception 31"; - default: return "Unknown Exception"; - } -} - -// Implements the fault Has Error Code operation. -static int KiFaultHasErrorCode(int vector) { - switch (vector) { - case 8: // #DF - case 10: // #TS - case 11: // #NP - case 12: // #SS - case 13: // #GP - case 14: // #PF - case 17: // #AC - case 21: // #CP - case 29: // #VC - case 30: // #SX - return 1; - default: - return 0; - } -} - // Walk the process module list to find which image owns an address. // Returns the module name string, or "unknown" if the address is outside all // known image ranges. Base/size are optional and are useful for offset dumps. @@ -703,21 +637,9 @@ static void KiDumpFaultFrame(PROCESS* proc, const KFAULT_FRAME* f) { KiDumpUserStack(proc, (uintptr_t)f->Rsp); } -static KSTATUS KiFaultExitStatus(int vector) { - switch (vector) { - case 0: return STATUS_PROCESS_DIVIDE_BY_ZERO; - case 3: return STATUS_PROCESS_BREAKPOINT; - case 6: return STATUS_PROCESS_ILLEGAL_OPCODE; - case 13: return STATUS_PROCESS_GENERAL_PROTECTION; - case 14: return STATUS_PROCESS_PAGE_FAULT; - case 17: return STATUS_PROCESS_ALIGNMENT_FAULT; - default: return STATUS_PROCESS_UNKNOWN_FAULT; - } -} - static void KiPrintCrashHeader(PROCESS* proc, int vector, uintptr_t rip, uintptr_t errCode, uintptr_t cr2) { - const char* faultName = KiFaultVectorName(vector); + const char* faultName = KeExceptionVectorName((uint32_t)vector); const char* procName = proc ? proc->Name : "unknown"; uint32_t pid = proc ? proc->ProcessId : 0; const char* modName = proc ? KiResolveModule(proc, rip) : "unknown"; @@ -768,11 +690,79 @@ _Noreturn void KeBugCheckProcess(int vector, uintptr_t rip, uintptr_t errCode, u KiPrintCrashHeader(proc, vector, rip, errCode, cr2); KiDumpModules(proc); - KiFinishFaultedProcess(proc, thread, KiFaultExitStatus(vector)); + KiFinishFaultedProcess(proc, thread, KeExceptionProcessExitStatus((uint32_t)vector)); } -// Dispatches a CPU fault frame and returns only when a user #PF was repaired. -__declspec(dllexport) KSTATUS KeFaultDispatchFrame(const KFAULT_FRAME* frame) { +// Panics after printing a kernel-mode CPU exception report. +static _Noreturn void KiPanicKernelFault(PROCESS* proc, THREAD* thread, const KFAULT_FRAME* frame) { + KiBeginFatalReport(); + + int vector = (int)frame->Vector; + const char* name = KeExceptionVectorName((uint32_t)vector); + + DbgPrint("FAULT: kernel exception vector=%d name=%s rip=%016llx rsp=%016llx err=%04llx cr2=%016llx thread=0x%016llX pid=%u proc=%s\n", + vector, + name, + (unsigned long long)frame->Rip, + (unsigned long long)frame->Rsp, + (unsigned long long)frame->ErrorCode, + (unsigned long long)frame->Cr2, + thread, + proc ? proc->ProcessId : 0, + proc ? proc->Name : ""); + KiDumpFaultFrame(proc, frame); + if (vector == 14) { + MmDebugDescribeAddress((uintptr_t)frame->Cr2); + if (frame->Rip) MmDebugDescribeAddress((uintptr_t)frame->Rip); + if (frame->Rsp) MmDebugDescribeAddress((uintptr_t)frame->Rsp); + MmVadDebugDumpProcess(proc); + } + + if (vector == 14) { + KePanic(KE_PANIC_CODE_FAULT, "PANIC: %s | RIP: %016llx | RSP: %016llx | Code: %04llx | CR2: %016llx\n", + name, + (unsigned long long)frame->Rip, + (unsigned long long)frame->Rsp, + (unsigned long long)frame->ErrorCode, + (unsigned long long)frame->Cr2); + } else if (KeExceptionVectorHasErrorCode((uint32_t)vector)) { + const uint8_t* ip = (const uint8_t*)(uintptr_t)frame->Rip; + KePanic(KE_PANIC_CODE_FAULT, + "PANIC: %s | RIP: %016llx | Code: %04llx | CS=%04llx RFLAGS=%016llx RSP=%016llx | bytes=%02x %02x %02x %02x %02x %02x %02x %02x\n", + name, + (unsigned long long)frame->Rip, + (unsigned long long)frame->ErrorCode, + (unsigned long long)frame->Cs, + (unsigned long long)frame->Rflags, + (unsigned long long)frame->Rsp, + ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7]); + } else { + const uint8_t* ip = (const uint8_t*)(uintptr_t)frame->Rip; + KePanic(KE_PANIC_CODE_FAULT, + "PANIC: %s | RIP: %016llx | CS=%04llx RFLAGS=%016llx RSP=%016llx | bytes=%02x %02x %02x %02x %02x %02x %02x %02x\n", + name, + (unsigned long long)frame->Rip, + (unsigned long long)frame->Cs, + (unsigned long long)frame->Rflags, + (unsigned long long)frame->Rsp, + ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7]); + } +} + +// Terminates the current process after printing an unhandled user exception report. +static _Noreturn void KiTerminateUserFault(PROCESS* proc, THREAD* thread, const KFAULT_FRAME* frame) { + KiPrintCrashHeader(proc, (int)frame->Vector, + (uintptr_t)frame->Rip, + (uintptr_t)frame->ErrorCode, + (uintptr_t)frame->Cr2); + KiDumpFaultFrame(proc, frame); + KiDumpModules(proc); + + KiFinishFaultedProcess(proc, thread, KeExceptionProcessExitStatus((uint32_t)frame->Vector)); +} + +// Dispatches a CPU fault frame and returns only when a page fault was repaired. +__declspec(dllexport) KSTATUS KeFaultDispatchFrame(KFAULT_FRAME* frame) { // Panic NMIs are broadcast to stop all other CPUs. Do not try to decode // the interrupted context on a secondary CPU once another CPU owns panic. if (KiPanicIsActive()) @@ -781,93 +771,42 @@ __declspec(dllexport) KSTATUS KeFaultDispatchFrame(const KFAULT_FRAME* frame) { THREAD* thread = KeGetCurrentThread(); PROCESS* proc = thread ? thread->Owner : (PROCESS*)0; - if (!frame || frame->Magic != 0x3146544C5541464BULL) { + if (!KeFaultFrameIsValid(frame)) { KePanic(KE_PANIC_CODE_FAULT, "PANIC: bad KFAULT_FRAME %016llx\n", (unsigned long long)(uintptr_t)frame); } - if (frame->Vector == 14) { - KSTATUS handled = MmVadResolvePageFaultByAddress((uintptr_t)frame->Cr2, frame->ErrorCode); - if (KSUCCESS(handled)) - return STATUS_SUCCESS; - } + KSTATUS repaired = KeExceptionResolveRecoverableFault(frame); + if (KSUCCESS(repaired)) + return NTLSTATUS_SUCCESS; - if ((frame->Cs & 3) == 0) { - KiBeginFatalReport(); + if (!KeFaultFrameFromUser(frame)) + KiPanicKernelFault(proc, thread, frame); - int vector = (int)frame->Vector; - const char* name = KiFaultVectorName(vector); + KSTATUS delivered = KeDeliverUserException(frame); + if (KSUCCESS(delivered)) + return NTLSTATUS_SUCCESS; - DbgPrint("FAULT: kernel exception vector=%d name=%s rip=%016llx rsp=%016llx err=%04llx cr2=%016llx thread=%p pid=%u proc=%s\n", - vector, - name, + if (delivered != NTLSTATUS_NOT_FOUND) + DbgPrint("USER/EXC: delivery failed vector=%llu rip=%016llx rsp=%016llx status=%u\n", + frame->Vector, (unsigned long long)frame->Rip, (unsigned long long)frame->Rsp, - (unsigned long long)frame->ErrorCode, - (unsigned long long)frame->Cr2, - thread, - proc ? proc->ProcessId : 0, - proc ? proc->Name : ""); - KiDumpFaultFrame(proc, frame); - if (vector == 14) { - MmDebugDescribeAddress((uintptr_t)frame->Cr2); - if (frame->Rip) MmDebugDescribeAddress((uintptr_t)frame->Rip); - if (frame->Rsp) MmDebugDescribeAddress((uintptr_t)frame->Rsp); - MmVadDebugDumpProcess(proc); - } + delivered); - if (vector == 14) { - KePanic(KE_PANIC_CODE_FAULT, "PANIC: %s | RIP: %016llx | RSP: %016llx | Code: %04llx | CR2: %016llx\n", - name, - (unsigned long long)frame->Rip, - (unsigned long long)frame->Rsp, - (unsigned long long)frame->ErrorCode, - (unsigned long long)frame->Cr2); - } else if (KiFaultHasErrorCode(vector)) { - const uint8_t* ip = (const uint8_t*)(uintptr_t)frame->Rip; - KePanic(KE_PANIC_CODE_FAULT, - "PANIC: %s | RIP: %016llx | Code: %04llx | CS=%04llx RFLAGS=%016llx RSP=%016llx | bytes=%02x %02x %02x %02x %02x %02x %02x %02x\n", - name, - (unsigned long long)frame->Rip, - (unsigned long long)frame->ErrorCode, - (unsigned long long)frame->Cs, - (unsigned long long)frame->Rflags, - (unsigned long long)frame->Rsp, - ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7]); - } else { - const uint8_t* ip = (const uint8_t*)(uintptr_t)frame->Rip; - KePanic(KE_PANIC_CODE_FAULT, - "PANIC: %s | RIP: %016llx | CS=%04llx RFLAGS=%016llx RSP=%016llx | bytes=%02x %02x %02x %02x %02x %02x %02x %02x\n", - name, - (unsigned long long)frame->Rip, - (unsigned long long)frame->Cs, - (unsigned long long)frame->Rflags, - (unsigned long long)frame->Rsp, - ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7]); - } - } - - KiPrintCrashHeader(proc, (int)frame->Vector, - (uintptr_t)frame->Rip, - (uintptr_t)frame->ErrorCode, - (uintptr_t)frame->Cr2); - KiDumpFaultFrame(proc, frame); - KiDumpModules(proc); - - KiFinishFaultedProcess(proc, thread, KiFaultExitStatus((int)frame->Vector)); + KiTerminateUserFault(proc, thread, frame); } // KeFaultDispatch - single C entry point for all three IDT fault stubs. -// The asm stubs (ke_syscall.asm) collect the CPU exception frame values and -// call here. We check the CS RPL to decide: kernel fault → panic and halt, -// user fault → KeBugCheckProcess (kill process, resume scheduler). +// The asm stubs collect the CPU exception frame values and call here. +// KeFaultDispatchFrame owns the mode split and default unhandled policy. __declspec(dllexport) _Noreturn void KeFaultDispatch(int vector, uintptr_t rip, uintptr_t errCode, uintptr_t cr2, uintptr_t cs) { KFAULT_FRAME frame; memset(&frame, 0, sizeof(frame)); - frame.Magic = 0x3146544C5541464BULL; + frame.Magic = KFAULT_FRAME_MAGIC_VALUE; frame.Vector = (uint64_t)vector; frame.ErrorCode = errCode; frame.Cr2 = cr2; diff --git a/code/kernel/ke_display.c b/code/kernel/ke_display.c index 931b74b..f4693d8 100644 --- a/code/kernel/ke_display.c +++ b/code/kernel/ke_display.c @@ -138,10 +138,10 @@ static KSTATUS KiDisplayAcquireProviderMutex(bool* acquired) { *acquired = false; if (!gDisplayProviderMutex || !KiDisplayProviderCallbacksRequirePassive()) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (!KeCanWait()) - return STATUS_INVALID_IRQL; + return NTLSTATUS_INVALID_IRQL; if (KeGetDebugFlags() & KE_DEBUG_DISPLAY_ASSERTS) KeAssertIrql(PASSIVE_LEVEL); @@ -163,9 +163,9 @@ static KSTATUS KiDisplayFallbackPrintChar(char c, uint32_t fg, uint32_t bg) { const HAL_API* hal = gDisplayHal; if (hal && hal->Screen.PrintChar) { hal->Screen.PrintChar(c, fg, bg); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } - return STATUS_INVALID_IRQL; + return NTLSTATUS_INVALID_IRQL; } static void KiDisplayQueueCursorWork(void) { @@ -259,7 +259,7 @@ static void KiDisplayCursorWorker(void* context) { bool positionCommitted = false; int newCommittedX = committedX; int newCommittedY = committedY; - KSTATUS status = STATUS_SUCCESS; + KSTATUS status = NTLSTATUS_SUCCESS; bool hasCursorOps = device && ops && ops->ShowCursor && (caps & (DISPLAY_CAP_SOFTWARE_CURSOR | DISPLAY_CAP_HARDWARE_CURSOR)); bool softwareCursor = hasCursorOps && (caps & DISPLAY_CAP_SOFTWARE_CURSOR) != 0; @@ -446,7 +446,7 @@ static void KiDisplayRecordCopyLocked(const DISPLAY_MODE* mode, int dstX, int ds static KSTATUS KiDisplayFlushDirtyWithSnapshot(DISPLAY_DEVICE* device, const DISPLAY_DEVICE_OPS* ops) { if (!device || !ops || !ops->Present) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; DISPLAY_RECT localRects[DISPLAY_MAX_DIRTY_RECTS]; DISPLAY_RECT fullRect; @@ -457,7 +457,7 @@ static KSTATUS KiDisplayFlushDirtyWithSnapshot(DISPLAY_DEVICE* device, const DIS uintptr_t flags = KeAcquireSpinlock(&gDisplayLock); if (device != gPrimaryDisplay || (!gDirtyAll && gDirtyRectCount == 0)) { KeReleaseSpinlock(&gDisplayLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } dirtyAll = gDirtyAll; @@ -473,7 +473,7 @@ static KSTATUS KiDisplayFlushDirtyWithSnapshot(DISPLAY_DEVICE* device, const DIS if (dirtyAll) { DISPLAY_MODE mode; if (!ops->GetMode) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; KSTATUS ms = ops->GetMode(device, &mode); if (!KSUCCESS(ms)) return ms; @@ -578,9 +578,9 @@ static KSTATUS KiDisplayGetProviderSnapshot(DISPLAY_DEVICE** outDevice, uint32_t caps = 0; if (!KiDisplaySnapshotPrimary(&device, &ops, &caps, 0) || !device || !ops) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (!ops->GetMode) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; KSTATUS s = ops->GetMode(device, outMode); if (!KSUCCESS(s)) @@ -589,7 +589,7 @@ static KSTATUS KiDisplayGetProviderSnapshot(DISPLAY_DEVICE** outDevice, if (outDevice) *outDevice = device; if (outOps) *outOps = ops; if (outCaps) *outCaps = caps; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static void KiDisplayBuildGlyphPixels(char c, uint32_t fg, uint32_t bg, uint32_t* outPixels) { @@ -610,7 +610,7 @@ static KSTATUS KiDisplayBlitGlyphSnapshot(DISPLAY_DEVICE* device, uint32_t fg, uint32_t bg) { if (!device || !ops || !ops->Blit || !mode) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; uint32_t glyphPixels[FONT_W * FONT_H]; KiDisplayBuildGlyphPixels(c, fg, bg, glyphPixels); @@ -633,9 +633,9 @@ static KSTATUS KiDisplayDrawBlitSnapshot(DISPLAY_DEVICE* device, int h, const uint32_t* pixels) { if (!pixels || w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!device || !ops || !ops->Blit || !mode) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; KSTATUS s = ops->Blit(device, x, y, w, h, pixels); if (KSUCCESS(s)) { @@ -656,9 +656,9 @@ static KSTATUS KiDisplayFillRectSnapshot(DISPLAY_DEVICE* device, int h, uint32_t color) { if (w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!device || !ops || !ops->FillRect || !mode) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; KSTATUS s = ops->FillRect(device, x, y, w, h, color); if (KSUCCESS(s)) { @@ -680,9 +680,9 @@ static KSTATUS KiDisplayCopyRectSnapshot(DISPLAY_DEVICE* device, int w, int h) { if (w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!device || !ops || !ops->CopyRect || !mode) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; KSTATUS s = ops->CopyRect(device, dstX, dstY, srcX, srcY, w, h); if (KSUCCESS(s)) { @@ -698,7 +698,7 @@ static KSTATUS KiDisplayFinishProviderDraw(DISPLAY_DEVICE* device, const DISPLAY_DEVICE_OPS* ops, uint32_t caps, KSTATUS drawStatus) { - KSTATUS presentStatus = STATUS_SUCCESS; + KSTATUS presentStatus = NTLSTATUS_SUCCESS; if (KSUCCESS(drawStatus)) presentStatus = KiDisplayFlushDirtyWithSnapshot(device, ops); KiDisplayRestoreCursorAfterDrawSnapshot(device, ops, caps); @@ -743,9 +743,9 @@ static void KiDisplayAddDirty(int x, int y, int w, int h) { // Implements the display Flush Dirty operation. static KSTATUS KiDisplayFlushDirty(void) { if (!KiDisplayHasDevice() || !gPrimaryDisplay->Ops->Present) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (!gDirtyAll && gDirtyRectCount == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; DISPLAY_RECT full; const DISPLAY_RECT* rects = gDirtyRects; @@ -803,7 +803,7 @@ static void KiDisplayBeginDraw(void) { // Implements the display End Draw operation. static KSTATUS KiDisplayEndDraw(void) { - KSTATUS s = STATUS_SUCCESS; + KSTATUS s = NTLSTATUS_SUCCESS; if (gDrawDepth > 0) gDrawDepth--; @@ -817,9 +817,9 @@ static KSTATUS KiDisplayEndDraw(void) { // Implements the display Draw Blit No Cursor operation. static KSTATUS KiDisplayDrawBlitNoCursor(int x, int y, int w, int h, const uint32_t* pixels) { if (!pixels || w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!KiDisplayHasDevice() || !gPrimaryDisplay->Ops->Blit) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; KSTATUS s = gPrimaryDisplay->Ops->Blit(gPrimaryDisplay, x, y, w, h, pixels); if (KSUCCESS(s)) { @@ -833,9 +833,9 @@ static KSTATUS KiDisplayDrawBlitNoCursor(int x, int y, int w, int h, const uint3 // Implements the display Fill Rect No Cursor operation. static KSTATUS KiDisplayFillRectNoCursor(int x, int y, int w, int h, uint32_t color) { if (w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!KiDisplayHasDevice() || !gPrimaryDisplay->Ops->FillRect) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; KSTATUS s = gPrimaryDisplay->Ops->FillRect(gPrimaryDisplay, x, y, w, h, color); if (KSUCCESS(s)) { @@ -849,9 +849,9 @@ static KSTATUS KiDisplayFillRectNoCursor(int x, int y, int w, int h, uint32_t co // Implements the display Copy Rect No Cursor operation. static KSTATUS KiDisplayCopyRectNoCursor(int dstX, int dstY, int srcX, int srcY, int w, int h) { if (w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!KiDisplayHasDevice() || !gPrimaryDisplay->Ops->CopyRect) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; KSTATUS s = gPrimaryDisplay->Ops->CopyRect(gPrimaryDisplay, dstX, dstY, srcX, srcY, w, h); if (KSUCCESS(s)) { @@ -1180,13 +1180,13 @@ void KeDisplayInitialize(const HAL_API* hal) { DISPLAY_API KSTATUS KeDisplayRegisterDevice(DISPLAY_DEVICE* device) { if (!device || !device->Name || !device->Ops || !device->Ops->GetMode) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; - KSTATUS result = STATUS_SUCCESS; + KSTATUS result = NTLSTATUS_SUCCESS; uintptr_t flags = KeAcquireSpinlock(&gDisplayLock); for (DISPLAY_DEVICE* it = gDisplayList; it; it = it->Next) { if (it == device) { - result = STATUS_ALREADY_EXISTS; + result = NTLSTATUS_ALREADY_EXISTS; break; } } @@ -1205,10 +1205,10 @@ DISPLAY_API KSTATUS KeDisplayRegisterDevice(DISPLAY_DEVICE* device) { // Implements the display Seed New Primary operation. static KSTATUS KiDisplaySeedNewPrimary(DISPLAY_DEVICE* oldDevice, DISPLAY_DEVICE* newDevice) { if (!oldDevice || !newDevice || oldDevice == newDevice) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (!oldDevice->Ops || !oldDevice->Ops->ReadRect || !newDevice->Ops || !newDevice->Ops->GetMode || !newDevice->Ops->Blit) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; DISPLAY_MODE oldMode; DISPLAY_MODE newMode; @@ -1221,11 +1221,11 @@ static KSTATUS KiDisplaySeedNewPrimary(DISPLAY_DEVICE* oldDevice, DISPLAY_DEVICE if (oldMode.Format != DisplayPixelFormatX8R8G8B8 || newMode.Format != DisplayPixelFormatX8R8G8B8 || oldMode.Width != newMode.Width || oldMode.Height != newMode.Height) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; uint32_t* row = (uint32_t*)MmAllocatePool((size_t)newMode.Width * sizeof(uint32_t)); if (!row) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; for (uint32_t y = 0; y < newMode.Height; y++) { s = oldDevice->Ops->ReadRect(oldDevice, 0, (int)y, (int)newMode.Width, 1, row, newMode.Width); @@ -1251,7 +1251,7 @@ static bool KiDisplayOutputSuspended(void) { DISPLAY_API KSTATUS KeDisplaySetPrimary(DISPLAY_DEVICE* device) { if (!device || !device->Ops || !device->Ops->GetMode) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; const char* name = device->Name ? device->Name : "?"; @@ -1265,7 +1265,7 @@ DISPLAY_API KSTATUS KeDisplaySetPrimary(DISPLAY_DEVICE* device) { } if (!found) { KeReleaseSpinlock(&gDisplayLock, flags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } DISPLAY_DEVICE* oldDevice = gPrimaryDisplay; @@ -1342,7 +1342,7 @@ DISPLAY_API KSTATUS KeDisplaySetPrimary(DISPLAY_DEVICE* device) { DISPLAY_API KSTATUS KeDisplayGetMode(DISPLAY_MODE* outMode) { if (!outMode) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; bool providerHeld = false; KSTATUS s = KiDisplayAcquireProviderMutex(&providerHeld); @@ -1355,7 +1355,7 @@ DISPLAY_API KSTATUS KeDisplayGetMode(DISPLAY_MODE* outMode) { KeReleaseSpinlock(&gDisplayLock, flags); s = (!device || !ops || !ops->GetMode) - ? STATUS_INVALID_PARAMETER + ? NTLSTATUS_INVALID_PARAMETER : ops->GetMode(device, outMode); KiDisplayReleaseProviderMutex(providerHeld); @@ -1369,7 +1369,7 @@ DISPLAY_API KSTATUS KeDisplayGetSize(int* outWidth, int* outHeight) { return s; if (outWidth) *outWidth = (int)mode.Width; if (outHeight) *outHeight = (int)mode.Height; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } DISPLAY_API KSTATUS KeDisplaySync(void) { @@ -1385,7 +1385,7 @@ DISPLAY_API KSTATUS KeDisplaySync(void) { if (!device || !ops || !ops->Sync) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } s = ops->Sync(device); @@ -1401,7 +1401,7 @@ DISPLAY_API KSTATUS KeDisplaySync(void) { DISPLAY_API KSTATUS KeDisplayQueryInfo(KE_DISPLAY_INFO* outInfo) { if (!outInfo) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; bool providerHeld = false; KSTATUS s = KiDisplayAcquireProviderMutex(&providerHeld); @@ -1435,7 +1435,7 @@ DISPLAY_API KSTATUS KeDisplayQueryInfo(KE_DISPLAY_INFO* outInfo) { if (!device || !ops) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } if (ops->GetMode) { @@ -1451,7 +1451,7 @@ DISPLAY_API KSTATUS KeDisplayQueryInfo(KE_DISPLAY_INFO* outInfo) { *outInfo = info; KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } DISPLAY_API KSTATUS KeDisplayBlit(int x, int y, int w, int h, const uint32_t* pixels) { @@ -1477,7 +1477,7 @@ DISPLAY_API KSTATUS KeDisplayBlit(int x, int y, int w, int h, const uint32_t* pi DISPLAY_API KSTATUS KeDisplayBlitRows(int x, int y, int w, int h, KE_DISPLAY_ROW_SOURCE source, void* context, uint32_t* scratch) { if (!source || !scratch || w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; bool providerHeld = false; KSTATUS s = KiDisplayAcquireProviderMutex(&providerHeld); @@ -1580,7 +1580,7 @@ DISPLAY_API KSTATUS KeDisplayCopyRect(int dstX, int dstY, int srcX, int srcY, in DISPLAY_API KSTATUS KeDisplayScroll(int lines) { if (lines <= 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; bool providerHeld = false; KSTATUS s = KiDisplayAcquireProviderMutex(&providerHeld); @@ -1646,7 +1646,7 @@ static KSTATUS KiDisplayPrintCharInternal(char c, uint32_t fg, uint32_t bg) { if (KiDisplayOutputSuspended()) { if (!KeCanWait()) return KiDisplayFallbackPrintChar(c, fg, bg); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Once the scheduler/work-queue era begins, display provider callbacks are @@ -1677,7 +1677,7 @@ static KSTATUS KiDisplayPrintCharInternal(char c, uint32_t fg, uint32_t bg) { int rows = 0; if (!KiDisplayConsoleGridFromMode(&mode, &cols, &rows)) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; } (void)KiDisplayHideCursorForDrawSnapshot(device, ops, caps); @@ -1726,7 +1726,7 @@ static KSTATUS KiDisplayPrintCharInternal(char c, uint32_t fg, uint32_t bg) { KeReleaseSpinlock(&gDisplayLock, flags); } } else { - s = STATUS_SUCCESS; + s = NTLSTATUS_SUCCESS; } if (KSUCCESS(s) && needScroll) { @@ -1760,7 +1760,7 @@ DISPLAY_API KSTATUS KeDisplayPrintChar(char c, uint32_t fg, uint32_t bg) { DISPLAY_API KSTATUS KeDisplayGetConsoleInfo(KE_CONSOLE_INFO* outInfo) { if (!outInfo) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; bool providerHeld = false; KSTATUS s = KiDisplayAcquireProviderMutex(&providerHeld); @@ -1775,14 +1775,14 @@ DISPLAY_API KSTATUS KeDisplayGetConsoleInfo(KE_CONSOLE_INFO* outInfo) { s = KiDisplayGetProviderSnapshot(&device, &ops, &caps, &mode); if (!KSUCCESS(s)) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } int cols = 0; int rows = 0; if (!KiDisplayConsoleGridFromMode(&mode, &cols, &rows)) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } uintptr_t flags = KeAcquireSpinlock(&gDisplayLock); @@ -1794,7 +1794,7 @@ DISPLAY_API KSTATUS KeDisplayGetConsoleInfo(KE_CONSOLE_INFO* outInfo) { KeReleaseSpinlock(&gDisplayLock, flags); KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } DISPLAY_API KSTATUS KeDisplaySetConsoleCursor(int col, int row) { @@ -1811,18 +1811,18 @@ DISPLAY_API KSTATUS KeDisplaySetConsoleCursor(int col, int row) { s = KiDisplayGetProviderSnapshot(&device, &ops, &caps, &mode); if (!KSUCCESS(s)) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } int cols = 0; int rows = 0; if (!KiDisplayConsoleGridFromMode(&mode, &cols, &rows)) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } if (col < 0 || row < 0 || col >= cols || row >= rows) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } uintptr_t flags = KeAcquireSpinlock(&gDisplayLock); @@ -1831,7 +1831,7 @@ DISPLAY_API KSTATUS KeDisplaySetConsoleCursor(int col, int row) { KeReleaseSpinlock(&gDisplayLock, flags); KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } DISPLAY_API KSTATUS KeDisplayFillConsoleChars(char c, int col, int row, size_t length, size_t* writtenOut) { @@ -1849,18 +1849,18 @@ DISPLAY_API KSTATUS KeDisplayFillConsoleChars(char c, int col, int row, size_t l s = KiDisplayGetProviderSnapshot(&device, &ops, &caps, &mode); if (!KSUCCESS(s)) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } int cols = 0; int rows = 0; if (!KiDisplayConsoleGridFromMode(&mode, &cols, &rows)) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } if (col < 0 || row < 0 || col >= cols || row >= rows) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } (void)KiDisplayHideCursorForDrawSnapshot(device, ops, caps); @@ -1918,18 +1918,18 @@ DISPLAY_API KSTATUS KeDisplayFillConsoleAttrs(uint16_t attr, int col, int row, s s = KiDisplayGetProviderSnapshot(&device, &ops, &caps, &mode); if (!KSUCCESS(s)) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } int cols = 0; int rows = 0; if (!KiDisplayConsoleGridFromMode(&mode, &cols, &rows)) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } if (col < 0 || row < 0 || col >= cols || row >= rows) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } (void)KiDisplayHideCursorForDrawSnapshot(device, ops, caps); @@ -1989,7 +1989,7 @@ DISPLAY_API KSTATUS KeDisplayPresent(const DISPLAY_RECT* rects, size_t rectCount } if (!ops->Present) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } (void)KiDisplayHideCursorForDrawSnapshot(device, ops, caps); @@ -2024,7 +2024,7 @@ DISPLAY_API KSTATUS KeDisplaySetCursorImage(int width, int height, int hotX, int if (!device || !ops || !ops->SetCursorImage) { KiDisplayReleaseProviderMutex(providerHeld); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } s = ops->SetCursorImage(device, width, height, hotX, hotY, argbPixels); @@ -2049,7 +2049,7 @@ DISPLAY_API KSTATUS KeDisplaySetCursorPosition(int x, int y) { if (shouldQueue) KiDisplayQueueCursorWork(); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } DISPLAY_API KSTATUS KeDisplayShowCursor(bool show) { @@ -2071,7 +2071,7 @@ DISPLAY_API KSTATUS KeDisplayShowCursor(bool show) { if (shouldQueue) KiDisplayQueueCursorWork(); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the boot Fb Context operation. @@ -2083,20 +2083,20 @@ static BOOTFB_CONTEXT* BootFbContext(DISPLAY_DEVICE* device) { static KSTATUS BootFbGetMode(DISPLAY_DEVICE* device, DISPLAY_MODE* outMode) { BOOTFB_CONTEXT* fb = BootFbContext(device); if (!fb || !fb->Framebuffer || !outMode) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; outMode->Width = fb->Width; outMode->Height = fb->Height; outMode->Stride = fb->Stride; outMode->Format = DisplayPixelFormatX8R8G8B8; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the boot Fb Blit operation. static KSTATUS BootFbBlit(DISPLAY_DEVICE* device, int x, int y, int w, int h, const uint32_t* pixels) { BOOTFB_CONTEXT* fb = BootFbContext(device); if (!fb || !fb->Framebuffer || !pixels || w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t* dstBase = fb->Backbuffer ? fb->Backbuffer : fb->Framebuffer; @@ -2105,7 +2105,7 @@ static KSTATUS BootFbBlit(DISPLAY_DEVICE* device, int x, int y, int w, int h, co int endX = x + w > (int)fb->Width ? (int)fb->Width : x + w; int endY = y + h > (int)fb->Height ? (int)fb->Height : y + h; if (startX >= endX || startY >= endY) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; int srcOffsetX = startX - x; int srcOffsetY = startY - y; @@ -2119,14 +2119,14 @@ static KSTATUS BootFbBlit(DISPLAY_DEVICE* device, int x, int y, int w, int h, co const uint32_t* src = pixels + ((size_t)(srcOffsetY + row) * (size_t)w) + srcOffsetX; memcpy(dst, src, bytesPerRow); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the boot Fb Fill Rect operation. static KSTATUS BootFbFillRect(DISPLAY_DEVICE* device, int x, int y, int w, int h, uint32_t color) { BOOTFB_CONTEXT* fb = BootFbContext(device); if (!fb || !fb->Framebuffer || w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t* dstBase = fb->Backbuffer ? fb->Backbuffer : fb->Framebuffer; @@ -2135,7 +2135,7 @@ static KSTATUS BootFbFillRect(DISPLAY_DEVICE* device, int x, int y, int w, int h int endX = x + w > (int)fb->Width ? (int)fb->Width : x + w; int endY = y + h > (int)fb->Height ? (int)fb->Height : y + h; if (startX >= endX || startY >= endY) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; fb->Stats.FillRectCount++; fb->Stats.BytesCopied += (uint64_t)(endX - startX) * (uint64_t)(endY - startY) * sizeof(uint32_t); @@ -2145,14 +2145,14 @@ static KSTATUS BootFbFillRect(DISPLAY_DEVICE* device, int x, int y, int w, int h for (int xx = startX; xx < endX; xx++) *dst++ = color; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the boot Fb Copy Rect operation. static KSTATUS BootFbCopyRect(DISPLAY_DEVICE* device, int dstX, int dstY, int srcX, int srcY, int w, int h) { BOOTFB_CONTEXT* fb = BootFbContext(device); if (!fb || !fb->Framebuffer || w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t* base = fb->Backbuffer ? fb->Backbuffer : fb->Framebuffer; @@ -2165,7 +2165,7 @@ static KSTATUS BootFbCopyRect(DISPLAY_DEVICE* device, int dstX, int dstY, int sr if (srcY + h > (int)fb->Height) h = (int)fb->Height - srcY; if (dstY + h > (int)fb->Height) h = (int)fb->Height - dstY; if (w <= 0 || h <= 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; fb->Stats.CopyRectCount++; fb->Stats.BytesCopied += (uint64_t)(uint32_t)w * (uint64_t)(uint32_t)h * sizeof(uint32_t); @@ -2184,20 +2184,20 @@ static KSTATUS BootFbCopyRect(DISPLAY_DEVICE* device, int dstX, int dstY, int sr memmove(dst, src, rowBytes); } } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the boot Fb Read Rect operation. static KSTATUS BootFbReadRect(DISPLAY_DEVICE* device, int x, int y, int w, int h, uint32_t* outPixels, uint32_t outStride) { BOOTFB_CONTEXT* fb = BootFbContext(device); if (!fb || !fb->Framebuffer || !outPixels || outStride == 0 || w <= 0 || h <= 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t* srcBase = fb->Backbuffer ? fb->Backbuffer : fb->Framebuffer; DISPLAY_MODE mode = { fb->Width, fb->Height, fb->Stride, DisplayPixelFormatX8R8G8B8 }; DISPLAY_RECT r = { x, y, w, h }; if (!KiDisplayClipRect(&mode, &r)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; fb->Stats.ReadRectCount++; fb->Stats.BytesCopied += (uint64_t)(uint32_t)r.W * (uint64_t)(uint32_t)r.H * sizeof(uint32_t); @@ -2209,16 +2209,16 @@ static KSTATUS BootFbReadRect(DISPLAY_DEVICE* device, int x, int y, int w, int h uint32_t* dst = outPixels + ((size_t)(dstOffsetY + row) * outStride) + dstOffsetX; memcpy(dst, src, (size_t)r.W * sizeof(uint32_t)); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the boot Fb Present operation. static KSTATUS BootFbPresent(DISPLAY_DEVICE* device, const DISPLAY_RECT* rects, size_t rectCount) { BOOTFB_CONTEXT* fb = BootFbContext(device); if (!fb || !fb->Framebuffer) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!fb->Backbuffer || !rects || rectCount == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; DISPLAY_MODE mode; KSTATUS s = BootFbGetMode(device, &mode); @@ -2240,14 +2240,14 @@ static KSTATUS BootFbPresent(DISPLAY_DEVICE* device, const DISPLAY_RECT* rects, memcpy(dst, src, bytesPerRow); } } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the boot Fb Sync operation. static KSTATUS BootFbSync(DISPLAY_DEVICE* device) { BOOTFB_CONTEXT* fb = BootFbContext(device); if (fb) fb->Stats.SyncCount++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the boot Fb Set Cursor Image operation. @@ -2258,7 +2258,7 @@ static KSTATUS BootFbSetCursorImage(DISPLAY_DEVICE* device, int width, int heigh (void)hotX; (void)hotY; (void)argbPixels; - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } // Implements the boot Fb Set Cursor Position operation. @@ -2267,7 +2267,7 @@ static KSTATUS BootFbSetCursorPosition(DISPLAY_DEVICE* device, int x, int y) { if (fb) fb->Stats.CursorMoveCount++; (void)x; (void)y; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the display Blend Pixel operation. @@ -2338,7 +2338,7 @@ static void BootFbDrawCursor(BOOTFB_CONTEXT* fb, int x, int y) { static KSTATUS BootFbShowCursor(DISPLAY_DEVICE* device, bool show) { BOOTFB_CONTEXT* fb = BootFbContext(device); if (!fb || !fb->Framebuffer || !fb->Backbuffer) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (show) { fb->Stats.CursorShowCount++; @@ -2347,14 +2347,14 @@ static KSTATUS BootFbShowCursor(DISPLAY_DEVICE* device, bool show) { fb->Stats.CursorHideCount++; BootFbRestoreCursor(fb); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the boot Fb Query Stats operation. static KSTATUS BootFbQueryStats(DISPLAY_DEVICE* device, DISPLAY_STATS* outStats) { BOOTFB_CONTEXT* fb = BootFbContext(device); if (!fb || !outStats) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *outStats = fb->Stats; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } diff --git a/code/kernel/ke_event.c b/code/kernel/ke_event.c index 179e10e..f41bee9 100644 --- a/code/kernel/ke_event.c +++ b/code/kernel/ke_event.c @@ -49,9 +49,9 @@ static void KiCompleteMultiWaitBlockLocked(KE_EVENT_WAIT_BLOCK* block) { if (_InterlockedCompareExchange(&ctx->Completed, 1, 0) != 0) return; - ctx->Status = STATUS_SUCCESS; + ctx->Status = NTLSTATUS_SUCCESS; ctx->SelectedIndex = block->Index; - KeUnblockThreadFromWaitListWithStatus(ctx->Thread, STATUS_SUCCESS); + KeUnblockThreadFromWaitListWithStatus(ctx->Thread, NTLSTATUS_SUCCESS); } // Removes any wait blocks that are still linked after the wait completed. @@ -96,9 +96,9 @@ static void KiRundownMultiWait(THREAD* thread, void* context, KSTATUS status) { // Creates event. __declspec(dllexport) KSTATUS KeEventCreate(EVENT_TYPE type, uint32_t initialState, EVENT **out) { - if (!out) return STATUS_INVALID_PARAMETER; + if (!out) return NTLSTATUS_INVALID_PARAMETER; EVENT* e = (EVENT *)ObAllocateObject(ObjectTypeEvent, sizeof(EVENT)); - if (!e) return STATUS_NO_MEMORY; + if (!e) return NTLSTATUS_NO_MEMORY; e->Header.Destroy = KiEventDestroy; e->Lock = (SPINLOCK)SPINLOCK_INIT; e->Type = type; @@ -106,7 +106,7 @@ __declspec(dllexport) KSTATUS KeEventCreate(EVENT_TYPE type, uint32_t initialSta LIST_INIT(&e->WaitList); LIST_INIT(&e->MultiWaitList); *out = e; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Signals event. @@ -121,7 +121,7 @@ __declspec(dllexport) void KeSignalEvent(EVENT* event) { THREAD* t = CONTAINING_RECORD(node, THREAD, SchedulerLink); KeSetThreadWaitList(t, (LIST_ENTRY*)0); KeReleaseSpinlock(&event->Lock, flags); - KeUnblockThreadWithStatus(t, STATUS_SUCCESS); + KeUnblockThreadWithStatus(t, NTLSTATUS_SUCCESS); flags = KeAcquireSpinlock(&event->Lock); } while (!LIST_IS_EMPTY(&event->MultiWaitList)) { @@ -136,7 +136,7 @@ __declspec(dllexport) void KeSignalEvent(EVENT* event) { THREAD* t = CONTAINING_RECORD(node, THREAD, SchedulerLink); KeSetThreadWaitList(t, (LIST_ENTRY*)0); KeReleaseSpinlock(&event->Lock, flags); - KeUnblockThreadWithStatus(t, STATUS_SUCCESS); + KeUnblockThreadWithStatus(t, NTLSTATUS_SUCCESS); return; } @@ -167,31 +167,31 @@ __declspec(dllexport) void KeClearEvent(EVENT* event) { // Attempts to consume an event signal without blocking. __declspec(dllexport) KSTATUS KeTryWaitEvent(EVENT* event) { - if (!event) return STATUS_INVALID_PARAMETER; + if (!event) return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&event->Lock); if (!event->Signaled) { KeReleaseSpinlock(&event->Lock, flags); - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } if (event->Type == EventAutoReset) event->Signaled = 0; KeReleaseSpinlock(&event->Lock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Waits for Event. __declspec(dllexport) KSTATUS KeWaitForEvent(EVENT* event, uint8_t alertable) { - if (!event) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; - if (alertable && KeAreKernelApcsDisabled()) return STATUS_INVALID_PARAMETER; + if (!event) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; + if (alertable && KeAreKernelApcsDisabled()) return NTLSTATUS_INVALID_PARAMETER; THREAD* self = KeGetCurrentThread(); uintptr_t flags = KeAcquireSpinlock(&event->Lock); if (event->Signaled) { if (event->Type == EventAutoReset) event->Signaled = 0; KeReleaseSpinlock(&event->Lock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KePrepareBlockThread(self, &event->Header, alertable); @@ -206,21 +206,21 @@ __declspec(dllexport) KSTATUS KeWaitForMultipleEvents(EVENT** events, uint32_t c uint8_t alertable, uint64_t timeoutMs, uint32_t* signaledIndexOut) { if (!events || count == 0 || count > SYS_WAIT_MANY_MAX_HANDLES) - return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; - if (alertable && KeAreKernelApcsDisabled()) return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; + if (alertable && KeAreKernelApcsDisabled()) return NTLSTATUS_INVALID_PARAMETER; for (uint32_t i = 0; i < count; i++) { - if (!events[i]) return STATUS_INVALID_PARAMETER; + if (!events[i]) return NTLSTATUS_INVALID_PARAMETER; KSTATUS s = KeTryWaitEvent(events[i]); if (KSUCCESS(s)) { if (signaledIndexOut) *signaledIndexOut = i; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } if (timeoutMs == 0) - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; KE_EVENT_WAIT_BLOCK stackBlocks[SYS_WAIT_MANY_MAX_HANDLES]; KE_EVENT_MULTI_WAIT_CONTEXT ctx; @@ -228,7 +228,7 @@ __declspec(dllexport) KSTATUS KeWaitForMultipleEvents(EVENT** events, uint32_t c ctx.Blocks = stackBlocks; ctx.Count = count; ctx.Completed = 0; - ctx.Status = STATUS_PENDING; + ctx.Status = NTLSTATUS_PENDING; ctx.SelectedIndex = 0; for (uint32_t i = 0; i < count; i++) { @@ -243,7 +243,7 @@ __declspec(dllexport) KSTATUS KeWaitForMultipleEvents(EVENT** events, uint32_t c KeSetThreadWaitRundown(ctx.Thread, KiRundownMultiWait, &ctx); if (timeoutMs != SYS_WAIT_TIMEOUT_INFINITE) { - KSTATUS ts = KeArmCurrentThreadTimeout(timeoutMs, STATUS_TIMEOUT); + KSTATUS ts = KeArmCurrentThreadTimeout(timeoutMs, NTLSTATUS_TIMEOUT); if (!KSUCCESS(ts)) { KeClearThreadWaitRundown(ctx.Thread); KeUnblockThreadFromWaitListWithStatus(ctx.Thread, ts); @@ -257,11 +257,11 @@ __declspec(dllexport) KSTATUS KeWaitForMultipleEvents(EVENT** events, uint32_t c if (_InterlockedCompareExchange(&ctx.Completed, 0, 0) == 0 && event->Signaled) { if (event->Type == EventAutoReset) event->Signaled = 0; - ctx.Status = STATUS_SUCCESS; + ctx.Status = NTLSTATUS_SUCCESS; ctx.SelectedIndex = i; _InterlockedExchange(&ctx.Completed, 1); KeReleaseSpinlock(&event->Lock, flags); - KeUnblockThreadFromWaitListWithStatus(ctx.Thread, STATUS_SUCCESS); + KeUnblockThreadFromWaitListWithStatus(ctx.Thread, NTLSTATUS_SUCCESS); break; } @@ -279,7 +279,7 @@ __declspec(dllexport) KSTATUS KeWaitForMultipleEvents(EVENT** events, uint32_t c KiCleanupMultiWaitBlocks(&ctx); KeClearThreadWaitRundown(ctx.Thread); - if (ctx.Status == STATUS_SUCCESS && signaledIndexOut) + if (ctx.Status == NTLSTATUS_SUCCESS && signaledIndexOut) *signaledIndexOut = ctx.SelectedIndex; return ctx.Status; } diff --git a/code/kernel/ke_exception.c b/code/kernel/ke_exception.c new file mode 100644 index 0000000..9eb59f1 --- /dev/null +++ b/code/kernel/ke_exception.c @@ -0,0 +1,801 @@ +// Kernel exception classification and recoverable fault policy. + +#include +#include +#include +#include +#include +#include +#include + + +#define KI_EXCEPTION_MAX_DISPATCH_DEPTH KE_USER_EXCEPTION_MAX_DEPTH +#define KI_EXCEPTION_USER_ENTRY_SHADOW 40u +#define KI_EXCEPTION_FRAME_ALIGNMENT 16u +#define KI_USER_CS 0x1BULL +#define KI_USER_SS 0x23ULL +#define KI_RFLAGS_FIXED 0x2ULL +#define KI_RFLAGS_IOPL 0x3000ULL +#define KI_RFLAGS_NT 0x4000ULL +#define KI_RFLAGS_VM 0x20000ULL + +// Returns whether one user address can be used as a control-flow target or pointer. +static bool KiExceptionUserAddressValid(uintptr_t address) { + return address >= USER_BASE && address < USER_LIMIT; +} + +// Returns whether one byte range stays wholly inside user address space. +static bool KiExceptionUserRangeValid(uintptr_t base, size_t size) { + if (size == 0) + return false; + if (base < USER_BASE || base >= USER_LIMIT) + return false; + if (size > (size_t)(USER_LIMIT - base)) + return false; + return true; +} + +// Returns whether a saved user RFLAGS value can be restored safely. +static bool KiExceptionUserRflagsValid(uint64_t rflags) { + if ((rflags & KI_RFLAGS_FIXED) == 0) + return false; + if ((rflags & (KI_RFLAGS_IOPL | KI_RFLAGS_NT | KI_RFLAGS_VM)) != 0) + return false; + return true; +} + +// Rounds an address down to the alignment required by the user-mode ABI. +static uintptr_t KiExceptionAlignDown(uintptr_t value, uintptr_t alignment) { + return value & ~(alignment - 1u); +} + +// Terminates the current process from exception-return policy code. +static _Noreturn void KiTerminateCurrentExceptionProcess(KSTATUS exitStatus) { + THREAD* thread = KeGetCurrentThread(); + PROCESS* process = thread ? thread->Owner : (PROCESS*)0; + int32_t exitCode = (int32_t)exitStatus; + + if (process) + (void)KeTerminateProcess(process, exitCode); + if (thread) + KeExitThread(thread, exitCode); + + for (;;) { + KeYield(); + } +} + +// Records a delivered exception against the process that owns user policy. +static void KiRecordExceptionDelivery(PROCESS* process, const SYS_EXCEPTION_RECORD* record, + uint32_t nestedDepth, bool userRaised) { + if (!process || !record) + return; + + uintptr_t flags = KeAcquireSpinlock(&process->ExceptionLock); + process->ExceptionDeliveredCount++; + if (userRaised) + process->ExceptionUserRaisedCount++; + if (nestedDepth > process->ExceptionMaxNestedDispatch) + process->ExceptionMaxNestedDispatch = nestedDepth; + process->LastExceptionCode = record->Code; + process->LastExceptionAddress = record->ExceptionAddress; + process->LastExceptionFaultAddress = record->FaultAddress; + KeReleaseSpinlock(&process->ExceptionLock, flags); +} + +// Records one completed exception continuation. +static void KiRecordExceptionContinued(PROCESS* process) { + if (!process) + return; + uintptr_t flags = KeAcquireSpinlock(&process->ExceptionLock); + process->ExceptionContinuedCount++; + KeReleaseSpinlock(&process->ExceptionLock, flags); +} + +// Records that user policy declined or failed to handle an exception. +static void KiRecordExceptionUnhandled(PROCESS* process) { + if (!process) + return; + uintptr_t flags = KeAcquireSpinlock(&process->ExceptionLock); + process->ExceptionUnhandledCount++; + KeReleaseSpinlock(&process->ExceptionLock, flags); +} + +// Records a malformed or forbidden exception continuation request. +static void KiRecordExceptionInvalidContinue(PROCESS* process) { + if (!process) + return; + uintptr_t flags = KeAcquireSpinlock(&process->ExceptionLock); + process->ExceptionInvalidContinueCount++; + KeReleaseSpinlock(&process->ExceptionLock, flags); +} + + +// Returns the process exit status for one unhandled native exception record. +static KSTATUS KiExceptionUnhandledExitStatus(const SYS_EXCEPTION_RECORD* record) { + if (!record) + return NTLSTATUS_PROCESS_UNKNOWN_FAULT; + + switch (record->Code) { + case SYS_EXCEPTION_CODE_INT_DIVIDE_BY_ZERO: + return NTLSTATUS_PROCESS_DIVIDE_BY_ZERO; + case SYS_EXCEPTION_CODE_BREAKPOINT: + return NTLSTATUS_PROCESS_BREAKPOINT; + case SYS_EXCEPTION_CODE_ILLEGAL_INSTRUCTION: + return NTLSTATUS_PROCESS_ILLEGAL_OPCODE; + case SYS_EXCEPTION_CODE_PRIVILEGED_INSTRUCTION: + return NTLSTATUS_PROCESS_GENERAL_PROTECTION; + case SYS_EXCEPTION_CODE_ACCESS_VIOLATION: + return NTLSTATUS_PROCESS_PAGE_FAULT; + case SYS_EXCEPTION_CODE_DATATYPE_MISALIGNMENT: + return NTLSTATUS_PROCESS_ALIGNMENT_FAULT; + default: + return (KSTATUS)record->Code; + } +} + +// Maps an architectural vector to the native structured-exception code. +static uint32_t KiExceptionCodeFromVector(uint32_t vector) { + switch (vector) { + case 0: return SYS_EXCEPTION_CODE_INT_DIVIDE_BY_ZERO; + case 1: return SYS_EXCEPTION_CODE_SINGLE_STEP; + case 3: return SYS_EXCEPTION_CODE_BREAKPOINT; + case 4: return SYS_EXCEPTION_CODE_INT_OVERFLOW; + case 5: return SYS_EXCEPTION_CODE_ARRAY_BOUNDS_EXCEEDED; + case 6: return SYS_EXCEPTION_CODE_ILLEGAL_INSTRUCTION; + case 13: return SYS_EXCEPTION_CODE_PRIVILEGED_INSTRUCTION; + case 14: return SYS_EXCEPTION_CODE_ACCESS_VIOLATION; + case 17: return SYS_EXCEPTION_CODE_DATATYPE_MISALIGNMENT; + default: return SYS_EXCEPTION_CODE_NTLITE_UNKNOWN; + } +} + +// Fills the user-mode context record from a captured CPU fault frame. +static void KiCaptureUserContextFromFault(const KFAULT_FRAME* frame, SYS_USER_CONTEXT* context) { + memset(context, 0, sizeof(*context)); + context->Size = sizeof(*context); + context->Version = SYS_EXCEPTION_ABI_VERSION; + context->Flags = SYS_CONTEXT_FLAG_ALL; + context->Rip = frame->Rip; + context->Rsp = frame->Rsp; + context->Rflags = frame->Rflags; + context->Rax = frame->Rax; + context->Rcx = frame->Rcx; + context->Rdx = frame->Rdx; + context->Rbx = frame->Rbx; + context->Rbp = frame->Rbp; + context->Rsi = frame->Rsi; + context->Rdi = frame->Rdi; + context->R8 = frame->R8; + context->R9 = frame->R9; + context->R10 = frame->R10; + context->R11 = frame->R11; + context->R12 = frame->R12; + context->R13 = frame->R13; + context->R14 = frame->R14; + context->R15 = frame->R15; + context->SegCs = (uint32_t)frame->Cs; + context->SegSs = (uint32_t)frame->Ss; +} + +// Fills the user-mode context record from the current syscall return frame. +static void KiCaptureUserContextFromTrap(const KTRAP_FRAME* frame, SYS_USER_CONTEXT* context) { + memset(context, 0, sizeof(*context)); + context->Size = sizeof(*context); + context->Version = SYS_EXCEPTION_ABI_VERSION; + context->Flags = SYS_CONTEXT_FLAG_ALL; + context->Rip = frame->Rip; + context->Rsp = frame->Rsp; + context->Rflags = frame->Rflags; + context->Rax = NTLSTATUS_SUCCESS; + context->Rcx = frame->Rcx; + context->Rdx = frame->Rdx; + context->Rbx = frame->Rbx; + context->Rbp = frame->Rbp; + context->Rsi = frame->Rsi; + context->Rdi = frame->Rdi; + context->R8 = frame->R8; + context->R9 = frame->R9; + context->R10 = frame->R10; + context->R11 = frame->R11; + context->R12 = frame->R12; + context->R13 = frame->R13; + context->R14 = frame->R14; + context->R15 = frame->R15; + context->SegCs = (uint32_t)frame->Cs; + context->SegSs = (uint32_t)frame->Ss; +} + +// Fills the native exception record from an architectural user fault. +static void KiCaptureExceptionRecordFromFault(const KFAULT_FRAME* frame, SYS_EXCEPTION_RECORD* record) { + memset(record, 0, sizeof(*record)); + record->Size = sizeof(*record); + record->Version = SYS_EXCEPTION_ABI_VERSION; + record->Code = KiExceptionCodeFromVector((uint32_t)frame->Vector); + record->Flags = SYS_EXCEPTION_FLAG_FIRST_CHANCE; + if ((frame->Vector == 8) || (frame->Vector == 18)) + record->Flags |= SYS_EXCEPTION_FLAG_NONCONTINUABLE; + record->ExceptionAddress = (uintptr_t)frame->Rip; + record->FaultAddress = frame->Vector == 14 ? (uintptr_t)frame->Cr2 : (uintptr_t)frame->Rip; + record->ErrorCode = frame->ErrorCode; + + if (frame->Vector == 14) { + uint64_t accessKind = 0; + if (frame->ErrorCode & 0x10u) + accessKind = 8; + else if (frame->ErrorCode & 0x2u) + accessKind = 1; + record->ParameterCount = 2; + record->Parameters[0] = accessKind; + record->Parameters[1] = frame->Cr2; + } +} + +// Captures a stable process dispatcher snapshot outside the process lock. +static KSTATUS KiSnapshotExceptionDispatcher(PROCESS* process, + SYS_EXCEPTION_DISPATCHER_REQUEST* out) { + if (!process || !out) + return NTLSTATUS_INVALID_PARAMETER; + + memset(out, 0, sizeof(*out)); + out->Size = sizeof(*out); + + uintptr_t flags = KeAcquireSpinlock(&process->ExceptionLock); + out->Flags = process->ExceptionDispatchFlags; + out->DispatcherRoutine = (SYS_USER_EXCEPTION_DISPATCHER)process->ExceptionDispatcher; + out->DispatcherContext = (void*)process->ExceptionDispatcherContext; + out->ExceptionStackBase = (void*)process->ExceptionStackBase; + out->ExceptionStackSize = process->ExceptionStackSize; + KeReleaseSpinlock(&process->ExceptionLock, flags); + + if (!out->DispatcherRoutine) + return NTLSTATUS_NOT_FOUND; + return NTLSTATUS_SUCCESS; +} + +// Selects the stack top used to inject one exception dispatcher frame. +static KSTATUS KiSelectExceptionStackTop(THREAD* thread, + const SYS_EXCEPTION_DISPATCHER_REQUEST* dispatcher, + const KFAULT_FRAME* fault, + uintptr_t* stackTopOut) { + if (!thread || !dispatcher || !fault || !stackTopOut) + return NTLSTATUS_INVALID_PARAMETER; + + if (dispatcher->ExceptionStackBase) { + uintptr_t base = (uintptr_t)dispatcher->ExceptionStackBase; + uintptr_t top = base + dispatcher->ExceptionStackSize; + uintptr_t stride = KiExceptionAlignDown(sizeof(SYS_EXCEPTION_FRAME) + + KI_EXCEPTION_USER_ENTRY_SHADOW + + KI_EXCEPTION_FRAME_ALIGNMENT - 1u, + KI_EXCEPTION_FRAME_ALIGNMENT); + uintptr_t needed = (uintptr_t)(thread->UserExceptionDepth + 1u) * stride; + if (needed > dispatcher->ExceptionStackSize) + return NTLSTATUS_BUFFER_TOO_SMALL; + *stackTopOut = top - (uintptr_t)thread->UserExceptionDepth * stride; + return NTLSTATUS_SUCCESS; + } + + if (!KiExceptionUserAddressValid((uintptr_t)fault->Rsp)) + return NTLSTATUS_ACCESS_DENIED; + *stackTopOut = (uintptr_t)fault->Rsp; + return NTLSTATUS_SUCCESS; +} + +// Selects an exception stack using an explicit user RSP. +static KSTATUS KiSelectExceptionStackTopFromRsp(THREAD* thread, + const SYS_EXCEPTION_DISPATCHER_REQUEST* dispatcher, + uintptr_t rsp, + uintptr_t* stackTopOut) { + if (!thread || !dispatcher || !stackTopOut) + return NTLSTATUS_INVALID_PARAMETER; + + if (dispatcher->ExceptionStackBase) { + uintptr_t base = (uintptr_t)dispatcher->ExceptionStackBase; + uintptr_t top = base + dispatcher->ExceptionStackSize; + uintptr_t stride = KiExceptionAlignDown(sizeof(SYS_EXCEPTION_FRAME) + + KI_EXCEPTION_USER_ENTRY_SHADOW + + KI_EXCEPTION_FRAME_ALIGNMENT - 1u, + KI_EXCEPTION_FRAME_ALIGNMENT); + uintptr_t needed = (uintptr_t)(thread->UserExceptionDepth + 1u) * stride; + if (needed > dispatcher->ExceptionStackSize) + return NTLSTATUS_BUFFER_TOO_SMALL; + *stackTopOut = top - (uintptr_t)thread->UserExceptionDepth * stride; + return NTLSTATUS_SUCCESS; + } + + if (!KiExceptionUserAddressValid(rsp)) + return NTLSTATUS_ACCESS_DENIED; + *stackTopOut = rsp; + return NTLSTATUS_SUCCESS; +} + +// Copies the native exception delivery frame to the selected user stack. +static KSTATUS KiBuildUserExceptionFrame(THREAD* thread, + const SYS_EXCEPTION_DISPATCHER_REQUEST* dispatcher, + KFAULT_FRAME* fault, + uintptr_t* frameAddressOut, + uintptr_t* entryRspOut) { + uintptr_t stackTop = 0; + KSTATUS status = KiSelectExceptionStackTop(thread, dispatcher, fault, &stackTop); + if (!KSUCCESS(status)) + return status; + + uintptr_t frameAddress = KiExceptionAlignDown(stackTop - sizeof(SYS_EXCEPTION_FRAME), + KI_EXCEPTION_FRAME_ALIGNMENT); + uintptr_t entryRsp = frameAddress - KI_EXCEPTION_USER_ENTRY_SHADOW; + if (!KiExceptionUserRangeValid(entryRsp, + KI_EXCEPTION_USER_ENTRY_SHADOW + sizeof(SYS_EXCEPTION_FRAME))) + return NTLSTATUS_ACCESS_DENIED; + + SYS_EXCEPTION_FRAME userFrame; + memset(&userFrame, 0, sizeof(userFrame)); + userFrame.Size = sizeof(userFrame); + userFrame.Version = SYS_EXCEPTION_ABI_VERSION; + KiCaptureExceptionRecordFromFault(fault, &userFrame.ExceptionRecord); + KiCaptureUserContextFromFault(fault, &userFrame.ContextRecord); + userFrame.DispatcherContext = dispatcher->DispatcherContext; + + uint8_t shadow[KI_EXCEPTION_USER_ENTRY_SHADOW]; + memset(shadow, 0, sizeof(shadow)); + status = CopyToUser((void*)entryRsp, shadow, sizeof(shadow)); + if (!KSUCCESS(status)) + return status; + + status = CopyToUser((void*)frameAddress, &userFrame, sizeof(userFrame)); + if (!KSUCCESS(status)) + return status; + + *frameAddressOut = frameAddress; + *entryRspOut = entryRsp; + return NTLSTATUS_SUCCESS; +} + +// Copies an already-classified user exception frame to the selected user stack. +static KSTATUS KiBuildUserRaisedExceptionFrame(THREAD* thread, + const SYS_EXCEPTION_DISPATCHER_REQUEST* dispatcher, + const KTRAP_FRAME* trapFrame, + const SYS_EXCEPTION_RECORD* record, + uintptr_t* frameAddressOut, + uintptr_t* entryRspOut) { + uintptr_t stackTop = 0; + KSTATUS status = KiSelectExceptionStackTopFromRsp(thread, dispatcher, trapFrame->Rsp, &stackTop); + if (!KSUCCESS(status)) + return status; + + uintptr_t frameAddress = KiExceptionAlignDown(stackTop - sizeof(SYS_EXCEPTION_FRAME), + KI_EXCEPTION_FRAME_ALIGNMENT); + uintptr_t entryRsp = frameAddress - KI_EXCEPTION_USER_ENTRY_SHADOW; + if (!KiExceptionUserRangeValid(entryRsp, + KI_EXCEPTION_USER_ENTRY_SHADOW + sizeof(SYS_EXCEPTION_FRAME))) + return NTLSTATUS_ACCESS_DENIED; + + SYS_EXCEPTION_FRAME userFrame; + memset(&userFrame, 0, sizeof(userFrame)); + userFrame.Size = sizeof(userFrame); + userFrame.Version = SYS_EXCEPTION_ABI_VERSION; + userFrame.ExceptionRecord = *record; + KiCaptureUserContextFromTrap(trapFrame, &userFrame.ContextRecord); + userFrame.DispatcherContext = dispatcher->DispatcherContext; + + uint8_t shadow[KI_EXCEPTION_USER_ENTRY_SHADOW]; + memset(shadow, 0, sizeof(shadow)); + status = CopyToUser((void*)entryRsp, shadow, sizeof(shadow)); + if (!KSUCCESS(status)) + return status; + + status = CopyToUser((void*)frameAddress, &userFrame, sizeof(userFrame)); + if (!KSUCCESS(status)) + return status; + + *frameAddressOut = frameAddress; + *entryRspOut = entryRsp; + return NTLSTATUS_SUCCESS; +} + +// Validates a user context before using it as an exception resume target. +static KSTATUS KiValidateContinueContext(const SYS_USER_CONTEXT* context) { + if (!context) + return NTLSTATUS_INVALID_PARAMETER; + if (context->Size != sizeof(*context) || context->Version != SYS_EXCEPTION_ABI_VERSION) + return NTLSTATUS_INVALID_PARAMETER; + if (context->Flags != SYS_CONTEXT_FLAG_ALL) + return NTLSTATUS_INVALID_PARAMETER; + if (!KiExceptionUserAddressValid((uintptr_t)context->Rip) || + !KiExceptionUserAddressValid((uintptr_t)context->Rsp)) + return NTLSTATUS_ACCESS_DENIED; + if (!KiExceptionUserRflagsValid(context->Rflags)) + return NTLSTATUS_ACCESS_DENIED; + if (context->SegCs != KI_USER_CS || context->SegSs != KI_USER_SS) + return NTLSTATUS_ACCESS_DENIED; + return NTLSTATUS_SUCCESS; +} + +// Applies a validated user context to the current syscall return trap frame. +static void KiApplyContinueContextToTrapFrame(KTRAP_FRAME* frame, + const SYS_USER_CONTEXT* context) { + frame->Rip = context->Rip; + frame->Rsp = context->Rsp; + frame->Rflags = context->Rflags; + frame->Cs = context->SegCs; + frame->Ss = context->SegSs; + frame->Rax = context->Rax; + frame->Rcx = context->Rcx; + frame->Rdx = context->Rdx; + frame->Rbx = context->Rbx; + frame->Rbp = context->Rbp; + frame->Rsi = context->Rsi; + frame->Rdi = context->Rdi; + frame->R8 = context->R8; + frame->R9 = context->R9; + frame->R10 = context->R10; + frame->R11 = context->R11; + frame->R12 = context->R12; + frame->R13 = context->R13; + frame->R14 = context->R14; + frame->R15 = context->R15; +} + +// Redirects a captured user fault to the registered native exception dispatcher. +KSTATUS KeDeliverUserException(KFAULT_FRAME* frame) { + if (!frame || !KeFaultFrameIsValid(frame) || !KeFaultFrameFromUser(frame)) + return NTLSTATUS_INVALID_PARAMETER; + + THREAD* thread = KeGetCurrentThread(); + PROCESS* process = thread ? thread->Owner : (PROCESS*)0; + if (!thread || !process) + return NTLSTATUS_FAILURE; + if (thread->UserExceptionDepth >= KI_EXCEPTION_MAX_DISPATCH_DEPTH) + return NTLSTATUS_PROCESS_UNKNOWN_FAULT; + + SYS_EXCEPTION_DISPATCHER_REQUEST dispatcher; + KSTATUS status = KiSnapshotExceptionDispatcher(process, &dispatcher); + if (!KSUCCESS(status)) + return status; + + uintptr_t frameAddress = 0; + uintptr_t entryRsp = 0; + status = KiBuildUserExceptionFrame(thread, &dispatcher, frame, &frameAddress, &entryRsp); + if (!KSUCCESS(status)) + return status; + + SYS_EXCEPTION_RECORD deliveredRecord; + KiCaptureExceptionRecordFromFault(frame, &deliveredRecord); + + uint32_t depth = thread->UserExceptionDepth; + if ((frame->Vector == 8) || (frame->Vector == 18)) + thread->UserExceptionNoncontinuableMask |= (1u << depth); + thread->UserExceptionExitStatus[depth] = KiExceptionUnhandledExitStatus(&deliveredRecord); + + KiRecordExceptionDelivery(process, &deliveredRecord, depth + 1u, false); + thread->UserExceptionDepth = depth + 1u; + thread->UserExceptionFrameUserAddress = frameAddress; + + frame->Rip = (uint64_t)(uintptr_t)dispatcher.DispatcherRoutine; + frame->Rsp = entryRsp; + frame->Rcx = frameAddress; + frame->Rdx = 0; + frame->R8 = 0; + frame->R9 = 0; + frame->R10 = 0; + frame->R11 = 0; + frame->Rax = NTLSTATUS_SUCCESS; + frame->Cs = KI_USER_CS; + frame->Ss = KI_USER_SS; + frame->Rflags |= KI_RFLAGS_FIXED; + frame->Rflags &= ~(KI_RFLAGS_IOPL | KI_RFLAGS_NT | KI_RFLAGS_VM); + return NTLSTATUS_SUCCESS; +} + +// Raises a user-authored structured exception from the current syscall frame. +uint64_t KeRaiseUserException(const SYS_RAISE_EXCEPTION_REQUEST* request, const uint64_t* parameters) { + if (!request) + return NTLSTATUS_INVALID_PARAMETER; + if (request->Size != sizeof(*request)) + return NTLSTATUS_INVALID_PARAMETER; + if (request->Flags & ~SYS_RAISE_EXCEPTION_FLAG_NONCONTINUABLE) + return NTLSTATUS_INVALID_PARAMETER; + if (request->ParameterCount > SYS_EXCEPTION_MAXIMUM_PARAMETERS) + return NTLSTATUS_INVALID_PARAMETER; + if (request->ParameterCount && !parameters) + return NTLSTATUS_INVALID_PARAMETER; + + THREAD* thread = KeGetCurrentThread(); + PROCESS* process = thread ? thread->Owner : (PROCESS*)0; + if (!thread || !process) + return NTLSTATUS_FAILURE; + if (thread->UserExceptionDepth >= KI_EXCEPTION_MAX_DISPATCH_DEPTH) + return NTLSTATUS_PROCESS_UNKNOWN_FAULT; + + KTRAP_FRAME* trapFrame = KeGetCurrentTrapFrame(); + if (!trapFrame || !KeTrapFrameFromUser(trapFrame) || trapFrame->Kind != KTRAP_KIND_SYSCALL) + return NTLSTATUS_FAILURE; + + SYS_EXCEPTION_DISPATCHER_REQUEST dispatcher; + KSTATUS status = KiSnapshotExceptionDispatcher(process, &dispatcher); + if (!KSUCCESS(status)) + return status; + + SYS_EXCEPTION_RECORD record; + memset(&record, 0, sizeof(record)); + record.Size = sizeof(record); + record.Version = SYS_EXCEPTION_ABI_VERSION; + record.Code = request->Code; + record.Flags = SYS_EXCEPTION_FLAG_FIRST_CHANCE; + if (request->Flags & SYS_RAISE_EXCEPTION_FLAG_NONCONTINUABLE) + record.Flags |= SYS_EXCEPTION_FLAG_NONCONTINUABLE; + record.ExceptionAddress = (uintptr_t)trapFrame->Rip; + record.FaultAddress = 0; + record.ParameterCount = request->ParameterCount; + for (uint32_t i = 0; i < request->ParameterCount; i++) + record.Parameters[i] = parameters[i]; + + uintptr_t frameAddress = 0; + uintptr_t entryRsp = 0; + status = KiBuildUserRaisedExceptionFrame(thread, &dispatcher, trapFrame, &record, + &frameAddress, &entryRsp); + if (!KSUCCESS(status)) + return status; + + uint32_t depth = thread->UserExceptionDepth; + if (record.Flags & SYS_EXCEPTION_FLAG_NONCONTINUABLE) + thread->UserExceptionNoncontinuableMask |= (1u << depth); + thread->UserExceptionExitStatus[depth] = KiExceptionUnhandledExitStatus(&record); + + KiRecordExceptionDelivery(process, &record, depth + 1u, true); + thread->UserExceptionDepth = depth + 1u; + thread->UserExceptionFrameUserAddress = frameAddress; + + trapFrame->Rip = (uint64_t)(uintptr_t)dispatcher.DispatcherRoutine; + trapFrame->Rsp = entryRsp; + trapFrame->Rcx = frameAddress; + trapFrame->Rdx = 0; + trapFrame->R8 = 0; + trapFrame->R9 = 0; + trapFrame->R10 = 0; + trapFrame->R11 = 0; + trapFrame->Rax = NTLSTATUS_SUCCESS; + trapFrame->Cs = KI_USER_CS; + trapFrame->Ss = KI_USER_SS; + trapFrame->Rflags |= KI_RFLAGS_FIXED; + trapFrame->Rflags &= ~(KI_RFLAGS_IOPL | KI_RFLAGS_NT | KI_RFLAGS_VM); + return NTLSTATUS_SUCCESS; +} + +// Completes native exception dispatch by applying the user-selected disposition. +uint64_t KeContinueException(const SYS_CONTINUE_EXCEPTION_REQUEST* request) { + if (!request) + return NTLSTATUS_INVALID_PARAMETER; + if (request->Size != sizeof(*request) || request->Flags != SYS_EXCEPTION_CONTINUE_FLAG_NONE) + return NTLSTATUS_INVALID_PARAMETER; + + THREAD* thread = KeGetCurrentThread(); + PROCESS* process = thread ? thread->Owner : (PROCESS*)0; + if (!thread || thread->UserExceptionDepth == 0) { + KiRecordExceptionInvalidContinue(process); + return NTLSTATUS_INVALID_PARAMETER; + } + + uint32_t activeDepth = thread->UserExceptionDepth - 1u; + uint32_t activeBit = 1u << activeDepth; + KSTATUS activeExitStatus = thread->UserExceptionExitStatus[activeDepth]; + if (activeExitStatus == NTLSTATUS_SUCCESS) + activeExitStatus = NTLSTATUS_PROCESS_UNKNOWN_FAULT; + + if (request->Disposition == SYS_EXCEPTION_DISPOSITION_CONTINUE_SEARCH || + request->Disposition == SYS_EXCEPTION_DISPOSITION_TERMINATE_PROCESS) { + KiRecordExceptionUnhandled(process); + thread->UserExceptionDepth = activeDepth; + thread->UserExceptionNoncontinuableMask &= ~activeBit; + thread->UserExceptionFrameUserAddress = 0; + thread->UserExceptionExitStatus[activeDepth] = NTLSTATUS_SUCCESS; + KiTerminateCurrentExceptionProcess(activeExitStatus); + } + + if (request->Disposition != SYS_EXCEPTION_DISPOSITION_CONTINUE_EXECUTION) { + KiRecordExceptionInvalidContinue(process); + return NTLSTATUS_INVALID_PARAMETER; + } + if (thread->UserExceptionNoncontinuableMask & activeBit) { + KiRecordExceptionInvalidContinue(process); + thread->UserExceptionDepth = activeDepth; + thread->UserExceptionNoncontinuableMask &= ~activeBit; + thread->UserExceptionFrameUserAddress = 0; + thread->UserExceptionExitStatus[activeDepth] = NTLSTATUS_SUCCESS; + KiTerminateCurrentExceptionProcess(NTLSTATUS_PROCESS_UNKNOWN_FAULT); + } + if (!request->Context) { + KiRecordExceptionInvalidContinue(process); + return NTLSTATUS_INVALID_PARAMETER; + } + + SYS_USER_CONTEXT context; + KSTATUS status = CopyFromUser(&context, request->Context, sizeof(context)); + if (!KSUCCESS(status)) + return status; + + status = KiValidateContinueContext(&context); + if (!KSUCCESS(status)) { + KiRecordExceptionInvalidContinue(process); + KiTerminateCurrentExceptionProcess(status); + } + + KTRAP_FRAME* trapFrame = KeGetCurrentTrapFrame(); + if (!trapFrame || !KeTrapFrameFromUser(trapFrame) || trapFrame->Kind != KTRAP_KIND_SYSCALL) { + KiRecordExceptionInvalidContinue(process); + return NTLSTATUS_FAILURE; + } + + KiApplyContinueContextToTrapFrame(trapFrame, &context); + KiRecordExceptionContinued(process); + thread->UserExceptionDepth = activeDepth; + thread->UserExceptionNoncontinuableMask &= ~activeBit; + thread->UserExceptionFrameUserAddress = 0; + thread->UserExceptionExitStatus[activeDepth] = NTLSTATUS_SUCCESS; + return context.Rax; +} + +// Returns whether a fault frame was initialized by the assembly stubs. +bool KeFaultFrameIsValid(const KFAULT_FRAME* frame) { + return frame && frame->Magic == KFAULT_FRAME_MAGIC_VALUE; +} + +// Returns whether a fault frame captured an interrupted user-mode context. +bool KeFaultFrameFromUser(const KFAULT_FRAME* frame) { + return KeFaultFrameIsValid(frame) && ((frame->Cs & 3u) == 3u); +} + +// Returns the short architectural name for one CPU exception vector. +const char* KeExceptionVectorName(uint32_t vector) { + switch (vector) { + case 0: return "#DE Divide Error"; + case 1: return "#DB Debug"; + case 2: return "NMI Interrupt"; + case 3: return "#BP Breakpoint"; + case 4: return "#OF Overflow"; + case 5: return "#BR Bound Range Exceeded"; + case 6: return "#UD Invalid Opcode"; + case 7: return "#NM Device Not Available"; + case 8: return "#DF Double Fault"; + case 9: return "Coprocessor Segment Overrun"; + case 10: return "#TS Invalid TSS"; + case 11: return "#NP Segment Not Present"; + case 12: return "#SS Stack-Segment Fault"; + case 13: return "#GP General Protection"; + case 14: return "#PF Page Fault"; + case 15: return "Reserved Exception 15"; + case 16: return "#MF x87 Floating-Point Exception"; + case 17: return "#AC Alignment Check"; + case 18: return "#MC Machine Check"; + case 19: return "#XM SIMD Floating-Point Exception"; + case 20: return "#VE Virtualization Exception"; + case 21: return "#CP Control Protection Exception"; + case 22: return "Reserved Exception 22"; + case 23: return "Reserved Exception 23"; + case 24: return "Reserved Exception 24"; + case 25: return "Reserved Exception 25"; + case 26: return "Reserved Exception 26"; + case 27: return "Reserved Exception 27"; + case 28: return "#HV Hypervisor Injection Exception"; + case 29: return "#VC VMM Communication Exception"; + case 30: return "#SX Security Exception"; + case 31: return "Reserved Exception 31"; + default: return "Unknown Exception"; + } +} + +// Returns whether the CPU pushes an error code for one exception vector. +bool KeExceptionVectorHasErrorCode(uint32_t vector) { + switch (vector) { + case 8: + case 10: + case 11: + case 12: + case 13: + case 14: + case 17: + case 21: + case 29: + case 30: + return true; + default: + return false; + } +} + +// Maps an unhandled user-mode CPU exception to the legacy process exit status. +KSTATUS KeExceptionProcessExitStatus(uint32_t vector) { + switch (vector) { + case 0: return NTLSTATUS_PROCESS_DIVIDE_BY_ZERO; + case 3: return NTLSTATUS_PROCESS_BREAKPOINT; + case 6: return NTLSTATUS_PROCESS_ILLEGAL_OPCODE; + case 13: return NTLSTATUS_PROCESS_GENERAL_PROTECTION; + case 14: return NTLSTATUS_PROCESS_PAGE_FAULT; + case 17: return NTLSTATUS_PROCESS_ALIGNMENT_FAULT; + default: return NTLSTATUS_PROCESS_UNKNOWN_FAULT; + } +} + +// Handles faults that are still kernel-owned repair cases, not user exceptions. +KSTATUS KeExceptionResolveRecoverableFault(const KFAULT_FRAME* frame) { + if (!KeFaultFrameIsValid(frame)) + return NTLSTATUS_INVALID_PARAMETER; + if (frame->Vector != 14) + return NTLSTATUS_NOT_SUPPORTED; + + return MmVadResolvePageFaultByAddress((uintptr_t)frame->Cr2, frame->ErrorCode); +} + +// Validates a user exception dispatcher registration before publishing it. +static KSTATUS KiValidateExceptionDispatcherRequest(const SYS_EXCEPTION_DISPATCHER_REQUEST* request) { + if (!request) + return NTLSTATUS_INVALID_PARAMETER; + if (request->Size != sizeof(*request)) + return NTLSTATUS_INVALID_PARAMETER; + if (request->Flags != SYS_EXCEPTION_DISPATCH_FLAG_NONE) + return NTLSTATUS_INVALID_PARAMETER; + + if (!request->DispatcherRoutine) { + if (request->ExceptionStackBase || request->ExceptionStackSize) + return NTLSTATUS_INVALID_PARAMETER; + return NTLSTATUS_SUCCESS; + } + + if (!KiExceptionUserAddressValid((uintptr_t)request->DispatcherRoutine)) + return NTLSTATUS_ACCESS_DENIED; + + if ((request->ExceptionStackBase == 0) != (request->ExceptionStackSize == 0)) + return NTLSTATUS_INVALID_PARAMETER; + if (request->ExceptionStackBase) { + if (!KiExceptionUserRangeValid((uintptr_t)request->ExceptionStackBase, request->ExceptionStackSize)) + return NTLSTATUS_ACCESS_DENIED; + if (request->ExceptionStackSize < sizeof(SYS_EXCEPTION_FRAME) + 64u) + return NTLSTATUS_BUFFER_TOO_SMALL; + } + + return NTLSTATUS_SUCCESS; +} + +// Registers or clears the current process's native user exception dispatcher. +KSTATUS KeSetExceptionDispatcher(PROCESS* process, const SYS_EXCEPTION_DISPATCHER_REQUEST* request) { + if (!process || !request) + return NTLSTATUS_INVALID_PARAMETER; + + KSTATUS status = KiValidateExceptionDispatcherRequest(request); + if (!KSUCCESS(status)) + return status; + + uintptr_t flags = KeAcquireSpinlock(&process->ExceptionLock); + if (!request->DispatcherRoutine) { + process->ExceptionDispatcher = 0; + process->ExceptionDispatcherContext = 0; + process->ExceptionStackBase = 0; + process->ExceptionStackSize = 0; + process->ExceptionDispatchFlags = SYS_EXCEPTION_DISPATCH_FLAG_NONE; + } else { + process->ExceptionDispatcher = (uintptr_t)request->DispatcherRoutine; + process->ExceptionDispatcherContext = (uintptr_t)request->DispatcherContext; + process->ExceptionStackBase = (uintptr_t)request->ExceptionStackBase; + process->ExceptionStackSize = request->ExceptionStackSize; + process->ExceptionDispatchFlags = request->Flags; + } + KeReleaseSpinlock(&process->ExceptionLock, flags); + return NTLSTATUS_SUCCESS; +} + +// Copies a stable snapshot of the current process's exception dispatcher registration. +KSTATUS KeGetExceptionDispatcher(PROCESS* process, SYS_EXCEPTION_DISPATCHER_REQUEST* request) { + if (!process || !request) + return NTLSTATUS_INVALID_PARAMETER; + + memset(request, 0, sizeof(*request)); + request->Size = sizeof(*request); + + uintptr_t flags = KeAcquireSpinlock(&process->ExceptionLock); + request->Flags = process->ExceptionDispatchFlags; + request->DispatcherRoutine = (SYS_USER_EXCEPTION_DISPATCHER)process->ExceptionDispatcher; + request->DispatcherContext = (void*)process->ExceptionDispatcherContext; + request->ExceptionStackBase = (void*)process->ExceptionStackBase; + request->ExceptionStackSize = process->ExceptionStackSize; + KeReleaseSpinlock(&process->ExceptionLock, flags); + return NTLSTATUS_SUCCESS; +} diff --git a/code/kernel/ke_idt.c b/code/kernel/ke_idt.c index 4f57451..ab4fc31 100644 --- a/code/kernel/ke_idt.c +++ b/code/kernel/ke_idt.c @@ -163,6 +163,9 @@ void KeSetCurrentTssRsp0(uintptr_t rsp0) { // IDT. #define IDT_ENTRIES 256 +#define KI_IDT_TYPE_INTERRUPT_GATE 0x8Eu +#define KI_IDT_TYPE_USER_INTERRUPT_GATE 0xEEu + #pragma pack(push, 1) typedef struct { uint16_t OffsetLow; @@ -211,9 +214,12 @@ void KeInitializeIdt(void) { }; for (int i = 0; i < 32; i++) - KiIdtSetGate(i, (uintptr_t)faultStubs[i], 0x8E, 0); + KiIdtSetGate(i, (uintptr_t)faultStubs[i], KI_IDT_TYPE_INTERRUPT_GATE, 0); - KiIdtSetGate(0x40, (uintptr_t)KeSyscallEntry, 0xEE, 0); + // User-mode INT3 must enter #BP, not fail the gate-DPL check and become #GP. + KiIdtSetGate(3, (uintptr_t)KeFaultBP, KI_IDT_TYPE_USER_INTERRUPT_GATE, 0); + + KiIdtSetGate(0x40, (uintptr_t)KeSyscallEntry, KI_IDT_TYPE_USER_INTERRUPT_GATE, 0); static void *irqStubs[NUM_IRQS] = { (void*)KeIrqStub0, (void*)KeIrqStub1, (void*)KeIrqStub2, @@ -226,9 +232,10 @@ void KeInitializeIdt(void) { (void*)KeIrqStub21, (void*)KeIrqStub22, (void*)KeIrqStub23, }; for (int i = 0; i < NUM_IRQS; i++) - KiIdtSetGate(0x20 + i, (uintptr_t)irqStubs[i], 0x8E, 0); + KiIdtSetGate(0x20 + i, (uintptr_t)irqStubs[i], KI_IDT_TYPE_INTERRUPT_GATE, 0); - KiIdtSetGate(KE_VECTOR_RESCHEDULE_IPI, (uintptr_t)KeRescheduleIpiStub, 0x8E, 0); + KiIdtSetGate(KE_VECTOR_RESCHEDULE_IPI, (uintptr_t)KeRescheduleIpiStub, + KI_IDT_TYPE_INTERRUPT_GATE, 0); KeLoadIdtForCurrentCpu(); } diff --git a/code/kernel/ke_input.c b/code/kernel/ke_input.c index ba60eb9..f92c5b5 100644 --- a/code/kernel/ke_input.c +++ b/code/kernel/ke_input.c @@ -263,10 +263,10 @@ void KeInputInitialize(const HAL_API* hal) { __declspec(dllexport) KSTATUS KeInputRegisterDevice(const char* name, uint32_t flags, uint32_t* outDeviceId) { (void)flags; uint32_t id = gNextInputDeviceId++; - if (id >= MAX_INPUT_DEVICES) return STATUS_NO_MEMORY; + if (id >= MAX_INPUT_DEVICES) return NTLSTATUS_NO_MEMORY; if (outDeviceId) *outDeviceId = id; DbgPrint("Input: registered device %u (%s)\n", id, name ? name : "unnamed"); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the input Submit Key operation. @@ -378,9 +378,9 @@ INPUT_KEY KeInputKbPoll(void) { // Waits until at least one keyboard event is available or the timeout expires. KSTATUS KeInputWaitKey(uint8_t alertable, uint64_t timeoutMs) { if (KeInputKbPoll() != INPUT_KEY_NONE) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (!gKeyboardEvent) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; for (;;) { EVENT* event = gKeyboardEvent; @@ -389,7 +389,7 @@ KSTATUS KeInputWaitKey(uint8_t alertable, uint64_t timeoutMs) { if (!KSUCCESS(s)) return s; if (KeInputKbPoll() != INPUT_KEY_NONE) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } @@ -505,17 +505,17 @@ static void KiInputQueueDestroy(OBJECT* object) { // Opens the default keyboard input queue as a waitable object. KSTATUS KeInputOpenQueue(INPUT_QUEUE** out) { - if (!out) return STATUS_INVALID_PARAMETER; + if (!out) return NTLSTATUS_INVALID_PARAMETER; *out = (INPUT_QUEUE*)0; - if (!gKeyboardEvent) return STATUS_FAILURE; + if (!gKeyboardEvent) return NTLSTATUS_FAILURE; INPUT_QUEUE* queue = (INPUT_QUEUE*)ObAllocateObject(ObjectTypeInputQueue, sizeof(INPUT_QUEUE)); - if (!queue) return STATUS_NO_MEMORY; + if (!queue) return NTLSTATUS_NO_MEMORY; queue->Header.Destroy = KiInputQueueDestroy; ObReferenceObject(&gKeyboardEvent->Header); queue->WaitEvent = gKeyboardEvent; *out = queue; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns the event that wakes when keyboard input can be read. diff --git a/code/kernel/ke_irp.c b/code/kernel/ke_irp.c index 33ced20..05ad272 100644 --- a/code/kernel/ke_irp.c +++ b/code/kernel/ke_irp.c @@ -66,13 +66,13 @@ __declspec(dllexport) void IrpQueueCancelAll(IRP_QUEUE* q, KSTATUS status) { // Remove locks. __declspec(dllexport) KSTATUS IoInitializeRemoveLock(IO_REMOVE_LOCK* lock) { - if (!lock) return STATUS_INVALID_PARAMETER; + if (!lock) return NTLSTATUS_INVALID_PARAMETER; memset(lock, 0, sizeof(*lock)); lock->Lock = (SPINLOCK)SPINLOCK_INIT; lock->IoCount = 1; // sentinel reference released by IoReleaseRemoveLockAndWait KSTATUS st = KeEventCreate(EventManualReset, 0, &lock->RemovedEvent); if (!KSUCCESS(st)) return st; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Releases remove Lock. @@ -87,15 +87,15 @@ __declspec(dllexport) void IoDestroyRemoveLock(IO_REMOVE_LOCK* lock) { // Implements the acquire Remove Lock operation. __declspec(dllexport) KSTATUS IoAcquireRemoveLock(IO_REMOVE_LOCK* lock, IRP* irp) { (void)irp; - if (!lock) return STATUS_INVALID_PARAMETER; + if (!lock) return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&lock->Lock); if (lock->Removing) { KeReleaseSpinlock(&lock->Lock, flags); - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; } _InterlockedIncrement(&lock->IoCount); KeReleaseSpinlock(&lock->Lock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Releases remove Lock. @@ -136,13 +136,13 @@ static size_t IoIrpSize(uint8_t stackCount) { // Creates irp. __declspec(dllexport) KSTATUS IoAllocateIrp(uint8_t stackCount, IRP** outIrp) { - if (!outIrp) return STATUS_INVALID_PARAMETER; + if (!outIrp) return NTLSTATUS_INVALID_PARAMETER; if (stackCount == 0) stackCount = 1; IRP* irp = (IRP*)MmAllocatePoolTag(IoIrpSize(stackCount), MM_POOL_TAG('i', 'r', 'p', ' ')); - if (!irp) return STATUS_NO_MEMORY; + if (!irp) return NTLSTATUS_NO_MEMORY; IoInitializeIrp(irp, stackCount); *outIrp = irp; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Releases irp. @@ -156,7 +156,7 @@ __declspec(dllexport) void IoInitializeIrp(IRP* irp, uint8_t stackCount) { if (stackCount == 0) stackCount = 1; memset(irp, 0, IoIrpSize(stackCount)); LIST_INIT(&irp->Link); - irp->Status = STATUS_FAILURE; + irp->Status = NTLSTATUS_FAILURE; irp->Information = 0; irp->CancelLock = (SPINLOCK)SPINLOCK_INIT; irp->StackCount = stackCount; @@ -276,9 +276,9 @@ __declspec(dllexport) void IoBuildDeviceIoControlIrp(IRP* irp, // Completion/submission. __declspec(dllexport) KSTATUS IoCompleteRequest(IRP* irp, KSTATUS status, size_t information) { - if (!irp) return STATUS_INVALID_PARAMETER; + if (!irp) return NTLSTATUS_INVALID_PARAMETER; if (irp->Flags & IRP_FLAG_COMPLETED) - return STATUS_ALREADY_EXISTS; + return NTLSTATUS_ALREADY_EXISTS; irp->Flags |= IRP_FLAG_COMPLETED; irp->Status = status; @@ -299,13 +299,13 @@ __declspec(dllexport) KSTATUS IoCompleteRequest(IRP* irp, KSTATUS status, size_t if (irp->CompletionFn) irp->CompletionFn(irp, irp->CompletionCtx); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Submits irp. __declspec(dllexport) KSTATUS IoSubmitIrp(DEVICE_OBJECT* device, IRP* irp) { - if (!device || !irp) return STATUS_INVALID_PARAMETER; - irp->Status = STATUS_FAILURE; + if (!device || !irp) return NTLSTATUS_INVALID_PARAMETER; + irp->Status = NTLSTATUS_FAILURE; irp->Information = 0; irp->Flags &= ~IRP_FLAG_COMPLETED; return IoCallDriver(device, irp); @@ -313,7 +313,7 @@ __declspec(dllexport) KSTATUS IoSubmitIrp(DEVICE_OBJECT* device, IRP* irp) { // Submits irp Sync. __declspec(dllexport) KSTATUS IoSubmitIrpSync(DEVICE_OBJECT* device, IRP* irp) { - if (!device || !irp) return STATUS_INVALID_PARAMETER; + if (!device || !irp) return NTLSTATUS_INVALID_PARAMETER; EVENT* ev = (EVENT*)0; KSTATUS st = KeEventCreate(EventAutoReset, 0, &ev); @@ -322,7 +322,7 @@ __declspec(dllexport) KSTATUS IoSubmitIrpSync(DEVICE_OBJECT* device, IRP* irp) { irp->CompletionEvent = ev; st = IoSubmitIrp(device, irp); - if (st == STATUS_PENDING) { + if (st == NTLSTATUS_PENDING) { KeWaitForEvent(ev, 0); st = irp->Status; } diff --git a/code/kernel/ke_irq.c b/code/kernel/ke_irq.c index 35f969f..e15526f 100644 --- a/code/kernel/ke_irq.c +++ b/code/kernel/ke_irq.c @@ -40,7 +40,7 @@ void KeIrqInitialize(const HAL_API *hal) { // Implements the irq Allocate Msi Vector operation. __declspec(dllexport) KSTATUS KeIrqAllocateMsiVector(uint8_t* outIrq) { - if (!outIrq) return STATUS_INVALID_PARAMETER; + if (!outIrq) return NTLSTATUS_INVALID_PARAMETER; for (uint8_t irq = MSI_IRQ_FIRST; irq <= MSI_IRQ_LAST; irq++) { IRQ_HANDLER_LIST* list = &gIrqHandlers[irq]; @@ -49,11 +49,11 @@ __declspec(dllexport) KSTATUS KeIrqAllocateMsiVector(uint8_t* outIrq) { *outIrq = irq; DbgPrint("KeIrq: allocated MSI vector slot IRQ %u vector 0x%02x\n", irq, 0x20u + irq); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } // Implements the irq Register operation. diff --git a/code/kernel/ke_mutex.c b/code/kernel/ke_mutex.c index fe50c5e..5139b8e 100644 --- a/code/kernel/ke_mutex.c +++ b/code/kernel/ke_mutex.c @@ -13,28 +13,28 @@ static void KiMutexDestroy(OBJECT* obj) { (void)obj; } // Implements the mutex Create operation. __declspec(dllexport) KSTATUS KeMutexCreate(MUTEX **out) { - if (!out) return STATUS_INVALID_PARAMETER; + if (!out) return NTLSTATUS_INVALID_PARAMETER; MUTEX* m = (MUTEX *)ObAllocateObject(ObjectTypeMutex, sizeof(MUTEX)); - if (!m) return STATUS_NO_MEMORY; + if (!m) return NTLSTATUS_NO_MEMORY; m->Header.Destroy = KiMutexDestroy; m->Lock = (SPINLOCK)SPINLOCK_INIT; m->Owner = (struct THREAD *)0; LIST_INIT(&m->WaitList); *out = m; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the acquire Mutex operation. __declspec(dllexport) KSTATUS KeAcquireMutex(MUTEX* mutex) { - if (!mutex) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; + if (!mutex) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; THREAD* self = KeGetCurrentThread(); uintptr_t flags = KeAcquireSpinlock(&mutex->Lock); if (!mutex->Owner) { mutex->Owner = self; KeReleaseSpinlock(&mutex->Lock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KePrepareBlockThread(self, &mutex->Header, 0); @@ -46,16 +46,16 @@ __declspec(dllexport) KSTATUS KeAcquireMutex(MUTEX* mutex) { // Implements the try Acquire Mutex operation. __declspec(dllexport) KSTATUS KeTryAcquireMutex(MUTEX* mutex) { - if (!mutex) return STATUS_INVALID_PARAMETER; + if (!mutex) return NTLSTATUS_INVALID_PARAMETER; THREAD* self = KeGetCurrentThread(); uintptr_t flags = KeAcquireSpinlock(&mutex->Lock); if (!mutex->Owner) { mutex->Owner = self; KeReleaseSpinlock(&mutex->Lock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KeReleaseSpinlock(&mutex->Lock, flags); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } // Releases mutex. @@ -71,7 +71,7 @@ __declspec(dllexport) void KeReleaseMutex(MUTEX* mutex) { // returns. Do not drop Owner to NULL, or another thread can steal it. mutex->Owner = waiter; KeReleaseSpinlock(&mutex->Lock, flags); - KeUnblockThreadWithStatus(waiter, STATUS_SUCCESS); + KeUnblockThreadWithStatus(waiter, NTLSTATUS_SUCCESS); return; } diff --git a/code/kernel/ke_process.c b/code/kernel/ke_process.c index 75b1e50..ad64d80 100644 --- a/code/kernel/ke_process.c +++ b/code/kernel/ke_process.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -53,10 +54,10 @@ PROCESS* KeGetSystemProcess(void) { // Creates system Process. KSTATUS KeCreateSystemProcess(PROCESS** out) { - if (!out) return STATUS_INVALID_PARAMETER; + if (!out) return NTLSTATUS_INVALID_PARAMETER; if (gSystemProcess) { *out = gSystemProcess; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } PROCESS* proc = (PROCESS*)0; @@ -69,7 +70,7 @@ KSTATUS KeCreateSystemProcess(PROCESS** out) { proc->Flags |= KE_PROCESS_FLAG_SYSTEM | KE_PROCESS_FLAG_TERMINATION_PROTECTED; gSystemProcess = proc; *out = proc; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the count Process Handles Locked operation. @@ -96,6 +97,38 @@ static void KiCopyTruncatedString(char* dst, size_t dstSize, const char* src, si dst[n] = '\0'; } +// Aggregates native structured-exception counters across all processes. +void KeQueryExceptionStats(SYS_EXCEPTION_STATS* statsOut) { + if (!statsOut) + return; + + memset(statsOut, 0, sizeof(*statsOut)); + statsOut->Size = sizeof(*statsOut); + statsOut->Version = SYS_STATS_VERSION; + + KiProcessInit(); + uintptr_t flags = KeAcquireSpinlock(&gProcessListLock); + LIST_ENTRY* head = &gProcessList; + for (LIST_ENTRY* node = head->Fwd; node != head; node = node->Fwd) { + PROCESS* p = CONTAINING_RECORD(node, PROCESS, GlobalLink); + uintptr_t exceptionFlags = KeAcquireSpinlock(&p->ExceptionLock); + statsOut->Delivered += p->ExceptionDeliveredCount; + statsOut->UserRaised += p->ExceptionUserRaisedCount; + statsOut->Continued += p->ExceptionContinuedCount; + statsOut->Unhandled += p->ExceptionUnhandledCount; + statsOut->InvalidContinue += p->ExceptionInvalidContinueCount; + if (p->ExceptionMaxNestedDispatch > statsOut->MaxNestedDispatch) + statsOut->MaxNestedDispatch = p->ExceptionMaxNestedDispatch; + if (p->LastExceptionCode) { + statsOut->LastCode = p->LastExceptionCode; + statsOut->LastExceptionAddress = p->LastExceptionAddress; + statsOut->LastFaultAddress = p->LastExceptionFaultAddress; + } + KeReleaseSpinlock(&p->ExceptionLock, exceptionFlags); + } + KeReleaseSpinlock(&gProcessListLock, flags); +} + // Copies process Info. size_t KeCopyProcessInfo(struct SYS_PROCESS_INFO* infoOut, size_t maxCount) { KiProcessInit(); @@ -130,6 +163,18 @@ size_t KeCopyProcessInfo(struct SYS_PROCESS_INFO* infoOut, size_t maxCount) { info->HandleCount = handleCount; info->ExitCode = exitCode; + uintptr_t exceptionFlags = KeAcquireSpinlock(&p->ExceptionLock); + info->ExceptionDelivered = p->ExceptionDeliveredCount; + info->ExceptionUserRaised = p->ExceptionUserRaisedCount; + info->ExceptionContinued = p->ExceptionContinuedCount; + info->ExceptionUnhandled = p->ExceptionUnhandledCount; + info->ExceptionInvalidContinue = p->ExceptionInvalidContinueCount; + info->ExceptionMaxNestedDispatch = p->ExceptionMaxNestedDispatch; + info->LastExceptionCode = p->LastExceptionCode; + info->LastExceptionAddress = p->LastExceptionAddress; + info->LastExceptionFaultAddress = p->LastExceptionFaultAddress; + KeReleaseSpinlock(&p->ExceptionLock, exceptionFlags); + if (exited) { info->State = SYS_PROCESS_STATE_EXITED; info->Flags |= SYS_PROCESS_FLAG_EXITED; @@ -201,11 +246,11 @@ static uint32_t KiWaitObjectTypeToSys(OBJECT_TYPE type) { // Copies one process's thread telemetry into caller-provided storage. KSTATUS KeCopyProcessThreadInfo(uint32_t pid, struct SYS_THREAD_INFO* infoOut, size_t maxCount, size_t* countOut) { - if (!countOut) return STATUS_INVALID_PARAMETER; - if (maxCount && !infoOut) return STATUS_INVALID_PARAMETER; + if (!countOut) return NTLSTATUS_INVALID_PARAMETER; + if (maxCount && !infoOut) return NTLSTATUS_INVALID_PARAMETER; PROCESS* process = KeGetProcessById(pid); - if (!process) return STATUS_NOT_FOUND; + if (!process) return NTLSTATUS_NOT_FOUND; THREAD* current = KeGetCurrentThread(); size_t count = 0; @@ -246,7 +291,7 @@ KSTATUS KeCopyProcessThreadInfo(uint32_t pid, struct SYS_THREAD_INFO* infoOut, s *countOut = count; ObDereferenceObject(&process->Header); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Releases all kernel objects still reachable from a process handle table. @@ -268,8 +313,10 @@ static void KiProcessReleaseAllHandles(PROCESS* proc) { } KeReleaseSpinlock(&proc->HandleLock, flags); - if (obj) + if (obj) { + KeNamedQueueUnpublishHandle(proc, (uint32_t)i, obj); ObDereferenceObject(obj); + } } } @@ -301,6 +348,13 @@ static void KiProcessRundownResources(PROCESS* proc) { proc->UserCmdlineSize = 0; proc->UserCwdBase = 0; proc->UserCwdSize = 0; + uintptr_t exceptionFlags = KeAcquireSpinlock(&proc->ExceptionLock); + proc->ExceptionDispatcher = 0; + proc->ExceptionDispatcherContext = 0; + proc->ExceptionStackBase = 0; + proc->ExceptionStackSize = 0; + proc->ExceptionDispatchFlags = SYS_EXCEPTION_DISPATCH_FLAG_NONE; + KeReleaseSpinlock(&proc->ExceptionLock, exceptionFlags); } // Destructor (called by ObDereferenceObject when RefCount hits zero). @@ -334,10 +388,10 @@ static void KiProcessDestroy(OBJECT* obj) { KSTATUS KeCreateProcess(const char* name, PROCESS **out) { KiProcessInit(); - if (!name || !out) return STATUS_INVALID_PARAMETER; + if (!name || !out) return NTLSTATUS_INVALID_PARAMETER; PROCESS* proc = (PROCESS *)ObAllocateObject(ObjectTypeProcess, sizeof(PROCESS)); - if (!proc) return STATUS_NO_MEMORY; + if (!proc) return NTLSTATUS_NO_MEMORY; proc->Header.Destroy = KiProcessDestroy; @@ -365,6 +419,21 @@ KSTATUS KeCreateProcess(const char* name, PROCESS **out) { proc->UserCwdSize = 0; proc->ModuleCount = 0; proc->ModuleLock = (SPINLOCK)SPINLOCK_INIT; + proc->ExceptionDispatcher = 0; + proc->ExceptionDispatcherContext = 0; + proc->ExceptionStackBase = 0; + proc->ExceptionStackSize = 0; + proc->ExceptionDispatchFlags = SYS_EXCEPTION_DISPATCH_FLAG_NONE; + proc->ExceptionDeliveredCount = 0; + proc->ExceptionUserRaisedCount = 0; + proc->ExceptionContinuedCount = 0; + proc->ExceptionUnhandledCount = 0; + proc->ExceptionInvalidContinueCount = 0; + proc->ExceptionMaxNestedDispatch = 0; + proc->LastExceptionCode = 0; + proc->LastExceptionAddress = 0; + proc->LastExceptionFaultAddress = 0; + proc->ExceptionLock = (SPINLOCK)SPINLOCK_INIT; proc->CurrentDirectory[0] = '\0'; proc->CurrentDirectoryLength = 0; proc->CurrentDrive = KeGetSystemRootDrive(); @@ -380,7 +449,7 @@ KSTATUS KeCreateProcess(const char* name, PROCESS **out) { // Create the manual-reset exit event (initially unsignaled). if (!KSUCCESS(KeEventCreate(EventManualReset, 0, &proc->ExitEvent))) { ObDereferenceObject(&proc->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } uintptr_t flags = KeAcquireSpinlock(&gProcessListLock); @@ -388,7 +457,7 @@ KSTATUS KeCreateProcess(const char* name, PROCESS **out) { KeReleaseSpinlock(&gProcessListLock, flags); *out = proc; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // KeSetupUserProcessEnvironment. @@ -396,24 +465,24 @@ static KSTATUS KiCopyEnvironmentStringView(PROCESS* proc, SYS_STRING_VIEW src, uintptr_t* baseOut, size_t* sizeOut) { - if (!baseOut || !sizeOut) return STATUS_INVALID_PARAMETER; + if (!baseOut || !sizeOut) return NTLSTATUS_INVALID_PARAMETER; *baseOut = 0; *sizeOut = 0; - if (!SysSvIsValid(src)) return STATUS_INVALID_PARAMETER; - if (SysSvContainsByte(src, '\0')) return STATUS_INVALID_PARAMETER; - if (src.Length == (size_t)-1) return STATUS_BUFFER_TOO_SMALL; + if (!SysSvIsValid(src)) return NTLSTATUS_INVALID_PARAMETER; + if (SysSvContainsByte(src, '\0')) return NTLSTATUS_INVALID_PARAMETER; + if (src.Length == (size_t)-1) return NTLSTATUS_BUFFER_TOO_SMALL; size_t len = src.Length + 1; char* dst = (char*)MmAllocateUserMemoryForProcess(proc, len); - if (!dst) return STATUS_NO_MEMORY; + if (!dst) return NTLSTATUS_NO_MEMORY; if (src.Length) memcpy(dst, src.Data, src.Length); dst[src.Length] = '\0'; *baseOut = (uintptr_t)dst; *sizeOut = len; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS KiCopyEnvironmentStringViewFixed(PROCESS* proc, @@ -421,16 +490,16 @@ static KSTATUS KiCopyEnvironmentStringViewFixed(PROCESS* proc, size_t capacity, uintptr_t* baseOut, size_t* sizeOut) { - if (!baseOut || !sizeOut || capacity == 0) return STATUS_INVALID_PARAMETER; + if (!baseOut || !sizeOut || capacity == 0) return NTLSTATUS_INVALID_PARAMETER; *baseOut = 0; *sizeOut = 0; - if (!SysSvIsValid(src)) return STATUS_INVALID_PARAMETER; - if (SysSvContainsByte(src, '\0')) return STATUS_INVALID_PARAMETER; - if (src.Length + 1 > capacity) return STATUS_BUFFER_TOO_SMALL; + if (!SysSvIsValid(src)) return NTLSTATUS_INVALID_PARAMETER; + if (SysSvContainsByte(src, '\0')) return NTLSTATUS_INVALID_PARAMETER; + if (src.Length + 1 > capacity) return NTLSTATUS_BUFFER_TOO_SMALL; char* dst = (char*)MmAllocateUserMemoryForProcess(proc, capacity); - if (!dst) return STATUS_NO_MEMORY; + if (!dst) return NTLSTATUS_NO_MEMORY; memset(dst, 0, capacity); if (src.Length) memcpy(dst, src.Data, src.Length); @@ -438,7 +507,7 @@ static KSTATUS KiCopyEnvironmentStringViewFixed(PROCESS* proc, *baseOut = (uintptr_t)dst; *sizeOut = capacity; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Releases partial Process Environment. @@ -473,16 +542,16 @@ static KSTATUS KiFormatNativeCwdV(const PROCESS* proc, size_t outSize, size_t* lengthOut) { if (lengthOut) *lengthOut = 0; - if (!out || outSize == 0) return STATUS_INVALID_PARAMETER; + if (!out || outSize == 0) return NTLSTATUS_INVALID_PARAMETER; out[0] = '\0'; - if (!SysSvIsValid(currentDirectory)) return STATUS_INVALID_PARAMETER; - if (SysSvContainsByte(currentDirectory, '\0')) return STATUS_INVALID_PARAMETER; + if (!SysSvIsValid(currentDirectory)) return NTLSTATUS_INVALID_PARAMETER; + if (SysSvContainsByte(currentDirectory, '\0')) return NTLSTATUS_INVALID_PARAMETER; uint8_t drive = proc ? proc->CurrentDrive : 0; if (drive > 7) drive = 0; - if (currentDirectory.Length + 4 > outSize) return STATUS_BUFFER_TOO_SMALL; + if (currentDirectory.Length + 4 > outSize) return NTLSTATUS_BUFFER_TOO_SMALL; out[0] = (char)('0' + drive); out[1] = ':'; @@ -492,20 +561,20 @@ static KSTATUS KiFormatNativeCwdV(const PROCESS* proc, out[3 + currentDirectory.Length] = '\0'; if (lengthOut) *lengthOut = 3 + currentDirectory.Length; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KSTATUS KeSetupUserProcessEnvironment(PROCESS* proc, SYS_STRING_VIEW imagePath, SYS_STRING_VIEW commandLine, SYS_STRING_VIEW currentDirectory) { - if (!proc || imagePath.Length == 0) return STATUS_INVALID_PARAMETER; + if (!proc || imagePath.Length == 0) return NTLSTATUS_INVALID_PARAMETER; if (!SysSvIsValid(imagePath) || !SysSvIsValid(commandLine) || !SysSvIsValid(currentDirectory)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (SysSvContainsByte(imagePath, '\0') || SysSvContainsByte(commandLine, '\0') || SysSvContainsByte(currentDirectory, '\0')) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; SYS_STRING_VIEW finalCommandLine = commandLine.Length ? commandLine : imagePath; SYS_STRING_VIEW finalCwdRel = currentDirectory; @@ -533,7 +602,7 @@ KSTATUS KeSetupUserProcessEnvironment(PROCESS* proc, if (!KSUCCESS(s)) goto fail; SYS_PEB* peb = (SYS_PEB*)MmAllocateUserMemoryForProcess(proc, sizeof(SYS_PEB)); - if (!peb) { s = STATUS_NO_MEMORY; goto fail; } + if (!peb) { s = NTLSTATUS_NO_MEMORY; goto fail; } memset(peb, 0, sizeof(SYS_PEB)); peb->Magic = SYS_PEB_MAGIC; @@ -545,7 +614,7 @@ KSTATUS KeSetupUserProcessEnvironment(PROCESS* proc, proc->UserPebBase = (uintptr_t)peb; proc->UserPebSize = sizeof(SYS_PEB); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; fail: KiFreePartialProcessEnvironment(proc); @@ -568,8 +637,8 @@ void KeCompleteProcessExitIfLastThread(PROCESS* process) { // Implements the exit Process operation. KSTATUS KeExitProcess(PROCESS* process, int32_t exitCode) { - if (!process) return STATUS_INVALID_PARAMETER; - if (KeIsProcessTerminationProtected(process)) return STATUS_ACCESS_DENIED; + if (!process) return NTLSTATUS_INVALID_PARAMETER; + if (KeIsProcessTerminationProtected(process)) return NTLSTATUS_ACCESS_DENIED; process->ExitCode = exitCode; _InterlockedExchange(&process->Terminating, 1); @@ -578,13 +647,13 @@ KSTATUS KeExitProcess(PROCESS* process, int32_t exitCode) { // not drop the process object here: each thread owns one process reference, // and KiThreadDestroy releases that reference after unlinking the thread. KeCompleteProcessExitIfLastThread(process); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the terminate Process operation. KSTATUS KeTerminateProcess(PROCESS* process, int32_t exitCode) { - if (!process) return STATUS_INVALID_PARAMETER; - if (KeIsProcessTerminationProtected(process)) return STATUS_ACCESS_DENIED; + if (!process) return NTLSTATUS_INVALID_PARAMETER; + if (KeIsProcessTerminationProtected(process)) return NTLSTATUS_ACCESS_DENIED; process->ExitCode = exitCode; _InterlockedExchange(&process->Terminating, 1); @@ -606,7 +675,7 @@ KSTATUS KeTerminateProcess(PROCESS* process, int32_t exitCode) { // thread crashes, those waiters would otherwise keep ThreadCount > 0 // and prevent the process ExitEvent from waking the shell. if (t->State == ThreadWaiting) - KeAbortThreadWait(t, STATUS_ALERTED); + KeAbortThreadWait(t, NTLSTATUS_ALERTED); else (void)KeAlertThread(t); @@ -621,7 +690,7 @@ KSTATUS KeTerminateProcess(PROCESS* process, int32_t exitCode) { KeReleaseSpinlock(&process->HandleLock, flags); KeCompleteProcessExitIfLastThread(process); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Checks whether process Terminating. @@ -636,14 +705,14 @@ int KeIsProcessTerminationProtected(PROCESS* process) { // Copies the recorded process exit code. KSTATUS KeGetProcessExitCode(PROCESS* process, int32_t* exitCodeOut) { - if (!process || !exitCodeOut) return STATUS_INVALID_PARAMETER; + if (!process || !exitCodeOut) return NTLSTATUS_INVALID_PARAMETER; *exitCodeOut = process->ExitCode; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Handle table. KSTATUS KeAllocateHandleWithRights(PROCESS* process, OBJECT* object, uint32_t rights, uint32_t* handleOut) { - if (!process || !object || !handleOut || rights == 0) return STATUS_INVALID_PARAMETER; + if (!process || !object || !handleOut || rights == 0) return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&process->HandleLock); @@ -655,12 +724,12 @@ KSTATUS KeAllocateHandleWithRights(PROCESS* process, OBJECT* object, uint32_t ri process->Handles[i].Flags = 0; *handleOut = (uint32_t)i; KeReleaseSpinlock(&process->HandleLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } KeReleaseSpinlock(&process->HandleLock, flags); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } // Creates handle. @@ -681,6 +750,7 @@ void KeCloseHandle(PROCESS* process, uint32_t handle) { KeReleaseSpinlock(&process->HandleLock, flags); if (obj->Type == ObjectTypeFile) (void)IoFlushFile((FILE_OBJECT*)obj); + KeNamedQueueUnpublishHandle(process, handle, obj); ObDereferenceObject(obj); return; } @@ -719,18 +789,18 @@ uint32_t KeGetHandleRights(PROCESS* process, uint32_t handle) { // Duplicates a handle from one process table into another. KSTATUS KeDuplicateHandleToProcess(PROCESS* sourceProcess, uint32_t sourceHandle, PROCESS* targetProcess, uint32_t desiredRights, uint32_t duplicateFlags, uint32_t* targetHandleOut) { - if (!sourceProcess || !targetProcess || !targetHandleOut) return STATUS_INVALID_PARAMETER; - if (sourceHandle == 0 || sourceHandle >= HANDLE_TABLE_SIZE) return STATUS_INVALID_HANDLE; + if (!sourceProcess || !targetProcess || !targetHandleOut) return NTLSTATUS_INVALID_PARAMETER; + if (sourceHandle == 0 || sourceHandle >= HANDLE_TABLE_SIZE) return NTLSTATUS_INVALID_HANDLE; const uint32_t validDuplicateFlags = SYS_DUPLICATE_HANDLE_FLAG_SAME_RIGHTS; const uint32_t publicHandleRights = SYS_HANDLE_RIGHT_ALL; - if ((duplicateFlags & ~validDuplicateFlags) != 0) return STATUS_INVALID_PARAMETER; + if ((duplicateFlags & ~validDuplicateFlags) != 0) return NTLSTATUS_INVALID_PARAMETER; if ((duplicateFlags & SYS_DUPLICATE_HANDLE_FLAG_SAME_RIGHTS) != 0 && desiredRights != 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if ((duplicateFlags & SYS_DUPLICATE_HANDLE_FLAG_SAME_RIGHTS) == 0) { - if (desiredRights == 0) return STATUS_INVALID_PARAMETER; - if ((desiredRights & ~publicHandleRights) != 0) return STATUS_INVALID_PARAMETER; + if (desiredRights == 0) return NTLSTATUS_INVALID_PARAMETER; + if ((desiredRights & ~publicHandleRights) != 0) return NTLSTATUS_INVALID_PARAMETER; } OBJECT* obj = NULL; @@ -740,11 +810,11 @@ KSTATUS KeDuplicateHandleToProcess(PROCESS* sourceProcess, uint32_t sourceHandle HANDLE_ENTRY* entry = &sourceProcess->Handles[sourceHandle]; if (!entry->Object) { KeReleaseSpinlock(&sourceProcess->HandleLock, savedFlags); - return STATUS_INVALID_HANDLE; + return NTLSTATUS_INVALID_HANDLE; } if ((entry->Rights & HANDLE_RIGHT_DUPLICATE) == 0) { KeReleaseSpinlock(&sourceProcess->HandleLock, savedFlags); - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; } obj = entry->Object; @@ -756,7 +826,7 @@ KSTATUS KeDuplicateHandleToProcess(PROCESS* sourceProcess, uint32_t sourceHandle if ((duplicateFlags & SYS_DUPLICATE_HANDLE_FLAG_SAME_RIGHTS) == 0) { if ((desiredRights & ~sourceRights) != 0) { ObDereferenceObject(obj); - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; } targetRights = desiredRights; } diff --git a/code/kernel/ke_queue.c b/code/kernel/ke_queue.c index bab2eb9..17a8193 100644 --- a/code/kernel/ke_queue.c +++ b/code/kernel/ke_queue.c @@ -84,13 +84,13 @@ static uint64_t KiQueueRemainingMilliseconds(uint64_t deadlineTick) { // Waits for a queue state event using either an infinite or finite timeout. static KSTATUS KiQueueWaitForEvent(QUEUE* queue, EVENT* event, uint64_t timeoutMilliseconds, uint64_t deadlineTick) { if (!queue || !event) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint64_t waitMilliseconds = timeoutMilliseconds; if (timeoutMilliseconds != QUEUE_TIMEOUT_INFINITE) { waitMilliseconds = KiQueueRemainingMilliseconds(deadlineTick); if (waitMilliseconds == 0) - return STATUS_TIMEOUT; + return NTLSTATUS_TIMEOUT; } EVENT* events[1] = { event }; @@ -99,11 +99,11 @@ static KSTATUS KiQueueWaitForEvent(QUEUE* queue, EVENT* event, uint64_t timeoutM // Creates a fixed-depth queue with waitable occupancy and capacity events. KSTATUS KeQueueCreate(QUEUE **out) { - if (!out) return STATUS_INVALID_PARAMETER; + if (!out) return NTLSTATUS_INVALID_PARAMETER; *out = (QUEUE*)0; QUEUE* q = (QUEUE *)ObAllocateObject(ObjectTypeQueue, sizeof(QUEUE)); - if (!q) return STATUS_NO_MEMORY; + if (!q) return NTLSTATUS_NO_MEMORY; q->Header.Destroy = KiQueueDestroy; q->Lock = (SPINLOCK)SPINLOCK_INIT; q->Head = q->Tail = q->Count = 0; @@ -121,13 +121,13 @@ KSTATUS KeQueueCreate(QUEUE **out) { } *out = q; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Sends one fixed-size queue message, waiting according to the timeout contract. KSTATUS KeSendMessage(QUEUE* queue, const QUEUE_MESSAGE* msg, uint64_t timeoutMilliseconds) { - if (!queue || !msg) return STATUS_INVALID_PARAMETER; - if (timeoutMilliseconds != 0 && !KeCanWait()) return STATUS_INVALID_IRQL; + if (!queue || !msg) return NTLSTATUS_INVALID_PARAMETER; + if (timeoutMilliseconds != 0 && !KeCanWait()) return NTLSTATUS_INVALID_IRQL; uint64_t deadlineTick = 0; if (timeoutMilliseconds != 0 && timeoutMilliseconds != QUEUE_TIMEOUT_INFINITE) @@ -142,24 +142,24 @@ KSTATUS KeSendMessage(QUEUE* queue, const QUEUE_MESSAGE* msg, uint64_t timeoutMi queue->Count++; KiQueueNoteInsertedLocked(queue, previousCount); KeReleaseSpinlock(&queue->Lock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KeClearEvent(queue->NotFullEvent); KeReleaseSpinlock(&queue->Lock, flags); if (timeoutMilliseconds == 0) - return STATUS_WOULD_BLOCK; + return NTLSTATUS_WOULD_BLOCK; KSTATUS s = KiQueueWaitForEvent(queue, queue->NotFullEvent, timeoutMilliseconds, deadlineTick); - if (s == STATUS_TIMEOUT || KFAILED(s)) + if (s == NTLSTATUS_TIMEOUT || KFAILED(s)) return s; } } // Receives one fixed-size queue message, waiting according to the timeout contract. KSTATUS KeReceiveMessage(QUEUE* queue, QUEUE_MESSAGE* msg, uint64_t timeoutMilliseconds) { - if (!queue || !msg) return STATUS_INVALID_PARAMETER; - if (timeoutMilliseconds != 0 && !KeCanWait()) return STATUS_INVALID_IRQL; + if (!queue || !msg) return NTLSTATUS_INVALID_PARAMETER; + if (timeoutMilliseconds != 0 && !KeCanWait()) return NTLSTATUS_INVALID_IRQL; uint64_t deadlineTick = 0; if (timeoutMilliseconds != 0 && timeoutMilliseconds != QUEUE_TIMEOUT_INFINITE) @@ -174,16 +174,16 @@ KSTATUS KeReceiveMessage(QUEUE* queue, QUEUE_MESSAGE* msg, uint64_t timeoutMilli queue->Count--; KiQueueNoteRemovedLocked(queue, previousCount); KeReleaseSpinlock(&queue->Lock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KeClearEvent(queue->NotEmptyEvent); KeReleaseSpinlock(&queue->Lock, flags); if (timeoutMilliseconds == 0) - return STATUS_WOULD_BLOCK; + return NTLSTATUS_WOULD_BLOCK; KSTATUS s = KiQueueWaitForEvent(queue, queue->NotEmptyEvent, timeoutMilliseconds, deadlineTick); - if (s == STATUS_TIMEOUT || KFAILED(s)) + if (s == NTLSTATUS_TIMEOUT || KFAILED(s)) return s; } } diff --git a/code/kernel/ke_sched.c b/code/kernel/ke_sched.c index 3e1be18..6cda8fd 100644 --- a/code/kernel/ke_sched.c +++ b/code/kernel/ke_sched.c @@ -322,13 +322,13 @@ void KiInitializeSchedulerGlobal(void) { // Creates idle Thread For Cpu. KSTATUS KiCreateIdleThreadForCpu(KCPU* cpu) { if (!cpu || !gIdleProcess) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (cpu->IdleThread) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; THREAD* idle = (THREAD *)ObAllocateObject(ObjectTypeThread, sizeof(THREAD)); if (!idle) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; idle->Header.Destroy = (void *)0; idle->ThreadId = cpu->CpuIndex ? (0x80000000u | cpu->CpuIndex) : 0; @@ -347,11 +347,11 @@ KSTATUS KiCreateIdleThreadForCpu(KCPU* cpu) { idle->AffinityMask = (cpu->CpuIndex < 64) ? (1ULL << cpu->CpuIndex) : 0ULL; idle->Owner = gIdleProcess; idle->WaitObject = (OBJECT *)0; - idle->WaitStatus = STATUS_SUCCESS; + idle->WaitStatus = NTLSTATUS_SUCCESS; idle->WaitListHead = (LIST_ENTRY*)0; idle->AlertableWait = 0; idle->SleepUntilTick = 0; - idle->TimeoutStatus = STATUS_SUCCESS; + idle->TimeoutStatus = NTLSTATUS_SUCCESS; idle->UserStackBase = (void*)0; idle->Teb = (void*)0; idle->TebSize = 0; @@ -364,7 +364,7 @@ KSTATUS KiCreateIdleThreadForCpu(KCPU* cpu) { void* kstack = MmAllocatePoolTag(KSTACK_SIZE, MM_POOL_TAG('k', 's', 't', 'k')); if (!kstack) { ObDereferenceObject(&idle->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } idle->KernelStackBase = kstack; idle->KernelStackTop = (uintptr_t)kstack + KSTACK_SIZE; @@ -391,7 +391,7 @@ KSTATUS KiCreateIdleThreadForCpu(KCPU* cpu) { cpu->CurrentThread = idle; cpu->OutgoingThread = (THREAD*)0; idle->SwitchLockCookie = 0x202ULL; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Initializes scheduler. @@ -639,7 +639,7 @@ static void KiWakeThreadLocked(THREAD* thread, KSTATUS status) { thread->WaitListHead = (LIST_ENTRY*)0; thread->AlertableWait = 0; thread->SleepUntilTick = 0; - thread->TimeoutStatus = STATUS_SUCCESS; + thread->TimeoutStatus = NTLSTATUS_SUCCESS; thread->CpuBurstTicks = 0; thread->QuantaConsumed = 0; @@ -669,7 +669,7 @@ void KeUnblockThreadFromWaitListWithStatus(THREAD* thread, KSTATUS status) { ListRemove(&thread->SchedulerLink); thread->WaitListHead = (LIST_ENTRY*)0; thread->SleepUntilTick = 0; - thread->TimeoutStatus = STATUS_SUCCESS; + thread->TimeoutStatus = NTLSTATUS_SUCCESS; } KiWakeThreadLocked(thread, status); KeReleaseSpinlock(&gSchedLock, flags); @@ -787,13 +787,13 @@ void KeSchedulerTick(void) { // Arms a timeout for the current thread after a wait primitive has prepared it to block. KSTATUS KeArmCurrentThreadTimeout(uint64_t milliseconds, KSTATUS timeoutStatus) { if (milliseconds == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!KeCanWait()) - return STATUS_INVALID_IRQL; + return NTLSTATUS_INVALID_IRQL; THREAD* self = KeGetCurrentThread(); if (!self || self->IsIdleThread) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint64_t ticks = milliseconds / SCHED_TICK_MS; if ((milliseconds % SCHED_TICK_MS) != 0) @@ -805,7 +805,7 @@ KSTATUS KeArmCurrentThreadTimeout(uint64_t milliseconds, KSTATUS timeoutStatus) if (self->State != ThreadWaiting || self->WaitListHead != (LIST_ENTRY*)0 || self->RunningCpu != KeGetCurrentCpu()->CpuIndex) { KeReleaseSpinlock(&gSchedLock, flags); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } uint64_t now = gSchedStats.Ticks; @@ -818,22 +818,22 @@ KSTATUS KeArmCurrentThreadTimeout(uint64_t milliseconds, KSTATUS timeoutStatus) self->TimeoutStatus = timeoutStatus; ListInsertTail(&gSleepList, &self->SchedulerLink); KeReleaseSpinlock(&gSchedLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the delay Thread operation. __declspec(dllexport) KSTATUS KeDelayThread(uint64_t milliseconds) { if (milliseconds == 0) { KeYield(); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (!KeCanWait()) - return STATUS_INVALID_IRQL; + return NTLSTATUS_INVALID_IRQL; THREAD* self = KeGetCurrentThread(); if (!self || self->IsIdleThread) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint64_t ticks = milliseconds / SCHED_TICK_MS; if ((milliseconds % SCHED_TICK_MS) != 0) @@ -846,7 +846,7 @@ __declspec(dllexport) KSTATUS KeDelayThread(uint64_t milliseconds) { if (self->Queued || self->State != ThreadRunning || self->RunningCpu != KeGetCurrentCpu()->CpuIndex) { KeReleaseSpinlock(&gSchedLock, flags); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } uint64_t now = gSchedStats.Ticks; @@ -856,11 +856,11 @@ __declspec(dllexport) KSTATUS KeDelayThread(uint64_t milliseconds) { self->State = ThreadWaiting; self->WaitObject = (OBJECT*)0; - self->WaitStatus = STATUS_PENDING; + self->WaitStatus = NTLSTATUS_PENDING; self->WaitListHead = &gSleepList; self->AlertableWait = 0; self->SleepUntilTick = wakeTick; - self->TimeoutStatus = STATUS_SUCCESS; + self->TimeoutStatus = NTLSTATUS_SUCCESS; ListInsertTail(&gSleepList, &self->SchedulerLink); KeReleaseSpinlock(&gSchedLock, flags); diff --git a/code/kernel/ke_selftest.c b/code/kernel/ke_selftest.c index 3004636..43fc155 100644 --- a/code/kernel/ke_selftest.c +++ b/code/kernel/ke_selftest.c @@ -152,7 +152,7 @@ static void KiApcAlertableSelfTestWorker(void* arg) { DbgPrint("APC selftest: alertable wait returned status=%u delivered=%d\n", s, st->ApcDelivered); - if (s != STATUS_KERNEL_APC) + if (s != NTLSTATUS_KERNEL_APC) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alertable wait returned wrong status=%u\n", s); if (st->ApcDelivered != 1) @@ -298,7 +298,7 @@ static void KiRunKernelApcSelfTest(void) { KI_APC_ALERTABLE_SELFTEST_STATE st; KAPC apc; memset(&st, 0, sizeof(st)); - st.WaitStatus = STATUS_PENDING; + st.WaitStatus = NTLSTATUS_PENDING; KSTATUS s; s = KeEventCreate(EventAutoReset, 0, &st.ReadyEvent); @@ -336,7 +336,7 @@ static void KiRunKernelApcSelfTest(void) { if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alert finished wait failed %d\n", s); - if (st.WaitStatus != STATUS_KERNEL_APC || st.ApcDelivered != 1) + if (st.WaitStatus != NTLSTATUS_KERNEL_APC || st.ApcDelivered != 1) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alertable result bad status=%u delivered=%d\n", st.WaitStatus, st.ApcDelivered); @@ -447,7 +447,7 @@ static void KiRunIrpKernelApcSelfTest(const HAL_API* hal) { DbgPrint("IRP/APC selftest: submitting drive=0 lba=0 sectors=1\n"); s = IoSubmitIrp(st.DiskDevice, &st.Irp); - if (s != STATUS_PENDING) + if (s != NTLSTATUS_PENDING) KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: IoSubmitIrp returned %u\n", s); s = KeWaitForEvent(st.CompletionEvent, 0); @@ -501,13 +501,13 @@ static void KiRunPfnDatabaseSelfTest(void) { if (!KSUCCESS(MmPfnPin(frame)) || pfn->PinCount != 1) KePanic(KE_PANIC_CODE_SELFTEST, "PFN selftest: pin failed pin=%u\n", pfn->PinCount); - if (MmPfnFree(frame) != STATUS_ACCESS_DENIED) + if (MmPfnFree(frame) != NTLSTATUS_ACCESS_DENIED) KePanic(KE_PANIC_CODE_SELFTEST, "PFN selftest: pinned frame was freed\n"); if (!KSUCCESS(MmPfnUnpin(frame)) || pfn->PinCount != 0) KePanic(KE_PANIC_CODE_SELFTEST, "PFN selftest: unpin failed pin=%u\n", pfn->PinCount); if (!KSUCCESS(MmPfnAddMapping(frame)) || pfn->MappedCount != 1) KePanic(KE_PANIC_CODE_SELFTEST, "PFN selftest: mapping add failed maps=%u\n", pfn->MappedCount); - if (MmPfnFree(frame) != STATUS_ACCESS_DENIED) + if (MmPfnFree(frame) != NTLSTATUS_ACCESS_DENIED) KePanic(KE_PANIC_CODE_SELFTEST, "PFN selftest: mapped frame was freed\n"); if (!KSUCCESS(MmPfnRemoveMapping(frame)) || pfn->MappedCount != 0) KePanic(KE_PANIC_CODE_SELFTEST, "PFN selftest: mapping remove failed maps=%u\n", pfn->MappedCount); @@ -589,7 +589,7 @@ static void KiRunMemoryMappingSelfTest(void) { PHYSICAL_ADDRESS phys = 0; uint64_t flags = 0; KSTATUS s = MmPteQueryPageFor(MmPteQuerySelfTest, 0, &phys, &flags); - if (s != STATUS_NOT_FOUND) { + if (s != NTLSTATUS_NOT_FOUND) { KePanic(KE_PANIC_CODE_SELFTEST, "MM selftest: virtual page zero is mapped phys=%016llx flags=%016llx status=%u\n", (unsigned long long)phys, (unsigned long long)flags, @@ -598,7 +598,7 @@ static void KiRunMemoryMappingSelfTest(void) { uintptr_t testVa = 0xFFFFA00000000000ULL; s = MmPteQueryPageFor(MmPteQuerySelfTest, testVa, &phys, &flags); - if (s != STATUS_NOT_FOUND) { + if (s != NTLSTATUS_NOT_FOUND) { KePanic(KE_PANIC_CODE_SELFTEST, "MM selftest: test VA already mapped va=%016llx phys=%016llx flags=%016llx\n", (unsigned long long)testVa, (unsigned long long)phys, @@ -643,7 +643,7 @@ static void KiRunMemoryMappingSelfTest(void) { KePanic(KE_PANIC_CODE_SELFTEST, "MM selftest: MmPteUnmapPage failed status=%u\n", s); s = MmPteQueryPageFor(MmPteQuerySelfTest, testVa, &phys, &flags); - if (s != STATUS_NOT_FOUND) + if (s != NTLSTATUS_NOT_FOUND) KePanic(KE_PANIC_CODE_SELFTEST, "MM selftest: test VA still mapped after unmap status=%u\n", s); MmPfnFree(frame); @@ -688,11 +688,11 @@ static void KiRunVadSparseSelfTest(void) { uint64_t queryFlags = 0; s = MmVadQuery(process, p, &queryBase, &querySize, &queryFlags, (MM_VAD_TYPE*)0, (uint32_t*)0); if (!KSUCCESS(s) || queryBase != p || querySize != PAGE_SIZE || !(queryFlags & PAGE_WRITE)) - KePanic(KE_PANIC_CODE_SELFTEST, "VAD selftest: first query failed status=%u base=%p size=%llu flags=%016llx\n", + KePanic(KE_PANIC_CODE_SELFTEST, "VAD selftest: first query failed status=%u base=0x%016llX size=%llu flags=%016llx\n", s, queryBase, (unsigned long long)querySize, (unsigned long long)queryFlags); s = MmPteQueryPageFor(MmPteQuerySelfTest, (uintptr_t)p, (PHYSICAL_ADDRESS*)0, (uint64_t*)0); - if (s != STATUS_NOT_FOUND) + if (s != NTLSTATUS_NOT_FOUND) KePanic(KE_PANIC_CODE_SELFTEST, "VAD selftest: demand-zero page was mapped before access status=%u\n", s); s = MmVadEnsureResident(process, p, PAGE_SIZE, PAGE_WRITE | PAGE_USER); @@ -703,7 +703,7 @@ static void KiRunVadSparseSelfTest(void) { KePanic(KE_PANIC_CODE_SELFTEST, "VAD selftest: sparse demand-zero materialization failed %u\n", s); s = MmVadQuery(process, p + PAGE_SIZE, &queryBase, &querySize, &queryFlags, (MM_VAD_TYPE*)0, (uint32_t*)0); - if (s != STATUS_NOT_FOUND) + if (s != NTLSTATUS_NOT_FOUND) KePanic(KE_PANIC_CODE_SELFTEST, "VAD selftest: uncommitted hole queried as committed status=%u\n", s); p[0] = 0x5A; @@ -714,7 +714,7 @@ static void KiRunVadSparseSelfTest(void) { KePanic(KE_PANIC_CODE_SELFTEST, "VAD selftest: NOACCESS protect failed %u\n", s); s = MmPteQueryPageFor(MmPteQuerySelfTest, (uintptr_t)p, (PHYSICAL_ADDRESS*)0, (uint64_t*)0); - if (s != STATUS_NOT_FOUND) + if (s != NTLSTATUS_NOT_FOUND) KePanic(KE_PANIC_CODE_SELFTEST, "VAD selftest: NOACCESS page still had a PTE status=%u\n", s); s = MmVadQuery(process, p, &queryBase, &querySize, &queryFlags, (MM_VAD_TYPE*)0, (uint32_t*)0); @@ -901,10 +901,10 @@ static void KiRunVadSwapSelfTest(void) { void* trimmed = (void*)0; s = MmVadTrimOnePageForTest(process, &trimmed); if (!KSUCCESS(s) || trimmed != base) - KePanic(KE_PANIC_CODE_SELFTEST, "VAD swap selftest: trim failed status=%u trimmed=%p base=%p\n", s, trimmed, base); + KePanic(KE_PANIC_CODE_SELFTEST, "VAD swap selftest: trim failed status=%u trimmed=0x%016llX base=0x%016llX\n", s, trimmed, base); s = MmPteQueryPageFor(MmPteQuerySelfTest, (uintptr_t)base, (PHYSICAL_ADDRESS*)0, (uint64_t*)0); - if (s != STATUS_NOT_FOUND) + if (s != NTLSTATUS_NOT_FOUND) KePanic(KE_PANIC_CODE_SELFTEST, "VAD swap selftest: swapped page still had a PTE status=%u\n", s); s = MmVadResolveUserPageFault(process, (uintptr_t)base, 0); @@ -944,7 +944,7 @@ static void KiRunStringViewSelfTest(void) { // accept embedded NUL bytes. This must fail before reaching any filesystem. FILE_OBJECT* f = (FILE_OBJECT*)0; KSTATUS s = IoOpenFile(SysSvFromParts("system/init.exe\0junk", 20), &f); - if (s != STATUS_INVALID_PARAMETER) + if (s != NTLSTATUS_INVALID_PARAMETER) KePanic(KE_PANIC_CODE_SELFTEST, "STRINGVIEW selftest: embedded-NUL path status=%u\n", s); DbgPrint("STRINGVIEW selftest: sample view='%v' len=%llu\n", @@ -1007,7 +1007,7 @@ static void KiRunAsyncFileIoSelfTest(void) { KI_FILE_ASYNC_SELFTEST_STATE st; memset(&st, 0, sizeof(st)); - st.Iosb.Status = STATUS_FAILURE; + st.Iosb.Status = NTLSTATUS_FAILURE; KSTATUS s = IoOpenFile(SYS_SV_LITERAL("system/init.exe"), &st.File); if (!KSUCCESS(s)) { @@ -1042,14 +1042,14 @@ static void KiRunAsyncFileIoSelfTest(void) { (MM_LOCKED_USER_BUFFER*)0, (MM_LOCKED_USER_BUFFER*)0, &readReq); - if (s != STATUS_PENDING) + if (s != NTLSTATUS_PENDING) KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: submit returned %u\n", s); s = KeWaitForEvent(st.CompletionEvent, 1); - if (s != STATUS_SUCCESS && s != STATUS_KERNEL_APC) + if (s != NTLSTATUS_SUCCESS && s != NTLSTATUS_KERNEL_APC) KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: wait returned %u\n", s); - if (st.Iosb.Status == STATUS_PENDING) { + if (st.Iosb.Status == NTLSTATUS_PENDING) { s = KeWaitForEvent(st.CompletionEvent, 0); if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: final event wait returned %u\n", s); @@ -1088,7 +1088,7 @@ static void KiRunAsyncFileIoSelfTest(void) { size_t got = 0; memset(verify, 0, sizeof(verify)); - wiosb.Status = STATUS_FAILURE; + wiosb.Status = NTLSTATUS_FAILURE; wiosb.Information = 0; (void)IoDeleteFile(SYS_SV_LITERAL("asyncio.tmp")); @@ -1114,7 +1114,7 @@ static void KiRunAsyncFileIoSelfTest(void) { (MM_LOCKED_USER_BUFFER*)0, (MM_LOCKED_USER_BUFFER*)0, &writeReq); - if (s != STATUS_PENDING) + if (s != NTLSTATUS_PENDING) KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: write submit returned %u\n", s); s = KeWaitForEvent(wev, 1); diff --git a/code/kernel/ke_semaphore.c b/code/kernel/ke_semaphore.c index ec6c1ea..ea16f4e 100644 --- a/code/kernel/ke_semaphore.c +++ b/code/kernel/ke_semaphore.c @@ -13,29 +13,29 @@ static void KiSemaphoreDestroy(OBJECT* obj) { (void)obj; } // Implements the semaphore Create operation. __declspec(dllexport) KSTATUS KeSemaphoreCreate(int32_t initial, int32_t max, SEMAPHORE **out) { if (!out || initial < 0 || max < 1 || initial > max) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; SEMAPHORE* s = (SEMAPHORE *)ObAllocateObject(ObjectTypeSemaphore, sizeof(SEMAPHORE)); - if (!s) return STATUS_NO_MEMORY; + if (!s) return NTLSTATUS_NO_MEMORY; s->Header.Destroy = KiSemaphoreDestroy; s->Lock = (SPINLOCK)SPINLOCK_INIT; s->Count = initial; s->MaxCount = max; LIST_INIT(&s->WaitList); *out = s; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Waits for semaphore. __declspec(dllexport) KSTATUS KeWaitSemaphore(SEMAPHORE* sem) { - if (!sem) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; + if (!sem) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; THREAD* self = KeGetCurrentThread(); uintptr_t flags = KeAcquireSpinlock(&sem->Lock); if (sem->Count > 0) { sem->Count--; KeReleaseSpinlock(&sem->Lock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KePrepareBlockThread(self, &sem->Header, 0); @@ -47,15 +47,15 @@ __declspec(dllexport) KSTATUS KeWaitSemaphore(SEMAPHORE* sem) { // Implements the try Semaphore operation. __declspec(dllexport) KSTATUS KeTrySemaphore(SEMAPHORE* sem) { - if (!sem) return STATUS_INVALID_PARAMETER; + if (!sem) return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&sem->Lock); if (sem->Count > 0) { sem->Count--; KeReleaseSpinlock(&sem->Lock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KeReleaseSpinlock(&sem->Lock, flags); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } // Signals semaphore. @@ -70,7 +70,7 @@ __declspec(dllexport) void KeSignalSemaphore(SEMAPHORE* sem) { THREAD* waiter = CONTAINING_RECORD(node, THREAD, SchedulerLink); KeSetThreadWaitList(waiter, (LIST_ENTRY*)0); KeReleaseSpinlock(&sem->Lock, flags); - KeUnblockThreadWithStatus(waiter, STATUS_SUCCESS); + KeUnblockThreadWithStatus(waiter, NTLSTATUS_SUCCESS); return; } if (sem->Count < sem->MaxCount) sem->Count++; diff --git a/code/kernel/ke_settings.c b/code/kernel/ke_settings.c index 1cf3f09..f2099e4 100644 --- a/code/kernel/ke_settings.c +++ b/code/kernel/ke_settings.c @@ -25,7 +25,7 @@ typedef struct KE_FIND_SETTING_CTX { static void KeFindSettingCallback(const char* section, const char* key, const char* value, void* userdata) { KE_FIND_SETTING_CTX* ctx = (KE_FIND_SETTING_CTX*)userdata; - if (!ctx || ctx->Status != STATUS_NOT_FOUND) + if (!ctx || ctx->Status != NTLSTATUS_NOT_FOUND) return; if (!section || !key || !value) return; @@ -36,12 +36,12 @@ static void KeFindSettingCallback(const char* section, const char* key, if (len + 1 > ctx->BufferSize) { if (ctx->BufferSize) ctx->Buffer[0] = '\0'; - ctx->Status = STATUS_BUFFER_TOO_SMALL; + ctx->Status = NTLSTATUS_BUFFER_TOO_SMALL; return; } memcpy(ctx->Buffer, value, len + 1); - ctx->Status = STATUS_SUCCESS; + ctx->Status = NTLSTATUS_SUCCESS; } __declspec(dllexport) KSTATUS KeGetSettingString(const char* section, @@ -49,7 +49,7 @@ __declspec(dllexport) KSTATUS KeGetSettingString(const char* section, char* buffer, size_t bufferSize) { if (!section || !*section || !key || !*key || !buffer || bufferSize == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; buffer[0] = '\0'; @@ -61,14 +61,14 @@ __declspec(dllexport) KSTATUS KeGetSettingString(const char* section, uint64_t fileSize64 = IoGetFileSize(file); if (fileSize64 >= KE_SETTINGS_MAX_FILE_BYTES) { IoCloseFile(file); - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; } size_t fileSize = (size_t)fileSize64; char* text = (char*)MmAllocatePool(fileSize + 1); if (!text) { IoCloseFile(file); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } size_t got = 0; @@ -86,7 +86,7 @@ __declspec(dllexport) KSTATUS KeGetSettingString(const char* section, ctx.Key = key; ctx.Buffer = buffer; ctx.BufferSize = bufferSize; - ctx.Status = STATUS_NOT_FOUND; + ctx.Status = NTLSTATUS_NOT_FOUND; IniParse(text, KeFindSettingCallback, &ctx); MmFreePool(text); diff --git a/code/kernel/ke_smp.c b/code/kernel/ke_smp.c index ceaf151..8cc466b 100644 --- a/code/kernel/ke_smp.c +++ b/code/kernel/ke_smp.c @@ -120,7 +120,7 @@ void KeSetApplicationProcessorTrampoline(uint64_t trampolinePhys) { // Builds ap Trampoline. static KSTATUS KiBuildApTrampoline(void) { if (gApTrampolinePhys) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; PHYSICAL_ADDRESS frame = gReservedApTrampolinePhys; if (frame) { @@ -155,7 +155,7 @@ static KSTATUS KiBuildApTrampoline(void) { if (!frame) { DbgPrint("SMP: no free PMM frame available below 0x%016llX for AP trampoline\n", (uint64_t)AP_TRAMPOLINE_MAX_PHYS); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } DbgPrint("SMP: AP trampoline frame 0x%016llX selected\n", (uint64_t)frame); @@ -234,7 +234,7 @@ static KSTATUS KiBuildApTrampoline(void) { KiEmit32(&p, physBase + gdtOff); if ((uintptr_t)(p - page) >= AP_TRAMPOLINE_BOOT_OFF) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; AP_BOOT_BLOCK* boot = (AP_BOOT_BLOCK*)(page + AP_TRAMPOLINE_BOOT_OFF); memset(boot, 0, sizeof(*boot)); @@ -248,7 +248,7 @@ static KSTATUS KiBuildApTrampoline(void) { gApTrampolinePhys = frame; gApBootBlock = boot; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } _Noreturn void KiApKernelEntry(KCPU* cpu) { @@ -594,7 +594,7 @@ static KSTATUS KiAllocateApStack(KCPU* cpu) { if (!stack) { DbgPrint("SMP: AP%u stack allocation failed bytes=%llu\n", cpu ? cpu->CpuIndex : 0xFFFFFFFFu, (uint64_t)stackBytes); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } cpu->KernelStack = stack; @@ -604,7 +604,7 @@ static KSTATUS KiAllocateApStack(KCPU* cpu) { cpu->Tss.IoMapBase = sizeof(TSS64); cpu->Tss.RSP0 = cpu->KernelStackTop; KeInitializeGdtForCpu(cpu); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the ap Stage Name operation. @@ -641,7 +641,7 @@ KSTATUS KeStartApplicationProcessors(void) { if (!KSUCCESS(st)) return st; if (topo.CpuCount == 0 || topo.CpuCount > KE_MAX_CPUS) - return STATUS_DEVICE_ERROR; + return NTLSTATUS_DEVICE_ERROR; uint32_t bspLapic = HalGetBspLapicId(); KCPU* bsp = KeGetCurrentCpu(); @@ -683,14 +683,14 @@ KSTATUS KeStartApplicationProcessors(void) { DbgPrint("SMP: discovered %u addressable CPU(s), BSP LAPIC=%u\n", gCpuCount, bspLapic); if (gCpuCount <= 1) { DbgPrint("SMP: no application processors present\n"); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if ((__readcr3() >> 32) != 0) { DbgPrint("SMP: disabled; bootstrap CR3 is above 4GiB (cr3=0x%016llX), AP trampoline cannot load it yet\n", (uint64_t)__readcr3()); gCpuCount = 1; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } DbgPrint("SMP: bootloader AP trampoline phys=0x%016llX\n", @@ -699,7 +699,7 @@ KSTATUS KeStartApplicationProcessors(void) { if (!KSUCCESS(st)) { DbgPrint("SMP: disabled; AP trampoline allocation/build failed status=0x%x\n", st); gCpuCount = 1; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } uint8_t sipiVector = (uint8_t)(gApTrampolinePhys >> 12); @@ -771,14 +771,14 @@ KSTATUS KeStartApplicationProcessors(void) { KeBuildProcessorTopology(); DbgPrint("SMP: kernel claimed %u APs\n", claimed); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the admit Application Processors To Scheduler operation. KSTATUS KeAdmitApplicationProcessorsToScheduler(void) { if (gCpuCount <= 1) { DbgPrint("SMP: no AP scheduler admission needed\n"); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } uint32_t admitted = 0; @@ -828,7 +828,7 @@ KSTATUS KeAdmitApplicationProcessorsToScheduler(void) { } DbgPrint("SMP: scheduler admitted %u APs\n", admitted); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } #define SMP_AP_WORKER_ROUNDS 64u @@ -933,13 +933,13 @@ static int KiWaitForWorkerCounter(volatile long* counter, long expected, const c KSTATUS KeRunApplicationProcessorSchedulerSelfTests(void) { if (gCpuCount <= 1) { DbgPrint("SMP scheduler selftest: SKIP, no APs\n"); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } DbgPrint("SMP scheduler selftest: begin AP-affine workers\n"); SMP_AP_WORK_TEST* test = (SMP_AP_WORK_TEST*)MmAllocatePool(sizeof(SMP_AP_WORK_TEST)); - if (!test) return STATUS_NO_MEMORY; + if (!test) return NTLSTATUS_NO_MEMORY; memset(test, 0, sizeof(*test)); test->Magic = SMP_AP_TEST_MAGIC; @@ -982,7 +982,7 @@ KSTATUS KeRunApplicationProcessorSchedulerSelfTests(void) { if (workerCount == 0) { MmFreePool(test); DbgPrint("SMP scheduler selftest: SKIP, no online AP workers\n"); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (!KiWaitForWorkerCounter(&test->ReadyCount, (long)workerCount, "AP worker ready")) { @@ -1041,5 +1041,5 @@ KSTATUS KeRunApplicationProcessorSchedulerSelfTests(void) { DbgPrint("SMP scheduler selftest: PASS workers=%u rounds=%u\n", workerCount, SMP_AP_WORKER_ROUNDS); MmFreePool(test); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } diff --git a/code/kernel/ke_syscall.asm b/code/kernel/ke_syscall.asm index f119815..d2c9da9 100644 --- a/code/kernel/ke_syscall.asm +++ b/code/kernel/ke_syscall.asm @@ -136,9 +136,25 @@ KeSyscallEntry PROC call KiExitTrapFrame add rsp, 32 + ; Restore the editable trap-frame register image. Normal syscalls only + ; require RAX, but exception continuation may redirect the IRET to an + ; arbitrary saved user context that needs the full GPR set. mov rax, [rbx + TF_Rax] - add rsp, KTRAP_FRAME_SIZE - pop rbx + mov rcx, [rbx + TF_Rcx] + mov rdx, [rbx + TF_Rdx] + mov rbp, [rbx + TF_Rbp] + mov rsi, [rbx + TF_Rsi] + mov rdi, [rbx + TF_Rdi] + mov r8, [rbx + TF_R8] + mov r9, [rbx + TF_R9] + mov r10, [rbx + TF_R10] + mov r11, [rbx + TF_R11] + mov r12, [rbx + TF_R12] + mov r13, [rbx + TF_R13] + mov r14, [rbx + TF_R14] + mov r15, [rbx + TF_R15] + lea rsp, [rbx + KTRAP_FRAME_SIZE + 8] + mov rbx, [rbx + TF_Rbx] swapgs ; GS_BASE: KCPU -> user TEB before returning to ring 3 iretq KeSyscallEntry ENDP @@ -152,7 +168,7 @@ KeSyscallEntry ENDP ; also shows which register held the null target. ; ; KeFaultDispatchFrame signature (MS x64): -; KSTATUS KeFaultDispatchFrame(const KFAULT_FRAME* frame) ; rcx +; KSTATUS KeFaultDispatchFrame(KFAULT_FRAME* frame) ; rcx ; --------------------------------------------------------------------------- KFAULT_MAGIC EQU 3146544C5541464Bh ; "KFAULTF1" little-ish @@ -185,6 +201,118 @@ KF_R15 EQU 0B8h FAULT_CALL_SHADOW EQU 28h +FAULT_RESUME_NOERR MACRO + LOCAL noerr_skip_user_slots, noerr_no_swapgs, noerr_unhandled_halt + test eax, eax + jnz noerr_unhandled_halt + + mov rdx, rbx + mov rax, [rdx + KF_Rip] + mov [rdx + KFAULT_SIZE + 16], rax + mov rax, [rdx + KF_Cs] + mov [rdx + KFAULT_SIZE + 24], rax + mov rax, [rdx + KF_Rflags] + mov [rdx + KFAULT_SIZE + 32], rax + + mov rax, [rdx + KF_Cs] + test rax, 3 + jz noerr_skip_user_slots + mov rax, [rdx + KF_Rsp] + mov [rdx + KFAULT_SIZE + 40], rax + mov rax, [rdx + KF_Ss] + mov [rdx + KFAULT_SIZE + 48], rax + +noerr_skip_user_slots: + mov rcx, [rdx + KF_Rcx] + mov r8, [rdx + KF_R8] + mov r9, [rdx + KF_R9] + mov rsi, [rdx + KF_Rsi] + mov rdi, [rdx + KF_Rdi] + mov rbp, [rdx + KF_Rbp] + mov r12, [rdx + KF_R12] + mov r13, [rdx + KF_R13] + mov r14, [rdx + KF_R14] + mov r15, [rdx + KF_R15] + lea rsp, [rdx + KFAULT_SIZE + 16] + mov rax, [rdx + KF_Rax] + mov r11, [rdx + KF_R11] + mov r10, [rdx + KF_Cs] + test r10, 3 + jz noerr_no_swapgs + mov r10, [rdx + KF_R10] + mov rbx, [rdx + KF_Rbx] + mov rdx, [rdx + KF_Rdx] + swapgs + iretq +noerr_no_swapgs: + mov r10, [rdx + KF_R10] + mov rbx, [rdx + KF_Rbx] + mov rdx, [rdx + KF_Rdx] + iretq + +noerr_unhandled_halt: + cli +@@: + hlt + jmp @B +ENDM + +FAULT_RESUME_ERR MACRO + LOCAL err_skip_user_slots, err_no_swapgs, err_unhandled_halt + test eax, eax + jnz err_unhandled_halt + + mov rdx, rbx + mov rax, [rdx + KF_Rip] + mov [rdx + KFAULT_SIZE + 24], rax + mov rax, [rdx + KF_Cs] + mov [rdx + KFAULT_SIZE + 32], rax + mov rax, [rdx + KF_Rflags] + mov [rdx + KFAULT_SIZE + 40], rax + + mov rax, [rdx + KF_Cs] + test rax, 3 + jz err_skip_user_slots + mov rax, [rdx + KF_Rsp] + mov [rdx + KFAULT_SIZE + 48], rax + mov rax, [rdx + KF_Ss] + mov [rdx + KFAULT_SIZE + 56], rax + +err_skip_user_slots: + mov rcx, [rdx + KF_Rcx] + mov r8, [rdx + KF_R8] + mov r9, [rdx + KF_R9] + mov rsi, [rdx + KF_Rsi] + mov rdi, [rdx + KF_Rdi] + mov rbp, [rdx + KF_Rbp] + mov r12, [rdx + KF_R12] + mov r13, [rdx + KF_R13] + mov r14, [rdx + KF_R14] + mov r15, [rdx + KF_R15] + lea rsp, [rdx + KFAULT_SIZE + 24] + mov rax, [rdx + KF_Rax] + mov r11, [rdx + KF_R11] + mov r10, [rdx + KF_Cs] + test r10, 3 + jz err_no_swapgs + mov r10, [rdx + KF_R10] + mov rbx, [rdx + KF_Rbx] + mov rdx, [rdx + KF_Rdx] + swapgs + iretq +err_no_swapgs: + mov r10, [rdx + KF_R10] + mov rbx, [rdx + KF_Rbx] + mov rdx, [rdx + KF_Rdx] + iretq + +err_unhandled_halt: + cli +@@: + hlt + jmp @B +ENDM + ; --------------------------------------------------------- ; Divide Error (#0) - NO error code pushed by CPU ; User exception frame: [E]=RIP [E+8]=CS [E+16]=RFLAGS [E+24]=RSP [E+32]=SS @@ -246,8 +374,10 @@ de_kernel_frame: de_call: and rsp, -16 sub rsp, FAULT_CALL_SHADOW + mov rbx, rax mov rcx, rax call KeFaultDispatchFrame + FAULT_RESUME_NOERR KeFaultDE ENDP ; --------------------------------------------------------- @@ -312,8 +442,10 @@ gp_kernel_frame: gp_call: and rsp, -16 sub rsp, FAULT_CALL_SHADOW + mov rbx, rax mov rcx, rax call KeFaultDispatchFrame + FAULT_RESUME_ERR KeFaultGP ENDP ; --------------------------------------------------------- @@ -382,42 +514,7 @@ pf_call: mov rbx, rax ; Keep the KFAULT_FRAME pointer across C. mov rcx, rax call KeFaultDispatchFrame - test eax, eax - jnz pf_unhandled_return - - mov rdx, rbx ; rdx = KFAULT_FRAME*. - mov rcx, [rdx + KF_Rcx] - mov r8, [rdx + KF_R8] - mov r9, [rdx + KF_R9] - mov rsi, [rdx + KF_Rsi] - mov rdi, [rdx + KF_Rdi] - mov rbp, [rdx + KF_Rbp] - mov r12, [rdx + KF_R12] - mov r13, [rdx + KF_R13] - mov r14, [rdx + KF_R14] - mov r15, [rdx + KF_R15] - mov rbx, [rdx + KF_Rbx] - - lea rsp, [rdx + KFAULT_SIZE + 24] ; Skip saved RAX/R11 and the CPU error code. - mov rax, [rdx + KF_Rax] - mov r11, [rdx + KF_R11] - mov r10, [rdx + KF_Cs] - test r10, 3 - jz pf_resume_no_swapgs - mov r10, [rdx + KF_R10] - mov rdx, [rdx + KF_Rdx] - swapgs - iretq -pf_resume_no_swapgs: - mov r10, [rdx + KF_R10] - mov rdx, [rdx + KF_Rdx] - iretq - -pf_unhandled_return: - cli -pf_unhandled_halt: - hlt - jmp pf_unhandled_halt + FAULT_RESUME_ERR KeFaultPF ENDP ; --------------------------------------------------------- @@ -484,8 +581,10 @@ noerr_kernel_frame: noerr_call: and rsp, -16 sub rsp, FAULT_CALL_SHADOW + mov rbx, rax mov rcx, rax call KeFaultDispatchFrame + FAULT_RESUME_NOERR StubName ENDP ENDM @@ -549,8 +648,10 @@ err_kernel_frame: err_call: and rsp, -16 sub rsp, FAULT_CALL_SHADOW + mov rbx, rax mov rcx, rax call KeFaultDispatchFrame + FAULT_RESUME_ERR StubName ENDP ENDM diff --git a/code/kernel/ke_syscall.c b/code/kernel/ke_syscall.c index 344ea56..4176af2 100644 --- a/code/kernel/ke_syscall.c +++ b/code/kernel/ke_syscall.c @@ -43,6 +43,8 @@ #include #include #include +#include +#include #ifndef PROCESS_LAUNCH_DEBUG #define PROCESS_LAUNCH_DEBUG 0 @@ -143,10 +145,10 @@ static void KiModuleHandleDestroy(OBJECT* obj) { // Creates a user-visible module handle for one public load reference. static KSTATUS KiCreateModuleHandle(PROCESS* owner, uintptr_t base, uint32_t* handleOut) { - if (!owner || !base || !handleOut) return STATUS_INVALID_PARAMETER; + if (!owner || !base || !handleOut) return NTLSTATUS_INVALID_PARAMETER; MODULE_HANDLE_OBJECT* module = (MODULE_HANDLE_OBJECT*)ObAllocateObject(ObjectTypeModule, sizeof(MODULE_HANDLE_OBJECT)); - if (!module) return STATUS_NO_MEMORY; + if (!module) return NTLSTATUS_NO_MEMORY; module->Header.Destroy = KiModuleHandleDestroy; module->Owner = owner; module->Base = base; @@ -301,21 +303,21 @@ typedef struct SURFACE_ROW_CONTEXT { static KSTATUS KiSurfaceCopyRow(void* context, int rowIndex, uint32_t* scratch, size_t pixelCount) { SURFACE_ROW_CONTEXT* ctx = (SURFACE_ROW_CONTEXT*)context; if (!ctx || !ctx->Surface || !scratch || rowIndex < 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; SURFACE_OBJECT* surface = ctx->Surface; uint64_t row = (uint64_t)ctx->SourceY + (uint64_t)(uint32_t)rowIndex; uint64_t offset = row * (uint64_t)surface->PitchBytes + (uint64_t)ctx->SourceX * sizeof(uint32_t); uint64_t bytes = (uint64_t)pixelCount * sizeof(uint32_t); if (offset > (uint64_t)surface->PayloadSize || bytes > (uint64_t)surface->PayloadSize - offset) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint8_t* dst = (uint8_t*)scratch; while (bytes) { size_t frameIndex = (size_t)(offset / PAGE_SIZE); size_t pageOffset = (size_t)(offset & (PAGE_SIZE - 1)); if (frameIndex >= surface->PageCount || !surface->Frames[frameIndex]) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; size_t chunk = PAGE_SIZE - pageOffset; if (chunk > bytes) @@ -323,7 +325,7 @@ static KSTATUS KiSurfaceCopyRow(void* context, int rowIndex, uint32_t* scratch, const uint8_t* src = (const uint8_t*)MmPfnToVirtual(surface->Frames[frameIndex]); if (!src) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; memcpy(dst, src + pageOffset, chunk); dst += chunk; @@ -331,7 +333,7 @@ static KSTATUS KiSurfaceCopyRow(void* context, int rowIndex, uint32_t* scratch, bytes -= chunk; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the syscall Init operation. @@ -361,7 +363,7 @@ static KSTATUS KiAllocHandleForCurrentWithRights(OBJECT* obj, uint32_t rights, u PROCESS* proc = KeGetCurrentProcess(); if (!proc) { ObDereferenceObject(obj); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } KSTATUS s = KeAllocateHandleWithRights(proc, obj, rights, handleOut); @@ -387,7 +389,7 @@ static KSTATUS KiAllocHandleForCurrent(OBJECT* obj, uint32_t* handleOut) { // Copies user Request. static KSTATUS KiCopyUserRequest(uint64_t arg, void* dst, size_t size) { - if (!arg || !dst || size == 0) return STATUS_INVALID_PARAMETER; + if (!arg || !dst || size == 0) return NTLSTATUS_INVALID_PARAMETER; return CopyFromUser(dst, (const void*)(uintptr_t)arg, size); } @@ -396,29 +398,29 @@ static KSTATUS KiImportUserStringView(SYS_STRING_VIEW userView, size_t dstSize, SYS_STRING_VIEW* out, bool nulTerminate) { - if (!out) return STATUS_INVALID_PARAMETER; + if (!out) return NTLSTATUS_INVALID_PARAMETER; *out = SysSvFromParts((const char*)0, 0); if (userView.Length == 0) { if (nulTerminate) { - if (!dst || dstSize == 0) return STATUS_BUFFER_TOO_SMALL; + if (!dst || dstSize == 0) return NTLSTATUS_BUFFER_TOO_SMALL; dst[0] = '\0'; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } - if (!userView.Data || !dst) return STATUS_INVALID_PARAMETER; - if (userView.Length > SYSCALL_STRING_MAX) return STATUS_BUFFER_TOO_SMALL; + if (!userView.Data || !dst) return NTLSTATUS_INVALID_PARAMETER; + if (userView.Length > SYSCALL_STRING_MAX) return NTLSTATUS_BUFFER_TOO_SMALL; size_t needed = userView.Length + (nulTerminate ? 1 : 0); - if (needed < userView.Length || needed > dstSize) return STATUS_BUFFER_TOO_SMALL; + if (needed < userView.Length || needed > dstSize) return NTLSTATUS_BUFFER_TOO_SMALL; KSTATUS s = CopyFromUser(dst, userView.Data, userView.Length); if (!KSUCCESS(s)) return s; if (nulTerminate) dst[userView.Length] = '\0'; *out = SysSvFromParts(dst, userView.Length); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static KSTATUS KiImportUserTextView(SYS_STRING_VIEW userView, @@ -428,43 +430,43 @@ static KSTATUS KiImportUserTextView(SYS_STRING_VIEW userView, bool nulTerminate) { KSTATUS s = KiImportUserStringView(userView, dst, dstSize, out, nulTerminate); if (!KSUCCESS(s)) return s; - if (out && SysSvContainsByte(*out, '\0')) return STATUS_INVALID_PARAMETER; - return STATUS_SUCCESS; + if (out && SysSvContainsByte(*out, '\0')) return NTLSTATUS_INVALID_PARAMETER; + return NTLSTATUS_SUCCESS; } // Copies handle To User. static KSTATUS KiCopyHandleToUser(uint64_t arg, uint32_t value) { - if (!arg) return STATUS_INVALID_PARAMETER; + if (!arg) return NTLSTATUS_INVALID_PARAMETER; return CopyToUser((void*)(uintptr_t)arg, &value, sizeof(value)); } // Copies u32 To User. static KSTATUS KiCopyU32ToUser(uint64_t arg, uint32_t value) { - if (!arg) return STATUS_INVALID_PARAMETER; + if (!arg) return NTLSTATUS_INVALID_PARAMETER; return CopyToUser((void*)(uintptr_t)arg, &value, sizeof(value)); } // Copies size To User. static KSTATUS KiCopySizeToUser(uint64_t arg, size_t value) { - if (!arg) return STATUS_INVALID_PARAMETER; + if (!arg) return NTLSTATUS_INVALID_PARAMETER; return CopyToUser((void*)(uintptr_t)arg, &value, sizeof(value)); } // Copies u64 To User. static KSTATUS KiCopyU64ToUser(uint64_t arg, uint64_t value) { - if (!arg) return STATUS_INVALID_PARAMETER; + if (!arg) return NTLSTATUS_INVALID_PARAMETER; return CopyToUser((void*)(uintptr_t)arg, &value, sizeof(value)); } // Copies int To User. static KSTATUS KiCopyIntToUser(uint64_t arg, int value) { - if (!arg) return STATUS_INVALID_PARAMETER; + if (!arg) return NTLSTATUS_INVALID_PARAMETER; return CopyToUser((void*)(uintptr_t)arg, &value, sizeof(value)); } // Copies one signed 32-bit integer to user memory. static KSTATUS KiCopyInt32ToUser(uint64_t arg, int32_t value) { - if (!arg) return STATUS_INVALID_PARAMETER; + if (!arg) return NTLSTATUS_INVALID_PARAMETER; return CopyToUser((void*)(uintptr_t)arg, &value, sizeof(value)); } @@ -492,7 +494,7 @@ static uint64_t SyscallExitProcess(uint64_t a0, uint64_t a1, uint64_t a2, THREAD* t = KeGetCurrentThread(); PROCESS* proc = t ? t->Owner : NULL; int32_t exitCode = (int32_t)a0; - if (!proc || !t) return STATUS_FAILURE; + if (!proc || !t) return NTLSTATUS_FAILURE; KSTATUS s = KeExitProcess(proc, exitCode); if (!KSUCCESS(s)) return s; @@ -522,11 +524,11 @@ static uint64_t SyscallCreateThread(uint64_t a0, uint64_t a1, uint64_t a2, if (!KSUCCESS(s)) return s; PROCESS* proc = KeGetCurrentProcess(); - if (!proc) return STATUS_FAILURE; - if (!req.Entry) return STATUS_INVALID_PARAMETER; - if (req.Priority >= PriorityCount) return STATUS_INVALID_PARAMETER; - if (req.Flags) return STATUS_INVALID_PARAMETER; - if (!req.ThreadHandleOut && !req.ThreadIdOut) return STATUS_INVALID_PARAMETER; + if (!proc) return NTLSTATUS_FAILURE; + if (!req.Entry) return NTLSTATUS_INVALID_PARAMETER; + if (req.Priority >= PriorityCount) return NTLSTATUS_INVALID_PARAMETER; + if (req.Flags) return NTLSTATUS_INVALID_PARAMETER; + if (!req.ThreadHandleOut && !req.ThreadIdOut) return NTLSTATUS_INVALID_PARAMETER; s = MmProbeUserRead((const void*)req.Entry, 1); if (!KSUCCESS(s)) return s; @@ -574,7 +576,7 @@ static uint64_t SyscallCreateThread(uint64_t a0, uint64_t a1, uint64_t a2, } ObDereferenceObject(&newt->Header); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static void KiFinishAlertableUserWait(uint8_t alertable) { @@ -587,12 +589,12 @@ static void KiFinishAlertableUserWait(uint8_t alertable) { // Maps a waitable handle to its passive event backing object. static KSTATUS KiHandleToWaitEvent(PROCESS* proc, uint32_t handle, EVENT** eventOut, OBJECT** objectOut) { - if (!proc || !eventOut || !objectOut) return STATUS_INVALID_PARAMETER; + if (!proc || !eventOut || !objectOut) return NTLSTATUS_INVALID_PARAMETER; *eventOut = (EVENT*)0; *objectOut = (OBJECT*)0; OBJECT* obj = KeLookupHandleWithRights(proc, handle, HANDLE_RIGHT_WAIT); - if (!obj) return STATUS_INVALID_HANDLE; + if (!obj) return NTLSTATUS_INVALID_HANDLE; EVENT* event = (EVENT*)0; switch (obj->Type) { @@ -616,17 +618,17 @@ static KSTATUS KiHandleToWaitEvent(PROCESS* proc, uint32_t handle, EVENT** event break; default: ObDereferenceObject(obj); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } if (!event) { ObDereferenceObject(obj); - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; } *eventOut = event; *objectOut = obj; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_WAIT_SINGLE a0=handle a1=SYS_WAIT_FLAG_* a2=timeoutMs. @@ -638,40 +640,40 @@ static uint64_t SyscallWaitSingle(uint64_t a0, uint64_t a1, uint64_t a2, uint32_t flags = (uint32_t)a1; uint64_t timeoutMs = a2; - if (flags & ~SYS_WAIT_FLAG_ALERTABLE) return STATUS_INVALID_PARAMETER; + if (flags & ~SYS_WAIT_FLAG_ALERTABLE) return NTLSTATUS_INVALID_PARAMETER; PROCESS* proc = KeGetCurrentProcess(); - if (!proc) return STATUS_FAILURE; + if (!proc) return NTLSTATUS_FAILURE; OBJECT* obj = KeLookupHandleWithRights(proc, (uint32_t)a0, HANDLE_RIGHT_WAIT); - if (!obj) return STATUS_INVALID_HANDLE; + if (!obj) return NTLSTATUS_INVALID_HANDLE; uint8_t alertable = (flags & SYS_WAIT_FLAG_ALERTABLE) ? 1 : 0; - KSTATUS s = STATUS_NOT_SUPPORTED; + KSTATUS s = NTLSTATUS_NOT_SUPPORTED; if (obj->Type == ObjectTypeMutex) { - if (alertable) s = STATUS_NOT_SUPPORTED; + if (alertable) s = NTLSTATUS_NOT_SUPPORTED; else if (timeoutMs == 0) { s = KeTryAcquireMutex(CONTAINING_RECORD(obj, MUTEX, Header)); - if (s == STATUS_FAILURE) s = STATUS_TIMEOUT; + if (s == NTLSTATUS_FAILURE) s = NTLSTATUS_TIMEOUT; } else if (timeoutMs == SYS_WAIT_TIMEOUT_INFINITE) { s = KeAcquireMutex(CONTAINING_RECORD(obj, MUTEX, Header)); } else { - s = STATUS_NOT_SUPPORTED; + s = NTLSTATUS_NOT_SUPPORTED; } ObDereferenceObject(obj); return s; } if (obj->Type == ObjectTypeSemaphore) { - if (alertable) s = STATUS_NOT_SUPPORTED; + if (alertable) s = NTLSTATUS_NOT_SUPPORTED; else if (timeoutMs == 0) { s = KeTrySemaphore(CONTAINING_RECORD(obj, SEMAPHORE, Header)); - if (s == STATUS_FAILURE) s = STATUS_TIMEOUT; + if (s == NTLSTATUS_FAILURE) s = NTLSTATUS_TIMEOUT; } else if (timeoutMs == SYS_WAIT_TIMEOUT_INFINITE) { s = KeWaitSemaphore(CONTAINING_RECORD(obj, SEMAPHORE, Header)); } else { - s = STATUS_NOT_SUPPORTED; + s = NTLSTATUS_NOT_SUPPORTED; } ObDereferenceObject(obj); return s; @@ -687,7 +689,7 @@ static uint64_t SyscallWaitSingle(uint64_t a0, uint64_t a1, uint64_t a2, uint32_t selected = 0; s = KeWaitForMultipleEvents(&event, 1, alertable, timeoutMs, &selected); ObDereferenceObject(ref); - if (s != STATUS_TIMEOUT && s != STATUS_NOT_SUPPORTED) + if (s != NTLSTATUS_TIMEOUT && s != NTLSTATUS_NOT_SUPPORTED) KiFinishAlertableUserWait(alertable); return s; } @@ -701,10 +703,10 @@ static uint64_t SyscallWaitMany(uint64_t a0, uint64_t a1, uint64_t a2, SYS_WAIT_MANY_REQUEST req; KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; - if (req.Size != sizeof(req)) return STATUS_INVALID_PARAMETER; - if (req.Flags & ~SYS_WAIT_FLAG_ALERTABLE) return STATUS_INVALID_PARAMETER; + if (req.Size != sizeof(req)) return NTLSTATUS_INVALID_PARAMETER; + if (req.Flags & ~SYS_WAIT_FLAG_ALERTABLE) return NTLSTATUS_INVALID_PARAMETER; if (!req.Handles || req.Count == 0 || req.Count > SYS_WAIT_MANY_MAX_HANDLES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t handles[SYS_WAIT_MANY_MAX_HANDLES]; size_t handleBytes = (size_t)req.Count * sizeof(handles[0]); @@ -712,7 +714,7 @@ static uint64_t SyscallWaitMany(uint64_t a0, uint64_t a1, uint64_t a2, if (!KSUCCESS(s)) return s; PROCESS* proc = KeGetCurrentProcess(); - if (!proc) return STATUS_FAILURE; + if (!proc) return NTLSTATUS_FAILURE; EVENT* events[SYS_WAIT_MANY_MAX_HANDLES]; OBJECT* refs[SYS_WAIT_MANY_MAX_HANDLES]; @@ -742,7 +744,7 @@ static uint64_t SyscallWaitMany(uint64_t a0, uint64_t a1, uint64_t a2, if (!KSUCCESS(cs)) return cs; } - if (s != STATUS_TIMEOUT && s != STATUS_NOT_SUPPORTED) + if (s != NTLSTATUS_TIMEOUT && s != NTLSTATUS_NOT_SUPPORTED) KiFinishAlertableUserWait(alertable); return s; } @@ -751,8 +753,8 @@ static uint64_t SyscallWaitMany(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallOpenInputQueue(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (a0 != 0) return STATUS_INVALID_PARAMETER; - if (!a1) return STATUS_INVALID_PARAMETER; + if (a0 != 0) return NTLSTATUS_INVALID_PARAMETER; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; INPUT_QUEUE* queue = (INPUT_QUEUE*)0; KSTATUS s = KeInputOpenQueue(&queue); @@ -791,14 +793,14 @@ static uint64_t SyscallYield(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a0; (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; KeYield(); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_CREATE_TIMER a0=*handleOut. static uint64_t SyscallCreateTimer(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; KTIMER* timer = (KTIMER*)0; KSTATUS s = KeTimerCreate(&timer); @@ -828,10 +830,10 @@ static uint64_t SyscallSetTimer(uint64_t a0, uint64_t a1, uint64_t a2, KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; if (req.Size != sizeof(req) || req.Flags != SYS_TIMER_FLAG_NONE) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KTIMER* timer = (KTIMER*)KiHandleToObject(req.TimerHandle, ObjectTypeTimer, HANDLE_RIGHT_SIGNAL); - if (!timer) return STATUS_INVALID_HANDLE; + if (!timer) return NTLSTATUS_INVALID_HANDLE; s = KeTimerSet(timer, req.DueTimeMilliseconds, req.PeriodMilliseconds); ObDereferenceObject(&timer->Header); return s; @@ -843,7 +845,7 @@ static uint64_t SyscallCancelTimer(uint64_t a0, uint64_t a1, uint64_t a2, (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; KTIMER* timer = (KTIMER*)KiHandleToObject((uint32_t)a0, ObjectTypeTimer, HANDLE_RIGHT_SIGNAL); - if (!timer) return STATUS_INVALID_HANDLE; + if (!timer) return NTLSTATUS_INVALID_HANDLE; KSTATUS s = KeTimerCancel(timer); ObDereferenceObject(&timer->Header); return s; @@ -858,7 +860,7 @@ static uint64_t SyscallSleep(uint64_t a0, uint64_t a1, uint64_t a2, if (a0 == 0) { KeYield(); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KTIMER* timer = (KTIMER*)0; @@ -880,7 +882,7 @@ static uint64_t SyscallSleep(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallSetUserApcDispatcher(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; KSTATUS s = MmProbeUserRead((const void*)(uintptr_t)a0, 1); if (!KSUCCESS(s)) return s; return KeSetUserApcDispatcher((void*)(uintptr_t)a0); @@ -893,39 +895,126 @@ static uint64_t SyscallApcReturn(uint64_t a0, uint64_t a1, uint64_t a2, return KeUserApcReturn((const SYS_USER_APC_FRAME_K*)(uintptr_t)a0); } + +// SYS_SET_EXCEPTION_DISPATCHER a0 = SYS_EXCEPTION_DISPATCHER_REQUEST*. +static uint64_t SyscallSetExceptionDispatcher(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t a3, uint64_t a4, uint64_t a5) { + (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; + + SYS_EXCEPTION_DISPATCHER_REQUEST request; + KSTATUS status = KiCopyUserRequest(a0, &request, sizeof(request)); + if (!KSUCCESS(status)) + return status; + + PROCESS* process = KeGetCurrentProcess(); + if (!process) + return NTLSTATUS_FAILURE; + + return KeSetExceptionDispatcher(process, &request); +} + +// SYS_GET_EXCEPTION_DISPATCHER a0 = SYS_EXCEPTION_DISPATCHER_REQUEST*. +static uint64_t SyscallGetExceptionDispatcher(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t a3, uint64_t a4, uint64_t a5) { + (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; + if (!a0) + return NTLSTATUS_INVALID_PARAMETER; + + uint32_t userSize = 0; + KSTATUS status = CopyFromUser(&userSize, (const void*)(uintptr_t)a0, sizeof(userSize)); + if (!KSUCCESS(status)) + return status; + if (userSize != sizeof(SYS_EXCEPTION_DISPATCHER_REQUEST)) + return NTLSTATUS_INVALID_PARAMETER; + + PROCESS* process = KeGetCurrentProcess(); + if (!process) + return NTLSTATUS_FAILURE; + + SYS_EXCEPTION_DISPATCHER_REQUEST request; + status = KeGetExceptionDispatcher(process, &request); + if (!KSUCCESS(status)) + return status; + + return CopyToUser((void*)(uintptr_t)a0, &request, sizeof(request)); +} + +// SYS_CONTINUE_EXCEPTION a0 = SYS_CONTINUE_EXCEPTION_REQUEST*. +static uint64_t SyscallContinueException(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t a3, uint64_t a4, uint64_t a5) { + (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; + + SYS_CONTINUE_EXCEPTION_REQUEST request; + KSTATUS status = KiCopyUserRequest(a0, &request, sizeof(request)); + if (!KSUCCESS(status)) + return status; + + return KeContinueException(&request); +} + + +// SYS_RAISE_EXCEPTION a0 = SYS_RAISE_EXCEPTION_REQUEST*. +static uint64_t SyscallRaiseException(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t a3, uint64_t a4, uint64_t a5) { + (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; + + SYS_RAISE_EXCEPTION_REQUEST request; + KSTATUS status = KiCopyUserRequest(a0, &request, sizeof(request)); + if (!KSUCCESS(status)) + return status; + + if (request.Size != sizeof(request)) + return NTLSTATUS_INVALID_PARAMETER; + if (request.ParameterCount > SYS_EXCEPTION_MAXIMUM_PARAMETERS) + return NTLSTATUS_INVALID_PARAMETER; + + uint64_t parameters[SYS_EXCEPTION_MAXIMUM_PARAMETERS]; + memset(parameters, 0, sizeof(parameters)); + if (request.ParameterCount) { + if (!request.Parameters) + return NTLSTATUS_INVALID_PARAMETER; + status = CopyFromUser(parameters, request.Parameters, + (size_t)request.ParameterCount * sizeof(parameters[0])); + if (!KSUCCESS(status)) + return status; + } + + return KeRaiseUserException(&request, parameters); +} + // SYS_SET_THREAD_PRIORITY (7) a0 = priority. static uint64_t SyscallSetThreadPriority(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (a0 >= PriorityCount) return STATUS_INVALID_PARAMETER; + if (a0 >= PriorityCount) return NTLSTATUS_INVALID_PARAMETER; THREAD* t = KeGetCurrentThread(); - if (!t) return STATUS_FAILURE; + if (!t) return NTLSTATUS_FAILURE; t->Priority = (THREAD_PRIORITY)a0; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_VM_* page-granular user virtual memory. static KSTATUS KiVmProtectToPageFlags(uint32_t protect, uint64_t* flagsOut) { - if (!flagsOut) return STATUS_INVALID_PARAMETER; + if (!flagsOut) return NTLSTATUS_INVALID_PARAMETER; switch (protect) { case SYS_VM_NOACCESS: *flagsOut = 0; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case SYS_VM_READ: *flagsOut = PAGE_PRESENT | PAGE_USER | PAGE_NX; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case SYS_VM_READWRITE: *flagsOut = PAGE_PRESENT | PAGE_USER | PAGE_WRITE | PAGE_NX; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case SYS_VM_EXECUTE: case SYS_VM_EXECUTE_READ: *flagsOut = PAGE_PRESENT | PAGE_USER; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case SYS_VM_EXECUTE_READWRITE: *flagsOut = PAGE_PRESENT | PAGE_USER | PAGE_WRITE; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; default: - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } } @@ -940,25 +1029,32 @@ static uint32_t KiPageFlagsToVmProtect(uint64_t flags) { return SYS_VM_READ; } +// SYS_ALLOC_VM a0=*SYS_ALLOC_VM_REQUEST. static uint64_t SyscallVmAlloc(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { - (void)a5; - void* preferredBase = (void*)(uintptr_t)a0; - size_t pageCount = (size_t)a1; - uint32_t protect = (uint32_t)a2; - uint32_t flags = (uint32_t)a3; - void** baseOut = (void**)(uintptr_t)a4; + (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!pageCount || !baseOut) return STATUS_INVALID_PARAMETER; - if (pageCount > ((size_t)-1) / PAGE_SIZE) return STATUS_NO_MEMORY; - if (preferredBase || (flags & SYS_VM_FLAG_FIXED)) return STATUS_NOT_SUPPORTED; + SYS_ALLOC_VM_REQUEST req; + KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); + if (!KSUCCESS(s)) return s; + if (req.Size != sizeof(req) || req.Reserved != 0) return NTLSTATUS_INVALID_PARAMETER; + + void* preferredBase = req.PreferredBase; + size_t pageCount = req.PageCount; + uint32_t protect = req.Protect; + uint32_t flags = req.Flags; + void** baseOut = req.BaseOut; + + if (!pageCount || !baseOut) return NTLSTATUS_INVALID_PARAMETER; + if (pageCount > ((size_t)-1) / PAGE_SIZE) return NTLSTATUS_NO_MEMORY; + if (preferredBase || (flags & SYS_VM_FLAG_FIXED)) return NTLSTATUS_NOT_SUPPORTED; uint64_t pageFlags = 0; - KSTATUS s = KiVmProtectToPageFlags(protect, &pageFlags); + s = KiVmProtectToPageFlags(protect, &pageFlags); if (!KSUCCESS(s)) return s; PROCESS* process = KeGetCurrentProcess(); - if (!process) return STATUS_FAILURE; + if (!process) return NTLSTATUS_FAILURE; void* base = (void*)0; s = MmVadCreateCommitted(process, pageCount * PAGE_SIZE, PAGE_SIZE, @@ -973,29 +1069,29 @@ static uint64_t SyscallVmAlloc(uint64_t a0, uint64_t a1, uint64_t a2, MmVadDestroy(process, base); return s; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static uint64_t SyscallVmFree(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; PROCESS* process = KeGetCurrentProcess(); - if (!process || !a0) return STATUS_INVALID_PARAMETER; + if (!process || !a0) return NTLSTATUS_INVALID_PARAMETER; return MmVadDestroy(process, (void*)(uintptr_t)a0); } static uint64_t SyscallVmProtect(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a4; (void)a5; - if (!a0 || !a1) return STATUS_INVALID_PARAMETER; - if ((size_t)a1 > ((size_t)-1) / PAGE_SIZE) return STATUS_NO_MEMORY; + if (!a0 || !a1) return NTLSTATUS_INVALID_PARAMETER; + if ((size_t)a1 > ((size_t)-1) / PAGE_SIZE) return NTLSTATUS_NO_MEMORY; uint64_t pageFlags = 0; KSTATUS s = KiVmProtectToPageFlags((uint32_t)a2, &pageFlags); if (!KSUCCESS(s)) return s; PROCESS* process = KeGetCurrentProcess(); - if (!process) return STATUS_FAILURE; + if (!process) return NTLSTATUS_FAILURE; if (a3) { void* regionBase = (void*)0; @@ -1016,10 +1112,10 @@ static uint64_t SyscallVmProtect(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallVmQuery(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0 || !a1) return STATUS_INVALID_PARAMETER; + if (!a0 || !a1) return NTLSTATUS_INVALID_PARAMETER; PROCESS* process = KeGetCurrentProcess(); - if (!process) return STATUS_FAILURE; + if (!process) return NTLSTATUS_FAILURE; void* base = (void*)0; size_t size = 0; @@ -1043,7 +1139,7 @@ static uint64_t SyscallVmQuery(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallMutexCreate(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; MUTEX* mx = NULL; KSTATUS s = KeMutexCreate(&mx); if (!KSUCCESS(s)) return s; @@ -1063,7 +1159,7 @@ static uint64_t SyscallMutexTryAcquire(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; MUTEX* mx = (MUTEX*)KiHandleToObject((uint32_t)a0, ObjectTypeMutex, HANDLE_RIGHT_WAIT); - if (!mx) return STATUS_NOT_FOUND; + if (!mx) return NTLSTATUS_NOT_FOUND; KSTATUS s = KeTryAcquireMutex(mx); ObDereferenceObject(&mx->Header); return s; @@ -1074,17 +1170,17 @@ static uint64_t SyscallMutexRelease(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; MUTEX* mx = (MUTEX*)KiHandleToObject((uint32_t)a0, ObjectTypeMutex, HANDLE_RIGHT_SIGNAL); - if (!mx) return STATUS_NOT_FOUND; + if (!mx) return NTLSTATUS_NOT_FOUND; KeReleaseMutex(mx); ObDereferenceObject(&mx->Header); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_CREATE_SEM (15) a0=initial a1=max a2=*handleOut. static uint64_t SyscallSemCreate(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a3; (void)a4; (void)a5; - if (!a2) return STATUS_INVALID_PARAMETER; + if (!a2) return NTLSTATUS_INVALID_PARAMETER; SEMAPHORE* sem = NULL; KSTATUS s = KeSemaphoreCreate((int32_t)a0, (int32_t)a1, &sem); if (!KSUCCESS(s)) return s; @@ -1104,7 +1200,7 @@ static uint64_t SyscallSemTryWait(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; SEMAPHORE* sem = (SEMAPHORE*)KiHandleToObject((uint32_t)a0, ObjectTypeSemaphore, HANDLE_RIGHT_WAIT); - if (!sem) return STATUS_NOT_FOUND; + if (!sem) return NTLSTATUS_NOT_FOUND; KSTATUS s = KeTrySemaphore(sem); ObDereferenceObject(&sem->Header); return s; @@ -1115,17 +1211,17 @@ static uint64_t SyscallSemSignal(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; SEMAPHORE* sem = (SEMAPHORE*)KiHandleToObject((uint32_t)a0, ObjectTypeSemaphore, HANDLE_RIGHT_SIGNAL); - if (!sem) return STATUS_NOT_FOUND; + if (!sem) return NTLSTATUS_NOT_FOUND; KeSignalSemaphore(sem); ObDereferenceObject(&sem->Header); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_CREATE_EVENT (19) a0=type a1=initialState a2=*handleOut. static uint64_t SyscallEventCreate(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a3; (void)a4; (void)a5; - if (!a2 || a0 > EventManualReset) return STATUS_INVALID_PARAMETER; + if (!a2 || a0 > EventManualReset) return NTLSTATUS_INVALID_PARAMETER; EVENT* ev = NULL; KSTATUS s = KeEventCreate((EVENT_TYPE)a0, (uint32_t)a1, &ev); if (!KSUCCESS(s)) return s; @@ -1145,10 +1241,10 @@ static uint64_t SyscallEventSignal(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; EVENT* ev = (EVENT*)KiHandleToObject((uint32_t)a0, ObjectTypeEvent, HANDLE_RIGHT_SIGNAL); - if (!ev) return STATUS_NOT_FOUND; + if (!ev) return NTLSTATUS_NOT_FOUND; KeSignalEvent(ev); ObDereferenceObject(&ev->Header); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_CLEAR_EVENT (21) a0 = handle. @@ -1156,17 +1252,17 @@ static uint64_t SyscallEventClear(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; EVENT* ev = (EVENT*)KiHandleToObject((uint32_t)a0, ObjectTypeEvent, HANDLE_RIGHT_SIGNAL); - if (!ev) return STATUS_NOT_FOUND; + if (!ev) return NTLSTATUS_NOT_FOUND; KeClearEvent(ev); ObDereferenceObject(&ev->Header); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_CREATE_QUEUE (23) a0 = *handleOut. static uint64_t SyscallQueueCreate(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; QUEUE* q = NULL; KSTATUS s = KeQueueCreate(&q); if (!KSUCCESS(s)) return s; @@ -1190,14 +1286,14 @@ static uint64_t SyscallQueueSend(uint64_t a0, uint64_t a1, uint64_t a2, KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; if (req.Size != sizeof(req) || req.Flags != SYS_QUEUE_FLAG_NONE || !req.Message) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; QUEUE_MESSAGE msg; s = CopyFromUser(&msg, req.Message, sizeof(msg)); if (!KSUCCESS(s)) return s; QUEUE* q = (QUEUE*)KiHandleToObject(req.QueueHandle, ObjectTypeQueue, HANDLE_RIGHT_WRITE); - if (!q) return STATUS_NOT_FOUND; + if (!q) return NTLSTATUS_NOT_FOUND; s = KeSendMessage(q, &msg, req.TimeoutMilliseconds); ObDereferenceObject(&q->Header); return s; @@ -1212,10 +1308,10 @@ static uint64_t SyscallQueueRecv(uint64_t a0, uint64_t a1, uint64_t a2, KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; if (req.Size != sizeof(req) || req.Flags != SYS_QUEUE_FLAG_NONE || !req.MessageOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; QUEUE* q = (QUEUE*)KiHandleToObject(req.QueueHandle, ObjectTypeQueue, HANDLE_RIGHT_READ); - if (!q) return STATUS_NOT_FOUND; + if (!q) return NTLSTATUS_NOT_FOUND; QUEUE_MESSAGE msg; s = KeReceiveMessage(q, &msg, req.TimeoutMilliseconds); @@ -1242,19 +1338,19 @@ static uint64_t SyscallCreateFileMapping(uint64_t a0, uint64_t a1, uint64_t a2, uint32_t* handleOut = (uint32_t*)(uintptr_t)a4; if (!fileHandle || !handleOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint64_t pageFlags = 0; KSTATUS s = KiVmProtectToPageFlags(protect, &pageFlags); if (!KSUCCESS(s)) return s; - if (!pageFlags) return STATUS_ACCESS_DENIED; + if (!pageFlags) return NTLSTATUS_ACCESS_DENIED; uint32_t neededRights = HANDLE_RIGHT_READ | HANDLE_RIGHT_QUERY; if (pageFlags & PAGE_WRITE) neededRights |= HANDLE_RIGHT_WRITE; FILE_OBJECT* file = (FILE_OBJECT*)KiHandleToObject(fileHandle, ObjectTypeFile, neededRights); - if (!file) return STATUS_NOT_FOUND; + if (!file) return NTLSTATUS_NOT_FOUND; if (maximumSize == 0) maximumSize = IoGetFileSize(file); @@ -1263,7 +1359,7 @@ static uint64_t SyscallCreateFileMapping(uint64_t a0, uint64_t a1, uint64_t a2, sizeof(FILE_MAPPING_OBJECT)); if (!mapping) { ObDereferenceObject(&file->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } mapping->Header.Destroy = KiFileMappingDestroy; @@ -1292,21 +1388,21 @@ static KSTATUS KiMapAccessToPageFlags(const FILE_MAPPING_OBJECT* mapping, uint32_t access, uint64_t* pageFlagsOut) { if (!mapping || !pageFlagsOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint64_t mappingFlags = mapping->PageFlags; if (!mappingFlags) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; if (access == 0) access = SYS_MAP_ACCESS_READ; if ((access & SYS_MAP_ACCESS_WRITE) && (access & SYS_MAP_ACCESS_COPY)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (((access & SYS_MAP_ACCESS_COPY) || (access & SYS_MAP_ACCESS_WRITE)) && (mappingFlags & PAGE_WRITE) == 0) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; uint64_t flags = PAGE_PRESENT | PAGE_USER; if ((access & SYS_MAP_ACCESS_COPY) || (access & SYS_MAP_ACCESS_WRITE)) @@ -1314,13 +1410,13 @@ static KSTATUS KiMapAccessToPageFlags(const FILE_MAPPING_OBJECT* mapping, if (access & SYS_MAP_ACCESS_EXECUTE) { if (mappingFlags & PAGE_NX) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; } else { flags |= PAGE_NX; } *pageFlagsOut = flags; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static uint64_t SyscallMapFile(uint64_t a0, uint64_t a1, uint64_t a2, @@ -1333,15 +1429,15 @@ static uint64_t SyscallMapFile(uint64_t a0, uint64_t a1, uint64_t a2, void** baseOut = (void**)(uintptr_t)a5; if (!mappingHandle || !baseOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (offset & (PAGE_SIZE - 1)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; FILE_MAPPING_OBJECT* mapping = (FILE_MAPPING_OBJECT*)KiHandleToObject(mappingHandle, ObjectTypeFileMapping, HANDLE_RIGHT_READ); if (!mapping) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; uint64_t maximumSize = mapping->MaximumSize; if (maximumSize == 0) @@ -1349,23 +1445,23 @@ static uint64_t SyscallMapFile(uint64_t a0, uint64_t a1, uint64_t a2, if (offset >= maximumSize) { ObDereferenceObject(&mapping->Header); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (size == 0) { uint64_t tail = maximumSize - offset; if (tail > (uint64_t)((size_t)-1)) { ObDereferenceObject(&mapping->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } size = (size_t)tail; } if (size == 0) { ObDereferenceObject(&mapping->Header); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if ((uint64_t)size > maximumSize - offset) { ObDereferenceObject(&mapping->Header); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } uint64_t pageFlags = 0; @@ -1378,7 +1474,7 @@ static uint64_t SyscallMapFile(uint64_t a0, uint64_t a1, uint64_t a2, PROCESS* process = KeGetCurrentProcess(); if (!process) { ObDereferenceObject(&mapping->Header); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } uint32_t vadFlags = flags; @@ -1397,14 +1493,14 @@ static uint64_t SyscallMapFile(uint64_t a0, uint64_t a1, uint64_t a2, MmVadDestroy(process, base); return s; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static uint64_t SyscallCloseHandle(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; PROCESS* proc = KeGetCurrentProcess(); - if (!proc) return STATUS_FAILURE; + if (!proc) return NTLSTATUS_FAILURE; OBJECT* obj = KeLookupHandleWithRights(proc, (uint32_t)a0, 0); if (obj) { @@ -1419,13 +1515,13 @@ static uint64_t SyscallCloseHandle(uint64_t a0, uint64_t a1, uint64_t a2, } KeCloseHandle(proc, (uint32_t)a0); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Converts public file access flags to handle rights and file object flags. static KSTATUS KiFileAccessToHandleRights(uint32_t access, uint32_t* rightsOut, uint32_t* fileFlagsOut) { if (!rightsOut || !fileFlagsOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t valid = SYS_FILE_ACCESS_READ | SYS_FILE_ACCESS_WRITE | @@ -1433,7 +1529,7 @@ static KSTATUS KiFileAccessToHandleRights(uint32_t access, uint32_t* rightsOut, SYS_FILE_ACCESS_QUERY | SYS_FILE_ACCESS_LOCK; if ((access & ~valid) != 0 || access == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t rights = 0; uint32_t fileFlags = 0; @@ -1452,7 +1548,7 @@ static KSTATUS KiFileAccessToHandleRights(uint32_t access, uint32_t* rightsOut, *rightsOut = rights; *fileFlagsOut = fileFlags; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Opens a file using the public disposition contract. @@ -1461,7 +1557,7 @@ static KSTATUS KiOpenFileByDisposition(SYS_STRING_VIEW path, uint32_t access, FILE_OBJECT** fileOut) { if (!fileOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *fileOut = NULL; bool writes = (access & (SYS_FILE_ACCESS_WRITE | SYS_FILE_ACCESS_APPEND)) != 0; @@ -1473,14 +1569,14 @@ static KSTATUS KiOpenFileByDisposition(SYS_STRING_VIEW path, case SYS_FILE_CREATE_NEW: if (!writes) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; return IoCreateFile(path, fileOut); case SYS_FILE_CREATE_ALWAYS: if (!writes) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; s = IoCreateFile(path, fileOut); - if (s == STATUS_OBJECT_NAME_COLLISION) { + if (s == NTLSTATUS_OBJECT_NAME_COLLISION) { s = IoOpenFile(path, fileOut); if (KSUCCESS(s)) { KSTATUS ts = IoTruncateFile(*fileOut, 0); @@ -1495,16 +1591,16 @@ static KSTATUS KiOpenFileByDisposition(SYS_STRING_VIEW path, case SYS_FILE_OPEN_ALWAYS: s = IoOpenFile(path, fileOut); - if (s == STATUS_NOT_FOUND) { + if (s == NTLSTATUS_NOT_FOUND) { if (!writes) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; s = IoCreateFile(path, fileOut); } return s; case SYS_FILE_TRUNCATE_EXISTING: if (!writes) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; s = IoOpenFile(path, fileOut); if (KSUCCESS(s)) { KSTATUS ts = IoTruncateFile(*fileOut, 0); @@ -1517,7 +1613,7 @@ static KSTATUS KiOpenFileByDisposition(SYS_STRING_VIEW path, return s; default: - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } } @@ -1529,8 +1625,8 @@ static uint64_t SyscallOpenFile(uint64_t a0, uint64_t a1, uint64_t a2, SYS_OPEN_FILE_REQUEST req; KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; - if (!req.HandleOut) return STATUS_INVALID_PARAMETER; - if (req.Flags != SYS_FILE_FLAG_NONE) return STATUS_INVALID_PARAMETER; + if (!req.HandleOut) return NTLSTATUS_INVALID_PARAMETER; + if (req.Flags != SYS_FILE_FLAG_NONE) return NTLSTATUS_INVALID_PARAMETER; uint32_t rights = 0; uint32_t fileFlags = 0; @@ -1541,7 +1637,7 @@ static uint64_t SyscallOpenFile(uint64_t a0, uint64_t a1, uint64_t a2, SYS_STRING_VIEW path; s = KiImportUserTextView(req.Path, pathBuf, sizeof(pathBuf), &path, true); if (!KSUCCESS(s)) return s; - if (path.Length == 0) return STATUS_INVALID_PARAMETER; + if (path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; FILE_OBJECT* file = NULL; s = KiOpenFileByDisposition(path, req.Disposition, req.Access, &file); @@ -1595,13 +1691,13 @@ static KSTATUS KiImportSyncFileIoRequest(uint64_t arg, SYS_FILE_IO_REQUEST* req) return s; if (req->Flags != 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (req->Size > SYSCALL_IO_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (req->Size && !req->Buffer) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_READ_FILE a0=*SYS_FILE_IO_REQUEST. @@ -1617,29 +1713,29 @@ static uint64_t SyscallReadFile(uint64_t a0, uint64_t a1, uint64_t a2, if (req.Size == 0) { if (req.TransferredOut) return KiCopySizeToUser((uint64_t)(uintptr_t)req.TransferredOut, 0); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } FILE_OBJECT* file = (FILE_OBJECT*)KiHandleToObject(req.FileHandle, ObjectTypeFile, HANDLE_RIGHT_READ); - if (!file) return STATUS_NOT_FOUND; + if (!file) return NTLSTATUS_NOT_FOUND; size_t chunkSize = 0; void* kbuf = KiAllocateSyscallIoBuffer(req.Size, &chunkSize); if (!kbuf) { ObDereferenceObject(&file->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } uintptr_t user = (uintptr_t)req.Buffer; size_t total = 0; - s = STATUS_SUCCESS; + s = NTLSTATUS_SUCCESS; while (total < req.Size) { size_t todo = req.Size - total; if (todo > chunkSize) todo = chunkSize; if (user > (uintptr_t)-1 - total) { - s = STATUS_INVALID_PARAMETER; + s = NTLSTATUS_INVALID_PARAMETER; break; } @@ -1684,29 +1780,29 @@ static uint64_t SyscallWriteFile(uint64_t a0, uint64_t a1, uint64_t a2, if (req.Size == 0) { if (req.TransferredOut) return KiCopySizeToUser((uint64_t)(uintptr_t)req.TransferredOut, 0); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } FILE_OBJECT* file = (FILE_OBJECT*)KiHandleToObject(req.FileHandle, ObjectTypeFile, HANDLE_RIGHT_WRITE); - if (!file) return STATUS_NOT_FOUND; + if (!file) return NTLSTATUS_NOT_FOUND; size_t chunkSize = 0; void* kbuf = KiAllocateSyscallIoBuffer(req.Size, &chunkSize); if (!kbuf) { ObDereferenceObject(&file->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } uintptr_t user = (uintptr_t)req.Buffer; size_t total = 0; - s = STATUS_SUCCESS; + s = NTLSTATUS_SUCCESS; while (total < req.Size) { size_t todo = req.Size - total; if (todo > chunkSize) todo = chunkSize; if (user > (uintptr_t)-1 - total) { - s = STATUS_INVALID_PARAMETER; + s = NTLSTATUS_INVALID_PARAMETER; break; } @@ -1792,19 +1888,19 @@ static void SyscallUserAsyncNormalRoutine(void* normalContext, // Implements the async File Common operation. static uint64_t SyscallAsyncFileCommon(uint64_t a0, bool write) { - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; SYS_ASYNC_FILE_REQUEST_K req; KSTATUS s = CopyFromUser(&req, (const void*)(uintptr_t)a0, sizeof(req)); if (!KSUCCESS(s)) return s; - if (req.Flags) return STATUS_INVALID_PARAMETER; - if (!req.Iosb) return STATUS_INVALID_PARAMETER; - if (!req.Buffer && req.Size) return STATUS_INVALID_PARAMETER; - if (req.Size > SYSCALL_IO_MAX_BYTES) return STATUS_INVALID_PARAMETER; + if (req.Flags) return NTLSTATUS_INVALID_PARAMETER; + if (!req.Iosb) return NTLSTATUS_INVALID_PARAMETER; + if (!req.Buffer && req.Size) return NTLSTATUS_INVALID_PARAMETER; + if (req.Size > SYSCALL_IO_MAX_BYTES) return NTLSTATUS_INVALID_PARAMETER; PROCESS* proc = KeGetCurrentProcess(); - if (!proc) return STATUS_FAILURE; + if (!proc) return NTLSTATUS_FAILURE; if (req.RequestHandleOut) { s = MmProbeUserWrite(req.RequestHandleOut, sizeof(*req.RequestHandleOut)); @@ -1813,14 +1909,14 @@ static uint64_t SyscallAsyncFileCommon(uint64_t a0, bool write) { FILE_OBJECT* file = (FILE_OBJECT*)KiHandleToObject(req.FileHandle, ObjectTypeFile, write ? HANDLE_RIGHT_WRITE : HANDLE_RIGHT_READ); - if (!file) return STATUS_NOT_FOUND; + if (!file) return NTLSTATUS_NOT_FOUND; EVENT* event = (EVENT*)0; if (req.EventHandle) { event = (EVENT*)KiHandleToObject(req.EventHandle, ObjectTypeEvent, HANDLE_RIGHT_SIGNAL); if (!event) { ObDereferenceObject(&file->Header); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } } @@ -1831,14 +1927,14 @@ static uint64_t SyscallAsyncFileCommon(uint64_t a0, bool write) { if (!thread || !thread->UserApcDispatcher) { if (event) ObDereferenceObject(&event->Header); ObDereferenceObject(&file->Header); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } apcCtx = (SYS_USER_ASYNC_APC_CONTEXT*)MmAllocatePoolTag(sizeof(SYS_USER_ASYNC_APC_CONTEXT), MM_POOL_TAG('u', 'a', 'p', 'c')); if (!apcCtx) { if (event) ObDereferenceObject(&event->Header); ObDereferenceObject(&file->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } memset(apcCtx, 0, sizeof(*apcCtx)); @@ -1898,7 +1994,7 @@ static uint64_t SyscallAsyncFileCommon(uint64_t a0, bool write) { lockedBuffer = (MM_LOCKED_USER_BUFFER*)0; lockedIosb = (MM_LOCKED_USER_BUFFER*)0; - if (s == STATUS_PENDING && req.RequestHandleOut && asyncReq) { + if (s == NTLSTATUS_PENDING && req.RequestHandleOut && asyncReq) { uint32_t requestHandle = 0; KSTATUS hs = KeAllocateHandleWithRights(proc, IoAsyncFileRequestObject(asyncReq), HANDLE_RIGHT_WAIT | HANDLE_RIGHT_QUERY | HANDLE_RIGHT_TERMINATE, @@ -1925,7 +2021,7 @@ static uint64_t SyscallAsyncFileCommon(uint64_t a0, bool write) { KSTATUS cs = CopyToUser(req.RequestHandleOut, &zeroHandle, sizeof(zeroHandle)); if (!KSUCCESS(cs)) { if (asyncReq) ObDereferenceObject(IoAsyncFileRequestObject(asyncReq)); - if (s != STATUS_PENDING && apcCtx) + if (s != NTLSTATUS_PENDING && apcCtx) SyscallUserAsyncApcContextFree(apcCtx); if (event) ObDereferenceObject(&event->Header); ObDereferenceObject(&file->Header); @@ -1936,7 +2032,7 @@ static uint64_t SyscallAsyncFileCommon(uint64_t a0, bool write) { if (asyncReq) ObDereferenceObject(IoAsyncFileRequestObject(asyncReq)); // drop creator reference - if (s != STATUS_PENDING && apcCtx) + if (s != NTLSTATUS_PENDING && apcCtx) SyscallUserAsyncApcContextFree(apcCtx); if (event) ObDereferenceObject(&event->Header); @@ -1964,7 +2060,7 @@ static uint64_t SyscallCancelIo(uint64_t a0, uint64_t a1, uint64_t a2, (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; IO_ASYNC_REQUEST_OBJECT* req = (IO_ASYNC_REQUEST_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeAsyncIo, HANDLE_RIGHT_TERMINATE); - if (!req) return STATUS_INVALID_HANDLE; + if (!req) return NTLSTATUS_INVALID_HANDLE; KSTATUS s = IoCancelAsyncRequest(req); ObDereferenceObject(IoAsyncRequestObject(req)); @@ -1984,7 +2080,7 @@ static uint64_t SyscallDeleteFile(uint64_t a0, uint64_t a1, uint64_t a2, SYS_STRING_VIEW path; s = KiImportUserTextView(req.Path, pathBuf, sizeof(pathBuf), &path, true); if (!KSUCCESS(s)) return s; - if (path.Length == 0) return STATUS_INVALID_PARAMETER; + if (path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; return IoDeleteFile(path); } @@ -1994,7 +2090,7 @@ static uint64_t SyscallTruncateFile(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; FILE_OBJECT* file = (FILE_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeFile, HANDLE_RIGHT_WRITE); - if (!file) return STATUS_NOT_FOUND; + if (!file) return NTLSTATUS_NOT_FOUND; KSTATUS s = IoTruncateFile(file, (uint64_t)a1); ObDereferenceObject(&file->Header); return s; @@ -2005,7 +2101,7 @@ static uint64_t SyscallFlushFile(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; FILE_OBJECT* file = (FILE_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeFile, HANDLE_RIGHT_WRITE); - if (!file) return STATUS_NOT_FOUND; + if (!file) return NTLSTATUS_NOT_FOUND; KSTATUS s = IoFlushFile(file); ObDereferenceObject(&file->Header); return s; @@ -2015,10 +2111,10 @@ static uint64_t SyscallFlushFile(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallGetFilePos(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; FILE_OBJECT* file = (FILE_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeFile, HANDLE_RIGHT_QUERY); - if (!file) return STATUS_INVALID_HANDLE; + if (!file) return NTLSTATUS_INVALID_HANDLE; uintptr_t flags = KeAcquireSpinlock(&file->Lock); uint64_t pos = file->Offset; @@ -2033,7 +2129,7 @@ static uint64_t SyscallSeekFile(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; FILE_OBJECT* file = (FILE_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeFile, HANDLE_RIGHT_QUERY); - if (!file) return STATUS_NOT_FOUND; + if (!file) return NTLSTATUS_NOT_FOUND; KSTATUS s = IoSeekFile(file, (uint64_t)a1); ObDereferenceObject(&file->Header); return s; @@ -2043,10 +2139,10 @@ static uint64_t SyscallSeekFile(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallGetFileSize(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; FILE_OBJECT* file = (FILE_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeFile, HANDLE_RIGHT_QUERY); - if (!file) return STATUS_INVALID_HANDLE; + if (!file) return NTLSTATUS_INVALID_HANDLE; uint64_t sz = IoGetFileSize(file); ObDereferenceObject(&file->Header); @@ -2057,10 +2153,10 @@ static uint64_t SyscallGetFileSize(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallGetFileStat(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; FILE_OBJECT* file = (FILE_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeFile, HANDLE_RIGHT_QUERY); - if (!file) return STATUS_INVALID_HANDLE; + if (!file) return NTLSTATUS_INVALID_HANDLE; SYS_FILE_STAT stat; KSTATUS s = IoGetFileStat(file, &stat); @@ -2078,13 +2174,13 @@ static uint64_t SyscallStatFile(uint64_t a0, uint64_t a1, uint64_t a2, SYS_STAT_FILE_REQUEST req; KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; - if (!req.StatOut) return STATUS_INVALID_PARAMETER; + if (!req.StatOut) return NTLSTATUS_INVALID_PARAMETER; char pathBuf[SYSCALL_STRING_MAX]; SYS_STRING_VIEW path; s = KiImportUserTextView(req.Path, pathBuf, sizeof(pathBuf), &path, true); if (!KSUCCESS(s)) return s; - if (path.Length == 0) return STATUS_INVALID_PARAMETER; + if (path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; SYS_FILE_STAT stat; s = IoStatFile(path, &stat); @@ -2093,43 +2189,49 @@ static uint64_t SyscallStatFile(uint64_t a0, uint64_t a1, uint64_t a2, return CopyToUser(req.StatOut, &stat, sizeof(stat)); } -// SYS_CREATE_SURFACE (99) a0=width a1=height a2=format a3=flags a4=*handleOut. +// SYS_CREATE_SURFACE a0=*SYS_CREATE_SURFACE_REQUEST. static uint64_t SyscallCreateSurface(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { - (void)a5; - uint32_t width = (uint32_t)a0; - uint32_t height = (uint32_t)a1; - uint32_t format = (uint32_t)a2; - uint32_t flags = (uint32_t)a3; - if (!width || !height || !a4) - return STATUS_INVALID_PARAMETER; + (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; + + SYS_CREATE_SURFACE_REQUEST req; + KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); + if (!KSUCCESS(s)) return s; + if (req.Size != sizeof(req)) return NTLSTATUS_INVALID_PARAMETER; + + uint32_t width = req.Width; + uint32_t height = req.Height; + uint32_t format = req.Format; + uint32_t flags = req.Flags; + if (!width || !height || !req.HandleOut) + return NTLSTATUS_INVALID_PARAMETER; if (format != SYS_SURFACE_FORMAT_XRGB8888 || flags != SYS_SURFACE_FLAG_NONE) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; DISPLAY_MODE mode; - KSTATUS s = KeDisplayGetMode(&mode); + s = KeDisplayGetMode(&mode); if (!KSUCCESS(s)) return s; if (width > mode.Width || height > mode.Height) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; size_t rowBytes = 0; if (!KiMulSize((size_t)width, sizeof(uint32_t), &rowBytes)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; size_t pitchBytes = KiAlignUpSize(rowBytes, 64); if (pitchBytes < rowBytes) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; size_t payloadSize = 0; if (!KiMulSize(pitchBytes, (size_t)height, &payloadSize)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; size_t pageCount = (payloadSize + PAGE_SIZE - 1) / PAGE_SIZE; if (!pageCount || pageCount > (SIZE_MAX / sizeof(PHYSICAL_ADDRESS))) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; SURFACE_OBJECT* surface = (SURFACE_OBJECT*)ObAllocateObject(ObjectTypeSurface, sizeof(SURFACE_OBJECT)); if (!surface) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; surface->Header.Destroy = KiSurfaceDestroy; surface->Owner = KeGetCurrentProcess(); surface->Width = width; @@ -2145,7 +2247,7 @@ static uint64_t SyscallCreateSurface(uint64_t a0, uint64_t a1, uint64_t a2, s = KeMutexCreate(&surface->Lock); if (!surface->Frames || !surface->RowScratch || !KSUCCESS(s)) { ObDereferenceObject(&surface->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } memset(surface->Frames, 0, pageCount * sizeof(PHYSICAL_ADDRESS)); @@ -2153,7 +2255,7 @@ static uint64_t SyscallCreateSurface(uint64_t a0, uint64_t a1, uint64_t a2, PHYSICAL_ADDRESS frame = MmPfnAllocate(MmPfnUseSurface); if (!frame) { ObDereferenceObject(&surface->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } surface->Frames[i] = frame; void* kva = MmPfnToVirtual(frame); @@ -2168,12 +2270,12 @@ static uint64_t SyscallCreateSurface(uint64_t a0, uint64_t a1, uint64_t a2, KiSurfaceStatsRegister(surface); - s = CopyToUser((void*)(uintptr_t)a4, &handle, sizeof(handle)); + s = CopyToUser(req.HandleOut, &handle, sizeof(handle)); if (!KSUCCESS(s)) { KeCloseHandle(KeGetCurrentProcess(), handle); return s; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_MAP_SURFACE (100) a0=surfaceHandle a1=*baseOut a2=*pitchBytesOut. @@ -2181,16 +2283,16 @@ static uint64_t SyscallMapSurface(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a3; (void)a4; (void)a5; if (!a1 || !a2) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; SURFACE_OBJECT* surface = (SURFACE_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeSurface, HANDLE_RIGHT_READ | HANDLE_RIGHT_WRITE); if (!surface) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; PROCESS* current = KeGetCurrentProcess(); if (surface->Owner != current) { ObDereferenceObject(&surface->Header); - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; } KSTATUS s = KeAcquireMutex(surface->Lock); @@ -2226,15 +2328,15 @@ static uint64_t SyscallQuerySurface(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; if (!a1) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; SURFACE_OBJECT* surface = (SURFACE_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeSurface, HANDLE_RIGHT_QUERY); if (!surface) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (surface->Owner != KeGetCurrentProcess()) { ObDereferenceObject(&surface->Header); - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; } SYS_SURFACE_DESC desc; @@ -2307,17 +2409,17 @@ static uint64_t SyscallPresentSurface(uint64_t a0, uint64_t a1, uint64_t a2, (void)a3; (void)a4; (void)a5; uint32_t rectCount = (uint32_t)a2; if (rectCount > SYS_SURFACE_MAX_RECTS) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (rectCount != 0 && !a1) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; SURFACE_OBJECT* surface = (SURFACE_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeSurface, HANDLE_RIGHT_READ); if (!surface) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (surface->Owner != KeGetCurrentProcess()) { ObDereferenceObject(&surface->Header); - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; } DISPLAY_RECT rects[SYS_SURFACE_MAX_RECTS]; @@ -2341,7 +2443,7 @@ static uint64_t SyscallPresentSurface(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t rowsCopied = 0; uint64_t bytesCopied = 0; - KSTATUS s = STATUS_SUCCESS; + KSTATUS s = NTLSTATUS_SUCCESS; for (uint32_t i = 0; i < rectCount; ++i) { DISPLAY_RECT clipped; if (!KiClipSurfaceRect(surface, &rects[i], &clipped)) { @@ -2392,7 +2494,7 @@ static uint64_t SyscallGetScreenSize(uint64_t a0, uint64_t a1, uint64_t a2, KSTATUS s = KiCopyIntToUser(a1, h); if (!KSUCCESS(s)) return s; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_PUT_SCREEN_CHAR (65) a0=c a1=x a2=y a3=fg a4=bg. @@ -2407,7 +2509,7 @@ static uint64_t SyscallPutScreenChar(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallGetConsoleInfo(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; KE_CONSOLE_INFO ki; KSTATUS s = KeDisplayGetConsoleInfo(&ki); @@ -2429,7 +2531,7 @@ static uint64_t SyscallSetConsoleCursor(uint64_t a0, uint64_t a1, uint64_t a2, (void)a2; (void)a3; (void)a4; (void)a5; int col = (int)(int32_t)a0; int row = (int)(int32_t)a1; - if (col < 0 || row < 0) return STATUS_INVALID_PARAMETER; + if (col < 0 || row < 0) return NTLSTATUS_INVALID_PARAMETER; return KeDisplaySetConsoleCursor(col, row); } @@ -2439,7 +2541,7 @@ static uint64_t SyscallFillConsoleCharacter(uint64_t a0, uint64_t a1, uint64_t a (void)a5; int col = (int)(int32_t)a1; int row = (int)(int32_t)a2; - if (col < 0 || row < 0) return STATUS_INVALID_PARAMETER; + if (col < 0 || row < 0) return NTLSTATUS_INVALID_PARAMETER; size_t written = 0; KSTATUS s = KeDisplayFillConsoleChars((char)a0, col, row, (size_t)a3, &written); @@ -2456,7 +2558,7 @@ static uint64_t SyscallFillConsoleAttribute(uint64_t a0, uint64_t a1, uint64_t a (void)a5; int col = (int)(int32_t)a1; int row = (int)(int32_t)a2; - if (col < 0 || row < 0) return STATUS_INVALID_PARAMETER; + if (col < 0 || row < 0) return NTLSTATUS_INVALID_PARAMETER; size_t written = 0; KSTATUS s = KeDisplayFillConsoleAttrs((uint16_t)a0, col, row, (size_t)a3, &written); @@ -2469,17 +2571,17 @@ static uint64_t SyscallFillConsoleAttribute(uint64_t a0, uint64_t a1, uint64_t a // Validates a user input queue handle. Handle zero means the default queue. static KSTATUS KiValidateInputQueueHandle(uint32_t handle) { - if (handle == 0) return STATUS_SUCCESS; + if (handle == 0) return NTLSTATUS_SUCCESS; OBJECT* obj = KiHandleToObject(handle, ObjectTypeInputQueue, HANDLE_RIGHT_READ); - if (!obj) return STATUS_INVALID_HANDLE; + if (!obj) return NTLSTATUS_INVALID_HANDLE; ObDereferenceObject(obj); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Copies one keyboard input record to user mode. static KSTATUS KiCopyInputRecordToUser(INPUT_KEY_RECORD* userRecord, const INPUT_KEY_RECORD* record) { - if (!userRecord || !record) return STATUS_INVALID_PARAMETER; + if (!userRecord || !record) return NTLSTATUS_INVALID_PARAMETER; return CopyToUser(userRecord, record, sizeof(*record)); } @@ -2487,9 +2589,9 @@ static KSTATUS KiCopyInputRecordToUser(INPUT_KEY_RECORD* userRecord, const INPUT static KSTATUS KiCopyInputEventRequest(uint64_t arg, SYS_INPUT_EVENT_REQUEST* req) { KSTATUS s = KiCopyUserRequest(arg, req, sizeof(*req)); if (!KSUCCESS(s)) return s; - if (req->Size != sizeof(*req)) return STATUS_INVALID_PARAMETER; - if (req->Flags != SYS_INPUT_EVENT_FLAG_NONE) return STATUS_INVALID_PARAMETER; - if (!req->RecordOut) return STATUS_INVALID_PARAMETER; + if (req->Size != sizeof(*req)) return NTLSTATUS_INVALID_PARAMETER; + if (req->Flags != SYS_INPUT_EVENT_FLAG_NONE) return NTLSTATUS_INVALID_PARAMETER; + if (!req->RecordOut) return NTLSTATUS_INVALID_PARAMETER; return KiValidateInputQueueHandle(req->QueueHandle); } @@ -2497,19 +2599,19 @@ static KSTATUS KiCopyInputEventRequest(uint64_t arg, SYS_INPUT_EVENT_REQUEST* re static uint64_t SyscallKbPoll(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; INPUT_KEY key = KeInputKbPoll(); KSTATUS s = CopyToUser((void*)(uintptr_t)a0, &key, sizeof(key)); if (!KSUCCESS(s)) return s; - return (key == INPUT_KEY_NONE) ? STATUS_WOULD_BLOCK : STATUS_SUCCESS; + return (key == INPUT_KEY_NONE) ? NTLSTATUS_WOULD_BLOCK : NTLSTATUS_SUCCESS; } // SYS_IS_KEY_DOWN a0=INPUT_KEY a1=*bool -> KSTATUS. static uint64_t SyscallKbIsKeyDown(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; bool down = KeInputIsKeyDown((INPUT_KEY)a0); return CopyToUser((void*)(uintptr_t)a1, &down, sizeof(down)); @@ -2519,7 +2621,7 @@ static uint64_t SyscallKbIsKeyDown(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallKbReadChar(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; for (;;) { char ch = KeInputReadChar(); @@ -2536,7 +2638,7 @@ static uint64_t SyscallKbReadChar(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallKbReadKey(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; for (;;) { INPUT_KEY key = KeInputReadKey(); @@ -2571,7 +2673,7 @@ static uint64_t SyscallKbReadInputEvent(uint64_t a0, uint64_t a1, uint64_t a2, return KiCopyInputRecordToUser(req.RecordOut, &record); if (req.TimeoutMilliseconds == 0) - return STATUS_WOULD_BLOCK; + return NTLSTATUS_WOULD_BLOCK; s = KeInputWaitKey(0, req.TimeoutMilliseconds); if (!KSUCCESS(s)) @@ -2594,7 +2696,7 @@ static uint64_t SyscallKbPeekInputEvent(uint64_t a0, uint64_t a1, uint64_t a2, return KiCopyInputRecordToUser(req.RecordOut, &record); if (req.TimeoutMilliseconds == 0) - return STATUS_WOULD_BLOCK; + return NTLSTATUS_WOULD_BLOCK; s = KeInputWaitKey(0, req.TimeoutMilliseconds); if (!KSUCCESS(s)) @@ -2606,10 +2708,10 @@ static uint64_t SyscallKbPeekInputEvent(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallMousePeek(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; INPUT_MOUSE_EVENT event; - if (!KeInputMousePeek(&event)) return STATUS_WOULD_BLOCK; + if (!KeInputMousePeek(&event)) return NTLSTATUS_WOULD_BLOCK; return CopyToUser((void*)(uintptr_t)a0, &event, sizeof(event)); } @@ -2617,10 +2719,10 @@ static uint64_t SyscallMousePeek(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallMouseRead(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; INPUT_MOUSE_EVENT event; - if (!KeInputMouseRead(&event)) return STATUS_WOULD_BLOCK; + if (!KeInputMouseRead(&event)) return NTLSTATUS_WOULD_BLOCK; return CopyToUser((void*)(uintptr_t)a0, &event, sizeof(event)); } @@ -2628,7 +2730,7 @@ static uint64_t SyscallMouseRead(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallMouseGetPos(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0 || !a1) return STATUS_INVALID_PARAMETER; + if (!a0 || !a1) return NTLSTATUS_INVALID_PARAMETER; int x = 0, y = 0; KeInputMouseGetPosition(&x, &y); @@ -2648,10 +2750,10 @@ static uint64_t SyscallGetTick(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallGetTickFrequency(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!gHal || !gHal->Timer.QueryTickFrequency) return STATUS_DEVICE_ERROR; + if (!gHal || !gHal->Timer.QueryTickFrequency) return NTLSTATUS_DEVICE_ERROR; uint64_t frequency = gHal->Timer.QueryTickFrequency(); - if (!frequency) return STATUS_DEVICE_ERROR; + if (!frequency) return NTLSTATUS_DEVICE_ERROR; return KiCopyU64ToUser(a0, frequency); } @@ -2659,7 +2761,7 @@ static uint64_t SyscallGetTickFrequency(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallGetSystemTime(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; SYS_SYSTEM_TIME t; KSTATUS s = KeQuerySystemTime(&t); @@ -2675,9 +2777,9 @@ static uint64_t SyscallDebugPrint(uint64_t a0, uint64_t a1, uint64_t a2, SYS_PRINT_DEBUG_REQUEST req; KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; - if (req.Text.Length == 0) return STATUS_SUCCESS; - if (!req.Text.Data) return STATUS_INVALID_PARAMETER; - if (req.Text.Length > SYSCALL_TEXT_MAX_BYTES) return STATUS_BUFFER_TOO_SMALL; + if (req.Text.Length == 0) return NTLSTATUS_SUCCESS; + if (!req.Text.Data) return NTLSTATUS_INVALID_PARAMETER; + if (req.Text.Length > SYSCALL_TEXT_MAX_BYTES) return NTLSTATUS_BUFFER_TOO_SMALL; char chunk[512]; size_t offset = 0; @@ -2689,14 +2791,14 @@ static uint64_t SyscallDebugPrint(uint64_t a0, uint64_t a1, uint64_t a2, DbgPrint("%v", SysSvFromParts(chunk, todo)); offset += todo; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_QUERY_TRAP_FRAME a0=*SYS_TRAP_FRAME_INFO. static uint64_t SyscallQueryTrapFrame(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; uint32_t userSize = 0; KSTATUS s = CopyFromUser(&userSize, (const void*)(uintptr_t)a0, sizeof(userSize)); @@ -2707,7 +2809,7 @@ static uint64_t SyscallQueryTrapFrame(uint64_t a0, uint64_t a1, uint64_t a2, info.Size = userSize; s = KeQueryCurrentTrapFrame(&info); - size_t copySize = (s == STATUS_BUFFER_TOO_SMALL) ? sizeof(info.Size) : sizeof(info); + size_t copySize = (s == NTLSTATUS_BUFFER_TOO_SMALL) ? sizeof(info.Size) : sizeof(info); KSTATUS cs = CopyToUser((void*)(uintptr_t)a0, &info, copySize); if (!KSUCCESS(cs)) return cs; return s; @@ -2721,7 +2823,7 @@ static uint64_t SyscallCreateProcess(uint64_t a0, uint64_t a1, uint64_t a2, SYS_CREATE_PROCESS_REQUEST req; KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; - if (!req.HandleOut) return STATUS_INVALID_PARAMETER; + if (!req.HandleOut) return NTLSTATUS_INVALID_PARAMETER; char pathBuf[SYSCALL_STRING_MAX]; char cmdlineBuf[SYSCALL_STRING_MAX]; @@ -2730,7 +2832,7 @@ static uint64_t SyscallCreateProcess(uint64_t a0, uint64_t a1, uint64_t a2, s = KiImportUserTextView(req.Path, pathBuf, sizeof(pathBuf), &path, true); if (!KSUCCESS(s)) return s; - if (path.Length == 0) return STATUS_INVALID_PARAMETER; + if (path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; s = KiImportUserTextView(req.CommandLine, cmdlineBuf, sizeof(cmdlineBuf), &cmdlineView, true); if (!KSUCCESS(s)) return s; @@ -2801,7 +2903,7 @@ static uint64_t SyscallCreateProcess(uint64_t a0, uint64_t a1, uint64_t a2, PROCESS* caller = KeGetCurrentProcess(); if (!caller) { ObDereferenceObject(&proc->Header); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } uint32_t handle = 0; @@ -2829,7 +2931,7 @@ static uint64_t SyscallCreateProcess(uint64_t a0, uint64_t a1, uint64_t a2, s = KiCopyHandleToUser((uint64_t)(uintptr_t)req.HandleOut, handle); if (!KSUCCESS(s)) { - KeTerminateProcess(proc, (int)STATUS_PROCESS_PAGE_FAULT); + KeTerminateProcess(proc, (int)NTLSTATUS_PROCESS_PAGE_FAULT); KeCloseHandle(caller, handle); ObDereferenceObject(&proc->Header); return s; @@ -2838,24 +2940,24 @@ static uint64_t SyscallCreateProcess(uint64_t a0, uint64_t a1, uint64_t a2, // Drop the creator's local reference. The returned handle and live thread // references now own the process lifetime. ObDereferenceObject(&proc->Header); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_OPEN_PROCESS a0=pid a1=*handleOut. static uint64_t SyscallOpenProcess(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; KSTATUS s = MmProbeUserWrite((void*)(uintptr_t)a1, sizeof(uint32_t)); if (!KSUCCESS(s)) return s; PROCESS* proc = KeGetProcessById((uint32_t)a0); - if (!proc) return STATUS_NOT_FOUND; + if (!proc) return NTLSTATUS_NOT_FOUND; PROCESS* caller = KeGetCurrentProcess(); if (!caller) { ObDereferenceObject(&proc->Header); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } uint32_t handle = 0; @@ -2870,17 +2972,17 @@ static uint64_t SyscallOpenProcess(uint64_t a0, uint64_t a1, uint64_t a2, KeCloseHandle(caller, handle); return s; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_GET_PROCESS_EXIT_CODE (4) copies the process exit code. static uint64_t SyscallGetProcessExitCode(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; PROCESS* proc = (PROCESS*)KiHandleToObject((uint32_t)a0, ObjectTypeProcess, HANDLE_RIGHT_QUERY); - if (!proc) return STATUS_INVALID_HANDLE; + if (!proc) return NTLSTATUS_INVALID_HANDLE; int32_t exitCode = 0; KSTATUS s = KeGetProcessExitCode(proc, &exitCode); @@ -2898,9 +3000,9 @@ static uint64_t SyscallWriteConsole(uint64_t a0, uint64_t a1, uint64_t a2, SYS_WRITE_CONSOLE_REQUEST req; KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; - if (req.Text.Length == 0) return STATUS_SUCCESS; - if (!req.Text.Data) return STATUS_INVALID_PARAMETER; - if (req.Text.Length > SYSCALL_TEXT_MAX_BYTES) return STATUS_BUFFER_TOO_SMALL; + if (req.Text.Length == 0) return NTLSTATUS_SUCCESS; + if (!req.Text.Data) return NTLSTATUS_INVALID_PARAMETER; + if (req.Text.Length > SYSCALL_TEXT_MAX_BYTES) return NTLSTATUS_BUFFER_TOO_SMALL; char chunk[512]; size_t offset = 0; @@ -2912,7 +3014,7 @@ static uint64_t SyscallWriteConsole(uint64_t a0, uint64_t a1, uint64_t a2, KePrintConsole(chunk, todo); offset += todo; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_OPEN_DIR (54) a0=*dirPath a1=*handleOut. @@ -2923,7 +3025,7 @@ static uint64_t SyscallOpenDir(uint64_t a0, uint64_t a1, uint64_t a2, SYS_PATH_HANDLE_REQUEST req; KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; - if (!req.HandleOut) return STATUS_INVALID_PARAMETER; + if (!req.HandleOut) return NTLSTATUS_INVALID_PARAMETER; char dirPathBuf[SYSCALL_STRING_MAX]; SYS_STRING_VIEW dirPath; @@ -2950,18 +3052,18 @@ static uint64_t SyscallOpenDir(uint64_t a0, uint64_t a1, uint64_t a2, if (proc) KeCloseHandle(proc, handle); return s; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_READ_DIR (55) a0=handle a1=*KDIR_ENTRY -// Returns STATUS_NO_MORE_FILES when the directory is exhausted. +// Returns NTLSTATUS_NO_MORE_FILES when the directory is exhausted. static uint64_t SyscallReadDir(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; DIR_OBJECT* dir = (DIR_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeDir, HANDLE_RIGHT_READ); - if (!dir) return STATUS_INVALID_PARAMETER; + if (!dir) return NTLSTATUS_INVALID_PARAMETER; KDIR_ENTRY entry; KSTATUS s = IoReadDir(dir, &entry); @@ -2984,7 +3086,7 @@ static uint64_t SyscallSetCwd(uint64_t a0, uint64_t a1, uint64_t a2, SYS_STRING_VIEW path; s = KiImportUserTextView(req.Path, pathBuf, sizeof(pathBuf), &path, true); if (!KSUCCESS(s)) return s; - if (path.Length == 0) return STATUS_INVALID_PARAMETER; + if (path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; return IoSetCwd(path); } @@ -2998,9 +3100,9 @@ static uint64_t SyscallRealPath(uint64_t a0, uint64_t a1, uint64_t a2, KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; if (req.Size != sizeof(req) || req.Flags != SYS_REAL_PATH_FLAG_NONE) - return STATUS_INVALID_PARAMETER; - if (!req.Buffer && req.BufferSize != 0) return STATUS_INVALID_PARAMETER; - if (!req.Buffer && !req.RequiredSizeOut) return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; + if (!req.Buffer && req.BufferSize != 0) return NTLSTATUS_INVALID_PARAMETER; + if (!req.Buffer && !req.RequiredSizeOut) return NTLSTATUS_INVALID_PARAMETER; if (req.RequiredSizeOut) { s = MmProbeUserWrite(req.RequiredSizeOut, sizeof(size_t)); @@ -3011,7 +3113,7 @@ static uint64_t SyscallRealPath(uint64_t a0, uint64_t a1, uint64_t a2, SYS_STRING_VIEW path; s = KiImportUserTextView(req.Path, pathBuf, sizeof(pathBuf), &path, true); if (!KSUCCESS(s)) return s; - if (path.Length == 0) return STATUS_INVALID_PARAMETER; + if (path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; char resolved[SYS_CWD_MAX]; size_t required = 0; @@ -3024,9 +3126,9 @@ static uint64_t SyscallRealPath(uint64_t a0, uint64_t a1, uint64_t a2, } if (!req.Buffer) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (req.BufferSize < required) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; return CopyToUser(req.Buffer, resolved, required); } @@ -3037,10 +3139,10 @@ static uint64_t SyscallRealPath(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallGetProcessPid(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; PROCESS* proc = (PROCESS*)KiHandleToObject((uint32_t)a0, ObjectTypeProcess, HANDLE_RIGHT_QUERY); - if (!proc) return STATUS_INVALID_HANDLE; + if (!proc) return NTLSTATUS_INVALID_HANDLE; uint32_t pid = proc->ProcessId; ObDereferenceObject(&proc->Header); @@ -3065,6 +3167,7 @@ typedef struct { size_t NameLength; QUEUE* Queue; // NULL = slot free; non-NULL = occupied uint32_t PublisherPid; // ProcessId of whoever called SysPublishQueue + uint32_t PublisherHandle; // Publisher-owned handle that keeps the name live } NAMED_QUEUE_ENTRY; static NAMED_QUEUE_ENTRY gNamedQueues[NAMED_QUEUE_MAX]; @@ -3076,11 +3179,80 @@ static int KiNamedQueueNameEquals(const NAMED_QUEUE_ENTRY* entry, return SysSvEqual(SysSvFromParts(entry->Name, entry->NameLength), name); } +static int KiNamedQueueOwnedByHandle(const NAMED_QUEUE_ENTRY* entry, + const PROCESS* process, + uint32_t handle, + const OBJECT* object) { + if (!entry || !entry->Queue || !process || !object) + return 0; + return entry->PublisherPid == process->ProcessId && + entry->PublisherHandle == handle && + &entry->Queue->Header == object; +} + +// Clears a named queue slot and returns the registry reference for later release. +static QUEUE* KiNamedQueueClearSlotLocked(NAMED_QUEUE_ENTRY* entry) { + if (!entry || !entry->Queue) + return (QUEUE*)0; + + QUEUE* queue = entry->Queue; + memset(entry, 0, sizeof(*entry)); + return queue; +} + +// Removes one published queue name owned by the current process. +static KSTATUS KiNamedQueueUnpublishByName(SYS_STRING_VIEW nameView) { + PROCESS* process = KeGetCurrentProcess(); + if (!process) + return NTLSTATUS_FAILURE; + + QUEUE* queue = (QUEUE*)0; + uintptr_t flags = KeAcquireSpinlock(&gNamedQueueLock); + for (int i = 0; i < NAMED_QUEUE_MAX; i++) { + if (KiNamedQueueNameEquals(&gNamedQueues[i], nameView)) { + if (gNamedQueues[i].PublisherPid != process->ProcessId) { + KeReleaseSpinlock(&gNamedQueueLock, flags); + return NTLSTATUS_ACCESS_DENIED; + } + queue = KiNamedQueueClearSlotLocked(&gNamedQueues[i]); + break; + } + } + KeReleaseSpinlock(&gNamedQueueLock, flags); + + if (!queue) + return NTLSTATUS_NOT_FOUND; + ObDereferenceObject(&queue->Header); + return NTLSTATUS_SUCCESS; +} + +// Removes published names whose owner handle is being closed. +void KeNamedQueueUnpublishHandle(PROCESS* process, uint32_t handle, OBJECT* object) { + if (!process || !object || object->Type != ObjectTypeQueue) + return; + + for (;;) { + QUEUE* queue = (QUEUE*)0; + uintptr_t flags = KeAcquireSpinlock(&gNamedQueueLock); + for (int i = 0; i < NAMED_QUEUE_MAX; i++) { + if (KiNamedQueueOwnedByHandle(&gNamedQueues[i], process, handle, object)) { + queue = KiNamedQueueClearSlotLocked(&gNamedQueues[i]); + break; + } + } + KeReleaseSpinlock(&gNamedQueueLock, flags); + + if (!queue) + break; + ObDereferenceObject(&queue->Header); + } +} + // SYS_PUBLISH_QUEUE (60) a0=*name a1=queueHandle -// Registers the queue identified by 'queueHandle' under 'name'. -// Fails with STATUS_ALREADY_EXISTS if the name is already taken. -// The registry bumps the queue's refcount so it outlives the handle. +// Registers the queue identified by QueueHandle under Name. +// The published name is owned by the publishing process and handle. Closing that +// handle or exiting the process withdraws every name published through it. static uint64_t SyscallPublishQueue(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; @@ -3093,10 +3265,10 @@ static uint64_t SyscallPublishQueue(uint64_t a0, uint64_t a1, uint64_t a2, SYS_STRING_VIEW nameView; s = KiImportUserTextView(req.Name, name, sizeof(name), &nameView, false); if (!KSUCCESS(s)) return s; - if (nameView.Length == 0) return STATUS_INVALID_PARAMETER; + if (nameView.Length == 0) return NTLSTATUS_INVALID_PARAMETER; QUEUE* q = (QUEUE*)KiHandleToObject(req.QueueHandle, ObjectTypeQueue, HANDLE_RIGHT_DUPLICATE); - if (!q) return STATUS_INVALID_HANDLE; + if (!q) return NTLSTATUS_INVALID_HANDLE; uintptr_t flags = KeAcquireSpinlock(&gNamedQueueLock); @@ -3104,7 +3276,7 @@ static uint64_t SyscallPublishQueue(uint64_t a0, uint64_t a1, uint64_t a2, if (KiNamedQueueNameEquals(&gNamedQueues[i], nameView)) { KeReleaseSpinlock(&gNamedQueueLock, flags); ObDereferenceObject(&q->Header); - return STATUS_ALREADY_EXISTS; + return NTLSTATUS_ALREADY_EXISTS; } } @@ -3114,20 +3286,40 @@ static uint64_t SyscallPublishQueue(uint64_t a0, uint64_t a1, uint64_t a2, gNamedQueues[i].NameLength = nameView.Length; gNamedQueues[i].Queue = q; gNamedQueues[i].PublisherPid = KeGetCurrentProcess()->ProcessId; + gNamedQueues[i].PublisherHandle = req.QueueHandle; KeReleaseSpinlock(&gNamedQueueLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } KeReleaseSpinlock(&gNamedQueueLock, flags); ObDereferenceObject(&q->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; +} + +// SYS_UNPUBLISH_QUEUE a0=*SYS_UNPUBLISH_QUEUE_REQUEST. +// Withdraws a published queue name owned by the calling process. +static uint64_t SyscallUnpublishQueue(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t a3, uint64_t a4, uint64_t a5) { + (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; + + SYS_UNPUBLISH_QUEUE_REQUEST req; + KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); + if (!KSUCCESS(s)) return s; + + char name[NAMED_QUEUE_NAME_MAX]; + SYS_STRING_VIEW nameView; + s = KiImportUserTextView(req.Name, name, sizeof(name), &nameView, false); + if (!KSUCCESS(s)) return s; + if (nameView.Length == 0) return NTLSTATUS_INVALID_PARAMETER; + + return KiNamedQueueUnpublishByName(nameView); } // SYS_OPEN_NAMED_QUEUE (61) a0=*name a1=*handleOut // Looks up 'name' in the registry and allocates a handle to the queue in the -// calling process's handle table. Returns STATUS_NOT_FOUND if no match. +// calling process's handle table. Returns NTLSTATUS_NOT_FOUND if no match. // Callers that race against the publisher should retry on NOT_FOUND. static uint64_t SyscallOpenNamedQueue(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { @@ -3136,13 +3328,13 @@ static uint64_t SyscallOpenNamedQueue(uint64_t a0, uint64_t a1, uint64_t a2, SYS_OPEN_NAMED_QUEUE_REQUEST req; KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; - if (!req.HandleOut) return STATUS_INVALID_PARAMETER; + if (!req.HandleOut) return NTLSTATUS_INVALID_PARAMETER; char name[NAMED_QUEUE_NAME_MAX]; SYS_STRING_VIEW nameView; s = KiImportUserTextView(req.Name, name, sizeof(name), &nameView, false); if (!KSUCCESS(s)) return s; - if (nameView.Length == 0) return STATUS_INVALID_PARAMETER; + if (nameView.Length == 0) return NTLSTATUS_INVALID_PARAMETER; s = MmProbeUserWrite(req.HandleOut, sizeof(uint32_t)); if (!KSUCCESS(s)) return s; @@ -3160,7 +3352,7 @@ static uint64_t SyscallOpenNamedQueue(uint64_t a0, uint64_t a1, uint64_t a2, KeReleaseSpinlock(&gNamedQueueLock, flags); - if (!q) return STATUS_NOT_FOUND; + if (!q) return NTLSTATUS_NOT_FOUND; uint32_t handle = 0; s = KiAllocHandleForCurrentWithRights(&q->Header, HANDLE_RIGHT_READ | HANDLE_RIGHT_WRITE | HANDLE_RIGHT_DUPLICATE | HANDLE_RIGHT_QUERY, &handle); @@ -3172,7 +3364,7 @@ static uint64_t SyscallOpenNamedQueue(uint64_t a0, uint64_t a1, uint64_t a2, if (proc) KeCloseHandle(proc, handle); return s; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_DUPLICATE_HANDLE a0=*request. @@ -3186,16 +3378,16 @@ static uint64_t SyscallDuplicateHandle(uint64_t a0, uint64_t a1, uint64_t a2, KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; if (!req.SourceHandle || !req.TargetProcessHandle || !req.TargetHandleOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; s = MmProbeUserWrite(req.TargetHandleOut, sizeof(uint32_t)); if (!KSUCCESS(s)) return s; PROCESS* caller = KeGetCurrentProcess(); - if (!caller) return STATUS_FAILURE; + if (!caller) return NTLSTATUS_FAILURE; PROCESS* target = (PROCESS*)KiHandleToObject(req.TargetProcessHandle, ObjectTypeProcess, HANDLE_RIGHT_DUPLICATE); - if (!target) return STATUS_INVALID_HANDLE; + if (!target) return NTLSTATUS_INVALID_HANDLE; uint32_t targetHandle = 0; s = KeDuplicateHandleToProcess(caller, req.SourceHandle, target, req.DesiredRights, req.Flags, &targetHandle); @@ -3212,7 +3404,7 @@ static uint64_t SyscallDuplicateHandle(uint64_t a0, uint64_t a1, uint64_t a2, } ObDereferenceObject(&target->Header); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_OPEN_NAMED_QUEUE_OWNER_PROCESS a0=*request. @@ -3225,13 +3417,13 @@ static uint64_t SyscallOpenNamedQueueOwnerProcess(uint64_t a0, uint64_t a1, uint SYS_NAMED_QUEUE_OWNER_REQUEST req; KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; - if (!req.ProcessHandleOut) return STATUS_INVALID_PARAMETER; + if (!req.ProcessHandleOut) return NTLSTATUS_INVALID_PARAMETER; char name[NAMED_QUEUE_NAME_MAX]; SYS_STRING_VIEW nameView; s = KiImportUserTextView(req.Name, name, sizeof(name), &nameView, false); if (!KSUCCESS(s)) return s; - if (nameView.Length == 0) return STATUS_INVALID_PARAMETER; + if (nameView.Length == 0) return NTLSTATUS_INVALID_PARAMETER; s = MmProbeUserWrite(req.ProcessHandleOut, sizeof(uint32_t)); if (!KSUCCESS(s)) return s; @@ -3245,15 +3437,15 @@ static uint64_t SyscallOpenNamedQueueOwnerProcess(uint64_t a0, uint64_t a1, uint } } KeReleaseSpinlock(&gNamedQueueLock, flags); - if (!pid) return STATUS_NOT_FOUND; + if (!pid) return NTLSTATUS_NOT_FOUND; PROCESS* owner = KeGetProcessById(pid); - if (!owner) return STATUS_NOT_FOUND; + if (!owner) return NTLSTATUS_NOT_FOUND; PROCESS* caller = KeGetCurrentProcess(); if (!caller) { ObDereferenceObject(&owner->Header); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } uint32_t handle = 0; @@ -3268,14 +3460,14 @@ static uint64_t SyscallOpenNamedQueueOwnerProcess(uint64_t a0, uint64_t a1, uint KeCloseHandle(caller, handle); return s; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static uint64_t SyscallKillProcess(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; PROCESS* proc = (PROCESS*)KiHandleToObject((uint32_t)a0, ObjectTypeProcess, HANDLE_RIGHT_TERMINATE); - if (!proc) return STATUS_INVALID_HANDLE; + if (!proc) return NTLSTATUS_INVALID_HANDLE; THREAD* self = KeGetCurrentThread(); int32_t exitCode = (int32_t)a1; @@ -3298,7 +3490,7 @@ static uint64_t SyscallGetProcessList(uint64_t a0, uint64_t a1, uint64_t a2, (void)a3; (void)a4; (void)a5; size_t maxCount = (size_t)a1; - if (maxCount && !a0) return STATUS_INVALID_PARAMETER; + if (maxCount && !a0) return NTLSTATUS_INVALID_PARAMETER; if (a2) { KSTATUS s = MmProbeUserWrite((void*)(uintptr_t)a2, sizeof(size_t)); if (!KSUCCESS(s)) return s; @@ -3309,10 +3501,10 @@ static uint64_t SyscallGetProcessList(uint64_t a0, uint64_t a1, uint64_t a2, if (toCopy) { size_t bytes = 0; - if (!KiMulSize(toCopy, sizeof(SYS_PROCESS_INFO), &bytes)) return STATUS_INVALID_PARAMETER; + if (!KiMulSize(toCopy, sizeof(SYS_PROCESS_INFO), &bytes)) return NTLSTATUS_INVALID_PARAMETER; SYS_PROCESS_INFO* tmp = (SYS_PROCESS_INFO*)MmAllocatePoolTag(bytes, MM_POOL_TAG('s', 'y', 's', ' ')); - if (!tmp) return STATUS_NO_MEMORY; + if (!tmp) return NTLSTATUS_NO_MEMORY; size_t copied = KeCopyProcessInfo(tmp, toCopy); if (copied < toCopy) toCopy = copied; @@ -3323,7 +3515,7 @@ static uint64_t SyscallGetProcessList(uint64_t a0, uint64_t a1, uint64_t a2, } if (a2) return KiCopySizeToUser(a2, total); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_GET_THREAD_LIST (103) a0=pid a1=*SYS_THREAD_INFO[] a2=maxCount a3=*countOut. @@ -3333,7 +3525,7 @@ static uint64_t SyscallGetThreadList(uint64_t a0, uint64_t a1, uint64_t a2, uint32_t pid = (uint32_t)a0; size_t maxCount = (size_t)a2; - if (maxCount && !a1) return STATUS_INVALID_PARAMETER; + if (maxCount && !a1) return NTLSTATUS_INVALID_PARAMETER; if (a3) { KSTATUS s = MmProbeUserWrite((void*)(uintptr_t)a3, sizeof(size_t)); if (!KSUCCESS(s)) return s; @@ -3346,10 +3538,10 @@ static uint64_t SyscallGetThreadList(uint64_t a0, uint64_t a1, uint64_t a2, size_t toCopy = total < maxCount ? total : maxCount; if (toCopy) { size_t bytes = 0; - if (!KiMulSize(toCopy, sizeof(SYS_THREAD_INFO), &bytes)) return STATUS_INVALID_PARAMETER; + if (!KiMulSize(toCopy, sizeof(SYS_THREAD_INFO), &bytes)) return NTLSTATUS_INVALID_PARAMETER; SYS_THREAD_INFO* tmp = (SYS_THREAD_INFO*)MmAllocatePoolTag(bytes, MM_POOL_TAG('s', 't', 'h', 'r')); - if (!tmp) return STATUS_NO_MEMORY; + if (!tmp) return NTLSTATUS_NO_MEMORY; size_t copied = 0; s = KeCopyProcessThreadInfo(pid, tmp, toCopy, &copied); @@ -3362,7 +3554,7 @@ static uint64_t SyscallGetThreadList(uint64_t a0, uint64_t a1, uint64_t a2, } if (a3) return KiCopySizeToUser(a3, total); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } @@ -3374,9 +3566,9 @@ static uint64_t SyscallLoadModule(uint64_t a0, uint64_t a1, uint64_t a2, SYS_LOAD_MODULE_REQUEST req; KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; - if (req.Size != sizeof(req)) return STATUS_INVALID_PARAMETER; - if (req.Flags != SYS_LOAD_MODULE_FLAG_NONE) return STATUS_INVALID_PARAMETER; - if (!req.ModuleHandleOut) return STATUS_INVALID_PARAMETER; + if (req.Size != sizeof(req)) return NTLSTATUS_INVALID_PARAMETER; + if (req.Flags != SYS_LOAD_MODULE_FLAG_NONE) return NTLSTATUS_INVALID_PARAMETER; + if (!req.ModuleHandleOut) return NTLSTATUS_INVALID_PARAMETER; s = MmProbeUserWrite(req.ModuleHandleOut, sizeof(*req.ModuleHandleOut)); if (!KSUCCESS(s)) return s; @@ -3389,10 +3581,10 @@ static uint64_t SyscallLoadModule(uint64_t a0, uint64_t a1, uint64_t a2, SYS_STRING_VIEW path; s = KiImportUserTextView(req.Path, pathBuf, sizeof(pathBuf), &path, true); if (!KSUCCESS(s)) return s; - if (path.Length == 0) return STATUS_INVALID_PARAMETER; + if (path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; PROCESS* proc = KeGetCurrentProcess(); - if (!proc) return STATUS_FAILURE; + if (!proc) return NTLSTATUS_FAILURE; uintptr_t base = 0; s = LdrLoadModuleForProcess(proc, pathBuf, LDR_MODULE_LOAD_PUBLIC, &base); @@ -3427,7 +3619,7 @@ static uint64_t SyscallLoadModule(uint64_t a0, uint64_t a1, uint64_t a2, } } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_UNLOAD_MODULE a0=moduleHandle. @@ -3436,28 +3628,28 @@ static uint64_t SyscallUnloadModule(uint64_t a0, uint64_t a1, uint64_t a2, (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; PROCESS* proc = KeGetCurrentProcess(); - if (!proc) return STATUS_FAILURE; + if (!proc) return NTLSTATUS_FAILURE; uint32_t handle = (uint32_t)a0; MODULE_HANDLE_OBJECT* module = (MODULE_HANDLE_OBJECT*)KiHandleToObject(handle, ObjectTypeModule, HANDLE_RIGHT_TERMINATE); - if (!module) return STATUS_INVALID_HANDLE; + if (!module) return NTLSTATUS_INVALID_HANDLE; KeCloseHandle(proc, handle); ObDereferenceObject(&module->Header); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_GET_MODULE_INFO a0=moduleHandle a1=*SYS_MODULE_INFO. static uint64_t SyscallGetModuleInfo(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; KSTATUS s = MmProbeUserWrite((void*)(uintptr_t)a1, sizeof(SYS_MODULE_INFO)); if (!KSUCCESS(s)) return s; MODULE_HANDLE_OBJECT* module = (MODULE_HANDLE_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeModule, HANDLE_RIGHT_QUERY); - if (!module) return STATUS_INVALID_HANDLE; + if (!module) return NTLSTATUS_INVALID_HANDLE; SYS_MODULE_INFO info; s = LdrQueryModuleForProcess(module->Owner, module->Base, &info); @@ -3476,8 +3668,8 @@ static uint64_t SyscallGetModuleExport(uint64_t a0, uint64_t a1, uint64_t a2, SYS_GET_MODULE_EXPORT_REQUEST req; KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; - if (req.Size != sizeof(req)) return STATUS_INVALID_PARAMETER; - if (!req.AddressOut) return STATUS_INVALID_PARAMETER; + if (req.Size != sizeof(req)) return NTLSTATUS_INVALID_PARAMETER; + if (!req.AddressOut) return NTLSTATUS_INVALID_PARAMETER; s = MmProbeUserWrite(req.AddressOut, sizeof(*req.AddressOut)); if (!KSUCCESS(s)) return s; @@ -3486,14 +3678,14 @@ static uint64_t SyscallGetModuleExport(uint64_t a0, uint64_t a1, uint64_t a2, SYS_STRING_VIEW name; s = KiImportUserTextView(req.Name, nameBuf, sizeof(nameBuf), &name, true); if (!KSUCCESS(s)) return s; - if (name.Length == 0) return STATUS_INVALID_PARAMETER; + if (name.Length == 0) return NTLSTATUS_INVALID_PARAMETER; MODULE_HANDLE_OBJECT* module = (MODULE_HANDLE_OBJECT*)KiHandleToObject(req.ModuleHandle, ObjectTypeModule, HANDLE_RIGHT_QUERY); - if (!module) return STATUS_INVALID_HANDLE; + if (!module) return NTLSTATUS_INVALID_HANDLE; void* address = LdrGetModuleExportForProcess(module->Owner, module->Base, nameBuf); ObDereferenceObject(&module->Header); - if (!address) return STATUS_NOT_FOUND; + if (!address) return NTLSTATUS_NOT_FOUND; uintptr_t userAddress = (uintptr_t)address; return CopyToUser(req.AddressOut, &userAddress, sizeof(userAddress)); @@ -3505,31 +3697,31 @@ static uint64_t SyscallGetModuleList(uint64_t a0, uint64_t a1, uint64_t a2, (void)a3; (void)a4; (void)a5; size_t maxCount = (size_t)a1; - if (maxCount && !a0) return STATUS_INVALID_PARAMETER; + if (maxCount && !a0) return NTLSTATUS_INVALID_PARAMETER; if (a2) { KSTATUS s = MmProbeUserWrite((void*)(uintptr_t)a2, sizeof(size_t)); if (!KSUCCESS(s)) return s; } PROCESS* proc = KeGetCurrentProcess(); - if (!proc) return STATUS_FAILURE; + if (!proc) return NTLSTATUS_FAILURE; size_t total = 0; KSTATUS s = LdrCopyProcessModuleInfo(proc, NULL, 0, &total); - if (s != STATUS_BUFFER_TOO_SMALL && !KSUCCESS(s)) return s; + if (s != NTLSTATUS_BUFFER_TOO_SMALL && !KSUCCESS(s)) return s; size_t toCopy = total < maxCount ? total : maxCount; if (toCopy) { size_t bytes = 0; - if (!KiMulSize(toCopy, sizeof(SYS_MODULE_INFO), &bytes)) return STATUS_INVALID_PARAMETER; + if (!KiMulSize(toCopy, sizeof(SYS_MODULE_INFO), &bytes)) return NTLSTATUS_INVALID_PARAMETER; SYS_MODULE_INFO* tmp = (SYS_MODULE_INFO*)MmAllocatePoolTag(bytes, MM_POOL_TAG('m', 'o', 'd', 'l')); - if (!tmp) return STATUS_NO_MEMORY; + if (!tmp) return NTLSTATUS_NO_MEMORY; size_t copiedTotal = 0; s = LdrCopyProcessModuleInfo(proc, tmp, toCopy, &copiedTotal); - if (s == STATUS_BUFFER_TOO_SMALL) - s = STATUS_SUCCESS; + if (s == NTLSTATUS_BUFFER_TOO_SMALL) + s = NTLSTATUS_SUCCESS; if (KSUCCESS(s)) s = CopyToUser((void*)(uintptr_t)a0, tmp, toCopy * sizeof(SYS_MODULE_INFO)); MmFreePool(tmp); @@ -3537,7 +3729,7 @@ static uint64_t SyscallGetModuleList(uint64_t a0, uint64_t a1, uint64_t a2, } if (a2) return KiCopySizeToUser(a2, total); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // SYS_RENAME_FILE (66) a0=*oldPath a1=*newPath. @@ -3557,7 +3749,7 @@ static uint64_t SyscallRenameFile(uint64_t a0, uint64_t a1, uint64_t a2, if (!KSUCCESS(s)) return s; s = KiImportUserTextView(req.NewPath, newPathBuf, sizeof(newPathBuf), &newPath, true); if (!KSUCCESS(s)) return s; - if (oldPath.Length == 0 || newPath.Length == 0) return STATUS_INVALID_PARAMETER; + if (oldPath.Length == 0 || newPath.Length == 0) return NTLSTATUS_INVALID_PARAMETER; return IoRenameFile(oldPath, newPath); } @@ -3569,16 +3761,16 @@ static uint64_t SyscallLockFile(uint64_t a0, uint64_t a1, uint64_t a2, SYS_LOCK_FILE_REQUEST req; KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; - if (req.Size != sizeof(req)) return STATUS_INVALID_PARAMETER; - if (req.Flags != SYS_FILE_LOCK_FLAG_NONE) return STATUS_INVALID_PARAMETER; - if (req.Mode != SYS_FILE_LOCK_SHARED && req.Mode != SYS_FILE_LOCK_EXCLUSIVE) return STATUS_INVALID_PARAMETER; - if (req.Length == 0) return STATUS_INVALID_PARAMETER; + if (req.Size != sizeof(req)) return NTLSTATUS_INVALID_PARAMETER; + if (req.Flags != SYS_FILE_LOCK_FLAG_NONE) return NTLSTATUS_INVALID_PARAMETER; + if (req.Mode != SYS_FILE_LOCK_SHARED && req.Mode != SYS_FILE_LOCK_EXCLUSIVE) return NTLSTATUS_INVALID_PARAMETER; + if (req.Length == 0) return NTLSTATUS_INVALID_PARAMETER; PROCESS* proc = KeGetCurrentProcess(); - if (!proc) return STATUS_FAILURE; + if (!proc) return NTLSTATUS_FAILURE; FILE_OBJECT* file = (FILE_OBJECT*)KiHandleToObject(req.FileHandle, ObjectTypeFile, HANDLE_RIGHT_LOCK); - if (!file) return STATUS_INVALID_HANDLE; + if (!file) return NTLSTATUS_INVALID_HANDLE; s = IoLockFile(file, proc, req.Mode, req.Offset, req.Length, req.TimeoutMilliseconds); ObDereferenceObject(&file->Header); @@ -3593,15 +3785,15 @@ static uint64_t SyscallUnlockFile(uint64_t a0, uint64_t a1, uint64_t a2, SYS_UNLOCK_FILE_REQUEST req; KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); if (!KSUCCESS(s)) return s; - if (req.Size != sizeof(req)) return STATUS_INVALID_PARAMETER; - if (req.Flags != SYS_FILE_LOCK_FLAG_NONE) return STATUS_INVALID_PARAMETER; - if (req.Length == 0) return STATUS_INVALID_PARAMETER; + if (req.Size != sizeof(req)) return NTLSTATUS_INVALID_PARAMETER; + if (req.Flags != SYS_FILE_LOCK_FLAG_NONE) return NTLSTATUS_INVALID_PARAMETER; + if (req.Length == 0) return NTLSTATUS_INVALID_PARAMETER; PROCESS* proc = KeGetCurrentProcess(); - if (!proc) return STATUS_FAILURE; + if (!proc) return NTLSTATUS_FAILURE; FILE_OBJECT* file = (FILE_OBJECT*)KiHandleToObject(req.FileHandle, ObjectTypeFile, HANDLE_RIGHT_LOCK); - if (!file) return STATUS_INVALID_HANDLE; + if (!file) return NTLSTATUS_INVALID_HANDLE; s = IoUnlockFile(file, proc, req.Offset, req.Length); ObDereferenceObject(&file->Header); @@ -3621,7 +3813,7 @@ static uint64_t SyscallCreateDir(uint64_t a0, uint64_t a1, uint64_t a2, SYS_STRING_VIEW path; s = KiImportUserTextView(req.Path, pathBuf, sizeof(pathBuf), &path, true); if (!KSUCCESS(s)) return s; - if (path.Length == 0) return STATUS_INVALID_PARAMETER; + if (path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; return IoCreateDir(path); } @@ -3638,7 +3830,7 @@ static uint64_t SyscallRemoveDir(uint64_t a0, uint64_t a1, uint64_t a2, SYS_STRING_VIEW path; s = KiImportUserTextView(req.Path, pathBuf, sizeof(pathBuf), &path, true); if (!KSUCCESS(s)) return s; - if (path.Length == 0) return STATUS_INVALID_PARAMETER; + if (path.Length == 0) return NTLSTATUS_INVALID_PARAMETER; return IoRemoveDir(path); } @@ -3726,7 +3918,7 @@ typedef struct SYS_MEMORY_STATUS_K { static uint64_t SyscallSocket(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a4; (void)a5; - if (!a3) return STATUS_INVALID_PARAMETER; + if (!a3) return NTLSTATUS_INVALID_PARAMETER; SOCKET_OBJECT* socket = NULL; KSTATUS s = NetSocketCreate((uint32_t)a0, (uint32_t)a1, (uint32_t)a2, &socket); @@ -3747,19 +3939,40 @@ static uint64_t SyscallSocket(uint64_t a0, uint64_t a1, uint64_t a2, return s; } +// Validates the user-supplied socket address buffer size before copying. +static KSTATUS SyscallValidateSocketAddressBufferSize(size_t addressSize) { + if (addressSize < sizeof(SYS_SOCKET_ADDRESS_K)) + return NTLSTATUS_BUFFER_TOO_SMALL; + if (addressSize != sizeof(SYS_SOCKET_ADDRESS_K)) + return NTLSTATUS_INVALID_PARAMETER; + return NTLSTATUS_SUCCESS; +} + +// Validates the fixed-size socket address ABI after a bounded copy. +static KSTATUS SyscallValidateSocketAddressInput(const SYS_SOCKET_ADDRESS_K* address) { + if (!address) + return NTLSTATUS_INVALID_PARAMETER; + if (address->Size != sizeof(SYS_SOCKET_ADDRESS_K)) + return NTLSTATUS_INVALID_PARAMETER; + return NTLSTATUS_SUCCESS; +} + // SYS_BIND_SOCKET a0=socketHandle a1=*SYS_SOCKET_ADDRESS a2=addressSize. static uint64_t SyscallBind(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; - if ((size_t)a2 < sizeof(SYS_SOCKET_ADDRESS_K)) return STATUS_BUFFER_TOO_SMALL; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; + KSTATUS s = SyscallValidateSocketAddressBufferSize((size_t)a2); + if (!KSUCCESS(s)) return s; SYS_SOCKET_ADDRESS_K address; - KSTATUS s = CopyFromUser(&address, (const void*)(uintptr_t)a1, sizeof(address)); + s = CopyFromUser(&address, (const void*)(uintptr_t)a1, sizeof(address)); + if (!KSUCCESS(s)) return s; + s = SyscallValidateSocketAddressInput(&address); if (!KSUCCESS(s)) return s; SOCKET_OBJECT* socket = (SOCKET_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeSocket, HANDLE_RIGHT_READ | HANDLE_RIGHT_WRITE); - if (!socket) return STATUS_NOT_FOUND; + if (!socket) return NTLSTATUS_NOT_FOUND; s = NetSocketBind(socket, &address, (size_t)a2); ObDereferenceObject(&socket->Header); @@ -3772,7 +3985,7 @@ static uint64_t SyscallListen(uint64_t a0, uint64_t a1, uint64_t a2, (void)a2; (void)a3; (void)a4; (void)a5; SOCKET_OBJECT* socket = (SOCKET_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeSocket, HANDLE_RIGHT_READ | HANDLE_RIGHT_WRITE); - if (!socket) return STATUS_NOT_FOUND; + if (!socket) return NTLSTATUS_NOT_FOUND; KSTATUS s = NetSocketListen(socket, (uint32_t)a1); ObDereferenceObject(&socket->Header); @@ -3784,25 +3997,25 @@ static uint64_t SyscallListen(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallAccept(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a4; (void)a5; - if (!a3) return STATUS_INVALID_PARAMETER; + if (!a3) return NTLSTATUS_INVALID_PARAMETER; bool wantRemote = (a1 != 0); size_t remoteCapacity = 0; if (wantRemote) { - if (!a2) return STATUS_INVALID_PARAMETER; + if (!a2) return NTLSTATUS_INVALID_PARAMETER; KSTATUS cs = CopyFromUser(&remoteCapacity, (const void*)(uintptr_t)a2, sizeof(remoteCapacity)); if (!KSUCCESS(cs)) return cs; if (remoteCapacity < sizeof(SYS_SOCKET_ADDRESS_K)) { size_t required = sizeof(SYS_SOCKET_ADDRESS_K); (void)CopyToUser((void*)(uintptr_t)a2, &required, sizeof(required)); - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; } cs = MmProbeUserWrite((void*)(uintptr_t)a1, sizeof(SYS_SOCKET_ADDRESS_K)); if (!KSUCCESS(cs)) return cs; } SOCKET_OBJECT* listener = (SOCKET_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeSocket, HANDLE_RIGHT_READ | HANDLE_RIGHT_WRITE); - if (!listener) return STATUS_NOT_FOUND; + if (!listener) return NTLSTATUS_NOT_FOUND; SOCKET_OBJECT* accepted = NULL; SYS_SOCKET_ADDRESS_K remote; @@ -3838,15 +4051,18 @@ static uint64_t SyscallAccept(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallConnect(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; - if ((size_t)a2 < sizeof(SYS_SOCKET_ADDRESS_K)) return STATUS_BUFFER_TOO_SMALL; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; + KSTATUS s = SyscallValidateSocketAddressBufferSize((size_t)a2); + if (!KSUCCESS(s)) return s; SYS_SOCKET_ADDRESS_K address; - KSTATUS s = CopyFromUser(&address, (const void*)(uintptr_t)a1, sizeof(address)); + s = CopyFromUser(&address, (const void*)(uintptr_t)a1, sizeof(address)); + if (!KSUCCESS(s)) return s; + s = SyscallValidateSocketAddressInput(&address); if (!KSUCCESS(s)) return s; SOCKET_OBJECT* socket = (SOCKET_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeSocket, HANDLE_RIGHT_READ | HANDLE_RIGHT_WRITE); - if (!socket) return STATUS_NOT_FOUND; + if (!socket) return NTLSTATUS_NOT_FOUND; s = NetSocketConnect(socket, &address, (size_t)a2, (IO_ASYNC_REQUEST_OBJECT*)0); ObDereferenceObject(&socket->Header); @@ -3858,22 +4074,22 @@ static uint64_t SyscallSend(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a5; size_t length = (size_t)a2; - if (length && !a1) return STATUS_INVALID_PARAMETER; - if (length > SYSCALL_IO_MAX_BYTES) return STATUS_INVALID_PARAMETER; + if (length && !a1) return NTLSTATUS_INVALID_PARAMETER; + if (length > SYSCALL_IO_MAX_BYTES) return NTLSTATUS_INVALID_PARAMETER; if (length == 0) { if (a4) return KiCopySizeToUser(a4, 0); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } void* kbuf = MmAllocatePoolTag(length, MM_POOL_TAG('s', 'y', 's', ' ')); - if (!kbuf) return STATUS_NO_MEMORY; + if (!kbuf) return NTLSTATUS_NO_MEMORY; KSTATUS s = CopyFromUser(kbuf, (const void*)(uintptr_t)a1, length); if (!KSUCCESS(s)) { MmFreePool(kbuf); return s; } SOCKET_OBJECT* socket = (SOCKET_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeSocket, HANDLE_RIGHT_READ | HANDLE_RIGHT_WRITE); - if (!socket) { MmFreePool(kbuf); return STATUS_NOT_FOUND; } + if (!socket) { MmFreePool(kbuf); return NTLSTATUS_NOT_FOUND; } size_t sent = 0; s = NetSocketSend(socket, kbuf, length, (uint32_t)a3, &sent); @@ -3892,22 +4108,22 @@ static uint64_t SyscallRecv(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a5; size_t length = (size_t)a2; - if (length && !a1) return STATUS_INVALID_PARAMETER; - if (length > SYSCALL_IO_MAX_BYTES) return STATUS_INVALID_PARAMETER; + if (length && !a1) return NTLSTATUS_INVALID_PARAMETER; + if (length > SYSCALL_IO_MAX_BYTES) return NTLSTATUS_INVALID_PARAMETER; if (length == 0) { if (a4) return KiCopySizeToUser(a4, 0); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KSTATUS s = MmProbeUserWrite((void*)(uintptr_t)a1, length); if (!KSUCCESS(s)) return s; void* kbuf = MmAllocatePoolTag(length, MM_POOL_TAG('s', 'y', 's', ' ')); - if (!kbuf) return STATUS_NO_MEMORY; + if (!kbuf) return NTLSTATUS_NO_MEMORY; SOCKET_OBJECT* socket = (SOCKET_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeSocket, HANDLE_RIGHT_READ | HANDLE_RIGHT_WRITE); - if (!socket) { MmFreePool(kbuf); return STATUS_NOT_FOUND; } + if (!socket) { MmFreePool(kbuf); return NTLSTATUS_NOT_FOUND; } size_t received = 0; s = NetSocketReceive(socket, kbuf, length, (uint32_t)a3, &received, (IO_ASYNC_REQUEST_OBJECT*)0); @@ -3928,7 +4144,7 @@ static uint64_t SyscallShutdown(uint64_t a0, uint64_t a1, uint64_t a2, (void)a2; (void)a3; (void)a4; (void)a5; SOCKET_OBJECT* socket = (SOCKET_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeSocket, HANDLE_RIGHT_READ | HANDLE_RIGHT_WRITE); - if (!socket) return STATUS_NOT_FOUND; + if (!socket) return NTLSTATUS_NOT_FOUND; KSTATUS s = NetSocketShutdown(socket, (uint32_t)a1); ObDereferenceObject(&socket->Header); @@ -3939,30 +4155,33 @@ static uint64_t SyscallShutdown(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallSendTo(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; SYS_SOCKET_SEND_TO_REQUEST_K req; KSTATUS s = CopyFromUser(&req, (const void*)(uintptr_t)a1, sizeof(req)); if (!KSUCCESS(s)) return s; - if (req.Length && !req.Buffer) return STATUS_INVALID_PARAMETER; - if (!req.RemoteAddress) return STATUS_INVALID_PARAMETER; - if (req.RemoteAddressSize < sizeof(SYS_SOCKET_ADDRESS_K)) return STATUS_BUFFER_TOO_SMALL; - if (req.Length > SYSCALL_IO_MAX_BYTES) return STATUS_INVALID_PARAMETER; + if (req.Length && !req.Buffer) return NTLSTATUS_INVALID_PARAMETER; + if (!req.RemoteAddress) return NTLSTATUS_INVALID_PARAMETER; + if (req.Length > SYSCALL_IO_MAX_BYTES) return NTLSTATUS_INVALID_PARAMETER; + s = SyscallValidateSocketAddressBufferSize(req.RemoteAddressSize); + if (!KSUCCESS(s)) return s; SYS_SOCKET_ADDRESS_K remote; s = CopyFromUser(&remote, req.RemoteAddress, sizeof(remote)); if (!KSUCCESS(s)) return s; + s = SyscallValidateSocketAddressInput(&remote); + if (!KSUCCESS(s)) return s; void* kbuf = NULL; if (req.Length) { kbuf = MmAllocatePoolTag(req.Length, MM_POOL_TAG('s', 'y', 's', ' ')); - if (!kbuf) return STATUS_NO_MEMORY; + if (!kbuf) return NTLSTATUS_NO_MEMORY; s = CopyFromUser(kbuf, req.Buffer, req.Length); if (!KSUCCESS(s)) { MmFreePool(kbuf); return s; } } SOCKET_OBJECT* socket = (SOCKET_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeSocket, HANDLE_RIGHT_READ | HANDLE_RIGHT_WRITE); - if (!socket) { if (kbuf) MmFreePool(kbuf); return STATUS_NOT_FOUND; } + if (!socket) { if (kbuf) MmFreePool(kbuf); return NTLSTATUS_NOT_FOUND; } size_t sent = 0; s = NetSocketSendTo(socket, kbuf, req.Length, req.Flags, &remote, req.RemoteAddressSize, &sent); @@ -3980,24 +4199,24 @@ static uint64_t SyscallSendTo(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallRecvFrom(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; SYS_SOCKET_RECV_FROM_REQUEST_K req; KSTATUS s = CopyFromUser(&req, (const void*)(uintptr_t)a1, sizeof(req)); if (!KSUCCESS(s)) return s; - if (req.Length && !req.Buffer) return STATUS_INVALID_PARAMETER; - if (req.Length > SYSCALL_IO_MAX_BYTES) return STATUS_INVALID_PARAMETER; + if (req.Length && !req.Buffer) return NTLSTATUS_INVALID_PARAMETER; + if (req.Length > SYSCALL_IO_MAX_BYTES) return NTLSTATUS_INVALID_PARAMETER; bool wantRemote = (req.RemoteAddressOut != NULL); size_t remoteCapacity = 0; if (wantRemote) { - if (!req.RemoteAddressSizeInOut) return STATUS_INVALID_PARAMETER; + if (!req.RemoteAddressSizeInOut) return NTLSTATUS_INVALID_PARAMETER; s = CopyFromUser(&remoteCapacity, req.RemoteAddressSizeInOut, sizeof(remoteCapacity)); if (!KSUCCESS(s)) return s; if (remoteCapacity < sizeof(SYS_SOCKET_ADDRESS_K)) { size_t required = sizeof(SYS_SOCKET_ADDRESS_K); (void)CopyToUser(req.RemoteAddressSizeInOut, &required, sizeof(required)); - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; } s = MmProbeUserWrite(req.RemoteAddressOut, sizeof(SYS_SOCKET_ADDRESS_K)); if (!KSUCCESS(s)) return s; @@ -4012,11 +4231,11 @@ static uint64_t SyscallRecvFrom(uint64_t a0, uint64_t a1, uint64_t a2, void* kbuf = NULL; if (req.Length) { kbuf = MmAllocatePoolTag(req.Length, MM_POOL_TAG('s', 'y', 's', ' ')); - if (!kbuf) return STATUS_NO_MEMORY; + if (!kbuf) return NTLSTATUS_NO_MEMORY; } SOCKET_OBJECT* socket = (SOCKET_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeSocket, HANDLE_RIGHT_READ | HANDLE_RIGHT_WRITE); - if (!socket) { if (kbuf) MmFreePool(kbuf); return STATUS_NOT_FOUND; } + if (!socket) { if (kbuf) MmFreePool(kbuf); return NTLSTATUS_NOT_FOUND; } SYS_SOCKET_ADDRESS_K remote; memset(&remote, 0, sizeof(remote)); @@ -4044,20 +4263,20 @@ static uint64_t SyscallRecvFrom(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallResolveHost(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; SYS_RESOLVE_HOST_REQUEST_K req; KSTATUS s = CopyFromUser(&req, (const void*)(uintptr_t)a0, sizeof(req)); if (!KSUCCESS(s)) return s; if (!req.Name.Data || req.Name.Length == 0 || req.Name.Length > SYS_RESOLVE_HOST_NAME_MAX) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (req.Family != SYS_AF_INET && req.Family != SYS_AF_INET6) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (req.Flags != 0) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (!req.AddressOut || !req.AddressSizeInOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; size_t capacity = 0; s = CopyFromUser(&capacity, req.AddressSizeInOut, sizeof(capacity)); @@ -4065,7 +4284,7 @@ static uint64_t SyscallResolveHost(uint64_t a0, uint64_t a1, uint64_t a2, if (capacity < sizeof(SYS_SOCKET_ADDRESS_K)) { size_t required = sizeof(SYS_SOCKET_ADDRESS_K); (void)CopyToUser(req.AddressSizeInOut, &required, sizeof(required)); - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; } char name[SYS_RESOLVE_HOST_NAME_MAX + 1]; @@ -4087,20 +4306,20 @@ static uint64_t SyscallResolveHost(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallSetSocketOption(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; SYS_SOCKET_OPTION_REQUEST_K req; KSTATUS s = CopyFromUser(&req, (const void*)(uintptr_t)a1, sizeof(req)); if (!KSUCCESS(s)) return s; - if (!req.Value) return STATUS_INVALID_PARAMETER; + if (!req.Value) return NTLSTATUS_INVALID_PARAMETER; uint8_t value[sizeof(uint64_t)]; - if (req.ValueSize > sizeof(value)) return STATUS_BUFFER_TOO_SMALL; + if (req.ValueSize > sizeof(value)) return NTLSTATUS_BUFFER_TOO_SMALL; s = CopyFromUser(value, req.Value, req.ValueSize); if (!KSUCCESS(s)) return s; SOCKET_OBJECT* socket = (SOCKET_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeSocket, HANDLE_RIGHT_READ | HANDLE_RIGHT_WRITE); - if (!socket) return STATUS_NOT_FOUND; + if (!socket) return NTLSTATUS_NOT_FOUND; s = NetSocketSetOption(socket, req.Option, value, req.ValueSize); ObDereferenceObject(&socket->Header); @@ -4111,24 +4330,24 @@ static uint64_t SyscallSetSocketOption(uint64_t a0, uint64_t a1, uint64_t a2, static uint64_t SyscallGetSocketOption(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a2; (void)a3; (void)a4; (void)a5; - if (!a1) return STATUS_INVALID_PARAMETER; + if (!a1) return NTLSTATUS_INVALID_PARAMETER; SYS_SOCKET_OPTION_REQUEST_K req; KSTATUS s = CopyFromUser(&req, (const void*)(uintptr_t)a1, sizeof(req)); if (!KSUCCESS(s)) return s; - if (!req.Value) return STATUS_INVALID_PARAMETER; + if (!req.Value) return NTLSTATUS_INVALID_PARAMETER; uint8_t value[sizeof(uint64_t)]; - if (req.ValueSize > sizeof(value)) return STATUS_BUFFER_TOO_SMALL; + if (req.ValueSize > sizeof(value)) return NTLSTATUS_BUFFER_TOO_SMALL; SOCKET_OBJECT* socket = (SOCKET_OBJECT*)KiHandleToObject((uint32_t)a0, ObjectTypeSocket, HANDLE_RIGHT_READ | HANDLE_RIGHT_WRITE); - if (!socket) return STATUS_NOT_FOUND; + if (!socket) return NTLSTATUS_NOT_FOUND; size_t actual = 0; s = NetSocketGetOption(socket, req.Option, value, req.ValueSize, &actual); ObDereferenceObject(&socket->Header); if (!KSUCCESS(s)) { - if (s == STATUS_BUFFER_TOO_SMALL && req.ActualSizeOut) + if (s == NTLSTATUS_BUFFER_TOO_SMALL && req.ActualSizeOut) (void)CopyToUser(req.ActualSizeOut, &actual, sizeof(actual)); return s; } @@ -4150,24 +4369,28 @@ static int KiPollDeadlineExpired(uint64_t start, uint32_t timeoutMs) { return (gHal->Timer.QueryTicks() - start) >= ((uint64_t)timeoutMs * 1000u); } -// SYS_POLL a0=*SYS_POLLFD array a1=count a2=timeoutMs a3=*readyOut(optional). +// SYS_POLL a0=*SYS_POLL_REQUEST. static uint64_t SyscallPoll(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { - (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - size_t count = (size_t)a1; + SYS_POLL_REQUEST req; + KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req)); + if (!KSUCCESS(s)) return s; + if (req.Size != sizeof(req) || !req.Fds) return NTLSTATUS_INVALID_PARAMETER; + + size_t count = req.Count; if (count == 0 || count > SYS_POLL_MAX_FDS) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; size_t bytes = count * sizeof(SYS_POLLFD_K); SYS_POLLFD_K* fds = (SYS_POLLFD_K*)MmAllocatePoolTag(bytes, MM_POOL_TAG('s', 'y', 's', ' ')); - if (!fds) return STATUS_NO_MEMORY; + if (!fds) return NTLSTATUS_NO_MEMORY; - KSTATUS s = CopyFromUser(fds, (const void*)(uintptr_t)a0, bytes); + s = CopyFromUser(fds, req.Fds, bytes); if (!KSUCCESS(s)) { MmFreePool(fds); return s; } - uint32_t timeoutMs = (uint32_t)a2; + uint32_t timeoutMs = req.TimeoutMs; uint64_t start = gHal ? gHal->Timer.QueryTicks() : 0; size_t ready = 0; @@ -4200,9 +4423,9 @@ static uint64_t SyscallPoll(uint64_t a0, uint64_t a1, uint64_t a2, KeYield(); } - s = CopyToUser((void*)(uintptr_t)a0, fds, bytes); - if (KSUCCESS(s) && a3) - s = KiCopySizeToUser(a3, ready); + s = CopyToUser(req.Fds, fds, bytes); + if (KSUCCESS(s) && req.ReadyOut) + s = CopyToUser(req.ReadyOut, &ready, sizeof(ready)); MmFreePool(fds); return s; } @@ -4262,7 +4485,7 @@ static KSTATUS SyscallAsyncSocketLockOptional(PROCESS* proc, if (out) *out = (MM_LOCKED_USER_BUFFER*)0; if (!ptr || size == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; return MmLockUserBuffer(proc, ptr, size, 1, out); } @@ -4270,15 +4493,20 @@ static KSTATUS SyscallAsyncSocketLockOptional(PROCESS* proc, static KSTATUS SyscallAsyncSocketCopyInputAddress(const SYS_ASYNC_SOCKET_REQUEST_K* req, NET_ASYNC_SOCKET_SUBMIT* submit) { if (!req || !submit || !req->Address) - return STATUS_INVALID_PARAMETER; - if (req->AddressSize < sizeof(SYS_SOCKET_ADDRESS_K)) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_INVALID_PARAMETER; - KSTATUS status = CopyFromUser(&submit->Address, req->Address, sizeof(submit->Address)); + KSTATUS status = SyscallValidateSocketAddressBufferSize(req->AddressSize); + if (!KSUCCESS(status)) + return status; + + status = CopyFromUser(&submit->Address, req->Address, sizeof(submit->Address)); + if (!KSUCCESS(status)) + return status; + status = SyscallValidateSocketAddressInput(&submit->Address); if (!KSUCCESS(status)) return status; submit->AddressSize = req->AddressSize; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Validates and locks optional remote-address outputs for async accept/recvfrom. @@ -4286,11 +4514,11 @@ static KSTATUS SyscallAsyncSocketPrepareAddressOutput(PROCESS* proc, const SYS_ASYNC_SOCKET_REQUEST_K* req, NET_ASYNC_SOCKET_SUBMIT* submit) { if (!req || !submit) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!req->AddressOut) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (!req->AddressSizeInOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; size_t capacity = 0; KSTATUS status = CopyFromUser(&capacity, req->AddressSizeInOut, sizeof(capacity)); @@ -4299,7 +4527,7 @@ static KSTATUS SyscallAsyncSocketPrepareAddressOutput(PROCESS* proc, if (capacity < sizeof(SYS_SOCKET_ADDRESS_K)) { size_t required = sizeof(SYS_SOCKET_ADDRESS_K); (void)CopyToUser(req->AddressSizeInOut, &required, sizeof(required)); - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; } status = MmLockUserBuffer(proc, req->AddressOut, sizeof(SYS_SOCKET_ADDRESS_K), 1, @@ -4313,7 +4541,7 @@ static KSTATUS SyscallAsyncSocketPrepareAddressOutput(PROCESS* proc, submit->AddressOut = req->AddressOut; submit->AddressSizeInOut = req->AddressSizeInOut; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Prepares kernel-owned buffers and locked outputs for one async socket operation. @@ -4321,7 +4549,7 @@ static KSTATUS SyscallAsyncSocketPrepareOperation(PROCESS* proc, const SYS_ASYNC_SOCKET_REQUEST_K* req, NET_ASYNC_SOCKET_SUBMIT* submit) { if (!proc || !req || !submit) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; submit->Operation = req->Operation; submit->SocketFlags = req->SocketFlags; @@ -4338,11 +4566,11 @@ static KSTATUS SyscallAsyncSocketPrepareOperation(PROCESS* proc, case SYS_ASYNC_SOCKET_OP_LISTEN: case SYS_ASYNC_SOCKET_OP_SHUTDOWN: - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case SYS_ASYNC_SOCKET_OP_ACCEPT: { if (!req->HandleOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t zero = 0; KSTATUS status = MmLockUserBuffer(proc, req->HandleOut, sizeof(*req->HandleOut), 1, &submit->LockedHandleOut); @@ -4355,55 +4583,55 @@ static KSTATUS SyscallAsyncSocketPrepareOperation(PROCESS* proc, case SYS_ASYNC_SOCKET_OP_SEND: if (req->Length && !req->Buffer) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (req->Length > SYSCALL_IO_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (req->Length) { submit->KernelBuffer = MmAllocatePoolTag(req->Length, MM_POOL_TAG('s', 'a', 's', 'n')); if (!submit->KernelBuffer) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; return CopyFromUser(submit->KernelBuffer, req->Buffer, req->Length); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case SYS_ASYNC_SOCKET_OP_RECV: if (req->Length && !req->Buffer) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (req->Length > SYSCALL_IO_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (req->Length) { KSTATUS status = MmLockUserBuffer(proc, req->Buffer, req->Length, 1, &submit->LockedBuffer); if (!KSUCCESS(status)) return status; submit->KernelBuffer = MmAllocatePoolTag(req->Length, MM_POOL_TAG('s', 'a', 'r', 'n')); if (!submit->KernelBuffer) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } submit->UserBuffer = req->Buffer; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case SYS_ASYNC_SOCKET_OP_SEND_TO: { if (req->Length && !req->Buffer) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (req->Length > SYSCALL_IO_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS status = SyscallAsyncSocketCopyInputAddress(req, submit); if (!KSUCCESS(status)) return status; if (req->Length) { submit->KernelBuffer = MmAllocatePoolTag(req->Length, MM_POOL_TAG('s', 'a', 's', 'd')); if (!submit->KernelBuffer) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; return CopyFromUser(submit->KernelBuffer, req->Buffer, req->Length); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } case SYS_ASYNC_SOCKET_OP_RECV_FROM: { if (req->Length && !req->Buffer) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (req->Length > SYSCALL_IO_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS status = SyscallAsyncSocketPrepareAddressOutput(proc, req, submit); if (!KSUCCESS(status)) return status; @@ -4413,31 +4641,31 @@ static KSTATUS SyscallAsyncSocketPrepareOperation(PROCESS* proc, return status; submit->KernelBuffer = MmAllocatePoolTag(req->Length, MM_POOL_TAG('s', 'a', 'r', 'd')); if (!submit->KernelBuffer) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } submit->UserBuffer = req->Buffer; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } case SYS_ASYNC_SOCKET_OP_SET_OPT: if (!req->OptionValue) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (req->OptionValueSize > sizeof(uint64_t)) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; submit->OptionValueSize = req->OptionValueSize; if (req->OptionValueSize) { submit->OptionValue = MmAllocatePoolTag(req->OptionValueSize, MM_POOL_TAG('s', 'a', 'o', 's')); if (!submit->OptionValue) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; return CopyFromUser(submit->OptionValue, req->OptionValue, req->OptionValueSize); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; case SYS_ASYNC_SOCKET_OP_GET_OPT: { if (!req->OptionValue) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (req->OptionValueSize > sizeof(uint64_t)) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; submit->OptionValueSize = req->OptionValueSize; submit->UserOptionValue = req->OptionValue; KSTATUS status = MmLockUserBuffer(proc, req->OptionValue, req->OptionValueSize, 1, @@ -4454,9 +4682,9 @@ static KSTATUS SyscallAsyncSocketPrepareOperation(PROCESS* proc, if (req->OptionValueSize) { submit->OptionValue = MmAllocatePoolTag(req->OptionValueSize, MM_POOL_TAG('s', 'a', 'o', 'g')); if (!submit->OptionValue) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } case SYS_ASYNC_SOCKET_OP_POLL: { @@ -4469,11 +4697,11 @@ static KSTATUS SyscallAsyncSocketPrepareOperation(PROCESS* proc, *req->PollReturnedEventsOut = 0; submit->PollReturnedEventsOut = req->PollReturnedEventsOut; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } default: - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } } @@ -4482,14 +4710,14 @@ static uint64_t SyscallSocketIoAsync(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; if (!a0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; SYS_ASYNC_SOCKET_REQUEST_K req; KSTATUS status = CopyFromUser(&req, (const void*)(uintptr_t)a0, sizeof(req)); if (!KSUCCESS(status)) return status; if (req.Size != sizeof(req) || req.Flags != SYS_ASYNC_SOCKET_FLAG_NONE || !req.Iosb) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (req.RequestHandleOut) { status = MmProbeUserWrite(req.RequestHandleOut, sizeof(*req.RequestHandleOut)); if (!KSUCCESS(status)) @@ -4498,20 +4726,20 @@ static uint64_t SyscallSocketIoAsync(uint64_t a0, uint64_t a1, uint64_t a2, PROCESS* proc = KeGetCurrentProcess(); if (!proc) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; SOCKET_OBJECT* socket = (SOCKET_OBJECT*)KiHandleToObject(req.SocketHandle, ObjectTypeSocket, HANDLE_RIGHT_READ | HANDLE_RIGHT_WRITE); if (!socket) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; EVENT* event = (EVENT*)0; if (req.EventHandle) { event = (EVENT*)KiHandleToObject(req.EventHandle, ObjectTypeEvent, HANDLE_RIGHT_SIGNAL); if (!event) { ObDereferenceObject(&socket->Header); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } } @@ -4522,14 +4750,14 @@ static uint64_t SyscallSocketIoAsync(uint64_t a0, uint64_t a1, uint64_t a2, if (!thread || !thread->UserApcDispatcher) { if (event) ObDereferenceObject(&event->Header); ObDereferenceObject(&socket->Header); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } apcCtx = (SYS_USER_ASYNC_APC_CONTEXT*)MmAllocatePoolTag(sizeof(SYS_USER_ASYNC_APC_CONTEXT), MM_POOL_TAG('u', 'a', 'p', 'c')); if (!apcCtx) { if (event) ObDereferenceObject(&event->Header); ObDereferenceObject(&socket->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } memset(apcCtx, 0, sizeof(*apcCtx)); @@ -4564,10 +4792,10 @@ static uint64_t SyscallSocketIoAsync(uint64_t a0, uint64_t a1, uint64_t a2, NET_ASYNC_SOCKET_REQUEST_OBJECT* asyncReq = (NET_ASYNC_SOCKET_REQUEST_OBJECT*)0; status = NetSocketSubmitAsyncKernel(&submit, &asyncReq); - if (status == STATUS_PENDING) { + if (status == NTLSTATUS_PENDING) { memset(&submit, 0, sizeof(submit)); } - if (!KSUCCESS(status) && status != STATUS_PENDING) + if (!KSUCCESS(status) && status != NTLSTATUS_PENDING) goto fail; if (req.RequestHandleOut && asyncReq) { @@ -4622,7 +4850,7 @@ fail_after_submit: static uint64_t SyscallGetMemoryStatus(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; MM_PFN_STATS pfn; MmPfnQueryStats(&pfn); @@ -4652,10 +4880,10 @@ static KSTATUS KiReturnKernelStats(uint64_t bufferArg, size_t bufferSize, } if (!bufferArg) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (bufferSize < size) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; return CopyToUser((void*)(uintptr_t)bufferArg, src, size); } @@ -4663,7 +4891,7 @@ static KSTATUS KiReturnKernelStats(uint64_t bufferArg, size_t bufferSize, static uint64_t SyscallQueryDisplayInfo(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; - if (!a0) return STATUS_INVALID_PARAMETER; + if (!a0) return NTLSTATUS_INVALID_PARAMETER; KE_DISPLAY_INFO ki; KSTATUS s = KeDisplayQueryInfo(&ki); @@ -5015,6 +5243,13 @@ static uint64_t SyscallQueryKernelStats(uint64_t a0, uint64_t a1, uint64_t a2, return KiReturnKernelStats(a1, (size_t)a2, a3, &um, sizeof(um)); } + + case SYS_KERNEL_STATS_EXCEPTION: { + SYS_EXCEPTION_STATS stats; + KeQueryExceptionStats(&stats); + return KiReturnKernelStats(a1, (size_t)a2, a3, &stats, sizeof(stats)); + } + case SYS_KERNEL_STATS_CPU: { struct { SYS_CPU_STATS Header; @@ -5055,7 +5290,7 @@ static uint64_t SyscallQueryKernelStats(uint64_t a0, uint64_t a1, uint64_t a2, } default: - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } } @@ -5064,7 +5299,7 @@ typedef uint64_t (*SYSCALL_HANDLER)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); static const SYSCALL_HANDLER gSyscallTable[SYS_MAX] = { - // Process, threads, modules, waits, and APC. + // Process, threads, modules, waits, APC, and exceptions. [SYS_EXIT_PROCESS] = SyscallExitProcess, [SYS_EXIT_THREAD] = SyscallExitThread, [SYS_CREATE_PROCESS] = SyscallCreateProcess, @@ -5089,6 +5324,10 @@ static const SYSCALL_HANDLER gSyscallTable[SYS_MAX] = { [SYS_WAIT_MANY] = SyscallWaitMany, [SYS_SET_USER_APC_DISPATCHER] = SyscallSetUserApcDispatcher, [SYS_APC_RETURN] = SyscallApcReturn, + [SYS_SET_EXCEPTION_DISPATCHER] = SyscallSetExceptionDispatcher, + [SYS_GET_EXCEPTION_DISPATCHER] = SyscallGetExceptionDispatcher, + [SYS_CONTINUE_EXCEPTION] = SyscallContinueException, + [SYS_RAISE_EXCEPTION] = SyscallRaiseException, // Virtual memory, mappings, and handles. [SYS_ALLOC_VM] = SyscallVmAlloc, @@ -5116,6 +5355,7 @@ static const SYSCALL_HANDLER gSyscallTable[SYS_MAX] = { [SYS_SEND_QUEUE] = SyscallQueueSend, [SYS_RECV_QUEUE] = SyscallQueueRecv, [SYS_PUBLISH_QUEUE] = SyscallPublishQueue, + [SYS_UNPUBLISH_QUEUE] = SyscallUnpublishQueue, [SYS_OPEN_NAMED_QUEUE] = SyscallOpenNamedQueue, [SYS_OPEN_NAMED_QUEUE_OWNER_PROCESS] = SyscallOpenNamedQueueOwnerProcess, @@ -5216,7 +5456,7 @@ uint64_t KeSyscallDispatch(uint64_t nr, uint64_t a0, uint64_t a1, while (true) ; } - if (nr >= SYS_MAX || !gSyscallTable[nr]) return STATUS_NOT_SUPPORTED; + if (nr >= SYS_MAX || !gSyscallTable[nr]) return NTLSTATUS_NOT_SUPPORTED; uint64_t result = gSyscallTable[nr](a0, a1, a2, a3, a4, a5); diff --git a/code/kernel/ke_system_root.c b/code/kernel/ke_system_root.c index 37abd85..eb7bd14 100644 --- a/code/kernel/ke_system_root.c +++ b/code/kernel/ke_system_root.c @@ -61,10 +61,10 @@ KSTATUS KeInitializeSystemRootVolume(void) { gSystemRootDrive = drive; gSystemRootReady = true; DbgPrint("System root: drive=%u\n", drive); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } // Returns whether the system root volume has been selected. @@ -87,11 +87,11 @@ bool KeBuildSystemRootPath(const char* relative, char* out, size_t outSize) { // Opens a file rooted at the selected system volume. KSTATUS KeOpenSystemRootFile(const char* relative, FILE_OBJECT** out) { if (!out) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *out = NULL; char path[1024]; if (!KeBuildSystemRootPath(relative, path, sizeof(path))) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; return IoOpenFile(SysSvFromCstr(path), out); } diff --git a/code/kernel/ke_thread.c b/code/kernel/ke_thread.c index 00e2cb8..3e18338 100644 --- a/code/kernel/ke_thread.c +++ b/code/kernel/ke_thread.c @@ -41,7 +41,7 @@ static void KiThreadDestroy(OBJECT* obj) { // A wait that uses auxiliary stack wait blocks must be removed before the // kernel stack is released. A terminated thread may never return to the // wait syscall to run normal cleanup. - KeRundownThreadWait(thread, STATUS_ALERTED); + KeRundownThreadWait(thread, NTLSTATUS_ALERTED); KiRundownApcState(thread); @@ -94,11 +94,11 @@ static void KiThreadDestroy(OBJECT* obj) { __declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, uintptr_t arg, THREAD_PRIORITY priority, THREAD** out) { - if (!owner || !out) return STATUS_INVALID_PARAMETER; - if (priority >= PriorityCount) return STATUS_INVALID_PARAMETER; + if (!owner || !out) return NTLSTATUS_INVALID_PARAMETER; + if (priority >= PriorityCount) return NTLSTATUS_INVALID_PARAMETER; THREAD* thread = (THREAD *)ObAllocateObject(ObjectTypeThread, sizeof(THREAD)); - if (!thread) return STATUS_NO_MEMORY; + if (!thread) return NTLSTATUS_NO_MEMORY; thread->Header.Destroy = KiThreadDestroy; thread->ThreadId = _InterlockedExchangeAdd((volatile long *)&gNextThreadId, 1); @@ -118,19 +118,23 @@ __declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, ui LIST_INIT(&thread->ProcessLink); LIST_INIT(&thread->SchedulerLink); thread->WaitObject = (OBJECT *)0; - thread->WaitStatus = STATUS_SUCCESS; + thread->WaitStatus = NTLSTATUS_SUCCESS; thread->WaitListHead = (LIST_ENTRY*)0; thread->AlertableWait = 0; thread->SleepUntilTick = 0; - thread->TimeoutStatus = STATUS_SUCCESS; + thread->TimeoutStatus = NTLSTATUS_SUCCESS; thread->SwitchLockCookie = 0x202ULL; KiInitializeApcState(thread); thread->TrapFrame = (KTRAP_FRAME*)0; + thread->UserExceptionDepth = 0; + thread->UserExceptionNoncontinuableMask = 0; + thread->UserExceptionFrameUserAddress = 0; + memset(thread->UserExceptionExitStatus, 0, sizeof(thread->UserExceptionExitStatus)); void* kstack = MmAllocatePoolTag(KSTACK_SIZE, MM_POOL_TAG('k', 's', 't', 'k')); if (!kstack) { ObDereferenceObject(&thread->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } memset(kstack, 0, KSTACK_SIZE); thread->KernelStackBase = kstack; @@ -148,7 +152,7 @@ __declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, ui MmFreePool(kstack); thread->KernelStackBase = (void*)0; ObDereferenceObject(&thread->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } thread->UserStackBase = ustack; // Ring-3 starts at the image entry via IRET, not CALL. The MS x64 ABI @@ -172,7 +176,7 @@ __declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, ui MmFreePool(kstack); thread->KernelStackBase = (void*)0; ObDereferenceObject(&thread->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } memset(teb, 0, sizeof(SYS_TEB)); teb->Peb = (SYS_PEB*)owner->UserPebBase; @@ -241,7 +245,7 @@ __declspec(dllexport) KSTATUS KeCreateThread(PROCESS* owner, uintptr_t entry, ui *out = thread; KeReadyThread(thread); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the exit Thread operation. @@ -284,11 +288,11 @@ static KSTATUS KiCreateKernelThreadWithAffinity(uintptr_t fn, uintptr_t arg, THREAD* currentThread = KeGetCurrentThread(); owner = currentThread ? currentThread->Owner : (PROCESS*)0; } - if (!owner) return STATUS_INVALID_PARAMETER; - if (priority >= PriorityCount) return STATUS_INVALID_PARAMETER; + if (!owner) return NTLSTATUS_INVALID_PARAMETER; + if (priority >= PriorityCount) return NTLSTATUS_INVALID_PARAMETER; THREAD* thread = (THREAD*)ObAllocateObject(ObjectTypeThread, sizeof(THREAD)); - if (!thread) return STATUS_NO_MEMORY; + if (!thread) return NTLSTATUS_NO_MEMORY; thread->Header.Destroy = KiThreadDestroy; thread->ThreadId = _InterlockedExchangeAdd((volatile long*)&gNextThreadId, 1); @@ -308,14 +312,18 @@ static KSTATUS KiCreateKernelThreadWithAffinity(uintptr_t fn, uintptr_t arg, LIST_INIT(&thread->ProcessLink); LIST_INIT(&thread->SchedulerLink); thread->WaitObject = (OBJECT*)0; - thread->WaitStatus = STATUS_SUCCESS; + thread->WaitStatus = NTLSTATUS_SUCCESS; thread->WaitListHead = (LIST_ENTRY*)0; thread->AlertableWait = 0; thread->SleepUntilTick = 0; - thread->TimeoutStatus = STATUS_SUCCESS; + thread->TimeoutStatus = NTLSTATUS_SUCCESS; thread->SwitchLockCookie = 0x202ULL; KiInitializeApcState(thread); thread->TrapFrame = (KTRAP_FRAME*)0; + thread->UserExceptionDepth = 0; + thread->UserExceptionNoncontinuableMask = 0; + thread->UserExceptionFrameUserAddress = 0; + memset(thread->UserExceptionExitStatus, 0, sizeof(thread->UserExceptionExitStatus)); thread->UserStackBase = (void*)0; // no user stack thread->Teb = (void*)0; // no TEB; GS_BASE will be 0 in kernel ctx thread->TebSize = 0; @@ -323,7 +331,7 @@ static KSTATUS KiCreateKernelThreadWithAffinity(uintptr_t fn, uintptr_t arg, void* kstack = MmAllocatePoolTag(KSTACK_SIZE, MM_POOL_TAG('k', 's', 't', 'k')); if (!kstack) { ObDereferenceObject(&thread->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } memset(kstack, 0, KSTACK_SIZE); thread->KernelStackBase = kstack; @@ -363,7 +371,7 @@ static KSTATUS KiCreateKernelThreadWithAffinity(uintptr_t fn, uintptr_t arg, KeInitThreadFpuContext(thread); KeReadyThread(thread); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } __declspec(dllexport) KSTATUS KeCreateKernelThread(uintptr_t fn, uintptr_t arg, @@ -388,7 +396,7 @@ void KePrepareBlockThread(THREAD* thread, OBJECT* waitObject, uint8_t alertable) KiSchedulerMarkThreadWaiting(thread); thread->WaitObject = waitObject; - thread->WaitStatus = STATUS_PENDING; + thread->WaitStatus = NTLSTATUS_PENDING; thread->WaitListHead = (LIST_ENTRY*)0; thread->AlertableWait = alertable ? 1 : 0; thread->WaitRundownRoutine = (KE_WAIT_RUNDOWN_ROUTINE)0; @@ -436,13 +444,13 @@ static void KiFinishWait(THREAD* thread, KSTATUS status) { thread->WaitListHead = (LIST_ENTRY*)0; thread->AlertableWait = 0; thread->SleepUntilTick = 0; - thread->TimeoutStatus = STATUS_SUCCESS; + thread->TimeoutStatus = NTLSTATUS_SUCCESS; } // Implements the commit Block Thread operation. KSTATUS KeCommitBlockThread(THREAD* thread, uint8_t alertable) { KeAssertIrql(PASSIVE_LEVEL); - if (!thread) return STATUS_INVALID_PARAMETER; + if (!thread) return NTLSTATUS_INVALID_PARAMETER; if (alertable) thread->AlertableWait = 1; @@ -455,7 +463,7 @@ KSTATUS KeCommitBlockThread(THREAD* thread, uint8_t alertable) { KSTATUS status = thread->WaitStatus; thread->AlertableWait = 0; thread->SleepUntilTick = 0; - thread->TimeoutStatus = STATUS_SUCCESS; + thread->TimeoutStatus = NTLSTATUS_SUCCESS; return status; } @@ -464,21 +472,21 @@ KSTATUS KeCommitBlockThread(THREAD* thread, uint8_t alertable) { if (alertable && thread->UserApcPending && thread->UserApcDispatcher) { if (thread->WaitListHead) ListRemove(&thread->SchedulerLink); - KiFinishWait(thread, STATUS_USER_APC); + KiFinishWait(thread, NTLSTATUS_USER_APC); thread->State = ThreadRunning; - return STATUS_USER_APC; + return NTLSTATUS_USER_APC; } KiSchedulerNoteVoluntaryBlock(thread); KeYield(); // Kernel APCs are delivered before an alertable wait returns - // STATUS_KERNEL_APC to its caller. + // NTLSTATUS_KERNEL_APC to its caller. KiDeliverKernelApcs(); thread->AlertableWait = 0; thread->SleepUntilTick = 0; - thread->TimeoutStatus = STATUS_SUCCESS; + thread->TimeoutStatus = NTLSTATUS_SUCCESS; return thread->WaitStatus; } @@ -517,7 +525,7 @@ static int KiRemoveThreadFromObjectWaitListLocked(THREAD* thread, LIST_ENTRY* wa ListRemove(&thread->SchedulerLink); thread->WaitListHead = (LIST_ENTRY*)0; thread->SleepUntilTick = 0; - thread->TimeoutStatus = STATUS_SUCCESS; + thread->TimeoutStatus = NTLSTATUS_SUCCESS; return 1; } @@ -582,36 +590,36 @@ void KeAbortThreadWait(THREAD* thread, KSTATUS status) { // Implements the unblock Thread operation. void KeUnblockThread(THREAD* thread) { - KeUnblockThreadWithStatus(thread, STATUS_SUCCESS); + KeUnblockThreadWithStatus(thread, NTLSTATUS_SUCCESS); } // Implements the alert Thread With Status operation. static KSTATUS KiAlertThreadWithStatus(THREAD* thread, KSTATUS status) { - if (!thread) return STATUS_INVALID_PARAMETER; + if (!thread) return NTLSTATUS_INVALID_PARAMETER; if (thread->State != ThreadWaiting || !thread->AlertableWait) - return STATUS_PENDING; + return NTLSTATUS_PENDING; if (thread->WaitListHead) ListRemove(&thread->SchedulerLink); KeUnblockThreadWithStatus(thread, status); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the alert Thread operation. KSTATUS KeAlertThread(THREAD* thread) { - return KiAlertThreadWithStatus(thread, STATUS_ALERTED); + return KiAlertThreadWithStatus(thread, NTLSTATUS_ALERTED); } // Implements the wake Thread For Kernel Apc operation. void KiWakeThreadForKernelApc(THREAD* thread) { - (void)KiAlertThreadWithStatus(thread, STATUS_KERNEL_APC); + (void)KiAlertThreadWithStatus(thread, NTLSTATUS_KERNEL_APC); } // Implements the wake Thread For User Apc operation. void KiWakeThreadForUserApc(THREAD* thread) { - (void)KiAlertThreadWithStatus(thread, STATUS_USER_APC); + (void)KiAlertThreadWithStatus(thread, NTLSTATUS_USER_APC); } void KeInitThreadFpuContext(THREAD* thread) diff --git a/code/kernel/ke_time.c b/code/kernel/ke_time.c index 42b0d11..86a6a90 100644 --- a/code/kernel/ke_time.c +++ b/code/kernel/ke_time.c @@ -335,7 +335,7 @@ void KeTimeInitialize(const BOOT_INFO* bootInfo, const HAL_API* hal) { } else { HAL_RTC_TIME rtc; memset(&rtc, 0, sizeof(rtc)); - if (hal && hal->Rtc.QueryTime && hal->Rtc.QueryTime(&rtc) == STATUS_SUCCESS && + if (hal && hal->Rtc.QueryTime && hal->Rtc.QueryTime(&rtc) == NTLSTATUS_SUCCESS && (rtc.Flags & HAL_RTC_TIME_FLAG_VALID) && KiValidCalendar(rtc.Year, rtc.Month, rtc.Day, rtc.Hour, rtc.Minute, rtc.Second, rtc.Nanosecond)) { @@ -360,7 +360,7 @@ void KeTimeInitialize(const BOOT_INFO* bootInfo, const HAL_API* hal) { KiRebaseUtcFromSource(); SYS_SYSTEM_TIME now; - if (KeQuerySystemTime(&now) == STATUS_SUCCESS) { + if (KeQuerySystemTime(&now) == NTLSTATUS_SUCCESS) { DbgPrint("time: initialized %04u-%02u-%02u %02u:%02u:%02u.%03u flags=0x%x tz=%d hw=%s epoch=%llu\n", now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, now.Millisecond, now.Flags, now.TimeZoneMinutes, @@ -466,7 +466,7 @@ KSTATUS KeTimeReloadSettings(void) { KiRebaseUtcFromSource(); SYS_SYSTEM_TIME now; - if (KeQuerySystemTime(&now) == STATUS_SUCCESS) { + if (KeQuerySystemTime(&now) == NTLSTATUS_SUCCESS) { DbgPrint("time: settings timezone=%d dst=%s hw=%s now=%04u-%02u-%02u %02u:%02u:%02u flags=0x%x epoch=%llu\n", now.TimeZoneMinutes, (now.Flags & SYS_TIME_FLAG_DAYLIGHT) ? "on" : "off", @@ -474,12 +474,12 @@ KSTATUS KeTimeReloadSettings(void) { now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, now.Flags, now.EpochSeconds); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns system Time. __declspec(dllexport) KSTATUS KeQuerySystemTime(SYS_SYSTEM_TIME* outTime) { - if (!outTime) return STATUS_INVALID_PARAMETER; + if (!outTime) return NTLSTATUS_INVALID_PARAMETER; uint64_t nowTick = (gTimeHal && gTimeHal->Timer.QueryTicks) ? gTimeHal->Timer.QueryTicks() @@ -516,13 +516,13 @@ __declspec(dllexport) KSTATUS KeQuerySystemTime(SYS_SYSTEM_TIME* outTime) { t.TickMicroseconds = nowTick; *outTime = t; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns unix Time Seconds. __declspec(dllexport) uint64_t KeQueryUnixTimeSeconds(void) { SYS_SYSTEM_TIME t; - if (KeQuerySystemTime(&t) != STATUS_SUCCESS) + if (KeQuerySystemTime(&t) != NTLSTATUS_SUCCESS) return 0; return t.EpochSeconds; } diff --git a/code/kernel/ke_timer.c b/code/kernel/ke_timer.c index ae14033..9944b4a 100644 --- a/code/kernel/ke_timer.c +++ b/code/kernel/ke_timer.c @@ -80,14 +80,14 @@ static void KiTimerDestroy(OBJECT* obj) { // Creates an unset waitable timer object. KSTATUS KeTimerCreate(KTIMER** out) { if (!out) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *out = (KTIMER*)0; KiTimerEnsureInitialized(); KTIMER* timer = (KTIMER*)ObAllocateObject(ObjectTypeTimer, sizeof(KTIMER)); if (!timer) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; timer->Header.Destroy = KiTimerDestroy; LIST_INIT(&timer->Link); @@ -99,13 +99,13 @@ KSTATUS KeTimerCreate(KTIMER** out) { } *out = timer; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Arms or rearms a timer with a relative due time and optional period. KSTATUS KeTimerSet(KTIMER* timer, uint64_t dueTimeMilliseconds, uint64_t periodMilliseconds) { if (!timer || !timer->Event) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KiTimerEnsureInitialized(); @@ -147,13 +147,13 @@ KSTATUS KeTimerSet(KTIMER* timer, uint64_t dueTimeMilliseconds, uint64_t periodM if (signalNow) KeSignalEvent(event); ObDereferenceObject(&event->Header); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Cancels a timer and clears any retained signal. KSTATUS KeTimerCancel(KTIMER* timer) { if (!timer || !timer->Event) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KiTimerEnsureInitialized(); @@ -164,7 +164,7 @@ KSTATUS KeTimerCancel(KTIMER* timer) { if (hadListReference) ObDereferenceObject(&timer->Header); KeClearEvent(timer->Event); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns the event that backs timer waits. diff --git a/code/kernel/ke_trap.c b/code/kernel/ke_trap.c index 00867d8..9dc0107 100644 --- a/code/kernel/ke_trap.c +++ b/code/kernel/ke_trap.c @@ -120,16 +120,16 @@ void KiValidateSyscallTrapFrame(uint64_t nr, uint64_t a0, uint64_t a1, // Returns current Trap Frame. KSTATUS KeQueryCurrentTrapFrame(SYS_TRAP_FRAME_INFO_K* out) { - if (!out) return STATUS_INVALID_PARAMETER; + if (!out) return NTLSTATUS_INVALID_PARAMETER; KTRAP_FRAME* f = KeGetCurrentTrapFrame(); if (!f || f->Magic != KTRAP_FRAME_MAGIC) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; uint32_t size = out->Size; if (size < sizeof(SYS_TRAP_FRAME_INFO_K)) { out->Size = sizeof(SYS_TRAP_FRAME_INFO_K); - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; } memset(out, 0, sizeof(*out)); @@ -149,5 +149,5 @@ KSTATUS KeQueryCurrentTrapFrame(SYS_TRAP_FRAME_INFO_K* out) { out->R9 = f->R9; out->R10 = f->R10; out->R11 = f->R11; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } diff --git a/code/kernel/ke_work.c b/code/kernel/ke_work.c index 4f41b38..61e000b 100644 --- a/code/kernel/ke_work.c +++ b/code/kernel/ke_work.c @@ -86,11 +86,11 @@ bool KeQueueWorkItem(KWORK_ITEM* item) { KSTATUS KeStartWorkQueue(void) { long state = _InterlockedCompareExchange(&gWorkQueueStartState, 1, 0); if (state == 2) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (state == 1) { while (_InterlockedCompareExchange(&gWorkQueueStartState, 2, 2) == 1) KeYield(); - return KeIsWorkQueueStarted() ? STATUS_SUCCESS : STATUS_FAILURE; + return KeIsWorkQueueStarted() ? NTLSTATUS_SUCCESS : NTLSTATUS_FAILURE; } LIST_INIT(&gWorkQueueList); diff --git a/code/kernel/kmain.c b/code/kernel/kmain.c index e2c6821..f36f1f8 100644 --- a/code/kernel/kmain.c +++ b/code/kernel/kmain.c @@ -242,7 +242,7 @@ static void KiInitializeDrivers(BOOT_INFO* bootInfo, const HAL_API* hal) { FILE_OBJECT* f; s = KeInitializeSystemRootVolume(); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { KePanic(KE_PANIC_CODE_INIT, "KiInitializeDrivers: Failed to find system root volume (status %d)\n", s); } @@ -252,12 +252,12 @@ static void KiInitializeDrivers(BOOT_INFO* bootInfo, const HAL_API* hal) { root[2] = '/'; root[3] = '\0'; s = IoSetCwd(SysSvFromCstr(root)); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { KePanic(KE_PANIC_CODE_INIT, "KiInitializeDrivers: Failed to set system CWD to %s (status %d)\n", root, s); } s = KeOpenSystemRootFile("drivers\\drivers.ini", &f); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { KePanic(KE_PANIC_CODE_INIT, "KiInitializeDrivers: Failed to open drivers.ini on system root (status %d)\n", s); } @@ -294,7 +294,7 @@ static void KiInitializeDrivers(BOOT_INFO* bootInfo, const HAL_API* hal) { } s = IoOpenFile(SysSvFromCstr(path), &f); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { DbgPrint("KiInitializeDrivers: Failed to open runtime driver: %s (%s)\n", runtimeKeys[i], path); continue; } @@ -356,7 +356,7 @@ static PROCESS* KiLaunchUserProcess(const char* filePath, const char* args) { // Kernel-launched user images are rooted at the selected system volume. s = KeOpenSystemRootFile(filePath, &f); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { DbgPrint("Failed to load system file: \"%s\" (status %d)!\n", filePath, s); return 0; } @@ -469,7 +469,7 @@ void SystemInitThread(void* arg) { if (args->bootInfo->Debug & (KE_DEBUG_CONSOLE | KE_DEBUG_FILE_LOG)) { char logPath[1024]; - KSTATUS logStatus = STATUS_NOT_FOUND; + KSTATUS logStatus = NTLSTATUS_NOT_FOUND; if (KeBuildSystemRootPath("kernel.log", logPath, sizeof(logPath))) { logStatus = KeFlushDebugLogToFile(SysSvFromCstr(logPath)); if (!KSUCCESS(logStatus)) diff --git a/code/kernel/ldr_image.c b/code/kernel/ldr_image.c index 9ab7d4a..1b7dce8 100644 --- a/code/kernel/ldr_image.c +++ b/code/kernel/ldr_image.c @@ -97,7 +97,7 @@ static size_t KiAlignPeSize(size_t value) { // Implements the compute Required Image Size operation. static KSTATUS KiComputeRequiredImageSize(const PE_HEADER* pe, size_t fileSize, size_t* outSize) { - if (!pe || !outSize) return STATUS_INVALID_PARAMETER; + if (!pe || !outSize) return NTLSTATUS_INVALID_PARAMETER; const OPT_HEADER64* opt = &pe->OptionalHeader; size_t required = KiAlignPeSize(opt->SizeOfImage); @@ -113,19 +113,19 @@ static KSTATUS KiComputeRequiredImageSize(const PE_HEADER* pe, size_t fileSize, if (raw > span) span = raw; if (!span) continue; - if (va > (size_t)-1 - span) return STATUS_NO_MEMORY; + if (va > (size_t)-1 - span) return NTLSTATUS_NO_MEMORY; size_t end = KiAlignPeSize(va + span); if (end > required) required = end; if (raw) { size_t rawBase = (size_t)sec[i].PointerToRawData; - if (rawBase > fileSize || raw > fileSize - rawBase) return STATUS_FAILURE; + if (rawBase > fileSize || raw > fileSize - rawBase) return NTLSTATUS_FAILURE; } } - if (!required) return STATUS_FAILURE; + if (!required) return NTLSTATUS_FAILURE; *outSize = required; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } typedef struct { @@ -178,7 +178,7 @@ static uint32_t gModuleCount = 0; // Ensures a user image page is privately writable before the kernel patches it. static KSTATUS KiEnsureUserImageWrite(PROCESS* process, bool user, uintptr_t address, size_t size) { - if (!user) return STATUS_SUCCESS; + if (!user) return NTLSTATUS_SUCCESS; return MmVadMakeImageRangePrivate(process, (void*)address, size); } @@ -395,27 +395,27 @@ static uint64_t KiSectionPageProtection(const SECTION_HEADER* section, bool user // Applies final page protections to a mapped PE image. KSTATUS LdrProtectImageForProcess(PROCESS* process, uintptr_t imageBase, bool user) { - if (!imageBase) return STATUS_INVALID_PARAMETER; - if (user && !process) return STATUS_INVALID_PARAMETER; + if (!imageBase) return NTLSTATUS_INVALID_PARAMETER; + if (user && !process) return NTLSTATUS_INVALID_PARAMETER; size_t mappedSize = user ? LdrGetMappedImageSize(process, imageBase) : LdrGetImageSize(imageBase); - if (!mappedSize) return STATUS_FAILURE; + if (!mappedSize) return NTLSTATUS_FAILURE; uint32_t peOffset = *(uint32_t *)(imageBase + 0x3C); if ((size_t)peOffset > mappedSize || mappedSize - (size_t)peOffset < sizeof(uint32_t) + 20) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; PE_HEADER* pe = (PE_HEADER *)(imageBase + peOffset); - if (pe->Signature != PE_SIGNATURE) return STATUS_FAILURE; + if (pe->Signature != PE_SIGNATURE) return NTLSTATUS_FAILURE; size_t sectionTableOffset = (size_t)peOffset + 24u + (size_t)pe->SizeOfOptionalHeader; size_t sectionTableSize = (size_t)pe->NumberOfSections * sizeof(SECTION_HEADER); if (sectionTableOffset > mappedSize || sectionTableSize > mappedSize - sectionTableOffset) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; size_t pageCount = (mappedSize + PAGE_SIZE - 1) / PAGE_SIZE; uint64_t* pageProt = (uint64_t*)MmAllocatePoolTag(pageCount * sizeof(uint64_t), MM_POOL_TAG('i', 'p', 'r', 't')); - if (!pageProt) return STATUS_NO_MEMORY; + if (!pageProt) return NTLSTATUS_NO_MEMORY; uint64_t headerProt = PAGE_PRESENT | (user ? PAGE_USER : 0) | PAGE_NX; for (size_t i = 0; i < pageCount; ++i) @@ -438,7 +438,7 @@ KSTATUS LdrProtectImageForProcess(PROCESS* process, uintptr_t imageBase, bool us } if (secEnd < secBase) { MmFreePool(pageProt); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } if (secEnd > mapEnd) { LdrDbg("LDR: protect clamping section %d end=%016llx to mapEnd=%016llx\n", @@ -460,7 +460,7 @@ KSTATUS LdrProtectImageForProcess(PROCESS* process, uintptr_t imageBase, bool us } size_t runStart = 0; - KSTATUS s = STATUS_SUCCESS; + KSTATUS s = NTLSTATUS_SUCCESS; while (runStart < pageCount) { uint64_t prot = pageProt[runStart]; size_t runEnd = runStart + 1; @@ -501,10 +501,10 @@ static KSTATUS LdrApplyRelocationsForProcess(PROCESS* process, uintptr_t base, u PE_HEADER* pe = (PE_HEADER *)(base + peOffset); OPT_HEADER64* opt = &pe->OptionalHeader; - if (opt->NumberOfRvaAndSizes < 6) return STATUS_SUCCESS; + if (opt->NumberOfRvaAndSizes < 6) return NTLSTATUS_SUCCESS; uint32_t relocRva = opt->DataDirectory[5].VirtualAddress; uint32_t relocSize = opt->DataDirectory[5].Size; - if (!relocRva || !relocSize) return STATUS_SUCCESS; + if (!relocRva || !relocSize) return NTLSTATUS_SUCCESS; BASE_RELOC* block = (BASE_RELOC *)(base + relocRva); uintptr_t end = (uintptr_t)block + relocSize; @@ -527,7 +527,7 @@ static KSTATUS LdrApplyRelocationsForProcess(PROCESS* process, uintptr_t base, u } block = (BASE_RELOC *)((uint8_t *)block + block->SizeOfBlock); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Import resolution. @@ -555,11 +555,11 @@ static KSTATUS LdrResolveImportsCommon( OPT_HEADER64* opt = &pe->OptionalHeader; if (opt->NumberOfRvaAndSizes < 2) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; uint32_t impRva = opt->DataDirectory[1].VirtualAddress; if (!impRva) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; IMPORT_DESC* imp = (IMPORT_DESC *)(imageBase + impRva); @@ -606,7 +606,7 @@ static KSTATUS LdrResolveImportsCommon( "LdrResolveImports: Ordinal imports not supported! (%s)\n", dllName ); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } const char* funcName = @@ -621,7 +621,7 @@ static KSTATUS LdrResolveImportsCommon( dllName, funcName ); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } KSTATUS ws = KiEnsureUserImageWrite(process, process != (PROCESS*)0, (uintptr_t)thunk, sizeof(*thunk)); @@ -635,7 +635,7 @@ static KSTATUS LdrResolveImportsCommon( imp++; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the ldr Resolve Imports operation. @@ -661,7 +661,7 @@ KSTATUS LdrResolveImportsForProcess(PROCESS* process, uintptr_t imageBase) { // Loads a user image from an open file through the image-section object model. KSTATUS LdrLoadImageFileForProcess(PROCESS* process, FILE_OBJECT* file, uintptr_t* baseOut) { if (!process || !file || !baseOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *baseOut = 0; IMAGE_SECTION_OBJECT* section = (IMAGE_SECTION_OBJECT*)0; @@ -690,7 +690,7 @@ KSTATUS LdrLoadImageFileForProcess(PROCESS* process, FILE_OBJECT* file, uintptr_ LdrDereferenceImageSection(section); *baseOut = imageBase; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Converts a process module entry into the public module ABI. @@ -743,7 +743,7 @@ static PROCESS_MODULE* KiFindProcessModuleByBaseLocked(PROCESS* process, uintptr // Registers a mapped process module or records a reference to an existing one. static KSTATUS LdrRegisterProcessModule(PROCESS* process, const char* name, uintptr_t base, uint32_t loadFlags, uintptr_t* registeredBaseOut) { - if (!process || !name || !base || !loadFlags) return STATUS_INVALID_PARAMETER; + if (!process || !name || !base || !loadFlags) return NTLSTATUS_INVALID_PARAMETER; if (registeredBaseOut) *registeredBaseOut = 0; uintptr_t flags = KeAcquireSpinlock(&process->ModuleLock); @@ -752,12 +752,12 @@ static KSTATUS LdrRegisterProcessModule(PROCESS* process, const char* name, uint KiReferenceProcessModule(existing, loadFlags); if (registeredBaseOut) *registeredBaseOut = existing->Base; KeReleaseSpinlock(&process->ModuleLock, flags); - return STATUS_ALREADY_EXISTS; + return NTLSTATUS_ALREADY_EXISTS; } if (process->ModuleCount >= PROCESS_MODULE_MAX) { KeReleaseSpinlock(&process->ModuleLock, flags); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } PROCESS_MODULE* mod = &process->Modules[process->ModuleCount++]; @@ -770,12 +770,12 @@ static KSTATUS LdrRegisterProcessModule(PROCESS* process, const char* name, uint KiReferenceProcessModule(mod, loadFlags); if (registeredBaseOut) *registeredBaseOut = mod->Base; KeReleaseSpinlock(&process->ModuleLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Loads a DLL-like user module into a process and records the requested reference. KSTATUS LdrLoadModuleForProcess(PROCESS* process, const char* filename, uint32_t loadFlags, uintptr_t* baseOut) { - if (!process || !filename || !loadFlags) return STATUS_INVALID_PARAMETER; + if (!process || !filename || !loadFlags) return NTLSTATUS_INVALID_PARAMETER; filename = KiCanonicalModuleName(filename); @@ -785,7 +785,7 @@ KSTATUS LdrLoadModuleForProcess(PROCESS* process, const char* filename, uint32_t KiReferenceProcessModule(existing, loadFlags); if (baseOut) *baseOut = existing->Base; KeReleaseSpinlock(&process->ModuleLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KeReleaseSpinlock(&process->ModuleLock, flags); @@ -795,7 +795,7 @@ KSTATUS LdrLoadModuleForProcess(PROCESS* process, const char* filename, uint32_t char relative[260]; size_t nameLen = strnlen(filename, sizeof(relative) - 8); if (nameLen + 8 >= sizeof(relative)) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; memcpy(relative, "system/", 7); memcpy(relative + 7, filename, nameLen); relative[7 + nameLen] = '\0'; @@ -834,10 +834,10 @@ KSTATUS LdrLoadModuleForProcess(PROCESS* process, const char* filename, uint32_t uintptr_t registeredBase = 0; s = LdrRegisterProcessModule(process, filename, imageBase, loadFlags, ®isteredBase); - if (s == STATUS_ALREADY_EXISTS) { + if (s == NTLSTATUS_ALREADY_EXISTS) { KiFreeLoadedImageForProcess(process, imageBase, true); imageBase = registeredBase; - s = STATUS_SUCCESS; + s = NTLSTATUS_SUCCESS; } if (!KSUCCESS(s)) { KiFreeLoadedImageForProcess(process, imageBase, true); @@ -847,12 +847,12 @@ KSTATUS LdrLoadModuleForProcess(PROCESS* process, const char* filename, uint32_t LdrDbg("LDR: module registered pid=%u name=%s base=%016llx modules=%u\n", process->ProcessId, filename, (unsigned long long)imageBase, process->ModuleCount); if (baseOut) *baseOut = imageBase; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Releases one public module load reference and unmaps the image when no references remain. KSTATUS LdrUnloadModuleForProcess(PROCESS* process, uintptr_t imageBase) { - if (!process || !imageBase) return STATUS_INVALID_PARAMETER; + if (!process || !imageBase) return NTLSTATUS_INVALID_PARAMETER; char name[PROCESS_MODULE_NAME_MAX]; uintptr_t base = 0; @@ -862,11 +862,11 @@ KSTATUS LdrUnloadModuleForProcess(PROCESS* process, uintptr_t imageBase) { PROCESS_MODULE* mod = KiFindProcessModuleByBaseLocked(process, imageBase); if (!mod) { KeReleaseSpinlock(&process->ModuleLock, flags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } if (mod->PublicRefCount == 0) { KeReleaseSpinlock(&process->ModuleLock, flags); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } mod->PublicRefCount--; @@ -891,27 +891,27 @@ KSTATUS LdrUnloadModuleForProcess(PROCESS* process, uintptr_t imageBase) { KiFreeLoadedImageForProcess(process, base, true); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Queries one loaded process module by image base. KSTATUS LdrQueryModuleForProcess(PROCESS* process, uintptr_t imageBase, SYS_MODULE_INFO* infoOut) { - if (!process || !imageBase || !infoOut) return STATUS_INVALID_PARAMETER; + if (!process || !imageBase || !infoOut) return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&process->ModuleLock); PROCESS_MODULE* mod = KiFindProcessModuleByBaseLocked(process, imageBase); if (!mod) { KeReleaseSpinlock(&process->ModuleLock, flags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } KiFillProcessModuleInfo(mod, infoOut); KeReleaseSpinlock(&process->ModuleLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Copies a bounded snapshot of the process module table. KSTATUS LdrCopyProcessModuleInfo(PROCESS* process, SYS_MODULE_INFO* infoOut, size_t maxCount, size_t* countOut) { - if (!process || !countOut) return STATUS_INVALID_PARAMETER; + if (!process || !countOut) return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&process->ModuleLock); size_t count = process->ModuleCount; @@ -920,44 +920,44 @@ KSTATUS LdrCopyProcessModuleInfo(PROCESS* process, SYS_MODULE_INFO* infoOut, siz if (toCopy > maxCount) toCopy = maxCount; if (toCopy && !infoOut) { KeReleaseSpinlock(&process->ModuleLock, flags); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } for (size_t i = 0; i < toCopy; i++) KiFillProcessModuleInfo(&process->Modules[i], &infoOut[i]); KeReleaseSpinlock(&process->ModuleLock, flags); - return (maxCount < count) ? STATUS_BUFFER_TOO_SMALL : STATUS_SUCCESS; + return (maxCount < count) ? NTLSTATUS_BUFFER_TOO_SMALL : NTLSTATUS_SUCCESS; } // Loads a boot/kernel PE image from a raw memory buffer into kernel space. static KSTATUS KiLdrLoadKernelImageFromBuffer(const void* buffer, size_t size, uintptr_t* baseOut) { - if (!buffer || !size || !baseOut) return STATUS_INVALID_PARAMETER; - if (size < 0x40) return STATUS_FAILURE; + if (!buffer || !size || !baseOut) return NTLSTATUS_INVALID_PARAMETER; + if (size < 0x40) return NTLSTATUS_FAILURE; const uint8_t* bytes = (const uint8_t*)buffer; uint32_t peOffset = *(const uint32_t *)(bytes + 0x3C); - if ((size_t)peOffset > size || size - (size_t)peOffset < 24) return STATUS_FAILURE; + if ((size_t)peOffset > size || size - (size_t)peOffset < 24) return NTLSTATUS_FAILURE; uint32_t signature = *(const uint32_t *)(bytes + peOffset); - if (signature != PE_SIGNATURE) return STATUS_FAILURE; + if (signature != PE_SIGNATURE) return NTLSTATUS_FAILURE; uint16_t machine = *(const uint16_t *)(bytes + peOffset + 4); uint16_t optionalSize = *(const uint16_t *)(bytes + peOffset + 20); if (optionalSize < sizeof(OPT_HEADER64) || (size_t)peOffset + 24 + optionalSize > size) { - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } uint16_t optionalMagic = *(const uint16_t *)(bytes + peOffset + 24); if (machine == IMAGE_FILE_MACHINE_I386 || optionalMagic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { DbgPrint("LdrLoadKernelImage: hard error: 32-bit PE images are not supported (machine=0x%X magic=0x%X)\n", machine, optionalMagic); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } if (machine != IMAGE_FILE_MACHINE_AMD64 || optionalMagic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { DbgPrint("LdrLoadKernelImage: unsupported PE image (machine=0x%X magic=0x%X)\n", machine, optionalMagic); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } PE_HEADER* pe = (PE_HEADER *)(bytes + peOffset); @@ -976,7 +976,7 @@ static KSTATUS KiLdrLoadKernelImageFromBuffer(const void* buffer, size_t size, u if (!mem) { DbgPrint("LDR: kernel image allocation failed required=%llx\n", (unsigned long long)imageSize); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } memset(mem, 0, imageSize); @@ -1018,7 +1018,7 @@ static KSTATUS KiLdrLoadKernelImageFromBuffer(const void* buffer, size_t size, u } *baseOut = (uintptr_t)mem; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Loads a kernel image from a bootloader or driver raw buffer. diff --git a/code/kernel/ldr_section.c b/code/kernel/ldr_section.c index 4c660fc..a23d770 100644 --- a/code/kernel/ldr_section.c +++ b/code/kernel/ldr_section.c @@ -134,7 +134,7 @@ static uint64_t KiImageSectionProtection(uint32_t characteristics) { // Computes the required image mapping size after validating raw section extents. static KSTATUS KiImageSectionComputeSize(const LDR_PE_HEADER* pe, size_t fileSize, size_t* outSize) { - if (!pe || !outSize) return STATUS_INVALID_PARAMETER; + if (!pe || !outSize) return NTLSTATUS_INVALID_PARAMETER; const LDR_OPT_HEADER64* opt = &pe->OptionalHeader; size_t required = KiImageSectionAlignSize(opt->SizeOfImage); @@ -150,20 +150,20 @@ static KSTATUS KiImageSectionComputeSize(const LDR_PE_HEADER* pe, size_t fileSiz if (raw > span) span = raw; if (!span) continue; - if (va > (size_t)-1 - span) return STATUS_NO_MEMORY; + if (va > (size_t)-1 - span) return NTLSTATUS_NO_MEMORY; size_t end = KiImageSectionAlignSize(va + span); if (end > required) required = end; if (raw) { size_t rawBase = (size_t)sec[i].PointerToRawData; if (rawBase > fileSize || raw > fileSize - rawBase) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } } - if (!required) return STATUS_FAILURE; + if (!required) return NTLSTATUS_FAILURE; *outSize = required; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Parses and validates the PE header that backs an image section object. @@ -174,45 +174,45 @@ static KSTATUS KiImageSectionParseHeader(const void* buffer, const LDR_SECTION_HEADER** sectionsOut, size_t* imageSizeOut) { if (!buffer || !bufferSize || !peOut || !sectionsOut || !imageSizeOut) - return STATUS_INVALID_PARAMETER; - if (bufferSize < 0x40) return STATUS_FAILURE; + return NTLSTATUS_INVALID_PARAMETER; + if (bufferSize < 0x40) return NTLSTATUS_FAILURE; const uint8_t* bytes = (const uint8_t*)buffer; uint32_t peOffset = *(const uint32_t*)(bytes + 0x3C); if ((size_t)peOffset > bufferSize || bufferSize - (size_t)peOffset < 24) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; const LDR_PE_HEADER* pe = (const LDR_PE_HEADER*)(bytes + peOffset); if (pe->Signature != PE_SIGNATURE) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; uint16_t optionalSize = pe->SizeOfOptionalHeader; if (optionalSize < sizeof(LDR_OPT_HEADER64) || (size_t)peOffset + 24 + optionalSize > bufferSize) { - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } uint16_t optionalMagic = pe->OptionalHeader.Magic; if (pe->Machine == IMAGE_FILE_MACHINE_I386 || optionalMagic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { DbgPrint("LdrImageSection: 32-bit PE images are not supported (machine=0x%X magic=0x%X)\n", pe->Machine, optionalMagic); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } if (pe->Machine != IMAGE_FILE_MACHINE_AMD64 || optionalMagic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { DbgPrint("LdrImageSection: unsupported PE image (machine=0x%X magic=0x%X)\n", pe->Machine, optionalMagic); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } if (!pe->NumberOfSections) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; const LDR_SECTION_HEADER* sections = (const LDR_SECTION_HEADER*)((const uint8_t*)&pe->OptionalHeader + pe->SizeOfOptionalHeader); size_t sectionTableOffset = (size_t)peOffset + 24u + (size_t)pe->SizeOfOptionalHeader; size_t sectionTableBytes = (size_t)pe->NumberOfSections * sizeof(LDR_SECTION_HEADER); if (sectionTableOffset > bufferSize || sectionTableBytes > bufferSize - sectionTableOffset) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; size_t imageSize = 0; KSTATUS s = KiImageSectionComputeSize(pe, fileSize, &imageSize); @@ -221,7 +221,7 @@ static KSTATUS KiImageSectionParseHeader(const void* buffer, *peOut = pe; *sectionsOut = sections; *imageSizeOut = imageSize; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Releases all resources owned by an image section object. @@ -271,7 +271,7 @@ static IMAGE_SECTION_OBJECT* KiFindImageSectionLocked(const IO_FILE_IDENTITY* id // Verifies that a cached image section is still backed by the same file generation. static KSTATUS KiValidateImageSectionBackingFile(IMAGE_SECTION_OBJECT* section) { if (!section || !section->BackingFile) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; IO_FILE_IDENTITY identity; KSTATUS s = IoQueryFileIdentity(section->BackingFile, &identity); @@ -282,10 +282,10 @@ static KSTATUS KiValidateImageSectionBackingFile(IMAGE_SECTION_OBJECT* section) identity.FileId != section->Metadata.FileId || identity.Generation != section->Metadata.FileGeneration || identity.Size != section->Metadata.RawSize) { - return STATUS_CHECKSUM_MISMATCH; + return NTLSTATUS_CHECKSUM_MISMATCH; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns true when a virtual image page has initialized bytes in the backing file. @@ -323,17 +323,17 @@ static KSTATUS KiReadImageSectionFileBytes(IMAGE_SECTION_OBJECT* section, void* dst, size_t size) { if (!section || !section->BackingFile || (!dst && size)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!size) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; size_t got = 0; KSTATUS s = IoReadFileAt(section->BackingFile, fileOffset, dst, size, &got); if (!KSUCCESS(s)) return s; if (got != size) - return STATUS_FAILURE; - return STATUS_SUCCESS; + return NTLSTATUS_FAILURE; + return NTLSTATUS_SUCCESS; } // Fills one prototype frame from the image backing file. @@ -341,11 +341,11 @@ static KSTATUS KiFillImageSectionFrameFromFile(IMAGE_SECTION_OBJECT* section, size_t pageIndex, PHYSICAL_ADDRESS frame) { if (!section || !frame || pageIndex >= section->Metadata.PageCount) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint8_t* page = (uint8_t*)MmPfnToVirtual(frame); if (!page) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; memset(page, 0, PAGE_SIZE); size_t pageStart = pageIndex * PAGE_SIZE; @@ -375,7 +375,7 @@ static KSTATUS KiFillImageSectionFrameFromFile(IMAGE_SECTION_OBJECT* section, size_t sectionStart = desc->VirtualAddress; size_t sectionEnd = sectionStart + raw; if (sectionEnd < sectionStart) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; if (pageStart >= sectionEnd || pageEnd <= sectionStart) continue; @@ -392,34 +392,34 @@ static KSTATUS KiFillImageSectionFrameFromFile(IMAGE_SECTION_OBJECT* section, return s; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Ensures a prototype page exists for initialized image bytes. static KSTATUS KiEnsureImageSectionFrame(IMAGE_SECTION_OBJECT* section, size_t pageIndex) { if (!section || pageIndex >= section->Metadata.PageCount) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(§ion->Lock); PHYSICAL_ADDRESS existing = section->Frames[pageIndex]; KeReleaseSpinlock(§ion->Lock, flags); if (existing) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (section->BackingFile && !KiImageSectionPageHasFileBytes(section, pageIndex)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; PHYSICAL_ADDRESS frame = MmPfnAllocate(MmPfnUseImage); if (!frame) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; void* va = MmPfnToVirtual(frame); if (!va) { MmPfnFree(frame); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } - KSTATUS s = STATUS_SUCCESS; + KSTATUS s = NTLSTATUS_SUCCESS; if (section->BackingFile) { s = KiValidateImageSectionBackingFile(section); if (KSUCCESS(s)) @@ -436,11 +436,11 @@ static KSTATUS KiEnsureImageSectionFrame(IMAGE_SECTION_OBJECT* section, size_t p if (section->Frames[pageIndex]) { KeReleaseSpinlock(§ion->Lock, flags); MmPfnFree(frame); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } section->Frames[pageIndex] = frame; KeReleaseSpinlock(§ion->Lock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Builds an uncached image section object backed directly by an open file. @@ -451,7 +451,7 @@ static KSTATUS KiBuildImageSectionObjectFromFile(FILE_OBJECT* file, uint64_t key, IMAGE_SECTION_OBJECT** sectionOut) { if (!file || !headerBuffer || !headerBufferSize || !identity || !sectionOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *sectionOut = (IMAGE_SECTION_OBJECT*)0; size_t fileSize = (size_t)identity->Size; @@ -469,19 +469,19 @@ static KSTATUS KiBuildImageSectionObjectFromFile(FILE_OBJECT* file, size_t pageCount = (imageSize + PAGE_SIZE - 1) / PAGE_SIZE; if (!pageCount || pageCount > ((size_t)-1 / sizeof(PHYSICAL_ADDRESS))) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; IMAGE_SECTION_OBJECT* section = (IMAGE_SECTION_OBJECT*)ObAllocateObject(ObjectTypeImageSection, sizeof(IMAGE_SECTION_OBJECT)); if (!section) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; section->Header.Destroy = KiDestroyImageSectionObject; PHYSICAL_ADDRESS* frames = (PHYSICAL_ADDRESS*)MmAllocatePoolTag(pageCount * sizeof(PHYSICAL_ADDRESS), MM_POOL_TAG('i', 's', 'f', 'r')); if (!frames) { ObDereferenceObject(§ion->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } memset(frames, 0, pageCount * sizeof(PHYSICAL_ADDRESS)); @@ -491,7 +491,7 @@ static KSTATUS KiBuildImageSectionObjectFromFile(FILE_OBJECT* file, if (!descriptors) { MmFreePool(frames); ObDereferenceObject(§ion->Header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } memset(descriptors, 0, (size_t)pe->NumberOfSections * sizeof(IMAGE_SECTION_DESCRIPTOR)); @@ -527,14 +527,14 @@ static KSTATUS KiBuildImageSectionObjectFromFile(FILE_OBJECT* file, } *sectionOut = section; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Creates or references an image section object backed by an open file. KSTATUS LdrCreateImageSectionFromFile(FILE_OBJECT* file, IMAGE_SECTION_OBJECT** sectionOut) { if (!file || !sectionOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *sectionOut = (IMAGE_SECTION_OBJECT*)0; IO_FILE_IDENTITY identity; @@ -544,32 +544,32 @@ KSTATUS LdrCreateImageSectionFromFile(FILE_OBJECT* file, size_t fileSize = (size_t)identity.Size; if (!fileSize) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; size_t firstRead = fileSize < 4096u ? fileSize : 4096u; uint8_t stackHeader[4096]; size_t got = 0; s = IoReadFileAt(file, 0, stackHeader, firstRead, &got); if (!KSUCCESS(s) || got != firstRead) - return KSUCCESS(s) ? STATUS_FAILURE : s; + return KSUCCESS(s) ? NTLSTATUS_FAILURE : s; if (firstRead < 0x40) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; uint32_t peOffset = *(const uint32_t*)(stackHeader + 0x3C); if ((size_t)peOffset > fileSize || fileSize - (size_t)peOffset < 24) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; size_t minimumHeader = (size_t)peOffset + 24u; if (minimumHeader > firstRead) { if (minimumHeader > 65536u || minimumHeader > fileSize) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; void* tmp = MmAllocatePoolTag(minimumHeader, MM_POOL_TAG('i', 's', 'h', 'd')); if (!tmp) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; s = IoReadFileAt(file, 0, tmp, minimumHeader, &got); if (!KSUCCESS(s) || got != minimumHeader) { MmFreePool(tmp); - return KSUCCESS(s) ? STATUS_FAILURE : s; + return KSUCCESS(s) ? NTLSTATUS_FAILURE : s; } uint16_t optSize = *(const uint16_t*)((const uint8_t*)tmp + peOffset + 20u); size_t fullHeader = (size_t)peOffset + 24u + (size_t)optSize; @@ -585,19 +585,19 @@ KSTATUS LdrCreateImageSectionFromFile(FILE_OBJECT* file, } if (firstRead > fileSize || firstRead > 65536u) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; void* header = stackHeader; bool heapHeader = false; if (firstRead > sizeof(stackHeader)) { header = MmAllocatePoolTag(firstRead, MM_POOL_TAG('i', 's', 'h', 'd')); if (!header) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; heapHeader = true; s = IoReadFileAt(file, 0, header, firstRead, &got); if (!KSUCCESS(s) || got != firstRead) { MmFreePool(header); - return KSUCCESS(s) ? STATUS_FAILURE : s; + return KSUCCESS(s) ? NTLSTATUS_FAILURE : s; } } @@ -607,18 +607,18 @@ KSTATUS LdrCreateImageSectionFromFile(FILE_OBJECT* file, if (tableEnd > firstRead) { if (tableEnd > fileSize || tableEnd > 65536u) { if (heapHeader) MmFreePool(header); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } void* bigger = MmAllocatePoolTag(tableEnd, MM_POOL_TAG('i', 's', 'h', 'd')); if (!bigger) { if (heapHeader) MmFreePool(header); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } s = IoReadFileAt(file, 0, bigger, tableEnd, &got); if (heapHeader) MmFreePool(header); if (!KSUCCESS(s) || got != tableEnd) { MmFreePool(bigger); - return KSUCCESS(s) ? STATUS_FAILURE : s; + return KSUCCESS(s) ? NTLSTATUS_FAILURE : s; } header = bigger; firstRead = tableEnd; @@ -634,7 +634,7 @@ KSTATUS LdrCreateImageSectionFromFile(FILE_OBJECT* file, KeReleaseSpinlock(&gImageSectionCacheLock, flags); if (heapHeader) MmFreePool(header); *sectionOut = cached; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KeReleaseSpinlock(&gImageSectionCacheLock, flags); @@ -651,7 +651,7 @@ KSTATUS LdrCreateImageSectionFromFile(FILE_OBJECT* file, KeReleaseSpinlock(&gImageSectionCacheLock, flags); ObDereferenceObject(&built->Header); *sectionOut = cached; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } for (uint32_t i = 0; i < LDR_IMAGE_SECTION_CACHE_MAX; ++i) { @@ -664,7 +664,7 @@ KSTATUS LdrCreateImageSectionFromFile(FILE_OBJECT* file, KeReleaseSpinlock(&gImageSectionCacheLock, flags); *sectionOut = built; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Adds a reference to an existing image section object. @@ -697,10 +697,10 @@ const IMAGE_SECTION_DESCRIPTOR* LdrImageSectionDescriptors(const IMAGE_SECTION_O KSTATUS LdrRetainImageSectionPage(IMAGE_SECTION_OBJECT* section, size_t pageIndex, PHYSICAL_ADDRESS* frameOut) { - if (!section || !frameOut) return STATUS_INVALID_PARAMETER; + if (!section || !frameOut) return NTLSTATUS_INVALID_PARAMETER; *frameOut = 0; if (pageIndex >= section->Metadata.PageCount) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS es = KiEnsureImageSectionFrame(section, pageIndex); if (!KSUCCESS(es)) @@ -710,21 +710,21 @@ KSTATUS LdrRetainImageSectionPage(IMAGE_SECTION_OBJECT* section, PHYSICAL_ADDRESS frame = section->Frames[pageIndex]; KeReleaseSpinlock(§ion->Lock, flags); if (!frame) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; KSTATUS s = MmPfnRetain(frame); if (!KSUCCESS(s)) return s; *frameOut = frame; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Maps an image section into a process as an image-backed VAD. KSTATUS LdrMapImageSection(PROCESS* process, IMAGE_SECTION_OBJECT* section, void** baseOut) { - if (!process || !section || !baseOut) return STATUS_INVALID_PARAMETER; + if (!process || !section || !baseOut) return NTLSTATUS_INVALID_PARAMETER; *baseOut = (void*)0; return MmVadCreateImageSectionMapping(process, diff --git a/code/kernel/mm_file_cache.c b/code/kernel/mm_file_cache.c index 9edc2b2..37b6b82 100644 --- a/code/kernel/mm_file_cache.c +++ b/code/kernel/mm_file_cache.c @@ -203,13 +203,13 @@ static KSTATUS KiFileCacheDemoteOnePage(FILE_OBJECT* skipFile, uint64_t skipOffs if (KSUCCESS(s)) { KiFileCacheMoveEntryToStandbyLocked(demote); KeReleaseSpinlock(&gFileCacheLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } KeReleaseSpinlock(&gFileCacheLock, flags); } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } static KSTATUS KiFileCacheDropOneStandbyPage(FILE_OBJECT* skipFile, uint64_t skipOffset) { @@ -229,28 +229,28 @@ static KSTATUS KiFileCacheDropOneStandbyPage(FILE_OBJECT* skipFile, uint64_t ski KeReleaseSpinlock(&gFileCacheLock, flags); if (victim) { KiFileCacheFreeEntry(victim); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } static KSTATUS KiFileCacheReclaimOnePage(FILE_OBJECT* skipFile, uint64_t skipOffset) { KSTATUS s = KiFileCacheDropOneStandbyPage(skipFile, skipOffset); if (KSUCCESS(s)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; s = KiFileCacheDemoteOnePage(skipFile, skipOffset); if (KSUCCESS(s)) { s = KiFileCacheDropOneStandbyPage(skipFile, skipOffset); if (KSUCCESS(s)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } uintptr_t flags = KeAcquireSpinlock(&gFileCacheLock); gFileCacheStats.DropFailures++; KeReleaseSpinlock(&gFileCacheLock, flags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } static void KiFileCacheAddReadAheadStat(uint64_t* field, uint64_t value) { @@ -366,13 +366,13 @@ static KSTATUS KiFileCacheEnsureReadAheadStarted(void) { uintptr_t flags = KeAcquireSpinlock(&gReadAheadLock); if (gReadAheadStartState == 2) { KeReleaseSpinlock(&gReadAheadLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (gReadAheadStartState == 1) { KeReleaseSpinlock(&gReadAheadLock, flags); while (gReadAheadStartState == 1) KeYield(); - return gReadAheadStartState == 2 ? STATUS_SUCCESS : STATUS_FAILURE; + return gReadAheadStartState == 2 ? NTLSTATUS_SUCCESS : NTLSTATUS_FAILURE; } gReadAheadStartState = 1; @@ -408,7 +408,7 @@ static KSTATUS KiFileCacheFlushOneDirtyPage(FILE_OBJECT* file, int* didWork) { MM_FILE_CACHE_ENTRY* e = KiFileCacheFindLowestDirtyLocked(file); if (!e) { KeReleaseSpinlock(&gFileCacheLock, flags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } KSTATUS rs = MmPfnRetain(e->Frame); @@ -430,11 +430,11 @@ static KSTATUS KiFileCacheFlushOneDirtyPage(FILE_OBJECT* file, int* didWork) { void* page = MmPfnToVirtual(frame); size_t written = 0; - KSTATUS s = STATUS_FAILURE; + KSTATUS s = NTLSTATUS_FAILURE; if (page && target->Fs && target->Fs->Write) s = target->Fs->Write(target->Fs, target->FileCtx, offset, page, validBytes, &written); if (KSUCCESS(s) && written != validBytes) - s = STATUS_FAILURE; + s = NTLSTATUS_FAILURE; flags = KeAcquireSpinlock(&gFileCacheLock); uint32_t bucket = KiFileCacheHash(target, offset); @@ -489,13 +489,13 @@ static KSTATUS KiFileCacheEnsureWritebackStarted(void) { uintptr_t flags = KeAcquireSpinlock(&gWritebackLock); if (gWritebackStartState == 2) { KeReleaseSpinlock(&gWritebackLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (gWritebackStartState == 1) { KeReleaseSpinlock(&gWritebackLock, flags); while (gWritebackStartState == 1) KeYield(); - return gWritebackStartState == 2 ? STATUS_SUCCESS : STATUS_FAILURE; + return gWritebackStartState == 2 ? NTLSTATUS_SUCCESS : NTLSTATUS_FAILURE; } gWritebackStartState = 1; @@ -536,14 +536,14 @@ static KSTATUS KiFileCacheTryHit(FILE_OBJECT* file, uint64_t aligned, MM_FILE_CA if (!hit) { gFileCacheStats.Misses++; KeReleaseSpinlock(&gFileCacheLock, flags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } if (hit->Loading) { if (!waitForLoading) { gFileCacheStats.Misses++; KeReleaseSpinlock(&gFileCacheLock, flags); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } gFileCacheStats.InflightWaits++; @@ -555,7 +555,7 @@ static KSTATUS KiFileCacheTryHit(FILE_OBJECT* file, uint64_t aligned, MM_FILE_CA if (hit->Invalidated || !hit->Frame) { gFileCacheStats.Misses++; KeReleaseSpinlock(&gFileCacheLock, flags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } if (hit->Standby) { @@ -564,7 +564,7 @@ static KSTATUS KiFileCacheTryHit(FILE_OBJECT* file, uint64_t aligned, MM_FILE_CA KiFileCacheActivateEntryLocked(hit); } - KSTATUS rs = STATUS_SUCCESS; + KSTATUS rs = NTLSTATUS_SUCCESS; if (outPage) rs = MmPfnRetain(hit->Frame); if (KSUCCESS(rs)) { @@ -577,7 +577,7 @@ static KSTATUS KiFileCacheTryHit(FILE_OBJECT* file, uint64_t aligned, MM_FILE_CA outPage->ValidBytes = hit->ValidBytes; } KeReleaseSpinlock(&gFileCacheLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // A retained cache entry should never point at an invalid frame, but do not @@ -641,14 +641,14 @@ static KSTATUS KiFileCacheReserveLoadingPage(FILE_OBJECT* file, uint64_t aligned MM_FILE_CACHE_ENTRY* entry = KiFileCacheAllocateLoadingEntry(file, aligned); if (!entry) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; uint32_t bucket = KiFileCacheHash(file, aligned); uintptr_t flags = KeAcquireSpinlock(&gFileCacheLock); if (KiFileCacheFindLocked(file, aligned, bucket)) { KeReleaseSpinlock(&gFileCacheLock, flags); KiFileCacheFreeLoadingEntry(entry); - return STATUS_ALREADY_EXISTS; + return NTLSTATUS_ALREADY_EXISTS; } entry->Next = gFileCacheBuckets[bucket]; @@ -657,7 +657,7 @@ static KSTATUS KiFileCacheReserveLoadingPage(FILE_OBJECT* file, uint64_t aligned if (outEntry) *outEntry = entry; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static void KiFileCacheCancelLoadingPage(MM_FILE_CACHE_ENTRY* entry) { @@ -678,7 +678,7 @@ static KSTATUS KiFileCacheCompleteLoadingPage(MM_FILE_CACHE_ENTRY* entry, MM_FILE_CACHE_PAGE* requestedPage, uint64_t* publishedCount) { if (!entry || !frame) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&gFileCacheLock); if (entry->Invalidated) { @@ -686,7 +686,7 @@ static KSTATUS KiFileCacheCompleteLoadingPage(MM_FILE_CACHE_ENTRY* entry, KeReleaseSpinlock(&gFileCacheLock, flags); (void)MmPfnRelease(frame); KiFileCacheFreeLoadingEntry(entry); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } entry->Frame = frame; @@ -715,7 +715,7 @@ static KSTATUS KiFileCacheCompleteLoadingPage(MM_FILE_CACHE_ENTRY* entry, } KeReleaseSpinlock(&gFileCacheLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static uint32_t KiFileCacheChooseForegroundBatchPages(void) { @@ -746,7 +746,7 @@ static KSTATUS KiFileCacheLoadSpan(FILE_OBJECT* file, if (loadedPagesOut) *loadedPagesOut = 0; if (!file || maxPages == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (maxPages > MM_FILE_CACHE_BATCH_MAX_PAGES) maxPages = MM_FILE_CACHE_BATCH_MAX_PAGES; @@ -759,7 +759,7 @@ static KSTATUS KiFileCacheLoadSpan(FILE_OBJECT* file, uint64_t fileSize = file->Size; KeReleaseSpinlock(&file->Lock, fileFlags); if (aligned >= fileSize) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; MM_FILE_CACHE_ENTRY* entries[MM_FILE_CACHE_BATCH_MAX_PAGES]; PHYSICAL_ADDRESS frames[MM_FILE_CACHE_BATCH_MAX_PAGES]; @@ -767,7 +767,7 @@ static KSTATUS KiFileCacheLoadSpan(FILE_OBJECT* file, memset(frames, 0, sizeof(frames)); uint32_t pages = 0; - KSTATUS reserveStatus = STATUS_SUCCESS; + KSTATUS reserveStatus = NTLSTATUS_SUCCESS; while (pages < maxPages) { uint64_t pageOffset = aligned + ((uint64_t)pages * PAGE_SIZE); if (pageOffset >= fileSize) @@ -782,7 +782,7 @@ static KSTATUS KiFileCacheLoadSpan(FILE_OBJECT* file, if (pages == 0) { if (requestedPage) return KiFileCacheTryHit(file, aligned, requestedPage, 1); - return reserveStatus == STATUS_ALREADY_EXISTS ? STATUS_ALREADY_EXISTS : reserveStatus; + return reserveStatus == NTLSTATUS_ALREADY_EXISTS ? NTLSTATUS_ALREADY_EXISTS : reserveStatus; } uint8_t* readBuffer = (uint8_t*)MmAllocatePoolTag((size_t)pages * PAGE_SIZE, MM_POOL_TAG('f', 'c', 'b', 'l')); @@ -790,7 +790,7 @@ static KSTATUS KiFileCacheLoadSpan(FILE_OBJECT* file, for (uint32_t i = 0; i < pages; ++i) KiFileCacheCancelLoadingPage(entries[i]); KiFileCacheAddReadAheadStat(&gFileCacheStats.LoadFailures, 1); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } memset(readBuffer, 0, (size_t)pages * PAGE_SIZE); @@ -803,13 +803,13 @@ static KSTATUS KiFileCacheLoadSpan(FILE_OBJECT* file, KiFileCacheCancelLoadingPage(entries[j]); MmFreePool(readBuffer); KiFileCacheAddReadAheadStat(&gFileCacheStats.LoadFailures, 1); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } } size_t toRead = KiMinSize((size_t)pages * PAGE_SIZE, (size_t)(fileSize - aligned)); size_t got = 0; - KSTATUS s = STATUS_NOT_SUPPORTED; + KSTATUS s = NTLSTATUS_NOT_SUPPORTED; if (file->Fs && file->Fs->Read) s = file->Fs->Read(file->Fs, file->FileCtx, aligned, readBuffer, toRead, &got); if (!KSUCCESS(s)) { @@ -826,7 +826,7 @@ static KSTATUS KiFileCacheLoadSpan(FILE_OBJECT* file, got = toRead; uint64_t published = 0; - KSTATUS requestedStatus = STATUS_NOT_FOUND; + KSTATUS requestedStatus = NTLSTATUS_NOT_FOUND; for (uint32_t i = 0; i < pages; ++i) { uint64_t pageOffset = aligned + ((uint64_t)i * PAGE_SIZE); size_t pageBase = (size_t)i * PAGE_SIZE; @@ -859,7 +859,7 @@ static KSTATUS KiFileCacheLoadSpan(FILE_OBJECT* file, KSTATUS ps = KiFileCacheCompleteLoadingPage(entries[i], frames[i], validBytes, out, &published); if (KSUCCESS(ps)) { if (pageOffset == aligned) - requestedStatus = STATUS_SUCCESS; + requestedStatus = NTLSTATUS_SUCCESS; frames[i] = 0; } else { if (pageOffset == aligned) @@ -885,10 +885,10 @@ static KSTATUS KiFileCacheLoadSpan(FILE_OBJECT* file, if (requestedPage) { if (KSUCCESS(requestedStatus)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; return KiFileCacheTryHit(file, aligned, requestedPage, 1); } - return published ? STATUS_SUCCESS : STATUS_NOT_FOUND; + return published ? NTLSTATUS_SUCCESS : NTLSTATUS_NOT_FOUND; } // Returns a retained cache page suitable for in-place buffered writes. @@ -898,24 +898,24 @@ static KSTATUS KiFileCacheGetWritablePage(FILE_OBJECT* file, int needExistingBytes, MM_FILE_CACHE_PAGE* outPage) { if (!file || !outPage) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; memset(outPage, 0, sizeof(*outPage)); KSTATUS s = KiFileCacheTryHit(file, aligned, outPage, 1); if (KSUCCESS(s)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (needExistingBytes && aligned < oldFileSize) { s = KiFileCacheLoadSpan(file, aligned, 1, outPage, (uint32_t*)0); if (KSUCCESS(s)) - return STATUS_SUCCESS; - if (s != STATUS_NOT_FOUND) + return NTLSTATUS_SUCCESS; + if (s != NTLSTATUS_NOT_FOUND) return s; } MM_FILE_CACHE_ENTRY* entry = (MM_FILE_CACHE_ENTRY*)0; s = KiFileCacheReserveLoadingPage(file, aligned, &entry); - if (s == STATUS_ALREADY_EXISTS) + if (s == NTLSTATUS_ALREADY_EXISTS) return KiFileCacheTryHit(file, aligned, outPage, 1); if (!KSUCCESS(s)) return s; @@ -923,14 +923,14 @@ static KSTATUS KiFileCacheGetWritablePage(FILE_OBJECT* file, PHYSICAL_ADDRESS frame = MmPfnAllocate(MmPfnUseCleanFileCache); if (!frame) { KiFileCacheCancelLoadingPage(entry); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } void* page = MmPfnToVirtual(frame); if (!page) { (void)MmPfnRelease(frame); KiFileCacheCancelLoadingPage(entry); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } memset(page, 0, PAGE_SIZE); @@ -943,7 +943,7 @@ static KSTATUS KiFileCacheGetWritablePage(FILE_OBJECT* file, s = KiFileCacheCompleteLoadingPage(entry, frame, validBytes, outPage, (uint64_t*)0); if (!KSUCCESS(s)) return s; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Marks one cache page dirty and updates its valid byte range. @@ -971,7 +971,7 @@ KSTATUS MmFileCacheGetWritablePage(FILE_OBJECT* file, uint64_t offset, uint64_t fileSizeBefore, int needExistingBytes, MM_FILE_CACHE_PAGE* outPage) { if (!outPage) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint64_t aligned = offset & ~(uint64_t)(PAGE_SIZE - 1); return KiFileCacheGetWritablePage(file, aligned, fileSizeBefore, needExistingBytes, outPage); } @@ -994,13 +994,13 @@ KSTATUS MmFileCacheWrite(FILE_OBJECT* file, uint64_t offset, const void* buf, size_t size, uint64_t fileSizeBefore, size_t* writtenOut) { if (writtenOut) *writtenOut = 0; if (!file || (!buf && size) || !writtenOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!KeCanWait()) - return STATUS_INVALID_IRQL; + return NTLSTATUS_INVALID_IRQL; if (!file->Fs || !file->Fs->Write) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; if (size == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; size_t total = 0; const uint8_t* src = (const uint8_t*)buf; @@ -1028,12 +1028,12 @@ KSTATUS MmFileCacheWrite(FILE_OBJECT* file, uint64_t offset, const void* buf, MM_FILE_CACHE_PAGE page; KSTATUS s = KiFileCacheGetWritablePage(file, aligned, fileSizeBefore, needExisting, &page); if (!KSUCCESS(s)) - return total ? STATUS_SUCCESS : s; + return total ? NTLSTATUS_SUCCESS : s; void* dst = MmPfnToVirtual(page.Frame); if (!dst) { MmFileCacheReleasePage(&page); - return total ? STATUS_SUCCESS : STATUS_FAILURE; + return total ? NTLSTATUS_SUCCESS : NTLSTATUS_FAILURE; } memcpy((uint8_t*)dst + inPage, src + total, chunk); @@ -1049,20 +1049,20 @@ KSTATUS MmFileCacheWrite(FILE_OBJECT* file, uint64_t offset, const void* buf, } *writtenOut = total; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KSTATUS MmFileCacheFlushFile(FILE_OBJECT* file) { if (!file) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!KeCanWait()) - return STATUS_INVALID_IRQL; + return NTLSTATUS_INVALID_IRQL; uintptr_t flags = KeAcquireSpinlock(&gFileCacheLock); gFileCacheStats.FlushFileCalls++; KeReleaseSpinlock(&gFileCacheLock, flags); - KSTATUS firstError = STATUS_SUCCESS; + KSTATUS firstError = NTLSTATUS_SUCCESS; for (;;) { int didWork = 0; KSTATUS s = KiFileCacheFlushOneDirtyPage(file, &didWork); @@ -1081,15 +1081,15 @@ KSTATUS MmFileCacheFlushFile(FILE_OBJECT* file) { } KSTATUS MmFileCacheGetPage(FILE_OBJECT* file, uint64_t offset, MM_FILE_CACHE_PAGE* outPage) { - if (!outPage) return STATUS_INVALID_PARAMETER; + if (!outPage) return NTLSTATUS_INVALID_PARAMETER; memset(outPage, 0, sizeof(*outPage)); - if (!file) return STATUS_INVALID_PARAMETER; - if (!KeCanWait()) return STATUS_INVALID_IRQL; + if (!file) return NTLSTATUS_INVALID_PARAMETER; + if (!KeCanWait()) return NTLSTATUS_INVALID_IRQL; uint64_t aligned = offset & ~(uint64_t)(PAGE_SIZE - 1); KSTATUS s = KiFileCacheTryHit(file, aligned, outPage, 1); if (KSUCCESS(s)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; return KiFileCacheLoadSpan(file, aligned, KiFileCacheChooseForegroundBatchPages(), outPage, (uint32_t*)0); } @@ -1181,9 +1181,9 @@ KSTATUS MmFileCacheDropOnePageForPressure(void) { KSTATUS MmFileCacheScheduleReadAhead(FILE_OBJECT* file, uint64_t offset, uint32_t pages) { if (!file || pages == 0) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!KeCanWait()) - return STATUS_INVALID_IRQL; + return NTLSTATUS_INVALID_IRQL; uint32_t requestedPages = pages; if (pages > MM_FILE_CACHE_READAHEAD_MAX_PAGES) @@ -1199,14 +1199,14 @@ KSTATUS MmFileCacheScheduleReadAhead(FILE_OBJECT* file, uint64_t offset, uint32_ if (headroom <= MM_FILE_CACHE_READAHEAD_MIN_HEADROOM_PAGES) { gFileCacheStats.ReadAheadPagesThrottled += pages; KeReleaseSpinlock(&gFileCacheLock, cacheFlags); - return STATUS_QUEUE_FULL; + return NTLSTATUS_QUEUE_FULL; } headroom -= MM_FILE_CACHE_READAHEAD_MIN_HEADROOM_PAGES; if ((uint64_t)pages > headroom) pages = (uint32_t)headroom; KeReleaseSpinlock(&gFileCacheLock, cacheFlags); if (pages == 0) - return STATUS_QUEUE_FULL; + return NTLSTATUS_QUEUE_FULL; KSTATUS s = KiFileCacheEnsureReadAheadStarted(); if (!KSUCCESS(s)) { @@ -1218,7 +1218,7 @@ KSTATUS MmFileCacheScheduleReadAhead(FILE_OBJECT* file, uint64_t offset, uint32_ (MM_FILE_CACHE_READAHEAD_REQUEST*)MmAllocatePoolTag(sizeof(*req), MM_POOL_TAG('r', 'd', 'a', 'h')); if (!req) { KiFileCacheAddReadAheadStat(&gFileCacheStats.ReadAheadFailures, 1); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } LIST_INIT(&req->Link); @@ -1235,7 +1235,7 @@ KSTATUS MmFileCacheScheduleReadAhead(FILE_OBJECT* file, uint64_t offset, uint32_ ObDereferenceObject(&file->Header); MmFreePool(req); KiFileCacheAddReadAheadStat(&gFileCacheStats.ReadAheadPagesThrottled, pages); - return STATUS_QUEUE_FULL; + return NTLSTATUS_QUEUE_FULL; } uint32_t queueHeadroom = MM_FILE_CACHE_READAHEAD_QUEUE_PAGE_BUDGET - gReadAheadQueuedPages; if (pages > queueHeadroom) @@ -1253,7 +1253,7 @@ KSTATUS MmFileCacheScheduleReadAhead(FILE_OBJECT* file, uint64_t offset, uint32_ KeReleaseSpinlock(&gFileCacheLock, flags); KeSignalSemaphore(gReadAheadSemaphore); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } void MmFileCacheQueryStats(MM_FILE_CACHE_STATS* out) { diff --git a/code/kernel/mm_phys.c b/code/kernel/mm_phys.c index f711dcf..1680ff7 100644 --- a/code/kernel/mm_phys.c +++ b/code/kernel/mm_phys.c @@ -522,49 +522,49 @@ __declspec(dllexport) PHYSICAL_ADDRESS MmPfnAllocateContiguous(size_t count, MM_ __declspec(dllexport) KSTATUS MmPfnRetain(PHYSICAL_ADDRESS frame) { size_t pfn = MmPfnIndex(frame); if (pfn == MM_PFN_INVALID_INDEX) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&gPfnLock); MM_PFN* entry = &gPfnDatabase[pfn]; if (entry->State == MmPfnStateInvalid || entry->State == MmPfnStateFree || entry->State == MmPfnStateZeroed) { KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (entry->RefCount == UINT16_MAX) { KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } entry->RefCount++; gPfnRetains++; KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Releases a reference and returns the frame to the free list when the last owner leaves. __declspec(dllexport) KSTATUS MmPfnRelease(PHYSICAL_ADDRESS frame) { size_t pfn = MmPfnIndex(frame); if (pfn == MM_PFN_INVALID_INDEX) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&gPfnLock); MM_PFN* entry = &gPfnDatabase[pfn]; if (entry->State == MmPfnStateInvalid || entry->State == MmPfnStateFree || entry->State == MmPfnStateZeroed) { KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (entry->PinCount) { KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; } gPfnReleases++; if (entry->RefCount > 1) { entry->RefCount--; KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (entry->MappedCount) { KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; } entry->State = MmPfnStateFree; @@ -578,7 +578,7 @@ __declspec(dllexport) KSTATUS MmPfnRelease(PHYSICAL_ADDRESS frame) { gFreeFrames++; gPfnFrees++; KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Frees a frame that is expected to have a single owner. @@ -590,119 +590,119 @@ __declspec(dllexport) KSTATUS MmPfnFree(PHYSICAL_ADDRESS frame) { __declspec(dllexport) KSTATUS MmPfnPin(PHYSICAL_ADDRESS frame) { size_t pfn = MmPfnIndex(frame); if (pfn == MM_PFN_INVALID_INDEX) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&gPfnLock); MM_PFN* entry = &gPfnDatabase[pfn]; if (entry->State == MmPfnStateInvalid || entry->State == MmPfnStateFree || entry->State == MmPfnStateZeroed) { KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (entry->PinCount == UINT16_MAX) { KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } entry->PinCount++; gPfnPins++; KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Removes one pin from a frame. __declspec(dllexport) KSTATUS MmPfnUnpin(PHYSICAL_ADDRESS frame) { size_t pfn = MmPfnIndex(frame); if (pfn == MM_PFN_INVALID_INDEX) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&gPfnLock); MM_PFN* entry = &gPfnDatabase[pfn]; if (!entry->PinCount) { KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } entry->PinCount--; gPfnUnpins++; KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Records that a VAD now maps this frame into a user address space. __declspec(dllexport) KSTATUS MmPfnAddMapping(PHYSICAL_ADDRESS frame) { size_t pfn = MmPfnIndex(frame); if (pfn == MM_PFN_INVALID_INDEX) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&gPfnLock); MM_PFN* entry = &gPfnDatabase[pfn]; if (entry->State == MmPfnStateInvalid || entry->State == MmPfnStateFree || entry->State == MmPfnStateZeroed) { KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (entry->MappedCount == UINT32_MAX) { KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } entry->MappedCount++; KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Removes one user VAD mapping reference from a frame. __declspec(dllexport) KSTATUS MmPfnRemoveMapping(PHYSICAL_ADDRESS frame) { size_t pfn = MmPfnIndex(frame); if (pfn == MM_PFN_INVALID_INDEX) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&gPfnLock); MM_PFN* entry = &gPfnDatabase[pfn]; if (entry->State == MmPfnStateInvalid || entry->State == MmPfnStateFree || entry->State == MmPfnStateZeroed || entry->MappedCount == 0) { KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } entry->MappedCount--; KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Moves a clean, unshared frame to standby so pressure can reclaim it later. __declspec(dllexport) KSTATUS MmPfnMoveToStandby(PHYSICAL_ADDRESS frame) { size_t pfn = MmPfnIndex(frame); if (pfn == MM_PFN_INVALID_INDEX) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&gPfnLock); MM_PFN* entry = &gPfnDatabase[pfn]; if (entry->State != MmPfnStateActive || entry->PinCount || entry->MappedCount || entry->RefCount != 1) { KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; } if (entry->Usage != MmPfnUseCleanFileCache && entry->Usage != MmPfnUseImage) { KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } entry->State = MmPfnStateStandby; KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Reactivates a standby frame after a cache or image lookup found it still useful. __declspec(dllexport) KSTATUS MmPfnActivate(PHYSICAL_ADDRESS frame) { size_t pfn = MmPfnIndex(frame); if (pfn == MM_PFN_INVALID_INDEX) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&gPfnLock); MM_PFN* entry = &gPfnDatabase[pfn]; if (entry->State != MmPfnStateStandby || !entry->RefCount) { KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } entry->State = MmPfnStateActive; KeReleaseSpinlock(&gPfnLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns the number of frames that are immediately available for allocation. diff --git a/code/kernel/mm_pte.c b/code/kernel/mm_pte.c index 8c10d50..ba8d2f8 100644 --- a/code/kernel/mm_pte.c +++ b/code/kernel/mm_pte.c @@ -208,26 +208,26 @@ __declspec(dllexport) KSTATUS MmPteMapPage(uintptr_t virt, PHYSICAL_ADDRESS phys if (!pdpt) { KiPteStatInc(&gPteStats.MapFailures); KeReleaseSpinlock(&gPageTableLock, lockFlags); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } PHYSICAL_ADDRESS pdt = KiEnsureTable(pdpt, PDPT_IDX(virt), userFlag); if (!pdt) { KiPteStatInc(&gPteStats.MapFailures); KeReleaseSpinlock(&gPageTableLock, lockFlags); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } PHYSICAL_ADDRESS pt = KiEnsureTable(pdt, PDT_IDX(virt), userFlag); if (!pt) { KiPteStatInc(&gPteStats.MapFailures); KeReleaseSpinlock(&gPageTableLock, lockFlags); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } uint64_t* pte = KiPtePtr(pt, PT_IDX(virt)); if ((*pte & PAGE_PRESENT) && mode == MmPteMapFailIfPresent) { KiPteStatInc(&gPteStats.MapFailures); KeReleaseSpinlock(&gPageTableLock, lockFlags); - return STATUS_ALREADY_EXISTS; + return NTLSTATUS_ALREADY_EXISTS; } int wasPresent = ((*pte & PAGE_PRESENT) != 0); *pte = phys | flags; @@ -242,7 +242,7 @@ __declspec(dllexport) KSTATUS MmPteMapPage(uintptr_t virt, PHYSICAL_ADDRESS phys KiPteStatInc(&gPteStats.ReplacedMappingFlushes); MmPteFlushKernelAddress(virt); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Removes one 4 KiB leaf PTE from the shared page tables. @@ -254,25 +254,25 @@ __declspec(dllexport) KSTATUS MmPteUnmapPage(uintptr_t virt) { if (!(*e4 & PAGE_PRESENT)) { KiPteStatInc(&gPteStats.UnmapFailures); KeReleaseSpinlock(&gPageTableLock, lockFlags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } uint64_t* e3 = KiPtePtr(*e4 & PAGE_FRAME_4K_MASK, PDPT_IDX(virt)); if (!(*e3 & PAGE_PRESENT)) { KiPteStatInc(&gPteStats.UnmapFailures); KeReleaseSpinlock(&gPageTableLock, lockFlags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } uint64_t* e2 = KiPtePtr(*e3 & PAGE_FRAME_4K_MASK, PDT_IDX(virt)); if (!(*e2 & PAGE_PRESENT)) { KiPteStatInc(&gPteStats.UnmapFailures); KeReleaseSpinlock(&gPageTableLock, lockFlags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } uint64_t* pte = KiPtePtr(*e2 & PAGE_FRAME_4K_MASK, PT_IDX(virt)); if (!(*pte & PAGE_PRESENT)) { KiPteStatInc(&gPteStats.UnmapFailures); KeReleaseSpinlock(&gPageTableLock, lockFlags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } *pte = 0; if (gPteStats.CurrentLeafMappings) @@ -280,49 +280,49 @@ __declspec(dllexport) KSTATUS MmPteUnmapPage(uintptr_t virt) { KeReleaseSpinlock(&gPageTableLock, lockFlags); MmPteFlushKernelAddress(virt); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Replaces leaf flags for a 4 KiB range and refuses huge pages instead of silently corrupting them. __declspec(dllexport) KSTATUS MmPteProtectRange(uintptr_t virt, size_t size, uint64_t flags) { KiPteStatInc(&gPteStats.ProtectCalls); - if (!size) return STATUS_SUCCESS; + if (!size) return NTLSTATUS_SUCCESS; // The protection operation is page-granular even when callers pass an interior address. uintptr_t base = virt & PAGE_MASK; uintptr_t end = (virt + size + PAGE_SIZE - 1) & PAGE_MASK; uintptr_t lockFlags = KeAcquireSpinlock(&gPageTableLock); - KSTATUS status = STATUS_SUCCESS; + KSTATUS status = NTLSTATUS_SUCCESS; uintptr_t flushEnd = base; for (uintptr_t va = base; va < end; va += PAGE_SIZE) { uint64_t* e4 = KiPtePtr(gPml4Phys, PML4_IDX(va)); if (!(*e4 & PAGE_PRESENT)) { - status = STATUS_NOT_FOUND; + status = NTLSTATUS_NOT_FOUND; break; } uint64_t* e3 = KiPtePtr(*e4 & PAGE_FRAME_4K_MASK, PDPT_IDX(va)); if (!(*e3 & PAGE_PRESENT)) { - status = STATUS_NOT_FOUND; + status = NTLSTATUS_NOT_FOUND; break; } if (*e3 & PAGE_PS) { - status = STATUS_NOT_SUPPORTED; + status = NTLSTATUS_NOT_SUPPORTED; break; } uint64_t* e2 = KiPtePtr(*e3 & PAGE_FRAME_4K_MASK, PDT_IDX(va)); if (!(*e2 & PAGE_PRESENT)) { - status = STATUS_NOT_FOUND; + status = NTLSTATUS_NOT_FOUND; break; } if (*e2 & PAGE_PS) { - status = STATUS_NOT_SUPPORTED; + status = NTLSTATUS_NOT_SUPPORTED; break; } uint64_t* pte = KiPtePtr(*e2 & PAGE_FRAME_4K_MASK, PT_IDX(va)); if (!(*pte & PAGE_PRESENT)) { - status = STATUS_NOT_FOUND; + status = NTLSTATUS_NOT_FOUND; break; } @@ -474,10 +474,10 @@ KSTATUS MmPteQueryPageFor(MM_PTE_QUERY_PURPOSE purpose, if (!gPml4Phys) { KiPteStatInc(&gPteStats.QueryFailures); KiPteStatInc(&gPteStats.QueryFailuresByPurpose[purpose]); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } - KSTATUS status = STATUS_NOT_FOUND; + KSTATUS status = NTLSTATUS_NOT_FOUND; uintptr_t lockFlags = KeAcquireSpinlock(&gPageTableLock); uint64_t* pml4 = (uint64_t*)KiPhysToVirt(gPml4Phys); @@ -504,7 +504,7 @@ KSTATUS MmPteQueryPageFor(MM_PTE_QUERY_PURPOSE purpose, if (!effectiveUser) flags &= ~PAGE_USER; *flagsOut = flags; } - status = STATUS_SUCCESS; + status = NTLSTATUS_SUCCESS; goto out; } @@ -524,7 +524,7 @@ KSTATUS MmPteQueryPageFor(MM_PTE_QUERY_PURPOSE purpose, if (!effectiveUser) flags &= ~PAGE_USER; *flagsOut = flags; } - status = STATUS_SUCCESS; + status = NTLSTATUS_SUCCESS; goto out; } @@ -543,7 +543,7 @@ KSTATUS MmPteQueryPageFor(MM_PTE_QUERY_PURPOSE purpose, if (!effectiveUser) flags &= ~PAGE_USER; *flagsOut = flags; } - status = STATUS_SUCCESS; + status = NTLSTATUS_SUCCESS; out: if (!KSUCCESS(status)) { diff --git a/code/kernel/mm_swap.c b/code/kernel/mm_swap.c index 34cb563..f239766 100644 --- a/code/kernel/mm_swap.c +++ b/code/kernel/mm_swap.c @@ -42,13 +42,13 @@ static void KiSwapSetSlot(uint32_t slot, int used) { // Allocates one pagefile slot. static KSTATUS KiSwapAllocateSlot(uint32_t* slotOut) { - if (!slotOut) return STATUS_INVALID_PARAMETER; + if (!slotOut) return NTLSTATUS_INVALID_PARAMETER; *slotOut = 0; uintptr_t flags = KeAcquireSpinlock(&gSwap.Lock); if (!gSwap.Enabled || !gSwap.Bitmap || !gSwap.SlotCount) { KeReleaseSpinlock(&gSwap.Lock, flags); - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; } for (uint32_t slot = 0; slot < gSwap.SlotCount; ++slot) { @@ -60,26 +60,26 @@ static KSTATUS KiSwapAllocateSlot(uint32_t* slotOut) { gSwap.Stats.SlotAllocations++; *slotOut = slot; KeReleaseSpinlock(&gSwap.Lock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } gSwap.Stats.SlotAllocationFailures++; KeReleaseSpinlock(&gSwap.Lock, flags); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } // Initializes the fixed pagefile backend. KSTATUS MmSwapInitialize(SYS_STRING_VIEW path, uint64_t sizeBytes) { if (!path.Data || !path.Length || sizeBytes < PAGE_SIZE) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (sizeBytes & (PAGE_SIZE - 1)) sizeBytes = (sizeBytes + PAGE_SIZE - 1) & ~(uint64_t)(PAGE_SIZE - 1); uintptr_t flags = KeAcquireSpinlock(&gSwap.Lock); if (gSwap.Enabled) { KeReleaseSpinlock(&gSwap.Lock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KeReleaseSpinlock(&gSwap.Lock, flags); @@ -105,7 +105,7 @@ KSTATUS MmSwapInitialize(SYS_STRING_VIEW path, uint64_t sizeBytes) { uint64_t slots64 = sizeBytes / PAGE_SIZE; if (!slots64 || slots64 > 0xFFFFFFFFull) { IoCloseFile(file); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } uint32_t slotCount = (uint32_t)slots64; @@ -113,7 +113,7 @@ KSTATUS MmSwapInitialize(SYS_STRING_VIEW path, uint64_t sizeBytes) { uint8_t* bitmap = (uint8_t*)MmAllocatePoolTag(bitmapBytes, MM_POOL_TAG('s', 'w', 'a', 'p')); if (!bitmap) { IoCloseFile(file); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } memset(bitmap, 0, bitmapBytes); @@ -122,7 +122,7 @@ KSTATUS MmSwapInitialize(SYS_STRING_VIEW path, uint64_t sizeBytes) { KeReleaseSpinlock(&gSwap.Lock, flags); MmFreePool(bitmap); IoCloseFile(file); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } gSwap.File = file; @@ -141,7 +141,7 @@ KSTATUS MmSwapInitialize(SYS_STRING_VIEW path, uint64_t sizeBytes) { slotCount, (unsigned long long)(sizeBytes / 1024), path); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns whether swap is available for pageout. @@ -152,10 +152,10 @@ int MmSwapIsEnabled(void) { // Writes one physical page to a newly allocated swap slot. KSTATUS MmSwapPageOut(PHYSICAL_ADDRESS frame, uint32_t* slotOut) { if (!slotOut || !frame) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *slotOut = 0; if (!gSwap.Enabled || !gSwap.File) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; uint32_t slot = 0; KSTATUS s = KiSwapAllocateSlot(&slot); @@ -168,7 +168,7 @@ KSTATUS MmSwapPageOut(PHYSICAL_ADDRESS frame, uint32_t* slotOut) { if (!page) { MmSwapFreeSlot(slot); gSwap.Stats.PageOutFailures++; - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } size_t written = 0; @@ -176,44 +176,44 @@ KSTATUS MmSwapPageOut(PHYSICAL_ADDRESS frame, uint32_t* slotOut) { if (!KSUCCESS(s) || written != PAGE_SIZE) { MmSwapFreeSlot(slot); gSwap.Stats.PageOutFailures++; - return KSUCCESS(s) ? STATUS_DEVICE_ERROR : s; + return KSUCCESS(s) ? NTLSTATUS_DEVICE_ERROR : s; } gSwap.Stats.PageOuts++; *slotOut = slot; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Reads one swap slot into an already allocated physical page. KSTATUS MmSwapPageIn(uint32_t slot, PHYSICAL_ADDRESS frame) { if (!frame) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!gSwap.Enabled || !gSwap.File) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; uintptr_t flags = KeAcquireSpinlock(&gSwap.Lock); int valid = slot < gSwap.SlotCount && KiSwapTestSlot(slot); KeReleaseSpinlock(&gSwap.Lock, flags); if (!valid) { gSwap.Stats.PageInFailures++; - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } void* page = MmPfnToVirtual(frame); if (!page) { gSwap.Stats.PageInFailures++; - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } size_t read = 0; KSTATUS s = IoReadFileAt(gSwap.File, (uint64_t)slot * PAGE_SIZE, page, PAGE_SIZE, &read); if (!KSUCCESS(s) || read != PAGE_SIZE) { gSwap.Stats.PageInFailures++; - return KSUCCESS(s) ? STATUS_DEVICE_ERROR : s; + return KSUCCESS(s) ? NTLSTATUS_DEVICE_ERROR : s; } gSwap.Stats.PageIns++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Releases a swap slot after the owning VAD page no longer references it. diff --git a/code/kernel/mm_virt.c b/code/kernel/mm_virt.c index 520ed02..4ebbd71 100644 --- a/code/kernel/mm_virt.c +++ b/code/kernel/mm_virt.c @@ -54,14 +54,14 @@ static int KiUserRangeValid(uintptr_t addr, size_t size) { // Probes user Range and materializes demand-zero pages before the kernel copies through it. static KSTATUS KiProbeUserRange(uintptr_t addr, size_t size, uint64_t requiredFlags) { if (!KiUserRangeValid(addr, size)) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; if (size == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; PROCESS* process = KeGetCurrentProcess(); if (!process) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; return KiVadEnsureResidentRange(process, addr, size, requiredFlags); } @@ -200,7 +200,7 @@ static const char* KiPoolStateName(uint32_t state) { static _Noreturn void KiPoolPanic(const char* reason, HEAP* h, BLOCK_HDR* blk, const void* ptr) { KePanic(KE_PANIC_CODE_GENERIC, - "MM: pool corruption: %s ptr=%p hdr=%p heap=[%016llx,%016llx) magic=%08x state=%u(%s) size=%llu req=%llu tag=%08x flags=%08x seq=%llu alloc=%p free=%p\n", + "MM: pool corruption: %s ptr=0x%016llX hdr=0x%016llX heap=[%016llx,%016llx) magic=%08x state=%u(%s) size=%llu req=%llu tag=%08x flags=%08x seq=%llu alloc=0x%016llX free=0x%016llX\n", reason ? reason : "unknown", ptr, blk, @@ -873,15 +873,15 @@ static int KiRangesOverlap(uintptr_t aBase, size_t aSize, uintptr_t bBase, size_ // Finds a free range in the global user VA arena. static KSTATUS KiFindVadRange(size_t reservationSize, size_t alignment, uintptr_t* baseOut) { - if (!baseOut || !reservationSize) return STATUS_INVALID_PARAMETER; - if (!gVadListReady) return STATUS_FAILURE; + if (!baseOut || !reservationSize) return NTLSTATUS_INVALID_PARAMETER; + if (!gVadListReady) return NTLSTATUS_FAILURE; uintptr_t candidate = KiAlignUpPtr(MM_VAD_ARENA_BASE, alignment); - if (!candidate) return STATUS_INVALID_PARAMETER; + if (!candidate) return NTLSTATUS_INVALID_PARAMETER; for (;;) { if (candidate < MM_VAD_ARENA_BASE || reservationSize > (size_t)(USER_LIMIT - candidate)) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; uintptr_t next = candidate; int collided = 0; @@ -891,7 +891,7 @@ static KSTATUS KiFindVadRange(size_t reservationSize, size_t alignment, uintptr_ if (KiRangesOverlap(candidate, reservationSize, vad->ReservationBase, vad->ReservationSize)) { uintptr_t end = vad->ReservationBase + vad->ReservationSize; next = KiAlignUpPtr(end, alignment); - if (!next || next <= candidate) return STATUS_NO_MEMORY; + if (!next || next <= candidate) return NTLSTATUS_NO_MEMORY; collided = 1; break; } @@ -899,7 +899,7 @@ static KSTATUS KiFindVadRange(size_t reservationSize, size_t alignment, uintptr_ if (!collided) { *baseOut = candidate; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } candidate = next; } @@ -962,17 +962,17 @@ static KSTATUS KiVadUnmapPageTracked(uintptr_t va, PHYSICAL_ADDRESS frame); static KSTATUS KiVadMarkSharedFilePageDirty(MM_VAD* vad, size_t index, int writeProtect) { if (!vad || index >= vad->PageCount || !vad->FileObject) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; MM_VAD_PAGE* page = &vad->Pages[index]; if ((page->Flags & MM_VAD_PAGE_FILE_BACKED) == 0 || (page->Flags & MM_VAD_PAGE_FILE_SHARED_WRITE) == 0) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; uint64_t pageDelta = (uint64_t)index * (uint64_t)PAGE_SIZE; uint64_t fileOffset = vad->FileOffset + pageDelta; if (fileOffset < vad->FileOffset) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uint32_t validBytes = PAGE_SIZE; if (pageDelta >= (uint64_t)vad->FileLength) { @@ -998,7 +998,7 @@ static KSTATUS KiVadMarkSharedFilePageDirty(MM_VAD* vad, size_t index, int write } gVadStats.FileBackedDirtySyncs++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static void KiVadSyncSharedFilePageBeforeRelease(MM_VAD* vad, size_t index) { @@ -1073,7 +1073,7 @@ static KSTATUS KiVadMapPageTracked(uintptr_t va, PHYSICAL_ADDRESS frame, uint64_ (void)MmPteUnmapPage(va); return s; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Unmaps a user VAD PTE and removes the matching PFN mapping reference. @@ -1087,16 +1087,16 @@ static KSTATUS KiVadUnmapPageTracked(uintptr_t va, PHYSICAL_ADDRESS frame) { // Returns whether the committed page allows the requested fault or probe access. static KSTATUS KiVadCheckPageAccess(const MM_VAD_PAGE* page, int wantWrite, int wantExecute) { if (!page || page->State != MmVadPageCommitted) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; if (!page->PageFlags) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; if ((page->PageFlags & PAGE_USER) == 0) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; if (wantWrite && (page->PageFlags & PAGE_WRITE) == 0) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; if (wantExecute && (page->PageFlags & PAGE_NX)) - return STATUS_ACCESS_DENIED; - return STATUS_SUCCESS; + return NTLSTATUS_ACCESS_DENIED; + return NTLSTATUS_SUCCESS; } // Waits for another CPU/thread to finish a page-in/page-out transition on a VAD page. @@ -1151,23 +1151,23 @@ static void KiVadEndPaging(MM_VAD_PAGE* page) { // whole file up front. static KSTATUS KiVadFillFileBackedPage(MM_VAD* vad, size_t pageIndex, PHYSICAL_ADDRESS frame) { if (!vad || !vad->FileObject || !frame || pageIndex >= vad->PageCount) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; void* pageVa = MmPfnToVirtual(frame); if (!pageVa) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; memset(pageVa, 0, PAGE_SIZE); uint64_t pageDelta = (uint64_t)pageIndex * (uint64_t)PAGE_SIZE; if (pageDelta >= (uint64_t)vad->FileLength) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; size_t remaining = vad->FileLength - (size_t)pageDelta; size_t toRead = remaining < PAGE_SIZE ? remaining : PAGE_SIZE; uint64_t fileOffset = vad->FileOffset + pageDelta; if (fileOffset < vad->FileOffset) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; size_t got = 0; KSTATUS s = IoReadFileAt(vad->FileObject, fileOffset, pageVa, toRead, &got); @@ -1178,13 +1178,13 @@ static KSTATUS KiVadFillFileBackedPage(MM_VAD* vad, size_t pageIndex, PHYSICAL_A gVadStats.FileBackedReads++; if (got < toRead) memset((uint8_t*)pageVa + got, 0, toRead - got); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Materializes one image-backed prototype page or zero-fill page for an image VAD. static KSTATUS KiVadFillImageBackedPage(MM_VAD* vad, size_t pageIndex, int wantWrite) { if (!vad || !vad->ImageSection || pageIndex >= vad->PageCount) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; MM_VAD_PAGE* page = &vad->Pages[pageIndex]; uintptr_t va = vad->Base + pageIndex * PAGE_SIZE; @@ -1211,7 +1211,7 @@ static KSTATUS KiVadFillImageBackedPage(MM_VAD* vad, size_t pageIndex, int wantW } gVadStats.ImageBackedFaults++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (!wantWrite && gVadZeroPageFrame) { @@ -1231,17 +1231,17 @@ static KSTATUS KiVadFillImageBackedPage(MM_VAD* vad, size_t pageIndex, int wantW } gVadStats.ImageBackedZeroFaults++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } frame = MmPfnAllocate(MmPfnUseImage); if (!frame) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; void* pageVa = MmPfnToVirtual(frame); if (!pageVa) { MmPfnFree(frame); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } memset(pageVa, 0, PAGE_SIZE); @@ -1260,13 +1260,13 @@ static KSTATUS KiVadFillImageBackedPage(MM_VAD* vad, size_t pageIndex, int wantW } gVadStats.ImageBackedPrivateFaults++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Materializes one committed VAD page as either the shared zero page or a private frame. static KSTATUS KiVadEnsurePageResident(MM_VAD* vad, size_t pageIndex, int wantWrite, int wantExecute) { if (!vad || pageIndex >= vad->PageCount) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; MM_VAD_PAGE* page = &vad->Pages[pageIndex]; retry_after_paging: @@ -1279,7 +1279,7 @@ retry_after_paging: uintptr_t va = vad->Base + pageIndex * PAGE_SIZE; if (page->Resident) { gVadStats.AlreadyResidentPages++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (!KiVadTryBeginPaging(page)) @@ -1295,7 +1295,7 @@ retry_after_paging: if (page->Resident) { KiVadEndPaging(page); gVadStats.AlreadyResidentPages++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if ((page->Flags & MM_VAD_PAGE_SWAPPED) && page->SwapSlot != 0xFFFFFFFFu) { @@ -1304,7 +1304,7 @@ retry_after_paging: PHYSICAL_ADDRESS frame = MmPfnAllocate(MmPfnUseAnonymous); if (!frame) { KiVadEndPaging(page); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } KSTATUS swapStatus = MmSwapPageIn(oldSlot, frame); @@ -1333,7 +1333,7 @@ retry_after_paging: KiVadEndPaging(page); MmSwapFreeSlot(oldSlot); gVadStats.SwapPageIns++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (page->Flags & MM_VAD_PAGE_IMAGE_BACKED) { @@ -1350,7 +1350,7 @@ retry_after_paging: uint64_t fileOffset = vad->FileOffset + (uint64_t)pageIndex * (uint64_t)PAGE_SIZE; if (fileOffset < vad->FileOffset) { KiVadEndPaging(page); - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; } if (page->Flags & MM_VAD_PAGE_FILE_SHARED_WRITE) { @@ -1379,7 +1379,7 @@ retry_after_paging: frame = MmPfnAllocate(MmPfnUseMappedFile); if (!frame) { KiVadEndPaging(page); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } s = KiVadFillFileBackedPage(vad, pageIndex, frame); @@ -1407,7 +1407,7 @@ retry_after_paging: KiVadEndPaging(page); gVadStats.FileBackedFaults++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (!wantWrite && gVadZeroPageFrame) { @@ -1429,20 +1429,20 @@ retry_after_paging: KiVadEndPaging(page); gVadStats.ZeroPageMaps++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } PHYSICAL_ADDRESS frame = MmPfnAllocate(MmPfnUseAnonymous); if (!frame) { KiVadEndPaging(page); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } void* pageVa = MmPfnToVirtual(frame); if (!pageVa) { KiVadEndPaging(page); MmPfnFree(frame); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } memset(pageVa, 0, PAGE_SIZE); @@ -1462,30 +1462,30 @@ retry_after_paging: KiVadEndPaging(page); gVadStats.DemandZeroPages++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Splits a copy-on-write page so this VAD receives a private writable frame. static KSTATUS KiVadBreakCopyOnWrite(MM_VAD* vad, size_t pageIndex) { if (!vad || pageIndex >= vad->PageCount) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; MM_VAD_PAGE* page = &vad->Pages[pageIndex]; if (page->State != MmVadPageCommitted || !(page->Flags & MM_VAD_PAGE_COW)) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; if (!page->Resident || !page->Frame) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; if ((page->PageFlags & PAGE_WRITE) == 0) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; PHYSICAL_ADDRESS newFrame = MmPfnAllocate(MmPfnUseCow); if (!newFrame) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; void* newPage = MmPfnToVirtual(newFrame); if (!newPage) { MmPfnFree(newFrame); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } if (page->Flags & MM_VAD_PAGE_ZERO_PAGE) { @@ -1495,7 +1495,7 @@ static KSTATUS KiVadBreakCopyOnWrite(MM_VAD* vad, size_t pageIndex) { void* oldPage = MmPfnToVirtual(page->Frame); if (!oldPage) { MmPfnFree(newFrame); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } memcpy(newPage, oldPage, PAGE_SIZE); } @@ -1520,33 +1520,33 @@ static KSTATUS KiVadBreakCopyOnWrite(MM_VAD* vad, size_t pageIndex) { page->Flags &= ~(MM_VAD_PAGE_COW | MM_VAD_PAGE_ZERO_PAGE | MM_VAD_PAGE_SHARED_FRAME | MM_VAD_PAGE_IMAGE_BACKED); page->Resident = 1; gVadStats.CowPagesCopied++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Ensures that every committed page in a range is resident and accessible. static KSTATUS KiVadEnsureResidentRange(PROCESS* process, uintptr_t start, size_t size, uint64_t accessFlags) { if (!process || !size) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (start > (uintptr_t)-1 - (size - 1)) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; uintptr_t alignedStart = start & PAGE_MASK; uintptr_t alignedEnd = (start + size + PAGE_SIZE - 1) & PAGE_MASK; if (alignedEnd <= alignedStart) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; uintptr_t procFlags = KeAcquireSpinlock(&process->VadLock); MM_VAD* vad = KiFindReservedVadContainingLocked(process, alignedStart, alignedEnd - alignedStart); KeReleaseSpinlock(&process->VadLock, procFlags); if (!vad) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; int wantWrite = (accessFlags & PAGE_WRITE) ? 1 : 0; int wantExecute = (accessFlags & PAGE_NX) ? 1 : 0; size_t first = KiVadPageIndex(vad, alignedStart); size_t count = KiVadRangePageCount(alignedStart, alignedEnd); if (first > vad->PageCount || count > vad->PageCount - first) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; gVadStats.EnsureResidentCalls++; for (size_t i = 0; i < count; ++i) { @@ -1561,36 +1561,36 @@ static KSTATUS KiVadEnsureResidentRange(PROCESS* process, uintptr_t start, size_ gVadStats.EnsureResidentPages++; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Makes an image VAD range private before the loader patches relocations or imports. KSTATUS MmVadMakeImageRangePrivate(PROCESS* process, void* base, size_t size) { KeAssertIrql(PASSIVE_LEVEL); if (!process || !base || !size) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t start = (uintptr_t)base; if (start > (uintptr_t)-1 - (size - 1)) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; uintptr_t alignedStart = start & PAGE_MASK; uintptr_t alignedEnd = (start + size + PAGE_SIZE - 1) & PAGE_MASK; if (alignedEnd <= alignedStart) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; uintptr_t procFlags = KeAcquireSpinlock(&process->VadLock); MM_VAD* vad = KiFindReservedVadContainingLocked(process, alignedStart, alignedEnd - alignedStart); KeReleaseSpinlock(&process->VadLock, procFlags); if (!vad) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; if (vad->Type != MmVadImage) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; size_t first = KiVadPageIndex(vad, alignedStart); size_t count = KiVadRangePageCount(alignedStart, alignedEnd); if (first > vad->PageCount || count > vad->PageCount - first) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; gVadStats.ImageFixupPrivateCalls++; for (size_t i = 0; i < count; ++i) { @@ -1615,7 +1615,7 @@ KSTATUS MmVadMakeImageRangePrivate(PROCESS* process, void* base, size_t size) { } } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Pins the user page that contains the supplied address after materializing it. @@ -1626,11 +1626,11 @@ KSTATUS MmVadMakeImageRangePrivate(PROCESS* process, void* base, size_t size) { static KSTATUS KiVadPinUserPage(PROCESS* process, uintptr_t address, uint64_t accessFlags, MM_PINNED_USER_PAGE* out) { if (!process || !out) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; memset(out, 0, sizeof(*out)); if (!KiUserRangeValid(address, 1)) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; uintptr_t pageBase = address & PAGE_MASK; KSTATUS s = KiVadEnsureResidentRange(process, pageBase, PAGE_SIZE, accessFlags | PAGE_USER); @@ -1654,7 +1654,7 @@ static KSTATUS KiVadPinUserPage(PROCESS* process, uintptr_t address, KeReleaseSpinlock(&process->VadLock, procFlags); if (!frame) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; s = MmPfnPin(frame); if (!KSUCCESS(s)) @@ -1680,7 +1680,7 @@ static KSTATUS KiVadPinUserPage(PROCESS* process, uintptr_t address, if (!stillValid) { (void)MmPfnUnpin(frame); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } out->UserPage = pageBase; @@ -1690,9 +1690,9 @@ static KSTATUS KiVadPinUserPage(PROCESS* process, uintptr_t address, out->PageFlags = pageFlags; if (!out->KernelAddress) { MmUnpinUserPage(out); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } __declspec(dllexport) KSTATUS MmPinUserPageForRead(PROCESS* process, const void* userAddress, MM_PINNED_USER_PAGE* out) { @@ -1728,22 +1728,22 @@ static MM_VAD** KiLockedUserBufferVads(MM_LOCKED_USER_BUFFER* buffer) { static KSTATUS KiVadAddUserBufferPageLock(PROCESS* process, uintptr_t pageBase, MM_VAD** vadOut) { if (vadOut) *vadOut = (MM_VAD*)0; if (!process || !vadOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t procFlags = KeAcquireSpinlock(&process->VadLock); MM_VAD* vad = KiFindReservedVadContainingLocked(process, pageBase, PAGE_SIZE); if (!vad) { KeReleaseSpinlock(&process->VadLock, procFlags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } if (vad->LockCount == UINT32_MAX) { KeReleaseSpinlock(&process->VadLock, procFlags); - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; } vad->LockCount++; *vadOut = vad; KeReleaseSpinlock(&process->VadLock, procFlags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Removes one outstanding user-buffer lock from a VAD. @@ -1764,36 +1764,36 @@ __declspec(dllexport) KSTATUS MmLockUserBuffer(PROCESS* process, int writeAccess, MM_LOCKED_USER_BUFFER** out) { if (!out) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *out = (MM_LOCKED_USER_BUFFER*)0; if (size == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (!process || !userAddress) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t start = (uintptr_t)userAddress; if (!KiUserRangeValid(start, size)) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; uintptr_t alignedStart = start & PAGE_MASK; uintptr_t alignedEnd = (start + size + PAGE_SIZE - 1) & PAGE_MASK; if (alignedEnd <= alignedStart) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; size_t pageCount = KiVadRangePageCount(alignedStart, alignedEnd); if (!pageCount) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (pageCount > (((size_t)-1) - sizeof(MM_LOCKED_USER_BUFFER)) / (sizeof(MM_PINNED_USER_PAGE) + sizeof(MM_VAD*))) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; size_t allocSize = sizeof(MM_LOCKED_USER_BUFFER) + (pageCount - 1) * sizeof(MM_PINNED_USER_PAGE) + pageCount * sizeof(MM_VAD*); MM_LOCKED_USER_BUFFER* buffer = (MM_LOCKED_USER_BUFFER*)MmAllocatePoolTag(allocSize, MM_POOL_TAG('u', 'l', 'o', 'k')); if (!buffer) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; memset(buffer, 0, allocSize); buffer->Process = process; @@ -1804,7 +1804,7 @@ __declspec(dllexport) KSTATUS MmLockUserBuffer(PROCESS* process, ObReferenceObject(&process->Header); MM_VAD** vads = KiLockedUserBufferVads(buffer); - KSTATUS s = STATUS_SUCCESS; + KSTATUS s = NTLSTATUS_SUCCESS; size_t lockedPages = 0; for (size_t i = 0; i < pageCount; ++i) { uintptr_t pageBase = alignedStart + i * PAGE_SIZE; @@ -1834,7 +1834,7 @@ __declspec(dllexport) KSTATUS MmLockUserBuffer(PROCESS* process, } *out = buffer; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Unlocks a user buffer locked for asynchronous kernel access. @@ -1860,17 +1860,17 @@ __declspec(dllexport) void MmUnlockUserBuffer(MM_LOCKED_USER_BUFFER* buffer) { // the PTE while the kernel is executing the memcpy. static KSTATUS KiCopyUserPaged(void* dst, const void* src, size_t size, int toUser) { if (size == 0) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; if (!dst || !src) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t user = toUser ? (uintptr_t)dst : (uintptr_t)src; if (!KiUserRangeValid(user, size)) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; PROCESS* process = KeGetCurrentProcess(); if (!process) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; uint8_t* d = (uint8_t*)dst; const uint8_t* s = (const uint8_t*)src; @@ -1901,7 +1901,7 @@ static KSTATUS KiCopyUserPaged(void* dst, const void* src, size_t size, int toUs done += chunk; } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Copies from user memory after pinning each source page for the duration of the copy. @@ -1919,33 +1919,33 @@ KSTATUS MmVadReserve(PROCESS* process, size_t size, size_t alignment, uint64_t pageFlags, uint32_t vadFlags, MM_VAD_TYPE type, void** outBase) { KeAssertIrql(PASSIVE_LEVEL); - if (!process || !outBase || !size) return STATUS_INVALID_PARAMETER; + if (!process || !outBase || !size) return NTLSTATUS_INVALID_PARAMETER; *outBase = (void*)0; size_t payloadSize = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); - if (payloadSize < size) return STATUS_NO_MEMORY; + if (payloadSize < size) return NTLSTATUS_NO_MEMORY; size_t guardLow = (vadFlags & MM_VAD_GUARD_LOW) ? PAGE_SIZE : 0; size_t guardHigh = (vadFlags & MM_VAD_GUARD_HIGH) ? PAGE_SIZE : 0; size_t reservationSize = guardLow + payloadSize + guardHigh; - if (reservationSize < payloadSize) return STATUS_NO_MEMORY; + if (reservationSize < payloadSize) return NTLSTATUS_NO_MEMORY; if (alignment < PAGE_SIZE) alignment = PAGE_SIZE; - if (alignment & (alignment - 1)) return STATUS_INVALID_PARAMETER; + if (alignment & (alignment - 1)) return NTLSTATUS_INVALID_PARAMETER; size_t pageCount = payloadSize / PAGE_SIZE; - if (!pageCount) return STATUS_INVALID_PARAMETER; + if (!pageCount) return NTLSTATUS_INVALID_PARAMETER; if (pageFlags && !(pageFlags & PAGE_USER)) pageFlags |= PAGE_USER; MM_VAD* vad = (MM_VAD*)MmAllocatePoolTag(sizeof(MM_VAD), MM_POOL_TAG('v', 'a', 'd', ' ')); - if (!vad) return STATUS_NO_MEMORY; + if (!vad) return NTLSTATUS_NO_MEMORY; memset(vad, 0, sizeof(*vad)); MM_VAD_PAGE* pages = (MM_VAD_PAGE*)MmAllocatePoolTag(pageCount * sizeof(MM_VAD_PAGE), MM_POOL_TAG('v', 'p', 'g', 's')); if (!pages) { MmFreePool(vad); - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; } memset(pages, 0, pageCount * sizeof(MM_VAD_PAGE)); @@ -1983,21 +1983,21 @@ KSTATUS MmVadReserve(PROCESS* process, size_t size, size_t alignment, KeReleaseSpinlock(&process->VadLock, procFlags); *outBase = (void*)vad->Base; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Commits pages in an existing VAD without allocating PFNs until access. KSTATUS MmVadCommit(PROCESS* process, void* base, size_t size, uint64_t pageFlags, uint32_t commitFlags) { KeAssertIrql(PASSIVE_LEVEL); - if (!process || !base || !size) return STATUS_INVALID_PARAMETER; + if (!process || !base || !size) return NTLSTATUS_INVALID_PARAMETER; uintptr_t start = (uintptr_t)base; - if (start > (uintptr_t)-1 - (size - 1)) return STATUS_NO_MEMORY; + if (start > (uintptr_t)-1 - (size - 1)) return NTLSTATUS_NO_MEMORY; uintptr_t alignedStart = start & PAGE_MASK; uintptr_t alignedEnd = (start + size + PAGE_SIZE - 1) & PAGE_MASK; - if (alignedEnd <= alignedStart) return STATUS_NO_MEMORY; + if (alignedEnd <= alignedStart) return NTLSTATUS_NO_MEMORY; uintptr_t procFlags = KeAcquireSpinlock(&process->VadLock); MM_VAD* vad = KiFindReservedVadContainingLocked(process, alignedStart, alignedEnd - alignedStart); @@ -2008,7 +2008,7 @@ KSTATUS MmVadCommit(PROCESS* process, void* base, size_t size, process->ProcessId, (unsigned long long)alignedStart, (unsigned long long)alignedEnd); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } uint64_t flags = pageFlags ? pageFlags : vad->PageFlags; @@ -2017,13 +2017,13 @@ KSTATUS MmVadCommit(PROCESS* process, void* base, size_t size, size_t first = KiVadPageIndex(vad, alignedStart); size_t count = KiVadRangePageCount(alignedStart, alignedEnd); if (first > vad->PageCount || count > vad->PageCount - first) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; uint8_t* newlyCommitted = (uint8_t*)MmAllocatePool(count ? count : 1); - if (!newlyCommitted) return STATUS_NO_MEMORY; + if (!newlyCommitted) return NTLSTATUS_NO_MEMORY; memset(newlyCommitted, 0, count ? count : 1); - KSTATUS s = STATUS_SUCCESS; + KSTATUS s = NTLSTATUS_SUCCESS; for (size_t i = 0; i < count; ++i) { size_t pageIndex = first + i; MM_VAD_PAGE* page = &vad->Pages[pageIndex]; @@ -2061,7 +2061,7 @@ KSTATUS MmVadCommit(PROCESS* process, void* base, size_t size, KSTATUS MmVadCreateCommitted(PROCESS* process, size_t size, size_t alignment, uint64_t pageFlags, uint32_t vadFlags, MM_VAD_TYPE type, void** outBase) { - if (!outBase) return STATUS_INVALID_PARAMETER; + if (!outBase) return NTLSTATUS_INVALID_PARAMETER; *outBase = (void*)0; void* base = (void*)0; @@ -2075,7 +2075,7 @@ KSTATUS MmVadCreateCommitted(PROCESS* process, size_t size, size_t alignment, } *outBase = base; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Creates a demand-paged file-backed user mapping. The VAD owns a reference to @@ -2089,15 +2089,15 @@ KSTATUS MmVadCreateFileMapping(PROCESS* process, FILE_OBJECT* file, void** outBase) { KeAssertIrql(PASSIVE_LEVEL); if (!process || !file || !size || !outBase) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *outBase = (void*)0; if (fileOffset & (PAGE_SIZE - 1)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; size_t alignedSize = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); if (!alignedSize || alignedSize < size) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; if (pageFlags && !(pageFlags & PAGE_USER)) pageFlags |= PAGE_USER; @@ -2114,7 +2114,7 @@ KSTATUS MmVadCreateFileMapping(PROCESS* process, FILE_OBJECT* file, KeReleaseSpinlock(&process->VadLock, procFlags); if (!vad) { (void)MmVadDestroy(process, base); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } ObReferenceObject(&file->Header); @@ -2137,7 +2137,7 @@ KSTATUS MmVadCreateFileMapping(PROCESS* process, FILE_OBJECT* file, } *outBase = base; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Creates an image-backed VAD whose pages fault from a shared image section object. @@ -2146,12 +2146,12 @@ KSTATUS MmVadCreateImageSectionMapping(PROCESS* process, IMAGE_SECTION_OBJECT* s void** outBase) { KeAssertIrql(PASSIVE_LEVEL); if (!process || !section || !outBase) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *outBase = (void*)0; const IMAGE_SECTION_METADATA* metadata = LdrImageSectionMetadata(section); if (!metadata || !metadata->ImageSize || !metadata->PageCount) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; pageFlags |= PAGE_PRESENT | PAGE_USER; @@ -2166,7 +2166,7 @@ KSTATUS MmVadCreateImageSectionMapping(PROCESS* process, IMAGE_SECTION_OBJECT* s KeReleaseSpinlock(&process->VadLock, procFlags); if (!vad) { (void)MmVadDestroy(process, base); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } LdrReferenceImageSection(section); @@ -2184,13 +2184,13 @@ KSTATUS MmVadCreateImageSectionMapping(PROCESS* process, IMAGE_SECTION_OBJECT* s } *outBase = base; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Materializes committed VAD pages before the kernel or a recovered user fault touches them. KSTATUS MmVadEnsureResident(PROCESS* process, void* base, size_t size, uint64_t accessFlags) { if (!process || !base || !size) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; return KiVadEnsureResidentRange(process, (uintptr_t)base, size, accessFlags | PAGE_USER); } @@ -2199,15 +2199,15 @@ KSTATUS MmVadCreateCowView(PROCESS* sourceProcess, void* sourceBase, size_t size PROCESS* targetProcess, void** outBase) { KeAssertIrql(PASSIVE_LEVEL); if (!sourceProcess || !sourceBase || !targetProcess || !outBase || !size) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *outBase = (void*)0; uintptr_t start = (uintptr_t)sourceBase; if (start & (PAGE_SIZE - 1)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; size_t alignedSize = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); if (!alignedSize || alignedSize < size) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; KSTATUS s = KiVadEnsureResidentRange(sourceProcess, start, alignedSize, PAGE_USER); if (!KSUCCESS(s)) @@ -2217,7 +2217,7 @@ KSTATUS MmVadCreateCowView(PROCESS* sourceProcess, void* sourceBase, size_t size MM_VAD* sourceVad = KiFindReservedVadContainingLocked(sourceProcess, start, alignedSize); KeReleaseSpinlock(&sourceProcess->VadLock, srcFlags); if (!sourceVad || !KiVadRangeCommitted(sourceVad, start, start + alignedSize)) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; void* targetBase = (void*)0; s = MmVadReserve(targetProcess, alignedSize, PAGE_SIZE, sourceVad->PageFlags, sourceVad->Flags, sourceVad->Type, &targetBase); @@ -2229,7 +2229,7 @@ KSTATUS MmVadCreateCowView(PROCESS* sourceProcess, void* sourceBase, size_t size KeReleaseSpinlock(&targetProcess->VadLock, dstFlags); if (!targetVad) { (void)MmVadDestroy(targetProcess, targetBase); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } uintptr_t dst = (uintptr_t)targetBase; @@ -2239,7 +2239,7 @@ KSTATUS MmVadCreateCowView(PROCESS* sourceProcess, void* sourceBase, size_t size for (size_t i = 0; i < count; ++i) { MM_VAD_PAGE* srcPage = &sourceVad->Pages[first + i]; if (srcPage->State != MmVadPageCommitted || !srcPage->Resident || !srcPage->Frame) { - s = STATUS_NOT_FOUND; + s = NTLSTATUS_NOT_FOUND; break; } @@ -2276,7 +2276,7 @@ KSTATUS MmVadCreateCowView(PROCESS* sourceProcess, void* sourceBase, size_t size gVadStats.CowViewsCreated++; *outBase = targetBase; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Creates a COW view from loader-owned template frames. @@ -2290,12 +2290,12 @@ KSTATUS MmVadCreateCowViewFromFrames(PROCESS* targetProcess, void** outBase) { KeAssertIrql(PASSIVE_LEVEL); if (!targetProcess || !frames || !pageCount || !payloadSize || !outBase) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *outBase = (void*)0; size_t alignedSize = (payloadSize + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); if (!alignedSize || alignedSize / PAGE_SIZE > pageCount) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; void* targetBase = (void*)0; KSTATUS s = MmVadReserve(targetProcess, alignedSize, PAGE_SIZE, pageFlags, vadFlags, type, &targetBase); @@ -2307,7 +2307,7 @@ KSTATUS MmVadCreateCowViewFromFrames(PROCESS* targetProcess, KeReleaseSpinlock(&targetProcess->VadLock, dstFlags); if (!targetVad) { (void)MmVadDestroy(targetProcess, targetBase); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } uintptr_t dst = (uintptr_t)targetBase; @@ -2345,7 +2345,7 @@ KSTATUS MmVadCreateCowViewFromFrames(PROCESS* targetProcess, gVadStats.CowViewsCreated++; *outBase = targetBase; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KSTATUS MmVadCreateSharedViewFromFrames(PROCESS* targetProcess, @@ -2358,12 +2358,12 @@ KSTATUS MmVadCreateSharedViewFromFrames(PROCESS* targetProcess, void** outBase) { KeAssertIrql(PASSIVE_LEVEL); if (!targetProcess || !frames || !pageCount || !payloadSize || !outBase) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *outBase = (void*)0; size_t alignedSize = (payloadSize + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); if (!alignedSize || alignedSize / PAGE_SIZE > pageCount) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; pageFlags |= PAGE_PRESENT | PAGE_USER; @@ -2378,14 +2378,14 @@ KSTATUS MmVadCreateSharedViewFromFrames(PROCESS* targetProcess, KeReleaseSpinlock(&targetProcess->VadLock, dstFlags); if (!targetVad) { (void)MmVadDestroy(targetProcess, targetBase); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } uintptr_t dst = (uintptr_t)targetBase; size_t count = alignedSize / PAGE_SIZE; for (size_t i = 0; i < count; ++i) { if (!frames[i]) { - s = STATUS_INVALID_PARAMETER; + s = NTLSTATUS_INVALID_PARAMETER; break; } @@ -2427,7 +2427,7 @@ KSTATUS MmVadCreateSharedViewFromFrames(PROCESS* targetProcess, gVadStats.CowViewsCreated++; *outBase = targetBase; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns whether a resident file-backed page can be discarded instead of @@ -2509,16 +2509,16 @@ static int KiVadPageCanSwapAfterPagingClaim(const MM_VAD_PAGE* page) { static KSTATUS KiVadDiscardCleanFilePage(MM_VAD* vad, size_t pageIndex, void** baseOut) { if (baseOut) *baseOut = (void*)0; if (!vad || pageIndex >= vad->PageCount) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; MM_VAD_PAGE* page = &vad->Pages[pageIndex]; if (!KiVadPageCanDiscardCleanFile(vad, page)) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; PHYSICAL_ADDRESS frame = page->Frame; MM_PFN* pfn = MmPfnGet(frame); if (!pfn || pfn->PinCount) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; uintptr_t va = vad->Base + pageIndex * PAGE_SIZE; @@ -2528,14 +2528,14 @@ static KSTATUS KiVadDiscardCleanFilePage(MM_VAD* vad, size_t pageIndex, void** b // the hardware accessed bit and skip the page once; if it stays cold until // a later pressure scan, it may be discarded then. if (MmPteTestAndClearAccessed(va)) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; if (!KiVadTryBeginPaging(page)) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; if (!KiVadPageCanDiscardCleanFileAfterPagingClaim(vad, page) || page->Frame != frame) { KiVadEndPaging(page); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } KSTATUS s = MmPfnPin(frame); @@ -2567,34 +2567,34 @@ static KSTATUS KiVadDiscardCleanFilePage(MM_VAD* vad, size_t pageIndex, void** b gVadStats.FileBackedDiscards++; if (baseOut) *baseOut = (void*)va; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Moves one private resident VAD page to the swap backend. static KSTATUS KiVadTrimPageToSwap(MM_VAD* vad, size_t pageIndex, void** baseOut) { if (baseOut) *baseOut = (void*)0; if (!vad || pageIndex >= vad->PageCount) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; MM_VAD_PAGE* page = &vad->Pages[pageIndex]; if (!KiVadPageCanSwap(page)) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; PHYSICAL_ADDRESS frame = page->Frame; MM_PFN* pfn = MmPfnGet(frame); if (!pfn || pfn->RefCount != 1 || pfn->PinCount) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; // Claim the transient paging bit atomically before pinning/removing the // user PTE. This serializes page-out against another page-out and against // a concurrent fault on the same VAD page without holding a spinlock across // pagefile I/O. if (!KiVadTryBeginPaging(page)) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; if (!KiVadPageCanSwapAfterPagingClaim(page) || page->Frame != frame) { KiVadEndPaging(page); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } KSTATUS s = MmPfnPin(frame); @@ -2633,29 +2633,29 @@ static KSTATUS KiVadTrimPageToSwap(MM_VAD* vad, size_t pageIndex, void** baseOut gVadStats.SwapPageOuts++; if (baseOut) *baseOut = (void*)va; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Finds one private resident page in a process and swaps it out. static KSTATUS KiVadTrimOnePageInProcess(PROCESS* process, void** baseOut) { if (baseOut) *baseOut = (void*)0; - if (!process) return STATUS_INVALID_PARAMETER; + if (!process) return NTLSTATUS_INVALID_PARAMETER; for (LIST_ENTRY* node = process->VadList.Fwd; node != &process->VadList; node = node->Fwd) { MM_VAD* vad = CONTAINING_RECORD(node, MM_VAD, ProcessLink); for (size_t i = 0; i < vad->PageCount; ++i) { KSTATUS s = KiVadTrimPageToSwap(vad, i, baseOut); if (KSUCCESS(s)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } // Moves one private resident user page to the swap backend for self-tests. KSTATUS MmVadTrimOnePageForTest(PROCESS* process, void** baseOut) { KeAssertIrql(PASSIVE_LEVEL); - if (!MmSwapIsEnabled()) return STATUS_NOT_SUPPORTED; + if (!MmSwapIsEnabled()) return NTLSTATUS_NOT_SUPPORTED; return KiVadTrimOnePageInProcess(process, baseOut); } @@ -2664,37 +2664,37 @@ KSTATUS MmVadTrimOnePageForTest(PROCESS* process, void** baseOut) { // consuming swap. Fall back to anonymous/private swap only when no such page is // available. KSTATUS MmVadTrimOnePageForPressure(void) { - if (!gVadListReady) return STATUS_NOT_SUPPORTED; + if (!gVadListReady) return NTLSTATUS_NOT_SUPPORTED; KSTATUS cacheDrop = MmFileCacheDropOnePageForPressure(); if (KSUCCESS(cacheDrop)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; for (LIST_ENTRY* node = gVadList.Fwd; node != &gVadList; node = node->Fwd) { MM_VAD* vad = CONTAINING_RECORD(node, MM_VAD, GlobalLink); for (size_t i = 0; i < vad->PageCount; ++i) { KSTATUS s = KiVadDiscardCleanFilePage(vad, i, (void**)0); if (KSUCCESS(s)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - if (!MmSwapIsEnabled()) return STATUS_NOT_SUPPORTED; + if (!MmSwapIsEnabled()) return NTLSTATUS_NOT_SUPPORTED; for (LIST_ENTRY* node = gVadList.Fwd; node != &gVadList; node = node->Fwd) { MM_VAD* vad = CONTAINING_RECORD(node, MM_VAD, GlobalLink); for (size_t i = 0; i < vad->PageCount; ++i) { KSTATUS s = KiVadTrimPageToSwap(vad, i, (void**)0); if (KSUCCESS(s)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } KSTATUS MmVadSyncFileMappings(FILE_OBJECT* file) { if (!file) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&gVadLock); for (LIST_ENTRY* node = gVadList.Fwd; node != &gVadList; node = node->Fwd) { @@ -2721,7 +2721,7 @@ KSTATUS MmVadSyncFileMappings(FILE_OBJECT* file) { } } KeReleaseSpinlock(&gVadLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Resolves a user-mode page fault against committed VAD metadata. @@ -2730,11 +2730,11 @@ KSTATUS MmVadResolveUserPageFault(PROCESS* process, uintptr_t faultAddress, uint gVadStats.ResolveFaultCalls++; if (!process) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; if (!KiUserRangeValid(faultAddress, 1)) { gVadStats.NoVadFaults++; gVadStats.FailedFaults++; - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; } uintptr_t va = faultAddress & PAGE_MASK; @@ -2744,19 +2744,19 @@ KSTATUS MmVadResolveUserPageFault(PROCESS* process, uintptr_t faultAddress, uint if (!vad) { gVadStats.NoVadFaults++; gVadStats.FailedFaults++; - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } size_t index = KiVadPageIndex(vad, va); if (index >= vad->PageCount || vad->Pages[index].State != MmVadPageCommitted) { gVadStats.UncommittedFaults++; gVadStats.FailedFaults++; - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } if (!vad->Pages[index].PageFlags) { gVadStats.NoAccessFaults++; gVadStats.FailedFaults++; - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; } int presentFault = (errorCode & 0x1) ? 1 : 0; @@ -2773,7 +2773,7 @@ KSTATUS MmVadResolveUserPageFault(PROCESS* process, uintptr_t faultAddress, uint if (KSUCCESS(ps)) { gVadStats.FileBackedDirtyFaults++; gVadStats.ResolvedFaults++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } dirty = ps; } @@ -2786,12 +2786,12 @@ KSTATUS MmVadResolveUserPageFault(PROCESS* process, uintptr_t faultAddress, uint if (KSUCCESS(cow)) { gVadStats.CowFaults++; gVadStats.ResolvedFaults++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } gVadStats.ProtectionFaults++; gVadStats.FailedFaults++; - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; } KSTATUS s = KiVadEnsurePageResident(vad, index, wantWrite, wantExecute); @@ -2801,7 +2801,7 @@ KSTATUS MmVadResolveUserPageFault(PROCESS* process, uintptr_t faultAddress, uint } gVadStats.ResolvedFaults++; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Resolves a page fault by looking up the owning VAD in the global user arena. @@ -2810,9 +2810,9 @@ KSTATUS MmVadResolveUserPageFault(PROCESS* process, uintptr_t faultAddress, uint // that owns the virtual address rather than from the currently running process. KSTATUS MmVadResolvePageFaultByAddress(uintptr_t faultAddress, uint64_t errorCode) { if (!KiUserRangeValid(faultAddress, 1)) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; if (!gVadListReady) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; uintptr_t va = faultAddress & PAGE_MASK; PROCESS* owner = (PROCESS*)0; @@ -2829,7 +2829,7 @@ KSTATUS MmVadResolvePageFaultByAddress(uintptr_t faultAddress, uint64_t errorCod KeReleaseSpinlock(&gVadLock, flags); if (!owner) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; return MmVadResolveUserPageFault(owner, faultAddress, errorCode); } @@ -2837,14 +2837,14 @@ KSTATUS MmVadResolvePageFaultByAddress(uintptr_t faultAddress, uint64_t errorCod // Changes page protections on a committed VAD range. KSTATUS MmVadProtect(PROCESS* process, void* base, size_t size, uint64_t pageFlags) { KeAssertIrql(PASSIVE_LEVEL); - if (!process || !base || !size) return STATUS_INVALID_PARAMETER; + if (!process || !base || !size) return NTLSTATUS_INVALID_PARAMETER; uintptr_t start = (uintptr_t)base; - if (start > (uintptr_t)-1 - (size - 1)) return STATUS_NO_MEMORY; + if (start > (uintptr_t)-1 - (size - 1)) return NTLSTATUS_NO_MEMORY; uintptr_t alignedStart = start & PAGE_MASK; uintptr_t alignedEnd = (start + size + PAGE_SIZE - 1) & PAGE_MASK; - if (alignedEnd <= alignedStart) return STATUS_NO_MEMORY; + if (alignedEnd <= alignedStart) return NTLSTATUS_NO_MEMORY; uintptr_t procFlags = KeAcquireSpinlock(&process->VadLock); MM_VAD* vad = KiFindReservedVadContainingLocked(process, alignedStart, alignedEnd - alignedStart); @@ -2855,10 +2855,10 @@ KSTATUS MmVadProtect(PROCESS* process, void* base, size_t size, uint64_t pageFla process->ProcessId, (unsigned long long)alignedStart, (unsigned long long)alignedEnd); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } if (vad->LockCount) - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; uint64_t finalFlags = pageFlags ? (pageFlags | PAGE_PRESENT | PAGE_USER) : 0; size_t first = KiVadPageIndex(vad, alignedStart); @@ -2892,23 +2892,23 @@ KSTATUS MmVadProtect(PROCESS* process, void* base, size_t size, uint64_t pageFla } } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Destroys a VAD and releases all resident payload pages. KSTATUS MmVadDestroy(PROCESS* process, void* base) { KeAssertIrql(PASSIVE_LEVEL); - if (!process || !base) return STATUS_INVALID_PARAMETER; + if (!process || !base) return NTLSTATUS_INVALID_PARAMETER; uintptr_t procFlags = KeAcquireSpinlock(&process->VadLock); MM_VAD* vad = KiFindVadByBaseLocked(process, base); if (!vad) { KeReleaseSpinlock(&process->VadLock, procFlags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } if (vad->LockCount) { KeReleaseSpinlock(&process->VadLock, procFlags); - return STATUS_ACCESS_DENIED; + return NTLSTATUS_ACCESS_DENIED; } ListRemove(&vad->ProcessLink); KeReleaseSpinlock(&process->VadLock, procFlags); @@ -2928,7 +2928,7 @@ KSTATUS MmVadDestroy(PROCESS* process, void* base) { } MmFreePool(vad->Pages); MmFreePool(vad); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Destroys every VAD owned by a process during teardown. @@ -2980,7 +2980,7 @@ void MmVadDestroyAllForProcess(PROCESS* process) { // Queries the committed VAD range containing an address. KSTATUS MmVadQuery(PROCESS* process, const void* address, void** baseOut, size_t* sizeOut, uint64_t* pageFlagsOut, MM_VAD_TYPE* typeOut, uint32_t* vadFlagsOut) { - if (!process || !address) return STATUS_INVALID_PARAMETER; + if (!process || !address) return NTLSTATUS_INVALID_PARAMETER; uintptr_t addr = (uintptr_t)address; uintptr_t procFlags = KeAcquireSpinlock(&process->VadLock); @@ -2992,7 +2992,7 @@ KSTATUS MmVadQuery(PROCESS* process, const void* address, void** baseOut, size_t size_t index = KiVadPageIndex(vad, addr & PAGE_MASK); if (index >= vad->PageCount || vad->Pages[index].State != MmVadPageCommitted) { KeReleaseSpinlock(&process->VadLock, procFlags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } uint64_t flags = vad->Pages[index].PageFlags; @@ -3016,10 +3016,10 @@ KSTATUS MmVadQuery(PROCESS* process, const void* address, void** baseOut, size_t if (typeOut) *typeOut = vad->Type; if (vadFlagsOut) *vadFlagsOut = vad->Flags; KeReleaseSpinlock(&process->VadLock, procFlags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } KeReleaseSpinlock(&process->VadLock, procFlags); - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } // Returns per-process VAD accounting for ps and memory telemetry. @@ -3143,7 +3143,7 @@ static void KiDebugDescribePoolAddress(uintptr_t addr) { (uintptr_t)cur < gPoolHeap.Brk; cur = KiNextBlock(cur)) { if (cur->Magic != BLOCK_MAGIC) { - DbgPrint("MM: pool walk corrupt at hdr=%p magic=%08x\n", cur, cur->Magic); + DbgPrint("MM: pool walk corrupt at hdr=0x%016llX magic=%08x\n", cur, cur->Magic); break; } uintptr_t hdr = (uintptr_t)cur; @@ -3153,7 +3153,7 @@ static void KiDebugDescribePoolAddress(uintptr_t addr) { BLOCK_FTR* footer = KiHdrToFtr(cur); if ((uintptr_t)footer + FTR_SIZE > gPoolHeap.Brk || footer->Magic != BLOCK_MAGIC || footer->Size != cur->Size || footer->Free != cur->Free) { - DbgPrint("MM: pool walk corrupt footer hdr=%p state=%u size=%llx footer=%p fmagic=%08x fstate=%u fsize=%llx\n", + DbgPrint("MM: pool walk corrupt footer hdr=0x%016llX state=%u size=%llx footer=0x%016llX fmagic=%08x fstate=%u fsize=%llx\n", cur, cur->Free, (unsigned long long)cur->Size, @@ -3164,7 +3164,7 @@ static void KiDebugDescribePoolAddress(uintptr_t addr) { break; } if (addr >= hdr && addr < ftr + FTR_SIZE) { - DbgPrint("MM: address %016llx in pool block hdr=%016llx data=%016llx-%016llx size=%llx req=%llx state=%u(%s) tag=%08x flags=%08x seq=%llu alloc=%p free=%p\n", + DbgPrint("MM: address %016llx in pool block hdr=%016llx data=%016llx-%016llx size=%llx req=%llx state=%u(%s) tag=%08x flags=%08x seq=%llu alloc=0x%016llX free=0x%016llX\n", (unsigned long long)addr, (unsigned long long)hdr, (unsigned long long)data, @@ -3181,7 +3181,7 @@ static void KiDebugDescribePoolAddress(uintptr_t addr) { break; } if (KiNextBlock(cur) <= cur) { - DbgPrint("MM: pool walk stopped: non-advancing block hdr=%p size=%llx\n", cur, (unsigned long long)cur->Size); + DbgPrint("MM: pool walk stopped: non-advancing block hdr=0x%016llX size=%llx\n", cur, (unsigned long long)cur->Size); break; } } diff --git a/code/kernel/net_device.c b/code/kernel/net_device.c index 0a913d1..5d8ca0a 100644 --- a/code/kernel/net_device.c +++ b/code/kernel/net_device.c @@ -56,18 +56,18 @@ static void NetLogHardwareAddress(const NET_DEVICE* device) { // Implements the net Register Device operation. __declspec(dllexport) KSTATUS NetRegisterDevice(NET_DEVICE* device) { if (!device || !device->SendFrame) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (device->HardwareAddressLength > NET_HWADDR_MAX) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; uintptr_t flags = KeAcquireSpinlock(&gNetLock); if (NetIsDeviceRegisteredLocked(device)) { KeReleaseSpinlock(&gNetLock, flags); - return STATUS_ALREADY_EXISTS; + return NTLSTATUS_ALREADY_EXISTS; } if (gNetDeviceCount >= NET_MAX_DEVICES) { KeReleaseSpinlock(&gNetLock, flags); - return STATUS_QUEUE_FULL; + return NTLSTATUS_QUEUE_FULL; } uint32_t index = gNetDeviceCount; @@ -93,7 +93,7 @@ __declspec(dllexport) KSTATUS NetRegisterDevice(NET_DEVICE* device) { } } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the net Get Device Count operation. @@ -115,16 +115,16 @@ __declspec(dllexport) NET_DEVICE* NetGetDevice(uint32_t index) { __declspec(dllexport) KSTATUS NetGetDeviceStats(uint32_t index, NET_DEVICE_STATS* stats) { if (!stats) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; NET_DEVICE* device = NetGetDevice(index); if (!device) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; uintptr_t flags = KeAcquireSpinlock(&gNetLock); memcpy(stats, &device->Stats, sizeof(*stats)); KeReleaseSpinlock(&gNetLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } __declspec(dllexport) KSTATUS NetSendFrame(uint32_t index, @@ -132,11 +132,11 @@ __declspec(dllexport) KSTATUS NetSendFrame(uint32_t index, size_t length) { NET_DEVICE* device = NetGetDevice(index); if (!device || !device->SendFrame) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; if (!frame || length < NET_ETHERNET_HEADER_LENGTH) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (length > (size_t)device->Mtu + NET_ETHERNET_HEADER_LENGTH) - return STATUS_BUFFER_TOO_SMALL; + return NTLSTATUS_BUFFER_TOO_SMALL; KSTATUS st = device->SendFrame(device, frame, length); uintptr_t flags = KeAcquireSpinlock(&gNetLock); @@ -168,7 +168,7 @@ __declspec(dllexport) void NetReceiveFrame(NET_DEVICE* device, KeReleaseSpinlock(&gNetLock, flags); const NET_STACK_PROVIDER* provider = NetGetStackProvider(); - KSTATUS rxStatus = STATUS_NOT_SUPPORTED; + KSTATUS rxStatus = NTLSTATUS_NOT_SUPPORTED; if (provider && provider->ReceiveFrame) rxStatus = provider->ReceiveFrame(device, frame, length); diff --git a/code/kernel/net_socket.c b/code/kernel/net_socket.c index 6e3f958..307a23e 100644 --- a/code/kernel/net_socket.c +++ b/code/kernel/net_socket.c @@ -51,11 +51,11 @@ static void NetIrpStatsComplete(KSTATUS status, bool asynchronous) { else gNetIrpStats.CompletedSynchronously++; - if (status == STATUS_CANCELLED) + if (status == NTLSTATUS_CANCELLED) gNetIrpStats.Cancelled++; - else if (status == STATUS_WOULD_BLOCK) + else if (status == NTLSTATUS_WOULD_BLOCK) gNetIrpStats.WouldBlock++; - else if (status == STATUS_TIMEOUT) + else if (status == NTLSTATUS_TIMEOUT) gNetIrpStats.Timeout++; else if (KFAILED(status)) gNetIrpStats.Failed++; @@ -193,7 +193,7 @@ static void NetAsyncSocketRequestCleanup(IO_ASYNC_REQUEST_OBJECT* async, void* c static KSTATUS NetCancelAsyncSocketRequest(IO_ASYNC_REQUEST_OBJECT* async, void* context) { (void)context; if (!async) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; NetIrpStatsCancelRequested(); @@ -206,19 +206,19 @@ static KSTATUS NetCancelAsyncSocketRequest(IO_ASYNC_REQUEST_OBJECT* async, void* IoAsyncRequestSetState(async, IoAsyncRequestCancelled); KeReleaseSpinlock(&gAsyncSocketQueueLock, flags); - IoCompleteAsyncRequest(async, STATUS_CANCELLED, 0); + IoCompleteAsyncRequest(async, NTLSTATUS_CANCELLED, 0); ObDereferenceObject(&async->Header); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (state == IoAsyncRequestRunning) { IoAsyncRequestRequestCancel(async); KeReleaseSpinlock(&gAsyncSocketQueueLock, flags); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } KeReleaseSpinlock(&gAsyncSocketQueueLock, flags); - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; } // Removes one queued async socket request for the worker. @@ -256,7 +256,7 @@ static size_t NetAsyncSocketPublishAddress(NET_ASYNC_SOCKET_REQUEST_OBJECT* req, static void NetAsyncSocketExecute(NET_ASYNC_SOCKET_REQUEST_OBJECT* req, KSTATUS* statusOut, size_t* informationOut) { - KSTATUS status = STATUS_INVALID_PARAMETER; + KSTATUS status = NTLSTATUS_INVALID_PARAMETER; size_t information = 0; if (!req || !statusOut || !informationOut) @@ -351,7 +351,7 @@ static void NetAsyncSocketExecute(NET_ASYNC_SOCKET_REQUEST_OBJECT* req, status = NetSocketGetOption(req->Socket, req->Option, req->OptionValue, req->OptionValueSize, &actual); if (KSUCCESS(status) && actual && req->UserOptionValue) memcpy(req->UserOptionValue, req->OptionValue, actual); - if ((KSUCCESS(status) || status == STATUS_BUFFER_TOO_SMALL) && req->OptionActualSizeOut) + if ((KSUCCESS(status) || status == NTLSTATUS_BUFFER_TOO_SMALL) && req->OptionActualSizeOut) *req->OptionActualSizeOut = actual; information = actual; break; @@ -367,7 +367,7 @@ static void NetAsyncSocketExecute(NET_ASYNC_SOCKET_REQUEST_OBJECT* req, } default: - status = STATUS_INVALID_PARAMETER; + status = NTLSTATUS_INVALID_PARAMETER; break; } @@ -390,7 +390,7 @@ static void NetAsyncSocketWorker(void* arg) { if (!req) continue; - KSTATUS status = STATUS_CANCELLED; + KSTATUS status = NTLSTATUS_CANCELLED; size_t information = 0; if (!IoAsyncRequestIsCancelRequested(&req->Async) && IoAsyncRequestGetState(&req->Async) != IoAsyncRequestCancelled) { @@ -409,13 +409,13 @@ static KSTATUS NetEnsureAsyncSocketWorkerStarted(void) { uintptr_t flags = KeAcquireSpinlock(&gAsyncSocketInitLock); if (gAsyncSocketInitState == 2) { KeReleaseSpinlock(&gAsyncSocketInitLock, flags); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } if (gAsyncSocketInitState == 1) { KeReleaseSpinlock(&gAsyncSocketInitLock, flags); while (gAsyncSocketInitState == 1) KeYield(); - return (gAsyncSocketInitState == 2) ? STATUS_SUCCESS : STATUS_FAILURE; + return (gAsyncSocketInitState == 2) ? NTLSTATUS_SUCCESS : NTLSTATUS_FAILURE; } gAsyncSocketInitState = 1; @@ -445,7 +445,7 @@ KSTATUS NetSocketSubmitAsyncKernel(const NET_ASYNC_SOCKET_SUBMIT* submit, if (requestOut) *requestOut = (NET_ASYNC_SOCKET_REQUEST_OBJECT*)0; if (!submit || !submit->OwnerProcess || !submit->Socket || !submit->Iosb) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; KSTATUS status = NetEnsureAsyncSocketWorkerStarted(); if (!KSUCCESS(status)) @@ -509,7 +509,7 @@ KSTATUS NetSocketSubmitAsyncKernel(const NET_ASYNC_SOCKET_SUBMIT* submit, *requestOut = req; else ObDereferenceObject(&req->Async.Header); - return STATUS_PENDING; + return NTLSTATUS_PENDING; } // Returns the object header embedded in a socket async request. @@ -522,12 +522,12 @@ static KSTATUS NetSubmitSocketIrp(const NET_STACK_PROVIDER* provider, NET_SOCKET_IRP_REQUEST* request, IO_ASYNC_REQUEST_OBJECT* async) { if (!provider || !provider->StackDevice || !request) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (request->Size != sizeof(*request)) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (request->Operation == NetSocketIrpInvalid || request->Operation >= NetSocketIrpOperationCount) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; request->CancelRequested = async ? &async->CancelRequested : (volatile uint8_t*)0; @@ -551,7 +551,7 @@ static KSTATUS NetSubmitSocketIrp(const NET_STACK_PROVIDER* provider, st = IoSubmitIrp(provider->StackDevice, &irp); bool asynchronous = false; - if (st == STATUS_PENDING) { + if (st == NTLSTATUS_PENDING) { asynchronous = true; NetIrpStatsPending(); (void)KeWaitForEvent(event, 0); @@ -594,11 +594,11 @@ static KSTATUS NetSocketAllocate(const NET_STACK_PROVIDER* provider, uint32_t protocol, SOCKET_OBJECT** out) { if (!provider || !providerSocket || !out) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; SOCKET_OBJECT* socket = (SOCKET_OBJECT*)ObAllocateObject(ObjectTypeSocket, sizeof(SOCKET_OBJECT)); if (!socket) - return STATUS_NO_MEMORY; + return NTLSTATUS_NO_MEMORY; socket->Header.Destroy = NetSocketDestroy; socket->Provider = provider; @@ -607,7 +607,7 @@ static KSTATUS NetSocketAllocate(const NET_STACK_PROVIDER* provider, socket->Type = type; socket->Protocol = protocol; *out = socket; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Returns the provider and provider-private state behind a live socket object. @@ -615,24 +615,24 @@ static KSTATUS NetSocketGetProviderSocket(SOCKET_OBJECT* socket, const NET_STACK_PROVIDER** providerOut, void** providerSocketOut) { if (!socket || !providerOut || !providerSocketOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!socket->Provider || !socket->ProviderSocket) - return STATUS_OBJECT_DEAD; + return NTLSTATUS_OBJECT_DEAD; *providerOut = socket->Provider; *providerSocketOut = socket->ProviderSocket; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Creates a socket by submitting a create request to the active stack device. KSTATUS NetSocketCreate(uint32_t domain, uint32_t type, uint32_t protocol, SOCKET_OBJECT** out) { if (!out) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *out = NULL; const NET_STACK_PROVIDER* provider = NetGetStackProvider(); if (!provider) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; void* providerSocket = NULL; NET_SOCKET_IRP_REQUEST request; @@ -648,7 +648,7 @@ KSTATUS NetSocketCreate(uint32_t domain, uint32_t type, uint32_t protocol, SOCKE if (!KSUCCESS(st)) return st; if (!providerSocket) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; st = NetSocketAllocate(provider, providerSocket, domain, type, protocol, out); if (!KSUCCESS(st)) @@ -696,7 +696,7 @@ KSTATUS NetSocketAccept(SOCKET_OBJECT* socket, SOCKET_OBJECT** acceptedOut, SYS_SOCKET_ADDRESS_K* remoteOut, IO_ASYNC_REQUEST_OBJECT* async) { if (!acceptedOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *acceptedOut = NULL; const NET_STACK_PROVIDER* provider = NULL; @@ -718,7 +718,7 @@ KSTATUS NetSocketAccept(SOCKET_OBJECT* socket, SOCKET_OBJECT** acceptedOut, if (!KSUCCESS(st)) return st; if (!acceptedProviderSocket) - return STATUS_FAILURE; + return NTLSTATUS_FAILURE; st = NetSocketAllocate(provider, acceptedProviderSocket, @@ -757,9 +757,9 @@ KSTATUS NetSocketSend(SOCKET_OBJECT* socket, const void* buffer, size_t length, if (sentOut) *sentOut = 0; if (!buffer && length) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (length > NET_SOCKET_IO_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; const NET_STACK_PROVIDER* provider = NULL; void* providerSocket = NULL; @@ -786,9 +786,9 @@ KSTATUS NetSocketReceive(SOCKET_OBJECT* socket, void* buffer, size_t length, if (receivedOut) *receivedOut = 0; if (!buffer && length) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (length > NET_SOCKET_IO_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; const NET_STACK_PROVIDER* provider = NULL; void* providerSocket = NULL; @@ -815,13 +815,13 @@ KSTATUS NetSocketSendTo(SOCKET_OBJECT* socket, const void* buffer, size_t length if (sentOut) *sentOut = 0; if (!buffer && length) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (socket && socket->Type == SYS_SOCK_DGRAM && length > NET_SOCKET_UDP_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (socket && socket->Type == SYS_SOCK_RAW && length > NET_SOCKET_RAW_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (socket && socket->Type != SYS_SOCK_DGRAM && socket->Type != SYS_SOCK_RAW) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; const NET_STACK_PROVIDER* provider = NULL; void* providerSocket = NULL; @@ -850,13 +850,13 @@ KSTATUS NetSocketReceiveFrom(SOCKET_OBJECT* socket, void* buffer, size_t length, if (receivedOut) *receivedOut = 0; if (!buffer && length) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (socket && socket->Type == SYS_SOCK_DGRAM && length > NET_SOCKET_UDP_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (socket && socket->Type == SYS_SOCK_RAW && length > NET_SOCKET_RAW_MAX_BYTES) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (socket && socket->Type != SYS_SOCK_DGRAM && socket->Type != SYS_SOCK_RAW) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; const NET_STACK_PROVIDER* provider = NULL; void* providerSocket = NULL; @@ -937,7 +937,7 @@ KSTATUS NetSocketGetOption(SOCKET_OBJECT* socket, uint32_t option, void* value, // Polls socket readiness through the stack device IRP path. KSTATUS NetSocketPoll(SOCKET_OBJECT* socket, uint32_t events, uint32_t* returnedEventsOut) { if (!returnedEventsOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; *returnedEventsOut = 0; const NET_STACK_PROVIDER* provider = NULL; @@ -959,11 +959,11 @@ KSTATUS NetSocketPoll(SOCKET_OBJECT* socket, uint32_t events, uint32_t* returned // Resolves a host name through the stack device IRP path. KSTATUS NetResolveHost(const char* name, uint32_t family, SYS_SOCKET_ADDRESS_K* addressOut) { if (!name || !addressOut) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; const NET_STACK_PROVIDER* provider = NetGetStackProvider(); if (!provider) - return STATUS_NOT_SUPPORTED; + return NTLSTATUS_NOT_SUPPORTED; NET_SOCKET_IRP_REQUEST request; memset(&request, 0, sizeof(request)); diff --git a/code/kernel/net_stack.c b/code/kernel/net_stack.c index 368b5ec..b8f18bf 100644 --- a/code/kernel/net_stack.c +++ b/code/kernel/net_stack.c @@ -14,16 +14,16 @@ static SPINLOCK gNetStackLock = SPINLOCK_INIT; // Implements the net Validate Stack Provider operation. static KSTATUS NetValidateStackProvider(const NET_STACK_PROVIDER* p) { if (!p || p->Version != NET_STACK_PROVIDER_VERSION || !p->Name) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!p->StackDevice || !p->AttachDevice || !p->ReceiveFrame) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; if (!p->StackDevice->DriverObject || !p->StackDevice->DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL]) - return STATUS_INVALID_PARAMETER; + return NTLSTATUS_INVALID_PARAMETER; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the net Register Stack Provider operation. @@ -35,7 +35,7 @@ __declspec(dllexport) KSTATUS NetRegisterStackProvider(const NET_STACK_PROVIDER* uintptr_t flags = KeAcquireSpinlock(&gNetStackLock); if (gNetStackProvider) { KeReleaseSpinlock(&gNetStackLock, flags); - return STATUS_ALREADY_EXISTS; + return NTLSTATUS_ALREADY_EXISTS; } gNetStackProvider = provider; KeReleaseSpinlock(&gNetStackLock, flags); @@ -56,7 +56,7 @@ __declspec(dllexport) KSTATUS NetRegisterStackProvider(const NET_STACK_PROVIDER* } } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the net Get Stack Provider operation. diff --git a/code/public/ntlite/ddi/net_abi.h b/code/public/ntlite/ddi/net_abi.h index 6cdbacb..f6332f1 100644 --- a/code/public/ntlite/ddi/net_abi.h +++ b/code/public/ntlite/ddi/net_abi.h @@ -35,7 +35,10 @@ #define SYS_POLL_INVALID 0x0010u #define SYS_POLL_TIMEOUT_INFINITE 0xFFFFFFFFu -// Kernel socket providers use the same tagged native address shape as syscalls. +// Kernel socket providers use the same fixed-size tagged native address shape as syscalls. +// Input requests use the syscall pointer-length parameter as the definitive +// buffer bound and require Size to equal SYS_SOCKET_ADDRESS_SIZE after copying. +// Address stores textual-order bytes; Port is host byte order. typedef struct SYS_SOCKET_ADDRESS_K { uint16_t Family; uint16_t Size; diff --git a/code/public/ntlite/exception.h b/code/public/ntlite/exception.h new file mode 100644 index 0000000..0c318b6 --- /dev/null +++ b/code/public/ntlite/exception.h @@ -0,0 +1,24 @@ +// Native user-mode exception runtime declarations shared by applications and personalities. + +#pragma once + +#include +#include + +#if defined(NTL_EXCEPTION_EXPORTS) +#define NTL_EXCEPTION_API __declspec(dllexport) +#else +#define NTL_EXCEPTION_API +#endif + +#define NTL_EXCEPTION_CONTINUE_EXECUTION ((int)SYS_EXCEPTION_DISPOSITION_CONTINUE_EXECUTION) +#define NTL_EXCEPTION_CONTINUE_SEARCH ((int)SYS_EXCEPTION_DISPOSITION_CONTINUE_SEARCH) +#define NTL_EXCEPTION_TERMINATE_PROCESS ((int)SYS_EXCEPTION_DISPOSITION_TERMINATE_PROCESS) + +typedef int (*NTL_EXCEPTION_HANDLER)(SYS_EXCEPTION_RECORD* record, + SYS_USER_CONTEXT* context, + void* userContext); + +NTL_EXCEPTION_API uint32_t NtlInitializeExceptionRuntime(void); +NTL_EXCEPTION_API void* NtlAddExceptionHandler(int first, NTL_EXCEPTION_HANDLER handler, void* context); +NTL_EXCEPTION_API uint32_t NtlRemoveExceptionHandler(void* handle); diff --git a/code/public/ntlite/status.h b/code/public/ntlite/status.h index 3d1a63d..fba063f 100644 --- a/code/public/ntlite/status.h +++ b/code/public/ntlite/status.h @@ -24,52 +24,52 @@ typedef uint32_t KSTATUS; #define KSTATUS_FACILITY(status) ((((KSTATUS)(status)) >> KSTATUS_FACILITY_SHIFT) & KSTATUS_FACILITY_MASK) #define KSTATUS_CODE(status) (((KSTATUS)(status)) & KSTATUS_CODE_MASK) -#define STATUS_FACILITY_WAIT 0x00u -#define STATUS_FACILITY_SYSTEM 0x01u -#define STATUS_FACILITY_PROCESS 0x61u +#define NTLSTATUS_FACILITY_WAIT 0x00u +#define NTLSTATUS_FACILITY_SYSTEM 0x01u +#define NTLSTATUS_FACILITY_PROCESS 0x61u -// Wait-completion statuses are non-error statuses. STATUS_SUCCESS is exactly +// Wait-completion statuses are non-error statuses. NTLSTATUS_SUCCESS is exactly // zero so old zero-initialisation and direct syscall success checks stay valid. -#define STATUS_SUCCESS ((KSTATUS)0x00000000u) -#define STATUS_TIMEOUT KSTATUS_MAKE_SUCCESS(STATUS_FACILITY_WAIT, 0x000001u) -#define STATUS_PENDING KSTATUS_MAKE_SUCCESS(STATUS_FACILITY_WAIT, 0x000002u) -#define STATUS_ALERTED KSTATUS_MAKE_SUCCESS(STATUS_FACILITY_WAIT, 0x000003u) -#define STATUS_KERNEL_APC KSTATUS_MAKE_SUCCESS(STATUS_FACILITY_WAIT, 0x000004u) -#define STATUS_USER_APC KSTATUS_MAKE_SUCCESS(STATUS_FACILITY_WAIT, 0x000005u) +#define NTLSTATUS_SUCCESS ((KSTATUS)0x00000000u) +#define NTLSTATUS_TIMEOUT KSTATUS_MAKE_SUCCESS(NTLSTATUS_FACILITY_WAIT, 0x000001u) +#define NTLSTATUS_PENDING KSTATUS_MAKE_SUCCESS(NTLSTATUS_FACILITY_WAIT, 0x000002u) +#define NTLSTATUS_ALERTED KSTATUS_MAKE_SUCCESS(NTLSTATUS_FACILITY_WAIT, 0x000003u) +#define NTLSTATUS_KERNEL_APC KSTATUS_MAKE_SUCCESS(NTLSTATUS_FACILITY_WAIT, 0x000004u) +#define NTLSTATUS_USER_APC KSTATUS_MAKE_SUCCESS(NTLSTATUS_FACILITY_WAIT, 0x000005u) // System-facility failures. -// STATUS_WOULD_BLOCK is the canonical result for immediate nonblocking operations that cannot make progress. -// STATUS_TIMEOUT is reserved for finite waits whose deadline expires. -#define STATUS_FAILURE KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000001u) -#define STATUS_NOT_SUPPORTED KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000002u) -#define STATUS_INVALID_PARAMETER KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000003u) -#define STATUS_INVALID_HANDLE KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000004u) -#define STATUS_BUFFER_TOO_SMALL KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000005u) -#define STATUS_CHECKSUM_MISMATCH KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000006u) -#define STATUS_NO_MEMORY KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000007u) -#define STATUS_ACCESS_DENIED KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000008u) -#define STATUS_NOT_FOUND KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000009u) -#define STATUS_ALREADY_EXISTS KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x00000Au) -#define STATUS_OBJECT_NAME_COLLISION KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x00000Bu) -#define STATUS_OBJECT_DEAD KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x00000Cu) -#define STATUS_QUEUE_FULL KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x00000Du) -#define STATUS_QUEUE_EMPTY KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x00000Eu) -#define STATUS_CANCELLED KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x00000Fu) -#define STATUS_DEVICE_ERROR KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000010u) -#define STATUS_NO_MORE_FILES KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000011u) -#define STATUS_INVALID_IRQL KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000012u) -#define STATUS_WOULD_BLOCK KSTATUS_MAKE_ERROR(STATUS_FACILITY_SYSTEM, 0x000013u) +// NTLSTATUS_WOULD_BLOCK is the canonical result for immediate nonblocking operations that cannot make progress. +// NTLSTATUS_TIMEOUT is reserved for finite waits whose deadline expires. +#define NTLSTATUS_FAILURE KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000001u) +#define NTLSTATUS_NOT_SUPPORTED KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000002u) +#define NTLSTATUS_INVALID_PARAMETER KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000003u) +#define NTLSTATUS_INVALID_HANDLE KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000004u) +#define NTLSTATUS_BUFFER_TOO_SMALL KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000005u) +#define NTLSTATUS_CHECKSUM_MISMATCH KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000006u) +#define NTLSTATUS_NO_MEMORY KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000007u) +#define NTLSTATUS_ACCESS_DENIED KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000008u) +#define NTLSTATUS_NOT_FOUND KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000009u) +#define NTLSTATUS_ALREADY_EXISTS KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x00000Au) +#define NTLSTATUS_OBJECT_NAME_COLLISION KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x00000Bu) +#define NTLSTATUS_OBJECT_DEAD KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x00000Cu) +#define NTLSTATUS_QUEUE_FULL KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x00000Du) +#define NTLSTATUS_QUEUE_EMPTY KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x00000Eu) +#define NTLSTATUS_CANCELLED KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x00000Fu) +#define NTLSTATUS_DEVICE_ERROR KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000010u) +#define NTLSTATUS_NO_MORE_FILES KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000011u) +#define NTLSTATUS_INVALID_IRQL KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000012u) +#define NTLSTATUS_WOULD_BLOCK KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_SYSTEM, 0x000013u) // Process termination and fault statuses use the process facility. -#define STATUS_PROCESS_BASE KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000000u) -#define STATUS_PROCESS_KILLED KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000000u) -#define STATUS_PROCESS_PAGE_FAULT KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000010u) -#define STATUS_PROCESS_GENERAL_PROTECTION KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000011u) -#define STATUS_PROCESS_ILLEGAL_OPCODE KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000012u) -#define STATUS_PROCESS_DIVIDE_BY_ZERO KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000013u) -#define STATUS_PROCESS_BREAKPOINT KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000014u) -#define STATUS_PROCESS_ALIGNMENT_FAULT KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x000015u) -#define STATUS_PROCESS_UNKNOWN_FAULT KSTATUS_MAKE_ERROR(STATUS_FACILITY_PROCESS, 0x00001Fu) +#define NTLSTATUS_PROCESS_BASE KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000000u) +#define NTLSTATUS_PROCESS_KILLED KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000000u) +#define NTLSTATUS_PROCESS_PAGE_FAULT KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000010u) +#define NTLSTATUS_PROCESS_GENERAL_PROTECTION KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000011u) +#define NTLSTATUS_PROCESS_ILLEGAL_OPCODE KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000012u) +#define NTLSTATUS_PROCESS_DIVIDE_BY_ZERO KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000013u) +#define NTLSTATUS_PROCESS_BREAKPOINT KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000014u) +#define NTLSTATUS_PROCESS_ALIGNMENT_FAULT KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x000015u) +#define NTLSTATUS_PROCESS_UNKNOWN_FAULT KSTATUS_MAKE_ERROR(NTLSTATUS_FACILITY_PROCESS, 0x00001Fu) -#define KSUCCESS(status) (((KSTATUS)(status)) == STATUS_SUCCESS) +#define KSUCCESS(status) (((KSTATUS)(status)) == NTLSTATUS_SUCCESS) #define KFAILED(status) KSTATUS_IS_ERROR(status) diff --git a/code/public/ntlite/syscall.h b/code/public/ntlite/syscall.h index 24b49d7..a321c80 100644 --- a/code/public/ntlite/syscall.h +++ b/code/public/ntlite/syscall.h @@ -13,6 +13,10 @@ #include #include +// Syscall ABI convention: status-returning calls use KSTATUS. New or revised +// operations use a request struct when they need five or more logical arguments +// or when a pointer/length pair would otherwise be split across flat arguments. + // User process/thread environment. // GS base points at SYS_TEB. GS:[0] is the process PEB pointer. #define SYS_PEB_MAGIC 0x30424550u // "PEB0" @@ -104,7 +108,7 @@ typedef struct SYS_ASYNC_FILE_REQUEST { uint64_t Offset; // explicit byte offset; does not touch file pointer void* Buffer; size_t Size; - SYS_IO_STATUS_BLOCK* Iosb; // required; initialized to STATUS_PENDING + SYS_IO_STATUS_BLOCK* Iosb; // required; initialized to NTLSTATUS_PENDING SYS_USER_APC_ROUTINE ApcRoutine; // optional; requires SysSetUserApcDispatcher void* ApcContext; uint32_t* RequestHandleOut; // optional; receives cancel/query handle @@ -148,6 +152,155 @@ typedef struct SYS_TRAP_FRAME_INFO { uint64_t R11; } SYS_TRAP_FRAME_INFO; + +// Structured exception delivery ABI. The kernel owns capture, delivery, and +// context validation; personalities own VEH, SEH, signal, and unwind policy. +#define SYS_EXCEPTION_ABI_VERSION 1u +#define SYS_EXCEPTION_MAXIMUM_PARAMETERS 15u + +#define SYS_EXCEPTION_FLAG_NONE 0x00000000u +#define SYS_EXCEPTION_FLAG_NONCONTINUABLE 0x00000001u +#define SYS_EXCEPTION_FLAG_FIRST_CHANCE 0x00000002u + +#define SYS_EXCEPTION_DISPATCH_FLAG_NONE 0x00000000u +#define SYS_EXCEPTION_CONTINUE_FLAG_NONE 0x00000000u +#define SYS_RAISE_EXCEPTION_FLAG_NONE 0x00000000u +#define SYS_RAISE_EXCEPTION_FLAG_NONCONTINUABLE 0x00000001u + +// Common exception codes intentionally match the Windows values used by user +// VEH/SEH code. The native ABI remains policy-neutral; the matching numbers +// only avoid needless translation in the Win32 personality. +#define SYS_EXCEPTION_CODE_GUARD_PAGE_VIOLATION 0x80000001u +#define SYS_EXCEPTION_CODE_DATATYPE_MISALIGNMENT 0x80000002u +#define SYS_EXCEPTION_CODE_BREAKPOINT 0x80000003u +#define SYS_EXCEPTION_CODE_SINGLE_STEP 0x80000004u +#define SYS_EXCEPTION_CODE_ACCESS_VIOLATION 0xC0000005u +#define SYS_EXCEPTION_CODE_ILLEGAL_INSTRUCTION 0xC000001Du +#define SYS_EXCEPTION_CODE_NONCONTINUABLE_EXCEPTION 0xC0000025u +#define SYS_EXCEPTION_CODE_INVALID_DISPOSITION 0xC0000026u +#define SYS_EXCEPTION_CODE_ARRAY_BOUNDS_EXCEEDED 0xC000008Cu +#define SYS_EXCEPTION_CODE_FLT_DENORMAL_OPERAND 0xC000008Du +#define SYS_EXCEPTION_CODE_FLT_DIVIDE_BY_ZERO 0xC000008Eu +#define SYS_EXCEPTION_CODE_FLT_INEXACT_RESULT 0xC000008Fu +#define SYS_EXCEPTION_CODE_FLT_INVALID_OPERATION 0xC0000090u +#define SYS_EXCEPTION_CODE_FLT_OVERFLOW 0xC0000091u +#define SYS_EXCEPTION_CODE_FLT_STACK_CHECK 0xC0000092u +#define SYS_EXCEPTION_CODE_FLT_UNDERFLOW 0xC0000093u +#define SYS_EXCEPTION_CODE_INT_DIVIDE_BY_ZERO 0xC0000094u +#define SYS_EXCEPTION_CODE_INT_OVERFLOW 0xC0000095u +#define SYS_EXCEPTION_CODE_PRIVILEGED_INSTRUCTION 0xC0000096u +#define SYS_EXCEPTION_CODE_STACK_OVERFLOW 0xC00000FDu +#define SYS_EXCEPTION_CODE_NTLITE_UNKNOWN 0xE0000001u +#define SYS_EXCEPTION_CODE_NTLITE_USER_RAISED 0xE0000002u + +#define SYS_EXCEPTION_DISPOSITION_CONTINUE_EXECUTION 0u +#define SYS_EXCEPTION_DISPOSITION_CONTINUE_SEARCH 1u +#define SYS_EXCEPTION_DISPOSITION_EXECUTE_HANDLER 2u +#define SYS_EXCEPTION_DISPOSITION_TERMINATE_PROCESS 3u + +#define SYS_CONTEXT_FLAG_NONE 0x0000000000000000ull +#define SYS_CONTEXT_FLAG_CONTROL 0x0000000000000001ull +#define SYS_CONTEXT_FLAG_INTEGER 0x0000000000000002ull +#define SYS_CONTEXT_FLAG_SEGMENTS 0x0000000000000004ull +#define SYS_CONTEXT_FLAG_ALL (SYS_CONTEXT_FLAG_CONTROL | \ + SYS_CONTEXT_FLAG_INTEGER | \ + SYS_CONTEXT_FLAG_SEGMENTS) + +typedef struct SYS_USER_CONTEXT { + uint32_t Size; + uint32_t Version; + uint64_t Flags; + + uint64_t Rip; + uint64_t Rsp; + uint64_t Rflags; + + uint64_t Rax; + uint64_t Rcx; + uint64_t Rdx; + uint64_t Rbx; + uint64_t Rbp; + uint64_t Rsi; + uint64_t Rdi; + uint64_t R8; + uint64_t R9; + uint64_t R10; + uint64_t R11; + uint64_t R12; + uint64_t R13; + uint64_t R14; + uint64_t R15; + + uint32_t SegCs; + uint32_t SegSs; + uint32_t SegDs; + uint32_t SegEs; + uint32_t SegFs; + uint32_t SegGs; + uint32_t Reserved0; + uint32_t Reserved1; +} SYS_USER_CONTEXT; + +typedef struct SYS_EXCEPTION_RECORD { + uint32_t Size; + uint32_t Version; + uint32_t Code; + uint32_t Flags; + + uintptr_t ExceptionAddress; + uintptr_t FaultAddress; + uint64_t ErrorCode; + + uint32_t ParameterCount; + uint32_t Reserved; + uint64_t Parameters[SYS_EXCEPTION_MAXIMUM_PARAMETERS]; +} SYS_EXCEPTION_RECORD; + +typedef struct SYS_EXCEPTION_FRAME { + uint32_t Size; + uint32_t Version; + uint32_t Flags; + uint32_t Reserved; + + SYS_EXCEPTION_RECORD ExceptionRecord; + SYS_USER_CONTEXT ContextRecord; + void* DispatcherContext; +} SYS_EXCEPTION_FRAME; + +typedef void (*SYS_USER_EXCEPTION_DISPATCHER)(SYS_EXCEPTION_FRAME* frame); + +typedef struct SYS_EXCEPTION_DISPATCHER_REQUEST { + uint32_t Size; + uint32_t Flags; + + // A null routine unregisters the dispatcher and clears the optional stack. + SYS_USER_EXCEPTION_DISPATCHER DispatcherRoutine; + + // Opaque user-mode value passed back to the dispatcher. + void* DispatcherContext; + + // Optional user-mode stack extent. Base is the low address and size is the + // byte length; delivery will consume it from high addresses downward. + void* ExceptionStackBase; + size_t ExceptionStackSize; +} SYS_EXCEPTION_DISPATCHER_REQUEST; + +typedef struct SYS_CONTINUE_EXCEPTION_REQUEST { + uint32_t Size; + uint32_t Flags; + uint32_t Disposition; + uint32_t Reserved; + const SYS_USER_CONTEXT* Context; +} SYS_CONTINUE_EXCEPTION_REQUEST; + +typedef struct SYS_RAISE_EXCEPTION_REQUEST { + uint32_t Size; + uint32_t Flags; + uint32_t Code; + uint32_t ParameterCount; + const uint64_t* Parameters; +} SYS_RAISE_EXCEPTION_REQUEST; + // String-view based syscall request structures. typedef struct SYS_CREATE_PROCESS_REQUEST { SYS_STRING_VIEW Path; @@ -234,8 +387,8 @@ typedef struct SYS_RENAME_FILE_REQUEST { #define SYS_FILE_LOCK_TO_EOF UINT64_MAX // File locks are advisory, process-owned byte-range locks keyed by filesystem -// identity. A zero timeout is an immediate try and returns STATUS_WOULD_BLOCK -// on conflict. A finite timeout returns STATUS_TIMEOUT only when its deadline +// identity. A zero timeout is an immediate try and returns NTLSTATUS_WOULD_BLOCK +// on conflict. A finite timeout returns NTLSTATUS_TIMEOUT only when its deadline // expires. SYS_WAIT_TIMEOUT_INFINITE waits without a deadline. Length must be // nonzero; SYS_FILE_LOCK_TO_EOF locks from Offset through end-of-file growth. // Unlock removes this process's overlapping locks for the file identity. @@ -265,11 +418,18 @@ typedef struct SYS_PRINT_DEBUG_REQUEST { SYS_STRING_VIEW Text; } SYS_PRINT_DEBUG_REQUEST; +// Published queue names are owned by the publishing process and QueueHandle. +// SysUnpublishQueue withdraws a name explicitly. Closing the publishing handle +// or exiting the process withdraws every name published through that handle. typedef struct SYS_PUBLISH_QUEUE_REQUEST { SYS_STRING_VIEW Name; uint32_t QueueHandle; } SYS_PUBLISH_QUEUE_REQUEST; +typedef struct SYS_UNPUBLISH_QUEUE_REQUEST { + SYS_STRING_VIEW Name; +} SYS_UNPUBLISH_QUEUE_REQUEST; + typedef struct SYS_OPEN_NAMED_QUEUE_REQUEST { SYS_STRING_VIEW Name; uint32_t* HandleOut; @@ -284,7 +444,7 @@ typedef struct SYS_NAMED_QUEUE_OWNER_REQUEST { #define SYS_QUEUE_MESSAGE_SIZE 56u // Queue send and receive requests use wait-style timeouts. A zero timeout is -// an immediate try operation and returns STATUS_WOULD_BLOCK if the queue cannot +// an immediate try operation and returns NTLSTATUS_WOULD_BLOCK if the queue cannot // make progress without waiting. SYS_WAIT_TIMEOUT_INFINITE requests a blocking // wait without a deadline. Message pointers reference SYS_QUEUE_MESSAGE_SIZE // bytes owned by the caller for the duration of the syscall. The common IPC @@ -336,24 +496,24 @@ typedef struct SYS_CREATE_THREAD_REQUEST { void SysExitProcess(int32_t exitCode); void SysExitThread(int32_t exitCode); -uint32_t SysCreateProcess(const SYS_CREATE_PROCESS_REQUEST* request); -uint32_t SysWaitSingle(uint32_t handle, uint32_t flags, uint64_t timeoutMilliseconds); -uint32_t SysWaitMany(const SYS_WAIT_MANY_REQUEST* request); +KSTATUS SysCreateProcess(const SYS_CREATE_PROCESS_REQUEST* request); +KSTATUS SysWaitSingle(uint32_t handle, uint32_t flags, uint64_t timeoutMilliseconds); +KSTATUS SysWaitMany(const SYS_WAIT_MANY_REQUEST* request); // SysOpenInputQueue returns a readable and waitable handle to the default // keyboard input queue. The handle does not create a second event stream; // SysReadInputEvent, SysPeekInputEvent, SysReadKey, and SysReadKeyboardChar // consume the same queue. SysWaitSingle succeeds for this handle when a // keyboard input event can be read. -uint32_t SysOpenInputQueue(uint32_t flags, uint32_t* handleOut); +KSTATUS SysOpenInputQueue(uint32_t flags, uint32_t* handleOut); -static inline uint32_t SysWait(uint32_t handle, uint32_t flags) { +static inline KSTATUS SysWait(uint32_t handle, uint32_t flags) { return SysWaitSingle(handle, flags, SYS_WAIT_TIMEOUT_INFINITE); } -uint32_t SysGetProcessExitCode(uint32_t handle, int32_t* exitCodeOut); -uint32_t SysOpenProcess(uint32_t pid, uint32_t* handleOut); +KSTATUS SysGetProcessExitCode(uint32_t handle, int32_t* exitCodeOut); +KSTATUS SysOpenProcess(uint32_t pid, uint32_t* handleOut); // Protected kernel processes remain openable for query and wait operations, -// but SysKillProcess returns STATUS_ACCESS_DENIED for them. -uint32_t SysKillProcess(uint32_t processHandle, int32_t exitCode); +// but SysKillProcess returns NTLSTATUS_ACCESS_DENIED for them. +KSTATUS SysKillProcess(uint32_t processHandle, int32_t exitCode); #define SYS_PROCESS_NAME_MAX 64u #define SYS_PROCESS_CWD_MAX 128u @@ -446,13 +606,23 @@ typedef struct SYS_PROCESS_INFO { size_t UserReservedBytes; size_t UserCommittedBytes; + uint64_t ExceptionDelivered; + uint64_t ExceptionUserRaised; + uint64_t ExceptionContinued; + uint64_t ExceptionUnhandled; + uint64_t ExceptionInvalidContinue; + uint32_t ExceptionMaxNestedDispatch; + uint32_t LastExceptionCode; + uintptr_t LastExceptionAddress; + uintptr_t LastExceptionFaultAddress; + char Name[SYS_PROCESS_NAME_MAX]; char CurrentDirectory[SYS_PROCESS_CWD_MAX]; } SYS_PROCESS_INFO; -uint32_t SysGetProcessList(SYS_PROCESS_INFO* processesOut, size_t maxCount, size_t* countOut); -uint32_t SysGetProcessPid(uint32_t handle, uint32_t* pidOut); -uint32_t SysGetThreadList(uint32_t pid, SYS_THREAD_INFO* threadsOut, size_t maxCount, size_t* countOut); +KSTATUS SysGetProcessList(SYS_PROCESS_INFO* processesOut, size_t maxCount, size_t* countOut); +KSTATUS SysGetProcessPid(uint32_t handle, uint32_t* pidOut); +KSTATUS SysGetThreadList(uint32_t pid, SYS_THREAD_INFO* threadsOut, size_t maxCount, size_t* countOut); #define SYS_MODULE_NAME_MAX 64u #define SYS_MODULE_INFO_VERSION 1u @@ -496,17 +666,17 @@ typedef struct SYS_GET_MODULE_EXPORT_REQUEST { uintptr_t* AddressOut; } SYS_GET_MODULE_EXPORT_REQUEST; -uint32_t SysLoadModule(const SYS_LOAD_MODULE_REQUEST* request); -uint32_t SysUnloadModule(uint32_t moduleHandle); -uint32_t SysGetModuleInfo(uint32_t moduleHandle, SYS_MODULE_INFO* infoOut); -uint32_t SysGetModuleExport(const SYS_GET_MODULE_EXPORT_REQUEST* request); -uint32_t SysGetModuleList(SYS_MODULE_INFO* modulesOut, size_t maxCount, size_t* countOut); +KSTATUS SysLoadModule(const SYS_LOAD_MODULE_REQUEST* request); +KSTATUS SysUnloadModule(uint32_t moduleHandle); +KSTATUS SysGetModuleInfo(uint32_t moduleHandle, SYS_MODULE_INFO* infoOut); +KSTATUS SysGetModuleExport(const SYS_GET_MODULE_EXPORT_REQUEST* request); +KSTATUS SysGetModuleList(SYS_MODULE_INFO* modulesOut, size_t maxCount, size_t* countOut); -uint32_t SysCreateThread(const SYS_CREATE_THREAD_REQUEST* request); +KSTATUS SysCreateThread(const SYS_CREATE_THREAD_REQUEST* request); uint32_t SysGetCurrentTid(void); uint32_t SysGetCurrentPid(void); -uint32_t SysSetThreadPriority(uint32_t priority); -uint32_t SysYield(void); +KSTATUS SysSetThreadPriority(uint32_t priority); +KSTATUS SysYield(void); #define SYS_TIMER_FLAG_NONE 0u @@ -522,19 +692,26 @@ typedef struct SYS_SET_TIMER_REQUEST { uint64_t PeriodMilliseconds; } SYS_SET_TIMER_REQUEST; -uint32_t SysCreateTimer(uint32_t* handleOut); -uint32_t SysSetTimer(const SYS_SET_TIMER_REQUEST* request); -uint32_t SysCancelTimer(uint32_t timerHandle); +KSTATUS SysCreateTimer(uint32_t* handleOut); +KSTATUS SysSetTimer(const SYS_SET_TIMER_REQUEST* request); +KSTATUS SysCancelTimer(uint32_t timerHandle); // SysSleep blocks the current thread through the same timer backend used by // waitable timer handles. A zero-length sleep yields the processor. -uint32_t SysSleep(uint64_t ms); -uint32_t SysSetUserApcDispatcher(void* dispatcher); +KSTATUS SysSleep(uint64_t ms); +KSTATUS SysSetUserApcDispatcher(void* dispatcher); // Returns from the active user APC dispatcher. The frame pointer must identify // the kernel-issued frame for the current delivery; it is not a general resume // or context-switch syscall. -uint32_t SysApcReturn(const SYS_USER_APC_FRAME* frame); +KSTATUS SysApcReturn(const SYS_USER_APC_FRAME* frame); + +// Registers or queries the native user-mode exception dispatcher. Actual fault +// delivery, validated continuation, and user-raised exceptions are later cuts. +KSTATUS SysSetExceptionDispatcher(const SYS_EXCEPTION_DISPATCHER_REQUEST* request); +KSTATUS SysGetExceptionDispatcher(SYS_EXCEPTION_DISPATCHER_REQUEST* request); +KSTATUS SysContinueException(const SYS_CONTINUE_EXCEPTION_REQUEST* request); +KSTATUS SysRaiseException(const SYS_RAISE_EXCEPTION_REQUEST* request); // Virtual memory and handles. typedef enum SYS_VM_PROTECTION { @@ -558,10 +735,20 @@ typedef struct SYS_VM_REGION_INFO { uint32_t OwnerPid; } SYS_VM_REGION_INFO; -uint32_t SysAllocVm(void* preferredBase, size_t pageCount, uint32_t protect, uint32_t flags, void** baseOut); -uint32_t SysFreeVm(void* base); -uint32_t SysProtectVm(void* base, size_t pageCount, uint32_t protect, uint32_t* oldProtectOut); -uint32_t SysQueryVm(void* address, SYS_VM_REGION_INFO* out); +typedef struct SYS_ALLOC_VM_REQUEST { + uint32_t Size; + uint32_t Protect; + uint32_t Flags; + uint32_t Reserved; + void* PreferredBase; + size_t PageCount; + void** BaseOut; +} SYS_ALLOC_VM_REQUEST; + +KSTATUS SysAllocVm(const SYS_ALLOC_VM_REQUEST* request); +KSTATUS SysFreeVm(void* base); +KSTATUS SysProtectVm(void* base, size_t pageCount, uint32_t protect, uint32_t* oldProtectOut); +KSTATUS SysQueryVm(void* address, SYS_VM_REGION_INFO* out); #define SYS_MAP_ACCESS_READ 0x00000001u #define SYS_MAP_ACCESS_WRITE 0x00000002u @@ -569,11 +756,11 @@ uint32_t SysQueryVm(void* address, SYS_VM_REGION_INFO* out); #define SYS_MAP_ACCESS_EXECUTE 0x00000008u #define SYS_MAP_FLAG_NONE 0x00000000u -uint32_t SysCreateFileMapping(uint32_t fileHandle, uint32_t protect, uint32_t flags, +KSTATUS SysCreateFileMapping(uint32_t fileHandle, uint32_t protect, uint32_t flags, uint64_t maximumSize, uint32_t* mappingHandleOut); -uint32_t SysMapFile(uint32_t mappingHandle, uint64_t offset, size_t size, +KSTATUS SysMapFile(uint32_t mappingHandle, uint64_t offset, size_t size, uint32_t access, uint32_t flags, void** baseOut); -uint32_t SysCloseHandle(uint32_t handle); +KSTATUS SysCloseHandle(uint32_t handle); #define SYS_HANDLE_RIGHT_READ 0x00000001u #define SYS_HANDLE_RIGHT_WRITE 0x00000002u @@ -596,51 +783,52 @@ typedef struct SYS_DUPLICATE_HANDLE_REQUEST { uint32_t* TargetHandleOut; } SYS_DUPLICATE_HANDLE_REQUEST; -uint32_t SysDuplicateHandle(const SYS_DUPLICATE_HANDLE_REQUEST* request); +KSTATUS SysDuplicateHandle(const SYS_DUPLICATE_HANDLE_REQUEST* request); -uint32_t SysCreateMutex(uint32_t* handleOut); -uint32_t SysTryAcquireMutex(uint32_t handle); -uint32_t SysReleaseMutex(uint32_t handle); +KSTATUS SysCreateMutex(uint32_t* handleOut); +KSTATUS SysTryAcquireMutex(uint32_t handle); +KSTATUS SysReleaseMutex(uint32_t handle); -uint32_t SysCreateSem(int32_t initial, int32_t max, uint32_t* handleOut); -uint32_t SysTryWaitSem(uint32_t handle); -uint32_t SysSignalSem(uint32_t handle); +KSTATUS SysCreateSem(int32_t initial, int32_t max, uint32_t* handleOut); +KSTATUS SysTryWaitSem(uint32_t handle); +KSTATUS SysSignalSem(uint32_t handle); -uint32_t SysCreateEvent(uint32_t type, uint32_t initialState, uint32_t* handleOut); -uint32_t SysSignalEvent(uint32_t handle); -uint32_t SysClearEvent(uint32_t handle); +KSTATUS SysCreateEvent(uint32_t type, uint32_t initialState, uint32_t* handleOut); +KSTATUS SysSignalEvent(uint32_t handle); +KSTATUS SysClearEvent(uint32_t handle); -uint32_t SysCreateQueue(uint32_t* handleOut); -uint32_t SysSendQueue(const SYS_QUEUE_SEND_REQUEST* request); -uint32_t SysRecvQueue(const SYS_QUEUE_RECV_REQUEST* request); -uint32_t SysPublishQueue(const SYS_PUBLISH_QUEUE_REQUEST* request); -uint32_t SysOpenNamedQueue(const SYS_OPEN_NAMED_QUEUE_REQUEST* request); -uint32_t SysOpenNamedQueueOwnerProcess(const SYS_NAMED_QUEUE_OWNER_REQUEST* request); +KSTATUS SysCreateQueue(uint32_t* handleOut); +KSTATUS SysSendQueue(const SYS_QUEUE_SEND_REQUEST* request); +KSTATUS SysRecvQueue(const SYS_QUEUE_RECV_REQUEST* request); +KSTATUS SysPublishQueue(const SYS_PUBLISH_QUEUE_REQUEST* request); +KSTATUS SysUnpublishQueue(const SYS_UNPUBLISH_QUEUE_REQUEST* request); +KSTATUS SysOpenNamedQueue(const SYS_OPEN_NAMED_QUEUE_REQUEST* request); +KSTATUS SysOpenNamedQueueOwnerProcess(const SYS_NAMED_QUEUE_OWNER_REQUEST* request); -uint32_t SysOpenFile(const SYS_OPEN_FILE_REQUEST* request); -uint32_t SysReadFile(const SYS_FILE_IO_REQUEST* request); -uint32_t SysWriteFile(const SYS_FILE_IO_REQUEST* request); -uint32_t SysReadFileAsync(const SYS_ASYNC_FILE_REQUEST* request); -uint32_t SysWriteFileAsync(const SYS_ASYNC_FILE_REQUEST* request); -uint32_t SysCancelIo(uint32_t asyncRequestHandle); -uint32_t SysSeekFile(uint32_t handle, uint64_t offset); -uint32_t SysGetFilePos(uint32_t handle, uint64_t* positionOut); -uint32_t SysGetFileSize(uint32_t handle, uint64_t* sizeOut); -uint32_t SysGetFileStat(uint32_t handle, SYS_FILE_STAT* statOut); -uint32_t SysStatFile(const SYS_STAT_FILE_REQUEST* request); -uint32_t SysTruncateFile(uint32_t handle, uint64_t newSize); -uint32_t SysFlushFile(uint32_t handle); -uint32_t SysDeleteFile(const SYS_PATH_REQUEST* request); -uint32_t SysRenameFile(const SYS_RENAME_FILE_REQUEST* request); -uint32_t SysLockFile(const SYS_LOCK_FILE_REQUEST* request); -uint32_t SysUnlockFile(const SYS_UNLOCK_FILE_REQUEST* request); +KSTATUS SysOpenFile(const SYS_OPEN_FILE_REQUEST* request); +KSTATUS SysReadFile(const SYS_FILE_IO_REQUEST* request); +KSTATUS SysWriteFile(const SYS_FILE_IO_REQUEST* request); +KSTATUS SysReadFileAsync(const SYS_ASYNC_FILE_REQUEST* request); +KSTATUS SysWriteFileAsync(const SYS_ASYNC_FILE_REQUEST* request); +KSTATUS SysCancelIo(uint32_t asyncRequestHandle); +KSTATUS SysSeekFile(uint32_t handle, uint64_t offset); +KSTATUS SysGetFilePos(uint32_t handle, uint64_t* positionOut); +KSTATUS SysGetFileSize(uint32_t handle, uint64_t* sizeOut); +KSTATUS SysGetFileStat(uint32_t handle, SYS_FILE_STAT* statOut); +KSTATUS SysStatFile(const SYS_STAT_FILE_REQUEST* request); +KSTATUS SysTruncateFile(uint32_t handle, uint64_t newSize); +KSTATUS SysFlushFile(uint32_t handle); +KSTATUS SysDeleteFile(const SYS_PATH_REQUEST* request); +KSTATUS SysRenameFile(const SYS_RENAME_FILE_REQUEST* request); +KSTATUS SysLockFile(const SYS_LOCK_FILE_REQUEST* request); +KSTATUS SysUnlockFile(const SYS_UNLOCK_FILE_REQUEST* request); -uint32_t SysOpenDir(const SYS_PATH_HANDLE_REQUEST* request); -uint32_t SysReadDir(uint32_t handle, SYS_DIR_ENTRY* entryOut); -uint32_t SysCreateDir(const SYS_PATH_REQUEST* request); -uint32_t SysRemoveDir(const SYS_PATH_REQUEST* request); -uint32_t SysSetCwd(const SYS_PATH_REQUEST* request); -uint32_t SysRealPath(const SYS_REAL_PATH_REQUEST* request); +KSTATUS SysOpenDir(const SYS_PATH_HANDLE_REQUEST* request); +KSTATUS SysReadDir(uint32_t handle, SYS_DIR_ENTRY* entryOut); +KSTATUS SysCreateDir(const SYS_PATH_REQUEST* request); +KSTATUS SysRemoveDir(const SYS_PATH_REQUEST* request); +KSTATUS SysSetCwd(const SYS_PATH_REQUEST* request); +KSTATUS SysRealPath(const SYS_REAL_PATH_REQUEST* request); // Console and graphics. typedef struct SYS_CONSOLE_INFO { @@ -651,19 +839,29 @@ typedef struct SYS_CONSOLE_INFO { uint16_t Attribute; } SYS_CONSOLE_INFO; -uint32_t SysWriteConsole(const SYS_WRITE_CONSOLE_REQUEST* request); -uint32_t SysGetConsoleInfo(SYS_CONSOLE_INFO* infoOut); -uint32_t SysSetConsoleCursor(int x, int y); -uint32_t SysFillConsoleCharacter(char c, int x, int y, size_t length, size_t* writtenOut); -uint32_t SysFillConsoleAttribute(uint16_t attr, int x, int y, size_t length, size_t* writtenOut); -uint32_t SysPutScreenChar(char c, int x, int y, uint32_t fg, uint32_t bg); -uint32_t SysCreateSurface(uint32_t width, uint32_t height, uint32_t format, uint32_t flags, uint32_t* handleOut); -uint32_t SysMapSurface(uint32_t surfaceHandle, void** baseOut, uint32_t* pitchBytesOut); -uint32_t SysQuerySurface(uint32_t surfaceHandle, SYS_SURFACE_DESC* descOut); -uint32_t SysPresentSurface(uint32_t surfaceHandle, const DISPLAY_RECT* rects, uint32_t rectCount); -uint32_t SysClearScreen(uint32_t color); -uint32_t SysGetScreenSize(int* widthOut, int* heightOut); -uint32_t SysQueryDisplayInfo(SYS_DISPLAY_INFO* infoOut); +KSTATUS SysWriteConsole(const SYS_WRITE_CONSOLE_REQUEST* request); +KSTATUS SysGetConsoleInfo(SYS_CONSOLE_INFO* infoOut); +KSTATUS SysSetConsoleCursor(int x, int y); +KSTATUS SysFillConsoleCharacter(char c, int x, int y, size_t length, size_t* writtenOut); +KSTATUS SysFillConsoleAttribute(uint16_t attr, int x, int y, size_t length, size_t* writtenOut); +KSTATUS SysPutScreenChar(char c, int x, int y, uint32_t fg, uint32_t bg); + +typedef struct SYS_CREATE_SURFACE_REQUEST { + uint32_t Size; + uint32_t Width; + uint32_t Height; + uint32_t Format; + uint32_t Flags; + uint32_t* HandleOut; +} SYS_CREATE_SURFACE_REQUEST; + +KSTATUS SysCreateSurface(const SYS_CREATE_SURFACE_REQUEST* request); +KSTATUS SysMapSurface(uint32_t surfaceHandle, void** baseOut, uint32_t* pitchBytesOut); +KSTATUS SysQuerySurface(uint32_t surfaceHandle, SYS_SURFACE_DESC* descOut); +KSTATUS SysPresentSurface(uint32_t surfaceHandle, const DISPLAY_RECT* rects, uint32_t rectCount); +KSTATUS SysClearScreen(uint32_t color); +KSTATUS SysGetScreenSize(int* widthOut, int* heightOut); +KSTATUS SysQueryDisplayInfo(SYS_DISPLAY_INFO* infoOut); // Input. #define SYS_INPUT_QUEUE_FLAG_NONE 0x00000000u @@ -671,8 +869,8 @@ uint32_t SysQueryDisplayInfo(SYS_DISPLAY_INFO* infoOut); // A zero QueueHandle means the default keyboard input queue. A // nonzero QueueHandle must be a handle returned by SysOpenInputQueue. A zero -// timeout is an immediate try and returns STATUS_WOULD_BLOCK when the queue is -// empty. A finite timeout returns STATUS_TIMEOUT only when its deadline expires. +// timeout is an immediate try and returns NTLSTATUS_WOULD_BLOCK when the queue is +// empty. A finite timeout returns NTLSTATUS_TIMEOUT only when its deadline expires. typedef struct SYS_INPUT_EVENT_REQUEST { uint32_t Size; uint32_t QueueHandle; @@ -681,17 +879,17 @@ typedef struct SYS_INPUT_EVENT_REQUEST { INPUT_KEY_RECORD* RecordOut; } SYS_INPUT_EVENT_REQUEST; -uint32_t SysPollKeyboard(INPUT_KEY* keyOut); -uint32_t SysIsKeyDown(INPUT_KEY key, bool* downOut); -uint32_t SysReadKeyboardChar(char* charOut); -uint32_t SysReadKey(INPUT_KEY* keyOut); +KSTATUS SysPollKeyboard(INPUT_KEY* keyOut); +KSTATUS SysIsKeyDown(INPUT_KEY key, bool* downOut); +KSTATUS SysReadKeyboardChar(char* charOut); +KSTATUS SysReadKey(INPUT_KEY* keyOut); uint32_t SysGetKeyModifiers(void); -uint32_t SysReadInputEvent(const SYS_INPUT_EVENT_REQUEST* request); -uint32_t SysPeekInputEvent(const SYS_INPUT_EVENT_REQUEST* request); +KSTATUS SysReadInputEvent(const SYS_INPUT_EVENT_REQUEST* request); +KSTATUS SysPeekInputEvent(const SYS_INPUT_EVENT_REQUEST* request); -uint32_t SysPeekMouse(INPUT_MOUSE_EVENT* eventOut); -uint32_t SysReadMouse(INPUT_MOUSE_EVENT* eventOut); -uint32_t SysGetMousePos(int* xOut, int* yOut); +KSTATUS SysPeekMouse(INPUT_MOUSE_EVENT* eventOut); +KSTATUS SysReadMouse(INPUT_MOUSE_EVENT* eventOut); +KSTATUS SysGetMousePos(int* xOut, int* yOut); // Native sockets. #define SYS_AF_INET 2u @@ -722,9 +920,13 @@ uint32_t SysGetMousePos(int* xOut, int* yOut); #define SYS_SOCKET_ADDRESS_SIZE 28u -// Socket addresses are tagged native records. For IPv4, Address[0..3] -// contains the address bytes. For IPv6, all 16 address bytes are used and -// ScopeId carries the zone index for scoped addresses. Port is host byte order. +// Socket addresses are tagged native records with one fixed ABI size. The +// syscall pointer-length parameter is the user-buffer bound and must be exactly +// SYS_SOCKET_ADDRESS_SIZE for input addresses; Size must also equal +// SYS_SOCKET_ADDRESS_SIZE after the kernel copies the fixed record. The macro is +// only the compile-time ABI constant. Address stores textual-order bytes +// (for example, 127,0,0,1), not an integer requiring byte-order conversion. Port +// is host byte order. typedef struct SYS_SOCKET_ADDRESS { uint16_t Family; uint16_t Size; @@ -772,6 +974,14 @@ typedef struct SYS_POLLFD { uint32_t ReturnedEvents; } SYS_POLLFD; +typedef struct SYS_POLL_REQUEST { + uint32_t Size; + uint32_t TimeoutMs; + SYS_POLLFD* Fds; + size_t Count; + size_t* ReadyOut; +} SYS_POLL_REQUEST; + #define SYS_ASYNC_SOCKET_FLAG_NONE 0x00000000u #define SYS_ASYNC_SOCKET_OP_BIND 1u @@ -826,21 +1036,21 @@ typedef struct SYS_ASYNC_SOCKET_REQUEST { uint32_t* RequestHandleOut; } SYS_ASYNC_SOCKET_REQUEST; -uint32_t SysCreateSocket(uint32_t domain, uint32_t type, uint32_t protocol, uint32_t* handleOut); -uint32_t SysBindSocket(uint32_t socket, const SYS_SOCKET_ADDRESS* address, size_t addressSize); -uint32_t SysListenSocket(uint32_t socket, uint32_t backlog); -uint32_t SysAcceptSocket(uint32_t socket, SYS_SOCKET_ADDRESS* remoteAddressOut, size_t* remoteAddressSizeInOut, uint32_t* acceptedHandleOut); -uint32_t SysConnectSocket(uint32_t socket, const SYS_SOCKET_ADDRESS* address, size_t addressSize); -uint32_t SysSendSocket(uint32_t socket, const void* buffer, size_t length, uint32_t flags, size_t* sentOut); -uint32_t SysRecvSocket(uint32_t socket, void* buffer, size_t length, uint32_t flags, size_t* receivedOut); -uint32_t SysShutdownSocket(uint32_t socket, uint32_t how); -uint32_t SysSendToSocket(uint32_t socket, const SYS_SOCKET_SEND_TO_REQUEST* request); -uint32_t SysRecvFromSocket(uint32_t socket, const SYS_SOCKET_RECV_FROM_REQUEST* request); -uint32_t SysResolveHost(const SYS_RESOLVE_HOST_REQUEST* request); -uint32_t SysSetSocketOption(uint32_t socket, const SYS_SOCKET_OPTION_REQUEST* request); -uint32_t SysGetSocketOption(uint32_t socket, const SYS_SOCKET_OPTION_REQUEST* request); -uint32_t SysPoll(SYS_POLLFD* fds, size_t count, uint32_t timeoutMs, size_t* readyOut); -uint32_t SysSocketIoAsync(const SYS_ASYNC_SOCKET_REQUEST* request); +KSTATUS SysCreateSocket(uint32_t domain, uint32_t type, uint32_t protocol, uint32_t* handleOut); +KSTATUS SysBindSocket(uint32_t socket, const SYS_SOCKET_ADDRESS* address, size_t addressSize); +KSTATUS SysListenSocket(uint32_t socket, uint32_t backlog); +KSTATUS SysAcceptSocket(uint32_t socket, SYS_SOCKET_ADDRESS* remoteAddressOut, size_t* remoteAddressSizeInOut, uint32_t* acceptedHandleOut); +KSTATUS SysConnectSocket(uint32_t socket, const SYS_SOCKET_ADDRESS* address, size_t addressSize); +KSTATUS SysSendSocket(uint32_t socket, const void* buffer, size_t length, uint32_t flags, size_t* sentOut); +KSTATUS SysRecvSocket(uint32_t socket, void* buffer, size_t length, uint32_t flags, size_t* receivedOut); +KSTATUS SysShutdownSocket(uint32_t socket, uint32_t how); +KSTATUS SysSendToSocket(uint32_t socket, const SYS_SOCKET_SEND_TO_REQUEST* request); +KSTATUS SysRecvFromSocket(uint32_t socket, const SYS_SOCKET_RECV_FROM_REQUEST* request); +KSTATUS SysResolveHost(const SYS_RESOLVE_HOST_REQUEST* request); +KSTATUS SysSetSocketOption(uint32_t socket, const SYS_SOCKET_OPTION_REQUEST* request); +KSTATUS SysGetSocketOption(uint32_t socket, const SYS_SOCKET_OPTION_REQUEST* request); +KSTATUS SysPoll(const SYS_POLL_REQUEST* request); +KSTATUS SysSocketIoAsync(const SYS_ASYNC_SOCKET_REQUEST* request); typedef struct SYS_MEMORY_STATUS { uint64_t FreePhysicalBytes; @@ -866,12 +1076,28 @@ typedef struct SYS_MEMORY_STATUS { #define SYS_KERNEL_STATS_FILESYSTEM 10u #define SYS_KERNEL_STATS_DISK 11u #define SYS_KERNEL_STATS_NET_IRP 12u +#define SYS_KERNEL_STATS_EXCEPTION 13u // Public stats payloads start with Size and Version. Size is the byte count // returned for that payload, including any trailing records. Version describes // the field layout for fixed fields in the named payload. #define SYS_STATS_VERSION 1u + +typedef struct SYS_EXCEPTION_STATS { + uint32_t Size; + uint32_t Version; + uint64_t Delivered; + uint64_t UserRaised; + uint64_t Continued; + uint64_t Unhandled; + uint64_t InvalidContinue; + uint32_t MaxNestedDispatch; + uint32_t LastCode; + uintptr_t LastExceptionAddress; + uintptr_t LastFaultAddress; +} SYS_EXCEPTION_STATS; + typedef struct SYS_SCHEDULER_STATS { uint32_t Size; uint32_t Version; @@ -1211,8 +1437,8 @@ typedef struct SYS_PTE_STATS { // SysGetTickFrequency and is not a wall-clock timestamp. uint64_t SysGetTick(void); -// SysGetTickFrequency returns the number of SysGetTick ticks per second. -uint32_t SysGetTickFrequency(uint64_t* frequencyOut); +// SysGetTickFrequency writes the number of SysGetTick ticks per second to frequencyOut. +KSTATUS SysGetTickFrequency(uint64_t* frequencyOut); // Converts a tick delta to milliseconds using the supplied tick frequency. static inline uint64_t SysTicksToMilliseconds(uint64_t ticks, uint64_t frequency) { @@ -1226,9 +1452,9 @@ static inline uint64_t SysTicksToMicroseconds(uint64_t ticks, uint64_t frequency return (ticks / frequency) * 1000000ull + ((ticks % frequency) * 1000000ull) / frequency; } -uint32_t SysPrintDebug(const SYS_PRINT_DEBUG_REQUEST* request); -uint32_t SysQueryTrapFrame(SYS_TRAP_FRAME_INFO* info); +KSTATUS SysPrintDebug(const SYS_PRINT_DEBUG_REQUEST* request); +KSTATUS SysQueryTrapFrame(SYS_TRAP_FRAME_INFO* info); -uint32_t SysGetMemoryStatus(SYS_MEMORY_STATUS* statusOut); -uint32_t SysQueryKernelStats(uint32_t classId, void* buffer, size_t bufferSize, size_t* requiredSizeOut); -uint32_t SysGetSystemTime(SYS_SYSTEM_TIME* timeOut); +KSTATUS SysGetMemoryStatus(SYS_MEMORY_STATUS* statusOut); +KSTATUS SysQueryKernelStats(uint32_t classId, void* buffer, size_t bufferSize, size_t* requiredSizeOut); +KSTATUS SysGetSystemTime(SYS_SYSTEM_TIME* timeOut); diff --git a/code/user/apps/doom/doom.c b/code/user/apps/doom/doom.c index 2970610..6fee03c 100644 --- a/code/user/apps/doom/doom.c +++ b/code/user/apps/doom/doom.c @@ -173,7 +173,7 @@ static int doom_eof_wrapper(void* handle) static void doom_gettime_wrapper(int* sec, int* usec) { uint64_t frequency = 0; - if (SysGetTickFrequency(&frequency) != STATUS_SUCCESS || !frequency) { + if (SysGetTickFrequency(&frequency) != NTLSTATUS_SUCCESS || !frequency) { *sec = 0; *usec = 0; return; @@ -278,7 +278,7 @@ static bool g_prev_key[KEYMAP_COUNT]; static bool ntlite_key_down(INPUT_KEY key) { bool down = false; - return SysIsKeyDown(key, &down) == STATUS_SUCCESS && down; + return SysIsKeyDown(key, &down) == NTLSTATUS_SUCCESS && down; } static void poll_input(void) @@ -309,9 +309,16 @@ static uint32_t g_surface_pitch_pixels; static void init_surface(void) { - uint32_t s = SysCreateSurface(DISP_W, DISP_H, SYS_SURFACE_FORMAT_XRGB8888, - SYS_SURFACE_FLAG_NONE, &g_surface_handle); - if (s != STATUS_SUCCESS || !g_surface_handle) { + SYS_CREATE_SURFACE_REQUEST req; + memset(&req, 0, sizeof(req)); + req.Size = sizeof(req); + req.Width = DISP_W; + req.Height = DISP_H; + req.Format = SYS_SURFACE_FORMAT_XRGB8888; + req.Flags = SYS_SURFACE_FLAG_NONE; + req.HandleOut = &g_surface_handle; + uint32_t s = SysCreateSurface(&req); + if (s != NTLSTATUS_SUCCESS || !g_surface_handle) { doom_print_wrapper("doom: SysCreateSurface failed\n"); SysExitProcess(1); } @@ -319,7 +326,7 @@ static void init_surface(void) void* base = 0; uint32_t pitchBytes = 0; s = SysMapSurface(g_surface_handle, &base, &pitchBytes); - if (s != STATUS_SUCCESS || !base || pitchBytes < DISP_W * sizeof(uint32_t)) { + if (s != NTLSTATUS_SUCCESS || !base || pitchBytes < DISP_W * sizeof(uint32_t)) { doom_print_wrapper("doom: SysMapSurface failed\n"); SysExitProcess(1); } @@ -359,7 +366,7 @@ static void render_frame(const uint8_t* rgba) DISPLAY_RECT rect = { 0, 0, DISP_W, DISP_H }; uint32_t code = SysPresentSurface(g_surface_handle, &rect, 1); - if (code != STATUS_SUCCESS) { + if (code != NTLSTATUS_SUCCESS) { SysExitProcess(code); } } diff --git a/code/user/apps/edit/edit.c b/code/user/apps/edit/edit.c index 510954e..9a4a204 100644 --- a/code/user/apps/edit/edit.c +++ b/code/user/apps/edit/edit.c @@ -508,7 +508,7 @@ static void editor_loop(void) { render(); INPUT_KEY key = INPUT_KEY_NONE; - if (SysReadKey(&key) != STATUS_SUCCESS) continue; + if (SysReadKey(&key) != NTLSTATUS_SUCCESS) continue; uint32_t mods = SysGetKeyModifiers(); bool ctrl = (mods & INPUT_MOD_CTRL) != 0; diff --git a/code/user/apps/httpget/httpget.c b/code/user/apps/httpget/httpget.c index c210172..663ca52 100644 --- a/code/user/apps/httpget/httpget.c +++ b/code/user/apps/httpget/httpget.c @@ -160,7 +160,7 @@ static uint32_t resolve_host(const char* host, SYS_SOCKET_ADDRESS* address) { address->Size = sizeof(*address); address->Family = SYS_AF_INET; memcpy(address->Address, ip, 4); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } size_t resolvedSize = sizeof(*address); @@ -173,8 +173,8 @@ static uint32_t resolve_host(const char* host, SYS_SOCKET_ADDRESS* address) { req.AddressSizeInOut = &resolvedSize; uint32_t st = SysResolveHost(&req); - if (st == STATUS_SUCCESS) - return STATUS_SUCCESS; + if (st == NTLSTATUS_SUCCESS) + return NTLSTATUS_SUCCESS; resolvedSize = sizeof(*address); memset(address, 0, sizeof(*address)); @@ -224,7 +224,7 @@ int main(void) { } uint32_t st = resolve_host(host, &addr); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("httpget: resolve failed "); print_u64(st); print(" for "); print(host); print("\n"); usage(); SysExitProcess(1); @@ -242,7 +242,7 @@ int main(void) { uint32_t sock = 0; st = SysCreateSocket(addr.Family, SYS_SOCK_STREAM, SYS_IPPROTO_TCP, &sock); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("httpget: SysCreateSocket failed "); print_u64(st); print("\n"); SysExitProcess(1); } @@ -250,7 +250,7 @@ int main(void) { addr.Port = 80; st = SysConnectSocket(sock, &addr, sizeof(addr)); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("httpget: SysConnectSocket failed "); print_u64(st); print("\n"); SysCloseHandle(sock); SysExitProcess(1); @@ -269,7 +269,7 @@ int main(void) { while (totalSent < off) { size_t sent = 0; st = SysSendSocket(sock, request + totalSent, off - totalSent, 0, &sent); - if (st != STATUS_SUCCESS || sent == 0) { + if (st != NTLSTATUS_SUCCESS || sent == 0) { print("httpget: SysSendSocket failed "); print_u64(st); print(" sent="); print_u64(sent); print("\n"); SysCloseHandle(sock); SysExitProcess(1); @@ -282,7 +282,7 @@ int main(void) { for (;;) { size_t got = 0; st = SysRecvSocket(sock, buf, sizeof(buf) - 1, 0, &got); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("\nhttpget: SysRecvSocket failed "); print_u64(st); print(" after "); print_u64(total); print(" bytes\n"); SysCloseHandle(sock); SysExitProcess(1); diff --git a/code/user/apps/memtop/memtop.c b/code/user/apps/memtop/memtop.c index c187961..c45f049 100644 --- a/code/user/apps/memtop/memtop.c +++ b/code/user/apps/memtop/memtop.c @@ -30,8 +30,8 @@ int main(void) { char metricsBuf[128]; while (true) { - if (SysGetConsoleInfo(&console) == STATUS_SUCCESS && - SysGetMemoryStatus(&mem) == STATUS_SUCCESS) { + if (SysGetConsoleInfo(&console) == NTLSTATUS_SUCCESS && + SysGetMemoryStatus(&mem) == NTLSTATUS_SUCCESS) { // If the system isn't reporting columns correctly, default to a safe standard width int columns = (console.Columns > 0) ? (int)console.Columns : 80; diff --git a/code/user/apps/ping/ping.c b/code/user/apps/ping/ping.c index a3eae11..5ac7f6b 100644 --- a/code/user/apps/ping/ping.c +++ b/code/user/apps/ping/ping.c @@ -133,7 +133,7 @@ static bool parse_u32(const char* s, uint32_t* out) { // Implements the resolve host operation. static uint32_t resolve_host(const char* host, uint8_t ip[4]) { if (parse_ipv4(host, ip)) - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; SYS_SOCKET_ADDRESS resolved; size_t resolvedSize = sizeof(resolved); @@ -146,16 +146,16 @@ static uint32_t resolve_host(const char* host, uint8_t ip[4]) { req.AddressSizeInOut = &resolvedSize; uint32_t st = SysResolveHost(&req); - if (st != STATUS_SUCCESS) + if (st != NTLSTATUS_SUCCESS) return st; if (resolved.Family != SYS_AF_INET) - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; ip[0] = resolved.Address[0]; ip[1] = resolved.Address[1]; ip[2] = resolved.Address[2]; ip[3] = resolved.Address[3]; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the icmp checksum operation. @@ -258,7 +258,7 @@ int main(void) { uint8_t ip[4]; uint32_t st = resolve_host(host, ip); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("ping: resolve failed "); print_u64(st); print(" for "); print(host); print("\n"); SysExitProcess(1); } @@ -268,7 +268,7 @@ int main(void) { uint32_t sock = 0; st = SysCreateSocket(SYS_AF_INET, SYS_SOCK_RAW, SYS_IPPROTO_ICMP, &sock); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("ping: SysCreateSocket(raw icmp) failed "); print_u64(st); print("\n"); SysExitProcess(1); } @@ -283,7 +283,7 @@ int main(void) { uint64_t tickFrequency = 0; st = SysGetTickFrequency(&tickFrequency); - if (st != STATUS_SUCCESS || !tickFrequency) { + if (st != NTLSTATUS_SUCCESS || !tickFrequency) { print("ping: SysGetTickFrequency failed "); print_u64(st); print("\n"); SysCloseHandle(sock); SysExitProcess(1); @@ -323,7 +323,7 @@ int main(void) { uint64_t start = SysGetTick(); st = SysSendToSocket(sock, &sendReq); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("ping: send failed seq="); print_u64(seq); print(" status="); print_u64(st); print("\n"); if (i + 1 < count) SysSleep(1000); continue; @@ -346,9 +346,9 @@ int main(void) { recvReq.ReceivedOut = &got; st = SysRecvFromSocket(sock, &recvReq); - if (st == STATUS_TIMEOUT) + if (st == NTLSTATUS_TIMEOUT) break; - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("ping: recv failed status="); print_u64(st); print("\n"); break; } diff --git a/code/user/apps/resolve/resolve.c b/code/user/apps/resolve/resolve.c index 1cf6156..d33cbad 100644 --- a/code/user/apps/resolve/resolve.c +++ b/code/user/apps/resolve/resolve.c @@ -109,12 +109,12 @@ int main(void) { req.AddressSizeInOut = &addrSize; uint32_t st = SysResolveHost(&req); - if (st != STATUS_SUCCESS && family == 0) { + if (st != NTLSTATUS_SUCCESS && family == 0) { req.Family = SYS_AF_INET; addrSize = sizeof(addr); st = SysResolveHost(&req); } - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("resolve: SysResolveHost failed "); print_u64(st); print("\n"); SysExitProcess(1); } diff --git a/code/user/apps/shell_native/shell_native.c b/code/user/apps/shell_native/shell_native.c index dbfb5ee..fa96b8b 100644 --- a/code/user/apps/shell_native/shell_native.c +++ b/code/user/apps/shell_native/shell_native.c @@ -138,14 +138,14 @@ static void printUInt64Width(uint64_t n, size_t width) { // Names nt-lite process-abort exit statuses. static const char* processExitStatusName(uint32_t code) { switch (code) { - case STATUS_PROCESS_KILLED: return "killed"; - case STATUS_PROCESS_PAGE_FAULT: return "page-fault"; - case STATUS_PROCESS_GENERAL_PROTECTION: return "general-protection"; - case STATUS_PROCESS_ILLEGAL_OPCODE: return "illegal-opcode"; - case STATUS_PROCESS_DIVIDE_BY_ZERO: return "divide-by-zero"; - case STATUS_PROCESS_BREAKPOINT: return "breakpoint"; - case STATUS_PROCESS_ALIGNMENT_FAULT: return "alignment-fault"; - case STATUS_PROCESS_UNKNOWN_FAULT: return "unknown-fault"; + case NTLSTATUS_PROCESS_KILLED: return "killed"; + case NTLSTATUS_PROCESS_PAGE_FAULT: return "page-fault"; + case NTLSTATUS_PROCESS_GENERAL_PROTECTION: return "general-protection"; + case NTLSTATUS_PROCESS_ILLEGAL_OPCODE: return "illegal-opcode"; + case NTLSTATUS_PROCESS_DIVIDE_BY_ZERO: return "divide-by-zero"; + case NTLSTATUS_PROCESS_BREAKPOINT: return "breakpoint"; + case NTLSTATUS_PROCESS_ALIGNMENT_FAULT: return "alignment-fault"; + case NTLSTATUS_PROCESS_UNKNOWN_FAULT: return "unknown-fault"; default: return NULL; } } @@ -527,7 +527,7 @@ static bool readLine(char* buf, int len) { inputReq.Flags = SYS_INPUT_EVENT_FLAG_NONE; inputReq.TimeoutMilliseconds = SYS_WAIT_TIMEOUT_INFINITE; inputReq.RecordOut = &input; - if (SysReadInputEvent(&inputReq) != STATUS_SUCCESS) { SysYield(); continue; } + if (SysReadInputEvent(&inputReq) != NTLSTATUS_SUCCESS) { SysYield(); continue; } INPUT_KEY key = input.Key; if (key == INPUT_KEY_NONE) { SysYield(); continue; } @@ -653,6 +653,7 @@ static void cmd_stats(void) { SYS_DISK_STATS disk; SYS_PTE_STATS pte; SYS_SURFACE_STATS surface; + SYS_EXCEPTION_STATS exceptionStats; uint32_t status; status = SysQueryKernelStats(SYS_KERNEL_STATS_SCHEDULER, &sched, sizeof(sched), NULL); @@ -682,7 +683,14 @@ static void cmd_stats(void) { size_t cpuPages = (cpuSize + 4095u) / 4096u; if (cpuPages == 0) cpuPages = 1; - status = SysAllocVm(0, cpuPages, SYS_VM_READWRITE, SYS_VM_FLAG_NONE, &cpuBuffer); + SYS_ALLOC_VM_REQUEST allocReq; + memset(&allocReq, 0, sizeof(allocReq)); + allocReq.Size = sizeof(allocReq); + allocReq.PageCount = cpuPages; + allocReq.Protect = SYS_VM_READWRITE; + allocReq.Flags = SYS_VM_FLAG_NONE; + allocReq.BaseOut = &cpuBuffer; + status = SysAllocVm(&allocReq); if (status != 0 || !cpuBuffer) { print("stats: cpu buffer allocation failed: "); printUInt(status); @@ -772,6 +780,15 @@ static void cmd_stats(void) { return; } + status = SysQueryKernelStats(SYS_KERNEL_STATS_EXCEPTION, &exceptionStats, sizeof(exceptionStats), NULL); + if (status != 0) { + print("stats: exception query failed: "); + printUInt(status); + print("\n"); + SysFreeVm(cpuBuffer); + return; + } + print("Scheduler:\n"); print(" ticks: "); printUInt64(sched.Ticks); print("\n"); print(" context switches: "); printUInt64(sched.ContextSwitches); print("\n"); @@ -785,6 +802,15 @@ static void cmd_stats(void) { print(" SMT deferrals: "); printUInt64(sched.SmtSiblingDeferrals); print("\n"); print(" SMT primary pokes: "); printUInt64(sched.SmtPrimaryPokes); print("\n"); + print("Exceptions:\n"); + print(" delivered: "); printUInt64(exceptionStats.Delivered); print("\n"); + print(" user-raised: "); printUInt64(exceptionStats.UserRaised); print("\n"); + print(" continued: "); printUInt64(exceptionStats.Continued); print("\n"); + print(" unhandled: "); printUInt64(exceptionStats.Unhandled); print("\n"); + print(" invalid continue: "); printUInt64(exceptionStats.InvalidContinue); print("\n"); + print(" max nesting: "); printUInt(exceptionStats.MaxNestedDispatch); print("\n"); + print(" last code: "); printUInt(exceptionStats.LastCode); print("\n"); + print("CPUs:\n"); const SYS_CPU_STAT* cpuRecords = SYS_CPU_STATS_CONST_RECORDS(cpu); uint32_t n = cpu->RecordCount; @@ -1352,11 +1378,11 @@ static void cmd_kill(const char* args) { uint32_t hProc = 0; uint32_t status = SysOpenProcess(pid, &hProc); if (status == 0) { - status = SysKillProcess(hProc, (int32_t)STATUS_PROCESS_KILLED); + status = SysKillProcess(hProc, (int32_t)NTLSTATUS_PROCESS_KILLED); SysCloseHandle(hProc); } - if (status == STATUS_ACCESS_DENIED) { + if (status == NTLSTATUS_ACCESS_DENIED) { print("kill: process "); printUInt(pid); print(" is termination-protected.\n"); @@ -1466,7 +1492,7 @@ static bool shellConsumeQueuedCtrlC(void) { inputReq.Flags = SYS_INPUT_EVENT_FLAG_NONE; inputReq.TimeoutMilliseconds = 0; inputReq.RecordOut = &input; - if (SysPeekInputEvent(&inputReq) != STATUS_SUCCESS) return false; + if (SysPeekInputEvent(&inputReq) != NTLSTATUS_SUCCESS) return false; if ((input.Modifiers & INPUT_MOD_CTRL) && input.Key == INPUT_KEY_C) { (void)SysReadInputEvent(&inputReq); @@ -1487,7 +1513,7 @@ static bool shellConsumeQueuedCtrlC(void) { // Returns whether one input key is currently held. static bool shellIsKeyDown(INPUT_KEY key) { bool down = false; - return SysIsKeyDown(key, &down) == STATUS_SUCCESS && down; + return SysIsKeyDown(key, &down) == NTLSTATUS_SUCCESS && down; } // Waits for a foreground process while watching Ctrl-C without stealing ordinary stdin. @@ -1511,7 +1537,7 @@ static uint32_t waitForegroundProcess(uint32_t hProc) { for (;;) { index = 0; uint32_t status = SysWaitMany(&waitReq); - if (status != STATUS_SUCCESS) { + if (status != NTLSTATUS_SUCCESS) { SysCloseHandle(inputQueue); return status; } @@ -1525,7 +1551,7 @@ static uint32_t waitForegroundProcess(uint32_t hProc) { if (((modifiers & INPUT_MOD_CTRL) && shellIsKeyDown(INPUT_KEY_C)) || shellConsumeQueuedCtrlC()) { if (!sentBreak) { print("^C\n"); - (void)SysKillProcess(hProc, (int32_t)STATUS_PROCESS_KILLED); + (void)SysKillProcess(hProc, (int32_t)NTLSTATUS_PROCESS_KILLED); sentBreak = true; } } @@ -1624,7 +1650,7 @@ static int runCommand(const char* cmd) { } else { // Foreground mode: Wait for completion and flush standard keyboard stream. uint32_t waitStatus = waitForegroundProcess(hProc); - if (waitStatus != STATUS_SUCCESS) { + if (waitStatus != NTLSTATUS_SUCCESS) { print("shell: wait failed: "); printUInt(waitStatus); print("\n"); @@ -1644,7 +1670,7 @@ static int runCommand(const char* cmd) { print("\n"); SysCloseHandle(hProc); INPUT_KEY drainedKey; - while (SysPollKeyboard(&drainedKey) == STATUS_SUCCESS) (void)SysReadKey(&drainedKey); + while (SysPollKeyboard(&drainedKey) == NTLSTATUS_SUCCESS) (void)SysReadKey(&drainedKey); } } else { print("shell: launch failed\n"); diff --git a/code/user/apps/tcpserve/tcpserve.c b/code/user/apps/tcpserve/tcpserve.c index 325e6c3..a480091 100644 --- a/code/user/apps/tcpserve/tcpserve.c +++ b/code/user/apps/tcpserve/tcpserve.c @@ -131,7 +131,7 @@ int main(void) { uint32_t listener = 0; uint32_t st = SysCreateSocket(family, SYS_SOCK_STREAM, SYS_IPPROTO_TCP, &listener); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("tcpserve: SysCreateSocket failed "); print_u64(st); print("\n"); SysExitProcess(1); } @@ -143,14 +143,14 @@ int main(void) { bindAddr.Port = port; st = SysBindSocket(listener, &bindAddr, sizeof(bindAddr)); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("tcpserve: SysBindSocket failed "); print_u64(st); print("\n"); SysCloseHandle(listener); SysExitProcess(1); } st = SysListenSocket(listener, 4); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("tcpserve: SysListenSocket failed "); print_u64(st); print("\n"); SysCloseHandle(listener); SysExitProcess(1); @@ -165,7 +165,7 @@ int main(void) { size_t remoteSize = sizeof(remote); uint32_t client = 0; st = SysAcceptSocket(listener, &remote, &remoteSize, &client); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("tcpserve: SysAcceptSocket failed "); print_u64(st); print("\n"); SysCloseHandle(listener); SysExitProcess(1); @@ -178,7 +178,7 @@ int main(void) { char request[1025]; size_t got = 0; st = SysRecvSocket(client, request, sizeof(request) - 1, 0, &got); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("tcpserve: SysRecvSocket failed "); print_u64(st); print("\n"); SysCloseHandle(client); SysCloseHandle(listener); @@ -217,9 +217,9 @@ int main(void) { size_t sent = 0; st = SysSendSocket(client, response, off, 0, &sent); - if (st == STATUS_SUCCESS) + if (st == NTLSTATUS_SUCCESS) st = SysSendSocket(client, body, sizeof(body) - 1, 0, &sent); - if (st != STATUS_SUCCESS) + if (st != NTLSTATUS_SUCCESS) print("tcpserve: SysSendSocket failed "), print_u64(st), print("\n"); SysShutdownSocket(client, SYS_SHUTDOWN_BOTH); diff --git a/code/user/apps/udp/udp.c b/code/user/apps/udp/udp.c index 76b2c40..d0eaa85 100644 --- a/code/user/apps/udp/udp.c +++ b/code/user/apps/udp/udp.c @@ -148,7 +148,7 @@ static uint32_t resolve_address(const char* text, SYS_SOCKET_ADDRESS* out) { out->Size = sizeof(*out); out->Family = SYS_AF_INET; memcpy(out->Address, ip, 4); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } SYS_RESOLVE_HOST_REQUEST req; @@ -161,8 +161,8 @@ static uint32_t resolve_address(const char* text, SYS_SOCKET_ADDRESS* out) { req.AddressSizeInOut = &addressSize; uint32_t status = SysResolveHost(&req); - if (status == STATUS_SUCCESS) - return STATUS_SUCCESS; + if (status == NTLSTATUS_SUCCESS) + return NTLSTATUS_SUCCESS; addressSize = sizeof(*out); memset(out, 0, sizeof(*out)); @@ -179,7 +179,7 @@ static int run_send(const char* cmd) { cmd = next_token(cmd, tok, sizeof(tok)); if (!tok[0]) { usage(); return 1; } uint32_t status = resolve_address(tok, &remote); - if (status != STATUS_SUCCESS) { print("udp: resolve failed "); print_u64(status); print("\n"); return 1; } + if (status != NTLSTATUS_SUCCESS) { print("udp: resolve failed "); print_u64(status); print("\n"); return 1; } cmd = next_token(cmd, tok, sizeof(tok)); if (!tok[0] || !parse_port(tok, &port)) { usage(); return 1; } @@ -197,7 +197,7 @@ static int run_send(const char* cmd) { uint32_t sock = 0; uint32_t st = SysCreateSocket(remote.Family, SYS_SOCK_DGRAM, SYS_IPPROTO_UDP, &sock); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("udp: SysCreateSocket failed "); print_u64(st); print("\n"); return 1; } @@ -215,7 +215,7 @@ static int run_send(const char* cmd) { st = SysSendToSocket(sock, &req); SysCloseHandle(sock); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("udp: SysSendToSocket failed "); print_u64(st); print("\n"); return 1; } @@ -242,7 +242,7 @@ static int run_listen(const char* cmd) { uint32_t sock = 0; uint32_t st = SysCreateSocket(family, SYS_SOCK_DGRAM, SYS_IPPROTO_UDP, &sock); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("udp: SysCreateSocket failed "); print_u64(st); print("\n"); return 1; } @@ -254,7 +254,7 @@ static int run_listen(const char* cmd) { bindAddr.Port = port; st = SysBindSocket(sock, &bindAddr, sizeof(bindAddr)); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("udp: SysBindSocket failed "); print_u64(st); print("\n"); SysCloseHandle(sock); return 1; @@ -278,7 +278,7 @@ static int run_listen(const char* cmd) { st = SysRecvFromSocket(sock, &req); SysCloseHandle(sock); - if (st != STATUS_SUCCESS) { + if (st != NTLSTATUS_SUCCESS) { print("udp: SysRecvFromSocket failed "); print_u64(st); print("\n"); return 1; } diff --git a/code/user/apps/video/video.c b/code/user/apps/video/video.c index 8edc519..cb2b35c 100644 --- a/code/user/apps/video/video.c +++ b/code/user/apps/video/video.c @@ -150,7 +150,7 @@ int main(void) { uint32_t file = 0; uint32_t status = open_file_view(pathView, &file); - if (status != STATUS_SUCCESS) { + if (status != NTLSTATUS_SUCCESS) { char pathBuf[260]; print("video: failed to open input file: "); print(path_to_cstr(pathView, pathBuf, sizeof(pathBuf))); @@ -160,7 +160,7 @@ int main(void) { uint64_t fileSize = 0; status = SysGetFileSize(file, &fileSize); - if (status != STATUS_SUCCESS) { + if (status != NTLSTATUS_SUCCESS) { SysCloseHandle(file); fail_status("SysGetFileSize", status); } @@ -172,7 +172,7 @@ int main(void) { uint32_t mapping = 0; status = SysCreateFileMapping(file, SYS_VM_READ, SYS_MAP_FLAG_NONE, fileSize, &mapping); - if (status != STATUS_SUCCESS || !mapping) { + if (status != NTLSTATUS_SUCCESS || !mapping) { SysCloseHandle(file); fail_status("SysCreateFileMapping", status); } @@ -180,7 +180,7 @@ int main(void) { void* buf = 0; status = SysMapFile(mapping, 0, (size_t)fileSize, SYS_MAP_ACCESS_READ, SYS_MAP_FLAG_NONE, &buf); - if (status != STATUS_SUCCESS || !buf) { + if (status != NTLSTATUS_SUCCESS || !buf) { SysCloseHandle(mapping); SysCloseHandle(file); fail_status("SysMapFile", status); @@ -214,9 +214,16 @@ int main(void) { } uint32_t surface = 0; - status = SysCreateSurface(width, height, SYS_SURFACE_FORMAT_XRGB8888, - SYS_SURFACE_FLAG_NONE, &surface); - if (status != STATUS_SUCCESS || !surface) { + SYS_CREATE_SURFACE_REQUEST surfaceReq; + memset(&surfaceReq, 0, sizeof(surfaceReq)); + surfaceReq.Size = sizeof(surfaceReq); + surfaceReq.Width = width; + surfaceReq.Height = height; + surfaceReq.Format = SYS_SURFACE_FORMAT_XRGB8888; + surfaceReq.Flags = SYS_SURFACE_FLAG_NONE; + surfaceReq.HandleOut = &surface; + status = SysCreateSurface(&surfaceReq); + if (status != NTLSTATUS_SUCCESS || !surface) { BinkClose(b); SysFreeVm(buf); fail_status("SysCreateSurface", status); @@ -225,7 +232,7 @@ int main(void) { void* surfaceBase = 0; uint32_t pitchBytes = 0; status = SysMapSurface(surface, &surfaceBase, &pitchBytes); - if (status != STATUS_SUCCESS || !surfaceBase || pitchBytes < width * sizeof(uint32_t)) { + if (status != NTLSTATUS_SUCCESS || !surfaceBase || pitchBytes < width * sizeof(uint32_t)) { SysCloseHandle(surface); BinkClose(b); SysFreeVm(buf); @@ -253,7 +260,7 @@ int main(void) { BinkCopyToBuffer(b, surfaceBase, pitchBytes, height, 0, 0, BINKSURFACE32); status = SysPresentSurface(surface, &fullFrame, 1); - if (status != STATUS_SUCCESS) { + if (status != NTLSTATUS_SUCCESS) { SysCloseHandle(surface); BinkClose(b); SysFreeVm(buf); diff --git a/code/user/personalities/posix/posix_dir.c b/code/user/personalities/posix/posix_dir.c index 71c9039..24e3da5 100644 --- a/code/user/personalities/posix/posix_dir.c +++ b/code/user/personalities/posix/posix_dir.c @@ -82,7 +82,7 @@ __declspec(dllexport) char* realpath(const char* path, char* resolved_path) { &required, }; uint32_t status = SysRealPath(&query); - if (status != STATUS_SUCCESS) { errno = PosixStatusToErrno(status); return (char*)0; } + if (status != NTLSTATUS_SUCCESS) { errno = PosixStatusToErrno(status); return (char*)0; } if (required == 0 || required > SYS_CWD_MAX) { errno = ERANGE; return (char*)0; } char nativeResolved[SYS_CWD_MAX]; @@ -95,7 +95,7 @@ __declspec(dllexport) char* realpath(const char* path, char* resolved_path) { &required, }; status = SysRealPath(&request); - if (status != STATUS_SUCCESS) { errno = PosixStatusToErrno(status); return (char*)0; } + if (status != NTLSTATUS_SUCCESS) { errno = PosixStatusToErrno(status); return (char*)0; } char posix[SYS_CWD_MAX]; NativeToPosix(nativeResolved, posix, sizeof(posix)); diff --git a/code/user/personalities/posix/posix_dlfcn.c b/code/user/personalities/posix/posix_dlfcn.c index 590047d..7130bd0 100644 --- a/code/user/personalities/posix/posix_dlfcn.c +++ b/code/user/personalities/posix/posix_dlfcn.c @@ -58,7 +58,7 @@ __declspec(dllexport) void* dlopen(const char* filename, int flags) { req.ModuleHandleOut = &handle; uint32_t status = SysLoadModule(&req); - if (status != STATUS_SUCCESS || handle == 0) { + if (status != NTLSTATUS_SUCCESS || handle == 0) { DlSetStatusError("dlopen failed", status); return 0; } @@ -84,7 +84,7 @@ __declspec(dllexport) void* dlsym(void* handle, const char* symbol) { req.AddressOut = &address; uint32_t status = SysGetModuleExport(&req); - if (status != STATUS_SUCCESS || address == 0) { + if (status != NTLSTATUS_SUCCESS || address == 0) { DlSetStatusError("dlsym failed", status); return 0; } @@ -102,7 +102,7 @@ __declspec(dllexport) int dlclose(void* handle) { } uint32_t status = SysUnloadModule((uint32_t)(uintptr_t)handle); - if (status != STATUS_SUCCESS) { + if (status != NTLSTATUS_SUCCESS) { DlSetStatusError("dlclose failed", status); return -1; } diff --git a/code/user/personalities/posix/posix_fd.c b/code/user/personalities/posix/posix_fd.c index 05bbbbc..3bf8288 100644 --- a/code/user/personalities/posix/posix_fd.c +++ b/code/user/personalities/posix/posix_fd.c @@ -9,23 +9,23 @@ int errno = 0; // Implements the status To Errno operation. int PosixStatusToErrno(uint32_t s) { switch (s) { - case STATUS_SUCCESS: return 0; - case STATUS_NOT_SUPPORTED: return ENOSYS; - case STATUS_TIMEOUT: return EAGAIN; - case STATUS_WOULD_BLOCK: return EAGAIN; - case STATUS_INVALID_PARAMETER: return EINVAL; - case STATUS_INVALID_HANDLE: return EBADF; - case STATUS_BUFFER_TOO_SMALL: return ERANGE; - case STATUS_NO_MEMORY: return ENOMEM; - case STATUS_ACCESS_DENIED: return EACCES; - case STATUS_NOT_FOUND: return ENOENT; - case STATUS_ALREADY_EXISTS: return EEXIST; - case STATUS_OBJECT_NAME_COLLISION: return EEXIST; - case STATUS_OBJECT_DEAD: return ECONNRESET; - case STATUS_QUEUE_FULL: return EAGAIN; - case STATUS_QUEUE_EMPTY: return EAGAIN; - case STATUS_CANCELLED: return ECANCELED; - case STATUS_NO_MORE_FILES: return ENOENT; + case NTLSTATUS_SUCCESS: return 0; + case NTLSTATUS_NOT_SUPPORTED: return ENOSYS; + case NTLSTATUS_TIMEOUT: return EAGAIN; + case NTLSTATUS_WOULD_BLOCK: return EAGAIN; + case NTLSTATUS_INVALID_PARAMETER: return EINVAL; + case NTLSTATUS_INVALID_HANDLE: return EBADF; + case NTLSTATUS_BUFFER_TOO_SMALL: return ERANGE; + case NTLSTATUS_NO_MEMORY: return ENOMEM; + case NTLSTATUS_ACCESS_DENIED: return EACCES; + case NTLSTATUS_NOT_FOUND: return ENOENT; + case NTLSTATUS_ALREADY_EXISTS: return EEXIST; + case NTLSTATUS_OBJECT_NAME_COLLISION: return EEXIST; + case NTLSTATUS_OBJECT_DEAD: return ECONNRESET; + case NTLSTATUS_QUEUE_FULL: return EAGAIN; + case NTLSTATUS_QUEUE_EMPTY: return EAGAIN; + case NTLSTATUS_CANCELLED: return ECANCELED; + case NTLSTATUS_NO_MORE_FILES: return ENOENT; default: return EIO; } } diff --git a/code/user/personalities/posix/posix_io.c b/code/user/personalities/posix/posix_io.c index b8f956e..aa19c8d 100644 --- a/code/user/personalities/posix/posix_io.c +++ b/code/user/personalities/posix/posix_io.c @@ -15,7 +15,7 @@ __declspec(dllexport) void clearscreen(void) { // Implements the clearkeyboard operation. __declspec(dllexport) void clearkeyboard(void) { INPUT_KEY key; - while (SysPollKeyboard(&key) == STATUS_SUCCESS) { + while (SysPollKeyboard(&key) == NTLSTATUS_SUCCESS) { char ignored; (void)SysReadKeyboardChar(&ignored); } @@ -90,7 +90,7 @@ __declspec(dllexport) ssize_t read(int fd, void* buf, size_t count) { char* dst = (char*)buf; for (size_t i = 0; i < count; i++) { uint32_t s = SysReadKeyboardChar(&dst[i]); - if (s != STATUS_SUCCESS) { errno = PosixStatusToErrno(s); return -1; } + if (s != NTLSTATUS_SUCCESS) { errno = PosixStatusToErrno(s); return -1; } if (dst[i] == '\n' || dst[i] == '\r') return (ssize_t)(i + 1); } return (ssize_t)count; diff --git a/code/user/personalities/posix/posix_mman.c b/code/user/personalities/posix/posix_mman.c index 5a1ebdb..6692cf4 100644 --- a/code/user/personalities/posix/posix_mman.c +++ b/code/user/personalities/posix/posix_mman.c @@ -52,7 +52,7 @@ __declspec(dllexport) void* mmap(void* addr, size_t length, int prot, uint32_t mapping = 0; uint32_t s = SysCreateFileMapping(e->KHandle, protect, SYS_MAP_FLAG_NONE, maxSize, &mapping); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { errno = PosixStatusToErrno(s); return MAP_FAILED; } @@ -62,7 +62,7 @@ __declspec(dllexport) void* mmap(void* addr, size_t length, int prot, PosixProtToSysMapAccess(prot, flags), SYS_MAP_FLAG_NONE, &base); SysCloseHandle(mapping); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { errno = PosixStatusToErrno(s); return MAP_FAILED; } @@ -73,7 +73,7 @@ __declspec(dllexport) int munmap(void* addr, size_t length) { (void)length; if (!addr) { errno = EINVAL; return -1; } uint32_t s = SysFreeVm(addr); - if (s != STATUS_SUCCESS) { errno = PosixStatusToErrno(s); return -1; } + if (s != NTLSTATUS_SUCCESS) { errno = PosixStatusToErrno(s); return -1; } return 0; } diff --git a/code/user/personalities/posix/posix_socket.c b/code/user/personalities/posix/posix_socket.c index 5b88d61..2b4c1ec 100644 --- a/code/user/personalities/posix/posix_socket.c +++ b/code/user/personalities/posix/posix_socket.c @@ -535,7 +535,14 @@ __declspec(dllexport) int poll(struct pollfd* fds, nfds_t nfds, int timeout) { size_t ready = 0; uint32_t timeoutMs = timeout < 0 ? SYS_POLL_TIMEOUT_INFINITE : (uint32_t)timeout; - uint32_t s = SysPoll(kfds, nfds, timeoutMs, &ready); + SYS_POLL_REQUEST req; + memset(&req, 0, sizeof(req)); + req.Size = sizeof(req); + req.TimeoutMs = timeoutMs; + req.Fds = kfds; + req.Count = nfds; + req.ReadyOut = &ready; + KSTATUS s = SysPoll(&req); if (s != 0) { free(kfds); errno = PosixStatusToErrno(s); diff --git a/code/user/personalities/win32/kernel32.c b/code/user/personalities/win32/kernel32.c index 592dd8b..0f2211a 100644 --- a/code/user/personalities/win32/kernel32.c +++ b/code/user/personalities/win32/kernel32.c @@ -23,12 +23,14 @@ #include #include #include +#include extern size_t _malloc_usable_size(const void* ptr); // Types. typedef void* HANDLE; typedef unsigned long DWORD; +typedef unsigned long long DWORD64; typedef unsigned short WORD; typedef int BOOL; typedef unsigned char BYTE; @@ -252,13 +254,13 @@ static uint32_t K32SetCwdNative(const char* path) { // Implements the k32 Get Cwd Native operation. static uint32_t K32GetCwdNative(char* buffer, size_t capacity, size_t* lengthOut) { SYS_STRING_VIEW cwd = SysGetCurrentDirectoryView(); - if ((cwd.Length && !cwd.Data) || cwd.Length > SYS_CWD_MAX) return STATUS_INVALID_PARAMETER; + if ((cwd.Length && !cwd.Data) || cwd.Length > SYS_CWD_MAX) return NTLSTATUS_INVALID_PARAMETER; if (lengthOut) *lengthOut = cwd.Length; - if (!buffer || cwd.Length + 1 > capacity) return STATUS_BUFFER_TOO_SMALL; + if (!buffer || cwd.Length + 1 > capacity) return NTLSTATUS_BUFFER_TOO_SMALL; if (cwd.Length) memcpy(buffer, cwd.Data, cwd.Length); buffer[cwd.Length] = '\0'; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } // Implements the k32 Create Process Native operation. @@ -289,6 +291,7 @@ typedef struct WIN32_THREAD_ENV { DWORD Reserved0; void* TlsSlots[WIN32_TLS_SLOTS]; void* FlsSlots[FLS_MAX_SLOTS]; + void* ExceptionFrameHead; } WIN32_THREAD_ENV; static WIN32_THREAD_ENV gFallbackThreadEnv; @@ -429,7 +432,7 @@ __declspec(dllexport) void OutputDebugStringA(const char* str) { // Queries the native monotonic tick frequency. static uint64_t K32TickFrequency(void) { uint64_t frequency = 0; - if (SysGetTickFrequency(&frequency) != STATUS_SUCCESS) return 0; + if (SysGetTickFrequency(&frequency) != NTLSTATUS_SUCCESS) return 0; return frequency; } @@ -525,9 +528,17 @@ __declspec(dllexport) void* VirtualAlloc(void* lpAddress, size_t dwSize, size_t pages = (dwSize + 4095u) / 4096u; void* base = NULL; uint32_t flags = lpAddress ? SYS_VM_FLAG_FIXED : SYS_VM_FLAG_NONE; - uint32_t s = SysAllocVm(lpAddress, pages, WinProtectToSysVm(flProtect), flags, &base); - if (s != STATUS_SUCCESS) { - gLastError = (s == STATUS_NOT_FOUND || s == STATUS_INVALID_PARAMETER) ? 87 : 8; + SYS_ALLOC_VM_REQUEST req; + memset(&req, 0, sizeof(req)); + req.Size = sizeof(req); + req.PreferredBase = lpAddress; + req.PageCount = pages; + req.Protect = WinProtectToSysVm(flProtect); + req.Flags = flags; + req.BaseOut = &base; + KSTATUS s = SysAllocVm(&req); + if (s != NTLSTATUS_SUCCESS) { + gLastError = (s == NTLSTATUS_NOT_FOUND || s == NTLSTATUS_INVALID_PARAMETER) ? 87 : 8; return NULL; } return base; @@ -538,7 +549,7 @@ __declspec(dllexport) BOOL VirtualFree(void* lpAddress, size_t dwSize, DWORD dwF (void)dwSize; (void)dwFreeType; if (!lpAddress) return TRUE; uint32_t s = SysFreeVm(lpAddress); - if (s != STATUS_SUCCESS) { gLastError = 87; return FALSE; } + if (s != NTLSTATUS_SUCCESS) { gLastError = 87; return FALSE; } return TRUE; } @@ -549,7 +560,7 @@ __declspec(dllexport) BOOL VirtualProtect(void* lpAddress, size_t dwSize, uint32_t oldSysProtect = 0; uint32_t s = SysProtectVm(lpAddress, pages, WinProtectToSysVm(flNewProtect), lpflOldProtect ? &oldSysProtect : NULL); - if (s != STATUS_SUCCESS) { gLastError = 87; return FALSE; } + if (s != NTLSTATUS_SUCCESS) { gLastError = 87; return FALSE; } if (lpflOldProtect) *lpflOldProtect = SysProtectVmToWin(oldSysProtect); return TRUE; } @@ -564,7 +575,7 @@ __declspec(dllexport) size_t VirtualQuery(const void* lpAddress, SYS_VM_REGION_INFO info; uint32_t s = SysQueryVm((void*)lpAddress, &info); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { gLastError = 87; return 0; } @@ -600,8 +611,8 @@ __declspec(dllexport) HANDLE CreateFileMappingA(HANDLE hFile, SYS_MAP_FLAG_NONE, maximumSize, &kh); - if (s != STATUS_SUCCESS) { - gLastError = (s == STATUS_NOT_SUPPORTED) ? 120 : ((s == STATUS_NO_MEMORY) ? 8 : 87); + if (s != NTLSTATUS_SUCCESS) { + gLastError = (s == NTLSTATUS_NOT_SUPPORTED) ? 120 : ((s == NTLSTATUS_NO_MEMORY) ? 8 : 87); return NULL; } return KH_TO_HANDLE(kh); @@ -636,8 +647,8 @@ __declspec(dllexport) void* MapViewOfFile(HANDLE hFileMappingObject, WinFileMapAccessToSys(dwDesiredAccess), SYS_MAP_FLAG_NONE, &base); - if (s != STATUS_SUCCESS) { - gLastError = (s == STATUS_NOT_SUPPORTED) ? 120 : ((s == STATUS_NO_MEMORY) ? 8 : 87); + if (s != NTLSTATUS_SUCCESS) { + gLastError = (s == NTLSTATUS_NOT_SUPPORTED) ? 120 : ((s == NTLSTATUS_NO_MEMORY) ? 8 : 87); return NULL; } return base; @@ -646,7 +657,7 @@ __declspec(dllexport) void* MapViewOfFile(HANDLE hFileMappingObject, __declspec(dllexport) BOOL UnmapViewOfFile(const void* lpBaseAddress) { if (!lpBaseAddress) { gLastError = 87; return FALSE; } uint32_t s = SysFreeVm((void*)lpBaseAddress); - if (s != STATUS_SUCCESS) { gLastError = 87; return FALSE; } + if (s != NTLSTATUS_SUCCESS) { gLastError = 87; return FALSE; } return TRUE; } @@ -663,7 +674,7 @@ __declspec(dllexport) BOOL FlushViewOfFile(const void* lpBaseAddress, size_t dwN // Returns whether one input key is currently held for Win32 adapters. static bool Win32IsInputKeyDown(INPUT_KEY key) { bool down = false; - return SysIsKeyDown(key, &down) == STATUS_SUCCESS && down; + return SysIsKeyDown(key, &down) == NTLSTATUS_SUCCESS && down; } // GetAsyncKeyState implementation over the canonical input key namespace. @@ -731,7 +742,7 @@ __declspec(dllexport) BOOL FlushConsoleInputBuffer(HANDLE hConsoleInput) { (void)hConsoleInput; // Drain the keyboard buffer by reading until empty. INPUT_KEY key; - while (SysPollKeyboard(&key) == STATUS_SUCCESS) { + while (SysPollKeyboard(&key) == NTLSTATUS_SUCCESS) { char ignored; (void)SysReadKeyboardChar(&ignored); } @@ -832,8 +843,8 @@ __declspec(dllexport) HANDLE CreateFileA(const char* name, uint32_t kh = 0; uint32_t s = K32OpenFileNative(translatedName, sysAccess, sysDisposition, &kh); if (s != 0) { - gLastError = (s == STATUS_OBJECT_NAME_COLLISION) ? 80 : - (s == STATUS_NOT_FOUND) ? 2 : 5; + gLastError = (s == NTLSTATUS_OBJECT_NAME_COLLISION) ? 80 : + (s == NTLSTATUS_NOT_FOUND) ? 2 : 5; return INVALID_HANDLE_VALUE; } @@ -1115,7 +1126,7 @@ __declspec(dllexport) HANDLE LoadLibraryA(const char* lpLibFileName) { req.ModuleHandleOut = &handle; uint32_t status = SysLoadModule(&req); - if (status != STATUS_SUCCESS) { + if (status != NTLSTATUS_SUCCESS) { gLastError = 126; return NULL; } @@ -1160,7 +1171,7 @@ __declspec(dllexport) void* GetProcAddress(HANDLE hModule, const char* lpProcNam req.Name = SysSvFromCstr(lpProcName); req.AddressOut = &address; uint32_t status = SysGetModuleExport(&req); - if (status != STATUS_SUCCESS || !address) { gLastError = 127; return NULL; } + if (status != NTLSTATUS_SUCCESS || !address) { gLastError = 127; return NULL; } return (void*)address; } @@ -1184,7 +1195,7 @@ __declspec(dllexport) BOOL FreeLibrary(HANDLE hLibModule) { if (!hLibModule || hLibModule == WIN32_HMODULE_WIN32 || hLibModule == WIN32_HMODULE_EXE) return TRUE; uint32_t status = SysUnloadModule((uint32_t)(uintptr_t)hLibModule); - if (status != STATUS_SUCCESS) { + if (status != NTLSTATUS_SUCCESS) { gLastError = 126; return FALSE; } @@ -1223,7 +1234,7 @@ __declspec(dllexport) BOOL TerminateProcess(HANDLE hProcess, unsigned int uExitC uint32_t s = SysKillProcess(HANDLE_TO_KH(hProcess), (int32_t)uExitCode); if (s != 0) { - gLastError = (s == STATUS_INVALID_HANDLE) ? 6 : 5; + gLastError = (s == NTLSTATUS_INVALID_HANDLE) ? 6 : 5; return FALSE; } return TRUE; @@ -1491,13 +1502,13 @@ static BOOL K32IsConsoleOutputHandle(HANDLE h) { // Implements the k32 Set Console Last Error operation. static void K32SetConsoleLastError(uint32_t status) { switch (status) { - case STATUS_SUCCESS: + case NTLSTATUS_SUCCESS: gLastError = 0; break; - case STATUS_INVALID_PARAMETER: + case NTLSTATUS_INVALID_PARAMETER: gLastError = 87; break; - case STATUS_NO_MEMORY: + case NTLSTATUS_NO_MEMORY: gLastError = 8; break; default: @@ -1527,7 +1538,7 @@ __declspec(dllexport) BOOL ReadConsoleA(HANDLE hConsoleInput, while (i < nNumberOfCharsToRead) { char c = 0; - if (SysReadKeyboardChar(&c) != STATUS_SUCCESS) continue; + if (SysReadKeyboardChar(&c) != NTLSTATUS_SUCCESS) continue; // Ignore unmapped keys (Shift, Ctrl, etc.). if (c == 0) continue; @@ -1579,7 +1590,7 @@ __declspec(dllexport) BOOL GetConsoleScreenBufferInfo(HANDLE hConsoleOutput, SYS_CONSOLE_INFO info; uint32_t s = SysGetConsoleInfo(&info); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { K32SetConsoleLastError(s); return FALSE; } @@ -1610,7 +1621,7 @@ __declspec(dllexport) BOOL SetConsoleCursorPosition(HANDLE hConsoleOutput, } uint32_t s = SysSetConsoleCursor((int)dwCursorPosition.X, (int)dwCursorPosition.Y); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { K32SetConsoleLastError(s); return FALSE; } @@ -1639,7 +1650,7 @@ __declspec(dllexport) BOOL FillConsoleOutputCharacterA(HANDLE hConsoleOutput, (int)dwWriteCoord.Y, (size_t)nLength, &written); if (lpNumberOfCharsWritten) *lpNumberOfCharsWritten = (DWORD)written; - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { K32SetConsoleLastError(s); return FALSE; } @@ -1668,7 +1679,7 @@ __declspec(dllexport) BOOL FillConsoleOutputAttribute(HANDLE hConsoleOutput, (int)dwWriteCoord.Y, (size_t)nLength, &written); if (lpNumberOfAttrsWritten) *lpNumberOfAttrsWritten = (DWORD)written; - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { K32SetConsoleLastError(s); return FALSE; } @@ -2220,7 +2231,7 @@ __declspec(dllexport) void GetSystemTime(SYSTEMTIME* lpSystemTime) { if (!lpSystemTime) return; SYS_SYSTEM_TIME st; - if (SysGetSystemTime(&st) != STATUS_SUCCESS) { + if (SysGetSystemTime(&st) != NTLSTATUS_SUCCESS) { memset(lpSystemTime, 0, sizeof(*lpSystemTime)); return; } @@ -2258,7 +2269,7 @@ __declspec(dllexport) void GetSystemTimeAsFileTime(void* lpSystemTimeAsFileTime) SYS_SYSTEM_TIME st; uint64_t ft; - if (SysGetSystemTime(&st) == STATUS_SUCCESS) { + if (SysGetSystemTime(&st) == NTLSTATUS_SUCCESS) { ft = K32EpochToFileTime(st.EpochSeconds, st.Nanosecond); } else { uint64_t frequency = K32TickFrequency(); @@ -2436,32 +2447,504 @@ __declspec(dllexport) DWORD GetFileType(HANDLE hFile) { // Exception Handling & Debugging. +#define EXCEPTION_CONTINUE_EXECUTION ((LONG)-1) #define EXCEPTION_CONTINUE_SEARCH 0 #define EXCEPTION_EXECUTE_HANDLER 1 +#define EXCEPTION_NONCONTINUABLE 0x1UL +#define EXCEPTION_MAXIMUM_PARAMETERS SYS_EXCEPTION_MAXIMUM_PARAMETERS +#define WIN_VECTORED_MAX_HANDLERS 16u +#define WIN_SEH_MAX_FRAMES 16u -// Implements the add Vectored Exception Handler operation. -__declspec(dllexport) void* AddVectoredExceptionHandler(unsigned long First, void* Handler) { - (void)First; (void)Handler; - // Return a non-NULL sentinel so callers can pass it to RemoveVectoredExceptionHandler. - return (void*)(uintptr_t)0x56455843UL; // 'VEXC' +typedef struct _EXCEPTION_RECORD { + DWORD ExceptionCode; + DWORD ExceptionFlags; + struct _EXCEPTION_RECORD* ExceptionRecord; + void* ExceptionAddress; + DWORD NumberParameters; + uintptr_t ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; +} EXCEPTION_RECORD; + +typedef struct _CONTEXT { + DWORD64 P1Home; + DWORD64 P2Home; + DWORD64 P3Home; + DWORD64 P4Home; + DWORD64 P5Home; + DWORD64 P6Home; + DWORD ContextFlags; + DWORD MxCsr; + WORD SegCs; + WORD SegDs; + WORD SegEs; + WORD SegFs; + WORD SegGs; + WORD SegSs; + DWORD EFlags; + DWORD64 Dr0; + DWORD64 Dr1; + DWORD64 Dr2; + DWORD64 Dr3; + DWORD64 Dr6; + DWORD64 Dr7; + DWORD64 Rax; + DWORD64 Rcx; + DWORD64 Rdx; + DWORD64 Rbx; + DWORD64 Rsp; + DWORD64 Rbp; + DWORD64 Rsi; + DWORD64 Rdi; + DWORD64 R8; + DWORD64 R9; + DWORD64 R10; + DWORD64 R11; + DWORD64 R12; + DWORD64 R13; + DWORD64 R14; + DWORD64 R15; + DWORD64 Rip; +} CONTEXT; + +typedef struct _EXCEPTION_POINTERS { + EXCEPTION_RECORD* ExceptionRecord; + CONTEXT* ContextRecord; +} EXCEPTION_POINTERS; + +typedef LONG (*PVECTORED_EXCEPTION_HANDLER)(EXCEPTION_POINTERS* ExceptionInfo); + +typedef LONG (*PRTL_EXCEPTION_FRAME_HANDLER)(EXCEPTION_POINTERS* ExceptionInfo, void* UserContext); + +typedef struct _RTL_EXCEPTION_FRAME { + DWORD Size; + DWORD Flags; + struct _RTL_EXCEPTION_FRAME* Previous; + PRTL_EXCEPTION_FRAME_HANDLER Handler; + void* UserContext; +} RTL_EXCEPTION_FRAME; + +typedef struct WIN_VECTORED_HANDLER_ENTRY { + uint32_t Active; + uint32_t IsContinue; + uint32_t Previous; + uint32_t Next; + PVECTORED_EXCEPTION_HANDLER Handler; +} WIN_VECTORED_HANDLER_ENTRY; + +typedef struct WIN_VECTORED_HANDLER_SNAPSHOT { + PVECTORED_EXCEPTION_HANDLER Handler; +} WIN_VECTORED_HANDLER_SNAPSHOT; + +typedef struct WIN_SEH_FRAME_SNAPSHOT { + PRTL_EXCEPTION_FRAME_HANDLER Handler; + void* UserContext; +} WIN_SEH_FRAME_SNAPSHOT; + +static volatile long gWinVectoredLock; +static uint32_t gWinVectoredExceptionHead = UINT32_MAX; +static uint32_t gWinVectoredExceptionTail = UINT32_MAX; +static uint32_t gWinVectoredContinueHead = UINT32_MAX; +static uint32_t gWinVectoredContinueTail = UINT32_MAX; +static WIN_VECTORED_HANDLER_ENTRY gWinVectoredHandlers[WIN_VECTORED_MAX_HANDLERS]; +static void* gWinExceptionNativeHandle; + +// Acquires the Win32 vectored-handler list lock. +static void WinpVectoredLock(void) { + while (_InterlockedCompareExchange(&gWinVectoredLock, 1, 0) != 0) + _mm_pause(); + _ReadWriteBarrier(); } -// Releases vectored Exception Handler. +// Releases the Win32 vectored-handler list lock. +static void WinpVectoredUnlock(void) { + _ReadWriteBarrier(); + _InterlockedExchange(&gWinVectoredLock, 0); +} + +// Returns the list head slot for one vectored-handler kind. +static uint32_t* WinpVectoredHeadSlot(uint32_t isContinue) { + return isContinue ? &gWinVectoredContinueHead : &gWinVectoredExceptionHead; +} + +// Returns the list tail slot for one vectored-handler kind. +static uint32_t* WinpVectoredTailSlot(uint32_t isContinue) { + return isContinue ? &gWinVectoredContinueTail : &gWinVectoredExceptionTail; +} + +// Copies native exception state into the Win32-facing exception record. +static void WinpBuildExceptionRecord(const SYS_EXCEPTION_RECORD* source, EXCEPTION_RECORD* target) { + memset(target, 0, sizeof(*target)); + target->ExceptionCode = source->Code; + if (source->Flags & SYS_EXCEPTION_FLAG_NONCONTINUABLE) + target->ExceptionFlags |= EXCEPTION_NONCONTINUABLE; + target->ExceptionAddress = (void*)(uintptr_t)source->ExceptionAddress; + target->NumberParameters = source->ParameterCount; + if (target->NumberParameters > EXCEPTION_MAXIMUM_PARAMETERS) + target->NumberParameters = EXCEPTION_MAXIMUM_PARAMETERS; + for (DWORD i = 0; i < target->NumberParameters; i++) + target->ExceptionInformation[i] = (uintptr_t)source->Parameters[i]; +} + +// Copies native user context into the subset of x64 CONTEXT currently exposed by Win32. +static void WinpBuildContext(const SYS_USER_CONTEXT* source, CONTEXT* target) { + memset(target, 0, sizeof(*target)); + target->SegCs = (WORD)source->SegCs; + target->SegSs = (WORD)source->SegSs; + target->EFlags = (DWORD)source->Rflags; + target->Rax = source->Rax; + target->Rcx = source->Rcx; + target->Rdx = source->Rdx; + target->Rbx = source->Rbx; + target->Rsp = source->Rsp; + target->Rbp = source->Rbp; + target->Rsi = source->Rsi; + target->Rdi = source->Rdi; + target->R8 = source->R8; + target->R9 = source->R9; + target->R10 = source->R10; + target->R11 = source->R11; + target->R12 = source->R12; + target->R13 = source->R13; + target->R14 = source->R14; + target->R15 = source->R15; + target->Rip = source->Rip; +} + +// Copies handler-edited Win32 context back to the native resume context. +static void WinpStoreContext(SYS_USER_CONTEXT* target, const CONTEXT* source) { + target->Rflags = source->EFlags; + target->Rax = source->Rax; + target->Rcx = source->Rcx; + target->Rdx = source->Rdx; + target->Rbx = source->Rbx; + target->Rsp = source->Rsp; + target->Rbp = source->Rbp; + target->Rsi = source->Rsi; + target->Rdi = source->Rdi; + target->R8 = source->R8; + target->R9 = source->R9; + target->R10 = source->R10; + target->R11 = source->R11; + target->R12 = source->R12; + target->R13 = source->R13; + target->R14 = source->R14; + target->R15 = source->R15; + target->Rip = source->Rip; +} + +// Copies one vectored-handler list so callbacks can run without the list lock. +static size_t WinpSnapshotVectoredHandlers(uint32_t isContinue, + WIN_VECTORED_HANDLER_SNAPSHOT* snapshot, + size_t capacity) { + size_t count = 0; + + WinpVectoredLock(); + uint32_t head = *WinpVectoredHeadSlot(isContinue); + for (uint32_t index = head; + index != UINT32_MAX && count < capacity; + index = gWinVectoredHandlers[index].Next) { + WIN_VECTORED_HANDLER_ENTRY* entry = &gWinVectoredHandlers[index]; + if (!entry->Active || entry->IsContinue != isContinue || !entry->Handler) + continue; + snapshot[count++].Handler = entry->Handler; + } + WinpVectoredUnlock(); + + return count; +} + +// Runs one Win32 vectored-handler list against the current exception state. +static int WinpRunVectoredList(uint32_t isContinue, + EXCEPTION_POINTERS* pointers, + SYS_USER_CONTEXT* nativeContext) { + WIN_VECTORED_HANDLER_SNAPSHOT snapshot[WIN_VECTORED_MAX_HANDLERS]; + size_t count = WinpSnapshotVectoredHandlers(isContinue, snapshot, WIN_VECTORED_MAX_HANDLERS); + + for (size_t i = 0; i < count; i++) { + LONG disposition = snapshot[i].Handler(pointers); + if (disposition == EXCEPTION_CONTINUE_SEARCH) + continue; + if (disposition == EXCEPTION_CONTINUE_EXECUTION) { + if (pointers->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) + return NTL_EXCEPTION_TERMINATE_PROCESS; + WinpStoreContext(nativeContext, pointers->ContextRecord); + return NTL_EXCEPTION_CONTINUE_EXECUTION; + } + } + + return NTL_EXCEPTION_CONTINUE_SEARCH; +} + +// Returns the current thread's top runtime-registered SEH frame. +static RTL_EXCEPTION_FRAME* WinpSehFrameHead(void) { + return (RTL_EXCEPTION_FRAME*)K32ThreadEnv()->ExceptionFrameHead; +} + +// Updates the current thread's top runtime-registered SEH frame. +static void WinpSetSehFrameHead(RTL_EXCEPTION_FRAME* frame) { + K32ThreadEnv()->ExceptionFrameHead = frame; +} + +// Copies the current SEH frame chain so callbacks can mutate registration safely. +static size_t WinpSnapshotSehFrames(WIN_SEH_FRAME_SNAPSHOT* snapshot, size_t capacity) { + size_t count = 0; + + for (RTL_EXCEPTION_FRAME* frame = WinpSehFrameHead(); + frame && count < capacity; + frame = frame->Previous) { + if (frame->Size != sizeof(*frame) || !frame->Handler) + break; + snapshot[count].Handler = frame->Handler; + snapshot[count].UserContext = frame->UserContext; + count++; + } + + return count; +} + +// Runs runtime-registered SEH frames after VEH has declined the exception. +static int WinpRunSehFrames(EXCEPTION_POINTERS* pointers, SYS_USER_CONTEXT* nativeContext) { + WIN_SEH_FRAME_SNAPSHOT snapshot[WIN_SEH_MAX_FRAMES]; + size_t count = WinpSnapshotSehFrames(snapshot, WIN_SEH_MAX_FRAMES); + + for (size_t i = 0; i < count; i++) { + LONG disposition = snapshot[i].Handler(pointers, snapshot[i].UserContext); + if (disposition == EXCEPTION_CONTINUE_SEARCH) + continue; + if (disposition == EXCEPTION_CONTINUE_EXECUTION) { + if (pointers->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) + return NTL_EXCEPTION_TERMINATE_PROCESS; + WinpStoreContext(nativeContext, pointers->ContextRecord); + return NTL_EXCEPTION_CONTINUE_EXECUTION; + } + if (disposition == EXCEPTION_EXECUTE_HANDLER) { + // Runtime frames do not have a compiler-generated landing pad yet. + return NTL_EXCEPTION_TERMINATE_PROCESS; + } + return NTL_EXCEPTION_TERMINATE_PROCESS; + } + + return NTL_EXCEPTION_CONTINUE_SEARCH; +} + +// Bridges the native exception runtime into Win32 exception policy. +static int WinpExceptionNativeDispatch(SYS_EXCEPTION_RECORD* record, SYS_USER_CONTEXT* context, void* userContext) { + (void)userContext; + + EXCEPTION_RECORD winRecord; + CONTEXT winContext; + EXCEPTION_POINTERS pointers; + WinpBuildExceptionRecord(record, &winRecord); + WinpBuildContext(context, &winContext); + pointers.ExceptionRecord = &winRecord; + pointers.ContextRecord = &winContext; + + int disposition = WinpRunVectoredList(0, &pointers, context); + if (disposition != NTL_EXCEPTION_CONTINUE_SEARCH) + return disposition; + + disposition = WinpRunSehFrames(&pointers, context); + if (disposition != NTL_EXCEPTION_CONTINUE_SEARCH) + return disposition; + + return WinpRunVectoredList(1, &pointers, context); +} + +// Ensures the Win32 exception bridge is registered with the native exception runtime. +static BOOL WinpEnsureExceptionBridge(void) { + if (gWinExceptionNativeHandle) + return TRUE; + + WinpVectoredLock(); + if (gWinExceptionNativeHandle) { + WinpVectoredUnlock(); + return TRUE; + } + + void* handle = NtlAddExceptionHandler(1, WinpExceptionNativeDispatch, NULL); + if (!handle) { + WinpVectoredUnlock(); + gLastError = 8; + return FALSE; + } + + gWinExceptionNativeHandle = handle; + WinpVectoredUnlock(); + return TRUE; +} + +// Adds one Win32 vectored exception or continue handler. +static void* WinpAddVectoredHandler(uint32_t isContinue, unsigned long first, void* handler) { + if (!handler) { + gLastError = 87; + return NULL; + } + if (!WinpEnsureExceptionBridge()) + return NULL; + + WinpVectoredLock(); + + uint32_t slot = UINT32_MAX; + for (uint32_t i = 0; i < WIN_VECTORED_MAX_HANDLERS; i++) { + if (!gWinVectoredHandlers[i].Active) { + slot = i; + break; + } + } + + if (slot == UINT32_MAX) { + WinpVectoredUnlock(); + gLastError = 8; + return NULL; + } + + uint32_t* head = WinpVectoredHeadSlot(isContinue); + uint32_t* tail = WinpVectoredTailSlot(isContinue); + WIN_VECTORED_HANDLER_ENTRY* entry = &gWinVectoredHandlers[slot]; + entry->Active = 1; + entry->IsContinue = isContinue; + entry->Handler = (PVECTORED_EXCEPTION_HANDLER)handler; + entry->Previous = UINT32_MAX; + entry->Next = UINT32_MAX; + + if (*head == UINT32_MAX) { + *head = slot; + *tail = slot; + } else if (first) { + entry->Next = *head; + gWinVectoredHandlers[*head].Previous = slot; + *head = slot; + } else { + entry->Previous = *tail; + gWinVectoredHandlers[*tail].Next = slot; + *tail = slot; + } + + WinpVectoredUnlock(); + return entry; +} + +// Removes one Win32 vectored exception or continue handler. +static unsigned long WinpRemoveVectoredHandler(uint32_t isContinue, void* handle) { + if (!handle) { + gLastError = 6; + return 0; + } + + WinpVectoredLock(); + + uint32_t slot = UINT32_MAX; + for (uint32_t i = 0; i < WIN_VECTORED_MAX_HANDLERS; i++) { + if (handle == &gWinVectoredHandlers[i]) { + slot = i; + break; + } + } + + if (slot == UINT32_MAX || !gWinVectoredHandlers[slot].Active || + gWinVectoredHandlers[slot].IsContinue != isContinue) { + WinpVectoredUnlock(); + gLastError = 6; + return 0; + } + + uint32_t* head = WinpVectoredHeadSlot(isContinue); + uint32_t* tail = WinpVectoredTailSlot(isContinue); + WIN_VECTORED_HANDLER_ENTRY* entry = &gWinVectoredHandlers[slot]; + if (entry->Previous != UINT32_MAX) + gWinVectoredHandlers[entry->Previous].Next = entry->Next; + else + *head = entry->Next; + + if (entry->Next != UINT32_MAX) + gWinVectoredHandlers[entry->Next].Previous = entry->Previous; + else + *tail = entry->Previous; + + memset(entry, 0, sizeof(*entry)); + entry->Previous = UINT32_MAX; + entry->Next = UINT32_MAX; + + WinpVectoredUnlock(); + return 1; +} + +// Registers one Win32 vectored exception handler. +__declspec(dllexport) void* AddVectoredExceptionHandler(unsigned long First, void* Handler) { + return WinpAddVectoredHandler(0, First, Handler); +} + +// Removes one Win32 vectored exception handler. __declspec(dllexport) unsigned long RemoveVectoredExceptionHandler(void* Handle) { - (void)Handle; - return 1; // success + return WinpRemoveVectoredHandler(0, Handle); +} + +// Registers one Win32 vectored continue handler. +__declspec(dllexport) void* AddVectoredContinueHandler(unsigned long First, void* Handler) { + return WinpAddVectoredHandler(1, First, Handler); +} + +// Removes one Win32 vectored continue handler. +__declspec(dllexport) unsigned long RemoveVectoredContinueHandler(void* Handle) { + return WinpRemoveVectoredHandler(1, Handle); +} + +// Pushes one explicit runtime SEH frame for tests and hand-written personality code. +__declspec(dllexport) void* RtlPushExceptionFrame(RTL_EXCEPTION_FRAME* Frame, + PRTL_EXCEPTION_FRAME_HANDLER Handler, + void* UserContext) { + if (!Frame || !Handler) { + gLastError = 87; + return NULL; + } + if (!WinpEnsureExceptionBridge()) + return NULL; + + memset(Frame, 0, sizeof(*Frame)); + Frame->Size = sizeof(*Frame); + Frame->Previous = WinpSehFrameHead(); + Frame->Handler = Handler; + Frame->UserContext = UserContext; + WinpSetSehFrameHead(Frame); + return Frame; +} + +// Pops the current explicit runtime SEH frame and enforces stack discipline. +__declspec(dllexport) BOOL RtlPopExceptionFrame(RTL_EXCEPTION_FRAME* Frame) { + if (!Frame || WinpSehFrameHead() != Frame) { + gLastError = 87; + return FALSE; + } + + WinpSetSehFrameHead(Frame->Previous); + memset(Frame, 0, sizeof(*Frame)); + return TRUE; } __declspec(dllexport) void RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const uintptr_t* lpArguments) { - (void)dwExceptionCode; (void)dwExceptionFlags; - (void)nNumberOfArguments; (void)lpArguments; - // Best-effort: nothing to unwind; just halt. - while (true) ; -} + uint64_t arguments[EXCEPTION_MAXIMUM_PARAMETERS]; + DWORD count = nNumberOfArguments; + if (count > EXCEPTION_MAXIMUM_PARAMETERS) + count = EXCEPTION_MAXIMUM_PARAMETERS; -typedef struct _EXCEPTION_POINTERS { void* ExceptionRecord; void* ContextRecord; } EXCEPTION_POINTERS; + for (DWORD i = 0; i < count; i++) + arguments[i] = lpArguments ? (uint64_t)lpArguments[i] : 0; + + SYS_RAISE_EXCEPTION_REQUEST request; + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + request.Code = dwExceptionCode; + request.Flags = (dwExceptionFlags & EXCEPTION_NONCONTINUABLE) ? + SYS_RAISE_EXCEPTION_FLAG_NONCONTINUABLE : + SYS_RAISE_EXCEPTION_FLAG_NONE; + request.ParameterCount = count; + request.Parameters = count ? arguments : NULL; + + uint32_t status = SysRaiseException(&request); + if (status != NTLSTATUS_SUCCESS) + SysExitProcess((int32_t)status); +} // Implements the unhandled Exception Filter operation. __declspec(dllexport) long UnhandledExceptionFilter(EXCEPTION_POINTERS* ExceptionInfo) { @@ -2483,7 +2966,7 @@ __declspec(dllexport) BOOL IsDebuggerPresent(void) { return FALSE; } -// RTL Exception / Unwind (SEH infrastructure - all stubs). +// RTL Exception / Unwind metadata helpers. typedef struct _RUNTIME_FUNCTION { unsigned int BeginAddress; diff --git a/code/user/personalities/win32/winmm.c b/code/user/personalities/win32/winmm.c index c9cff70..f3e4eaf 100644 --- a/code/user/personalities/win32/winmm.c +++ b/code/user/personalities/win32/winmm.c @@ -50,7 +50,7 @@ typedef struct { __declspec(dllexport) unsigned long timeGetTime(void) { uint64_t frequency = 0; - if (SysGetTickFrequency(&frequency) != STATUS_SUCCESS || !frequency) return 0; + if (SysGetTickFrequency(&frequency) != NTLSTATUS_SUCCESS || !frequency) return 0; return (unsigned long)SysTicksToMilliseconds(SysGetTick(), frequency); } diff --git a/code/user/runtime/heap.c b/code/user/runtime/heap.c index f71eb87..39d5cc8 100644 --- a/code/user/runtime/heap.c +++ b/code/user/runtime/heap.c @@ -116,8 +116,15 @@ static HEAP_SEGMENT* AddSegment(size_t payloadSize) { if (pages < USER_HEAP_MIN_PAGES) pages = USER_HEAP_MIN_PAGES; void* base = 0; - uint32_t s = SysAllocVm(0, pages, SYS_VM_READWRITE, SYS_VM_FLAG_NONE, &base); - if (s != STATUS_SUCCESS || !base) + SYS_ALLOC_VM_REQUEST req; + memset(&req, 0, sizeof(req)); + req.Size = sizeof(req); + req.PageCount = pages; + req.Protect = SYS_VM_READWRITE; + req.Flags = SYS_VM_FLAG_NONE; + req.BaseOut = &base; + KSTATUS s = SysAllocVm(&req); + if (s != NTLSTATUS_SUCCESS || !base) return (HEAP_SEGMENT*)0; HEAP_SEGMENT* seg = (HEAP_SEGMENT*)base; diff --git a/code/user/runtime/native_exception.c b/code/user/runtime/native_exception.c new file mode 100644 index 0000000..e3f9c5b --- /dev/null +++ b/code/user/runtime/native_exception.c @@ -0,0 +1,256 @@ +// Native user-mode exception runtime. This file owns process-local native handler dispatch. + +#include +#include +#include +#include +#include +#include + +#define NTL_EXCEPTION_MAX_HANDLERS 16u + +typedef struct NTL_EXCEPTION_HANDLER_ENTRY { + uint32_t Active; + uint32_t Previous; + uint32_t Next; + NTL_EXCEPTION_HANDLER Handler; + void* Context; +} NTL_EXCEPTION_HANDLER_ENTRY; + +typedef struct NTL_EXCEPTION_HANDLER_SNAPSHOT { + NTL_EXCEPTION_HANDLER Handler; + void* Context; +} NTL_EXCEPTION_HANDLER_SNAPSHOT; + +static volatile long gNtlExceptionLock; +static uint32_t gNtlExceptionListHead = UINT32_MAX; +static uint32_t gNtlExceptionListTail = UINT32_MAX; +static NTL_EXCEPTION_HANDLER_ENTRY gNtlExceptionHandlers[NTL_EXCEPTION_MAX_HANDLERS]; + +// Acquires the process-local exception handler lock. +static void NtlpExceptionLock(void) { + while (_InterlockedCompareExchange(&gNtlExceptionLock, 1, 0) != 0) + _mm_pause(); + _ReadWriteBarrier(); +} + +// Releases the process-local exception handler lock. +static void NtlpExceptionUnlock(void) { + _ReadWriteBarrier(); + _InterlockedExchange(&gNtlExceptionLock, 0); +} + +// Returns a generic status after a failed exception-continue syscall. +static uint32_t NtlpStatusOrFailure(uint32_t status) { + return status == NTLSTATUS_SUCCESS ? NTLSTATUS_FAILURE : status; +} + +// Asks the kernel to terminate the active exception dispatch. +static void NtlpTerminateExceptionDispatch(void) { + SYS_CONTINUE_EXCEPTION_REQUEST request; + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + request.Disposition = SYS_EXCEPTION_DISPOSITION_TERMINATE_PROCESS; + + uint32_t status = SysContinueException(&request); + for (;;) SysExitProcess((int32_t)NtlpStatusOrFailure(status)); +} + +// Asks the kernel to continue searching from the top-level native dispatcher. +static void NtlpContinueExceptionSearch(void) { + SYS_CONTINUE_EXCEPTION_REQUEST request; + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + request.Disposition = SYS_EXCEPTION_DISPOSITION_CONTINUE_SEARCH; + + uint32_t status = SysContinueException(&request); + for (;;) SysExitProcess((int32_t)NtlpStatusOrFailure(status)); +} + +// Asks the kernel to resume execution with a handler-edited user context. +static void NtlpContinueExecution(SYS_USER_CONTEXT* context) { + SYS_CONTINUE_EXCEPTION_REQUEST request; + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + request.Disposition = SYS_EXCEPTION_DISPOSITION_CONTINUE_EXECUTION; + request.Context = context; + + uint32_t status = SysContinueException(&request); + for (;;) SysExitProcess((int32_t)NtlpStatusOrFailure(status)); +} + +// Returns whether one kernel-provided exception frame has the expected ABI shape. +static int NtlpFrameIsValid(SYS_EXCEPTION_FRAME* frame) { + if (!frame) + return 0; + if (frame->Size != sizeof(*frame) || frame->Version != SYS_EXCEPTION_ABI_VERSION) + return 0; + if (frame->ExceptionRecord.Size != sizeof(frame->ExceptionRecord) || + frame->ExceptionRecord.Version != SYS_EXCEPTION_ABI_VERSION) + return 0; + if (frame->ContextRecord.Size != sizeof(frame->ContextRecord) || + frame->ContextRecord.Version != SYS_EXCEPTION_ABI_VERSION) + return 0; + return 1; +} + +// Copies the current handler list so callbacks can run without holding the list lock. +static size_t NtlpSnapshotExceptionHandlers(NTL_EXCEPTION_HANDLER_SNAPSHOT* snapshot, size_t capacity) { + size_t count = 0; + + NtlpExceptionLock(); + for (uint32_t index = gNtlExceptionListHead; + index != UINT32_MAX && count < capacity; + index = gNtlExceptionHandlers[index].Next) { + NTL_EXCEPTION_HANDLER_ENTRY* entry = &gNtlExceptionHandlers[index]; + if (!entry->Active || !entry->Handler) + continue; + snapshot[count].Handler = entry->Handler; + snapshot[count].Context = entry->Context; + count++; + } + NtlpExceptionUnlock(); + + return count; +} + +// Dispatches one kernel-delivered exception through the native handler list. +static void NtlpUserExceptionDispatcher(SYS_EXCEPTION_FRAME* frame) { + if (!NtlpFrameIsValid(frame)) + NtlpTerminateExceptionDispatch(); + + NTL_EXCEPTION_HANDLER_SNAPSHOT snapshot[NTL_EXCEPTION_MAX_HANDLERS]; + size_t count = NtlpSnapshotExceptionHandlers(snapshot, NTL_EXCEPTION_MAX_HANDLERS); + + for (size_t i = 0; i < count; i++) { + int disposition = snapshot[i].Handler(&frame->ExceptionRecord, + &frame->ContextRecord, + snapshot[i].Context); + if (disposition == NTL_EXCEPTION_CONTINUE_SEARCH) + continue; + if (disposition == NTL_EXCEPTION_CONTINUE_EXECUTION) + NtlpContinueExecution(&frame->ContextRecord); + if (disposition == NTL_EXCEPTION_TERMINATE_PROCESS) + NtlpTerminateExceptionDispatch(); + NtlpTerminateExceptionDispatch(); + } + + NtlpContinueExceptionSearch(); +} + +// Registers the native dispatcher for the current process when no other dispatcher owns the process. +NTL_EXCEPTION_API uint32_t NtlInitializeExceptionRuntime(void) { + NtlpExceptionLock(); + + SYS_EXCEPTION_DISPATCHER_REQUEST current; + memset(¤t, 0, sizeof(current)); + current.Size = sizeof(current); + uint32_t status = SysGetExceptionDispatcher(¤t); + if (status != NTLSTATUS_SUCCESS) { + NtlpExceptionUnlock(); + return status; + } + + if (current.DispatcherRoutine == NtlpUserExceptionDispatcher) { + NtlpExceptionUnlock(); + return NTLSTATUS_SUCCESS; + } + if (current.DispatcherRoutine) { + NtlpExceptionUnlock(); + return NTLSTATUS_ALREADY_EXISTS; + } + + SYS_EXCEPTION_DISPATCHER_REQUEST request; + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + request.DispatcherRoutine = NtlpUserExceptionDispatcher; + + status = SysSetExceptionDispatcher(&request); + NtlpExceptionUnlock(); + return status; +} + +// Adds one process-local native exception handler. +NTL_EXCEPTION_API void* NtlAddExceptionHandler(int first, NTL_EXCEPTION_HANDLER handler, void* context) { + if (!handler) + return 0; + if (NtlInitializeExceptionRuntime() != NTLSTATUS_SUCCESS) + return 0; + + NtlpExceptionLock(); + + uint32_t slot = UINT32_MAX; + for (uint32_t i = 0; i < NTL_EXCEPTION_MAX_HANDLERS; i++) { + if (!gNtlExceptionHandlers[i].Active) { + slot = i; + break; + } + } + + if (slot == UINT32_MAX) { + NtlpExceptionUnlock(); + return 0; + } + + NTL_EXCEPTION_HANDLER_ENTRY* entry = &gNtlExceptionHandlers[slot]; + entry->Active = 1; + entry->Handler = handler; + entry->Context = context; + entry->Previous = UINT32_MAX; + entry->Next = UINT32_MAX; + + if (gNtlExceptionListHead == UINT32_MAX) { + gNtlExceptionListHead = slot; + gNtlExceptionListTail = slot; + } else if (first) { + entry->Next = gNtlExceptionListHead; + gNtlExceptionHandlers[gNtlExceptionListHead].Previous = slot; + gNtlExceptionListHead = slot; + } else { + entry->Previous = gNtlExceptionListTail; + gNtlExceptionHandlers[gNtlExceptionListTail].Next = slot; + gNtlExceptionListTail = slot; + } + + NtlpExceptionUnlock(); + return entry; +} + +// Removes one process-local native exception handler. +NTL_EXCEPTION_API uint32_t NtlRemoveExceptionHandler(void* handle) { + if (!handle) + return NTLSTATUS_INVALID_PARAMETER; + + NtlpExceptionLock(); + + uint32_t slot = UINT32_MAX; + for (uint32_t i = 0; i < NTL_EXCEPTION_MAX_HANDLERS; i++) { + if (handle == &gNtlExceptionHandlers[i]) { + slot = i; + break; + } + } + + if (slot == UINT32_MAX || !gNtlExceptionHandlers[slot].Active) { + NtlpExceptionUnlock(); + return NTLSTATUS_NOT_FOUND; + } + + NTL_EXCEPTION_HANDLER_ENTRY* entry = &gNtlExceptionHandlers[slot]; + if (entry->Previous != UINT32_MAX) + gNtlExceptionHandlers[entry->Previous].Next = entry->Next; + else + gNtlExceptionListHead = entry->Next; + + if (entry->Next != UINT32_MAX) + gNtlExceptionHandlers[entry->Next].Previous = entry->Previous; + else + gNtlExceptionListTail = entry->Previous; + + memset(entry, 0, sizeof(*entry)); + entry->Previous = UINT32_MAX; + entry->Next = UINT32_MAX; + + NtlpExceptionUnlock(); + return NTLSTATUS_SUCCESS; +} diff --git a/code/user/runtime/native_start.c b/code/user/runtime/native_start.c new file mode 100644 index 0000000..fdcdf35 --- /dev/null +++ b/code/user/runtime/native_start.c @@ -0,0 +1,18 @@ +// Native process startup. This file owns process-local native runtime initialization before main runs. + +#include +#include +#include + +extern int main(void); + +// Initializes native process state and exits with main's return value. +void NtlNativeStart(void) { + uint32_t status = NtlInitializeExceptionRuntime(); + if (status != NTLSTATUS_SUCCESS) { + for (;;) SysExitProcess((int32_t)status); + } + + int exitCode = main(); + for (;;) SysExitProcess(exitCode); +} diff --git a/code/user/runtime/posix_start.c b/code/user/runtime/posix_start.c index 391e7a8..4615d22 100644 --- a/code/user/runtime/posix_start.c +++ b/code/user/runtime/posix_start.c @@ -1,13 +1,22 @@ // POSIX process startup. This file owns process-local POSIX personality initialization before main runs. +#include +#include +#include + extern int main(void); extern void exit(int status); extern void PosixFdInit(void); // Initializes POSIX process state and exits with main's return value. void PosixStart(void) { + uint32_t status = NtlInitializeExceptionRuntime(); + if (status != NTLSTATUS_SUCCESS) { + for (;;) SysExitProcess((int32_t)status); + } + PosixFdInit(); - int status = main(); - exit(status); + int exitCode = main(); + exit(exitCode); for (;;) {} } diff --git a/code/user/syscall/syscall_nr.inc b/code/user/syscall/syscall_nr.inc index cfd7a83..c084ed8 100644 --- a/code/user/syscall/syscall_nr.inc +++ b/code/user/syscall/syscall_nr.inc @@ -1,140 +1,145 @@ ; Syscall numbers shared by MASM user-mode stubs. -; Process, threads, modules, waits, and APC. -SYS_EXIT_PROCESS EQU 0 -SYS_EXIT_THREAD EQU 1 -SYS_CREATE_PROCESS EQU 2 -SYS_OPEN_PROCESS EQU 3 -SYS_GET_PROCESS_EXIT_CODE EQU 4 -SYS_KILL_PROCESS EQU 5 -SYS_GET_PROCESS_LIST EQU 6 -SYS_GET_PROCESS_PID EQU 7 -SYS_CREATE_THREAD EQU 8 -SYS_GET_THREAD_LIST EQU 9 -SYS_LOAD_MODULE EQU 10 -SYS_UNLOAD_MODULE EQU 11 -SYS_GET_MODULE_INFO EQU 12 -SYS_GET_MODULE_EXPORT EQU 13 -SYS_GET_MODULE_LIST EQU 14 -SYS_GET_CURRENT_TID EQU 15 -SYS_GET_CURRENT_PID EQU 16 -SYS_SET_THREAD_PRIORITY EQU 17 -SYS_YIELD EQU 18 -SYS_SLEEP EQU 19 -SYS_WAIT_SINGLE EQU 20 -SYS_WAIT_MANY EQU 21 -SYS_SET_USER_APC_DISPATCHER EQU 22 -SYS_APC_RETURN EQU 23 +; Process, threads, modules, waits, APC, and exceptions. +SYS_EXIT_PROCESS EQU 0 +SYS_EXIT_THREAD EQU 1 +SYS_CREATE_PROCESS EQU 2 +SYS_OPEN_PROCESS EQU 3 +SYS_GET_PROCESS_EXIT_CODE EQU 4 +SYS_KILL_PROCESS EQU 5 +SYS_GET_PROCESS_LIST EQU 6 +SYS_GET_PROCESS_PID EQU 7 +SYS_CREATE_THREAD EQU 8 +SYS_GET_THREAD_LIST EQU 9 +SYS_LOAD_MODULE EQU 10 +SYS_UNLOAD_MODULE EQU 11 +SYS_GET_MODULE_INFO EQU 12 +SYS_GET_MODULE_EXPORT EQU 13 +SYS_GET_MODULE_LIST EQU 14 +SYS_GET_CURRENT_TID EQU 15 +SYS_GET_CURRENT_PID EQU 16 +SYS_SET_THREAD_PRIORITY EQU 17 +SYS_YIELD EQU 18 +SYS_SLEEP EQU 19 +SYS_WAIT_SINGLE EQU 20 +SYS_WAIT_MANY EQU 21 +SYS_SET_USER_APC_DISPATCHER EQU 22 +SYS_APC_RETURN EQU 23 +SYS_SET_EXCEPTION_DISPATCHER EQU 24 +SYS_GET_EXCEPTION_DISPATCHER EQU 25 +SYS_CONTINUE_EXCEPTION EQU 26 +SYS_RAISE_EXCEPTION EQU 27 ; Virtual memory, mappings, and handles. -SYS_ALLOC_VM EQU 24 -SYS_FREE_VM EQU 25 -SYS_PROTECT_VM EQU 26 -SYS_QUERY_VM EQU 27 -SYS_CLOSE_HANDLE EQU 28 -SYS_DUPLICATE_HANDLE EQU 29 -SYS_CREATE_FILE_MAPPING EQU 30 -SYS_MAP_FILE EQU 31 +SYS_ALLOC_VM EQU 28 +SYS_FREE_VM EQU 29 +SYS_PROTECT_VM EQU 30 +SYS_QUERY_VM EQU 31 +SYS_CLOSE_HANDLE EQU 32 +SYS_DUPLICATE_HANDLE EQU 33 +SYS_CREATE_FILE_MAPPING EQU 34 +SYS_MAP_FILE EQU 35 ; Synchronization objects. -SYS_CREATE_MUTEX EQU 32 -SYS_TRY_ACQUIRE_MUTEX EQU 33 -SYS_RELEASE_MUTEX EQU 34 -SYS_CREATE_SEM EQU 35 -SYS_TRY_WAIT_SEM EQU 36 -SYS_SIGNAL_SEM EQU 37 -SYS_CREATE_EVENT EQU 38 -SYS_SIGNAL_EVENT EQU 39 -SYS_CLEAR_EVENT EQU 40 +SYS_CREATE_MUTEX EQU 36 +SYS_TRY_ACQUIRE_MUTEX EQU 37 +SYS_RELEASE_MUTEX EQU 38 +SYS_CREATE_SEM EQU 39 +SYS_TRY_WAIT_SEM EQU 40 +SYS_SIGNAL_SEM EQU 41 +SYS_CREATE_EVENT EQU 42 +SYS_SIGNAL_EVENT EQU 43 +SYS_CLEAR_EVENT EQU 44 ; Queues and named queues. -SYS_CREATE_QUEUE EQU 41 -SYS_SEND_QUEUE EQU 42 -SYS_RECV_QUEUE EQU 43 -SYS_PUBLISH_QUEUE EQU 44 -SYS_OPEN_NAMED_QUEUE EQU 45 -SYS_OPEN_NAMED_QUEUE_OWNER_PROCESS EQU 46 +SYS_CREATE_QUEUE EQU 45 +SYS_SEND_QUEUE EQU 46 +SYS_RECV_QUEUE EQU 47 +SYS_PUBLISH_QUEUE EQU 48 +SYS_OPEN_NAMED_QUEUE EQU 49 +SYS_OPEN_NAMED_QUEUE_OWNER_PROCESS EQU 50 ; Files, directories, and current directory. -SYS_OPEN_FILE EQU 47 -SYS_READ_FILE EQU 48 -SYS_WRITE_FILE EQU 49 -SYS_READ_FILE_ASYNC EQU 50 -SYS_WRITE_FILE_ASYNC EQU 51 -SYS_CANCEL_IO EQU 52 -SYS_SEEK_FILE EQU 53 -SYS_GET_FILE_POS EQU 54 -SYS_GET_FILE_SIZE EQU 55 -SYS_GET_FILE_STAT EQU 56 -SYS_STAT_FILE EQU 57 -SYS_TRUNCATE_FILE EQU 58 -SYS_FLUSH_FILE EQU 59 -SYS_DELETE_FILE EQU 60 -SYS_RENAME_FILE EQU 61 -SYS_LOCK_FILE EQU 62 -SYS_UNLOCK_FILE EQU 63 -SYS_OPEN_DIR EQU 64 -SYS_READ_DIR EQU 65 -SYS_CREATE_DIR EQU 66 -SYS_REMOVE_DIR EQU 67 -SYS_SET_CWD EQU 68 -SYS_REAL_PATH EQU 69 +SYS_OPEN_FILE EQU 51 +SYS_READ_FILE EQU 52 +SYS_WRITE_FILE EQU 53 +SYS_READ_FILE_ASYNC EQU 54 +SYS_WRITE_FILE_ASYNC EQU 55 +SYS_CANCEL_IO EQU 56 +SYS_SEEK_FILE EQU 57 +SYS_GET_FILE_POS EQU 58 +SYS_GET_FILE_SIZE EQU 59 +SYS_GET_FILE_STAT EQU 60 +SYS_STAT_FILE EQU 61 +SYS_TRUNCATE_FILE EQU 62 +SYS_FLUSH_FILE EQU 63 +SYS_DELETE_FILE EQU 64 +SYS_RENAME_FILE EQU 65 +SYS_LOCK_FILE EQU 66 +SYS_UNLOCK_FILE EQU 67 +SYS_OPEN_DIR EQU 68 +SYS_READ_DIR EQU 69 +SYS_CREATE_DIR EQU 70 +SYS_REMOVE_DIR EQU 71 +SYS_SET_CWD EQU 72 +SYS_REAL_PATH EQU 73 ; Console, display, and surfaces. -SYS_WRITE_CONSOLE EQU 70 -SYS_GET_CONSOLE_INFO EQU 71 -SYS_SET_CONSOLE_CURSOR EQU 72 -SYS_FILL_CONSOLE_CHARACTER EQU 73 -SYS_FILL_CONSOLE_ATTRIBUTE EQU 74 -SYS_PUT_SCREEN_CHAR EQU 75 -SYS_CLEAR_SCREEN EQU 76 -SYS_GET_SCREEN_SIZE EQU 77 -SYS_QUERY_DISPLAY_INFO EQU 78 -SYS_CREATE_SURFACE EQU 79 -SYS_MAP_SURFACE EQU 80 -SYS_QUERY_SURFACE EQU 81 -SYS_PRESENT_SURFACE EQU 82 +SYS_WRITE_CONSOLE EQU 74 +SYS_GET_CONSOLE_INFO EQU 75 +SYS_SET_CONSOLE_CURSOR EQU 76 +SYS_FILL_CONSOLE_CHARACTER EQU 77 +SYS_FILL_CONSOLE_ATTRIBUTE EQU 78 +SYS_PUT_SCREEN_CHAR EQU 79 +SYS_CLEAR_SCREEN EQU 80 +SYS_GET_SCREEN_SIZE EQU 81 +SYS_QUERY_DISPLAY_INFO EQU 82 +SYS_CREATE_SURFACE EQU 83 +SYS_MAP_SURFACE EQU 84 +SYS_QUERY_SURFACE EQU 85 +SYS_PRESENT_SURFACE EQU 86 ; Input. -SYS_POLL_KEYBOARD EQU 83 -SYS_IS_KEY_DOWN EQU 84 -SYS_READ_KEYBOARD_CHAR EQU 85 -SYS_READ_KEY EQU 86 -SYS_GET_KEY_MODIFIERS EQU 87 -SYS_OPEN_INPUT_QUEUE EQU 88 -SYS_READ_INPUT_EVENT EQU 89 -SYS_PEEK_INPUT_EVENT EQU 90 -SYS_PEEK_MOUSE EQU 91 -SYS_READ_MOUSE EQU 92 -SYS_GET_MOUSE_POS EQU 93 +SYS_POLL_KEYBOARD EQU 87 +SYS_IS_KEY_DOWN EQU 88 +SYS_READ_KEYBOARD_CHAR EQU 89 +SYS_READ_KEY EQU 90 +SYS_GET_KEY_MODIFIERS EQU 91 +SYS_OPEN_INPUT_QUEUE EQU 92 +SYS_READ_INPUT_EVENT EQU 93 +SYS_PEEK_INPUT_EVENT EQU 94 +SYS_PEEK_MOUSE EQU 95 +SYS_READ_MOUSE EQU 96 +SYS_GET_MOUSE_POS EQU 97 ; Time, debug, and system information. -SYS_CREATE_TIMER EQU 94 -SYS_SET_TIMER EQU 95 -SYS_CANCEL_TIMER EQU 96 -SYS_GET_TICK EQU 97 -SYS_GET_TICK_FREQUENCY EQU 98 -SYS_GET_SYSTEM_TIME EQU 99 -SYS_PRINT_DEBUG EQU 100 -SYS_QUERY_TRAP_FRAME EQU 101 -SYS_GET_MEMORY_STATUS EQU 102 -SYS_QUERY_KERNEL_STATS EQU 103 +SYS_CREATE_TIMER EQU 98 +SYS_SET_TIMER EQU 99 +SYS_CANCEL_TIMER EQU 100 +SYS_GET_TICK EQU 101 +SYS_GET_TICK_FREQUENCY EQU 102 +SYS_GET_SYSTEM_TIME EQU 103 +SYS_PRINT_DEBUG EQU 104 +SYS_QUERY_TRAP_FRAME EQU 105 +SYS_GET_MEMORY_STATUS EQU 106 +SYS_QUERY_KERNEL_STATS EQU 107 ; Native sockets and polling. -SYS_CREATE_SOCKET EQU 104 -SYS_SOCKET_IO_ASYNC EQU 105 -SYS_BIND_SOCKET EQU 106 -SYS_LISTEN_SOCKET EQU 107 -SYS_ACCEPT_SOCKET EQU 108 -SYS_CONNECT_SOCKET EQU 109 -SYS_SEND_SOCKET EQU 110 -SYS_RECV_SOCKET EQU 111 -SYS_SHUTDOWN_SOCKET EQU 112 -SYS_SEND_TO_SOCKET EQU 113 -SYS_RECV_FROM_SOCKET EQU 114 -SYS_RESOLVE_HOST EQU 115 -SYS_SET_SOCKET_OPTION EQU 116 -SYS_GET_SOCKET_OPTION EQU 117 -SYS_POLL EQU 118 +SYS_CREATE_SOCKET EQU 108 +SYS_SOCKET_IO_ASYNC EQU 109 +SYS_BIND_SOCKET EQU 110 +SYS_LISTEN_SOCKET EQU 111 +SYS_ACCEPT_SOCKET EQU 112 +SYS_CONNECT_SOCKET EQU 113 +SYS_SEND_SOCKET EQU 114 +SYS_RECV_SOCKET EQU 115 +SYS_SHUTDOWN_SOCKET EQU 116 +SYS_SEND_TO_SOCKET EQU 117 +SYS_RECV_FROM_SOCKET EQU 118 +SYS_RESOLVE_HOST EQU 119 +SYS_SET_SOCKET_OPTION EQU 120 +SYS_GET_SOCKET_OPTION EQU 121 +SYS_POLL EQU 122 +SYS_UNPUBLISH_QUEUE EQU 123 -SYS_MAX EQU 119 +SYS_MAX EQU 124 diff --git a/code/user/syscall/syscall_stubs.asm b/code/user/syscall/syscall_stubs.asm index 14c721a..6dc5d6a 100644 --- a/code/user/syscall/syscall_stubs.asm +++ b/code/user/syscall/syscall_stubs.asm @@ -104,6 +104,10 @@ SYSCALL_STUB2 Yield, SYS_YIELD SYSCALL_STUB2 Sleep, SYS_SLEEP SYSCALL_STUB2 SetUserApcDispatcher, SYS_SET_USER_APC_DISPATCHER SYSCALL_STUB2 ApcReturn, SYS_APC_RETURN +SYSCALL_STUB2 SetExceptionDispatcher, SYS_SET_EXCEPTION_DISPATCHER +SYSCALL_STUB2 GetExceptionDispatcher, SYS_GET_EXCEPTION_DISPATCHER +SYSCALL_STUB2 ContinueException, SYS_CONTINUE_EXCEPTION +SYSCALL_STUB2 RaiseException, SYS_RAISE_EXCEPTION ; --------------------------------------------------------------------------- ; User APC dispatcher @@ -137,7 +141,7 @@ SysUserApcDispatcher ENDP ; --------------------------------------------------------------------------- ; Virtual memory and handles ; --------------------------------------------------------------------------- -SYSCALL_STUB6 AllocVm, SYS_ALLOC_VM +SYSCALL_STUB2 AllocVm, SYS_ALLOC_VM SYSCALL_STUB2 FreeVm, SYS_FREE_VM SYSCALL_STUB2 ProtectVm, SYS_PROTECT_VM SYSCALL_STUB2 QueryVm, SYS_QUERY_VM @@ -166,6 +170,7 @@ SYSCALL_STUB2 CreateQueue, SYS_CREATE_QUEUE SYSCALL_STUB2 SendQueue, SYS_SEND_QUEUE SYSCALL_STUB2 RecvQueue, SYS_RECV_QUEUE SYSCALL_STUB2 PublishQueue, SYS_PUBLISH_QUEUE +SYSCALL_STUB2 UnpublishQueue, SYS_UNPUBLISH_QUEUE SYSCALL_STUB2 OpenNamedQueue, SYS_OPEN_NAMED_QUEUE SYSCALL_STUB2 OpenNamedQueueOwnerProcess, SYS_OPEN_NAMED_QUEUE_OWNER_PROCESS @@ -206,7 +211,7 @@ SYSCALL_STUB2 SetConsoleCursor, SYS_SET_CONSOLE_CURSOR SYSCALL_STUB6 FillConsoleCharacter, SYS_FILL_CONSOLE_CHARACTER SYSCALL_STUB6 FillConsoleAttribute, SYS_FILL_CONSOLE_ATTRIBUTE SYSCALL_STUB6 PutScreenChar, SYS_PUT_SCREEN_CHAR -SYSCALL_STUB5 CreateSurface, SYS_CREATE_SURFACE +SYSCALL_STUB2 CreateSurface, SYS_CREATE_SURFACE SYSCALL_STUB2 MapSurface, SYS_MAP_SURFACE SYSCALL_STUB2 QuerySurface, SYS_QUERY_SURFACE SYSCALL_STUB2 PresentSurface, SYS_PRESENT_SURFACE diff --git a/code/user/system/init/init.c b/code/user/system/init/init.c index d5b71e4..b8fd743 100644 --- a/code/user/system/init/init.c +++ b/code/user/system/init/init.c @@ -3,6 +3,7 @@ #include #include #include +#include #include // Implements the itoa operation. @@ -54,8 +55,13 @@ static void debug_print(const char* s) { (void)SysPrintDebug(&req); } +// Initializes init process state and supervises the configured child process. void _start(void) { + uint32_t runtimeStatus = NtlInitializeExceptionRuntime(); + if (runtimeStatus != NTLSTATUS_SUCCESS) + SysExitProcess((int32_t)runtimeStatus); + SYS_STRING_VIEW args = SysGetPeb()->CommandLine; uint32_t h = 0; uint32_t s = 0; @@ -64,7 +70,7 @@ void _start(void) debug_print("[init] starting\n"); SYS_CREATE_PROCESS_REQUEST cp = { args, SysSvFromParts(0, 0), &h }; s = SysCreateProcess(&cp); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { debug_print("[init] FATAL: failed to start!\n"); char buffer[12]; itoa(s, buffer); @@ -75,11 +81,11 @@ void _start(void) debug_print("[init] waiting\n"); s = SysWait(h, SYS_WAIT_FLAG_NONE); - if (s != STATUS_SUCCESS) + if (s != NTLSTATUS_SUCCESS) debug_print("[init] WARNING: SysWait returned error\n"); int32_t exitCode = 0; - if (SysGetProcessExitCode(h, &exitCode) != STATUS_SUCCESS) { + if (SysGetProcessExitCode(h, &exitCode) != NTLSTATUS_SUCCESS) { debug_print("[init] WARNING: failed to read exit code\n"); exitCode = 1; } diff --git a/code/user/tests/apc_return_smoke/apc_return_smoke.c b/code/user/tests/apc_return_smoke/apc_return_smoke.c index 3362a88..6ea3432 100644 --- a/code/user/tests/apc_return_smoke/apc_return_smoke.c +++ b/code/user/tests/apc_return_smoke/apc_return_smoke.c @@ -57,13 +57,13 @@ static uint32_t open_test_file(uint32_t* handleOut) { SYS_FILE_FLAG_NONE, &handle); uint32_t status = SysOpenFile(&request); - if (status == STATUS_SUCCESS) { + if (status == NTLSTATUS_SUCCESS) { *handleOut = handle; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } typedef struct APC_RETURN_STATE { @@ -75,7 +75,7 @@ typedef struct APC_RETURN_STATE { // Records that the user APC callback ran and observed the I/O status block. static void file_apc(void* context, SYS_IO_STATUS_BLOCK* iosb, uint64_t information) { APC_RETURN_STATE* state = (APC_RETURN_STATE*)context; - state->Status = iosb ? iosb->Status : STATUS_FAILURE; + state->Status = iosb ? iosb->Status : NTLSTATUS_FAILURE; state->Information = information; state->Delivered++; } @@ -97,29 +97,29 @@ int main(void) { print("apc_return_smoke: start\n"); uint32_t status = SysApcReturn((const SYS_USER_APC_FRAME*)0); - if (status != STATUS_INVALID_PARAMETER) - fail_status("inactive null return", status, STATUS_INVALID_PARAMETER); + if (status != NTLSTATUS_INVALID_PARAMETER) + fail_status("inactive null return", status, NTLSTATUS_INVALID_PARAMETER); SYS_USER_APC_FRAME fakeFrame; memset(&fakeFrame, 0, sizeof(fakeFrame)); fakeFrame.Magic = SYS_USER_APC_FRAME_MAGIC; status = SysApcReturn(&fakeFrame); - if (status != STATUS_INVALID_PARAMETER) - fail_status("inactive forged return", status, STATUS_INVALID_PARAMETER); + if (status != NTLSTATUS_INVALID_PARAMETER) + fail_status("inactive forged return", status, NTLSTATUS_INVALID_PARAMETER); status = SysSetUserApcDispatcher((void*)SysUserApcDispatcher); - if (status != STATUS_SUCCESS) - fail_status("set dispatcher", status, STATUS_SUCCESS); + if (status != NTLSTATUS_SUCCESS) + fail_status("set dispatcher", status, NTLSTATUS_SUCCESS); uint32_t file = 0; status = open_test_file(&file); - if (status != STATUS_SUCCESS) - fail_status("open", status, STATUS_SUCCESS); + if (status != NTLSTATUS_SUCCESS) + fail_status("open", status, NTLSTATUS_SUCCESS); uint32_t event = 0; status = SysCreateEvent(EVENT_AUTO_RESET, 0, &event); - if (status != STATUS_SUCCESS) - fail_status("create event", status, STATUS_SUCCESS); + if (status != NTLSTATUS_SUCCESS) + fail_status("create event", status, NTLSTATUS_SUCCESS); uint8_t* buffer = (uint8_t*)malloc(512); if (!buffer) { @@ -146,16 +146,16 @@ int main(void) { request.ApcContext = &state; status = SysReadFileAsync(&request); - if (status != STATUS_PENDING) - fail_status("submit", status, STATUS_PENDING); + if (status != NTLSTATUS_PENDING) + fail_status("submit", status, NTLSTATUS_PENDING); while (!state.Delivered) { status = SysWait(event, SYS_WAIT_FLAG_ALERTABLE); - if (status != STATUS_USER_APC && status != STATUS_SUCCESS && status != STATUS_PENDING) - fail_status("alertable wait", status, STATUS_USER_APC); + if (status != NTLSTATUS_USER_APC && status != NTLSTATUS_SUCCESS && status != NTLSTATUS_PENDING) + fail_status("alertable wait", status, NTLSTATUS_USER_APC); } - uint32_t ok = state.Delivered == 1 && state.Status == STATUS_SUCCESS && state.Information == 512; + uint32_t ok = state.Delivered == 1 && state.Status == NTLSTATUS_SUCCESS && state.Information == 512; SysCloseHandle(event); SysCloseHandle(file); diff --git a/code/user/tests/async_apc/async_apc.c b/code/user/tests/async_apc/async_apc.c index 96339ca..fd8f522 100644 --- a/code/user/tests/async_apc/async_apc.c +++ b/code/user/tests/async_apc/async_apc.c @@ -39,15 +39,15 @@ static uint32_t open_test_file(uint32_t* handleOut, const char** pathOut) { SYS_FILE_FLAG_NONE, &h); uint32_t s = SysOpenFile(&req); - if (s == STATUS_SUCCESS) { + if (s == NTLSTATUS_SUCCESS) { *handleOut = h; if (pathOut) *pathOut = paths[i]; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } // Prints hex8. @@ -95,7 +95,7 @@ int main(void) { print("async_apc: start\n"); uint32_t s = SysSetUserApcDispatcher((void*)SysUserApcDispatcher); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { print("async_apc: dispatcher registration failed status="); print_u64(s); print("\n"); @@ -105,7 +105,7 @@ int main(void) { uint32_t file = 0; const char* openedPath = 0; s = open_test_file(&file, &openedPath); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { print("async_apc: open failed status="); print_u64(s); print("\n"); @@ -118,7 +118,7 @@ int main(void) { uint32_t event = 0; s = SysCreateEvent(EVENT_AUTO_RESET, 0, &event); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { print("async_apc: event create failed status="); print_u64(s); print("\n"); @@ -151,7 +151,7 @@ int main(void) { req.ApcContext = &state; s = SysReadFileAsync(&req); - if (s != STATUS_PENDING) { + if (s != NTLSTATUS_PENDING) { print("async_apc: submit failed status="); print_u64(s); print("\n"); @@ -163,7 +163,7 @@ int main(void) { print("async_apc: alertable wait returned "); print_u64(s); print("\n"); - if (s != STATUS_USER_APC && s != STATUS_SUCCESS && s != STATUS_PENDING) + if (s != NTLSTATUS_USER_APC && s != NTLSTATUS_SUCCESS && s != NTLSTATUS_PENDING) break; } @@ -179,7 +179,7 @@ int main(void) { print_hex8(buffer[2]); print(" "); print_hex8(buffer[3]); print("\n"); - uint32_t ok = (state.Delivered == 1 && state.Status == STATUS_SUCCESS && + uint32_t ok = (state.Delivered == 1 && state.Status == NTLSTATUS_SUCCESS && state.Information == 512 && buffer[0] == 'M' && buffer[1] == 'Z'); SysCloseHandle(event); diff --git a/code/user/tests/async_cancel/async_cancel.c b/code/user/tests/async_cancel/async_cancel.c index 891207b..bb64a51 100644 --- a/code/user/tests/async_cancel/async_cancel.c +++ b/code/user/tests/async_cancel/async_cancel.c @@ -38,15 +38,15 @@ static uint32_t open_test_file(uint32_t* handleOut, const char** pathOut) { SYS_FILE_FLAG_NONE, &h); uint32_t s = SysOpenFile(&req); - if (s == STATUS_SUCCESS) { + if (s == NTLSTATUS_SUCCESS) { *handleOut = h; if (pathOut) *pathOut = paths[i]; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } // Prints u64. @@ -77,7 +77,7 @@ int main(void) { const char* openedPath = 0; uint32_t s = open_test_file(&file, &openedPath); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { print("async_cancel: open failed status="); print_u64(s); print("\n"); SysExitProcess(1); } @@ -87,7 +87,7 @@ int main(void) { print("\n"); s = SysCreateEvent(EVENT_AUTO_RESET, 0, &event); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { print("async_cancel: event create failed status="); print_u64(s); print("\n"); SysExitProcess(1); } @@ -114,7 +114,7 @@ int main(void) { req.RequestHandleOut = &request; s = SysReadFileAsync(&req); - if (s != STATUS_PENDING || request == 0) { + if (s != NTLSTATUS_PENDING || request == 0) { print("async_cancel: submit failed status="); print_u64(s); print(" request="); print_u64(request); print("\n"); SysExitProcess(1); @@ -123,10 +123,10 @@ int main(void) { uint32_t cs = SysCancelIo(request); print("async_cancel: cancel returned "); print_u64(cs); print("\n"); - while (iosb.Status == STATUS_PENDING) { + while (iosb.Status == NTLSTATUS_PENDING) { s = SysWait(event, SYS_WAIT_FLAG_ALERTABLE); print("async_cancel: wait returned "); print_u64(s); print("\n"); - if (s != STATUS_SUCCESS && s != STATUS_KERNEL_APC && s != STATUS_USER_APC && s != STATUS_ALERTED) + if (s != NTLSTATUS_SUCCESS && s != NTLSTATUS_KERNEL_APC && s != NTLSTATUS_USER_APC && s != NTLSTATUS_ALERTED) break; } @@ -135,9 +135,9 @@ int main(void) { // If the worker had already started, cancellation is best-effort and the // request may complete successfully. If it was still queued, it must report - // STATUS_CANCELLED. Both outcomes are valid; STATUS_PENDING is not. - uint32_t ok = (iosb.Status == STATUS_CANCELLED) || - (iosb.Status == STATUS_SUCCESS && iosb.Information == 512); + // NTLSTATUS_CANCELLED. Both outcomes are valid; NTLSTATUS_PENDING is not. + uint32_t ok = (iosb.Status == NTLSTATUS_CANCELLED) || + (iosb.Status == NTLSTATUS_SUCCESS && iosb.Information == 512); SysCloseHandle(request); SysCloseHandle(event); diff --git a/code/user/tests/cwd_peb_smoke/cwd_peb_smoke.c b/code/user/tests/cwd_peb_smoke/cwd_peb_smoke.c index 213837f..c35ee35 100644 --- a/code/user/tests/cwd_peb_smoke/cwd_peb_smoke.c +++ b/code/user/tests/cwd_peb_smoke/cwd_peb_smoke.c @@ -58,7 +58,7 @@ static void fail(const char* what) { static void set_cwd_or_fail(const char* path, const char* what) { SYS_PATH_REQUEST req = { SysSvFromCstr(path) }; uint32_t status = SysSetCwd(&req); - if (status != STATUS_SUCCESS) fail_status(what, status); + if (status != NTLSTATUS_SUCCESS) fail_status(what, status); } // Verifies the current-directory PEB view against one native path. @@ -87,11 +87,11 @@ int main(void) { SYS_PATH_REQUEST dirReq = { SysSvFromCstr(tempDir) }; uint32_t status = SysRemoveDir(&dirReq); - if (status != STATUS_SUCCESS && status != STATUS_NOT_FOUND) + if (status != NTLSTATUS_SUCCESS && status != NTLSTATUS_NOT_FOUND) fail_status("remove stale temp dir", status); status = SysCreateDir(&dirReq); - if (status != STATUS_SUCCESS) fail_status("create temp dir", status); + if (status != NTLSTATUS_SUCCESS) fail_status("create temp dir", status); set_cwd_or_fail(tempDir, "set temp cwd"); expect_cwd(tempDir); @@ -100,7 +100,7 @@ int main(void) { expect_cwd(rootPath); status = SysRemoveDir(&dirReq); - if (status != STATUS_SUCCESS) fail_status("remove temp dir", status); + if (status != NTLSTATUS_SUCCESS) fail_status("remove temp dir", status); print("cwd_peb_smoke: PASS\n"); exit_now(0); diff --git a/code/user/tests/dirty_writeback/dirty_writeback.c b/code/user/tests/dirty_writeback/dirty_writeback.c index f438782..280037f 100644 --- a/code/user/tests/dirty_writeback/dirty_writeback.c +++ b/code/user/tests/dirty_writeback/dirty_writeback.c @@ -79,19 +79,19 @@ static uint32_t create_temp(uint32_t* fileOut, const char** pathOut) { uint32_t h = 0; delete_path(paths[i]); SYS_OPEN_FILE_REQUEST req = SysMakeOpenFileRequest(SysSvFromCstr(paths[i]), - SYS_FILE_ACCESS_WRITE | SYS_FILE_ACCESS_QUERY, + 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 == STATUS_SUCCESS) { + if (s == NTLSTATUS_SUCCESS) { *fileOut = h; if (pathOut) *pathOut = paths[i]; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } static uint32_t open_path(const char* path, uint32_t* fileOut) { @@ -102,7 +102,7 @@ static uint32_t open_path(const char* path, uint32_t* fileOut) { SYS_FILE_FLAG_NONE, &h); uint32_t s = SysOpenFile(&req); - if (s == STATUS_SUCCESS) + if (s == NTLSTATUS_SUCCESS) *fileOut = h; return s; } @@ -118,7 +118,7 @@ static void checked_write(uint32_t file, const void* buffer, size_t size, const size_t done = 0; SYS_FILE_IO_REQUEST req = SysMakeFileIoRequest(file, buffer, size, &done); uint32_t s = SysWriteFile(&req); - if (s != STATUS_SUCCESS) fail_status(what, s); + if (s != NTLSTATUS_SUCCESS) fail_status(what, s); if (done != size) fail("short write"); } @@ -127,13 +127,13 @@ static void checked_read(uint32_t file, void* buffer, size_t size, size_t* gotOu memset(buffer, 0xCC, size); SYS_FILE_IO_REQUEST req = SysMakeFileIoRequest(file, buffer, size, &got); uint32_t s = SysReadFile(&req); - if (s != STATUS_SUCCESS) fail_status(what, s); + if (s != NTLSTATUS_SUCCESS) fail_status(what, s); if (gotOut) *gotOut = got; } static void checked_seek(uint32_t file, uint64_t offset, const char* what) { uint32_t s = SysSeekFile(file, offset); - if (s != STATUS_SUCCESS) fail_status(what, s); + if (s != NTLSTATUS_SUCCESS) fail_status(what, s); } static void expect_writeback_progress(const SYS_FILE_CACHE_STATS* before, @@ -158,7 +158,7 @@ int main(void) { uint32_t file = 0; const char* path = 0; uint32_t s = create_temp(&file, &path); - if (s != STATUS_SUCCESS) fail_status("create temp", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create temp", s); print("dirty_writeback: using "); print(path ? path : ""); @@ -170,11 +170,11 @@ int main(void) { SYS_FILE_CACHE_STATS beforeClose; SYS_FILE_CACHE_STATS afterClose; - if (query_cache(&before) != STATUS_SUCCESS) fail("initial stats query failed"); + if (query_cache(&before) != NTLSTATUS_SUCCESS) fail("initial stats query failed"); checked_write(file, gPatternA, sizeof(gPatternA), "write pattern A"); - if (query_cache(&afterWrite) != STATUS_SUCCESS) fail("post-write stats query failed"); + if (query_cache(&afterWrite) != NTLSTATUS_SUCCESS) fail("post-write stats query failed"); if (afterWrite.DirtyMarks <= before.DirtyMarks) fail("write did not mark dirty cache pages"); if (afterWrite.DirtyPages <= before.DirtyPages) fail("write did not leave dirty pages resident"); @@ -185,9 +185,9 @@ int main(void) { if (memcmp(gReadback, gPatternA, sizeof(gPatternA)) != 0) fail("cached read before flush mismatch"); s = SysFlushFile(file); - if (s != STATUS_SUCCESS) fail_status("explicit flush", s); + if (s != NTLSTATUS_SUCCESS) fail_status("explicit flush", s); - if (query_cache(&afterFlush) != STATUS_SUCCESS) fail("post-flush stats query failed"); + if (query_cache(&afterFlush) != NTLSTATUS_SUCCESS) fail("post-flush stats query failed"); if (afterFlush.FlushFileCalls <= afterWrite.FlushFileCalls) fail("flush call counter did not increase"); expect_writeback_progress(&afterWrite, &afterFlush, "explicit flush"); @@ -196,19 +196,19 @@ int main(void) { checked_seek(file, REWRITE_SIZE, "seek close-tail"); checked_write(file, gPatternA + REWRITE_SIZE, CLOSE_SIZE - REWRITE_SIZE, "write close tail"); - if (query_cache(&beforeClose) != STATUS_SUCCESS) fail("pre-close stats query failed"); + if (query_cache(&beforeClose) != NTLSTATUS_SUCCESS) fail("pre-close stats query failed"); if (beforeClose.DirtyMarks <= afterFlush.DirtyMarks) fail("rewrite did not mark dirty pages"); s = SysCloseHandle(file); file = 0; - if (s != STATUS_SUCCESS) fail_status("close", s); + if (s != NTLSTATUS_SUCCESS) fail_status("close", s); - if (query_cache(&afterClose) != STATUS_SUCCESS) fail("post-close stats query failed"); + if (query_cache(&afterClose) != NTLSTATUS_SUCCESS) fail("post-close stats query failed"); if (afterClose.FlushFileCalls <= beforeClose.FlushFileCalls) fail("close did not flush file"); expect_writeback_progress(&beforeClose, &afterClose, "close flush"); s = open_path(path, &file); - if (s != STATUS_SUCCESS) fail_status("reopen", s); + if (s != NTLSTATUS_SUCCESS) fail_status("reopen", s); checked_read(file, gReadback, CLOSE_SIZE, &got, "read after reopen"); if (got != CLOSE_SIZE) fail("read after reopen size mismatch"); @@ -218,7 +218,7 @@ int main(void) { s = SysCloseHandle(file); file = 0; - if (s != STATUS_SUCCESS) fail_status("close reopened", s); + if (s != NTLSTATUS_SUCCESS) fail_status("close reopened", s); delete_path(path); print("dirty_writeback: dirty-marks+="); diff --git a/code/user/tests/exception_dispatcher_smoke/exception_dispatcher_smoke.c b/code/user/tests/exception_dispatcher_smoke/exception_dispatcher_smoke.c new file mode 100644 index 0000000..1e7f2d0 --- /dev/null +++ b/code/user/tests/exception_dispatcher_smoke/exception_dispatcher_smoke.c @@ -0,0 +1,197 @@ +// User-mode smoke test for native exception dispatcher registration. + +#include +#include +#include +#include +#include + +// 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. +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 process. +static void exit_now(int32_t code) { + for (;;) SysExitProcess(code); +} + +// Fails the test with one message. +static void fail(const char* message) { + print("exception_dispatcher_smoke: "); + print(message); + print("\n"); + exit_now(1); +} + +// Fails the test with one status value. +static void fail_status(const char* what, uint32_t status) { + print("exception_dispatcher_smoke: "); + print(what); + print(" status="); + print_u64(status); + print("\n"); + exit_now(1); +} + +// Dummy dispatcher used only as a validated user-mode code pointer. +static void smoke_dispatcher(SYS_EXCEPTION_FRAME* frame) { + (void)frame; +} + +// Dispatcher hit count used by the delivery/continue stage. +static volatile uint32_t gBreakpointDispatchCount; + +// Continues from a breakpoint exception using the kernel-provided context. +static void smoke_continue_dispatcher(SYS_EXCEPTION_FRAME* frame) { + if (!frame) + fail("dispatcher received null frame"); + if (frame->Size != sizeof(*frame) || frame->Version != SYS_EXCEPTION_ABI_VERSION) + fail("dispatcher frame ABI mismatch"); + if (frame->ExceptionRecord.Code != SYS_EXCEPTION_CODE_BREAKPOINT) + fail("dispatcher received unexpected exception code"); + if (frame->DispatcherContext != (void*)(uintptr_t)0xBEEF) + fail("dispatcher context mismatch during delivery"); + + gBreakpointDispatchCount++; + + SYS_CONTINUE_EXCEPTION_REQUEST request; + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + request.Disposition = SYS_EXCEPTION_DISPOSITION_CONTINUE_EXECUTION; + request.Context = &frame->ContextRecord; + + uint32_t status = SysContinueException(&request); + fail_status("continue exception returned", status); +} + +// Requires one syscall to return the expected status. +static void expect_status(const char* what, uint32_t got, uint32_t expected) { + if (got != expected) { + print("exception_dispatcher_smoke: "); + print(what); + print(" expected="); + print_u64(expected); + print(" got="); + print_u64(got); + print("\n"); + exit_now(1); + } +} + +// Reads the current dispatcher registration. +static SYS_EXCEPTION_DISPATCHER_REQUEST get_registration(void) { + SYS_EXCEPTION_DISPATCHER_REQUEST request; + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + uint32_t status = SysGetExceptionDispatcher(&request); + if (status != NTLSTATUS_SUCCESS) + fail_status("get dispatcher", status); + if (request.Size != sizeof(request)) + fail("get dispatcher size mismatch"); + return request; +} + +// Runs the native dispatcher registration smoke test. +int main(void) { + print("exception_dispatcher_smoke: start\n"); + + expect_status("null get", SysGetExceptionDispatcher(0), NTLSTATUS_INVALID_PARAMETER); + expect_status("null set", SysSetExceptionDispatcher(0), NTLSTATUS_INVALID_PARAMETER); + + SYS_EXCEPTION_DISPATCHER_REQUEST initial = get_registration(); + SYS_EXCEPTION_DISPATCHER_REQUEST request; + + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request) - 1; + request.DispatcherRoutine = smoke_dispatcher; + expect_status("bad size", SysSetExceptionDispatcher(&request), NTLSTATUS_INVALID_PARAMETER); + + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + request.Flags = 1; + request.DispatcherRoutine = smoke_dispatcher; + expect_status("bad flags", SysSetExceptionDispatcher(&request), NTLSTATUS_INVALID_PARAMETER); + + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + request.DispatcherRoutine = (SYS_USER_EXCEPTION_DISPATCHER)(uintptr_t)0xFFFF800000000000ull; + expect_status("kernel dispatcher", SysSetExceptionDispatcher(&request), NTLSTATUS_ACCESS_DENIED); + + char tinyStack[32]; + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + request.DispatcherRoutine = smoke_dispatcher; + request.ExceptionStackBase = tinyStack; + request.ExceptionStackSize = sizeof(tinyStack); + expect_status("tiny exception stack", SysSetExceptionDispatcher(&request), NTLSTATUS_BUFFER_TOO_SMALL); + + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + request.DispatcherRoutine = smoke_dispatcher; + request.DispatcherContext = (void*)(uintptr_t)0x1234; + uint32_t status = SysSetExceptionDispatcher(&request); + if (status != NTLSTATUS_SUCCESS) + fail_status("set dispatcher", status); + + SYS_EXCEPTION_DISPATCHER_REQUEST snapshot = get_registration(); + if (snapshot.DispatcherRoutine != smoke_dispatcher) + fail("dispatcher routine mismatch"); + if (snapshot.DispatcherContext != (void*)(uintptr_t)0x1234) + fail("dispatcher context mismatch"); + if (snapshot.ExceptionStackBase || snapshot.ExceptionStackSize) + fail("unexpected exception stack registration"); + + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + request.DispatcherRoutine = smoke_continue_dispatcher; + request.DispatcherContext = (void*)(uintptr_t)0xBEEF; + status = SysSetExceptionDispatcher(&request); + if (status != NTLSTATUS_SUCCESS) + fail_status("set continue dispatcher", status); + + __debugbreak(); + if (gBreakpointDispatchCount != 1) + fail("breakpoint was not delivered exactly once"); + + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + status = SysSetExceptionDispatcher(&request); + if (status != NTLSTATUS_SUCCESS) + fail_status("clear dispatcher", status); + + snapshot = get_registration(); + if (snapshot.DispatcherRoutine || snapshot.DispatcherContext || + snapshot.ExceptionStackBase || snapshot.ExceptionStackSize) + fail("dispatcher did not clear"); + + if (initial.DispatcherRoutine) { + status = SysSetExceptionDispatcher(&initial); + if (status != NTLSTATUS_SUCCESS) + fail_status("restore initial dispatcher", status); + } + + print("exception_dispatcher_smoke: PASS\n"); + exit_now(0); + return 0; +} diff --git a/code/user/tests/exception_smoke/exception_smoke.c b/code/user/tests/exception_smoke/exception_smoke.c new file mode 100644 index 0000000..bdf6853 --- /dev/null +++ b/code/user/tests/exception_smoke/exception_smoke.c @@ -0,0 +1,256 @@ +// Native exception pipeline integration smoke test. + +#include +#include +#include +#include +#include +#include + +#define CHILD_DIVIDE_BY_ZERO "child-divide-by-zero" +#define CHILD_ACCESS_VIOLATION "child-access-violation" +#define CHILD_INVALID_RESUME "child-invalid-resume" +#define CHILD_NONCONTINUABLE "child-noncontinuable" +#define SMOKE_NONCONTINUABLE_CODE 0xE1111003u + +// 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. +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 process. +static void exit_now(int32_t code) { + for (;;) SysExitProcess(code); +} + +// Fails the test with one message. +static void fail(const char* message) { + print("exception_smoke: "); + print(message); + print("\n"); + exit_now(1); +} + +// Fails the test with one status value. +static void fail_status(const char* what, uint32_t status) { + print("exception_smoke: "); + print(what); + print(" status="); + print_u64(status); + print("\n"); + exit_now(1); +} + +// Returns whether a string view exactly matches a literal string. +static int sv_equals_cstr(SYS_STRING_VIEW sv, const char* literal) { + size_t len = strlen(literal); + return sv.Length == len && sv.Data && memcmp(sv.Data, literal, len) == 0; +} + +// Returns the current process command line. +static SYS_STRING_VIEW current_command_line(void) { + SYS_PEB* peb = SysGetPeb(); + if (!peb) + return SysSvFromParts(NULL, 0); + return peb->CommandLine; +} + +// Requires one syscall to return the expected status. +static void expect_status(const char* what, uint32_t got, uint32_t expected) { + if (got != expected) { + print("exception_smoke: "); + print(what); + print(" expected="); + print_u64(expected); + print(" got="); + print_u64(got); + print("\n"); + exit_now(1); + } +} + +// Runs this image as a child and requires the expected exit code. +static void run_child_expect_exit(const char* mode, uint32_t expectedExit) { + SYS_PEB* peb = SysGetPeb(); + if (!peb || !peb->ImagePath.Data || peb->ImagePath.Length == 0) + fail("missing image path"); + + uint32_t child = 0; + SYS_CREATE_PROCESS_REQUEST request = { + peb->ImagePath, + SysSvFromCstr(mode), + &child, + }; + uint32_t status = SysCreateProcess(&request); + if (status != NTLSTATUS_SUCCESS) + fail_status("create child", status); + + status = SysWait(child, SYS_WAIT_FLAG_NONE); + if (status != NTLSTATUS_SUCCESS) + fail_status("wait child", status); + + int32_t exitCode = 0; + status = SysGetProcessExitCode(child, &exitCode); + if (status != NTLSTATUS_SUCCESS) + fail_status("query child", status); + SysCloseHandle(child); + + if ((uint32_t)exitCode != expectedExit) { + print("exception_smoke: child "); + print(mode); + print(" expected exit="); + print_u64(expectedExit); + print(" got="); + print_u64((uint32_t)exitCode); + print("\n"); + exit_now(1); + } +} + +// Triggers a divide-by-zero with no registered native handlers. +static void child_divide_by_zero(void) { + volatile int one = 1; + volatile int zero = 0; + volatile int sink = one / zero; + (void)sink; + exit_now(2); +} + +// Observes an access violation and exits from inside the native handler. +static int access_violation_handler(SYS_EXCEPTION_RECORD* record, + SYS_USER_CONTEXT* context, + void* userContext) { + (void)context; + if (userContext != (void*)(uintptr_t)0xA11C) + exit_now(10); + if (!record || record->Code != SYS_EXCEPTION_CODE_ACCESS_VIOLATION) + exit_now(11); + if (record->FaultAddress != 0) + exit_now(12); + if (record->ParameterCount != 2 || record->Parameters[1] != 0) + exit_now(13); + exit_now(0); + return NTL_EXCEPTION_TERMINATE_PROCESS; +} + +// Triggers a null read so the handler can inspect the fault address. +static void child_access_violation(void) { + void* handle = NtlAddExceptionHandler(1, access_violation_handler, (void*)(uintptr_t)0xA11C); + if (!handle) + exit_now(20); + + volatile uint8_t* p = (volatile uint8_t*)0; + volatile uint8_t value = *p; + (void)value; + exit_now(21); +} + +// Returns a resume context with an invalid user RIP. +static int invalid_resume_handler(SYS_EXCEPTION_RECORD* record, + SYS_USER_CONTEXT* context, + void* userContext) { + (void)userContext; + if (!record || !context || record->Code != SYS_EXCEPTION_CODE_BREAKPOINT) + exit_now(30); + context->Rip = 0; + return NTL_EXCEPTION_CONTINUE_EXECUTION; +} + +// Triggers a breakpoint whose handler asks the kernel to resume at RIP zero. +static void child_invalid_resume(void) { + void* handle = NtlAddExceptionHandler(1, invalid_resume_handler, NULL); + if (!handle) + exit_now(31); + __debugbreak(); + exit_now(32); +} + +// Attempts to continue a noncontinuable user-raised exception. +static int noncontinuable_handler(SYS_EXCEPTION_RECORD* record, + SYS_USER_CONTEXT* context, + void* userContext) { + (void)context; + (void)userContext; + if (!record || record->Code != SMOKE_NONCONTINUABLE_CODE) + exit_now(40); + if ((record->Flags & SYS_EXCEPTION_FLAG_NONCONTINUABLE) == 0) + exit_now(41); + return NTL_EXCEPTION_CONTINUE_EXECUTION; +} + +// Raises a noncontinuable exception that a handler must not resume. +static void child_noncontinuable(void) { + void* handle = NtlAddExceptionHandler(1, noncontinuable_handler, NULL); + if (!handle) + exit_now(42); + + SYS_RAISE_EXCEPTION_REQUEST request; + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + request.Flags = SYS_RAISE_EXCEPTION_FLAG_NONCONTINUABLE; + request.Code = SMOKE_NONCONTINUABLE_CODE; + + uint32_t status = SysRaiseException(&request); + exit_now((int32_t)status); +} + +// Dispatches the child process mode selected by the command line. +static void run_child_if_requested(void) { + SYS_STRING_VIEW command = current_command_line(); + if (sv_equals_cstr(command, CHILD_DIVIDE_BY_ZERO)) + child_divide_by_zero(); + if (sv_equals_cstr(command, CHILD_ACCESS_VIOLATION)) + child_access_violation(); + if (sv_equals_cstr(command, CHILD_INVALID_RESUME)) + child_invalid_resume(); + if (sv_equals_cstr(command, CHILD_NONCONTINUABLE)) + child_noncontinuable(); +} + +// Runs validation that does not intentionally fault this process. +static void verify_continue_validation(void) { + expect_status("null continue", SysContinueException(NULL), NTLSTATUS_INVALID_PARAMETER); + + SYS_CONTINUE_EXCEPTION_REQUEST request; + memset(&request, 0, sizeof(request)); + request.Size = sizeof(request); + request.Disposition = SYS_EXCEPTION_DISPOSITION_CONTINUE_EXECUTION; + expect_status("inactive continue", SysContinueException(&request), NTLSTATUS_INVALID_PARAMETER); +} + +// Runs the native exception integration smoke test. +int main(void) { + run_child_if_requested(); + + print("exception_smoke: start\n"); + + verify_continue_validation(); + run_child_expect_exit(CHILD_DIVIDE_BY_ZERO, NTLSTATUS_PROCESS_DIVIDE_BY_ZERO); + run_child_expect_exit(CHILD_ACCESS_VIOLATION, NTLSTATUS_SUCCESS); + run_child_expect_exit(CHILD_INVALID_RESUME, NTLSTATUS_ACCESS_DENIED); + run_child_expect_exit(CHILD_NONCONTINUABLE, NTLSTATUS_PROCESS_UNKNOWN_FAULT); + + print("exception_smoke: PASS\n"); + exit_now(0); + return 0; +} diff --git a/code/user/tests/file_lock_smoke/file_lock_smoke.c b/code/user/tests/file_lock_smoke/file_lock_smoke.c index 2388fea..b9bbd73 100644 --- a/code/user/tests/file_lock_smoke/file_lock_smoke.c +++ b/code/user/tests/file_lock_smoke/file_lock_smoke.c @@ -75,7 +75,7 @@ static uint32_t open_existing_lockable(const char* path, uint32_t* fileOut) { SYS_FILE_FLAG_NONE, &h); uint32_t s = SysOpenFile(&req); - if (s == STATUS_SUCCESS) + if (s == NTLSTATUS_SUCCESS) *fileOut = h; return s; } @@ -98,13 +98,13 @@ static uint32_t create_temp_file(uint32_t* fileOut, const char** pathOut) { SYS_FILE_FLAG_NONE, &h); uint32_t s = SysOpenFile(&req); - if (s == STATUS_SUCCESS) { + if (s == NTLSTATUS_SUCCESS) { *fileOut = h; *pathOut = paths[i]; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } // Locks a range through the public request ABI. @@ -175,49 +175,49 @@ static void run_child(SYS_STRING_VIEW commandLine) { uint32_t file = 0; uint32_t s = open_existing_lockable(path, &file); - if (s != STATUS_SUCCESS) + if (s != NTLSTATUS_SUCCESS) exit_now(3); if (str_eq(mode, "excl-blocked")) { s = lock_range(file, SYS_FILE_LOCK_EXCLUSIVE, LOCK_OFFSET, LOCK_LENGTH, 0); SysCloseHandle(file); - exit_now(s == STATUS_WOULD_BLOCK ? 0 : 4); + exit_now(s == NTLSTATUS_WOULD_BLOCK ? 0 : 4); } if (str_eq(mode, "excl-timeout")) { s = lock_range(file, SYS_FILE_LOCK_EXCLUSIVE, LOCK_OFFSET, LOCK_LENGTH, 20); SysCloseHandle(file); - exit_now(s == STATUS_TIMEOUT ? 0 : 5); + exit_now(s == NTLSTATUS_TIMEOUT ? 0 : 5); } if (str_eq(mode, "excl-wait")) { s = lock_range(file, SYS_FILE_LOCK_EXCLUSIVE, LOCK_OFFSET, LOCK_LENGTH, SYS_WAIT_TIMEOUT_INFINITE); - if (s == STATUS_SUCCESS) + if (s == NTLSTATUS_SUCCESS) (void)unlock_range(file, LOCK_OFFSET, LOCK_LENGTH); SysCloseHandle(file); - exit_now(s == STATUS_SUCCESS ? 0 : 6); + exit_now(s == NTLSTATUS_SUCCESS ? 0 : 6); } if (str_eq(mode, "shared-ok")) { s = lock_range(file, SYS_FILE_LOCK_SHARED, LOCK_OFFSET, LOCK_LENGTH, 0); - if (s == STATUS_SUCCESS) + if (s == NTLSTATUS_SUCCESS) (void)unlock_range(file, LOCK_OFFSET, LOCK_LENGTH); SysCloseHandle(file); - exit_now(s == STATUS_SUCCESS ? 0 : 7); + exit_now(s == NTLSTATUS_SUCCESS ? 0 : 7); } if (str_eq(mode, "excl-nonoverlap")) { s = lock_range(file, SYS_FILE_LOCK_EXCLUSIVE, NONOVERLAP_OFFSET, LOCK_LENGTH, 0); - if (s == STATUS_SUCCESS) + if (s == NTLSTATUS_SUCCESS) (void)unlock_range(file, NONOVERLAP_OFFSET, LOCK_LENGTH); SysCloseHandle(file); - exit_now(s == STATUS_SUCCESS ? 0 : 8); + exit_now(s == NTLSTATUS_SUCCESS ? 0 : 8); } if (str_eq(mode, "hold-exit")) { s = lock_range(file, SYS_FILE_LOCK_EXCLUSIVE, LOCK_OFFSET, LOCK_LENGTH, 0); SysCloseHandle(file); - exit_now(s == STATUS_SUCCESS ? 0 : 9); + exit_now(s == NTLSTATUS_SUCCESS ? 0 : 9); } SysCloseHandle(file); @@ -251,14 +251,14 @@ static void run_child_expect_success(const char* mode, const char* path) { &child, }; uint32_t s = SysCreateProcess(&req); - if (s != STATUS_SUCCESS) fail_status("create child", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create child", s); s = SysWait(child, SYS_WAIT_FLAG_NONE); - if (s != STATUS_SUCCESS) fail_status("wait child", s); + if (s != NTLSTATUS_SUCCESS) fail_status("wait child", s); int32_t exitCode = 0; s = SysGetProcessExitCode(child, &exitCode); - if (s != STATUS_SUCCESS) fail_status("query child", s); + if (s != NTLSTATUS_SUCCESS) fail_status("query child", s); SysCloseHandle(child); if (exitCode != 0) { print("file_lock_smoke: child "); @@ -282,12 +282,12 @@ static void test_validation(uint32_t file) { 0, }; uint32_t s = SysLockFile(&lockReq); - if (s != STATUS_INVALID_PARAMETER) fail_status("bad lock size", s); + if (s != NTLSTATUS_INVALID_PARAMETER) fail_status("bad lock size", s); lockReq.Size = sizeof(lockReq); lockReq.Length = 0; s = SysLockFile(&lockReq); - if (s != STATUS_INVALID_PARAMETER) fail_status("zero lock length", s); + if (s != NTLSTATUS_INVALID_PARAMETER) fail_status("zero lock length", s); SYS_UNLOCK_FILE_REQUEST unlockReq = { sizeof(unlockReq), @@ -297,12 +297,12 @@ static void test_validation(uint32_t file) { LOCK_LENGTH, }; s = SysUnlockFile(&unlockReq); - if (s != STATUS_NOT_FOUND) fail_status("unlock missing range", s); + if (s != NTLSTATUS_NOT_FOUND) fail_status("unlock missing range", s); lockReq.Length = LOCK_LENGTH; lockReq.FileHandle = 0xeeeeeeeeu; s = SysLockFile(&lockReq); - if (s != STATUS_INVALID_HANDLE) fail_status("bad lock handle", s); + if (s != NTLSTATUS_INVALID_HANDLE) fail_status("bad lock handle", s); } // Program entry point. @@ -322,27 +322,27 @@ int main(void) { uint32_t file = 0; const char* path = 0; uint32_t s = create_temp_file(&file, &path); - if (s != STATUS_SUCCESS) fail_status("create temp", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create temp", s); test_validation(file); s = lock_range(file, SYS_FILE_LOCK_EXCLUSIVE, LOCK_OFFSET, LOCK_LENGTH, 0); - if (s != STATUS_SUCCESS) fail_status("exclusive parent lock", s); + if (s != NTLSTATUS_SUCCESS) fail_status("exclusive parent lock", s); run_child_expect_success("excl-blocked", path); run_child_expect_success("excl-timeout", path); run_child_expect_success("excl-nonoverlap", path); s = unlock_range(file, LOCK_OFFSET, LOCK_LENGTH); - if (s != STATUS_SUCCESS) fail_status("exclusive parent unlock", s); + if (s != NTLSTATUS_SUCCESS) fail_status("exclusive parent unlock", s); s = lock_range(file, SYS_FILE_LOCK_SHARED, LOCK_OFFSET, LOCK_LENGTH, 0); - if (s != STATUS_SUCCESS) fail_status("shared parent lock", s); + if (s != NTLSTATUS_SUCCESS) fail_status("shared parent lock", s); run_child_expect_success("shared-ok", path); run_child_expect_success("excl-blocked", path); s = unlock_range(file, LOCK_OFFSET, LOCK_LENGTH); - if (s != STATUS_SUCCESS) fail_status("shared parent unlock", s); + if (s != NTLSTATUS_SUCCESS) fail_status("shared parent unlock", s); s = lock_range(file, SYS_FILE_LOCK_EXCLUSIVE, LOCK_OFFSET, LOCK_LENGTH, 0); - if (s != STATUS_SUCCESS) fail_status("blocking setup lock", s); + if (s != NTLSTATUS_SUCCESS) fail_status("blocking setup lock", s); SYS_PEB* selfPeb = SysGetPeb(); if (!selfPeb || !selfPeb->ImagePath.Data || selfPeb->ImagePath.Length == 0) fail("missing self image"); char command[CHILD_PREFIX_MAX + CHILD_PATH_MAX]; @@ -350,23 +350,23 @@ int main(void) { uint32_t child = 0; SYS_CREATE_PROCESS_REQUEST createReq = { selfPeb->ImagePath, SysSvFromCstr(command), &child }; s = SysCreateProcess(&createReq); - if (s != STATUS_SUCCESS) fail_status("create blocking child", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create blocking child", s); SysSleep(30); s = unlock_range(file, LOCK_OFFSET, LOCK_LENGTH); - if (s != STATUS_SUCCESS) fail_status("wake unlock", s); + if (s != NTLSTATUS_SUCCESS) fail_status("wake unlock", s); s = SysWait(child, SYS_WAIT_FLAG_NONE); - if (s != STATUS_SUCCESS) fail_status("wait blocking child", s); + if (s != NTLSTATUS_SUCCESS) fail_status("wait blocking child", s); int32_t exitCode = 0; s = SysGetProcessExitCode(child, &exitCode); - if (s != STATUS_SUCCESS) fail_status("query blocking child", s); + if (s != NTLSTATUS_SUCCESS) fail_status("query blocking child", s); SysCloseHandle(child); if (exitCode != 0) fail("blocking child failed"); run_child_expect_success("hold-exit", path); s = lock_range(file, SYS_FILE_LOCK_EXCLUSIVE, LOCK_OFFSET, LOCK_LENGTH, 0); - if (s != STATUS_SUCCESS) fail_status("exit released lock", s); + if (s != NTLSTATUS_SUCCESS) fail_status("exit released lock", s); s = unlock_range(file, LOCK_OFFSET, LOCK_LENGTH); - if (s != STATUS_SUCCESS) fail_status("exit release cleanup unlock", s); + if (s != NTLSTATUS_SUCCESS) fail_status("exit release cleanup unlock", s); SysCloseHandle(file); delete_path(path); diff --git a/code/user/tests/file_stat_smoke/file_stat_smoke.c b/code/user/tests/file_stat_smoke/file_stat_smoke.c index fbec137..7c3b159 100644 --- a/code/user/tests/file_stat_smoke/file_stat_smoke.c +++ b/code/user/tests/file_stat_smoke/file_stat_smoke.c @@ -88,14 +88,14 @@ static uint32_t create_temp_file(uint32_t* fileOut, const char** pathOut) { SYS_FILE_FLAG_NONE, &h); uint32_t s = SysOpenFile(&req); - if (s == STATUS_SUCCESS) { + if (s == NTLSTATUS_SUCCESS) { *fileOut = h; *pathOut = paths[i]; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } // Creates a temporary directory on the first writable path that works. @@ -111,13 +111,13 @@ static uint32_t create_temp_dir(const char** pathOut) { remove_dir_path(paths[i]); SYS_PATH_REQUEST req = { SysSvFromCstr(paths[i]) }; uint32_t s = SysCreateDir(&req); - if (s == STATUS_SUCCESS) { + if (s == NTLSTATUS_SUCCESS) { *pathOut = paths[i]; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } // Fills the write pattern used by the test file. @@ -131,11 +131,11 @@ 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 != STATUS_SUCCESS) fail_status("write test file", s); + if (s != NTLSTATUS_SUCCESS) fail_status("write test file", s); if (done != sizeof(gPattern)) fail("short write"); s = SysFlushFile(file); - if (s != STATUS_SUCCESS) fail_status("flush test file", s); + if (s != NTLSTATUS_SUCCESS) fail_status("flush test file", s); } // Checks one regular-file metadata result. @@ -176,19 +176,19 @@ static void test_file_stat(uint32_t file, const char* path) { SYS_FILE_STAT byHandle; memset(&byHandle, 0xA5, sizeof(byHandle)); uint32_t s = SysGetFileStat(file, &byHandle); - if (s != STATUS_SUCCESS) fail_status("get file stat", s); + if (s != NTLSTATUS_SUCCESS) fail_status("get file stat", s); check_regular_stat(&byHandle, sizeof(gPattern), "handle stat"); uint64_t size = 0; s = SysGetFileSize(file, &size); - if (s != STATUS_SUCCESS) fail_status("get file size", s); + 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(path), &byPath }; s = SysStatFile(&statReq); - if (s != STATUS_SUCCESS) fail_status("path stat", s); + if (s != NTLSTATUS_SUCCESS) fail_status("path stat", s); check_regular_stat(&byPath, sizeof(gPattern), "path stat"); if (byHandle.VolumeId != 0 && byPath.VolumeId != 0 && byHandle.VolumeId != byPath.VolumeId) @@ -203,7 +203,7 @@ static void test_directory_stat(const char* path) { memset(&stat, 0xCC, sizeof(stat)); SYS_STAT_FILE_REQUEST statReq = { SysSvFromCstr(path), &stat }; uint32_t s = SysStatFile(&statReq); - if (s != STATUS_SUCCESS) fail_status("directory stat", s); + if (s != NTLSTATUS_SUCCESS) fail_status("directory stat", s); check_directory_stat(&stat); } @@ -212,14 +212,14 @@ 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 != STATUS_NOT_FOUND) fail_status("missing path status", s); + if (s != NTLSTATUS_NOT_FOUND) fail_status("missing path status", s); s = SysGetFileStat(0xFFFFFFFFu, &stat); - if (s != STATUS_INVALID_HANDLE) fail_status("invalid handle status", s); + 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 != STATUS_INVALID_PARAMETER) fail_status("null stat output status", s); + if (s != NTLSTATUS_INVALID_PARAMETER) fail_status("null stat output status", s); } // Runs the native file metadata smoke test. @@ -231,7 +231,7 @@ int main(void) { uint32_t file = 0; const char* filePath = 0; uint32_t s = create_temp_file(&file, &filePath); - if (s != STATUS_SUCCESS) fail_status("create temp file", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create temp file", s); write_test_file(file); test_file_stat(file, filePath); @@ -240,13 +240,13 @@ int main(void) { const char* dirPath = 0; s = create_temp_dir(&dirPath); - if (s != STATUS_SUCCESS) fail_status("create temp dir", s); + 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 != STATUS_SUCCESS) fail_status("recreate temp dir", s); + if (s != NTLSTATUS_SUCCESS) fail_status("recreate temp dir", s); test_directory_stat(dirPath); remove_dir_path(dirPath); diff --git a/code/user/tests/handle_dup_smoke/handle_dup_smoke.c b/code/user/tests/handle_dup_smoke/handle_dup_smoke.c index aa98ae6..64f4b63 100644 --- a/code/user/tests/handle_dup_smoke/handle_dup_smoke.c +++ b/code/user/tests/handle_dup_smoke/handle_dup_smoke.c @@ -127,61 +127,61 @@ int main(void) { uint32_t currentPid = SysGetCurrentPid(); uint32_t process = 0; uint32_t s = SysOpenProcess(currentPid, &process); - if (s != STATUS_SUCCESS) fail_status("open current process", s); + if (s != NTLSTATUS_SUCCESS) fail_status("open current process", s); uint32_t queue = 0; s = SysCreateQueue(&queue); - if (s != STATUS_SUCCESS) fail_status("create queue", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create queue", s); uint32_t readOnly = 0; s = duplicate_handle(queue, process, SYS_HANDLE_RIGHT_READ, SYS_DUPLICATE_HANDLE_FLAG_NONE, &readOnly); - if (s != STATUS_SUCCESS) fail_status("duplicate read-only", s); + if (s != NTLSTATUS_SUCCESS) fail_status("duplicate read-only", s); uint32_t writeOnly = 0; s = duplicate_handle(queue, process, SYS_HANDLE_RIGHT_WRITE, SYS_DUPLICATE_HANDLE_FLAG_NONE, &writeOnly); - if (s != STATUS_SUCCESS) fail_status("duplicate write-only", s); + if (s != NTLSTATUS_SUCCESS) fail_status("duplicate write-only", s); uint32_t sameRights = 0; s = duplicate_handle(queue, process, 0, SYS_DUPLICATE_HANDLE_FLAG_SAME_RIGHTS, &sameRights); - if (s != STATUS_SUCCESS) fail_status("duplicate same rights", s); + if (s != NTLSTATUS_SUCCESS) fail_status("duplicate same rights", s); s = send_message(readOnly, 10, 100); - if (s == STATUS_SUCCESS) fail("read-only duplicate allowed send"); + if (s == NTLSTATUS_SUCCESS) fail("read-only duplicate allowed send"); TEST_QUEUE_MESSAGE msg; s = recv_message(writeOnly, &msg); - if (s == STATUS_SUCCESS) fail("write-only duplicate allowed receive"); + if (s == NTLSTATUS_SUCCESS) fail("write-only duplicate allowed receive"); s = send_message(queue, 11, 101); - if (s != STATUS_SUCCESS) fail_status("send original", s); + if (s != NTLSTATUS_SUCCESS) fail_status("send original", s); s = recv_message(readOnly, &msg); - if (s != STATUS_SUCCESS) fail_status("receive read-only", s); + if (s != NTLSTATUS_SUCCESS) fail_status("receive read-only", s); check_message(&msg, 11, 101); s = send_message(writeOnly, 12, 102); - if (s != STATUS_SUCCESS) fail_status("send write-only", s); + if (s != NTLSTATUS_SUCCESS) fail_status("send write-only", s); s = recv_message(queue, &msg); - if (s != STATUS_SUCCESS) fail_status("receive original", s); + if (s != NTLSTATUS_SUCCESS) fail_status("receive original", s); check_message(&msg, 12, 102); s = send_message(sameRights, 13, 103); - if (s != STATUS_SUCCESS) fail_status("send same-rights", s); + if (s != NTLSTATUS_SUCCESS) fail_status("send same-rights", s); s = recv_message(sameRights, &msg); - if (s != STATUS_SUCCESS) fail_status("receive same-rights", s); + if (s != NTLSTATUS_SUCCESS) fail_status("receive same-rights", s); check_message(&msg, 13, 103); uint32_t ignored = 0; s = duplicate_handle(readOnly, process, SYS_HANDLE_RIGHT_READ, SYS_DUPLICATE_HANDLE_FLAG_NONE, &ignored); - expect_status("duplicate non-duplicable handle", s, STATUS_ACCESS_DENIED); + expect_status("duplicate non-duplicable handle", s, NTLSTATUS_ACCESS_DENIED); s = duplicate_handle(queue, process, SYS_HANDLE_RIGHT_READ | 0x80000000u, SYS_DUPLICATE_HANDLE_FLAG_NONE, &ignored); - expect_status("duplicate unknown rights", s, STATUS_INVALID_PARAMETER); + expect_status("duplicate unknown rights", s, NTLSTATUS_INVALID_PARAMETER); s = duplicate_handle(queue, process, SYS_HANDLE_RIGHT_READ, SYS_DUPLICATE_HANDLE_FLAG_SAME_RIGHTS, &ignored); - expect_status("duplicate same-rights with desired rights", s, STATUS_INVALID_PARAMETER); + expect_status("duplicate same-rights with desired rights", s, NTLSTATUS_INVALID_PARAMETER); s = duplicate_handle(queue, process, 0, SYS_DUPLICATE_HANDLE_FLAG_NONE, &ignored); - expect_status("duplicate zero rights", s, STATUS_INVALID_PARAMETER); + expect_status("duplicate zero rights", s, NTLSTATUS_INVALID_PARAMETER); SYS_DUPLICATE_HANDLE_REQUEST badOut = { queue, @@ -191,7 +191,7 @@ int main(void) { 0, }; s = SysDuplicateHandle(&badOut); - expect_status("duplicate null output", s, STATUS_INVALID_PARAMETER); + expect_status("duplicate null output", s, NTLSTATUS_INVALID_PARAMETER); SysCloseHandle(sameRights); SysCloseHandle(writeOnly); diff --git a/code/user/tests/input_api_smoke/input_api_smoke.c b/code/user/tests/input_api_smoke/input_api_smoke.c index c4afb7b..e370778 100644 --- a/code/user/tests/input_api_smoke/input_api_smoke.c +++ b/code/user/tests/input_api_smoke/input_api_smoke.c @@ -62,21 +62,21 @@ static void expect_status(const char* what, uint32_t got, uint32_t expected) { int main(void) { print("input_api_smoke: start\n"); - expect_status("poll keyboard null", SysPollKeyboard((INPUT_KEY*)0), STATUS_INVALID_PARAMETER); - expect_status("is key down null", SysIsKeyDown(INPUT_KEY_A, (bool*)0), STATUS_INVALID_PARAMETER); - expect_status("read key null", SysReadKey((INPUT_KEY*)0), STATUS_INVALID_PARAMETER); - expect_status("read char null", SysReadKeyboardChar((char*)0), STATUS_INVALID_PARAMETER); + expect_status("poll keyboard null", SysPollKeyboard((INPUT_KEY*)0), NTLSTATUS_INVALID_PARAMETER); + expect_status("is key down null", SysIsKeyDown(INPUT_KEY_A, (bool*)0), NTLSTATUS_INVALID_PARAMETER); + expect_status("read key null", SysReadKey((INPUT_KEY*)0), NTLSTATUS_INVALID_PARAMETER); + expect_status("read char null", SysReadKeyboardChar((char*)0), NTLSTATUS_INVALID_PARAMETER); bool down = true; uint32_t status = SysIsKeyDown(INPUT_KEY_A, &down); - if (status != STATUS_SUCCESS) + if (status != NTLSTATUS_SUCCESS) fail_status("is key down", status); INPUT_KEY key = INPUT_KEY_A; status = SysPollKeyboard(&key); - if (status != STATUS_SUCCESS && status != STATUS_WOULD_BLOCK) + if (status != NTLSTATUS_SUCCESS && status != NTLSTATUS_WOULD_BLOCK) fail_status("poll keyboard", status); - if (status == STATUS_WOULD_BLOCK && key != INPUT_KEY_NONE) + if (status == NTLSTATUS_WOULD_BLOCK && key != INPUT_KEY_NONE) fail_status("poll keyboard would-block key", key); INPUT_KEY_RECORD input; @@ -87,33 +87,33 @@ int main(void) { inputReq.TimeoutMilliseconds = 0; inputReq.RecordOut = &input; - expect_status("peek input null", SysPeekInputEvent((const SYS_INPUT_EVENT_REQUEST*)0), STATUS_INVALID_PARAMETER); + expect_status("peek input null", SysPeekInputEvent((const SYS_INPUT_EVENT_REQUEST*)0), NTLSTATUS_INVALID_PARAMETER); status = SysPeekInputEvent(&inputReq); - if (status != STATUS_SUCCESS && status != STATUS_WOULD_BLOCK) + if (status != NTLSTATUS_SUCCESS && status != NTLSTATUS_WOULD_BLOCK) fail_status("peek input", status); INPUT_MOUSE_EVENT mouse; - expect_status("peek mouse null", SysPeekMouse((INPUT_MOUSE_EVENT*)0), STATUS_INVALID_PARAMETER); - expect_status("read mouse null", SysReadMouse((INPUT_MOUSE_EVENT*)0), STATUS_INVALID_PARAMETER); + expect_status("peek mouse null", SysPeekMouse((INPUT_MOUSE_EVENT*)0), NTLSTATUS_INVALID_PARAMETER); + expect_status("read mouse null", SysReadMouse((INPUT_MOUSE_EVENT*)0), NTLSTATUS_INVALID_PARAMETER); status = SysPeekMouse(&mouse); - if (status != STATUS_SUCCESS && status != STATUS_WOULD_BLOCK) + if (status != NTLSTATUS_SUCCESS && status != NTLSTATUS_WOULD_BLOCK) fail_status("peek mouse", status); uint32_t readStatus = SysReadMouse(&mouse); - if (status == STATUS_SUCCESS) { - if (readStatus != STATUS_SUCCESS) + if (status == NTLSTATUS_SUCCESS) { + if (readStatus != NTLSTATUS_SUCCESS) fail_status("read mouse after peek", readStatus); - } else if (readStatus != STATUS_WOULD_BLOCK) { + } else if (readStatus != NTLSTATUS_WOULD_BLOCK) { fail_status("read mouse would-block", readStatus); } int x = 0; int y = 0; - expect_status("get mouse pos null x", SysGetMousePos((int*)0, &y), STATUS_INVALID_PARAMETER); - expect_status("get mouse pos null y", SysGetMousePos(&x, (int*)0), STATUS_INVALID_PARAMETER); + expect_status("get mouse pos null x", SysGetMousePos((int*)0, &y), NTLSTATUS_INVALID_PARAMETER); + expect_status("get mouse pos null y", SysGetMousePos(&x, (int*)0), NTLSTATUS_INVALID_PARAMETER); status = SysGetMousePos(&x, &y); - if (status != STATUS_SUCCESS) + if (status != NTLSTATUS_SUCCESS) fail_status("get mouse pos", status); print("input_api_smoke: PASS\n"); diff --git a/code/user/tests/input_model_smoke/input_model_smoke.c b/code/user/tests/input_model_smoke/input_model_smoke.c index 53b175d..19c4000 100644 --- a/code/user/tests/input_model_smoke/input_model_smoke.c +++ b/code/user/tests/input_model_smoke/input_model_smoke.c @@ -62,11 +62,11 @@ int main(void) { print("input_model_smoke: start\n"); uint32_t inputQueue = 0; - expect_status("open input queue null", SysOpenInputQueue(SYS_INPUT_QUEUE_FLAG_NONE, (uint32_t*)0), STATUS_INVALID_PARAMETER); - expect_status("open input queue bad flags", SysOpenInputQueue(1, &inputQueue), STATUS_INVALID_PARAMETER); + expect_status("open input queue null", SysOpenInputQueue(SYS_INPUT_QUEUE_FLAG_NONE, (uint32_t*)0), NTLSTATUS_INVALID_PARAMETER); + expect_status("open input queue bad flags", SysOpenInputQueue(1, &inputQueue), NTLSTATUS_INVALID_PARAMETER); uint32_t status = SysOpenInputQueue(SYS_INPUT_QUEUE_FLAG_NONE, &inputQueue); - if (status != STATUS_SUCCESS) + if (status != NTLSTATUS_SUCCESS) fail_status("open input queue", status); INPUT_KEY_RECORD record; @@ -79,31 +79,31 @@ int main(void) { SYS_INPUT_EVENT_REQUEST badReq = req; badReq.Size = 0; - expect_status("read input bad size", SysReadInputEvent(&badReq), STATUS_INVALID_PARAMETER); + expect_status("read input bad size", SysReadInputEvent(&badReq), NTLSTATUS_INVALID_PARAMETER); badReq = req; badReq.RecordOut = (INPUT_KEY_RECORD*)0; - expect_status("peek input null out", SysPeekInputEvent(&badReq), STATUS_INVALID_PARAMETER); + expect_status("peek input null out", SysPeekInputEvent(&badReq), NTLSTATUS_INVALID_PARAMETER); badReq = req; badReq.QueueHandle = 0xdeadbeefu; - expect_status("read input bad handle", SysReadInputEvent(&badReq), STATUS_INVALID_HANDLE); + expect_status("read input bad handle", SysReadInputEvent(&badReq), NTLSTATUS_INVALID_HANDLE); status = SysPeekInputEvent(&req); - if (status != STATUS_SUCCESS && status != STATUS_WOULD_BLOCK) + if (status != NTLSTATUS_SUCCESS && status != NTLSTATUS_WOULD_BLOCK) fail_status("peek input immediate", status); uint32_t waitStatus = SysWaitSingle(inputQueue, SYS_WAIT_FLAG_NONE, 0); - if (status == STATUS_SUCCESS) { - if (waitStatus != STATUS_SUCCESS) + if (status == NTLSTATUS_SUCCESS) { + if (waitStatus != NTLSTATUS_SUCCESS) fail_status("wait input after readable peek", waitStatus); - } else if (waitStatus != STATUS_TIMEOUT) { + } else if (waitStatus != NTLSTATUS_TIMEOUT) { fail_status("wait empty input immediate", waitStatus); } req.TimeoutMilliseconds = 1; status = SysReadInputEvent(&req); - if (status != STATUS_SUCCESS && status != STATUS_TIMEOUT) + if (status != NTLSTATUS_SUCCESS && status != NTLSTATUS_TIMEOUT) fail_status("read input finite timeout", status); SysCloseHandle(inputQueue); diff --git a/code/user/tests/mmap_smoke/mmap_smoke.c b/code/user/tests/mmap_smoke/mmap_smoke.c index 817c7df..438e407 100644 --- a/code/user/tests/mmap_smoke/mmap_smoke.c +++ b/code/user/tests/mmap_smoke/mmap_smoke.c @@ -76,15 +76,15 @@ static uint32_t open_first_existing(uint32_t* fileOut, const char** pathOut) { SYS_FILE_FLAG_NONE, &file); uint32_t s = SysOpenFile(&openReq); - if (s == STATUS_SUCCESS) { + if (s == NTLSTATUS_SUCCESS) { *fileOut = file; if (pathOut) *pathOut = candidates[i]; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } int main(void) { @@ -93,7 +93,7 @@ int main(void) { uint32_t file = 0; const char* openedPath = 0; uint32_t s = open_first_existing(&file, &openedPath); - if (s != STATUS_SUCCESS) + if (s != NTLSTATUS_SUCCESS) fail_status("open test file", s); print("mmap_smoke: using "); @@ -105,7 +105,7 @@ int main(void) { SYS_FILE_IO_REQUEST ioReq = SysMakeFileIoRequest(file, gExpected, sizeof(gExpected), &got); s = SysReadFile(&ioReq); - if (s != STATUS_SUCCESS) + if (s != NTLSTATUS_SUCCESS) fail_status("read baseline", s); if (got < 64) fail_msg("baseline read was unexpectedly short"); @@ -118,7 +118,7 @@ int main(void) { SYS_MAP_FLAG_NONE, sizeof(gExpected), &mapping); - if (s != STATUS_SUCCESS) + if (s != NTLSTATUS_SUCCESS) fail_status("create file mapping", s); print("mmap_smoke: mapping created\n"); @@ -141,7 +141,7 @@ int main(void) { SysCloseHandle(mapping); mapping = 0; - if (s != STATUS_SUCCESS) + if (s != NTLSTATUS_SUCCESS) fail_status("map file view", s); if (!base) fail_msg("map returned null base"); @@ -191,7 +191,7 @@ int main(void) { print("mmap_smoke: EOF fill OK\n"); s = SysFreeVm(base); - if (s != STATUS_SUCCESS) + if (s != NTLSTATUS_SUCCESS) fail_status("unmap", s); print("mmap_smoke: PASS\n"); diff --git a/code/user/tests/module_load_smoke/module_load_smoke.c b/code/user/tests/module_load_smoke/module_load_smoke.c index 2e195fd..4120dc7 100644 --- a/code/user/tests/module_load_smoke/module_load_smoke.c +++ b/code/user/tests/module_load_smoke/module_load_smoke.c @@ -68,14 +68,14 @@ static void check_module_info(const SYS_MODULE_INFO* info) { static int module_list_contains(uintptr_t base) { size_t count = 0; uint32_t status = SysGetModuleList(0, 0, &count); - if (status != STATUS_SUCCESS) fail_status("query module count", status); + if (status != NTLSTATUS_SUCCESS) fail_status("query module count", status); if (count == 0) return 0; if (count > 32) fail("module count unexpectedly large"); SYS_MODULE_INFO modules[32]; memset(modules, 0, sizeof(modules)); status = SysGetModuleList(modules, count, &count); - if (status != STATUS_SUCCESS) fail_status("query module list", status); + if (status != NTLSTATUS_SUCCESS) fail_status("query module list", status); for (size_t i = 0; i < count; i++) { if (modules[i].Base == base) @@ -95,7 +95,7 @@ static void check_export_lookup(void) { req.ModuleHandleOut = &handle; uint32_t status = SysLoadModule(&req); - if (status != STATUS_SUCCESS) fail_status("load syscall.dll", status); + if (status != NTLSTATUS_SUCCESS) fail_status("load syscall.dll", status); if (handle == 0) fail("syscall load returned null handle"); uintptr_t address = 0; @@ -107,11 +107,11 @@ static void check_export_lookup(void) { exportReq.AddressOut = &address; status = SysGetModuleExport(&exportReq); - if (status != STATUS_SUCCESS) fail_status("lookup SysGetCurrentPid", status); + if (status != NTLSTATUS_SUCCESS) fail_status("lookup SysGetCurrentPid", status); if (address == 0) fail("export address is zero"); status = SysUnloadModule(handle); - if (status != STATUS_SUCCESS) fail_status("unload syscall.dll handle", status); + if (status != NTLSTATUS_SUCCESS) fail_status("unload syscall.dll handle", status); } // Runs the public dynamic module loader smoke test. @@ -131,7 +131,7 @@ int main(void) { req.InfoOut = &info; uint32_t status = SysLoadModule(&req); - if (status != STATUS_SUCCESS) fail_status("load posix.dll", status); + if (status != NTLSTATUS_SUCCESS) fail_status("load posix.dll", status); if (handle == 0) fail("load returned null handle"); check_module_info(&info); if (!module_list_contains(info.Base)) fail("loaded module absent from list"); @@ -139,16 +139,16 @@ int main(void) { SYS_MODULE_INFO byHandle; memset(&byHandle, 0, sizeof(byHandle)); status = SysGetModuleInfo(handle, &byHandle); - if (status != STATUS_SUCCESS) fail_status("get module info", status); + if (status != NTLSTATUS_SUCCESS) fail_status("get module info", status); check_module_info(&byHandle); if (byHandle.Base != info.Base) fail("module handle base mismatch"); status = SysUnloadModule(handle); - if (status != STATUS_SUCCESS) fail_status("unload module", status); + if (status != NTLSTATUS_SUCCESS) fail_status("unload module", status); memset(&byHandle, 0, sizeof(byHandle)); status = SysGetModuleInfo(handle, &byHandle); - if (status != STATUS_INVALID_HANDLE) fail_status("query unloaded handle", status); + if (status != NTLSTATUS_INVALID_HANDLE) fail_status("query unloaded handle", status); print("module_load_smoke: PASS\n"); exit_now(0); diff --git a/code/user/tests/named_queue_lifetime_smoke/named_queue_lifetime_smoke.c b/code/user/tests/named_queue_lifetime_smoke/named_queue_lifetime_smoke.c new file mode 100644 index 0000000..5b0d180 --- /dev/null +++ b/code/user/tests/named_queue_lifetime_smoke/named_queue_lifetime_smoke.c @@ -0,0 +1,194 @@ +// Native named queue lifetime smoke test. +// Verifies explicit name withdrawal and automatic withdrawal on owner handle close. + +#include +#include +#include + +#define TEST_MESSAGE_TYPE 0x71756575u +#define TEST_MESSAGE_VALUE 0x123456789abcdef0ull + +typedef struct TEST_QUEUE_MESSAGE { + uint32_t Type; + uint32_t Flags; + uint64_t Param[6]; +} TEST_QUEUE_MESSAGE; + +typedef char TEST_QUEUE_MESSAGE_SIZE_CHECK[ + (sizeof(TEST_QUEUE_MESSAGE) == SYS_QUEUE_MESSAGE_SIZE) ? 1 : -1 +]; + +// 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) { + for (;;) SysExitProcess(code); +} + +// Fails the test with one plain message. +static void fail(const char* msg) { + print("named_queue_lifetime_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("named_queue_lifetime_smoke: "); + print(what); + print(" status="); + print_u64(status); + print("\n"); + exit_now(1); +} + +// Requires one exact status value. +static void expect_status(const char* what, uint32_t got, uint32_t expected) { + if (got == expected) return; + print("named_queue_lifetime_smoke: "); + print(what); + print(" got="); + print_u64(got); + print(" expected="); + print_u64(expected); + print("\n"); + exit_now(1); +} + +// Publishes one queue under a short test name. +static uint32_t publish_queue(const char* name, uint32_t queue) { + SYS_PUBLISH_QUEUE_REQUEST req; + memset(&req, 0, sizeof(req)); + req.Name = SysSvFromCstr(name); + req.QueueHandle = queue; + return SysPublishQueue(&req); +} + +// Withdraws one named queue publication. +static uint32_t unpublish_queue(const char* name) { + SYS_UNPUBLISH_QUEUE_REQUEST req; + memset(&req, 0, sizeof(req)); + req.Name = SysSvFromCstr(name); + return SysUnpublishQueue(&req); +} + +// Opens one named queue publication. +static uint32_t open_named_queue(const char* name, uint32_t* out) { + SYS_OPEN_NAMED_QUEUE_REQUEST req; + memset(&req, 0, sizeof(req)); + req.Name = SysSvFromCstr(name); + req.HandleOut = out; + return SysOpenNamedQueue(&req); +} + +// Sends one fixed-size queue message. +static uint32_t send_message(uint32_t queue, const TEST_QUEUE_MESSAGE* message) { + SYS_QUEUE_SEND_REQUEST req; + memset(&req, 0, sizeof(req)); + req.Size = sizeof(req); + req.QueueHandle = queue; + req.Flags = SYS_QUEUE_FLAG_NONE; + req.TimeoutMilliseconds = 0; + req.Message = message; + return SysSendQueue(&req); +} + +// Receives one fixed-size queue message. +static uint32_t recv_message(uint32_t queue, TEST_QUEUE_MESSAGE* message) { + SYS_QUEUE_RECV_REQUEST req; + memset(&req, 0, sizeof(req)); + req.Size = sizeof(req); + req.QueueHandle = queue; + req.Flags = SYS_QUEUE_FLAG_NONE; + req.TimeoutMilliseconds = 0; + req.MessageOut = message; + return SysRecvQueue(&req); +} + +// Verifies explicit unpublish removes only the name, not existing handles. +static void check_explicit_unpublish(void) { + uint32_t queue = 0; + uint32_t opened = 0; + uint32_t status = SysCreateQueue(&queue); + if (status != NTLSTATUS_SUCCESS) fail_status("create queue", status); + + status = publish_queue("ntl.queue.explicit", queue); + if (status != NTLSTATUS_SUCCESS) fail_status("publish queue", status); + + status = open_named_queue("ntl.queue.explicit", &opened); + if (status != NTLSTATUS_SUCCESS) fail_status("open published queue", status); + if (!opened) fail("opened handle is zero"); + + status = unpublish_queue("ntl.queue.explicit"); + if (status != NTLSTATUS_SUCCESS) fail_status("unpublish queue", status); + + uint32_t missing = 0; + status = open_named_queue("ntl.queue.explicit", &missing); + expect_status("open withdrawn name", status, NTLSTATUS_NOT_FOUND); + + TEST_QUEUE_MESSAGE out; + TEST_QUEUE_MESSAGE in; + memset(&out, 0, sizeof(out)); + memset(&in, 0, sizeof(in)); + out.Type = TEST_MESSAGE_TYPE; + out.Param[0] = TEST_MESSAGE_VALUE; + status = send_message(queue, &out); + if (status != NTLSTATUS_SUCCESS) fail_status("send after unpublish", status); + status = recv_message(opened, &in); + if (status != NTLSTATUS_SUCCESS) fail_status("recv after unpublish", status); + if (in.Type != TEST_MESSAGE_TYPE || in.Param[0] != TEST_MESSAGE_VALUE) + fail("message mismatch after unpublish"); + + SysCloseHandle(opened); + SysCloseHandle(queue); +} + +// Verifies closing the publishing handle withdraws its names. +static void check_close_withdraws_name(void) { + uint32_t queue = 0; + uint32_t status = SysCreateQueue(&queue); + if (status != NTLSTATUS_SUCCESS) fail_status("create close queue", status); + + status = publish_queue("ntl.queue.close", queue); + if (status != NTLSTATUS_SUCCESS) fail_status("publish close queue", status); + + SysCloseHandle(queue); + + uint32_t opened = 0; + status = open_named_queue("ntl.queue.close", &opened); + expect_status("open close-withdrawn name", status, NTLSTATUS_NOT_FOUND); +} + +// Runs the named queue lifetime smoke test. +int main(void) { + print("named_queue_lifetime_smoke: start\n"); + check_explicit_unpublish(); + check_close_withdraws_name(); + print("named_queue_lifetime_smoke: PASS\n"); + exit_now(0); + return 0; +} diff --git a/code/user/tests/native_exception_runtime_smoke/native_exception_runtime_smoke.c b/code/user/tests/native_exception_runtime_smoke/native_exception_runtime_smoke.c new file mode 100644 index 0000000..3dae79f --- /dev/null +++ b/code/user/tests/native_exception_runtime_smoke/native_exception_runtime_smoke.c @@ -0,0 +1,151 @@ +// Native exception runtime smoke test. This file verifies process-start registration and handler dispatch. + +#include +#include +#include +#include + +static volatile uint32_t gSearchHits; +static volatile uint32_t gContinueHits; + +// 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. +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 process. +static void exit_now(int32_t code) { + for (;;) SysExitProcess(code); +} + +// Fails the test with one message. +static void fail(const char* message) { + print("native_exception_runtime_smoke: "); + print(message); + print("\n"); + exit_now(1); +} + +// Fails the test with one status value. +static void fail_status(const char* what, uint32_t status) { + print("native_exception_runtime_smoke: "); + print(what); + print(" status="); + print_u64(status); + print("\n"); + exit_now(1); +} + +// Requires one syscall to return the expected status. +static void expect_status(const char* what, uint32_t got, uint32_t expected) { + if (got != expected) { + print("native_exception_runtime_smoke: "); + print(what); + print(" expected="); + print_u64(expected); + print(" got="); + print_u64(got); + print("\n"); + exit_now(1); + } +} + +// Verifies the native runtime installed the process dispatcher during startup. +static void verify_startup_registration(void) { + SYS_EXCEPTION_DISPATCHER_REQUEST request; + for (size_t i = 0; i < sizeof(request); i++) + ((char*)&request)[i] = 0; + request.Size = sizeof(request); + + uint32_t status = SysGetExceptionDispatcher(&request); + if (status != NTLSTATUS_SUCCESS) + fail_status("get dispatcher", status); + if (!request.DispatcherRoutine) + fail("runtime dispatcher was not registered"); +} + +// Verifies one breakpoint exception record has the expected native shape. +static void verify_breakpoint_record(SYS_EXCEPTION_RECORD* record, SYS_USER_CONTEXT* context) { + if (!record || !context) + fail("handler received null state"); + if (record->Size != sizeof(*record) || record->Version != SYS_EXCEPTION_ABI_VERSION) + fail("record ABI mismatch"); + if (context->Size != sizeof(*context) || context->Version != SYS_EXCEPTION_ABI_VERSION) + fail("context ABI mismatch"); + if (record->Code != SYS_EXCEPTION_CODE_BREAKPOINT) + fail("unexpected exception code"); +} + +// Records a first-chance exception and asks the dispatcher to continue searching. +static int search_handler(SYS_EXCEPTION_RECORD* record, SYS_USER_CONTEXT* context, void* userContext) { + if (userContext != (void*)(uintptr_t)0x1111) + fail("search handler context mismatch"); + verify_breakpoint_record(record, context); + gSearchHits++; + return NTL_EXCEPTION_CONTINUE_SEARCH; +} + +// Records a first-chance exception and asks the kernel to resume the saved context. +static int continue_handler(SYS_EXCEPTION_RECORD* record, SYS_USER_CONTEXT* context, void* userContext) { + if (userContext != (void*)(uintptr_t)0x2222) + fail("continue handler context mismatch"); + verify_breakpoint_record(record, context); + gContinueHits++; + return NTL_EXCEPTION_CONTINUE_EXECUTION; +} + +// Verifies the process-local handler list can dispatch and remove handlers. +static void verify_handler_dispatch(void) { + expect_status("remove null", NtlRemoveExceptionHandler(0), NTLSTATUS_INVALID_PARAMETER); + if (NtlAddExceptionHandler(0, 0, 0)) + fail("null handler was accepted"); + + void* search = NtlAddExceptionHandler(0, search_handler, (void*)(uintptr_t)0x1111); + void* cont = NtlAddExceptionHandler(0, continue_handler, (void*)(uintptr_t)0x2222); + if (!search || !cont) + fail("handler registration failed"); + + __debugbreak(); + if (gSearchHits != 1 || gContinueHits != 1) + fail("breakpoint did not visit both handlers"); + + expect_status("remove search", NtlRemoveExceptionHandler(search), NTLSTATUS_SUCCESS); + __debugbreak(); + if (gSearchHits != 1 || gContinueHits != 2) + fail("removed handler still participated"); + + expect_status("remove continue", NtlRemoveExceptionHandler(cont), NTLSTATUS_SUCCESS); + expect_status("remove continue twice", NtlRemoveExceptionHandler(cont), NTLSTATUS_NOT_FOUND); +} + +// Runs the native exception runtime smoke test. +int main(void) { + print("native_exception_runtime_smoke: start\n"); + + verify_startup_registration(); + verify_handler_dispatch(); + + print("native_exception_runtime_smoke: PASS\n"); + exit_now(0); + return 0; +} diff --git a/code/user/tests/native_raise_exception_smoke/native_raise_exception_smoke.c b/code/user/tests/native_raise_exception_smoke/native_raise_exception_smoke.c new file mode 100644 index 0000000..72a0124 --- /dev/null +++ b/code/user/tests/native_raise_exception_smoke/native_raise_exception_smoke.c @@ -0,0 +1,143 @@ +// Native user-raised exception smoke test. + +#include +#include +#include +#include + +#define SMOKE_EXCEPTION_CODE 0xE1111001u + +static volatile uint32_t gHandlerHits; + +// 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. +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 process. +static void exit_now(int32_t code) { + for (;;) SysExitProcess(code); +} + +// Fails the test with one message. +static void fail(const char* message) { + print("native_raise_exception_smoke: "); + print(message); + print("\n"); + exit_now(1); +} + +// Fails the test with one status value. +static void fail_status(const char* what, uint32_t status) { + print("native_raise_exception_smoke: "); + print(what); + print(" status="); + print_u64(status); + print("\n"); + exit_now(1); +} + +// Requires one syscall to return the expected status. +static void expect_status(const char* what, uint32_t got, uint32_t expected) { + if (got != expected) { + print("native_raise_exception_smoke: "); + print(what); + print(" expected="); + print_u64(expected); + print(" got="); + print_u64(got); + print("\n"); + exit_now(1); + } +} + +// Reads aggregate exception counters. +static void query_exception_stats(SYS_EXCEPTION_STATS* out) { + uint32_t status = SysQueryKernelStats(SYS_KERNEL_STATS_EXCEPTION, out, sizeof(*out), 0); + expect_status("query exception stats", status, NTLSTATUS_SUCCESS); + if (out->Size != sizeof(*out) || out->Version != SYS_STATS_VERSION) + fail("exception stats ABI mismatch"); +} + +// Handles the user-raised exception and verifies its native record payload. +static int smoke_handler(SYS_EXCEPTION_RECORD* record, SYS_USER_CONTEXT* context, void* userContext) { + if (userContext != (void*)(uintptr_t)0x111E) + fail("handler context mismatch"); + if (!record || !context) + fail("handler received null records"); + if (record->Code != SMOKE_EXCEPTION_CODE) + fail("handler received wrong exception code"); + if ((record->Flags & SYS_EXCEPTION_FLAG_FIRST_CHANCE) == 0) + fail("handler missing first-chance flag"); + if (record->Flags & SYS_EXCEPTION_FLAG_NONCONTINUABLE) + fail("handler received unexpected noncontinuable flag"); + if (record->ParameterCount != 2) + fail("handler received wrong parameter count"); + if (record->Parameters[0] != 0x12345678u || record->Parameters[1] != 0xABCDEF00u) + fail("handler received wrong parameters"); + if (!context->Rip || !context->Rsp) + fail("handler received empty context"); + + gHandlerHits++; + return NTL_EXCEPTION_CONTINUE_EXECUTION; +} + +int main(void) { + print("native_raise_exception_smoke: start\n"); + + SYS_EXCEPTION_STATS before; + SYS_EXCEPTION_STATS after; + query_exception_stats(&before); + + void* handle = NtlAddExceptionHandler(1, smoke_handler, (void*)(uintptr_t)0x111E); + if (!handle) + fail("failed to add native exception handler"); + + uint64_t args[2] = { 0x12345678u, 0xABCDEF00u }; + SYS_RAISE_EXCEPTION_REQUEST request; + request.Size = sizeof(request); + request.Flags = SYS_RAISE_EXCEPTION_FLAG_NONE; + request.Code = SMOKE_EXCEPTION_CODE; + request.ParameterCount = 2; + request.Parameters = args; + + uint32_t status = SysRaiseException(&request); + expect_status("raise exception", status, NTLSTATUS_SUCCESS); + if (gHandlerHits != 1) + fail("handler was not called exactly once"); + + status = NtlRemoveExceptionHandler(handle); + expect_status("remove native exception handler", status, NTLSTATUS_SUCCESS); + + query_exception_stats(&after); + if (after.Delivered < before.Delivered + 1 || + after.UserRaised < before.UserRaised + 1 || + after.Continued < before.Continued + 1) + fail("exception counters did not advance"); + if (after.LastCode != SMOKE_EXCEPTION_CODE) + fail("last exception code was not updated"); + + print("native_raise_exception_smoke: PASS\n"); + exit_now(0); + return 0; +} diff --git a/code/user/tests/net_irp_smoke/net_irp_smoke.c b/code/user/tests/net_irp_smoke/net_irp_smoke.c index d2eeaa3..f9b6cf7 100644 --- a/code/user/tests/net_irp_smoke/net_irp_smoke.c +++ b/code/user/tests/net_irp_smoke/net_irp_smoke.c @@ -62,7 +62,7 @@ static SYS_NET_IRP_STATS query_stats(void) { SYS_NET_IRP_STATS stats; memset(&stats, 0, sizeof(stats)); uint32_t status = SysQueryKernelStats(SYS_KERNEL_STATS_NET_IRP, &stats, sizeof(stats), 0); - if (status != STATUS_SUCCESS) + if (status != NTLSTATUS_SUCCESS) fail_status("query net irp stats", status); if (stats.Size != sizeof(stats)) fail("net irp stats size mismatch"); @@ -93,20 +93,20 @@ static void set_u32_option(uint32_t socket, uint32_t option, uint32_t value) { req.Value = &value; req.ValueSize = sizeof(value); uint32_t status = SysSetSocketOption(socket, &req); - if (status != STATUS_SUCCESS) + if (status != NTLSTATUS_SUCCESS) fail_status("set socket option", status); } // Waits for an async socket request to publish a terminal IOSB status. static void wait_for_async(uint32_t event, SYS_IO_STATUS_BLOCK* iosb, const char* what) { - for (uint32_t i = 0; i < 200u && iosb->Status == STATUS_PENDING; ++i) { + for (uint32_t i = 0; i < 200u && iosb->Status == NTLSTATUS_PENDING; ++i) { uint32_t status = SysWait(event, 0); - if (status != STATUS_SUCCESS && status != STATUS_ALERTED && - status != STATUS_KERNEL_APC && status != STATUS_USER_APC) { + if (status != NTLSTATUS_SUCCESS && status != NTLSTATUS_ALERTED && + status != NTLSTATUS_KERNEL_APC && status != NTLSTATUS_USER_APC) { fail_status(what, status); } } - if (iosb->Status == STATUS_PENDING) + if (iosb->Status == NTLSTATUS_PENDING) fail("async request stayed pending"); } @@ -114,12 +114,12 @@ static void wait_for_async(uint32_t event, SYS_IO_STATUS_BLOCK* iosb, const char static void check_nonblocking_receive(void) { uint32_t udp = 0; uint32_t status = SysCreateSocket(SYS_AF_INET, SYS_SOCK_DGRAM, SYS_IPPROTO_UDP, &udp); - if (status != STATUS_SUCCESS) + if (status != NTLSTATUS_SUCCESS) fail_status("create udp socket", status); SYS_SOCKET_ADDRESS bindAddress = make_ipv4(0, 0, 0, 0, NET_IRP_SMOKE_UDP_PORT); status = SysBindSocket(udp, &bindAddress, sizeof(bindAddress)); - if (status != STATUS_SUCCESS) { + if (status != NTLSTATUS_SUCCESS) { SysCloseHandle(udp); fail_status("bind udp socket", status); } @@ -143,7 +143,7 @@ static void check_nonblocking_receive(void) { status = SysRecvFromSocket(udp, &req); SysCloseHandle(udp); - if (status != STATUS_WOULD_BLOCK) + if (status != NTLSTATUS_WOULD_BLOCK) fail_status("nonblocking udp recvfrom", status); } @@ -151,19 +151,19 @@ static void check_nonblocking_receive(void) { static void check_async_receive_cancel(void) { uint32_t udp = 0; uint32_t status = SysCreateSocket(SYS_AF_INET, SYS_SOCK_DGRAM, SYS_IPPROTO_UDP, &udp); - if (status != STATUS_SUCCESS) + if (status != NTLSTATUS_SUCCESS) fail_status("create cancel udp socket", status); SYS_SOCKET_ADDRESS bindAddress = make_ipv4(0, 0, 0, 0, NET_IRP_SMOKE_UDP_PORT + 1u); status = SysBindSocket(udp, &bindAddress, sizeof(bindAddress)); - if (status != STATUS_SUCCESS) { + if (status != NTLSTATUS_SUCCESS) { SysCloseHandle(udp); fail_status("bind cancel udp socket", status); } uint32_t event = 0; status = SysCreateEvent(EVENT_AUTO_RESET, 0, &event); - if (status != STATUS_SUCCESS) { + if (status != NTLSTATUS_SUCCESS) { SysCloseHandle(udp); fail_status("create event", status); } @@ -193,7 +193,7 @@ static void check_async_receive_cancel(void) { SYS_NET_IRP_STATS beforeSubmit = query_stats(); status = SysSocketIoAsync(&req); - if (status != STATUS_PENDING || requestHandle == 0) { + if (status != NTLSTATUS_PENDING || requestHandle == 0) { SysCloseHandle(event); SysCloseHandle(udp); fail_status("submit async recvfrom", status); @@ -213,17 +213,17 @@ static void check_async_receive_cancel(void) { fail("async recvfrom did not enter the IRP path"); uint32_t cancelStatus = SysCancelIo(requestHandle); - if (cancelStatus != STATUS_SUCCESS && cancelStatus != STATUS_PENDING) + if (cancelStatus != NTLSTATUS_SUCCESS && cancelStatus != NTLSTATUS_PENDING) fail_status("cancel async recvfrom", cancelStatus); wait_for_async(event, &iosb, "wait async recvfrom cancel"); - if (iosb.Status != STATUS_CANCELLED) + if (iosb.Status != NTLSTATUS_CANCELLED) fail_status("async recvfrom iosb", iosb.Status); if (iosb.Information != 0) fail("async recvfrom cancel transferred bytes"); status = SysWaitSingle(requestHandle, 0, 0); - if (status != STATUS_SUCCESS) + if (status != NTLSTATUS_SUCCESS) fail_status("wait cancelled request handle", status); SysCloseHandle(requestHandle); @@ -235,7 +235,7 @@ static void check_async_receive_cancel(void) { static void try_http_async_success(void) { uint32_t tcp = 0; uint32_t status = SysCreateSocket(SYS_AF_INET, SYS_SOCK_STREAM, SYS_IPPROTO_TCP, &tcp); - if (status != STATUS_SUCCESS) { + if (status != NTLSTATUS_SUCCESS) { print("net_irp_smoke: http success path skipped create status="); print_u64(status); print("\n"); @@ -244,7 +244,7 @@ static void try_http_async_success(void) { SYS_SOCKET_ADDRESS address = make_ipv4(10, 0, 2, 2, NET_IRP_SMOKE_HTTP_PORT); status = SysConnectSocket(tcp, &address, sizeof(address)); - if (status != STATUS_SUCCESS) { + if (status != NTLSTATUS_SUCCESS) { print("net_irp_smoke: http success path skipped connect status="); print_u64(status); print("\n"); @@ -254,7 +254,7 @@ static void try_http_async_success(void) { uint32_t event = 0; status = SysCreateEvent(EVENT_AUTO_RESET, 0, &event); - if (status != STATUS_SUCCESS) { + if (status != NTLSTATUS_SUCCESS) { SysCloseHandle(tcp); fail_status("create http event", status); } @@ -276,10 +276,10 @@ static void try_http_async_success(void) { sendReq.RequestHandleOut = &sendRequest; status = SysSocketIoAsync(&sendReq); - if (status != STATUS_PENDING || sendRequest == 0) + if (status != NTLSTATUS_PENDING || sendRequest == 0) fail_status("submit async send", status); wait_for_async(event, &sendIosb, "wait async send"); - if (sendIosb.Status != STATUS_SUCCESS) + if (sendIosb.Status != NTLSTATUS_SUCCESS) fail_status("async send iosb", sendIosb.Status); if (sendIosb.Information != sizeof(requestText) - 1u) fail("async send byte count mismatch"); @@ -303,10 +303,10 @@ static void try_http_async_success(void) { recvReq.RequestHandleOut = &recvRequest; status = SysSocketIoAsync(&recvReq); - if (status != STATUS_PENDING || recvRequest == 0) + if (status != NTLSTATUS_PENDING || recvRequest == 0) fail_status("submit async recv", status); wait_for_async(event, &recvIosb, "wait async recv"); - if (recvIosb.Status != STATUS_SUCCESS) + if (recvIosb.Status != NTLSTATUS_SUCCESS) fail_status("async recv iosb", recvIosb.Status); if (recvIosb.Information == 0) fail("async recv returned no bytes"); diff --git a/code/user/tests/pcache_invalidate/pcache_invalidate.c b/code/user/tests/pcache_invalidate/pcache_invalidate.c index b9a6617..1e369b2 100644 --- a/code/user/tests/pcache_invalidate/pcache_invalidate.c +++ b/code/user/tests/pcache_invalidate/pcache_invalidate.c @@ -1,5 +1,5 @@ -// Page-cache write/truncate invalidation regression test. -// Verifies cached clean pages are not reused after file write or truncate. +// Page-cache write/truncate coherency regression test. +// Verifies cached pages stay coherent after file write and cached tails are dropped after truncate. #include #include @@ -79,14 +79,14 @@ static uint32_t create_temp(uint32_t* fileOut, const char** pathOut) { SYS_FILE_FLAG_NONE, &h); uint32_t s = SysOpenFile(&req); - if (s == STATUS_SUCCESS) { + if (s == NTLSTATUS_SUCCESS) { *fileOut = h; if (pathOut) *pathOut = paths[i]; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } static void fill_patterns(void) { @@ -100,7 +100,7 @@ static void checked_write(uint32_t file, const void* buffer, size_t size, const size_t done = 0; SYS_FILE_IO_REQUEST req = SysMakeFileIoRequest(file, buffer, size, &done); uint32_t s = SysWriteFile(&req); - if (s != STATUS_SUCCESS) fail_status(what, s); + if (s != NTLSTATUS_SUCCESS) fail_status(what, s); if (done != size) fail("short write"); } @@ -109,7 +109,7 @@ static void checked_read(uint32_t file, void* buffer, size_t size, size_t* gotOu memset(buffer, 0xCC, size); SYS_FILE_IO_REQUEST req = SysMakeFileIoRequest(file, buffer, size, &got); uint32_t s = SysReadFile(&req); - if (s != STATUS_SUCCESS) fail_status(what, s); + if (s != NTLSTATUS_SUCCESS) fail_status(what, s); if (gotOut) *gotOut = got; } @@ -120,7 +120,7 @@ int main(void) { uint32_t file = 0; const char* path = 0; uint32_t s = create_temp(&file, &path); - if (s != STATUS_SUCCESS) fail_status("create temp", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create temp", s); print("pcache_invalidate: using "); print(path ? path : ""); @@ -129,7 +129,7 @@ int main(void) { checked_write(file, gOriginal, sizeof(gOriginal), "write original"); s = SysSeekFile(file, 0); - if (s != STATUS_SUCCESS) fail_status("seek fill", s); + if (s != NTLSTATUS_SUCCESS) fail_status("seek fill", s); SYS_FILE_CACHE_STATS before; SYS_FILE_CACHE_STATS afterFill; @@ -137,23 +137,24 @@ int main(void) { SYS_FILE_CACHE_STATS afterWrite; SYS_FILE_CACHE_STATS afterRewriteRead; SYS_FILE_CACHE_STATS afterTruncate; - if (query_cache(&before) != STATUS_SUCCESS) fail("initial stats query failed"); + if (query_cache(&before) != NTLSTATUS_SUCCESS) fail("initial stats query failed"); size_t got = 0; checked_read(file, gReadback, sizeof(gReadback), &got, "first read"); if (got != sizeof(gOriginal)) fail("first read size mismatch"); if (memcmp(gReadback, gOriginal, sizeof(gOriginal)) != 0) fail("first read data mismatch"); - if (query_cache(&afterFill) != STATUS_SUCCESS) fail("fill stats query failed"); - if (afterFill.Loads <= before.Loads) fail("initial read did not populate cache"); + if (query_cache(&afterFill) != NTLSTATUS_SUCCESS) fail("fill stats query failed"); + if (afterFill.Loads <= before.Loads && afterFill.Hits <= before.Hits) + fail("initial read did not touch cache"); s = SysSeekFile(file, 0); - if (s != STATUS_SUCCESS) fail_status("seek second", s); + if (s != NTLSTATUS_SUCCESS) fail_status("seek second", s); checked_read(file, gReadback, sizeof(gReadback), &got, "second read"); if (got != sizeof(gOriginal)) fail("second read size mismatch"); if (memcmp(gReadback, gOriginal, sizeof(gOriginal)) != 0) fail("second read data mismatch"); - if (query_cache(&afterSecond) != STATUS_SUCCESS) fail("second stats query failed"); + if (query_cache(&afterSecond) != NTLSTATUS_SUCCESS) fail("second stats query failed"); // Do not require this second read to hit: the cache is intentionally // bounded and pcache_pressure.exe may have left it at the soft limit, so // the newly-populated temp pages are eligible for immediate pressure @@ -161,20 +162,20 @@ int main(void) { // is covered by pcache_mmap_read_reuse.exe. s = SysSeekFile(file, 0); - if (s != STATUS_SUCCESS) fail_status("seek rewrite", s); + if (s != NTLSTATUS_SUCCESS) fail_status("seek rewrite", s); checked_write(file, gReplacement, sizeof(gReplacement), "rewrite first page"); - if (query_cache(&afterWrite) != STATUS_SUCCESS) fail("post-write stats query failed"); - if (afterWrite.Invalidations <= afterSecond.Invalidations) fail("write did not invalidate cached page"); + if (query_cache(&afterWrite) != NTLSTATUS_SUCCESS) fail("post-write stats query failed"); + if (afterWrite.DirtyMarks <= afterSecond.DirtyMarks) fail("rewrite did not dirty cached page"); uint32_t mapping = 0; s = SysCreateFileMapping(file, SYS_VM_READ, SYS_MAP_FLAG_NONE, sizeof(gReplacement), &mapping); - if (s != STATUS_SUCCESS) fail_status("create mapping after rewrite", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create mapping after rewrite", s); void* mappedBase = 0; s = SysMapFile(mapping, 0, sizeof(gReplacement), SYS_MAP_ACCESS_READ, SYS_MAP_FLAG_NONE, &mappedBase); SysCloseHandle(mapping); - if (s != STATUS_SUCCESS) fail_status("map after rewrite", s); + if (s != NTLSTATUS_SUCCESS) fail_status("map after rewrite", s); if (!mappedBase) fail("map after rewrite returned null"); volatile uint8_t* mappedView = (volatile uint8_t*)mappedBase; @@ -185,30 +186,30 @@ int main(void) { fail("stale mmap data after write invalidation"); } s = SysFreeVm(mappedBase); - if (s != STATUS_SUCCESS) fail_status("unmap after rewrite", s); + if (s != NTLSTATUS_SUCCESS) fail_status("unmap after rewrite", s); s = SysSeekFile(file, 0); - if (s != STATUS_SUCCESS) fail_status("seek verify rewrite", s); + if (s != NTLSTATUS_SUCCESS) fail_status("seek verify rewrite", s); checked_read(file, gReadback, sizeof(gReadback), &got, "read after rewrite"); if (got != sizeof(gOriginal)) fail("rewrite read size mismatch"); if (memcmp(gReadback, gReplacement, sizeof(gReplacement)) != 0) fail("stale data after write invalidation"); if (memcmp(gReadback + sizeof(gReplacement), gOriginal + sizeof(gReplacement), sizeof(gOriginal) - sizeof(gReplacement)) != 0) fail("unwritten page changed after rewrite"); - if (query_cache(&afterRewriteRead) != STATUS_SUCCESS) fail("rewrite-read stats query failed"); + if (query_cache(&afterRewriteRead) != NTLSTATUS_SUCCESS) fail("rewrite-read stats query failed"); s = SysTruncateFile(file, TRUNC_SIZE); - if (s != STATUS_SUCCESS) fail_status("truncate", s); + if (s != NTLSTATUS_SUCCESS) fail_status("truncate", s); uint64_t truncatedSize = 0; s = SysGetFileSize(file, &truncatedSize); - if (s != STATUS_SUCCESS) fail_status("get truncated size", s); + if (s != NTLSTATUS_SUCCESS) fail_status("get truncated size", s); if (truncatedSize != TRUNC_SIZE) fail("truncate size mismatch"); - if (query_cache(&afterTruncate) != STATUS_SUCCESS) fail("truncate stats query failed"); + if (query_cache(&afterTruncate) != NTLSTATUS_SUCCESS) fail("truncate stats query failed"); if (afterTruncate.Invalidations <= afterRewriteRead.Invalidations) fail("truncate did not invalidate cached tail"); s = SysSeekFile(file, 0); - if (s != STATUS_SUCCESS) fail_status("seek truncated", s); + if (s != NTLSTATUS_SUCCESS) fail_status("seek truncated", s); checked_read(file, gReadback, sizeof(gReadback), &got, "read truncated"); if (got != TRUNC_SIZE) fail("truncated read length mismatch"); if (memcmp(gReadback, gReplacement, TRUNC_SIZE) != 0) fail("truncated data mismatch"); diff --git a/code/user/tests/pcache_mmap_read_reuse/pcache_mmap_read_reuse.c b/code/user/tests/pcache_mmap_read_reuse/pcache_mmap_read_reuse.c index 8d054e8..21cdac9 100644 --- a/code/user/tests/pcache_mmap_read_reuse/pcache_mmap_read_reuse.c +++ b/code/user/tests/pcache_mmap_read_reuse/pcache_mmap_read_reuse.c @@ -78,13 +78,13 @@ static uint32_t open_test_file(uint32_t* out, const char** pathOut) { SYS_FILE_FLAG_NONE, &h); uint32_t s = SysOpenFile(&req); - if (s == STATUS_SUCCESS) { + if (s == NTLSTATUS_SUCCESS) { *out = h; if (pathOut) *pathOut = paths[i]; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } int main(void) { @@ -94,16 +94,16 @@ int main(void) { SYS_FILE_CACHE_STATS afterFault; SYS_FILE_CACHE_STATS afterRead; uint32_t s = query_cache(&before); - if (s != STATUS_SUCCESS) fail_status("query initial stats", s); + if (s != NTLSTATUS_SUCCESS) fail_status("query initial stats", s); uint32_t file = 0; const char* path = 0; s = open_test_file(&file, &path); - if (s != STATUS_SUCCESS) fail_status("open test file", s); + if (s != NTLSTATUS_SUCCESS) fail_status("open test file", s); uint64_t fileSize = 0; s = SysGetFileSize(file, &fileSize); - if (s != STATUS_SUCCESS) fail_status("get file size", s); + if (s != NTLSTATUS_SUCCESS) fail_status("get file size", s); if (fileSize < 4096) fail("test file too small"); size_t mapSize = (fileSize < TEST_SIZE) ? (size_t)fileSize : TEST_SIZE; @@ -115,12 +115,12 @@ int main(void) { uint32_t mapping = 0; s = SysCreateFileMapping(file, SYS_VM_READ, SYS_MAP_FLAG_NONE, mapSize, &mapping); - if (s != STATUS_SUCCESS) fail_status("create mapping", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create mapping", s); void* base = 0; s = SysMapFile(mapping, 0, mapSize, SYS_MAP_ACCESS_READ, SYS_MAP_FLAG_NONE, &base); SysCloseHandle(mapping); - if (s != STATUS_SUCCESS) fail_status("map file", s); + if (s != NTLSTATUS_SUCCESS) fail_status("map file", s); if (!base) fail("map returned null"); volatile uint8_t* view = (volatile uint8_t*)base; @@ -129,14 +129,14 @@ int main(void) { (void)view[mapSize - 1]; s = query_cache(&afterFault); - if (s != STATUS_SUCCESS) fail_status("query after mmap faults", s); + if (s != NTLSTATUS_SUCCESS) fail_status("query after mmap faults", s); if (afterFault.Loads <= before.Loads) { SysFreeVm(base); fail("mmap faults did not populate file cache"); } s = SysSeekFile(file, 0); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { SysFreeVm(base); fail_status("seek", s); } @@ -145,7 +145,7 @@ int main(void) { memset(gReadback, 0xCC, sizeof(gReadback)); SYS_FILE_IO_REQUEST readReq = SysMakeFileIoRequest(file, gReadback, mapSize, &got); s = SysReadFile(&readReq); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { SysFreeVm(base); fail_status("read", s); } @@ -159,7 +159,7 @@ int main(void) { } s = query_cache(&afterRead); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { SysFreeVm(base); fail_status("query after read", s); } diff --git a/code/user/tests/pcache_multithread/pcache_multithread.c b/code/user/tests/pcache_multithread/pcache_multithread.c index 0668a38..6ae8442 100644 --- a/code/user/tests/pcache_multithread/pcache_multithread.c +++ b/code/user/tests/pcache_multithread/pcache_multithread.c @@ -87,14 +87,14 @@ static uint32_t create_temp(uint32_t* fileOut, const char** pathOut) { SYS_FILE_FLAG_NONE, &h); uint32_t s = SysOpenFile(&req); - if (s == STATUS_SUCCESS) { + if (s == NTLSTATUS_SUCCESS) { *fileOut = h; if (pathOut) *pathOut = paths[i]; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } static void fill_pattern(void) { @@ -107,7 +107,7 @@ static uint32_t validate_mapping(const uint8_t* base) { if (base[i] != gPattern[i]) return 0x10000000u | (uint32_t)(i & 0x0FFFFFFFu); } - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } static void thread_main(uintptr_t arg) { @@ -118,8 +118,8 @@ static void thread_main(uintptr_t arg) { void* base = 0; uint32_t s = SysMapFile(ctx->Mapping, 0, TEST_SIZE, SYS_MAP_ACCESS_READ, SYS_MAP_FLAG_NONE, &base); - if (s != STATUS_SUCCESS || !base) { - ctx->Status = s ? s : STATUS_INVALID_PARAMETER; + if (s != NTLSTATUS_SUCCESS || !base) { + ctx->Status = s ? s : NTLSTATUS_INVALID_PARAMETER; SysExitThread(1); } @@ -130,18 +130,18 @@ static void thread_main(uintptr_t arg) { s = validate_mapping((const uint8_t*)base); uint32_t fs = SysFreeVm(base); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { ctx->Status = s; SysExitThread(1); } - if (fs != STATUS_SUCCESS) { + if (fs != NTLSTATUS_SUCCESS) { ctx->Status = fs; SysExitThread(1); } ctx->IterationsDone++; } - ctx->Status = STATUS_SUCCESS; + ctx->Status = NTLSTATUS_SUCCESS; SysExitThread(0); } @@ -152,21 +152,21 @@ int main(void) { uint32_t file = 0; const char* path = 0; uint32_t s = create_temp(&file, &path); - if (s != STATUS_SUCCESS) fail_status("create temp", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create temp", s); size_t written = 0; SYS_FILE_IO_REQUEST writeReq = SysMakeFileIoRequest(file, gPattern, sizeof(gPattern), &written); s = SysWriteFile(&writeReq); - if (s != STATUS_SUCCESS) fail_status("write pattern", s); + if (s != NTLSTATUS_SUCCESS) fail_status("write pattern", s); if (written != sizeof(gPattern)) fail("short write"); uint32_t mapping = 0; s = SysCreateFileMapping(file, SYS_VM_READ, SYS_MAP_FLAG_NONE, TEST_SIZE, &mapping); - if (s != STATUS_SUCCESS) fail_status("create mapping", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create mapping", s); SYS_FILE_CACHE_STATS before; SYS_FILE_CACHE_STATS after; - if (query_cache(&before) != STATUS_SUCCESS) fail("initial stats query failed"); + if (query_cache(&before) != NTLSTATUS_SUCCESS) fail("initial stats query failed"); uint32_t handles[THREAD_COUNT]; uint32_t tids[THREAD_COUNT]; @@ -177,7 +177,7 @@ int main(void) { for (uint32_t i = 0; i < THREAD_COUNT; ++i) { gThreads[i].Index = i; gThreads[i].Mapping = mapping; - gThreads[i].Status = STATUS_PENDING; + gThreads[i].Status = NTLSTATUS_PENDING; SYS_CREATE_THREAD_REQUEST req = { (uintptr_t)thread_main, (uintptr_t)&gThreads[i], @@ -187,17 +187,17 @@ int main(void) { &tids[i] }; s = SysCreateThread(&req); - if (s != STATUS_SUCCESS) fail_status("create thread", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create thread", s); } for (uint32_t i = 0; i < THREAD_COUNT; ++i) { s = SysWait(handles[i], SYS_WAIT_FLAG_NONE); - if (s != STATUS_SUCCESS) fail_status("wait thread", s); + if (s != NTLSTATUS_SUCCESS) fail_status("wait thread", s); SysCloseHandle(handles[i]); } for (uint32_t i = 0; i < THREAD_COUNT; ++i) { - if (gThreads[i].Status != STATUS_SUCCESS) { + if (gThreads[i].Status != NTLSTATUS_SUCCESS) { print("pcache_multithread: worker "); print_u64(i); print(" status="); @@ -210,8 +210,9 @@ int main(void) { if (gThreads[i].IterationsDone != ITERATIONS) fail("worker iteration count mismatch"); } - if (query_cache(&after) != STATUS_SUCCESS) fail("final stats query failed"); - if (after.Loads <= before.Loads) fail("concurrent mmap did not load cache pages"); + if (query_cache(&after) != NTLSTATUS_SUCCESS) fail("final stats query failed"); + if (after.Loads <= before.Loads && after.Hits <= before.Hits) + fail("concurrent mmap did not touch cache pages"); if (after.Hits <= before.Hits) fail("concurrent mmap did not reuse cache pages"); SysCloseHandle(mapping); diff --git a/code/user/tests/pcache_pressure/pcache_pressure.c b/code/user/tests/pcache_pressure/pcache_pressure.c index f5f5156..73c2ca1 100644 --- a/code/user/tests/pcache_pressure/pcache_pressure.c +++ b/code/user/tests/pcache_pressure/pcache_pressure.c @@ -77,12 +77,12 @@ static uint32_t open_first_large(uint32_t* fileOut, const char** pathOut, uint64 SYS_FILE_FLAG_NONE, &h); uint32_t s = SysOpenFile(&req); - if (s != STATUS_SUCCESS) + if (s != NTLSTATUS_SUCCESS) continue; uint64_t size = 0; s = SysGetFileSize(h, &size); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { SysCloseHandle(h); continue; } @@ -90,13 +90,13 @@ static uint32_t open_first_large(uint32_t* fileOut, const char** pathOut, uint64 *fileOut = h; *pathOut = candidates[i]; *sizeOut = size; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } SysCloseHandle(h); } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } int main(void) { @@ -104,14 +104,14 @@ int main(void) { SYS_FILE_CACHE_STATS before; SYS_FILE_CACHE_STATS after; - if (query_cache(&before) != STATUS_SUCCESS) + if (query_cache(&before) != NTLSTATUS_SUCCESS) fail("initial cache stats query failed"); uint32_t file = 0; const char* path = 0; uint64_t size = 0; uint32_t s = open_first_large(&file, &path, &size); - if (s != STATUS_SUCCESS) + if (s != NTLSTATUS_SUCCESS) fail_status("open large asset", s); print("pcache_pressure: using "); @@ -126,7 +126,7 @@ int main(void) { size_t got = 0; SYS_FILE_IO_REQUEST readReq = SysMakeFileIoRequest(file, gBuf, sizeof(gBuf), &got); s = SysReadFile(&readReq); - if (s != STATUS_SUCCESS) + if (s != NTLSTATUS_SUCCESS) fail_status("read", s); if (got == 0) break; @@ -138,7 +138,7 @@ int main(void) { if (total < MIN_PRESSURE_BYTES) fail("asset read was too short to pressure the cache"); - if (query_cache(&after) != STATUS_SUCCESS) + if (query_cache(&after) != NTLSTATUS_SUCCESS) fail("final cache stats query failed"); uint64_t loads = after.Loads - before.Loads; diff --git a/code/user/tests/pcache_smoke/pcache_smoke.c b/code/user/tests/pcache_smoke/pcache_smoke.c index 95680c2..3fcc798 100644 --- a/code/user/tests/pcache_smoke/pcache_smoke.c +++ b/code/user/tests/pcache_smoke/pcache_smoke.c @@ -72,13 +72,13 @@ static uint32_t open_self(uint32_t* out) { SYS_FILE_FLAG_NONE, &h); uint32_t s = SysOpenFile(&req); - if (s == STATUS_SUCCESS) { + if (s == NTLSTATUS_SUCCESS) { *out = h; print("pcache_smoke: using "); print(paths[i]); print("\n"); - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } int main(void) { @@ -86,52 +86,52 @@ int main(void) { SYS_FILE_CACHE_STATS before, afterFirst, afterSecond, afterMap; uint32_t s = query_cache(&before); - if (s != STATUS_SUCCESS) fail_status("query initial stats", s); + if (s != NTLSTATUS_SUCCESS) fail_status("query initial stats", s); uint32_t file = 0; s = open_self(&file); - if (s != STATUS_SUCCESS) fail_status("open test file", s); + if (s != NTLSTATUS_SUCCESS) fail_status("open test file", s); size_t gotA = 0; memset(gA, 0xA5, sizeof(gA)); SYS_FILE_IO_REQUEST readReqA = SysMakeFileIoRequest(file, gA, sizeof(gA), &gotA); s = SysReadFile(&readReqA); - if (s != STATUS_SUCCESS) fail_status("first read", s); + if (s != NTLSTATUS_SUCCESS) fail_status("first read", s); if (gotA < 4096) fail("first read too short"); print("pcache_smoke: first read OK\n"); s = query_cache(&afterFirst); - if (s != STATUS_SUCCESS) fail_status("query after first read", s); + if (s != NTLSTATUS_SUCCESS) fail_status("query after first read", s); if (afterFirst.Loads <= before.Loads) fail("first read did not load file-cache pages"); s = SysSeekFile(file, 0); - if (s != STATUS_SUCCESS) fail_status("seek", s); + if (s != NTLSTATUS_SUCCESS) fail_status("seek", s); size_t gotB = 0; memset(gB, 0x5A, sizeof(gB)); SYS_FILE_IO_REQUEST readReqB = SysMakeFileIoRequest(file, gB, sizeof(gB), &gotB); s = SysReadFile(&readReqB); - if (s != STATUS_SUCCESS) fail_status("second read", s); + if (s != NTLSTATUS_SUCCESS) fail_status("second read", s); if (gotB != gotA) fail("second read length mismatch"); if (memcmp(gA, gB, gotA) != 0) fail("second read data mismatch"); print("pcache_smoke: second read OK\n"); s = query_cache(&afterSecond); - if (s != STATUS_SUCCESS) fail_status("query after second read", s); + if (s != NTLSTATUS_SUCCESS) fail_status("query after second read", s); if (afterSecond.Hits <= afterFirst.Hits) fail("second read did not hit file cache"); uint32_t mapping = 0; s = SysCreateFileMapping(file, SYS_VM_READ, SYS_MAP_FLAG_NONE, sizeof(gA), &mapping); - if (s != STATUS_SUCCESS) fail_status("create mapping", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create mapping", s); SysCloseHandle(file); file = 0; void* base = 0; s = SysMapFile(mapping, 0, sizeof(gA), SYS_MAP_ACCESS_READ, SYS_MAP_FLAG_NONE, &base); SysCloseHandle(mapping); - if (s != STATUS_SUCCESS) fail_status("map file", s); + if (s != NTLSTATUS_SUCCESS) fail_status("map file", s); if (!base) fail("map returned null"); volatile uint8_t* view = (volatile uint8_t*)base; @@ -145,7 +145,7 @@ int main(void) { } s = query_cache(&afterMap); - if (s != STATUS_SUCCESS) fail_status("query after map", s); + if (s != NTLSTATUS_SUCCESS) fail_status("query after map", s); if (afterMap.Hits <= afterSecond.Hits) fail("mmap faults did not hit already cached pages"); diff --git a/code/user/tests/process_protection_smoke/process_protection_smoke.c b/code/user/tests/process_protection_smoke/process_protection_smoke.c index d4af26b..a9c8234 100644 --- a/code/user/tests/process_protection_smoke/process_protection_smoke.c +++ b/code/user/tests/process_protection_smoke/process_protection_smoke.c @@ -54,18 +54,18 @@ static void fail_status(const char* operation, uint32_t status) { static void verify_protected_process(const SYS_PROCESS_INFO* process) { uint32_t handle = 0; uint32_t status = SysOpenProcess(process->ProcessId, &handle); - if (status != STATUS_SUCCESS) + if (status != NTLSTATUS_SUCCESS) fail_status("open protected process", status); - status = SysKillProcess(handle, (int32_t)STATUS_PROCESS_KILLED); - if (status != STATUS_ACCESS_DENIED) { + status = SysKillProcess(handle, (int32_t)NTLSTATUS_PROCESS_KILLED); + if (status != NTLSTATUS_ACCESS_DENIED) { SysCloseHandle(handle); fail_status("kill protected process", status); } status = SysWaitSingle(handle, SYS_WAIT_FLAG_NONE, 0); SysCloseHandle(handle); - if (status != STATUS_TIMEOUT) + if (status != NTLSTATUS_TIMEOUT) fail_status("protected process remained signaled", status); } @@ -76,7 +76,7 @@ void main(void) { SYS_PROCESS_INFO processes[MAX_PROCESSES]; size_t count = 0; uint32_t status = SysGetProcessList(processes, MAX_PROCESSES, &count); - if (status != STATUS_SUCCESS) + if (status != NTLSTATUS_SUCCESS) fail_status("query process list", status); int sawIdle = 0; diff --git a/code/user/tests/realpath_smoke/realpath_smoke.c b/code/user/tests/realpath_smoke/realpath_smoke.c index 9c98dd0..e4c19c6 100644 --- a/code/user/tests/realpath_smoke/realpath_smoke.c +++ b/code/user/tests/realpath_smoke/realpath_smoke.c @@ -75,7 +75,7 @@ static void get_current_drive_root(char* out, size_t cap) { &required, }; uint32_t status = SysRealPath(&req); - if (status != STATUS_SUCCESS) fail_status("query current path", status); + if (status != NTLSTATUS_SUCCESS) fail_status("query current path", status); if (required < 4 || current[0] < '0' || current[0] > '7' || current[1] != ':' || current[2] != '/') fail("current path is not native drive-rooted"); if (cap < 4) fail("drive root output too small"); @@ -98,7 +98,7 @@ static void expect_realpath(const char* input, const char* expected) { &required, }; uint32_t status = SysRealPath(&req); - if (status != STATUS_SUCCESS) fail_status("realpath", status); + if (status != NTLSTATUS_SUCCESS) fail_status("realpath", status); if (required != strlen(expected) + 1) fail("required size mismatch"); if (strcmp(out, expected) != 0) fail("resolved path mismatch"); } @@ -115,7 +115,7 @@ static void check_size_reporting(const char* input, const char* expected) { &required, }; uint32_t status = SysRealPath(&query); - if (status != STATUS_SUCCESS) fail_status("size query", status); + if (status != NTLSTATUS_SUCCESS) fail_status("size query", status); if (required != strlen(expected) + 1) fail("size query required mismatch"); char small[4]; @@ -129,7 +129,7 @@ static void check_size_reporting(const char* input, const char* expected) { &smallRequired, }; status = SysRealPath(&smallReq); - if (status != STATUS_BUFFER_TOO_SMALL) fail_status("small buffer", status); + if (status != NTLSTATUS_BUFFER_TOO_SMALL) fail_status("small buffer", status); if (smallRequired != required) fail("small required mismatch"); } @@ -165,7 +165,7 @@ int main(void) { (size_t*)0, }; uint32_t status = SysRealPath(¤tReq); - if (status != STATUS_SUCCESS) fail_status("current realpath", status); + if (status != NTLSTATUS_SUCCESS) fail_status("current realpath", status); memcpy(input, "missing_realpath_dir/../missing_file", sizeof("missing_realpath_dir/../missing_file")); append(expected, sizeof(expected), expected[strlen(expected) - 1] == '/' ? "missing_file" : "/missing_file"); diff --git a/code/user/tests/shared_mmap/shared_mmap.c b/code/user/tests/shared_mmap/shared_mmap.c index c9aa50c..650371d 100644 --- a/code/user/tests/shared_mmap/shared_mmap.c +++ b/code/user/tests/shared_mmap/shared_mmap.c @@ -79,13 +79,13 @@ static uint32_t create_temp(uint32_t* fileOut, const char** pathOut) { SYS_FILE_FLAG_NONE, &h); uint32_t s = SysOpenFile(&req); - if (s == STATUS_SUCCESS) { + if (s == NTLSTATUS_SUCCESS) { *fileOut = h; if (pathOut) *pathOut = paths[i]; - return STATUS_SUCCESS; + return NTLSTATUS_SUCCESS; } } - return STATUS_NOT_FOUND; + return NTLSTATUS_NOT_FOUND; } static uint32_t open_path(const char* path, uint32_t* fileOut) { @@ -96,21 +96,21 @@ static uint32_t open_path(const char* path, uint32_t* fileOut) { SYS_FILE_FLAG_NONE, &h); uint32_t s = SysOpenFile(&req); - if (s == STATUS_SUCCESS) + if (s == NTLSTATUS_SUCCESS) *fileOut = h; return s; } static void checked_seek(uint32_t file, uint64_t offset, const char* what) { uint32_t s = SysSeekFile(file, offset); - if (s != STATUS_SUCCESS) fail_status(what, s); + if (s != NTLSTATUS_SUCCESS) fail_status(what, s); } static void checked_write(uint32_t file, const void* buffer, size_t size, const char* what) { size_t done = 0; SYS_FILE_IO_REQUEST req = SysMakeFileIoRequest(file, buffer, size, &done); uint32_t s = SysWriteFile(&req); - if (s != STATUS_SUCCESS) fail_status(what, s); + if (s != NTLSTATUS_SUCCESS) fail_status(what, s); if (done != size) fail("short write"); } @@ -119,7 +119,7 @@ static void checked_read(uint32_t file, void* buffer, size_t size, size_t* gotOu memset(buffer, 0xCC, size); SYS_FILE_IO_REQUEST req = SysMakeFileIoRequest(file, buffer, size, &got); uint32_t s = SysReadFile(&req); - if (s != STATUS_SUCCESS) fail_status(what, s); + if (s != NTLSTATUS_SUCCESS) fail_status(what, s); if (gotOut) *gotOut = got; } @@ -137,7 +137,7 @@ int main(void) { uint32_t file = 0; const char* path = 0; uint32_t s = create_temp(&file, &path); - if (s != STATUS_SUCCESS) fail_status("create temp", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create temp", s); print("shared_mmap: creating temporary file "); print(path ? path : ""); @@ -145,16 +145,16 @@ int main(void) { checked_write(file, gInitial, TEST_SIZE, "initial write"); s = SysFlushFile(file); - if (s != STATUS_SUCCESS) fail_status("initial flush", s); + if (s != NTLSTATUS_SUCCESS) fail_status("initial flush", s); uint32_t mapping = 0; s = SysCreateFileMapping(file, SYS_VM_READWRITE, SYS_MAP_FLAG_NONE, TEST_SIZE, &mapping); - if (s != STATUS_SUCCESS) fail_status("create mapping", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create mapping", s); uint8_t* view = 0; s = SysMapFile(mapping, 0, TEST_SIZE, SYS_MAP_ACCESS_READ | SYS_MAP_ACCESS_WRITE, SYS_MAP_FLAG_NONE, (void**)&view); - if (s != STATUS_SUCCESS) fail_status("map shared write", s); + if (s != NTLSTATUS_SUCCESS) fail_status("map shared write", s); for (size_t i = 128; i < 128 + 3000; ++i) { view[i] = (uint8_t)(0xA0u + (uint8_t)i); @@ -167,12 +167,12 @@ int main(void) { SYS_FILE_CACHE_STATS beforeFlush; SYS_FILE_CACHE_STATS afterFlush; - if (query_cache(&beforeFlush) != STATUS_SUCCESS) fail("pre-flush stats failed"); + if (query_cache(&beforeFlush) != NTLSTATUS_SUCCESS) fail("pre-flush stats failed"); s = SysFlushFile(file); - if (s != STATUS_SUCCESS) fail_status("flush mapped writes", s); + if (s != NTLSTATUS_SUCCESS) fail_status("flush mapped writes", s); - if (query_cache(&afterFlush) != STATUS_SUCCESS) fail("post-flush stats failed"); + if (query_cache(&afterFlush) != NTLSTATUS_SUCCESS) fail("post-flush stats failed"); if (afterFlush.MappedDirtyPages <= beforeFlush.MappedDirtyPages) fail("mapped dirty pages were not harvested"); if (afterFlush.WritebackBytes <= beforeFlush.WritebackBytes) @@ -191,18 +191,18 @@ int main(void) { s = SysFreeVm(view); view = 0; - if (s != STATUS_SUCCESS) fail_status("unmap", s); + if (s != NTLSTATUS_SUCCESS) fail_status("unmap", s); s = SysCloseHandle(mapping); mapping = 0; - if (s != STATUS_SUCCESS) fail_status("close mapping", s); + if (s != NTLSTATUS_SUCCESS) fail_status("close mapping", s); s = SysCloseHandle(file); file = 0; - if (s != STATUS_SUCCESS) fail_status("close file", s); + if (s != NTLSTATUS_SUCCESS) fail_status("close file", s); s = open_path(path, &file); - if (s != STATUS_SUCCESS) fail_status("reopen", s); + if (s != NTLSTATUS_SUCCESS) fail_status("reopen", s); checked_read(file, gReadback, TEST_SIZE, &got, "read after close"); if (got != TEST_SIZE) fail("read after close size mismatch"); @@ -210,7 +210,7 @@ int main(void) { s = SysCloseHandle(file); file = 0; - if (s != STATUS_SUCCESS) fail_status("close reopened", s); + if (s != NTLSTATUS_SUCCESS) fail_status("close reopened", s); delete_path(path); print("shared_mmap: mapped-dirty-pages+="); diff --git a/code/user/tests/socket_addr_smoke/socket_addr_smoke.c b/code/user/tests/socket_addr_smoke/socket_addr_smoke.c index 3e0c824..dfe2efc 100644 --- a/code/user/tests/socket_addr_smoke/socket_addr_smoke.c +++ b/code/user/tests/socket_addr_smoke/socket_addr_smoke.c @@ -73,7 +73,7 @@ static void check_ipv4_resolve(void) { req.AddressSizeInOut = &addressSize; uint32_t status = SysResolveHost(&req); - if (status != STATUS_SUCCESS) fail_status("resolve ipv4", status); + if (status != NTLSTATUS_SUCCESS) fail_status("resolve ipv4", status); if (addressSize != sizeof(address)) fail("resolve ipv4 size mismatch"); if (address.Family != SYS_AF_INET || address.Size != sizeof(address)) fail("resolve ipv4 tag mismatch"); if (address.Address[0] != 127 || address.Address[1] != 0 || address.Address[2] != 0 || address.Address[3] != 1) @@ -93,7 +93,7 @@ static void check_ipv6_resolve(void) { req.AddressSizeInOut = &addressSize; uint32_t status = SysResolveHost(&req); - if (status != STATUS_SUCCESS) fail_status("resolve ipv6", status); + if (status != NTLSTATUS_SUCCESS) fail_status("resolve ipv6", status); if (addressSize != sizeof(address)) fail("resolve ipv6 size mismatch"); if (address.Family != SYS_AF_INET6 || address.Size != sizeof(address)) fail("resolve ipv6 tag mismatch"); for (int i = 0; i < 15; i++) { @@ -107,10 +107,10 @@ static void check_socket_address_validation(void) { uint32_t ipv4 = 0; uint32_t ipv6 = 0; uint32_t status = SysCreateSocket(SYS_AF_INET, SYS_SOCK_DGRAM, SYS_IPPROTO_UDP, &ipv4); - if (status != STATUS_SUCCESS) fail_status("create ipv4 udp", status); + if (status != NTLSTATUS_SUCCESS) fail_status("create ipv4 udp", status); status = SysCreateSocket(SYS_AF_INET6, SYS_SOCK_DGRAM, SYS_IPPROTO_UDP, &ipv6); - if (status != STATUS_SUCCESS) fail_status("create ipv6 udp", status); + if (status != NTLSTATUS_SUCCESS) fail_status("create ipv6 udp", status); SYS_SOCKET_ADDRESS ipv4Address; memset(&ipv4Address, 0, sizeof(ipv4Address)); @@ -128,10 +128,16 @@ static void check_socket_address_validation(void) { SYS_SOCKET_ADDRESS badSize = ipv6Address; badSize.Size = sizeof(badSize) - 1; status = SysBindSocket(ipv6, &badSize, sizeof(badSize)); - if (status == STATUS_SUCCESS) fail("bind accepted wrong ipv6 size"); + if (status != NTLSTATUS_INVALID_PARAMETER) fail_status("bind wrong struct size", status); + + status = SysBindSocket(ipv6, &ipv6Address, sizeof(ipv6Address) - 1); + if (status != NTLSTATUS_BUFFER_TOO_SMALL) fail_status("bind short buffer size", status); + + status = SysBindSocket(ipv6, &ipv6Address, sizeof(ipv6Address) + 1); + if (status != NTLSTATUS_INVALID_PARAMETER) fail_status("bind oversized buffer size", status); status = SysConnectSocket(ipv4, &ipv6Address, sizeof(ipv6Address)); - if (status == STATUS_SUCCESS) fail("connect accepted wrong address family"); + if (status == NTLSTATUS_SUCCESS) fail("connect accepted wrong address family"); SysCloseHandle(ipv4); SysCloseHandle(ipv6); diff --git a/code/user/tests/stats_abi_smoke/stats_abi_smoke.c b/code/user/tests/stats_abi_smoke/stats_abi_smoke.c index 36664a4..28ecb31 100644 --- a/code/user/tests/stats_abi_smoke/stats_abi_smoke.c +++ b/code/user/tests/stats_abi_smoke/stats_abi_smoke.c @@ -3,6 +3,7 @@ #include #include +#include #include // Prints one NUL-terminated string to the kernel console. @@ -70,50 +71,63 @@ static void expect_status(const char* what, uint32_t got, uint32_t expected) { static void check_fixed_stats(void) { size_t required = 0; uint32_t status = SysQueryKernelStats(SYS_KERNEL_STATS_SCHEDULER, 0, 0, &required); - if (status != STATUS_SUCCESS) fail_status("scheduler size", status); + if (status != NTLSTATUS_SUCCESS) fail_status("scheduler size", status); if (required != sizeof(SYS_SCHEDULER_STATS)) fail("scheduler required size mismatch"); uint8_t small[sizeof(SYS_SCHEDULER_STATS) - 1u]; size_t smallRequired = 0; status = SysQueryKernelStats(SYS_KERNEL_STATS_SCHEDULER, small, sizeof(small), &smallRequired); - expect_status("scheduler small buffer", status, STATUS_BUFFER_TOO_SMALL); + expect_status("scheduler small buffer", status, NTLSTATUS_BUFFER_TOO_SMALL); if (smallRequired != sizeof(SYS_SCHEDULER_STATS)) fail("scheduler small required mismatch"); SYS_SCHEDULER_STATS scheduler; status = SysQueryKernelStats(SYS_KERNEL_STATS_SCHEDULER, &scheduler, sizeof(scheduler), 0); - if (status != STATUS_SUCCESS) fail_status("scheduler exact", status); + if (status != NTLSTATUS_SUCCESS) fail_status("scheduler exact", status); if (scheduler.Size != sizeof(scheduler)) fail("scheduler size field mismatch"); if (scheduler.Version != SYS_STATS_VERSION) fail("scheduler version mismatch"); SYS_FILESYSTEM_STATS filesystem; status = SysQueryKernelStats(SYS_KERNEL_STATS_FILESYSTEM, &filesystem, sizeof(filesystem), 0); - if (status != STATUS_SUCCESS) fail_status("filesystem exact", status); + if (status != NTLSTATUS_SUCCESS) fail_status("filesystem exact", status); if (filesystem.Size != sizeof(filesystem)) fail("filesystem size field mismatch"); if (filesystem.Version != SYS_STATS_VERSION) fail("filesystem version mismatch"); + + SYS_EXCEPTION_STATS exceptionStats; + status = SysQueryKernelStats(SYS_KERNEL_STATS_EXCEPTION, &exceptionStats, sizeof(exceptionStats), 0); + if (status != NTLSTATUS_SUCCESS) fail_status("exception exact", status); + if (exceptionStats.Size != sizeof(exceptionStats)) fail("exception size field mismatch"); + if (exceptionStats.Version != SYS_STATS_VERSION) fail("exception version mismatch"); } // Verifies CPU stats use a size-reported trailing-record layout. static void check_cpu_stats(void) { size_t required = 0; uint32_t status = SysQueryKernelStats(SYS_KERNEL_STATS_CPU, 0, 0, &required); - if (status != STATUS_SUCCESS) fail_status("cpu size", status); + if (status != NTLSTATUS_SUCCESS) fail_status("cpu size", status); if (required < sizeof(SYS_CPU_STATS) + sizeof(SYS_CPU_STAT)) fail("cpu required size too small"); SYS_CPU_STATS headerOnly; size_t smallRequired = 0; status = SysQueryKernelStats(SYS_KERNEL_STATS_CPU, &headerOnly, sizeof(headerOnly), &smallRequired); - expect_status("cpu header-only buffer", status, STATUS_BUFFER_TOO_SMALL); + expect_status("cpu header-only buffer", status, NTLSTATUS_BUFFER_TOO_SMALL); if (smallRequired != required) fail("cpu small required mismatch"); void* buffer = 0; size_t pages = (required + 4095u) / 4096u; if (pages == 0) pages = 1; - status = SysAllocVm(0, pages, SYS_VM_READWRITE, SYS_VM_FLAG_NONE, &buffer); - if (status != STATUS_SUCCESS || !buffer) fail_status("cpu buffer alloc", status); + SYS_ALLOC_VM_REQUEST allocReq; + memset(&allocReq, 0, sizeof(allocReq)); + allocReq.Size = sizeof(allocReq); + allocReq.PageCount = pages; + allocReq.Protect = SYS_VM_READWRITE; + allocReq.Flags = SYS_VM_FLAG_NONE; + allocReq.BaseOut = &buffer; + status = SysAllocVm(&allocReq); + if (status != NTLSTATUS_SUCCESS || !buffer) fail_status("cpu buffer alloc", status); SYS_CPU_STATS* cpu = (SYS_CPU_STATS*)buffer; status = SysQueryKernelStats(SYS_KERNEL_STATS_CPU, cpu, pages * 4096u, 0); - if (status != STATUS_SUCCESS) { + if (status != NTLSTATUS_SUCCESS) { SysFreeVm(buffer); fail_status("cpu exact", status); } diff --git a/code/user/tests/surface_invalid_rect/surface_invalid_rect.c b/code/user/tests/surface_invalid_rect/surface_invalid_rect.c index de74b3e..2173215 100644 --- a/code/user/tests/surface_invalid_rect/surface_invalid_rect.c +++ b/code/user/tests/surface_invalid_rect/surface_invalid_rect.c @@ -65,38 +65,49 @@ int main(void) { print("surface_invalid_rect: start\n"); uint32_t bad = 0; - uint32_t s = SysCreateSurface(0, SURFACE_H, SYS_SURFACE_FORMAT_XRGB8888, SYS_SURFACE_FLAG_NONE, &bad); - expect_status("zero width", s, STATUS_INVALID_PARAMETER); + SYS_CREATE_SURFACE_REQUEST req; + memset(&req, 0, sizeof(req)); + req.Size = sizeof(req); + req.Width = 0; + req.Height = SURFACE_H; + req.Format = SYS_SURFACE_FORMAT_XRGB8888; + req.Flags = SYS_SURFACE_FLAG_NONE; + req.HandleOut = &bad; + uint32_t s = SysCreateSurface(&req); + expect_status("zero width", s, NTLSTATUS_INVALID_PARAMETER); - s = SysCreateSurface(SURFACE_W, SURFACE_H, 0x9999u, SYS_SURFACE_FLAG_NONE, &bad); - expect_status("bad format", s, STATUS_NOT_SUPPORTED); + req.Width = SURFACE_W; + req.Format = 0x9999u; + s = SysCreateSurface(&req); + expect_status("bad format", s, NTLSTATUS_NOT_SUPPORTED); uint32_t surface = 0; - s = SysCreateSurface(SURFACE_W, SURFACE_H, SYS_SURFACE_FORMAT_XRGB8888, - SYS_SURFACE_FLAG_NONE, &surface); - if (s != STATUS_SUCCESS) fail_status("create surface", s); + req.Format = SYS_SURFACE_FORMAT_XRGB8888; + req.HandleOut = &surface; + s = SysCreateSurface(&req); + if (s != NTLSTATUS_SUCCESS) fail_status("create surface", s); void* base = 0; uint32_t pitch = 0; s = SysMapSurface(surface, &base, &pitch); - if (s != STATUS_SUCCESS) fail_status("map surface", s); + if (s != NTLSTATUS_SUCCESS) fail_status("map surface", s); if (!base || pitch < SURFACE_W * sizeof(uint32_t)) fail("invalid mapping"); s = SysPresentSurface(surface, 0, 1); - expect_status("null rect array with nonzero count", s, STATUS_INVALID_PARAMETER); + expect_status("null rect array with nonzero count", s, NTLSTATUS_INVALID_PARAMETER); DISPLAY_RECT rects[SYS_SURFACE_MAX_RECTS + 1]; memset(rects, 0, sizeof(rects)); s = SysPresentSurface(surface, rects, SYS_SURFACE_MAX_RECTS + 1); - expect_status("too many rects", s, STATUS_INVALID_PARAMETER); + expect_status("too many rects", s, NTLSTATUS_INVALID_PARAMETER); DISPLAY_RECT clipped = { -8, -8, 24, 24 }; s = SysPresentSurface(surface, &clipped, 1); - if (s != STATUS_SUCCESS) fail_status("present clipped rect", s); + if (s != NTLSTATUS_SUCCESS) fail_status("present clipped rect", s); DISPLAY_RECT empty = { 10000, 10000, 16, 16 }; s = SysPresentSurface(surface, &empty, 1); - if (s != STATUS_SUCCESS) fail_status("present empty clipped rect", s); + if (s != NTLSTATUS_SUCCESS) fail_status("present empty clipped rect", s); SysCloseHandle(surface); print("surface_invalid_rect: PASS\n"); diff --git a/code/user/tests/surface_multithread_present/surface_multithread_present.c b/code/user/tests/surface_multithread_present/surface_multithread_present.c index 4165a5a..d242ccc 100644 --- a/code/user/tests/surface_multithread_present/surface_multithread_present.c +++ b/code/user/tests/surface_multithread_present/surface_multithread_present.c @@ -80,7 +80,7 @@ static void worker_main(uintptr_t arg) { DISPLAY_RECT rect = { 0, (int32_t)y0, (int32_t)SURFACE_W, (int32_t)h }; uint32_t s = SysPresentSurface(st->Surface, &rect, 1); - if (s != STATUS_SUCCESS) { + if (s != NTLSTATUS_SUCCESS) { st->Status = s; SysExitThread(1); } @@ -88,7 +88,7 @@ static void worker_main(uintptr_t arg) { SysYield(); } - st->Status = STATUS_SUCCESS; + st->Status = NTLSTATUS_SUCCESS; SysExitThread(0); } @@ -96,14 +96,21 @@ int main(void) { print("surface_multithread_present: start\n"); uint32_t surface = 0; - uint32_t s = SysCreateSurface(SURFACE_W, SURFACE_H, SYS_SURFACE_FORMAT_XRGB8888, - SYS_SURFACE_FLAG_NONE, &surface); - if (s != STATUS_SUCCESS) fail_status("create surface", s); + SYS_CREATE_SURFACE_REQUEST req; + memset(&req, 0, sizeof(req)); + req.Size = sizeof(req); + req.Width = SURFACE_W; + req.Height = SURFACE_H; + req.Format = SYS_SURFACE_FORMAT_XRGB8888; + req.Flags = SYS_SURFACE_FLAG_NONE; + req.HandleOut = &surface; + uint32_t s = SysCreateSurface(&req); + if (s != NTLSTATUS_SUCCESS) fail_status("create surface", s); void* base = 0; uint32_t pitch = 0; s = SysMapSurface(surface, &base, &pitch); - if (s != STATUS_SUCCESS) fail_status("map surface", s); + if (s != NTLSTATUS_SUCCESS) fail_status("map surface", s); if (!base || pitch < SURFACE_W * sizeof(uint32_t)) fail("invalid mapping"); uint32_t handles[THREAD_COUNT]; @@ -117,7 +124,7 @@ int main(void) { gWorkers[i].Surface = surface; gWorkers[i].Base = (uint8_t*)base; gWorkers[i].Pitch = pitch; - gWorkers[i].Status = STATUS_PENDING; + gWorkers[i].Status = NTLSTATUS_PENDING; SYS_CREATE_THREAD_REQUEST req = { (uintptr_t)worker_main, (uintptr_t)&gWorkers[i], @@ -127,17 +134,17 @@ int main(void) { &tids[i] }; s = SysCreateThread(&req); - if (s != STATUS_SUCCESS) fail_status("create thread", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create thread", s); } for (uint32_t i = 0; i < THREAD_COUNT; ++i) { s = SysWait(handles[i], SYS_WAIT_FLAG_NONE); - if (s != STATUS_SUCCESS) fail_status("wait thread", s); + if (s != NTLSTATUS_SUCCESS) fail_status("wait thread", s); SysCloseHandle(handles[i]); } for (uint32_t i = 0; i < THREAD_COUNT; ++i) { - if (gWorkers[i].Status != STATUS_SUCCESS) { + if (gWorkers[i].Status != NTLSTATUS_SUCCESS) { print("surface_multithread_present: worker "); print_u64(i); print(" status="); diff --git a/code/user/tests/surface_smoke/surface_smoke.c b/code/user/tests/surface_smoke/surface_smoke.c index d78adec..0c9b9dd 100644 --- a/code/user/tests/surface_smoke/surface_smoke.c +++ b/code/user/tests/surface_smoke/surface_smoke.c @@ -53,21 +53,28 @@ int main(void) { print("surface_smoke: start\n"); uint32_t surface = 0; - uint32_t s = SysCreateSurface(SURFACE_W, SURFACE_H, SYS_SURFACE_FORMAT_XRGB8888, - SYS_SURFACE_FLAG_NONE, &surface); - if (s != STATUS_SUCCESS) fail_status("create surface", s); + SYS_CREATE_SURFACE_REQUEST req; + memset(&req, 0, sizeof(req)); + req.Size = sizeof(req); + req.Width = SURFACE_W; + req.Height = SURFACE_H; + req.Format = SYS_SURFACE_FORMAT_XRGB8888; + req.Flags = SYS_SURFACE_FLAG_NONE; + req.HandleOut = &surface; + uint32_t s = SysCreateSurface(&req); + if (s != NTLSTATUS_SUCCESS) fail_status("create surface", s); if (!surface) fail("surface handle is zero"); void* base = 0; uint32_t pitch = 0; s = SysMapSurface(surface, &base, &pitch); - if (s != STATUS_SUCCESS) fail_status("map surface", s); + if (s != NTLSTATUS_SUCCESS) fail_status("map surface", s); if (!base || pitch < SURFACE_W * sizeof(uint32_t)) fail("invalid mapping"); SYS_SURFACE_DESC desc; memset(&desc, 0, sizeof(desc)); s = SysQuerySurface(surface, &desc); - if (s != STATUS_SUCCESS) fail_status("query surface", s); + if (s != NTLSTATUS_SUCCESS) fail_status("query surface", s); if (desc.Width != SURFACE_W || desc.Height != SURFACE_H) fail("query dimensions mismatch"); if (desc.PitchBytes != pitch || desc.Format != SYS_SURFACE_FORMAT_XRGB8888) fail("query metadata mismatch"); if (desc.Base != base) fail("query base mismatch"); @@ -81,10 +88,10 @@ int main(void) { DISPLAY_RECT rect = { 0, 0, (int32_t)SURFACE_W, (int32_t)SURFACE_H }; s = SysPresentSurface(surface, &rect, 1); - if (s != STATUS_SUCCESS) fail_status("present surface", s); + if (s != NTLSTATUS_SUCCESS) fail_status("present surface", s); s = SysPresentSurface(surface, 0, 0); - if (s != STATUS_SUCCESS) fail_status("present full surface", s); + if (s != NTLSTATUS_SUCCESS) fail_status("present full surface", s); SysCloseHandle(surface); print("surface_smoke: PASS\n"); diff --git a/code/user/tests/syscall_contract_smoke/syscall_contract_smoke.c b/code/user/tests/syscall_contract_smoke/syscall_contract_smoke.c index 7964225..70be498 100644 --- a/code/user/tests/syscall_contract_smoke/syscall_contract_smoke.c +++ b/code/user/tests/syscall_contract_smoke/syscall_contract_smoke.c @@ -70,12 +70,12 @@ static void fail_status(const char* what, uint32_t status) { static void check_tick_contract(void) { uint64_t frequency = 0; uint32_t s = SysGetTickFrequency(&frequency); - if (s != STATUS_SUCCESS) fail_status("query tick frequency", s); + if (s != NTLSTATUS_SUCCESS) fail_status("query tick frequency", s); if (!frequency) fail("tick frequency was zero"); uint64_t t0 = SysGetTick(); s = SysSleep(1); - if (s != STATUS_SUCCESS) fail_status("sleep", s); + if (s != NTLSTATUS_SUCCESS) fail_status("sleep", s); uint64_t t1 = SysGetTick(); if (t1 < t0) fail("tick moved backwards across sleep"); @@ -96,14 +96,14 @@ static void check_exit_code_contract(void) { }; uint32_t s = SysCreateProcess(&req); - if (s != STATUS_SUCCESS) fail_status("create child", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create child", s); s = SysWait(child, SYS_WAIT_FLAG_NONE); - if (s != STATUS_SUCCESS) fail_status("wait child", s); + if (s != NTLSTATUS_SUCCESS) fail_status("wait child", s); int32_t exitCode = 0; s = SysGetProcessExitCode(child, &exitCode); - if (s != STATUS_SUCCESS) fail_status("query child exit code", s); + if (s != NTLSTATUS_SUCCESS) fail_status("query child exit code", s); if (exitCode != CHILD_EXIT_CODE) fail("child exit code mismatch"); SysCloseHandle(child); diff --git a/code/user/tests/timer_smoke/timer_smoke.c b/code/user/tests/timer_smoke/timer_smoke.c index 70bfee1..d124a66 100644 --- a/code/user/tests/timer_smoke/timer_smoke.c +++ b/code/user/tests/timer_smoke/timer_smoke.c @@ -72,14 +72,14 @@ static uint32_t set_timer(uint32_t timer, uint64_t dueMs, uint64_t periodMs) { // Verifies timer request validation paths. static void test_validation(void) { uint32_t timer = 0; - expect_status("create timer null", SysCreateTimer((uint32_t*)0), STATUS_INVALID_PARAMETER); + expect_status("create timer null", SysCreateTimer((uint32_t*)0), NTLSTATUS_INVALID_PARAMETER); uint32_t s = SysCreateTimer(&timer); - if (s != STATUS_SUCCESS) fail_status("create validation timer", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create validation timer", s); - expect_status("set timer null", SysSetTimer((const SYS_SET_TIMER_REQUEST*)0), STATUS_INVALID_PARAMETER); - expect_status("cancel invalid", SysCancelTimer(0xdeadbeefu), STATUS_INVALID_HANDLE); - expect_status("wait invalid", SysWaitSingle(0xdeadbeefu, SYS_WAIT_FLAG_NONE, 0), STATUS_INVALID_HANDLE); + expect_status("set timer null", SysSetTimer((const SYS_SET_TIMER_REQUEST*)0), NTLSTATUS_INVALID_PARAMETER); + expect_status("cancel invalid", SysCancelTimer(0xdeadbeefu), NTLSTATUS_INVALID_HANDLE); + expect_status("wait invalid", SysWaitSingle(0xdeadbeefu, SYS_WAIT_FLAG_NONE, 0), NTLSTATUS_INVALID_HANDLE); SYS_SET_TIMER_REQUEST req = { 0, @@ -88,11 +88,11 @@ static void test_validation(void) { 1, 0, }; - expect_status("set bad size", SysSetTimer(&req), STATUS_INVALID_PARAMETER); + expect_status("set bad size", SysSetTimer(&req), NTLSTATUS_INVALID_PARAMETER); req.Size = sizeof(req); req.Flags = 1; - expect_status("set bad flags", SysSetTimer(&req), STATUS_INVALID_PARAMETER); + expect_status("set bad flags", SysSetTimer(&req), NTLSTATUS_INVALID_PARAMETER); SysCloseHandle(timer); } @@ -101,16 +101,16 @@ static void test_validation(void) { static void test_one_shot(void) { uint32_t timer = 0; uint32_t s = SysCreateTimer(&timer); - if (s != STATUS_SUCCESS) fail_status("create one-shot timer", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create one-shot timer", s); - expect_status("unset immediate wait", SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 0), STATUS_TIMEOUT); + expect_status("unset immediate wait", SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 0), NTLSTATUS_TIMEOUT); s = set_timer(timer, 20, 0); - if (s != STATUS_SUCCESS) fail_status("set one-shot", s); + if (s != NTLSTATUS_SUCCESS) fail_status("set one-shot", s); s = SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, SYS_WAIT_TIMEOUT_INFINITE); - if (s != STATUS_SUCCESS) fail_status("wait one-shot", s); + if (s != NTLSTATUS_SUCCESS) fail_status("wait one-shot", s); - expect_status("one-shot consumed", SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 0), STATUS_TIMEOUT); + expect_status("one-shot consumed", SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 0), NTLSTATUS_TIMEOUT); SysCloseHandle(timer); } @@ -118,24 +118,24 @@ static void test_one_shot(void) { static void test_cancel(void) { uint32_t timer = 0; uint32_t s = SysCreateTimer(&timer); - if (s != STATUS_SUCCESS) fail_status("create cancel timer", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create cancel timer", s); s = set_timer(timer, 100, 0); - if (s != STATUS_SUCCESS) fail_status("set cancel timer", s); + if (s != NTLSTATUS_SUCCESS) fail_status("set cancel timer", s); s = SysCancelTimer(timer); - if (s != STATUS_SUCCESS) fail_status("cancel timer", s); + if (s != NTLSTATUS_SUCCESS) fail_status("cancel timer", s); - expect_status("cancelled timer wait", SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 30), STATUS_TIMEOUT); + expect_status("cancelled timer wait", SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 30), NTLSTATUS_TIMEOUT); s = set_timer(timer, 0, 0); - if (s != STATUS_SUCCESS) fail_status("set immediate", s); - expect_status("immediate timer wait", SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 0), STATUS_SUCCESS); + if (s != NTLSTATUS_SUCCESS) fail_status("set immediate", s); + expect_status("immediate timer wait", SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 0), NTLSTATUS_SUCCESS); s = set_timer(timer, 0, 0); - if (s != STATUS_SUCCESS) fail_status("set immediate before cancel", s); + if (s != NTLSTATUS_SUCCESS) fail_status("set immediate before cancel", s); s = SysCancelTimer(timer); - if (s != STATUS_SUCCESS) fail_status("cancel signaled", s); - expect_status("cancel clears signal", SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 0), STATUS_TIMEOUT); + if (s != NTLSTATUS_SUCCESS) fail_status("cancel signaled", s); + expect_status("cancel clears signal", SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 0), NTLSTATUS_TIMEOUT); SysCloseHandle(timer); } @@ -144,15 +144,15 @@ static void test_cancel(void) { static void test_reset_changes_deadline(void) { uint32_t timer = 0; uint32_t s = SysCreateTimer(&timer); - if (s != STATUS_SUCCESS) fail_status("create reset timer", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create reset timer", s); s = set_timer(timer, 100, 0); - if (s != STATUS_SUCCESS) fail_status("set reset timer long", s); + if (s != NTLSTATUS_SUCCESS) fail_status("set reset timer long", s); s = set_timer(timer, 20, 0); - if (s != STATUS_SUCCESS) fail_status("set reset timer short", s); + if (s != NTLSTATUS_SUCCESS) fail_status("set reset timer short", s); s = SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 80); - if (s != STATUS_SUCCESS) fail_status("wait reset timer", s); + if (s != NTLSTATUS_SUCCESS) fail_status("wait reset timer", s); SysCloseHandle(timer); } @@ -161,18 +161,18 @@ static void test_reset_changes_deadline(void) { static void test_periodic(void) { uint32_t timer = 0; uint32_t s = SysCreateTimer(&timer); - if (s != STATUS_SUCCESS) fail_status("create periodic timer", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create periodic timer", s); s = set_timer(timer, 10, 20); - if (s != STATUS_SUCCESS) fail_status("set periodic timer", s); + if (s != NTLSTATUS_SUCCESS) fail_status("set periodic timer", s); s = SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 80); - if (s != STATUS_SUCCESS) fail_status("wait periodic first", s); + if (s != NTLSTATUS_SUCCESS) fail_status("wait periodic first", s); s = SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 80); - if (s != STATUS_SUCCESS) fail_status("wait periodic second", s); + if (s != NTLSTATUS_SUCCESS) fail_status("wait periodic second", s); s = SysCancelTimer(timer); - if (s != STATUS_SUCCESS) fail_status("cancel periodic", s); - expect_status("periodic cancelled wait", SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 30), STATUS_TIMEOUT); + if (s != NTLSTATUS_SUCCESS) fail_status("cancel periodic", s); + expect_status("periodic cancelled wait", SysWaitSingle(timer, SYS_WAIT_FLAG_NONE, 30), NTLSTATUS_TIMEOUT); SysCloseHandle(timer); } diff --git a/code/user/tests/win32_exception_smoke/win32_exception_smoke.c b/code/user/tests/win32_exception_smoke/win32_exception_smoke.c new file mode 100644 index 0000000..461e3e2 --- /dev/null +++ b/code/user/tests/win32_exception_smoke/win32_exception_smoke.c @@ -0,0 +1,186 @@ +// Win32 vectored exception smoke test. This file verifies Win32 VEH policy over the native exception runtime. + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include + +static volatile uint32_t gFirstHits; + +static volatile uint32_t gTailHits; +static volatile uint32_t gContinueHits; +static volatile uint32_t gOnlyHits; +static volatile uint32_t gRaisedHits; + +// 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. +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 process. +static void exit_now(int32_t code) { + for (;;) SysExitProcess(code); +} + +// Fails the test with one message. +static void fail(const char* message) { + print("win32_exception_smoke: "); + print(message); + print("\n"); + exit_now(1); +} + +// Fails the test with one integer value. +static void fail_value(const char* message, uint64_t value) { + print("win32_exception_smoke: "); + print(message); + print(" value="); + print_u64(value); + print("\n"); + exit_now(1); +} + +// Verifies the Win32 exception pointers contain a breakpoint and editable context. +static void verify_breakpoint(EXCEPTION_POINTERS* info) { + if (!info || !info->ExceptionRecord || !info->ContextRecord) + fail("handler received null exception pointers"); + if (info->ExceptionRecord->ExceptionCode != EXCEPTION_BREAKPOINT) + fail_value("handler received unexpected exception code", info->ExceptionRecord->ExceptionCode); + if (!info->ExceptionRecord->ExceptionAddress) + fail("handler received null exception address"); + if (!info->ContextRecord->Rip || !info->ContextRecord->Rsp) + fail("handler received empty context"); +} + +// Handles the first breakpoint before later exception handlers can observe it. +static LONG first_continue_handler(EXCEPTION_POINTERS* info) { + verify_breakpoint(info); + gFirstHits++; + return EXCEPTION_CONTINUE_EXECUTION; +} + +// Records an exception pass and asks Win32 policy to keep searching. +static LONG tail_search_handler(EXCEPTION_POINTERS* info) { + verify_breakpoint(info); + gTailHits++; + return EXCEPTION_CONTINUE_SEARCH; +} + +// Continues a breakpoint after the exception-handler list declines it. +static LONG continue_handler(EXCEPTION_POINTERS* info) { + verify_breakpoint(info); + gContinueHits++; + return EXCEPTION_CONTINUE_EXECUTION; +} + +// Handles a breakpoint after earlier handlers have been removed. +static LONG only_continue_handler(EXCEPTION_POINTERS* info) { + verify_breakpoint(info); + gOnlyHits++; + return EXCEPTION_CONTINUE_EXECUTION; +} + + +// Handles a user-raised Win32 exception and verifies parameter translation. +static LONG raised_continue_handler(EXCEPTION_POINTERS* info) { + if (!info || !info->ExceptionRecord || !info->ContextRecord) + fail("raised handler received null exception pointers"); + if (info->ExceptionRecord->ExceptionCode != 0xE1111002u) + fail_value("raised handler received unexpected exception code", info->ExceptionRecord->ExceptionCode); + if (info->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) + fail("raised handler received unexpected noncontinuable flag"); + if (info->ExceptionRecord->NumberParameters != 2) + fail_value("raised handler received wrong parameter count", info->ExceptionRecord->NumberParameters); + if (info->ExceptionRecord->ExceptionInformation[0] != 0x1122u || + info->ExceptionRecord->ExceptionInformation[1] != 0x3344u) + fail("raised handler received wrong parameters"); + gRaisedHits++; + return EXCEPTION_CONTINUE_EXECUTION; +} + +// Verifies one successful remove operation. +static void expect_remove(const char* what, unsigned long removed) { + if (!removed) + fail(what); +} + +// Runs the Win32 vectored exception smoke test. +int main(void) { + print("win32_exception_smoke: start\n"); + + if (AddVectoredExceptionHandler(0, 0)) + fail("null exception handler was accepted"); + if (GetLastError() != 87) + fail_value("null handler did not set ERROR_INVALID_PARAMETER", GetLastError()); + + void* tail = AddVectoredExceptionHandler(0, tail_search_handler); + void* first = AddVectoredExceptionHandler(1, first_continue_handler); + if (!tail || !first) + fail("exception handler registration failed"); + + __debugbreak(); + if (gFirstHits != 1 || gTailHits != 0) + fail("first vectored handler did not run before tail handler"); + + expect_remove("remove first failed", RemoveVectoredExceptionHandler(first)); + + void* cont = AddVectoredContinueHandler(0, continue_handler); + if (!cont) + fail("continue handler registration failed"); + + __debugbreak(); + if (gTailHits != 1 || gContinueHits != 1) + fail("continue handler did not run after exception search"); + + expect_remove("remove tail failed", RemoveVectoredExceptionHandler(tail)); + expect_remove("remove continue failed", RemoveVectoredContinueHandler(cont)); + if (RemoveVectoredContinueHandler(cont)) + fail("second continue-handler removal succeeded unexpectedly"); + if (GetLastError() != 6) + fail_value("second removal did not set ERROR_INVALID_HANDLE", GetLastError()); + + void* only = AddVectoredExceptionHandler(0, only_continue_handler); + if (!only) + fail("single handler registration failed"); + + __debugbreak(); + if (gOnlyHits != 1) + fail("single vectored exception handler did not continue execution"); + + expect_remove("remove single handler failed", RemoveVectoredExceptionHandler(only)); + + void* raised = AddVectoredExceptionHandler(1, raised_continue_handler); + if (!raised) + fail("raised handler registration failed"); + ULONG_PTR args[2] = { 0x1122u, 0x3344u }; + RaiseException(0xE1111002u, 0, 2, args); + if (gRaisedHits != 1) + fail("raised vectored handler did not continue execution"); + expect_remove("remove raised handler failed", RemoveVectoredExceptionHandler(raised)); + + print("win32_exception_smoke: PASS\n"); + exit_now(0); + return 0; +} diff --git a/code/user/tests/win32_seh_smoke/win32_seh_smoke.c b/code/user/tests/win32_seh_smoke/win32_seh_smoke.c new file mode 100644 index 0000000..84d59a9 --- /dev/null +++ b/code/user/tests/win32_seh_smoke/win32_seh_smoke.c @@ -0,0 +1,157 @@ +// Win32 runtime SEH smoke test. This file verifies explicit runtime frames before compiler SEH exists. + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include + +typedef LONG (*PRTL_EXCEPTION_FRAME_HANDLER)(EXCEPTION_POINTERS* ExceptionInfo, PVOID UserContext); + +typedef struct _RTL_EXCEPTION_FRAME { + DWORD Size; + DWORD Flags; + struct _RTL_EXCEPTION_FRAME* Previous; + PRTL_EXCEPTION_FRAME_HANDLER Handler; + PVOID UserContext; +} RTL_EXCEPTION_FRAME; + +PVOID RtlPushExceptionFrame(RTL_EXCEPTION_FRAME* Frame, + PRTL_EXCEPTION_FRAME_HANDLER Handler, + PVOID UserContext); +BOOL RtlPopExceptionFrame(RTL_EXCEPTION_FRAME* Frame); + +static volatile uint32_t gTopHits; + +static volatile uint32_t gBottomHits; +static volatile uint32_t gVehHits; + +// 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. +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 process. +static void exit_now(int32_t code) { + for (;;) SysExitProcess(code); +} + +// Fails the test with one message. +static void fail(const char* message) { + print("win32_seh_smoke: "); + print(message); + print("\n"); + exit_now(1); +} + +// Fails the test with one integer value. +static void fail_value(const char* message, uint64_t value) { + print("win32_seh_smoke: "); + print(message); + print(" value="); + print_u64(value); + print("\n"); + exit_now(1); +} + +// Verifies a breakpoint exception and editable context. +static void verify_breakpoint(EXCEPTION_POINTERS* info) { + if (!info || !info->ExceptionRecord || !info->ContextRecord) + fail("handler received null exception pointers"); + if (info->ExceptionRecord->ExceptionCode != EXCEPTION_BREAKPOINT) + fail_value("handler received unexpected exception code", info->ExceptionRecord->ExceptionCode); + if (!info->ContextRecord->Rip || !info->ContextRecord->Rsp) + fail("handler received empty context"); +} + +// Handles the first breakpoint from the newest runtime SEH frame. +static LONG top_frame_handler(EXCEPTION_POINTERS* info, void* userContext) { + verify_breakpoint(info); + if (userContext != (void*)0x1111u) + fail("top frame context was not preserved"); + gTopHits++; + return EXCEPTION_CONTINUE_EXECUTION; +} + +// Handles a breakpoint after the top frame is removed. +static LONG bottom_frame_handler(EXCEPTION_POINTERS* info, void* userContext) { + verify_breakpoint(info); + if (userContext != (void*)0x2222u) + fail("bottom frame context was not preserved"); + gBottomHits++; + return EXCEPTION_CONTINUE_EXECUTION; +} + +// Proves VEH still sees exceptions before the runtime SEH chain. +static LONG veh_search_handler(EXCEPTION_POINTERS* info) { + verify_breakpoint(info); + gVehHits++; + return EXCEPTION_CONTINUE_SEARCH; +} + +// Runs the runtime-registered Win32 SEH smoke test. +int main(void) { + print("win32_seh_smoke: start\n"); + + if (RtlPushExceptionFrame(NULL, top_frame_handler, NULL)) + fail("null frame was accepted"); + if (GetLastError() != 87) + fail_value("null frame did not set ERROR_INVALID_PARAMETER", GetLastError()); + + RTL_EXCEPTION_FRAME bottom; + RTL_EXCEPTION_FRAME top; + if (!RtlPushExceptionFrame(&bottom, bottom_frame_handler, (void*)0x2222u)) + fail("bottom SEH frame registration failed"); + if (!RtlPushExceptionFrame(&top, top_frame_handler, (void*)0x1111u)) + fail("top SEH frame registration failed"); + + if (RtlPopExceptionFrame(&bottom)) + fail("non-top SEH frame pop succeeded unexpectedly"); + if (GetLastError() != 87) + fail_value("non-top pop did not set ERROR_INVALID_PARAMETER", GetLastError()); + + __debugbreak(); + if (gTopHits != 1 || gBottomHits != 0) + fail("top SEH frame did not run before bottom frame"); + + if (!RtlPopExceptionFrame(&top)) + fail("top SEH frame pop failed"); + + void* veh = AddVectoredExceptionHandler(0, veh_search_handler); + if (!veh) + fail("VEH registration failed"); + + __debugbreak(); + if (gVehHits != 1 || gBottomHits != 1) + fail("VEH did not search before SEH handled the exception"); + + if (!RemoveVectoredExceptionHandler(veh)) + fail("VEH removal failed"); + if (!RtlPopExceptionFrame(&bottom)) + fail("bottom SEH frame pop failed"); + + print("win32_seh_smoke: PASS\n"); + exit_now(0); + return 0; +} diff --git a/code/user/tests/would_block_smoke/would_block_smoke.c b/code/user/tests/would_block_smoke/would_block_smoke.c index 83f57cc..097fc44 100644 --- a/code/user/tests/would_block_smoke/would_block_smoke.c +++ b/code/user/tests/would_block_smoke/would_block_smoke.c @@ -119,7 +119,7 @@ static void sender_thread(uintptr_t arg) { msg.Type = TEST_MESSAGE_WAKE; msg.Param[0] = TEST_WAKE_VALUE; ctx->Status = send_queue(ctx->Queue, &msg, SYS_WAIT_TIMEOUT_INFINITE); - SysExitThread(ctx->Status == STATUS_SUCCESS ? 0 : 1); + SysExitThread(ctx->Status == NTLSTATUS_SUCCESS ? 0 : 1); } // Fills one queue with immediate sends until the queue reports would-block. @@ -131,9 +131,9 @@ static void fill_until_would_block(uint32_t queue) { for (; sends < TEST_FILL_LIMIT; sends++) { msg.Param[0] = sends; uint32_t s = send_queue(queue, &msg, 0); - if (s == STATUS_WOULD_BLOCK) + if (s == NTLSTATUS_WOULD_BLOCK) break; - if (s != STATUS_SUCCESS) + if (s != NTLSTATUS_SUCCESS) fail_status("fill send", s); } @@ -145,20 +145,20 @@ static void fill_until_would_block(uint32_t queue) { static void test_queue_empty_and_full(void) { uint32_t queue = 0; uint32_t s = SysCreateQueue(&queue); - if (s != STATUS_SUCCESS) fail_status("create empty queue", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create empty queue", s); TEST_QUEUE_MESSAGE msg = {0}; - expect_status("empty nonblocking receive", recv_queue(queue, &msg, 0), STATUS_WOULD_BLOCK); - expect_status("empty finite receive", recv_queue(queue, &msg, 20), STATUS_TIMEOUT); + expect_status("empty nonblocking receive", recv_queue(queue, &msg, 0), NTLSTATUS_WOULD_BLOCK); + expect_status("empty finite receive", recv_queue(queue, &msg, 20), NTLSTATUS_TIMEOUT); SysCloseHandle(queue); queue = 0; s = SysCreateQueue(&queue); - if (s != STATUS_SUCCESS) fail_status("create full queue", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create full queue", s); fill_until_would_block(queue); - expect_status("full nonblocking send", send_queue(queue, &msg, 0), STATUS_WOULD_BLOCK); - expect_status("full finite send", send_queue(queue, &msg, 20), STATUS_TIMEOUT); + expect_status("full nonblocking send", send_queue(queue, &msg, 0), NTLSTATUS_WOULD_BLOCK); + expect_status("full finite send", send_queue(queue, &msg, 20), NTLSTATUS_TIMEOUT); SysCloseHandle(queue); } @@ -166,9 +166,9 @@ static void test_queue_empty_and_full(void) { static void test_queue_infinite_receive_wakeup(void) { uint32_t queue = 0; uint32_t s = SysCreateQueue(&queue); - if (s != STATUS_SUCCESS) fail_status("create wake queue", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create wake queue", s); - TEST_SENDER_CONTEXT ctx = { queue, STATUS_PENDING }; + TEST_SENDER_CONTEXT ctx = { queue, NTLSTATUS_PENDING }; uint32_t threadHandle = 0; uint32_t threadId = 0; SYS_CREATE_THREAD_REQUEST req = { @@ -180,17 +180,17 @@ static void test_queue_infinite_receive_wakeup(void) { &threadId }; s = SysCreateThread(&req); - if (s != STATUS_SUCCESS) fail_status("create sender", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create sender", s); TEST_QUEUE_MESSAGE msg = {0}; s = recv_queue(queue, &msg, SYS_WAIT_TIMEOUT_INFINITE); - if (s != STATUS_SUCCESS) fail_status("infinite receive", s); + if (s != NTLSTATUS_SUCCESS) fail_status("infinite receive", s); if (msg.Type != TEST_MESSAGE_WAKE || msg.Param[0] != TEST_WAKE_VALUE) fail("wake message payload mismatch"); s = SysWait(threadHandle, SYS_WAIT_FLAG_NONE); - if (s != STATUS_SUCCESS) fail_status("wait sender", s); - if (ctx.Status != STATUS_SUCCESS) fail_status("sender status", ctx.Status); + if (s != NTLSTATUS_SUCCESS) fail_status("wait sender", s); + if (ctx.Status != NTLSTATUS_SUCCESS) fail_status("sender status", ctx.Status); SysCloseHandle(threadHandle); SysCloseHandle(queue); @@ -200,11 +200,11 @@ static void test_queue_infinite_receive_wakeup(void) { static void test_queue_request_validation(void) { uint32_t queue = 0; uint32_t s = SysCreateQueue(&queue); - if (s != STATUS_SUCCESS) fail_status("create validation queue", s); + if (s != NTLSTATUS_SUCCESS) fail_status("create validation queue", s); TEST_QUEUE_MESSAGE msg = {0}; - expect_status("null send request", SysSendQueue((const SYS_QUEUE_SEND_REQUEST*)0), STATUS_INVALID_PARAMETER); - expect_status("null recv request", SysRecvQueue((const SYS_QUEUE_RECV_REQUEST*)0), STATUS_INVALID_PARAMETER); + expect_status("null send request", SysSendQueue((const SYS_QUEUE_SEND_REQUEST*)0), NTLSTATUS_INVALID_PARAMETER); + expect_status("null recv request", SysRecvQueue((const SYS_QUEUE_RECV_REQUEST*)0), NTLSTATUS_INVALID_PARAMETER); SYS_QUEUE_SEND_REQUEST sendReq = { 0, @@ -213,15 +213,15 @@ static void test_queue_request_validation(void) { 0, &msg, }; - expect_status("bad send size", SysSendQueue(&sendReq), STATUS_INVALID_PARAMETER); + expect_status("bad send size", SysSendQueue(&sendReq), NTLSTATUS_INVALID_PARAMETER); sendReq.Size = sizeof(sendReq); sendReq.Flags = 1; - expect_status("bad send flags", SysSendQueue(&sendReq), STATUS_INVALID_PARAMETER); + expect_status("bad send flags", SysSendQueue(&sendReq), NTLSTATUS_INVALID_PARAMETER); sendReq.Flags = SYS_QUEUE_FLAG_NONE; sendReq.Message = (const void*)0; - expect_status("bad send message", SysSendQueue(&sendReq), STATUS_INVALID_PARAMETER); + expect_status("bad send message", SysSendQueue(&sendReq), NTLSTATUS_INVALID_PARAMETER); SYS_QUEUE_RECV_REQUEST recvReq = { sizeof(recvReq), @@ -230,7 +230,7 @@ static void test_queue_request_validation(void) { 0, (void*)0, }; - expect_status("bad recv message", SysRecvQueue(&recvReq), STATUS_INVALID_PARAMETER); + expect_status("bad recv message", SysRecvQueue(&recvReq), NTLSTATUS_INVALID_PARAMETER); SysCloseHandle(queue); } diff --git a/docs.md b/docs.md index 6298943..7d89d79 100644 --- a/docs.md +++ b/docs.md @@ -92,3 +92,10 @@ Breaking changes are allowed. When making one: - When a change crosses layers, verify every layer that knows about the new object, file, syscall, or artifact. - Prefer finishing the feature the user needs over endlessly polishing the audit around it. - Do not hide uncertainty. Say what was checked and what still needs a real build or boot test. + +## comments from developer + +- 0x%016llX over %p +- never add Ex, it makes me mad +- i do put a focus on overengineering if it means it will be cleaner and futureproof +- please do ask questions