VirtualBox

Changeset 55963 in vbox


Ignore:
Timestamp:
May 20, 2015 11:18:14 AM (9 years ago)
Author:
vboxsync
Message:

DnD: Fixed hang when reporting host errors such as inaccessible (locked) files.

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/err.h

    r55660 r55963  
    26462646/** @} */
    26472647
     2648/** @name VBox Drag and Drop Status Codes
     2649 * @{
     2650 */
     2651/** Guest side reported an error. */
     2652#define VERR_GSTDND_GUEST_ERROR                     (-6500)
     2653/** @} */
     2654
    26482655
    26492656/* SED-END */
  • trunk/src/VBox/Main/include/GuestDnDPrivate.h

    r55640 r55963  
    5050    int Reset(void);
    5151
    52     int Notify(int rc);
     52    int Notify(int rc = VINF_SUCCESS);
    5353
    5454    int Result(void) const { return mRc; }
     
    367367    bool isProgressCanceled(void) const;
    368368    int setCallback(uint32_t uMsg, PFNGUESTDNDCALLBACK pfnCallback, void *pvUser = NULL);
    369     int setProgress(unsigned uPercentage, uint32_t uState, int rcOp = VINF_SUCCESS);
     369    int setProgress(unsigned uPercentage, uint32_t uState, int rcOp = VINF_SUCCESS, const Utf8Str &strMsg = "");
    370370    HRESULT resetProgress(const ComObjPtr<Guest>& pParent);
    371371    HRESULT queryProgressTo(IProgress **ppProgress);
     
    377377    int onDispatch(uint32_t u32Function, void *pvParms, uint32_t cbParms);
    378378    /** @}  */
    379 
    380 public:
    381 
    382     Utf8Str errorToString(const ComObjPtr<Guest>& pGuest, int guestRc);
    383379
    384380protected:
  • trunk/src/VBox/Main/include/GuestDnDSourceImpl.h

    r55549 r55963  
    7474protected:
    7575
     76    static Utf8Str i_guestErrorToString(int guestRc);
     77    static Utf8Str i_hostErrorToString(int hostRc);
     78
     79    /** @name Thread callbacks.
     80     * @{ */
    7681    static DECLCALLBACK(int) i_receiveDataThread(RTTHREAD Thread, void *pvUser);
     82    /** @}  */
    7783
    7884    /** @name Callbacks for dispatch handler.
  • trunk/src/VBox/Main/include/GuestDnDTargetImpl.h

    r55571 r55963  
    6868protected:
    6969
     70    static Utf8Str i_guestErrorToString(int guestRc);
     71    static Utf8Str i_hostErrorToString(int hostRc);
     72
     73    /** @name Thread callbacks.
     74     * @{ */
    7075    static DECLCALLBACK(int) i_sendDataThread(RTTHREAD Thread, void *pvUser);
     76    /** @}  */
     77
     78    /** @name Callbacks for dispatch handler.
     79     * @{ */
    7180    static DECLCALLBACK(int) i_sendURIDataCallback(uint32_t uMsg, void *pvParms, size_t cbParms, void *pvUser);
     81    /** @}  */
    7282
    7383protected:
  • trunk/src/VBox/Main/src-client/GuestDnDPrivate.cpp

    r55640 r55963  
    177177}
    178178
    179 int GuestDnDCallbackEvent::Notify(int rc)
     179int GuestDnDCallbackEvent::Notify(int rc /* = VINF_SUCCESS */)
    180180{
    181181    mRc = rc;
     
    209209}
    210210
    211 /* static */
    212 Utf8Str GuestDnDResponse::errorToString(const ComObjPtr<Guest>& pGuest, int guestRc)
    213 {
    214     Utf8Str strError;
    215 
    216     switch (guestRc)
    217     {
    218         case VERR_ACCESS_DENIED:
    219             strError += Utf8StrFmt(pGuest->tr("For one or more guest files or directories selected for transferring to the host your guest "
    220                                               "user does not have the appropriate access rights for. Please make sure that all selected "
    221                                               "elements can be accessed and that your guest user has the appropriate rights."));
    222             break;
    223 
    224         case VERR_NOT_FOUND:
    225             /* Should not happen due to file locking on the guest, but anyway ... */
    226             strError += Utf8StrFmt(pGuest->tr("One or more guest files or directories selected for transferring to the host were not"
    227                                               "found on the guest anymore. This can be the case if the guest files were moved and/or"
    228                                               "altered while the drag and drop operation was in progress."));
    229             break;
    230 
    231         case VERR_SHARING_VIOLATION:
    232             strError += Utf8StrFmt(pGuest->tr("One or more guest files or directories selected for transferring to the host were locked. "
    233                                               "Please make sure that all selected elements can be accessed and that your guest user has "
    234                                               "the appropriate rights."));
    235             break;
    236 
    237         default:
    238             strError += Utf8StrFmt("Drag and drop guest error (%Rrc)", guestRc);
    239             break;
    240     }
    241 
    242     return strError;
    243 }
    244 
    245211int GuestDnDResponse::notifyAboutGuestResponse(void) const
    246212{
     
    312278
    313279int GuestDnDResponse::setProgress(unsigned uPercentage,
    314                                   uint32_t uStatus, int rcOp /* = VINF_SUCCESS */)
    315 {
    316     LogFlowFunc(("uStatus=%RU32, uPercentage=%RU32, rcOp=%Rrc\n",
    317                  uStatus, uPercentage, rcOp));
     280                                  uint32_t uStatus,
     281                                  int rcOp /* = VINF_SUCCESS */, const Utf8Str &strMsg /* = "" */)
     282{
     283    LogFlowFunc(("uStatus=%RU32, uPercentage=%RU32, rcOp=%Rrc, strMsg=%s\n",
     284                 uStatus, uPercentage, rcOp, strMsg.c_str()));
    318285
    319286    int rc = VINF_SUCCESS;
     
    338305                    hr = m_progress->i_notifyComplete(VBOX_E_IPRT_ERROR,
    339306                                                      COM_IIDOF(IGuest),
    340                                                       m_parent->getComponentName(),
    341                                                       GuestDnDResponse::errorToString(m_parent, rcOp).c_str());
     307                                                      m_parent->getComponentName(), strMsg.c_str());
    342308                    reset();
    343309                    break;
     
    898864         * Wait until our desired callback triggered the
    899865         * wait event. As we don't want to block if the guest does not
    900          * respond, so do busy waiting here.
     866         * respond, do busy waiting here.
    901867         */
    902868        rc = Event.Wait(500 /* ms */);
     
    908874        }
    909875        else if (rc == VERR_TIMEOUT) /* Continue waiting. */
    910             rc = VINF_SUCCESS;
     876            continue;
    911877
    912878        if (   msTimeout != RT_INDEFINITE_WAIT
     
    914880        {
    915881            rc = VERR_TIMEOUT;
    916         }
    917         else if (pResp->isProgressCanceled())
    918         {
    919             pResp->setProgress(100 /* Percent */, DragAndDropSvc::DND_PROGRESS_CANCELLED);
     882            LogFlowFunc(("Guest did not respond within time\n"));
     883        }
     884        else if (pResp->isProgressCanceled()) /** @todo GuestDnDResponse *pResp needs to go. */
     885        {
     886            LogFlowFunc(("Canceled by user\n"));
    920887            rc = VERR_CANCELLED;
    921888        }
  • trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp

    r55823 r55963  
    325325        RecvDataTask *pTask = new RecvDataTask(this, &mData.mRecvCtx);
    326326        AssertReturn(pTask->isOk(), pTask->getRC());
    327        
     327
    328328        LogFlowFunc(("Starting thread ...\n"));
    329329
     
    415415
    416416#ifdef VBOX_WITH_DRAG_AND_DROP_GH
     417/* static */
     418Utf8Str GuestDnDSource::i_guestErrorToString(int guestRc)
     419{
     420    Utf8Str strError;
     421
     422    switch (guestRc)
     423    {
     424        case VERR_ACCESS_DENIED:
     425            strError += Utf8StrFmt(tr("For one or more guest files or directories selected for transferring to the host your guest "
     426                                      "user does not have the appropriate access rights for. Please make sure that all selected "
     427                                      "elements can be accessed and that your guest user has the appropriate rights."));
     428            break;
     429
     430        case VERR_NOT_FOUND:
     431            /* Should not happen due to file locking on the guest, but anyway ... */
     432            strError += Utf8StrFmt(tr("One or more guest files or directories selected for transferring to the host were not"
     433                                      "found on the guest anymore. This can be the case if the guest files were moved and/or"
     434                                      "altered while the drag and drop operation was in progress."));
     435            break;
     436
     437        case VERR_SHARING_VIOLATION:
     438            strError += Utf8StrFmt(tr("One or more guest files or directories selected for transferring to the host were locked. "
     439                                      "Please make sure that all selected elements can be accessed and that your guest user has "
     440                                      "the appropriate rights."));
     441            break;
     442
     443        default:
     444            strError += Utf8StrFmt(tr("Drag and drop error from guest (%Rrc)"), guestRc);
     445            break;
     446    }
     447
     448    return strError;
     449}
     450
     451
     452/* static */
     453Utf8Str GuestDnDSource::i_hostErrorToString(int hostRc)
     454{
     455    Utf8Str strError;
     456
     457    switch (hostRc)
     458    {
     459        case VERR_ACCESS_DENIED:
     460            strError += Utf8StrFmt(tr("For one or more host files or directories selected for transferring to the guest your host "
     461                                      "user does not have the appropriate access rights for. Please make sure that all selected "
     462                                      "elements can be accessed and that your host user has the appropriate rights."));
     463            break;
     464
     465        case VERR_NOT_FOUND:
     466            /* Should not happen due to file locking on the host, but anyway ... */
     467            strError += Utf8StrFmt(tr("One or more host files or directories selected for transferring to the host were not"
     468                                      "found on the host anymore. This can be the case if the host files were moved and/or"
     469                                      "altered while the drag and drop operation was in progress."));
     470            break;
     471
     472        case VERR_SHARING_VIOLATION:
     473            strError += Utf8StrFmt(tr("One or more host files or directories selected for transferring to the guest were locked. "
     474                                      "Please make sure that all selected elements can be accessed and that your host user has "
     475                                      "the appropriate rights."));
     476            break;
     477
     478        default:
     479            strError += Utf8StrFmt(tr("Drag and drop error from host (%Rrc)"), hostRc);
     480            break;
     481    }
     482
     483    return strError;
     484}
     485
    417486int GuestDnDSource::i_onReceiveData(PRECVDATACTX pCtx, const void *pvData, uint32_t cbData, uint64_t cbTotalSize)
    418487{
     
    839908        rc = pInst->hostCall(Msg.getType(), Msg.getCount(), Msg.getParms());
    840909        if (RT_SUCCESS(rc))
     910        {
    841911            rc = waitForEvent(msTimeout, pCtx->mCallback, pCtx->mpResp);
     912            if (RT_FAILURE(rc))
     913            {
     914                if (rc == VERR_CANCELLED)
     915                    rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_CANCELLED, VINF_SUCCESS);
     916                else if (rc != VERR_GSTDND_GUEST_ERROR) /* Guest-side error are already handled in the callback. */
     917                    rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, rc,
     918                                                   GuestDnDSource::i_hostErrorToString(rc));
     919            }
     920            else
     921                rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_COMPLETE, VINF_SUCCESS);
     922        }
    842923
    843924    } while (0);
     
    9191000        rc = pInst->hostCall(Msg.getType(), Msg.getCount(), Msg.getParms());
    9201001        if (RT_SUCCESS(rc))
     1002        {
    9211003            rc = waitForEvent(msTimeout, pCtx->mCallback, pCtx->mpResp);
     1004            if (RT_FAILURE(rc))
     1005            {
     1006                if (rc == VERR_CANCELLED)
     1007                    rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_CANCELLED, VINF_SUCCESS);
     1008                else if (rc != VERR_GSTDND_GUEST_ERROR) /* Guest-side error are already handled in the callback. */
     1009                    rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, rc,
     1010                                                   GuestDnDSource::i_hostErrorToString(rc));
     1011            }
     1012            else
     1013                rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_COMPLETE, VINF_SUCCESS);
     1014        }
    9221015
    9231016    } while (0);
     
    9711064    int rc = VINF_SUCCESS;
    9721065
     1066    int rcCallback = VINF_SUCCESS; /* rc for the callback. */
     1067    bool fNotify = false;
     1068
    9731069    switch (uMsg)
    9741070    {
     
    9921088
    9931089            pCtx->mpResp->reset();
    994             rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc);
     1090
     1091            if (RT_SUCCESS(pCBData->rc))
     1092                pCBData->rc = VERR_GENERAL_FAILURE; /* Make sure some error is set. */
     1093
     1094            rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc,
     1095                                           GuestDnDSource::i_guestErrorToString(pCBData->rc));
    9951096            if (RT_SUCCESS(rc))
    996                 rc = pCBData->rc;
     1097                rcCallback = VERR_GSTDND_GUEST_ERROR;
    9971098            break;
    9981099        }
     
    11181219    }
    11191220
     1221    if (RT_FAILURE(rc))
     1222    {
     1223        switch (rc)
     1224        {
     1225            case VERR_NO_DATA:
     1226                LogRel2(("DnD: Transfer to host complete\n"));
     1227                break;
     1228
     1229            case VERR_CANCELLED:
     1230                LogRel2(("DnD: Transfer to host canceled\n"));
     1231                break;
     1232
     1233            default:
     1234                LogRel(("DnD: Error %Rrc occurred, aborting transfer to host\n", rc));
     1235                break;
     1236        }
     1237
     1238        /* Unregister this callback. */
     1239        AssertPtr(pCtx->mpResp);
     1240        int rc2 = pCtx->mpResp->setCallback(uMsg, NULL /* PFNGUESTDNDCALLBACK */);
     1241        AssertRC(rc2);
     1242    }
     1243
    11201244    /* All URI data processed? */
    11211245    if (pCtx->mData.cbProcessed >= pCtx->mData.cbToProcess)
  • trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp

    r55822 r55963  
    605605}
    606606
     607/* static */
     608Utf8Str GuestDnDTarget::i_guestErrorToString(int guestRc)
     609{
     610    Utf8Str strError;
     611
     612    switch (guestRc)
     613    {
     614        case VERR_ACCESS_DENIED:
     615            strError += Utf8StrFmt(tr("For one or more guest files or directories selected for transferring to the host your guest "
     616                                      "user does not have the appropriate access rights for. Please make sure that all selected "
     617                                      "elements can be accessed and that your guest user has the appropriate rights."));
     618            break;
     619
     620        case VERR_NOT_FOUND:
     621            /* Should not happen due to file locking on the guest, but anyway ... */
     622            strError += Utf8StrFmt(tr("One or more guest files or directories selected for transferring to the host were not"
     623                                      "found on the guest anymore. This can be the case if the guest files were moved and/or"
     624                                      "altered while the drag and drop operation was in progress."));
     625            break;
     626
     627        case VERR_SHARING_VIOLATION:
     628            strError += Utf8StrFmt(tr("One or more guest files or directories selected for transferring to the host were locked. "
     629                                      "Please make sure that all selected elements can be accessed and that your guest user has "
     630                                      "the appropriate rights."));
     631            break;
     632
     633        default:
     634            strError += Utf8StrFmt(tr("Drag and drop error from guest (%Rrc)"), guestRc);
     635            break;
     636    }
     637
     638    return strError;
     639}
     640
     641/* static */
     642Utf8Str GuestDnDTarget::i_hostErrorToString(int hostRc)
     643{
     644    Utf8Str strError;
     645
     646    switch (hostRc)
     647    {
     648        case VERR_ACCESS_DENIED:
     649            strError += Utf8StrFmt(tr("For one or more host files or directories selected for transferring to the guest your host "
     650                                      "user does not have the appropriate access rights for. Please make sure that all selected "
     651                                      "elements can be accessed and that your host user has the appropriate rights."));
     652            break;
     653
     654        case VERR_NOT_FOUND:
     655            /* Should not happen due to file locking on the host, but anyway ... */
     656            strError += Utf8StrFmt(tr("One or more host files or directories selected for transferring to the host were not"
     657                                      "found on the host anymore. This can be the case if the host files were moved and/or"
     658                                      "altered while the drag and drop operation was in progress."));
     659            break;
     660
     661        case VERR_SHARING_VIOLATION:
     662            strError += Utf8StrFmt(tr("One or more host files or directories selected for transferring to the guest were locked. "
     663                                      "Please make sure that all selected elements can be accessed and that your host user has "
     664                                      "the appropriate rights."));
     665            break;
     666
     667        default:
     668            strError += Utf8StrFmt(tr("Drag and drop error from host (%Rrc)"), hostRc);
     669            break;
     670    }
     671
     672    return strError;
     673}
     674
    607675int GuestDnDTarget::i_sendData(PSENDDATACTX pCtx, RTMSINTERVAL msTimeout)
    608676{
    609     AssertPtrReturn(pCtx,  VERR_INVALID_POINTER);
     677    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
    610678
    611679    GuestDnD *pInst = GuestDnDInst();
     
    682750                          RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE, 0 /* fFlags */);
    683751        if (RT_FAILURE(rc))
    684             LogRel2(("DnD: Error opening host file \"%s\", rc=%Rrc\n", strPathSrc.c_str(), rc));
     752            LogRel(("DnD: Error opening host file \"%s\", rc=%Rrc\n", strPathSrc.c_str(), rc));
    685753    }
    686754
     
    814882    LogFlowFunc(("pThis=%p, uMsg=%RU32\n", pThis, uMsg));
    815883
    816     int rc = VINF_SUCCESS;
     884    int rc = VINF_SUCCESS; /* Will be reported back to guest. */
     885
     886    int rcCallback = VINF_SUCCESS; /* rc for the callback. */
     887    bool fNotify = false;
    817888
    818889    switch (uMsg)
     
    858929
    859930            pCtx->mpResp->reset();
    860             rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc);
     931
     932            if (RT_SUCCESS(pCBData->rc))
     933                pCBData->rc = VERR_GENERAL_FAILURE; /* Make sure some error is set. */
     934
     935            rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc,
     936                                           GuestDnDTarget::i_guestErrorToString(pCBData->rc));
    861937            if (RT_SUCCESS(rc))
    862                 rc = pCBData->rc;
     938                rcCallback = VERR_GSTDND_GUEST_ERROR;
    863939            break;
    864940        }
     
    915991    }
    916992
     993    if (   RT_FAILURE(rc)
     994        || RT_FAILURE(rcCallback))
     995    {
     996        fNotify = true;
     997        if (RT_SUCCESS(rcCallback))
     998            rcCallback = rc;
     999    }
     1000
    9171001    if (RT_FAILURE(rc))
    9181002    {
     
    9201004        {
    9211005            case VERR_NO_DATA:
    922                 LogRel2(("DnD: Transfer complete\n"));
     1006                LogRel2(("DnD: Transfer to guest complete\n"));
    9231007                break;
    9241008
    9251009            case VERR_CANCELLED:
    926                 LogRel2(("DnD: Transfer canceled\n"));
     1010                LogRel2(("DnD: Transfer to guest canceled\n"));
    9271011                break;
    9281012
    9291013            default:
    930                 LogRel(("DnD: Error %Rrc occurred, aborting transfer\n", rc));
     1014                LogRel(("DnD: Error %Rrc occurred, aborting transfer to guest\n", rc));
    9311015                break;
    9321016        }
     
    9361020        int rc2 = pCtx->mpResp->setCallback(uMsg, NULL /* PFNGUESTDNDCALLBACK */);
    9371021        AssertRC(rc2);
    938 
    939         /* Notify waiters. */
    940         rc2 = pCtx->mCallback.Notify(rc);
     1022    }
     1023
     1024    LogFlowFunc(("fNotify=%RTbool, rcCallback=%Rrc, rc=%Rrc\n", fNotify, rcCallback, rc));
     1025
     1026    if (fNotify)
     1027    {
     1028        int rc2 = pCtx->mCallback.Notify(rcCallback);
    9411029        AssertRC(rc2);
    9421030    }
     
    10441132        rc = GuestDnDInst()->hostCall(MsgSndData.getType(), MsgSndData.getCount(), MsgSndData.getParms());
    10451133        if (RT_SUCCESS(rc))
     1134        {
    10461135            rc = waitForEvent(msTimeout, pCtx->mCallback, pCtx->mpResp);
     1136            if (RT_FAILURE(rc))
     1137            {
     1138                if (rc == VERR_CANCELLED)
     1139                    rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_CANCELLED, VINF_SUCCESS);
     1140                else if (rc != VERR_GSTDND_GUEST_ERROR) /* Guest-side error are already handled in the callback. */
     1141                    rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, rc,
     1142                                                   GuestDnDTarget::i_hostErrorToString(rc));
     1143            }
     1144            else
     1145                rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_COMPLETE, VINF_SUCCESS);
     1146        }
    10471147
    10481148    } while (0);
     
    10651165    /*
    10661166     * Now that we've cleaned up tell the guest side to cancel.
     1167     * This does not imply we're waiting for the guest to react, as the
     1168     * host side never must depend on anything from the guest.
    10671169     */
    10681170    if (rc == VERR_CANCELLED)
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