mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
try fix clipboard, flutter version
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
@@ -191,8 +191,6 @@ extern "C"
|
||||
typedef UINT (*pcCliprdrServerFileContentsResponse)(
|
||||
CliprdrClientContext *context, const CLIPRDR_FILE_CONTENTS_RESPONSE *fileContentsResponse);
|
||||
|
||||
typedef BOOL (*pcCheckEnabled)(UINT32 connID);
|
||||
|
||||
// TODO: hide more members of clipboard context
|
||||
struct _cliprdr_client_context
|
||||
{
|
||||
@@ -200,7 +198,6 @@ extern "C"
|
||||
BOOL enableFiles;
|
||||
BOOL enableOthers;
|
||||
|
||||
pcCheckEnabled CheckEnabled;
|
||||
pcCliprdrServerCapabilities ServerCapabilities;
|
||||
pcCliprdrClientCapabilities ClientCapabilities;
|
||||
pcCliprdrMonitorReady MonitorReady;
|
||||
|
||||
@@ -444,9 +444,6 @@ pub type pcCliprdrServerFileContentsResponse = ::std::option::Option<
|
||||
fileContentsResponse: *const CLIPRDR_FILE_CONTENTS_RESPONSE,
|
||||
) -> UINT,
|
||||
>;
|
||||
pub type pcCheckEnabled = ::std::option::Option<
|
||||
unsafe extern "C" fn(connID: UINT32) -> BOOL,
|
||||
>;
|
||||
|
||||
// TODO: hide more members of clipboard context
|
||||
#[repr(C)]
|
||||
@@ -455,7 +452,6 @@ pub struct _cliprdr_client_context {
|
||||
pub custom: *mut ::std::os::raw::c_void,
|
||||
pub enableFiles: BOOL,
|
||||
pub enableOthers: BOOL,
|
||||
pub CheckEnabled: pcCheckEnabled,
|
||||
pub ServerCapabilities: pcCliprdrServerCapabilities,
|
||||
pub ClientCapabilities: pcCliprdrClientCapabilities,
|
||||
pub MonitorReady: pcCliprdrMonitorReady,
|
||||
@@ -504,7 +500,6 @@ impl CliprdrClientContext {
|
||||
pub fn create(
|
||||
enable_files: bool,
|
||||
enable_others: bool,
|
||||
check_enabled: pcCheckEnabled,
|
||||
client_format_list: pcCliprdrClientFormatList,
|
||||
client_format_list_response: pcCliprdrClientFormatListResponse,
|
||||
client_format_data_request: pcCliprdrClientFormatDataRequest,
|
||||
@@ -516,7 +511,6 @@ impl CliprdrClientContext {
|
||||
custom: 0 as *mut _,
|
||||
enableFiles: if enable_files { TRUE } else { FALSE },
|
||||
enableOthers: if enable_others { TRUE } else { FALSE },
|
||||
CheckEnabled: check_enabled,
|
||||
ServerCapabilities: None,
|
||||
ClientCapabilities: None,
|
||||
MonitorReady: None,
|
||||
|
||||
@@ -1,28 +1,36 @@
|
||||
use crate::cliprdr::*;
|
||||
use hbb_common::log;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref CONTEXT_SEND: ContextSend = ContextSend{addr: Mutex::new(0)};
|
||||
static ref CONTEXT_SEND: Arc<Mutex<ContextSend>> = Arc::new(Mutex::new(ContextSend::new()));
|
||||
}
|
||||
|
||||
pub struct ContextSend {
|
||||
addr: Mutex<u64>,
|
||||
server_enabled: bool,
|
||||
addr: u64,
|
||||
}
|
||||
|
||||
impl ContextSend {
|
||||
pub fn is_enabled() -> bool {
|
||||
*CONTEXT_SEND.addr.lock().unwrap() != 0
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
server_enabled: false,
|
||||
addr: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enable(enabled: bool) {
|
||||
let mut lock = CONTEXT_SEND.addr.lock().unwrap();
|
||||
pub fn is_server_enabled() -> bool {
|
||||
CONTEXT_SEND.lock().unwrap().server_enabled
|
||||
}
|
||||
|
||||
pub fn enable(enabled: bool, is_server_side: bool, is_server_process: bool) {
|
||||
let mut lock = CONTEXT_SEND.lock().unwrap();
|
||||
if enabled {
|
||||
if *lock == 0 {
|
||||
match crate::create_cliprdr_context(true, false, crate::ProcessSide::ClientSide) {
|
||||
if lock.addr == 0 {
|
||||
match crate::create_cliprdr_context(true, false) {
|
||||
Ok(context) => {
|
||||
log::info!("clipboard context for file transfer created.");
|
||||
*lock = Box::into_raw(context) as _;
|
||||
lock.addr = Box::into_raw(context) as _;
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!(
|
||||
@@ -32,25 +40,29 @@ impl ContextSend {
|
||||
}
|
||||
}
|
||||
}
|
||||
if is_server_side {
|
||||
lock.server_enabled = true;
|
||||
}
|
||||
} else {
|
||||
if *lock != 0 {
|
||||
unsafe {
|
||||
let _ = Box::from_raw(*lock as *mut CliprdrClientContext);
|
||||
if lock.addr != 0 {
|
||||
if is_server_process {
|
||||
unsafe {
|
||||
let _ = Box::from_raw(lock.addr as *mut CliprdrClientContext);
|
||||
}
|
||||
log::info!("clipboard context for file transfer destroyed.");
|
||||
lock.addr = 0;
|
||||
}
|
||||
log::info!("clipboard context for file transfer destroyed.");
|
||||
*lock = 0;
|
||||
lock.server_enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn proc<F: FnOnce(&mut Box<CliprdrClientContext>) -> u32>(f: F) -> u32 {
|
||||
let mut lock = CONTEXT_SEND.addr.lock().unwrap();
|
||||
if *lock != 0 {
|
||||
let lock = CONTEXT_SEND.lock().unwrap();
|
||||
if lock.addr != 0 {
|
||||
unsafe {
|
||||
let mut context = Box::from_raw(*lock as *mut CliprdrClientContext);
|
||||
let res = f(&mut context);
|
||||
*lock = Box::into_raw(context) as _;
|
||||
res
|
||||
let mut context = Box::from_raw(lock.addr as *mut CliprdrClientContext);
|
||||
f(&mut context)
|
||||
}
|
||||
} else {
|
||||
0
|
||||
|
||||
@@ -10,7 +10,6 @@ use hbb_common::{
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::{
|
||||
boxed::Box,
|
||||
collections::HashMap,
|
||||
ffi::{CStr, CString},
|
||||
sync::{Arc, Mutex, RwLock},
|
||||
};
|
||||
@@ -53,11 +52,6 @@ pub enum ClipboardFile {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ConnEnabled {
|
||||
conn_enabled: HashMap<i32, bool>,
|
||||
}
|
||||
|
||||
struct MsgChannel {
|
||||
session_uuid: SessionID,
|
||||
conn_id: i32,
|
||||
@@ -65,17 +59,20 @@ struct MsgChannel {
|
||||
receiver: Arc<TokioMutex<UnboundedReceiver<ClipboardFile>>>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum ProcessSide {
|
||||
UnknownSide,
|
||||
ClientSide,
|
||||
ServerSide,
|
||||
}
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref VEC_MSG_CHANNEL: RwLock<Vec<MsgChannel>> = Default::default();
|
||||
static ref CLIP_CONN_ENABLED: Mutex<ConnEnabled> = Mutex::new(ConnEnabled::default());
|
||||
static ref PROCESS_SIDE: RwLock<ProcessSide> = RwLock::new(ProcessSide::UnknownSide);
|
||||
static ref CLIENT_CONN_ID_COUNTER: Mutex<i32> = Mutex::new(0);
|
||||
}
|
||||
|
||||
impl ClipboardFile {
|
||||
pub fn is_stopping_allowed(&self) -> bool {
|
||||
match self {
|
||||
ClipboardFile::MonitorReady
|
||||
| ClipboardFile::FormatList { .. }
|
||||
| ClipboardFile::FormatDataRequest { .. } => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_client_conn_id(session_uuid: &SessionID) -> Option<i32> {
|
||||
@@ -87,6 +84,12 @@ pub fn get_client_conn_id(session_uuid: &SessionID) -> Option<i32> {
|
||||
.map(|x| x.conn_id)
|
||||
}
|
||||
|
||||
fn get_conn_id() -> i32 {
|
||||
let mut lock = CLIENT_CONN_ID_COUNTER.lock().unwrap();
|
||||
*lock += 1;
|
||||
*lock
|
||||
}
|
||||
|
||||
pub fn get_rx_cliprdr_client(
|
||||
session_uuid: &SessionID,
|
||||
) -> (i32, Arc<TokioMutex<UnboundedReceiver<ClipboardFile>>>) {
|
||||
@@ -100,7 +103,7 @@ pub fn get_rx_cliprdr_client(
|
||||
let (sender, receiver) = unbounded_channel();
|
||||
let receiver = Arc::new(TokioMutex::new(receiver));
|
||||
let receiver2 = receiver.clone();
|
||||
let conn_id = lock.len() as i32 + 1;
|
||||
let conn_id = get_conn_id();
|
||||
let msg_channel = MsgChannel {
|
||||
session_uuid: session_uuid.to_owned(),
|
||||
conn_id,
|
||||
@@ -146,13 +149,6 @@ fn send_data(conn_id: i32, data: ClipboardFile) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_conn_enabled(conn_id: i32, enabled: bool) {
|
||||
let mut lock = CLIP_CONN_ENABLED.lock().unwrap();
|
||||
if conn_id != 0 {
|
||||
let _ = lock.conn_enabled.insert(conn_id, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty_clipboard(context: &mut Box<CliprdrClientContext>, conn_id: i32) -> bool {
|
||||
unsafe { TRUE == cliprdr::empty_cliprdr(&mut (**context), conn_id as u32) }
|
||||
}
|
||||
@@ -430,14 +426,10 @@ pub fn server_file_contents_response(
|
||||
pub fn create_cliprdr_context(
|
||||
enable_files: bool,
|
||||
enable_others: bool,
|
||||
process_side: ProcessSide,
|
||||
) -> ResultType<Box<CliprdrClientContext>> {
|
||||
*PROCESS_SIDE.write().unwrap() = process_side;
|
||||
|
||||
Ok(CliprdrClientContext::create(
|
||||
enable_files,
|
||||
enable_others,
|
||||
Some(check_enabled),
|
||||
Some(client_format_list),
|
||||
Some(client_format_list_response),
|
||||
Some(client_format_data_request),
|
||||
@@ -447,24 +439,6 @@ pub fn create_cliprdr_context(
|
||||
)?)
|
||||
}
|
||||
|
||||
extern "C" fn check_enabled(conn_id: UINT32) -> BOOL {
|
||||
if *PROCESS_SIDE.read().unwrap() == ProcessSide::ClientSide {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
let lock = CLIP_CONN_ENABLED.lock().unwrap();
|
||||
let mut connd_enabled = false;
|
||||
if conn_id != 0 {
|
||||
if let Some(true) = lock.conn_enabled.get(&(conn_id as i32)) {
|
||||
connd_enabled = true;
|
||||
}
|
||||
} else {
|
||||
connd_enabled = true;
|
||||
}
|
||||
|
||||
return if connd_enabled { TRUE } else { FALSE };
|
||||
}
|
||||
|
||||
extern "C" fn client_format_list(
|
||||
_context: *mut CliprdrClientContext,
|
||||
clip_format_list: *const CLIPRDR_FORMAT_LIST,
|
||||
|
||||
@@ -681,10 +681,6 @@ static HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetData(IDataObject *This, FO
|
||||
}
|
||||
|
||||
clipboard = (wfClipboard *)instance->m_pData;
|
||||
if (!clipboard->context->CheckEnabled(instance->m_connID))
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (!clipboard)
|
||||
return E_INVALIDARG;
|
||||
@@ -1470,14 +1466,7 @@ static UINT cliprdr_send_data_request(UINT32 connID, wfClipboard *clipboard, UIN
|
||||
DWORD waitRes = WaitForSingleObject(clipboard->response_data_event, 50);
|
||||
if (waitRes == WAIT_TIMEOUT)
|
||||
{
|
||||
if (clipboard->context->CheckEnabled(connID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (waitRes != WAIT_OBJECT_0)
|
||||
@@ -1542,14 +1531,7 @@ UINT cliprdr_send_request_filecontents(wfClipboard *clipboard, UINT32 connID, co
|
||||
DWORD waitRes = WaitForSingleObject(clipboard->req_fevent, 50);
|
||||
if (waitRes == WAIT_TIMEOUT)
|
||||
{
|
||||
if (clipboard->context->CheckEnabled(connID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (waitRes != WAIT_OBJECT_0)
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::{
|
||||
collections::HashMap,
|
||||
fs,
|
||||
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
||||
ops::{Deref, DerefMut},
|
||||
path::{Path, PathBuf},
|
||||
sync::{Arc, Mutex, RwLock},
|
||||
time::{Duration, Instant, SystemTime},
|
||||
@@ -132,6 +133,18 @@ macro_rules! serde_field_bool {
|
||||
UserDefaultConfig::read().get($field_name) == "Y"
|
||||
}
|
||||
}
|
||||
impl Deref for $struct_name {
|
||||
type Target = bool;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.v
|
||||
}
|
||||
}
|
||||
impl DerefMut for $struct_name {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.v
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user