mirror of
https://github.com/rustdesk/qemu-display.git
synced 2025-07-01 15:25:29 +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"
|
cfg-if = "1.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
derivative = "2.2.0"
|
derivative = "2.2.0"
|
||||||
zbus = { version = "3.0", features = ["xml"] }
|
zbus = { version = "3.2", features = ["xml"] }
|
||||||
zvariant = { version = "3.0", features = ["serde_bytes"] }
|
zvariant = { version = "3.0", features = ["serde_bytes"] }
|
||||||
libc = "0.2.86"
|
libc = "0.2.86"
|
||||||
enumflags2 = { version = "0.7", features = ["serde"] }
|
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<()> {
|
pub async fn register_out_listener<H: AudioOutHandler>(&mut self, handler: H) -> Result<()> {
|
||||||
let (p0, p1) = UnixStream::pair()?;
|
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?;
|
self.proxy.register_out_listener(p0).await?;
|
||||||
let c = zbus::ConnectionBuilder::unix_stream(p1)
|
let c = zbus::ConnectionBuilder::unix_stream(p1)
|
||||||
.p2p()
|
.p2p()
|
||||||
@ -260,7 +264,11 @@ impl Audio {
|
|||||||
|
|
||||||
pub async fn register_in_listener<H: AudioInHandler>(&mut self, handler: H) -> Result<()> {
|
pub async fn register_in_listener<H: AudioInHandler>(&mut self, handler: H) -> Result<()> {
|
||||||
let (p0, p1) = UnixStream::pair()?;
|
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?;
|
self.proxy.register_in_listener(p0).await?;
|
||||||
let c = zbus::ConnectionBuilder::unix_stream(p1)
|
let c = zbus::ConnectionBuilder::unix_stream(p1)
|
||||||
.p2p()
|
.p2p()
|
||||||
|
@ -87,7 +87,11 @@ impl Console {
|
|||||||
|
|
||||||
pub async fn register_listener<H: ConsoleListenerHandler>(&self, handler: H) -> Result<()> {
|
pub async fn register_listener<H: ConsoleListenerHandler>(&self, handler: H) -> Result<()> {
|
||||||
let (p0, p1) = UnixStream::pair()?;
|
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?;
|
self.proxy.register_listener(p0).await?;
|
||||||
let c = zbus::ConnectionBuilder::unix_stream(p1)
|
let c = zbus::ConnectionBuilder::unix_stream(p1)
|
||||||
.p2p()
|
.p2p()
|
||||||
|
@ -14,11 +14,11 @@ use std::os::windows::io::AsRawSocket;
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use uds_windows::UnixStream;
|
use uds_windows::UnixStream;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use windows::Win32::Networking::WinSock::{WSADuplicateSocketW, SOCKET, WSAPROTOCOL_INFOW};
|
use windows::Win32::Networking::WinSock::SOCKET;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use windows::Win32::System::Threading::PROCESS_DUP_HANDLE;
|
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)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
Ok(us.as_raw_fd().into())
|
Ok(us.as_raw_fd().into())
|
||||||
@ -26,21 +26,9 @@ pub fn prepare_uds_pass(us: &UnixStream) -> Result<Fd> {
|
|||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
let pid = win32::unix_stream_get_peer_pid(us)?;
|
// FIXME: we should use GetConnectionCredentials to work with a bus
|
||||||
let p = win32::ProcessHandle::open(Some(pid), PROCESS_DUP_HANDLE)?;
|
let pid = conn.peer_pid()?.unwrap();
|
||||||
let mut info = unsafe { std::mem::zeroed() };
|
let p = win32::ProcessHandle::open(Some(pid as _), PROCESS_DUP_HANDLE)?;
|
||||||
if unsafe {
|
p.duplicate_socket(SOCKET(us.as_raw_socket() as _))
|
||||||
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())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
use uds_windows::UnixStream;
|
|
||||||
use windows::Win32::Foundation::{CloseHandle, HANDLE};
|
use windows::Win32::Foundation::{CloseHandle, HANDLE};
|
||||||
|
use windows::Win32::Networking::WinSock::{WSADuplicateSocketW, SOCKET, WSAPROTOCOL_INFOW};
|
||||||
use windows::Win32::System::Threading::PROCESS_ACCESS_RIGHTS;
|
use windows::Win32::System::Threading::PROCESS_ACCESS_RIGHTS;
|
||||||
|
|
||||||
pub type Fd = Vec<u8>;
|
pub type Fd = Vec<u8>;
|
||||||
@ -36,6 +36,20 @@ impl ProcessHandle {
|
|||||||
|
|
||||||
unsafe { GetProcessId(self.0) }
|
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 {
|
pub(crate) fn wsa_last_err() -> io::Error {
|
||||||
@ -44,42 +58,3 @@ pub(crate) fn wsa_last_err() -> io::Error {
|
|||||||
let err = unsafe { WSAGetLastError() };
|
let err = unsafe { WSAGetLastError() };
|
||||||
io::Error::from_raw_os_error(err.0)
|
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;
|
use uds_windows::UnixStream;
|
||||||
|
|
||||||
let (p0, p1) = UnixStream::pair().unwrap();
|
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() {
|
if c.proxy.register(fd).await.is_ok() {
|
||||||
let mut reader = BufReader::new(p0.try_clone().unwrap());
|
let mut reader = BufReader::new(p0.try_clone().unwrap());
|
||||||
let mut line = String::new();
|
let mut line = String::new();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user