diff --git a/src/windows-emulator/devices/named_pipe.hpp b/src/windows-emulator/devices/named_pipe.hpp new file mode 100644 index 00000000..ef295342 --- /dev/null +++ b/src/windows-emulator/devices/named_pipe.hpp @@ -0,0 +1,21 @@ +#pragma once +#include "../io_device.hpp" + +class named_pipe : public io_device_container { +public: + std::u16string name; + ULONG pipe_type; + ULONG read_mode; + ULONG completion_mode; + ULONG max_instances; + ULONG inbound_quota; + ULONG outbound_quota; + LARGE_INTEGER default_timeout; + + void create(windows_emulator&, const io_device_creation_data&) override {} + void work(windows_emulator&) override {} + NTSTATUS io_control(windows_emulator&, const io_device_context&) override { return STATUS_NOT_SUPPORTED; } + + void serialize_object(utils::buffer_serializer&) const override {} + void deserialize_object(utils::buffer_deserializer&) override {} +}; \ No newline at end of file diff --git a/src/windows-emulator/io_device.cpp b/src/windows-emulator/io_device.cpp index ef6da159..9f34954d 100644 --- a/src/windows-emulator/io_device.cpp +++ b/src/windows-emulator/io_device.cpp @@ -4,6 +4,7 @@ #include "devices/afd_endpoint.hpp" #include "devices/mount_point_manager.hpp" #include "devices/security_support_provider.hpp" +#include "devices/named_pipe.hpp" namespace { @@ -49,6 +50,11 @@ std::unique_ptr create_device(const std::u16string_view device) return create_security_support_provider(); } + if (device == u"NamedPipe") + { + return std::make_unique(); + } + throw std::runtime_error("Unsupported device: " + u16_to_u8(device)); } diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index abba7931..c04e0d32 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -436,6 +436,11 @@ namespace syscalls return STATUS_SUCCESS; } + NTSTATUS handle_NtReleaseWorkerFactoryWorker() + { + return STATUS_SUCCESS; + } + NTSTATUS handle_NtCreateIoCompletion( const syscall_context& c, const emulator_object event_handle, const ACCESS_MASK desired_access, const emulator_object>> object_attributes, @@ -1185,6 +1190,7 @@ void syscall_dispatcher::add_handlers(std::map& ha add_handler(NtQueryEvent); add_handler(NtRemoveIoCompletionEx); add_handler(NtCreateDebugObject); + add_handler(NtReleaseWorkerFactoryWorker); #undef add_handler } diff --git a/src/windows-emulator/syscalls/file.cpp b/src/windows-emulator/syscalls/file.cpp index 55773b7d..149929b6 100644 --- a/src/windows-emulator/syscalls/file.cpp +++ b/src/windows-emulator/syscalls/file.cpp @@ -9,6 +9,8 @@ #include +#include "../devices/named_pipe.hpp" + #if defined(OS_WINDOWS) #define fstat64 _fstat64 #elif defined(OS_MAC) @@ -1067,21 +1069,72 @@ namespace syscalls return STATUS_NOT_SUPPORTED; } - NTSTATUS handle_NtCreateNamedPipeFile( - const syscall_context& c, const emulator_object /*file_handle*/, const ULONG /*desired_access*/, - const emulator_object>> /*object_attributes*/, - const emulator_object>> /*io_status_block*/, const ULONG /*share_access*/, - const ULONG /*create_disposition*/, const ULONG /*create_options*/, const ULONG /*named_pipe_type*/, - const ULONG /*read_mode*/, const ULONG /*completion_mode*/, const ULONG /*maximum_instances*/, - const ULONG /*inbound_quota*/, const ULONG /*outbound_quota*/, - const emulator_object /*default_timeout*/) + NTSTATUS handle_NtCreateNamedPipeFile(const syscall_context& c, emulator_object file_handle, + ULONG desired_access, + emulator_object>> object_attributes, + emulator_object>> io_status_block, + ULONG share_access, ULONG create_disposition, ULONG create_options, + ULONG named_pipe_type, ULONG read_mode, ULONG completion_mode, + ULONG maximum_instances, ULONG inbound_quota, ULONG outbound_quota, + emulator_object default_timeout) { - c.win_emu.log.error("Unimplemented syscall NtCreateNamedPipeFile!"); - c.emu.stop(); + UNREFERENCED_PARAMETER(desired_access); + UNREFERENCED_PARAMETER(share_access); + UNREFERENCED_PARAMETER(create_disposition); + UNREFERENCED_PARAMETER(create_options); + UNREFERENCED_PARAMETER(object_attributes); - return STATUS_NOT_SUPPORTED; + std::u16string file_name; + + object_attributes.access([&](const auto& attrs) { + emulator_object>> unicode_string( + c.emu, static_cast(attrs.ObjectName)); + + unicode_string.access([&](const auto& unicode) { + if (unicode.Length > 0 && unicode.Buffer != 0) + { + const uint64_t buffer_addr = static_cast(unicode.Buffer); + std::vector buffer(unicode.Length / sizeof(char16_t)); + c.emu.read_memory(buffer_addr, buffer.data(), unicode.Length); + file_name.assign(buffer.begin(), buffer.end()); + } + }); + }); + + io_device_creation_data data{}; + + io_device_container container{u"NamedPipe", c.win_emu, data}; + if (auto* pipe_device = container.get_internal_device()) + { + pipe_device->name = file_name; + } + + // Create pipe and fill details + auto* pipe_device = container.get_internal_device(); + pipe_device->name = u"StubPipe"; + pipe_device->pipe_type = named_pipe_type; + pipe_device->read_mode = read_mode; + pipe_device->completion_mode = completion_mode; + pipe_device->max_instances = maximum_instances; + pipe_device->inbound_quota = inbound_quota; + pipe_device->outbound_quota = outbound_quota; + pipe_device->default_timeout = default_timeout.read(); // <--- FIXED + + // Store in device handle table + handle pipe_handle = c.proc.devices.store(std::move(container)); + file_handle.write(pipe_handle); + + // Return status via IOSB + IO_STATUS_BLOCK> iosb{}; + iosb.Status = STATUS_SUCCESS; + iosb.Information = 0; + io_status_block.write(iosb); // <--- FIXED + + return STATUS_SUCCESS; } + + NTSTATUS handle_NtFsControlFile(const syscall_context& c, const handle /*event_handle*/, const uint64_t /*apc_routine*/, const uint64_t /*app_context*/, const emulator_object>> /*io_status_block*/,