Add basic windows support

This commit is contained in:
Marc-André Lureau 2022-10-20 12:10:10 +04:00
parent 817d44e17a
commit 91a8549b70
6 changed files with 62 additions and 20 deletions

View File

@ -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?;

View File

@ -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?;

View File

@ -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>> {

View File

@ -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 _))
}
}

View File

@ -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 {

View File

@ -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();