VirtualBox

Changeset 79702 in vbox


Ignore:
Timestamp:
Jul 11, 2019 7:34:05 PM (5 years ago)
Author:
vboxsync
Message:

Shared Clipboard/URI: Update.

Location:
trunk
Files:
9 edited

Legend:

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

    r79688 r79702  
    382382    /** Size (in bytes) of string list. */
    383383    uint32_t cbRoots;
    384     /** String list (separated with CRLF) containing the root items. */
     384    /** String list (separated with \r\n) containing the root items. */
    385385    char    *pszRoots;
    386386} VBOXCLIPBOARDROOTS, *PVBOXCLIPBOARDROOTS;
     
    699699    SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_ENTRY_READ,
    700700    SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_ENTRY_WRITE,
    701     SHAREDCLIPBOARDURITRANSFEREVENTTYPE_FILE_OPEN,
    702     SHAREDCLIPBOARDURITRANSFEREVENTTYPE_FILE_CLOSE,
    703     SHAREDCLIPBOARDURITRANSFEREVENTTYPE_FILE_READ,
    704     SHAREDCLIPBOARDURITRANSFEREVENTTYPE_FILE_WRITE,
     701    SHAREDCLIPBOARDURITRANSFEREVENTTYPE_OBJ_OPEN,
     702    SHAREDCLIPBOARDURITRANSFEREVENTTYPE_OBJ_CLOSE,
     703    SHAREDCLIPBOARDURITRANSFEREVENTTYPE_OBJ_READ,
     704    SHAREDCLIPBOARDURITRANSFEREVENTTYPE_OBJ_WRITE,
    705705    SHAREDCLIPBOARDURITRANSFEREVENTTYPE_ERROR,
    706706    /** Marks the end of the event list. */
     
    814814SHAREDCLIPBOARDPROVIDERFUNCDECL(OBJREAD, SHAREDCLIPBOARDOBJHANDLE hObj, void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbRead)
    815815SHAREDCLIPBOARDPROVIDERFUNCDECL(OBJWRITE, SHAREDCLIPBOARDOBJHANDLE hObj, void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbWritten)
    816 SHAREDCLIPBOARDPROVIDERFUNCDECLRET(uint64_t, OBJGETSIZE, SHAREDCLIPBOARDOBJHANDLE hObj)
    817 SHAREDCLIPBOARDPROVIDERFUNCDECLRET(uint64_t, OBJGETPROCESSED, SHAREDCLIPBOARDOBJHANDLE hObj)
    818 SHAREDCLIPBOARDPROVIDERFUNCDECLRET(const char *, OBJGETPATH, SHAREDCLIPBOARDOBJHANDLE hObj)
    819816
    820817/**
     
    836833    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(OBJREAD, pfnObjRead);
    837834    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(OBJWRITE, pfnObjWrite);
    838     SHAREDCLIPBOARDPROVIDERFUNCMEMBER(OBJGETSIZE, pfnObjGetSize);
    839     SHAREDCLIPBOARDPROVIDERFUNCMEMBER(OBJGETPROCESSED, pfnObjGetProcessed);
    840     SHAREDCLIPBOARDPROVIDERFUNCMEMBER(OBJGETPATH, pfnObjGetPath);
    841835} SHAREDCLIPBOARDPROVIDERINTERFACE, *PSHAREDCLIPBOARDPROVIDERINTERFACE;
    842836
     
    10561050
    10571051#endif /* !VBOX_INCLUDED_GuestHost_SharedClipboard_uri_h */
     1052
  • trunk/include/VBox/GuestHost/SharedClipboard-win.h

    r79630 r79702  
    3636
    3737# ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     38#  include <vector>
     39
    3840#  include <iprt/cpp/ministring.h> /* For RTCString. */
    39 #  include <iprt/win/shlobj.h> /* For DROPFILES and friends. */
     41#  include <iprt/win/shlobj.h>     /* For DROPFILES and friends. */
     42#  include <VBox/com/string.h>     /* For Utf8Str. */
    4043#  include <oleidl.h>
    4144
    4245# include <VBox/GuestHost/SharedClipboard-uri.h>
    43 # endif
     46
     47using namespace com;
     48# endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
    4449
    4550#ifndef WM_CLIPBOARDUPDATE
     
    163168    };
    164169
    165     enum FormatIndex
    166     {
    167         /** File descriptor, ANSI version. */
    168         FormatIndex_FileDescriptorA = 0,
    169         /** File descriptor, Unicode version. */
    170         FormatIndex_FileDescriptorW,
    171         /** File contents. */
    172         FormatIndex_FileContents
    173     };
    174 
    175170public:
    176171
     
    232227protected:
    233228
     229    /**
     230     * Structure for keeping a single file system object entry.
     231     */
     232    struct FSOBJENTRY
     233    {
     234        /** Relative path of the object. */
     235        Utf8Str                  strPath;
     236        /** Related (cached) object information. */
     237        SHAREDCLIPBOARDFSOBJINFO objInfo;
     238    };
     239
     240    /** Vector containing file system objects with its (cached) objection information. */
     241    typedef std::vector<FSOBJENTRY> FsObjEntryList;
     242
    234243    Status                      m_enmStatus;
    235244    LONG                        m_lRefCount;
     
    240249    IStream                    *m_pStream;
    241250    ULONG                       m_uObjIdx;
    242     /** Event being triggered when reading the transfer list been completed.*/
     251    /** List of (cached) file system root objects. */
     252    FsObjEntryList              m_lstRootEntries;
     253    /** Event being triggered when reading the transfer list been completed. */
    243254    RTSEMEVENT                  m_EventListComplete;
     255    /** Event being triggered when the transfer has been completed. */
    244256    RTSEMEVENT                  m_EventTransferComplete;
     257    UINT                        m_cfFileDescriptorA;
     258    UINT                        m_cfFileDescriptorW;
     259    UINT                        m_cfFileContents;
    245260};
    246261
     
    286301public:
    287302
    288     VBoxClipboardWinStreamImpl(VBoxClipboardWinDataObject *pParent,
    289                                PSHAREDCLIPBOARDURITRANSFER pTransfer, SHAREDCLIPBOARDOBJHANDLE hObj);
     303    VBoxClipboardWinStreamImpl(VBoxClipboardWinDataObject *pParent, PSHAREDCLIPBOARDURITRANSFER pTransfer,
     304                               const Utf8Str &strPath, PSHAREDCLIPBOARDFSOBJINFO pObjInfo);
    290305    virtual ~VBoxClipboardWinStreamImpl(void);
    291306
     
    312327public: /* Own methods. */
    313328
    314     static HRESULT Create(VBoxClipboardWinDataObject *pParent,
    315                           PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uObjIdx, IStream **ppStream);
    316 
     329    static HRESULT Create(VBoxClipboardWinDataObject *pParent, PSHAREDCLIPBOARDURITRANSFER pTransfer, const Utf8Str &strPath,
     330                          PSHAREDCLIPBOARDFSOBJINFO pObjInfo, IStream **ppStream);
    317331private:
    318332
     
    323337    /** Pointer to the associated URI transfer. */
    324338    PSHAREDCLIPBOARDURITRANSFER    m_pURITransfer;
    325     /** Handle to the associated URI object. */
     339    /** The object handle to use. */
    326340    SHAREDCLIPBOARDOBJHANDLE       m_hObj;
     341    /** Object path. */
     342    Utf8Str                        m_strPath;
     343    /** (Cached) object information. */
     344    SHAREDCLIPBOARDFSOBJINFO       m_objInfo;
     345    /** Number of bytes already processed. */
     346    uint64_t                       m_cbProcessed;
     347    /** Whether we already notified the parent of completion or not. */
     348    bool                           m_fNotifiedComplete;
    327349};
    328350
  • trunk/include/VBox/HostServices/VBoxClipboardSvc.h

    r79688 r79702  
    361361#define VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_INVALID           0
    362362#define VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_LIST_OPEN         1
    363 #define VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_OBJ_OPEN          2
     363#define VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_LIST_CLOSE        2
     364#define VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_OBJ_OPEN          3
     365#define VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_OBJ_CLOSE         4
    364366
    365367/**
     
    413415    /** uin32_t, out: Size (in bytes) of string list. */
    414416    HGCMFunctionParameter cbRoots;
    415     /** pointer, out: string list (separated with CRLF) containing the root items. */
     417    /** pointer, out: string list (separated with \r\n) containing the root items. */
    416418    HGCMFunctionParameter pvRoots;
    417419} VBoxClipboardRootsMsg;
     
    650652
    651653#endif /* !VBOX_INCLUDED_HostServices_VBoxClipboardSvc_h */
     654
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp

    r79672 r79702  
    801801                               if (RT_SUCCESS(rc))
    802802                               {
    803                                    rc = SharedClipboardURILTransferSetRoots(pTransfer, papszList, cbList);
     803                                   rc = SharedClipboardURILTransferSetRoots(pTransfer,
     804                                                                            papszList, cbList + 1 /* Include termination */);
    804805                                   if (RT_SUCCESS(rc))
    805806                                   {
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp

    r79672 r79702  
    423423}
    424424
     425VBGLR3DECL(int) VbglR3ClipboardListCloseReply(HGCMCLIENTID idClient, int rcReply, SHAREDCLIPBOARDLISTHANDLE hList)
     426{
     427    VBoxClipboardReplyMsg Msg;
     428    RT_ZERO(Msg);
     429
     430    VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
     431                       VBOX_SHARED_CLIPBOARD_GUEST_FN_REPLY, 6);
     432
     433    Msg.uContext.SetUInt32(0); /** @todo Context ID not used yet. */
     434    Msg.enmType.SetUInt32(VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_LIST_CLOSE);
     435    Msg.rc.SetUInt32((uint32_t)rcReply); /** int vs. uint32_t */
     436    Msg.cbPayload.SetUInt32(0);
     437    Msg.pvPayload.SetPtr(0, NULL);
     438
     439    Msg.u.ListOpen.uHandle.SetUInt64(hList);
     440
     441    int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     442
     443    LogFlowFuncLeaveRC(rc);
     444    return rc;
     445}
     446
    425447VBGLR3DECL(int) VbglR3ClipboardListCloseSend(HGCMCLIENTID idClient, SHAREDCLIPBOARDLISTHANDLE hList)
    426448{
     
    671693                    if (RT_SUCCESS(rc))
    672694                    {
    673                         /** @todo Handle fFlags. */
     695                        /** @todo Handle Roots.fRoots flags. */
    674696
    675697                        char    *pszRoots = NULL;
     
    680702                            /** @todo Split up transfers in _64K each. */
    681703
    682                             rc = VbglR3ClipboardRootsWrite(idClient, cRoots,
    683                                                            pszRoots, pszRoots ? (uint32_t)strlen(pszRoots) : NULL);
     704                            const uint32_t cbRoots = pszRoots
     705                                                   ? (uint32_t)strlen(pszRoots) + 1 /* Include termination. */
     706                                                   : 0;
     707
     708                            rc = VbglR3ClipboardRootsWrite(idClient, cRoots, pszRoots, cbRoots);
    684709                        }
    685710                    }
     
    725750                {
    726751                    rc = SharedClipboardURITransferListClose(pTransfer, hList);
     752
     753                    /* Reply in any case. */
     754                    int rc2 = VbglR3ClipboardListCloseReply(idClient, rc, hList);
     755                    AssertRC(rc2);
    727756                }
    728757
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp

    r79672 r79702  
    4343#include <VBox/log.h>
    4444
    45 /** Also handle Unicode entries. */
    46 #define VBOX_CLIPBOARD_WITH_UNICODE_SUPPORT 1
     45/** @todo Also handle Unicode entries.
     46 *        !!! WARNING: Buggy, doesn't work yet (some memory corruption / garbage in the file name descriptions) !!! */
     47//#define VBOX_CLIPBOARD_WITH_UNICODE_SUPPORT 0
    4748
    4849VBoxClipboardWinDataObject::VBoxClipboardWinDataObject(PSHAREDCLIPBOARDURITRANSFER pTransfer,
    4950                                                       LPFORMATETC pFormatEtc, LPSTGMEDIUM pStgMed, ULONG cFormats)
    5051    : m_enmStatus(Uninitialized)
    51     , m_lRefCount(1)
     52    , m_lRefCount(0)
    5253    , m_cFormats(0)
    5354    , m_pTransfer(pTransfer)
     
    7778         * Register fixed formats.
    7879         */
     80        unsigned uIdx = 0;
    7981
    8082        LogFlowFunc(("Registering CFSTR_FILEDESCRIPTORA ...\n"));
    81         registerFormat(&m_pFormatEtc[FormatIndex_FileDescriptorA],
    82                        RegisterClipboardFormat(CFSTR_FILEDESCRIPTORA));
     83        m_cfFileDescriptorA = RegisterClipboardFormat(CFSTR_FILEDESCRIPTORA);
     84        registerFormat(&m_pFormatEtc[uIdx++], m_cfFileDescriptorA);
    8385#ifdef VBOX_CLIPBOARD_WITH_UNICODE_SUPPORT
    8486        LogFlowFunc(("Registering CFSTR_FILEDESCRIPTORW ...\n"));
    85         registerFormat(&m_pFormatEtc[FormatIndex_FileDescriptorW],
    86                        RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW));
     87        m_cfFileDescriptorW = RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW);
     88        registerFormat(&m_pFormatEtc[uIdx++], m_cfFileDescriptorW);
    8789#endif
     90
    8891        /* IStream interface, implemented in ClipboardStreamImpl-win.cpp. */
    8992        LogFlowFunc(("Registering CFSTR_FILECONTENTS ...\n"));
    90         registerFormat(&m_pFormatEtc[FormatIndex_FileContents],
    91                        RegisterClipboardFormat(CFSTR_FILECONTENTS),
    92                        TYMED_ISTREAM, 0 /* lIndex */);
     93        m_cfFileContents = RegisterClipboardFormat(CFSTR_FILECONTENTS);
     94        registerFormat(&m_pFormatEtc[uIdx++], m_cfFileContents, TYMED_ISTREAM, 0 /* lIndex */);
    9395
    9496        /*
     
    296298
    297299                                    LogFlowFunc(("\t%s (%RU64 bytes)\n", entryList.pszName, pObjInfo->cbObject));
     300
     301                                    FSOBJENTRY objEntry = { entryList.pszName, *pObjInfo };
     302                                    pThis->m_lstRootEntries.push_back(objEntry); /** @todo Can this throw? */
    298303                                }
    299304                                else
     
    362367    const size_t cbFileDescriptor = fUnicode ? sizeof(FILEDESCRIPTORW) : sizeof(FILEDESCRIPTORA);
    363368
    364     const UINT   cItems = (UINT)0; /** @todo UINT vs. uint64_t */
     369    const UINT   cItems = (UINT)m_lstRootEntries.size(); /** UINT vs. size_t. */
    365370    if (!cItems)
    366371        return VERR_NOT_FOUND;
     372          UINT   curIdx = 0; /* Current index of the handled file group descriptor (FGD). */
    367373
    368374    const size_t cbFGD  = cbFileGroupDescriptor + (cbFileDescriptor * (cItems - 1));
     
    371377
    372378    /* FILEGROUPDESCRIPTORA / FILEGROUPDESCRIPTOR matches except the cFileName member (TCHAR vs. WCHAR). */
    373     FILEGROUPDESCRIPTOR *pFGD = (FILEGROUPDESCRIPTOR *)RTMemAlloc(cbFGD);
     379    FILEGROUPDESCRIPTOR *pFGD = (FILEGROUPDESCRIPTOR *)RTMemAllocZ(cbFGD);
    374380    if (!pFGD)
    375381        return VERR_NO_MEMORY;
     
    380386
    381387    char *pszFileSpec = NULL;
    382 #if 0
    383     for (UINT i = 0; i < cItems; i++)
    384     {
    385         FILEDESCRIPTOR *pFD = &pFGD->fgd[i];
     388
     389    FsObjEntryList::const_iterator itRoot = m_lstRootEntries.begin();
     390    while (itRoot != m_lstRootEntries.end())
     391    {
     392        FILEDESCRIPTOR *pFD = &pFGD->fgd[curIdx];
    386393        RT_BZERO(pFD, cbFileDescriptor);
    387394
    388         const SharedClipboardURIObject *pObj = pURIList->At(i);
    389         AssertPtr(pObj);
    390         const char *pszFile = pObj->GetSourcePathAbs().c_str();
     395        const char *pszFile = itRoot->strPath.c_str();
    391396        AssertPtr(pszFile);
    392397
     
    403408                                   pwszFileSpec, RTUtf16Len(pwszFileSpec));
    404409                RTUtf16Free(pwszFileSpec);
     410
     411                LogFlowFunc(("pFD->cFileNameW=%ls\n", pFD->cFileName));
    405412            }
    406413        }
    407414        else
     415        {
    408416            rc = RTStrCopy(pFD->cFileName, sizeof(pFD->cFileName), pszFileSpec);
     417            LogFlowFunc(("pFD->cFileNameA=%s\n", pFD->cFileName));
     418        }
    409419
    410420        RTStrFree(pszFileSpec);
     
    419429        pFD->dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
    420430
    421         switch (pObj->GetType())
    422         {
    423             case SharedClipboardURIObject::Type_Directory:
    424                 pFD->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
    425 
    426                 LogFunc(("pszDir=%s\n", pszFile));
    427                 break;
    428 
    429             case SharedClipboardURIObject::Type_File:
    430             {
    431                 pFD->dwFlags |= FD_FILESIZE;
    432 
    433                 const uint64_t cbObjSize = pObj->GetSize();
    434 
    435                 pFD->nFileSizeHigh = RT_HI_U32(cbObjSize);
    436                 pFD->nFileSizeLow  = RT_LO_U32(cbObjSize);
    437 
    438                 LogFunc(("pszFile=%s, cbObjSize=%RU64\n", pszFile, cbObjSize));
    439                 break;
    440             }
    441 
    442             default:
    443                 AssertFailed();
    444                 break;
    445         }
    446 #if 0
    447         pFD->dwFlags = FD_ATTRIBUTES | FD_CREATETIME | FD_ACCESSTIME | FD_WRITESTIME | FD_FILESIZE; /** @todo Implement this. */
     431        const SHAREDCLIPBOARDFSOBJINFO *pObjInfo = &itRoot->objInfo;
     432
     433        if (RTFS_IS_DIRECTORY(pObjInfo->Attr.fMode))
     434        {
     435            pFD->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
     436        }
     437        else if (RTFS_IS_FILE(pObjInfo->Attr.fMode))
     438        {
     439            pFD->dwFlags |= FD_FILESIZE;
     440
     441            const uint64_t cbObjSize = pObjInfo->cbObject;
     442
     443            pFD->nFileSizeHigh = RT_HI_U32(cbObjSize);
     444            pFD->nFileSizeLow  = RT_LO_U32(cbObjSize);
     445        }
     446        else if (RTFS_IS_SYMLINK(pObjInfo->Attr.fMode))
     447        {
     448            /** @todo Implement. */
     449        }
     450#if 0 /** @todo Implement this. */
     451        pFD->dwFlags = FD_ATTRIBUTES | FD_CREATETIME | FD_ACCESSTIME | FD_WRITESTIME | FD_FILESIZE;
    448452        pFD->dwFileAttributes =
    449453        pFD->ftCreationTime   =
     
    451455        pFD->ftLastWriteTime  =
    452456#endif
    453     }
    454 #endif
     457        ++curIdx;
     458        ++itRoot;
     459    }
    455460
    456461    if (pszFileSpec)
     
    458463
    459464    if (RT_SUCCESS(rc))
    460     {
    461465        rc = copyToHGlobal(pFGD, cbFGD, GMEM_MOVEABLE, phGlobal);
    462     }
    463     else
    464     {
    465         RTMemFree(pFGD);
    466     }
     466
     467    RTMemFree(pFGD);
    467468
    468469    LogFlowFuncLeaveRC(rc);
     
    486487    LogFlowFuncEnter();
    487488
    488     ULONG lIndex;
    489     if (!lookupFormatEtc(pFormatEtc, &lIndex)) /* Format supported? */
    490         return DV_E_FORMATETC;
    491     if (lIndex >= m_cFormats) /* Paranoia. */
    492         return DV_E_LINDEX;
    493 
    494     LPFORMATETC pThisFormat = &m_pFormatEtc[lIndex];
    495     AssertPtr(pThisFormat);
    496 
    497     LPSTGMEDIUM pThisMedium = &m_pStgMedium[lIndex];
    498     AssertPtr(pThisMedium);
    499 
    500     LogFlowFunc(("Using pThisFormat=%p, pThisMedium=%p\n", pThisFormat, pThisMedium));
    501 
    502     HRESULT hr = DV_E_FORMATETC; /* Play safe. */
    503 
    504     LogRel2(("Shared Clipboard: cfFormat=%RI16, sFormat=%s, tyMed=%RU32, dwAspect=%RU32 -> lIndex=%u\n",
    505              pThisFormat->cfFormat, VBoxClipboardWinDataObject::ClipboardFormatToString(pFormatEtc->cfFormat),
    506              pThisFormat->tymed, pThisFormat->dwAspect, lIndex));
     489    LogFlowFunc(("lIndex=%RI32\n", pFormatEtc->lindex));
    507490
    508491    /*
    509492     * Initialize default values.
    510493     */
    511     pMedium->tymed          = pThisFormat->tymed;
    512     pMedium->pUnkForRelease = NULL; /* Caller is responsible for deleting the data. */
    513 
    514     switch (lIndex)
    515     {
    516         case FormatIndex_FileDescriptorA: /* ANSI */
     494    RT_BZERO(pMedium, sizeof(STGMEDIUM));
     495
     496    HRESULT hr = DV_E_FORMATETC; /* Play safe. */
     497
     498    if (   pFormatEtc->cfFormat == m_cfFileDescriptorA
    517499#ifdef VBOX_CLIPBOARD_WITH_UNICODE_SUPPORT
    518             RT_FALL_THROUGH();
    519         case FormatIndex_FileDescriptorW: /* Unicode */
     500        || pFormatEtc->cfFormat == m_cfFileDescriptorW
    520501#endif
    521         {
    522             const bool fUnicode = lIndex == FormatIndex_FileDescriptorW;
    523 
    524             LogFlowFunc(("FormatIndex_FileDescriptor%s\n", fUnicode ? "W" : "A"));
    525 
    526             int rc;
    527 
    528             /* The caller can call GetData() several times, so make sure we don't do the same transfer multiple times. */
    529             if (SharedClipboardURITransferGetStatus(m_pTransfer) == SHAREDCLIPBOARDURITRANSFERSTATUS_NONE)
     502       )
     503    {
     504        const bool fUnicode = pFormatEtc->cfFormat == m_cfFileDescriptorW;
     505
     506        LogFlowFunc(("FormatIndex_FileDescriptor%s\n", fUnicode ? "W" : "A"));
     507
     508        int rc;
     509
     510        /* The caller can call GetData() several times, so make sure we don't do the same transfer multiple times. */
     511        if (SharedClipboardURITransferGetStatus(m_pTransfer) == SHAREDCLIPBOARDURITRANSFERSTATUS_NONE)
     512        {
     513            rc = SharedClipboardURITransferPrepare(m_pTransfer);
     514            if (RT_SUCCESS(rc))
    530515            {
    531                 rc = SharedClipboardURITransferPrepare(m_pTransfer);
     516                /* Start the transfer asynchronously in a separate thread. */
     517                rc = SharedClipboardURITransferRun(m_pTransfer, &VBoxClipboardWinDataObject::readThread, this);
    532518                if (RT_SUCCESS(rc))
    533519                {
    534                     /* Start the transfer asynchronously in a separate thread. */
    535                     rc = SharedClipboardURITransferRun(m_pTransfer, &VBoxClipboardWinDataObject::readThread, this);
     520                    /* Don't block for too long here, as this also will screw other apps running on the OS. */
     521                    LogFunc(("Waiting for listing to arrive ...\n"));
     522                    rc = RTSemEventWait(m_EventListComplete, 10 * 1000 /* 10s timeout */);
    536523                    if (RT_SUCCESS(rc))
    537524                    {
    538                         /* Don't block for too long here, as this also will screw other apps running on the OS. */
    539                         LogFunc(("Waiting for listing to arrive ...\n"));
    540                         rc = RTSemEventWait(m_EventListComplete, 10 * 1000 /* 10s timeout */);
    541                         if (RT_SUCCESS(rc))
    542                         {
    543                             LogFunc(("Listing complete\n"));
    544 
    545                             HGLOBAL hGlobal;
    546                             rc = createFileGroupDescriptorFromTransfer(m_pTransfer, fUnicode, &hGlobal);
    547                             if (RT_SUCCESS(rc))
    548                             {
    549                                 pMedium->tymed   = TYMED_HGLOBAL;
    550                                 pMedium->hGlobal = hGlobal;
    551                                 /* Note: hGlobal now is being owned by pMedium / the caller. */
    552 
    553                                 hr = S_OK;
    554                             }
    555                         }
     525                        LogFunc(("Listing complete\n"));
     526
     527
    556528                    }
    557529                }
    558530            }
    559             else
    560                 rc = VERR_ALREADY_EXISTS;
    561 
    562             if (RT_FAILURE(rc))
    563                 LogRel(("Shared Clipboard: Data object unable to get data, rc=%Rrc\n", rc));
    564 
    565             break;
    566         }
    567 
    568         case FormatIndex_FileContents:
    569         {
     531        }
     532        else
     533            rc = VINF_SUCCESS;
     534
     535        if (RT_SUCCESS(rc))
     536        {
     537            HGLOBAL hGlobal;
     538            rc = createFileGroupDescriptorFromTransfer(m_pTransfer, fUnicode, &hGlobal);
     539            if (RT_SUCCESS(rc))
     540            {
     541                pMedium->tymed   = TYMED_HGLOBAL;
     542                pMedium->hGlobal = hGlobal;
     543                /* Note: hGlobal now is being owned by pMedium / the caller. */
     544
     545                hr = S_OK;
     546            }
     547        }
     548
     549        if (RT_FAILURE(rc))
     550            LogRel(("Shared Clipboard: Data object unable to get data, rc=%Rrc\n", rc));
     551    }
     552
     553    if (pFormatEtc->cfFormat == m_cfFileContents)
     554    {
     555        if (   pFormatEtc->lindex >= 0
     556            && pFormatEtc->lindex < m_lstRootEntries.size())
     557        {
     558            m_uObjIdx = pFormatEtc->lindex; /* lIndex of FormatEtc contains the actual index to the object being handled. */
     559
    570560            LogFlowFunc(("FormatIndex_FileContents: m_uObjIdx=%u\n", m_uObjIdx));
    571561
    572             SHAREDCLIPBOARDOBJHANDLE hObj = 0; /** @todo */
     562            FSOBJENTRY &fsObjEntry = m_lstRootEntries.at(m_uObjIdx);
     563
     564            LogRel2(("Shared Clipboard: Receiving file '%s' ...\n", fsObjEntry.strPath.c_str()));
    573565
    574566            /* Hand-in the provider so that our IStream implementation can continue working with it. */
    575             hr = VBoxClipboardWinStreamImpl::Create(this /* pParent */, m_pTransfer, hObj, &m_pStream);
     567            hr = VBoxClipboardWinStreamImpl::Create(this /* pParent */, m_pTransfer,
     568                                                    fsObjEntry.strPath.c_str()/* File name */, &fsObjEntry.objInfo /* PSHAREDCLIPBOARDFSOBJINFO */,
     569                                                    &m_pStream);
    576570            if (SUCCEEDED(hr))
    577571            {
     
    579573                pMedium->tymed = TYMED_ISTREAM;
    580574                pMedium->pstm  = m_pStream;
    581 
    582                 /* Handle next object. */
    583                 m_uObjIdx++;
    584575            }
    585             break;
    586         }
    587 
    588         default:
    589             break;
     576        }
    590577    }
    591578
     
    595582        LogFunc(("Failed; copying medium ...\n"));
    596583
    597         pMedium->tymed          = pThisFormat->tymed;
    598         pMedium->pUnkForRelease = NULL;
     584        //pMedium->tymed          = pThisFormat->tymed;
     585        //pMedium->pUnkForRelease = NULL;
    599586    }
    600587
     
    734721    RT_NOREF(rc);
    735722
     723    LogFlowFunc(("m_uObjIdx=%RU32 (total: %zu)\n", m_uObjIdx, m_lstRootEntries.size()));
     724
     725    const bool fComplete = m_uObjIdx == m_lstRootEntries.size() - 1 /* Object index is zero-based */;
     726    if (fComplete)
     727    {
     728        int rc2 = RTSemEventSignal(m_EventTransferComplete);
     729        AssertRC(rc2);
     730    }
     731
    736732    LogFlowFuncLeaveRC(rc);
    737733}
     
    739735void VBoxClipboardWinDataObject::OnTransferCanceled(void)
    740736{
     737    LogFlowFuncEnter();
     738
     739    int rc2 = RTSemEventSignal(m_EventTransferComplete);
     740    AssertRC(rc2);
     741
    741742    LogFlowFuncLeave();
    742743}
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardStreamImpl-win.cpp

    r79630 r79702  
    4646
    4747
    48 VBoxClipboardWinStreamImpl::VBoxClipboardWinStreamImpl(VBoxClipboardWinDataObject *pParent,
    49                                                        PSHAREDCLIPBOARDURITRANSFER pTransfer, SHAREDCLIPBOARDOBJHANDLE hObj)
     48VBoxClipboardWinStreamImpl::VBoxClipboardWinStreamImpl(VBoxClipboardWinDataObject *pParent, PSHAREDCLIPBOARDURITRANSFER pTransfer,
     49                                                       const Utf8Str &strPath, PSHAREDCLIPBOARDFSOBJINFO pObjInfo)
    5050    : m_pParent(pParent)
    51     , m_lRefCount(1)
     51    , m_lRefCount(1) /* Our IDataObjct *always* holds the last reference to this object; needed for the callbacks. */
    5252    , m_pURITransfer(pTransfer)
    53     , m_hObj(hObj)
     53    , m_strPath(strPath)
     54    , m_hObj(SHAREDCLIPBOARDOBJHANDLE_INVALID)
     55    , m_objInfo(*pObjInfo)
     56    , m_cbProcessed(0)
     57    , m_fNotifiedComplete(false)
    5458{
    5559    AssertPtr(m_pURITransfer);
    5660
    57     LogFunc(("m_hObj=%RU64\n", m_hObj));
     61    LogFunc(("m_strPath=%s\n", m_strPath.c_str()));
    5862}
    5963
     
    109113    if (lCount == 0)
    110114    {
    111         if (m_pParent)
     115        if (  !m_fNotifiedComplete
     116            && m_pParent)
     117        {
    112118            m_pParent->OnTransferComplete();
     119        }
    113120
    114121        delete this;
     
    156163}
    157164
     165/* Note: Windows seems to assume EOF if nBytesRead < nBytesToRead. */
    158166STDMETHODIMP VBoxClipboardWinStreamImpl::Read(void *pvBuffer, ULONG nBytesToRead, ULONG *nBytesRead)
    159167{
    160     LogFlowThisFuncEnter();
    161 
    162     const uint64_t cbSize      = m_pURITransfer->ProviderIface.pfnObjGetSize(&m_pURITransfer->ProviderCtx, m_hObj);
    163           uint64_t cbProcessed = m_pURITransfer->ProviderIface.pfnObjGetProcessed(&m_pURITransfer->ProviderCtx, m_hObj);
    164 
    165     if (cbProcessed == cbSize)
    166     {
    167         /* There can be 0-byte files. */
    168         AssertMsg(cbSize == 0, ("Object is complete -- can't read from it anymore\n"));
     168    LogFlowThisFunc(("Enter: m_cbProcessed=%RU64\n", m_cbProcessed));
     169
     170    /** @todo Is there any locking required so that parallel reads aren't possible? */
     171
     172    if (!pvBuffer)
     173        return STG_E_INVALIDPOINTER;
     174
     175    if (nBytesToRead == 0)
     176    {
    169177        if (nBytesRead)
    170             *nBytesRead = 0; /** @todo If the file size is 0, already return at least 1 byte, else the whole operation will fail. */
    171         return S_OK; /* Don't report any failures back to Windows. */
    172     }
    173 
    174     const uint32_t cbToRead = RT_MIN(cbSize - cbProcessed, nBytesToRead);
    175           uint32_t cbRead   = 0;
    176 
    177     int rc = VINF_SUCCESS;
    178 
    179     if (cbToRead)
    180     {
    181         rc = m_pURITransfer->ProviderIface.pfnObjRead(&m_pURITransfer->ProviderCtx, m_hObj,
    182                                                       pvBuffer, cbToRead, 0 /* fFlags */, &cbRead);
     178            *nBytesRead = 0;
     179        return S_OK;
     180    }
     181
     182    int rc;
     183
     184    try
     185    {
     186        if (   m_hObj == SHAREDCLIPBOARDOBJHANDLE_INVALID
     187            && m_pURITransfer->ProviderIface.pfnObjOpen)
     188        {
     189            VBOXCLIPBOARDCREATEPARMS createParms;
     190            RT_ZERO(createParms);
     191
     192            rc = m_pURITransfer->ProviderIface.pfnObjOpen(&m_pURITransfer->ProviderCtx, m_strPath.c_str(), &createParms, &m_hObj);
     193        }
     194        else
     195            rc = VINF_SUCCESS;
     196
     197        uint32_t cbRead = 0;
     198
     199        const uint64_t cbSize   = (uint64_t)m_objInfo.cbObject;
     200        const uint32_t cbToRead = RT_MIN(cbSize - m_cbProcessed, nBytesToRead);
     201
     202        bool fComplete = false;
     203
    183204        if (RT_SUCCESS(rc))
    184205        {
    185             cbProcessed += cbRead;
    186             Assert(cbProcessed <= cbSize);
    187 
    188             if (cbProcessed == cbSize)
    189                 m_pParent->OnTransferComplete();
    190 
    191     #if 0
    192             m_pObj->State.cbProcessed = cbProcessed;
    193             Assert(m_pObj->State.cbProcessed <= m_pObj->objInfo.cbObject);
    194     #endif
    195         }
    196     }
    197 
    198     if (nBytesRead)
    199         *nBytesRead = (ULONG)cbRead;
    200 
    201     LogFlowThisFunc(("rc=%Rrc, cbSize=%RU64, cbProcessed=%RU64 -> cbToRead=%zu, cbRead=%zu\n",
    202                      rc, cbSize, cbProcessed, cbToRead, cbRead));
    203     return RT_SUCCESS(rc) ? S_OK : E_FAIL;
     206            if (cbToRead)
     207            {
     208                rc = m_pURITransfer->ProviderIface.pfnObjRead(&m_pURITransfer->ProviderCtx, m_hObj,
     209                                                              pvBuffer, cbToRead, 0 /* fFlags */, &cbRead);
     210                if (RT_SUCCESS(rc))
     211                {
     212                    m_cbProcessed += cbRead;
     213                    Assert(m_cbProcessed <= cbSize);
     214                }
     215            }
     216
     217            /* Transfer complete? Make sure to close the object again. */
     218            fComplete = m_cbProcessed == cbSize;
     219
     220            if (fComplete)
     221            {
     222                if (m_pURITransfer->ProviderIface.pfnObjClose)
     223                {
     224                    int rc2 = m_pURITransfer->ProviderIface.pfnObjClose(&m_pURITransfer->ProviderCtx, m_hObj);
     225                    AssertRC(rc2);
     226                }
     227
     228                if (m_pParent)
     229                {
     230                    m_pParent->OnTransferComplete();
     231                    m_fNotifiedComplete = true;
     232                }
     233            }
     234        }
     235
     236        LogFlowThisFunc(("Leave: rc=%Rrc, cbSize=%RU64, cbProcessed=%RU64 -> nBytesToRead=%RU32, cbToRead=%RU32, cbRead=%RU32\n",
     237                         rc, cbSize, m_cbProcessed, nBytesToRead, cbToRead, cbRead));
     238
     239        if (nBytesRead)
     240            *nBytesRead = (ULONG)cbRead;
     241
     242        if (nBytesToRead != cbRead)
     243            return S_FALSE;
     244
     245        return S_OK;
     246    }
     247    catch (...)
     248    {
     249        LogFunc(("Caught exception\n"));
     250    }
     251
     252    return E_FAIL;
    204253}
    205254
     
    207256{
    208257    LogFlowThisFuncEnter();
    209     return STG_E_INVALIDFUNCTION;
     258    return E_NOTIMPL;
    210259}
    211260
     
    214263    RT_NOREF(nMove, dwOrigin, nNewPos);
    215264
    216     LogFlowThisFuncEnter();
    217     return STG_E_INVALIDFUNCTION;
     265    LogFlowThisFunc(("nMove=%RI64, dwOrigin=%RI32\n", nMove, dwOrigin));
     266
     267    return E_NOTIMPL;
    218268}
    219269
     
    223273
    224274    LogFlowThisFuncEnter();
    225     return STG_E_INVALIDFUNCTION;
     275    return E_NOTIMPL;
    226276}
    227277
     
    242292            case STATFLAG_DEFAULT:
    243293            {
    244                 int rc2 = RTStrToUtf16(m_pURITransfer->ProviderIface.pfnObjGetPath(&m_pURITransfer->ProviderCtx, m_hObj),
    245                                        &pStatStg->pwcsName);
     294                int rc2 = RTStrToUtf16(m_strPath.c_str(), &pStatStg->pwcsName);
    246295                if (RT_FAILURE(rc2))
    247296                    hr = E_FAIL;
     
    259308            pStatStg->grfMode           = STGM_READ;
    260309            pStatStg->grfLocksSupported = 0;
    261             pStatStg->cbSize.QuadPart   = m_pURITransfer->ProviderIface.pfnObjGetSize(&m_pURITransfer->ProviderCtx, m_hObj);
     310            pStatStg->cbSize.QuadPart   = (uint64_t)m_objInfo.cbObject;
    262311        }
    263312    }
     
    274323
    275324    LogFlowThisFuncEnter();
    276     return STG_E_INVALIDFUNCTION;
     325    return E_NOTIMPL;
    277326}
    278327
     
    295344 * @param   pParent             Pointer to the parent data object.
    296345 * @param   pTransfer           Pointer to URI transfer object to use.
    297  * @param   hObj                Handle of URI transfer object.
     346 * @param   strPath             Path of object to handle for the stream.
     347 * @param   pObjInfo            Pointer to object information.
    298348 * @param   ppStream            Where to return the created stream object on success.
    299349 */
    300350/* static */
    301351HRESULT VBoxClipboardWinStreamImpl::Create(VBoxClipboardWinDataObject *pParent, PSHAREDCLIPBOARDURITRANSFER pTransfer,
    302                                            SHAREDCLIPBOARDOBJHANDLE hObj, IStream **ppStream)
     352                                           const Utf8Str &strPath, PSHAREDCLIPBOARDFSOBJINFO pObjInfo,
     353                                           IStream **ppStream)
    303354{
    304355    AssertPtrReturn(pTransfer, E_POINTER);
    305356
    306     VBoxClipboardWinStreamImpl *pStream = new VBoxClipboardWinStreamImpl(pParent, pTransfer, hObj);
     357    VBoxClipboardWinStreamImpl *pStream = new VBoxClipboardWinStreamImpl(pParent, pTransfer, strPath, pObjInfo);
    307358    if (pStream)
    308359    {
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-uri.cpp

    r79672 r79702  
    658658        if (pInfo)
    659659        {
     660            LogFlowFunc(("pszPath=%RU32\n", pOpenParms->pszPath));
     661
    660662            RTFSOBJINFO objInfo;
    661663            rc = RTPathQueryInfo(pOpenParms->pszPath, &objInfo, RTFSOBJATTRADD_NOTHING);
    662             if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
    663             {
    664                 rc = RTDirOpen(&pInfo->u.Local.hDirRoot, pOpenParms->pszPath);
    665             }
    666             else if (RTFS_IS_FILE(objInfo.Attr.fMode))
    667             {
    668                 rc = RTFileOpen(&pInfo->u.Local.hFile, pOpenParms->pszPath,
    669                                 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
    670             }
    671             else if (RTFS_IS_SYMLINK(objInfo.Attr.fMode))
    672             {
    673                 rc = VERR_NOT_IMPLEMENTED; /** @todo */
    674             }
    675             else
    676                 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
    677 
    678664            if (RT_SUCCESS(rc))
    679                 rc = SharedClipboardURIListOpenParmsCopy(&pInfo->OpenParms, pOpenParms);
    680 
    681             if (RT_SUCCESS(rc))
    682             {
    683                 pInfo->fMode = objInfo.Attr.fMode;
    684 
    685                 hList = sharedClipboardURITransferListHandleNew(pTransfer);
    686 
    687                 pTransfer->pMapLists->insert(
    688                     std::pair<SHAREDCLIPBOARDLISTHANDLE, PSHAREDCLIPBOARDURILISTHANDLEINFO>(hList, pInfo));
    689             }
    690             else
    691665            {
    692666                if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
    693667                {
    694                     if (RTDirIsValid(pInfo->u.Local.hDirRoot))
    695                         RTDirClose(pInfo->u.Local.hDirRoot);
     668                    rc = RTDirOpen(&pInfo->u.Local.hDirRoot, pOpenParms->pszPath);
    696669                }
    697670                else if (RTFS_IS_FILE(objInfo.Attr.fMode))
    698671                {
    699                     if (RTFileIsValid(pInfo->u.Local.hFile))
    700                         RTFileClose(pInfo->u.Local.hFile);
     672                    rc = RTFileOpen(&pInfo->u.Local.hFile, pOpenParms->pszPath,
     673                                    RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
    701674                }
    702 
    703                 RTMemFree(pInfo);
    704                 pInfo = NULL;
     675                else if (RTFS_IS_SYMLINK(objInfo.Attr.fMode))
     676                {
     677                    rc = VERR_NOT_IMPLEMENTED; /** @todo */
     678                }
     679                else
     680                    AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
     681
     682                if (RT_SUCCESS(rc))
     683                    rc = SharedClipboardURIListOpenParmsCopy(&pInfo->OpenParms, pOpenParms);
     684
     685                if (RT_SUCCESS(rc))
     686                {
     687                    pInfo->fMode = objInfo.Attr.fMode;
     688
     689                    hList = sharedClipboardURITransferListHandleNew(pTransfer);
     690
     691                    pTransfer->pMapLists->insert(
     692                        std::pair<SHAREDCLIPBOARDLISTHANDLE, PSHAREDCLIPBOARDURILISTHANDLEINFO>(hList, pInfo));
     693                }
     694                else
     695                {
     696                    if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
     697                    {
     698                        if (RTDirIsValid(pInfo->u.Local.hDirRoot))
     699                            RTDirClose(pInfo->u.Local.hDirRoot);
     700                    }
     701                    else if (RTFS_IS_FILE(objInfo.Attr.fMode))
     702                    {
     703                        if (RTFileIsValid(pInfo->u.Local.hFile))
     704                            RTFileClose(pInfo->u.Local.hFile);
     705                    }
     706
     707                    RTMemFree(pInfo);
     708                    pInfo = NULL;
     709                }
    705710            }
    706711        }
     
    13331338        for (size_t i = 0; i < pTransfer->lstRootEntries.size(); ++i)
    13341339        {
    1335             if (pszRoots)
    1336                 rc = RTStrAAppend(&pszRoots, "\r\n");
     1340            rc = RTStrAAppend(&pszRoots, pTransfer->lstRootEntries.at(i).c_str());
     1341
     1342            /* Add separation between paths.
     1343             * Note: Also do this for the last element of the list. */
    13371344            if (RT_SUCCESS(rc))
    1338                 rc = RTStrAAppend(&pszRoots, pTransfer->lstRootEntries.at(i).c_str());
     1345                rc = RTStrAAppendExN(&pszRoots, 1 /* cPairs */, "\r\n", 2 /* Bytes */);
    13391346
    13401347            if (RT_FAILURE(rc))
     
    13471354
    13481355            *ppszRoots = pszRoots;
    1349             *pcRoots     = (uint32_t)pTransfer->lstRootEntries.size();
     1356            *pcRoots   = (uint32_t)pTransfer->lstRootEntries.size();
    13501357        }
    13511358        else
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-uri.cpp

    r79672 r79702  
    5151int VBoxSvcClipboardURISetListOpen(uint32_t cParms, VBOXHGCMSVCPARM paParms[],
    5252                                   PVBOXCLIPBOARDLISTOPENPARMS pOpenParms);
     53int VBoxSvcClipboardURISetListClose(uint32_t cParms, VBOXHGCMSVCPARM paParms[],
     54                                    SHAREDCLIPBOARDLISTHANDLE hList);
    5355
    5456
     
    186188                                              PVBOXCLIPBOARDLISTOPENPARMS pOpenParms, PSHAREDCLIPBOARDLISTHANDLE phList)
    187189{
    188     RT_NOREF(phList);
    189 
    190190    LogFlowFuncEnter();
    191191
     
    241241DECLCALLBACK(int) vboxSvcClipboardURIListClose(PSHAREDCLIPBOARDPROVIDERCTX pCtx, SHAREDCLIPBOARDLISTHANDLE hList)
    242242{
    243     RT_NOREF(pCtx, hList);
    244 
    245     LogFlowFuncEnter();
    246 
    247     int rc = VINF_SUCCESS;
     243    LogFlowFuncEnter();
     244
     245    PVBOXCLIPBOARDCLIENT pClient = (PVBOXCLIPBOARDCLIENT)pCtx->pvUser;
     246    AssertPtr(pClient);
     247
     248    int rc;
     249
     250    PVBOXCLIPBOARDCLIENTMSG pMsg = vboxSvcClipboardMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_CLOSE,
     251                                                            VBOX_SHARED_CLIPBOARD_CPARMS_LIST_CLOSE);
     252    if (pMsg)
     253    {
     254        rc = VBoxSvcClipboardURISetListClose(pMsg->m_cParms, pMsg->m_paParms, hList);
     255        if (RT_SUCCESS(rc))
     256        {
     257            rc = vboxSvcClipboardMsgAdd(pClient->pData, pMsg, true /* fAppend */);
     258            if (RT_SUCCESS(rc))
     259            {
     260                int rc2 = SharedClipboardURITransferEventRegister(pCtx->pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_CLOSE);
     261                AssertRC(rc2);
     262
     263                vboxSvcClipboardClientWakeup(pClient);
     264            }
     265        }
     266    }
     267    else
     268        rc = VERR_NO_MEMORY;
     269
     270    if (RT_SUCCESS(rc))
     271    {
     272        PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload;
     273        rc = SharedClipboardURITransferEventWait(pCtx->pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_CLOSE,
     274                                                 30 * 1000 /* Timeout in ms */, &pPayload);
     275        if (RT_SUCCESS(rc))
     276            SharedClipboardURITransferPayloadFree(pPayload);
     277    }
    248278
    249279    LogFlowFuncLeaveRC(rc);
     
    378408    LogFlowFuncEnter();
    379409
    380     return VERR_NOT_IMPLEMENTED;
    381 }
    382 
    383 int vboxSvcClipboardURIObjClose(PSHAREDCLIPBOARDPROVIDERCTX pCtx, SHAREDCLIPBOARDOBJHANDLE hObj)
    384 {
    385     RT_NOREF(pCtx, hObj);
    386 
    387     LogFlowFuncEnter();
    388 
    389410    int rc = VINF_SUCCESS;
    390411
     
    396417}
    397418
     419int vboxSvcClipboardURIObjClose(PSHAREDCLIPBOARDPROVIDERCTX pCtx, SHAREDCLIPBOARDOBJHANDLE hObj)
     420{
     421    RT_NOREF(pCtx, hObj);
     422
     423    LogFlowFuncEnter();
     424
     425    int rc = VINF_SUCCESS;
     426
     427    PVBOXCLIPBOARDCONTEXT pThisCtx = (PVBOXCLIPBOARDCONTEXT)pCtx->pvUser;
     428    AssertPtr(pThisCtx);
     429
     430    LogFlowFuncLeaveRC(rc);
     431    return rc;
     432}
     433
    398434int vboxSvcClipboardURIObjRead(PSHAREDCLIPBOARDPROVIDERCTX pCtx, SHAREDCLIPBOARDOBJHANDLE hObj,
    399435                               void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbRead)
    400436{
    401     RT_NOREF(pCtx, pCtx, hObj, pvData, cbData, fFlags, pcbRead);
    402 
    403     LogFlowFuncEnter();
    404 
    405     return VERR_NOT_IMPLEMENTED;
     437    RT_NOREF(pCtx, hObj, pvData, cbData, fFlags, pcbRead);
     438
     439    LogFlowFuncEnter();
     440
     441    int rc = VINF_SUCCESS;
     442
     443    *pcbRead = cbData;
     444
     445    LogFlowFuncLeaveRC(rc);
     446    return rc;
    406447}
    407448
     
    454495    LogRel(("Shared Clipboard: Transfer failed with %Rrc\n", rc));
    455496}
     497
     498/*********************************************************************************************************************************
     499*   HGCM getters / setters                                                                                                       *
     500*********************************************************************************************************************************/
    456501
    457502/**
     
    522567}
    523568
     569/**
     570 * Gets the URI root entries from HGCM service parameters.
     571 *
     572 * @returns VBox status code.
     573 * @param   cParms              Number of HGCM parameters supplied in \a paParms.
     574 * @param   paParms             Array of HGCM parameters.
     575 * @param   pRoots              Where to store the URI root entries on success.
     576 */
    524577int VBoxSvcClipboardURIGetRoots(uint32_t cParms, VBOXHGCMSVCPARM paParms[],
    525578                                PVBOXCLIPBOARDROOTS pRoots)
     
    604657}
    605658
     659/**
     660 * Sets an URI list open request to HGCM service parameters.
     661 *
     662 * @returns VBox status code.
     663 * @param   cParms              Number of HGCM parameters supplied in \a paParms.
     664 * @param   paParms             Array of HGCM parameters.
     665 * @param   pOpenParms          List open parameters to set.
     666 */
    606667int VBoxSvcClipboardURISetListOpen(uint32_t cParms, VBOXHGCMSVCPARM paParms[],
    607668                                   PVBOXCLIPBOARDLISTOPENPARMS pOpenParms)
     
    618679        HGCMSvcSetPv (&paParms[5], pOpenParms->pszPath, pOpenParms->cbPath);
    619680        HGCMSvcSetU64(&paParms[6], 0); /* OUT: uHandle */
     681
     682        rc = VINF_SUCCESS;
     683    }
     684    else
     685        rc = VERR_INVALID_PARAMETER;
     686
     687    LogFlowFuncLeaveRC(rc);
     688    return rc;
     689}
     690
     691/**
     692 * Sets an URI list close request to HGCM service parameters.
     693 *
     694 * @returns VBox status code.
     695 * @param   cParms              Number of HGCM parameters supplied in \a paParms.
     696 * @param   paParms             Array of HGCM parameters.
     697 * @param   hList               Handle of list to close.
     698 */
     699int VBoxSvcClipboardURISetListClose(uint32_t cParms, VBOXHGCMSVCPARM paParms[],
     700                                    SHAREDCLIPBOARDLISTHANDLE hList)
     701{
     702    int rc;
     703
     704    if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_LIST_CLOSE)
     705    {
     706        HGCMSvcSetU32(&paParms[0], 0 /* uContextID */);
     707        HGCMSvcSetU64(&paParms[1], hList);
    620708
    621709        rc = VINF_SUCCESS;
     
    809897}
    810898
     899/**
     900 * Handles a guest reply (VBOX_SHARED_CLIPBOARD_GUEST_FN_REPLY) message.
     901 *
     902 * @returns VBox status code.
     903 * @param   pClient             Pointer to associated client.
     904 * @param   pTransfer           Pointer to transfer to handle guest reply for.
     905 * @param   cParms              Number of function parameters supplied.
     906 * @param   paParms             Array function parameters supplied.
     907 */
    811908int VBoxSvcClipboardURITransferHandleReply(PVBOXCLIPBOARDCLIENT pClient, PSHAREDCLIPBOARDURITRANSFER pTransfer,
    812909                                           uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     
    836933                        rc = SharedClipboardURITransferEventSignal(pTransfer,
    837934                                                                   SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_OPEN, pPayload);
     935                        break;
     936                    }
     937
     938                    case VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_LIST_CLOSE:
     939                    {
     940                        rc = SharedClipboardURITransferEventSignal(pTransfer,
     941                                                                   SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_CLOSE, pPayload);
     942                        break;
     943                    }
     944
     945                    case VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_OBJ_OPEN:
     946                    {
     947                        rc = SharedClipboardURITransferEventSignal(pTransfer,
     948                                                                   SHAREDCLIPBOARDURITRANSFEREVENTTYPE_OBJ_OPEN, pPayload);
     949                        break;
     950                    }
     951
     952                    case VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_OBJ_CLOSE:
     953                    {
     954                        rc = SharedClipboardURITransferEventSignal(pTransfer,
     955                                                                   SHAREDCLIPBOARDURITRANSFEREVENTTYPE_OBJ_CLOSE, pPayload);
    838956                        break;
    839957                    }
     
    9991117                        if (enmDir == SHAREDCLIPBOARDURITRANSFERDIR_READ)
    10001118                        {
    1001                             creationCtx.Interface.pfnGetRoots      = vboxSvcClipboardURIGetRoots;
    1002                             creationCtx.Interface.pfnListHdrRead   = vboxSvcClipboardURIListHdrRead;
    1003                             creationCtx.Interface.pfnListEntryRead = vboxSvcClipboardURIListEntryRead;
    1004                             creationCtx.Interface.pfnObjRead       = vboxSvcClipboardURIObjRead;
     1119                            creationCtx.Interface.pfnGetRoots        = vboxSvcClipboardURIGetRoots;
     1120                            creationCtx.Interface.pfnListHdrRead     = vboxSvcClipboardURIListHdrRead;
     1121                            creationCtx.Interface.pfnListEntryRead   = vboxSvcClipboardURIListEntryRead;
     1122                            creationCtx.Interface.pfnObjRead         = vboxSvcClipboardURIObjRead;
    10051123                        }
    10061124                        else
Note: See TracChangeset for help on using the changeset viewer.

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