fix hang up
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
128a4aca69
commit
01591d1abf
@ -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,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user