VirtualBox

Changeset 80845 in vbox


Ignore:
Timestamp:
Sep 17, 2019 9:05:21 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
133415
Message:

Shared Clipboard/URI: More code for transfer channel handling.

Location:
trunk
Files:
17 edited

Legend:

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

    r80663 r80845  
    4343#include <VBox/GuestHost/SharedClipboard.h>
    4444
     45
     46/** @name Shared Clipboard transfer definitions.
     47 *  @{
     48 */
     49
     50/** No status set. */
     51#define SHCLURITRANSFERSTATUS_NONE           0
     52/** The transfer has been announced but is not running yet. */
     53#define SHCLURITRANSFERSTATUS_READY          1
     54/** The transfer is active and running. */
     55#define SHCLURITRANSFERSTATUS_STARTED        2
     56/** The transfer has been stopped. */
     57#define SHCLURITRANSFERSTATUS_STOPPED        3
     58/** The transfer has been canceled. */
     59#define SHCLURITRANSFERSTATUS_CANCELED       4
     60/** The transfer has been killed. */
     61#define SHCLURITRANSFERSTATUS_KILLED         5
     62/** The transfer ran into an unrecoverable error. */
     63#define SHCLURITRANSFERSTATUS_ERROR          6
     64
     65/** Defines a transfer status. */
     66typedef uint32_t SHCLURITRANSFERSTATUS;
     67
     68/** @} */
     69
    4570/** @name Shared Clipboard handles.
    4671 *  @{
     
    357382    union
    358383    {
     384        struct
     385        {
     386            SHCLURITRANSFERSTATUS uStatus;
     387        } TransferStatus;
    359388        struct
    360389        {
     
    657686    /** The usual 32-bit hack. */
    658687    SHCLURITRANSFERDIR_32BIT_HACK = 0x7fffffff
    659 } SHCLURITRANSFERDIR;
     688} SHCLURITRANSFERDIR, *PSHCLURITRANSFERDIR;
    660689
    661690struct _SHCLURITRANSFER;
     
    673702typedef struct _SHCLURITRANSFEROBJSTATE
    674703{
    675     uint64_t                    cbProcessed;
     704    /** How many bytes were processed (read / write) so far. */
     705    uint64_t cbProcessed;
    676706} SHCLURITRANSFEROBJSTATE, *PSHCLURITRANSFEROBJSTATE;
    677707
     
    679709{
    680710    SHCLOBJHANDLE           uHandle;
    681     char                              *pszPathAbs;
     711    char                   *pszPathAbs;
    682712    SHCLFSOBJINFO           objInfo;
    683713    SHCLSOURCE              enmSource;
     
    685715} SHCLURITRANSFEROBJ, *PSHCLURITRANSFEROBJ;
    686716
    687 /** No status set. */
    688 #define SHCLURITRANSFERSTATUS_NONE           0
    689 /** The transfer has been announced but is not running yet. */
    690 #define SHCLURITRANSFERSTATUS_READY          1
    691 /** The transfer is active and running. */
    692 #define SHCLURITRANSFERSTATUS_RUNNING        2
    693 /** The transfer has been completed. */
    694 #define SHCLURITRANSFERSTATUS_COMPLETED      3
    695 /** The transfer has been canceled. */
    696 #define SHCLURITRANSFERSTATUS_CANCELED       4
    697 /** The transfer ran into an unrecoverable error. */
    698 #define SHCLURITRANSFERSTATUS_ERROR          5
    699 
    700 /** Defines a transfer status. */
    701 typedef uint32_t SHCLURITRANSFERSTATUS;
     717/** Defines a transfer ID. */
     718typedef uint16_t SHCLURITRANSFERID;
    702719
    703720/**
     
    725742{
    726743    /** The list node. */
    727     RTLISTNODE                    Node;
     744    RTLISTNODE      Node;
    728745    /** The list's handle. */
    729     SHCLLISTHANDLE     hList;
     746    SHCLLISTHANDLE  hList;
    730747    /** Type of list handle. */
    731     SHCLURIOBJTYPE     enmType;
     748    SHCLURIOBJTYPE  enmType;
    732749    /** Absolute local path of the list object. */
    733     char                         *pszPathLocalAbs;
     750    char           *pszPathLocalAbs;
    734751    union
    735752    {
     
    753770{
    754771    /** The list node. */
    755     RTLISTNODE                Node;
     772    RTLISTNODE     Node;
    756773    /** The object's handle. */
    757774    SHCLOBJHANDLE  hObj;
     
    759776    SHCLURIOBJTYPE enmType;
    760777    /** Absolute local path of the object. */
    761     char                     *pszPathLocalAbs;
     778    char          *pszPathLocalAbs;
    762779    union
    763780    {
     
    792809{
    793810    /** The transfer's (local) ID. */
    794     uint16_t                            uID;
     811    SHCLURITRANSFERID     uID;
    795812    /** The transfer's current status. */
    796     SHCLURITRANSFERSTATUS    enmStatus;
     813    SHCLURITRANSFERSTATUS enmStatus;
    797814    /** The transfer's direction. */
    798     SHCLURITRANSFERDIR       enmDir;
     815    SHCLURITRANSFERDIR    enmDir;
    799816    /** The transfer's source. */
    800     SHCLSOURCE               enmSource;
     817    SHCLSOURCE            enmSource;
    801818} SHCLURITRANSFERSTATE, *PSHCLURITRANSFERSTATE;
    802819
     
    879896    SHCLPROVIDERINTERFACE  Interface;
    880897    /** Provider callback data. */
    881     void                             *pvUser;
     898    void                  *pvUser;
    882899} SHCLPROVIDERCREATIONCTX, *PSHCLPROVIDERCREATIONCTX;
    883900
     
    893910    PSHCLURITRANSFER pTransfer;
    894911    /** Saved user pointer. */
    895     void                       *pvUser;
     912    void            *pvUser;
    896913} SHCLURITRANSFERCALLBACKDATA, *PSHCLURITRANSFERCALLBACKDATA;
    897914
     
    963980{
    964981    /** The node member for using this struct in a RTList. */
    965     RTLISTNODE                          Node;
     982    RTLISTNODE               Node;
    966983    /** Critical section for serializing access. */
    967     RTCRITSECT                          CritSect;
     984    RTCRITSECT               CritSect;
    968985    /** The transfer's state (for SSM, later). */
    969986    SHCLURITRANSFERSTATE     State;
    970987    /** Timeout (in ms) for waiting of events. Default is 30s. */
    971     RTMSINTERVAL                        uTimeoutMs;
     988    RTMSINTERVAL             uTimeoutMs;
    972989    /** Absolute path to root entries. */
    973     char                               *pszPathRootAbs;
     990    char                    *pszPathRootAbs;
    974991    /** Maximum data chunk size (in bytes) to transfer. Default is 64K. */
    975     uint32_t                            cbMaxChunkSize;
     992    uint32_t                 cbMaxChunkSize;
    976993    /** The transfer's own event source. */
    977994    SHCLEVENTSOURCE          Events;
     
    979996    SHCLLISTHANDLE           uListHandleNext;
    980997    /** List of all list handles elated to this transfer. */
    981     RTLISTANCHOR                        lstList;
     998    RTLISTANCHOR             lstList;
    982999    /** Number of root entries in list. */
    983     uint64_t                            cRoots;
     1000    uint64_t                 cRoots;
    9841001    /** List of root entries of this transfer. */
    985     RTLISTANCHOR                        lstRoots;
     1002    RTLISTANCHOR             lstRoots;
    9861003    /** Next upcoming object handle. */
    9871004    SHCLOBJHANDLE            uObjHandleNext;
    9881005    /** Map of all objects handles related to this transfer. */
    989     RTLISTANCHOR                        lstObj;
     1006    RTLISTANCHOR             lstObj;
    9901007    /** The transfer's own (local) area, if any (can be NULL if not needed).
    9911008     *  The area itself has a clipboard area ID assigned.
    9921009     *  On the host this area ID gets shared (maintained / locked) across all VMs via VBoxSVC. */
    993     SharedClipboardArea                *pArea;
     1010    SharedClipboardArea     *pArea;
     1011    /** The transfer's own provider context. */
    9941012    SHCLPROVIDERCTX          ProviderCtx;
    9951013    /** The transfer's provider interface. */
     
    9981016    SHCLURITRANSFERCALLBACKS Callbacks;
    9991017    /** Opaque pointer to implementation-specific parameters. */
    1000     void                               *pvUser;
     1018    void                    *pvUser;
    10011019    /** Size (in bytes) of implementation-specific parameters. */
    1002     size_t                              cbUser;
     1020    size_t                   cbUser;
    10031021    /** Contains thread-related attributes. */
    10041022    SHCLURITRANSFERTHREAD    Thread;
    10051023} SHCLURITRANSFER, *PSHCLURITRANSFER;
     1024
     1025/**
     1026 * Structure for keeping an URI transfer status report.
     1027 */
     1028typedef struct _SHCLURITRANSFERREPORT
     1029{
     1030    /** Actual status to report. */
     1031    SHCLURITRANSFERSTATUS uStatus;
     1032    /** Result code (rc) to report; might be unused / invalid, based on enmStatus. */
     1033    int                   rc;
     1034    /** Reporting flags. Currently unused and must be 0. */
     1035    uint32_t              fFlags;
     1036} SHCLURITRANSFERREPORT, *PSHCLURITRANSFERREPORT;
    10061037
    10071038/**
     
    10141045    /** List of transfers. */
    10151046    RTLISTANCHOR                List;
    1016     /** Number of running (concurrent) transfers.
    1017      *  At the moment we only support only one transfer per client at a time. */
    1018     uint32_t                    cRunning;
    1019     /** Maximum Number of running (concurrent) transfers.
    1020      *  At the moment we only support only one transfer per client at a time. */
    1021     uint32_t                    cMaxRunning;
     1047    /** Transfer ID allocation bitmap; clear bits are free, set bits are busy. */
     1048    uint64_t                    bmTransferIds[VBOX_SHARED_CLIPBOARD_MAX_TRANSFERS / sizeof(uint64_t) / 8];
     1049    /** Number of running (concurrent) transfers. */
     1050    uint16_t                    cRunning;
     1051    /** Maximum Number of running (concurrent) transfers. */
     1052    uint16_t                    cMaxRunning;
    10221053    /** Number of total transfers (in list). */
    1023     uint32_t                    cTransfers;
     1054    uint16_t                    cTransfers;
    10241055} SHCLURICTX, *PSHCLURICTX;
    10251056
     
    10421073void SharedClipboardURIObjectDataChunkFree(PSHCLOBJDATACHUNK pDataChunk);
    10431074
    1044 int SharedClipboardURITransferCreate(SHCLURITRANSFERDIR enmDir, SHCLSOURCE enmSource,
    1045                                      PSHCLURITRANSFER *ppTransfer);
     1075int SharedClipboardURITransferCreate(PSHCLURITRANSFER *ppTransfer);
    10461076int SharedClipboardURITransferDestroy(PSHCLURITRANSFER pTransfer);
    10471077
     1078int SharedClipboardURITransferInit(PSHCLURITRANSFER pTransfer, uint32_t uID, SHCLURITRANSFERDIR enmDir, SHCLSOURCE enmSource);
    10481079int SharedClipboardURITransferOpen(PSHCLURITRANSFER pTransfer);
    10491080int SharedClipboardURITransferClose(PSHCLURITRANSFER pTransfer);
     
    10731104int SharedClipboardURILTransferRootsAsList(PSHCLURITRANSFER pTransfer, PSHCLROOTLIST *ppRootList);
    10741105
     1106SHCLURITRANSFERID SharedClipboardURITransferGetID(PSHCLURITRANSFER pTransfer);
    10751107SHCLSOURCE SharedClipboardURITransferGetSource(PSHCLURITRANSFER pTransfer);
    10761108SHCLURITRANSFERSTATUS SharedClipboardURITransferGetStatus(PSHCLURITRANSFER pTransfer);
     
    10941126void SharedClipboardURICtxTransfersCleanup(PSHCLURICTX pURI);
    10951127bool SharedClipboardURICtxTransfersMaximumReached(PSHCLURICTX pURI);
    1096 int SharedClipboardURICtxTransferAdd(PSHCLURICTX pURI, PSHCLURITRANSFER pTransfer);
    1097 int SharedClipboardURICtxTransferRemove(PSHCLURICTX pURI, PSHCLURITRANSFER pTransfer);
     1128int SharedClipboardURICtxTransferRegister(PSHCLURICTX pURI, PSHCLURITRANSFER pTransfer, uint32_t *pidTransfer);
     1129int SharedClipboardURICtxTransferRegisterByIndex(PSHCLURICTX pURI, PSHCLURITRANSFER pTransfer, uint32_t idTransfer);
     1130int SharedClipboardURICtxTransferUnregister(PSHCLURICTX pURI, uint32_t idTransfer);
    10981131
    10991132void SharedClipboardFsObjFromIPRT(PSHCLFSOBJINFO pDst, PCRTFSOBJINFO pSrc);
     
    11021135bool SharedClipboardMIMENeedsCache(const char *pcszFormat, size_t cchFormatMax);
    11031136
     1137const char *VBoxClipboardTransferStatusToStr(uint32_t uStatus);
     1138
    11041139#endif /* !VBOX_INCLUDED_GuestHost_SharedClipboard_uri_h */
    11051140
  • trunk/include/VBox/GuestHost/SharedClipboard-win.h

    r80664 r80845  
    3030#endif
    3131
     32#include <iprt/critsect.h>
    3233#include <iprt/types.h>
    3334#include <iprt/win/windows.h>
     
    6263
    6364/** Reports clipboard formats. */
    64 #define SHCL_WIN_WM_REPORT_FORMATS    WM_USER
     65#define SHCL_WIN_WM_REPORT_FORMATS          WM_USER
    6566/** Reads data from the clipboard and sends it to the destination. */
    66 #define SHCL_WIN_WM_READ_DATA         WM_USER + 1
     67#define SHCL_WIN_WM_READ_DATA               WM_USER + 1
    6768#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    68 /** Starts a reading transfer from the guest. */
    69 # define SHCL_WIN_WM_URI_START_READ   WM_USER + 2
    70 /** Starts a writing transfer to the guest. */
    71 # define SHCL_WIN_WM_URI_START_WRITE  WM_USER + 3
     69/** Reports a transfer status to the guest. */
     70# define SHCL_WIN_WM_URI_TRANSFER_STATUS    WM_USER + 2
    7271#endif
    7372
     
    105104typedef struct _SHCLWINCTX
    106105{
     106    /** Critical section to serialize access. */
     107    RTCRITSECT         CritSect;
    107108    /** Window handle of our (invisible) clipbaord window. */
    108109    HWND               hWnd;
     
    120121int SharedClipboardWinClose(void);
    121122int SharedClipboardWinClear(void);
     123
     124int SharedClipboardWinCtxInit(PSHCLWINCTX pWinCtx);
     125void SharedClipboardWinCtxDestroy(PSHCLWINCTX pWinCtx);
    122126
    123127int SharedClipboardWinCheckAndInitNewAPI(PSHCLWINAPINEW pAPI);
  • trunk/include/VBox/GuestHost/SharedClipboard.h

    r80662 r80845  
    6868    SHCLFORMAT  uFormat;
    6969    /** Pointer to actual data block. */
    70     void                *pvData;
     70    void       *pvData;
    7171    /** Size (in bytes) of actual data block. */
    72     uint32_t             cbData;
     72    uint32_t    cbData;
    7373} SHCLDATABLOCK, *PSHCLDATABLOCK;
    7474
     
    8181    SHCLFORMAT uFmt;
    8282    /** Read flags; currently unused. */
    83     uint32_t            fFlags;
     83    uint32_t   fFlags;
    8484    /** Maximum data (in byte) can be sent. */
    85     uint32_t            cbSize;
     85    uint32_t   cbSize;
    8686} SHCLDATAREQ, *PSHCLDATAREQ;
    8787
     
    9494    SHCLFORMATS uFormats;
    9595    /** Formats flags. Currently unused. */
    96     uint32_t             fFlags;
     96    uint32_t    fFlags;
    9797} SHCLFORMATDATA, *PSHCLFORMATDATA;
    9898
     
    120120typedef SHCLEVENTID *PSHCLEVENTID;
    121121
    122 /** Maximum number of concurrent Shared Clipboard transfers a VM can have.
    123  *  Number 0 always is reserved for the client itself. */
    124 #define VBOX_SHARED_CLIPBOARD_MAX_TRANSFERS                   UINT16_MAX - 1
    125 /** Maximum number of concurrent event sources. */
    126 #define VBOX_SHARED_CLIPBOARD_MAX_EVENT_SOURCES               UINT16_MAX
    127 /** Maximum number of concurrent events a single event source can have. */
    128 #define VBOX_SHARED_CLIPBOARD_MAX_EVENTS                      UINT16_MAX
     122/** Maximum number of concurrent Shared Clipboard client sessions a VM can have. */
     123#define VBOX_SHARED_CLIPBOARD_MAX_SESSIONS                   32
     124/** Maximum number of concurrent Shared Clipboard transfers a single
     125 *  client can have. */
     126#define VBOX_SHARED_CLIPBOARD_MAX_TRANSFERS                  _2K
     127/** Maximum number of events a single Shared Clipboard transfer can have. */
     128#define VBOX_SHARED_CLIPBOARD_MAX_EVENTS                     _64K
     129
     130/**
     131 * Creates a context ID out of a client ID, a transfer ID and a count.
     132 */
     133#define VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(uSessionID, uTransferID, uEventID) \
     134    (  (uint32_t)((uSessionID)  &   0x1f) << 27 \
     135     | (uint32_t)((uTransferID) &  0x7ff) << 16 \
     136     | (uint32_t)((uEventID)    & 0xffff)       \
     137    )
     138/** Creates a context ID out of a session ID. */
     139#define VBOX__SHARED_CLIPBOARD_CONTEXTID_MAKE_SESSION(uSessionID) \
     140    ((uint32_t)((uSessionID) & 0x1f) << 27)
     141/** Gets the session ID out of a context ID. */
     142#define VBOX_SHARED_CLIPBOARD_CONTEXTID_GET_SESSION(uContextID) \
     143    (((uContextID) >> 27) & 0x1f)
     144/** Gets the transfer ID out of a context ID. */
     145#define VBO_SHARED_CLIPBOARD_CONTEXTID_GET_TRANSFER(uContextID) \
     146    (((uContextID) >> 16) & 0x7ff)
     147/** Gets the transfer event out of a context ID. */
     148#define VBOX_SHARED_CLIPBOARD_CONTEXTID_GET_EVENT(uContextID) \
     149    ((uContextID) & 0xffff)
    129150
    130151/**
     
    134155{
    135156    /** List node. */
    136     RTLISTNODE                   Node;
     157    RTLISTNODE        Node;
    137158    /** The event's ID, for self-reference. */
    138     SHCLEVENTID         uID;
     159    SHCLEVENTID       uID;
    139160    /** Event semaphore for signalling the event. */
    140     RTSEMEVENT                   hEventSem;
     161    RTSEMEVENT        hEventSem;
    141162    /** Payload to this event. Optional and can be NULL. */
    142163    PSHCLEVENTPAYLOAD pPayload;
     
    156177    SHCLEVENTID       uEventIDNext;
    157178    /** List of events (PSHCLEVENT). */
    158     RTLISTANCHOR               lstEvents;
     179    RTLISTANCHOR      lstEvents;
    159180} SHCLEVENTSOURCE, *PSHCLEVENTSOURCE;
    160181
  • trunk/include/VBox/HostServices/VBoxClipboardSvc.h

    r80662 r80845  
    109109#define VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS_REPORT               3
    110110
    111 /** Initiates a new transfer (read / write) on the guest side. */
    112 #define VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_TRANSFER_START           50
     111/** Sends a transfer status to the guest side. */
     112#define VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_TRANSFER_STATUS          50
    113113/** Reads the root list header from the guest. */
    114114#define VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOT_LIST_HDR_READ       51
     
    226226#define VBOX_SHARED_CLIPBOARD_MAX_CHUNK_SIZE                  _64K
    227227
    228 /**
    229  * Creates a context ID out of a source ID and and event ID.
    230  */
    231 #define VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(uSourceID, uEventID) \
    232     RT_MAKE_U32(uEventID, uSourceID)
    233 /** Gets the source ID out of a context ID. */
    234 #define VBOX_SHARED_CLIPBOARD_CONTEXTID_GET_SOURCE(uContextID) \
    235     RT_HI_U16(uContextID)
    236 /** Gets the event ID out of a context ID. */
    237 #define VBOX_SHARED_CLIPBOARD_CONTEXTID_GET_EVENT(uContextID) \
    238     RT_LO_U16(uContextID)
    239 
    240228/*
    241229 * HGCM parameter structures.
     
    354342#define VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA 4
    355343
    356 typedef struct _VBoxClipboardTransferReport
     344/**
     345 * Reports a transfer status.
     346 */
     347typedef struct _VBoxClipboardTransferStatusMsg
    357348{
    358349    VBGLIOCHGCMCALL hdr;
     
    360351    /** uint32_t, out: Context ID. */
    361352    HGCMFunctionParameter uContext;
    362     /** uint32_t, out: Status to report. */
    363     HGCMFunctionParameter uStatus;
    364 } VBoxClipboardTransferReport;
    365 
    366 #define VBOX_SHARED_CLIPBOARD_CPARMS_TRANSFER_REPORT 2
     353    /** uint32_t, out: Direction of transfer; of type SHCLURITRANSFERDIR_. */
     354    HGCMFunctionParameter enmDir;
     355    /** uint32_t, out: Status to report; of type SHCLURITRANSFERSTATUS_. */
     356    HGCMFunctionParameter enmStatus;
     357    /** uint32_t, out: Result code to report. Optional. */
     358    HGCMFunctionParameter rc;
     359    /** uint32_t, out: Reporting flags. Currently unused and must be 0. */
     360    HGCMFunctionParameter fFlags;
     361} VBoxClipboardTransferStatusMsg;
     362
     363#define VBOX_SHARED_CLIPBOARD_CPARMS_TRANSFER_STATUS 5
    367364
    368365/**
     
    401398
    402399/**
    403  * Transfert status message.
     400 * Status messag for lists and objects.
    404401 */
    405402typedef struct _VBoxClipboardStatusMsg
     
    419416#define VBOX_SHARED_CLIPBOARD_CPARMS_STATUS 4
    420417
     418/** Invalid message type, do not use. */
    421419#define VBOX_SHCL_REPLYMSGTYPE_INVALID           0
    422 #define VBOX_SHCL_REPLYMSGTYPE_LIST_OPEN         1
    423 #define VBOX_SHCL_REPLYMSGTYPE_LIST_CLOSE        2
    424 #define VBOX_SHCL_REPLYMSGTYPE_OBJ_OPEN          3
    425 #define VBOX_SHCL_REPLYMSGTYPE_OBJ_CLOSE         4
     420/** Replies a transfer status. */
     421#define VBOX_SHCL_REPLYMSGTYPE_TRANSFER_STATUS   1
     422/** Replies a list open status. */
     423#define VBOX_SHCL_REPLYMSGTYPE_LIST_OPEN         2
     424/** Replies a list close status. */
     425#define VBOX_SHCL_REPLYMSGTYPE_LIST_CLOSE        3
     426/** Replies an object open status. */
     427#define VBOX_SHCL_REPLYMSGTYPE_OBJ_OPEN          4
     428/** Replies an object close status. */
     429#define VBOX_SHCL_REPLYMSGTYPE_OBJ_CLOSE         5
    426430
    427431/**
     
    444448    union
    445449    {
     450        struct
     451        {
     452            HGCMFunctionParameter enmStatus;
     453        } TransferStatus;
    446454        struct
    447455        {
     
    459467} VBoxClipboardReplyMsg;
    460468
     469/** Minimum parameters (HGCM function parameters minus the union) a reply message must have. */
    461470#define VBOX_SHARED_CLIPBOARD_CPARMS_REPLY_MIN 5
    462471
  • trunk/include/VBox/VBoxGuestLib.h

    r80662 r80845  
    591591
    592592    /** IN: HGCM client ID to use for communication. */
    593     uint32_t uClientID;
     593    uint32_t            uClientID;
    594594    /** IN/OUT: Context ID to retrieve or to use. */
    595     uint32_t uContextID;
     595    uint32_t            uContextID;
    596596    /** IN: Protocol version to use. */
    597     uint32_t uProtocolVer;
     597    uint32_t            uProtocolVer;
    598598    /** IN: Protocol flags. Currently unused. */
    599     uint32_t uProtocolFlags;
     599    uint32_t            uProtocolFlags;
    600600    /** IN: Maximum chunk size (in bytes). */
    601     uint32_t cbChunkSize;
     601    uint32_t            cbChunkSize;
    602602    /** OUT: Number of parameters retrieved. */
    603     uint32_t uNumParms;
     603    uint32_t            uNumParms;
    604604} VBGLR3SHCLCMDCTX, *PVBGLR3SHCLCMDCTX;
    605605
     
    613613    VBGLR3CLIPBOARDEVENTTYPE_READ_DATA,
    614614    VBGLR3CLIPBOARDEVENTTYPE_QUIT,
    615     VBGLR3CLIPBOARDEVENTTYPE_URI_LIST_HDR_READ,
    616     VBGLR3CLIPBOARDEVENTTYPE_URI_LIST_HDR_WRITE,
    617     VBGLR3CLIPBOARDEVENTTYPE_URI_LIST_ENTRY_READ,
    618     VBGLR3CLIPBOARDEVENTTYPE_URI_LIST_ENTRY_WRITE,
    619     VBGLR3CLIPBOARDEVENTTYPE_URI_OBJ_OPEN,
    620     VBGLR3CLIPBOARDEVENTTYPE_URI_OBJ_CLOSE,
    621     VBGLR3CLIPBOARDEVENTTYPE_URI_OBJ_READ,
    622     VBGLR3CLIPBOARDEVENTTYPE_URI_OBJ_WRITE,
    623     VBGLR3CLIPBOARDEVENTTYPE_URI_CANCEL,
    624     VBGLR3CLIPBOARDEVENTTYPE_URI_ERROR,
     615#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     616    /** Reports a transfer status to the guest. */
     617    VBGLR3CLIPBOARDEVENTTYPE_URI_TRANSFER_STATUS,
     618#endif
    625619    /** Blow the type up to 32-bit. */
    626620    VBGLR3CLIPBOARDEVENTTYPE_32BIT_HACK = 0x7fffffff
     
    639633    {
    640634        /** Reports available formats from the host. */
    641         SHCLFORMATDATA ReportFormats;
    642         /** Requests data to be read from the guest. */
    643         SHCLDATAREQ ReadData;
     635        SHCLFORMATDATA       ReportedFormats;
     636        /** Reports that data needs to be read from the guest. */
     637        SHCLDATAREQ          ReadData;
     638#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     639        /** Reports a transfer status to the guest. */
     640        struct
     641        {
     642            /** ID of the trnasfer. */
     643            SHCLURITRANSFERID     uID;
     644            /** Transfer direction. */
     645            SHCLURITRANSFERDIR    enmDir;
     646            /** Additional reproting information. */
     647            SHCLURITRANSFERREPORT Report;
     648        } TransferStatus;
     649#endif
    644650    } u;
    645651} VBGLR3CLIPBOARDEVENT, *PVBGLR3CLIPBOARDEVENT;
     
    657663VBGLR3DECL(int)     VbglR3ClipboardConnectEx(PVBGLR3SHCLCMDCTX pCtx);
    658664VBGLR3DECL(int)     VbglR3ClipboardDisconnectEx(PVBGLR3SHCLCMDCTX pCtx);
    659 VBGLR3DECL(int)     VbglR3ClipboardEventGetNext(PVBGLR3SHCLCMDCTX pCtx, PVBGLR3CLIPBOARDEVENT *ppEvent);
     665
     666VBGLR3DECL(int)     VbglR3ClipboardMsgPeekWait(PVBGLR3SHCLCMDCTX pCtx, uint32_t *pidMsg, uint32_t *pcParameters, uint64_t *pidRestoreCheck);
     667VBGLR3DECL(int)     VbglR3ClipboardEventGetNext(uint32_t idMsg, uint32_t cParms, PVBGLR3SHCLCMDCTX pCtx, PVBGLR3CLIPBOARDEVENT pEvent);
    660668VBGLR3DECL(void)    VbglR3ClipboardEventFree(PVBGLR3CLIPBOARDEVENT pEvent);
    661669
     
    663671
    664672#  ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    665 VBGLR3DECL(int)     VbglR3ClipboardTransferEvent(PVBGLR3SHCLCMDCTX pCtx, uint32_t uMsg, uint32_t cParms,
    666                                                  PSHCLURITRANSFER pTransfer);
    667 VBGLR3DECL(int)     VbglR3ClipboardTransferSendStatus(PVBGLR3SHCLCMDCTX pCtx, PSHCLURITRANSFER pTransfer,
    668                                                       SHCLURITRANSFERSTATUS uStatus);
     673VBGLR3DECL(int)     VbglR3ClipboardEventGetNextEx(uint32_t idMsg, uint32_t cParms, PVBGLR3SHCLCMDCTX pCtx, PSHCLURICTX pTransferCtx, PVBGLR3CLIPBOARDEVENT pEvent);
     674
     675VBGLR3DECL(int)     VbglR3ClipboardTransferStatusReply(PVBGLR3SHCLCMDCTX pCtx, PSHCLURITRANSFER pTransfer, SHCLURITRANSFERSTATUS uStatus);
    669676
    670677VBGLR3DECL(int)     VbglR3ClipboardRootListRead(PVBGLR3SHCLCMDCTX pCtx, PSHCLROOTLIST *ppRootList);
  • trunk/include/VBox/err.h

    r80641 r80845  
    29422942/** A Shared Clipboard objects handle is invalid. */
    29432943#define VERR_SHCLPB_OBJ_HANDLE_INVALID              (-7103)
     2944/** A Shared Clipboard transfer ID is invalid. */
     2945#define VERR_SHCLPB_TRANSFER_ID_NOT_FOUND           (-7104)
    29442946/** @} */
    29452947/* SED-END */
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp

    r80667 r80845  
    5555{
    5656    /** Pointer to the VBoxClient service environment. */
    57     const VBOXSERVICEENV    *pEnv;
     57    const VBOXSERVICEENV *pEnv;
    5858    /** Command context. */
    59     VBGLR3SHCLCMDCTX         CmdCtx;
     59    VBGLR3SHCLCMDCTX      CmdCtx;
    6060    /** Windows-specific context data. */
    61     SHCLWINCTX      Win;
    62 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    63     /** URI transfer data. */
    64     SHCLURICTX    URI;
     61    SHCLWINCTX            Win;
     62#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     63    /** Associated transfer data. */
     64    SHCLURICTX            URI;
    6565#endif
    6666} SHCLCONTEXT, *PSHCLCONTEXT;
     
    6969typedef struct _SHCLURIREADTHREADCTX
    7070{
    71     PSHCLCONTEXT       pClipboardCtx;
     71    PSHCLCONTEXT     pClipboardCtx;
    7272    PSHCLURITRANSFER pTransfer;
    7373} SHCLURIREADTHREADCTX, *PSHCLURIREADTHREADCTX;
     
    7575typedef struct _SHCLURIWRITETHREADCTX
    7676{
    77     PSHCLCONTEXT       pClipboardCtx;
     77    PSHCLCONTEXT     pClipboardCtx;
    7878    PSHCLURITRANSFER pTransfer;
    7979} SHCLURIWRITETHREADCTX, *PSHCLURIWRITETHREADCTX;
     
    100100
    101101#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     102#if 0
    102103static DECLCALLBACK(int) vboxClipboardURIWriteThread(RTTHREAD ThreadSelf, void *pvUser)
    103104{
     
    157158    return rc;
    158159}
    159 
    160 static DECLCALLBACK(void) vboxClipboardURITransferCompleteCallback(PSHCLURITRANSFERCALLBACKDATA pData, int rc)
    161 {
    162     RT_NOREF(rc);
    163 
    164     LogFlowFunc(("pData=%p, rc=%Rrc\n", pData, rc));
    165 
    166     LogRel2(("Shared Clipboard: Transfer to destination complete\n"));
    167 
     160#endif
     161
     162static void vboxClipboardURITransferCallbackCleanup(PSHCLURITRANSFERCALLBACKDATA pData)
     163{
    168164    PSHCLURICTX pCtx = (PSHCLURICTX)pData->pvUser;
    169165    AssertPtr(pCtx);
     
    178174    }
    179175
    180     int rc2 = SharedClipboardURICtxTransferRemove(pCtx, pTransfer);
     176    int rc2 = SharedClipboardURICtxTransferUnregister(pCtx, pTransfer->State.uID);
    181177    AssertRC(rc2);
     178
     179    SharedClipboardURITransferDestroy(pTransfer);
     180
     181    RTMemFree(pTransfer);
     182    pTransfer = NULL;
     183}
     184
     185static DECLCALLBACK(void) vboxClipboardURITransferCompleteCallback(PSHCLURITRANSFERCALLBACKDATA pData, int rc)
     186{
     187    RT_NOREF(rc);
     188
     189    LogFlowFunc(("pData=%p, rc=%Rrc\n", pData, rc));
     190
     191    LogRel2(("Shared Clipboard: Transfer to destination complete\n"));
     192
     193    vboxClipboardURITransferCallbackCleanup(pData);
    182194}
    183195
     
    190202    LogRel(("Shared Clipboard: Transfer to destination failed with %Rrc\n", rc));
    191203
    192     PSHCLURICTX pCtx = (PSHCLURICTX)pData->pvUser;
    193     AssertPtr(pCtx);
    194 
    195     PSHCLURITRANSFER pTransfer = pData->pTransfer;
    196     AssertPtr(pTransfer);
    197 
    198     if (pTransfer->pvUser) /* SharedClipboardWinURITransferCtx */
    199     {
    200         delete pTransfer->pvUser;
    201         pTransfer->pvUser = NULL;
    202     }
    203 
    204     int rc2 = SharedClipboardURICtxTransferRemove(pCtx, pTransfer);
    205     AssertRC(rc2);
     204    vboxClipboardURITransferCallbackCleanup(pData);
    206205}
    207206
     
    640639       case SHCL_WIN_WM_REPORT_FORMATS:
    641640       {
    642            LogFunc(("VBOX_CLIPBOARD_WM_REPORT_FORMATS\n"));
     641           LogFunc(("SHCL_WIN_WM_REPORT_FORMATS\n"));
    643642
    644643           /* Announce available formats. Do not insert data -- will be inserted in WM_RENDERFORMAT. */
     
    647646           Assert(pEvent->enmType == VBGLR3CLIPBOARDEVENTTYPE_REPORT_FORMATS);
    648647
    649            const SHCLFORMATS fFormats =  pEvent->u.ReportFormats.uFormats;
     648           const SHCLFORMATS fFormats =  pEvent->u.ReportedFormats.uFormats;
    650649
    651650           if (fFormats != VBOX_SHARED_CLIPBOARD_FMT_NONE) /* Could arrive with some older GA versions. */
     
    661660                        LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_URI_LIST\n"));
    662661
    663                         PSHCLURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(&pCtx->URI,
    664                                                                                                  0 /* uIdx */);
     662                        PSHCLURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(&pCtx->URI, 0); /** @todo FIX !!! */
    665663                        if (pTransfer)
    666664                        {
     
    687685           }
    688686
    689            LogFunc(("VBOX_CLIPBOARD_WM_SET_FORMATS: fFormats=0x%x, lastErr=%ld\n", fFormats, GetLastError()));
     687           LogFunc(("SHCL_WIN_WM_REPORT_FORMATS: fFormats=0x%x, lastErr=%ld\n", fFormats, GetLastError()));
    690688           break;
    691689       }
     
    702700           HANDLE hClip = NULL;
    703701
    704            LogFlowFunc(("VBOX_CLIPBOARD_WM_READ_DATA: uFormat=0x%x\n", uFormat));
     702           LogFlowFunc(("SHCL_WIN_WM_READ_DATA: uFormat=0x%x\n", uFormat));
    705703
    706704           int rc = SharedClipboardWinOpen(hwnd);
     
    781779                   {
    782780                       PSHCLURITRANSFER pTransfer;
    783                        rc = SharedClipboardURITransferCreate(SHCLURITRANSFERDIR_WRITE,
    784                                                              SHCLSOURCE_LOCAL,
    785                                                              &pTransfer);
     781                       rc = SharedClipboardURITransferCreate(&pTransfer);
     782                       if (RT_SUCCESS(rc))
     783                           rc = SharedClipboardURITransferInit(pTransfer, 0 /* uID */,
     784                                                               SHCLURITRANSFERDIR_WRITE, SHCLSOURCE_LOCAL);
    786785                       if (RT_SUCCESS(rc))
    787786                       {
    788                            rc = SharedClipboardURICtxTransferAdd(&pCtx->URI, pTransfer);
    789                            if (RT_SUCCESS(rc))
     787                           /* The data data in CF_HDROP format, as the files are locally present and don't need to be
     788                            * presented as a IDataObject or IStream. */
     789                           HANDLE hClip = hClip = GetClipboardData(CF_HDROP);
     790                           if (hClip)
    790791                           {
    791                                /* The data data in CF_HDROP format, as the files are locally present and don't need to be
    792                                 * presented as a IDataObject or IStream. */
    793                                HANDLE hClip = hClip = GetClipboardData(CF_HDROP);
    794                                if (hClip)
     792                               HDROP hDrop = (HDROP)GlobalLock(hClip);
     793                               if (hDrop)
    795794                               {
    796                                    HDROP hDrop = (HDROP)GlobalLock(hClip);
    797                                    if (hDrop)
     795                                   char    *papszList;
     796                                   uint32_t cbList;
     797                                   rc = SharedClipboardWinDropFilesToStringList((DROPFILES *)hDrop, &papszList, &cbList);
     798
     799                                   GlobalUnlock(hClip);
     800
     801                                   if (RT_SUCCESS(rc))
    798802                                   {
    799                                        char    *papszList;
    800                                        uint32_t cbList;
    801                                        rc = SharedClipboardWinDropFilesToStringList((DROPFILES *)hDrop, &papszList, &cbList);
    802 
    803                                        GlobalUnlock(hClip);
    804 
     803                                       rc = SharedClipboardURILTransferSetRoots(pTransfer,
     804                                                                                papszList, cbList + 1 /* Include termination */);
    805805                                       if (RT_SUCCESS(rc))
    806806                                       {
    807                                            rc = SharedClipboardURILTransferSetRoots(pTransfer,
    808                                                                                     papszList, cbList + 1 /* Include termination */);
    809                                            if (RT_SUCCESS(rc))
     807                                           PSHCLURIWRITETHREADCTX pThreadCtx
     808                                               = (PSHCLURIWRITETHREADCTX)RTMemAllocZ(sizeof(SHCLURIWRITETHREADCTX));
     809                                           if (pThreadCtx)
    810810                                           {
    811                                                PSHCLURIWRITETHREADCTX pThreadCtx
    812                                                    = (PSHCLURIWRITETHREADCTX)RTMemAllocZ(sizeof(SHCLURIWRITETHREADCTX));
    813                                                if (pThreadCtx)
     811                                               pThreadCtx->pClipboardCtx = pCtx;
     812                                               pThreadCtx->pTransfer     = pTransfer;
     813
     814                                               rc = SharedClipboardURITransferPrepare(pTransfer);
     815                                               if (RT_SUCCESS(rc))
    814816                                               {
    815                                                    pThreadCtx->pClipboardCtx = pCtx;
    816                                                    pThreadCtx->pTransfer     = pTransfer;
    817 
    818                                                    rc = SharedClipboardURITransferPrepare(pTransfer);
     817                                                   rc = SharedClipboardURICtxTransferRegister(&pCtx->URI, pTransfer,
     818                                                                                              NULL /* puTransferID */);
     819                                            #if 0
    819820                                                   if (RT_SUCCESS(rc))
    820821                                                   {
     
    823824                                                       /* pThreadCtx now is owned by vboxClipboardURIWriteThread(). */
    824825                                                   }
     826                                            #endif
    825827                                               }
    826                                                else
    827                                                    rc = VERR_NO_MEMORY;
    828828                                           }
    829 
    830                                            if (papszList)
    831                                                RTStrFree(papszList);
     829                                           else
     830                                               rc = VERR_NO_MEMORY;
    832831                                       }
     832
     833                                       if (papszList)
     834                                           RTStrFree(papszList);
    833835                                   }
    834                                    else
    835                                    {
    836                                        hClip = NULL;
    837                                    }
     836                               }
     837                               else
     838                               {
     839                                   hClip = NULL;
    838840                               }
    839841                           }
     
    844846
    845847                   if (RT_FAILURE(rc))
    846                        LogFunc(("VBOX_CLIPBOARD_WM_READ_DATA: Failed with rc=%Rrc\n", rc));
    847                }
    848 #endif
     848                       LogFunc(("SHCL_WIN_WM_READ_DATA: Failed with rc=%Rrc\n", rc));
     849               }
     850#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
    849851
    850852               if (hClip == NULL)
    851853               {
    852                    LogFunc(("VBOX_CLIPBOARD_WM_READ_DATA: hClip=NULL, lastError=%ld\n", GetLastError()));
     854                   LogFunc(("SHCL_WIN_WM_READ_DATA: hClip=NULL, lastError=%ld\n", GetLastError()));
    853855
    854856                   /* Requested clipboard format is not available, send empty data. */
     
    863865           break;
    864866       }
     867
     868#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     869       case SHCL_WIN_WM_URI_TRANSFER_STATUS:
     870       {
     871           LogFunc(("SHCL_WIN_WM_URI_TRANSFER_STATUS\n"));
     872
     873           break;
     874       }
     875#endif
    865876
    866877#if 0
     
    942953       }
    943954
    944 #if 1
    945955       /* The host wants to write URI data. */
    946956       case VBOX_CLIPBOARD_WM_URI_START_WRITE:
     
    9971007           break;
    9981008       }
    999 #endif
    1000 #endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
     1009#endif /* 0 */
    10011010
    10021011       case WM_DESTROY:
     
    10971106
    10981107    UnregisterClass(s_szClipWndClassName, pCtx->pEnv->hInstance);
     1108
     1109    SharedClipboardWinCtxDestroy(&pCtx->Win);
    10991110}
    11001111
     
    11241135    {
    11251136        /* Do not use clipboard for remote sessions. */
    1126         LogRel(("Clipboard: Clipboard has been disabled for a remote session\n"));
     1137        LogRel(("Shared Clipboard: Clipboard has been disabled for a remote session\n"));
    11271138        return VERR_NOT_SUPPORTED;
    11281139    }
     
    11361147    if (FAILED(hr))
    11371148    {
    1138         LogRel(("Clipboard: Initializing OLE failed (%Rhrc) -- file transfers unavailable\n"));
     1149        LogRel(("Shared Clipboard: Initializing OLE failed (%Rhrc) -- file transfers unavailable\n"));
    11391150        /* Not critical, the rest of the clipboard might work. */
    11401151    }
    11411152    else
    1142         LogRel(("Clipboard: Initialized OLE\n"));
     1153        LogRel(("Shared Clipboard: Initialized OLE\n"));
    11431154#endif
    11441155
     
    11461157    {
    11471158        /* Check if new Clipboard API is available. */
    1148         /* ignore rc */ SharedClipboardWinCheckAndInitNewAPI(&pCtx->Win.newAPI);
    1149 
    1150         rc = VbglR3ClipboardConnectEx(&pCtx->CmdCtx);
     1159        rc = SharedClipboardWinCtxInit(&pCtx->Win);
     1160        if (RT_SUCCESS(rc))
     1161            rc = VbglR3ClipboardConnectEx(&pCtx->CmdCtx);
    11511162        if (RT_SUCCESS(rc))
    11521163        {
     
    12141225            {
    12151226                pEvent = (PVBGLR3CLIPBOARDEVENT)RTMemAllocZ(sizeof(VBGLR3CLIPBOARDEVENT));
    1216                 if (!pEvent)
    1217                 {
    1218                     rc = VERR_NO_MEMORY;
    1219                     break;
    1220                 }
     1227                AssertPtrBreakStmt(pEvent, rc = VERR_NO_MEMORY);
    12211228
    12221229                switch (uMsg)
     
    12251232                    {
    12261233                        pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_REPORT_FORMATS;
    1227                         pEvent->u.ReportFormats.uFormats = uFormats;
     1234                        pEvent->u.ReportedFormats.uFormats = uFormats;
    12281235                        break;
    12291236                    }
     
    12441251        else /* Protocol >= v1. */
    12451252        {
    1246             rc = VbglR3ClipboardEventGetNext(&pCtx->CmdCtx, &pEvent);
     1253            pEvent = (PVBGLR3CLIPBOARDEVENT)RTMemAllocZ(sizeof(VBGLR3CLIPBOARDEVENT));
     1254            AssertPtrBreakStmt(pEvent, rc = VERR_NO_MEMORY);
     1255
     1256            uint32_t uMsg   = 0;
     1257            uint32_t cParms = 0;
     1258            rc = VbglR3ClipboardMsgPeekWait(&pCtx->CmdCtx, &uMsg, &cParms, NULL /* pidRestoreCheck */);
     1259            if (RT_SUCCESS(rc))
     1260            {
     1261#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     1262                rc = VbglR3ClipboardEventGetNextEx(uMsg, cParms, &pCtx->CmdCtx, &pCtx->URI, pEvent);
     1263#else
     1264                rc = VbglR3ClipboardEventGetNext(uMsg, cParms, &pCtx->CmdCtx, pEvent);
     1265#endif
     1266            }
    12471267        }
    12481268
    12491269        if (RT_FAILURE(rc))
    12501270        {
     1271            VbglR3ClipboardEventFree(pEvent);
     1272            pEvent = NULL;
     1273
    12511274            if (*pfShutdown)
    12521275                break;
     
    12801303                   break;
    12811304               }
    1282 #if 0
    1283                case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_TRANSFER_START:
    1284                {
    1285                    const UINT uMsg = u32Formats == 0 ?
    1286                                      VBOX_CLIPBOARD_WM_URI_START_READ : VBOX_CLIPBOARD_WM_URI_START_WRITE;
    1287 
    1288                    ::PostMessage(pWinCtx->hWnd, uMsg, 0 /* wParm */, 0 /* lParm */);
     1305
     1306#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     1307               case VBGLR3CLIPBOARDEVENTTYPE_URI_TRANSFER_STATUS:
     1308               {
     1309                   ::PostMessage(pWinCtx->hWnd, SHCL_WIN_WM_URI_TRANSFER_STATUS,
     1310                                 0 /* wParm */, (LPARAM)pEvent /* lParm */);
    12891311                   break;
    12901312               }
     
    12931315               {
    12941316                   /* The host is terminating. */
    1295                    LogRel(("Clipboard: Terminating ...\n"));
     1317                   LogRel(("Shared Clipboard: Terminating ...\n"));
    12961318                   ASMAtomicXchgBool(pfShutdown, true);
    12971319                   break;
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp

    r80662 r80845  
    155155
    156156
    157 VBGLR3DECL(int) VbglR3ClipboardFormatsWriteRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLFORMATDATA pFormats)
     157VBGLR3DECL(int) VbglR3ClipboardFormatsReportRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLFORMATDATA pFormats)
    158158{
    159159    AssertPtrReturn(pCtx,     VERR_INVALID_POINTER);
     
    313313 * @note    Restore check is only performed optimally with a 6.0 host.
    314314 */
    315 static int vbglR3ClipboardMsgPeekWait(PVBGLR3SHCLCMDCTX pCtx, uint32_t *pidMsg, uint32_t *pcParameters, uint64_t *pidRestoreCheck)
     315int VbglR3ClipboardMsgPeekWait(PVBGLR3SHCLCMDCTX pCtx, uint32_t *pidMsg, uint32_t *pcParameters, uint64_t *pidRestoreCheck)
    316316{
    317317    AssertPtrReturn(pidMsg, VERR_INVALID_POINTER);
     
    365365
    366366#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    367 VBGLR3DECL(int) VbglR3ClipboardTransferSendStatus(PVBGLR3SHCLCMDCTX pCtx,
    368                                                   PSHCLURITRANSFER pTransfer, SHCLURITRANSFERSTATUS uStatus)
    369 {
    370     AssertPtrReturn(pCtx,      VERR_INVALID_POINTER);
    371     AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
    372 
    373     VBoxClipboardStatusMsg Msg;
    374     RT_ZERO(Msg);
    375 
    376     VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID,
    377                        VBOX_SHARED_CLIPBOARD_GUEST_FN_STATUS, VBOX_SHARED_CLIPBOARD_CPARMS_STATUS);
    378 
    379     Msg.uContext.SetUInt32(VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pTransfer->State.uID, 0 /* Event, ignored */));
    380     Msg.uStatus.SetUInt32(uStatus);
    381     Msg.cbPayload.SetUInt32(0);
    382     Msg.pvPayload.SetPtr(NULL, 0);
    383 
    384     int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
    385 
    386     LogFlowFuncLeaveRC(rc);
    387     return rc;
    388 }
    389 
    390367static int vbglR3ClipboardRootListHdrRead(PVBGLR3SHCLCMDCTX pCtx, PSHCLROOTLISTHDR pRootListHdr)
    391368{
     
    501478}
    502479
     480VBGLR3DECL(int) VbglR3ClipboarTransferStatusRecv(PVBGLR3SHCLCMDCTX pCtx,
     481                                                 PSHCLURITRANSFERDIR pEnmDir, PSHCLURITRANSFERREPORT pReport)
     482{
     483    AssertPtrReturn(pCtx,    VERR_INVALID_POINTER);
     484    AssertPtrReturn(pReport, VERR_INVALID_POINTER);
     485    AssertPtrReturn(pEnmDir, VERR_INVALID_POINTER);
     486
     487    VBoxClipboardTransferStatusMsg Msg;
     488    RT_ZERO(Msg);
     489
     490    VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID,
     491                       VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_GET, VBOX_SHARED_CLIPBOARD_CPARMS_TRANSFER_STATUS);
     492
     493    Msg.uContext.SetUInt32(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_TRANSFER_STATUS);
     494    Msg.enmDir.SetUInt32(0);
     495    Msg.enmStatus.SetUInt32(0);
     496    Msg.rc.SetUInt32(0);
     497    Msg.fFlags.SetUInt32(0);
     498
     499    int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     500    if (RT_SUCCESS(rc))
     501    {
     502        rc = Msg.uContext.GetUInt32(&pCtx->uContextID); AssertRC(rc);
     503        if (RT_SUCCESS(rc))
     504            rc = Msg.enmDir.GetUInt32((uint32_t *)pEnmDir); AssertRC(rc);
     505        if (RT_SUCCESS(rc))
     506            rc = Msg.enmStatus.GetUInt32(&pReport->uStatus); AssertRC(rc);
     507        if (RT_SUCCESS(rc))
     508            rc = Msg.rc.GetUInt32((uint32_t *)&pReport->rc); AssertRC(rc);
     509        if (RT_SUCCESS(rc))
     510            rc = Msg.fFlags.GetUInt32(&pReport->fFlags); AssertRC(rc);
     511    }
     512
     513    LogFlowFuncLeaveRC(rc);
     514    return rc;
     515}
     516
     517VBGLR3DECL(int) VbglR3ClipboardTransferStatusReply(PVBGLR3SHCLCMDCTX pCtx, PSHCLURITRANSFER pTransfer,
     518                                                   SHCLURITRANSFERSTATUS uStatus, int rcTransfer)
     519{
     520    AssertPtrReturn(pCtx,      VERR_INVALID_POINTER);
     521    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     522
     523    RT_NOREF(pTransfer);
     524
     525    VBoxClipboardReplyMsg Msg;
     526    RT_ZERO(Msg);
     527
     528    VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID,
     529                       VBOX_SHARED_CLIPBOARD_GUEST_FN_REPLY, VBOX_SHARED_CLIPBOARD_CPARMS_REPLY_MIN + 1);
     530
     531    Msg.uContext.SetUInt32(pCtx->uContextID);
     532    Msg.enmType.SetUInt32(VBOX_SHCL_REPLYMSGTYPE_TRANSFER_STATUS);
     533    Msg.rc.SetUInt32((uint32_t )rcTransfer); /* int vs. uint32_t */
     534    Msg.cbPayload.SetUInt32(0);
     535    Msg.pvPayload.SetPtr(NULL, 0);
     536
     537    Msg.u.TransferStatus.enmStatus.SetUInt32((uint32_t)uStatus);
     538
     539    LogFlowFunc(("%s\n", VBoxClipboardTransferStatusToStr(uStatus)));
     540
     541    int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     542
     543    LogFlowFuncLeaveRC(rc);
     544    return rc;
     545}
     546
    503547VBGLR3DECL(int) VbglR3ClipboardRootListHdrReadReq(PVBGLR3SHCLCMDCTX pCtx, uint32_t *pfRoots)
    504548{
     
    677721
    678722    VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID,
    679                        VBOX_SHARED_CLIPBOARD_GUEST_FN_REPLY, 6);
     723                       VBOX_SHARED_CLIPBOARD_GUEST_FN_REPLY, VBOX_SHARED_CLIPBOARD_CPARMS_REPLY_MIN + 1);
    680724
    681725    Msg.uContext.SetUInt32(pCtx->uContextID);
     
    727771
    728772    VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID,
    729                        VBOX_SHARED_CLIPBOARD_GUEST_FN_REPLY, 6);
     773                       VBOX_SHARED_CLIPBOARD_GUEST_FN_REPLY, VBOX_SHARED_CLIPBOARD_CPARMS_REPLY_MIN + 1);
    730774
    731775    Msg.uContext.SetUInt32(pCtx->uContextID);
     
    9801024
    9811025    VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID,
    982                        VBOX_SHARED_CLIPBOARD_GUEST_FN_REPLY, 6);
     1026                       VBOX_SHARED_CLIPBOARD_GUEST_FN_REPLY, VBOX_SHARED_CLIPBOARD_CPARMS_REPLY_MIN + 1);
    9831027
    9841028    Msg.uContext.SetUInt32(pCtx->uContextID);
     
    10591103
    10601104    VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID,
    1061                        VBOX_SHARED_CLIPBOARD_GUEST_FN_REPLY, 6);
     1105                       VBOX_SHARED_CLIPBOARD_GUEST_FN_REPLY, VBOX_SHARED_CLIPBOARD_CPARMS_REPLY_MIN + 1);
    10621106
    10631107    Msg.uContext.SetUInt32(pCtx->uContextID);
     
    12001244}
    12011245
    1202 VBGLR3DECL(int) VbglR3ClipboardTransferEvent(PVBGLR3SHCLCMDCTX pCtx, uint32_t uMsg, uint32_t cParms,
    1203                                              PSHCLURITRANSFER pTransfer)
    1204 {
    1205     RT_NOREF(cParms);
    1206 
    1207     LogFunc(("Handling uMsg=%RU32 (%s), cParms=%RU32\n", uMsg, VBoxClipboardHostMsgToStr(uMsg), cParms));
    1208 
     1246/**
     1247 * Starts a transfer on the guest side.
     1248 *
     1249 * @returns VBox status code.
     1250 * @param   pCmdCtx             Command context to use.
     1251 * @param   pTransferCtx        Transfer context to create transfer for.
     1252 * @param   uTransferID         ID to use for transfer to start.
     1253 * @param   enmDir              Direction of transfer to start.
     1254 * @param   enmSource           Source of transfer to start.
     1255 * @param   ppTransfer          Where to return the transfer object on success. Optional.
     1256 */
     1257static int vbglR3ClipboardTransferStart(PVBGLR3SHCLCMDCTX pCmdCtx, PSHCLURICTX pTransferCtx,
     1258                                        SHCLURITRANSFERID uTransferID, SHCLURITRANSFERDIR enmDir, SHCLSOURCE enmSource,
     1259                                        PSHCLURITRANSFER *ppTransfer)
     1260{
     1261    PSHCLURITRANSFER pTransfer;
     1262    int rc = SharedClipboardURITransferCreate(&pTransfer);
     1263    if (RT_SUCCESS(rc))
     1264    {
     1265        rc = SharedClipboardURICtxTransferRegisterByIndex(pTransferCtx, pTransfer, uTransferID);
     1266        if (RT_SUCCESS(rc))
     1267        {
     1268            rc = SharedClipboardURITransferInit(pTransfer, uTransferID, enmDir, enmSource);
     1269            if (RT_FAILURE(rc))
     1270                SharedClipboardURICtxTransferUnregister(pTransferCtx, uTransferID);
     1271        }
     1272    }
     1273
     1274    if (RT_SUCCESS(rc))
     1275    {
     1276        if (ppTransfer)
     1277            *ppTransfer = pTransfer;
     1278
     1279        LogRel2(("Shared Clipboard: Transfer ID=%RU16 successfully started\n", uTransferID));
     1280    }
     1281    else
     1282        LogRel(("Shared Clipboard: Unable to start transfer ID=%RU16, rc=%Rrc\n", uTransferID, rc));
     1283
     1284    /* Send a reply in any case. */
     1285    int rc2 = VbglR3ClipboardTransferStatusReply(pCmdCtx, pTransfer,
     1286                                                   RT_SUCCESS(rc)
     1287                                                 ? SHCLURITRANSFERSTATUS_STARTED : SHCLURITRANSFERSTATUS_ERROR, rc);
     1288    AssertRC(rc2);
     1289
     1290    LogFlowFuncLeaveRC(rc);
     1291    return rc;
     1292}
     1293
     1294/**
     1295 * Stops a transfer on the guest side.
     1296 *
     1297 * @returns VBox status code, or VERR_NOT_FOUND if transfer has not been found.
     1298 * @param   pCmdCtx             Command context to use.
     1299 * @param   pTransferCtx        Transfer context to stop transfer for.
     1300 * @param   uTransferID         ID of transfer to stop.
     1301 */
     1302static int vbglR3ClipboardTransferStop(PVBGLR3SHCLCMDCTX pCmdCtx, PSHCLURICTX pTransferCtx,
     1303                                       SHCLURITRANSFERID uTransferID)
     1304{
    12091305    int rc;
    12101306
    1211     switch (uMsg)
    1212     {
    1213         case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOT_LIST_HDR_READ:
    1214         {
    1215             uint32_t fRoots;
    1216             rc = VbglR3ClipboardRootListHdrReadReq(pCtx, &fRoots);
    1217 
    1218             /** @todo Validate / handle fRoots. */
    1219 
     1307    PSHCLURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(pTransferCtx, uTransferID);
     1308    if (pTransfer)
     1309    {
     1310        rc = SharedClipboardURITransferClose(pTransfer);
     1311        if (RT_SUCCESS(rc))
     1312            rc = SharedClipboardURICtxTransferUnregister(pTransferCtx, uTransferID);
     1313
     1314        if (RT_SUCCESS(rc))
     1315        {
     1316            LogRel2(("Shared Clipboard: Transfer ID=%RU16 successfully stopped\n", uTransferID));
     1317        }
     1318        else
     1319            LogRel(("Shared Clipboard: Unable to stop transfer ID=%RU16, rc=%Rrc\n", uTransferID, rc));
     1320
     1321        /* Send a reply in any case. */
     1322        int rc2 = VbglR3ClipboardTransferStatusReply(pCmdCtx, pTransfer,
     1323                                                       RT_SUCCESS(rc)
     1324                                                     ? SHCLURITRANSFERSTATUS_STOPPED : SHCLURITRANSFERSTATUS_ERROR, rc);
     1325        AssertRC(rc2);
     1326    }
     1327    else
     1328        rc = VERR_NOT_FOUND;
     1329
     1330    LogFlowFuncLeaveRC(rc);
     1331    return rc;
     1332}
     1333
     1334VBGLR3DECL(int) VbglR3ClipboardEventGetNextEx(uint32_t idMsg, uint32_t cParms,
     1335                                              PVBGLR3SHCLCMDCTX pCmdCtx, PSHCLURICTX pTransferCtx,
     1336                                              PVBGLR3CLIPBOARDEVENT pEvent)
     1337{
     1338    AssertPtrReturn(pCmdCtx,      VERR_INVALID_POINTER);
     1339    AssertPtrReturn(pTransferCtx, VERR_INVALID_POINTER);
     1340    AssertPtrReturn(pEvent,       VERR_INVALID_POINTER);
     1341
     1342    LogFunc(("Handling idMsg=%RU32 (%s), cParms=%RU32\n", idMsg, VBoxClipboardHostMsgToStr(idMsg), cParms));
     1343
     1344    int rc;
     1345
     1346    switch (idMsg)
     1347    {
     1348        case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_TRANSFER_STATUS:
     1349        {
     1350            SHCLURITRANSFERDIR    enmDir;
     1351            SHCLURITRANSFERREPORT transferReport;
     1352            rc = VbglR3ClipboarTransferStatusRecv(pCmdCtx, &enmDir, &transferReport);
    12201353            if (RT_SUCCESS(rc))
    12211354            {
     1355                const SHCLURITRANSFERID uTransferID = VBO_SHARED_CLIPBOARD_CONTEXTID_GET_TRANSFER(pCmdCtx->uContextID);
     1356
     1357                LogFlowFunc(("[Transfer %RU16] %s\n", uTransferID, VBoxClipboardTransferStatusToStr(transferReport.uStatus)));
     1358
     1359                switch (transferReport.uStatus)
     1360                {
     1361                    case SHCLURITRANSFERSTATUS_READY:
     1362                        RT_FALL_THROUGH();
     1363                    case SHCLURITRANSFERSTATUS_STARTED:
     1364                    {
     1365                        SHCLSOURCE enmSource = enmDir == SHCLURITRANSFERDIR_READ
     1366                                             ? SHCLSOURCE_LOCAL
     1367                                             : SHCLSOURCE_REMOTE;
     1368
     1369                        rc = vbglR3ClipboardTransferStart(pCmdCtx, pTransferCtx, uTransferID,
     1370                                                          enmDir, enmSource, NULL /* ppTransfer */);
     1371                        if (RT_SUCCESS(rc))
     1372                        {
     1373
     1374                        }
     1375                        break;
     1376                    }
     1377
     1378                    case SHCLURITRANSFERSTATUS_CANCELED:
     1379                        RT_FALL_THROUGH();
     1380                    case SHCLURITRANSFERSTATUS_KILLED:
     1381                        RT_FALL_THROUGH();
     1382                    case SHCLURITRANSFERSTATUS_ERROR:
     1383                    {
     1384                        rc = vbglR3ClipboardTransferStop(pCmdCtx, pTransferCtx,
     1385                                                         VBO_SHARED_CLIPBOARD_CONTEXTID_GET_TRANSFER(pCmdCtx->uContextID));
     1386                        break;
     1387                    }
     1388
     1389                    default:
     1390                        rc = VERR_NOT_SUPPORTED;
     1391                        break;
     1392                }
     1393
     1394                if (RT_SUCCESS(rc))
     1395                {
     1396                    pEvent->u.TransferStatus.enmDir = enmDir;
     1397                    pEvent->u.TransferStatus.Report = transferReport;
     1398                    pEvent->u.TransferStatus.uID    = VBO_SHARED_CLIPBOARD_CONTEXTID_GET_TRANSFER(pCmdCtx->uContextID);
     1399
     1400                    pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_URI_TRANSFER_STATUS;
     1401
     1402                    LogRel2(("Shared Clipboard: Received status %RU32 (%Rrc) for transfer ID=%RU16\n",
     1403                             pEvent->u.TransferStatus.Report.uStatus, pEvent->u.TransferStatus.Report.rc,
     1404                             pEvent->u.TransferStatus.uID));
     1405                }
     1406            }
     1407            break;
     1408        }
     1409
     1410        case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOT_LIST_HDR_READ:
     1411        {
     1412            uint32_t fRoots;
     1413            rc = VbglR3ClipboardRootListHdrReadReq(pCmdCtx, &fRoots);
     1414
     1415            /** @todo Validate / handle fRoots. */
     1416
     1417            if (RT_SUCCESS(rc))
     1418            {
     1419                PSHCLURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(pTransferCtx,
     1420                                                                              VBO_SHARED_CLIPBOARD_CONTEXTID_GET_TRANSFER(pCmdCtx->uContextID));
     1421                AssertPtrBreakStmt(pTransfer, VERR_NOT_FOUND);
     1422
    12221423                SHCLROOTLISTHDR rootListHdr;
    12231424                RT_ZERO(rootListHdr);
     
    12271428                LogFlowFunc(("cRoots=%RU32\n", rootListHdr.cRoots));
    12281429
    1229                 rc = VbglR3ClipboardRootListHdrReadReply(pCtx, &rootListHdr);
     1430                rc = VbglR3ClipboardRootListHdrReadReply(pCmdCtx, &rootListHdr);
    12301431            }
    12311432            break;
     
    12361437            uint32_t uIndex;
    12371438            uint32_t fInfo;
    1238             rc = VbglR3ClipboardRootListEntryReadReq(pCtx, &uIndex, &fInfo);
     1439            rc = VbglR3ClipboardRootListEntryReadReq(pCmdCtx, &uIndex, &fInfo);
    12391440            if (RT_SUCCESS(rc))
    12401441            {
     1442                PSHCLURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(pTransferCtx,
     1443                                                                              VBO_SHARED_CLIPBOARD_CONTEXTID_GET_TRANSFER(pCmdCtx->uContextID));
     1444                AssertPtrBreakStmt(pTransfer, VERR_NOT_FOUND);
     1445
    12411446                SHCLROOTLISTENTRY rootListEntry;
    12421447                rc = SharedClipboardURILTransferRootsEntry(pTransfer, uIndex, &rootListEntry);
    12431448                if (RT_SUCCESS(rc))
    1244                     rc = VbglR3ClipboardRootListEntryReadReply(pCtx, uIndex, &rootListEntry);
     1449                    rc = VbglR3ClipboardRootListEntryReadReply(pCmdCtx, uIndex, &rootListEntry);
    12451450            }
    12461451            break;
     
    12531458            if (RT_SUCCESS(rc))
    12541459            {
    1255                 rc = VbglR3ClipboardListOpenRecv(pCtx, &openParmsList);
     1460                rc = VbglR3ClipboardListOpenRecv(pCmdCtx, &openParmsList);
    12561461                if (RT_SUCCESS(rc))
    12571462                {
     1463                    PSHCLURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(pTransferCtx,
     1464                                                                                  VBO_SHARED_CLIPBOARD_CONTEXTID_GET_TRANSFER(pCmdCtx->uContextID));
     1465                    AssertPtrBreakStmt(pTransfer, VERR_NOT_FOUND);
     1466
    12581467                    LogFlowFunc(("pszPath=%s\n", openParmsList.pszPath));
    12591468
     
    12621471
    12631472                    /* Reply in any case. */
    1264                     int rc2 = VbglR3ClipboardListOpenReply(pCtx, rc, hList);
     1473                    int rc2 = VbglR3ClipboardListOpenReply(pCmdCtx, rc, hList);
    12651474                    AssertRC(rc2);
    12661475                }
     
    12751484        {
    12761485            SHCLLISTHANDLE hList;
    1277             rc = VbglR3ClipboardListCloseRecv(pCtx, &hList);
     1486            rc = VbglR3ClipboardListCloseRecv(pCmdCtx, &hList);
    12781487            if (RT_SUCCESS(rc))
    12791488            {
     1489                PSHCLURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(pTransferCtx,
     1490                                                                              VBO_SHARED_CLIPBOARD_CONTEXTID_GET_TRANSFER(pCmdCtx->uContextID));
     1491                AssertPtrBreakStmt(pTransfer, VERR_NOT_FOUND);
     1492
    12801493                rc = SharedClipboardURITransferListClose(pTransfer, hList);
    12811494
    12821495                /* Reply in any case. */
    1283                 int rc2 = VbglR3ClipboardListCloseReply(pCtx, rc, hList);
     1496                int rc2 = VbglR3ClipboardListCloseReply(pCmdCtx, rc, hList);
    12841497                AssertRC(rc2);
    12851498            }
     
    12941507            SHCLLISTHANDLE hList  = SHCLLISTHANDLE_INVALID;
    12951508            uint32_t                  fFlags = 0;
    1296             rc = VbglR3ClipboardListHdrReadRecvReq(pCtx, &hList, &fFlags);
     1509            rc = VbglR3ClipboardListHdrReadRecvReq(pCmdCtx, &hList, &fFlags);
    12971510            if (RT_SUCCESS(rc))
    12981511            {
     1512                PSHCLURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(pTransferCtx,
     1513                                                                              VBO_SHARED_CLIPBOARD_CONTEXTID_GET_TRANSFER(pCmdCtx->uContextID));
     1514                AssertPtrBreakStmt(pTransfer, VERR_NOT_FOUND);
     1515
    12991516                SHCLLISTHDR hdrList;
    13001517                rc = SharedClipboardURITransferListGetHeader(pTransfer, hList, &hdrList);
    13011518                if (RT_SUCCESS(rc))
    13021519                {
    1303                     rc = VbglR3ClipboardListHdrWrite(pCtx, hList, &hdrList);
     1520                    rc = VbglR3ClipboardListHdrWrite(pCmdCtx, hList, &hdrList);
    13041521
    13051522                    SharedClipboardURIListHdrDestroy(&hdrList);
     
    13351552                SHCLLISTHANDLE hList;
    13361553                uint32_t                  fInfo;
    1337                 rc = VbglR3ClipboardListEntryReadRecvReq(pCtx, &hList, &fInfo);
     1554                rc = VbglR3ClipboardListEntryReadRecvReq(pCmdCtx, &hList, &fInfo);
    13381555                if (RT_SUCCESS(rc))
    13391556                {
     1557                    PSHCLURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(pTransferCtx,
     1558                                                                                  VBO_SHARED_CLIPBOARD_CONTEXTID_GET_TRANSFER(pCmdCtx->uContextID));
     1559                    AssertPtrBreakStmt(pTransfer, VERR_NOT_FOUND);
     1560
    13401561                    rc = SharedClipboardURITransferListRead(pTransfer, hList, &entryList);
    13411562                    if (RT_SUCCESS(rc))
     
    13481569                        LogFlowFunc(("\t%s (%RU64 bytes)\n", entryList.pszName, pObjInfo->cbObject));
    13491570
    1350                         rc = VbglR3ClipboardListEntryWrite(pCtx, hList, &entryList);
     1571                        rc = VbglR3ClipboardListEntryWrite(pCmdCtx, hList, &entryList);
    13511572                    }
    13521573                }
     
    13731594            if (RT_SUCCESS(rc))
    13741595            {
    1375                 rc = VbglR3ClipboardObjOpenRecv(pCtx, &openParms);
     1596                rc = VbglR3ClipboardObjOpenRecv(pCmdCtx, &openParms);
    13761597                if (RT_SUCCESS(rc))
    13771598                {
     1599                    PSHCLURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(pTransferCtx,
     1600                                                                                  VBO_SHARED_CLIPBOARD_CONTEXTID_GET_TRANSFER(pCmdCtx->uContextID));
     1601                    AssertPtrBreakStmt(pTransfer, VERR_NOT_FOUND);
     1602
    13781603                    SHCLOBJHANDLE hObj;
    13791604                    rc = SharedClipboardURIObjectOpen(pTransfer, &openParms, &hObj);
    13801605
    13811606                    /* Reply in any case. */
    1382                     int rc2 = VbglR3ClipboardObjOpenReply(pCtx, rc, hObj);
     1607                    int rc2 = VbglR3ClipboardObjOpenReply(pCmdCtx, rc, hObj);
    13831608                    AssertRC(rc2);
    13841609                }
     
    13931618        {
    13941619            SHCLOBJHANDLE hObj;
    1395             rc = VbglR3ClipboardObjCloseRecv(pCtx, &hObj);
     1620            rc = VbglR3ClipboardObjCloseRecv(pCmdCtx, &hObj);
    13961621            if (RT_SUCCESS(rc))
    13971622            {
     1623                PSHCLURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(pTransferCtx,
     1624                                                                              VBO_SHARED_CLIPBOARD_CONTEXTID_GET_TRANSFER(pCmdCtx->uContextID));
     1625                AssertPtrBreakStmt(pTransfer, VERR_NOT_FOUND);
     1626
    13981627                rc = SharedClipboardURIObjectClose(pTransfer, hObj);
    13991628
    14001629                /* Reply in any case. */
    1401                 int rc2 = VbglR3ClipboardObjCloseReply(pCtx, rc, hObj);
     1630                int rc2 = VbglR3ClipboardObjCloseReply(pCmdCtx, rc, hObj);
    14021631                AssertRC(rc2);
    14031632            }
     
    14111640            uint32_t cbBuf;
    14121641            uint32_t fFlags;
    1413             rc = VbglR3ClipboardObjReadRecv(pCtx, &hObj, &cbBuf, &fFlags);
     1642            rc = VbglR3ClipboardObjReadRecv(pCmdCtx, &hObj, &cbBuf, &fFlags);
    14141643            if (RT_SUCCESS(rc))
    14151644            {
    1416                 AssertBreakStmt(pCtx->cbChunkSize, rc = VERR_INVALID_PARAMETER);
    1417 
    1418                 const uint32_t cbToRead = RT_MIN(cbBuf, pCtx->cbChunkSize);
     1645                PSHCLURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(pTransferCtx,
     1646                                                                              VBO_SHARED_CLIPBOARD_CONTEXTID_GET_TRANSFER(pCmdCtx->uContextID));
     1647                AssertPtrBreakStmt(pTransfer, VERR_NOT_FOUND);
     1648
     1649                AssertBreakStmt(pCmdCtx->cbChunkSize, rc = VERR_INVALID_PARAMETER);
     1650
     1651                const uint32_t cbToRead = RT_MIN(cbBuf, pCmdCtx->cbChunkSize);
    14191652
    14201653                LogFlowFunc(("hObj=%RU64, cbBuf=%RU32, fFlags=0x%x -> cbChunkSize=%RU32, cbToRead=%RU32\n",
    1421                              hObj, cbBuf, fFlags, pCtx->cbChunkSize, cbToRead));
     1654                             hObj, cbBuf, fFlags, pCmdCtx->cbChunkSize, cbToRead));
    14221655
    14231656                void *pvBuf = RTMemAlloc(cbToRead);
     
    14271660                    rc = SharedClipboardURIObjectRead(pTransfer, hObj, pvBuf, cbToRead, &cbRead, fFlags);
    14281661                    if (RT_SUCCESS(rc))
    1429                         rc = VbglR3ClipboardObjWrite(pCtx, hObj, pvBuf, cbRead, NULL /* pcbWritten */);
     1662                        rc = VbglR3ClipboardObjWrite(pCmdCtx, hObj, pvBuf, cbRead, NULL /* pcbWritten */);
    14301663
    14311664                    RTMemFree(pvBuf);
     
    14471680
    14481681        default:
     1682        {
     1683            rc = VbglR3ClipboardEventGetNext(idMsg, cParms, pCmdCtx, pEvent);
     1684            break;
     1685        }
     1686    }
     1687
     1688    LogFlowFuncLeaveRC(rc);
     1689    return rc;
     1690}
     1691#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
     1692
     1693VBGLR3DECL(int) VbglR3ClipboardEventGetNext(uint32_t idMsg, uint32_t cParms,
     1694                                            PVBGLR3SHCLCMDCTX pCtx, PVBGLR3CLIPBOARDEVENT pEvent)
     1695{
     1696    AssertPtrReturn(pCtx,   VERR_INVALID_POINTER);
     1697    AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
     1698
     1699    RT_NOREF(cParms);
     1700
     1701    int rc;
     1702
     1703#ifdef LOG_ENABLED
     1704    LogFunc(("Handling idMsg=%RU32 (%s), protocol v%RU32\n", idMsg, VBoxClipboardHostMsgToStr(idMsg), pCtx->uProtocolVer));
     1705#endif
     1706    switch (idMsg)
     1707    {
     1708        case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS_REPORT:
     1709        {
     1710            rc = VbglR3ClipboardFormatsReportRecv(pCtx, &pEvent->u.ReportedFormats);
     1711            if (RT_SUCCESS(rc))
     1712                pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_REPORT_FORMATS;
     1713            break;
     1714        }
     1715
     1716        case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA:
     1717        {
     1718            rc = VbglR3ClipboardReadDataRecv(pCtx, &pEvent->u.ReadData);
     1719            if (RT_SUCCESS(rc))
     1720                pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_READ_DATA;
     1721            break;
     1722        }
     1723
     1724        default:
     1725        {
    14491726            rc = VERR_NOT_SUPPORTED;
    14501727            break;
    1451     }
    1452 
    1453     LogFlowFuncLeaveRC(rc);
    1454     return rc;
    1455 }
    1456 #endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
    1457 
    1458 VBGLR3DECL(int) VbglR3ClipboardEventGetNext(PVBGLR3SHCLCMDCTX pCtx, PVBGLR3CLIPBOARDEVENT *ppEvent)
    1459 {
    1460     AssertPtrReturn(pCtx,      VERR_INVALID_POINTER);
    1461     AssertPtrReturn(ppEvent,   VERR_INVALID_POINTER);
    1462 
    1463     PVBGLR3CLIPBOARDEVENT pEvent = (PVBGLR3CLIPBOARDEVENT)RTMemAllocZ(sizeof(VBGLR3CLIPBOARDEVENT));
    1464     if (!pEvent)
    1465         return VERR_NO_MEMORY;
    1466 
    1467     pEvent->cmdCtx = *pCtx; /* Use the handed-in context as the base. */
    1468 
    1469     uint32_t uMsg   = 0;
    1470     uint32_t cParms = 0;
    1471     int rc = vbglR3ClipboardMsgPeekWait(&pEvent->cmdCtx, &uMsg, &cParms, NULL /* pidRestoreCheck */);
    1472     if (RT_SUCCESS(rc))
    1473     {
    1474 #ifdef LOG_ENABLED
    1475         LogFunc(("Handling uMsg=%RU32 (%s)\n", uMsg, VBoxClipboardHostMsgToStr(uMsg)));
    1476 #endif
    1477         switch (uMsg)
    1478         {
    1479             case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS_REPORT:
    1480             {
    1481                 rc = VbglR3ClipboardFormatsWriteRecv(&pEvent->cmdCtx, &pEvent->u.ReportFormats);
    1482                 if (RT_SUCCESS(rc))
    1483                     pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_REPORT_FORMATS;
    1484                 break;
    1485             }
    1486 
    1487             case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA:
    1488             {
    1489                 rc = VbglR3ClipboardReadDataRecv(&pEvent->cmdCtx, &pEvent->u.ReadData);
    1490                 if (RT_SUCCESS(rc))
    1491                     pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_READ_DATA;
    1492                 break;
    1493             }
    1494 
    1495             default:
    1496             {
    1497 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    1498                 rc = VbglR3ClipboardTransferEvent(&pEvent->cmdCtx, uMsg, cParms, NULL /* pTransfer */ ); /** @todo FIX !!! */
    1499 #endif
    1500                 rc = VERR_NOT_SUPPORTED;
    1501                 break;
    1502             }
    1503         }
    1504     }
    1505 
    1506     if (RT_SUCCESS(rc))
    1507     {
    1508         if (pEvent->enmType != VBGLR3CLIPBOARDEVENTTYPE_INVALID)
    1509         {
    1510             *ppEvent = pEvent;
    1511         }
    1512         else
    1513             VbglR3ClipboardEventFree(pEvent);
     1728        }
     1729    }
     1730
     1731    if (RT_SUCCESS(rc))
     1732    {
     1733        /* Copy over our command context to the event. */
     1734        pEvent->cmdCtx = *pCtx;
    15141735    }
    15151736    else
     
    15191740        AssertRC(rc2);
    15201741
    1521         VbglR3ClipboardEventFree(pEvent);
    1522     }
     1742   }
    15231743
    15241744    LogFlowFuncLeaveRC(rc);
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp

    r80664 r80845  
    406406 */
    407407int SharedClipboardWinDataObject::createFileGroupDescriptorFromTransfer(PSHCLURITRANSFER pTransfer,
    408                                                                       bool fUnicode, HGLOBAL *phGlobal)
     408                                                                        bool fUnicode, HGLOBAL *phGlobal)
    409409{
    410410    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp

    r80662 r80845  
    180180    RTListForEachSafe(&pSource->lstEvents, pEvIt, pEvItNext, SHCLEVENT, Node)
    181181    {
     182        RTListNodeRemove(&pEvIt->Node);
     183
    182184        SharedClipboardEventDestroy(pEvIt);
     185
    183186        RTMemFree(pEvIt);
     187        pEvIt = NULL;
    184188    }
    185189
     
    199203
    200204    LogFlowFunc(("uSource=%RU16: New event: %RU16\n", pSource->uID, pSource->uEventIDNext));
    201     return pSource->uEventIDNext++; /** @todo Handle rollovers? */
     205
     206    pSource->uEventIDNext++;
     207    if (pSource->uEventIDNext == VBOX_SHARED_CLIPBOARD_MAX_EVENTS)
     208        pSource->uEventIDNext = 0;
     209
     210    return pSource->uEventIDNext;
    202211}
    203212
     
    235244
    236245    return 0;
     246}
     247
     248/**
     249 * Detaches a payload from an event, internal version.
     250 *
     251 * @param   pEvent              Event to detach payload for.
     252 */
     253static void sharedClipboardEventPayloadDetachInternal(PSHCLEVENT pEvent)
     254{
     255    AssertPtrReturnVoid(pEvent);
     256
     257    pEvent->pPayload = NULL;
    237258}
    238259
     
    324345 * @param   uTimeoutMs          Timeout (in ms) to wait.
    325346 * @param   ppPayload           Where to store the (allocated) event payload on success. Needs to be free'd with
    326  *                              SharedClipboardPayloadFree().
     347 *                              SharedClipboardPayloadFree(). Optional.
    327348 */
    328349int SharedClipboardEventWait(PSHCLEVENTSOURCE pSource, SHCLEVENTID uID, RTMSINTERVAL uTimeoutMs,
     
    330351{
    331352    AssertPtrReturn(pSource, VERR_INVALID_POINTER);
     353    /** ppPayload is optional. */
    332354
    333355    LogFlowFuncEnter();
     
    341363        if (RT_SUCCESS(rc))
    342364        {
    343             *ppPayload = pEvent->pPayload;
    344 
    345             pEvent->pPayload = NULL;
     365            if (ppPayload)
     366            {
     367                *ppPayload = pEvent->pPayload;
     368
     369                /* Make sure to detach payload here, as the caller now owns the data. */
     370                sharedClipboardEventPayloadDetachInternal(pEvent);
     371            }
    346372        }
    347373    }
     
    402428    if (pEvent)
    403429    {
    404         pEvent->pPayload = NULL;
     430        sharedClipboardEventPayloadDetachInternal(pEvent);
    405431    }
    406432#ifdef DEBUG_andy
     
    803829        RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA);
    804830        RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS_REPORT);
    805         RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_TRANSFER_START);
     831        RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_TRANSFER_STATUS);
    806832        RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOT_LIST_HDR_READ);
    807833        RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOT_LIST_HDR_WRITE);
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-uri.cpp

    r80662 r80845  
    2323#include <iprt/list.h>
    2424#include <iprt/path.h>
     25#include <iprt/rand.h>
    2526#include <iprt/semaphore.h>
    2627
     
    10401041
    10411042/**
    1042  * Initializes an URI clipboard transfer struct.
    1043  *
    1044  * @returns VBox status code.
    1045  * @param   enmDir              Specifies the transfer direction of this transfer.
    1046  * @param   enmSource           Specifies the data source of the transfer.
     1043 * Creates an URI clipboard transfer.
     1044 *
     1045 * @returns VBox status code.
    10471046 * @param   ppTransfer          Where to return the created URI transfer struct.
    10481047 *                              Must be destroyed by SharedClipboardURITransferDestroy().
    10491048 */
    1050 int SharedClipboardURITransferCreate(SHCLURITRANSFERDIR enmDir, SHCLSOURCE enmSource,
    1051                                      PSHCLURITRANSFER *ppTransfer)
     1049int SharedClipboardURITransferCreate(PSHCLURITRANSFER *ppTransfer)
    10521050{
    10531051    AssertPtrReturn(ppTransfer, VERR_INVALID_POINTER);
     
    10631061    pTransfer->State.uID       = 0;
    10641062    pTransfer->State.enmStatus = SHCLURITRANSFERSTATUS_NONE;
    1065     pTransfer->State.enmDir    = enmDir;
    1066     pTransfer->State.enmSource = enmSource;
     1063    pTransfer->State.enmDir    = SHCLURITRANSFERDIR_UNKNOWN;
     1064    pTransfer->State.enmSource = SHCLSOURCE_INVALID;
    10671065
    10681066    LogFlowFunc(("enmDir=%RU32, enmSource=%RU32\n", pTransfer->State.enmDir, pTransfer->State.enmSource));
     
    10941092    RTListInit(&pTransfer->lstRoots);
    10951093
    1096     *ppTransfer = pTransfer;
    1097 
    1098     if (RT_FAILURE(rc))
     1094    RT_ZERO(pTransfer->Events);
     1095
     1096    if (RT_SUCCESS(rc))
     1097    {
     1098        *ppTransfer = pTransfer;
     1099    }
     1100    else
    10991101    {
    11001102        if (pTransfer)
     
    11541156}
    11551157
     1158/**
     1159 * Initializes an URI transfer object.
     1160 *
     1161 * @returns VBox status code.
     1162 * @param   pTransfer           Transfer to initialize.
     1163 * @param   uID                 ID to use for the transfer. Can be set to 0 if not important.
     1164 * @param   enmDir              Specifies the transfer direction of this transfer.
     1165 * @param   enmSource           Specifies the data source of the transfer.
     1166 */
     1167int SharedClipboardURITransferInit(PSHCLURITRANSFER pTransfer,
     1168                                   uint32_t uID, SHCLURITRANSFERDIR enmDir, SHCLSOURCE enmSource)
     1169{
     1170    pTransfer->State.uID       = uID;
     1171    pTransfer->State.enmDir    = enmDir;
     1172    pTransfer->State.enmSource = enmSource;
     1173
     1174    int rc = SharedClipboardEventSourceCreate(&pTransfer->Events, pTransfer->State.uID);
     1175
     1176    LogFlowFuncLeaveRC(rc);
     1177    return rc;
     1178}
     1179
    11561180int SharedClipboardURITransferOpen(PSHCLURITRANSFER pTransfer)
    11571181{
     
    11831207 * @param   hList               List handle of the list to get handle info for.
    11841208 */
    1185 inline PSHCLURILISTHANDLEINFO sharedClipboardURITransferListGet(PSHCLURITRANSFER pTransfer,
    1186                                                                            SHCLLISTHANDLE hList)
     1209inline PSHCLURILISTHANDLEINFO sharedClipboardURITransferListGet(PSHCLURITRANSFER pTransfer, SHCLLISTHANDLE hList)
    11871210{
    11881211    PSHCLURILISTHANDLEINFO pIt;
     
    13301353                {
    13311354                    if (RTDirIsValid(pInfo->u.Local.hDir))
     1355                    {
    13321356                        RTDirClose(pInfo->u.Local.hDir);
     1357                        pInfo->u.Local.hDir = NIL_RTDIR;
     1358                    }
    13331359                    break;
    13341360                }
     
    13701396{
    13711397    uint64_t cbSize = 0;
    1372     int rc = RTFileQuerySize(pszPath, &cbSize);
     1398    int rc = RTFileQuerySizeByPath(pszPath, &cbSize);
    13731399    if (RT_SUCCESS(rc))
    13741400    {
     
    21952221
    21962222/**
     2223 * Returns the transfer's ID.
     2224 *
     2225 * @returns The transfer's ID.
     2226 * @param   pTransfer           URI clipboard transfer to return ID for.
     2227 */
     2228SHCLURITRANSFERID SharedClipboardURITransferGetID(PSHCLURITRANSFER pTransfer)
     2229{
     2230    AssertPtrReturn(pTransfer, 0);
     2231
     2232    return pTransfer->State.uID;
     2233}
     2234
     2235/**
    21972236 * Returns the transfer's source.
    21982237 *
     
    22972336        if (pTransfer->Thread.fStarted) /* Did the thread indicate that it started correctly? */
    22982337        {
    2299             pTransfer->State.enmStatus = SHCLURITRANSFERSTATUS_RUNNING;
     2338            pTransfer->State.enmStatus = SHCLURITRANSFERSTATUS_STARTED;
    23002339        }
    23012340        else
     
    23522391
    23532392        pURI->cRunning    = 0;
    2354         pURI->cMaxRunning = 1; /* For now we only support one transfer per client at a time. */
    2355 
    2356 #ifdef DEBUG_andy
    2357         pURI->cMaxRunning = UINT32_MAX;
    2358 #endif
     2393        pURI->cMaxRunning = UINT16_MAX;
     2394
     2395        RT_ZERO(pURI->bmTransferIds);
     2396
    23592397        SharedClipboardURICtxReset(pURI);
    23602398    }
     
    24082446
    24092447/**
    2410  * Adds a new URI transfer to an clipboard URI transfer.
    2411  *
    2412  * @returns VBox status code.
    2413  * @param   pURI                URI clipboard context to add transfer to.
    2414  * @param   pTransfer           Pointer to URI clipboard transfer to add.
    2415  */
    2416 int SharedClipboardURICtxTransferAdd(PSHCLURICTX pURI, PSHCLURITRANSFER pTransfer)
     2448 * Returns a specific URI transfer, internal version.
     2449 *
     2450 * @returns URI transfer, or NULL if not found.
     2451 * @param   pURI                URI clipboard context to return transfer for.
     2452 * @param   uID                 ID of the transfer to return.
     2453 */
     2454static PSHCLURITRANSFER sharedClipboardURICtxGetTransferInternal(PSHCLURICTX pURI, uint32_t uID)
     2455{
     2456    PSHCLURITRANSFER pTransfer;
     2457    RTListForEach(&pURI->List, pTransfer, SHCLURITRANSFER, Node) /** @todo Slow, but works for now. */
     2458    {
     2459        if (pTransfer->State.uID == uID)
     2460            return pTransfer;
     2461    }
     2462
     2463    return NULL;
     2464}
     2465
     2466/**
     2467 * Returns a specific URI transfer.
     2468 *
     2469 * @returns URI transfer, or NULL if not found.
     2470 * @param   pURI                URI clipboard context to return transfer for.
     2471 * @param   uID                 ID of the transfer to return.
     2472 */
     2473PSHCLURITRANSFER SharedClipboardURICtxGetTransfer(PSHCLURICTX pURI, uint32_t uID)
     2474{
     2475    return sharedClipboardURICtxGetTransferInternal(pURI, uID);
     2476}
     2477
     2478/**
     2479 * Returns the number of running URI transfers.
     2480 *
     2481 * @returns Number of running transfers.
     2482 * @param   pURI                URI clipboard context to return number for.
     2483 */
     2484uint32_t SharedClipboardURICtxGetRunningTransfers(PSHCLURICTX pURI)
     2485{
     2486    AssertPtrReturn(pURI, 0);
     2487    return pURI->cRunning;
     2488}
     2489
     2490/**
     2491 * Returns the number of total URI transfers.
     2492 *
     2493 * @returns Number of total transfers.
     2494 * @param   pURI                URI clipboard context to return number for.
     2495 */
     2496uint32_t SharedClipboardURICtxGetTotalTransfers(PSHCLURICTX pURI)
     2497{
     2498    AssertPtrReturn(pURI, 0);
     2499    return pURI->cTransfers;
     2500}
     2501
     2502/**
     2503 * Registers an URI transfer with an URI context, i.e. allocates a transfer ID.
     2504 *
     2505 * @return  VBox status code.
     2506 * @retval  VERR_SHCLPB_MAX_TRANSFERS_REACHED if the maximum of concurrent transfers
     2507 *          is reached.
     2508 * @param   pURI                URI clipboard context to register transfer to.
     2509 * @param   pTransfer           Transfer to register.
     2510 * @param   pidTransfer         Where to return the transfer ID on success. Optional.
     2511 */
     2512int SharedClipboardURICtxTransferRegister(PSHCLURICTX pURI, PSHCLURITRANSFER pTransfer, uint32_t *pidTransfer)
    24172513{
    24182514    AssertPtrReturn(pURI,      VERR_INVALID_POINTER);
    24192515    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
    2420 
    2421     LogFlowFuncEnter();
    2422 
    2423     if (pURI->cRunning == pURI->cMaxRunning)
     2516    /* pidTransfer is optional. */
     2517
     2518    /*
     2519     * Pick a random bit as starting point.  If it's in use, search forward
     2520     * for a free one, wrapping around.  We've reserved both the zero'th and
     2521     * max-1 IDs.
     2522     */
     2523    uint32_t idTransfer = RTRandU32Ex(1, VBOX_SHARED_CLIPBOARD_MAX_TRANSFERS - 2);
     2524
     2525    if (!ASMBitTestAndSet(&pURI->bmTransferIds[0], idTransfer))
     2526    { /* likely */ }
     2527    else if (pURI->cTransfers < VBOX_SHARED_CLIPBOARD_MAX_TRANSFERS - 2 /* First and last are not used */)
     2528    {
     2529        /* Forward search. */
     2530        int iHit = ASMBitNextClear(&pURI->bmTransferIds[0], VBOX_SHARED_CLIPBOARD_MAX_TRANSFERS, idTransfer);
     2531        if (iHit < 0)
     2532            iHit = ASMBitFirstClear(&pURI->bmTransferIds[0], VBOX_SHARED_CLIPBOARD_MAX_TRANSFERS);
     2533        AssertLogRelMsgReturn(iHit >= 0, ("Transfer count: %RU16\n", pURI->cTransfers), VERR_SHCLPB_MAX_TRANSFERS_REACHED);
     2534        idTransfer = iHit;
     2535        AssertLogRelMsgReturn(!ASMBitTestAndSet(&pURI->bmTransferIds[0], idTransfer), ("idObject=%#x\n", idTransfer), VERR_INTERNAL_ERROR_2);
     2536    }
     2537    else
     2538    {
     2539        LogFunc(("Maximum number of transfers reached (%RU16 transfers)\n", pURI->cTransfers));
    24242540        return VERR_SHCLPB_MAX_TRANSFERS_REACHED;
     2541    }
     2542
     2543    Log2Func(("pTransfer=%p, idTransfer=%RU32 (%RU16 transfers)\n", pTransfer, idTransfer, pURI->cTransfers));
    24252544
    24262545    RTListAppend(&pURI->List, &pTransfer->Node);
    24272546
    24282547    pURI->cTransfers++;
    2429     LogFlowFunc(("cTransfers=%RU32, cRunning=%RU32\n", pURI->cTransfers, pURI->cRunning));
     2548
     2549    if (pidTransfer)
     2550        *pidTransfer = idTransfer;
    24302551
    24312552    return VINF_SUCCESS;
     
    24332554
    24342555/**
    2435  * Removes an URI transfer from a clipboard URI transfer.
    2436  *
    2437  * @returns VBox status code.
    2438  * @param   pURI                URI clipboard context to remove transfer from.
    2439  * @param   pTransfer           Pointer to URI clipboard transfer to remove.
    2440  */
    2441 int SharedClipboardURICtxTransferRemove(PSHCLURICTX pURI, PSHCLURITRANSFER pTransfer)
    2442 {
    2443     AssertPtrReturn(pURI,      VERR_INVALID_POINTER);
    2444     AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
    2445 
    2446     LogFlowFuncEnter();
    2447 
    2448 
    2449     int rc = SharedClipboardURITransferDestroy(pTransfer);
    2450     if (RT_SUCCESS(rc))
     2556 * Registers an URI transfer with an URI context by specifying an ID for the transfer.
     2557 *
     2558 * @return  VBox status code.
     2559 * @retval  VERR_ALREADY_EXISTS if a transfer with the given ID already exists.
     2560 * @retval  VERR_SHCLPB_MAX_TRANSFERS_REACHED if the maximum of concurrent transfers for this context has been reached.
     2561 * @param   pURI                URI clipboard context to register transfer to.
     2562 * @param   pTransfer           Transfer to register.
     2563 * @param   idTransfer          Transfer ID to use for registration.
     2564 */
     2565int SharedClipboardURICtxTransferRegisterByIndex(PSHCLURICTX pURI, PSHCLURITRANSFER pTransfer, uint32_t idTransfer)
     2566{
     2567    LogFlowFunc(("cTransfers=%RU16, idTransfer=%RU32\n", pURI->cTransfers, idTransfer));
     2568
     2569    if (pURI->cTransfers < VBOX_SHARED_CLIPBOARD_MAX_TRANSFERS - 2 /* First and last are not used */)
     2570    {
     2571        if (!ASMBitTestAndSet(&pURI->bmTransferIds[0], idTransfer))
     2572        {
     2573            RTListAppend(&pURI->List, &pTransfer->Node);
     2574
     2575            pURI->cTransfers++;
     2576            return VINF_SUCCESS;
     2577        }
     2578
     2579        return VERR_ALREADY_EXISTS;
     2580    }
     2581
     2582    LogFunc(("Maximum number of transfers reached (%RU16 transfers)\n", pURI->cTransfers));
     2583    return VERR_SHCLPB_MAX_TRANSFERS_REACHED;
     2584}
     2585
     2586/**
     2587 * Unregisters a transfer from an URI clipboard context.
     2588 *
     2589 * @retval  VINF_SUCCESS on success.
     2590 * @retval  VERR_NOT_FOUND if the transfer ID was not found.
     2591 * @param   pURI                URI clipboard context to unregister transfer from.
     2592 * @param   idTransfer          Transfer ID to unregister.
     2593 */
     2594int SharedClipboardURICtxTransferUnregister(PSHCLURICTX pURI, uint32_t idTransfer)
     2595{
     2596    int rc = VINF_SUCCESS;
     2597    AssertMsgStmt(ASMBitTestAndClear(&pURI->bmTransferIds, idTransfer), ("idTransfer=%#x\n", idTransfer), rc = VERR_NOT_FOUND);
     2598
     2599    PSHCLURITRANSFER pTransfer = sharedClipboardURICtxGetTransferInternal(pURI, idTransfer);
     2600    if (pTransfer)
    24512601    {
    24522602        RTListNodeRemove(&pTransfer->Node);
    24532603
    2454         RTMemFree(pTransfer);
    2455         pTransfer = NULL;
    2456     }
    2457 
    2458     LogFlowFuncLeaveRC(rc);
    2459     return rc;
    2460 }
    2461 
    2462 /**
    2463  * Returns a specific URI transfer, internal version.
    2464  *
    2465  * @returns URI transfer, or NULL if not found.
    2466  * @param   pURI                URI clipboard context to return transfer for.
    2467  * @param   uIdx                Index of the transfer to return.
    2468  */
    2469 static PSHCLURITRANSFER sharedClipboardURICtxGetTransferInternal(PSHCLURICTX pURI, uint32_t uIdx)
    2470 {
    2471     AssertReturn(uIdx == 0, NULL); /* Only one transfer allowed at the moment. */
    2472     return RTListGetFirst(&pURI->List, SHCLURITRANSFER, Node);
    2473 }
    2474 
    2475 /**
    2476  * Returns a specific URI transfer.
    2477  *
    2478  * @returns URI transfer, or NULL if not found.
    2479  * @param   pURI                URI clipboard context to return transfer for.
    2480  * @param   uIdx                Index of the transfer to return.
    2481  */
    2482 PSHCLURITRANSFER SharedClipboardURICtxGetTransfer(PSHCLURICTX pURI, uint32_t uIdx)
    2483 {
    2484     return sharedClipboardURICtxGetTransferInternal(pURI, uIdx);
    2485 }
    2486 
    2487 /**
    2488  * Returns the number of running URI transfers.
    2489  *
    2490  * @returns Number of running transfers.
    2491  * @param   pURI                URI clipboard context to return number for.
    2492  */
    2493 uint32_t SharedClipboardURICtxGetRunningTransfers(PSHCLURICTX pURI)
    2494 {
    2495     AssertPtrReturn(pURI, 0);
    2496     return pURI->cRunning;
    2497 }
    2498 
    2499 /**
    2500  * Returns the number of total URI transfers.
    2501  *
    2502  * @returns Number of total transfers.
    2503  * @param   pURI                URI clipboard context to return number for.
    2504  */
    2505 uint32_t SharedClipboardURICtxGetTotalTransfers(PSHCLURICTX pURI)
    2506 {
    2507     AssertPtrReturn(pURI, 0);
    2508     return pURI->cTransfers;
     2604        Assert(pURI->cTransfers);
     2605        pURI->cTransfers--;
     2606    }
     2607    else
     2608        rc = VERR_NOT_FOUND;
     2609
     2610    LogFlowFunc(("idTransfer=%RU32, rc=%Rrc\n", idTransfer, rc));
     2611    return rc;
    25092612}
    25102613
     
    25252628    RTListForEachSafe(&pURI->List, pTransfer, pTransferNext, SHCLURITRANSFER, Node)
    25262629    {
    2527         if (SharedClipboardURITransferGetStatus(pTransfer) != SHCLURITRANSFERSTATUS_RUNNING)
     2630        if (SharedClipboardURITransferGetStatus(pTransfer) != SHCLURITRANSFERSTATUS_STARTED)
    25282631        {
    25292632            SharedClipboardURITransferDestroy(pTransfer);
     
    28412944}
    28422945
     2946/**
     2947 * Translates a Shared Clipboard transfer status (SHCLURITRANSFERSTATUS_XXX) into a string.
     2948 *
     2949 * @returns Transfer status string name.
     2950 * @param   uStatus             The transfer status to translate.
     2951 */
     2952const char *VBoxClipboardTransferStatusToStr(uint32_t uStatus)
     2953{
     2954    switch (uStatus)
     2955    {
     2956        RT_CASE_RET_STR(SHCLURITRANSFERSTATUS_NONE);
     2957        RT_CASE_RET_STR(SHCLURITRANSFERSTATUS_READY);
     2958        RT_CASE_RET_STR(SHCLURITRANSFERSTATUS_STARTED);
     2959        RT_CASE_RET_STR(SHCLURITRANSFERSTATUS_STOPPED);
     2960        RT_CASE_RET_STR(SHCLURITRANSFERSTATUS_CANCELED);
     2961        RT_CASE_RET_STR(SHCLURITRANSFERSTATUS_KILLED);
     2962        RT_CASE_RET_STR(SHCLURITRANSFERSTATUS_ERROR);
     2963    }
     2964    return "Unknown";
     2965}
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp

    r80664 r80845  
    106106        const DWORD dwLastErr = GetLastError();
    107107        if (dwLastErr == ERROR_CLIPBOARD_NOT_OPEN)
    108             rc = VERR_INVALID_STATE;
     108        {
     109            rc = VINF_SUCCESS; /* Not important, so just report success instead. */
     110        }
    109111        else
     112        {
    110113            rc = RTErrConvertFromWin32(dwLastErr);
    111 
    112         LogFunc(("Failed with %Rrc (0x%x)\n", rc, dwLastErr));
     114            LogFunc(("Failed with %Rrc (0x%x)\n", rc, dwLastErr));
     115        }
    113116    }
    114117    else
     
    147150
    148151/**
     152 * Initializes a Shared Clipboard Windows context.
     153 *
     154 * @returns VBox status code.
     155 * @param   pWinCtx             Shared Clipboard Windows context to initialize.
     156 */
     157int SharedClipboardWinCtxInit(PSHCLWINCTX pWinCtx)
     158{
     159    int rc = RTCritSectInit(&pWinCtx->CritSect);
     160    if (RT_SUCCESS(rc))
     161    {
     162        /* Check that new Clipboard API is available. */
     163        rc = SharedClipboardWinCheckAndInitNewAPI(&pWinCtx->newAPI);
     164        if (RT_SUCCESS(rc))
     165        {
     166            pWinCtx->hWnd                 = NULL;
     167            pWinCtx->hWndClipboardOwnerUs = NULL;
     168            pWinCtx->hWndNextInChain      = NULL;
     169        }
     170    }
     171
     172    LogFlowFuncLeaveRC(rc);
     173    return rc;
     174}
     175
     176/**
     177 * Destroys a Shared Clipboard Windows context.
     178 *
     179 * @param   pWinCtx             Shared Clipboard Windows context to destroy.
     180 */
     181void SharedClipboardWinCtxDestroy(PSHCLWINCTX pWinCtx)
     182{
     183    if (!pWinCtx)
     184        return;
     185
     186    if (RTCritSectIsInitialized(&pWinCtx->CritSect))
     187    {
     188        int rc2 = RTCritSectDelete(&pWinCtx->CritSect);
     189        AssertRC(rc2);
     190    }
     191}
     192
     193/**
    149194 * Checks and initializes function pointer which are required for using
    150195 * the new clipboard API.
     
    299344 */
    300345LRESULT SharedClipboardWinChainPassToNext(PSHCLWINCTX pWinCtx,
    301                                         UINT msg, WPARAM wParam, LPARAM lParam)
     346                                          UINT msg, WPARAM wParam, LPARAM lParam)
    302347{
    303348    LogFlowFuncEnter();
     
    874919                 *        where another application could own the clipboard (open), and thus the call to
    875920                 *        OleSetClipboard() will fail. Needs (better) fixing. */
     921                HRESULT hr = S_OK;
     922
    876923                for (unsigned uTries = 0; uTries < 3; uTries++)
    877924                {
    878                     HRESULT hr = OleSetClipboard(pWinURITransferCtx->pDataObj);
    879                     if (SUCCEEDED(hr))
     925                    /* Make sure to enter the critical section before setting the clipboard data, as otherwise WM_CLIPBOARDUPDATE
     926                     * might get called *before* we had the opportunity to set pWinCtx->hWndClipboardOwnerUs below. */
     927                    rc = RTCritSectEnter(&pWinCtx->CritSect);
     928                    if (RT_SUCCESS(rc))
    880929                    {
    881                         /*
    882                          * Calling OleSetClipboard() changed the clipboard owner, which in turn will let us receive
    883                          * a WM_CLIPBOARDUPDATE message. To not confuse ourselves with our own clipboard owner changes,
    884                          * save a new window handle and deal with it in WM_CLIPBOARDUPDATE.
    885                          */
    886                         pWinCtx->hWndClipboardOwnerUs = GetClipboardOwner();
    887                         break;
     930                        hr = OleSetClipboard(pWinURITransferCtx->pDataObj);
     931                        if (SUCCEEDED(hr))
     932                        {
     933                            Assert(OleIsCurrentClipboard(pWinURITransferCtx->pDataObj) == S_OK); /* Sanity. */
     934
     935                            /*
     936                             * Calling OleSetClipboard() changed the clipboard owner, which in turn will let us receive
     937                             * a WM_CLIPBOARDUPDATE message. To not confuse ourselves with our own clipboard owner changes,
     938                             * save a new window handle and deal with it in WM_CLIPBOARDUPDATE.
     939                             */
     940                            pWinCtx->hWndClipboardOwnerUs = GetClipboardOwner();
     941
     942                            rc = RTCritSectLeave(&pWinCtx->CritSect);
     943                            AssertRC(rc);
     944                            break;
     945                        }
    888946                    }
    889                     else
    890                     {
    891                         rc = VERR_ACCESS_DENIED; /** @todo Fudge; fix this. */
    892                         LogRel(("Shared Clipboard: Failed with %Rhrc when setting data object to clipboard\n", hr));
    893                         RTThreadSleep(100); /* Wait a bit. */
    894                     }
     947
     948                    rc = RTCritSectLeave(&pWinCtx->CritSect);
     949                    AssertRCBreak(rc);
     950
     951                    LogFlowFunc(("Failed with %Rhrc (try %u/3)\n", hr, uTries + 1));
     952                    RTThreadSleep(500); /* Wait a bit. */
     953                }
     954
     955                if (FAILED(hr))
     956                {
     957                    rc = VERR_ACCESS_DENIED; /** @todo Fudge; fix this. */
     958                    LogRel(("Shared Clipboard: Failed with %Rhrc when setting data object to clipboard\n", hr));
    895959                }
    896960            }
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h

    r80664 r80845  
    5858{
    5959    /** Stored message type. */
    60     uint32_t         m_uMsg;
     60    uint32_t         uMsg;
    6161    /** Number of stored HGCM parameters. */
    62     uint32_t         m_cParms;
     62    uint32_t         cParms;
    6363    /** Stored HGCM parameters. */
    64     PVBOXHGCMSVCPARM m_paParms;
     64    PVBOXHGCMSVCPARM paParms;
    6565    /** Message context. */
    66     SHCLMSGCTX       m_Ctx;
     66    SHCLMSGCTX       Ctx;
    6767} SHCLCLIENTMSG, *PSHCLCLIENTMSG;
    6868
     
    8484    SHCLCONTEXT            *pCtx;
    8585
    86     /** The client's HGCM ID. */
    87     uint32_t                         u32ClientID;
     86    /** The client's HGCM ID. Not related to the session ID below! */
     87    uint32_t                uClientID;
     88    /** The client's session ID. */
     89    uint32_t                uSessionID;
    8890    /** Optional protocol version the client uses. Set to 0 by default. */
    89     uint32_t                         uProtocolVer;
     91    uint32_t                uProtocolVer;
    9092    /** Maximum chunk size to use for data transfers. Set to _64K by default. */
    91     uint32_t                         cbChunkSize;
    92     SHCLSOURCE            enmSource;
     93    uint32_t                cbChunkSize;
     94    SHCLSOURCE              enmSource;
    9395    /** The client's URI state. */
    9496    SHCLCLIENTURISTATE      URI;
     
    9799typedef struct _SHCLCLIENTCMDCTX
    98100{
    99     uint32_t                          uContextID;
     101    uint32_t uContextID;
    100102} SHCLCLIENTCMDCTX, *PSHCLCLIENTCMDCTX;
    101103
    102104typedef struct _SHCLCLIENT
    103105{
    104     /** The client's HGCM client ID. */
    105     uint32_t                          uClientID;
    106106    /** General client state data. */
    107107    SHCLCLIENTSTATE          State;
    108108    /** The client's message queue (FIFO). */
    109109    RTCList<SHCLCLIENTMSG *> queueMsg;
    110     /** The client's own event source. */
    111     SHCLEVENTSOURCE        Events;
     110    /** The client's own event source.
     111     *  Needed for events which are not bound to a specific transfer. */
     112    SHCLEVENTSOURCE          Events;
    112113#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    113114    /** URI context data. */
    114     SHCLURICTX             URI;
     115    SHCLURICTX               URI;
    115116#endif
    116117    /** Structure for keeping the client's pending (deferred return) state.
     
    226227int sharedClipboardSvcURIGetRoots(PSHCLPROVIDERCTX pCtx, PSHCLROOTLIST *ppRootList);
    227228
    228 int sharedClipboardSvcURIListOpen(PSHCLPROVIDERCTX pCtx,
    229                                 PSHCLLISTOPENPARMS pOpenParms, PSHCLLISTHANDLE phList);
     229int sharedClipboardSvcURIListOpen(PSHCLPROVIDERCTX pCtx, PSHCLLISTOPENPARMS pOpenParms, PSHCLLISTHANDLE phList);
    230230int sharedClipboardSvcURIListClose(PSHCLPROVIDERCTX pCtx, SHCLLISTHANDLE hList);
    231 int sharedClipboardSvcURIListHdrRead(PSHCLPROVIDERCTX pCtx, SHCLLISTHANDLE hList,
    232                                    PSHCLLISTHDR pListHdr);
    233 int sharedClipboardSvcURIListHdrWrite(PSHCLPROVIDERCTX pCtx, SHCLLISTHANDLE hList,
    234                                     PSHCLLISTHDR pListHdr);
    235 int sharedClipboardSvcURIListEntryRead(PSHCLPROVIDERCTX pCtx, SHCLLISTHANDLE hList,
    236                                      PSHCLLISTENTRY pListEntry);
    237 int sharedClipboardSvcURIListEntryWrite(PSHCLPROVIDERCTX pCtx, SHCLLISTHANDLE hList,
    238                                       PSHCLLISTENTRY pListEntry);
     231int sharedClipboardSvcURIListHdrRead(PSHCLPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr);
     232int sharedClipboardSvcURIListHdrWrite(PSHCLPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr);
     233int sharedClipboardSvcURIListEntryRead(PSHCLPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry);
     234int sharedClipboardSvcURIListEntryWrite(PSHCLPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry);
    239235
    240236int sharedClipboardSvcURIObjOpen(PSHCLPROVIDERCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms,
    241                                PSHCLOBJHANDLE phObj);
     237                                 PSHCLOBJHANDLE phObj);
    242238int sharedClipboardSvcURIObjClose(PSHCLPROVIDERCTX pCtx, SHCLOBJHANDLE hObj);
    243239int sharedClipboardSvcURIObjRead(PSHCLPROVIDERCTX pCtx, SHCLOBJHANDLE hObj,
    244                                void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbRead);
     240                                 void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbRead);
    245241int sharedClipboardSvcURIObjWrite(PSHCLPROVIDERCTX pCtx, SHCLOBJHANDLE hObj,
    246                                 void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbWritten);
     242                                  void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbWritten);
    247243
    248244DECLCALLBACK(void) VBoxSvcClipboardURITransferPrepareCallback(PSHCLURITRANSFERCALLBACKDATA pData);
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-uri.cpp

    r80664 r80845  
    8484
    8585    PSHCLCLIENTMSG pMsgHdr = sharedClipboardSvcMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOT_LIST_HDR_READ,
    86                                                                VBOX_SHARED_CLIPBOARD_CPARMS_ROOT_LIST_HDR_READ);
     86                                                        VBOX_SHARED_CLIPBOARD_CPARMS_ROOT_LIST_HDR_READ);
    8787    if (pMsgHdr)
    8888    {
    8989        SHCLEVENTID uEvent = SharedClipboardEventIDGenerate(&pCtx->pTransfer->Events);
    9090
    91         HGCMSvcSetU32(&pMsgHdr->m_paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pCtx->pTransfer->State.uID, uEvent));
    92         HGCMSvcSetU32(&pMsgHdr->m_paParms[1], 0 /* fRoots */);
     91        HGCMSvcSetU32(&pMsgHdr->paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->State.uSessionID,
     92                                                                                   pCtx->pTransfer->State.uID, uEvent));
     93        HGCMSvcSetU32(&pMsgHdr->paParms[1], 0 /* fRoots */);
    9394
    9495        rc = sharedClipboardSvcMsgAdd(pClient, pMsgHdr, true /* fAppend */);
     
    124125                                {
    125126                                    PSHCLCLIENTMSG pMsgEntry = sharedClipboardSvcMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOT_LIST_ENTRY_READ,
    126                                                                                                  VBOX_SHARED_CLIPBOARD_CPARMS_ROOT_LIST_ENTRY_READ_REQ);
     127                                                                                          VBOX_SHARED_CLIPBOARD_CPARMS_ROOT_LIST_ENTRY_READ_REQ);
    127128
    128129                                    uEvent = SharedClipboardEventIDGenerate(&pCtx->pTransfer->Events);
    129130
    130                                     HGCMSvcSetU32(&pMsgEntry->m_paParms[0],
    131                                                   VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pCtx->pTransfer->State.uID, uEvent));
    132                                     HGCMSvcSetU32(&pMsgEntry->m_paParms[1], 0 /* fRoots */);
    133                                     HGCMSvcSetU32(&pMsgEntry->m_paParms[2], i /* uIndex */);
     131                                    HGCMSvcSetU32(&pMsgEntry->paParms[0],
     132                                                  VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->State.uClientID,
     133                                                                                       pCtx->pTransfer->State.uID, uEvent));
     134                                    HGCMSvcSetU32(&pMsgEntry->paParms[1], 0 /* fRoots */);
     135                                    HGCMSvcSetU32(&pMsgEntry->paParms[2], i /* uIndex */);
    134136
    135137                                    rc2 = SharedClipboardEventRegister(&pCtx->pTransfer->Events, uEvent);
     
    206208        const SHCLEVENTID uEvent = SharedClipboardEventIDGenerate(&pCtx->pTransfer->Events);
    207209
    208         pMsg->m_Ctx.uContextID = VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pCtx->pTransfer->State.uID, uEvent);
    209 
    210         rc = sharedClipboardSvcURISetListOpen(pMsg->m_cParms, pMsg->m_paParms, &pMsg->m_Ctx, pOpenParms);
     210        pMsg->Ctx.uContextID = VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->State.uSessionID,  pCtx->pTransfer->State.uID,
     211                                                                      uEvent);
     212
     213        rc = sharedClipboardSvcURISetListOpen(pMsg->cParms, pMsg->paParms, &pMsg->Ctx, pOpenParms);
    211214        if (RT_SUCCESS(rc))
    212215        {
     
    258261
    259262    PSHCLCLIENTMSG pMsg = sharedClipboardSvcMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_CLOSE,
    260                                                             VBOX_SHARED_CLIPBOARD_CPARMS_LIST_CLOSE);
     263                                                     VBOX_SHARED_CLIPBOARD_CPARMS_LIST_CLOSE);
    261264    if (pMsg)
    262265    {
    263266        const SHCLEVENTID uEvent = SharedClipboardEventIDGenerate(&pCtx->pTransfer->Events);
    264267
    265         pMsg->m_Ctx.uContextID = VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pCtx->pTransfer->State.uID, uEvent);
    266 
    267         rc = sharedClipboardSvcURISetListClose(pMsg->m_cParms, pMsg->m_paParms, &pMsg->m_Ctx, hList);
     268        pMsg->Ctx.uContextID = VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->State.uSessionID, pCtx->pTransfer->State.uID,
     269                                                                    uEvent);
     270
     271        rc = sharedClipboardSvcURISetListClose(pMsg->cParms, pMsg->paParms, &pMsg->Ctx, hList);
    268272        if (RT_SUCCESS(rc))
    269273        {
     
    310314        const SHCLEVENTID uEvent = SharedClipboardEventIDGenerate(&pCtx->pTransfer->Events);
    311315
    312         HGCMSvcSetU32(&pMsg->m_paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pCtx->pTransfer->State.uID, uEvent));
    313         HGCMSvcSetU64(&pMsg->m_paParms[1], hList);
    314         HGCMSvcSetU32(&pMsg->m_paParms[2], 0 /* fFlags */);
     316        HGCMSvcSetU32(&pMsg->paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->State.uSessionID,
     317                                                                              pCtx->pTransfer->State.uID, uEvent));
     318        HGCMSvcSetU64(&pMsg->paParms[1], hList);
     319        HGCMSvcSetU32(&pMsg->paParms[2], 0 /* fFlags */);
    315320
    316321        rc = sharedClipboardSvcMsgAdd(pClient, pMsg, true /* fAppend */);
     
    370375        const SHCLEVENTID uEvent = SharedClipboardEventIDGenerate(&pCtx->pTransfer->Events);
    371376
    372         HGCMSvcSetU32(&pMsg->m_paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pCtx->pTransfer->State.uID, uEvent));
    373         HGCMSvcSetU64(&pMsg->m_paParms[1], hList);
    374         HGCMSvcSetU32(&pMsg->m_paParms[2], 0 /* fInfo */);
     377        HGCMSvcSetU32(&pMsg->paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->State.uSessionID,
     378                                                                              pCtx->pTransfer->State.uID, uEvent));
     379        HGCMSvcSetU64(&pMsg->paParms[1], hList);
     380        HGCMSvcSetU32(&pMsg->paParms[2], 0 /* fInfo */);
    375381
    376382        rc = sharedClipboardSvcMsgAdd(pClient, pMsg, true /* fAppend */);
     
    433439        const uint32_t cbPath = (uint32_t)strlen(pCreateParms->pszPath) + 1; /* Include terminating zero */
    434440
    435         HGCMSvcSetU32(&pMsg->m_paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pCtx->pTransfer->State.uID, uEvent));
    436         HGCMSvcSetU64(&pMsg->m_paParms[1], 0); /* uHandle */
    437         HGCMSvcSetU32(&pMsg->m_paParms[2], cbPath);
    438         HGCMSvcSetPv (&pMsg->m_paParms[3], pCreateParms->pszPath, cbPath);
    439         HGCMSvcSetU32(&pMsg->m_paParms[4], pCreateParms->fCreate);
     441        HGCMSvcSetU32(&pMsg->paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->State.uSessionID,
     442                                                                              pCtx->pTransfer->State.uID, uEvent));
     443        HGCMSvcSetU64(&pMsg->paParms[1], 0); /* uHandle */
     444        HGCMSvcSetU32(&pMsg->paParms[2], cbPath);
     445        HGCMSvcSetPv (&pMsg->paParms[3], pCreateParms->pszPath, cbPath);
     446        HGCMSvcSetU32(&pMsg->paParms[4], pCreateParms->fCreate);
    440447
    441448        rc = sharedClipboardSvcMsgAdd(pClient, pMsg, true /* fAppend */);
     
    483490
    484491    PSHCLCLIENTMSG pMsg = sharedClipboardSvcMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_CLOSE,
    485                                                             VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_CLOSE);
     492                                                     VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_CLOSE);
    486493    if (pMsg)
    487494    {
    488495        const SHCLEVENTID uEvent = SharedClipboardEventIDGenerate(&pCtx->pTransfer->Events);
    489496
    490         HGCMSvcSetU32(&pMsg->m_paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pCtx->pTransfer->State.uID, uEvent));
    491         HGCMSvcSetU64(&pMsg->m_paParms[1], hObj);
     497        HGCMSvcSetU32(&pMsg->paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->State.uSessionID,
     498                                                                              pCtx->pTransfer->State.uID, uEvent));
     499        HGCMSvcSetU64(&pMsg->paParms[1], hObj);
    492500
    493501        rc = sharedClipboardSvcMsgAdd(pClient, pMsg, true /* fAppend */);
     
    536544
    537545    PSHCLCLIENTMSG pMsg = sharedClipboardSvcMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_READ,
    538                                                             VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_READ_REQ);
     546                                                     VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_READ_REQ);
    539547    if (pMsg)
    540548    {
    541549        const SHCLEVENTID uEvent = SharedClipboardEventIDGenerate(&pCtx->pTransfer->Events);
    542550
    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);
     551        HGCMSvcSetU32(&pMsg->paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->State.uSessionID,
     552                                                                              pCtx->pTransfer->State.uID, uEvent));
     553        HGCMSvcSetU64(&pMsg->paParms[1], hObj);
     554        HGCMSvcSetU32(&pMsg->paParms[2], cbData);
     555        HGCMSvcSetU32(&pMsg->paParms[3], fFlags);
    547556
    548557        rc = sharedClipboardSvcMsgAdd(pClient, pMsg, true /* fAppend */);
     
    594603
    595604    PSHCLCLIENTMSG pMsg = sharedClipboardSvcMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_WRITE,
    596                                                             VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_WRITE);
     605                                                     VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_WRITE);
    597606    if (pMsg)
    598607    {
    599608        const SHCLEVENTID uEvent = SharedClipboardEventIDGenerate(&pCtx->pTransfer->Events);
    600609
    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);
     610        HGCMSvcSetU32(&pMsg->paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->State.uSessionID,
     611                                                                              pCtx->pTransfer->State.uID, uEvent));
     612        HGCMSvcSetU64(&pMsg->paParms[1], hObj);
     613        HGCMSvcSetU64(&pMsg->paParms[2], cbData);
     614        HGCMSvcSetU64(&pMsg->paParms[3], fFlags);
    605615
    606616        rc = sharedClipboardSvcMsgAdd(pClient, pMsg, true /* fAppend */);
     
    697707        uint32_t cbPayload = 0;
    698708
     709        /* paParms[0] has the context ID. */
    699710        rc = HGCMSvcGetU32(&paParms[1], &pReply->uType);
    700711        if (RT_SUCCESS(rc))
     
    714725            switch (pReply->uType)
    715726            {
     727                case VBOX_SHCL_REPLYMSGTYPE_TRANSFER_STATUS:
     728                {
     729                    if (cParms >= 6)
     730                        rc = HGCMSvcGetU32(&paParms[5], &pReply->u.TransferStatus.uStatus);
     731                    break;
     732                }
     733
    716734                case VBOX_SHCL_REPLYMSGTYPE_LIST_OPEN:
    717735                {
     
    11511169    int rc;
    11521170
    1153     uint32_t            cbReply = sizeof(SHCLREPLY);
     1171    uint32_t   cbReply = sizeof(SHCLREPLY);
    11541172    PSHCLREPLY pReply  = (PSHCLREPLY)RTMemAlloc(cbReply);
    11551173    if (pReply)
     
    11671185                switch (pReply->uType)
    11681186                {
     1187                    case VBOX_SHCL_REPLYMSGTYPE_TRANSFER_STATUS:
     1188                        RT_FALL_THROUGH();
    11691189                    case VBOX_SHCL_REPLYMSGTYPE_LIST_OPEN:
    11701190                        RT_FALL_THROUGH();
     
    12371257
    12381258    LogFlowFunc(("uClient=%RU32, u32Function=%RU32 (%s), cParms=%RU32, g_ExtState.pfnExtension=%p\n",
    1239                  pClient->uClientID, u32Function, VBoxClipboardGuestMsgToStr(u32Function), cParms, g_ExtState.pfnExtension));
    1240 
     1259                 pClient->State.uClientID, u32Function, VBoxClipboardGuestMsgToStr(u32Function), cParms, g_ExtState.pfnExtension));
     1260
     1261#if 0
    12411262    /* Check if we've the right mode set. */
    12421263    if (!sharedClipboardSvcURIMsgIsAllowed(sharedClipboardSvcGetMode(), u32Function))
     
    12451266        return VERR_ACCESS_DENIED;
    12461267    }
     1268#endif
    12471269
    12481270    /* A (valid) service extension is needed because VBoxSVC needs to keep track of the
     
    12571279    }
    12581280
    1259     int rc = VINF_SUCCESS;
     1281    int rc = VERR_INVALID_PARAMETER; /* Play safe by default. */
    12601282
    12611283    /*
    12621284     * Pre-check: For certain messages we need to make sure that a (right) transfer is present.
    12631285     */
     1286    uint32_t         uCID      = 0; /* Context ID */
    12641287    PSHCLURITRANSFER pTransfer = NULL;
     1288
    12651289    switch (u32Function)
    12661290    {
     
    12721296            {
    12731297                LogFunc(("No transfers found\n"));
    1274                 rc = VERR_WRONG_ORDER;
     1298                rc = VERR_SHCLPB_TRANSFER_ID_NOT_FOUND;
    12751299                break;
    12761300            }
    12771301
    1278             const uint32_t uTransferID = 0; /* Only one transfer per client is supported at the moment. */
     1302            if (cParms < 1)
     1303                break;
     1304
     1305            rc = HGCMSvcGetU32(&paParms[0], &uCID);
     1306            if (RT_FAILURE(rc))
     1307                break;
     1308
     1309            const SHCLURITRANSFERID uTransferID = VBO_SHARED_CLIPBOARD_CONTEXTID_GET_TRANSFER(uCID);
    12791310
    12801311            pTransfer = SharedClipboardURICtxGetTransfer(&pClient->URI, uTransferID);
     
    12821313            {
    12831314                LogFunc(("Transfer with ID %RU32 not found\n", uTransferID));
    1284                 rc = VERR_WRONG_ORDER;
     1315                rc = VERR_SHCLPB_TRANSFER_ID_NOT_FOUND;
    12851316            }
    12861317            break;
     
    12921323
    12931324    rc = VERR_INVALID_PARAMETER; /* Play safe. */
     1325
     1326    bool fDoCallComplete = true;
    12941327
    12951328    switch (u32Function)
     
    13991432        {
    14001433            rc = sharedClipboardSvcURITransferHandleReply(pClient, pTransfer, cParms, paParms);
     1434
     1435            /* This message does not need any completion, as it can happen at any time from the guest side. */
     1436            fDoCallComplete = false;
    14011437            break;
    14021438        }
     
    14161452                uint32_t cbData = sizeof(SHCLROOTLISTHDR);
    14171453
    1418                 uint32_t uCID;
    1419                 rc = HGCMSvcGetU32(&paParms[0], &uCID);
     1454                const SHCLEVENTID uEvent = VBOX_SHARED_CLIPBOARD_CONTEXTID_GET_EVENT(uCID);
     1455
     1456                PSHCLEVENTPAYLOAD pPayload;
     1457                rc = SharedClipboardPayloadAlloc(uEvent, pvData, cbData, &pPayload);
    14201458                if (RT_SUCCESS(rc))
    14211459                {
     1460                    rc = SharedClipboardEventSignal(&pTransfer->Events, uEvent, pPayload);
     1461                    if (RT_FAILURE(rc))
     1462                        SharedClipboardPayloadFree(pPayload);
     1463                }
     1464            }
     1465            break;
     1466        }
     1467
     1468        case VBOX_SHARED_CLIPBOARD_GUEST_FN_ROOT_LIST_ENTRY_READ:
     1469        {
     1470    #if 0
     1471            SHCLROOTLISTENTRY lstEntry;
     1472            rc = VBoxSvcClipboardURIGetRootListEntry(cParms, paParms, &lstEntry);
     1473            if (RT_SUCCESS(rc))
     1474            {
     1475                void    *pvData = SharedClipboardURIRootListEntryDup(&lstEntry);
     1476                uint32_t cbData = sizeof(SHCLROOTLISTENTRY);
     1477
     1478                PSHCLURITRANSFERPAYLOAD pPayload;
     1479                rc = SharedClipboardURITransferPayloadAlloc(SHCLURITRANSFEREVENTTYPE_ROOT_LIST_HDR_READ,
     1480                                                            pvData, cbData, &pPayload);
     1481                if (RT_SUCCESS(rc))
     1482                    rc = SharedClipboardURITransferEventSignal(pTransfer, SHCLURITRANSFEREVENTTYPE_ROOT_LIST_HDR_READ,
     1483                                                               pPayload);
     1484            }
     1485            break;
     1486    #endif
     1487        }
     1488
     1489        case VBOX_SHARED_CLIPBOARD_GUEST_FN_ROOT_LIST_ENTRY_WRITE:
     1490        {
     1491            SHCLROOTLISTENTRY lstEntry;
     1492            rc = sharedClipboardSvcURIGetRootListEntry(cParms, paParms, &lstEntry);
     1493            if (RT_SUCCESS(rc))
     1494            {
     1495                void    *pvData = SharedClipboardURIRootListEntryDup(&lstEntry);
     1496                uint32_t cbData = sizeof(SHCLROOTLISTENTRY);
     1497
     1498                const SHCLEVENTID uEvent = VBOX_SHARED_CLIPBOARD_CONTEXTID_GET_EVENT(uCID);
     1499
     1500                PSHCLEVENTPAYLOAD pPayload;
     1501                rc = SharedClipboardPayloadAlloc(uEvent, pvData, cbData, &pPayload);
     1502                if (RT_SUCCESS(rc))
     1503                {
     1504                    rc = SharedClipboardEventSignal(&pTransfer->Events, uEvent, pPayload);
     1505                    if (RT_FAILURE(rc))
     1506                        SharedClipboardPayloadFree(pPayload);
     1507                }
     1508            }
     1509            break;
     1510        }
     1511
     1512        case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_OPEN:
     1513        {
     1514            SHCLLISTOPENPARMS listOpenParms;
     1515            rc = sharedClipboardSvcURIGetListOpen(cParms, paParms, &listOpenParms);
     1516            if (RT_SUCCESS(rc))
     1517            {
     1518                SHCLLISTHANDLE hList;
     1519                rc = SharedClipboardURITransferListOpen(pTransfer, &listOpenParms, &hList);
     1520                if (RT_SUCCESS(rc))
     1521                {
     1522                    /* Return list handle. */
     1523                    HGCMSvcSetU32(&paParms[1], hList);
     1524                }
     1525            }
     1526            break;
     1527        }
     1528
     1529        case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_CLOSE:
     1530        {
     1531            if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_LIST_CLOSE)
     1532                break;
     1533
     1534            SHCLLISTHANDLE hList;
     1535            rc = HGCMSvcGetU64(&paParms[1], &hList);
     1536            if (RT_SUCCESS(rc))
     1537            {
     1538                rc = SharedClipboardURITransferListClose(pTransfer, hList);
     1539            }
     1540            break;
     1541        }
     1542
     1543        case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_READ:
     1544        {
     1545            if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR)
     1546                break;
     1547
     1548            SHCLLISTHANDLE hList;
     1549            rc = HGCMSvcGetU64(&paParms[1], &hList); /* Get list handle. */
     1550            if (RT_SUCCESS(rc))
     1551            {
     1552                SHCLLISTHDR hdrList;
     1553                rc = SharedClipboardURITransferListGetHeader(pTransfer, hList, &hdrList);
     1554                /*if (RT_SUCCESS(rc))
     1555                    rc = sharedClipboardSvcURISetListHdr(cParms, paParms, &hdrList);*/
     1556            }
     1557            break;
     1558        }
     1559
     1560        case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_WRITE:
     1561        {
     1562            SHCLLISTHDR hdrList;
     1563            rc = SharedClipboardURIListHdrInit(&hdrList);
     1564            if (RT_SUCCESS(rc))
     1565            {
     1566                SHCLLISTHANDLE hList;
     1567                rc = sharedClipboardSvcURIGetListHdr(cParms, paParms, &hList, &hdrList);
     1568                if (RT_SUCCESS(rc))
     1569                {
     1570                    void    *pvData = SharedClipboardURIListHdrDup(&hdrList);
     1571                    uint32_t cbData = sizeof(SHCLLISTHDR);
     1572
    14221573                    const SHCLEVENTID uEvent = VBOX_SHARED_CLIPBOARD_CONTEXTID_GET_EVENT(uCID);
    14231574
     
    14351586        }
    14361587
    1437         case VBOX_SHARED_CLIPBOARD_GUEST_FN_ROOT_LIST_ENTRY_READ:
    1438         {
    1439     #if 0
    1440             SHCLROOTLISTENTRY lstEntry;
    1441             rc = VBoxSvcClipboardURIGetRootListEntry(cParms, paParms, &lstEntry);
    1442             if (RT_SUCCESS(rc))
    1443             {
    1444                 void    *pvData = SharedClipboardURIRootListEntryDup(&lstEntry);
    1445                 uint32_t cbData = sizeof(SHCLROOTLISTENTRY);
    1446 
    1447                 PSHCLURITRANSFERPAYLOAD pPayload;
    1448                 rc = SharedClipboardURITransferPayloadAlloc(SHCLURITRANSFEREVENTTYPE_ROOT_LIST_HDR_READ,
    1449                                                             pvData, cbData, &pPayload);
     1588        case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_ENTRY_READ:
     1589        {
     1590            if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY)
     1591                break;
     1592
     1593            SHCLLISTHANDLE hList;
     1594            rc = HGCMSvcGetU64(&paParms[1], &hList); /* Get list handle. */
     1595            if (RT_SUCCESS(rc))
     1596            {
     1597                SHCLLISTENTRY entryList;
     1598                rc = SharedClipboardURITransferListRead(pTransfer, hList, &entryList);
     1599            }
     1600            break;
     1601        }
     1602
     1603        case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_ENTRY_WRITE:
     1604        {
     1605            SHCLLISTENTRY entryList;
     1606            rc = SharedClipboardURIListEntryInit(&entryList);
     1607            if (RT_SUCCESS(rc))
     1608            {
     1609                SHCLLISTHANDLE hList;
     1610                rc = sharedClipboardSvcURIGetListEntry(cParms, paParms, &hList, &entryList);
    14501611                if (RT_SUCCESS(rc))
    1451                     rc = SharedClipboardURITransferEventSignal(pTransfer, SHCLURITRANSFEREVENTTYPE_ROOT_LIST_HDR_READ,
    1452                                                                pPayload);
    1453             }
    1454             break;
    1455     #endif
    1456         }
    1457 
    1458         case VBOX_SHARED_CLIPBOARD_GUEST_FN_ROOT_LIST_ENTRY_WRITE:
    1459         {
    1460             SHCLROOTLISTENTRY lstEntry;
    1461             rc = sharedClipboardSvcURIGetRootListEntry(cParms, paParms, &lstEntry);
    1462             if (RT_SUCCESS(rc))
    1463             {
    1464                 void    *pvData = SharedClipboardURIRootListEntryDup(&lstEntry);
    1465                 uint32_t cbData = sizeof(SHCLROOTLISTENTRY);
    1466 
    1467                 uint32_t uCID;
    1468                 rc = HGCMSvcGetU32(&paParms[0], &uCID);
    1469                 if (RT_SUCCESS(rc))
    1470                 {
     1612                {
     1613                    void    *pvData = SharedClipboardURIListEntryDup(&entryList);
     1614                    uint32_t cbData = sizeof(SHCLLISTENTRY);
     1615
    14711616                    const SHCLEVENTID uEvent = VBOX_SHARED_CLIPBOARD_CONTEXTID_GET_EVENT(uCID);
    14721617
     
    14841629        }
    14851630
    1486         case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_OPEN:
    1487         {
    1488             SHCLLISTOPENPARMS listOpenParms;
    1489             rc = sharedClipboardSvcURIGetListOpen(cParms, paParms, &listOpenParms);
    1490             if (RT_SUCCESS(rc))
    1491             {
    1492                 SHCLLISTHANDLE hList;
    1493                 rc = SharedClipboardURITransferListOpen(pTransfer, &listOpenParms, &hList);
    1494                 if (RT_SUCCESS(rc))
    1495                 {
    1496                     /* Return list handle. */
    1497                     HGCMSvcSetU32(&paParms[1], hList);
    1498                 }
    1499             }
    1500             break;
    1501         }
    1502 
    1503         case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_CLOSE:
    1504         {
    1505             if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_LIST_CLOSE)
    1506                 break;
    1507 
    1508             SHCLLISTHANDLE hList;
    1509             rc = HGCMSvcGetU64(&paParms[1], &hList);
    1510             if (RT_SUCCESS(rc))
    1511             {
    1512                 rc = SharedClipboardURITransferListClose(pTransfer, hList);
    1513             }
    1514             break;
    1515         }
    1516 
    1517         case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_READ:
    1518         {
    1519             if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR)
    1520                 break;
    1521 
    1522             SHCLLISTHANDLE hList;
    1523             rc = HGCMSvcGetU64(&paParms[1], &hList); /* Get list handle. */
    1524             if (RT_SUCCESS(rc))
    1525             {
    1526                 SHCLLISTHDR hdrList;
    1527                 rc = SharedClipboardURITransferListGetHeader(pTransfer, hList, &hdrList);
    1528                 /*if (RT_SUCCESS(rc))
    1529                     rc = sharedClipboardSvcURISetListHdr(cParms, paParms, &hdrList);*/
    1530             }
    1531             break;
    1532         }
    1533 
    1534         case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_WRITE:
    1535         {
    1536             SHCLLISTHDR hdrList;
    1537             rc = SharedClipboardURIListHdrInit(&hdrList);
    1538             if (RT_SUCCESS(rc))
    1539             {
    1540                 SHCLLISTHANDLE hList;
    1541                 rc = sharedClipboardSvcURIGetListHdr(cParms, paParms, &hList, &hdrList);
    1542                 if (RT_SUCCESS(rc))
    1543                 {
    1544                     void    *pvData = SharedClipboardURIListHdrDup(&hdrList);
    1545                     uint32_t cbData = sizeof(SHCLLISTHDR);
    1546 
    1547                     uint32_t uCID;
    1548                     rc = HGCMSvcGetU32(&paParms[0], &uCID);
    1549                     if (RT_SUCCESS(rc))
    1550                     {
    1551                         const SHCLEVENTID uEvent = VBOX_SHARED_CLIPBOARD_CONTEXTID_GET_EVENT(uCID);
    1552 
    1553                         PSHCLEVENTPAYLOAD pPayload;
    1554                         rc = SharedClipboardPayloadAlloc(uEvent, pvData, cbData, &pPayload);
    1555                         if (RT_SUCCESS(rc))
    1556                         {
    1557                             rc = SharedClipboardEventSignal(&pTransfer->Events, uEvent, pPayload);
    1558                             if (RT_FAILURE(rc))
    1559                                 SharedClipboardPayloadFree(pPayload);
    1560                         }
    1561                     }
    1562                 }
    1563             }
    1564             break;
    1565         }
    1566 
    1567         case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_ENTRY_READ:
    1568         {
    1569             if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY)
    1570                 break;
    1571 
    1572             SHCLLISTHANDLE hList;
    1573             rc = HGCMSvcGetU64(&paParms[1], &hList); /* Get list handle. */
    1574             if (RT_SUCCESS(rc))
    1575             {
    1576                 SHCLLISTENTRY entryList;
    1577                 rc = SharedClipboardURITransferListRead(pTransfer, hList, &entryList);
    1578             }
    1579             break;
    1580         }
    1581 
    1582         case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_ENTRY_WRITE:
    1583         {
    1584             SHCLLISTENTRY entryList;
    1585             rc = SharedClipboardURIListEntryInit(&entryList);
    1586             if (RT_SUCCESS(rc))
    1587             {
    1588                 SHCLLISTHANDLE hList;
    1589                 rc = sharedClipboardSvcURIGetListEntry(cParms, paParms, &hList, &entryList);
    1590                 if (RT_SUCCESS(rc))
    1591                 {
    1592                     void    *pvData = SharedClipboardURIListEntryDup(&entryList);
    1593                     uint32_t cbData = sizeof(SHCLLISTENTRY);
    1594 
    1595                     uint32_t uCID;
    1596                     rc = HGCMSvcGetU32(&paParms[0], &uCID);
    1597                     if (RT_SUCCESS(rc))
    1598                     {
    1599                         const SHCLEVENTID uEvent = VBOX_SHARED_CLIPBOARD_CONTEXTID_GET_EVENT(uCID);
    1600 
    1601                         PSHCLEVENTPAYLOAD pPayload;
    1602                         rc = SharedClipboardPayloadAlloc(uEvent, pvData, cbData, &pPayload);
    1603                         if (RT_SUCCESS(rc))
    1604                         {
    1605                             rc = SharedClipboardEventSignal(&pTransfer->Events, uEvent, pPayload);
    1606                             if (RT_FAILURE(rc))
    1607                                 SharedClipboardPayloadFree(pPayload);
    1608                         }
    1609                     }
    1610                 }
    1611             }
    1612             break;
    1613         }
    1614 
    16151631    #if 0
    16161632        case VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_OPEN:
     
    16391655                uint32_t cbData = sizeof(SHCLOBJDATACHUNK);
    16401656
    1641                 uint32_t uCID;
    1642                 rc = HGCMSvcGetU32(&paParms[0], &uCID);
     1657                const SHCLEVENTID uEvent = VBOX_SHARED_CLIPBOARD_CONTEXTID_GET_EVENT(uCID);
     1658
     1659                PSHCLEVENTPAYLOAD pPayload;
     1660                rc = SharedClipboardPayloadAlloc(uEvent, pvData, cbData, &pPayload);
    16431661                if (RT_SUCCESS(rc))
    16441662                {
    1645                     const SHCLEVENTID uEvent = VBOX_SHARED_CLIPBOARD_CONTEXTID_GET_EVENT(uCID);
    1646 
    1647                     PSHCLEVENTPAYLOAD pPayload;
    1648                     rc = SharedClipboardPayloadAlloc(uEvent, pvData, cbData, &pPayload);
    1649                     if (RT_SUCCESS(rc))
    1650                     {
    1651                         rc = SharedClipboardEventSignal(&pTransfer->Events, uEvent, pPayload);
    1652                         if (RT_FAILURE(rc))
    1653                             SharedClipboardPayloadFree(pPayload);
    1654                     }
     1663                    rc = SharedClipboardEventSignal(&pTransfer->Events, uEvent, pPayload);
     1664                    if (RT_FAILURE(rc))
     1665                        SharedClipboardPayloadFree(pPayload);
    16551666                }
    16561667            }
     
    18491860    }
    18501861
    1851     if (rc != VINF_HGCM_ASYNC_EXECUTE)
     1862    if (fDoCallComplete)
    18521863    {
    18531864        /* Tell the client that the call is complete (unblocks waiting). */
    1854         LogFlowFunc(("[Client %RU32] Calling pfnCallComplete w/ rc=%Rrc\n", pClient->uClientID, rc));
     1865        LogFlowFunc(("[Client %RU32] Calling pfnCallComplete w/ rc=%Rrc\n", pClient->State.uClientID, rc));
    18551866        AssertPtr(g_pHelpers);
    18561867        g_pHelpers->pfnCallComplete(callHandle, rc);
    18571868    }
    18581869
    1859     LogFlowFunc(("[Client %RU32] Returning rc=%Rrc\n", pClient->uClientID, rc));
     1870    LogFlowFunc(("[Client %RU32] Returning rc=%Rrc\n", pClient->State.uClientID, rc));
    18601871    return rc;
    18611872}
     
    19341945
    19351946        LogFlowFunc(("Registered new clipboard area (%RU32) by client %RU32 with rc=%Rrc\n",
    1936                      parms.uID, pClientState->u32ClientID, rc));
     1947                     parms.uID, pClientState->uClientID, rc));
    19371948    }
    19381949    else
     
    19801991
    19811992        LogFlowFunc(("Unregistered clipboard area (%RU32) by client %RU32 with rc=%Rrc\n",
    1982                      parms.uID, pClientState->u32ClientID, rc));
     1993                     parms.uID, pClientState->uClientID, rc));
    19831994    }
    19841995
     
    20302041
    20312042        LogFlowFunc(("Attached client %RU32 to clipboard area %RU32 with rc=%Rrc\n",
    2032                      pClientState->u32ClientID, parms.uID, rc));
     2043                     pClientState->uClientID, parms.uID, rc));
    20332044    }
    20342045    else
     
    20682079
    20692080        LogFlowFunc(("Detached client %RU32 from clipboard area %RU32 with rc=%Rrc\n",
    2070                      pClientState->u32ClientID, uAreaID, rc));
     2081                     pClientState->uClientID, uAreaID, rc));
    20712082    }
    20722083
     
    20782089}
    20792090
     2091/**
     2092 * Reports a transfer status to the guest.
     2093 *
     2094 * @returns VBox status code.
     2095 * @param   pClient             Client that owns the transfer.
     2096 * @param   pTransfer           Transfer to report status for.
     2097 * @param   uStatus             Status to report.
     2098 * @param   rcTransfer          Result code to report. Optional and depending on status.
     2099 * @param   puEvent             Where to store the created wait event. Optional.
     2100 */
     2101int sharedClipboardSvcURITransferSendStatus(PSHCLCLIENT pClient, PSHCLURITRANSFER pTransfer, SHCLURITRANSFERSTATUS uStatus,
     2102                                            int rcTransfer, PSHCLEVENTID puEvent)
     2103{
     2104    AssertPtrReturn(pClient,   VERR_INVALID_POINTER);
     2105    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     2106    /* puEvent is optional. */
     2107
     2108    PSHCLCLIENTMSG pMsgReadData = sharedClipboardSvcMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_TRANSFER_STATUS,
     2109                                                             VBOX_SHARED_CLIPBOARD_CPARMS_TRANSFER_STATUS);
     2110    if (!pMsgReadData)
     2111        return VERR_NO_MEMORY;
     2112
     2113    const SHCLEVENTID uEvent = SharedClipboardEventIDGenerate(&pTransfer->Events);
     2114
     2115    HGCMSvcSetU32(&pMsgReadData->paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->State.uSessionID,
     2116                                                                                  pTransfer->State.uID, uEvent));
     2117    HGCMSvcSetU32(&pMsgReadData->paParms[1], pTransfer->State.enmDir);
     2118    HGCMSvcSetU32(&pMsgReadData->paParms[2], uStatus);
     2119    HGCMSvcSetU32(&pMsgReadData->paParms[3], (uint32_t)rcTransfer); /** @todo uint32_t vs. int. */
     2120    HGCMSvcSetU32(&pMsgReadData->paParms[4], 0 /* fFlags, unused */);
     2121
     2122    int rc = sharedClipboardSvcMsgAdd(pClient, pMsgReadData, true /* fAppend */);
     2123    if (RT_SUCCESS(rc))
     2124    {
     2125        rc = SharedClipboardEventRegister(&pTransfer->Events, uEvent);
     2126        if (RT_SUCCESS(rc))
     2127        {
     2128            rc = sharedClipboardSvcClientWakeup(pClient);
     2129            if (RT_SUCCESS(rc))
     2130            {
     2131                LogRel2(("Shared Clipboard: Reported status %s (rc=%Rrc) of transfer %RU32 to guest\n",
     2132                         VBoxClipboardTransferStatusToStr(uStatus), rcTransfer, pTransfer->State.uID));
     2133
     2134                if (puEvent)
     2135                    *puEvent = uEvent;
     2136            }
     2137            else
     2138                SharedClipboardEventUnregister(&pTransfer->Events, uEvent);
     2139        }
     2140    }
     2141
     2142    LogFlowFuncLeaveRC(rc);
     2143    return rc;
     2144}
     2145
     2146/**
     2147 * Starts a new transfer, waiting for acknowledgement by the guest side.
     2148 *
     2149 * @returns VBox status code.
     2150 * @param   pClient             Client that owns the transfer.
     2151 * @param   enmDir              Transfer direction to start.
     2152 * @param   enmSource           Transfer source to start.
     2153 * @param   ppTransfer          Where to return the created transfer on success. Optional.
     2154 */
     2155int sharedClipboardSvcURITransferStart(PSHCLCLIENT pClient,
     2156                                       SHCLURITRANSFERDIR enmDir, SHCLSOURCE enmSource,
     2157                                       PSHCLURITRANSFER *ppTransfer)
     2158{
     2159    AssertPtrReturn(pClient, VERR_INVALID_POINTER);
     2160    /* ppTransfer is optional. */
     2161
     2162    LogFlowFuncEnter();
     2163
     2164    SharedClipboardURICtxTransfersCleanup(&pClient->URI);
     2165
     2166    int rc;
     2167
     2168    if (!SharedClipboardURICtxTransfersMaximumReached(&pClient->URI))
     2169    {
     2170        LogRel2(("Shared Clipboard: Starting %s transfer ...\n", enmDir == SHCLURITRANSFERDIR_READ ? "read" : "write"));
     2171
     2172        PSHCLURITRANSFER pTransfer;
     2173        rc = SharedClipboardURITransferCreate(&pTransfer);
     2174        if (RT_SUCCESS(rc))
     2175        {
     2176            SHCLPROVIDERCREATIONCTX creationCtx;
     2177            RT_ZERO(creationCtx);
     2178
     2179            if (enmDir == SHCLURITRANSFERDIR_READ)
     2180            {
     2181                rc = sharedClipboardSvcURIAreaRegister(&pClient->State, pTransfer);
     2182                if (RT_SUCCESS(rc))
     2183                {
     2184                    creationCtx.Interface.pfnTransferOpen    = sharedClipboardSvcURITransferOpen;
     2185                    creationCtx.Interface.pfnTransferClose   = sharedClipboardSvcURITransferClose;
     2186                    creationCtx.Interface.pfnListOpen        = sharedClipboardSvcURIListOpen;
     2187                    creationCtx.Interface.pfnListClose       = sharedClipboardSvcURIListClose;
     2188                    creationCtx.Interface.pfnObjOpen         = sharedClipboardSvcURIObjOpen;
     2189                    creationCtx.Interface.pfnObjClose        = sharedClipboardSvcURIObjClose;
     2190
     2191                    creationCtx.Interface.pfnGetRoots        = sharedClipboardSvcURIGetRoots;
     2192                    creationCtx.Interface.pfnListHdrRead     = sharedClipboardSvcURIListHdrRead;
     2193                    creationCtx.Interface.pfnListEntryRead   = sharedClipboardSvcURIListEntryRead;
     2194                    creationCtx.Interface.pfnObjRead         = sharedClipboardSvcURIObjRead;
     2195                }
     2196            }
     2197            else if (enmDir == SHCLURITRANSFERDIR_WRITE)
     2198            {
     2199                creationCtx.Interface.pfnListHdrWrite   = sharedClipboardSvcURIListHdrWrite;
     2200                creationCtx.Interface.pfnListEntryWrite = sharedClipboardSvcURIListEntryWrite;
     2201                creationCtx.Interface.pfnObjWrite       = sharedClipboardSvcURIObjWrite;
     2202            }
     2203            else
     2204                AssertFailed();
     2205
     2206            creationCtx.enmSource = pClient->State.enmSource;
     2207            creationCtx.pvUser    = pClient;
     2208
     2209            /* Register needed callbacks so that we can wait for the meta data to arrive here. */
     2210            SHCLURITRANSFERCALLBACKS Callbacks;
     2211            RT_ZERO(Callbacks);
     2212
     2213            Callbacks.pvUser                = pClient;
     2214
     2215            Callbacks.pfnTransferPrepare    = VBoxSvcClipboardURITransferPrepareCallback;
     2216            Callbacks.pfnTransferComplete   = VBoxSvcClipboardURITransferCompleteCallback;
     2217            Callbacks.pfnTransferCanceled   = VBoxSvcClipboardURITransferCanceledCallback;
     2218            Callbacks.pfnTransferError      = VBoxSvcClipboardURITransferErrorCallback;
     2219
     2220            SharedClipboardURITransferSetCallbacks(pTransfer, &Callbacks);
     2221
     2222            uint32_t uTransferID = 0;
     2223
     2224            rc = SharedClipboardURITransferSetInterface(pTransfer, &creationCtx);
     2225            if (RT_SUCCESS(rc))
     2226            {
     2227                rc = SharedClipboardSvcImplURITransferCreate(pClient, pTransfer);
     2228                if (RT_SUCCESS(rc))
     2229                {
     2230                    rc = SharedClipboardURICtxTransferRegister(&pClient->URI, pTransfer, &uTransferID);
     2231                    if (RT_SUCCESS(rc))
     2232                    {
     2233                        rc = SharedClipboardURITransferInit(pTransfer, uTransferID, enmDir, enmSource);
     2234                        if (RT_SUCCESS(rc))
     2235                        {
     2236                            SHCLEVENTID uEvent;
     2237                            rc = sharedClipboardSvcURITransferSendStatus(pClient, pTransfer,
     2238                                                                         SHCLURITRANSFERSTATUS_READY, VINF_SUCCESS,
     2239                                                                         &uEvent);
     2240                            if (RT_SUCCESS(rc))
     2241                            {
     2242                                LogRel2(("Shared Clipboard: Waiting for start of transfer %RU32 on guest ...\n",
     2243                                         pTransfer->State.uID));
     2244
     2245                                PSHCLEVENTPAYLOAD pPayload;
     2246                                rc = SharedClipboardEventWait(&pTransfer->Events, uEvent, pTransfer->uTimeoutMs, &pPayload);
     2247                                if (RT_SUCCESS(rc))
     2248                                {
     2249                                    Assert(pPayload->cbData == sizeof(SHCLREPLY));
     2250                                    PSHCLREPLY pReply = (PSHCLREPLY)pPayload->pvData;
     2251                                    AssertPtr(pReply);
     2252
     2253                                    Assert(pReply->uType == VBOX_SHCL_REPLYMSGTYPE_TRANSFER_STATUS);
     2254
     2255                                    if (pReply->u.TransferStatus.uStatus)
     2256                                    {
     2257                                        LogRel2(("Shared Clipboard: Started transfer %RU32 on guest\n", pTransfer->State.uID));
     2258                                    }
     2259                                    else
     2260                                        LogRel(("Shared Clipboard: Guest reported status %s (error %Rrc) while starting transfer %RU32\n",
     2261                                                VBoxClipboardTransferStatusToStr(pReply->u.TransferStatus.uStatus),
     2262                                                pReply->rc, pTransfer->State.uID));
     2263                                }
     2264                                else
     2265                                   LogRel(("Shared Clipboard: Unable to start transfer %RU32 on guest, rc=%Rrc\n",
     2266                                           pTransfer->State.uID, rc));
     2267                            }
     2268                        }
     2269                    }
     2270                }
     2271            }
     2272
     2273            if (RT_FAILURE(rc))
     2274            {
     2275                SharedClipboardURICtxTransferUnregister(&pClient->URI, uTransferID);
     2276
     2277                SharedClipboardURITransferDestroy(pTransfer);
     2278
     2279                RTMemFree(pTransfer);
     2280                pTransfer = NULL;
     2281            }
     2282            else
     2283            {
     2284                if (ppTransfer)
     2285                    *ppTransfer = pTransfer;
     2286            }
     2287        }
     2288
     2289        if (RT_FAILURE(rc))
     2290            LogRel(("Shared Clipboard: Starting transfer failed with %Rrc\n", rc));
     2291    }
     2292    else
     2293        rc = VERR_SHCLPB_MAX_TRANSFERS_REACHED;
     2294
     2295    LogFlowFuncLeaveRC(rc);
     2296    return rc;
     2297}
     2298
     2299/**
     2300 * Stops a transfer, communicating the status to the guest side.
     2301 *
     2302 * @returns VBox status code.
     2303 * @param   pClient             Client that owns the transfer.
     2304 * @param   pTransfer           Transfer to stop.
     2305 */
     2306int sharedClipboardSvcURITransferStop(PSHCLCLIENT pClient, PSHCLURITRANSFER pTransfer)
     2307{
     2308    int rc = SharedClipboardURITransferClose(pTransfer);
     2309    if (RT_SUCCESS(rc))
     2310    {
     2311        SHCLEVENTID uEvent;
     2312        rc = sharedClipboardSvcURITransferSendStatus(pClient, pTransfer,
     2313                                                     SHCLURITRANSFERSTATUS_STOPPED, VINF_SUCCESS,
     2314                                                     &uEvent);
     2315        if (RT_SUCCESS(rc))
     2316        {
     2317            LogRel2(("Shared Clipboard: Waiting for stop of transfer %RU32 on guest ...\n", pTransfer->State.uID));
     2318
     2319            rc = SharedClipboardEventWait(&pTransfer->Events, uEvent, pTransfer->uTimeoutMs, NULL);
     2320            if (RT_SUCCESS(rc))
     2321            {
     2322                rc = SharedClipboardURICtxTransferUnregister(&pClient->URI, SharedClipboardURITransferGetID(pTransfer));
     2323
     2324                LogRel2(("Shared Clipboard: Stopped transfer %RU32 on guest\n", pTransfer->State.uID));
     2325            }
     2326            else
     2327               LogRel(("Shared Clipboard: Unable to stop transfer %RU32 on guest, rc=%Rrc\n",
     2328                       pTransfer->State.uID, rc));
     2329        }
     2330    }
     2331
     2332    LogFlowFuncLeaveRC(rc);
     2333    return rc;
     2334}
     2335
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp

    r80664 r80845  
    5858{
    5959    /** Handle for window message handling thread. */
    60     RTTHREAD                 hThread;
     60    RTTHREAD    hThread;
    6161    /** Structure for keeping and communicating with service client. */
    62     PSHCLCLIENT     pClient;
     62    PSHCLCLIENT pClient;
    6363    /** Windows-specific context data. */
    64     SHCLWINCTX      Win;
     64    SHCLWINCTX  Win;
    6565};
    6666
     
    213213        case WM_CLIPBOARDUPDATE:
    214214        {
    215             const HWND hWndClipboardOwner = GetClipboardOwner();
    216             if (pWinCtx->hWndClipboardOwnerUs != hWndClipboardOwner)
    217             {
     215            LogFunc(("WM_CLIPBOARDUPDATE: Waiting ...\n"));
     216
     217            int rc = RTCritSectEnter(&pWinCtx->CritSect);
     218            if (RT_SUCCESS(rc))
     219            {
     220                const HWND hWndClipboardOwner = GetClipboardOwner();
     221
    218222                LogFunc(("WM_CLIPBOARDUPDATE: hWndClipboardOwnerUs=%p, hWndNewClipboardOwner=%p\n",
    219223                         pWinCtx->hWndClipboardOwnerUs, hWndClipboardOwner));
    220224
    221                 /* Clipboard was updated by another application, retrieve formats and report back. */
    222                 int rc = vboxClipboardSvcWinSyncInternal(pCtx);
    223                 if (RT_SUCCESS(rc))
    224                     sharedClipboardSvcSetSource(pCtx->pClient, SHCLSOURCE_LOCAL);
    225             }
     225                if (pWinCtx->hWndClipboardOwnerUs != hWndClipboardOwner)
     226                {
     227                    int rc2 = RTCritSectLeave(&pWinCtx->CritSect);
     228                    AssertRC(rc2);
     229
     230                    /* Clipboard was updated by another application, retrieve formats and report back. */
     231                    rc = vboxClipboardSvcWinSyncInternal(pCtx);
     232                    if (RT_SUCCESS(rc))
     233                        rc = sharedClipboardSvcSetSource(pCtx->pClient, SHCLSOURCE_LOCAL);
     234                }
     235                else
     236                {
     237                    int rc2 = RTCritSectLeave(&pWinCtx->CritSect);
     238                    AssertRC(rc2);
     239                }
     240            }
     241
     242            if (RT_FAILURE(rc))
     243                LogRel(("Shared Clipboard: WM_CLIPBOARDUPDATE failed with %Rrc\n", rc));
    226244
    227245            break;
     
    311329        case SHCL_WIN_WM_REPORT_FORMATS:
    312330        {
    313             LogFunc(("VBOX_CLIPBOARD_WM_REPORT_FORMATS\n"));
    314 
    315             /* Announce available formats. Do not insert data -- will be inserted in WM_RENDERFORMAT. */
     331            /* Announce available formats. Do not insert data -- will be inserted in WM_RENDERFORMAT (or via IDataObject). */
    316332            SHCLFORMATS fFormats = (uint32_t)lParam;
    317             if (fFormats != VBOX_SHARED_CLIPBOARD_FMT_NONE) /* Could arrive with some older GA versions. */
    318             {
     333            LogFunc(("SHCL_WIN_WM_REPORT_FORMATS: fFormats=0x%x\n", fFormats));
     334
     335            if (fFormats == VBOX_SHARED_CLIPBOARD_FMT_NONE) /* Could arrive with some older GA versions. */
     336                break;
     337
     338#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     339            if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
     340            {
     341                PSHCLURITRANSFER pTransfer;
     342                int rc = sharedClipboardSvcURITransferStart(pCtx->pClient,
     343                                                            SHCLURITRANSFERDIR_READ, SHCLSOURCE_REMOTE,
     344                                                            &pTransfer);
     345                if (RT_SUCCESS(rc))
     346                {
     347                    /* Create the IDataObject implementation the host OS needs and assign
     348                     * the newly created transfer to this object. */
     349                    rc = SharedClipboardWinURITransferCreate(&pCtx->Win, pTransfer);
     350
     351                    /*  Note: The actual requesting + retrieving of data will be done in the IDataObject implementation
     352                              (ClipboardDataObjectImpl::GetData()). */
     353                }
     354                else
     355                    LogRel(("Shared Clipboard: Initializing read transfer failed with %Rrc\n", rc));
     356            }
     357            else
     358            {
     359#endif
    319360                int rc = SharedClipboardWinOpen(hWnd);
    320361                if (RT_SUCCESS(rc))
     
    326367                    SharedClipboardWinClose();
    327368                }
    328 
    329                 LogFunc(("VBOX_CLIPBOARD_WM_REPORT_FORMATS: fFormats=0x%x, lastErr=%ld\n", fFormats, GetLastError()));
    330             }
    331 
     369#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     370            }
     371#endif
     372            LogFunc(("SHCL_WIN_WM_REPORT_FORMATS: lastErr=%ld\n", GetLastError()));
    332373            break;
    333374        }
     
    457498                if (FAILED(hr))
    458499                {
    459                     LogRel(("Clipboard: Initializing OLE failed (%Rhrc) -- file transfers unavailable\n"));
     500                    LogRel(("Shared Clipboard: Initializing window thread OLE failed (%Rhrc) -- file transfers unavailable\n", hr));
    460501                    /* Not critical, the rest of the clipboard might work. */
    461502                }
    462503                else
    463                     LogRel(("Clipboard: Initialized OLE\n"));
    464             }
    465 #endif
    466 
     504                    LogRel(("Shared Clipboard: Initialized window thread OLE\n"));
     505            }
     506#endif
    467507            int rc2 = RTThreadUserSignal(hThreadSelf);
    468508            AssertRC(rc2);
     
    550590int SharedClipboardSvcImplInit(void)
    551591{
    552     /* Initialization is done in SharedClipboardSvcImplConnect(). */
     592#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     593    HRESULT hr = OleInitialize(NULL);
     594    if (FAILED(hr))
     595    {
     596        LogRel(("Shared Clipboard: Initializing OLE failed (%Rhrc) -- file transfers unavailable\n", hr));
     597        /* Not critical, the rest of the clipboard might work. */
     598    }
     599    else
     600        LogRel(("Shared Clipboard: Initialized OLE\n"));
     601#endif
     602
    553603    return VINF_SUCCESS;
    554604}
     
    556606void SharedClipboardSvcImplDestroy(void)
    557607{
    558     /* Destruction is done in SharedClipboardSvcImplDisconnect(). */
     608#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     609    OleSetClipboard(NULL); /* Make sure to flush the clipboard on destruction. */
     610    OleUninitialize();
     611#endif
    559612}
    560613
     
    570623    if (pCtx)
    571624    {
    572         /* Check that new Clipboard API is available. */
    573         rc = SharedClipboardWinCheckAndInitNewAPI(&pCtx->Win.newAPI);
     625        rc = SharedClipboardWinCtxInit(&pCtx->Win);
    574626        if (RT_SUCCESS(rc))
    575627        {
     
    628680        }
    629681
     682        SharedClipboardWinCtxDestroy(&pCtx->Win);
     683
    630684        if (RT_SUCCESS(rc))
    631685        {
     
    654708    LogFlowFunc(("uFormats=0x%x, hWnd=%p\n", pFormats->uFormats, pCtx->Win.hWnd));
    655709
    656 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    657     if (pFormats->uFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
    658     {
    659         PSHCLURITRANSFER pTransfer;
    660         rc = sharedClipboardSvcURITransferStart(pClient,
    661                                                 SHCLURITRANSFERDIR_READ, SHCLSOURCE_REMOTE,
    662                                                 &pTransfer);
    663         if (RT_SUCCESS(rc))
    664         {
    665             /* Create the IDataObject implementation the host OS needs and assign
    666              * the newly created transfer to this object. */
    667             rc = SharedClipboardWinURITransferCreate(&pCtx->Win, pTransfer);
    668 
    669             /*  Note: The actual requesting + retrieving of data will be done in the IDataObject implementation
    670                       (ClipboardDataObjectImpl::GetData()). */
    671         }
    672     }
    673     else
    674     {
    675 #endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
    676 
    677         /*
    678          * The guest announced formats. Forward to the window thread.
    679          */
    680         PostMessage(pCtx->Win.hWnd, SHCL_WIN_WM_REPORT_FORMATS,
    681                     0 /* wParam */, pFormats->uFormats /* lParam */);
    682 
    683         rc = VINF_SUCCESS;
    684 
    685 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    686     }
    687 #endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
     710    /*
     711     * The guest announced formats. Forward to the window thread.
     712     */
     713    PostMessage(pCtx->Win.hWnd, SHCL_WIN_WM_REPORT_FORMATS,
     714                0 /* wParam */, pFormats->uFormats /* lParam */);
     715
     716    rc = VINF_SUCCESS;
    688717
    689718    LogFlowFuncLeaveRC(rc);
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp

    r80664 r80845  
    246246ClipboardClientMap g_mapClients;
    247247
    248 /** Global map of all registered event sources. */
    249 ClipboardEventSourceMap g_mapEventSources;
    250 
    251248/** Global list of all clients which are queued up (deferred return) and ready
    252249 *  to process new commands. The key is the (unique) client ID. */
    253250ClipboardClientQueue g_listClientsDeferred;
    254251
    255 
    256 /**
    257  * Creates a (unique) event source ID.
    258  *
    259  * @returns VBox status code, or VERR_NOT_FOUND on error.
    260  * @param   puID                Where to store the created event source ID on success.
    261  */
    262 int sharedClipboardSvcEventSourceCreateID(PSHCLEVENTSOURCEID puID)
    263 {
    264     AssertPtrReturn(puID, VERR_INVALID_POINTER);
    265 
    266     for (uint32_t i = 0; i < 32; i++) /* Don't try too hard. */
    267     {
    268         SHCLEVENTSOURCEID uID = RTRandU32() % VBOX_SHARED_CLIPBOARD_MAX_EVENT_SOURCES;
    269         if (g_mapEventSources.find(uID) == g_mapEventSources.end())
    270         {
    271             *puID = uID;
    272             return VINF_SUCCESS;
    273         }
    274     }
    275 
    276     return VERR_NOT_FOUND;
    277 }
    278252
    279253uint32_t sharedClipboardSvcGetMode(void)
     
    366340    if (pMsg)
    367341    {
    368         pMsg->m_paParms = (PVBOXHGCMSVCPARM)RTMemAllocZ(sizeof(VBOXHGCMSVCPARM) * cParms);
    369         if (pMsg->m_paParms)
    370         {
    371             pMsg->m_cParms = cParms;
    372             pMsg->m_uMsg   = uMsg;
     342        pMsg->paParms = (PVBOXHGCMSVCPARM)RTMemAllocZ(sizeof(VBOXHGCMSVCPARM) * cParms);
     343        if (pMsg->paParms)
     344        {
     345            pMsg->cParms = cParms;
     346            pMsg->uMsg   = uMsg;
    373347
    374348            return pMsg;
     
    391365        return;
    392366
    393     if (pMsg->m_paParms)
    394         RTMemFree(pMsg->m_paParms);
     367    if (pMsg->paParms)
     368        RTMemFree(pMsg->paParms);
    395369
    396370    RTMemFree(pMsg);
     
    411385    Assert(cDstParms >= 2);
    412386    if (paDstParms[0].type == VBOX_HGCM_SVC_PARM_32BIT)
    413         paDstParms[0].u.uint32 = pMsg->m_uMsg;
     387        paDstParms[0].u.uint32 = pMsg->uMsg;
    414388    else
    415         paDstParms[0].u.uint64 = pMsg->m_uMsg;
    416     paDstParms[1].u.uint32 = pMsg->m_cParms;
    417 
    418     uint32_t i = RT_MIN(cDstParms, pMsg->m_cParms + 2);
     389        paDstParms[0].u.uint64 = pMsg->uMsg;
     390    paDstParms[1].u.uint32 = pMsg->cParms;
     391
     392    uint32_t i = RT_MIN(cDstParms, pMsg->cParms + 2);
    419393    while (i-- > 2)
    420         switch (pMsg->m_paParms[i - 2].type)
     394        switch (pMsg->paParms[i - 2].type)
    421395        {
    422396            case VBOX_HGCM_SVC_PARM_32BIT: paDstParms[i].u.uint32 = ~(uint32_t)sizeof(uint32_t); break;
    423397            case VBOX_HGCM_SVC_PARM_64BIT: paDstParms[i].u.uint32 = ~(uint32_t)sizeof(uint64_t); break;
    424             case VBOX_HGCM_SVC_PARM_PTR:   paDstParms[i].u.uint32 = pMsg->m_paParms[i - 2].u.pointer.size; break;
     398            case VBOX_HGCM_SVC_PARM_PTR:   paDstParms[i].u.uint32 = pMsg->paParms[i - 2].u.pointer.size; break;
    425399        }
    426400}
     
    445419    int rc = VINF_SUCCESS;
    446420
    447     switch (pMsg->m_uMsg)
     421    switch (pMsg->uMsg)
    448422    {
    449423        case VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT:
     
    457431        {
    458432            HGCMSvcSetU32(&paDstParms[0], VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA);
    459             AssertBreakStmt(pMsg->m_cParms >= 2, rc = VERR_INVALID_PARAMETER); /* Paranoia. */
     433            AssertBreakStmt(pMsg->cParms >= 2, rc = VERR_INVALID_PARAMETER); /* Paranoia. */
    460434            uint32_t uFmt;
    461             rc = HGCMSvcGetU32(&pMsg->m_paParms[1] /* uFormat */, &uFmt);
     435            rc = HGCMSvcGetU32(&pMsg->paParms[1] /* uFormat */, &uFmt);
    462436            if (RT_SUCCESS(rc))
    463437                HGCMSvcSetU32(&paDstParms[1], uFmt);
     
    468442        {
    469443            HGCMSvcSetU32(&paDstParms[0], VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS_REPORT);
    470             AssertBreakStmt(pMsg->m_cParms >= 2, rc = VERR_INVALID_PARAMETER); /* Paranoia. */
     444            AssertBreakStmt(pMsg->cParms >= 2, rc = VERR_INVALID_PARAMETER); /* Paranoia. */
    471445            uint32_t uFmts;
    472             rc = HGCMSvcGetU32(&pMsg->m_paParms[1] /* uFormats */, &uFmts);
     446            rc = HGCMSvcGetU32(&pMsg->paParms[1] /* uFormats */, &uFmts);
    473447            if (RT_SUCCESS(rc))
    474448                HGCMSvcSetU32(&paDstParms[1], uFmts);
     
    499473
    500474    LogFlowFunc(("uMsg=%RU32 (%s), cParms=%RU32, fAppend=%RTbool\n",
    501                  pMsg->m_uMsg, VBoxClipboardHostMsgToStr(pMsg->m_uMsg), pMsg->m_cParms, fAppend));
     475                 pMsg->uMsg, VBoxClipboardHostMsgToStr(pMsg->uMsg), pMsg->cParms, fAppend));
    502476
    503477    if (fAppend)
     
    560534            paParms[0].u.uint64 = idRestore;
    561535            LogFlowFunc(("[Client %RU32] VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_XXX -> VERR_VM_RESTORED (%#RX64 -> %#RX64)\n",
    562                          pClient->uClientID, idRestoreCheck, idRestore));
     536                         pClient->State.uClientID, idRestoreCheck, idRestore));
    563537            return VERR_VM_RESTORED;
    564538        }
     
    576550            sharedClipboardSvcMsgSetPeekReturn(pFirstMsg, paParms, cParms);
    577551            LogFlowFunc(("[Client %RU32] VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_XXX -> VINF_SUCCESS (idMsg=%u (%s), cParms=%u)\n",
    578                          pClient->uClientID, pFirstMsg->m_uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->m_uMsg),
    579                          pFirstMsg->m_cParms));
     552                         pClient->State.uClientID, pFirstMsg->uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->uMsg),
     553                         pFirstMsg->cParms));
    580554            return VINF_SUCCESS;
    581555        }
     
    587561    if (!fWait)
    588562    {
    589         LogFlowFunc(("[Client %RU32] GUEST_MSG_PEEK_NOWAIT -> VERR_TRY_AGAIN\n", pClient->uClientID));
     563        LogFlowFunc(("[Client %RU32] GUEST_MSG_PEEK_NOWAIT -> VERR_TRY_AGAIN\n", pClient->State.uClientID));
    590564        return VERR_TRY_AGAIN;
    591565    }
     
    595569     */
    596570    ASSERT_GUEST_MSG_RETURN(pClient->Pending.uType == 0, ("Already pending! (idClient=%RU32)\n",
    597                                                            pClient->uClientID), VERR_RESOURCE_BUSY);
     571                                                           pClient->State.uClientID), VERR_RESOURCE_BUSY);
    598572    pClient->Pending.hHandle = hCall;
    599573    pClient->Pending.cParms  = cParms;
    600574    pClient->Pending.paParms = paParms;
    601575    pClient->Pending.uType   = VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_WAIT;
    602     LogFlowFunc(("[Client %RU32] Is now in pending mode...\n", pClient->uClientID));
     576    LogFlowFunc(("[Client %RU32] Is now in pending mode...\n", pClient->State.uClientID));
    603577    return VINF_HGCM_ASYNC_EXECUTE;
    604578}
     
    637611
    638612            LogFlowFunc(("[Client %RU32] uMsg=%RU32 (%s), cParms=%RU32\n",
    639                          pClient->uClientID, pFirstMsg->m_uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->m_uMsg),
    640                          pFirstMsg->m_cParms));
     613                         pClient->State.uClientID, pFirstMsg->uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->uMsg),
     614                         pFirstMsg->cParms));
    641615
    642616            rc = sharedClipboardSvcMsgSetGetHostMsgOldReturn(pFirstMsg, paParms, cParms);
     
    657631        {
    658632            ASSERT_GUEST_MSG_RETURN(pClient->Pending.uType == 0, ("Already pending! (idClient=%RU32)\n",
    659                                                                    pClient->uClientID), VERR_RESOURCE_BUSY);
     633                                                                   pClient->State.uClientID), VERR_RESOURCE_BUSY);
    660634
    661635            pClient->Pending.hHandle = hCall;
     
    666640            rc = VINF_HGCM_ASYNC_EXECUTE; /* The caller must not complete it. */
    667641
    668             LogFlowFunc(("[Client %RU32] Is now in pending mode...\n", pClient->uClientID));
    669         }
    670     }
    671 
    672     LogFlowFunc(("[Client %RU32] rc=%Rrc\n", pClient->uClientID, rc));
     642            LogFlowFunc(("[Client %RU32] Is now in pending mode...\n", pClient->State.uClientID));
     643        }
     644    }
     645
     646    LogFlowFunc(("[Client %RU32] rc=%Rrc\n", pClient->State.uClientID, rc));
    673647    return rc;
    674648}
     
    710684        {
    711685            LogFlowFunc(("First message is: %RU32 (%s), cParms=%RU32\n",
    712                          pFirstMsg->m_uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->m_uMsg), pFirstMsg->m_cParms));
    713 
    714             ASSERT_GUEST_MSG_RETURN(pFirstMsg->m_uMsg == idMsgExpected || idMsgExpected == UINT32_MAX,
     686                         pFirstMsg->uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->uMsg), pFirstMsg->cParms));
     687
     688            ASSERT_GUEST_MSG_RETURN(pFirstMsg->uMsg == idMsgExpected || idMsgExpected == UINT32_MAX,
    715689                                    ("idMsg=%u (%s) cParms=%u, caller expected %u (%s) and %u\n",
    716                                      pFirstMsg->m_uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->m_uMsg), pFirstMsg->m_cParms,
     690                                     pFirstMsg->uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->uMsg), pFirstMsg->cParms,
    717691                                     idMsgExpected, VBoxClipboardHostMsgToStr(idMsgExpected), cParms),
    718692                                    VERR_MISMATCH);
    719             ASSERT_GUEST_MSG_RETURN(pFirstMsg->m_cParms == cParms,
     693            ASSERT_GUEST_MSG_RETURN(pFirstMsg->cParms == cParms,
    720694                                    ("idMsg=%u (%s) cParms=%u, caller expected %u (%s) and %u\n",
    721                                      pFirstMsg->m_uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->m_uMsg), pFirstMsg->m_cParms,
     695                                     pFirstMsg->uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->uMsg), pFirstMsg->cParms,
    722696                                     idMsgExpected, VBoxClipboardHostMsgToStr(idMsgExpected), cParms),
    723697                                    VERR_WRONG_PARAMETER_COUNT);
     
    725699            /* Check the parameter types. */
    726700            for (uint32_t i = 0; i < cParms; i++)
    727                 ASSERT_GUEST_MSG_RETURN(pFirstMsg->m_paParms[i].type == paParms[i].type,
    728                                         ("param #%u: type %u, caller expected %u (idMsg=%u %s)\n", i, pFirstMsg->m_paParms[i].type,
    729                                          paParms[i].type, pFirstMsg->m_uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->m_uMsg)),
     701                ASSERT_GUEST_MSG_RETURN(pFirstMsg->paParms[i].type == paParms[i].type,
     702                                        ("param #%u: type %u, caller expected %u (idMsg=%u %s)\n", i, pFirstMsg->paParms[i].type,
     703                                         paParms[i].type, pFirstMsg->uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->uMsg)),
    730704                                        VERR_WRONG_PARAMETER_TYPE);
    731705            /*
     
    737711            int rc = VINF_SUCCESS;
    738712            for (uint32_t i = 0; i < cParms; i++)
    739                 switch (pFirstMsg->m_paParms[i].type)
     713                switch (pFirstMsg->paParms[i].type)
    740714                {
    741715                    case VBOX_HGCM_SVC_PARM_32BIT:
    742                         paParms[i].u.uint32 = pFirstMsg->m_paParms[i].u.uint32;
     716                        paParms[i].u.uint32 = pFirstMsg->paParms[i].u.uint32;
    743717                        break;
    744718
    745719                    case VBOX_HGCM_SVC_PARM_64BIT:
    746                         paParms[i].u.uint64 = pFirstMsg->m_paParms[i].u.uint64;
     720                        paParms[i].u.uint64 = pFirstMsg->paParms[i].u.uint64;
    747721                        break;
    748722
    749723                    case VBOX_HGCM_SVC_PARM_PTR:
    750724                    {
    751                         uint32_t const cbSrc = pFirstMsg->m_paParms[i].u.pointer.size;
     725                        uint32_t const cbSrc = pFirstMsg->paParms[i].u.pointer.size;
    752726                        uint32_t const cbDst = paParms[i].u.pointer.size;
    753727                        paParms[i].u.pointer.size = cbSrc; /** @todo Check if this is safe in other layers...
    754728                                                            * Update: Safe, yes, but VMMDevHGCM doesn't pass it along. */
    755729                        if (cbSrc <= cbDst)
    756                             memcpy(paParms[i].u.pointer.addr, pFirstMsg->m_paParms[i].u.pointer.addr, cbSrc);
     730                            memcpy(paParms[i].u.pointer.addr, pFirstMsg->paParms[i].u.pointer.addr, cbSrc);
    757731                        else
    758732                        {
     
    764738
    765739                    default:
    766                         AssertMsgFailed(("#%u: %u\n", i, pFirstMsg->m_paParms[i].type));
     740                        AssertMsgFailed(("#%u: %u\n", i, pFirstMsg->paParms[i].type));
    767741                        rc = VERR_INTERNAL_ERROR;
    768742                        break;
     
    777751                rc = g_pHelpers->pfnCallComplete(hCall, rc);
    778752
    779                 LogFlowFunc(("[Client %RU32] pfnCallComplete -> %Rrc\n", pClient->uClientID, rc));
     753                LogFlowFunc(("[Client %RU32] pfnCallComplete -> %Rrc\n", pClient->State.uClientID, rc));
    780754
    781755                if (rc != VERR_CANCELLED)
     
    788762            }
    789763
    790             LogFlowFunc(("[Client %RU32] Returning %Rrc\n", pClient->uClientID, rc));
     764            LogFlowFunc(("[Client %RU32] Returning %Rrc\n", pClient->State.uClientID, rc));
    791765            return rc;
    792766        }
     
    795769    paParms[0].u.uint32 = 0;
    796770    paParms[1].u.uint32 = 0;
    797     LogFlowFunc(("[Client %RU32] -> VERR_TRY_AGAIN\n", pClient->uClientID));
     771    LogFlowFunc(("[Client %RU32] -> VERR_TRY_AGAIN\n", pClient->State.uClientID));
    798772    return VERR_TRY_AGAIN;
    799773}
     
    813787    if (pClient->Pending.uType)
    814788    {
    815         LogFunc(("[Client %RU32] Waking up ...\n", pClient->uClientID));
     789        LogFunc(("[Client %RU32] Waking up ...\n", pClient->State.uClientID));
    816790
    817791        rc = VINF_SUCCESS;
     
    823797            {
    824798                LogFunc(("[Client %RU32] Current host message is %RU32 (%s), cParms=%RU32\n",
    825                          pClient->uClientID, pFirstMsg->m_uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->m_uMsg),
    826                          pFirstMsg->m_cParms));
     799                         pClient->State.uClientID, pFirstMsg->uMsg, VBoxClipboardHostMsgToStr(pFirstMsg->uMsg),
     800                         pFirstMsg->cParms));
    827801
    828802                bool fDonePending = false;
     
    861835        }
    862836        else
    863             AssertMsgFailed(("Waking up client ID=%RU32 with no host message in queue is a bad idea\n", pClient->uClientID));
     837            AssertMsgFailed(("Waking up client ID=%RU32 with no host message in queue is a bad idea\n", pClient->State.uClientID));
    864838
    865839        return rc;
    866840    }
    867841    else
    868         LogFunc(("[Client %RU32] Not in pending state, skipping wakeup\n", pClient->uClientID));
     842        LogFunc(("[Client %RU32] Not in pending state, skipping wakeup\n", pClient->State.uClientID));
    869843
    870844    return VINF_NO_CHANGE;
     
    894868        const SHCLEVENTID uEvent = SharedClipboardEventIDGenerate(&pClient->Events);
    895869
    896         HGCMSvcSetU32(&pMsgReadData->m_paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->Events.uID, uEvent));
    897         HGCMSvcSetU32(&pMsgReadData->m_paParms[1], pDataReq->uFmt);
    898         HGCMSvcSetU32(&pMsgReadData->m_paParms[2], pClient->State.cbChunkSize);
     870        HGCMSvcSetU32(&pMsgReadData->paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->State.uSessionID,
     871                                                                                      pClient->Events.uID, uEvent));
     872        HGCMSvcSetU32(&pMsgReadData->paParms[1], pDataReq->uFmt);
     873        HGCMSvcSetU32(&pMsgReadData->paParms[2], pClient->State.cbChunkSize);
    899874
    900875        rc = sharedClipboardSvcMsgAdd(pClient, pMsgReadData, true /* fAppend */);
     
    964939        SHCLEVENTID uEvent = SharedClipboardEventIDGenerate(&pClient->Events);
    965940
    966         HGCMSvcSetU32(&pMsg->m_paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->Events.uID, uEvent));
    967         HGCMSvcSetU32(&pMsg->m_paParms[1], pFormats->uFormats);
    968         HGCMSvcSetU32(&pMsg->m_paParms[2], 0 /* fFlags */);
     941        HGCMSvcSetU32(&pMsg->paParms[0], VBOX_SHARED_CLIPBOARD_CONTEXTID_MAKE(pClient->State.uSessionID,
     942                                                                              pClient->Events.uID, uEvent));
     943        HGCMSvcSetU32(&pMsg->paParms[1], pFormats->uFormats);
     944        HGCMSvcSetU32(&pMsg->paParms[2], 0 /* fFlags */);
    969945
    970946        rc = sharedClipboardSvcMsgAdd(pClient, pMsg, true /* fAppend */);
     
    10721048        pClient->State.enmSource = enmSource;
    10731049
    1074         LogFlowFunc(("Source of client %RU32 is now %RU32\n", pClient->State.u32ClientID, pClient->State.enmSource));
     1050        LogFlowFunc(("Source of client %RU32 is now %RU32\n", pClient->State.uClientID, pClient->State.enmSource));
    10751051
    10761052        VBoxSvcClipboardUnlock();
     
    10801056    return rc;
    10811057}
    1082 
    1083 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    1084 int sharedClipboardSvcURITransferStart(PSHCLCLIENT pClient,
    1085                                      SHCLURITRANSFERDIR enmDir, SHCLSOURCE enmSource,
    1086                                      PSHCLURITRANSFER *ppTransfer)
    1087 {
    1088     LogFlowFuncEnter();
    1089 
    1090     SharedClipboardURICtxTransfersCleanup(&pClient->URI);
    1091 
    1092     int rc;
    1093 
    1094     if (!SharedClipboardURICtxTransfersMaximumReached(&pClient->URI))
    1095     {
    1096         PSHCLURITRANSFER pTransfer;
    1097         rc = SharedClipboardURITransferCreate(enmDir, enmSource, &pTransfer);
    1098         if (RT_SUCCESS(rc))
    1099         {
    1100             SHCLPROVIDERCREATIONCTX creationCtx;
    1101             RT_ZERO(creationCtx);
    1102 
    1103             if (enmDir == SHCLURITRANSFERDIR_READ)
    1104             {
    1105                 rc = sharedClipboardSvcURIAreaRegister(&pClient->State, pTransfer);
    1106                 if (RT_SUCCESS(rc))
    1107                 {
    1108                     creationCtx.enmSource = pClient->State.enmSource;
    1109 
    1110                     creationCtx.Interface.pfnTransferOpen    = sharedClipboardSvcURITransferOpen;
    1111                     creationCtx.Interface.pfnTransferClose   = sharedClipboardSvcURITransferClose;
    1112                     creationCtx.Interface.pfnListOpen        = sharedClipboardSvcURIListOpen;
    1113                     creationCtx.Interface.pfnListClose       = sharedClipboardSvcURIListClose;
    1114                     creationCtx.Interface.pfnObjOpen         = sharedClipboardSvcURIObjOpen;
    1115                     creationCtx.Interface.pfnObjClose        = sharedClipboardSvcURIObjClose;
    1116 
    1117                     creationCtx.Interface.pfnGetRoots        = sharedClipboardSvcURIGetRoots;
    1118                     creationCtx.Interface.pfnListHdrRead     = sharedClipboardSvcURIListHdrRead;
    1119                     creationCtx.Interface.pfnListEntryRead   = sharedClipboardSvcURIListEntryRead;
    1120                     creationCtx.Interface.pfnObjRead         = sharedClipboardSvcURIObjRead;
    1121 
    1122                     creationCtx.pvUser = pClient;
    1123                 }
    1124             }
    1125             else if (enmDir == SHCLURITRANSFERDIR_WRITE)
    1126             {
    1127                 AssertFailed(); /** @todo Implement this. */
    1128             }
    1129 
    1130             /* Register needed callbacks so that we can wait for the meta data to arrive here. */
    1131             SHCLURITRANSFERCALLBACKS Callbacks;
    1132             RT_ZERO(Callbacks);
    1133 
    1134             Callbacks.pvUser                = pClient;
    1135 
    1136             Callbacks.pfnTransferPrepare    = VBoxSvcClipboardURITransferPrepareCallback;
    1137             Callbacks.pfnTransferComplete   = VBoxSvcClipboardURITransferCompleteCallback;
    1138             Callbacks.pfnTransferCanceled   = VBoxSvcClipboardURITransferCanceledCallback;
    1139             Callbacks.pfnTransferError      = VBoxSvcClipboardURITransferErrorCallback;
    1140 
    1141             SharedClipboardURITransferSetCallbacks(pTransfer, &Callbacks);
    1142 
    1143             rc = SharedClipboardURITransferSetInterface(pTransfer, &creationCtx);
    1144             if (RT_SUCCESS(rc))
    1145             {
    1146                 rc = SharedClipboardURICtxTransferAdd(&pClient->URI, pTransfer);
    1147                 if (RT_SUCCESS(rc))
    1148                     rc = SharedClipboardSvcImplURITransferCreate(pClient, pTransfer);
    1149 
    1150                 if (RT_FAILURE(rc))
    1151                     SharedClipboardSvcImplURITransferDestroy(pClient, pTransfer);
    1152             }
    1153 
    1154             if (RT_FAILURE(rc))
    1155             {
    1156                 SharedClipboardURITransferDestroy(pTransfer);
    1157                 pTransfer = NULL;
    1158             }
    1159             else
    1160             {
    1161                 *ppTransfer = pTransfer;
    1162             }
    1163         }
    1164     }
    1165     else
    1166         rc = VERR_SHCLPB_MAX_TRANSFERS_REACHED;
    1167 
    1168     LogFlowFuncLeaveRC(rc);
    1169     return rc;
    1170 }
    1171 #endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
    11721058
    11731059static int svcInit(void)
     
    12471133
    12481134    /* Assign the client ID. */
    1249     pClient->uClientID = u32ClientID;
     1135    pClient->State.uClientID = u32ClientID;
    12501136
    12511137    /* Create the client's own event source. */
    1252     SHCLEVENTSOURCEID uEventSourceID;
    1253     int rc = sharedClipboardSvcEventSourceCreateID(&uEventSourceID);
    1254     if (RT_SUCCESS(rc))
    1255         rc = SharedClipboardEventSourceCreate(&pClient->Events, uEventSourceID);
     1138    int rc = SharedClipboardEventSourceCreate(&pClient->Events, 0 /* ID, ignored */);
    12561139    if (RT_SUCCESS(rc))
    12571140    {
     
    14951378                    if (uFormat == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
    14961379                    {
    1497                         if (!SharedClipboardURICtxTransfersMaximumReached(&pClient->URI))
    1498                         {
    1499                             SharedClipboardURICtxTransfersCleanup(&pClient->URI);
    1500 
    1501                             PSHCLURITRANSFER pTransfer;
    1502                             rc = SharedClipboardURITransferCreate(SHCLURITRANSFERDIR_WRITE,
    1503                                                                   pClient->State.enmSource,
    1504                                                                   &pTransfer);
    1505                             if (RT_SUCCESS(rc))
    1506                             {
    1507                                 /* Attach to the most recent clipboard area. */
    1508                                 rc = sharedClipboardSvcURIAreaAttach(&pClient->State, pTransfer, 0 /* Area ID */);
    1509                                 if (RT_SUCCESS(rc))
    1510                                 {
    1511                                     SHCLPROVIDERCREATIONCTX creationCtx;
    1512                                     RT_ZERO(creationCtx);
    1513 
    1514                                     creationCtx.enmSource = SharedClipboardURITransferGetSource(pTransfer);
    1515 
    1516                                     RT_ZERO(creationCtx.Interface);
    1517 
    1518                                     creationCtx.Interface.pfnListHdrWrite    = sharedClipboardSvcURIListHdrWrite;
    1519                                     creationCtx.Interface.pfnListEntryWrite  = sharedClipboardSvcURIListEntryWrite;
    1520                                     creationCtx.Interface.pfnObjWrite        = sharedClipboardSvcURIObjWrite;
    1521 
    1522                                     creationCtx.pvUser = pClient;
    1523 
    1524                                     rc = SharedClipboardURITransferSetInterface(pTransfer, &creationCtx);
    1525                                     if (RT_SUCCESS(rc))
    1526                                         rc = SharedClipboardURICtxTransferAdd(&pClient->URI, pTransfer);
    1527                                 }
    1528 
    1529                                 if (RT_SUCCESS(rc))
    1530                                 {
    1531                                     rc = SharedClipboardSvcImplURITransferCreate(pClient, pTransfer);
    1532                                 }
    1533                                 else
    1534                                 {
    1535                                     SharedClipboardSvcImplURITransferDestroy(pClient, pTransfer);
    1536                                     SharedClipboardURITransferDestroy(pTransfer);
    1537                                 }
    1538                             }
    1539                         }
    1540                         else
    1541                             rc = VERR_SHCLPB_MAX_TRANSFERS_REACHED;
    1542 
     1380                        rc = sharedClipboardSvcURITransferStart(pClient, SHCLURITRANSFERDIR_WRITE, SHCLSOURCE_LOCAL,
     1381                                                                NULL /* pTransfer */);
    15431382                        if (RT_FAILURE(rc))
    1544                             LogRel(("Shared Clipboard: Initializing URI host to guest write transfer failed with %Rrc\n", rc));
     1383                            LogRel(("Shared Clipboard: Initializing host write transfer failed with %Rrc\n", rc));
    15451384                    }
    15461385                    else
     
    16451484    }
    16461485
    1647     LogFlowFunc(("u32ClientID=%RU32, fDoCallComplete=%RTbool, rc=%Rrc\n", pClient->uClientID, fDoCallComplete, rc));
     1486    LogFlowFunc(("u32ClientID=%RU32, fDoCallComplete=%RTbool, rc=%Rrc\n", pClient->State.uClientID, fDoCallComplete, rc));
    16481487
    16491488    if (fDoCallComplete)
     
    16681507    /* Register the client.
    16691508     * Note: Do *not* memset the struct, as it contains classes (for caching). */
    1670     pClientState->u32ClientID    = uClientID;
    1671     pClientState->uProtocolVer   = 0;
     1509    pClientState->uClientID    = uClientID;
     1510    pClientState->uProtocolVer = 0;
    16721511
    16731512    return VINF_SUCCESS;
     
    17991638static SSMFIELD const s_aShClSSMClientMsgHdr[] =
    18001639{
    1801     SSMFIELD_ENTRY(SHCLCLIENTMSG, m_uMsg),
    1802     SSMFIELD_ENTRY(SHCLCLIENTMSG, m_cParms),
     1640    SSMFIELD_ENTRY(SHCLCLIENTMSG, uMsg),
     1641    SSMFIELD_ENTRY(SHCLCLIENTMSG, cParms),
    18031642    SSMFIELD_ENTRY_TERM()
    18041643};
     
    18511690        AssertRCReturn(rc, rc);
    18521691
    1853         rc = SSMR3PutStructEx(pSSM, &pMsg->m_Ctx, sizeof(SHCLMSGCTX), 0 /*fFlags*/, &s_aShClSSMClientMsgCtx[0], NULL);
     1692        rc = SSMR3PutStructEx(pSSM, &pMsg->Ctx, sizeof(SHCLMSGCTX), 0 /*fFlags*/, &s_aShClSSMClientMsgCtx[0], NULL);
    18541693        AssertRCReturn(rc, rc);
    18551694
    1856         for (uint32_t p = 0; p < pMsg->m_cParms; p++)
    1857         {
    1858             rc = HGCMSvcSSMR3Put(&pMsg->m_paParms[p], pSSM);
     1695        for (uint32_t p = 0; p < pMsg->cParms; p++)
     1696        {
     1697            rc = HGCMSvcSSMR3Put(&pMsg->paParms[p], pSSM);
    18591698            AssertRCReturn(rc, rc);
    18601699        }
     
    19411780            AssertRCReturn(rc, rc);
    19421781
    1943             rc = SSMR3GetStructEx(pSSM, &pMsg->m_Ctx, sizeof(SHCLMSGCTX), 0 /*fFlags*/, &s_aShClSSMClientMsgCtx[0], NULL);
     1782            rc = SSMR3GetStructEx(pSSM, &pMsg->Ctx, sizeof(SHCLMSGCTX), 0 /*fFlags*/, &s_aShClSSMClientMsgCtx[0], NULL);
    19441783            AssertRCReturn(rc, rc);
    19451784
    1946             pMsg->m_paParms = (PVBOXHGCMSVCPARM)RTMemAllocZ(sizeof(VBOXHGCMSVCPARM) * pMsg->m_cParms);
    1947             AssertPtrReturn(pMsg->m_paParms, VERR_NO_MEMORY);
    1948 
    1949             for (uint32_t p = 0; p < pMsg->m_cParms; p++)
    1950             {
    1951                 rc = HGCMSvcSSMR3Get(&pMsg->m_paParms[p], pSSM);
     1785            pMsg->paParms = (PVBOXHGCMSVCPARM)RTMemAllocZ(sizeof(VBOXHGCMSVCPARM) * pMsg->cParms);
     1786            AssertPtrReturn(pMsg->paParms, VERR_NO_MEMORY);
     1787
     1788            for (uint32_t p = 0; p < pMsg->cParms; p++)
     1789            {
     1790                rc = HGCMSvcSSMR3Get(&pMsg->paParms[p], pSSM);
    19521791                AssertRCReturn(rc, rc);
    19531792            }
  • trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp

    r80824 r80845  
    35853585        if (itArea != m->SharedClipboard.mapClipboardAreas.end())
    35863586        {
    3587             uint32_t cRefs = itArea->second->Area.AddRef();
     3587            const uint32_t cRefs = itArea->second->Area.AddRef();
     3588            RT_NOREF(cRefs);
    35883589            LogFlowThisFunc(("aID=%RU32 -> cRefs=%RU32\n", aID, cRefs));
    35893590            vrc = VINF_SUCCESS;
     
    36163617        if (itArea != m->SharedClipboard.mapClipboardAreas.end())
    36173618        {
    3618             uint32_t cRefs = itArea->second->Area.Release();
     3619            const uint32_t cRefs = itArea->second->Area.Release();
     3620            RT_NOREF(cRefs);
    36193621            LogFlowThisFunc(("aID=%RU32 -> cRefs=%RU32\n", aID, cRefs));
    36203622            vrc = VINF_SUCCESS;
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