VirtualBox

Changeset 97783 in vbox for trunk/src/VBox/Main/src-client


Ignore:
Timestamp:
Dec 12, 2022 5:26:43 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
154854
Message:

DnD/Main: Added ability to report back the guest-side rc when waiting for a guest response + the guest source / target implementations now make use of the COM object error setting functions provided by GuestDnDBase. How (and if at all) those errors will be reported will depend on the client using those APIs.

Location:
trunk/src/VBox/Main/src-client
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/src/VBox/Main/src-client/GuestDnDPrivate.cpp

    r97781 r97783  
    304304    , m_fGuestFeatures0(VBOX_DND_GF_NONE)
    305305    , m_EventSem(NIL_RTSEMEVENT)
     306    , m_rcGuest(VERR_IPE_UNINITIALIZED_STATUS)
    306307    , m_dndActionDefault(0)
    307308    , m_dndLstActionsAllowed(0)
     
    323324/**
    324325 * Notifies the waiting side about a guest notification response.
    325  */
    326 int GuestDnDState::notifyAboutGuestResponse(void) const
    327 {
     326 *
     327 * @returns VBox status code.
     328 * @param   rcGuest             Guest rc to set for the response.
     329 *                              Defaults to VINF_SUCCESS (for success).
     330 */
     331int GuestDnDState::notifyAboutGuestResponse(int rcGuest /* = VINF_SUCCESS */)
     332{
     333    m_rcGuest = rcGuest;
    328334    return RTSemEventSignal(m_EventSem);
    329335}
     
    340346
    341347    m_lstFormats.clear();
     348
     349    m_rcGuest = VERR_IPE_UNINITIALIZED_STATUS;
    342350}
    343351
     
    619627            rc = setProgress(pCBData->uPercentage, pCBData->uStatus, pCBData->rc);
    620628            if (RT_SUCCESS(rc))
    621                 rc = notifyAboutGuestResponse();
     629                rc = notifyAboutGuestResponse(pCBData->rc);
    622630            break;
    623631        }
     
    699707
    700708/**
     709 * Waits for a guest response to happen, extended version.
     710 *
     711 * @returns VBox status code.
     712 * @retval  VERR_TIMEOUT when waiting has timed out.
     713 * @retval  VERR_DND_GUEST_ERROR on an error reported back from the guest.
     714 * @param   msTimeout           Timeout (in ms) for waiting. Optional, waits 3000 ms if not specified.
     715 * @param   prcGuest            Where to return the guest error when VERR_DND_GUEST_ERROR is returned. Optional.
     716 */
     717int GuestDnDState::waitForGuestResponseEx(RTMSINTERVAL msTimeout /* = 3000 */, int *prcGuest /* = NULL */)
     718{
     719    int vrc = RTSemEventWait(m_EventSem, msTimeout);
     720    if (RT_SUCCESS(vrc))
     721    {
     722        if (RT_FAILURE(m_rcGuest))
     723            vrc = VERR_DND_GUEST_ERROR;
     724        if (prcGuest)
     725            *prcGuest = m_rcGuest;
     726    }
     727    return vrc;
     728}
     729
     730/**
    701731 * Waits for a guest response to happen.
    702732 *
    703733 * @returns VBox status code.
    704  * @param   msTimeout           Timeout (in ms) for waiting. Optional, waits 3000 ms if not specified.
    705  */
    706 int GuestDnDState::waitForGuestResponse(RTMSINTERVAL msTimeout /*= 3000 */) const
    707 {
    708     int rc = RTSemEventWait(m_EventSem, msTimeout);
    709 #ifdef DEBUG_andy
    710     LogFlowFunc(("msTimeout=%RU32, rc=%Rrc\n", msTimeout, rc));
    711 #endif
    712     return rc;
     734 * @retval  VERR_TIMEOUT when waiting has timed out.
     735 * @retval  VERR_DND_GUEST_ERROR on an error reported back from the guest.
     736 * @param   prcGuest            Where to return the guest error when VERR_DND_GUEST_ERROR is returned. Optional.
     737 *
     738 * @note    Uses the default timeout of 3000 ms.
     739 */
     740int GuestDnDState::waitForGuestResponse(int *prcGuest /* = NULL */)
     741{
     742    return waitForGuestResponseEx(3000 /* ms */, prcGuest);
    713743}
    714744
  • TabularUnified trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp

    r97780 r97783  
    285285        *aDefaultAction = DnDAction_Ignore;
    286286
    287     HRESULT hr = S_OK;
     287    GuestDnDState *pState = GuestDnDInst()->getState();
     288    AssertPtrReturn(pState, E_POINTER);
     289
     290    HRESULT hrc = S_OK;
    288291
    289292    GuestDnDMsg Msg;
     
    293296    Msg.appendUInt32(uScreenId);
    294297
    295     int rc = GuestDnDInst()->hostCall(Msg.getType(), Msg.getCount(), Msg.getParms());
    296     if (RT_SUCCESS(rc))
    297     {
    298         GuestDnDState *pState = GuestDnDInst()->getState();
    299         AssertPtr(pState);
    300 
    301         bool fFetchResult = true;
    302 
    303         rc = pState->waitForGuestResponse(100 /* Timeout in ms */);
    304         if (RT_FAILURE(rc))
    305             fFetchResult = false;
    306 
    307         if (   fFetchResult
    308             && isDnDIgnoreAction(pState->getActionDefault()))
    309             fFetchResult = false;
    310 
    311         /* Fetch the default action to use. */
    312         if (fFetchResult)
    313         {
    314             /*
    315              * In the GuestDnDSource case the source formats are from the guest,
    316              * as GuestDnDSource acts as a target for the guest. The host always
    317              * dictates what's supported and what's not, so filter out all formats
    318              * which are not supported by the host.
    319              */
    320             GuestDnDMIMEList lstFiltered  = GuestDnD::toFilteredFormatList(m_lstFmtSupported, pState->formats());
    321             if (lstFiltered.size())
     298    int vrc = GuestDnDInst()->hostCall(Msg.getType(), Msg.getCount(), Msg.getParms());
     299    if (RT_SUCCESS(vrc))
     300    {
     301        int vrcGuest;
     302        vrc = pState->waitForGuestResponseEx(100 /* Timeout in ms */, &vrcGuest);
     303        if (RT_SUCCESS(vrc))
     304        {
     305            if (!isDnDIgnoreAction(pState->getActionDefault()))
    322306            {
    323                 LogRel3(("DnD: Host offered the following formats:\n"));
    324                 for (size_t i = 0; i < lstFiltered.size(); i++)
    325                     LogRel3(("DnD:\tFormat #%zu: %s\n", i, lstFiltered.at(i).c_str()));
    326 
    327                 aFormats            = lstFiltered;
    328                 aAllowedActions     = GuestDnD::toMainActions(pState->getActionsAllowed());
    329                 if (aDefaultAction)
    330                     *aDefaultAction = GuestDnD::toMainAction(pState->getActionDefault());
    331 
    332                 /* Apply the (filtered) formats list. */
    333                 m_lstFmtOffered     = lstFiltered;
     307                /*
     308                 * In the GuestDnDSource case the source formats are from the guest,
     309                 * as GuestDnDSource acts as a target for the guest. The host always
     310                 * dictates what's supported and what's not, so filter out all formats
     311                 * which are not supported by the host.
     312                 */
     313                GuestDnDMIMEList lstFiltered  = GuestDnD::toFilteredFormatList(m_lstFmtSupported, pState->formats());
     314                if (lstFiltered.size())
     315                {
     316                    LogRel2(("DnD: Host offered the following formats:\n"));
     317                    for (size_t i = 0; i < lstFiltered.size(); i++)
     318                        LogRel2(("DnD:\tFormat #%zu: %s\n", i, lstFiltered.at(i).c_str()));
     319
     320                    aFormats            = lstFiltered;
     321                    aAllowedActions     = GuestDnD::toMainActions(pState->getActionsAllowed());
     322                    if (aDefaultAction)
     323                        *aDefaultAction = GuestDnD::toMainAction(pState->getActionDefault());
     324
     325                    /* Apply the (filtered) formats list. */
     326                    m_lstFmtOffered     = lstFiltered;
     327                }
     328                else
     329                    hrc = i_setErrorAndReset(tr("Negotiation of formats between guest and host failed!\n\nHost offers: %s\n\nGuest offers: %s"),
     330                                             GuestDnD::toFormatString(m_lstFmtSupported , ",").c_str(),
     331                                             GuestDnD::toFormatString(pState->formats() , ",").c_str());
    334332            }
    335             else
    336                 LogRel2(("DnD: Negotiation of formats between guest and host failed, drag and drop to host not possible\n"));
    337         }
    338 
    339         LogFlowFunc(("fFetchResult=%RTbool, lstActionsAllowed=0x%x\n", fFetchResult, pState->getActionsAllowed()));
    340     }
    341 
    342     LogFlowFunc(("hr=%Rhrc\n", hr));
    343     return hr;
     333            /* Note: Don't report an error here when the action is "ignore" -- that only means that the current window on the guest
     334                     simply doesn't support the format or drag and drop at all. */
     335        }
     336        else
     337            hrc = i_setErrorAndReset(vrc == VERR_DND_GUEST_ERROR ? vrcGuest : vrc, tr("Requesting pending data from guest failed"));
     338    }
     339    else
     340        hrc = i_setErrorAndReset(vrc, tr("Sending drag pending event to guest failed"));
     341
     342    LogFlowFunc(("hr=%Rhrc\n", hrc));
     343    return hrc;
    344344#endif /* VBOX_WITH_DRAG_AND_DROP */
    345345}
     
    419419    catch (std::bad_alloc &)
    420420    {
    421         hr = setError(E_OUTOFMEMORY);
     421        hr = E_OUTOFMEMORY;
    422422    }
    423423    catch (...)
     
    437437    }
    438438    else
    439         hr = setError(hr, tr("Starting thread for GuestDnDSource failed (%Rhrc)"), hr);
     439        hr = i_setErrorAndReset(tr("Starting thread for GuestDnDSource failed (%Rhrc)"), hr);
    440440
    441441    LogFlowFunc(("Returning hr=%Rhrc\n", hr));
  • TabularUnified trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp

    r97780 r97783  
    300300    if (isDnDIgnoreAction(dndActionDefault))
    301301        return S_OK;
     302
     303    GuestDnDState *pState = GuestDnDInst()->getState();
     304    AssertPtrReturn(pState, E_POINTER);
    302305
    303306    /*
     
    340343        if (RT_SUCCESS(vrc))
    341344        {
    342             GuestDnDState *pState = GuestDnDInst()->getState();
    343             if (pState && RT_SUCCESS(vrc = pState->waitForGuestResponse()))
     345            int vrcGuest;
     346            if (RT_SUCCESS(vrc = pState->waitForGuestResponse(&vrcGuest)))
    344347            {
    345348                resAction = GuestDnD::toMainAction(m_pState->getActionDefault());
     
    349352            }
    350353            else
    351                 hrc = setErrorBoth(VBOX_E_DND_ERROR, vrc, tr("Waiting for response of enter event failed (%Rrc)"), vrc);
     354                hrc = i_setErrorAndReset(vrc == VERR_DND_GUEST_ERROR ? vrcGuest : vrc, tr("Entering VM window failed"));
    352355        }
    353356        else
    354             hrc = setErrorBoth(VBOX_E_DND_ERROR, vrc, tr("Sending enter event to guest failed (%Rrc)"), vrc);
     357        {
     358            switch (vrc)
     359            {
     360                case VERR_ACCESS_DENIED:
     361                {
     362                    hrc = i_setErrorAndReset(tr("Drag and drop to guest not allowed. Select the right mode first"));
     363                    break;
     364                }
     365
     366                case VERR_NOT_SUPPORTED:
     367                {
     368                    hrc = i_setErrorAndReset(tr("Drag and drop to guest not possible -- either the guest OS does not support this, "
     369                                                "or the Guest Additions are not installed"));
     370                    break;
     371                }
     372
     373                default:
     374                    hrc = i_setErrorAndReset(vrc, tr("Entering VM window failed"));
     375                    break;
     376            }
     377        }
    355378    }
    356379
     
    393416    if (isDnDIgnoreAction(dndActionDefault))
    394417        return S_OK;
     418
     419    GuestDnDState *pState = GuestDnDInst()->getState();
     420    AssertPtrReturn(pState, E_POINTER);
    395421
    396422    /*
     
    422448        if (RT_SUCCESS(vrc))
    423449        {
    424             GuestDnDState *pState = GuestDnDInst()->getState();
    425             if (pState && RT_SUCCESS(vrc = pState->waitForGuestResponse()))
     450            int vrcGuest;
     451            if (RT_SUCCESS(vrc = pState->waitForGuestResponse(&vrcGuest)))
    426452            {
    427453                resAction = GuestDnD::toMainAction(pState->getActionDefault());
     
    431457            }
    432458            else
    433                 hrc = setErrorBoth(VBOX_E_DND_ERROR, vrc, tr("Waiting for response of move event failed (%Rrc)"), vrc);
     459                hrc = i_setErrorAndReset(vrc == VERR_DND_GUEST_ERROR ? vrcGuest : vrc,
     460                                         tr("Moving to %RU32,%RU32 (screen %u) failed"), aX, aY, aScreenId);
    434461        }
    435462        else
    436             hrc = setErrorBoth(VBOX_E_DND_ERROR, vrc, tr("Sending move event to guest failed (%Rrc)"), vrc);
     463        {
     464            switch (vrc)
     465            {
     466                case VERR_ACCESS_DENIED:
     467                {
     468                    hrc = i_setErrorAndReset(tr("Moving in guest not allowed. Select the right mode first"));
     469                    break;
     470                }
     471
     472                case VERR_NOT_SUPPORTED:
     473                {
     474                    hrc = i_setErrorAndReset(tr("Moving in guest not possible -- either the guest OS does not support this, "
     475                                                "or the Guest Additions are not installed"));
     476                    break;
     477                }
     478
     479                default:
     480                    hrc = i_setErrorAndReset(vrc, tr("Moving in VM window failed"));
     481                    break;
     482            }
     483        }
    437484    }
    438485    else
    439         hrc = setError(hrc, tr("Retrieving move coordinates failed"));
     486        hrc = i_setErrorAndReset(tr("Retrieving move coordinates failed"));
    440487
    441488    if (SUCCEEDED(hrc))
     
    460507    if (autoCaller.isNotOk()) return autoCaller.rc();
    461508
     509    GuestDnDState *pState = GuestDnDInst()->getState();
     510    AssertPtrReturn(pState, E_POINTER);
     511
    462512    HRESULT hrc = S_OK;
    463513
     
    472522    if (RT_SUCCESS(vrc))
    473523    {
    474         GuestDnDState *pState = GuestDnDInst()->getState();
    475         if (pState && RT_SUCCESS(vrc = pState->waitForGuestResponse()))
     524        int vrcGuest;
     525        if (RT_SUCCESS(vrc = pState->waitForGuestResponse(&vrcGuest)))
    476526        {
    477527            /* Nothing to do here. */
    478528        }
    479529        else
    480             hrc = setErrorBoth(VBOX_E_DND_ERROR, vrc, tr("Waiting for response of leave event failed (%Rrc)"), vrc);
     530            hrc = i_setErrorAndReset(vrc == VERR_DND_GUEST_ERROR ? vrcGuest : vrc, tr("Leaving VM window failed"));
    481531    }
    482532    else
    483         hrc = setErrorBoth(VBOX_E_DND_ERROR, vrc, tr("Sending leave event to guest failed (%Rrc)"), vrc);
     533    {
     534        switch (vrc)
     535        {
     536            case VERR_ACCESS_DENIED:
     537            {
     538                hrc = i_setErrorAndReset(tr("Leaving guest not allowed. Select the right mode first"));
     539                break;
     540            }
     541
     542            case VERR_NOT_SUPPORTED:
     543            {
     544                hrc = i_setErrorAndReset(tr("Leaving guest not possible -- either the guest OS does not support this, "
     545                                            "or the Guest Additions are not installed"));
     546                break;
     547            }
     548
     549            default:
     550                hrc = i_setErrorAndReset(vrc, tr("Leaving VM window failed"));
     551                break;
     552        }
     553    }
    484554
    485555    LogFlowFunc(("hrc=%Rhrc\n", hrc));
     
    528598        return S_OK;
    529599    }
     600
     601    GuestDnDState *pState = GuestDnDInst()->getState();
     602    AssertPtrReturn(pState, E_POINTER);
    530603
    531604    /*
     
    561634        if (RT_SUCCESS(vrc))
    562635        {
    563             GuestDnDState *pState = GuestDnDInst()->getState();
    564             if (pState && RT_SUCCESS(pState->waitForGuestResponse()))
     636            int vrcGuest;
     637            if (RT_SUCCESS(vrc = pState->waitForGuestResponse(&vrcGuest)))
    565638            {
    566639                resAct = GuestDnD::toMainAction(pState->getActionDefault());
     
    575648                    {
    576649                        if (lstFormats.size() == 0)
    577                             hrc = setError(VBOX_E_DND_ERROR, tr("Guest accepted drop, but did not specify the format"));
     650                            hrc = i_setErrorAndReset(VERR_DND_GUEST_ERROR, tr("Guest accepted drop, but did not specify the format"));
    578651                        else
    579                             hrc = setError(VBOX_E_DND_ERROR, tr("Guest accepted drop, but returned more than one drop format (%zu formats)"),
    580                                           lstFormats.size());
     652                            hrc = i_setErrorAndReset(VERR_DND_GUEST_ERROR, tr("Guest accepted drop, but returned more than one drop format (%zu formats)"),
     653                                                     lstFormats.size());
    581654                    }
    582 
    583                     LogRel2(("DnD: Guest accepted drop in format '%s' (action %#x, %zu format(s))\n",
    584                              resFmt.c_str(), resAct, lstFormats.size()));
    585655                }
    586656            }
    587657            else
    588                 hrc = setErrorBoth(VBOX_E_DND_ERROR, vrc, tr("Waiting for response of dropped event failed (%Rrc)"), vrc);
     658                hrc = i_setErrorAndReset(vrc == VERR_DND_GUEST_ERROR ? vrcGuest : vrc, tr("Dropping into VM failed"));
    589659        }
    590660        else
    591             hrc = setErrorBoth(VBOX_E_DND_ERROR, vrc, tr("Sending dropped event to guest failed (%Rrc)"), vrc);
     661            hrc = i_setErrorAndReset(vrc, tr("Sending dropped event to guest failed"));
    592662    }
    593663    else
    594         hrc = setError(hrc, tr("Retrieving drop coordinates failed"));
     664        hrc = i_setErrorAndReset(hrc, tr("Retrieving drop coordinates failed"));
    595665
    596666    if (SUCCEEDED(hrc))
     
    682752    catch (std::bad_alloc &)
    683753    {
    684         hr = setError(E_OUTOFMEMORY);
     754        hr = E_OUTOFMEMORY;
    685755    }
    686756    catch (...)
     
    700770    }
    701771    else
    702         hr = setError(hr, tr("Starting thread for GuestDnDTarget failed (%Rhrc)"), hr);
     772        hr = i_setErrorAndReset(tr("Starting thread for GuestDnDTarget failed (%Rhrc)"), hr);
    703773
    704774    LogFlowFunc(("Returning hr=%Rhrc\n", hr));
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