avoid waiting too long if the clipboard message is blocked
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
5a8c2d9cd0
commit
733e4236c4
@ -194,10 +194,11 @@ extern "C"
|
||||
// TODO: hide more members of clipboard context
|
||||
struct _cliprdr_client_context
|
||||
{
|
||||
void *custom;
|
||||
BOOL enableFiles;
|
||||
BOOL enableOthers;
|
||||
void *Custom;
|
||||
BOOL EnableFiles;
|
||||
BOOL EnableOthers;
|
||||
|
||||
BOOL IsStopped;
|
||||
pcCliprdrServerCapabilities ServerCapabilities;
|
||||
pcCliprdrClientCapabilities ClientCapabilities;
|
||||
pcCliprdrMonitorReady MonitorReady;
|
||||
@ -219,7 +220,7 @@ extern "C"
|
||||
pcCliprdrClientFileContentsResponse ClientFileContentsResponse;
|
||||
pcCliprdrServerFileContentsResponse ServerFileContentsResponse;
|
||||
|
||||
UINT32 lastRequestedFormatId;
|
||||
UINT32 LastRequestedFormatId;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -449,9 +449,10 @@ pub type pcCliprdrServerFileContentsResponse = ::std::option::Option<
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct _cliprdr_client_context {
|
||||
pub custom: *mut ::std::os::raw::c_void,
|
||||
pub enableFiles: BOOL,
|
||||
pub enableOthers: BOOL,
|
||||
pub Custom: *mut ::std::os::raw::c_void,
|
||||
pub EnableFiles: BOOL,
|
||||
pub EnableOthers: BOOL,
|
||||
pub IsStopped: BOOL,
|
||||
pub ServerCapabilities: pcCliprdrServerCapabilities,
|
||||
pub ClientCapabilities: pcCliprdrClientCapabilities,
|
||||
pub MonitorReady: pcCliprdrMonitorReady,
|
||||
@ -472,7 +473,7 @@ pub struct _cliprdr_client_context {
|
||||
pub ServerFileContentsRequest: pcCliprdrServerFileContentsRequest,
|
||||
pub ClientFileContentsResponse: pcCliprdrClientFileContentsResponse,
|
||||
pub ServerFileContentsResponse: pcCliprdrServerFileContentsResponse,
|
||||
pub lastRequestedFormatId: UINT32,
|
||||
pub LastRequestedFormatId: UINT32,
|
||||
}
|
||||
|
||||
// #[link(name = "user32")]
|
||||
@ -480,10 +481,7 @@ pub struct _cliprdr_client_context {
|
||||
extern "C" {
|
||||
pub(crate) fn init_cliprdr(context: *mut CliprdrClientContext) -> BOOL;
|
||||
pub(crate) fn uninit_cliprdr(context: *mut CliprdrClientContext) -> BOOL;
|
||||
pub(crate) fn empty_cliprdr(
|
||||
context: *mut CliprdrClientContext,
|
||||
connID: UINT32,
|
||||
) -> BOOL;
|
||||
pub(crate) fn empty_cliprdr(context: *mut CliprdrClientContext, connID: UINT32) -> BOOL;
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
@ -508,9 +506,10 @@ impl CliprdrClientContext {
|
||||
client_file_contents_response: pcCliprdrClientFileContentsResponse,
|
||||
) -> Result<Box<Self>, CliprdrError> {
|
||||
let context = CliprdrClientContext {
|
||||
custom: 0 as *mut _,
|
||||
enableFiles: if enable_files { TRUE } else { FALSE },
|
||||
enableOthers: if enable_others { TRUE } else { FALSE },
|
||||
Custom: 0 as *mut _,
|
||||
EnableFiles: if enable_files { TRUE } else { FALSE },
|
||||
EnableOthers: if enable_others { TRUE } else { FALSE },
|
||||
IsStopped: FALSE,
|
||||
ServerCapabilities: None,
|
||||
ClientCapabilities: None,
|
||||
MonitorReady: None,
|
||||
@ -531,7 +530,7 @@ impl CliprdrClientContext {
|
||||
ServerFileContentsRequest: None,
|
||||
ClientFileContentsResponse: client_file_contents_response,
|
||||
ServerFileContentsResponse: None,
|
||||
lastRequestedFormatId: 0,
|
||||
LastRequestedFormatId: 0,
|
||||
};
|
||||
let mut context = Box::new(context);
|
||||
unsafe {
|
||||
|
@ -24,6 +24,13 @@ impl ContextSend {
|
||||
CONTEXT_SEND.lock().unwrap().cm_enabled
|
||||
}
|
||||
|
||||
pub fn set_is_stopped() {
|
||||
let _res = Self::proc(|c| {
|
||||
c.IsStopped = TRUE;
|
||||
0
|
||||
});
|
||||
}
|
||||
|
||||
pub fn enable(enabled: bool, is_cm_side: bool, is_server_process: bool) {
|
||||
let mut lock = CONTEXT_SEND.lock().unwrap();
|
||||
if enabled {
|
||||
|
@ -1,3 +1,5 @@
|
||||
// to-do: TOO MANY compilation warnings. Fix them.
|
||||
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Windows Clipboard Redirection
|
||||
@ -136,11 +138,13 @@ typedef struct _FORMAT_IDS FORMAT_IDS;
|
||||
#define TAG "windows"
|
||||
|
||||
#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
|
||||
#define DEBUG_CLIPRDR(fmt, ...) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
@ -1440,6 +1444,55 @@ static UINT cliprdr_send_format_list(wfClipboard *clipboard, UINT32 connID)
|
||||
return rc;
|
||||
}
|
||||
|
||||
UINT wait_response_event(wfClipboard *clipboard, HANDLE event, void *data)
|
||||
{
|
||||
UINT rc = ERROR_INTERNAL_ERROR;
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
UINT rc;
|
||||
@ -1460,44 +1513,7 @@ static UINT cliprdr_send_data_request(UINT32 connID, wfClipboard *clipboard, UIN
|
||||
return rc;
|
||||
}
|
||||
|
||||
// with default 3min timeout
|
||||
for (int i = 0; i < 20 * 60 * 3; i++)
|
||||
{
|
||||
DWORD waitRes = WaitForSingleObject(clipboard->response_data_event, 50);
|
||||
if (waitRes == WAIT_TIMEOUT)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
wait_response_event(clipboard, clipboard->response_data_event, clipboard->hmem);
|
||||
}
|
||||
|
||||
UINT cliprdr_send_request_filecontents(wfClipboard *clipboard, UINT32 connID, const void *streamid, ULONG index,
|
||||
@ -1525,43 +1541,7 @@ UINT cliprdr_send_request_filecontents(wfClipboard *clipboard, UINT32 connID, co
|
||||
return rc;
|
||||
}
|
||||
|
||||
// with default 3min timeout
|
||||
for (int i = 0; i < 20 * 60 * 3; i++)
|
||||
{
|
||||
DWORD waitRes = WaitForSingleObject(clipboard->req_fevent, 50);
|
||||
if (waitRes == WAIT_TIMEOUT)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
return wait_response_event(clipboard, clipboard->req_fevent, clipboard->req_fdata);
|
||||
}
|
||||
|
||||
static UINT cliprdr_send_response_filecontents(
|
||||
@ -2069,8 +2049,8 @@ static BOOL wf_cliprdr_traverse_directory(wfClipboard *clipboard, WCHAR *Dir, si
|
||||
while (FindNextFileW(hFind, &FindFileData))
|
||||
{
|
||||
// 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 &&
|
||||
wcscmp(FindFileData.cFileName, L".") == 0 ||
|
||||
wcscmp(FindFileData.cFileName, L"..") == 0)
|
||||
@ -2123,7 +2103,8 @@ static UINT wf_cliprdr_send_client_capabilities(wfClipboard *clipboard)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
|
||||
// Ignore ClientCapabilities for now
|
||||
if (!clipboard->context->ClientCapabilities) {
|
||||
if (!clipboard->context->ClientCapabilities)
|
||||
{
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
@ -2147,7 +2128,7 @@ static UINT wf_cliprdr_monitor_ready(CliprdrClientContext *context,
|
||||
const CLIPRDR_MONITOR_READY *monitorReady)
|
||||
{
|
||||
UINT rc;
|
||||
wfClipboard *clipboard = (wfClipboard *)context->custom;
|
||||
wfClipboard *clipboard = (wfClipboard *)context->Custom;
|
||||
|
||||
if (!context || !monitorReady)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
@ -2171,7 +2152,7 @@ static UINT wf_cliprdr_server_capabilities(CliprdrClientContext *context,
|
||||
{
|
||||
UINT32 index;
|
||||
CLIPRDR_CAPABILITY_SET *capabilitySet;
|
||||
wfClipboard *clipboard = (wfClipboard *)context->custom;
|
||||
wfClipboard *clipboard = (wfClipboard *)context->Custom;
|
||||
|
||||
if (!context || !capabilities)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
@ -2205,7 +2186,7 @@ static UINT wf_cliprdr_server_format_list(CliprdrClientContext *context,
|
||||
UINT32 i;
|
||||
formatMapping *mapping;
|
||||
CLIPRDR_FORMAT *format;
|
||||
wfClipboard *clipboard = (wfClipboard *)context->custom;
|
||||
wfClipboard *clipboard = (wfClipboard *)context->Custom;
|
||||
|
||||
if (!clear_format_map(clipboard))
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
@ -2241,7 +2222,7 @@ static UINT wf_cliprdr_server_format_list(CliprdrClientContext *context,
|
||||
|
||||
if (file_transferring(clipboard))
|
||||
{
|
||||
if (context->enableFiles)
|
||||
if (context->EnableFiles)
|
||||
{
|
||||
UINT32 *p_conn_id = (UINT32 *)calloc(1, sizeof(UINT32));
|
||||
*p_conn_id = formatList->connID;
|
||||
@ -2255,7 +2236,7 @@ static UINT wf_cliprdr_server_format_list(CliprdrClientContext *context,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (context->enableOthers)
|
||||
if (context->EnableOthers)
|
||||
{
|
||||
if (!try_open_clipboard(clipboard->hwnd))
|
||||
return CHANNEL_RC_OK; /* Ignore, other app holding clipboard */
|
||||
@ -2264,7 +2245,7 @@ static UINT wf_cliprdr_server_format_list(CliprdrClientContext *context,
|
||||
{
|
||||
// Modified: do not apply delayed rendering
|
||||
// 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->connID = formatList->connID;
|
||||
@ -2399,7 +2380,7 @@ wf_cliprdr_server_format_data_request(CliprdrClientContext *context,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
clipboard = (wfClipboard *)context->custom;
|
||||
clipboard = (wfClipboard *)context->Custom;
|
||||
|
||||
if (!clipboard)
|
||||
{
|
||||
@ -2579,7 +2560,7 @@ wf_cliprdr_server_format_data_response(CliprdrClientContext *context,
|
||||
break;
|
||||
}
|
||||
|
||||
clipboard = (wfClipboard *)context->custom;
|
||||
clipboard = (wfClipboard *)context->Custom;
|
||||
if (!clipboard)
|
||||
{
|
||||
rc = ERROR_INTERNAL_ERROR;
|
||||
@ -2660,7 +2641,7 @@ wf_cliprdr_server_file_contents_request(CliprdrClientContext *context,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
clipboard = (wfClipboard *)context->custom;
|
||||
clipboard = (wfClipboard *)context->Custom;
|
||||
|
||||
if (!clipboard)
|
||||
{
|
||||
@ -2838,7 +2819,7 @@ exit:
|
||||
}
|
||||
|
||||
// if (sRc != CHANNEL_RC_OK)
|
||||
// return sRc;
|
||||
// return sRc;
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -2863,7 +2844,7 @@ wf_cliprdr_server_file_contents_response(CliprdrClientContext *context,
|
||||
break;
|
||||
}
|
||||
|
||||
clipboard = (wfClipboard *)context->custom;
|
||||
clipboard = (wfClipboard *)context->Custom;
|
||||
if (!clipboard)
|
||||
{
|
||||
rc = ERROR_INTERNAL_ERROR;
|
||||
@ -2951,7 +2932,7 @@ BOOL wf_cliprdr_init(wfClipboard *clipboard, CliprdrClientContext *cliprdr)
|
||||
cliprdr->ServerFormatDataResponse = wf_cliprdr_server_format_data_response;
|
||||
cliprdr->ServerFileContentsRequest = wf_cliprdr_server_file_contents_request;
|
||||
cliprdr->ServerFileContentsResponse = wf_cliprdr_server_file_contents_response;
|
||||
cliprdr->custom = (void *)clipboard;
|
||||
cliprdr->Custom = (void *)clipboard;
|
||||
return TRUE;
|
||||
error:
|
||||
wf_cliprdr_uninit(clipboard, cliprdr);
|
||||
@ -2963,7 +2944,7 @@ BOOL wf_cliprdr_uninit(wfClipboard *clipboard, CliprdrClientContext *cliprdr)
|
||||
if (!clipboard || !cliprdr)
|
||||
return FALSE;
|
||||
|
||||
cliprdr->custom = NULL;
|
||||
cliprdr->Custom = NULL;
|
||||
|
||||
/* discard all contexts in clipboard */
|
||||
if (try_open_clipboard(clipboard->hwnd))
|
||||
@ -3038,7 +3019,7 @@ BOOL empty_cliprdr(CliprdrClientContext *context, UINT32 connID)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
clipboard = (wfClipboard *)context->custom;
|
||||
clipboard = (wfClipboard *)context->Custom;
|
||||
if (!clipboard)
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -212,7 +212,9 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
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 {
|
||||
if stop {
|
||||
ContextSend::set_is_stopped();
|
||||
} else {
|
||||
allow_err!(peer.send(&crate::clipboard_file::clip_2_msg(clip)).await);
|
||||
}
|
||||
}
|
||||
|
@ -442,7 +442,9 @@ impl Connection {
|
||||
let file_transfer_enabled = conn.file_transfer_enabled();
|
||||
let stop = is_stopping_allowed && !file_transfer_enabled;
|
||||
log::debug!("Process clipboard message from cm, stop: {}, is_stopping_allowed: {}, file_transfer_enabled: {}", stop, is_stopping_allowed, file_transfer_enabled);
|
||||
if !stop {
|
||||
if stop {
|
||||
clipboard::ContextSend::set_is_stopped();
|
||||
} else {
|
||||
allow_err!(conn.stream.send(&clip_2_msg(clip)).await);
|
||||
}
|
||||
}
|
||||
|
@ -406,7 +406,9 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
||||
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 peer, stop: {}, is_stopping_allowed: {}, is_clipboard_enabled: {}, file_transfer_enabled: {}", stop, is_stopping_allowed, is_clipboard_enabled, file_transfer_enabled);
|
||||
if !stop {
|
||||
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)
|
||||
@ -461,7 +463,9 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
||||
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 cm, stop: {}, is_stopping_allowed: {}, is_clipboard_enabled: {}, file_transfer_enabled: {}", stop, is_stopping_allowed, is_clipboard_enabled, file_transfer_enabled);
|
||||
if !stop {
|
||||
if stop {
|
||||
ContextSend::set_is_stopped();
|
||||
} else {
|
||||
allow_err!(self.tx.send(Data::ClipboardFile(_clip)));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user