mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
Merge pull request #4700 from fufesou/fix/clipboard_flutter
Fix/clipboard flutter
This commit is contained in:
commit
dfa3db42ec
@ -191,16 +191,14 @@ extern "C"
|
|||||||
typedef UINT (*pcCliprdrServerFileContentsResponse)(
|
typedef UINT (*pcCliprdrServerFileContentsResponse)(
|
||||||
CliprdrClientContext *context, const CLIPRDR_FILE_CONTENTS_RESPONSE *fileContentsResponse);
|
CliprdrClientContext *context, const CLIPRDR_FILE_CONTENTS_RESPONSE *fileContentsResponse);
|
||||||
|
|
||||||
typedef BOOL (*pcCheckEnabled)(UINT32 connID);
|
|
||||||
|
|
||||||
// TODO: hide more members of clipboard context
|
// TODO: hide more members of clipboard context
|
||||||
struct _cliprdr_client_context
|
struct _cliprdr_client_context
|
||||||
{
|
{
|
||||||
void *custom;
|
void *Custom;
|
||||||
BOOL enableFiles;
|
BOOL EnableFiles;
|
||||||
BOOL enableOthers;
|
BOOL EnableOthers;
|
||||||
|
|
||||||
pcCheckEnabled CheckEnabled;
|
BOOL IsStopped;
|
||||||
pcCliprdrServerCapabilities ServerCapabilities;
|
pcCliprdrServerCapabilities ServerCapabilities;
|
||||||
pcCliprdrClientCapabilities ClientCapabilities;
|
pcCliprdrClientCapabilities ClientCapabilities;
|
||||||
pcCliprdrMonitorReady MonitorReady;
|
pcCliprdrMonitorReady MonitorReady;
|
||||||
@ -222,7 +220,7 @@ extern "C"
|
|||||||
pcCliprdrClientFileContentsResponse ClientFileContentsResponse;
|
pcCliprdrClientFileContentsResponse ClientFileContentsResponse;
|
||||||
pcCliprdrServerFileContentsResponse ServerFileContentsResponse;
|
pcCliprdrServerFileContentsResponse ServerFileContentsResponse;
|
||||||
|
|
||||||
UINT32 lastRequestedFormatId;
|
UINT32 LastRequestedFormatId;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@ -444,18 +444,15 @@ pub type pcCliprdrServerFileContentsResponse = ::std::option::Option<
|
|||||||
fileContentsResponse: *const CLIPRDR_FILE_CONTENTS_RESPONSE,
|
fileContentsResponse: *const CLIPRDR_FILE_CONTENTS_RESPONSE,
|
||||||
) -> UINT,
|
) -> UINT,
|
||||||
>;
|
>;
|
||||||
pub type pcCheckEnabled = ::std::option::Option<
|
|
||||||
unsafe extern "C" fn(connID: UINT32) -> BOOL,
|
|
||||||
>;
|
|
||||||
|
|
||||||
// TODO: hide more members of clipboard context
|
// TODO: hide more members of clipboard context
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct _cliprdr_client_context {
|
pub struct _cliprdr_client_context {
|
||||||
pub custom: *mut ::std::os::raw::c_void,
|
pub Custom: *mut ::std::os::raw::c_void,
|
||||||
pub enableFiles: BOOL,
|
pub EnableFiles: BOOL,
|
||||||
pub enableOthers: BOOL,
|
pub EnableOthers: BOOL,
|
||||||
pub CheckEnabled: pcCheckEnabled,
|
pub IsStopped: BOOL,
|
||||||
pub ServerCapabilities: pcCliprdrServerCapabilities,
|
pub ServerCapabilities: pcCliprdrServerCapabilities,
|
||||||
pub ClientCapabilities: pcCliprdrClientCapabilities,
|
pub ClientCapabilities: pcCliprdrClientCapabilities,
|
||||||
pub MonitorReady: pcCliprdrMonitorReady,
|
pub MonitorReady: pcCliprdrMonitorReady,
|
||||||
@ -476,7 +473,7 @@ pub struct _cliprdr_client_context {
|
|||||||
pub ServerFileContentsRequest: pcCliprdrServerFileContentsRequest,
|
pub ServerFileContentsRequest: pcCliprdrServerFileContentsRequest,
|
||||||
pub ClientFileContentsResponse: pcCliprdrClientFileContentsResponse,
|
pub ClientFileContentsResponse: pcCliprdrClientFileContentsResponse,
|
||||||
pub ServerFileContentsResponse: pcCliprdrServerFileContentsResponse,
|
pub ServerFileContentsResponse: pcCliprdrServerFileContentsResponse,
|
||||||
pub lastRequestedFormatId: UINT32,
|
pub LastRequestedFormatId: UINT32,
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[link(name = "user32")]
|
// #[link(name = "user32")]
|
||||||
@ -484,10 +481,7 @@ pub struct _cliprdr_client_context {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
pub(crate) fn init_cliprdr(context: *mut CliprdrClientContext) -> BOOL;
|
pub(crate) fn init_cliprdr(context: *mut CliprdrClientContext) -> BOOL;
|
||||||
pub(crate) fn uninit_cliprdr(context: *mut CliprdrClientContext) -> BOOL;
|
pub(crate) fn uninit_cliprdr(context: *mut CliprdrClientContext) -> BOOL;
|
||||||
pub(crate) fn empty_cliprdr(
|
pub(crate) fn empty_cliprdr(context: *mut CliprdrClientContext, connID: UINT32) -> BOOL;
|
||||||
context: *mut CliprdrClientContext,
|
|
||||||
connID: UINT32,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
@ -504,7 +498,6 @@ impl CliprdrClientContext {
|
|||||||
pub fn create(
|
pub fn create(
|
||||||
enable_files: bool,
|
enable_files: bool,
|
||||||
enable_others: bool,
|
enable_others: bool,
|
||||||
check_enabled: pcCheckEnabled,
|
|
||||||
client_format_list: pcCliprdrClientFormatList,
|
client_format_list: pcCliprdrClientFormatList,
|
||||||
client_format_list_response: pcCliprdrClientFormatListResponse,
|
client_format_list_response: pcCliprdrClientFormatListResponse,
|
||||||
client_format_data_request: pcCliprdrClientFormatDataRequest,
|
client_format_data_request: pcCliprdrClientFormatDataRequest,
|
||||||
@ -513,10 +506,10 @@ impl CliprdrClientContext {
|
|||||||
client_file_contents_response: pcCliprdrClientFileContentsResponse,
|
client_file_contents_response: pcCliprdrClientFileContentsResponse,
|
||||||
) -> Result<Box<Self>, CliprdrError> {
|
) -> Result<Box<Self>, CliprdrError> {
|
||||||
let context = CliprdrClientContext {
|
let context = CliprdrClientContext {
|
||||||
custom: 0 as *mut _,
|
Custom: 0 as *mut _,
|
||||||
enableFiles: if enable_files { TRUE } else { FALSE },
|
EnableFiles: if enable_files { TRUE } else { FALSE },
|
||||||
enableOthers: if enable_others { TRUE } else { FALSE },
|
EnableOthers: if enable_others { TRUE } else { FALSE },
|
||||||
CheckEnabled: check_enabled,
|
IsStopped: FALSE,
|
||||||
ServerCapabilities: None,
|
ServerCapabilities: None,
|
||||||
ClientCapabilities: None,
|
ClientCapabilities: None,
|
||||||
MonitorReady: None,
|
MonitorReady: None,
|
||||||
@ -537,7 +530,7 @@ impl CliprdrClientContext {
|
|||||||
ServerFileContentsRequest: None,
|
ServerFileContentsRequest: None,
|
||||||
ClientFileContentsResponse: client_file_contents_response,
|
ClientFileContentsResponse: client_file_contents_response,
|
||||||
ServerFileContentsResponse: None,
|
ServerFileContentsResponse: None,
|
||||||
lastRequestedFormatId: 0,
|
LastRequestedFormatId: 0,
|
||||||
};
|
};
|
||||||
let mut context = Box::new(context);
|
let mut context = Box::new(context);
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|||||||
@ -11,15 +11,23 @@ pub struct ContextSend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ContextSend {
|
impl ContextSend {
|
||||||
|
#[inline]
|
||||||
pub fn is_enabled() -> bool {
|
pub fn is_enabled() -> bool {
|
||||||
*CONTEXT_SEND.addr.lock().unwrap() != 0
|
*CONTEXT_SEND.addr.lock().unwrap() != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_is_stopped() {
|
||||||
|
let _res = Self::proc(|c| {
|
||||||
|
c.IsStopped = TRUE;
|
||||||
|
0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn enable(enabled: bool) {
|
pub fn enable(enabled: bool) {
|
||||||
let mut lock = CONTEXT_SEND.addr.lock().unwrap();
|
let mut lock = CONTEXT_SEND.addr.lock().unwrap();
|
||||||
if enabled {
|
if enabled {
|
||||||
if *lock == 0 {
|
if *lock == 0 {
|
||||||
match crate::create_cliprdr_context(true, false, crate::ProcessSide::ClientSide) {
|
match crate::create_cliprdr_context(true, false) {
|
||||||
Ok(context) => {
|
Ok(context) => {
|
||||||
log::info!("clipboard context for file transfer created.");
|
log::info!("clipboard context for file transfer created.");
|
||||||
*lock = Box::into_raw(context) as _;
|
*lock = Box::into_raw(context) as _;
|
||||||
@ -44,13 +52,13 @@ impl ContextSend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn proc<F: FnOnce(&mut Box<CliprdrClientContext>) -> u32>(f: F) -> u32 {
|
pub fn proc<F: FnOnce(&mut Box<CliprdrClientContext>) -> u32>(f: F) -> u32 {
|
||||||
let mut lock = CONTEXT_SEND.addr.lock().unwrap();
|
let lock = CONTEXT_SEND.addr.lock().unwrap();
|
||||||
if *lock != 0 {
|
if *lock != 0 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut context = Box::from_raw(*lock as *mut CliprdrClientContext);
|
let mut context = Box::from_raw(*lock as *mut CliprdrClientContext);
|
||||||
let res = f(&mut context);
|
let code = f(&mut context);
|
||||||
*lock = Box::into_raw(context) as _;
|
std::mem::forget(context);
|
||||||
res
|
code
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
|
|||||||
@ -10,7 +10,6 @@ use hbb_common::{
|
|||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
collections::HashMap,
|
|
||||||
ffi::{CStr, CString},
|
ffi::{CStr, CString},
|
||||||
sync::{Arc, Mutex, RwLock},
|
sync::{Arc, Mutex, RwLock},
|
||||||
};
|
};
|
||||||
@ -19,6 +18,8 @@ pub mod cliprdr;
|
|||||||
pub mod context_send;
|
pub mod context_send;
|
||||||
pub use context_send::*;
|
pub use context_send::*;
|
||||||
|
|
||||||
|
const ERR_CODE_SERVER_FUNCTION_NONE: u32 = 0x00000001;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
#[serde(tag = "t", content = "c")]
|
#[serde(tag = "t", content = "c")]
|
||||||
pub enum ClipboardFile {
|
pub enum ClipboardFile {
|
||||||
@ -53,11 +54,6 @@ pub enum ClipboardFile {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
struct ConnEnabled {
|
|
||||||
conn_enabled: HashMap<i32, bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MsgChannel {
|
struct MsgChannel {
|
||||||
session_uuid: SessionID,
|
session_uuid: SessionID,
|
||||||
conn_id: i32,
|
conn_id: i32,
|
||||||
@ -65,17 +61,27 @@ struct MsgChannel {
|
|||||||
receiver: Arc<TokioMutex<UnboundedReceiver<ClipboardFile>>>,
|
receiver: Arc<TokioMutex<UnboundedReceiver<ClipboardFile>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
|
||||||
pub enum ProcessSide {
|
|
||||||
UnknownSide,
|
|
||||||
ClientSide,
|
|
||||||
ServerSide,
|
|
||||||
}
|
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
static ref VEC_MSG_CHANNEL: RwLock<Vec<MsgChannel>> = Default::default();
|
static ref VEC_MSG_CHANNEL: RwLock<Vec<MsgChannel>> = Default::default();
|
||||||
static ref CLIP_CONN_ENABLED: Mutex<ConnEnabled> = Mutex::new(ConnEnabled::default());
|
static ref CLIENT_CONN_ID_COUNTER: Mutex<i32> = Mutex::new(0);
|
||||||
static ref PROCESS_SIDE: RwLock<ProcessSide> = RwLock::new(ProcessSide::UnknownSide);
|
}
|
||||||
|
|
||||||
|
impl ClipboardFile {
|
||||||
|
pub fn is_stopping_allowed(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
ClipboardFile::MonitorReady
|
||||||
|
| ClipboardFile::FormatList { .. }
|
||||||
|
| ClipboardFile::FormatDataRequest { .. } => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_stopping_allowed_from_peer(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
ClipboardFile::MonitorReady | ClipboardFile::FormatList { .. } => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_client_conn_id(session_uuid: &SessionID) -> Option<i32> {
|
pub fn get_client_conn_id(session_uuid: &SessionID) -> Option<i32> {
|
||||||
@ -87,6 +93,12 @@ pub fn get_client_conn_id(session_uuid: &SessionID) -> Option<i32> {
|
|||||||
.map(|x| x.conn_id)
|
.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(
|
pub fn get_rx_cliprdr_client(
|
||||||
session_uuid: &SessionID,
|
session_uuid: &SessionID,
|
||||||
) -> (i32, Arc<TokioMutex<UnboundedReceiver<ClipboardFile>>>) {
|
) -> (i32, Arc<TokioMutex<UnboundedReceiver<ClipboardFile>>>) {
|
||||||
@ -100,7 +112,7 @@ pub fn get_rx_cliprdr_client(
|
|||||||
let (sender, receiver) = unbounded_channel();
|
let (sender, receiver) = unbounded_channel();
|
||||||
let receiver = Arc::new(TokioMutex::new(receiver));
|
let receiver = Arc::new(TokioMutex::new(receiver));
|
||||||
let receiver2 = receiver.clone();
|
let receiver2 = receiver.clone();
|
||||||
let conn_id = lock.len() as i32 + 1;
|
let conn_id = get_conn_id();
|
||||||
let msg_channel = MsgChannel {
|
let msg_channel = MsgChannel {
|
||||||
session_uuid: session_uuid.to_owned(),
|
session_uuid: session_uuid.to_owned(),
|
||||||
conn_id,
|
conn_id,
|
||||||
@ -146,13 +158,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 {
|
pub fn empty_clipboard(context: &mut Box<CliprdrClientContext>, conn_id: i32) -> bool {
|
||||||
unsafe { TRUE == cliprdr::empty_cliprdr(&mut (**context), conn_id as u32) }
|
unsafe { TRUE == cliprdr::empty_cliprdr(&mut (**context), conn_id as u32) }
|
||||||
}
|
}
|
||||||
@ -251,8 +256,12 @@ pub fn server_monitor_ready(context: &mut Box<CliprdrClientContext>, conn_id: i3
|
|||||||
msgFlags: 0 as UINT16,
|
msgFlags: 0 as UINT16,
|
||||||
dataLen: 0 as UINT32,
|
dataLen: 0 as UINT32,
|
||||||
};
|
};
|
||||||
let ret = ((**context).MonitorReady.unwrap())(&mut (**context), &monitor_ready);
|
if let Some(f) = (**context).MonitorReady {
|
||||||
ret as u32
|
let ret = f(&mut (**context), &monitor_ready);
|
||||||
|
ret as u32
|
||||||
|
} else {
|
||||||
|
ERR_CODE_SERVER_FUNCTION_NONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,7 +302,11 @@ pub fn server_format_list(
|
|||||||
formats: formats.as_mut_ptr(),
|
formats: formats.as_mut_ptr(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ret = ((**context).ServerFormatList.unwrap())(&mut (**context), &format_list);
|
let ret = if let Some(f) = (**context).ServerFormatList {
|
||||||
|
f(&mut (**context), &format_list)
|
||||||
|
} else {
|
||||||
|
ERR_CODE_SERVER_FUNCTION_NONE
|
||||||
|
};
|
||||||
|
|
||||||
for f in formats {
|
for f in formats {
|
||||||
if !f.formatName.is_null() {
|
if !f.formatName.is_null() {
|
||||||
@ -319,10 +332,11 @@ pub fn server_format_list_response(
|
|||||||
dataLen: 0 as UINT32,
|
dataLen: 0 as UINT32,
|
||||||
};
|
};
|
||||||
|
|
||||||
let ret =
|
if let Some(f) = (**context).ServerFormatListResponse {
|
||||||
(**context).ServerFormatListResponse.unwrap()(&mut (**context), &format_list_response);
|
f(&mut (**context), &format_list_response)
|
||||||
|
} else {
|
||||||
ret as u32
|
ERR_CODE_SERVER_FUNCTION_NONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,9 +353,11 @@ pub fn server_format_data_request(
|
|||||||
dataLen: 0 as UINT32,
|
dataLen: 0 as UINT32,
|
||||||
requestedFormatId: requested_format_id as UINT32,
|
requestedFormatId: requested_format_id as UINT32,
|
||||||
};
|
};
|
||||||
let ret =
|
if let Some(f) = (**context).ServerFormatDataRequest {
|
||||||
((**context).ServerFormatDataRequest.unwrap())(&mut (**context), &format_data_request);
|
f(&mut (**context), &format_data_request)
|
||||||
ret as u32
|
} else {
|
||||||
|
ERR_CODE_SERVER_FUNCTION_NONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,11 +375,11 @@ pub fn server_format_data_response(
|
|||||||
dataLen: format_data.len() as UINT32,
|
dataLen: format_data.len() as UINT32,
|
||||||
requestedFormatData: format_data.as_mut_ptr(),
|
requestedFormatData: format_data.as_mut_ptr(),
|
||||||
};
|
};
|
||||||
let ret = ((**context).ServerFormatDataResponse.unwrap())(
|
if let Some(f) = (**context).ServerFormatDataResponse {
|
||||||
&mut (**context),
|
f(&mut (**context), &format_data_response)
|
||||||
&format_data_response,
|
} else {
|
||||||
);
|
ERR_CODE_SERVER_FUNCTION_NONE
|
||||||
ret as u32
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,11 +410,11 @@ pub fn server_file_contents_request(
|
|||||||
haveClipDataId: if have_clip_data_id { TRUE } else { FALSE },
|
haveClipDataId: if have_clip_data_id { TRUE } else { FALSE },
|
||||||
clipDataId: clip_data_id as UINT32,
|
clipDataId: clip_data_id as UINT32,
|
||||||
};
|
};
|
||||||
let ret = ((**context).ServerFileContentsRequest.unwrap())(
|
if let Some(f) = (**context).ServerFileContentsRequest {
|
||||||
&mut (**context),
|
f(&mut (**context), &file_contents_request)
|
||||||
&file_contents_request,
|
} else {
|
||||||
);
|
ERR_CODE_SERVER_FUNCTION_NONE
|
||||||
ret as u32
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,25 +435,21 @@ pub fn server_file_contents_response(
|
|||||||
cbRequested: requested_data.len() as UINT32,
|
cbRequested: requested_data.len() as UINT32,
|
||||||
requestedData: requested_data.as_mut_ptr(),
|
requestedData: requested_data.as_mut_ptr(),
|
||||||
};
|
};
|
||||||
let ret = ((**context).ServerFileContentsResponse.unwrap())(
|
if let Some(f) = (**context).ServerFileContentsResponse {
|
||||||
&mut (**context),
|
f(&mut (**context), &file_contents_response)
|
||||||
&file_contents_response,
|
} else {
|
||||||
);
|
ERR_CODE_SERVER_FUNCTION_NONE
|
||||||
ret as u32
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_cliprdr_context(
|
pub fn create_cliprdr_context(
|
||||||
enable_files: bool,
|
enable_files: bool,
|
||||||
enable_others: bool,
|
enable_others: bool,
|
||||||
process_side: ProcessSide,
|
|
||||||
) -> ResultType<Box<CliprdrClientContext>> {
|
) -> ResultType<Box<CliprdrClientContext>> {
|
||||||
*PROCESS_SIDE.write().unwrap() = process_side;
|
|
||||||
|
|
||||||
Ok(CliprdrClientContext::create(
|
Ok(CliprdrClientContext::create(
|
||||||
enable_files,
|
enable_files,
|
||||||
enable_others,
|
enable_others,
|
||||||
Some(check_enabled),
|
|
||||||
Some(client_format_list),
|
Some(client_format_list),
|
||||||
Some(client_format_list_response),
|
Some(client_format_list_response),
|
||||||
Some(client_format_data_request),
|
Some(client_format_data_request),
|
||||||
@ -447,24 +459,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(
|
extern "C" fn client_format_list(
|
||||||
_context: *mut CliprdrClientContext,
|
_context: *mut CliprdrClientContext,
|
||||||
clip_format_list: *const CLIPRDR_FORMAT_LIST,
|
clip_format_list: *const CLIPRDR_FORMAT_LIST,
|
||||||
@ -498,9 +492,9 @@ extern "C" fn client_format_list(
|
|||||||
let data = ClipboardFile::FormatList { format_list };
|
let data = ClipboardFile::FormatList { format_list };
|
||||||
// no need to handle result here
|
// no need to handle result here
|
||||||
if conn_id == 0 {
|
if conn_id == 0 {
|
||||||
VEC_MSG_CHANNEL
|
// msg_channel is used for debug, VEC_MSG_CHANNEL cannot be inspected by the debugger.
|
||||||
.read()
|
let msg_channel = VEC_MSG_CHANNEL.read().unwrap();
|
||||||
.unwrap()
|
msg_channel
|
||||||
.iter()
|
.iter()
|
||||||
.for_each(|msg_channel| allow_err!(msg_channel.sender.send(data.clone())));
|
.for_each(|msg_channel| allow_err!(msg_channel.sender.send(data.clone())));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
// to-do: TOO MANY compilation warnings. Fix them.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||||
* Windows Clipboard Redirection
|
* Windows Clipboard Redirection
|
||||||
@ -136,11 +138,13 @@ typedef struct _FORMAT_IDS FORMAT_IDS;
|
|||||||
#define TAG "windows"
|
#define TAG "windows"
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_CLIPRDR
|
#ifdef WITH_DEBUG_CLIPRDR
|
||||||
#define DEBUG_CLIPRDR(fmt, ...) fprintf(stderr, "DEBUG %s[%d] %s() " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__);fflush(stderr)
|
#define DEBUG_CLIPRDR(fmt, ...) \
|
||||||
|
fprintf(stderr, "DEBUG %s[%d] %s() " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
|
||||||
|
fflush(stderr)
|
||||||
#else
|
#else
|
||||||
#define DEBUG_CLIPRDR(fmt, ...) \
|
#define DEBUG_CLIPRDR(fmt, ...) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -354,6 +358,7 @@ static HRESULT STDMETHODCALLTYPE CliprdrStream_Read(IStream *This, void *pv, ULO
|
|||||||
{
|
{
|
||||||
CopyMemory(pv, clipboard->req_fdata, clipboard->req_fsize);
|
CopyMemory(pv, clipboard->req_fdata, clipboard->req_fsize);
|
||||||
free(clipboard->req_fdata);
|
free(clipboard->req_fdata);
|
||||||
|
clipboard->req_fdata = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
*pcbRead = clipboard->req_fsize;
|
*pcbRead = clipboard->req_fsize;
|
||||||
@ -565,6 +570,7 @@ static CliprdrStream *CliprdrStream_New(UINT32 connID, ULONG index, void *pData,
|
|||||||
|
|
||||||
instance->m_lSize.QuadPart = *((LONGLONG *)clipboard->req_fdata);
|
instance->m_lSize.QuadPart = *((LONGLONG *)clipboard->req_fdata);
|
||||||
free(clipboard->req_fdata);
|
free(clipboard->req_fdata);
|
||||||
|
clipboard->req_fdata = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
@ -681,10 +687,6 @@ static HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetData(IDataObject *This, FO
|
|||||||
}
|
}
|
||||||
|
|
||||||
clipboard = (wfClipboard *)instance->m_pData;
|
clipboard = (wfClipboard *)instance->m_pData;
|
||||||
if (!clipboard->context->CheckEnabled(instance->m_connID))
|
|
||||||
{
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!clipboard)
|
if (!clipboard)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
@ -1444,6 +1446,56 @@ static UINT cliprdr_send_format_list(wfClipboard *clipboard, UINT32 connID)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT wait_response_event(wfClipboard *clipboard, HANDLE event, void **data)
|
||||||
|
{
|
||||||
|
UINT rc = ERROR_SUCCESS;
|
||||||
|
clipboard->context->IsStopped = FALSE;
|
||||||
|
// with default 3min timeout
|
||||||
|
for (int i = 0; i < 20 * 60 * 3; i++)
|
||||||
|
{
|
||||||
|
DWORD waitRes = WaitForSingleObject(event, 50);
|
||||||
|
if (waitRes == WAIT_TIMEOUT && clipboard->context->IsStopped == FALSE)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clipboard->context->IsStopped == TRUE)
|
||||||
|
{
|
||||||
|
wf_do_empty_cliprdr(clipboard);
|
||||||
|
rc = ERROR_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (waitRes != WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
return ERROR_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ResetEvent(event))
|
||||||
|
{
|
||||||
|
// NOTE: critical error here, crash may be better
|
||||||
|
rc = ERROR_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*data) == NULL)
|
||||||
|
{
|
||||||
|
rc = ERROR_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*data) != NULL)
|
||||||
|
{
|
||||||
|
if (!ResetEvent(event))
|
||||||
|
{
|
||||||
|
// NOTE: critical error here, crash may be better
|
||||||
|
}
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
static UINT cliprdr_send_data_request(UINT32 connID, wfClipboard *clipboard, UINT32 formatId)
|
static UINT cliprdr_send_data_request(UINT32 connID, wfClipboard *clipboard, UINT32 formatId)
|
||||||
{
|
{
|
||||||
UINT rc;
|
UINT rc;
|
||||||
@ -1464,51 +1516,7 @@ static UINT cliprdr_send_data_request(UINT32 connID, wfClipboard *clipboard, UIN
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// with default 3min timeout
|
wait_response_event(clipboard, clipboard->response_data_event, &clipboard->hmem);
|
||||||
for (int i = 0; i < 20 * 60 * 3; i++)
|
|
||||||
{
|
|
||||||
DWORD waitRes = WaitForSingleObject(clipboard->response_data_event, 50);
|
|
||||||
if (waitRes == WAIT_TIMEOUT)
|
|
||||||
{
|
|
||||||
if (clipboard->context->CheckEnabled(connID))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (waitRes != WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
return ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ResetEvent(clipboard->response_data_event))
|
|
||||||
{
|
|
||||||
// NOTE: critical error here, crash may be better
|
|
||||||
rc = ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!clipboard->hmem)
|
|
||||||
{
|
|
||||||
rc = ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clipboard->hmem)
|
|
||||||
{
|
|
||||||
if (!ResetEvent(clipboard->response_data_event))
|
|
||||||
{
|
|
||||||
// NOTE: critical error here, crash may be better
|
|
||||||
}
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT cliprdr_send_request_filecontents(wfClipboard *clipboard, UINT32 connID, const void *streamid, ULONG index,
|
UINT cliprdr_send_request_filecontents(wfClipboard *clipboard, UINT32 connID, const void *streamid, ULONG index,
|
||||||
@ -1536,50 +1544,7 @@ UINT cliprdr_send_request_filecontents(wfClipboard *clipboard, UINT32 connID, co
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// with default 3min timeout
|
return wait_response_event(clipboard, clipboard->req_fevent, (void**)&clipboard->req_fdata);
|
||||||
for (int i = 0; i < 20 * 60 * 3; i++)
|
|
||||||
{
|
|
||||||
DWORD waitRes = WaitForSingleObject(clipboard->req_fevent, 50);
|
|
||||||
if (waitRes == WAIT_TIMEOUT)
|
|
||||||
{
|
|
||||||
if (clipboard->context->CheckEnabled(connID))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (waitRes != WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
return ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ResetEvent(clipboard->req_fevent))
|
|
||||||
{
|
|
||||||
// NOTE: critical error here, crash may be better
|
|
||||||
rc = ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
if (!clipboard->req_fdata)
|
|
||||||
{
|
|
||||||
rc = ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clipboard->req_fdata)
|
|
||||||
{
|
|
||||||
if (!ResetEvent(clipboard->req_fevent))
|
|
||||||
{
|
|
||||||
// NOTE: critical error here, crash may be better
|
|
||||||
}
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT cliprdr_send_response_filecontents(
|
static UINT cliprdr_send_response_filecontents(
|
||||||
@ -2087,8 +2052,8 @@ static BOOL wf_cliprdr_traverse_directory(wfClipboard *clipboard, WCHAR *Dir, si
|
|||||||
while (FindNextFileW(hFind, &FindFileData))
|
while (FindNextFileW(hFind, &FindFileData))
|
||||||
{
|
{
|
||||||
// if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 &&
|
// if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 &&
|
||||||
// wcscmp(FindFileData.cFileName, _T(".")) == 0 ||
|
// wcscmp(FindFileData.cFileName, _T(".")) == 0 ||
|
||||||
// wcscmp(FindFileData.cFileName, _T("..")) == 0)
|
// wcscmp(FindFileData.cFileName, _T("..")) == 0)
|
||||||
if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 &&
|
if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 &&
|
||||||
wcscmp(FindFileData.cFileName, L".") == 0 ||
|
wcscmp(FindFileData.cFileName, L".") == 0 ||
|
||||||
wcscmp(FindFileData.cFileName, L"..") == 0)
|
wcscmp(FindFileData.cFileName, L"..") == 0)
|
||||||
@ -2141,7 +2106,8 @@ static UINT wf_cliprdr_send_client_capabilities(wfClipboard *clipboard)
|
|||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
|
|
||||||
// Ignore ClientCapabilities for now
|
// Ignore ClientCapabilities for now
|
||||||
if (!clipboard->context->ClientCapabilities) {
|
if (!clipboard->context->ClientCapabilities)
|
||||||
|
{
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2165,7 +2131,7 @@ static UINT wf_cliprdr_monitor_ready(CliprdrClientContext *context,
|
|||||||
const CLIPRDR_MONITOR_READY *monitorReady)
|
const CLIPRDR_MONITOR_READY *monitorReady)
|
||||||
{
|
{
|
||||||
UINT rc;
|
UINT rc;
|
||||||
wfClipboard *clipboard = (wfClipboard *)context->custom;
|
wfClipboard *clipboard = (wfClipboard *)context->Custom;
|
||||||
|
|
||||||
if (!context || !monitorReady)
|
if (!context || !monitorReady)
|
||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
@ -2189,7 +2155,7 @@ static UINT wf_cliprdr_server_capabilities(CliprdrClientContext *context,
|
|||||||
{
|
{
|
||||||
UINT32 index;
|
UINT32 index;
|
||||||
CLIPRDR_CAPABILITY_SET *capabilitySet;
|
CLIPRDR_CAPABILITY_SET *capabilitySet;
|
||||||
wfClipboard *clipboard = (wfClipboard *)context->custom;
|
wfClipboard *clipboard = (wfClipboard *)context->Custom;
|
||||||
|
|
||||||
if (!context || !capabilities)
|
if (!context || !capabilities)
|
||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
@ -2223,7 +2189,7 @@ static UINT wf_cliprdr_server_format_list(CliprdrClientContext *context,
|
|||||||
UINT32 i;
|
UINT32 i;
|
||||||
formatMapping *mapping;
|
formatMapping *mapping;
|
||||||
CLIPRDR_FORMAT *format;
|
CLIPRDR_FORMAT *format;
|
||||||
wfClipboard *clipboard = (wfClipboard *)context->custom;
|
wfClipboard *clipboard = (wfClipboard *)context->Custom;
|
||||||
|
|
||||||
if (!clear_format_map(clipboard))
|
if (!clear_format_map(clipboard))
|
||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
@ -2259,7 +2225,7 @@ static UINT wf_cliprdr_server_format_list(CliprdrClientContext *context,
|
|||||||
|
|
||||||
if (file_transferring(clipboard))
|
if (file_transferring(clipboard))
|
||||||
{
|
{
|
||||||
if (context->enableFiles)
|
if (context->EnableFiles)
|
||||||
{
|
{
|
||||||
UINT32 *p_conn_id = (UINT32 *)calloc(1, sizeof(UINT32));
|
UINT32 *p_conn_id = (UINT32 *)calloc(1, sizeof(UINT32));
|
||||||
*p_conn_id = formatList->connID;
|
*p_conn_id = formatList->connID;
|
||||||
@ -2273,7 +2239,7 @@ static UINT wf_cliprdr_server_format_list(CliprdrClientContext *context,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (context->enableOthers)
|
if (context->EnableOthers)
|
||||||
{
|
{
|
||||||
if (!try_open_clipboard(clipboard->hwnd))
|
if (!try_open_clipboard(clipboard->hwnd))
|
||||||
return CHANNEL_RC_OK; /* Ignore, other app holding clipboard */
|
return CHANNEL_RC_OK; /* Ignore, other app holding clipboard */
|
||||||
@ -2282,7 +2248,7 @@ static UINT wf_cliprdr_server_format_list(CliprdrClientContext *context,
|
|||||||
{
|
{
|
||||||
// Modified: do not apply delayed rendering
|
// Modified: do not apply delayed rendering
|
||||||
// for (i = 0; i < (UINT32)clipboard->map_size; i++)
|
// for (i = 0; i < (UINT32)clipboard->map_size; i++)
|
||||||
// SetClipboardData(clipboard->format_mappings[i].local_format_id, NULL);
|
// SetClipboardData(clipboard->format_mappings[i].local_format_id, NULL);
|
||||||
|
|
||||||
FORMAT_IDS *format_ids = (FORMAT_IDS *)calloc(1, sizeof(FORMAT_IDS));
|
FORMAT_IDS *format_ids = (FORMAT_IDS *)calloc(1, sizeof(FORMAT_IDS));
|
||||||
format_ids->connID = formatList->connID;
|
format_ids->connID = formatList->connID;
|
||||||
@ -2417,7 +2383,7 @@ wf_cliprdr_server_format_data_request(CliprdrClientContext *context,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
clipboard = (wfClipboard *)context->custom;
|
clipboard = (wfClipboard *)context->Custom;
|
||||||
|
|
||||||
if (!clipboard)
|
if (!clipboard)
|
||||||
{
|
{
|
||||||
@ -2597,7 +2563,7 @@ wf_cliprdr_server_format_data_response(CliprdrClientContext *context,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
clipboard = (wfClipboard *)context->custom;
|
clipboard = (wfClipboard *)context->Custom;
|
||||||
if (!clipboard)
|
if (!clipboard)
|
||||||
{
|
{
|
||||||
rc = ERROR_INTERNAL_ERROR;
|
rc = ERROR_INTERNAL_ERROR;
|
||||||
@ -2678,7 +2644,7 @@ wf_cliprdr_server_file_contents_request(CliprdrClientContext *context,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
clipboard = (wfClipboard *)context->custom;
|
clipboard = (wfClipboard *)context->Custom;
|
||||||
|
|
||||||
if (!clipboard)
|
if (!clipboard)
|
||||||
{
|
{
|
||||||
@ -2856,7 +2822,7 @@ exit:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if (sRc != CHANNEL_RC_OK)
|
// if (sRc != CHANNEL_RC_OK)
|
||||||
// return sRc;
|
// return sRc;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -2881,7 +2847,7 @@ wf_cliprdr_server_file_contents_response(CliprdrClientContext *context,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
clipboard = (wfClipboard *)context->custom;
|
clipboard = (wfClipboard *)context->Custom;
|
||||||
if (!clipboard)
|
if (!clipboard)
|
||||||
{
|
{
|
||||||
rc = ERROR_INTERNAL_ERROR;
|
rc = ERROR_INTERNAL_ERROR;
|
||||||
@ -2969,7 +2935,7 @@ BOOL wf_cliprdr_init(wfClipboard *clipboard, CliprdrClientContext *cliprdr)
|
|||||||
cliprdr->ServerFormatDataResponse = wf_cliprdr_server_format_data_response;
|
cliprdr->ServerFormatDataResponse = wf_cliprdr_server_format_data_response;
|
||||||
cliprdr->ServerFileContentsRequest = wf_cliprdr_server_file_contents_request;
|
cliprdr->ServerFileContentsRequest = wf_cliprdr_server_file_contents_request;
|
||||||
cliprdr->ServerFileContentsResponse = wf_cliprdr_server_file_contents_response;
|
cliprdr->ServerFileContentsResponse = wf_cliprdr_server_file_contents_response;
|
||||||
cliprdr->custom = (void *)clipboard;
|
cliprdr->Custom = (void *)clipboard;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
error:
|
error:
|
||||||
wf_cliprdr_uninit(clipboard, cliprdr);
|
wf_cliprdr_uninit(clipboard, cliprdr);
|
||||||
@ -2981,7 +2947,7 @@ BOOL wf_cliprdr_uninit(wfClipboard *clipboard, CliprdrClientContext *cliprdr)
|
|||||||
if (!clipboard || !cliprdr)
|
if (!clipboard || !cliprdr)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
cliprdr->custom = NULL;
|
cliprdr->Custom = NULL;
|
||||||
|
|
||||||
/* discard all contexts in clipboard */
|
/* discard all contexts in clipboard */
|
||||||
if (try_open_clipboard(clipboard->hwnd))
|
if (try_open_clipboard(clipboard->hwnd))
|
||||||
@ -3056,7 +3022,7 @@ BOOL empty_cliprdr(CliprdrClientContext *context, UINT32 connID)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
clipboard = (wfClipboard *)context->custom;
|
clipboard = (wfClipboard *)context->Custom;
|
||||||
if (!clipboard)
|
if (!clipboard)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|||||||
@ -2,6 +2,7 @@ use std::{
|
|||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fs,
|
fs,
|
||||||
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::{Arc, Mutex, RwLock},
|
sync::{Arc, Mutex, RwLock},
|
||||||
time::{Duration, Instant, SystemTime},
|
time::{Duration, Instant, SystemTime},
|
||||||
@ -132,6 +133,18 @@ macro_rules! serde_field_bool {
|
|||||||
UserDefaultConfig::read().get($field_name) == "Y"
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2336,6 +2336,7 @@ pub enum Data {
|
|||||||
CancelJob(i32),
|
CancelJob(i32),
|
||||||
RemovePortForward(i32),
|
RemovePortForward(i32),
|
||||||
AddPortForward((i32, String, i32)),
|
AddPortForward((i32, String, i32)),
|
||||||
|
#[cfg(not(feature = "flutter"))]
|
||||||
ToggleClipboardFile,
|
ToggleClipboardFile,
|
||||||
NewRDP,
|
NewRDP,
|
||||||
SetConfirmOverrideFile((i32, i32, bool, bool, bool)),
|
SetConfirmOverrideFile((i32, i32, bool, bool, bool)),
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use std::sync::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use clipboard::{cliprdr::CliprdrClientContext, ContextSend};
|
use clipboard::{cliprdr::CliprdrClientContext, empty_clipboard, ContextSend};
|
||||||
use crossbeam_queue::ArrayQueue;
|
use crossbeam_queue::ArrayQueue;
|
||||||
use hbb_common::config::{PeerConfig, TransferSerde};
|
use hbb_common::config::{PeerConfig, TransferSerde};
|
||||||
use hbb_common::fs::{
|
use hbb_common::fs::{
|
||||||
@ -58,7 +58,7 @@ pub struct Remote<T: InvokeUiSession> {
|
|||||||
last_update_jobs_status: (Instant, HashMap<i32, u64>),
|
last_update_jobs_status: (Instant, HashMap<i32, u64>),
|
||||||
first_frame: bool,
|
first_frame: bool,
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
client_conn_id: i32, // used for clipboard
|
client_conn_id: i32, // used for file clipboard
|
||||||
data_count: Arc<AtomicUsize>,
|
data_count: Arc<AtomicUsize>,
|
||||||
frame_count: Arc<AtomicUsize>,
|
frame_count: Arc<AtomicUsize>,
|
||||||
video_format: CodecFormat,
|
video_format: CodecFormat,
|
||||||
@ -207,7 +207,16 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
match _msg {
|
match _msg {
|
||||||
Some(clip) => {
|
Some(clip) => {
|
||||||
allow_err!(peer.send(&crate::clipboard_file::clip_2_msg(clip)).await);
|
let is_stopping_allowed = clip.is_stopping_allowed();
|
||||||
|
let server_file_transfer_enabled = *self.handler.server_file_transfer_enabled.read().unwrap();
|
||||||
|
let file_transfer_enabled = self.handler.lc.read().unwrap().enable_file_transfer.v;
|
||||||
|
let stop = is_stopping_allowed && !(server_file_transfer_enabled && file_transfer_enabled);
|
||||||
|
log::debug!("Process clipboard message from system, stop: {}, is_stopping_allowed: {}, server_file_transfer_enabled: {}, file_transfer_enabled: {}", stop, is_stopping_allowed, server_file_transfer_enabled, file_transfer_enabled);
|
||||||
|
if stop {
|
||||||
|
ContextSend::set_is_stopped();
|
||||||
|
} else {
|
||||||
|
allow_err!(peer.send(&crate::clipboard_file::clip_2_msg(clip)).await);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// unreachable!()
|
// unreachable!()
|
||||||
@ -263,6 +272,15 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
}
|
}
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
Client::try_stop_clipboard(&self.handler.session_id);
|
Client::try_stop_clipboard(&self.handler.session_id);
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
let conn_id = self.client_conn_id;
|
||||||
|
ContextSend::proc(|context: &mut Box<CliprdrClientContext>| -> u32 {
|
||||||
|
empty_clipboard(context, conn_id);
|
||||||
|
0
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_job_status(&mut self, id: i32, file_num: i32, err: Option<String>) {
|
fn handle_job_status(&mut self, id: i32, file_num: i32, err: Option<String>) {
|
||||||
@ -389,6 +407,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
.handle_login_from_ui(os_username, os_password, password, remember, peer)
|
.handle_login_from_ui(os_username, os_password, password, remember, peer)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
#[cfg(not(feature = "flutter"))]
|
||||||
Data::ToggleClipboardFile => {
|
Data::ToggleClipboardFile => {
|
||||||
self.check_clipboard_file_context();
|
self.check_clipboard_file_context();
|
||||||
}
|
}
|
||||||
@ -938,6 +957,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
}
|
}
|
||||||
Some(login_response::Union::PeerInfo(pi)) => {
|
Some(login_response::Union::PeerInfo(pi)) => {
|
||||||
self.handler.handle_peer_info(pi);
|
self.handler.handle_peer_info(pi);
|
||||||
|
#[cfg(not(feature = "flutter"))]
|
||||||
self.check_clipboard_file_context();
|
self.check_clipboard_file_context();
|
||||||
if !(self.handler.is_file_transfer() || self.handler.is_port_forward()) {
|
if !(self.handler.is_file_transfer() || self.handler.is_port_forward()) {
|
||||||
#[cfg(feature = "flutter")]
|
#[cfg(feature = "flutter")]
|
||||||
@ -1188,7 +1208,6 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
if !p.enabled && self.handler.is_file_transfer() {
|
if !p.enabled && self.handler.is_file_transfer() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
self.check_clipboard_file_context();
|
|
||||||
self.handler.set_permission("file", p.enabled);
|
self.handler.set_permission("file", p.enabled);
|
||||||
}
|
}
|
||||||
Ok(Permission::Restart) => {
|
Ok(Permission::Restart) => {
|
||||||
@ -1525,6 +1544,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "flutter"))]
|
||||||
fn check_clipboard_file_context(&self) {
|
fn check_clipboard_file_context(&self) {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
@ -1536,18 +1556,23 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn handle_cliprdr_msg(&self, clip: hbb_common::message_proto::Cliprdr) {
|
fn handle_cliprdr_msg(&self, clip: hbb_common::message_proto::Cliprdr) {
|
||||||
if !self.handler.lc.read().unwrap().disable_clipboard.v {
|
#[cfg(feature = "flutter")]
|
||||||
#[cfg(feature = "flutter")]
|
if let Some(hbb_common::message_proto::cliprdr::Union::FormatList(_)) = &clip.union {
|
||||||
if let Some(hbb_common::message_proto::cliprdr::Union::FormatList(_)) = &clip.union {
|
if self.client_conn_id
|
||||||
if self.client_conn_id
|
!= clipboard::get_client_conn_id(&crate::flutter::get_cur_session_id()).unwrap_or(0)
|
||||||
!= clipboard::get_client_conn_id(&crate::flutter::get_cur_session_id())
|
{
|
||||||
.unwrap_or(0)
|
return;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(clip) = crate::clipboard_file::msg_2_clip(clip) {
|
if let Some(clip) = crate::clipboard_file::msg_2_clip(clip) {
|
||||||
|
let is_stopping_allowed = clip.is_stopping_allowed_from_peer();
|
||||||
|
let file_transfer_enabled = self.handler.lc.read().unwrap().enable_file_transfer.v;
|
||||||
|
let stop = is_stopping_allowed && !file_transfer_enabled;
|
||||||
|
log::debug!(
|
||||||
|
"Process clipboard message from server peer, stop: {}, is_stopping_allowed: {}, file_transfer_enabled: {}",
|
||||||
|
stop, is_stopping_allowed, file_transfer_enabled);
|
||||||
|
if !stop {
|
||||||
ContextSend::proc(|context: &mut Box<CliprdrClientContext>| -> u32 {
|
ContextSend::proc(|context: &mut Box<CliprdrClientContext>| -> u32 {
|
||||||
clipboard::server_clip_file(context, self.client_conn_id, clip)
|
clipboard::server_clip_file(context, self.client_conn_id, clip)
|
||||||
});
|
});
|
||||||
|
|||||||
@ -122,6 +122,8 @@ pub fn core_main() -> Option<Vec<String>> {
|
|||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
init_plugins(&args);
|
init_plugins(&args);
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
|
#[cfg(windows)]
|
||||||
|
clipboard::ContextSend::enable(true);
|
||||||
std::thread::spawn(move || crate::start_server(false));
|
std::thread::spawn(move || crate::start_server(false));
|
||||||
} else {
|
} else {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
|||||||
@ -242,7 +242,7 @@ pub async fn start(postfix: &str) -> ResultType<()> {
|
|||||||
loop {
|
loop {
|
||||||
match stream.next().await {
|
match stream.next().await {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::trace!("ipc{} connection closed: {}", postfix, err);
|
log::trace!("ipc '{}' connection closed: {}", postfix, err);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Ok(Some(data)) => {
|
Ok(Some(data)) => {
|
||||||
|
|||||||
@ -282,6 +282,7 @@ impl Connection {
|
|||||||
keyboard: Connection::permission("enable-keyboard"),
|
keyboard: Connection::permission("enable-keyboard"),
|
||||||
clipboard: Connection::permission("enable-clipboard"),
|
clipboard: Connection::permission("enable-clipboard"),
|
||||||
audio: Connection::permission("enable-audio"),
|
audio: Connection::permission("enable-audio"),
|
||||||
|
// to-do: make sure is the option correct here
|
||||||
file: Connection::permission("enable-file-transfer"),
|
file: Connection::permission("enable-file-transfer"),
|
||||||
restart: Connection::permission("enable-remote-restart"),
|
restart: Connection::permission("enable-remote-restart"),
|
||||||
recording: Connection::permission("enable-record-session"),
|
recording: Connection::permission("enable-record-session"),
|
||||||
@ -424,7 +425,6 @@ impl Connection {
|
|||||||
} else if &name == "file" {
|
} else if &name == "file" {
|
||||||
conn.file = enabled;
|
conn.file = enabled;
|
||||||
conn.send_permission(Permission::File, enabled).await;
|
conn.send_permission(Permission::File, enabled).await;
|
||||||
conn.send_to_cm(ipc::Data::ClipboardFileEnabled(conn.file_transfer_enabled()));
|
|
||||||
} else if &name == "restart" {
|
} else if &name == "restart" {
|
||||||
conn.restart = enabled;
|
conn.restart = enabled;
|
||||||
conn.send_permission(Permission::Restart, enabled).await;
|
conn.send_permission(Permission::Restart, enabled).await;
|
||||||
@ -437,10 +437,8 @@ impl Connection {
|
|||||||
allow_err!(conn.stream.send_raw(bytes).await);
|
allow_err!(conn.stream.send_raw(bytes).await);
|
||||||
}
|
}
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
ipc::Data::ClipboardFile(_clip) => {
|
ipc::Data::ClipboardFile(clip) => {
|
||||||
if conn.file_transfer_enabled() {
|
allow_err!(conn.stream.send(&clip_2_msg(clip)).await);
|
||||||
allow_err!(conn.stream.send(&clip_2_msg(_clip)).await);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ipc::Data::PrivacyModeState((_, state)) => {
|
ipc::Data::PrivacyModeState((_, state)) => {
|
||||||
let msg_out = match state {
|
let msg_out = match state {
|
||||||
@ -1136,7 +1134,7 @@ impl Connection {
|
|||||||
clipboard: self.clipboard,
|
clipboard: self.clipboard,
|
||||||
audio: self.audio,
|
audio: self.audio,
|
||||||
file: self.file,
|
file: self.file,
|
||||||
file_transfer_enabled: self.file_transfer_enabled(),
|
file_transfer_enabled: self.file,
|
||||||
restart: self.restart,
|
restart: self.restart,
|
||||||
recording: self.recording,
|
recording: self.recording,
|
||||||
from_switch: self.from_switch,
|
from_switch: self.from_switch,
|
||||||
@ -1635,12 +1633,11 @@ impl Connection {
|
|||||||
update_clipboard(_cb, None);
|
update_clipboard(_cb, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(message::Union::Cliprdr(_clip)) => {
|
Some(message::Union::Cliprdr(_clip)) =>
|
||||||
if self.file_transfer_enabled() {
|
{
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
if let Some(clip) = msg_2_clip(_clip) {
|
if let Some(clip) = msg_2_clip(_clip) {
|
||||||
self.send_to_cm(ipc::Data::ClipboardFile(clip))
|
self.send_to_cm(ipc::Data::ClipboardFile(clip))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(message::Union::FileAction(fa)) => {
|
Some(message::Union::FileAction(fa)) => {
|
||||||
|
|||||||
@ -11,14 +11,12 @@ use std::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
use clipboard::{cliprdr::CliprdrClientContext, empty_clipboard, set_conn_enabled, ContextSend};
|
|
||||||
use serde_derive::Serialize;
|
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
use crate::ipc::Connection;
|
use crate::ipc::Connection;
|
||||||
#[cfg(not(any(target_os = "ios")))]
|
#[cfg(not(any(target_os = "ios")))]
|
||||||
use crate::ipc::{self, Data};
|
use crate::ipc::{self, Data};
|
||||||
|
#[cfg(windows)]
|
||||||
|
use clipboard::{cliprdr::CliprdrClientContext, empty_clipboard, ContextSend};
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
use hbb_common::tokio::sync::mpsc::unbounded_channel;
|
use hbb_common::tokio::sync::mpsc::unbounded_channel;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -37,6 +35,7 @@ use hbb_common::{
|
|||||||
task::spawn_blocking,
|
task::spawn_blocking,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use serde_derive::Serialize;
|
||||||
|
|
||||||
#[derive(Serialize, Clone)]
|
#[derive(Serialize, Clone)]
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
@ -73,6 +72,8 @@ struct IpcTaskRunner<T: InvokeUiCM> {
|
|||||||
conn_id: i32,
|
conn_id: i32,
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
file_transfer_enabled: bool,
|
file_transfer_enabled: bool,
|
||||||
|
#[cfg(windows)]
|
||||||
|
file_transfer_enabled_peer: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
@ -131,8 +132,7 @@ impl<T: InvokeUiCM> ConnectionManager<T> {
|
|||||||
restart: bool,
|
restart: bool,
|
||||||
recording: bool,
|
recording: bool,
|
||||||
from_switch: bool,
|
from_switch: bool,
|
||||||
#[cfg(not(any(target_os = "ios")))]
|
#[cfg(not(any(target_os = "ios")))] tx: mpsc::UnboundedSender<Data>,
|
||||||
tx: mpsc::UnboundedSender<Data>,
|
|
||||||
) {
|
) {
|
||||||
let client = Client {
|
let client = Client {
|
||||||
id,
|
id,
|
||||||
@ -173,6 +173,14 @@ impl<T: InvokeUiCM> ConnectionManager<T> {
|
|||||||
.map(|c| c.disconnected = true);
|
.map(|c| c.disconnected = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
ContextSend::proc(|context: &mut Box<CliprdrClientContext>| -> u32 {
|
||||||
|
empty_clipboard(context, id);
|
||||||
|
0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "android"))]
|
#[cfg(any(target_os = "android"))]
|
||||||
if CLIENTS
|
if CLIENTS
|
||||||
.read()
|
.read()
|
||||||
@ -303,42 +311,12 @@ pub fn switch_back(id: i32) {
|
|||||||
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
||||||
#[cfg(windows)]
|
|
||||||
async fn enable_cliprdr_file_context(&mut self, conn_id: i32, enabled: bool) {
|
|
||||||
if conn_id == 0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let pre_enabled = ContextSend::is_enabled();
|
|
||||||
ContextSend::enable(enabled);
|
|
||||||
if !pre_enabled && ContextSend::is_enabled() {
|
|
||||||
allow_err!(
|
|
||||||
self.stream
|
|
||||||
.send(&Data::ClipboardFile(clipboard::ClipboardFile::MonitorReady))
|
|
||||||
.await
|
|
||||||
);
|
|
||||||
}
|
|
||||||
set_conn_enabled(conn_id, enabled);
|
|
||||||
if !enabled {
|
|
||||||
ContextSend::proc(|context: &mut Box<CliprdrClientContext>| -> u32 {
|
|
||||||
empty_clipboard(context, conn_id);
|
|
||||||
0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn run(&mut self) {
|
async fn run(&mut self) {
|
||||||
use hbb_common::config::LocalConfig;
|
use hbb_common::config::LocalConfig;
|
||||||
|
|
||||||
// for tmp use, without real conn id
|
// for tmp use, without real conn id
|
||||||
let mut write_jobs: Vec<fs::TransferJob> = Vec::new();
|
let mut write_jobs: Vec<fs::TransferJob> = Vec::new();
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
if self.conn_id > 0 {
|
|
||||||
self.enable_cliprdr_file_context(self.conn_id, self.file_transfer_enabled)
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
let rx_clip1;
|
let rx_clip1;
|
||||||
let mut rx_clip;
|
let mut rx_clip;
|
||||||
@ -358,6 +336,17 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
|||||||
(_tx_clip, rx_clip) = unbounded_channel::<i32>();
|
(_tx_clip, rx_clip) = unbounded_channel::<i32>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
if ContextSend::is_enabled() {
|
||||||
|
allow_err!(
|
||||||
|
self.stream
|
||||||
|
.send(&Data::ClipboardFile(clipboard::ClipboardFile::MonitorReady))
|
||||||
|
.await
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.running = false;
|
self.running = false;
|
||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
@ -382,15 +371,11 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Data::Close => {
|
Data::Close => {
|
||||||
#[cfg(windows)]
|
|
||||||
self.enable_cliprdr_file_context(self.conn_id, false).await;
|
|
||||||
log::info!("cm ipc connection closed from connection request");
|
log::info!("cm ipc connection closed from connection request");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Data::Disconnected => {
|
Data::Disconnected => {
|
||||||
self.close = false;
|
self.close = false;
|
||||||
#[cfg(windows)]
|
|
||||||
self.enable_cliprdr_file_context(self.conn_id, false).await;
|
|
||||||
log::info!("cm ipc connection disconnect");
|
log::info!("cm ipc connection disconnect");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -414,20 +399,32 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
|||||||
handle_fs(fs, &mut write_jobs, &self.tx).await;
|
handle_fs(fs, &mut write_jobs, &self.tx).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(windows)]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
Data::ClipboardFile(_clip) => {
|
Data::ClipboardFile(_clip) => {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
let conn_id = self.conn_id;
|
let is_stopping_allowed = _clip.is_stopping_allowed_from_peer();
|
||||||
ContextSend::proc(|context: &mut Box<CliprdrClientContext>| -> u32 {
|
let is_clipboard_enabled = ContextSend::is_enabled();
|
||||||
clipboard::server_clip_file(context, conn_id, _clip)
|
let file_transfer_enabled = self.file_transfer_enabled;
|
||||||
});
|
let stop = !is_stopping_allowed && !(is_clipboard_enabled && file_transfer_enabled);
|
||||||
|
log::debug!(
|
||||||
|
"Process clipboard message from client peer, stop: {}, is_stopping_allowed: {}, is_clipboard_enabled: {}, file_transfer_enabled: {}",
|
||||||
|
stop, is_stopping_allowed, is_clipboard_enabled, file_transfer_enabled);
|
||||||
|
if stop {
|
||||||
|
ContextSend::set_is_stopped();
|
||||||
|
} else {
|
||||||
|
let conn_id = self.conn_id;
|
||||||
|
ContextSend::proc(|context: &mut Box<CliprdrClientContext>| -> u32 {
|
||||||
|
clipboard::server_clip_file(context, conn_id, _clip)
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(windows)]
|
|
||||||
Data::ClipboardFileEnabled(_enabled) => {
|
Data::ClipboardFileEnabled(_enabled) => {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
self.enable_cliprdr_file_context(self.conn_id, _enabled).await;
|
{
|
||||||
|
self.file_transfer_enabled_peer =_enabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Data::Theme(dark) => {
|
Data::Theme(dark) => {
|
||||||
self.cm.change_theme(dark);
|
self.cm.change_theme(dark);
|
||||||
@ -457,6 +454,12 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(data) = self.rx.recv() => {
|
Some(data) = self.rx.recv() => {
|
||||||
|
if let Data::SwitchPermission{name, enabled} = &data {
|
||||||
|
#[cfg(windows)]
|
||||||
|
if name == "file" {
|
||||||
|
self.file_transfer_enabled = *enabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
if self.stream.send(&data).await.is_err() {
|
if self.stream.send(&data).await.is_err() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -464,7 +467,21 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
|||||||
clip_file = rx_clip.recv() => match clip_file {
|
clip_file = rx_clip.recv() => match clip_file {
|
||||||
Some(_clip) => {
|
Some(_clip) => {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
allow_err!(self.tx.send(Data::ClipboardFile(_clip)));
|
{
|
||||||
|
let is_stopping_allowed = _clip.is_stopping_allowed();
|
||||||
|
let is_clipboard_enabled = ContextSend::is_enabled();
|
||||||
|
let file_transfer_enabled = self.file_transfer_enabled;
|
||||||
|
let file_transfer_enabled_peer = self.file_transfer_enabled_peer;
|
||||||
|
let stop = is_stopping_allowed && !(is_clipboard_enabled && file_transfer_enabled && file_transfer_enabled_peer);
|
||||||
|
log::debug!(
|
||||||
|
"Process clipboard message from cm, stop: {}, is_stopping_allowed: {}, is_clipboard_enabled: {}, file_transfer_enabled: {}, file_transfer_enabled_peer: {}",
|
||||||
|
stop, is_stopping_allowed, is_clipboard_enabled, file_transfer_enabled, file_transfer_enabled_peer);
|
||||||
|
if stop {
|
||||||
|
ContextSend::set_is_stopped();
|
||||||
|
} else {
|
||||||
|
allow_err!(self.tx.send(Data::ClipboardFile(_clip)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
//
|
//
|
||||||
@ -488,6 +505,8 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
|||||||
conn_id: 0,
|
conn_id: 0,
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
file_transfer_enabled: false,
|
file_transfer_enabled: false,
|
||||||
|
#[cfg(windows)]
|
||||||
|
file_transfer_enabled_peer: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
while task_runner.running {
|
while task_runner.running {
|
||||||
@ -517,6 +536,9 @@ pub async fn start_ipc<T: InvokeUiCM>(cm: ConnectionManager<T>) {
|
|||||||
allow_err!(crate::privacy_win_mag::start());
|
allow_err!(crate::privacy_win_mag::start());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
ContextSend::enable(Config::get_option("enable-file-transfer").is_empty());
|
||||||
|
|
||||||
match ipc::new_listener("_cm").await {
|
match ipc::new_listener("_cm").await {
|
||||||
Ok(mut incoming) => {
|
Ok(mut incoming) => {
|
||||||
while let Some(result) = incoming.next().await {
|
while let Some(result) = incoming.next().await {
|
||||||
|
|||||||
@ -857,6 +857,8 @@ async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedReceiver<ipc:
|
|||||||
let mut rx = rx;
|
let mut rx = rx;
|
||||||
let mut mouse_time = 0;
|
let mut mouse_time = 0;
|
||||||
let mut id = "".to_owned();
|
let mut id = "".to_owned();
|
||||||
|
let mut enable_file_transfer = "".to_owned();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if let Ok(mut c) = ipc::connect(1000, "").await {
|
if let Ok(mut c) = ipc::connect(1000, "").await {
|
||||||
let mut timer = time::interval(time::Duration::from_secs(1));
|
let mut timer = time::interval(time::Duration::from_secs(1));
|
||||||
@ -875,6 +877,15 @@ async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedReceiver<ipc:
|
|||||||
Ok(Some(ipc::Data::Options(Some(v)))) => {
|
Ok(Some(ipc::Data::Options(Some(v)))) => {
|
||||||
*OPTIONS.lock().unwrap() = v;
|
*OPTIONS.lock().unwrap() = v;
|
||||||
*OPTION_SYNCED.lock().unwrap() = true;
|
*OPTION_SYNCED.lock().unwrap() = true;
|
||||||
|
|
||||||
|
#[cfg(target_os="windows")]
|
||||||
|
{
|
||||||
|
let b = OPTIONS.lock().unwrap().get("enable-file-transfer").map(|x| x.to_string()).unwrap_or_default();
|
||||||
|
if b != enable_file_transfer {
|
||||||
|
clipboard::ContextSend::enable(b.is_empty());
|
||||||
|
enable_file_transfer = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(Some(ipc::Data::Config((name, Some(value))))) => {
|
Ok(Some(ipc::Data::Config((name, Some(value))))) => {
|
||||||
if name == "id" {
|
if name == "id" {
|
||||||
|
|||||||
@ -198,6 +198,7 @@ impl<T: InvokeUiSession> Session<T> {
|
|||||||
|
|
||||||
pub fn toggle_option(&mut self, name: String) {
|
pub fn toggle_option(&mut self, name: String) {
|
||||||
let msg = self.lc.write().unwrap().toggle_option(name.clone());
|
let msg = self.lc.write().unwrap().toggle_option(name.clone());
|
||||||
|
#[cfg(not(feature = "flutter"))]
|
||||||
if name == "enable-file-transfer" {
|
if name == "enable-file-transfer" {
|
||||||
self.send(Data::ToggleClipboardFile);
|
self.send(Data::ToggleClipboardFile);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user