/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT android_cliprdr_server_format_data_response(CliprdrClientContext* cliprdr, CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse) { BYTE* data; UINT32 size; UINT32 index; UINT32 formatId; CLIPRDR_FORMAT* format = NULL; androidContext* afc = (androidContext*) cliprdr->custom; freerdp* instance = ((rdpContext*) afc)->instance; for (index = 0; index < afc->numServerFormats; index++) { if (afc->requestedFormatId == afc->serverFormats[index].formatId) format = &(afc->serverFormats[index]); } if (!format) { SetEvent(afc->clipboardRequestEvent); return ERROR_INTERNAL_ERROR; } if (format->formatName) formatId = ClipboardRegisterFormat(afc->clipboard, format->formatName); else formatId = format->formatId; size = formatDataResponse->dataLen; data = (BYTE*) malloc(size); CopyMemory(data, formatDataResponse->requestedFormatData, size); ClipboardSetData(afc->clipboard, formatId, data, size); SetEvent(afc->clipboardRequestEvent); if ((formatId == CF_TEXT) || (formatId == CF_UNICODETEXT)) { JNIEnv* env; jstring jdata; jboolean attached; formatId = ClipboardRegisterFormat(afc->clipboard, "UTF8_STRING"); data = (void*) ClipboardGetData(afc->clipboard, formatId, &size); attached = jni_attach_thread(&env); jdata = jniNewStringUTF(env, data, size); freerdp_callback("OnRemoteClipboardChanged", "(ILjava/lang/String;)V", instance, jdata); (*env)->DeleteLocalRef(env, jdata); if (attached == JNI_TRUE) { jni_detach_thread(); } } return CHANNEL_RC_OK; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT android_cliprdr_server_format_data_request(CliprdrClientContext* cliprdr, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest) { BYTE* data; UINT32 size; UINT32 formatId; CLIPRDR_FORMAT_DATA_RESPONSE response; androidContext* afc = (androidContext*) cliprdr->custom; ZeroMemory(&response, sizeof(CLIPRDR_FORMAT_DATA_RESPONSE)); formatId = formatDataRequest->requestedFormatId; data = (BYTE*) ClipboardGetData(afc->clipboard, formatId, &size); response.msgFlags = CB_RESPONSE_OK; response.dataLen = size; response.requestedFormatData = data; if (!data) { response.msgFlags = CB_RESPONSE_FAIL; response.dataLen = 0; response.requestedFormatData = NULL; } cliprdr->ClientFormatDataResponse(cliprdr, &response); free(data); return CHANNEL_RC_OK; }
static int xf_cliprdr_server_format_data_response(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse) { BOOL bSuccess; BYTE* pSrcData; BYTE* pDstData; UINT32 DstSize; UINT32 SrcSize; UINT32 formatId; UINT32 altFormatId; xfCliprdrFormat* format; BOOL nullTerminated = FALSE; UINT32 size = formatDataResponse->dataLen; BYTE* data = formatDataResponse->requestedFormatData; xfClipboard* clipboard = (xfClipboard*) context->custom; xfContext* xfc = clipboard->xfc; if (!clipboard->respond) return 1; format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId); if (clipboard->data) { free(clipboard->data); clipboard->data = NULL; } pDstData = NULL; DstSize = 0; formatId = 0; altFormatId = 0; switch (clipboard->data_format) { case CF_TEXT: formatId = CF_TEXT; altFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); nullTerminated = TRUE; break; case CF_OEMTEXT: formatId = CF_OEMTEXT; altFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); nullTerminated = TRUE; break; case CF_UNICODETEXT: formatId = CF_UNICODETEXT; altFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); nullTerminated = TRUE; break; case CF_DIB: formatId = CF_DIB; altFormatId = ClipboardGetFormatId(clipboard->system, "image/bmp"); break; case CB_FORMAT_HTML: formatId = ClipboardGetFormatId(clipboard->system, "HTML Format"); altFormatId = ClipboardGetFormatId(clipboard->system, "text/html"); nullTerminated = TRUE; break; } SrcSize = (UINT32) size; pSrcData = (BYTE*) malloc(SrcSize); if (!pSrcData) return -1; CopyMemory(pSrcData, data, SrcSize); bSuccess = ClipboardSetData(clipboard->system, formatId, (void*) pSrcData, SrcSize); if (!bSuccess) free (pSrcData); if (bSuccess && altFormatId) { DstSize = 0; pDstData = (BYTE*) ClipboardGetData(clipboard->system, altFormatId, &DstSize); if ((DstSize > 1) && nullTerminated) DstSize--; } clipboard->data = pDstData; clipboard->data_length = DstSize; xf_cliprdr_provide_data(clipboard, clipboard->respond, pDstData, DstSize); XSendEvent(xfc->display, clipboard->respond->xselection.requestor, 0, 0, clipboard->respond); XFlush(xfc->display); free(clipboard->respond); clipboard->respond = NULL; return 1; }
static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasData, BYTE* data, int size) { BOOL bSuccess; UINT32 SrcSize; UINT32 DstSize; UINT32 formatId; UINT32 altFormatId; BYTE* pSrcData = NULL; BYTE* pDstData = NULL; xfCliprdrFormat* format; if (clipboard->incr_starts && hasData) return; format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId); if (!hasData || !data || !format) { xf_cliprdr_send_data_response(clipboard, NULL, 0); return; } formatId = 0; altFormatId = 0; switch (format->formatId) { case CF_TEXT: case CF_OEMTEXT: case CF_UNICODETEXT: size = strlen((char*) data) + 1; formatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); break; case CF_DIB: formatId = ClipboardGetFormatId(clipboard->system, "image/bmp"); break; case CB_FORMAT_HTML: size = strlen((char*) data) + 1; formatId = ClipboardGetFormatId(clipboard->system, "text/html"); break; } SrcSize = (UINT32) size; pSrcData = (BYTE*) malloc(SrcSize); if (!pSrcData) return; CopyMemory(pSrcData, data, SrcSize); bSuccess = ClipboardSetData(clipboard->system, formatId, (void*) pSrcData, SrcSize); if (!bSuccess) free(pSrcData); altFormatId = clipboard->requestedFormatId; if (bSuccess && altFormatId) { DstSize = 0; pDstData = (BYTE*) ClipboardGetData(clipboard->system, altFormatId, &DstSize); } if (!pDstData) { xf_cliprdr_send_data_response(clipboard, NULL, 0); return; } xf_cliprdr_send_data_response(clipboard, pDstData, (int) DstSize); free(pDstData); }
static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasData, BYTE* data, int size) { BOOL bSuccess; UINT32 SrcSize; UINT32 DstSize; UINT32 srcFormatId; UINT32 dstFormatId; BYTE* pDstData = NULL; xfCliprdrFormat* format; if (clipboard->incr_starts && hasData) return; format = xf_cliprdr_get_client_format_by_id(clipboard, clipboard->requestedFormatId); if (!hasData || !data || !format) { xf_cliprdr_send_data_response(clipboard, NULL, 0); return; } srcFormatId = 0; switch (format->formatId) { case CF_RAW: srcFormatId = CF_RAW; break; case CF_TEXT: case CF_OEMTEXT: case CF_UNICODETEXT: size = strlen((char*) data) + 1; srcFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); break; case CF_DIB: srcFormatId = ClipboardGetFormatId(clipboard->system, "image/bmp"); break; case CB_FORMAT_HTML: srcFormatId = ClipboardGetFormatId(clipboard->system, "text/html"); break; case CB_FORMAT_TEXTURILIST: srcFormatId = ClipboardGetFormatId(clipboard->system, "text/uri-list"); break; } SrcSize = (UINT32) size; bSuccess = ClipboardSetData(clipboard->system, srcFormatId, data, SrcSize); if (format->formatName) dstFormatId = ClipboardGetFormatId(clipboard->system, format->formatName); else dstFormatId = format->formatId; if (bSuccess) { DstSize = 0; pDstData = (BYTE*) ClipboardGetData(clipboard->system, dstFormatId, &DstSize); } if (!pDstData) { xf_cliprdr_send_data_response(clipboard, NULL, 0); return; } /* * File lists require a bit of postprocessing to convert them from WinPR's FILDESCRIPTOR * format to CLIPRDR_FILELIST expected by the server. * * We check for "FileGroupDescriptorW" format being registered (i.e., nonzero) in order * to not process CF_RAW as a file list in case WinPR does not support file transfers. */ if (dstFormatId && (dstFormatId == ClipboardGetFormatId(clipboard->system, "FileGroupDescriptorW"))) { UINT error = NO_ERROR; FILEDESCRIPTOR* file_array = (FILEDESCRIPTOR*) pDstData; UINT32 file_count = DstSize / sizeof(FILEDESCRIPTOR); pDstData = NULL; DstSize = 0; error = cliprdr_serialize_file_list(file_array, file_count, &pDstData, &DstSize); if (error) WLog_ERR(TAG, "failed to serialize CLIPRDR_FILELIST: 0x%08X", error); free(file_array); } xf_cliprdr_send_data_response(clipboard, pDstData, (int) DstSize); free(pDstData); }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse) { BOOL bSuccess; BYTE* pDstData; UINT32 DstSize; UINT32 SrcSize; UINT32 srcFormatId; UINT32 dstFormatId; BOOL nullTerminated = FALSE; UINT32 size = formatDataResponse->dataLen; BYTE* data = formatDataResponse->requestedFormatData; xfClipboard* clipboard = (xfClipboard*) context->custom; xfContext* xfc = clipboard->xfc; if (!clipboard->respond) return CHANNEL_RC_OK; xf_cliprdr_clear_cached_data(clipboard); pDstData = NULL; DstSize = 0; srcFormatId = 0; dstFormatId = 0; if (clipboard->data_raw_format) { srcFormatId = CF_RAW; dstFormatId = CF_RAW; } else if (clipboard->data_format_name) { if (strcmp(clipboard->data_format_name, "HTML Format") == 0) { srcFormatId = ClipboardGetFormatId(clipboard->system, "HTML Format"); dstFormatId = ClipboardGetFormatId(clipboard->system, "text/html"); nullTerminated = TRUE; } } else { switch (clipboard->data_format_id) { case CF_TEXT: srcFormatId = CF_TEXT; dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); nullTerminated = TRUE; break; case CF_OEMTEXT: srcFormatId = CF_OEMTEXT; dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); nullTerminated = TRUE; break; case CF_UNICODETEXT: srcFormatId = CF_UNICODETEXT; dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); nullTerminated = TRUE; break; case CF_DIB: srcFormatId = CF_DIB; dstFormatId = ClipboardGetFormatId(clipboard->system, "image/bmp"); break; } } SrcSize = (UINT32) size; bSuccess = ClipboardSetData(clipboard->system, srcFormatId, data, SrcSize); if (bSuccess) { DstSize = 0; pDstData = (BYTE*) ClipboardGetData(clipboard->system, dstFormatId, &DstSize); if (!pDstData) { WLog_ERR(TAG, "failed to get clipboard data in format %s [source format %s]", ClipboardGetFormatName(clipboard, dstFormatId), ClipboardGetFormatName(clipboard, srcFormatId)); return ERROR_INTERNAL_ERROR; } if (nullTerminated) { while (DstSize > 0 && pDstData[DstSize - 1] == '\0') DstSize--; } } /* Cache converted and original data to avoid doing a possibly costly * conversion again on subsequent requests */ clipboard->data = pDstData; clipboard->data_length = DstSize; /* We have to copy the original data again, as pSrcData is now owned * by clipboard->system. Memory allocation failure is not fatal here * as this is only a cached value. */ clipboard->data_raw = (BYTE*) malloc(size); if (clipboard->data_raw) { CopyMemory(clipboard->data_raw, data, size); clipboard->data_raw_length = size; } else { WLog_WARN(TAG, "failed to allocate %"PRIu32" bytes for a copy of raw clipboard data", size); } xf_cliprdr_provide_data(clipboard, clipboard->respond, pDstData, DstSize); XSendEvent(xfc->display, clipboard->respond->xselection.requestor, 0, 0, clipboard->respond); XFlush(xfc->display); free(clipboard->respond); clipboard->respond = NULL; return CHANNEL_RC_OK; }