mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-02-17 14:07:28 +08:00
fix: win, file clipboard, try empty (#10609)
Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
@@ -107,6 +107,7 @@ pub enum ClipboardFile {
|
||||
stream_id: i32,
|
||||
requested_data: Vec<u8>,
|
||||
},
|
||||
TryEmpty,
|
||||
}
|
||||
|
||||
struct MsgChannel {
|
||||
@@ -226,6 +227,16 @@ fn send_data_to_channel(conn_id: i32, data: ClipboardFile) -> ResultType<()> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn send_data_exclude(conn_id: i32, data: ClipboardFile) {
|
||||
use hbb_common::log;
|
||||
for msg_channel in VEC_MSG_CHANNEL.read().unwrap().iter() {
|
||||
if msg_channel.conn_id != conn_id {
|
||||
allow_err!(msg_channel.sender.send(data.clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unix-file-copy-paste")]
|
||||
#[inline]
|
||||
fn send_data_to_all(data: ClipboardFile) -> ResultType<()> {
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
#![allow(deref_nullptr)]
|
||||
|
||||
use crate::{
|
||||
allow_err, send_data, ClipboardFile, CliprdrError, CliprdrServiceContext, ResultType,
|
||||
send_data, send_data_exclude, ClipboardFile, CliprdrError, CliprdrServiceContext, ResultType,
|
||||
ERR_CODE_INVALID_PARAMETER, ERR_CODE_SEND_MSG, ERR_CODE_SERVER_FUNCTION_NONE, VEC_MSG_CHANNEL,
|
||||
};
|
||||
use hbb_common::log;
|
||||
use hbb_common::{allow_err, log};
|
||||
use std::{
|
||||
boxed::Box,
|
||||
ffi::{CStr, CString},
|
||||
@@ -643,6 +643,7 @@ pub fn server_clip_file(
|
||||
conn_id,
|
||||
&format_list
|
||||
);
|
||||
send_data_exclude(conn_id as _, ClipboardFile::TryEmpty);
|
||||
ret = server_format_list(context, conn_id, format_list);
|
||||
log::debug!(
|
||||
"server_format_list called, conn_id {}, return {}",
|
||||
@@ -740,6 +741,11 @@ pub fn server_clip_file(
|
||||
ret
|
||||
);
|
||||
}
|
||||
ClipboardFile::TryEmpty => {
|
||||
log::debug!("empty_clipboard called");
|
||||
let ret = empty_clipboard(context, conn_id);
|
||||
log::debug!("empty_clipboard called, conn_id {}, return {}", conn_id, ret);
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
@@ -269,6 +269,7 @@ static UINT cliprdr_send_request_filecontents(wfClipboard *clipboard, UINT32 con
|
||||
DWORD positionlow, ULONG request);
|
||||
|
||||
static BOOL is_file_descriptor_from_remote();
|
||||
static BOOL is_set_by_instance(wfClipboard *clipboard);
|
||||
|
||||
static void CliprdrDataObject_Delete(CliprdrDataObject *instance);
|
||||
|
||||
@@ -600,8 +601,11 @@ static CliprdrStream *CliprdrStream_New(UINT32 connID, ULONG index, void *pData,
|
||||
clipboard->req_fdata = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
instance->m_lSize.QuadPart =
|
||||
((UINT64)instance->m_Dsc.nFileSizeHigh << 32) | instance->m_Dsc.nFileSizeLow;
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1745,8 +1749,7 @@ static LRESULT CALLBACK cliprdr_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM
|
||||
DEBUG_CLIPRDR("info: WM_CLIPBOARDUPDATE");
|
||||
// if (clipboard->sync)
|
||||
{
|
||||
if ((GetClipboardOwner() != clipboard->hwnd) &&
|
||||
(S_FALSE == OleIsCurrentClipboard(clipboard->data_obj)))
|
||||
if (!is_set_by_instance(clipboard))
|
||||
{
|
||||
if (clipboard->hmem)
|
||||
{
|
||||
@@ -2086,6 +2089,8 @@ static FILEDESCRIPTORW *wf_cliprdr_get_file_descriptor(WCHAR *file_name, size_t
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// to-do: use `fd->dwFlags = FD_ATTRIBUTES | FD_FILESIZE | FD_WRITESTIME | FD_PROGRESSUI`.
|
||||
// We keep `fd->dwFlags = FD_ATTRIBUTES | FD_WRITESTIME | FD_PROGRESSUI` for compatibility.
|
||||
// fd->dwFlags = FD_ATTRIBUTES | FD_FILESIZE | FD_WRITESTIME | FD_PROGRESSUI;
|
||||
fd->dwFlags = FD_ATTRIBUTES | FD_WRITESTIME | FD_PROGRESSUI;
|
||||
fd->dwFileAttributes = GetFileAttributesW(file_name);
|
||||
@@ -2849,6 +2854,31 @@ wf_cliprdr_server_file_contents_request(CliprdrClientContext *context,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// If the clipboard is set by the instance, or the file descriptor is from remote,
|
||||
// we should not process the request.
|
||||
// Because this may be the following cases:
|
||||
// 1. `A` -> `B`, `C`
|
||||
// 2. Copy in `A`
|
||||
// 3. Copy in `B`
|
||||
// 4. Paste in `C`
|
||||
// In this case, `C` should not get the file content from `A`. The clipboard is set by `B`.
|
||||
//
|
||||
// Or
|
||||
// 1. `B` -> `A` -> `C`
|
||||
// 2. Copy in `A`
|
||||
// 2. Copy in `B`
|
||||
// 3. Paste in `C`
|
||||
// In this case, `C` should not get the file content from `A`. The clipboard is set by `B`.
|
||||
//
|
||||
// We can simply notify `C` to clear the clipboard when `A` received copy message from `B`,
|
||||
// if connections are in the same process.
|
||||
// But if connections are in different processes, it is not easy to notify the other process.
|
||||
// So we just ignore the request from `C` in this case.
|
||||
if (is_set_by_instance(clipboard) || is_file_descriptor_from_remote()) {
|
||||
rc = ERROR_INTERNAL_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
cbRequested = fileContentsRequest->cbRequested;
|
||||
if (fileContentsRequest->dwFlags == FILECONTENTS_SIZE)
|
||||
cbRequested = sizeof(UINT64);
|
||||
@@ -3089,6 +3119,14 @@ wf_cliprdr_server_file_contents_response(CliprdrClientContext *context,
|
||||
return rc;
|
||||
}
|
||||
|
||||
BOOL is_set_by_instance(wfClipboard *clipboard)
|
||||
{
|
||||
if (GetClipboardOwner() == clipboard->hwnd || S_OK == OleIsCurrentClipboard(clipboard->data_obj)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL is_file_descriptor_from_remote()
|
||||
{
|
||||
UINT fsid = 0;
|
||||
@@ -3175,7 +3213,7 @@ BOOL wf_cliprdr_uninit(wfClipboard *clipboard, CliprdrClientContext *cliprdr)
|
||||
/* discard all contexts in clipboard */
|
||||
if (try_open_clipboard(clipboard->hwnd))
|
||||
{
|
||||
if (is_file_descriptor_from_remote())
|
||||
if (is_set_by_instance(clipboard) || is_file_descriptor_from_remote())
|
||||
{
|
||||
if (!EmptyClipboard())
|
||||
{
|
||||
|
||||
Submodule libs/hbb_common updated: 49c6b24a7a...79f8ac2d68
@@ -134,6 +134,15 @@ pub fn clip_2_msg(clip: ClipboardFile) -> Message {
|
||||
})),
|
||||
..Default::default()
|
||||
},
|
||||
ClipboardFile::TryEmpty => Message {
|
||||
union: Some(message::Union::Cliprdr(Cliprdr {
|
||||
union: Some(cliprdr::Union::TryEmpty(CliprdrTryEmpty {
|
||||
..Default::default()
|
||||
})),
|
||||
..Default::default()
|
||||
})),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,6 +185,7 @@ pub fn msg_2_clip(msg: Cliprdr) -> Option<ClipboardFile> {
|
||||
requested_data: data.requested_data.into(),
|
||||
})
|
||||
}
|
||||
Some(cliprdr::Union::TryEmpty(_)) => Some(ClipboardFile::TryEmpty),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user