VirtualBox

Changeset 81212 in vbox


Ignore:
Timestamp:
Oct 10, 2019 12:22:34 PM (5 years ago)
Author:
vboxsync
Message:

Shared Clipboard/Transfers: Update.

Location:
trunk
Files:
11 edited

Legend:

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

    r81025 r81212  
    655655
    656656int SharedClipboardTransferRootListEntryCopy(PSHCLROOTLISTENTRY pDst, PSHCLROOTLISTENTRY pSrc);
     657int SharedClipboardTransferRootListEntryInit(PSHCLROOTLISTENTRY pRootListEntry);
     658void SharedClipboardTransferRootListEntryDestroy(PSHCLROOTLISTENTRY pRootListEntry);
    657659PSHCLROOTLISTENTRY SharedClipboardTransferRootListEntryDup(PSHCLROOTLISTENTRY pRootListEntry);
    658 void SharedClipboardTransferRootListEntryDestroy(PSHCLROOTLISTENTRY pRootListEntry);
    659660
    660661int SharedClipboardTransferListHdrAlloc(PSHCLLISTHDR *ppListHdr);
     
    10431044{
    10441045    /** Actual status to report. */
    1045     SHCLTRANSFERSTATUS uStatus;
     1046    SHCLTRANSFERSTATUS    uStatus;
    10461047    /** Result code (rc) to report; might be unused / invalid, based on enmStatus. */
    10471048    int                   rc;
     
    10731074bool SharedClipboardTransferObjCtxIsValid(PSHCLCLIENTTRANSFEROBJCTX pObjCtx);
    10741075
     1076int SharedClipboardTransferObjectHandleInfoInit(PSHCLOBJHANDLEINFO pInfo);
     1077void SharedClipboardTransferObjectHandleInfoDestroy(PSHCLOBJHANDLEINFO pInfo);
     1078
    10751079int SharedClipboardTransferObjectOpenParmsInit(PSHCLOBJOPENCREATEPARMS pParms);
    10761080int SharedClipboardTransferObjectOpenParmsCopy(PSHCLOBJOPENCREATEPARMS pParmsDst, PSHCLOBJOPENCREATEPARMS pParmsSrc);
  • trunk/include/VBox/GuestHost/SharedClipboard-win.h

    r81172 r81212  
    138138
    139139#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
     140int SharedClipboardWinGetRoots(PSHCLWINCTX pWinCtx, PSHCLTRANSFER pTransfer);
    140141int SharedClipboardWinDropFilesToStringList(DROPFILES *pDropFiles, char **papszList, uint32_t *pcbList);
    141142#endif
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp

    r81134 r81212  
    154154    if (enmDir == SHCLTRANSFERDIR_WRITE)
    155155    {
    156         Assert(SharedClipboardTransferGetSource(pTransfer) == SHCLSOURCE_LOCAL); /* Sanity. */
    157 
    158         rc = SharedClipboardWinOpen(pCtx->Win.hWnd);
    159         if (RT_SUCCESS(rc))
    160         {
    161             /* The data data in CF_HDROP format, as the files are locally present and don't need to be
    162              * presented as a IDataObject or IStream. */
    163             HANDLE hClip = hClip = GetClipboardData(CF_HDROP);
    164             if (hClip)
    165             {
    166                 HDROP hDrop = (HDROP)GlobalLock(hClip);
    167                 if (hDrop)
    168                 {
    169                     char    *papszList = NULL;
    170                     uint32_t cbList;
    171                     rc = SharedClipboardWinDropFilesToStringList((DROPFILES *)hDrop, &papszList, &cbList);
    172 
    173                     GlobalUnlock(hClip);
    174 
    175                     if (RT_SUCCESS(rc))
    176                     {
    177                         rc = SharedClipboardTransferRootsSet(pTransfer,
    178                                                              papszList, cbList + 1 /* Include termination */);
    179                         RTStrFree(papszList);
    180                     }
    181                 }
    182                 else
    183                     LogRel(("Shared Clipboard: Unable to lock clipboard data, last error: %ld\n", GetLastError()));
    184             }
    185             else
    186                 LogRel(("Shared Clipboard: Unable to retrieve clipboard data from clipboard (CF_HDROP), last error: %ld\n",
    187                         GetLastError()));
    188 
    189             SharedClipboardWinClose();
    190         }
     156        rc = SharedClipboardWinGetRoots(&pCtx->Win, pTransfer);
    191157    }
    192158    /* The guest wants to read data from a remote source. */
    193159    else if (enmDir == SHCLTRANSFERDIR_READ)
    194160    {
    195         Assert(SharedClipboardTransferGetSource(pTransfer) == SHCLSOURCE_REMOTE); /* Sanity. */
    196 
    197         rc = SharedClipboardWinTransferCreate(&pCtx->Win, pTransfer);
     161        /* The IDataObject *must* be created on the same thread as our (proxy) window, so post a message to it
     162         * to do the stuff for us. */
     163        const SHCLEVENTID uEvent = SharedClipboardEventIDGenerate(&pTransfer->Events);
     164
     165        rc = SharedClipboardEventRegister(&pTransfer->Events, uEvent);
     166        if (RT_SUCCESS(rc))
     167        {
     168            /* Don't want to rely on SendMessage (synchronous) here, so just post and wait the event getting signalled. */
     169            ::PostMessage(pCtx->Win.hWnd, SHCL_WIN_WM_TRANSFER_START, (WPARAM)pTransfer, (LPARAM)uEvent);
     170
     171            PSHCLEVENTPAYLOAD pPayload;
     172            rc = SharedClipboardEventWait(&pTransfer->Events, uEvent, 30 * 1000 /* Timeout in ms */, &pPayload);
     173            if (RT_SUCCESS(rc))
     174            {
     175                Assert(pPayload->cbData == sizeof(int));
     176                rc = *(int *)pPayload->pvData;
     177
     178                SharedClipboardPayloadFree(pPayload);
     179            }
     180
     181            SharedClipboardEventUnregister(&pTransfer->Events, uEvent);
     182        }
    198183    }
    199184    else
    200185        AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
     186
     187    if (RT_FAILURE(rc))
     188        LogRel(("Shared Clipboard: Starting transfer failed, rc=%Rrc\n", rc));
    201189
    202190    LogFlowFunc(("LEAVE: idTransfer=%RU16, rc=%Rrc\n", SharedClipboardTransferGetID(pTransfer), rc));
     
    651639        }
    652640
    653 #if 0
    654641        case SHCL_WIN_WM_TRANSFER_START:
    655642        {
    656643            LogFunc(("SHCL_WIN_WM_TRANSFER_START\n"));
    657644
    658             PSHCLTRANSFER pTransfer = (PSHCLTRANSFER)lParam;
     645            PSHCLTRANSFER pTransfer  = (PSHCLTRANSFER)wParam;
    659646            AssertPtr(pTransfer);
    660647
     648            const SHCLEVENTID uEvent = (SHCLEVENTID)lParam;
     649
    661650            Assert(SharedClipboardTransferGetSource(pTransfer) == SHCLSOURCE_REMOTE); /* Sanity. */
    662651
    663             int rc2 = SharedClipboardWinTransferCreate(pWinCtx, pTransfer);
    664             AssertRC(rc2);
    665             break;
    666         }
    667 #endif
     652            int rcTransfer = SharedClipboardWinTransferCreate(pWinCtx, pTransfer);
     653
     654            PSHCLEVENTPAYLOAD pPayload = NULL;
     655            int rc = SharedClipboardPayloadAlloc(uEvent, &rcTransfer, sizeof(rcTransfer), &pPayload);
     656            if (RT_SUCCESS(rc))
     657            {
     658                rc = SharedClipboardEventSignal(&pTransfer->Events, uEvent, pPayload);
     659                if (RT_FAILURE(rc))
     660                    SharedClipboardPayloadFree(pPayload);
     661            }
     662
     663            break;
     664        }
    668665
    669666        case WM_DESTROY:
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp

    r81154 r81212  
    501501                    for (uint32_t i = 0; i < srcRootListHdr.cRoots; i++)
    502502                    {
    503                         rc = vbglR3ClipboardRootListEntryRead(pCtx, i, &pRootList->paEntries[i]);
     503                        SHCLROOTLISTENTRY *pEntry = &pRootList->paEntries[i];
     504                        AssertPtr(pEntry);
     505
     506                        rc = SharedClipboardTransferRootListEntryInit(pEntry);
     507                        if (RT_SUCCESS(rc))
     508                            rc = vbglR3ClipboardRootListEntryRead(pCtx, i, pEntry);
     509
    504510                        if (RT_FAILURE(rc))
    505511                            break;
     
    12661272    Msg.uHandle.SetUInt64(0);
    12671273    Msg.cbPath.SetUInt32(pCreateParms->cbPath);
    1268     Msg.szPath.SetPtr((void *)pCreateParms->pszPath, pCreateParms->cbPath + 1 /* Include terminating zero */);
     1274    Msg.szPath.SetPtr((void *)pCreateParms->pszPath, pCreateParms->cbPath);
    12691275    Msg.fCreate.SetUInt32(pCreateParms->fCreate);
    12701276
     
    14401446    Msg.uContext.SetUInt32(pCtx->uContextID);
    14411447    Msg.uHandle.SetUInt64(hObj);
     1448    Msg.cbData.SetUInt32(cbData);
    14421449    Msg.pvData.SetPtr(pvData, cbData);
    1443     Msg.cbData.SetUInt32(cbData);
     1450    Msg.cbChecksum.SetUInt32(0);
    14441451    Msg.pvChecksum.SetPtr(NULL, 0);
    1445     Msg.cbChecksum.SetUInt32(0);
    14461452
    14471453    int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-transfers.cpp

    r81025 r81212  
    131131 *
    132132 * @returns VBox status code.
    133  * @param   pListEntry          Clipboard root list entry to copy.
     133 * @param   pDst                Where to copy the source root list entry to.
     134 * @param   pSrc                Source root list entry to copy.
    134135 */
    135136int SharedClipboardTransferRootListEntryCopy(PSHCLROOTLISTENTRY pDst, PSHCLROOTLISTENTRY pSrc)
     
    139140
    140141/**
     142 * Initializes a clipboard root list entry structure.
     143 *
     144 * @param   pRootListEntry      Clipboard root list entry structure to destroy.
     145 */
     146int SharedClipboardTransferRootListEntryInit(PSHCLROOTLISTENTRY pRootListEntry)
     147{
     148    return SharedClipboardTransferListEntryInit(pRootListEntry);
     149}
     150
     151/**
     152 * Destroys a clipboard root list entry structure.
     153 *
     154 * @param   pRootListEntry      Clipboard root list entry structure to destroy.
     155 */
     156void SharedClipboardTransferRootListEntryDestroy(PSHCLROOTLISTENTRY pRootListEntry)
     157{
     158    return SharedClipboardTransferListEntryDestroy(pRootListEntry);
     159}
     160
     161/**
    141162 * Duplicates (allocates) a clipboard root list entry structure.
    142163 *
    143164 * @returns Duplicated clipboard root list entry structure on success.
    144  * @param   pListEntry          Clipboard root list entry to duplicate.
     165 * @param   pRootListEntry      Clipboard root list entry to duplicate.
    145166 */
    146167PSHCLROOTLISTENTRY SharedClipboardTransferRootListEntryDup(PSHCLROOTLISTENTRY pRootListEntry)
    147168{
    148169    return SharedClipboardTransferListEntryDup(pRootListEntry);
    149 }
    150 
    151 /**
    152  * Destroys a clipboard root list entry structure.
    153  *
    154  * @param   pListEntry          Clipboard root list entry structure to destroy.
    155  */
    156 void SharedClipboardTransferRootListEntryDestroy(PSHCLROOTLISTENTRY pRootListEntry)
    157 {
    158     return SharedClipboardTransferListEntryDestroy(pRootListEntry);
    159170}
    160171
     
    517528
    518529    pListEntry->cbName = SHCLLISTENTRY_MAX_NAME;
    519     pListEntry->pvInfo = NULL;
    520     pListEntry->cbInfo = 0;
    521     pListEntry->fInfo  = 0;
    522 
    523     return VINF_SUCCESS;
     530
     531    pListEntry->pvInfo = (PSHCLFSOBJINFO)RTMemAlloc(sizeof(SHCLFSOBJINFO));
     532    if (pListEntry->pvInfo)
     533    {
     534        pListEntry->cbInfo = sizeof(SHCLFSOBJINFO);
     535        pListEntry->fInfo  = VBOX_SHCL_INFO_FLAG_FSOBJINFO;
     536
     537        return VINF_SUCCESS;
     538    }
     539
     540    return VERR_NO_MEMORY;
    524541}
    525542
     
    607624
    608625/**
     626 * Initializes an object handle info structure.
     627 *
     628 * @returns VBox status code.
     629 * @param   pInfo               Object handle info structure to initialize.
     630 */
     631int SharedClipboardTransferObjectHandleInfoInit(PSHCLOBJHANDLEINFO pInfo)
     632{
     633    AssertPtrReturn(pInfo, VERR_INVALID_POINTER);
     634
     635    pInfo->hObj    = SHCLOBJHANDLE_INVALID;
     636    pInfo->enmType = SHCLOBJTYPE_INVALID;
     637
     638    pInfo->pszPathLocalAbs = NULL;
     639
     640    RT_ZERO(pInfo->u);
     641
     642    return VINF_SUCCESS;
     643}
     644
     645/**
    609646 * Destroys an object handle info structure.
    610647 *
     
    743780        if (pInfo)
    744781        {
    745             const bool fWritable = true; /** @todo Fix this. */
    746 
    747             uint64_t fOpen;
    748             rc = sharedClipboardConvertFileCreateFlags(fWritable,
    749                                                        pOpenCreateParms->fCreate, pOpenCreateParms->ObjInfo.Attr.fMode,
    750                                                        SHCLOBJHANDLE_INVALID, &fOpen);
     782            rc = SharedClipboardTransferObjectHandleInfoInit(pInfo);
    751783            if (RT_SUCCESS(rc))
    752784            {
    753                 char *pszPathAbs = RTStrAPrintf2("%s/%s", pTransfer->pszPathRootAbs, pOpenCreateParms->pszPath);
    754                 if (pszPathAbs)
     785                const bool fWritable = true; /** @todo Fix this. */
     786
     787                uint64_t fOpen;
     788                rc = sharedClipboardConvertFileCreateFlags(fWritable,
     789                                                           pOpenCreateParms->fCreate, pOpenCreateParms->ObjInfo.Attr.fMode,
     790                                                           SHCLOBJHANDLE_INVALID, &fOpen);
     791                if (RT_SUCCESS(rc))
    755792                {
    756                     LogFlowFunc(("%s\n", pszPathAbs));
    757 
    758                     rc = RTFileOpen(&pInfo->u.Local.hFile, pszPathAbs, fOpen);
    759                     RTStrFree(pszPathAbs);
     793                    char *pszPathAbs = RTStrAPrintf2("%s/%s", pTransfer->pszPathRootAbs, pOpenCreateParms->pszPath);
     794                    if (pszPathAbs)
     795                    {
     796                        LogFlowFunc(("%s\n", pszPathAbs));
     797
     798                        rc = RTFileOpen(&pInfo->u.Local.hFile, pszPathAbs, fOpen);
     799                        RTStrFree(pszPathAbs);
     800                    }
     801                    else
     802                        rc = VERR_NO_MEMORY;
    760803                }
    761                 else
    762                     rc = VERR_NO_MEMORY;
    763804            }
    764805
     
    772813                *phObj = pInfo->hObj;
    773814            }
    774 
    775             if (RT_FAILURE(rc))
     815            else
     816            {
     817                SharedClipboardTransferObjectHandleInfoDestroy(pInfo);
    776818                RTMemFree(pInfo);
     819            }
    777820        }
    778821        else
     
    17461789                                && !fSkipEntry)
    17471790                            {
    1748                                 pEntry->pvInfo = (PSHCLFSOBJINFO)RTMemAlloc(sizeof(SHCLFSOBJINFO));
    1749                                 if (pEntry->pvInfo)
     1791                                rc = RTStrCopy(pEntry->pszName, pEntry->cbName, pDirEntry->szName);
     1792                                if (RT_SUCCESS(rc))
    17501793                                {
    1751                                     rc = RTStrCopy(pEntry->pszName, pEntry->cbName, pDirEntry->szName);
    1752                                     if (RT_SUCCESS(rc))
    1753                                     {
    1754                                         SharedClipboardFsObjFromIPRT(PSHCLFSOBJINFO(pEntry->pvInfo), &pDirEntry->Info);
    1755 
    1756                                         pEntry->cbInfo = sizeof(SHCLFSOBJINFO);
    1757                                         pEntry->fInfo  = VBOX_SHCL_INFO_FLAG_FSOBJINFO;
    1758                                     }
     1794                                    AssertPtr(pEntry->pvInfo);
     1795                                    Assert   (pEntry->cbInfo == sizeof(SHCLFSOBJINFO));
     1796
     1797                                    SharedClipboardFsObjFromIPRT(PSHCLFSOBJINFO(pEntry->pvInfo), &pDirEntry->Info);
    17591798                                }
    1760                                 else
    1761                                     rc = VERR_NO_MEMORY;
    17621799                            }
    17631800
     
    20332070                {
    20342071                    RTFSOBJINFO fsObjInfo;
    2035                     rc = RTPathQueryInfo(pcszSrcPath, & fsObjInfo, RTFSOBJATTRADD_NOTHING);
     2072                    rc = RTPathQueryInfo(pcszSrcPath, &fsObjInfo, RTFSOBJATTRADD_NOTHING);
    20362073                    if (RT_SUCCESS(rc))
    20372074                    {
    20382075                        SharedClipboardFsObjFromIPRT(PSHCLFSOBJINFO(pEntry->pvInfo), &fsObjInfo);
    20392076
    2040                         pEntry->fInfo  = VBOX_SHCL_INFO_FLAG_FSOBJINFO;
     2077                        pEntry->fInfo = VBOX_SHCL_INFO_FLAG_FSOBJINFO;
    20412078                    }
    20422079                }
     
    22472284
    22482285/**
    2249  * Starts (runs) a Shared Clipboard transfer in a dedicated thread.
     2286 * Runs a started Shared Clipboard transfer in a dedicated thread.
    22502287 *
    22512288 * @returns VBox status code.
    22522289 * @param   pTransfer           Clipboard transfer to run.
    22532290 * @param   pfnThreadFunc       Pointer to thread function to use.
    2254  * @param   pvUser              Pointer to user-provided data.
     2291 * @param   pvUser              Pointer to user-provided data. Optional.
    22552292 */
    22562293int SharedClipboardTransferRun(PSHCLTRANSFER pTransfer, PFNRTTHREAD pfnThreadFunc, void *pvUser)
    22572294{
    2258     AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
    2259 
    2260     int rc = SharedClipboardTransferStart(pTransfer);
    2261     if (RT_SUCCESS(rc))
    2262         rc = sharedClipboardTransferThreadCreate(pTransfer, pfnThreadFunc, pvUser);
     2295    AssertPtrReturn(pTransfer,     VERR_INVALID_POINTER);
     2296    AssertPtrReturn(pfnThreadFunc, VERR_INVALID_POINTER);
     2297    /* pvUser is optional. */
     2298
     2299    AssertMsgReturn(pTransfer->State.enmStatus == SHCLTRANSFERSTATUS_STARTED,
     2300                    ("Wrong status (currently is %s)\n", VBoxShClTransferStatusToStr(pTransfer->State.enmStatus)),
     2301                    VERR_WRONG_ORDER);
     2302
     2303    int rc = sharedClipboardTransferThreadCreate(pTransfer, pfnThreadFunc, pvUser);
    22632304
    22642305    LogFlowFuncLeaveRC(rc);
     
    22752316{
    22762317    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     2318
     2319    LogFlowFuncEnter();
    22772320
    22782321    /* Ready to start? */
     
    22912334        rc = VINF_SUCCESS;
    22922335
    2293     /* Nothing else to do here right now. */
     2336    if (RT_SUCCESS(rc))
     2337    {
     2338        pTransfer->State.enmStatus = SHCLTRANSFERSTATUS_STARTED;
     2339    }
    22942340
    22952341    LogFlowFuncLeaveRC(rc);
     
    23422388    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
    23432389
     2390    /* Already marked for stopping? */
     2391    AssertMsgReturn(pTransfer->Thread.fStop == false,
     2392                    ("Thransfer thread already marked for stopping"), VERR_WRONG_ORDER);
     2393    /* Already started? */
     2394    AssertMsgReturn(pTransfer->Thread.fStarted == false,
     2395                    ("Thransfer thread already started"), VERR_WRONG_ORDER);
     2396
    23442397    /* Spawn a worker thread, so that we don't block the window thread for too long. */
    23452398    int rc = RTThreadCreate(&pTransfer->Thread.hThread, pfnThreadFunc,
     
    23532406        if (pTransfer->Thread.fStarted) /* Did the thread indicate that it started correctly? */
    23542407        {
    2355             pTransfer->State.enmStatus = SHCLTRANSFERSTATUS_STARTED;
     2408            /* Nothing to do in here. */
    23562409        }
    23572410        else
     
    23912444
    23922445/**
    2393  * Initializes a Shared Clipboard transfer.
     2446 * Initializes a Shared Clipboard transfer context.
    23942447 *
    23952448 * @returns VBox status code.
     
    24072460        RTListInit(&pTransferCtx->List);
    24082461
     2462        pTransferCtx->cTransfers  = 0;
    24092463        pTransferCtx->cRunning    = 0;
    2410         pTransferCtx->cMaxRunning = UINT16_MAX;
     2464        pTransferCtx->cMaxRunning = UINT16_MAX; /** @todo Make this configurable? */
    24112465
    24122466        RT_ZERO(pTransferCtx->bmTransferIds);
     
    24192473
    24202474/**
    2421  * Destroys a shared Clipboard transfer context context struct.
     2475 * Destroys a shared Clipboard transfer context struct.
    24222476 *
    24232477 * @param   pTransferCtx                Transfer context to destroy.
     
    26422696                 pTransferCtx, pTransferCtx->cTransfers, pTransferCtx->cRunning));
    26432697
    2644     if (!RTListIsEmpty(&pTransferCtx->List))
    2645     {
    2646         /* Remove all transfers which are not in a running state (e.g. only announced). */
    2647         PSHCLTRANSFER pTransfer, pTransferNext;
    2648         RTListForEachSafe(&pTransferCtx->List, pTransfer, pTransferNext, SHCLTRANSFER, Node)
    2649         {
    2650             if (SharedClipboardTransferGetStatus(pTransfer) != SHCLTRANSFERSTATUS_STARTED)
    2651             {
    2652                 SharedClipboardTransferDestroy(pTransfer);
    2653                 RTListNodeRemove(&pTransfer->Node);
    2654 
    2655                 RTMemFree(pTransfer);
    2656                 pTransfer = NULL;
    2657 
    2658                 Assert(pTransferCtx->cTransfers);
    2659                 pTransferCtx->cTransfers--;
    2660             }
     2698    if (pTransferCtx->cTransfers == 0)
     2699        return;
     2700
     2701    /* Remove all transfers which are not in a running state (e.g. only announced). */
     2702    PSHCLTRANSFER pTransfer, pTransferNext;
     2703    RTListForEachSafe(&pTransferCtx->List, pTransfer, pTransferNext, SHCLTRANSFER, Node)
     2704    {
     2705        if (SharedClipboardTransferGetStatus(pTransfer) != SHCLTRANSFERSTATUS_STARTED)
     2706        {
     2707            SharedClipboardTransferDestroy(pTransfer);
     2708            RTListNodeRemove(&pTransfer->Node);
     2709
     2710            RTMemFree(pTransfer);
     2711            pTransfer = NULL;
     2712
     2713            Assert(pTransferCtx->cTransfers);
     2714            pTransferCtx->cTransfers--;
    26612715        }
    26622716    }
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp

    r81025 r81212  
    459459        LogFlowFunc(("fFormats=0x%08X\n", fFormats));
    460460
    461         pFormats->uFormats   = fFormats;
    462         pFormats->fFlags = 0; /** @todo Handle flags. */
     461        pFormats->uFormats = fFormats;
     462        pFormats->fFlags   = 0; /** @todo Handle flags. */
    463463    }
    464464
     
    889889 * @returns VBox status code.
    890890 * @param   pWinCtx             Windows context to use.
    891  * @param   pTransferCtxCtx             transfer contextto use.
     891 * @param   pTransferCtxCtx     Transfer contextto use.
    892892 * @param   pTransfer           Shared Clipboard transfer to use.
    893893 */
     
    10031003
    10041004/**
     1005 * Retrieves the roots for a transfer by opening the clipboard and getting the clipboard data
     1006 * as string list (CF_HDROP), assigning it to the transfer as roots then.
     1007 *
     1008 * @returns VBox status code.
     1009 * @param   pWinCtx             Windows context to use.
     1010 * @param   pTransfer           Transfer to get roots for.
     1011 */
     1012int SharedClipboardWinGetRoots(PSHCLWINCTX pWinCtx, PSHCLTRANSFER pTransfer)
     1013{
     1014    AssertPtrReturn(pWinCtx,   VERR_INVALID_POINTER);
     1015    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     1016
     1017    Assert(SharedClipboardTransferGetSource(pTransfer) == SHCLSOURCE_LOCAL); /* Sanity. */
     1018
     1019    int rc = SharedClipboardWinOpen(pWinCtx->hWnd);
     1020    if (RT_SUCCESS(rc))
     1021    {
     1022        /* The data data in CF_HDROP format, as the files are locally present and don't need to be
     1023         * presented as a IDataObject or IStream. */
     1024        HANDLE hClip = hClip = GetClipboardData(CF_HDROP);
     1025        if (hClip)
     1026        {
     1027            HDROP hDrop = (HDROP)GlobalLock(hClip);
     1028            if (hDrop)
     1029            {
     1030                char    *papszList = NULL;
     1031                uint32_t cbList;
     1032                rc = SharedClipboardWinDropFilesToStringList((DROPFILES *)hDrop, &papszList, &cbList);
     1033
     1034                GlobalUnlock(hClip);
     1035
     1036                if (RT_SUCCESS(rc))
     1037                {
     1038                    rc = SharedClipboardTransferRootsSet(pTransfer,
     1039                                                         papszList, cbList + 1 /* Include termination */);
     1040                    RTStrFree(papszList);
     1041                }
     1042            }
     1043            else
     1044                LogRel(("Shared Clipboard: Unable to lock clipboard data, last error: %ld\n", GetLastError()));
     1045        }
     1046        else
     1047            LogRel(("Shared Clipboard: Unable to retrieve clipboard data from clipboard (CF_HDROP), last error: %ld\n",
     1048                    GetLastError()));
     1049
     1050        SharedClipboardWinClose();
     1051    }
     1052
     1053    LogFlowFuncLeaveRC(rc);
     1054    return rc;
     1055}
     1056
     1057/**
    10051058 * Converts a DROPFILES (HDROP) structure to a string list, separated by \r\n.
    10061059 * Does not do any locking on the input data.
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h

    r81174 r81212  
    202202#endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
    203203
    204 /*
    205  * Platform-dependent implementations.
     204/** @name Platform-dependent implementations for the Shared Clipboard host service.
     205 * @{
    206206 */
    207207/**
     
    258258int ShClSvcImplWriteData(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, PSHCLDATABLOCK pData);
    259259/**
    260  * Synchronise the contents of the host clipboard with the guest, called by the HGCM layer
    261  * after a save and restore of the guest.
     260 * Called when synchronization of the clipboard contents of the host clipboard with the guest is needed.
    262261 *
    263262 * @returns VBox status code.
     
    265264 */
    266265int ShClSvcImplSync(PSHCLCLIENT pClient);
     266/** @} */
    267267
    268268#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
     269/** @name Host implementations for Shared Clipboard transfers.
     270 * @{
     271 */
     272/**
     273 * Called when a transfer gets created.
     274 *
     275 * @returns VBox status code.
     276 * @param   pClient             Shared Clipboard client context.
     277 * @param   pTransfer           Shared Clipboard transfer created.
     278 */
     279int ShClSvcImplTransferCreate(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);
     280/**
     281 * Called when a transfer gets destroyed.
     282 *
     283 * @returns VBox status code.
     284 * @param   pClient             Shared Clipboard client context.
     285 * @param   pTransfer           Shared Clipboard transfer to destroy.
     286 */
     287int ShClSvcImplTransferDestroy(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);
     288/**
     289 * Called when getting (determining) the transfer roots on the host side.
     290 *
     291 * @returns VBox status code.
     292 * @param   pClient             Shared Clipboard client context.
     293 * @param   pTransfer           Shared Clipboard transfer to get roots for.
     294 */
     295int ShClSvcImplTransferGetRoots(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);
     296/** @} */
     297#endif
     298
     299#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
     300/** @name Internal Shared Clipboard transfer host service functions.
     301 * @{
     302 */
    269303int shclSvcTransferAreaDetach(PSHCLCLIENTSTATE pClientState, PSHCLTRANSFER pTransfer);
    270304int shclSvcTransferHandler(PSHCLCLIENT pClient, VBOXHGCMCALLHANDLE callHandle, uint32_t u32Function,
    271305                           uint32_t cParms, VBOXHGCMSVCPARM paParms[], uint64_t tsArrival);
    272306int shclSvcTransferHostHandler(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    273 
     307/** @} */
     308
     309/** @name Shared Clipboard transfer interface implementations for the host service.
     310 * @{
     311 */
    274312int shclSvcTransferIfaceOpen(PSHCLPROVIDERCTX pCtx);
    275313int shclSvcTransferIfaceClose(PSHCLPROVIDERCTX pCtx);
     
    291329int shclSvcTransferIfaceObjWrite(PSHCLPROVIDERCTX pCtx, SHCLOBJHANDLE hObj,
    292330                                 void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbWritten);
    293 
     331/** @} */
     332
     333/** @name Shared Clipboard transfer callbacks for the host service.
     334 * @{
     335 */
    294336DECLCALLBACK(void) VBoxSvcClipboardTransferPrepareCallback(PSHCLTRANSFERCALLBACKDATA pData);
    295337DECLCALLBACK(void) VBoxSvcClipboardDataHeaderCompleteCallback(PSHCLTRANSFERCALLBACKDATA pData);
     
    298340DECLCALLBACK(void) VBoxSvcClipboardTransferCanceledCallback(PSHCLTRANSFERCALLBACKDATA pData);
    299341DECLCALLBACK(void) VBoxSvcClipboardTransferErrorCallback(PSHCLTRANSFERCALLBACKDATA pData, int rc);
    300 
    301 int ShClSvcImplTransferCreate(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);
    302 int ShClSvcImplTransferDestroy(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);
     342/** @} */
    303343#endif /*VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
    304344
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-transfers.cpp

    r81025 r81212  
    12731273
    12741274/**
    1275  * transfer client (guest) handler for the Shared Clipboard host service.
     1275 * Transfer client (guest) handler for the Shared Clipboard host service.
    12761276 *
    12771277 * @returns VBox status code, or VINF_HGCM_ASYNC_EXECUTE if returning to the client will be deferred.
     
    14201420                {
    14211421                    HGCMSvcSetPv (&paParms[3], rootListEntry.pszName, rootListEntry.cbName);
    1422                     HGCMSvcSetU32(&paParms[4], rootListEntry.cbName);
     1422                    HGCMSvcSetU32(&paParms[4], rootListEntry.cbInfo);
    14231423                    HGCMSvcSetPv (&paParms[5], rootListEntry.pvInfo, rootListEntry.cbInfo);
    14241424                }
     
    15691569        }
    15701570
    1571     #if 0
    15721571        case VBOX_SHCL_GUEST_FN_OBJ_OPEN:
    15731572        {
     1573            if (cParms != VBOX_SHCL_CPARMS_OBJ_OPEN)
     1574                break;
     1575
     1576            SHCLOBJOPENCREATEPARMS openCreateParms;
     1577            RT_ZERO(openCreateParms);
     1578
     1579            uint32_t cbPath;
     1580            rc = HGCMSvcGetU32(&paParms[2], &cbPath);
     1581            if (RT_SUCCESS(rc))
     1582            {
     1583                rc = HGCMSvcGetPv(&paParms[3], (void **)&openCreateParms.pszPath, &openCreateParms.cbPath);
     1584                if (cbPath != openCreateParms.cbPath)
     1585                    rc = VERR_INVALID_PARAMETER;
     1586            }
     1587            if (RT_SUCCESS(rc))
     1588                rc = HGCMSvcGetU32(&paParms[4], &openCreateParms.fCreate);
     1589
     1590            if (RT_SUCCESS(rc))
     1591            {
     1592                SHCLOBJHANDLE hObj;
     1593                rc = SharedClipboardTransferObjectOpen(pTransfer, &openCreateParms, &hObj);
     1594                if (RT_SUCCESS(rc))
     1595                {
     1596                    LogFlowFunc(("hObj=%RU64\n", hObj));
     1597
     1598                    HGCMSvcSetU64(&paParms[1], hObj);
     1599                }
     1600            }
    15741601            break;
    15751602        }
     
    15771604        case VBOX_SHCL_GUEST_FN_OBJ_CLOSE:
    15781605        {
     1606            if (cParms != VBOX_SHCL_CPARMS_OBJ_CLOSE)
     1607                break;
     1608
     1609            SHCLOBJHANDLE hObj;
     1610            rc = HGCMSvcGetU64(&paParms[1], &hObj); /* Get object handle. */
     1611            if (RT_SUCCESS(rc))
     1612                rc = SharedClipboardTransferObjectClose(pTransfer, hObj);
    15791613            break;
    15801614        }
     
    15821616        case VBOX_SHCL_GUEST_FN_OBJ_READ:
    15831617        {
    1584             break;
    1585         }
    1586     #endif
     1618            if (cParms != VBOX_SHCL_CPARMS_OBJ_READ)
     1619                break;
     1620
     1621            SHCLOBJHANDLE hObj;
     1622            rc = HGCMSvcGetU64(&paParms[1], &hObj); /* Get object handle. */
     1623
     1624            uint32_t cbToRead = 0;
     1625            if (RT_SUCCESS(rc))
     1626                rc = HGCMSvcGetU32(&paParms[2], &cbToRead);
     1627
     1628            void    *pvBuf = NULL;
     1629            uint32_t cbBuf = 0;
     1630            if (RT_SUCCESS(rc))
     1631                rc = HGCMSvcGetPv(&paParms[3], &pvBuf, &cbBuf);
     1632
     1633            LogFlowFunc(("hObj=%RU64, cbBuf=%RU32, cbToRead=%RU32, rc=%Rrc\n", hObj, cbBuf, cbToRead, rc));
     1634
     1635            if (   RT_SUCCESS(rc)
     1636                && (   !cbBuf
     1637                    || !cbToRead
     1638                    ||  cbBuf < cbToRead
     1639                   )
     1640               )
     1641            {
     1642                rc = VERR_INVALID_PARAMETER;
     1643            }
     1644
     1645            if (RT_SUCCESS(rc))
     1646            {
     1647                uint32_t cbRead;
     1648                rc = SharedClipboardTransferObjectRead(pTransfer, hObj, pvBuf, cbToRead, &cbRead, 0 /* fFlags */);
     1649                if (RT_SUCCESS(rc))
     1650                {
     1651                    HGCMSvcSetU32(&paParms[3], cbRead);
     1652
     1653                    /** @todo Implement checksum support. */
     1654                }
     1655            }
     1656            break;
     1657        }
    15871658
    15881659        case VBOX_SHCL_GUEST_FN_OBJ_WRITE:
     
    21062177        if (RT_SUCCESS(rc))
    21072178        {
    2108             SHCLPROVIDERCREATIONCTX creationCtx;
    2109             RT_ZERO(creationCtx);
    2110 
    2111             if (enmDir == SHCLTRANSFERDIR_READ)
    2112             {
    2113                 rc = shclSvcTransferAreaRegister(&pClient->State, pTransfer);
    2114                 if (RT_SUCCESS(rc))
    2115                 {
    2116                     creationCtx.Interface.pfnTransferOpen  = shclSvcTransferIfaceOpen;
    2117                     creationCtx.Interface.pfnTransferClose = shclSvcTransferIfaceClose;
    2118 
    2119                     creationCtx.Interface.pfnRootsGet      = shclSvcTransferIfaceGetRoots;
    2120 
    2121                     creationCtx.Interface.pfnListOpen      = shclSvcTransferIfaceListOpen;
    2122                     creationCtx.Interface.pfnListClose     = shclSvcTransferIfaceListClose;
    2123                     creationCtx.Interface.pfnListHdrRead   = shclSvcTransferIfaceListHdrRead;
    2124                     creationCtx.Interface.pfnListEntryRead = shclSvcTransferIfaceListEntryRead;
    2125 
    2126                     creationCtx.Interface.pfnObjOpen       = shclSvcTransferIfaceObjOpen;
    2127                     creationCtx.Interface.pfnObjClose      = shclSvcTransferIfaceObjClose;
    2128                     creationCtx.Interface.pfnObjRead       = shclSvcTransferIfaceObjRead;
    2129                 }
    2130             }
    2131             else if (enmDir == SHCLTRANSFERDIR_WRITE)
    2132             {
    2133                 creationCtx.Interface.pfnListHdrWrite   = shclSvcTransferIfaceListHdrWrite;
    2134                 creationCtx.Interface.pfnListEntryWrite = shclSvcTransferIfaceListEntryWrite;
    2135                 creationCtx.Interface.pfnObjWrite       = shclSvcTransferIfaceObjWrite;
    2136             }
    2137             else
    2138                 AssertFailed();
    2139 
    2140             creationCtx.enmSource = pClient->State.enmSource;
    2141             creationCtx.pvUser    = pClient;
    2142 
    2143             uint32_t uTransferID = 0;
    2144 
    2145             rc = SharedClipboardTransferSetInterface(pTransfer, &creationCtx);
    2146             if (RT_SUCCESS(rc))
    2147             {
    2148                 rc = ShClSvcImplTransferCreate(pClient, pTransfer);
     2179            rc = ShClSvcImplTransferCreate(pClient, pTransfer);
     2180            if (RT_SUCCESS(rc))
     2181            {
     2182                SHCLPROVIDERCREATIONCTX creationCtx;
     2183                RT_ZERO(creationCtx);
     2184
     2185                if (enmDir == SHCLTRANSFERDIR_READ)
     2186                {
     2187                    rc = shclSvcTransferAreaRegister(&pClient->State, pTransfer);
     2188                    if (RT_SUCCESS(rc))
     2189                    {
     2190                        creationCtx.Interface.pfnTransferOpen  = shclSvcTransferIfaceOpen;
     2191                        creationCtx.Interface.pfnTransferClose = shclSvcTransferIfaceClose;
     2192
     2193                        creationCtx.Interface.pfnRootsGet      = shclSvcTransferIfaceGetRoots;
     2194
     2195                        creationCtx.Interface.pfnListOpen      = shclSvcTransferIfaceListOpen;
     2196                        creationCtx.Interface.pfnListClose     = shclSvcTransferIfaceListClose;
     2197                        creationCtx.Interface.pfnListHdrRead   = shclSvcTransferIfaceListHdrRead;
     2198                        creationCtx.Interface.pfnListEntryRead = shclSvcTransferIfaceListEntryRead;
     2199
     2200                        creationCtx.Interface.pfnObjOpen       = shclSvcTransferIfaceObjOpen;
     2201                        creationCtx.Interface.pfnObjClose      = shclSvcTransferIfaceObjClose;
     2202                        creationCtx.Interface.pfnObjRead       = shclSvcTransferIfaceObjRead;
     2203                    }
     2204                }
     2205                else if (enmDir == SHCLTRANSFERDIR_WRITE)
     2206                {
     2207                    creationCtx.Interface.pfnListHdrWrite   = shclSvcTransferIfaceListHdrWrite;
     2208                    creationCtx.Interface.pfnListEntryWrite = shclSvcTransferIfaceListEntryWrite;
     2209                    creationCtx.Interface.pfnObjWrite       = shclSvcTransferIfaceObjWrite;
     2210                }
     2211                else
     2212                    AssertFailed();
     2213
     2214                creationCtx.enmSource = pClient->State.enmSource;
     2215                creationCtx.pvUser    = pClient;
     2216
     2217                uint32_t uTransferID = 0;
     2218
     2219                rc = SharedClipboardTransferSetInterface(pTransfer, &creationCtx);
    21492220                if (RT_SUCCESS(rc))
    21502221                {
     
    21552226                        if (RT_SUCCESS(rc))
    21562227                        {
    2157                             SHCLEVENTID uEvent;
    2158                             rc = shclSvcTransferSendStatus(pClient, pTransfer,
    2159                                                            SHCLTRANSFERSTATUS_INITIALIZED, VINF_SUCCESS,
    2160                                                            &uEvent);
     2228                            if (   enmSource == SHCLSOURCE_LOCAL
     2229                                && enmDir    == SHCLTRANSFERDIR_WRITE) /* Get roots if this is a local write transfer. */
     2230                            {
     2231                                rc = ShClSvcImplTransferGetRoots(pClient, pTransfer);
     2232                            }
     2233
     2234                            if (RT_SUCCESS(rc))
     2235                                rc = SharedClipboardTransferStart(pTransfer);
     2236
    21612237                            if (RT_SUCCESS(rc))
    21622238                            {
    2163                                 LogRel2(("Shared Clipboard: Waiting for start of transfer %RU32 on guest ...\n",
    2164                                          pTransfer->State.uID));
    2165 
    2166                                 PSHCLEVENTPAYLOAD pPayload;
    2167                                 rc = SharedClipboardEventWait(&pTransfer->Events, uEvent, pTransfer->uTimeoutMs, &pPayload);
     2239                                SHCLEVENTID uEvent;
     2240                                rc = shclSvcTransferSendStatus(pClient, pTransfer,
     2241                                                               SHCLTRANSFERSTATUS_INITIALIZED, VINF_SUCCESS,
     2242                                                               &uEvent);
    21682243                                if (RT_SUCCESS(rc))
    21692244                                {
    2170                                     Assert(pPayload->cbData == sizeof(SHCLREPLY));
    2171                                     PSHCLREPLY pReply = (PSHCLREPLY)pPayload->pvData;
    2172                                     AssertPtr(pReply);
    2173 
    2174                                     Assert(pReply->uType == VBOX_SHCL_REPLYMSGTYPE_TRANSFER_STATUS);
    2175 
    2176                                     if (pReply->u.TransferStatus.uStatus == SHCLTRANSFERSTATUS_STARTED)
     2245                                    LogRel2(("Shared Clipboard: Waiting for start of transfer %RU32 on guest ...\n",
     2246                                             pTransfer->State.uID));
     2247
     2248                                    PSHCLEVENTPAYLOAD pPayload;
     2249                                    rc = SharedClipboardEventWait(&pTransfer->Events, uEvent, pTransfer->uTimeoutMs, &pPayload);
     2250                                    if (RT_SUCCESS(rc))
    21772251                                    {
    2178                                         LogRel2(("Shared Clipboard: Started transfer %RU32 on guest\n", pTransfer->State.uID));
     2252                                        Assert(pPayload->cbData == sizeof(SHCLREPLY));
     2253                                        PSHCLREPLY pReply = (PSHCLREPLY)pPayload->pvData;
     2254                                        AssertPtr(pReply);
     2255
     2256                                        Assert(pReply->uType == VBOX_SHCL_REPLYMSGTYPE_TRANSFER_STATUS);
     2257
     2258                                        if (pReply->u.TransferStatus.uStatus == SHCLTRANSFERSTATUS_STARTED)
     2259                                        {
     2260                                            LogRel2(("Shared Clipboard: Started transfer %RU32 on guest\n", pTransfer->State.uID));
     2261                                        }
     2262                                        else
     2263                                            LogRel(("Shared Clipboard: Guest reported status %s (error %Rrc) while starting transfer %RU32\n",
     2264                                                    VBoxShClTransferStatusToStr(pReply->u.TransferStatus.uStatus),
     2265                                                    pReply->rc, pTransfer->State.uID));
    21792266                                    }
    21802267                                    else
    2181                                         LogRel(("Shared Clipboard: Guest reported status %s (error %Rrc) while starting transfer %RU32\n",
    2182                                                 VBoxShClTransferStatusToStr(pReply->u.TransferStatus.uStatus),
    2183                                                 pReply->rc, pTransfer->State.uID));
     2268                                       LogRel(("Shared Clipboard: Unable to start transfer %RU32 on guest, rc=%Rrc\n",
     2269                                               pTransfer->State.uID, rc));
    21842270                                }
    2185                                 else
    2186                                    LogRel(("Shared Clipboard: Unable to start transfer %RU32 on guest, rc=%Rrc\n",
    2187                                            pTransfer->State.uID, rc));
    21882271                            }
    21892272                        }
     2273
     2274                        if (RT_FAILURE(rc))
     2275                            SharedClipboardTransferCtxTransferUnregister(&pClient->TransferCtx, uTransferID);
    21902276                    }
    21912277                }
     
    21942280            if (RT_FAILURE(rc))
    21952281            {
    2196                 SharedClipboardTransferCtxTransferUnregister(&pClient->TransferCtx, uTransferID);
    2197 
     2282                ShClSvcImplTransferDestroy(pClient, pTransfer);
    21982283                SharedClipboardTransferDestroy(pTransfer);
    21992284
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp

    r81041 r81212  
    888888    return VINF_SUCCESS;
    889889}
     890
     891int ShClSvcImplTransferGetRoots(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)
     892{
     893    LogFlowFuncEnter();
     894
     895    const PSHCLWINCTX pWinCtx = &pClient->State.pCtx->Win;
     896
     897    int rc = SharedClipboardWinGetRoots(pWinCtx, pTransfer);
     898
     899    LogFlowFuncLeaveRC(rc);
     900    return rc;
     901}
    890902#endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
    891903
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-x11.cpp

    r81175 r81212  
    364364    return VINF_SUCCESS;
    365365}
     366
     367int ShClSvcImplTransferGetRoots(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)
     368{
     369    RT_NOREF(pClient, pTransfer);
     370    return VINF_SUCCESS;
     371}
    366372#endif
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp

    r81152 r81212  
    11811181        if (RT_SUCCESS(rc))
    11821182        {
    1183             rc = ShClSvcImplConnect(pClient, ShClSvcGetHeadless());
    11841183#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
     1184            rc = SharedClipboardTransferCtxInit(&pClient->TransferCtx);
     1185#endif
    11851186            if (RT_SUCCESS(rc))
    1186                 rc = SharedClipboardTransferCtxInit(&pClient->TransferCtx);
    1187 #endif
     1187                rc = ShClSvcImplConnect(pClient, ShClSvcGetHeadless());
    11881188            if (RT_SUCCESS(rc))
    11891189            {
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