mirror of
https://github.com/htrefil/rkvm.git
synced 2024-12-27 09:58:13 +01:00
Merge pull request #21 from h4ssi/switch-to-uac-desktop-and-retry-send-input
Retry `SendInput` after switching desktops upon initial failure
This commit is contained in:
commit
2d45ae6e5a
2 changed files with 36 additions and 3 deletions
|
@ -86,6 +86,7 @@ Regardless, if you want a working and stable solution for crossplatform keyboard
|
||||||
## Limitations
|
## Limitations
|
||||||
- Only keyboard and relative mouse events work (that is, can be forwarded to clients)
|
- Only keyboard and relative mouse events work (that is, can be forwarded to clients)
|
||||||
- Clients only are supported on Windows, however, server support will be added in the future
|
- Clients only are supported on Windows, however, server support will be added in the future
|
||||||
|
- When Windows UAC is active the client needs elevated privileges to function properly. You may need to run the client in the System account (e.g. `psexec -sid client ...`)
|
||||||
|
|
||||||
## Project structure
|
## Project structure
|
||||||
- `server` - server application code
|
- `server` - server application code
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::time::{Duration, Instant};
|
||||||
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
|
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
|
||||||
use tokio::sync::oneshot::{self, Receiver};
|
use tokio::sync::oneshot::{self, Receiver};
|
||||||
use tokio::time;
|
use tokio::time;
|
||||||
use winapi::um::winuser::{self, INPUT};
|
use winapi::um::winuser::{self, DESKTOP_JOURNALPLAYBACK, INPUT};
|
||||||
|
|
||||||
pub struct EventWriter {
|
pub struct EventWriter {
|
||||||
event_sender: UnboundedSender<Event>,
|
event_sender: UnboundedSender<Event>,
|
||||||
|
@ -98,8 +98,40 @@ fn write_raw(events: &mut [INPUT]) -> Result<(), Error> {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
if written != 1 {
|
if written == 0 {
|
||||||
return Err(Error::last_os_error());
|
let original = unsafe {
|
||||||
|
winuser::GetThreadDesktop(winapi::um::processthreadsapi::GetCurrentThreadId())
|
||||||
|
};
|
||||||
|
if original.is_null() {
|
||||||
|
return Err(Error::last_os_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
let other =
|
||||||
|
unsafe { winuser::OpenInputDesktop(0 as _, 0 as _, DESKTOP_JOURNALPLAYBACK as _) };
|
||||||
|
if other.is_null() {
|
||||||
|
return Err(Error::last_os_error());
|
||||||
|
}
|
||||||
|
if unsafe { winuser::SetThreadDesktop(other) } == 0 {
|
||||||
|
return Err(Error::last_os_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
let written = unsafe {
|
||||||
|
winuser::SendInput(
|
||||||
|
events.len() as _,
|
||||||
|
events.as_mut_ptr(),
|
||||||
|
std::mem::size_of_val(&events[0]) as _,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
if written == 0 {
|
||||||
|
return Err(Error::last_os_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
if unsafe { winuser::SetThreadDesktop(original) } == 0 {
|
||||||
|
return Err(Error::last_os_error());
|
||||||
|
}
|
||||||
|
if unsafe { winuser::CloseDesktop(other) } == 0 {
|
||||||
|
return Err(Error::last_os_error());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in a new issue