From e33e05787511572beced7077cc5b891943eb0b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Tue, 14 Jan 2025 18:33:43 +0400 Subject: [PATCH] qemu-display: add back manual win32 mmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's not yet possible to map from a mapping object in memmap2... Signed-off-by: Marc-André Lureau --- qemu-display/src/audio.rs | 19 +++++----- qemu-display/src/console.rs | 4 +-- qemu-display/src/console_listener.rs | 11 +++++- qemu-display/src/win32.rs | 52 +++++++++++++++++++++++++++- qemu-rdw/src/display.rs | 2 -- 5 files changed, 70 insertions(+), 18 deletions(-) diff --git a/qemu-display/src/audio.rs b/qemu-display/src/audio.rs index d6bb221..65cb1e9 100644 --- a/qemu-display/src/audio.rs +++ b/qemu-display/src/audio.rs @@ -269,11 +269,10 @@ impl Audio { &p0, )?; self.proxy.register_out_listener(p0).await?; - let conn = zbus::connection::Builder::unix_stream(p1).p2p() - .serve_at( - "/org/qemu/Display1/AudioOutListener", - AudioOutListener { handler }, - )?; + let conn = zbus::connection::Builder::unix_stream(p1).p2p().serve_at( + "/org/qemu/Display1/AudioOutListener", + AudioOutListener { handler }, + )?; #[cfg(windows)] let conn = conn.auth_mechanism(zbus::AuthMechanism::Anonymous); let conn = conn.build().await?; @@ -289,12 +288,10 @@ impl Audio { &p0, )?; self.proxy.register_in_listener(p0).await?; - let conn = zbus::connection::Builder::unix_stream(p1) - .p2p() - .serve_at( - "/org/qemu/Display1/AudioInListener", - AudioInListener { handler }, - )?; + let conn = zbus::connection::Builder::unix_stream(p1).p2p().serve_at( + "/org/qemu/Display1/AudioInListener", + AudioInListener { handler }, + )?; #[cfg(windows)] let conn = conn.auth_mechanism(zbus::AuthMechanism::Anonymous); let conn = conn.build().await?; diff --git a/qemu-display/src/console.rs b/qemu-display/src/console.rs index 3b8104a..3a3ca61 100644 --- a/qemu-display/src/console.rs +++ b/qemu-display/src/console.rs @@ -118,9 +118,7 @@ impl Console { .serve_at("/org/qemu/Display1/Listener", ConsoleListener::new(handler))?; #[cfg(windows)] let conn = conn.auth_mechanism(zbus::AuthMechanism::Anonymous); - let conn = conn - .build() - .await?; + let conn = conn.build().await?; *self.listener.write().unwrap() = Some(conn); Ok(()) } diff --git a/qemu-display/src/console_listener.rs b/qemu-display/src/console_listener.rs index 2ae2c19..7c72952 100644 --- a/qemu-display/src/console_listener.rs +++ b/qemu-display/src/console_listener.rs @@ -1,6 +1,7 @@ #[cfg(windows)] -use crate::win32::Fd; +use crate::win32::{Fd, Mmap}; use derivative::Derivative; +#[cfg(unix)] use memmap2::Mmap; use std::ops::Drop; #[cfg(windows)] @@ -66,6 +67,7 @@ impl ScanoutMap { #[cfg(windows)] let desc = self.handle.as_raw_handle(); + #[cfg(unix)] let mmap = unsafe { memmap2::MmapOptions::new() .len(len) @@ -73,6 +75,13 @@ impl ScanoutMap { .map(desc)? }; + #[cfg(windows)] + let mmap = { + use windows::Win32::Foundation::HANDLE; + let handle = HANDLE(desc as _); + Mmap::new(handle, offset.try_into().unwrap(), len)? + }; + Ok(ScanoutMmap { scanout: self, mmap, diff --git a/qemu-display/src/win32.rs b/qemu-display/src/win32.rs index 1692970..a09fce5 100644 --- a/qemu-display/src/win32.rs +++ b/qemu-display/src/win32.rs @@ -1,9 +1,13 @@ use std::io; +use tracing::warn; use windows::Win32::{ Foundation::{CloseHandle, HANDLE}, Networking::WinSock::{WSADuplicateSocketW, SOCKET, WSAPROTOCOL_INFOW}, - System::Threading::PROCESS_ACCESS_RIGHTS, + System::{ + Memory::{MapViewOfFile, UnmapViewOfFile, FILE_MAP_READ, MEMORY_MAPPED_VIEW_ADDRESS}, + Threading::PROCESS_ACCESS_RIGHTS, + }, }; #[cfg(feature = "qmp")] @@ -118,3 +122,49 @@ pub(crate) fn unix_stream_get_peer_pid(stream: &UnixStream) -> Result std::io::Result { + let ptr = unsafe { MapViewOfFile(handle, FILE_MAP_READ, 0, 0, offset + size) }; + if ptr.Value.is_null() { + return Err(io::Error::last_os_error()); + } + Ok(Self { + handle, + ptr, + offset: offset.try_into().unwrap(), + size, + }) + } + + pub(crate) fn as_ref(&self) -> &[u8] { + unsafe { + std::slice::from_raw_parts(self.ptr.Value.cast::().offset(self.offset), self.size) + } + } +} diff --git a/qemu-rdw/src/display.rs b/qemu-rdw/src/display.rs index be6dc59..bc2d09c 100644 --- a/qemu-rdw/src/display.rs +++ b/qemu-rdw/src/display.rs @@ -504,12 +504,10 @@ impl ConsoleListenerMapHandler for ConsoleHandler { #[cfg(windows)] #[async_trait::async_trait] impl ConsoleListenerD3d11Handler for ConsoleHandler { - #[cfg(windows)] async fn scanout_texture2d(&mut self, scanout: qemu_display::ScanoutD3dTexture2d) { self.send(ConsoleEvent::ScanoutD3dTexture2d(scanout)); } - #[cfg(windows)] async fn update_texture2d(&mut self, update: qemu_display::UpdateD3dTexture2d) { let (wait_tx, wait_rx) = futures::channel::oneshot::channel(); self.send(ConsoleEvent::UpdateD3dTexture2d { update, wait_tx });