fix hang up

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2022-02-24 02:32:29 +08:00
parent 128a4aca69
commit 01591d1abf
3 changed files with 303 additions and 112 deletions

View File

@ -605,11 +605,15 @@ extern "C" fn client_format_data_response(
server_conn_id = (*format_data_response).serverConnID as i32; server_conn_id = (*format_data_response).serverConnID as i32;
remote_conn_id = (*format_data_response).remoteConnID as i32; remote_conn_id = (*format_data_response).remoteConnID as i32;
msg_flags = (*format_data_response).msgFlags as i32; msg_flags = (*format_data_response).msgFlags as i32;
format_data = std::slice::from_raw_parts( if (*format_data_response).requestedFormatData.is_null() {
(*format_data_response).requestedFormatData, format_data = Vec::new();
(*format_data_response).dataLen as usize, } else {
) format_data = std::slice::from_raw_parts(
.to_vec(); (*format_data_response).requestedFormatData,
(*format_data_response).dataLen as usize,
)
.to_vec();
}
} }
let conn_id = ConnID { let conn_id = ConnID {
server_conn_id: server_conn_id as u32, server_conn_id: server_conn_id as u32,
@ -704,11 +708,15 @@ extern "C" fn client_file_contents_response(
remote_conn_id = (*file_contents_response).remoteConnID as i32; remote_conn_id = (*file_contents_response).remoteConnID as i32;
msg_flags = (*file_contents_response).msgFlags as i32; msg_flags = (*file_contents_response).msgFlags as i32;
stream_id = (*file_contents_response).streamId as i32; stream_id = (*file_contents_response).streamId as i32;
requested_data = std::slice::from_raw_parts( if (*file_contents_response).requestedData.is_null() {
(*file_contents_response).requestedData, requested_data = Vec::new();
(*file_contents_response).cbRequested as usize, } else {
) requested_data = std::slice::from_raw_parts(
.to_vec(); (*file_contents_response).requestedData,
(*file_contents_response).cbRequested as usize,
)
.to_vec();
}
} }
let conn_id = ConnID { let conn_id = ConnID {
server_conn_id: server_conn_id as u32, server_conn_id: server_conn_id as u32,

View File

@ -254,6 +254,7 @@ typedef struct wf_clipboard wfClipboard;
BOOL wf_cliprdr_init(wfClipboard *clipboard, CliprdrClientContext *cliprdr); BOOL wf_cliprdr_init(wfClipboard *clipboard, CliprdrClientContext *cliprdr);
BOOL wf_cliprdr_uninit(wfClipboard *clipboard, CliprdrClientContext *cliprdr); BOOL wf_cliprdr_uninit(wfClipboard *clipboard, CliprdrClientContext *cliprdr);
BOOL wf_do_empty_cliprdr(wfClipboard *clipboard);
static BOOL wf_create_file_obj(UINT32 serverConnID, UINT32 remoteConnID, wfClipboard *cliprdrrdr, IDataObject **ppDataObject); static BOOL wf_create_file_obj(UINT32 serverConnID, UINT32 remoteConnID, wfClipboard *cliprdrrdr, IDataObject **ppDataObject);
static void wf_destroy_file_obj(IDataObject *instance); static void wf_destroy_file_obj(IDataObject *instance);
@ -708,6 +709,10 @@ static HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetData(IDataObject *This, FO
{ {
return E_UNEXPECTED; return E_UNEXPECTED;
} }
if (!clipboard->hmem)
{
return E_UNEXPECTED;
}
pMedium->hGlobal = clipboard->hmem; /* points to a FILEGROUPDESCRIPTOR structure */ pMedium->hGlobal = clipboard->hmem; /* points to a FILEGROUPDESCRIPTOR structure */
/* GlobalLock returns a pointer to the first byte of the memory block, /* GlobalLock returns a pointer to the first byte of the memory block,
@ -1462,12 +1467,20 @@ static UINT cliprdr_send_data_request(UINT32 serverConnID, UINT32 remoteConnID,
return rc; return rc;
} }
while (clipboard->context->CheckEnabled(serverConnID, remoteConnID)) // with default 3min timeout
for (int i = 0; i < 20 * 60 * 3; i++)
{ {
DWORD waitRes = WaitForSingleObject(clipboard->response_data_event, 50); DWORD waitRes = WaitForSingleObject(clipboard->response_data_event, 50);
if (waitRes == WAIT_TIMEOUT) if (waitRes == WAIT_TIMEOUT)
{ {
continue; if (clipboard->context->CheckEnabled(serverConnID, remoteConnID))
{
continue;
}
else
{
break;
}
} }
if (waitRes != WAIT_OBJECT_0) if (waitRes != WAIT_OBJECT_0)
@ -1480,8 +1493,24 @@ static UINT cliprdr_send_data_request(UINT32 serverConnID, UINT32 remoteConnID,
// NOTE: critical error here, crash may be better // NOTE: critical error here, crash may be better
rc = ERROR_INTERNAL_ERROR; rc = ERROR_INTERNAL_ERROR;
} }
if (!clipboard->hmem)
{
rc = ERROR_INTERNAL_ERROR;
}
return rc; 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; return ERROR_INTERNAL_ERROR;
} }
@ -1511,12 +1540,20 @@ UINT cliprdr_send_request_filecontents(wfClipboard *clipboard, UINT32 serverConn
return rc; return rc;
} }
while (clipboard->context->CheckEnabled(serverConnID, remoteConnID)) // with default 3min timeout
for (int i = 0; i < 20 * 60 * 3; i++)
{ {
DWORD waitRes = WaitForSingleObject(clipboard->req_fevent, 50); DWORD waitRes = WaitForSingleObject(clipboard->req_fevent, 50);
if (waitRes == WAIT_TIMEOUT) if (waitRes == WAIT_TIMEOUT)
{ {
continue; if (clipboard->context->CheckEnabled(serverConnID, remoteConnID))
{
continue;
}
else
{
break;
}
} }
if (waitRes != WAIT_OBJECT_0) if (waitRes != WAIT_OBJECT_0)
@ -1529,25 +1566,50 @@ UINT cliprdr_send_request_filecontents(wfClipboard *clipboard, UINT32 serverConn
// NOTE: critical error here, crash may be better // NOTE: critical error here, crash may be better
rc = ERROR_INTERNAL_ERROR; rc = ERROR_INTERNAL_ERROR;
} }
if (!clipboard->req_fdata)
{
rc = ERROR_INTERNAL_ERROR;
}
return rc; 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 ERROR_INTERNAL_ERROR;
} }
static UINT cliprdr_send_response_filecontents(wfClipboard *clipboard, UINT32 serverConnID, UINT32 remoteConnID, UINT32 streamId, UINT32 size, static UINT cliprdr_send_response_filecontents(
BYTE *data) wfClipboard *clipboard,
UINT32 serverConnID,
UINT32 remoteConnID,
UINT16 msgFlags,
UINT32 streamId,
UINT32 size,
BYTE *data)
{ {
CLIPRDR_FILE_CONTENTS_RESPONSE fileContentsResponse; CLIPRDR_FILE_CONTENTS_RESPONSE fileContentsResponse;
if (!clipboard || !clipboard->context || !clipboard->context->ClientFileContentsResponse) if (!clipboard || !clipboard->context || !clipboard->context->ClientFileContentsResponse)
return ERROR_INTERNAL_ERROR; {
data = NULL;
size = 0;
msgFlags = CB_RESPONSE_FAIL;
}
fileContentsResponse.serverConnID = serverConnID; fileContentsResponse.serverConnID = serverConnID;
fileContentsResponse.remoteConnID = remoteConnID; fileContentsResponse.remoteConnID = remoteConnID;
fileContentsResponse.streamId = streamId; fileContentsResponse.streamId = streamId;
fileContentsResponse.cbRequested = size; fileContentsResponse.cbRequested = size;
fileContentsResponse.requestedData = data; fileContentsResponse.requestedData = data;
fileContentsResponse.msgFlags = CB_RESPONSE_OK; fileContentsResponse.msgFlags = msgFlags;
return clipboard->context->ClientFileContentsResponse(clipboard->context, return clipboard->context->ClientFileContentsResponse(clipboard->context,
&fileContentsResponse); &fileContentsResponse);
} }
@ -2343,7 +2405,7 @@ static UINT
wf_cliprdr_server_format_data_request(CliprdrClientContext *context, wf_cliprdr_server_format_data_request(CliprdrClientContext *context,
const CLIPRDR_FORMAT_DATA_REQUEST *formatDataRequest) const CLIPRDR_FORMAT_DATA_REQUEST *formatDataRequest)
{ {
UINT rc; UINT rc = ERROR_SUCCESS;
size_t size = 0; size_t size = 0;
void *buff = NULL; void *buff = NULL;
char *globlemem = NULL; char *globlemem = NULL;
@ -2353,12 +2415,18 @@ wf_cliprdr_server_format_data_request(CliprdrClientContext *context,
wfClipboard *clipboard; wfClipboard *clipboard;
if (!context || !formatDataRequest) if (!context || !formatDataRequest)
return ERROR_INTERNAL_ERROR; {
rc = ERROR_INTERNAL_ERROR;
goto exit;
}
clipboard = (wfClipboard *)context->custom; clipboard = (wfClipboard *)context->custom;
if (!clipboard) if (!clipboard)
return ERROR_INTERNAL_ERROR; {
rc = ERROR_INTERNAL_ERROR;
goto exit;
}
requestedFormatId = formatDataRequest->requestedFormatId; requestedFormatId = formatDataRequest->requestedFormatId;
@ -2376,7 +2444,10 @@ wf_cliprdr_server_format_data_request(CliprdrClientContext *context,
result = OleGetClipboard(&dataObj); result = OleGetClipboard(&dataObj);
if (FAILED(result)) if (FAILED(result))
return ERROR_INTERNAL_ERROR; {
rc = ERROR_INTERNAL_ERROR;
goto exit;
}
ZeroMemory(&format_etc, sizeof(FORMATETC)); ZeroMemory(&format_etc, sizeof(FORMATETC));
ZeroMemory(&stg_medium, sizeof(STGMEDIUM)); ZeroMemory(&stg_medium, sizeof(STGMEDIUM));
@ -2389,7 +2460,7 @@ wf_cliprdr_server_format_data_request(CliprdrClientContext *context,
if (FAILED(result)) if (FAILED(result))
{ {
DEBUG_CLIPRDR("dataObj->GetData failed."); rc = ERROR_INTERNAL_ERROR;
goto exit; goto exit;
} }
@ -2400,7 +2471,7 @@ wf_cliprdr_server_format_data_request(CliprdrClientContext *context,
GlobalUnlock(stg_medium.hGlobal); GlobalUnlock(stg_medium.hGlobal);
ReleaseStgMedium(&stg_medium); ReleaseStgMedium(&stg_medium);
clipboard->nFiles = 0; clipboard->nFiles = 0;
goto exit; goto resp;
} }
clear_file_array(clipboard); clear_file_array(clipboard);
@ -2417,7 +2488,6 @@ wf_cliprdr_server_format_data_request(CliprdrClientContext *context,
else else
{ {
char *p; char *p;
for (p = (char *)((char *)dropFiles + dropFiles->pFiles); (len = strlen(p)) > 0; for (p = (char *)((char *)dropFiles + dropFiles->pFiles); (len = strlen(p)) > 0;
p += len + 1, clipboard->nFiles++) p += len + 1, clipboard->nFiles++)
{ {
@ -2432,7 +2502,7 @@ wf_cliprdr_server_format_data_request(CliprdrClientContext *context,
GlobalUnlock(stg_medium.hGlobal); GlobalUnlock(stg_medium.hGlobal);
ReleaseStgMedium(&stg_medium); ReleaseStgMedium(&stg_medium);
exit: resp:
size = 4 + clipboard->nFiles * sizeof(FILEDESCRIPTORW); size = 4 + clipboard->nFiles * sizeof(FILEDESCRIPTORW);
groupDsc = (FILEGROUPDESCRIPTORW *)malloc(size); groupDsc = (FILEGROUPDESCRIPTORW *)malloc(size);
@ -2450,6 +2520,7 @@ wf_cliprdr_server_format_data_request(CliprdrClientContext *context,
} }
IDataObject_Release(dataObj); IDataObject_Release(dataObj);
rc = ERROR_SUCCESS;
} }
else else
{ {
@ -2461,26 +2532,50 @@ wf_cliprdr_server_format_data_request(CliprdrClientContext *context,
if (!hClipdata) if (!hClipdata)
{ {
CloseClipboard(); CloseClipboard();
return ERROR_INTERNAL_ERROR; {
rc = ERROR_INTERNAL_ERROR;
goto exit;
}
} }
else
globlemem = (char *)GlobalLock(hClipdata); {
size = (int)GlobalSize(hClipdata); globlemem = (char *)GlobalLock(hClipdata);
buff = malloc(size); size = (int)GlobalSize(hClipdata);
CopyMemory(buff, globlemem, size); buff = malloc(size);
GlobalUnlock(hClipdata); CopyMemory(buff, globlemem, size);
CloseClipboard(); GlobalUnlock(hClipdata);
CloseClipboard();
rc = ERROR_SUCCESS;
}
}
else
{
rc = ERROR_INTERNAL_ERROR;
} }
} }
exit:
if (rc == ERROR_SUCCESS)
{
response.msgFlags = CB_RESPONSE_OK;
}
else
{
response.msgFlags = CB_RESPONSE_FAIL;
}
response.serverConnID = formatDataRequest->serverConnID; response.serverConnID = formatDataRequest->serverConnID;
response.remoteConnID = formatDataRequest->remoteConnID; response.remoteConnID = formatDataRequest->remoteConnID;
response.msgFlags = CB_RESPONSE_OK;
response.dataLen = size; response.dataLen = size;
response.requestedFormatData = (BYTE *)buff; response.requestedFormatData = (BYTE *)buff;
rc = clipboard->context->ClientFormatDataResponse(clipboard->context, &response); if (ERROR_SUCCESS != clipboard->context->ClientFormatDataResponse(clipboard->context, &response))
{
// CAUTION: if failed to send, server will wait a long time
}
free(buff); if (buff)
{
free(buff);
}
return rc; return rc;
} }
@ -2493,48 +2588,69 @@ static UINT
wf_cliprdr_server_format_data_response(CliprdrClientContext *context, wf_cliprdr_server_format_data_response(CliprdrClientContext *context,
const CLIPRDR_FORMAT_DATA_RESPONSE *formatDataResponse) const CLIPRDR_FORMAT_DATA_RESPONSE *formatDataResponse)
{ {
UINT rc = ERROR_INTERNAL_ERROR;
BYTE *data; BYTE *data;
HANDLE hMem; HANDLE hMem;
wfClipboard *clipboard; wfClipboard *clipboard;
if (!context || !formatDataResponse) do
return ERROR_INTERNAL_ERROR;
if (formatDataResponse->msgFlags != CB_RESPONSE_OK)
return E_FAIL;
clipboard = (wfClipboard *)context->custom;
if (!clipboard)
return ERROR_INTERNAL_ERROR;
hMem = GlobalAlloc(GMEM_MOVEABLE, formatDataResponse->dataLen);
if (!hMem)
return ERROR_INTERNAL_ERROR;
data = (BYTE *)GlobalLock(hMem);
if (!data)
{ {
GlobalFree(hMem); if (!context || !formatDataResponse)
return ERROR_INTERNAL_ERROR; {
} rc = ERROR_INTERNAL_ERROR;
break;
}
CopyMemory(data, formatDataResponse->requestedFormatData, formatDataResponse->dataLen); clipboard = (wfClipboard *)context->custom;
if (!clipboard)
{
rc = ERROR_INTERNAL_ERROR;
break;
}
clipboard->hmem = NULL;
if (!GlobalUnlock(hMem) && GetLastError()) if (formatDataResponse->msgFlags != CB_RESPONSE_OK)
{ {
GlobalFree(hMem); // BOOL emptyRes = wf_do_empty_cliprdr((wfClipboard *)context->custom);
return ERROR_INTERNAL_ERROR; // (void)emptyRes;
} rc = E_FAIL;
break;
}
clipboard->hmem = hMem; hMem = GlobalAlloc(GMEM_MOVEABLE, formatDataResponse->dataLen);
if (!hMem)
{
rc = ERROR_INTERNAL_ERROR;
break;
}
data = (BYTE *)GlobalLock(hMem);
if (!data)
{
GlobalFree(hMem);
rc = ERROR_INTERNAL_ERROR;
break;
}
CopyMemory(data, formatDataResponse->requestedFormatData, formatDataResponse->dataLen);
if (!GlobalUnlock(hMem) && GetLastError())
{
GlobalFree(hMem);
rc = ERROR_INTERNAL_ERROR;
break;
}
clipboard->hmem = hMem;
rc = CHANNEL_RC_OK;
} while (0);
if (!SetEvent(clipboard->response_data_event)) if (!SetEvent(clipboard->response_data_event))
return ERROR_INTERNAL_ERROR; {
// CAUTION: critical error here, process will hang up until wait timeout default 3min.
return CHANNEL_RC_OK; rc = ERROR_INTERNAL_ERROR;
}
return rc;
} }
/** /**
@ -2561,12 +2677,18 @@ wf_cliprdr_server_file_contents_request(CliprdrClientContext *context,
UINT32 cbRequested; UINT32 cbRequested;
if (!context || !fileContentsRequest) if (!context || !fileContentsRequest)
return ERROR_INTERNAL_ERROR; {
rc = ERROR_INTERNAL_ERROR;
goto exit;
}
clipboard = (wfClipboard *)context->custom; clipboard = (wfClipboard *)context->custom;
if (!clipboard) if (!clipboard)
return ERROR_INTERNAL_ERROR; {
rc = ERROR_INTERNAL_ERROR;
goto exit;
}
cbRequested = fileContentsRequest->cbRequested; cbRequested = fileContentsRequest->cbRequested;
if (fileContentsRequest->dwFlags == FILECONTENTS_SIZE) if (fileContentsRequest->dwFlags == FILECONTENTS_SIZE)
@ -2575,14 +2697,18 @@ wf_cliprdr_server_file_contents_request(CliprdrClientContext *context,
pData = (BYTE *)calloc(1, cbRequested); pData = (BYTE *)calloc(1, cbRequested);
if (!pData) if (!pData)
goto error; {
rc = ERROR_INTERNAL_ERROR;
goto exit;
}
hRet = OleGetClipboard(&pDataObj); hRet = OleGetClipboard(&pDataObj);
if (FAILED(hRet)) if (FAILED(hRet))
{ {
printf("filecontents: get ole clipboard failed.\n"); printf("filecontents: get ole clipboard failed.\n");
goto error; rc = ERROR_INTERNAL_ERROR;
goto exit;
} }
ZeroMemory(&vFormatEtc, sizeof(FORMATETC)); ZeroMemory(&vFormatEtc, sizeof(FORMATETC));
@ -2666,7 +2792,10 @@ wf_cliprdr_server_file_contents_request(CliprdrClientContext *context,
if (fileContentsRequest->dwFlags == FILECONTENTS_SIZE) if (fileContentsRequest->dwFlags == FILECONTENTS_SIZE)
{ {
if (clipboard->nFiles <= fileContentsRequest->listIndex) if (clipboard->nFiles <= fileContentsRequest->listIndex)
goto error; {
rc = ERROR_INTERNAL_ERROR;
goto exit;
}
*((UINT32 *)&pData[0]) = *((UINT32 *)&pData[0]) =
clipboard->fileDescriptor[fileContentsRequest->listIndex]->nFileSizeLow; clipboard->fileDescriptor[fileContentsRequest->listIndex]->nFileSizeLow;
*((UINT32 *)&pData[4]) = *((UINT32 *)&pData[4]) =
@ -2677,7 +2806,10 @@ wf_cliprdr_server_file_contents_request(CliprdrClientContext *context,
{ {
BOOL bRet; BOOL bRet;
if (clipboard->nFiles <= fileContentsRequest->listIndex) if (clipboard->nFiles <= fileContentsRequest->listIndex)
goto error; {
rc = ERROR_INTERNAL_ERROR;
goto exit;
}
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,
@ -2687,21 +2819,30 @@ wf_cliprdr_server_file_contents_request(CliprdrClientContext *context,
{ {
printf("get file contents failed.\n"); printf("get file contents failed.\n");
uSize = 0; uSize = 0;
goto error; rc = ERROR_INTERNAL_ERROR;
goto exit;
} }
} }
} }
rc = CHANNEL_RC_OK; rc = CHANNEL_RC_OK;
error: exit:
if (pDataObj) if (pDataObj)
IDataObject_Release(pDataObj); IDataObject_Release(pDataObj);
if (rc != CHANNEL_RC_OK)
{
uSize = 0;
}
if (uSize == 0) if (uSize == 0)
{ {
free(pData); if (pData)
pData = NULL; {
free(pData);
pData = NULL;
}
} }
sRc = sRc =
@ -2709,13 +2850,18 @@ error:
clipboard, clipboard,
fileContentsRequest->serverConnID, fileContentsRequest->serverConnID,
fileContentsRequest->remoteConnID, fileContentsRequest->remoteConnID,
rc == CHANNEL_RC_OK ? CB_RESPONSE_OK : CB_RESPONSE_FAIL,
fileContentsRequest->streamId, fileContentsRequest->streamId,
uSize, uSize,
pData); pData);
free(pData);
if (sRc != CHANNEL_RC_OK) if (pData)
return sRc; {
free(pData);
}
// if (sRc != CHANNEL_RC_OK)
// return sRc;
return rc; return rc;
} }
@ -2730,34 +2876,50 @@ wf_cliprdr_server_file_contents_response(CliprdrClientContext *context,
const CLIPRDR_FILE_CONTENTS_RESPONSE *fileContentsResponse) const CLIPRDR_FILE_CONTENTS_RESPONSE *fileContentsResponse)
{ {
wfClipboard *clipboard; wfClipboard *clipboard;
UINT rc = ERROR_INTERNAL_ERROR;
if (!context || !fileContentsResponse) do
return ERROR_INTERNAL_ERROR; {
if (!context || !fileContentsResponse)
{
rc = ERROR_INTERNAL_ERROR;
break;
}
if (fileContentsResponse->msgFlags != CB_RESPONSE_OK) clipboard = (wfClipboard *)context->custom;
return E_FAIL; if (!clipboard)
{
rc = ERROR_INTERNAL_ERROR;
break;
}
clipboard->req_fsize = 0;
clipboard->req_fdata = NULL;
clipboard = (wfClipboard *)context->custom; if (fileContentsResponse->msgFlags != CB_RESPONSE_OK)
{
rc = E_FAIL;
break;
}
if (!clipboard) clipboard->req_fsize = fileContentsResponse->cbRequested;
return ERROR_INTERNAL_ERROR; clipboard->req_fdata = (char *)malloc(fileContentsResponse->cbRequested);
if (!clipboard->req_fdata)
{
rc = ERROR_INTERNAL_ERROR;
break;
}
clipboard->req_fsize = fileContentsResponse->cbRequested; CopyMemory(clipboard->req_fdata, fileContentsResponse->requestedData,
clipboard->req_fdata = (char *)malloc(fileContentsResponse->cbRequested); fileContentsResponse->cbRequested);
if (!clipboard->req_fdata) rc = CHANNEL_RC_OK;
return ERROR_INTERNAL_ERROR; } while (0);
CopyMemory(clipboard->req_fdata, fileContentsResponse->requestedData,
fileContentsResponse->cbRequested);
if (!SetEvent(clipboard->req_fevent)) if (!SetEvent(clipboard->req_fevent))
{ {
free(clipboard->req_fdata); // CAUTION: critical error here, process will hang up until wait timeout default 3min.
return ERROR_INTERNAL_ERROR;
} }
return rc;
return CHANNEL_RC_OK;
} }
BOOL wf_cliprdr_init(wfClipboard *clipboard, CliprdrClientContext *cliprdr) BOOL wf_cliprdr_init(wfClipboard *clipboard, CliprdrClientContext *cliprdr)
@ -2888,6 +3050,7 @@ BOOL uninit_cliprdr(CliprdrClientContext *context)
BOOL empty_cliprdr(CliprdrClientContext *context, UINT32 server_conn_id, UINT32 remote_conn_id) BOOL empty_cliprdr(CliprdrClientContext *context, UINT32 server_conn_id, UINT32 remote_conn_id)
{ {
wfClipboard *clipboard = NULL; wfClipboard *clipboard = NULL;
CliprdrDataObject *instance = NULL;
BOOL rc = FALSE; BOOL rc = FALSE;
if (!context) if (!context)
{ {
@ -2899,6 +3062,34 @@ BOOL empty_cliprdr(CliprdrClientContext *context, UINT32 server_conn_id, UINT32
} }
clipboard = (wfClipboard *)context->custom; clipboard = (wfClipboard *)context->custom;
if (!clipboard)
{
return FALSE;
}
instance = clipboard->data_obj;
if (instance)
{
if (server_conn_id != 0 && instance->m_serverConnID != server_conn_id)
{
return TRUE;
}
if (remote_conn_id != 0 && instance->m_remoteConnID != remote_conn_id)
{
return TRUE;
}
}
return wf_do_empty_cliprdr(clipboard);
}
BOOL wf_do_empty_cliprdr(wfClipboard *clipboard)
{
BOOL rc = FALSE;
if (!clipboard)
{
return FALSE;
}
if (WaitForSingleObject(clipboard->data_obj_mutex, INFINITE) != WAIT_OBJECT_0) if (WaitForSingleObject(clipboard->data_obj_mutex, INFINITE) != WAIT_OBJECT_0)
{ {
@ -2909,18 +3100,6 @@ BOOL empty_cliprdr(CliprdrClientContext *context, UINT32 server_conn_id, UINT32
{ {
if (clipboard->data_obj != NULL) if (clipboard->data_obj != NULL)
{ {
CliprdrDataObject *instance = clipboard->data_obj;
if (server_conn_id != 0 && instance->m_serverConnID != server_conn_id)
{
rc = TRUE;
break;
}
if (remote_conn_id != 0 && instance->m_remoteConnID != remote_conn_id)
{
rc = TRUE;
break;
}
wf_destroy_file_obj(clipboard->data_obj); wf_destroy_file_obj(clipboard->data_obj);
clipboard->data_obj = NULL; clipboard->data_obj = NULL;
} }

View File

@ -198,6 +198,7 @@ impl ConnectionManager {
allow_err!(_tx_clip_file.send((id, _clip))); allow_err!(_tx_clip_file.send((id, _clip)));
} }
Data::ClipboardFileEnabled(enabled) => { Data::ClipboardFileEnabled(enabled) => {
#[cfg(windows)]
set_conn_enabled(id, 0, enabled); set_conn_enabled(id, 0, enabled);
if !enabled { if !enabled {
allow_err!(_tx_clip_empty.send(id)); allow_err!(_tx_clip_empty.send(id));
@ -375,11 +376,14 @@ async fn start_ipc(cm: ConnectionManager) {
match data { match data {
Data::Login{id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file, file_transfer_enabled} => { Data::Login{id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file, file_transfer_enabled} => {
conn_id = id; conn_id = id;
#[cfg(windows)]
set_conn_enabled(id, 0, file_transfer_enabled); set_conn_enabled(id, 0, file_transfer_enabled);
let _ = file_transfer_enabled;
cm.add_connection(id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file, tx.clone()); cm.add_connection(id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file, tx.clone());
} }
Data::Close => { Data::Close => {
allow_err!(tx_clip_empty.send(conn_id)); allow_err!(tx_clip_empty.send(conn_id));
#[cfg(windows)]
set_conn_enabled(conn_id, 0, false); set_conn_enabled(conn_id, 0, false);
log::info!("cm ipc connection closed from connection request"); log::info!("cm ipc connection closed from connection request");
break; break;