mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-04-08 18:51:28 +03:00
feat: clipboard files, audit (#12730)
Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
@@ -170,6 +170,8 @@ extern "C"
|
|||||||
|
|
||||||
typedef UINT (*pcNotifyClipboardMsg)(UINT32 connID, const NOTIFICATION_MESSAGE *msg);
|
typedef UINT (*pcNotifyClipboardMsg)(UINT32 connID, const NOTIFICATION_MESSAGE *msg);
|
||||||
|
|
||||||
|
typedef UINT (*pcHandleClipboardFiles)(UINT32 connID, size_t nFiles, WCHAR **fileNames);
|
||||||
|
|
||||||
typedef UINT (*pcCliprdrClientFormatList)(CliprdrClientContext *context,
|
typedef UINT (*pcCliprdrClientFormatList)(CliprdrClientContext *context,
|
||||||
const CLIPRDR_FORMAT_LIST *formatList);
|
const CLIPRDR_FORMAT_LIST *formatList);
|
||||||
typedef UINT (*pcCliprdrServerFormatList)(CliprdrClientContext *context,
|
typedef UINT (*pcCliprdrServerFormatList)(CliprdrClientContext *context,
|
||||||
@@ -217,6 +219,7 @@ extern "C"
|
|||||||
pcCliprdrMonitorReady MonitorReady;
|
pcCliprdrMonitorReady MonitorReady;
|
||||||
pcCliprdrTempDirectory TempDirectory;
|
pcCliprdrTempDirectory TempDirectory;
|
||||||
pcNotifyClipboardMsg NotifyClipboardMsg;
|
pcNotifyClipboardMsg NotifyClipboardMsg;
|
||||||
|
pcHandleClipboardFiles HandleClipboardFiles;
|
||||||
pcCliprdrClientFormatList ClientFormatList;
|
pcCliprdrClientFormatList ClientFormatList;
|
||||||
pcCliprdrServerFormatList ServerFormatList;
|
pcCliprdrServerFormatList ServerFormatList;
|
||||||
pcCliprdrClientFormatListResponse ClientFormatListResponse;
|
pcCliprdrClientFormatListResponse ClientFormatListResponse;
|
||||||
|
|||||||
@@ -132,6 +132,9 @@ pub enum ClipboardFile {
|
|||||||
requested_data: Vec<u8>,
|
requested_data: Vec<u8>,
|
||||||
},
|
},
|
||||||
TryEmpty,
|
TryEmpty,
|
||||||
|
Files {
|
||||||
|
files: Vec<(String, u64)>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MsgChannel {
|
struct MsgChannel {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use hbb_common::{
|
|||||||
log,
|
log,
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::{path::PathBuf, sync::Arc};
|
use std::{path::PathBuf, sync::Arc, usize};
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
// local files are cached, this value should not be changed when copying files
|
// local files are cached, this value should not be changed when copying files
|
||||||
@@ -34,6 +34,7 @@ enum FileContentsRequest {
|
|||||||
struct ClipFiles {
|
struct ClipFiles {
|
||||||
files: Vec<String>,
|
files: Vec<String>,
|
||||||
file_list: Vec<LocalFile>,
|
file_list: Vec<LocalFile>,
|
||||||
|
first_file_index: usize,
|
||||||
files_pdu: Vec<u8>,
|
files_pdu: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,6 +42,7 @@ impl ClipFiles {
|
|||||||
fn clear(&mut self) {
|
fn clear(&mut self) {
|
||||||
self.files.clear();
|
self.files.clear();
|
||||||
self.file_list.clear();
|
self.file_list.clear();
|
||||||
|
self.first_file_index = usize::MAX;
|
||||||
self.files_pdu.clear();
|
self.files_pdu.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,6 +52,11 @@ impl ClipFiles {
|
|||||||
.map(|s| PathBuf::from(s))
|
.map(|s| PathBuf::from(s))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
self.file_list = construct_file_list(&clipboard_paths)?;
|
self.file_list = construct_file_list(&clipboard_paths)?;
|
||||||
|
self.first_file_index = self
|
||||||
|
.file_list
|
||||||
|
.iter()
|
||||||
|
.position(|f| !f.path.is_dir())
|
||||||
|
.unwrap_or(usize::MAX);
|
||||||
self.files = clipboard_files.to_vec();
|
self.files = clipboard_files.to_vec();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -63,6 +70,33 @@ impl ClipFiles {
|
|||||||
self.files_pdu = data.to_vec()
|
self.files_pdu = data.to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_files_for_audit(&self, request: &FileContentsRequest) -> Option<ClipboardFile> {
|
||||||
|
if let FileContentsRequest::Range {
|
||||||
|
file_idx, offset, ..
|
||||||
|
} = request
|
||||||
|
{
|
||||||
|
if *file_idx == self.first_file_index && *offset == 0 {
|
||||||
|
let files: Vec<(String, u64)> = self
|
||||||
|
.file_list
|
||||||
|
.iter()
|
||||||
|
.filter_map(|f| {
|
||||||
|
if f.path.is_file() {
|
||||||
|
Some((f.path.to_string_lossy().to_string(), f.size))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<_>();
|
||||||
|
if files.is_empty() {
|
||||||
|
return None;
|
||||||
|
} else {
|
||||||
|
return Some(ClipboardFile::Files { files });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn serve_file_contents(
|
fn serve_file_contents(
|
||||||
&mut self,
|
&mut self,
|
||||||
conn_id: i32,
|
conn_id: i32,
|
||||||
@@ -192,7 +226,7 @@ pub fn read_file_contents(
|
|||||||
n_position_low: i32,
|
n_position_low: i32,
|
||||||
n_position_high: i32,
|
n_position_high: i32,
|
||||||
cb_requested: i32,
|
cb_requested: i32,
|
||||||
) -> Result<ClipboardFile, CliprdrError> {
|
) -> Vec<Result<ClipboardFile, CliprdrError>> {
|
||||||
let fcr = if dw_flags == 0x1 {
|
let fcr = if dw_flags == 0x1 {
|
||||||
FileContentsRequest::Size {
|
FileContentsRequest::Size {
|
||||||
stream_id,
|
stream_id,
|
||||||
@@ -209,12 +243,18 @@ pub fn read_file_contents(
|
|||||||
length,
|
length,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(CliprdrError::InvalidRequest {
|
return vec![Err(CliprdrError::InvalidRequest {
|
||||||
description: format!("got invalid FileContentsRequest, dw_flats: {dw_flags}"),
|
description: format!("got invalid FileContentsRequest, dw_flats: {dw_flags}"),
|
||||||
});
|
})];
|
||||||
};
|
};
|
||||||
|
|
||||||
CLIP_FILES.lock().serve_file_contents(conn_id, fcr)
|
let mut clip_files = CLIP_FILES.lock();
|
||||||
|
let mut res = vec![];
|
||||||
|
if let Some(files_res) = clip_files.get_files_for_audit(&fcr) {
|
||||||
|
res.push(Ok(files_res));
|
||||||
|
}
|
||||||
|
res.push(clip_files.serve_file_contents(conn_id, fcr));
|
||||||
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync_files(files: &[String]) -> Result<(), CliprdrError> {
|
pub fn sync_files(files: &[String]) -> Result<(), CliprdrError> {
|
||||||
|
|||||||
@@ -381,6 +381,9 @@ pub type pcCliprdrTempDirectory = ::std::option::Option<
|
|||||||
pub type pcNotifyClipboardMsg = ::std::option::Option<
|
pub type pcNotifyClipboardMsg = ::std::option::Option<
|
||||||
unsafe extern "C" fn(connID: UINT32, msg: *const NOTIFICATION_MESSAGE) -> UINT,
|
unsafe extern "C" fn(connID: UINT32, msg: *const NOTIFICATION_MESSAGE) -> UINT,
|
||||||
>;
|
>;
|
||||||
|
pub type pcHandleClipboardFiles = ::std::option::Option<
|
||||||
|
unsafe extern "C" fn(connID: UINT32, nFiles: size_t, fileNames: *mut *mut WCHAR) -> UINT,
|
||||||
|
>;
|
||||||
pub type pcCliprdrClientFormatList = ::std::option::Option<
|
pub type pcCliprdrClientFormatList = ::std::option::Option<
|
||||||
unsafe extern "C" fn(
|
unsafe extern "C" fn(
|
||||||
context: *mut CliprdrClientContext,
|
context: *mut CliprdrClientContext,
|
||||||
@@ -492,6 +495,7 @@ pub struct _cliprdr_client_context {
|
|||||||
pub MonitorReady: pcCliprdrMonitorReady,
|
pub MonitorReady: pcCliprdrMonitorReady,
|
||||||
pub TempDirectory: pcCliprdrTempDirectory,
|
pub TempDirectory: pcCliprdrTempDirectory,
|
||||||
pub NotifyClipboardMsg: pcNotifyClipboardMsg,
|
pub NotifyClipboardMsg: pcNotifyClipboardMsg,
|
||||||
|
pub HandleClipboardFiles: pcHandleClipboardFiles,
|
||||||
pub ClientFormatList: pcCliprdrClientFormatList,
|
pub ClientFormatList: pcCliprdrClientFormatList,
|
||||||
pub ServerFormatList: pcCliprdrServerFormatList,
|
pub ServerFormatList: pcCliprdrServerFormatList,
|
||||||
pub ClientFormatListResponse: pcCliprdrClientFormatListResponse,
|
pub ClientFormatListResponse: pcCliprdrClientFormatListResponse,
|
||||||
@@ -529,6 +533,7 @@ impl CliprdrClientContext {
|
|||||||
enable_others: bool,
|
enable_others: bool,
|
||||||
response_wait_timeout_secs: u32,
|
response_wait_timeout_secs: u32,
|
||||||
notify_callback: pcNotifyClipboardMsg,
|
notify_callback: pcNotifyClipboardMsg,
|
||||||
|
handle_clipboard_files: pcHandleClipboardFiles,
|
||||||
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,
|
||||||
@@ -547,6 +552,7 @@ impl CliprdrClientContext {
|
|||||||
MonitorReady: None,
|
MonitorReady: None,
|
||||||
TempDirectory: None,
|
TempDirectory: None,
|
||||||
NotifyClipboardMsg: notify_callback,
|
NotifyClipboardMsg: notify_callback,
|
||||||
|
HandleClipboardFiles: handle_clipboard_files,
|
||||||
ClientFormatList: client_format_list,
|
ClientFormatList: client_format_list,
|
||||||
ServerFormatList: None,
|
ServerFormatList: None,
|
||||||
ClientFormatListResponse: client_format_list_response,
|
ClientFormatListResponse: client_format_list_response,
|
||||||
@@ -758,6 +764,9 @@ pub fn server_clip_file(
|
|||||||
ret
|
ret
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
ClipboardFile::Files { .. } => {
|
||||||
|
// unreachable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
@@ -967,6 +976,7 @@ pub fn create_cliprdr_context(
|
|||||||
enable_others,
|
enable_others,
|
||||||
response_wait_timeout_secs,
|
response_wait_timeout_secs,
|
||||||
Some(notify_callback),
|
Some(notify_callback),
|
||||||
|
Some(handle_clipboard_files),
|
||||||
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),
|
||||||
@@ -1021,6 +1031,61 @@ extern "C" fn notify_callback(conn_id: UINT32, msg: *const NOTIFICATION_MESSAGE)
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" fn handle_clipboard_files(
|
||||||
|
conn_id: UINT32,
|
||||||
|
n_files: size_t,
|
||||||
|
file_names: *mut *mut WCHAR,
|
||||||
|
) -> UINT {
|
||||||
|
if n_files == 0 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = unsafe {
|
||||||
|
let mut files = Vec::new();
|
||||||
|
use std::ffi::OsString;
|
||||||
|
use std::os::windows::ffi::OsStringExt;
|
||||||
|
for i in 0..n_files {
|
||||||
|
let file_name_ptr = *file_names.offset(i as isize);
|
||||||
|
if !file_name_ptr.is_null() {
|
||||||
|
let mut len = 0;
|
||||||
|
while *file_name_ptr.offset(len) != 0 {
|
||||||
|
len += 1;
|
||||||
|
}
|
||||||
|
let slice = std::slice::from_raw_parts(file_name_ptr, len as usize);
|
||||||
|
let os_string = OsString::from_wide(slice);
|
||||||
|
match os_string.to_str() {
|
||||||
|
Some(n) => match std::fs::metadata(n) {
|
||||||
|
Ok(meta) => {
|
||||||
|
if meta.is_file() {
|
||||||
|
files.push((n.to_owned(), meta.len()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!(
|
||||||
|
"handle_clipboard_files: Failed to get metadata for file '{}': {}",
|
||||||
|
n,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
log::warn!("handle_clipboard_files: Failed to convert file name to UTF-8");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if files.is_empty() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClipboardFile::Files { files }
|
||||||
|
};
|
||||||
|
// no need to handle result here
|
||||||
|
allow_err!(send_data(conn_id as _, data));
|
||||||
|
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
|||||||
@@ -239,6 +239,7 @@ struct wf_clipboard
|
|||||||
size_t nFiles;
|
size_t nFiles;
|
||||||
size_t file_array_size;
|
size_t file_array_size;
|
||||||
WCHAR **file_names;
|
WCHAR **file_names;
|
||||||
|
size_t first_file_index;
|
||||||
FILEDESCRIPTORW **fileDescriptor;
|
FILEDESCRIPTORW **fileDescriptor;
|
||||||
|
|
||||||
BOOL legacyApi;
|
BOOL legacyApi;
|
||||||
@@ -2024,6 +2025,7 @@ static void clear_file_array(wfClipboard *clipboard)
|
|||||||
|
|
||||||
clipboard->file_array_size = 0;
|
clipboard->file_array_size = 0;
|
||||||
clipboard->nFiles = 0;
|
clipboard->nFiles = 0;
|
||||||
|
clipboard->first_file_index = (size_t)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL wf_cliprdr_get_file_contents(WCHAR *file_name, BYTE *buffer, LONG positionLow,
|
static BOOL wf_cliprdr_get_file_contents(WCHAR *file_name, BYTE *buffer, LONG positionLow,
|
||||||
@@ -2179,6 +2181,11 @@ static BOOL wf_cliprdr_add_to_file_arrays(wfClipboard *clipboard, WCHAR *full_fi
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((clipboard->fileDescriptor[clipboard->nFiles]->dwFileAttributes &
|
||||||
|
FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
||||||
|
clipboard->first_file_index = clipboard->nFiles;
|
||||||
|
}
|
||||||
|
|
||||||
clipboard->nFiles++;
|
clipboard->nFiles++;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -2968,6 +2975,14 @@ wf_cliprdr_server_file_contents_request(CliprdrClientContext *context,
|
|||||||
{
|
{
|
||||||
LARGE_INTEGER dlibMove;
|
LARGE_INTEGER dlibMove;
|
||||||
ULARGE_INTEGER dlibNewPosition;
|
ULARGE_INTEGER dlibNewPosition;
|
||||||
|
|
||||||
|
if (clipboard->nFiles > 0 &&
|
||||||
|
fileContentsRequest->listIndex == (UINT32)clipboard->first_file_index &&
|
||||||
|
fileContentsRequest->nPositionLow == 0 &&
|
||||||
|
fileContentsRequest->nPositionHigh == 0) {
|
||||||
|
clipboard->context->HandleClipboardFiles(fileContentsRequest->connID, clipboard->nFiles, clipboard->file_names);
|
||||||
|
}
|
||||||
|
|
||||||
dlibMove.HighPart = fileContentsRequest->nPositionHigh;
|
dlibMove.HighPart = fileContentsRequest->nPositionHigh;
|
||||||
dlibMove.LowPart = fileContentsRequest->nPositionLow;
|
dlibMove.LowPart = fileContentsRequest->nPositionLow;
|
||||||
hRet = IStream_Seek(pStreamStc, dlibMove, STREAM_SEEK_SET, &dlibNewPosition);
|
hRet = IStream_Seek(pStreamStc, dlibMove, STREAM_SEEK_SET, &dlibNewPosition);
|
||||||
@@ -2999,6 +3014,13 @@ wf_cliprdr_server_file_contents_request(CliprdrClientContext *context,
|
|||||||
rc = ERROR_INTERNAL_ERROR;
|
rc = ERROR_INTERNAL_ERROR;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clipboard->nFiles > 0 &&
|
||||||
|
fileContentsRequest->listIndex == (UINT32)clipboard->first_file_index &&
|
||||||
|
fileContentsRequest->nPositionLow == 0 &&
|
||||||
|
fileContentsRequest->nPositionHigh == 0) {
|
||||||
|
clipboard->context->HandleClipboardFiles(fileContentsRequest->connID, clipboard->nFiles, clipboard->file_names);
|
||||||
|
}
|
||||||
bRet = wf_cliprdr_get_file_contents(
|
bRet = wf_cliprdr_get_file_contents(
|
||||||
clipboard->file_names[fileContentsRequest->listIndex], pData,
|
clipboard->file_names[fileContentsRequest->listIndex], pData,
|
||||||
fileContentsRequest->nPositionLow, fileContentsRequest->nPositionHigh, cbRequested,
|
fileContentsRequest->nPositionLow, fileContentsRequest->nPositionHigh, cbRequested,
|
||||||
|
|||||||
Submodule libs/hbb_common updated: 024380d0f9...221c2bfb3e
@@ -2257,7 +2257,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
}
|
}
|
||||||
#[cfg(feature = "unix-file-copy-paste")]
|
#[cfg(feature = "unix-file-copy-paste")]
|
||||||
if crate::is_support_file_copy_paste_num(self.handler.lc.read().unwrap().version) {
|
if crate::is_support_file_copy_paste_num(self.handler.lc.read().unwrap().version) {
|
||||||
let mut out_msg = None;
|
let mut out_msgs = vec![];
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
if clipboard::platform::unix::macos::should_handle_msg(&clip) {
|
if clipboard::platform::unix::macos::should_handle_msg(&clip) {
|
||||||
@@ -2269,7 +2269,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
log::error!("failed to handle cliprdr msg: {}", e);
|
log::error!("failed to handle cliprdr msg: {}", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out_msg = unix_file_clip::serve_clip_messages(
|
out_msgs = unix_file_clip::serve_clip_messages(
|
||||||
ClipboardSide::Client,
|
ClipboardSide::Client,
|
||||||
clip,
|
clip,
|
||||||
self.client_conn_id,
|
self.client_conn_id,
|
||||||
@@ -2278,14 +2278,14 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
{
|
{
|
||||||
out_msg = unix_file_clip::serve_clip_messages(
|
out_msgs = unix_file_clip::serve_clip_messages(
|
||||||
ClipboardSide::Client,
|
ClipboardSide::Client,
|
||||||
clip,
|
clip,
|
||||||
self.client_conn_id,
|
self.client_conn_id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(msg) = out_msg {
|
for msg in out_msgs.into_iter() {
|
||||||
allow_err!(_peer.send(&msg).await);
|
allow_err!(_peer.send(&msg).await);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,6 +143,40 @@ pub fn clip_2_msg(clip: ClipboardFile) -> Message {
|
|||||||
})),
|
})),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
ClipboardFile::Files { files } => {
|
||||||
|
let files = files
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(f, s)| {
|
||||||
|
if *s == 0 {
|
||||||
|
if let Ok(meta) = std::fs::metadata(f) {
|
||||||
|
Some(CliprdrFile {
|
||||||
|
name: f.to_owned(),
|
||||||
|
size: meta.len(),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Some(CliprdrFile {
|
||||||
|
name: f.to_owned(),
|
||||||
|
size: *s,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
Message {
|
||||||
|
union: Some(message::Union::Cliprdr(Cliprdr {
|
||||||
|
union: Some(cliprdr::Union::Files(CliprdrFiles {
|
||||||
|
files,
|
||||||
|
..Default::default()
|
||||||
|
})),
|
||||||
|
..Default::default()
|
||||||
|
})),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +277,7 @@ pub mod unix_file_clip {
|
|||||||
side: ClipboardSide,
|
side: ClipboardSide,
|
||||||
clip: ClipboardFile,
|
clip: ClipboardFile,
|
||||||
conn_id: i32,
|
conn_id: i32,
|
||||||
) -> Option<Message> {
|
) -> Vec<Message> {
|
||||||
log::debug!("got clipfile from client peer");
|
log::debug!("got clipfile from client peer");
|
||||||
match clip {
|
match clip {
|
||||||
ClipboardFile::MonitorReady => {
|
ClipboardFile::MonitorReady => {
|
||||||
@@ -257,7 +291,7 @@ pub mod unix_file_clip {
|
|||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
log::error!("no file contents format found");
|
log::error!("no file contents format found");
|
||||||
return None;
|
return vec![];
|
||||||
};
|
};
|
||||||
let Some(file_descriptor_id) = format_list
|
let Some(file_descriptor_id) = format_list
|
||||||
.iter()
|
.iter()
|
||||||
@@ -265,13 +299,13 @@ pub mod unix_file_clip {
|
|||||||
.map(|(id, _)| *id)
|
.map(|(id, _)| *id)
|
||||||
else {
|
else {
|
||||||
log::error!("no file descriptor format found");
|
log::error!("no file descriptor format found");
|
||||||
return None;
|
return vec![];
|
||||||
};
|
};
|
||||||
// sync file system from peer
|
// sync file system from peer
|
||||||
let data = ClipboardFile::FormatDataRequest {
|
let data = ClipboardFile::FormatDataRequest {
|
||||||
requested_format_id: file_descriptor_id,
|
requested_format_id: file_descriptor_id,
|
||||||
};
|
};
|
||||||
return Some(clip_2_msg(data));
|
return vec![clip_2_msg(data)];
|
||||||
}
|
}
|
||||||
ClipboardFile::FormatListResponse {
|
ClipboardFile::FormatListResponse {
|
||||||
msg_flags: _msg_flags,
|
msg_flags: _msg_flags,
|
||||||
@@ -282,13 +316,13 @@ pub mod unix_file_clip {
|
|||||||
log::debug!("requested format id: {}", _requested_format_id);
|
log::debug!("requested format id: {}", _requested_format_id);
|
||||||
let format_data = serv_files::get_file_list_pdu();
|
let format_data = serv_files::get_file_list_pdu();
|
||||||
if !format_data.is_empty() {
|
if !format_data.is_empty() {
|
||||||
return Some(clip_2_msg(ClipboardFile::FormatDataResponse {
|
return vec![clip_2_msg(ClipboardFile::FormatDataResponse {
|
||||||
msg_flags: 1,
|
msg_flags: 1,
|
||||||
format_data,
|
format_data,
|
||||||
}));
|
})];
|
||||||
}
|
}
|
||||||
// empty file list, send failure message
|
// empty file list, send failure message
|
||||||
return Some(msg_resp_format_data_failure());
|
return vec![msg_resp_format_data_failure()];
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
ClipboardFile::FormatDataResponse {
|
ClipboardFile::FormatDataResponse {
|
||||||
@@ -329,7 +363,7 @@ pub mod unix_file_clip {
|
|||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
log::debug!("file contents request: stream_id: {}, list_index: {}, dw_flags: {}, n_position_low: {}, n_position_high: {}, cb_requested: {}", stream_id, list_index, dw_flags, n_position_low, n_position_high, cb_requested);
|
log::debug!("file contents request: stream_id: {}, list_index: {}, dw_flags: {}, n_position_low: {}, n_position_high: {}, cb_requested: {}", stream_id, list_index, dw_flags, n_position_low, n_position_high, cb_requested);
|
||||||
match serv_files::read_file_contents(
|
return serv_files::read_file_contents(
|
||||||
conn_id,
|
conn_id,
|
||||||
stream_id,
|
stream_id,
|
||||||
list_index,
|
list_index,
|
||||||
@@ -337,15 +371,16 @@ pub mod unix_file_clip {
|
|||||||
n_position_low,
|
n_position_low,
|
||||||
n_position_high,
|
n_position_high,
|
||||||
cb_requested,
|
cb_requested,
|
||||||
) {
|
)
|
||||||
Ok(data) => {
|
.into_iter()
|
||||||
return Some(clip_2_msg(data));
|
.map(|res| match res {
|
||||||
}
|
Ok(data) => clip_2_msg(data),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("failed to read file contents: {:?}", e);
|
log::error!("failed to read file contents: {:?}", e);
|
||||||
return Some(resp_file_contents_fail(stream_id));
|
resp_file_contents_fail(stream_id)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
.collect::<_>();
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
ClipboardFile::FileContentsResponse {
|
ClipboardFile::FileContentsResponse {
|
||||||
@@ -387,6 +422,6 @@ pub mod unix_file_clip {
|
|||||||
log::error!("unsupported clipboard file type");
|
log::error!("unsupported clipboard file type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
vec![]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -633,7 +633,22 @@ impl Connection {
|
|||||||
}
|
}
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
ipc::Data::ClipboardFile(clip) => {
|
ipc::Data::ClipboardFile(clip) => {
|
||||||
allow_err!(conn.stream.send(&clip_2_msg(clip)).await);
|
match clip {
|
||||||
|
clipboard::ClipboardFile::Files { files } => {
|
||||||
|
let files = files.into_iter().map(|(f, s)| {
|
||||||
|
(f, s as i64)
|
||||||
|
}).collect::<Vec<_>>();
|
||||||
|
conn.post_file_audit(
|
||||||
|
FileAuditType::RemoteSend,
|
||||||
|
"",
|
||||||
|
files,
|
||||||
|
json!({}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
allow_err!(conn.stream.send(&clip_2_msg(clip)).await);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ipc::Data::PrivacyModeState((_, state, impl_key)) => {
|
ipc::Data::PrivacyModeState((_, state, impl_key)) => {
|
||||||
let msg_out = match state {
|
let msg_out = match state {
|
||||||
@@ -2463,14 +2478,25 @@ impl Connection {
|
|||||||
}
|
}
|
||||||
#[cfg(any(target_os = "windows", feature = "unix-file-copy-paste"))]
|
#[cfg(any(target_os = "windows", feature = "unix-file-copy-paste"))]
|
||||||
Some(message::Union::Cliprdr(clip)) => {
|
Some(message::Union::Cliprdr(clip)) => {
|
||||||
if let Some(clip) = msg_2_clip(clip) {
|
if let Some(cliprdr::Union::Files(files)) = &clip.union {
|
||||||
|
self.post_file_audit(
|
||||||
|
FileAuditType::RemoteReceive,
|
||||||
|
"",
|
||||||
|
files
|
||||||
|
.files
|
||||||
|
.iter()
|
||||||
|
.map(|f| (f.name.clone(), f.size as i64))
|
||||||
|
.collect::<Vec<(String, i64)>>(),
|
||||||
|
json!({}),
|
||||||
|
);
|
||||||
|
} else if let Some(clip) = msg_2_clip(clip) {
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
self.send_to_cm(ipc::Data::ClipboardFile(clip));
|
self.send_to_cm(ipc::Data::ClipboardFile(clip));
|
||||||
}
|
}
|
||||||
#[cfg(feature = "unix-file-copy-paste")]
|
#[cfg(feature = "unix-file-copy-paste")]
|
||||||
if crate::is_support_file_copy_paste(&self.lr.version) {
|
if crate::is_support_file_copy_paste(&self.lr.version) {
|
||||||
let mut out_msg = None;
|
let mut out_msgs = vec![];
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
if clipboard::platform::unix::macos::should_handle_msg(&clip) {
|
if clipboard::platform::unix::macos::should_handle_msg(&clip) {
|
||||||
@@ -2485,7 +2511,7 @@ impl Connection {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out_msg = unix_file_clip::serve_clip_messages(
|
out_msgs = unix_file_clip::serve_clip_messages(
|
||||||
ClipboardSide::Host,
|
ClipboardSide::Host,
|
||||||
clip,
|
clip,
|
||||||
self.inner.id(),
|
self.inner.id(),
|
||||||
@@ -2494,14 +2520,31 @@ impl Connection {
|
|||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
{
|
{
|
||||||
out_msg = unix_file_clip::serve_clip_messages(
|
out_msgs = unix_file_clip::serve_clip_messages(
|
||||||
ClipboardSide::Host,
|
ClipboardSide::Host,
|
||||||
clip,
|
clip,
|
||||||
self.inner.id(),
|
self.inner.id(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(msg) = out_msg {
|
for msg in out_msgs.into_iter() {
|
||||||
|
if let Some(message::Union::Cliprdr(cliprdr)) = msg.union.as_ref() {
|
||||||
|
if let Some(cliprdr::Union::Files(files)) =
|
||||||
|
cliprdr.union.as_ref()
|
||||||
|
{
|
||||||
|
self.post_file_audit(
|
||||||
|
FileAuditType::RemoteSend,
|
||||||
|
"",
|
||||||
|
files
|
||||||
|
.files
|
||||||
|
.iter()
|
||||||
|
.map(|f| (f.name.clone(), f.size as i64))
|
||||||
|
.collect::<Vec<(String, i64)>>(),
|
||||||
|
json!({}),
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
self.send(msg).await;
|
self.send(msg).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user