VirtualBox

Changeset 100412 in vbox


Ignore:
Timestamp:
Jul 6, 2023 2:08:30 PM (17 months ago)
Author:
vboxsync
Message:

Shared Clipboard: Windows host service now uses the same way as the Linux host service wrt transfer handling. ​​​bugref:9437

Location:
trunk
Files:
4 edited

Legend:

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

    r100407 r100412  
    295295    static int Thread(RTTHREAD hThread, void *pvUser);
    296296
     297    inline int lock(void);
     298    inline int unlock(void);
     299
    297300    int readDir(PSHCLTRANSFER pTransfer, const Utf8Str &strPath);
    298301
     
    304307    void registerFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat, TYMED tyMed = TYMED_HGLOBAL,
    305308                        LONG lindex = -1, DWORD dwAspect = DVASPECT_CONTENT, DVTARGETDEVICE *pTargetDevice = NULL);
     309    int setTransferLocked(PSHCLTRANSFER pTransfer);
    306310    int setStatusLocked(Status enmStatus, int rc = VINF_SUCCESS);
    307311
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp

    r100407 r100412  
    206206    switch(ShClTransferGetDir(pCbCtx->pTransfer))
    207207    {
    208         case SHCLTRANSFERDIR_FROM_REMOTE:
    209         {
    210             AssertPtrBreak(pCtx->Win.pDataObjInFlight);
    211             rc = pCtx->Win.pDataObjInFlight->SetTransfer(pCbCtx->pTransfer);
    212             if (RT_SUCCESS(rc))
    213                 rc = pCtx->Win.pDataObjInFlight->SetStatus(SharedClipboardWinDataObject::Running);
     208        case SHCLTRANSFERDIR_TO_REMOTE: /* G->H */
     209        {
     210            rc = SharedClipboardWinTransferGetRootsFromClipboard(&pCtx->Win, pCbCtx->pTransfer);
     211            break;
     212        }
     213
     214        case SHCLTRANSFERDIR_FROM_REMOTE: /* H->G */
     215        {
     216            SharedClipboardWinDataObject *pObj = pCtx->Win.pDataObjInFlight;
     217            if (pObj)
     218            {
     219                rc = pObj->SetTransfer(pCbCtx->pTransfer);
     220                if (RT_SUCCESS(rc))
     221                    rc = pObj->SetStatus(SharedClipboardWinDataObject::Running);
     222
     223                pCtx->Win.pDataObjInFlight = NULL; /* Hand off to Windows. */
     224            }
     225            else
     226                AssertMsgFailed(("No data object in flight!\n"));
     227
    214228            break;
    215229        }
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp

    r100407 r100412  
    188188    AssertReturnVoid(m_lRefCount == 0);
    189189
     190    /* Make sure to release the transfer. */
     191    setTransferLocked(NULL);
     192
    190193    int rc = RTCritSectDelete(&m_CritSect);
    191194    AssertRC(rc);
     
    310313    GlobalFree(hGlobal);
    311314    return VERR_ACCESS_DENIED;
     315}
     316
     317inline int SharedClipboardWinDataObject::lock(void)
     318{
     319    int rc = RTCritSectEnter(&m_CritSect);
     320    AssertRCReturn(rc, rc);
     321
     322    return rc;
     323}
     324
     325inline int SharedClipboardWinDataObject::unlock(void)
     326{
     327    int rc = RTCritSectLeave(&m_CritSect);
     328    AssertRCReturn(rc, rc);
     329
     330    return rc;
    312331}
    313332
     
    675694    AssertPtrReturn(pMedium, DV_E_FORMATETC);
    676695
    677     int rc2 = RTCritSectEnter(&m_CritSect);
    678     AssertRCReturn(rc2, E_UNEXPECTED);
     696    lock();
    679697
    680698    LogFlowFunc(("lIndex=%RI32, enmStatus=%#x\n", pFormatEtc->lindex, m_enmStatus));
     
    702720
    703721                /* Leave lock while requesting + waiting. */
    704                 rc2 = RTCritSectLeave(&m_CritSect);
    705                 AssertRCBreak(rc);
     722                unlock();
    706723
    707724                /* Start the transfer. */
     
    715732                 *       Windows Explorer unresponsive (i.e. "ghost window") when waiting for too long. */
    716733                rc = RTSemEventWait(m_EventStatusChanged, RT_MS_10SEC);
    717                 AssertRCBreak(rc);
    718734
    719735                /* Re-acquire lock. */
    720                 rc = RTCritSectEnter(&m_CritSect);
    721                 AssertRCBreak(rc);
     736                lock();
     737
     738                if (RT_FAILURE(rc))
     739                {
     740                    LogRel(("Shared Clipboard: Waiting for IDataObject status status failed, rc=%Rrc\n", rc));
     741                    break;
     742                }
    722743
    723744                if (m_enmStatus != Running)
     
    757778
    758779                            /* Leave lock while waiting. */
    759                             rc = RTCritSectLeave(&m_CritSect);
    760                             AssertRCReturn(rc, E_UNEXPECTED);
     780                            unlock();
    761781
    762782                            /* Don't block for too long here, as this also will screw other apps running on the OS. */
     
    765785
    766786                            /* Re-acquire lock. */
    767                             rc = RTCritSectEnter(&m_CritSect);
    768                             AssertRCReturn(rc, E_UNEXPECTED);
     787                            lock();
    769788                        }
    770789                    }
     
    847866    }
    848867
    849     rc2 = RTCritSectLeave(&m_CritSect);
    850     AssertRCReturn(rc2, E_UNEXPECTED);
     868    unlock();
    851869
    852870    LogFlowFunc(("hr=%Rhrc\n", hr));
     
    10121030
    10131031/**
    1014  * Assigns a transfer object for the data object.
     1032 * Assigns a transfer object for the data object, internal version.
    10151033 *
    10161034 * @returns VBox status code.
    10171035 * @param   pTransfer           Transfer to assign.
    1018  *                              Must be in started state.
    1019  */
    1020 int SharedClipboardWinDataObject::SetTransfer(PSHCLTRANSFER pTransfer)
    1021 {
    1022     AssertReturn(m_pTransfer == NULL, VERR_WRONG_ORDER); /* Transfer already set? */
    1023 
    1024     int rc = RTCritSectEnter(&m_CritSect);
    1025     if (RT_SUCCESS(rc))
    1026     {
     1036 *                              Must be in INITIALIZED state.
     1037 *                              When set to NULL, the transfer will be released from the object.
     1038 */
     1039int SharedClipboardWinDataObject::setTransferLocked(PSHCLTRANSFER pTransfer)
     1040{
     1041    LogFlowFunc(("pTransfer=%p\n", pTransfer));
     1042
     1043    int rc = VINF_SUCCESS;
     1044
     1045    if (pTransfer) /* Set */
     1046    {
     1047        Assert(m_pTransfer == NULL); /* Transfer already set? */
     1048
    10271049        if (m_enmStatus == Initialized)
    10281050        {
     
    10391061        else
    10401062            AssertFailedStmt(rc = VERR_WRONG_ORDER);
    1041 
    1042         RTCritSectLeave(&m_CritSect);
    1043     }
     1063    }
     1064    else /* Unset */
     1065    {
     1066        if (m_pTransfer)
     1067        {
     1068            ShClTransferRelease(m_pTransfer);
     1069            m_pTransfer = NULL;
     1070        }
     1071    }
     1072
     1073    return rc;
     1074}
     1075
     1076/**
     1077 * Assigns a transfer object for the data object.
     1078 *
     1079 * @returns VBox status code.
     1080 * @param   pTransfer           Transfer to assign.
     1081 *                              Must be in INITIALIZED state.
     1082 *                              When set to NULL, the transfer will be released from the object.
     1083 */
     1084int SharedClipboardWinDataObject::SetTransfer(PSHCLTRANSFER pTransfer)
     1085{
     1086    lock();
     1087
     1088    int rc = setTransferLocked(pTransfer);
     1089
     1090    unlock();
    10441091
    10451092    return rc;
     
    10571104int SharedClipboardWinDataObject::SetStatus(Status enmStatus, int rcSts /* = VINF_SUCCESS */)
    10581105{
    1059     int rc = RTCritSectEnter(&m_CritSect);
    1060     if (RT_SUCCESS(rc))
    1061     {
    1062         rc = setStatusLocked(enmStatus, rcSts);
    1063 
    1064         RTCritSectLeave(&m_CritSect);
    1065     }
    1066 
     1106    lock();
     1107
     1108    int rc = setStatusLocked(enmStatus, rcSts);
     1109
     1110    unlock();
    10671111    return rc;
    10681112}
     
    11411185    RT_NOREF(rc);
    11421186
    1143     int rc2 = RTCritSectEnter(&m_CritSect);
    1144     if (RT_SUCCESS(rc2))
    1145     {
    1146         LogFlowFunc(("enmStatus=%#x (current is: %#x)\n", enmStatus, m_enmStatus));
    1147 
    1148         switch (enmStatus)
    1149         {
    1150             case Completed:
    1151             {
    1152                 LogFlowFunc(("m_uObjIdx=%RU32 (total: %zu)\n", m_uObjIdx, m_lstEntries.size()));
    1153 
    1154                 const bool fComplete = m_uObjIdx == m_lstEntries.size() - 1 /* Object index is zero-based */;
    1155                 if (fComplete)
    1156                     m_enmStatus = Completed;
    1157                 break;
    1158             }
    1159 
    1160             default:
    1161             {
    1162                 m_enmStatus = enmStatus;
    1163                 break;
    1164             }
    1165         }
    1166 
    1167         if (RT_FAILURE(rc))
    1168             LogRel(("Shared Clipboard: Data object received error %Rrc (status %#x)\n", rc, enmStatus));
    1169 
    1170         if (m_EventStatusChanged != NIL_RTSEMEVENT)
    1171             rc2 = RTSemEventSignal(m_EventStatusChanged);
    1172 
    1173         RTCritSectLeave(&m_CritSect);
    1174     }
     1187    LogFlowFunc(("enmStatus=%#x (current is: %#x)\n", enmStatus, m_enmStatus));
     1188
     1189    int rc2 = VINF_SUCCESS;
     1190
     1191    switch (enmStatus)
     1192    {
     1193        case Completed:
     1194        {
     1195            LogFlowFunc(("m_uObjIdx=%RU32 (total: %zu)\n", m_uObjIdx, m_lstEntries.size()));
     1196
     1197            const bool fComplete = m_uObjIdx == m_lstEntries.size() - 1 /* Object index is zero-based */;
     1198            if (fComplete)
     1199                m_enmStatus = Completed;
     1200            break;
     1201        }
     1202
     1203        default:
     1204        {
     1205            m_enmStatus = enmStatus;
     1206            break;
     1207        }
     1208    }
     1209
     1210    if (RT_FAILURE(rc))
     1211        LogRel(("Shared Clipboard: Data object received error %Rrc (status %#x)\n", rc, enmStatus));
     1212
     1213    if (m_EventStatusChanged != NIL_RTSEMEVENT)
     1214        rc2 = RTSemEventSignal(m_EventStatusChanged);
    11751215
    11761216    return rc2;
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp

    r100394 r100412  
    301301static DECLCALLBACK(void) shClSvcWinTransferOnInitializedCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx)
    302302{
     303    LogFlowFuncEnter();
     304
    303305    PSHCLCONTEXT pCtx = (PSHCLCONTEXT)pCbCtx->pvUser;
    304306    AssertPtr(pCtx);
     
    317319            {
    318320                SharedClipboardWinDataObject *pObj = pCtx->Win.pDataObjInFlight;
    319                 AssertPtrReturnVoid(pObj);
    320                 rc = pObj->SetTransfer(pTransfer);
    321 
    322                 pCtx->Win.pDataObjInFlight = NULL; /* Hand off to Windows. */
     321                if (pObj)
     322                {
     323                    rc = pObj->SetTransfer(pTransfer);
     324                    if (RT_SUCCESS(rc))
     325                        rc = pObj->SetStatus(SharedClipboardWinDataObject::Running);
     326
     327                    pCtx->Win.pDataObjInFlight = NULL; /* Hand off to Windows. */
     328                }
     329                else
     330                    AssertMsgFailed(("No data object in flight!\n"));
    323331
    324332                int rc2 = RTCritSectLeave(&pCtx->Win.CritSect);
     
    350358static DECLCALLBACK(void) shClSvcWinTransferOnDestroyCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx)
    351359{
     360    LogFlowFuncEnter();
     361
    352362    PSHCLCONTEXT pCtx = (PSHCLCONTEXT)pCbCtx->pvUser;
    353363    AssertPtr(pCtx);
     
    360370
    361371/**
    362  * @copydoc SHCLTRANSFERCALLBACKS::pfnOnStarted
     372 * @copydoc SharedClipboardWinDataObject::CALLBACKS::pfnTransferStart
     373 *
     374 * Called by SharedClipboardWinDataObject::GetData() when the user wants to paste data.
     375 * This then creates and initializes a new transfer on the host + lets the guest know about that new transfer.
    363376 *
    364377 * @thread  Service main thread.
    365378 */
    366 static DECLCALLBACK(void) shClSvcWinTransferOnStartedCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx)
    367 {
     379static DECLCALLBACK(int) shClSvcWinDataObjectTransferStartCallback(SharedClipboardWinDataObject::PCALLBACKCTX pCbCtx)
     380{
     381    LogFlowFuncEnter();
     382
    368383    PSHCLCONTEXT pCtx = (PSHCLCONTEXT)pCbCtx->pvUser;
    369384    AssertPtr(pCtx);
    370385
    371     PSHCLTRANSFER pTransfer = pCbCtx->pTransfer;
    372     AssertPtr(pTransfer);
    373 
    374     if (ShClTransferGetDir(pTransfer) ==  SHCLTRANSFERDIR_FROM_REMOTE) /* G->H */
    375     {
    376         /* Report to the guest that we now entered the STARTED state. */
    377         ShClSvcTransferStart(pCtx->pClient, pTransfer);
    378     }
     386    PSHCLTRANSFER pTransfer;
     387    int rc = ShClSvcTransferCreate(pCtx->pClient, SHCLTRANSFERDIR_FROM_REMOTE, SHCLSOURCE_REMOTE,
     388                                   NIL_SHCLTRANSFERID /* Creates a new transfer ID */, &pTransfer);
     389    if (RT_SUCCESS(rc))
     390    {
     391        /* Initialize the transfer on the host side. */
     392        rc = ShClSvcTransferInit(pCtx->pClient, pTransfer);
     393        if (RT_FAILURE(rc))
     394             ShClSvcTransferDestroy(pCtx->pClient, pTransfer);
     395    }
     396
     397    LogFlowFuncLeaveRC(rc);
     398    return rc;
    379399}
    380400#endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
     
    545565
    546566            int rc = SharedClipboardWinClearAndAnnounceFormats(pWinCtx, fFormats, hWnd);
    547             if (RT_FAILURE(rc))
    548                 LogRel(("Shared Clipboard: Reporting clipboard formats %#x to Windows host failed with %Rrc\n", fFormats, rc));
    549 
     567#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
     568            if (   RT_SUCCESS(rc)
     569                && fFormats & VBOX_SHCL_FMT_URI_LIST)
     570            {
     571                /*
     572                 * Create our IDataObject implementation and push it to the Windows clibpoard.
     573                 * That way Windows will recognize that there is a data transfer available.
     574                 */
     575                SharedClipboardWinDataObject::CALLBACKS Callbacks;
     576                RT_ZERO(Callbacks);
     577                Callbacks.pfnTransferStart = shClSvcWinDataObjectTransferStartCallback;
     578
     579                rc = SharedClipboardWinTransferCreateAndSetDataObject(pWinCtx, pCtx, &Callbacks);
     580            }
     581#else
     582            RT_NOREF(rc);
     583#endif
    550584            LogFunc(("SHCL_WIN_WM_REPORT_FORMATS: lastErr=%ld\n", GetLastError()));
    551585            break;
     
    828862        pClient->Transfers.Callbacks.pfnOnCreated     = shClSvcWinTransferOnCreatedCallback;
    829863        pClient->Transfers.Callbacks.pfnOnInitialized = shClSvcWinTransferOnInitializedCallback;
    830         pClient->Transfers.Callbacks.pfnOnStarted     = shClSvcWinTransferOnStartedCallback;
    831864        pClient->Transfers.Callbacks.pfnOnDestroy     = shClSvcWinTransferOnDestroyCallback;
    832865#endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
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