From 75ee63803cc286a5ea8192a74f3c769e8c310591 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Tue, 20 May 2025 21:43:49 -0300 Subject: [PATCH 1/4] Add new device to `create_device` --- src/windows-emulator/io_device.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/windows-emulator/io_device.cpp b/src/windows-emulator/io_device.cpp index 93659d76..5522be44 100644 --- a/src/windows-emulator/io_device.cpp +++ b/src/windows-emulator/io_device.cpp @@ -18,6 +18,7 @@ std::unique_ptr create_device(const std::u16string_view device) { if (device == u"CNG" // || device == u"Nsi" // + || device == u"RasAcd" // || device == u"KsecDD" // || device == u"PcwDrv" // || device == u"DeviceApi\\CMApi" // From 4888142d224356e43b9d3537ca70c48800df74b3 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Tue, 20 May 2025 21:44:18 -0300 Subject: [PATCH 2/4] Better handling of NtCreateKey --- src/windows-emulator/syscalls.cpp | 6 +++++- src/windows-emulator/syscalls/registry.cpp | 16 ++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 364dcab0..14e4d8b9 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -236,7 +236,11 @@ namespace syscalls emulator_object>> value_name, KEY_VALUE_INFORMATION_CLASS key_value_information_class, uint64_t key_value_information, ULONG length, emulator_object result_length); - NTSTATUS handle_NtCreateKey(); + NTSTATUS handle_NtCreateKey(const syscall_context& c, emulator_object key_handle, + ACCESS_MASK desired_access, + emulator_object>> object_attributes, + ULONG /*title_index*/, emulator_object>> /*class*/, + ULONG /*create_options*/, emulator_object /*disposition*/); NTSTATUS handle_NtNotifyChangeKey(); NTSTATUS handle_NtSetInformationKey(); NTSTATUS handle_NtEnumerateKey(const syscall_context& c, handle key_handle, ULONG index, diff --git a/src/windows-emulator/syscalls/registry.cpp b/src/windows-emulator/syscalls/registry.cpp index 724d284a..2b219311 100644 --- a/src/windows-emulator/syscalls/registry.cpp +++ b/src/windows-emulator/syscalls/registry.cpp @@ -227,9 +227,21 @@ namespace syscalls return STATUS_NOT_SUPPORTED; } - NTSTATUS handle_NtCreateKey() + NTSTATUS handle_NtCreateKey(const syscall_context& c, const emulator_object key_handle, + const ACCESS_MASK desired_access, + const emulator_object>> object_attributes, + const ULONG /*title_index*/, + const emulator_object>> /*class*/, + const ULONG /*create_options*/, const emulator_object /*disposition*/) { - return STATUS_NOT_SUPPORTED; + const auto result = handle_NtOpenKey(c, key_handle, desired_access, object_attributes); + + if (result == STATUS_OBJECT_NAME_NOT_FOUND) + { + return STATUS_NOT_SUPPORTED; + } + + return result; } NTSTATUS handle_NtNotifyChangeKey() From 3e1f206bc00f75d82cc271f03ac2c9b7397137f1 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Tue, 20 May 2025 21:44:40 -0300 Subject: [PATCH 3/4] Fixes to file syscalls --- src/windows-emulator/syscalls/file.cpp | 54 +++++++++++++++++++++----- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/src/windows-emulator/syscalls/file.cpp b/src/windows-emulator/syscalls/file.cpp index 6c3dcd41..7f937f1c 100644 --- a/src/windows-emulator/syscalls/file.cpp +++ b/src/windows-emulator/syscalls/file.cpp @@ -115,7 +115,8 @@ namespace syscalls files.emplace_back(file_entry{.file_path = "..", .is_directory = true}); } - for (const auto& file : std::filesystem::directory_iterator(dir)) + std::error_code ec{}; + for (const auto& file : std::filesystem::directory_iterator(dir, ec)) { if (!file_mask.empty() && !utils::wildcard::match_filename(file.path().filename().u16string(), file_mask)) { @@ -363,6 +364,35 @@ namespace syscalls return ret(STATUS_SUCCESS); } + if (info_class == FileBasicInformation) + { + block.Information = sizeof(FILE_BASIC_INFORMATION); + + if (length < block.Information) + { + return ret(STATUS_BUFFER_OVERFLOW); + } + + struct _stat64 file_stat{}; + if (_fstat64(f->handle, &file_stat) != 0) + { + return STATUS_INVALID_HANDLE; + } + + const emulator_object info{c.emu, file_information}; + FILE_BASIC_INFORMATION i{}; + + i.CreationTime = utils::convert_unix_to_windows_time(file_stat.st_atime); + i.LastAccessTime = utils::convert_unix_to_windows_time(file_stat.st_atime); + i.LastWriteTime = utils::convert_unix_to_windows_time(file_stat.st_mtime); + i.ChangeTime = i.LastWriteTime; + i.FileAttributes = (file_stat.st_mode & _S_IFDIR) != 0 ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL; + + info.write(i); + + return ret(STATUS_SUCCESS); + } + if (info_class == FilePositionInformation) { if (!f->handle) @@ -411,6 +441,11 @@ namespace syscalls return ret(STATUS_SUCCESS); } + if (info_class == FileAllInformation) + { + return ret(STATUS_NOT_SUPPORTED); + } + c.win_emu.log.error("Unsupported query file info class: %X\n", info_class); c.emu.stop(); @@ -654,8 +689,10 @@ namespace syscalls printer.cancel(); + std::error_code ec{}; + const windows_path path = f.name; - const bool is_directory = std::filesystem::is_directory(c.win_emu.file_sys.translate(path)); + const bool is_directory = std::filesystem::is_directory(c.win_emu.file_sys.translate(path), ec); if (is_directory || create_options & FILE_DIRECTORY_FILE) { @@ -663,7 +700,6 @@ namespace syscalls if (create_disposition & FILE_CREATE) { - std::error_code ec{}; create_directory(c.win_emu.file_sys.translate(path), ec); if (ec) @@ -750,10 +786,10 @@ namespace syscalls c.win_emu.log.print(color::dark_gray, "--> Querying file attributes: %s\n", u16_to_u8(filename).c_str()); - const auto local_filename = c.win_emu.file_sys.translate(filename).string(); + const auto local_filename = c.win_emu.file_sys.translate(filename).u8string(); struct _stat64 file_stat{}; - if (_stat64(local_filename.c_str(), &file_stat) != 0) + if (_stat64(reinterpret_cast(local_filename.c_str()), &file_stat) != 0) { return STATUS_OBJECT_NAME_NOT_FOUND; } @@ -765,7 +801,7 @@ namespace syscalls info.AllocationSize.QuadPart = file_stat.st_size; info.EndOfFile.QuadPart = file_stat.st_size; info.ChangeTime = info.LastWriteTime; - info.FileAttributes = FILE_ATTRIBUTE_NORMAL; + info.FileAttributes = (file_stat.st_mode & _S_IFDIR) != 0 ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL; }); return STATUS_SUCCESS; @@ -791,10 +827,10 @@ namespace syscalls c.win_emu.log.print(color::dark_gray, "--> Querying file attributes: %s\n", u16_to_u8(filename).c_str()); - const auto local_filename = c.win_emu.file_sys.translate(filename).string(); + const auto local_filename = c.win_emu.file_sys.translate(filename).u8string(); struct _stat64 file_stat{}; - if (_stat64(local_filename.c_str(), &file_stat) != 0) + if (_stat64(reinterpret_cast(local_filename.c_str()), &file_stat) != 0) { return STATUS_OBJECT_NAME_NOT_FOUND; } @@ -804,7 +840,7 @@ namespace syscalls info.LastAccessTime = utils::convert_unix_to_windows_time(file_stat.st_atime); info.LastWriteTime = utils::convert_unix_to_windows_time(file_stat.st_mtime); info.ChangeTime = info.LastWriteTime; - info.FileAttributes = FILE_ATTRIBUTE_NORMAL; + info.FileAttributes = (file_stat.st_mode & _S_IFDIR) != 0 ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL; }); return STATUS_SUCCESS; From 5b4193cf924d083a4eb35f87fb60966ba480f0a8 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Tue, 20 May 2025 21:47:35 -0300 Subject: [PATCH 4/4] Fix failing checks --- src/windows-emulator/syscalls/file.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/windows-emulator/syscalls/file.cpp b/src/windows-emulator/syscalls/file.cpp index 7f937f1c..4e765cf4 100644 --- a/src/windows-emulator/syscalls/file.cpp +++ b/src/windows-emulator/syscalls/file.cpp @@ -9,6 +9,12 @@ #include +#if defined(OS_WINDOWS) +#define fstat64 _fstat64 +#elif defined(OS_MAC) +#define fstat64 fstat +#endif + namespace syscalls { NTSTATUS handle_NtSetInformationFile(const syscall_context& c, const handle file_handle, @@ -374,7 +380,7 @@ namespace syscalls } struct _stat64 file_stat{}; - if (_fstat64(f->handle, &file_stat) != 0) + if (fstat64(f->handle, &file_stat) != 0) { return STATUS_INVALID_HANDLE; } @@ -386,7 +392,7 @@ namespace syscalls i.LastAccessTime = utils::convert_unix_to_windows_time(file_stat.st_atime); i.LastWriteTime = utils::convert_unix_to_windows_time(file_stat.st_mtime); i.ChangeTime = i.LastWriteTime; - i.FileAttributes = (file_stat.st_mode & _S_IFDIR) != 0 ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL; + i.FileAttributes = (file_stat.st_mode & S_IFDIR) != 0 ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL; info.write(i); @@ -801,7 +807,7 @@ namespace syscalls info.AllocationSize.QuadPart = file_stat.st_size; info.EndOfFile.QuadPart = file_stat.st_size; info.ChangeTime = info.LastWriteTime; - info.FileAttributes = (file_stat.st_mode & _S_IFDIR) != 0 ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL; + info.FileAttributes = (file_stat.st_mode & S_IFDIR) != 0 ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL; }); return STATUS_SUCCESS; @@ -840,7 +846,7 @@ namespace syscalls info.LastAccessTime = utils::convert_unix_to_windows_time(file_stat.st_atime); info.LastWriteTime = utils::convert_unix_to_windows_time(file_stat.st_mtime); info.ChangeTime = info.LastWriteTime; - info.FileAttributes = (file_stat.st_mode & _S_IFDIR) != 0 ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL; + info.FileAttributes = (file_stat.st_mode & S_IFDIR) != 0 ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL; }); return STATUS_SUCCESS;