5#include "ClipboardFreeRDP.h" 
   12#include <QStandardPaths> 
   15#include "BackendFreeRDP.h" 
   16#include "ClipboardMimeData.h" 
   17#include "freerdp/version.h" 
   19static Q_LOGGING_CATEGORY(log, 
"FreeRDP.Clipboard")
 
   23    m_pCliprdrClientContext(
nullptr),
 
   24    m_pClipboard(
nullptr),
 
   25    m_FileCapabilityFlags(0),
 
   26    m_bFileSupported(false),
 
   27    m_bFileFormatsRegistered(false)
 
   29    qDebug(log) << 
"CClipboardFreeRDP::CClipboardFreeRDP()";
 
   30    m_pClipboard = ClipboardCreate();
 
   31    if (ClipboardGetFormatId(m_pClipboard, 
"text/uri-list"))
 
   32        m_bFileFormatsRegistered = 
true;
 
   33    wClipboardDelegate* pDelegate = ClipboardGetDelegate(m_pClipboard);
 
   34    pDelegate->custom = 
this;
 
   36    QString szPath = QStandardPaths::writableLocation(
 
   37                         QStandardPaths::TempLocation)
 
   38                     + QDir::separator() + 
"Rabbit" 
   39                     + QDir::separator() + 
"RabbitRemoteControl";
 
   40    qDebug(log) << 
"Delegate base path:" << szPath;
 
   42    pDelegate->basePath = _strdup(szPath.toStdString().c_str());
 
   43    pDelegate->ClipboardFileSizeSuccess = cb_clipboard_file_size_success;
 
   44    pDelegate->ClipboardFileSizeFailure = cb_clipboard_file_size_failure;
 
   45    pDelegate->ClipboardFileRangeSuccess = cb_clipboard_file_range_success;
 
   46    pDelegate->ClipboardFileRangeFailure = cb_clipboard_file_range_failure;
 
   48#if FREERDP_VERSION_MAJOR > 2 || (FREERDP_VERSION_MAJOR == 2 && FREERDP_VERSION_MINOR > 7) 
   49    pDelegate->IsFileNameComponentValid = cbIsFileNameComponentValid;
 
   53CClipboardFreeRDP::~CClipboardFreeRDP()
 
   55    qDebug(log) << 
"CClipboardFreeRdp::~CClipboardFreeRdp()";
 
   60    emit sigServerFileContentsRespose(-1, data);
 
   61    ClipboardDestroy(m_pClipboard);
 
   64int CClipboardFreeRDP::Init(CliprdrClientContext *context, 
bool bEnable)
 
   66    if(!bEnable) 
return 0;
 
   68    m_pCliprdrClientContext = context;
 
   69    context->custom = 
this;
 
   73    context->ServerCapabilities = cb_cliprdr_server_capabilities;
 
   74    context->MonitorReady = cb_cliprdr_monitor_ready;
 
   75    context->ServerFormatList = cb_cliprdr_server_format_list;
 
   76    context->ServerFormatListResponse = cb_cliprdr_server_format_list_response;
 
   77    context->ServerFormatDataRequest = cb_cliprdr_server_format_data_request;
 
   78    context->ServerFormatDataResponse = cb_cliprdr_server_format_data_response;
 
   79    context->ServerFileContentsRequest = cb_cliprdr_server_file_contents_request;
 
   84int CClipboardFreeRDP::UnInit(CliprdrClientContext *context, 
bool bEnable)
 
   86    context->custom = 
nullptr;
 
   87    m_pCliprdrClientContext = 
nullptr;
 
   91void CClipboardFreeRDP::slotClipBoardChanged()
 
   93    qDebug(log) << 
"CClipboardFreeRdp::slotClipBoardChanged";
 
   95    const QMimeData* pMimeType = QApplication::clipboard()->mimeData();
 
   96    if(!pMimeType) 
return;
 
   99    QVariant d = pMimeType->data(MIME_TYPE_RABBITREMOTECONTROL_PLUGINS_FREERDP);
 
  102        if(!m_lstClipboardMimeDataId.isEmpty()
 
  103            && m_lstClipboardMimeDataId.contains(data))
 
  106                << 
"CClipboardFreeRdp::slotClipBoardChanged: clipboard is this owner" 
  107                << data << m_lstClipboardMimeDataId;
 
  113    qDebug(log) << 
"CClipboardFreeRdp::slotClipBoardChanged:" 
  114                << data << m_lstClipboardMimeDataId;
 
  115    m_lstClipboardMimeDataId.clear();
 
  116    SendClientFormatList(m_pCliprdrClientContext);
 
  119UINT CClipboardFreeRDP::cb_cliprdr_server_capabilities(
 
  120    CliprdrClientContext* context,
 
  121    const CLIPRDR_CAPABILITIES* capabilities)
 
  123    qDebug(log) << 
"CClipboardFreeRdp::cb_cliprdr_server_capabilities";
 
  125    int nRet = CHANNEL_RC_OK;
 
  128    pThis->m_bFileSupported = FALSE;
 
  129    const CLIPRDR_CAPABILITY_SET* caps;
 
  130    const CLIPRDR_GENERAL_CAPABILITY_SET* generalCaps;
 
  131    const BYTE* capsPtr = (
const BYTE*)capabilities->capabilitySets;
 
  133    for (UINT32 i = 0; i < capabilities->cCapabilitiesSets; i++)
 
  135        caps = (
const CLIPRDR_CAPABILITY_SET*)capsPtr;
 
  137        if (caps->capabilitySetType == CB_CAPSTYPE_GENERAL)
 
  139            generalCaps = (
const CLIPRDR_GENERAL_CAPABILITY_SET*)caps;
 
  141            if (generalCaps->generalFlags & CB_STREAM_FILECLIP_ENABLED)
 
  144                pThis->m_bFileSupported = TRUE;
 
  148        capsPtr += caps->capabilitySetLength;
 
  157UINT CClipboardFreeRDP::cb_cliprdr_monitor_ready(
 
  158    CliprdrClientContext *context,
 
  159    const CLIPRDR_MONITOR_READY *monitorReady)
 
  161    qDebug(log) << 
