VirtualBox

Changeset 79027 in vbox for trunk/src/VBox/Additions/common


Ignore:
Timestamp:
Jun 6, 2019 2:47:16 PM (6 years ago)
Author:
vboxsync
Message:

Shared Clipboard/URI: Update (more glue code, transfer callbacks).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp

    r78946 r79027  
    165165 * @param   pDataHdr            Where to store the read meta data header.
    166166 */
    167 static int vbglR3ClipboardReadDataHdr(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr)
     167VBGLR3DECL(int) VbglR3ClipboardReadDataHdr(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr)
    168168{
    169169    AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER);
     
    206206
    207207/**
     208 * Sends a guest clipboard data header to the host.
     209 *
     210 * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_WRITE_DATA_HDR message
     211 * from the host.
     212 *
     213 * @returns VBox status code.
     214 * @param   idClient        The client id returned by VbglR3ClipboardConnect().
     215 * @param   pDataHdr        Pointer to data header to send.
     216 */
     217VBGLR3DECL(int) VbglR3ClipboardWriteDataHdr(HGCMCLIENTID idClient, const PVBOXCLIPBOARDDATAHDR pDataHdr)
     218{
     219    VBoxClipboardWriteDataHdrMsg Msg;
     220    VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA_HDR, VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA_HDR);
     221
     222    VbglHGCMParmUInt32Set(&Msg.uFlags, pDataHdr->uFlags);                             /** @todo Not used yet. */
     223    VbglHGCMParmUInt32Set(&Msg.uScreenId, pDataHdr->uScreenId);                       /** @todo Not used for guest->host (yet). */
     224    VbglHGCMParmUInt64Set(&Msg.cbTotal, pDataHdr->cbTotal);
     225    VbglHGCMParmUInt32Set(&Msg.cbMeta, pDataHdr->cbMeta);
     226    VbglHGCMParmPtrSet(&Msg.cbMetaFmt, pDataHdr->pvMetaFmt, pDataHdr->cbMetaFmt);
     227    VbglHGCMParmUInt32Set(&Msg.cbMetaFmt, pDataHdr->cbMetaFmt);
     228    VbglHGCMParmUInt64Set(&Msg.cObjects, pDataHdr->cObjects);
     229    VbglHGCMParmUInt32Set(&Msg.enmCompression, pDataHdr->enmCompression);             /** @todo Not used yet. */
     230    VbglHGCMParmUInt32Set(&Msg.enmChecksumType, pDataHdr->enmChecksumType);           /** @todo Not used yet. */
     231    VbglHGCMParmPtrSet(&Msg.cbChecksum, pDataHdr->pvChecksum, pDataHdr->cbChecksum);  /** @todo Not used yet. */
     232    VbglHGCMParmUInt32Set(&Msg.cbChecksum, pDataHdr->cbChecksum);                     /** @todo Not used yet. */
     233
     234    return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     235}
     236
     237/**
    208238 * Reads a (meta) data chunk from the host.
    209239 *
     
    261291 * @returns IPRT status code.
    262292 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
    263  * @param   pDataHdr            Where to store the data header data.
    264  * @param   pMetaData           Returns the received meta data. Needs to be free'd by the caller.
     293 * @param   pDataHdr            Pointer to data header to use.
     294 * @param   pvMeta              Where to store the received meta data.
     295 * @param   cbMeta              Size (in bytes) of meta data buffer.
     296 * @param   pcbRead             How much bytes were read on success. Optional.
    265297 */
    266298static int vbglR3ClipboardReadMetaDataLoop(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr,
    267                                            PSHAREDCLIPBOARDMETADATA pMetaData)
    268 {
    269     AssertPtrReturn(pDataHdr,  VERR_INVALID_POINTER);
    270     AssertPtrReturn(pMetaData, VERR_INVALID_POINTER);
    271 
    272     int rc;
    273     uint32_t cbDataRecv;
     299                                           void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead)
     300{
     301    AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER);
     302    AssertPtrReturn(pvMeta,   VERR_INVALID_POINTER);
    274303
    275304    LogFlowFuncEnter();
    276305
    277     rc = vbglR3ClipboardReadDataHdr(idClient, pDataHdr);
    278     if (RT_FAILURE(rc))
    279         return rc;
     306    int rc = VINF_SUCCESS;
     307
     308    uint32_t cbReadTotal = 0;
    280309
    281310    LogFlowFunc(("cbTotal=%RU64, cbMeta=%RU32, cObjects=%RU32\n", pDataHdr->cbTotal, pDataHdr->cbMeta, pDataHdr->cObjects));
    282311    if (pDataHdr->cbMeta)
    283312    {
    284         uint64_t cbDataTmp = 0;
    285         void    *pvDataTmp = RTMemAlloc(pDataHdr->cbMeta);
    286         if (!pvDataTmp)
    287             rc = VERR_NO_MEMORY;
    288 
    289         if (RT_SUCCESS(rc))
     313        uint32_t cbToRead = RT_MIN(cbMeta, pDataHdr->cbMeta);
     314        while (cbToRead)
    290315        {
    291             const uint32_t cbMaxChunkSize = VBOX_SHARED_CLIPBOARD_MAX_CHUNK_SIZE;
    292 
    293             uint8_t *pvDataOff = (uint8_t *)pvDataTmp;
    294             while (cbDataTmp < pDataHdr->cbMeta)
    295             {
    296                 rc = vbglR3ClipboardReadDataChunk(idClient, pDataHdr,
    297                                                   pvDataOff, RT_MIN(pDataHdr->cbMeta - cbDataTmp, cbMaxChunkSize),
    298                                                   &cbDataRecv);
    299                 if (RT_SUCCESS(rc))
    300                 {
    301                     LogFlowFunc(("cbDataRecv=%RU32, cbDataTmp=%RU64\n", cbDataRecv, cbDataTmp));
    302                     Assert(cbDataTmp + cbDataRecv <= pDataHdr->cbMeta);
    303                     cbDataTmp += cbDataRecv;
    304                     pvDataOff += cbDataRecv;
    305                 }
    306                 else
    307                     break;
    308             }
    309 
    310             if (RT_SUCCESS(rc))
    311             {
    312                 Assert(cbDataTmp == pDataHdr->cbMeta);
    313 
    314                 LogFlowFunc(("Received %RU64 bytes of data\n", cbDataTmp));
    315 
    316                 pMetaData->pvMeta = pvDataTmp;
    317                 pMetaData->cbMeta = cbDataTmp;
    318                 pMetaData->cbUsed = cbDataTmp;
    319             }
    320             else
    321                 RTMemFree(pvDataTmp);
     316            uint32_t cbRead;
     317            rc = vbglR3ClipboardReadDataChunk(idClient, pDataHdr,
     318                                              (uint8_t *)pvMeta + cbReadTotal, cbToRead, &cbRead);
     319            if (RT_FAILURE(rc))
     320                break;
     321
     322            Assert(cbToRead >= cbRead);
     323            cbToRead -= cbRead;
     324
     325            cbReadTotal += cbRead;
    322326        }
    323327    }
    324     else
    325         SharedClipboardMetaDataDestroy(pMetaData);
     328
     329    if (RT_SUCCESS(rc))
     330    {
     331        if (pcbRead)
     332            *pcbRead = cbReadTotal;
     333    }
    326334
    327335    LogFlowFuncLeaveRC(rc);
     
    334342 * @returns IPRT status code.
    335343 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
    336  * @param   URIList             Where to store received meta data.
    337  */
    338 static int vbglR3ClipboardReadMetaDataEx(HGCMCLIENTID idClient, SharedClipboardURIList &URIList)
    339 {
    340     /* The rest is optional. */
    341 
    342     VBOXCLIPBOARDDATAHDR dataHdr;
    343     RT_ZERO(dataHdr);
    344 
    345     dataHdr.cbMetaFmt = VBOX_SHARED_CLIPBOARD_MAX_CHUNK_SIZE;
    346     dataHdr.pvMetaFmt = RTMemAlloc(dataHdr.cbMetaFmt);
    347     if (!dataHdr.pvMetaFmt)
    348         return VERR_NO_MEMORY;
    349 
    350     SHAREDCLIPBOARDMETADATA dataMeta;
    351     SharedClipboardMetaDataInit(&dataMeta);
    352 
    353     int rc = vbglR3ClipboardReadMetaDataLoop(idClient, &dataHdr, &dataMeta);
    354     if (RT_SUCCESS(rc))
    355     {
    356         /**
    357          * Check if this is an URI event. If so, let VbglR3 do all the actual
    358          * data transfer + file/directory creation internally without letting
    359          * the caller know.
    360          *
    361          * This keeps the actual (guest OS-)dependent client (like VBoxClient /
    362          * VBoxTray) small by not having too much redundant code.
    363          */
    364         Assert(dataHdr.cbMetaFmt);
    365         AssertPtr(dataHdr.pvMetaFmt);
    366         if (SharedClipboardMIMEHasFileURLs((char *)dataHdr.pvMetaFmt, dataHdr.cbMetaFmt)) /* URI data. */
    367         {
    368             rc = URIList.SetFromURIData(dataMeta.pvMeta, dataMeta.cbMeta, 0 /* fFlags */);
    369 
    370         #if 0
    371             if (RT_SUCCESS(rc))
    372                 rc = vbglR3ClipboardReadURIData(idClient, &dataHdr);
    373 
    374             if (RT_SUCCESS(rc))
    375             {
    376                 if (pvData)
    377                 {
    378                     /* Reuse data buffer to fill in the transformed URI file list. */
    379                     RTMemFree(pvData);
    380                     pvData = NULL;
    381                 }
    382 
    383             #if 0
    384                 RTCString strData = lstURI.GetRootEntries(clipboardCache.GetDirAbs());
    385                 Assert(!strData.isEmpty());
    386 
    387                 cbData = strData.length() + 1;
    388                 LogFlowFunc(("URI list has %zu bytes\n", cbData));
    389 
    390                 pvData = RTMemAlloc(cbData);
    391                 if (pvData)
    392                 {
    393                     memcpy(pvData, strData.c_str(), cbData);
    394                 }
    395                 else
    396                     rc =  VERR_NO_MEMORY;
    397             #endif
    398             }
    399         #endif
    400         }
    401         else /* Raw data. */
    402         {
    403             /** @todo Implement this. */
    404         }
    405 
    406         SharedClipboardMetaDataDestroy(&dataMeta);
    407     }
    408 
    409     if (dataHdr.pvMetaFmt)
    410     {
    411         RTMemFree(dataHdr.pvMetaFmt);
    412         dataHdr.pvMetaFmt = NULL;
    413     }
     344 * @param   pDataHdr            Pointer to data header to use.
     345 * @param   pvMeta              Where to store the received meta data.
     346 * @param   cbMeta              Size (in bytes) of meta data buffer.
     347 * @param   pcbRead             How much bytes were read on success. Optional.
     348 */
     349static int vbglR3ClipboardReadMetaDataInternal(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr,
     350                                               void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead)
     351{
     352   LogFlowFuncEnter();
     353
     354    int rc = vbglR3ClipboardReadMetaDataLoop(idClient, pDataHdr, pvMeta, cbMeta, pcbRead);
    414355
    415356    LogFlowFuncLeaveRC(rc);
     
    418359
    419360/**
     361 * Reads the actual meta data from the host, extended version.
     362 *
     363 * @returns IPRT status code.
     364 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
     365 * @param   pvMeta              Where to store the received meta data.
     366 * @param   cbMeta              Size (in bytes) of meta data buffer.
     367 * @param   pcbRead             How much bytes were read on success. Optional.
     368 */
     369VBGLR3DECL(int) VbglR3ClipboardReadMetaDataEx(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr,
     370                                              void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead)
     371{
     372    return vbglR3ClipboardReadMetaDataInternal(idClient, pDataHdr, pvMeta, cbMeta, pcbRead);
     373}
     374
     375/**
    420376 * Reads the actual meta data from the host.
    421377 *
    422378 * @returns IPRT status code.
    423379 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
    424  * @param   URIList             Where to store received meta data.
    425  */
    426 VBGLR3DECL(int) VbglR3ClipboardReadMetaData(HGCMCLIENTID idClient, SharedClipboardURIList &URIList)
    427 {
    428     return vbglR3ClipboardReadMetaDataEx(idClient, URIList);
    429 }
    430 
    431 VBGLR3DECL(int) VbglR3ClipboardWriteMetaData(HGCMCLIENTID idClient, const SharedClipboardURIList &URIList)
    432 {
    433     RT_NOREF(idClient, URIList);
     380 * @param   pvMeta              Where to store the received meta data.
     381 * @param   cbMeta              Size (in bytes) of meta data buffer.
     382 * @param   pcbRead             How much bytes were read on success. Optional.
     383 */
     384VBGLR3DECL(int) VbglR3ClipboardReadMetaData(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr,
     385                                            void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead)
     386{
     387    return VbglR3ClipboardReadMetaDataEx(idClient, pDataHdr, pvMeta, cbMeta, pcbRead);
     388}
     389
     390/**
     391 * Writes the actual meta data to the host, extended version.
     392 *
     393 * @returns IPRT status code.
     394 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
     395 * @param   pvMeta              Pointer to meta data buffer.
     396 * @param   cbMeta              Size (in bytes) of meta data buffer.
     397 * @param   pcbWritten          How much bytes were written on success. Optional.
     398 */
     399VBGLR3DECL(int) VbglR3ClipboardWriteMetaDataEx(HGCMCLIENTID idClient, const void *pvMeta, uint32_t cbMeta, uint32_t *pcbWritten)
     400{
     401    RT_NOREF(idClient, pvMeta, cbMeta, pcbWritten);
    434402    return 0;
     403}
     404
     405/**
     406 * Writes the actual meta data to the host.
     407 *
     408 * @returns IPRT status code.
     409 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
     410 * @param   pvMeta              Pointer to meta data buffer.
     411 * @param   cbMeta              Size (in bytes) of meta data buffer.
     412 * @param   pcbWritten          How much bytes were written on success. Optional.
     413 */
     414VBGLR3DECL(int) VbglR3ClipboardWriteMetaData(HGCMCLIENTID idClient, const void *pvMeta, uint32_t cbMeta, uint32_t *pcbWritten)
     415{
     416    return VbglR3ClipboardWriteMetaDataEx(idClient, pvMeta, cbMeta, pcbWritten);
    435417}
    436418
     
    688670    VBoxClipboardWriteFormatsMsg Msg;
    689671
    690     VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_REPORT_FORMATS, 1);
     672    VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_REPORT_FORMATS, VBOX_SHARED_CLIPBOARD_CPARMS_FORMATS);
    691673    VbglHGCMParmUInt32Set(&Msg.formats, fFormats);
    692674
     
    709691{
    710692    VBoxClipboardWriteDataMsg Msg;
    711     VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA, 2);
     693    VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA, VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA);
    712694    VbglHGCMParmUInt32Set(&Msg.format, fFormat);
    713695    VbglHGCMParmPtrSet(&Msg.ptr, pv, cb);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette