VirtualBox

Changeset 78307 in vbox for trunk/src


Ignore:
Timestamp:
Apr 26, 2019 6:41:46 AM (6 years ago)
Author:
vboxsync
Message:

Shared Clipboard/URI: First commit; work in progress.

Location:
trunk/src/VBox
Files:
12 edited
5 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk

    r78151 r78307  
    4747ifdef VBOX_WITH_SHARED_CLIPBOARD
    4848 VBoxTray_DEFS     += \
    49         VBOX_WITH_SHARED_CLIPBOARD
     49        VBOX_WITH_SHARED_CLIPBOARD \
     50        $(if $(VBOX_WITH_SHARED_CLIPBOARD_URI_LIST),VBOX_WITH_SHARED_CLIPBOARD_URI_LIST,)
    5051 VBoxTray_SOURCES  += \
    5152        VBoxClipboard.cpp \
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp

    r78172 r78307  
    7878               int vboxrc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats);
    7979               if (RT_SUCCESS(vboxrc))
    80                    vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats);
     80                   vboxrc = VbglR3ClipboardWriteFormats(pCtx->u32ClientID, uFormats);
    8181           }
    8282        }
     
    128128               int vboxrc = VBoxClipboardWinGetFormats(pWinCtx, &uFormats);
    129129               if (RT_SUCCESS(vboxrc))
    130                    vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats);
     130                   vboxrc = VbglR3ClipboardWriteFormats(pCtx->u32ClientID, uFormats);
    131131           }
    132132
     
    386386               }
    387387
     388#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     389               if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
     390                   hClip = SetClipboardData(CF_HDROP, NULL);
     391#endif
    388392               VBoxClipboardWinClose();
    389393
     
    466470                   }
    467471               }
    468 
     472#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     473               else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
     474               {
     475                   hClip = GetClipboardData(CF_HDROP);
     476                   if (hClip)
     477                   {
     478                       HDROP hDrop = (HDROP)GlobalLock(hClip);
     479                       if (hDrop)
     480                       {
     481                           vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_URI_LIST,
     482                                                             );
     483                           GlobalUnlock(hClip);
     484                       }
     485                       else
     486                       {
     487                           hClip = NULL;
     488                       }
     489                   }
     490               }
     491#endif
    469492               VBoxClipboardWinClose();
    470493           }
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/Makefile.kmk

    r76553 r78307  
    110110        VBOX_WITH_HGCM \
    111111        $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS,) \
     112        $(if $(VBOX_WITH_SHARED_CLIPBOARD),VBOX_WITH_SHARED_CLIPBOARD,) \
    112113        $(if $(VBOX_WITH_SHARED_FOLDERS),VBOX_WITH_SHARED_FOLDERS,) \
    113114        $(if $(VBOX_WITH_GUEST_CONTROL),VBOX_WITH_GUEST_CONTROL,)
     
    160161        VBoxGuestR3LibDragAndDrop.cpp
    161162endif
     163ifdef VBOX_WITH_SHARED_CLIPBOARD
     164 VBoxGuestR3Lib_DEFS      += \
     165        $(if $(VBOX_WITH_SHARED_CLIPBOARD_URI_LIST),VBOX_WITH_SHARED_CLIPBOARD_URI_LIST,)
     166endif
    162167
    163168VBoxGuestR3LibAdditions.cpp_DEFS = VBOX_SVN_REV=$(VBOX_SVN_REV)
     
    202207        $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS,) \
    203208        $(if $(VBOX_WITH_DRAG_AND_DROP),VBOX_WITH_DRAG_AND_DROP,) \
    204         $(if $(VBOX_WITH_DRAG_AND_DROP_GH),VBOX_WITH_DRAG_AND_DROP_GH,)
     209        $(if $(VBOX_WITH_DRAG_AND_DROP_GH),VBOX_WITH_DRAG_AND_DROP_GH,) \
     210        $(if $(VBOX_WITH_SHARED_CLIPBOARD_URI_LIST),VBOX_WITH_SHARED_CLIPBOARD_URI_LIST,)
    205211VBoxGuestR3LibXFree86_SOURCES  = \
    206212        VBoxGuestR3Lib.cpp \
     
    229235        $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS,) \
    230236        $(if $(VBOX_WITH_DRAG_AND_DROP),VBOX_WITH_DRAG_AND_DROP,) \
    231         $(if $(VBOX_WITH_DRAG_AND_DROP_GH),VBOX_WITH_DRAG_AND_DROP_GH,)
     237        $(if $(VBOX_WITH_DRAG_AND_DROP_GH),VBOX_WITH_DRAG_AND_DROP_GH,) \
     238        $(if $(VBOX_WITH_SHARED_CLIPBOARD_URI_LIST),VBOX_WITH_SHARED_CLIPBOARD_URI_LIST,)
    232239VBoxGuestR3LibXOrg_SOURCES  = $(VBoxGuestR3LibXFree86_SOURCES)
    233240
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp

    r76553 r78307  
    2929*   Header Files                                                                                                                 *
    3030*********************************************************************************************************************************/
     31#include <VBox/GuestHost/SharedClipboard.h>
     32#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     33# include <VBox/GuestHost/SharedClipboard-uri.h>
     34#endif
    3135#include <VBox/HostServices/VBoxClipboardSvc.h>
    3236#include <VBox/err.h>
    3337#include <iprt/assert.h>
    3438#include <iprt/string.h>
     39#include <iprt/cpp/ministring.h>
    3540#include "VBoxGuestR3LibInternal.h"
     41
     42
     43/*********************************************************************************************************************************
     44*   Prototypes                                                                                                                   *
     45*********************************************************************************************************************************/
     46#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     47static int vbglR3ClipboardSendErrorInternal(HGCMCLIENTID idClient, int rcErr);
     48static int vbglR3ClipboardSendURIData(HGCMCLIENTID idClient, const void *pvData, size_t cbData);
     49#endif
    3650
    3751
     
    140154
    141155/**
    142  * Advertises guest clipboard formats to the host.
     156 * Writes (advertises) guest clipboard formats to the host.
    143157 *
    144158 * @returns VBox status code.
     
    146160 * @param   fFormats        The formats to advertise.
    147161 */
    148 VBGLR3DECL(int) VbglR3ClipboardReportFormats(HGCMCLIENTID idClient, uint32_t fFormats)
    149 {
    150     VBoxClipboardFormats Msg;
    151 
    152     VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_FORMATS, 1);
     162VBGLR3DECL(int) VbglR3ClipboardWriteFormats(HGCMCLIENTID idClient, uint32_t fFormats)
     163{
     164    VBoxClipboardWriteFormats Msg;
     165
     166    VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_FORMATS, 1);
    153167    VbglHGCMParmUInt32Set(&Msg.formats, fFormats);
    154168
     
    156170}
    157171
    158 
    159 /**
    160  * Send guest clipboard data to the host.
     172/**
     173 * Sends guest clipboard data to the host.
    161174 *
    162175 * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA message
     
    169182 * @param   cb              The size of the data.
    170183 */
    171 VBGLR3DECL(int) VbglR3ClipboardWriteData(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb)
     184static int vbglR3ClipboardWriteDataRaw(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb)
    172185{
    173186    VBoxClipboardWriteData Msg;
     
    179192}
    180193
     194/**
     195 * Send guest clipboard data to the host.
     196 *
     197 * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA message
     198 * from the host.
     199 *
     200 * @returns VBox status code.
     201 * @param   idClient        The client id returned by VbglR3ClipboardConnect().
     202 * @param   fFormat         The format of the data.
     203 * @param   pv              The data.
     204 * @param   cb              The size of the data.
     205 */
     206VBGLR3DECL(int) VbglR3ClipboardWriteData(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb)
     207{
     208    int rc;
     209#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     210    if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
     211    {
     212        rc = vbglR3ClipboardSendURIData(idClient, pv, cb);
     213    }
     214    else
     215#else
     216        RT_NOREF(fFormat);
     217#endif
     218        rc = vbglR3ClipboardWriteDataRaw(idClient, fFormat, pv, cb);
     219
     220    if (RT_FAILURE(rc))
     221    {
     222        int rc2 = vbglR3ClipboardSendErrorInternal(idClient, rc);
     223        if (RT_FAILURE(rc2))
     224            LogFlowFunc(("Unable to send error (%Rrc) to host, rc=%Rrc\n", rc, rc2));
     225    }
     226
     227    return rc;
     228}
     229
     230#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     231/**
     232 * Guest -> Host
     233 * Utility function to send clipboard data from guest to the host.
     234 *
     235 * @returns IPRT status code.
     236 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
     237 * @param   pvData              Data block to send.
     238 * @param   cbData              Size (in bytes) of data block to send.
     239 * @param   pDataHdr            Data header to use -- needed for accounting.
     240 */
     241static int vbglR3ClipboardSendDataInternal(HGCMCLIENTID idClient,
     242                                           void *pvData, uint64_t cbData, PVBOXCLIPBOARDDATAHDR pDataHdr)
     243{
     244    AssertPtrReturn(pvData,   VERR_INVALID_POINTER);
     245    AssertReturn(cbData,      VERR_INVALID_PARAMETER);
     246    AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER);
     247
     248    VBoxClipboardWriteDataHdrMsg MsgHdr;
     249    RT_ZERO(MsgHdr);
     250
     251    VBGL_HGCM_HDR_INIT(&MsgHdr.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA_HDR, 12);
     252    MsgHdr.uContext.SetUInt32(0);                           /** @todo Not used yet. */
     253    MsgHdr.uFlags.SetUInt32(0);                             /** @todo Not used yet. */
     254    MsgHdr.uScreenId.SetUInt32(0);                          /** @todo Not used for guest->host (yet). */
     255    MsgHdr.cbTotal.SetUInt64(pDataHdr->cbTotal);
     256    MsgHdr.cbMeta.SetUInt32(pDataHdr->cbMeta);
     257    MsgHdr.pvMetaFmt.SetPtr(pDataHdr->pvMetaFmt, pDataHdr->cbMetaFmt);
     258    MsgHdr.cbMetaFmt.SetUInt32(pDataHdr->cbMetaFmt);
     259    MsgHdr.cObjects.SetUInt64(pDataHdr->cObjects);
     260    MsgHdr.enmCompression.SetUInt32(0);                     /** @todo Not used yet. */
     261    MsgHdr.enmChecksumType.SetUInt32(RTDIGESTTYPE_INVALID); /** @todo Not used yet. */
     262    MsgHdr.pvChecksum.SetPtr(NULL, 0);                      /** @todo Not used yet. */
     263    MsgHdr.cbChecksum.SetUInt32(0);                         /** @todo Not used yet. */
     264
     265    int rc = VbglR3HGCMCall(&MsgHdr.hdr, sizeof(MsgHdr));
     266
     267    LogFlowFunc(("cbTotal=%RU64, cbMeta=%RU32, cObjects=%RU64, rc=%Rrc\n",
     268                 pDataHdr->cbTotal, pDataHdr->cbMeta, pDataHdr->cObjects, rc));
     269
     270    if (RT_SUCCESS(rc))
     271    {
     272        VBoxClipboardWriteDataChunkMsg MsgData;
     273        RT_ZERO(MsgData);
     274
     275        VBGL_HGCM_HDR_INIT(&MsgData.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA_CHUNK, 5);
     276        MsgData.uContext.SetUInt32(0);      /** @todo Not used yet. */
     277        MsgData.pvChecksum.SetPtr(NULL, 0); /** @todo Not used yet. */
     278        MsgData.cbChecksum.SetUInt32(0);    /** @todo Not used yet. */
     279
     280        uint32_t       cbCurChunk;
     281        const uint32_t cbMaxChunk = VBOX_SHARED_CLIPBOARD_MAX_CHUNK_SIZE;
     282        uint32_t       cbSent     = 0;
     283
     284        HGCMFunctionParameter *pParm = &MsgData.pvData;
     285
     286        while (cbSent < cbData)
     287        {
     288            cbCurChunk = RT_MIN(cbData - cbSent, cbMaxChunk);
     289            pParm->SetPtr(static_cast<uint8_t *>(pvData) + cbSent, cbCurChunk);
     290
     291            MsgData.cbData.SetUInt32(cbCurChunk);
     292
     293            rc = VbglR3HGCMCall(&MsgData.hdr, sizeof(MsgData));
     294            if (RT_FAILURE(rc))
     295                break;
     296
     297            cbSent += cbCurChunk;
     298        }
     299
     300        LogFlowFunc(("cbMaxChunk=%RU32, cbData=%RU64, cbSent=%RU32, rc=%Rrc\n",
     301                     cbMaxChunk, cbData, cbSent, rc));
     302
     303        if (RT_SUCCESS(rc))
     304            Assert(cbSent == cbData);
     305    }
     306
     307    LogFlowFuncLeaveRC(rc);
     308    return rc;
     309}
     310
     311/**
     312 * Guest -> Host
     313 * Utility function to send a guest directory to the host.
     314 *
     315 * @returns IPRT status code.
     316 * @param   idClient        The client id returned by VbglR3ClipboardConnect().
     317 * @param   pObj            URI object containing the directory to send.
     318 */
     319static int vbglR3ClipboardSendDir(HGCMCLIENTID idClient, SharedClipboardURIObject *pObj)
     320{
     321    AssertPtrReturn(pObj,                                         VERR_INVALID_POINTER);
     322    AssertReturn(pObj->GetType() == SharedClipboardURIObject::Type_Directory, VERR_INVALID_PARAMETER);
     323
     324    RTCString strPath = pObj->GetDestPathAbs();
     325    LogFlowFunc(("strDir=%s (%zu), fMode=0x%x\n",
     326                 strPath.c_str(), strPath.length(), pObj->GetMode()));
     327
     328    if (strPath.length() > RTPATH_MAX)
     329        return VERR_INVALID_PARAMETER;
     330
     331    const uint32_t cbPath = (uint32_t)strPath.length() + 1; /* Include termination. */
     332
     333    VBoxClipboardWriteDirMsg Msg;
     334    RT_ZERO(Msg);
     335
     336    VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DIR, 4);
     337    /** @todo Context ID not used yet. */
     338    Msg.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)cbPath);
     339    Msg.cbName.SetUInt32((uint32_t)cbPath);
     340    Msg.fMode.SetUInt32(pObj->GetMode());
     341
     342    return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     343}
     344
     345/**
     346 * Guest -> Host
     347 * Utility function to send a file from the guest to the host.
     348 *
     349 * @returns IPRT status code.
     350 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
     351 * @param   pObj                URI object containing the file to send.
     352 */
     353static int vbglR3ClipboardSendFile(HGCMCLIENTID idClient, SharedClipboardURIObject *pObj)
     354{
     355    AssertPtrReturn(pObj,                                    VERR_INVALID_POINTER);
     356    AssertReturn(pObj->GetType() == SharedClipboardURIObject::Type_File, VERR_INVALID_PARAMETER);
     357    AssertReturn(pObj->IsOpen(),                             VERR_INVALID_STATE);
     358
     359    uint32_t cbBuf = _64K;           /** @todo Make this configurable? */
     360    void *pvBuf = RTMemAlloc(cbBuf);
     361    if (!pvBuf)
     362        return VERR_NO_MEMORY;
     363
     364    RTCString strPath = pObj->GetDestPathAbs();
     365
     366    LogFlowFunc(("strFile=%s (%zu), cbSize=%RU64, fMode=0x%x\n", strPath.c_str(), strPath.length(),
     367                 pObj->GetSize(), pObj->GetMode()));
     368
     369    VBoxClipboardWriteFileHdrMsg MsgHdr;
     370    RT_ZERO(MsgHdr);
     371
     372    VBGL_HGCM_HDR_INIT(&MsgHdr.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_FILE_HDR, 6);
     373    MsgHdr.uContext.SetUInt32(0);                                                    /* Context ID; unused at the moment. */
     374    MsgHdr.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)(strPath.length() + 1));
     375    MsgHdr.cbName.SetUInt32((uint32_t)(strPath.length() + 1));
     376    MsgHdr.uFlags.SetUInt32(0);                                                      /* Flags; unused at the moment. */
     377    MsgHdr.fMode.SetUInt32(pObj->GetMode());                                         /* File mode */
     378    MsgHdr.cbTotal.SetUInt64(pObj->GetSize());                                       /* File size (in bytes). */
     379
     380    int rc = VbglR3HGCMCall(&MsgHdr.hdr, sizeof(MsgHdr));
     381
     382    LogFlowFunc(("Sending file header resulted in %Rrc\n", rc));
     383
     384    if (RT_SUCCESS(rc))
     385    {
     386        /*
     387         * Send the actual file data, chunk by chunk.
     388         */
     389        VBoxClipboardWriteFileDataMsg Msg;
     390        RT_ZERO(Msg);
     391
     392        VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_FILE_DATA, 5);
     393        Msg.uContext.SetUInt32(0);
     394        Msg.pvChecksum.SetPtr(NULL, 0);
     395        Msg.cbChecksum.SetUInt32(0);
     396
     397        uint64_t cbToReadTotal  = pObj->GetSize();
     398        uint64_t cbWrittenTotal = 0;
     399        while (cbToReadTotal)
     400        {
     401            uint32_t cbToRead = RT_MIN(cbToReadTotal, cbBuf);
     402            uint32_t cbRead   = 0;
     403            if (cbToRead)
     404                rc = pObj->Read(pvBuf, cbToRead, &cbRead);
     405
     406            LogFlowFunc(("cbToReadTotal=%RU64, cbToRead=%RU32, cbRead=%RU32, rc=%Rrc\n",
     407                         cbToReadTotal, cbToRead, cbRead, rc));
     408
     409            if (   RT_SUCCESS(rc)
     410                && cbRead)
     411            {
     412                Msg.pvData.SetPtr(pvBuf, cbRead);
     413                Msg.cbData.SetUInt32(cbRead);
     414                /** @todo Calculate + set checksums. */
     415
     416                rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     417            }
     418
     419            if (RT_FAILURE(rc))
     420            {
     421                LogFlowFunc(("Reading failed with rc=%Rrc\n", rc));
     422                break;
     423            }
     424
     425            Assert(cbRead  <= cbToReadTotal);
     426            cbToReadTotal  -= cbRead;
     427            cbWrittenTotal += cbRead;
     428
     429            LogFlowFunc(("%RU64/%RU64 -- %RU8%%\n", cbWrittenTotal, pObj->GetSize(), cbWrittenTotal * 100 / pObj->GetSize()));
     430        };
     431    }
     432
     433    RTMemFree(pvBuf);
     434
     435    LogFlowFuncLeaveRC(rc);
     436    return rc;
     437}
     438
     439/**
     440 * Guest -> Host
     441 * Utility function to send an URI object from guest to the host.
     442 *
     443 * @returns IPRT status code.
     444 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
     445 * @param   pObj                URI object to send from guest to the host.
     446 */
     447static int vbglR3ClipboardSendURIObject(HGCMCLIENTID idClient, SharedClipboardURIObject *pObj)
     448{
     449    AssertPtrReturn(pObj, VERR_INVALID_POINTER);
     450
     451    int rc;
     452
     453    switch (pObj->GetType())
     454    {
     455        case SharedClipboardURIObject::Type_Directory:
     456            rc = vbglR3ClipboardSendDir(idClient, pObj);
     457            break;
     458
     459        case SharedClipboardURIObject::Type_File:
     460            rc = vbglR3ClipboardSendFile(idClient, pObj);
     461            break;
     462
     463        default:
     464            AssertMsgFailed(("Object type %ld not implemented\n", pObj->GetType()));
     465            rc = VERR_NOT_IMPLEMENTED;
     466            break;
     467    }
     468
     469    return rc;
     470}
     471
     472/**
     473 * Guest -> Host
     474 * Utility function to send URI data from guest to the host.
     475 *
     476 * @returns IPRT status code.
     477 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
     478 * @param   pvData              Block to URI data to send.
     479 * @param   cbData              Size (in bytes) of URI data to send.
     480 */
     481static int vbglR3ClipboardSendURIData(HGCMCLIENTID idClient, const void *pvData, size_t cbData)
     482{
     483    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
     484    AssertReturn(cbData,    VERR_INVALID_PARAMETER);
     485
     486    RTCList<RTCString> lstPaths =
     487        RTCString((const char *)pvData, cbData).split("\r\n");
     488
     489    /** @todo Add symlink support (SHAREDCLIPBOARDURILIST_FLAGS_RESOLVE_SYMLINKS) here. */
     490    /** @todo Add lazy loading (SHAREDCLIPBOARDURILIST_FLAGS_LAZY) here. */
     491    uint32_t fFlags = SHAREDCLIPBOARDURILIST_FLAGS_KEEP_OPEN;
     492
     493    SharedClipboardURIList lstURI;
     494    int rc = lstURI.AppendURIPathsFromList(lstPaths, fFlags);
     495    if (RT_SUCCESS(rc))
     496    {
     497        /*
     498         * Send the (meta) data; in case of URIs it's the (non-recursive) file/directory
     499         * URI list the host needs to know upfront to set up the drag'n drop operation.
     500         */
     501        RTCString strRootDest = lstURI.GetRootEntries();
     502        if (strRootDest.isNotEmpty())
     503        {
     504            void *pvURIList  = (void *)strRootDest.c_str(); /* URI root list. */
     505            uint32_t cbURLIist = (uint32_t)strRootDest.length() + 1; /* Include string termination. */
     506
     507            /* The total size also contains the size of the meta data. */
     508            uint64_t cbTotal  = cbURLIist;
     509                     cbTotal += lstURI.GetTotalBytes();
     510
     511            /* We're going to send an URI list in text format. */
     512            const char     szMetaFmt[] = "text/uri-list";
     513            const uint32_t cbMetaFmt   = (uint32_t)strlen(szMetaFmt) + 1; /* Include termination. */
     514
     515            VBOXCLIPBOARDDATAHDR dataHdr;
     516            dataHdr.uFlags    = 0; /* Flags not used yet. */
     517            dataHdr.cbTotal   = cbTotal;
     518            dataHdr.cbMeta    = cbURLIist;
     519            dataHdr.pvMetaFmt = (void *)szMetaFmt;
     520            dataHdr.cbMetaFmt = cbMetaFmt;
     521            dataHdr.cObjects  = lstURI.GetTotalCount();
     522
     523            rc = vbglR3ClipboardSendDataInternal(idClient,
     524                                                 pvURIList, cbURLIist, &dataHdr);
     525        }
     526        else
     527            rc = VERR_INVALID_PARAMETER;
     528    }
     529
     530    if (RT_SUCCESS(rc))
     531    {
     532        while (!lstURI.IsEmpty())
     533        {
     534            SharedClipboardURIObject *pNextObj = lstURI.First();
     535
     536            rc = vbglR3ClipboardSendURIObject(idClient, pNextObj);
     537            if (RT_FAILURE(rc))
     538                break;
     539
     540            lstURI.RemoveFirst();
     541        }
     542    }
     543
     544    return rc;
     545}
     546
     547/**
     548 * Guest -> Host
     549 * Sends an error back to the host.
     550 *
     551 * @returns IPRT status code.
     552 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
     553 * @param   rcErr               Error (IPRT-style) to send.
     554 */
     555static int vbglR3ClipboardSendErrorInternal(HGCMCLIENTID idClient, int rcErr)
     556{
     557    VBoxClipboardWriteErrorMsg Msg;
     558    RT_ZERO(Msg);
     559
     560    VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_ERROR, 2);
     561    /** @todo Context ID not used yet. */
     562    Msg.uContext.SetUInt32(0);
     563    Msg.rc.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */
     564
     565    int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     566
     567    /*
     568     * Never return an error if the host did not accept the error at the current
     569     * time.  This can be due to the host not having any appropriate callbacks
     570     * set which would handle that error.
     571     *
     572     * bird: Looks like VERR_NOT_SUPPORTED is what the host will return if it
     573     *       doesn't an appropriate callback.  The code used to ignore ALL errors
     574     *       the host would return, also relevant ones.
     575     */
     576    if (RT_FAILURE(rc))
     577        LogFlowFunc(("Sending error %Rrc failed with rc=%Rrc\n", rcErr, rc));
     578    if (rc == VERR_NOT_SUPPORTED)
     579        rc = VINF_SUCCESS;
     580
     581    return rc;
     582}
     583
     584/**
     585 * Guest -> Host
     586 * Send an error back to the host.
     587 *
     588 * @returns IPRT status code.
     589 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
     590 * @param   rcErr               Error (IPRT-style) to send.
     591 */
     592VBGLR3DECL(int) VbglR3ClipboardSendError(HGCMCLIENTID idClient, int rcErr)
     593{
     594    return vbglR3ClipboardSendErrorInternal(idClient, rcErr);
     595}
     596#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
     597
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceClipboard-os2.cpp

    r78181 r78307  
    611611    }
    612612    VGSvcVerbose(4, "clipboard: reporting fFormats=%#x\n", fFormats);
    613     VbglR3ClipboardReportFormats(g_u32ClientId, fFormats);
     613    VbglR3ClipboardWriteFormats(g_u32ClientId, fFormats);
    614614}
    615615
     
    658658                g_fEmptyClipboard = true;
    659659                VGSvcVerbose(3, "Reporting empty clipboard\n");
    660                 VbglR3ClipboardReportFormats(g_u32ClientId, 0);
     660                VbglR3ClipboardWriteFormats(g_u32ClientId, 0);
    661661            }
    662662        }
     
    681681    g_fEmptyClipboard = true;
    682682    VGSvcVerbose(3, "Reporting empty clipboard\n");
    683     VbglR3ClipboardReportFormats(g_u32ClientId, 0);
     683    VbglR3ClipboardWriteFormats(g_u32ClientId, 0);
    684684
    685685    vgsvcClipboardOs2PollViewer();
  • trunk/src/VBox/Additions/haiku/VBoxTray/VBoxClipboard.cpp

    r76553 r78307  
    345345            be_clipboard->Unlock();
    346346
    347             VbglR3ClipboardReportFormats(fClientId, formats);
     347            VbglR3ClipboardWriteFormats(fClientId, formats);
    348348            break;
    349349        }
  • trunk/src/VBox/Additions/x11/VBoxClient/Makefile.kmk

    r78162 r78307  
    4141        check3d.cpp
    4242
    43 ifdef VBOX_WITH_SHARED_CLIPBOARD
    44  VBoxClient_DEFS += \
    45         VBOX_WITH_SHARED_CLIPBOARD
    46  VBoxClient_SOURCES += \
    47         $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp \
    48         $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-x11.cpp \
    49         clipboard.cpp
    50 endif
    51 
    5243VBoxClient_SOURCES.linux = \
    5344        chk_stubs.c
     
    9182VBoxClient_DEFS += VBOX_WITH_GUEST_PROPS
    9283endif
     84
    9385ifdef VBOX_WITH_DRAG_AND_DROP
    9486VBoxClient_DEFS += \
     
    10092        $(VBOX_LIB_VBGL_R3) \
    10193        $(PATH_STAGE_LIB)/additions/VBoxDnDGuestR3Lib$(VBOX_SUFF_LIB)
     94endif
     95
     96ifdef VBOX_WITH_SHARED_CLIPBOARD
     97 VBoxClient_DEFS += \
     98        VBOX_WITH_SHARED_CLIPBOARD \
     99        $(if $(VBOX_WITH_SHARED_CLIPBOARD_URI_LIST),VBOX_WITH_SHARED_CLIPBOARD_URI_LIST,)
     100 VBoxClient_SOURCES += \
     101        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp \
     102        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-x11.cpp \
     103        clipboard.cpp
     104 ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     105  ifdef VBOX_WITH_LIBFUSE
     106   VBoxClient_SOURCES += \
     107        clipboard-fuse.cpp
     108   VBoxClient_LIBS += \
     109        libfuse
     110  endif
     111  ifdef VBOX_WITH_LIBGVFS
     112  VBoxClient_SOURCES += \
     113        clipboard-gvfs.c
     114  VBOX_VBOXCLIENT_GVFS_VER:=1.31.92
     115  VBoxClient_INCS += \
     116        gvfs-$(VBOX_VBOXCLIENT_GVFS_VER)/common \
     117        gvfs-$(VBOX_VBOXCLIENT_GVFS_VER)/client \
     118        gvfs-$(VBOX_VBOXCLIENT_GVFS_VER)/daemon \
     119        /usr/lib/x86_64-linux-gnu/glib-2.0/include \
     120        /usr/include/glib-2.0
     121  VBoxClient_LIBS += \
     122        libgio-2.0 \
     123        libglib-2.0
     124  endif
     125 endif
    102126endif
    103127
  • trunk/src/VBox/Additions/x11/VBoxClient/clipboard.cpp

    r76553 r78307  
    152152    RT_NOREF1(pCtx);
    153153    LogRelFlowFunc(("u32Formats=%d\n", u32Formats));
    154     int rc = VbglR3ClipboardReportFormats(g_ctx.client, u32Formats);
     154    int rc = VbglR3ClipboardWriteFormats(g_ctx.client, u32Formats);
    155155    LogRelFlowFunc(("rc=%Rrc\n", rc));
    156156}
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp

    r78171 r78307  
    303303                    break;
    304304
     305#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     306                case CF_HDROP:
     307                    uFormats |= VBOX_SHARED_CLIPBOARD_FMT_URI_LIST;
     308                    break;
     309#endif
    305310                default:
    306311                {
  • trunk/src/VBox/HostServices/SharedClipboard/Makefile.kmk

    r78161 r78307  
    2727DLLS += VBoxSharedClipboard
    2828VBoxSharedClipboard_TEMPLATE  = VBOXR3
    29 VBoxSharedClipboard_DEFS      = VBOX_WITH_HGCM
     29VBoxSharedClipboard_DEFS      = \
     30        VBOX_WITH_HGCM \
     31        $(if $(VBOX_WITH_SHARED_CLIPBOARD_URI_LIST),VBOX_WITH_SHARED_CLIPBOARD_URI_LIST,)
    3032VBoxSharedClipboard_INCS.win  = \
    3133        $(VBOX_PATH_SDK)
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp

    r78171 r78307  
    3232#include <iprt/thread.h>
    3333#include <iprt/ldr.h>
     34#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     35# include <iprt/utf16.h>
     36#endif
     37
    3438#include <process.h>
     39#include <shlobj.h> /* Needed for shell objects. */
    3540
    3641#include "VBoxClipboard.h"
     
    112117    LogFlow(("vboxClipboardGetData cbSrc = %d, cbDst = %d\n", cbSrc, cbDst));
    113118
    114     if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_HTML
     119    if (   u32Format == VBOX_SHARED_CLIPBOARD_FMT_HTML
    115120        && IsWindowsHTML((const char *)pvSrc))
    116121    {
     
    134139            *pcbActualDst = 0;
    135140    }
     141#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     142    if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
     143    {
     144        /* Convert data to URI list. */
     145    }
     146#endif
    136147    else
    137148    {
     
    283294            UINT format = (UINT)wParam;
    284295
    285             Log(("WM_RENDERFORMAT %d\n", format));
     296            Log(("WM_RENDERFORMAT: Format %u\n", format));
    286297
    287298            switch (format)
     
    298309                    if (format >= 0xC000)
    299310                    {
    300                         TCHAR szFormatName[256];
    301 
    302                         int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR));
    303 
     311                        TCHAR szFormatName[256]; /** @todo r=andy Unicode, 256 is enough? */
     312                        int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName) / sizeof (TCHAR));
    304313                        if (cActual)
    305314                        {
    306                             if (strcmp (szFormatName, "HTML Format") == 0)
    307                             {
     315                            if (RTStrCmp(szFormatName, "HTML Format") == 0)
    308316                                u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
    309                             }
     317#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     318                            if (   RTStrCmp(szFormatName, CFSTR_FILEDESCRIPTOR) == 0
     319                                || RTStrCmp(szFormatName, CFSTR_FILECONTENTS) == 0)
     320                                u32Format |= VBOX_SHARED_CLIPBOARD_FMT_URI_LIST;
     321#endif
    310322                        }
    311323                    }
     
    321333            else
    322334            {
    323                 int vboxrc = vboxClipboardReadDataFromClient (pCtx, u32Format);
     335                int vboxrc = vboxClipboardReadDataFromClient(pCtx, u32Format);
    324336
    325337                LogFunc(("vboxClipboardReadDataFromClient vboxrc = %d, pv %p, cb %d, u32Format %d\n",
     
    331343                    && pCtx->pClient->data.u32Format == u32Format)
    332344                {
    333                     HANDLE hMem = GlobalAlloc (GMEM_DDESHARE | GMEM_MOVEABLE, pCtx->pClient->data.cb);
     345                    HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, pCtx->pClient->data.cb);
    334346
    335347                    LogFunc(("hMem %p\n", hMem));
     
    337349                    if (hMem)
    338350                    {
    339                         void *pMem = GlobalLock (hMem);
    340 
    341                         LogFunc(("pMem %p, GlobalSize %d\n", pMem, GlobalSize (hMem)));
     351                        void *pMem = GlobalLock(hMem);
     352
     353                        LogFunc(("pMem %p, GlobalSize %d\n", pMem, GlobalSize(hMem)));
    342354
    343355                        if (pMem)
     
    347359                            if (pCtx->pClient->data.pv)
    348360                            {
    349                                 memcpy (pMem, pCtx->pClient->data.pv, pCtx->pClient->data.cb);
    350 
    351                                 RTMemFree (pCtx->pClient->data.pv);
     361                                memcpy(pMem, pCtx->pClient->data.pv, pCtx->pClient->data.cb);
     362
     363                                RTMemFree(pCtx->pClient->data.pv);
    352364                                pCtx->pClient->data.pv        = NULL;
    353365                            }
     
    357369
    358370                            /* The memory must be unlocked before inserting to the Clipboard. */
    359                             GlobalUnlock (hMem);
     371                            GlobalUnlock(hMem);
    360372
    361373                            /* 'hMem' contains the host clipboard data.
    362374                             * size is 'cb' and format is 'format'.
    363375                             */
    364                             HANDLE hClip = SetClipboardData (format, hMem);
     376                            HANDLE hClip = SetClipboardData(format, hMem);
    365377
    366378                            LogFunc(("vboxClipboardHostEvent hClip %p\n", hClip));
     
    373385                        }
    374386
    375                         GlobalFree (hMem);
     387                        GlobalFree(hMem);
    376388                    }
    377389                }
    378390
    379                 RTMemFree (pCtx->pClient->data.pv);
     391                RTMemFree(pCtx->pClient->data.pv);
    380392                pCtx->pClient->data.pv        = NULL;
    381393                pCtx->pClient->data.cb        = 0;
     
    446458                }
    447459
     460#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     461                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
     462                {
     463                    UINT format = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
     464                    if (format)
     465                        hClip = SetClipboardData(format, NULL);
     466                }
     467#endif
    448468                VBoxClipboardWinClose();
    449469
     
    590610    g_ctx.hRenderEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    591611
    592     rc = RTThreadCreate(&g_ctx.hThread, VBoxClipboardThread, NULL, 65536,
     612    rc = RTThreadCreate(&g_ctx.hThread, VBoxClipboardThread, NULL, _64K /* Stack size */,
    593613                        RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLIP");
    594614
     
    788808            }
    789809        }
    790 
     810#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     811        else if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
     812        {
     813    #if 0
     814            UINT format = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
     815            if (format)
     816            {
     817                hClip = GetClipboardData(format);
     818                if (hClip != NULL)
     819                {
     820                    LPVOID lp = GlobalLock(hClip);
     821
     822                    if (lp != NULL)
     823                    {
     824                        LogFunc(("CF_HTML\n"));
     825
     826                        vboxClipboardGetData(VBOX_SHARED_CLIPBOARD_FMT_HTML, lp, GlobalSize(hClip),
     827                                             pv, cb, pcbActual);
     828                        LogRelFlowFunc(("Raw HTML clipboard data from host :"));
     829                        DumpHtml((char *)pv, cb);
     830                        GlobalUnlock(hClip);
     831                    }
     832                    else
     833                    {
     834                        hClip = NULL;
     835                    }
     836                }
     837            }
     838    #else
     839            /* Convert to a string list, separated by \r\n. */
     840            DROPFILES *pDropFiles = (DROPFILES *)hClip;
     841            AssertPtr(pDropFiles);
     842
     843            /* Do we need to do Unicode stuff? */
     844            const bool fUnicode = RT_BOOL(pDropFiles->fWide);
     845
     846            /* Get the offset of the file list. */
     847            Assert(pDropFiles->pFiles >= sizeof(DROPFILES));
     848
     849            /* Note: This is *not* pDropFiles->pFiles! DragQueryFile only
     850             *       will work with the plain storage medium pointer! */
     851            HDROP hDrop = (HDROP)(hClip);
     852
     853            /* First, get the file count. */
     854            /** @todo Does this work on Windows 2000 / NT4? */
     855            char *pszFiles = NULL;
     856            uint32_t cchFiles = 0;
     857            UINT cFiles = DragQueryFile(hDrop, UINT32_MAX /* iFile */, NULL /* lpszFile */, 0 /* cchFile */);
     858
     859            LogRel(("DnD: Got %RU16 file(s), fUnicode=%RTbool\n", cFiles, fUnicode));
     860
     861            for (UINT i = 0; i < cFiles; i++)
     862            {
     863                UINT cchFile = DragQueryFile(hDrop, i /* File index */, NULL /* Query size first */, 0 /* cchFile */);
     864                Assert(cchFile);
     865
     866                if (RT_FAILURE(rc))
     867                    break;
     868
     869                char *pszFileUtf8 = NULL; /* UTF-8 version. */
     870                UINT cchFileUtf8 = 0;
     871                if (fUnicode)
     872                {
     873                    /* Allocate enough space (including terminator). */
     874                    WCHAR *pwszFile = (WCHAR *)RTMemAlloc((cchFile + 1) * sizeof(WCHAR));
     875                    if (pwszFile)
     876                    {
     877                        const UINT cwcFileUtf16 = DragQueryFileW(hDrop, i /* File index */,
     878                                                                 pwszFile, cchFile + 1 /* Include terminator */);
     879
     880                        AssertMsg(cwcFileUtf16 == cchFile, ("cchFileUtf16 (%RU16) does not match cchFile (%RU16)\n",
     881                                                            cwcFileUtf16, cchFile));
     882                        RT_NOREF(cwcFileUtf16);
     883
     884                        rc = RTUtf16ToUtf8(pwszFile, &pszFileUtf8);
     885                        if (RT_SUCCESS(rc))
     886                        {
     887                            cchFileUtf8 = (UINT)strlen(pszFileUtf8);
     888                            Assert(cchFileUtf8);
     889                        }
     890
     891                        RTMemFree(pwszFile);
     892                    }
     893                    else
     894                        rc = VERR_NO_MEMORY;
     895                }
     896                else /* ANSI */
     897                {
     898                    /* Allocate enough space (including terminator). */
     899                    pszFileUtf8 = (char *)RTMemAlloc((cchFile + 1) * sizeof(char));
     900                    if (pszFileUtf8)
     901                    {
     902                        cchFileUtf8 = DragQueryFileA(hDrop, i /* File index */,
     903                                                     pszFileUtf8, cchFile + 1 /* Include terminator */);
     904
     905                        AssertMsg(cchFileUtf8 == cchFile, ("cchFileUtf8 (%RU16) does not match cchFile (%RU16)\n",
     906                                                           cchFileUtf8, cchFile));
     907                    }
     908                    else
     909                        rc = VERR_NO_MEMORY;
     910                }
     911
     912                if (RT_SUCCESS(rc))
     913                {
     914                    LogFlowFunc(("\tFile: %s (cchFile=%RU16)\n", pszFileUtf8, cchFileUtf8));
     915
     916                    LogRel(("DnD: Adding guest file '%s'\n", pszFileUtf8));
     917
     918                    rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, pszFileUtf8, cchFileUtf8);
     919                    if (RT_SUCCESS(rc))
     920                        cchFiles += cchFileUtf8;
     921                }
     922                else
     923                    LogRel(("DnD: Error handling file entry #%u, rc=%Rrc\n", i, rc));
     924
     925                if (pszFileUtf8)
     926                    RTStrFree(pszFileUtf8);
     927
     928                if (RT_FAILURE(rc))
     929                    break;
     930
     931                /* Add separation between filenames.
     932                 * Note: Also do this for the last element of the list. */
     933                rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, "\r\n", 2 /* Bytes */);
     934                if (RT_SUCCESS(rc))
     935                    cchFiles += 2; /* Include \r\n */
     936            }
     937
     938            if (RT_SUCCESS(rc))
     939            {
     940                cchFiles += 1; /* Add string termination. */
     941                uint32_t cbFiles = cchFiles * sizeof(char);
     942
     943                LogFlowFunc(("cFiles=%u, cchFiles=%RU32, cbFiles=%RU32, pszFiles=0x%p\n",
     944                             cFiles, cchFiles, cbFiles, pszFiles));
     945
     946                /* Translate the list into URI elements. */
     947                DnDURIList lstURI;
     948                rc = lstURI.AppendNativePathsFromList(pszFiles, cbFiles,
     949                                                      DNDURILIST_FLAGS_ABSOLUTE_PATHS);
     950                if (RT_SUCCESS(rc))
     951                {
     952                    RTCString strRoot = lstURI.GetRootEntries();
     953                    size_t cbRoot = strRoot.length() + 1; /* Include termination */
     954
     955                    mpvData = RTMemAlloc(cbRoot);
     956                    if (mpvData)
     957                    {
     958                        memcpy(mpvData, strRoot.c_str(), cbRoot);
     959                        mcbData = cbRoot;
     960                    }
     961                    else
     962                        rc = VERR_NO_MEMORY;
     963                }
     964            }
     965
     966            LogFlowFunc(("Building CF_HDROP list rc=%Rrc, pszFiles=0x%p, cFiles=%RU16, cchFiles=%RU32\n",
     967                         rc, pszFiles, cFiles, cchFiles));
     968
     969            if (pszFiles)
     970                RTStrFree(pszFiles);
     971            break;
     972    #endif /* 0 */
     973        }
     974#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
    791975        VBoxClipboardWinClose();
    792976    }
     
    8931077
    8941078
    895 /*
    896  * Converts clipboard data from CF_HTML format to mimie clipboard format
     1079/**
     1080 * Converts clipboard data from CF_HTML format to MIME clipboard format.
    8971081 *
    8981082 * Returns allocated buffer that contains html converted to text/html mime type
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp

    r78171 r78307  
    484484        } break;
    485485
    486         case VBOX_SHARED_CLIPBOARD_FN_FORMATS:
     486        case VBOX_SHARED_CLIPBOARD_FN_WRITE_FORMATS:
    487487        {
    488488            /* The guest reports that some formats are available. */
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