VirtualBox

Changeset 80359 in vbox


Ignore:
Timestamp:
Aug 21, 2019 8:37:54 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
132824
Message:

Shared Clipboard/URI: Update.

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/GuestHost/SharedClipboard-uri.h

    r80283 r80359  
    5353
    5454/** Specifies an invalid Shared Clipboard list handle. */
    55 #define SHAREDCLIPBOARDLISTHANDLE_INVALID        0
     55#define SHAREDCLIPBOARDLISTHANDLE_INVALID        ((SHAREDCLIPBOARDLISTHANDLE)~0LL)
    5656
    5757/** A Shared Clipboard object handle. */
     
    6161
    6262/** Specifies an invalid Shared Clipboard object handle. */
    63 #define SHAREDCLIPBOARDOBJHANDLE_INVALID         0
     63#define SHAREDCLIPBOARDOBJHANDLE_INVALID         ((SHAREDCLIPBOARDOBJHANDLE)~0LL)
    6464
    6565/** @} */
     
    332332typedef struct _VBOXCLIPBOARDOBJOPENCREATEPARMS
    333333{
     334    /** Path to object to open / create. */
    334335    char                       *pszPath;
     336    /** Size (in bytes) of path to to object. */
    335337    uint32_t                    cbPath;
    336338    /** SHAREDCLIPBOARD_OBJ_CF_* */
    337339    uint32_t                    fCreate;
    338340    /**
    339      * Attributes of object to create and
     341     * Attributes of object to open/create and
    340342     * returned actual attributes of opened/created object.
    341343     */
     
    363365            SHAREDCLIPBOARDOBJHANDLE uHandle;
    364366        } ObjOpen;
     367        struct
     368        {
     369            SHAREDCLIPBOARDOBJHANDLE uHandle;
     370        } ObjClose;
    365371    } u;
    366372    /** Pointer to optional payload. */
     
    465471} VBOXCLIPBOARDLIST, *PVBOXCLIPBOARDLIST;
    466472
    467 /**
    468  * Structure for a Shared Clipboard object header.
    469  */
    470 typedef struct _VBOXCLIPBOARDOBJHDR
    471 {
    472     /** Header type. Currently not being used. */
    473     uint32_t enmType;
    474 } VBOXCLIPBOARDOBJHDR, *PVBOXCLIPBOARDOBJHDR;
     473typedef struct _VBOXCLIPBOARDOBJDATACHUNK
     474{
     475    uint64_t  uHandle;
     476    void     *pvData;
     477    uint32_t  cbData;
     478} VBOXCLIPBOARDOBJDATACHUNK, *PVBOXCLIPBOARDOBJDATACHUNK;
    475479
    476480/**
     
    723727typedef std::map<uint16_t, SHAREDCLIPBOARDURITRANSFEREVENT *> SharedClipboardURITransferEventMap;
    724728
     729/**
     730 * Enumeration for specifying a Shared Clipboard object type.
     731 */
     732typedef enum _SHAREDCLIPBOARDURIOBJTYPE
     733{
     734    /** Invalid object type. */
     735    SHAREDCLIPBOARDURIOBJTYPE_INVALID = 0,
     736    /** Object is a directory. */
     737    SHAREDCLIPBOARDURIOBJTYPE_DIRECTORY,
     738    /** Object is a file. */
     739    SHAREDCLIPBOARDURIOBJTYPE_FILE,
     740    /** Object is a symbolic link. */
     741    SHAREDCLIPBOARDURIOBJTYPE_SYMLINK,
     742    /** The usual 32-bit hack. */
     743    SHAREDCLIPBOARDURIOBJTYPE_32BIT_SIZE_HACK = 0x7fffffff
     744} SHAREDCLIPBOARDURIOBJTYPE;
     745
     746/**
     747 * Structure for keeping URI list handle information.
     748 * This is using to map own (local) handles to the underlying file system.
     749 */
    725750typedef struct _SHAREDCLIPBOARDURILISTHANDLEINFO
    726751{
    727     VBOXCLIPBOARDLISTOPENPARMS OpenParms;
    728     RTFMODE                    fMode;
     752    /** Type of list handle. */
     753    SHAREDCLIPBOARDURIOBJTYPE enmType;
     754    /** Absolute local path of the list object. */
     755    char                     *pszPathLocalAbs;
    729756    union
    730757    {
     758        /** Local data, based on enmType. */
    731759        struct
    732760        {
    733761            union
    734762            {
    735                 RTDIR  hDirRoot;
     763                RTDIR  hDir;
    736764                RTFILE hFile;
    737765            };
     
    740768} SHAREDCLIPBOARDURILISTHANDLEINFO, *PSHAREDCLIPBOARDURILISTHANDLEINFO;
    741769
    742 typedef struct _SHAREDCLIPBOARDOBJHANDLEINFO
    743 {
     770/** Map of URI list handles.
     771 *  The key specifies the list handle. */
     772typedef std::map<SHAREDCLIPBOARDLISTHANDLE, SHAREDCLIPBOARDURILISTHANDLEINFO *> SharedClipboardURIListMap;
     773
     774/**
     775 * Structure for keeping URI object handle information.
     776 * This is using to map own (local) handles to the underlying file system.
     777 */
     778typedef struct _SHAREDCLIPBOARDURIOBJHANDLEINFO
     779{
     780    /** Type of object handle. */
     781    SHAREDCLIPBOARDURIOBJTYPE enmType;
     782    /** Absolute local path of the object. */
     783    char                     *pszPathLocalAbs;
    744784    union
    745785    {
     786        /** Local data, based on enmType. */
    746787        struct
    747788        {
    748             RTDIR hDirRoot;
     789            union
     790            {
     791                RTDIR  hDir;
     792                RTFILE hFile;
     793            };
    749794        } Local;
    750795    } u;
    751796} SHAREDCLIPBOARDURIOBJHANDLEINFO, *PSHAREDCLIPBOARDURIOBJHANDLEINFO;
    752797
    753 /** Map of URI list handles.
    754  *  The key specifies the list handle. */
    755 typedef std::map<SHAREDCLIPBOARDLISTHANDLE, SHAREDCLIPBOARDURILISTHANDLEINFO *> SharedClipboardURIListMap;
    756 
    757798/** Map of URI object handles.
    758799 *  The key specifies the object handle. */
    759 typedef std::map<SHAREDCLIPBOARDOBJHANDLE, SHAREDCLIPBOARDURILISTHANDLEINFO *> SharedClipboardURIObjMap;
     800typedef std::map<SHAREDCLIPBOARDOBJHANDLE, SHAREDCLIPBOARDURIOBJHANDLEINFO *> SharedClipboardURIObjMap;
    760801
    761802/**
     
    796837 * This is handed in to the provider implementation callbacks.
    797838 */
    798 typedef struct _SHAREDCLIPBOARDPROVIDERCTX
     839    typedef struct _SHAREDCLIPBOARDPROVIDERCTX
    799840{
    800841    /** Pointer to the related URI transfer. */
     
    958999    /** Timeout (in ms) for waiting of events. Default is 30s. */
    9591000    RTMSINTERVAL                        uTimeoutMs;
     1001    /** Absolute path to root entries. */
     1002    char                               *pszPathRootAbs;
    9601003    /** Maximum data chunk size (in bytes) to transfer. Default is 64K. */
    9611004    uint32_t                            cbMaxChunkSize;
     
    9631006    SharedClipboardURITransferEventMap *pMapEvents;
    9641007    /** Next upcoming list handle. */
    965     uint64_t                            uListHandleNext;
     1008    SHAREDCLIPBOARDLISTHANDLE           uListHandleNext;
    9661009    /** Map of all lists related to this transfer. */
    9671010    SharedClipboardURIListMap          *pMapLists;
     
    9691012    SharedClipboardURIListRootEntries   lstRootEntries;
    9701013    /** Next upcoming object handle. */
    971     uint64_t                            uObjHandleNext;
     1014    SHAREDCLIPBOARDOBJHANDLE            uObjHandleNext;
    9721015    /** Next upcoming event ID.
    9731016     *  0 is reserved for invalid event IDs. */
     
    10151058bool SharedClipboardURIObjCtxIsValid(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx);
    10161059
     1060int SharedClipboardURIObjectOpenParmsInit(PVBOXCLIPBOARDOBJOPENCREATEPARMS pParms);
     1061int SharedClipboardURIObjectOpenParmsCopy(PVBOXCLIPBOARDOBJOPENCREATEPARMS pParmsDst, PVBOXCLIPBOARDOBJOPENCREATEPARMS pParmsSrc);
     1062void SharedClipboardURIObjectOpenParmsDestroy(PVBOXCLIPBOARDOBJOPENCREATEPARMS pParms);
     1063
    10171064int SharedClipboardURIObjectOpen(PSHAREDCLIPBOARDURITRANSFER pTransfer, PVBOXCLIPBOARDOBJOPENCREATEPARMS pOpenCreateParms,
    10181065                                 PSHAREDCLIPBOARDOBJHANDLE phObj);
    1019 int SharedClipboardURIObjectClose(SHAREDCLIPBOARDOBJHANDLE hObj);
    1020 int SharedClipboardURIObjectRead(SHAREDCLIPBOARDOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead, uint32_t fFlags);
    1021 int SharedClipboardURIObjectWrite(SHAREDCLIPBOARDOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten, uint32_t fFlags);
    1022 int SharedClipboardURIObjectQueryInfo(SHAREDCLIPBOARDOBJHANDLE hObj, PSHAREDCLIPBOARDFSOBJINFO pObjInfo);
     1066int SharedClipboardURIObjectClose(PSHAREDCLIPBOARDURITRANSFER pTransfer, SHAREDCLIPBOARDOBJHANDLE hObj);
     1067int SharedClipboardURIObjectRead(PSHAREDCLIPBOARDURITRANSFER pTransfer, SHAREDCLIPBOARDOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead, uint32_t fFlags);
     1068int SharedClipboardURIObjectWrite(PSHAREDCLIPBOARDURITRANSFER pTransfer, SHAREDCLIPBOARDOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten, uint32_t fFlags);
     1069
     1070PVBOXCLIPBOARDOBJDATACHUNK SharedClipboardURIObjectDataChunkDup(PVBOXCLIPBOARDOBJDATACHUNK pDataChunk);
     1071void SharedClipboardURIObjectDataChunkDestroy(PVBOXCLIPBOARDOBJDATACHUNK pDataChunk);
     1072void SharedClipboardURIObjectDataChunkFree(PVBOXCLIPBOARDOBJDATACHUNK pDataChunk);
    10231073
    10241074int SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR enmDir, SHAREDCLIPBOARDSOURCE enmSource,
     
    10461096int SharedClipboardURITransferSetInterface(PSHAREDCLIPBOARDURITRANSFER pTransfer,
    10471097                                           PSHAREDCLIPBOARDPROVIDERCREATIONCTX pCreationCtx);
    1048 int SharedClipboardURILTransferSetRoots(PSHAREDCLIPBOARDURITRANSFER pTransfer, const char *papszRoots, size_t cbRoots);
     1098int SharedClipboardURILTransferSetRoots(PSHAREDCLIPBOARDURITRANSFER pTransfer, const char *pszRoots, size_t cbRoots);
    10491099void SharedClipboardURITransferReset(PSHAREDCLIPBOARDURITRANSFER pTransfer);
    10501100SharedClipboardArea *SharedClipboardURITransferGetArea(PSHAREDCLIPBOARDURITRANSFER pTransfer);
  • trunk/include/VBox/HostServices/VBoxClipboardSvc.h

    r80320 r80359  
    585585    /** uint32_t in/out: Open / Create flags of type SHAREDCLIPBOARD_OBJ_CF_. */
    586586    HGCMFunctionParameter fCreate;
    587     /** pointer, in/out: SHAREDCLIPBOARDFSOBJINFO. */
    588     HGCMFunctionParameter objInfo;
    589587} VBoxClipboardObjOpenMsg;
    590588
    591 #define VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_OPEN 4
     589#define VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_OPEN 5
    592590
    593591typedef struct _VBoxClipboardObjCloseMsg
     
    611609    /** uint32_t, in: How many bytes to read. */
    612610    HGCMFunctionParameter cbToRead;
    613     /** uint32_t, in: Read flags. Currently unused. */
     611    /** uint32_t, in: Read flags. Currently unused and must be 0. */
    614612    HGCMFunctionParameter fRead;
    615613} VBoxClipboardObjReadReqParms;
     
    622620} VBoxClipboardObjReadReqMsg;
    623621
    624 #define VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_READ_REQ 3
     622#define VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_READ_REQ 4
    625623
    626624/**
  • trunk/include/VBox/VBoxGuestLib.h

    r80283 r80359  
    596596    /** IN: Protocol version to use. */
    597597    uint32_t uProtocol;
     598    /** IN: Maximum chunk size (in bytes). */
     599    uint32_t cbChunkSize;
    598600    /** OUT: Number of parameters retrieved. */
    599601    uint32_t uNumParms;
     
    644646
    645647#  ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     648VBGLR3DECL(int)     VbglR3ClipboardConnectEx(PVBGLR3SHCLCMDCTX pCtx);
     649VBGLR3DECL(int)     VbglR3ClipboardDisconnectEx(PVBGLR3SHCLCMDCTX pCtx);
    646650VBGLR3DECL(int)     VbglR3ClipboardEventGetNext(PVBGLR3SHCLCMDCTX pCtx, PSHAREDCLIPBOARDURITRANSFER pTransfer,
    647651                                                PVBGLR3CLIPBOARDEVENT *ppEvent);
     
    675679VBGLR3DECL(int)     VbglR3ClipboardObjReadRecv(PVBGLR3SHCLCMDCTX pCtx, PSHAREDCLIPBOARDOBJHANDLE phObj, uint32_t pcbToRead,
    676680                                               uint32_t *pfFlags);
    677 VBGLR3DECL(int)     VbglR3ClipboardObjReadSend(PVBGLR3SHCLCMDCTX pCtx, SHAREDCLIPBOARDOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf,
     681VBGLR3DECL(int)     VbglR3ClipboardObjRead(PVBGLR3SHCLCMDCTX pCtx, SHAREDCLIPBOARDOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf,
    678682                                               uint32_t *pcbRead);
    679 VBGLR3DECL(int)     VbglR3ClipboardObjWriteSend(PVBGLR3SHCLCMDCTX pCtx, SHAREDCLIPBOARDOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf,
    680                                                 uint32_t *pcbWritten);
     683VBGLR3DECL(int)     VbglR3ClipboardObjWrite(PVBGLR3SHCLCMDCTX pCtx, SHAREDCLIPBOARDOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf,
     684                                            uint32_t *pcbWritten);
    681685
    682686VBGLR3DECL(int)     VbglR3ClipboardWriteError(HGCMCLIENTID idClient, int rcErr);
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp

    r80324 r80359  
    115115
    116116    VBGLR3SHCLCMDCTX cmdCtx;
    117     RT_ZERO(cmdCtx);
    118 
    119     int rc = VbglR3ClipboardConnect(&cmdCtx.uClientID);
     117    int rc = VbglR3ClipboardConnectEx(&cmdCtx);
    120118    if (RT_SUCCESS(rc))
    121119    {
     
    149147        }
    150148
    151         VbglR3ClipboardDisconnect(cmdCtx.uClientID);
     149        VbglR3ClipboardDisconnectEx(&cmdCtx);
    152150    }
    153151
     
    354352    AssertPtr(pThisCtx);
    355353
    356     int rc = VbglR3ClipboardObjReadSend(&pThisCtx->CmdCtx, hObj, pvData, cbData, pcbRead);
     354    int rc = VbglR3ClipboardObjRead(&pThisCtx->CmdCtx, hObj, pvData, cbData, pcbRead);
    357355
    358356    LogFlowFuncLeaveRC(rc);
     
    370368    AssertPtr(pThisCtx);
    371369
    372     int rc = VbglR3ClipboardObjWriteSend(&pThisCtx->CmdCtx, hObj, pvData, cbData, pcbWritten);
     370    int rc = VbglR3ClipboardObjWrite(&pThisCtx->CmdCtx, hObj, pvData, cbData, pcbWritten);
    373371
    374372    LogFlowFuncLeaveRC(rc);
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp

    r80318 r80359  
    5454
    5555/**
    56  * Connects to the clipboard service.
     56 * Connects to the Shared Clipboard service.
    5757 *
    5858 * @returns VBox status code
     
    7272
    7373/**
    74  * Disconnect from the clipboard service.
     74 * Connects to the Shared Clipboard service, extended version.
     75 *
     76 * @returns VBox status code.
     77 * @param   pCtx                Shared Clipboard command context to use for the connection.
     78 */
     79VBGLR3DECL(int) VbglR3ClipboardConnectEx(PVBGLR3SHCLCMDCTX pCtx)
     80{
     81    int rc = VbglR3ClipboardConnect(&pCtx->uClientID);
     82    if (RT_SUCCESS(rc))
     83    {
     84        pCtx->uProtocol   = 0;    /** @todo Makke this dynamic. */
     85        pCtx->cbChunkSize = _64K; /** @todo Makke this dynamic. */
     86    }
     87
     88    LogFlowFuncLeaveRC(rc);
     89    return rc;
     90}
     91
     92
     93/**
     94 * Disconnects from the Shared Clipboard service.
    7595 *
    7696 * @returns VBox status code.
     
    80100{
    81101    return VbglR3HGCMDisconnect(idClient);
     102}
     103
     104
     105/**
     106 * Disconnects from the Shared Clipboard service, extended version.
     107 *
     108 * @returns VBox status code.
     109 * @param   pCtx                Shared Clipboard command context to use for the connection.
     110 */
     111VBGLR3DECL(int) VbglR3ClipboardDisconnectEx(PVBGLR3SHCLCMDCTX pCtx)
     112{
     113    int rc = VbglR3ClipboardDisconnect(pCtx->uClientID);
     114    if (RT_SUCCESS(rc))
     115    {
     116        pCtx->uClientID = 0;
     117    }
     118
     119    LogFlowFuncLeaveRC(rc);
     120    return rc;
    82121}
    83122
     
    199238 * @retval  VERR_VM_RESTORED if the VM has been restored (idRestoreCheck).
    200239 *
    201  * @param   idClient        The client ID returned by VbglR3GuestCtrlConnect().
     240 * @param   pCtx            Shared Clipboard command context to use for the connection.
    202241 * @param   pidMsg          Where to store the message id.
    203242 * @param   pcParameters    Where to store the number  of parameters which will
     
    743782
    744783    Msg.uContext.SetUInt32(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_OPEN);
    745     Msg.cbPath.SetUInt64(pCreateParms->cbPath);
     784    Msg.uHandle.SetUInt64(0);
     785    Msg.cbPath.SetUInt32(pCreateParms->cbPath);
    746786    Msg.szPath.SetPtr(pCreateParms->pszPath, pCreateParms->cbPath);
    747787    Msg.fCreate.SetUInt32(0);
    748     Msg.objInfo.SetPtr(&pCreateParms->ObjInfo, sizeof(pCreateParms->ObjInfo));
    749788
    750789    int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     
    804843    Msg.szPath.SetPtr((void *)pCreateParms->pszPath, pCreateParms->cbPath + 1 /* Include terminating zero */);
    805844    Msg.fCreate.SetUInt32(pCreateParms->fCreate);
    806     Msg.objInfo.SetPtr((void *)&pCreateParms->ObjInfo, sizeof(pCreateParms->ObjInfo));
    807845
    808846    int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     
    827865                       VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_GET, VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_CLOSE);
    828866
    829     Msg.uContext.SetUInt32(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_OPEN);
     867    Msg.uContext.SetUInt32(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_CLOSE);
    830868    Msg.uHandle.SetUInt64(0);
    831869
     
    920958}
    921959
    922 VBGLR3DECL(int) VbglR3ClipboardObjReadSend(PVBGLR3SHCLCMDCTX pCtx, SHAREDCLIPBOARDOBJHANDLE hObj,
    923                                            void *pvData, uint32_t cbData, uint32_t *pcbRead)
     960VBGLR3DECL(int) VbglR3ClipboardObjRead(PVBGLR3SHCLCMDCTX pCtx, SHAREDCLIPBOARDOBJHANDLE hObj,
     961                                       void *pvData, uint32_t cbData, uint32_t *pcbRead)
    924962{
    925963    AssertPtrReturn(pCtx,   VERR_INVALID_POINTER);
     
    931969    RT_ZERO(Msg);
    932970
    933     VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_READ, VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_READ);
     971    VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID,
     972                       VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_READ, VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_READ);
    934973
    935974    Msg.uContext.SetUInt32(pCtx->uContextID);
    936975    Msg.uHandle.SetUInt64(hObj);
    937976    Msg.pvData.SetPtr(pvData, cbData);
    938     Msg.cbData.SetUInt32(0);
     977    Msg.cbData.SetUInt32(cbData);
    939978    Msg.pvChecksum.SetPtr(NULL, 0);
    940979    Msg.cbChecksum.SetUInt32(0);
     
    943982    if (RT_SUCCESS(rc))
    944983    {
    945         /** @todo Context ID not used yet. */
    946984        /** @todo Add checksum support. */
    947985
     
    957995}
    958996
    959 VBGLR3DECL(int) VbglR3ClipboardObjWriteSend(PVBGLR3SHCLCMDCTX pCtx,
    960                                             SHAREDCLIPBOARDOBJHANDLE hObj,
    961                                             void *pvData, uint32_t cbData, uint32_t *pcbWritten)
     997VBGLR3DECL(int) VbglR3ClipboardObjWrite(PVBGLR3SHCLCMDCTX pCtx, SHAREDCLIPBOARDOBJHANDLE hObj,
     998                                        void *pvData, uint32_t cbData, uint32_t *pcbWritten)
    962999{
    9631000    AssertPtrReturn(pCtx,   VERR_INVALID_POINTER);
    9641001    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
    965     AssertReturn(cbData,    VERR_INVALID_PARAMETER);
     1002    /* cbData can be 0. */
    9661003    /* pcbWritten is optional. */
    9671004
     
    9691006    RT_ZERO(Msg);
    9701007
    971     VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_WRITE, VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_WRITE);
     1008    VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID,
     1009                       VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_WRITE, VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_WRITE);
    9721010
    9731011    Msg.uContext.SetUInt32(pCtx->uContextID);
     
    9751013    Msg.pvData.SetPtr(pvData, cbData);
    9761014    Msg.cbData.SetUInt32(cbData);
    977     Msg.pvChecksum.SetPtr(NULL, 0); /** @todo Implement this. */
    978     Msg.cbChecksum.SetUInt32(0); /** @todo Implement this. */
    979 
    980     int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
    981     if (RT_SUCCESS(rc))
    982     {
     1015    Msg.pvChecksum.SetPtr(NULL, 0);
     1016    Msg.cbChecksum.SetUInt32(0);
     1017
     1018    int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     1019    if (RT_SUCCESS(rc))
     1020    {
     1021        /** @todo Add checksum support. */
     1022
    9831023        if (pcbWritten)
    984             *pcbWritten = cbData;
     1024            *pcbWritten = cbData; /** @todo For now return all as being written. */
    9851025    }
    9861026
     
    10491089            case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_OPEN:
    10501090            {
    1051                 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_OPEN\n"));
    1052 
    10531091                VBOXCLIPBOARDLISTOPENPARMS openParmsList;
    10541092                rc = SharedClipboardURIListOpenParmsInit(&openParmsList);
     
    10761114            case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_CLOSE:
    10771115            {
    1078                 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_CLOSE\n"));
    1079 
    10801116                SHAREDCLIPBOARDLISTHANDLE hList;
    10811117                rc = VbglR3ClipboardListCloseRecv(pCtx, &hList);
     
    10941130            case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_HDR_READ:
    10951131            {
    1096                 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_HDR_READ\n"));
    1097 
    10981132                /** @todo Handle filter + list features. */
    10991133
     
    11751209            case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_OPEN:
    11761210            {
    1177                 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_OPEN\n"));
    1178 
    1179                 VBOXCLIPBOARDOBJOPENCREATEPARMS createParms;
    1180                 rc = VbglR3ClipboardObjOpenRecv(pCtx, &createParms);
     1211                VBOXCLIPBOARDOBJOPENCREATEPARMS openParms;
     1212                rc = SharedClipboardURIObjectOpenParmsInit(&openParms);
    11811213                if (RT_SUCCESS(rc))
    11821214                {
    1183                     SHAREDCLIPBOARDOBJHANDLE hObj;
    1184                     rc = SharedClipboardURIObjectOpen(pTransfer, &createParms, &hObj);
     1215                    rc = VbglR3ClipboardObjOpenRecv(pCtx, &openParms);
    11851216                    if (RT_SUCCESS(rc))
    11861217                    {
     1218                        SHAREDCLIPBOARDOBJHANDLE hObj;
     1219                        rc = SharedClipboardURIObjectOpen(pTransfer, &openParms, &hObj);
     1220
     1221                        /* Reply in any case. */
    11871222                        int rc2 = VbglR3ClipboardObjOpenReply(pCtx, rc, hObj);
    11881223                        AssertRC(rc2);
    11891224                    }
     1225
     1226                    SharedClipboardURIObjectOpenParmsDestroy(&openParms);
    11901227                }
    11911228
     
    11951232            case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_CLOSE:
    11961233            {
    1197                 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_CLOSE\n"));
    1198 
    11991234                SHAREDCLIPBOARDOBJHANDLE hObj;
    12001235                rc = VbglR3ClipboardObjCloseRecv(pCtx, &hObj);
    12011236                if (RT_SUCCESS(rc))
    12021237                {
    1203                     rc = SharedClipboardURIObjectClose(hObj);
     1238                    rc = SharedClipboardURIObjectClose(pTransfer, hObj);
    12041239
    12051240                    /* Reply in any case. */
     
    12121247            case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_READ:
    12131248            {
    1214                 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_READ\n"));
    1215 
    12161249                SHAREDCLIPBOARDOBJHANDLE hObj;
    12171250                uint32_t cbBuf;
     
    12201253                if (RT_SUCCESS(rc))
    12211254                {
    1222                     void *pvBuf = RTMemAlloc(RT_MIN(cbBuf, _64K)); /** @todo Make this more flexible. */
     1255                    AssertBreakStmt(pCtx->cbChunkSize, rc = VERR_INVALID_PARAMETER);
     1256
     1257                    const uint32_t cbToRead = RT_MIN(cbBuf, pCtx->cbChunkSize);
     1258
     1259                    LogFlowFunc(("hObj=%RU64, cbBuf=%RU32, fFlags=0x%x -> cbChunkSize=%RU32, cbToRead=%RU32\n",
     1260                                 hObj, cbBuf, fFlags, pCtx->cbChunkSize, cbToRead));
     1261
     1262                    void *pvBuf = RTMemAlloc(cbToRead);
    12231263                    if (pvBuf)
    12241264                    {
    12251265                        uint32_t cbRead;
    1226                         rc = SharedClipboardURIObjectRead(hObj, pvBuf, cbBuf, &cbRead, fFlags);
     1266                        rc = SharedClipboardURIObjectRead(pTransfer, hObj, pvBuf, cbToRead, &cbRead, fFlags);
    12271267                        if (RT_SUCCESS(rc))
    1228                             rc = VbglR3ClipboardObjReadSend(pCtx, hObj, pvBuf, cbRead, NULL /* pcbWritten */);
     1268                            rc = VbglR3ClipboardObjWrite(pCtx, hObj, pvBuf, cbRead, NULL /* pcbWritten */);
    12291269
    12301270                        RTMemFree(pvBuf);
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp

    r80318 r80359  
    2424#include <VBox/GuestHost/SharedClipboard-uri.h>
    2525
    26 /** !!! HACK ALERT !!! Dynamically resolve functions! */
    27 #ifdef _WIN32_IE
    28 #undef _WIN32_IE
    29 #define _WIN32_IE 0x0501
    30 #endif
    31 
    3226#include <iprt/win/windows.h>
    3327#include <iprt/win/shlobj.h>
     
    5549    , m_pStream(NULL)
    5650    , m_uObjIdx(0)
     51    , m_EventListComplete(NIL_RTSEMEVENT)
     52    , m_EventTransferComplete(NIL_RTSEMEVENT)
    5753{
    5854    AssertPtr(m_pTransfer);
     
    136132{
    137133    RTSemEventDestroy(m_EventListComplete);
     134    m_EventListComplete = NIL_RTSEMEVENT;
     135
    138136    RTSemEventDestroy(m_EventTransferComplete);
     137    m_EventTransferComplete = NIL_RTSEMEVENT;
    139138
    140139    if (m_pStream)
     
    776775    if (fComplete)
    777776    {
     777        if (m_EventTransferComplete != NIL_RTSEMEVENT)
     778        {
     779            int rc2 = RTSemEventSignal(m_EventTransferComplete);
     780            AssertRC(rc2);
     781        }
     782    }
     783
     784    LogFlowFuncLeaveRC(rc);
     785}
     786
     787void VBoxClipboardWinDataObject::OnTransferCanceled(void)
     788{
     789    LogFlowFuncEnter();
     790
     791    if (m_EventTransferComplete != NIL_RTSEMEVENT)
     792    {
    778793        int rc2 = RTSemEventSignal(m_EventTransferComplete);
    779794        AssertRC(rc2);
    780795    }
    781 
    782     LogFlowFuncLeaveRC(rc);
    783 }
    784 
    785 void VBoxClipboardWinDataObject::OnTransferCanceled(void)
    786 {
    787     LogFlowFuncEnter();
    788 
    789     int rc2 = RTSemEventSignal(m_EventTransferComplete);
    790     AssertRC(rc2);
    791796
    792797    LogFlowFuncLeave();
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardStreamImpl-win.cpp

    r80283 r80359  
    187187            && m_pURITransfer->ProviderIface.pfnObjOpen)
    188188        {
    189             VBOXCLIPBOARDOBJOPENCREATEPARMS createParms;
    190             RT_ZERO(createParms);
    191 
    192             createParms.pszPath = RTStrDup(m_strPath.c_str());
    193             if (createParms.pszPath)
     189            VBOXCLIPBOARDOBJOPENCREATEPARMS openParms;
     190            rc = SharedClipboardURIObjectOpenParmsInit(&openParms);
     191            if (RT_SUCCESS(rc))
    194192            {
    195                 rc = m_pURITransfer->ProviderIface.pfnObjOpen(&m_pURITransfer->ProviderCtx, &createParms, &m_hObj);
    196 
    197                 RTStrFree(createParms.pszPath);
     193                openParms.fCreate = SHAREDCLIPBOARD_OBJ_CF_ACT_OPEN_IF_EXISTS
     194                                  | SHAREDCLIPBOARD_OBJ_CF_ACT_FAIL_IF_NEW
     195                                  | SHAREDCLIPBOARD_OBJ_CF_ACCESS_READ
     196                                  | SHAREDCLIPBOARD_OBJ_CF_ACCESS_DENYWRITE;
     197
     198                rc = RTStrCopy(openParms.pszPath, openParms.cbPath, m_strPath.c_str());
     199                if (RT_SUCCESS(rc))
     200                {
     201                    rc = m_pURITransfer->ProviderIface.pfnObjOpen(&m_pURITransfer->ProviderCtx, &openParms, &m_hObj);
     202                }
     203
     204                SharedClipboardURIObjectOpenParmsDestroy(&openParms);
    198205            }
    199             else
    200                 rc = VERR_NO_MEMORY;
    201206        }
    202207        else
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-uri.cpp

    r80318 r80359  
    2929
    3030
    31 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    3231static int sharedClipboardURITransferThreadCreate(PSHAREDCLIPBOARDURITRANSFER pTransfer, PFNRTTHREAD pfnThreadFunc, void *pvUser);
    3332static int sharedClipboardURITransferThreadDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer, RTMSINTERVAL uTimeoutMs);
    3433static int sharedClipboardURITransferWriteThread(RTTHREAD hThread, void *pvUser);
    3534static PSHAREDCLIPBOARDURITRANSFER sharedClipboardURICtxGetTransferInternal(PSHAREDCLIPBOARDURICTX pURI, uint32_t uIdx);
    36 #endif
     35static int sharedClipboardConvertFileCreateFlags(bool fWritable, unsigned fShClFlags, RTFMODE fMode,
     36                                                 SHAREDCLIPBOARDOBJHANDLE handleInitial, uint64_t *pfOpen);
    3737
    3838/** @todo Split this file up in different modules. */
     
    156156{
    157157    return SharedClipboardURIListEntryDestroy(pRootListEntry);
     158}
     159
     160/**
     161 * Destroys a list handle info structure.
     162 *
     163 * @param   pInfo               List handle info structure to destroy.
     164 */
     165void SharedClipboardURIListHandleInfoDestroy(PSHAREDCLIPBOARDURILISTHANDLEINFO pInfo)
     166{
     167    if (!pInfo)
     168        return;
     169
     170    if (pInfo->pszPathLocalAbs)
     171    {
     172        RTStrFree(pInfo->pszPathLocalAbs);
     173        pInfo->pszPathLocalAbs = NULL;
     174    }
    158175}
    159176
     
    588605}
    589606
     607/**
     608 * Destroys an object handle info structure.
     609 *
     610 * @param   pInfo               Object handle info structure to destroy.
     611 */
     612void SharedClipboardURIObjectHandleInfoDestroy(PSHAREDCLIPBOARDURIOBJHANDLEINFO pInfo)
     613{
     614    if (!pInfo)
     615        return;
     616
     617    if (pInfo->pszPathLocalAbs)
     618    {
     619        RTStrFree(pInfo->pszPathLocalAbs);
     620        pInfo->pszPathLocalAbs = NULL;
     621    }
     622}
     623
     624/**
     625 * Initializes an URI object open parameters structure.
     626 *
     627 * @returns VBox status code.
     628 * @param   pParms              URI object open parameters structure to initialize.
     629 */
     630int SharedClipboardURIObjectOpenParmsInit(PVBOXCLIPBOARDOBJOPENCREATEPARMS pParms)
     631{
     632    AssertPtrReturn(pParms, VERR_INVALID_POINTER);
     633
     634    int rc;
     635
     636    RT_BZERO(pParms, sizeof(VBOXCLIPBOARDOBJOPENCREATEPARMS));
     637
     638    pParms->cbPath    = RTPATH_MAX; /** @todo Make this dynamic. */
     639    pParms->pszPath   = RTStrAlloc(pParms->cbPath);
     640    if (pParms->pszPath)
     641    {
     642        rc = VINF_SUCCESS;
     643    }
     644    else
     645        rc = VERR_NO_MEMORY;
     646
     647    LogFlowFuncLeaveRC(rc);
     648    return rc;
     649}
     650
     651/**
     652 * Copies an URI object open parameters structure from source to destination.
     653 *
     654 * @returns VBox status code.
     655 * @param   pParmsDst           Where to copy the source URI object open parameters to.
     656 * @param   pParmsSrc           Which source URI object open parameters to copy.
     657 */
     658int SharedClipboardURIObjectOpenParmsCopy(PVBOXCLIPBOARDOBJOPENCREATEPARMS pParmsDst, PVBOXCLIPBOARDOBJOPENCREATEPARMS pParmsSrc)
     659{
     660    int rc;
     661
     662    *pParmsDst = *pParmsSrc;
     663
     664    if (pParmsSrc->pszPath)
     665    {
     666        Assert(pParmsSrc->cbPath);
     667        pParmsDst->pszPath = RTStrDup(pParmsSrc->pszPath);
     668        if (pParmsDst->pszPath)
     669        {
     670            rc = VINF_SUCCESS;
     671        }
     672        else
     673            rc = VERR_NO_MEMORY;
     674    }
     675    else
     676        rc = VINF_SUCCESS;
     677
     678    LogFlowFuncLeaveRC(rc);
     679    return rc;
     680}
     681
     682/**
     683 * Destroys an URI object open parameters structure.
     684 *
     685 * @param   pParms              URI object open parameters structure to destroy.
     686 */
     687void SharedClipboardURIObjectOpenParmsDestroy(PVBOXCLIPBOARDOBJOPENCREATEPARMS pParms)
     688{
     689    if (!pParms)
     690        return;
     691
     692    if (pParms->pszPath)
     693    {
     694        RTStrFree(pParms->pszPath);
     695        pParms->pszPath = NULL;
     696    }
     697}
     698
     699/**
     700 * Opens an URI object.
     701 *
     702 * @returns VBox status code.
     703 * @param   pTransfer           URI clipboard transfer to open the object for.
     704 * @param   pOpenCreateParms    Open / create parameters of URI object to open / create.
     705 * @param   phObj               Where to store the handle of URI object opened on success.
     706 */
    590707int SharedClipboardURIObjectOpen(PSHAREDCLIPBOARDURITRANSFER pTransfer, PVBOXCLIPBOARDOBJOPENCREATEPARMS pOpenCreateParms,
    591708                                 PSHAREDCLIPBOARDOBJHANDLE phObj)
    592709{
    593     RT_NOREF(pTransfer, pOpenCreateParms, phObj);
    594     return 0;
    595 }
    596 
    597 int SharedClipboardURIObjectClose(SHAREDCLIPBOARDOBJHANDLE hObj)
    598 {
    599     RT_NOREF(hObj);
    600     return 0;
    601 }
    602 
    603 int SharedClipboardURIObjectRead(SHAREDCLIPBOARDOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead, uint32_t fFlags)
    604 {
    605     RT_NOREF(hObj, pvBuf, cbBuf, pcbRead, fFlags);
    606     return 0;
    607 }
    608 
    609 int SharedClipboardURIObjectWrite(SHAREDCLIPBOARDOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten,
     710    AssertPtrReturn(pTransfer,        VERR_INVALID_POINTER);
     711    AssertPtrReturn(pOpenCreateParms, VERR_INVALID_POINTER);
     712    AssertPtrReturn(phObj,            VERR_INVALID_POINTER);
     713
     714    int rc = VINF_SUCCESS;
     715
     716    LogFlowFunc(("pszPath=%s, fCreate=0x%x\n", pOpenCreateParms->pszPath, pOpenCreateParms->fCreate));
     717
     718    if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_LOCAL)
     719    {
     720        PSHAREDCLIPBOARDURIOBJHANDLEINFO pInfo
     721            = (PSHAREDCLIPBOARDURIOBJHANDLEINFO)RTMemAlloc(sizeof(SHAREDCLIPBOARDURIOBJHANDLEINFO));
     722        if (pInfo)
     723        {
     724            const bool fWritable = true; /** @todo Fix this. */
     725
     726            uint64_t fOpen;
     727            rc = sharedClipboardConvertFileCreateFlags(fWritable,
     728                                                       pOpenCreateParms->fCreate, pOpenCreateParms->ObjInfo.Attr.fMode,
     729                                                       SHAREDCLIPBOARDOBJHANDLE_INVALID, &fOpen);
     730            if (RT_SUCCESS(rc))
     731            {
     732                char *pszPathAbs = RTStrAPrintf2("%s/%s", pTransfer->pszPathRootAbs, pOpenCreateParms->pszPath);
     733                if (pszPathAbs)
     734                {
     735                    LogFlowFunc(("%s\n", pszPathAbs));
     736
     737                    rc = RTFileOpen(&pInfo->u.Local.hFile, pszPathAbs, fOpen);
     738                    RTStrFree(pszPathAbs);
     739                }
     740                else
     741                    rc = VERR_NO_MEMORY;
     742            }
     743
     744            if (RT_SUCCESS(rc))
     745            {
     746                const SHAREDCLIPBOARDOBJHANDLE hObj = pTransfer->uObjHandleNext++;
     747
     748                pInfo->enmType = SHAREDCLIPBOARDURIOBJTYPE_FILE;
     749
     750                pTransfer->pMapObj->insert(
     751                    std::pair<SHAREDCLIPBOARDOBJHANDLE, PSHAREDCLIPBOARDURIOBJHANDLEINFO>(hObj, pInfo));
     752
     753                *phObj = hObj;
     754            }
     755
     756            if (RT_FAILURE(rc))
     757                RTMemFree(pInfo);
     758        }
     759        else
     760            rc = VERR_NO_MEMORY;
     761    }
     762    else if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_REMOTE)
     763    {
     764        if (pTransfer->ProviderIface.pfnObjOpen)
     765        {
     766            rc = pTransfer->ProviderIface.pfnObjOpen(&pTransfer->ProviderCtx, pOpenCreateParms, phObj);
     767        }
     768        else
     769            rc = VERR_NOT_SUPPORTED;
     770    }
     771
     772    LogFlowFuncLeaveRC(rc);
     773    return rc;
     774}
     775
     776/**
     777 * Closes an URI object.
     778 *
     779 * @returns VBox status code.
     780 * @param   pTransfer           URI clipboard transfer that contains the object to close.
     781 * @param   hObj                Handle of URI object to close.
     782 */
     783int SharedClipboardURIObjectClose(PSHAREDCLIPBOARDURITRANSFER pTransfer, SHAREDCLIPBOARDOBJHANDLE hObj)
     784{
     785    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     786
     787    int rc = VINF_SUCCESS;
     788
     789    if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_LOCAL)
     790    {
     791        SharedClipboardURIObjMap::iterator itObj = pTransfer->pMapObj->find(hObj);
     792        if (itObj != pTransfer->pMapObj->end())
     793        {
     794            PSHAREDCLIPBOARDURIOBJHANDLEINFO pInfo = itObj->second;
     795            AssertPtr(pInfo);
     796
     797            switch (pInfo->enmType)
     798            {
     799                case SHAREDCLIPBOARDURIOBJTYPE_DIRECTORY:
     800                {
     801                    rc = RTDirClose(pInfo->u.Local.hDir);
     802                    if (RT_SUCCESS(rc))
     803                        pInfo->u.Local.hDir = NIL_RTDIR;
     804                    break;
     805                }
     806
     807                case SHAREDCLIPBOARDURIOBJTYPE_FILE:
     808                {
     809                    rc = RTFileClose(pInfo->u.Local.hFile);
     810                    if (RT_SUCCESS(rc))
     811                        pInfo->u.Local.hFile = NIL_RTFILE;
     812                    break;
     813                }
     814
     815                default:
     816                    rc = VERR_NOT_IMPLEMENTED;
     817                    break;
     818            }
     819
     820            RTMemFree(pInfo);
     821
     822            pTransfer->pMapObj->erase(itObj);
     823        }
     824        else
     825            rc = VERR_NOT_FOUND;
     826    }
     827    else if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_REMOTE)
     828    {
     829        if (pTransfer->ProviderIface.pfnObjClose)
     830        {
     831            rc = pTransfer->ProviderIface.pfnObjClose(&pTransfer->ProviderCtx, hObj);
     832        }
     833        else
     834            rc = VERR_NOT_SUPPORTED;
     835    }
     836
     837    LogFlowFuncLeaveRC(rc);
     838    return rc;
     839}
     840
     841/**
     842 * Reads from an URI object.
     843 *
     844 * @returns VBox status code.
     845 * @param   pTransfer           URI clipboard transfer that contains the object to read from.
     846 * @param   hObj                Handle of URI object to read from.
     847 * @param   pvBuf               Buffer for where to store the read data.
     848 * @param   cbBuf               Size (in bytes) of buffer.
     849 * @param   pcbRead             How much bytes were read on success. Optional.
     850 */
     851int SharedClipboardURIObjectRead(PSHAREDCLIPBOARDURITRANSFER pTransfer,
     852                                 SHAREDCLIPBOARDOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead, uint32_t fFlags)
     853{
     854    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     855    AssertPtrReturn(pvBuf,     VERR_INVALID_POINTER);
     856    AssertReturn   (cbBuf,     VERR_INVALID_PARAMETER);
     857    /* pcbRead is optional. */
     858    /** @todo Validate fFlags. */
     859
     860    int rc = VINF_SUCCESS;
     861
     862    if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_LOCAL)
     863    {
     864        SharedClipboardURIObjMap::iterator itObj = pTransfer->pMapObj->find(hObj);
     865        if (itObj != pTransfer->pMapObj->end())
     866        {
     867            PSHAREDCLIPBOARDURIOBJHANDLEINFO pInfo = itObj->second;
     868            AssertPtr(pInfo);
     869
     870            switch (pInfo->enmType)
     871            {
     872                case SHAREDCLIPBOARDURIOBJTYPE_FILE:
     873                {
     874                    size_t cbRead;
     875                    rc = RTFileRead(pInfo->u.Local.hFile, pvBuf, cbBuf, &cbRead);
     876                    if (RT_SUCCESS(rc))
     877                    {
     878                        if (pcbRead)
     879                            *pcbRead = (uint32_t)cbRead;
     880                    }
     881                    break;
     882                }
     883
     884                default:
     885                    rc = VERR_NOT_SUPPORTED;
     886                    break;
     887            }
     888        }
     889        else
     890            rc = VERR_NOT_FOUND;
     891    }
     892    else if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_REMOTE)
     893    {
     894        if (pTransfer->ProviderIface.pfnObjRead)
     895        {
     896            rc = pTransfer->ProviderIface.pfnObjRead(&pTransfer->ProviderCtx, hObj, pvBuf, cbBuf, fFlags, pcbRead);
     897        }
     898        else
     899            rc = VERR_NOT_SUPPORTED;
     900    }
     901
     902    LogFlowFuncLeaveRC(rc);
     903    return rc;
     904}
     905
     906/**
     907 * Writes to an URI object.
     908 *
     909 * @returns VBox status code.
     910 * @param   pTransfer           URI clipboard transfer that contains the object to write to.
     911 * @param   hObj                Handle of URI object to write to.
     912 * @param   pvBuf               Buffer of data to write.
     913 * @param   cbBuf               Size (in bytes) of buffer to write.
     914 * @param   pcbWritten          How much bytes were writtenon success. Optional.
     915 */
     916int SharedClipboardURIObjectWrite(PSHAREDCLIPBOARDURITRANSFER pTransfer,
     917                                  SHAREDCLIPBOARDOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten,
    610918                                  uint32_t fFlags)
    611919{
    612     RT_NOREF(hObj, pvBuf, cbBuf, pcbWritten, fFlags);
    613     return 0;
    614 }
    615 
    616 int SharedClipboardURIObjectQueryInfo(SHAREDCLIPBOARDOBJHANDLE hObj, PSHAREDCLIPBOARDFSOBJINFO pObjInfo)
    617 {
    618     RT_NOREF(hObj, pObjInfo);
    619     return 0;
     920    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     921    AssertPtrReturn(pvBuf,     VERR_INVALID_POINTER);
     922    AssertReturn   (cbBuf,     VERR_INVALID_PARAMETER);
     923    /* pcbWritten is optional. */
     924
     925    int rc = VINF_SUCCESS;
     926
     927    if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_LOCAL)
     928    {
     929        SharedClipboardURIObjMap::iterator itObj = pTransfer->pMapObj->find(hObj);
     930        if (itObj != pTransfer->pMapObj->end())
     931        {
     932            PSHAREDCLIPBOARDURIOBJHANDLEINFO pInfo = itObj->second;
     933            AssertPtr(pInfo);
     934
     935            switch (pInfo->enmType)
     936            {
     937                case SHAREDCLIPBOARDURIOBJTYPE_FILE:
     938                {
     939                    rc = RTFileWrite(pInfo->u.Local.hFile, pvBuf, cbBuf, (size_t *)pcbWritten);
     940                    break;
     941                }
     942
     943                default:
     944                    rc = VERR_NOT_SUPPORTED;
     945                    break;
     946            }
     947        }
     948        else
     949            rc = VERR_NOT_FOUND;
     950    }
     951    else if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_REMOTE)
     952    {
     953        if (pTransfer->ProviderIface.pfnObjWrite)
     954        {
     955            rc = pTransfer->ProviderIface.pfnObjWrite(&pTransfer->ProviderCtx, hObj, pvBuf, cbBuf, fFlags, pcbWritten);
     956        }
     957        else
     958            rc = VERR_NOT_SUPPORTED;
     959    }
     960
     961    LogFlowFuncLeaveRC(rc);
     962    return rc;
     963}
     964
     965/**
     966 * Duplicaates an URI object data chunk.
     967 *
     968 * @returns Duplicated object data chunk on success, or NULL on failure.
     969 * @param   pDataChunk          URI object data chunk to duplicate.
     970 */
     971PVBOXCLIPBOARDOBJDATACHUNK SharedClipboardURIObjectDataChunkDup(PVBOXCLIPBOARDOBJDATACHUNK pDataChunk)
     972{
     973    if (!pDataChunk)
     974        return NULL;
     975
     976    PVBOXCLIPBOARDOBJDATACHUNK pDataChunkDup = (PVBOXCLIPBOARDOBJDATACHUNK)RTMemAllocZ(sizeof(VBOXCLIPBOARDOBJDATACHUNK));
     977    if (!pDataChunkDup)
     978        return NULL;
     979
     980    if (pDataChunk->pvData)
     981    {
     982        Assert(pDataChunk->cbData);
     983
     984        pDataChunkDup->uHandle = pDataChunk->uHandle;
     985        pDataChunkDup->pvData  = RTMemDup(pDataChunk->pvData, pDataChunk->cbData);
     986        pDataChunkDup->cbData  = pDataChunk->cbData;
     987    }
     988
     989    return pDataChunkDup;
     990}
     991
     992/**
     993 * Destroys an URI object data chunk.
     994 *
     995 * @param   pDataChunk          URI object data chunk to destroy.
     996 */
     997void SharedClipboardURIObjectDataChunkDestroy(PVBOXCLIPBOARDOBJDATACHUNK pDataChunk)
     998{
     999    if (!pDataChunk)
     1000        return;
     1001
     1002    if (pDataChunk->pvData)
     1003    {
     1004        Assert(pDataChunk->cbData);
     1005
     1006        RTMemFree(pDataChunk->pvData);
     1007
     1008        pDataChunk->pvData = NULL;
     1009        pDataChunk->cbData = 0;
     1010    }
     1011
     1012    pDataChunk->uHandle = 0;
     1013}
     1014
     1015/**
     1016 * Frees an URI object data chunk.
     1017 *
     1018 * @param   pDataChunk          URI object data chunk to free. The handed-in pointer will
     1019 *                              be invalid after calling this function.
     1020 */
     1021void SharedClipboardURIObjectDataChunkFree(PVBOXCLIPBOARDOBJDATACHUNK pDataChunk)
     1022{
     1023    if (!pDataChunk)
     1024        return;
     1025
     1026    SharedClipboardURIObjectDataChunkDestroy(pDataChunk);
     1027
     1028    RTMemFree(pDataChunk);
     1029    pDataChunk = NULL;
    6201030}
    6211031
     
    6561066    pTransfer->Thread.fStop      = false;
    6571067
     1068    pTransfer->pszPathRootAbs    = NULL;
     1069
    6581070    pTransfer->uListHandleNext   = 1;
    6591071    pTransfer->uObjHandleNext    = 1;
     
    6741086        if (pTransfer->pMapLists)
    6751087        {
    676             *ppTransfer = pTransfer;
     1088            pTransfer->pMapObj = new SharedClipboardURIObjMap();
     1089            if (pTransfer->pMapObj)
     1090                *ppTransfer = pTransfer;
    6771091        }
    6781092    }
     
    7061120        return rc;
    7071121
     1122    RTStrFree(pTransfer->pszPathRootAbs);
     1123
    7081124    if (pTransfer->pMapEvents)
    7091125    {
     1126        SharedClipboardURITransferEventMap::iterator itEvent = pTransfer->pMapEvents->begin();
     1127        while (itEvent != pTransfer->pMapEvents->end())
     1128        {
     1129
     1130            itEvent = pTransfer->pMapEvents->begin();
     1131        }
     1132
    7101133        delete pTransfer->pMapEvents;
    7111134        pTransfer->pMapEvents = NULL;
     
    7141137    if (pTransfer->pMapLists)
    7151138    {
     1139        SharedClipboardURIListMap::iterator itList = pTransfer->pMapLists->begin();
     1140        while (itList != pTransfer->pMapLists->end())
     1141        {
     1142            SharedClipboardURIListHandleInfoDestroy(itList->second);
     1143            pTransfer->pMapLists->erase(itList);
     1144            itList = pTransfer->pMapLists->begin();
     1145        }
     1146
     1147        Assert(pTransfer->pMapLists->size() == 0);
     1148
    7161149        delete pTransfer->pMapLists;
    7171150        pTransfer->pMapLists = NULL;
     1151    }
     1152
     1153    if (pTransfer->pMapObj)
     1154    {
     1155        SharedClipboardURIObjMap::iterator itObj = pTransfer->pMapObj->begin();
     1156        while (itObj != pTransfer->pMapObj->end())
     1157        {
     1158            SharedClipboardURIObjectHandleInfoDestroy(itObj->second);
     1159            pTransfer->pMapObj->erase(itObj);
     1160            itObj = pTransfer->pMapObj->begin();
     1161        }
     1162
     1163        Assert(pTransfer->pMapObj->size() == 0);
     1164
     1165        delete pTransfer->pMapObj;
     1166        pTransfer->pMapObj = NULL;
    7181167    }
    7191168
     
    7861235            if (RT_SUCCESS(rc))
    7871236            {
    788                 if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
     1237                switch (pInfo->enmType)
    7891238                {
    790                     rc = RTDirOpen(&pInfo->u.Local.hDirRoot, pOpenParms->pszPath);
     1239                    case SHAREDCLIPBOARDURIOBJTYPE_DIRECTORY:
     1240                    {
     1241                        rc = RTDirOpen(&pInfo->u.Local.hDir, pOpenParms->pszPath);
     1242                    }
     1243
     1244                    case SHAREDCLIPBOARDURIOBJTYPE_FILE:
     1245                    {
     1246                        rc = RTFileOpen(&pInfo->u.Local.hFile, pOpenParms->pszPath,
     1247                                        RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
     1248                        break;
     1249                    }
     1250
     1251                    default:
     1252                        rc = VERR_NOT_SUPPORTED;
     1253                        break;
    7911254                }
    792                 else if (RTFS_IS_FILE(objInfo.Attr.fMode))
    793                 {
    794                     rc = RTFileOpen(&pInfo->u.Local.hFile, pOpenParms->pszPath,
    795                                     RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
    796                 }
    797                 else if (RTFS_IS_SYMLINK(objInfo.Attr.fMode))
    798                 {
    799                     rc = VERR_NOT_IMPLEMENTED; /** @todo */
    800                 }
    801                 else
    802                     AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
    803 
    804                 if (RT_SUCCESS(rc))
    805                     rc = SharedClipboardURIListOpenParmsCopy(&pInfo->OpenParms, pOpenParms);
    8061255
    8071256                if (RT_SUCCESS(rc))
    8081257                {
    809                     pInfo->fMode = objInfo.Attr.fMode;
    810 
    8111258                    hList = sharedClipboardURITransferListHandleNew(pTransfer);
    8121259
    8131260                    pTransfer->pMapLists->insert(
    814                         std::pair<SHAREDCLIPBOARDLISTHANDLE, PSHAREDCLIPBOARDURILISTHANDLEINFO>(hList, pInfo));
     1261                        std::pair<SHAREDCLIPBOARDLISTHANDLE, PSHAREDCLIPBOARDURILISTHANDLEINFO>(hList, pInfo)); /** @todo Can this throw? */
    8151262                }
    8161263                else
     
    8181265                    if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
    8191266                    {
    820                         if (RTDirIsValid(pInfo->u.Local.hDirRoot))
    821                             RTDirClose(pInfo->u.Local.hDirRoot);
     1267                        if (RTDirIsValid(pInfo->u.Local.hDir))
     1268                            RTDirClose(pInfo->u.Local.hDir);
    8221269                    }
    8231270                    else if (RTFS_IS_FILE(objInfo.Attr.fMode))
     
    8781325            AssertPtr(pInfo);
    8791326
    880             if (RTDirIsValid(pInfo->u.Local.hDirRoot))
    881                 RTDirClose(pInfo->u.Local.hDirRoot);
     1327            switch (pInfo->enmType)
     1328            {
     1329                case SHAREDCLIPBOARDURIOBJTYPE_DIRECTORY:
     1330                {
     1331                    if (RTDirIsValid(pInfo->u.Local.hDir))
     1332                        RTDirClose(pInfo->u.Local.hDir);
     1333                    break;
     1334                }
     1335
     1336                default:
     1337                    rc = VERR_NOT_SUPPORTED;
     1338                    break;
     1339            }
    8821340
    8831341            RTMemFree(pInfo);
     
    9351393static int sharedClipboardURITransferListHdrFromDir(PVBOXCLIPBOARDLISTHDR pHdr,
    9361394                                                    const char *pcszSrcPath, const char *pcszDstPath,
    937                                                     const char *pcszDstBase, size_t cchDstBase)
     1395                                                    const char *pcszDstBase)
    9381396{
    9391397    AssertPtrReturn(pcszSrcPath, VERR_INVALID_POINTER);
     
    9411399    AssertPtrReturn(pcszDstPath, VERR_INVALID_POINTER);
    9421400
    943     RT_NOREF(cchDstBase);
    944 
    945     LogFlowFunc(("pcszSrcPath=%s, pcszDstPath=%s, pcszDstBase=%s, cchDstBase=%zu\n",
    946                  pcszSrcPath, pcszDstPath, pcszDstBase, cchDstBase));
     1401    LogFlowFunc(("pcszSrcPath=%s, pcszDstPath=%s, pcszDstBase=%s\n",
     1402                 pcszSrcPath, pcszDstPath, pcszDstBase));
    9471403
    9481404    RTFSOBJINFO objInfo;
     
    10441500
    10451501/**
     1502 * Translates an absolute path to a relative one.
     1503 *
     1504 * @returns Translated, allocated path on success, or NULL on failure.
     1505 *          Must be free'd with RTStrFree().
     1506 * @param   pszPath             Absolute path to translate.
     1507 */
     1508static char *sharedClipboardPathTranslate(const char *pszPath)
     1509{
     1510    char *pszPathTranslated = NULL;
     1511
     1512    char *pszSrcPath = RTStrDup(pszPath);
     1513    if (pszSrcPath)
     1514    {
     1515        size_t cbSrcPathLen = RTPathStripTrailingSlash(pszSrcPath);
     1516        if (cbSrcPathLen)
     1517        {
     1518            char *pszFileName = RTPathFilename(pszSrcPath);
     1519            if (pszFileName)
     1520            {
     1521                Assert(pszFileName >= pszSrcPath);
     1522                size_t cchDstBase = pszFileName - pszSrcPath;
     1523
     1524                pszPathTranslated = RTStrDup(&pszSrcPath[cchDstBase]);
     1525
     1526                LogFlowFunc(("pszSrcPath=%s, pszFileName=%s -> pszPathTranslated=%s\n",
     1527                             pszSrcPath, pszFileName, pszPathTranslated));
     1528            }
     1529        }
     1530
     1531        RTStrFree(pszSrcPath);
     1532    }
     1533
     1534    return pszPathTranslated;
     1535}
     1536
     1537/**
    10461538 * Retrieves the header of a Shared Clipboard list.
    10471539 *
     
    10721564                AssertPtr(pInfo);
    10731565
    1074                 if (RTFS_IS_DIRECTORY(pInfo->fMode))
     1566                switch (pInfo->enmType)
    10751567                {
    1076                     char *pszSrcPath = RTStrDup(pInfo->OpenParms.pszPath);
    1077                     if (pszSrcPath)
     1568                    case SHAREDCLIPBOARDURIOBJTYPE_DIRECTORY:
    10781569                    {
    1079                         size_t cbSrcPathLen = RTPathStripTrailingSlash(pszSrcPath);
    1080                         if (cbSrcPathLen)
     1570                        char *pszPathRel = sharedClipboardPathTranslate(pInfo->pszPathLocalAbs);
     1571                        if (pszPathRel)
    10811572                        {
    1082                             char *pszFileName = RTPathFilename(pszSrcPath);
    1083                             if (pszFileName)
    1084                             {
    1085                                 Assert(pszFileName >= pszSrcPath);
    1086                                 size_t cchDstBase = pszFileName - pszSrcPath;
    1087 #ifdef VBOX_STRICT
    1088                                 char *pszDstPath  = &pszSrcPath[cchDstBase];
    1089                                 LogFlowFunc(("pszSrcPath=%s, pszFileName=%s, pszDstPath=%s\n",
    1090                                              pszSrcPath, pszFileName, pszDstPath));
    1091 #endif
    1092                                 rc = sharedClipboardURITransferListHdrFromDir(pHdr,
    1093                                                                               pszSrcPath, pszSrcPath, pszSrcPath, cchDstBase);
    1094                             }
    1095                             else
    1096                                 rc = VERR_PATH_NOT_FOUND;
     1573                            rc = sharedClipboardURITransferListHdrFromDir(pHdr,
     1574                                                                          pszPathRel, pszPathRel, pszPathRel);
     1575                            RTStrFree(pszPathRel);
    10971576                        }
    10981577                        else
    1099                             rc = VERR_INVALID_PARAMETER;
    1100 
    1101                         RTStrFree(pszSrcPath);
     1578                            rc = VERR_NO_MEMORY;
     1579                        break;
    11021580                    }
    1103                     else
    1104                         rc = VERR_NO_MEMORY;
     1581
     1582                    case SHAREDCLIPBOARDURIOBJTYPE_FILE:
     1583                    {
     1584                        pHdr->cTotalObjects = 1;
     1585
     1586                        RTFSOBJINFO objInfo;
     1587                        rc = RTFileQueryInfo(pInfo->u.Local.hFile, &objInfo, RTFSOBJATTRADD_NOTHING);
     1588                        if (RT_SUCCESS(rc))
     1589                        {
     1590                            pHdr->cbTotalSize = objInfo.cbObject;
     1591                        }
     1592                        break;
     1593                    }
     1594
     1595                    default:
     1596                        rc = VERR_NOT_SUPPORTED;
     1597                        break;
    11051598                }
    1106                 else if (RTFS_IS_FILE(pInfo->fMode))
     1599            }
     1600
     1601            LogFlowFunc(("cTotalObj=%RU64, cbTotalSize=%RU64\n", pHdr->cTotalObjects, pHdr->cbTotalSize));
     1602        }
     1603        else
     1604            rc = VERR_NOT_FOUND;
     1605    }
     1606    else if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_REMOTE)
     1607    {
     1608        if (pTransfer->ProviderIface.pfnListHdrRead)
     1609        {
     1610            rc = pTransfer->ProviderIface.pfnListHdrRead(&pTransfer->ProviderCtx, hList, pHdr);
     1611        }
     1612        else
     1613            rc = VERR_NOT_SUPPORTED;
     1614    }
     1615    else
     1616        AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
     1617
     1618    LogFlowFuncLeaveRC(rc);
     1619    return rc;
     1620}
     1621
     1622/**
     1623 * Returns the current URI object for a clipboard URI transfer list.
     1624 *
     1625 * Currently not implemented and wil return NULL.
     1626 *
     1627 * @returns Pointer to URI object, or NULL if not found / invalid.
     1628 * @param   pTransfer           URI clipboard transfer to return URI object for.
     1629 * @param   hList               Handle of URI transfer list to get object for.
     1630 * @param   uIdx                Index of object to get.
     1631 */
     1632PSHAREDCLIPBOARDURITRANSFEROBJ SharedClipboardURITransferListGetObj(PSHAREDCLIPBOARDURITRANSFER pTransfer,
     1633                                                                    SHAREDCLIPBOARDLISTHANDLE hList, uint64_t uIdx)
     1634{
     1635    AssertPtrReturn(pTransfer, NULL);
     1636
     1637    RT_NOREF(hList, uIdx);
     1638
     1639    LogFlowFunc(("hList=%RU64\n", hList));
     1640
     1641    return NULL;
     1642}
     1643
     1644/**
     1645 * Reads a single Shared Clipboard list entry.
     1646 *
     1647 * @returns VBox status code or VERR_NO_MORE_FILES if the end of the list has been reached.
     1648 * @param   pTransfer           URI clipboard transfer to handle.
     1649 * @param   hList               List handle of list to read from.
     1650 * @param   pEntry              Where to store the read information.
     1651 */
     1652int SharedClipboardURITransferListRead(PSHAREDCLIPBOARDURITRANSFER pTransfer, SHAREDCLIPBOARDLISTHANDLE hList,
     1653                                       PVBOXCLIPBOARDLISTENTRY pEntry)
     1654{
     1655    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     1656    AssertPtrReturn(pEntry,    VERR_INVALID_POINTER);
     1657
     1658    int rc = VINF_SUCCESS;
     1659
     1660    LogFlowFunc(("hList=%RU64\n", hList));
     1661
     1662    if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_LOCAL)
     1663    {
     1664        SharedClipboardURIListMap::iterator itList = pTransfer->pMapLists->find(hList);
     1665        if (itList != pTransfer->pMapLists->end())
     1666        {
     1667            PSHAREDCLIPBOARDURILISTHANDLEINFO pInfo = itList->second;
     1668            AssertPtr(pInfo);
     1669
     1670            switch (pInfo->enmType)
     1671            {
     1672                case SHAREDCLIPBOARDURIOBJTYPE_DIRECTORY:
    11071673                {
    1108                     pHdr->cTotalObjects = 1;
     1674                    LogFlowFunc(("\tDirectory: %s\n", pInfo->pszPathLocalAbs));
     1675
     1676                    for (;;)
     1677                    {
     1678                        bool fSkipEntry = false; /* Whether to skip an entry in the enumeration. */
     1679
     1680                        size_t        cbDirEntry = 0;
     1681                        PRTDIRENTRYEX pDirEntry  = NULL;
     1682                        rc = RTDirReadExA(pInfo->u.Local.hDir, &pDirEntry, &cbDirEntry, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
     1683                        if (RT_SUCCESS(rc))
     1684                        {
     1685                            switch (pDirEntry->Info.Attr.fMode & RTFS_TYPE_MASK)
     1686                            {
     1687                                case RTFS_TYPE_DIRECTORY:
     1688                                {
     1689                                    /* Skip "." and ".." entries. */
     1690                                    if (RTDirEntryExIsStdDotLink(pDirEntry))
     1691                                    {
     1692                                        fSkipEntry = true;
     1693                                        break;
     1694                                    }
     1695
     1696                                    LogFlowFunc(("Directory: %s\n", pDirEntry->szName));
     1697                                    break;
     1698                                }
     1699
     1700                                case RTFS_TYPE_FILE:
     1701                                {
     1702                                    LogFlowFunc(("File: %s\n", pDirEntry->szName));
     1703                                    break;
     1704                                }
     1705
     1706                                case RTFS_TYPE_SYMLINK:
     1707                                {
     1708                                    rc = VERR_NOT_IMPLEMENTED; /** @todo Not implemented yet. */
     1709                                    break;
     1710                                }
     1711
     1712                                default:
     1713                                    break;
     1714                            }
     1715
     1716                            if (   RT_SUCCESS(rc)
     1717                                && !fSkipEntry)
     1718                            {
     1719                                pEntry->pvInfo = (PSHAREDCLIPBOARDFSOBJINFO)RTMemAlloc(sizeof(SHAREDCLIPBOARDFSOBJINFO));
     1720                                if (pEntry->pvInfo)
     1721                                {
     1722                                    rc = RTStrCopy(pEntry->pszName, pEntry->cbName, pDirEntry->szName);
     1723                                    if (RT_SUCCESS(rc))
     1724                                    {
     1725                                        SharedClipboardFsObjFromIPRT(PSHAREDCLIPBOARDFSOBJINFO(pEntry->pvInfo), &pDirEntry->Info);
     1726
     1727                                        pEntry->cbInfo = sizeof(SHAREDCLIPBOARDFSOBJINFO);
     1728                                        pEntry->fInfo  = VBOX_SHAREDCLIPBOARD_INFO_FLAG_FSOBJINFO;
     1729                                    }
     1730                                }
     1731                                else
     1732                                    rc = VERR_NO_MEMORY;
     1733                            }
     1734
     1735                            RTDirReadExAFree(&pDirEntry, &cbDirEntry);
     1736                        }
     1737
     1738                        if (   !fSkipEntry /* Do we have a valid entry? Bail out. */
     1739                            || RT_FAILURE(rc))
     1740                        {
     1741                            break;
     1742                        }
     1743                    }
     1744
     1745                    break;
     1746                }
     1747
     1748                case SHAREDCLIPBOARDURIOBJTYPE_FILE:
     1749                {
     1750                    LogFlowFunc(("\tSingle file: %s\n", pInfo->pszPathLocalAbs));
    11091751
    11101752                    RTFSOBJINFO objInfo;
     
    11121754                    if (RT_SUCCESS(rc))
    11131755                    {
    1114                         pHdr->cbTotalSize = objInfo.cbObject;
     1756                        pEntry->pvInfo = (PSHAREDCLIPBOARDFSOBJINFO)RTMemAlloc(sizeof(SHAREDCLIPBOARDFSOBJINFO));
     1757                        if (pEntry->pvInfo)
     1758                        {
     1759                            rc = RTStrCopy(pEntry->pszName, pEntry->cbName, pInfo->pszPathLocalAbs);
     1760                            if (RT_SUCCESS(rc))
     1761                            {
     1762                                SharedClipboardFsObjFromIPRT(PSHAREDCLIPBOARDFSOBJINFO(pEntry->pvInfo), &objInfo);
     1763
     1764                                pEntry->cbInfo = sizeof(SHAREDCLIPBOARDFSOBJINFO);
     1765                                pEntry->fInfo  = VBOX_SHAREDCLIPBOARD_INFO_FLAG_FSOBJINFO;
     1766                            }
     1767                        }
     1768                        else
     1769                            rc = VERR_NO_MEMORY;
    11151770                    }
     1771
     1772                    break;
    11161773                }
    1117                 else if (RTFS_IS_SYMLINK(pInfo->fMode))
    1118                 {
    1119                     rc = VERR_NOT_IMPLEMENTED; /** @todo */
    1120                 }
    1121                 else
    1122                     AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
     1774
     1775                default:
     1776                    rc = VERR_NOT_SUPPORTED;
     1777                    break;
    11231778            }
    1124 
    1125             LogFlowFunc(("cTotalObj=%RU64, cbTotalSize=%RU64\n", pHdr->cTotalObjects, pHdr->cbTotalSize));
    1126         }
    1127         else
    1128             rc = VERR_NOT_FOUND;
    1129     }
    1130     else if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_REMOTE)
    1131     {
    1132         if (pTransfer->ProviderIface.pfnListHdrRead)
    1133         {
    1134             rc = pTransfer->ProviderIface.pfnListHdrRead(&pTransfer->ProviderCtx, hList, pHdr);
    1135         }
    1136         else
    1137             rc = VERR_NOT_SUPPORTED;
    1138     }
    1139     else
    1140         AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
    1141 
    1142     LogFlowFuncLeaveRC(rc);
    1143     return rc;
    1144 }
    1145 
    1146 /**
    1147  * Returns the current URI object for a clipboard URI transfer list.
    1148  *
    1149  * @returns Pointer to URI object.
    1150  * @param   pTransfer           URI clipboard transfer to return URI object for.
    1151  */
    1152 PSHAREDCLIPBOARDURITRANSFEROBJ SharedClipboardURITransferListGetObj(PSHAREDCLIPBOARDURITRANSFER pTransfer,
    1153                                                                     SHAREDCLIPBOARDLISTHANDLE hList, uint64_t uIdx)
    1154 {
    1155     AssertPtrReturn(pTransfer, NULL);
    1156 
    1157     RT_NOREF(hList, uIdx);
    1158 
    1159     LogFlowFunc(("hList=%RU64\n", hList));
    1160 
    1161     return NULL;
    1162 }
    1163 
    1164 /**
    1165  * Reads a single Shared Clipboard list entry.
    1166  *
    1167  * @returns VBox status code or VERR_NO_MORE_FILES if the end of the list has been reached.
    1168  * @param   pTransfer           URI clipboard transfer to handle.
    1169  * @param   hList               List handle of list to read from.
    1170  * @param   pEntry              Where to store the read information.
    1171  */
    1172 int SharedClipboardURITransferListRead(PSHAREDCLIPBOARDURITRANSFER pTransfer, SHAREDCLIPBOARDLISTHANDLE hList,
    1173                                        PVBOXCLIPBOARDLISTENTRY pEntry)
    1174 {
    1175     AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
    1176     AssertPtrReturn(pEntry,    VERR_INVALID_POINTER);
    1177 
    1178     int rc = VINF_SUCCESS;
    1179 
    1180     LogFlowFunc(("hList=%RU64\n", hList));
    1181 
    1182     if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_LOCAL)
    1183     {
    1184         SharedClipboardURIListMap::iterator itList = pTransfer->pMapLists->find(hList);
    1185         if (itList != pTransfer->pMapLists->end())
    1186         {
    1187             PSHAREDCLIPBOARDURILISTHANDLEINFO pInfo = itList->second;
    1188             AssertPtr(pInfo);
    1189 
    1190             LogFlowFunc(("\tfMode=%RU32, pszPath=%s\n", pInfo->fMode, pInfo->OpenParms.pszPath));
    1191 
    1192             if (RTFS_IS_DIRECTORY(pInfo->fMode))
    1193             {
    1194                 for (;;)
    1195                 {
    1196                     bool fSkipEntry = false; /* Whether to skip an entry in the enumeration. */
    1197 
    1198                     size_t        cbDirEntry = 0;
    1199                     PRTDIRENTRYEX pDirEntry  = NULL;
    1200                     rc = RTDirReadExA(pInfo->u.Local.hDirRoot, &pDirEntry, &cbDirEntry, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
    1201                     if (RT_SUCCESS(rc))
    1202                     {
    1203                         switch (pDirEntry->Info.Attr.fMode & RTFS_TYPE_MASK)
    1204                         {
    1205                             case RTFS_TYPE_DIRECTORY:
    1206                             {
    1207                                 /* Skip "." and ".." entries. */
    1208                                 if (RTDirEntryExIsStdDotLink(pDirEntry))
    1209                                 {
    1210                                     fSkipEntry = true;
    1211                                     break;
    1212                                 }
    1213 
    1214                                 LogFlowFunc(("Directory: %s\n", pDirEntry->szName));
    1215                                 break;
    1216                             }
    1217 
    1218                             case RTFS_TYPE_FILE:
    1219                             {
    1220                                 LogFlowFunc(("File: %s\n", pDirEntry->szName));
    1221                                 break;
    1222                             }
    1223 
    1224                             case RTFS_TYPE_SYMLINK:
    1225                             {
    1226                                 rc = VERR_NOT_IMPLEMENTED; /** @todo Not implemented yet. */
    1227                                 break;
    1228                             }
    1229 
    1230                             default:
    1231                                 break;
    1232                         }
    1233 
    1234                         if (   RT_SUCCESS(rc)
    1235                             && !fSkipEntry)
    1236                         {
    1237                             pEntry->pvInfo = (PSHAREDCLIPBOARDFSOBJINFO)RTMemAlloc(sizeof(SHAREDCLIPBOARDFSOBJINFO));
    1238                             if (pEntry->pvInfo)
    1239                             {
    1240                                 rc = RTStrCopy(pEntry->pszName, pEntry->cbName, pDirEntry->szName);
    1241                                 if (RT_SUCCESS(rc))
    1242                                 {
    1243                                     SharedClipboardFsObjFromIPRT(PSHAREDCLIPBOARDFSOBJINFO(pEntry->pvInfo), &pDirEntry->Info);
    1244 
    1245                                     pEntry->cbInfo = sizeof(SHAREDCLIPBOARDFSOBJINFO);
    1246                                     pEntry->fInfo  = VBOX_SHAREDCLIPBOARD_INFO_FLAG_FSOBJINFO;
    1247                                 }
    1248                             }
    1249                             else
    1250                                 rc = VERR_NO_MEMORY;
    1251                         }
    1252 
    1253                         RTDirReadExAFree(&pDirEntry, &cbDirEntry);
    1254                     }
    1255 
    1256                     if (   !fSkipEntry /* Do we have a valid entry? Bail out. */
    1257                         || RT_FAILURE(rc))
    1258                     {
    1259                         break;
    1260                     }
    1261                 }
    1262             }
    1263             else if (RTFS_IS_FILE(pInfo->fMode))
    1264             {
    1265                 LogFlowFunc(("\tSingle file: %s\n", pInfo->OpenParms.pszPath));
    1266 
    1267                 RTFSOBJINFO objInfo;
    1268                 rc = RTFileQueryInfo(pInfo->u.Local.hFile, &objInfo, RTFSOBJATTRADD_NOTHING);
    1269                 if (RT_SUCCESS(rc))
    1270                 {
    1271                     pEntry->pvInfo = (PSHAREDCLIPBOARDFSOBJINFO)RTMemAlloc(sizeof(SHAREDCLIPBOARDFSOBJINFO));
    1272                     if (pEntry->pvInfo)
    1273                     {
    1274                         rc = RTStrCopy(pEntry->pszName, pEntry->cbName, pInfo->OpenParms.pszPath);
    1275                         if (RT_SUCCESS(rc))
    1276                         {
    1277                             SharedClipboardFsObjFromIPRT(PSHAREDCLIPBOARDFSOBJINFO(pEntry->pvInfo), &objInfo);
    1278 
    1279                             pEntry->cbInfo = sizeof(SHAREDCLIPBOARDFSOBJINFO);
    1280                             pEntry->fInfo  = VBOX_SHAREDCLIPBOARD_INFO_FLAG_FSOBJINFO;
    1281                         }
    1282                     }
    1283                     else
    1284                         rc = VERR_NO_MEMORY;
    1285                 }
    1286             }
    1287             else if (RTFS_IS_SYMLINK(pInfo->fMode))
    1288             {
    1289                 rc = VERR_NOT_IMPLEMENTED;
    1290             }
    1291             else
    1292                 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
    12931779        }
    12941780        else
     
    14181904    AssertPtrReturnVoid(pTransfer);
    14191905
     1906    if (pTransfer->pszPathRootAbs)
     1907    {
     1908        RTStrFree(pTransfer->pszPathRootAbs);
     1909        pTransfer->pszPathRootAbs = NULL;
     1910    }
     1911
    14201912    pTransfer->lstRootEntries.clear();
    14211913}
     
    14271919 * @param   pTransfer           Transfer to set URI list entries for.
    14281920 * @param   pszRoots            String list (separated by CRLF) of root entries to set.
     1921 *                              All entries must have the same root path.
    14291922 * @param   cbRoots             Size (in bytes) of string list.
    14301923 */
    14311924int SharedClipboardURILTransferSetRoots(PSHAREDCLIPBOARDURITRANSFER pTransfer, const char *pszRoots, size_t cbRoots)
    14321925{
    1433     AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
    1434     AssertPtrReturn(pszRoots,  VERR_INVALID_POINTER);
    1435     AssertReturn(cbRoots,      VERR_INVALID_PARAMETER);
     1926    AssertPtrReturn(pTransfer,      VERR_INVALID_POINTER);
     1927    AssertPtrReturn(pszRoots,       VERR_INVALID_POINTER);
     1928    AssertReturn(cbRoots,           VERR_INVALID_PARAMETER);
    14361929
    14371930    if (!RTStrIsValidEncoding(pszRoots))
     
    14421935    sharedClipboardURIListTransferRootsClear(pTransfer);
    14431936
     1937    char *pszPathRootAbs = NULL;
     1938
    14441939    RTCList<RTCString> lstRootEntries = RTCString(pszRoots, cbRoots - 1).split("\r\n");
    14451940    for (size_t i = 0; i < lstRootEntries.size(); ++i)
    14461941    {
    14471942        SHAREDCLIPBOARDURILISTROOT listRoot;
    1448 
    14491943        listRoot.strPathAbs = lstRootEntries.at(i);
    14501944
     1945        if (!pszPathRootAbs)
     1946        {
     1947            pszPathRootAbs = RTStrDup(listRoot.strPathAbs.c_str());
     1948            if (pszPathRootAbs)
     1949            {
     1950                RTPathStripFilename(pszPathRootAbs);
     1951                LogFlowFunc(("pszPathRootAbs=%s\n", pszPathRootAbs));
     1952            }
     1953            else
     1954                rc = VERR_NO_MEMORY;
     1955        }
     1956
     1957        if (RT_FAILURE(rc))
     1958            break;
     1959
     1960        /* Make sure all entries have the same root path. */
     1961        if (!RTStrStartsWith(listRoot.strPathAbs.c_str(), pszPathRootAbs))
     1962        {
     1963            rc = VERR_INVALID_PARAMETER;
     1964            break;
     1965        }
     1966
    14511967        pTransfer->lstRootEntries.append(listRoot);
    14521968    }
    14531969
    1454     LogFlowFunc(("cRoots=%RU32\n", pTransfer->lstRootEntries.size()));
     1970    /** @todo Entry rollback on failure? */
     1971
     1972    if (RT_SUCCESS(rc))
     1973    {
     1974        pTransfer->pszPathRootAbs = pszPathRootAbs;
     1975        LogFlowFunc(("pszPathRootAbs=%s, cRoots=%zu\n", pTransfer->pszPathRootAbs, pTransfer->lstRootEntries.size()));
     1976    }
    14551977
    14561978    LogFlowFuncLeaveRC(rc);
     
    22492771}
    22502772
     2773/**
     2774 * Converts Shared Clipboard create flags (see SharedClipboard-uri.) into IPRT create flags.
     2775 *
     2776 * @returns IPRT status code.
     2777 * @param  fWritable            Whether the shared folder is writable
     2778 * @param  fShClFlags           Shared clipboard create flags.
     2779 * @param  fMode                File attributes.
     2780 * @param  handleInitial        Initial handle.
     2781 * @retval pfOpen               Where to store the IPRT creation / open flags.
     2782 *
     2783 * @sa Initially taken from vbsfConvertFileOpenFlags().
     2784 */
     2785static int sharedClipboardConvertFileCreateFlags(bool fWritable, unsigned fShClFlags, RTFMODE fMode,
     2786                                                 SHAREDCLIPBOARDOBJHANDLE handleInitial, uint64_t *pfOpen)
     2787{
     2788    uint64_t fOpen = 0;
     2789    int rc = VINF_SUCCESS;
     2790
     2791    if (   (fMode & RTFS_DOS_MASK) != 0
     2792        && (fMode & RTFS_UNIX_MASK) == 0)
     2793    {
     2794        /* A DOS/Windows guest, make RTFS_UNIX_* from RTFS_DOS_*.
     2795         * @todo this is based on rtFsModeNormalize/rtFsModeFromDos.
     2796         *       May be better to use RTFsModeNormalize here.
     2797         */
     2798        fMode |= RTFS_UNIX_IRUSR | RTFS_UNIX_IRGRP | RTFS_UNIX_IROTH;
     2799        /* x for directories. */
     2800        if (fMode & RTFS_DOS_DIRECTORY)
     2801            fMode |= RTFS_TYPE_DIRECTORY | RTFS_UNIX_IXUSR | RTFS_UNIX_IXGRP | RTFS_UNIX_IXOTH;
     2802        /* writable? */
     2803        if (!(fMode & RTFS_DOS_READONLY))
     2804            fMode |= RTFS_UNIX_IWUSR | RTFS_UNIX_IWGRP | RTFS_UNIX_IWOTH;
     2805
     2806        /* Set the requested mode using only allowed bits. */
     2807        fOpen |= ((fMode & RTFS_UNIX_MASK) << RTFILE_O_CREATE_MODE_SHIFT) & RTFILE_O_CREATE_MODE_MASK;
     2808    }
     2809    else
     2810    {
     2811        /* Old linux and solaris additions did not initialize the Info.Attr.fMode field
     2812         * and it contained random bits from stack. Detect this using the handle field value
     2813         * passed from the guest: old additions set it (incorrectly) to 0, new additions
     2814         * set it to SHAREDCLIPBOARDOBJHANDLE_INVALID(~0).
     2815         */
     2816        if (handleInitial == 0)
     2817        {
     2818            /* Old additions. Do nothing, use default mode. */
     2819        }
     2820        else
     2821        {
     2822            /* New additions or Windows additions. Set the requested mode using only allowed bits.
     2823             * Note: Windows guest set RTFS_UNIX_MASK bits to 0, which means a default mode
     2824             *       will be set in fOpen.
     2825             */
     2826            fOpen |= ((fMode & RTFS_UNIX_MASK) << RTFILE_O_CREATE_MODE_SHIFT) & RTFILE_O_CREATE_MODE_MASK;
     2827        }
     2828    }
     2829
     2830    switch ((fShClFlags & SHAREDCLIPBOARD_OBJ_CF_ACCESS_MASK_RW))
     2831    {
     2832        default:
     2833        case SHAREDCLIPBOARD_OBJ_CF_ACCESS_NONE:
     2834        {
     2835#ifdef RT_OS_WINDOWS
     2836            if ((fShClFlags & SHAREDCLIPBOARD_OBJ_CF_ACCESS_MASK_ATTR) != SHAREDCLIPBOARD_OBJ_CF_ACCESS_ATTR_NONE)
     2837                fOpen |= RTFILE_O_ATTR_ONLY;
     2838            else
     2839#endif
     2840                fOpen |= RTFILE_O_READ;
     2841            LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACCESS_NONE\n"));
     2842            break;
     2843        }
     2844
     2845        case SHAREDCLIPBOARD_OBJ_CF_ACCESS_READ:
     2846        {
     2847            fOpen |= RTFILE_O_READ;
     2848            LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACCESS_READ\n"));
     2849            break;
     2850        }
     2851
     2852        case SHAREDCLIPBOARD_OBJ_CF_ACCESS_WRITE:
     2853        {
     2854            fOpen |= RTFILE_O_WRITE;
     2855            LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACCESS_WRITE\n"));
     2856            break;
     2857        }
     2858
     2859        case SHAREDCLIPBOARD_OBJ_CF_ACCESS_READWRITE:
     2860        {
     2861            fOpen |= RTFILE_O_READWRITE;
     2862            LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACCESS_READWRITE\n"));
     2863            break;
     2864        }
     2865    }
     2866
     2867    if (fShClFlags & SHAREDCLIPBOARD_OBJ_CF_ACCESS_APPEND)
     2868    {
     2869        fOpen |= RTFILE_O_APPEND;
     2870    }
     2871
     2872    switch ((fShClFlags & SHAREDCLIPBOARD_OBJ_CF_ACCESS_MASK_ATTR))
     2873    {
     2874        default:
     2875        case SHAREDCLIPBOARD_OBJ_CF_ACCESS_ATTR_NONE:
     2876        {
     2877            fOpen |= RTFILE_O_ACCESS_ATTR_DEFAULT;
     2878            LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACCESS_ATTR_NONE\n"));
     2879            break;
     2880        }
     2881
     2882        case SHAREDCLIPBOARD_OBJ_CF_ACCESS_ATTR_READ:
     2883        {
     2884            fOpen |= RTFILE_O_ACCESS_ATTR_READ;
     2885            LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACCESS_ATTR_READ\n"));
     2886            break;
     2887        }
     2888
     2889        case SHAREDCLIPBOARD_OBJ_CF_ACCESS_ATTR_WRITE:
     2890        {
     2891            fOpen |= RTFILE_O_ACCESS_ATTR_WRITE;
     2892            LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACCESS_ATTR_WRITE\n"));
     2893            break;
     2894        }
     2895
     2896        case SHAREDCLIPBOARD_OBJ_CF_ACCESS_ATTR_READWRITE:
     2897        {
     2898            fOpen |= RTFILE_O_ACCESS_ATTR_READWRITE;
     2899            LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACCESS_ATTR_READWRITE\n"));
     2900            break;
     2901        }
     2902    }
     2903
     2904    /* Sharing mask */
     2905    switch ((fShClFlags & SHAREDCLIPBOARD_OBJ_CF_ACCESS_MASK_DENY))
     2906    {
     2907        default:
     2908        case SHAREDCLIPBOARD_OBJ_CF_ACCESS_DENYNONE:
     2909            fOpen |= RTFILE_O_DENY_NONE;
     2910            LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACCESS_DENYNONE\n"));
     2911            break;
     2912
     2913        case SHAREDCLIPBOARD_OBJ_CF_ACCESS_DENYREAD:
     2914            fOpen |= RTFILE_O_DENY_READ;
     2915            LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACCESS_DENYREAD\n"));
     2916            break;
     2917
     2918        case SHAREDCLIPBOARD_OBJ_CF_ACCESS_DENYWRITE:
     2919            fOpen |= RTFILE_O_DENY_WRITE;
     2920            LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACCESS_DENYWRITE\n"));
     2921            break;
     2922
     2923        case SHAREDCLIPBOARD_OBJ_CF_ACCESS_DENYALL:
     2924            fOpen |= RTFILE_O_DENY_ALL;
     2925            LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACCESS_DENYALL\n"));
     2926            break;
     2927    }
     2928
     2929    /* Open/Create action mask */
     2930    switch ((fShClFlags & SHAREDCLIPBOARD_OBJ_CF_ACT_MASK_IF_EXISTS))
     2931    {
     2932        case SHAREDCLIPBOARD_OBJ_CF_ACT_OPEN_IF_EXISTS:
     2933            if (SHAREDCLIPBOARD_OBJ_CF_ACT_CREATE_IF_NEW == (fShClFlags & SHAREDCLIPBOARD_OBJ_CF_ACT_MASK_IF_NEW))
     2934            {
     2935                fOpen |= RTFILE_O_OPEN_CREATE;
     2936                LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACT_OPEN_IF_EXISTS and SHAREDCLIPBOARD_OBJ_CF_ACT_CREATE_IF_NEW\n"));
     2937            }
     2938            else if (SHAREDCLIPBOARD_OBJ_CF_ACT_FAIL_IF_NEW == (fShClFlags & SHAREDCLIPBOARD_OBJ_CF_ACT_MASK_IF_NEW))
     2939            {
     2940                fOpen |= RTFILE_O_OPEN;
     2941                LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACT_OPEN_IF_EXISTS and SHAREDCLIPBOARD_OBJ_CF_ACT_FAIL_IF_NEW\n"));
     2942            }
     2943            else
     2944            {
     2945                LogFlowFunc(("invalid open/create action combination\n"));
     2946                rc = VERR_INVALID_PARAMETER;
     2947            }
     2948            break;
     2949        case SHAREDCLIPBOARD_OBJ_CF_ACT_FAIL_IF_EXISTS:
     2950            if (SHAREDCLIPBOARD_OBJ_CF_ACT_CREATE_IF_NEW == (fShClFlags & SHAREDCLIPBOARD_OBJ_CF_ACT_MASK_IF_NEW))
     2951            {
     2952                fOpen |= RTFILE_O_CREATE;
     2953                LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACT_FAIL_IF_EXISTS and SHAREDCLIPBOARD_OBJ_CF_ACT_CREATE_IF_NEW\n"));
     2954            }
     2955            else
     2956            {
     2957                LogFlowFunc(("invalid open/create action combination\n"));
     2958                rc = VERR_INVALID_PARAMETER;
     2959            }
     2960            break;
     2961        case SHAREDCLIPBOARD_OBJ_CF_ACT_REPLACE_IF_EXISTS:
     2962            if (SHAREDCLIPBOARD_OBJ_CF_ACT_CREATE_IF_NEW == (fShClFlags & SHAREDCLIPBOARD_OBJ_CF_ACT_MASK_IF_NEW))
     2963            {
     2964                fOpen |= RTFILE_O_CREATE_REPLACE;
     2965                LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACT_REPLACE_IF_EXISTS and SHAREDCLIPBOARD_OBJ_CF_ACT_CREATE_IF_NEW\n"));
     2966            }
     2967            else if (SHAREDCLIPBOARD_OBJ_CF_ACT_FAIL_IF_NEW == (fShClFlags & SHAREDCLIPBOARD_OBJ_CF_ACT_MASK_IF_NEW))
     2968            {
     2969                fOpen |= RTFILE_O_OPEN | RTFILE_O_TRUNCATE;
     2970                LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACT_REPLACE_IF_EXISTS and SHAREDCLIPBOARD_OBJ_CF_ACT_FAIL_IF_NEW\n"));
     2971            }
     2972            else
     2973            {
     2974                LogFlowFunc(("invalid open/create action combination\n"));
     2975                rc = VERR_INVALID_PARAMETER;
     2976            }
     2977            break;
     2978        case SHAREDCLIPBOARD_OBJ_CF_ACT_OVERWRITE_IF_EXISTS:
     2979            if (SHAREDCLIPBOARD_OBJ_CF_ACT_CREATE_IF_NEW == (fShClFlags & SHAREDCLIPBOARD_OBJ_CF_ACT_MASK_IF_NEW))
     2980            {
     2981                fOpen |= RTFILE_O_CREATE_REPLACE;
     2982                LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACT_OVERWRITE_IF_EXISTS and SHAREDCLIPBOARD_OBJ_CF_ACT_CREATE_IF_NEW\n"));
     2983            }
     2984            else if (SHAREDCLIPBOARD_OBJ_CF_ACT_FAIL_IF_NEW == (fShClFlags & SHAREDCLIPBOARD_OBJ_CF_ACT_MASK_IF_NEW))
     2985            {
     2986                fOpen |= RTFILE_O_OPEN | RTFILE_O_TRUNCATE;
     2987                LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACT_OVERWRITE_IF_EXISTS and SHAREDCLIPBOARD_OBJ_CF_ACT_FAIL_IF_NEW\n"));
     2988            }
     2989            else
     2990            {
     2991                LogFlowFunc(("invalid open/create action combination\n"));
     2992                rc = VERR_INVALID_PARAMETER;
     2993            }
     2994            break;
     2995        default:
     2996        {
     2997            rc = VERR_INVALID_PARAMETER;
     2998            LogFlowFunc(("SHAREDCLIPBOARD_OBJ_CF_ACT_MASK_IF_EXISTS - invalid parameter\n"));
     2999            break;
     3000        }
     3001    }
     3002
     3003    if (RT_SUCCESS(rc))
     3004    {
     3005        if (!fWritable)
     3006            fOpen &= ~RTFILE_O_WRITE;
     3007
     3008        *pfOpen = fOpen;
     3009    }
     3010
     3011    LogFlowFuncLeaveRC(rc);
     3012    return rc;
     3013}
     3014
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-uri.cpp

    r80318 r80359  
    418418                               PSHAREDCLIPBOARDOBJHANDLE phObj)
    419419{
    420     RT_NOREF(pCtx, pCreateParms, phObj);
    421 
    422420    LogFlowFuncEnter();
    423421
    424     int rc = VINF_SUCCESS;
    425 
    426     PVBOXCLIPBOARDCONTEXT pThisCtx = (PVBOXCLIPBOARDCONTEXT)pCtx->pvUser;
    427     AssertPtr(pThisCtx);
    428 
    429     RT_NOREF(pThisCtx);
     422    PVBOXCLIPBOARDCLIENT pClient = (PVBOXCLIPBOARDCLIENT)pCtx->pvUser;
     423    AssertPtr(pClient);
     424
     425    int rc;
     426
     427    PVBOXCLIPBOARDCLIENTMSG pMsg = vboxSvcClipboardMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_OPEN,
     428                                                            VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_OPEN);
     429    if (pMsg)
     430    {
     431        const uint16_t uEvent = SharedClipboardURITransferEventIDGenerate(pCtx->pTransfer);
     432
     433        LogFlowFunc(("pszPath=%s, fCreate=0x%x\n", pCreateParms->pszPath, pCreateParms->fCreate));
     434
     435        const uint32_t cbPath = (uint32_t)strlen(pCreateParms->pszPath) + 1; /* Include terminating zero */
     436
     437        HGCMSvcSetU32(&pMsg->m_paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pCtx->pTransfer->State.uID, uEvent));
     438        HGCMSvcSetU64(&pMsg->m_paParms[1], 0); /* uHandle */
     439        HGCMSvcSetU32(&pMsg->m_paParms[2], cbPath);
     440        HGCMSvcSetPv (&pMsg->m_paParms[3], pCreateParms->pszPath, cbPath);
     441        HGCMSvcSetU32(&pMsg->m_paParms[4], pCreateParms->fCreate);
     442
     443        rc = vboxSvcClipboardMsgAdd(pClient->pData, pMsg, true /* fAppend */);
     444        if (RT_SUCCESS(rc))
     445        {
     446            int rc2 = SharedClipboardURITransferEventRegister(pCtx->pTransfer, uEvent);
     447            AssertRC(rc2);
     448
     449            rc = vboxSvcClipboardClientWakeup(pClient);
     450            if (RT_SUCCESS(rc))
     451            {
     452                PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload;
     453                rc = SharedClipboardURITransferEventWait(pCtx->pTransfer, uEvent, pCtx->pTransfer->uTimeoutMs, &pPayload);
     454                if (RT_SUCCESS(rc))
     455                {
     456                    Assert(pPayload->cbData == sizeof(VBOXCLIPBOARDREPLY));
     457
     458                    PVBOXCLIPBOARDREPLY pReply = (PVBOXCLIPBOARDREPLY)pPayload->pvData;
     459                    AssertPtr(pReply);
     460
     461                    Assert(pReply->uType == VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_OBJ_OPEN);
     462
     463                    *phObj = pReply->u.ObjOpen.uHandle;
     464
     465                    SharedClipboardURITransferPayloadFree(pPayload);
     466                }
     467            }
     468        }
     469    }
     470    else
     471        rc = VERR_NO_MEMORY;
    430472
    431473    LogFlowFuncLeaveRC(rc);
     
    435477int vboxSvcClipboardURIObjClose(PSHAREDCLIPBOARDPROVIDERCTX pCtx, SHAREDCLIPBOARDOBJHANDLE hObj)
    436478{
    437     RT_NOREF(pCtx, hObj);
    438 
    439479    LogFlowFuncEnter();
    440480
    441     int rc = VINF_SUCCESS;
    442 
    443     PVBOXCLIPBOARDCONTEXT pThisCtx = (PVBOXCLIPBOARDCONTEXT)pCtx->pvUser;
    444     AssertPtr(pThisCtx);
    445 
    446     RT_NOREF(pThisCtx);
     481    PVBOXCLIPBOARDCLIENT pClient = (PVBOXCLIPBOARDCLIENT)pCtx->pvUser;
     482    AssertPtr(pClient);
     483
     484    int rc;
     485
     486    PVBOXCLIPBOARDCLIENTMSG pMsg = vboxSvcClipboardMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_CLOSE,
     487                                                            VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_CLOSE);
     488    if (pMsg)
     489    {
     490        const uint16_t uEvent = SharedClipboardURITransferEventIDGenerate(pCtx->pTransfer);
     491
     492        HGCMSvcSetU32(&pMsg->m_paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pCtx->pTransfer->State.uID, uEvent));
     493        HGCMSvcSetU64(&pMsg->m_paParms[1], hObj);
     494
     495        rc = vboxSvcClipboardMsgAdd(pClient->pData, pMsg, true /* fAppend */);
     496        if (RT_SUCCESS(rc))
     497        {
     498            int rc2 = SharedClipboardURITransferEventRegister(pCtx->pTransfer, uEvent);
     499            AssertRC(rc2);
     500
     501            rc = vboxSvcClipboardClientWakeup(pClient);
     502            if (RT_SUCCESS(rc))
     503            {
     504                PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload;
     505                rc = SharedClipboardURITransferEventWait(pCtx->pTransfer, uEvent, pCtx->pTransfer->uTimeoutMs, &pPayload);
     506                if (RT_SUCCESS(rc))
     507                {
     508                    Assert(pPayload->cbData == sizeof(VBOXCLIPBOARDREPLY));
     509
     510                    PVBOXCLIPBOARDREPLY pReply = (PVBOXCLIPBOARDREPLY)pPayload->pvData;
     511                    AssertPtr(pReply);
     512
     513                    Assert(pReply->uType == VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_OBJ_CLOSE);
     514
     515                    SharedClipboardURITransferPayloadFree(pPayload);
     516                }
     517            }
     518        }
     519    }
     520    else
     521        rc = VERR_NO_MEMORY;
    447522
    448523    LogFlowFuncLeaveRC(rc);
     
    453528                               void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbRead)
    454529{
    455     RT_NOREF(pCtx, hObj, pvData, cbData, fFlags, pcbRead);
    456 
    457530    LogFlowFuncEnter();
    458531
    459     int rc = VINF_SUCCESS;
    460 
    461     *pcbRead = cbData;
     532    PVBOXCLIPBOARDCLIENT pClient = (PVBOXCLIPBOARDCLIENT)pCtx->pvUser;
     533    AssertPtr(pClient);
     534
     535    int rc;
     536
     537    PVBOXCLIPBOARDCLIENTMSG pMsg = vboxSvcClipboardMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_READ,
     538                                                            VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_READ_REQ);
     539    if (pMsg)
     540    {
     541        const uint16_t uEvent = SharedClipboardURITransferEventIDGenerate(pCtx->pTransfer);
     542
     543        HGCMSvcSetU32(&pMsg->m_paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pCtx->pTransfer->State.uID, uEvent));
     544        HGCMSvcSetU64(&pMsg->m_paParms[1], hObj);
     545        HGCMSvcSetU32(&pMsg->m_paParms[2], cbData);
     546        HGCMSvcSetU32(&pMsg->m_paParms[3], fFlags);
     547
     548        rc = vboxSvcClipboardMsgAdd(pClient->pData, pMsg, true /* fAppend */);
     549        if (RT_SUCCESS(rc))
     550        {
     551            int rc2 = SharedClipboardURITransferEventRegister(pCtx->pTransfer, uEvent);
     552            AssertRC(rc2);
     553
     554            rc = vboxSvcClipboardClientWakeup(pClient);
     555            if (RT_SUCCESS(rc))
     556            {
     557                PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload;
     558                rc = SharedClipboardURITransferEventWait(pCtx->pTransfer, uEvent, pCtx->pTransfer->uTimeoutMs, &pPayload);
     559                if (RT_SUCCESS(rc))
     560                {
     561                    Assert(pPayload->cbData == sizeof(VBOXCLIPBOARDOBJDATACHUNK));
     562
     563                    PVBOXCLIPBOARDOBJDATACHUNK pDataChunk = (PVBOXCLIPBOARDOBJDATACHUNK)pPayload->pvData;
     564                    AssertPtr(pDataChunk);
     565
     566                    const uint32_t cbRead = RT_MIN(cbData, pDataChunk->cbData);
     567
     568                    memcpy(pvData, pDataChunk->pvData, cbRead);
     569
     570                    if (pcbRead)
     571                        *pcbRead = cbRead;
     572
     573                    SharedClipboardURITransferPayloadFree(pPayload);
     574                }
     575            }
     576        }
     577    }
     578    else
     579        rc = VERR_NO_MEMORY;
    462580
    463581    LogFlowFuncLeaveRC(rc);
     
    468586                                void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbWritten)
    469587{
    470     RT_NOREF(pCtx, pCtx, hObj, pvData, cbData, fFlags, pcbWritten);
    471 
    472588    LogFlowFuncEnter();
    473589
    474     return VERR_NOT_IMPLEMENTED;
    475 }
    476 
     590    PVBOXCLIPBOARDCLIENT pClient = (PVBOXCLIPBOARDCLIENT)pCtx->pvUser;
     591    AssertPtr(pClient);
     592
     593    int rc;
     594
     595    PVBOXCLIPBOARDCLIENTMSG pMsg = vboxSvcClipboardMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_WRITE,
     596                                                            VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_WRITE);
     597    if (pMsg)
     598    {
     599        const uint16_t uEvent = SharedClipboardURITransferEventIDGenerate(pCtx->pTransfer);
     600
     601        HGCMSvcSetU32(&pMsg->m_paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pCtx->pTransfer->State.uID, uEvent));
     602        HGCMSvcSetU64(&pMsg->m_paParms[1], hObj);
     603        HGCMSvcSetU64(&pMsg->m_paParms[2], cbData);
     604        HGCMSvcSetU64(&pMsg->m_paParms[3], fFlags);
     605
     606        rc = vboxSvcClipboardMsgAdd(pClient->pData, pMsg, true /* fAppend */);
     607        if (RT_SUCCESS(rc))
     608        {
     609            int rc2 = SharedClipboardURITransferEventRegister(pCtx->pTransfer, uEvent);
     610            AssertRC(rc2);
     611
     612            rc = vboxSvcClipboardClientWakeup(pClient);
     613            if (RT_SUCCESS(rc))
     614            {
     615                PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload;
     616                rc = SharedClipboardURITransferEventWait(pCtx->pTransfer, uEvent, pCtx->pTransfer->uTimeoutMs, &pPayload);
     617                if (RT_SUCCESS(rc))
     618                {
     619                    const uint32_t cbRead = RT_MIN(cbData, pPayload->cbData);
     620
     621                    memcpy(pvData, pPayload->pvData, cbRead);
     622
     623                    if (pcbWritten)
     624                        *pcbWritten = cbRead;
     625
     626                    SharedClipboardURITransferPayloadFree(pPayload);
     627                }
     628            }
     629        }
     630    }
     631    else
     632        rc = VERR_NO_MEMORY;
     633
     634    LogFlowFuncLeaveRC(rc);
     635    return rc;
     636}
    477637
    478638/*********************************************************************************************************************************
     
    549709        if (RT_SUCCESS(rc))
    550710        {
     711            rc = VERR_INVALID_PARAMETER; /* Play safe. */
     712
    551713            switch (pReply->uType)
    552714            {
     
    554716                {
    555717                    if (cParms >= 6)
    556                     {
    557718                        rc = HGCMSvcGetU64(&paParms[5], &pReply->u.ListOpen.uHandle);
    558                     }
    559                     else
    560                         rc = VERR_INVALID_PARAMETER;
    561719                    break;
    562720                }
     
    565723                {
    566724                    if (cParms >= 6)
    567                     {
    568725                        rc = HGCMSvcGetU64(&paParms[5], &pReply->u.ObjOpen.uHandle);
    569                     }
    570                     else
    571                         rc = VERR_INVALID_PARAMETER;
    572726                    break;
    573727                }
    574728
     729                case VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_OBJ_CLOSE:
     730                {
     731                    if (cParms >= 6)
     732                        rc = HGCMSvcGetU64(&paParms[5], &pReply->u.ObjClose.uHandle);
     733                    break;
     734                }
     735
    575736                default:
     737                    rc = VERR_NOT_SUPPORTED;
    576738                    break;
    577739            }
     
    9031065
    9041066        rc = VINF_SUCCESS;
     1067    }
     1068    else
     1069        rc = VERR_INVALID_PARAMETER;
     1070
     1071    LogFlowFuncLeaveRC(rc);
     1072    return rc;
     1073}
     1074
     1075/**
     1076 * Gets an URI object data chunk from HGCM service parameters.
     1077 *
     1078 * @returns VBox status code.
     1079 * @param   cParms              Number of HGCM parameters supplied in \a paParms.
     1080 * @param   paParms             Array of HGCM parameters.
     1081 * @param   pDataChunk          Where to store the object data chunk data.
     1082 */
     1083static int vboxSvcClipboardURIGetObjDataChunk(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDOBJDATACHUNK pDataChunk)
     1084{
     1085    AssertPtrReturn(paParms,    VERR_INVALID_PARAMETER);
     1086    AssertPtrReturn(pDataChunk, VERR_INVALID_PARAMETER);
     1087
     1088    int rc;
     1089
     1090    if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_WRITE)
     1091    {
     1092        rc = HGCMSvcGetU64(&paParms[1], &pDataChunk->uHandle);
     1093        if (RT_SUCCESS(rc))
     1094        {
     1095            uint32_t cbData;
     1096            rc = HGCMSvcGetU32(&paParms[2], &cbData);
     1097            if (RT_SUCCESS(rc))
     1098            {
     1099                rc = HGCMSvcGetPv(&paParms[3], &pDataChunk->pvData, &pDataChunk->cbData);
     1100                AssertReturn(cbData == pDataChunk->cbData, VERR_INVALID_PARAMETER);
     1101
     1102                /** @todo Implement checksum handling. */
     1103            }
     1104        }
    9051105    }
    9061106    else
     
    12521452                    rc = SharedClipboardURITransferPayloadAlloc(uEvent, pvData, cbData, &pPayload);
    12531453                    if (RT_SUCCESS(rc))
     1454                    {
    12541455                        rc = SharedClipboardURITransferEventSignal(pTransfer, uEvent, pPayload);
     1456                        if (RT_FAILURE(rc))
     1457                            SharedClipboardURITransferPayloadFree(pPayload);
     1458                    }
    12551459                }
    12561460            }
     
    12971501                    rc = SharedClipboardURITransferPayloadAlloc(uEvent, pvData, cbData, &pPayload);
    12981502                    if (RT_SUCCESS(rc))
     1503                    {
    12991504                        rc = SharedClipboardURITransferEventSignal(pTransfer, uEvent, pPayload);
     1505                        if (RT_FAILURE(rc))
     1506                            SharedClipboardURITransferPayloadFree(pPayload);
     1507                    }
    13001508                }
    13011509            }
     
    13731581                        rc = SharedClipboardURITransferPayloadAlloc(uEvent, pvData, cbData, &pPayload);
    13741582                        if (RT_SUCCESS(rc))
     1583                        {
    13751584                            rc = SharedClipboardURITransferEventSignal(pTransfer, uEvent, pPayload);
     1585                            if (RT_FAILURE(rc))
     1586                                SharedClipboardURITransferPayloadFree(pPayload);
     1587                        }
    13761588                    }
    13771589                }
     
    14171629                        rc = SharedClipboardURITransferPayloadAlloc(uEvent, pvData, cbData, &pPayload);
    14181630                        if (RT_SUCCESS(rc))
     1631                        {
    14191632                            rc = SharedClipboardURITransferEventSignal(pTransfer, uEvent, pPayload);
     1633                            if (RT_FAILURE(rc))
     1634                                SharedClipboardURITransferPayloadFree(pPayload);
     1635                        }
    14201636                    }
    14211637                }
    14221638            }
     1639            break;
     1640        }
     1641
     1642    #if 0
     1643        case VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_OPEN:
     1644        {
     1645            break;
     1646        }
     1647
     1648        case VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_CLOSE:
     1649        {
     1650            break;
     1651        }
     1652
     1653        case VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_READ:
     1654        {
     1655            break;
     1656        }
     1657    #endif
     1658
     1659        case VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_WRITE:
     1660        {
     1661            VBOXCLIPBOARDOBJDATACHUNK dataChunk;
     1662            rc = vboxSvcClipboardURIGetObjDataChunk(cParms, paParms, &dataChunk);
     1663            if (RT_SUCCESS(rc))
     1664            {
     1665                void    *pvData = SharedClipboardURIObjectDataChunkDup(&dataChunk);
     1666                uint32_t cbData = sizeof(VBOXCLIPBOARDOBJDATACHUNK);
     1667
     1668                uint32_t uCID;
     1669                rc = HGCMSvcGetU32(&paParms[0], &uCID);
     1670                if (RT_SUCCESS(rc))
     1671                {
     1672                    const uint16_t uEvent = VBOX_SHARED_CLIPBOARD_CONTEXTID_GET_EVENT(uCID);
     1673
     1674                    PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload;
     1675                    rc = SharedClipboardURITransferPayloadAlloc(uEvent, pvData, cbData, &pPayload);
     1676                    if (RT_SUCCESS(rc))
     1677                    {
     1678                        rc = SharedClipboardURITransferEventSignal(pTransfer, uEvent, pPayload);
     1679                        if (RT_FAILURE(rc))
     1680                            SharedClipboardURITransferPayloadFree(pPayload);
     1681                    }
     1682                }
     1683            }
     1684
    14231685            break;
    14241686        }
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp

    r80283 r80359  
    640640            if (pFirstMsg)
    641641            {
    642                 LogFlowFunc(("[Client %RU32] Current host message is %RU32 (cParms=%RU32)\n",
    643                              pClient->uClientID, pFirstMsg->m_uMsg, pFirstMsg->m_cParms));
     642                LogFlowFunc(("[Client %RU32] Current host message is %RU32 (%s), cParms=%RU32\n",
     643                             pClient->uClientID, pFirstMsg->m_uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->m_uMsg),
     644                             pFirstMsg->m_cParms));
    644645
    645646                if (pClient->Pending.uType == VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_WAIT)
Note: See TracChangeset for help on using the changeset viewer.

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