diff --git a/src/windows-emulator/devices/afd_endpoint.cpp b/src/windows-emulator/devices/afd_endpoint.cpp index f240857b..fd3dd8e3 100644 --- a/src/windows-emulator/devices/afd_endpoint.cpp +++ b/src/windows-emulator/devices/afd_endpoint.cpp @@ -569,7 +569,7 @@ namespace auto data = win_emu.emu().read_memory(c.input_buffer, c.input_buffer_length); - constexpr auto address_offset = 12; + constexpr auto address_offset = 24; if (data.size() < address_offset) { @@ -583,9 +583,15 @@ namespace const auto error = this->s_->get_last_error(); if (error == SERR(EWOULDBLOCK)) { - this->delay_ioctrl(c, true); + this->delay_ioctrl(c, false); return STATUS_PENDING; } + + if (this->executing_delayed_ioctl_ && error == SERR(EISCONN)) + { + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; } @@ -663,6 +669,7 @@ namespace this->delay_ioctrl(c, true); return STATUS_PENDING; } + return STATUS_UNSUCCESSFUL; } @@ -1044,9 +1051,46 @@ namespace return STATUS_SUCCESS; } }; + + struct afd_async_connect_hlp : stateless_device + { + NTSTATUS io_control(windows_emulator& win_emu, const io_device_context& c) override + { + if (c.io_control_code != 0x12007) + { + return STATUS_NOT_SUPPORTED; + } + + if (c.input_buffer_length < 40) + { + return STATUS_BUFFER_TOO_SMALL; + } + + const auto target_handle = win_emu.emu().read_memory(c.input_buffer + 16); + + auto* target_device = win_emu.process.devices.get(target_handle); + if (!target_device) + { + return STATUS_INVALID_HANDLE; + } + + auto* target_endpoint = target_device->get_internal_device(); + if (!target_endpoint) + { + return STATUS_INVALID_HANDLE; + } + + return target_endpoint->execute_ioctl(win_emu, c); + } + }; } std::unique_ptr create_afd_endpoint() { return std::make_unique(); } + +std::unique_ptr create_afd_async_connect_hlp() +{ + return std::make_unique(); +} \ No newline at end of file diff --git a/src/windows-emulator/devices/afd_endpoint.hpp b/src/windows-emulator/devices/afd_endpoint.hpp index caf72689..dd736ab3 100644 --- a/src/windows-emulator/devices/afd_endpoint.hpp +++ b/src/windows-emulator/devices/afd_endpoint.hpp @@ -2,3 +2,4 @@ #include "../io_device.hpp" std::unique_ptr create_afd_endpoint(); +std::unique_ptr create_afd_async_connect_hlp(); diff --git a/src/windows-emulator/io_device.cpp b/src/windows-emulator/io_device.cpp index 5522be44..dc8c86cd 100644 --- a/src/windows-emulator/io_device.cpp +++ b/src/windows-emulator/io_device.cpp @@ -32,6 +32,11 @@ std::unique_ptr create_device(const std::u16string_view device) return create_afd_endpoint(); } + if (device == u"Afd\\AsyncConnectHlp") + { + return create_afd_async_connect_hlp(); + } + if (device == u"MountPointManager") { return create_mount_point_manager(); diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 9e0e8f15..18924636 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -415,6 +415,11 @@ namespace syscalls return handle_NtCreateEvent(c, event_handle, desired_access, object_attributes, NotificationEvent, FALSE); } + NTSTATUS handle_NtSetIoCompletion() + { + return STATUS_NOT_SUPPORTED; + } + NTSTATUS handle_NtCreateWaitCompletionPacket( const syscall_context& c, const emulator_object event_handle, const ACCESS_MASK desired_access, const emulator_object>> object_attributes) @@ -940,6 +945,7 @@ void syscall_dispatcher::add_handlers(std::map& ha add_handler(NtTraceEvent); add_handler(NtAllocateVirtualMemoryEx); add_handler(NtCreateIoCompletion); + add_handler(NtSetIoCompletion); add_handler(NtCreateWaitCompletionPacket); add_handler(NtCreateWorkerFactory); add_handler(NtManageHotPatch); diff --git a/src/windows-emulator/syscalls/file.cpp b/src/windows-emulator/syscalls/file.cpp index 4e765cf4..6462e60b 100644 --- a/src/windows-emulator/syscalls/file.cpp +++ b/src/windows-emulator/syscalls/file.cpp @@ -25,6 +25,12 @@ namespace syscalls const auto* f = c.proc.files.get(file_handle); if (!f) { + if (c.proc.devices.get(file_handle)) + { + c.win_emu.log.error("Unsupported set device info class: %X\n", info_class); + return STATUS_SUCCESS; + } + return STATUS_INVALID_HANDLE; }