mirror of
https://github.com/htrefil/rkvm.git
synced 2024-12-26 09:58:32 +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
|
||||
- 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
|
||||
- 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
|
||||
- `server` - server application code
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::time::{Duration, Instant};
|
|||
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
|
||||
use tokio::sync::oneshot::{self, Receiver};
|
||||
use tokio::time;
|
||||
use winapi::um::winuser::{self, INPUT};
|
||||
use winapi::um::winuser::{self, DESKTOP_JOURNALPLAYBACK, INPUT};
|
||||
|
||||
pub struct EventWriter {
|
||||
event_sender: UnboundedSender<Event>,
|
||||
|
@ -98,8 +98,40 @@ fn write_raw(events: &mut [INPUT]) -> Result<(), Error> {
|
|||
)
|
||||
};
|
||||
|
||||
if written != 1 {
|
||||
return Err(Error::last_os_error());
|
||||
if written == 0 {
|
||||
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(())
|
||||
|
|
Loading…
Reference in a new issue