"CClipboardFreeRdp::cb_cliprdr_monitor_ready";
 
  162    UINT nRet = CHANNEL_RC_OK;
 
  164    if (!context || !context->ClientCapabilities)
 
  167        return ERROR_INTERNAL_ERROR;
 
  172    CLIPRDR_CAPABILITIES capabilities;
 
  173    CLIPRDR_GENERAL_CAPABILITY_SET generalCapabilitySet;
 
  174    capabilities.cCapabilitiesSets = 1;
 
  175    capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*)&(generalCapabilitySet);
 
  176    generalCapabilitySet.capabilitySetType = CB_CAPSTYPE_GENERAL;
 
  177    generalCapabilitySet.capabilitySetLength = 12;
 
  178    generalCapabilitySet.version = CB_CAPS_VERSION_2;
 
  179    generalCapabilitySet.generalFlags = CB_USE_LONG_FORMAT_NAMES;
 
  181    if (pThis->m_bFileSupported && pThis->m_bFileFormatsRegistered)
 
  183        generalCapabilitySet.generalFlags |=
 
  184            CB_STREAM_FILECLIP_ENABLED | CB_FILECLIP_NO_FILE_PATHS
 
  185#if FREERDP_VERSION_MAJOR > 2 || (FREERDP_VERSION_MAJOR == 2 && FREERDP_VERSION_MINOR > 7) 
  186            | CB_HUGE_FILE_SUPPORT_ENABLED
 
  191    pThis->m_FileCapabilityFlags = generalCapabilitySet.generalFlags;
 
  192    if((nRet = context->ClientCapabilities(context, &capabilities))
 
  195        qCritical(log) << 
"Send Client Capabilities fail";
 
  200    return SendClientFormatList(context);
 
  206UINT CClipboardFreeRDP::SendClientFormatList(CliprdrClientContext *context)
 
  208    qDebug(log) << 
"CClipboardFreeRdp::SendClientFormatList";
 
  209    int nRet = CHANNEL_RC_OK;
 
  211    CLIPRDR_FORMAT* pFormats = 
nullptr;
 
  212    CLIPRDR_FORMAT_LIST formatList = { 0 };
 
  213    UINT32 numFormats = 0;
 
  215    if(!context) 
return nRet;
 
  218    QClipboard *clipboard = QApplication::clipboard();
 
  221        qDebug(log) << 
"clipboard is null";
 
  225    QVector<UINT32> formatIds;
 
  226    const QMimeData* pData = clipboard->mimeData();
 
  227    if(!pData || pData->formats().isEmpty())
 
  229        qDebug(log) << 
"clipboard->mimeData is null";
 
  232    auto clipFormats = pData->formats();
 
  233    if(!clipFormats.isEmpty())
 
  235        nLen = clipFormats.length()
 
  236        + ClipboardCountRegisteredFormats(pThis->m_pClipboard);
 
  237        pFormats = 
new CLIPRDR_FORMAT[nLen];
 
  241        qCritical(log) << 
"Failed to allocate" 
  242                       << nLen << 
"CLIPRDR_FORMAT structs";
 
  243        return CHANNEL_RC_NO_MEMORY;
 
  245    memset(pFormats, 0, 
sizeof(CLIPRDR_FORMAT) * nLen);
 
  246    qDebug(log) << 
"Clipboard formats:" << clipFormats;
 
  247    foreach(
auto f, pData->formats())
 
  249        UINT32 
id = ClipboardRegisterFormat(
 
  250            pThis->m_pClipboard, f.toStdString().c_str());
 
  251        if(!formatIds.contains(
id))
 
  253            pFormats[numFormats].formatName = _strdup(f.toStdString().c_str());
 
  254            pFormats[numFormats].formatId = id;
 
  255            formatIds.push_back(pFormats[numFormats].formatId);
 
  262        UINT32 
id = ClipboardRegisterFormat(
 
  263            pThis->m_pClipboard, 
"FileGroupDescriptorW");
 
  264        if(!formatIds.contains(
id))
 
  266            pFormats[numFormats].formatName = _strdup(
"FileGroupDescriptorW");
 
  267            pFormats[numFormats].formatId = id;
 
  268            formatIds.push_back(pFormats[numFormats].formatId);
 
  271        id = ClipboardRegisterFormat(pThis->m_pClipboard, 
"FileContents");
 
  272        if(!formatIds.contains(
id))
 
  274            pFormats[numFormats].formatName = _strdup(
"FileContents");
 
  275            pFormats[numFormats].formatId = id;
 
  276            formatIds.push_back(pFormats[numFormats].formatId);
 
  279        id = ClipboardRegisterFormat(pThis->m_pClipboard, 
"text/uri-list");
 
  280        if(!formatIds.contains(
id))
 
  282            pFormats[numFormats].formatName = _strdup(
"text/uri-list");
 
  283            pFormats[numFormats].formatId = id;
 
  284            formatIds.push_back(pFormats[numFormats].formatId);
 
  288    if(pData->hasImage())
 
  297        if(!formatIds.contains(CF_DIB))
 
  299            pFormats[numFormats].formatId = CF_DIB;
 
  300            pFormats[numFormats].formatName = 
nullptr;
 
  301            formatIds.push_back(pFormats[numFormats].formatId);
 
  304        if(!formatIds.contains(CF_DIBV5))
 
  306            pFormats[numFormats].formatId = CF_DIBV5;
 
  307            pFormats[numFormats].formatName = 
nullptr;
 
  308            formatIds.push_back(pFormats[numFormats].formatId);
 
  314        UINT32 
id = ClipboardRegisterFormat(
 
  315            pThis->m_pClipboard, 
"text/html");
 
  316        if(!formatIds.contains(
id))
 
  318            pFormats[numFormats].formatId = id;
 
  319            pFormats[numFormats].formatName = _strdup(
"text/html");
 
  320            formatIds.push_back(pFormats[numFormats].formatId);
 
  323        id = ClipboardRegisterFormat(
 
  324            pThis->m_pClipboard, 
"HTML Format");
 
  325        if(!formatIds.contains(
id))
 
  327            pFormats[numFormats].formatId = id;
 
  328            pFormats[numFormats].formatName = _strdup(
"HTML Format");
 
  329            formatIds.push_back(pFormats[numFormats].formatId);
 
  335        if(!formatIds.contains(CF_TEXT))
 
  337            pFormats[numFormats].formatId = CF_TEXT;
 
  338            pFormats[numFormats].formatName = 
nullptr;
 
  339            formatIds.push_back(pFormats[numFormats].formatId);
 
  342        if(!formatIds.contains(CF_OEMTEXT))
 
  344            pFormats[numFormats].formatId = CF_OEMTEXT;
 
  345            pFormats[numFormats].formatName = 
nullptr;
 
  346            formatIds.push_back(pFormats[numFormats].formatId);
 
  349        if(!formatIds.contains(CF_UNICODETEXT))
 
  351            pFormats[numFormats].formatId = CF_UNICODETEXT;
 
  352            pFormats[numFormats].formatName = 
nullptr;
 
  353            formatIds.push_back(pFormats[numFormats].formatId);
 
  356        if(!formatIds.contains(CF_LOCALE))
 
  358            pFormats[numFormats].formatId = CF_LOCALE;
 
  359            pFormats[numFormats].formatName = 
nullptr;
 
  360            formatIds.push_back(pFormats[numFormats].formatId);
 
  366    for(
int i = 0; i < numFormats; i++)
 
  368        szFormats += 
" id:" + QString::number(pFormats[i].formatId);
 
  369        if(pFormats[i].formatName)
 
  372            szFormats += pFormats[i].formatName;
 
  377    qDebug(log, 
"SendClientFormatList formats: %d:%s",
 
  379           szFormats.toStdString().c_str());
 
  380#if FREERDP_VERSION_MAJOR >= 3 
  381    formatList.common.msgFlags = CB_RESPONSE_OK;
 
  382    formatList.common.msgType = CB_FORMAT_LIST;
 
  384    formatList.msgFlags = CB_RESPONSE_OK;
 
  385    formatList.msgType = CB_FORMAT_LIST;
 
  387    formatList.numFormats = numFormats;
 
  388    formatList.formats = pFormats;
 
  392    SendFormatDataResponse(context, NULL, 0);
 
  394    Q_ASSERT(context->ClientFormatList);
 
  395    nRet = context->ClientFormatList(context, &formatList);
 
  396    qDebug(log) << 
"SendClientFormatList nRet:" << nRet;
 
  397    for(UINT32 i = 0; i < numFormats; i++)
 
  398        if(pFormats[i].formatName)
 
  401            free(pFormats[i].formatName);
 
  409UINT CClipboardFreeRDP::cb_cliprdr_server_format_data_request(
 
  410    CliprdrClientContext* context,
 
  411    const CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest)
 
  414    << 
"CClipboardFreeRdp::cb_cliprdr_server_format_data_request";
 
  416    int nRet = CHANNEL_RC_OK;
 
  417    bool bSuucess = 
false;
 
  419    BYTE* pDstData = NULL;
 
  421    UINT32 dstFormatId = formatDataRequest->requestedFormatId;
 
  422    UINT32 scrFormatID = 0;
 
  423    if(!context) 
return ERROR_INTERNAL_ERROR;
 
  426    qDebug(log) << 
"server format date request formatID:" 
  428    QClipboard *clipboard = QApplication::clipboard();
 
  429    if(!clipboard) 
return ERROR_INTERNAL_ERROR;
 
  438        if(clipboard->mimeData()->hasText())
 
  440            QString szData = clipboard->text();
 
  441            bSuucess = ClipboardSetData(
 
  442                pThis->m_pClipboard, CF_UNICODETEXT,
 
  443                szData.data(), (szData.size() + 1) * 
sizeof(QChar));
 
  450        if(clipboard->mimeData()->hasImage())
 
  452            QImage img = clipboard->image();
 
  457            if(buffer.open(QIODevice::WriteOnly))
 
  459                img.save(&buffer, 
"BMP");
 
  463                bSuucess = ClipboardSetData(
 
  465                    ClipboardGetFormatId(pThis->m_pClipboard, 
"image/bmp"),
 
  466                    (BYTE*)d.data(), d.length());
 
  470        if(ClipboardGetFormatId(pThis->m_pClipboard, 
"HTML Format")
 
  473            mimeType = 
"text/html";
 
  474            scrFormatID = ClipboardGetFormatId(pThis->m_pClipboard,
 
  476        } 
else if(ClipboardGetFormatId(pThis->m_pClipboard,
 
  477                                        "FileGroupDescriptorW")
 
  480            mimeType = 
"text/uri-list";
 
  481            scrFormatID = ClipboardGetFormatId(pThis->m_pClipboard,
 
  484            mimeType = ClipboardGetFormatName(pThis->m_pClipboard, dstFormatId);
 
  485            scrFormatID = dstFormatId;
 
  487        if(!mimeType.isEmpty() && scrFormatID > 0)
 
  489            QByteArray data = clipboard->mimeData()->data(mimeType);
 
  490            qDebug(log) << 
"mimeData:" << data << data.length();
 
  492                bSuucess = ClipboardSetData(pThis->m_pClipboard, scrFormatID,
 
  493                                            data.data(), data.size());
 
  499        pDstData = (BYTE*)ClipboardGetData(pThis->m_pClipboard,
 
  500                                             dstFormatId, &dstSize);
 
  505        << 
"ClipboardGetData fail: dstFormatId:" << dstFormatId
 
  506        << 
", srcFormatId:" << scrFormatID;
 
  507        nRet = SendFormatDataResponse(context, NULL, 0);
 
  519        && (ClipboardGetFormatId(pThis->m_pClipboard, 
"FileGroupDescriptorW")
 
  522        UINT error = NO_ERROR;
 
  523        FILEDESCRIPTORW* file_array = (FILEDESCRIPTORW*)pDstData;
 
  524        UINT32 file_count = dstSize / 
sizeof(FILEDESCRIPTORW);
 
  526        error = cliprdr_serialize_file_list_ex(
 
  527            pThis->m_FileCapabilityFlags, file_array,
 
  528            file_count, &pDstData, &dstSize);
 
  531                << 
"failed to serialize CLIPRDR_FILELIST:" << error;
 
  535    nRet = SendFormatDataResponse(context, pDstData, dstSize);
 
  547UINT CClipboardFreeRDP::SendFormatDataResponse(CliprdrClientContext *context,
 
  548                                               const BYTE *data, 
size_t size)
 
  550    qDebug(log) << Q_FUNC_INFO;
 
  551    CLIPRDR_FORMAT_DATA_RESPONSE response = { 0 };
 
  552#if FREERDP_VERSION_MAJOR >= 3 
  553    response.common.msgFlags = (data) ? CB_RESPONSE_OK : CB_RESPONSE_FAIL;
 
  554    response.common.dataLen = size;
 
  556    response.msgFlags = (data) ? CB_RESPONSE_OK : CB_RESPONSE_FAIL;
 
  557    response.dataLen = size;
 
  559    response.requestedFormatData = data;
 
  560    return context->ClientFormatDataResponse(context, &response);
 
  565UINT CClipboardFreeRDP::cb_clipboard_file_size_success(
 
  566    wClipboardDelegate* delegate,
 
  567    const wClipboardFileSizeRequest* request,
 
  570    qDebug(log) << 
"CClipboardFreeRDP::cb_clipboard_file_size_success";
 
  571    CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 };
 
  573#if FREERDP_VERSION_MAJOR >= 3 
  574    response.common.msgFlags = CB_RESPONSE_OK;
 
  576    response.msgFlags = CB_RESPONSE_OK;
 
  578    response.streamId = request->streamId;
 
  579    response.cbRequested = 
sizeof(UINT64);
 
  580    response.requestedData = (BYTE*)&fileSize;
 
  581    return pThis->m_pCliprdrClientContext->ClientFileContentsResponse(
 
  582        pThis->m_pCliprdrClientContext, &response);
 
  585UINT CClipboardFreeRDP::cb_clipboard_file_size_failure(
 
  586    wClipboardDelegate* delegate,
 
  587    const wClipboardFileSizeRequest* request,
 
  590    qDebug(log) << 
"CClipboardFreeRDP::cb_clipboard_file_size_failure";
 
  591    CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 };
 
  593    WINPR_UNUSED(errorCode);
 
  594#if FREERDP_VERSION_MAJOR >= 3 
  595    response.common.msgFlags = CB_RESPONSE_FAIL;
 
  597    response.msgFlags = CB_RESPONSE_FAIL;
 
  599    response.streamId = request->streamId;
 
  600    return pThis->m_pCliprdrClientContext->ClientFileContentsResponse(
 
  601        pThis->m_pCliprdrClientContext, &response);
 
  604UINT CClipboardFreeRDP::cb_clipboard_file_range_success(
 
  605    wClipboardDelegate* delegate,
 
  606    const wClipboardFileRangeRequest* request,
 
  607    const BYTE* data, UINT32 size)
 
  609    qDebug(log) << 
"CClipboardFreeRDP::cb_clipboard_file_range_success";
 
  610    CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 };
 
  612#if FREERDP_VERSION_MAJOR >= 3 
  613    response.common.msgFlags = CB_RESPONSE_OK;
 
  615    response.msgFlags = CB_RESPONSE_OK;
 
  617    response.streamId = request->streamId;
 
  618    response.cbRequested = size;
 
  619    response.requestedData = (BYTE*)data;
 
  620    return pThis->m_pCliprdrClientContext->ClientFileContentsResponse(
 
  621        pThis->m_pCliprdrClientContext, &response);
 
  624UINT CClipboardFreeRDP::cb_clipboard_file_range_failure(
 
  625    wClipboardDelegate* delegate,
 
  626    const wClipboardFileRangeRequest* request,
 
  629    qDebug(log) << 
"CClipboardFreeRDP::cb_clipboard_file_range_failure";
 
  630    CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 };
 
  632    WINPR_UNUSED(errorCode);
 
  633#if FREERDP_VERSION_MAJOR >= 3 
  634    response.common.msgFlags = CB_RESPONSE_FAIL;
 
  636    response.msgFlags = CB_RESPONSE_FAIL;
 
  638    response.streamId = request->streamId;
 
  639    return pThis->m_pCliprdrClientContext->ClientFileContentsResponse(
 
  640        pThis->m_pCliprdrClientContext, &response);
 
  643BOOL CClipboardFreeRDP::cbIsFileNameComponentValid(LPCWSTR lpFileName)
 
  645    qDebug(log) << 
"CClipboardFreeRDP::cbIsFileNameComponentValid:" << lpFileName;
 
  651    if (lpFileName[0] == L
'\0')
 
  655    for (c = lpFileName; *c; ++c)
 
  664UINT CClipboardFreeRDP::SendFileContentsFailure(
 
  665    CliprdrClientContext* context,
 
  666    const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
 
  668    qDebug(log) << Q_FUNC_INFO;
 
  669    CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 };
 
  670#if FREERDP_VERSION_MAJOR >= 3 
  671    response.common.msgFlags = CB_RESPONSE_FAIL;
 
  673    response.msgFlags = CB_RESPONSE_FAIL;
 
  675    response.streamId = fileContentsRequest->streamId;
 
  676    return context->ClientFileContentsResponse(context, &response);
 
  679UINT CClipboardFreeRDP::ServerFileRangeRequest(
 
  680    const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
 
  682    qDebug(log) << Q_FUNC_INFO;
 
  683    wClipboardFileRangeRequest request = { 0 };
 
  684    request.streamId = fileContentsRequest->streamId;
 
  685    request.listIndex = fileContentsRequest->listIndex;
 
  686    request.nPositionLow = fileContentsRequest->nPositionLow;
 
  687    request.nPositionHigh = fileContentsRequest->nPositionHigh;
 
  688    request.cbRequested = fileContentsRequest->cbRequested;
 
  689    wClipboardDelegate* pDelegate = ClipboardGetDelegate(m_pClipboard);
 
  691        return pDelegate->ClientRequestFileRange(pDelegate, &request);
 
  695UINT CClipboardFreeRDP::ServerFileSizeRequest(
 
  696    const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
 
  698    qDebug(log) << Q_FUNC_INFO;
 
  699    wClipboardFileSizeRequest request = { 0 };
 
  700    request.streamId = fileContentsRequest->streamId;
 
  701    request.listIndex = fileContentsRequest->listIndex;
 
  703    wClipboardDelegate* pDelegate = ClipboardGetDelegate(m_pClipboard);
 
  704    if(!pDelegate) 
return E_FAIL;
 
  706    if (fileContentsRequest->cbRequested != 
sizeof(UINT64))
 
  708        qWarning(log) << 
"unexpected FILECONTENTS_SIZE request:" 
  709                      << fileContentsRequest->cbRequested << 
" bytes";
 
  712    return pDelegate->ClientRequestFileSize(pDelegate, &request);
 
  715UINT CClipboardFreeRDP::cb_cliprdr_server_file_contents_request(
 
  716    CliprdrClientContext* context,
 
  717    const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
 
  720        "CClipboardFreeRdp::cb_cliprdr_server_file_contents_request";
 
  721    int nRet = CHANNEL_RC_OK;
 
  723    UINT error = NO_ERROR;
 
  725    if(!context) 
return nRet;
 
  733    if ((fileContentsRequest->dwFlags
 
  734         & (FILECONTENTS_SIZE | FILECONTENTS_RANGE))
 
  735        == (FILECONTENTS_SIZE | FILECONTENTS_RANGE))
 
  737        qCritical(log) << 
"invalid CLIPRDR_FILECONTENTS_REQUEST.dwFlags";
 
  738        return SendFileContentsFailure(context, fileContentsRequest);
 
  741    if (fileContentsRequest->dwFlags & FILECONTENTS_SIZE)
 
  742        error = pThis->ServerFileSizeRequest(fileContentsRequest);
 
  744    if (fileContentsRequest->dwFlags & FILECONTENTS_RANGE)
 
  745        error = pThis->ServerFileRangeRequest(fileContentsRequest);
 
  750        << 
"failed to handle CLIPRDR_FILECONTENTS_REQUEST:" << error;
 
  751        return SendFileContentsFailure(context, fileContentsRequest);
 
  758UINT CClipboardFreeRDP::cb_cliprdr_server_format_list(
 
  759    CliprdrClientContext* context,
 
  760    const CLIPRDR_FORMAT_LIST* formatList)
 
  762    qDebug(log) << 
"CClipboardFreeRdp::cb_cliprdr_server_format_list";
 
  763    int nRet = CHANNEL_RC_OK;
 
  767    if(formatList->numFormats < 0)
 
  773    if(!pMimeData) 
return nRet;
 
  774    if(pMimeData->SetFormat(formatList))
 
  776        pMimeData->deleteLater();
 
  781    check = connect(pThis,
 
  784                    SLOT(slotServerFormatData(
const BYTE*, UINT32, UINT32)),
 
  785                    Qt::DirectConnection);
 
  787    check = connect(pThis,
 
  788                    SIGNAL(sigServerFileContentsRespose(UINT32, QByteArray&)),
 
  790                    SLOT(slotServerFileContentsRespose(UINT32, QByteArray&)),
 
  791                    Qt::DirectConnection);
 
  793    check = connect(pMimeData,
 
  794                    SIGNAL(sigSendDataRequest(CliprdrClientContext*, UINT32)),
 
  796                    SLOT(slotSendFormatDataRequest(CliprdrClientContext*, UINT32)));
 
  799    pThis->m_lstClipboardMimeDataId.push_back(pMimeData->GetId());
 
  800    emit pThis->m_pConnect->sigSetClipboard(pMimeData);
 
  804UINT CClipboardFreeRDP::cb_cliprdr_server_format_list_response(
 
  805    CliprdrClientContext* context,
 
  806    const CLIPRDR_FORMAT_LIST_RESPONSE* pformatListResponse)
 
  808#if FREERDP_VERSION_MAJOR >= 3 
  810        << 
"CClipboardFreeRdp::cb_cliprdr_server_format_list_response:type:" 
  811        << pformatListResponse->common.msgType
 
  812        << 
";flag:" << pformatListResponse->common.msgFlags
 
  813        << 
";datalen:" << pformatListResponse->common.dataLen;
 
  816        << 
"CClipboardFreeRdp::cb_cliprdr_server_format_list_response:type:" 
  817        << pformatListResponse->msgType
 
  818        << 
";flag:" << pformatListResponse->msgFlags
 
  819        << 
";datalen:" << pformatListResponse->dataLen;
 
  823#
if FREERDP_VERSION_MAJOR >= 3
 
  824        pformatListResponse->common.msgFlags
 
  826        pformatListResponse->msgFlags
 
  829        qDebug(log) << 
"The server is not support the format";
 
  830    return CHANNEL_RC_OK;
 
  833UINT CClipboardFreeRDP::slotSendFormatDataRequest(CliprdrClientContext* context,
 
  836    UINT rc = CHANNEL_RC_OK;
 
  837    CLIPRDR_FORMAT_DATA_REQUEST formatDataRequest;
 
  838    qDebug(log) << Q_FUNC_INFO;
 
  839    if (!context || !context->ClientFormatDataRequest)
 
  840        return ERROR_INTERNAL_ERROR;
 
  843    pThis->m_RequestFormatId = formatId;
 
  844    formatDataRequest.requestedFormatId = formatId;
 
  845    rc = context->ClientFormatDataRequest(context, &formatDataRequest);
 
  850UINT CClipboardFreeRDP::cb_cliprdr_server_format_data_response(
 
  851    CliprdrClientContext* context,
 
  852    const CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse)
 
  854    qDebug(log) << 
"CClipboardFreeRdp::cb_cliprdr_server_format_data_response";
 
  855    int nRet = CHANNEL_RC_OK;
 
  856    if(!context) 
return nRet;
 
  860    emit pThis->sigServerFormatData(formatDataResponse->requestedFormatData,
 
  861#
if FREERDP_VERSION_MAJOR >= 3
 
  862                                    formatDataResponse->common.dataLen,
 
  864                                    formatDataResponse->dataLen,
 
  866                                    pThis->m_RequestFormatId);
 
  870UINT CClipboardFreeRDP::cb_cliprdr_server_file_contents_response(
 
  871    CliprdrClientContext* context,
 
  872    const CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse)
 
  874    qDebug(log) << 
"CClipboardFreeRdp::cb_cliprdr_server_file_contents_response";
 
  875    int nRet = CHANNEL_RC_OK;
 
  877    if (!context || !fileContentsResponse)
 
  878        return ERROR_INTERNAL_ERROR;
 
  881#
if FREERDP_VERSION_MAJOR >= 3
 
  882        fileContentsResponse->common.msgFlags
 
  884        fileContentsResponse->msgFlags
 
  889            << 
"File contents response error";
 
  895    if(0 == fileContentsResponse->cbRequested)
 
  897        qDebug(log) << 
"CClipboardFreeRdp::cb_cliprdr_server_file_contents_response size is zero.";
 
  899        emit pThis->sigServerFileContentsRespose(
 
  900            fileContentsResponse->streamId,
 
  903        QByteArray data((
char*)fileContentsResponse->requestedData,
 
  904                        fileContentsResponse->cbRequested);
 
  905        emit pThis->sigServerFileContentsRespose(
 
  906            fileContentsResponse->streamId,
 
void sigServerFormatData(const BYTE *pData, UINT32 nLen, UINT32 formatId)
Notify clipboard get data from server.