mirror of
https://gitlab.com/marcandre.lureau/qemu-display.git
synced 2024-12-22 05:35:20 +00:00
Add basic windows support
This commit is contained in:
parent
817d44e17a
commit
91a8549b70
@ -72,6 +72,8 @@ pub struct Audio {
|
||||
pub proxy: AudioProxy<'static>,
|
||||
out_listener: Option<Connection>,
|
||||
in_listener: Option<Connection>,
|
||||
#[cfg(windows)]
|
||||
peer_pid: u32,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
@ -233,12 +235,14 @@ impl<H: AudioInHandler> AudioInListener<H> {
|
||||
}
|
||||
|
||||
impl Audio {
|
||||
pub async fn new(conn: &zbus::Connection) -> Result<Self> {
|
||||
pub async fn new(conn: &zbus::Connection, #[cfg(windows)] peer_pid: u32) -> Result<Self> {
|
||||
let proxy = AudioProxy::new(conn).await?;
|
||||
Ok(Self {
|
||||
proxy,
|
||||
in_listener: None,
|
||||
out_listener: None,
|
||||
#[cfg(windows)]
|
||||
peer_pid,
|
||||
})
|
||||
}
|
||||
|
||||
@ -246,7 +250,7 @@ impl Audio {
|
||||
let (p0, p1) = UnixStream::pair()?;
|
||||
let p0 = util::prepare_uds_pass(
|
||||
#[cfg(windows)]
|
||||
self.proxy.inner().connection(),
|
||||
self.peer_pid,
|
||||
&p0,
|
||||
)?;
|
||||
self.proxy.register_out_listener(p0).await?;
|
||||
@ -266,7 +270,7 @@ impl Audio {
|
||||
let (p0, p1) = UnixStream::pair()?;
|
||||
let p0 = util::prepare_uds_pass(
|
||||
#[cfg(windows)]
|
||||
self.proxy.inner().connection(),
|
||||
self.peer_pid,
|
||||
&p0,
|
||||
)?;
|
||||
self.proxy.register_in_listener(p0).await?;
|
||||
|
@ -54,10 +54,12 @@ pub struct Console {
|
||||
#[derivative(Debug = "ignore")]
|
||||
pub mouse: MouseProxy<'static>,
|
||||
listener: RefCell<Option<Connection>>,
|
||||
#[cfg(windows)]
|
||||
peer_pid: u32,
|
||||
}
|
||||
|
||||
impl Console {
|
||||
pub async fn new(conn: &Connection, idx: u32) -> Result<Self> {
|
||||
pub async fn new(conn: &Connection, idx: u32, #[cfg(windows)] peer_pid: u32) -> Result<Self> {
|
||||
let obj_path = ObjectPath::try_from(format!("/org/qemu/Display1/Console_{}", idx))?;
|
||||
let proxy = ConsoleProxy::builder(conn).path(&obj_path)?.build().await?;
|
||||
let keyboard = KeyboardProxy::builder(conn)
|
||||
@ -70,6 +72,8 @@ impl Console {
|
||||
keyboard,
|
||||
mouse,
|
||||
listener: RefCell::new(None),
|
||||
#[cfg(windows)]
|
||||
peer_pid,
|
||||
})
|
||||
}
|
||||
|
||||
@ -89,7 +93,7 @@ impl Console {
|
||||
let (p0, p1) = UnixStream::pair()?;
|
||||
let p0 = util::prepare_uds_pass(
|
||||
#[cfg(windows)]
|
||||
self.proxy.inner().connection(),
|
||||
self.peer_pid,
|
||||
&p0,
|
||||
)?;
|
||||
self.proxy.register_listener(p0).await?;
|
||||
|
@ -25,6 +25,8 @@ struct Inner<'d> {
|
||||
proxy: fdo::ObjectManagerProxy<'d>,
|
||||
conn: Connection,
|
||||
objects: ManagedObjects,
|
||||
#[cfg(windows)]
|
||||
peer_pid: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -82,7 +84,11 @@ impl<'d> Display<'d> {
|
||||
Ok(hm)
|
||||
}
|
||||
|
||||
pub async fn new<D>(conn: &Connection, dest: Option<D>) -> Result<Display<'d>>
|
||||
pub async fn new<D>(
|
||||
conn: &Connection,
|
||||
dest: Option<D>,
|
||||
#[cfg(windows)] peer_pid: u32,
|
||||
) -> Result<Display<'d>>
|
||||
where
|
||||
D: TryInto<BusName<'d>>,
|
||||
D::Error: Into<Error>,
|
||||
@ -102,6 +108,8 @@ impl<'d> Display<'d> {
|
||||
proxy,
|
||||
conn: conn.clone(),
|
||||
objects,
|
||||
#[cfg(windows)]
|
||||
peer_pid,
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
@ -113,6 +121,11 @@ impl<'d> Display<'d> {
|
||||
&self.inner.conn
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn peer_pid(&self) -> u32 {
|
||||
self.inner.peer_pid
|
||||
}
|
||||
|
||||
#[cfg(all(windows, feature = "qmp"))]
|
||||
pub async fn new_qmp<P: AsRef<std::path::Path>>(path: P) -> Result<Display<'d>> {
|
||||
#![allow(non_snake_case, non_camel_case_types)]
|
||||
@ -163,7 +176,7 @@ impl<'d> Display<'d> {
|
||||
.build()
|
||||
.await?;
|
||||
|
||||
Self::new(&conn, Option::<String>::None).await
|
||||
Self::new(&conn, Option::<String>::None, pid).await
|
||||
}
|
||||
|
||||
pub async fn receive_owner_changed(&self) -> Result<OwnerChangedStream<'_>> {
|
||||
@ -179,7 +192,14 @@ impl<'d> Display<'d> {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
Ok(Some(Audio::new(&self.inner.conn).await?))
|
||||
Ok(Some(
|
||||
Audio::new(
|
||||
&self.inner.conn,
|
||||
#[cfg(windows)]
|
||||
self.peer_pid(),
|
||||
)
|
||||
.await?,
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn clipboard(&self) -> Result<Option<Clipboard>> {
|
||||
|
@ -18,7 +18,7 @@ use windows::Win32::Networking::WinSock::SOCKET;
|
||||
#[cfg(windows)]
|
||||
use windows::Win32::System::Threading::PROCESS_DUP_HANDLE;
|
||||
|
||||
pub fn prepare_uds_pass(#[cfg(windows)] conn: &zbus::Connection, us: &UnixStream) -> Result<Fd> {
|
||||
pub fn prepare_uds_pass(#[cfg(windows)] peer_pid: u32, us: &UnixStream) -> Result<Fd> {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
Ok(us.as_raw_fd().into())
|
||||
@ -26,9 +26,7 @@ pub fn prepare_uds_pass(#[cfg(windows)] conn: &zbus::Connection, us: &UnixStream
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
// FIXME: we should use GetConnectionCredentials to work with a bus
|
||||
let pid = conn.peer_pid()?.unwrap();
|
||||
let p = win32::ProcessHandle::open(Some(pid as _), PROCESS_DUP_HANDLE)?;
|
||||
let p = win32::ProcessHandle::open(Some(peer_pid as _), PROCESS_DUP_HANDLE)?;
|
||||
p.duplicate_socket(SOCKET(us.as_raw_socket() as _))
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,9 @@ impl ProcessHandle {
|
||||
process_id: Option<u32>,
|
||||
desired_access: PROCESS_ACCESS_RIGHTS,
|
||||
) -> Result<Self, io::Error> {
|
||||
use windows::Win32::System::Threading::{GetCurrentProcess, OpenProcess, PROCESS_QUERY_INFORMATION};
|
||||
use windows::Win32::System::Threading::{
|
||||
GetCurrentProcess, OpenProcess, PROCESS_QUERY_INFORMATION,
|
||||
};
|
||||
|
||||
let process = if let Some(process_id) = process_id {
|
||||
let desired_access = desired_access | PROCESS_QUERY_INFORMATION;
|
||||
@ -51,11 +53,11 @@ impl ProcessHandle {
|
||||
}
|
||||
|
||||
pub fn process_id(&self) -> crate::Result<u32> {
|
||||
use windows::Win32::System::Threading::GetProcessId;
|
||||
use windows::Win32::Foundation::GetLastError;
|
||||
use windows::Win32::System::Threading::GetProcessId;
|
||||
|
||||
unsafe {
|
||||
let pid = GetProcessId(self.0);
|
||||
let pid = GetProcessId(self.0);
|
||||
if pid == 0 {
|
||||
Err(io::Error::from_raw_os_error(GetLastError().0 as _).into())
|
||||
} else {
|
||||
|
@ -73,7 +73,16 @@ async fn display_from_opt(opt: Arc<RefCell<AppOptions>>) -> Option<Display<'stat
|
||||
Display::lookup(&conn, wait, name.as_deref()).await.unwrap()
|
||||
};
|
||||
|
||||
Some(Display::new(&conn, dest).await.unwrap())
|
||||
Some(
|
||||
Display::new(
|
||||
&conn,
|
||||
dest,
|
||||
#[cfg(windows)]
|
||||
unimplemented!(),
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
impl App {
|
||||
@ -195,9 +204,14 @@ impl App {
|
||||
}
|
||||
});
|
||||
|
||||
let console = Console::new(display.connection(), 0)
|
||||
.await
|
||||
.expect("Failed to get the QEMU console");
|
||||
let console = Console::new(
|
||||
display.connection(),
|
||||
0,
|
||||
#[cfg(windows)]
|
||||
display.peer_pid(),
|
||||
)
|
||||
.await
|
||||
.expect("Failed to get the QEMU console");
|
||||
let rdw = display::Display::new(console);
|
||||
app_clone
|
||||
.inner
|
||||
@ -237,7 +251,7 @@ impl App {
|
||||
let (p0, p1) = UnixStream::pair().unwrap();
|
||||
let fd = util::prepare_uds_pass(
|
||||
#[cfg(windows)]
|
||||
c.proxy.inner().connection(),
|
||||
display.peer_pid(),
|
||||
&p1,
|
||||
)
|
||||
.unwrap();
|
||||
|
Loading…
Reference in New Issue
Block a user