VirtualBox

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

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

Location:
trunk/src/VBox/GuestHost/SharedClipboard
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp

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

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

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

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

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