mirror of
https://gitlab.com/marcandre.lureau/qemu-display.git
synced 2025-04-14 08:44:46 +00:00
qemu-display: pass sockets with win32
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
parent
5b428adace
commit
2ed1174df6
@ -10,7 +10,7 @@ edition = "2018"
|
||||
cfg-if = "1.0"
|
||||
log = "0.4"
|
||||
derivative = "2.2.0"
|
||||
zbus = { version = "3.0", features = ["xml"] }
|
||||
zbus = { version = "3.2", features = ["xml"] }
|
||||
zvariant = { version = "3.0", features = ["serde_bytes"] }
|
||||
libc = "0.2.86"
|
||||
enumflags2 = { version = "0.7", features = ["serde"] }
|
||||
|
@ -244,7 +244,11 @@ impl Audio {
|
||||
|
||||
pub async fn register_out_listener<H: AudioOutHandler>(&mut self, handler: H) -> Result<()> {
|
||||
let (p0, p1) = UnixStream::pair()?;
|
||||
let p0 = util::prepare_uds_pass(&p0)?;
|
||||
let p0 = util::prepare_uds_pass(
|
||||
#[cfg(windows)]
|
||||
self.proxy.inner().connection(),
|
||||
&p0,
|
||||
)?;
|
||||
self.proxy.register_out_listener(p0).await?;
|
||||
let c = zbus::ConnectionBuilder::unix_stream(p1)
|
||||
.p2p()
|
||||
@ -260,7 +264,11 @@ impl Audio {
|
||||
|
||||
pub async fn register_in_listener<H: AudioInHandler>(&mut self, handler: H) -> Result<()> {
|
||||
let (p0, p1) = UnixStream::pair()?;
|
||||
let p0 = util::prepare_uds_pass(&p0)?;
|
||||
let p0 = util::prepare_uds_pass(
|
||||
#[cfg(windows)]
|
||||
self.proxy.inner().connection(),
|
||||
&p0,
|
||||
)?;
|
||||
self.proxy.register_in_listener(p0).await?;
|
||||
let c = zbus::ConnectionBuilder::unix_stream(p1)
|
||||
.p2p()
|
||||
|
@ -87,7 +87,11 @@ impl Console {
|
||||
|
||||
pub async fn register_listener<H: ConsoleListenerHandler>(&self, handler: H) -> Result<()> {
|
||||
let (p0, p1) = UnixStream::pair()?;
|
||||
let p0 = util::prepare_uds_pass(&p0)?;
|
||||
let p0 = util::prepare_uds_pass(
|
||||
#[cfg(windows)]
|
||||
self.proxy.inner().connection(),
|
||||
&p0,
|
||||
)?;
|
||||
self.proxy.register_listener(p0).await?;
|
||||
let c = zbus::ConnectionBuilder::unix_stream(p1)
|
||||
.p2p()
|
||||
|
@ -14,11 +14,11 @@ use std::os::windows::io::AsRawSocket;
|
||||
#[cfg(windows)]
|
||||
use uds_windows::UnixStream;
|
||||
#[cfg(windows)]
|
||||
use windows::Win32::Networking::WinSock::{WSADuplicateSocketW, SOCKET, WSAPROTOCOL_INFOW};
|
||||
use windows::Win32::Networking::WinSock::SOCKET;
|
||||
#[cfg(windows)]
|
||||
use windows::Win32::System::Threading::PROCESS_DUP_HANDLE;
|
||||
|
||||
pub fn prepare_uds_pass(us: &UnixStream) -> Result<Fd> {
|
||||
pub fn prepare_uds_pass(#[cfg(windows)] conn: &zbus::Connection, us: &UnixStream) -> Result<Fd> {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
Ok(us.as_raw_fd().into())
|
||||
@ -26,21 +26,9 @@ pub fn prepare_uds_pass(us: &UnixStream) -> Result<Fd> {
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let pid = win32::unix_stream_get_peer_pid(us)?;
|
||||
let p = win32::ProcessHandle::open(Some(pid), PROCESS_DUP_HANDLE)?;
|
||||
let mut info = unsafe { std::mem::zeroed() };
|
||||
if unsafe {
|
||||
WSADuplicateSocketW(SOCKET(us.as_raw_socket() as _), p.process_id(), &mut info)
|
||||
} != 0
|
||||
{
|
||||
return Err(crate::Error::Io(win32::wsa_last_err()));
|
||||
}
|
||||
let info = unsafe {
|
||||
std::slice::from_raw_parts(
|
||||
&info as *const _ as *const u8,
|
||||
std::mem::size_of::<WSAPROTOCOL_INFOW>(),
|
||||
)
|
||||
};
|
||||
Ok(info.to_vec())
|
||||
// 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)?;
|
||||
p.duplicate_socket(SOCKET(us.as_raw_socket() as _))
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::io;
|
||||
use uds_windows::UnixStream;
|
||||
use windows::Win32::Foundation::{CloseHandle, HANDLE};
|
||||
use windows::Win32::Networking::WinSock::{WSADuplicateSocketW, SOCKET, WSAPROTOCOL_INFOW};
|
||||
use windows::Win32::System::Threading::PROCESS_ACCESS_RIGHTS;
|
||||
|
||||
pub type Fd = Vec<u8>;
|
||||
@ -36,6 +36,20 @@ impl ProcessHandle {
|
||||
|
||||
unsafe { GetProcessId(self.0) }
|
||||
}
|
||||
|
||||
pub fn duplicate_socket(&self, sock: SOCKET) -> crate::Result<Fd> {
|
||||
let mut info = unsafe { std::mem::zeroed() };
|
||||
if unsafe { WSADuplicateSocketW(sock, self.process_id(), &mut info) } != 0 {
|
||||
return Err(crate::Error::Io(wsa_last_err()));
|
||||
}
|
||||
let info = unsafe {
|
||||
std::slice::from_raw_parts(
|
||||
&info as *const _ as *const u8,
|
||||
std::mem::size_of::<WSAPROTOCOL_INFOW>(),
|
||||
)
|
||||
};
|
||||
Ok(info.to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn wsa_last_err() -> io::Error {
|
||||
@ -44,42 +58,3 @@ pub(crate) fn wsa_last_err() -> io::Error {
|
||||
let err = unsafe { WSAGetLastError() };
|
||||
io::Error::from_raw_os_error(err.0)
|
||||
}
|
||||
|
||||
// Get the process ID of the connected peer
|
||||
pub fn unix_stream_get_peer_pid(stream: &UnixStream) -> Result<u32, io::Error> {
|
||||
use std::os::windows::io::AsRawSocket;
|
||||
use windows::Win32::Networking::WinSock::{
|
||||
WSAIoctl, IOC_OUT, IOC_VENDOR, SOCKET, SOCKET_ERROR,
|
||||
};
|
||||
|
||||
macro_rules! _WSAIOR {
|
||||
($x:expr, $y:expr) => {
|
||||
IOC_OUT | $x | $y
|
||||
};
|
||||
}
|
||||
|
||||
let socket = stream.as_raw_socket();
|
||||
const SIO_AF_UNIX_GETPEERPID: u32 = _WSAIOR!(IOC_VENDOR, 256);
|
||||
let mut ret = 0 as u32;
|
||||
let mut bytes = 0;
|
||||
|
||||
let r = unsafe {
|
||||
WSAIoctl(
|
||||
SOCKET(socket as _),
|
||||
SIO_AF_UNIX_GETPEERPID,
|
||||
0 as *mut _,
|
||||
0,
|
||||
&mut ret as *mut _ as *mut _,
|
||||
std::mem::size_of_val(&ret) as u32,
|
||||
&mut bytes,
|
||||
0 as *mut _,
|
||||
None,
|
||||
)
|
||||
};
|
||||
|
||||
if r == SOCKET_ERROR {
|
||||
return Err(wsa_last_err());
|
||||
}
|
||||
|
||||
Ok(ret)
|
||||
}
|
||||
|
@ -208,7 +208,12 @@ impl App {
|
||||
use uds_windows::UnixStream;
|
||||
|
||||
let (p0, p1) = UnixStream::pair().unwrap();
|
||||
let fd = util::prepare_uds_pass(&p1).unwrap();
|
||||
let fd = util::prepare_uds_pass(
|
||||
#[cfg(windows)]
|
||||
c.proxy.inner().connection(),
|
||||
&p1,
|
||||
)
|
||||
.unwrap();
|
||||
if c.proxy.register(fd).await.is_ok() {
|
||||
let mut reader = BufReader::new(p0.try_clone().unwrap());
|
||||
let mut line = String::new();
|
||||
|
Loading…
x
Reference in New Issue
Block a user