VirtualBox

Changeset 55539 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Apr 30, 2015 9:48:34 AM (10 years ago)
Author:
vboxsync
Message:

DnD: ErrorInfo handling, formatting, validation.

Location:
trunk/src/VBox/Main
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/GuestDnDSourceImpl.h

    r55520 r55539  
    8484protected:
    8585
    86     int i_receiveData(PRECVDATACTX pCtx);
    87     int i_receiveRawData(PRECVDATACTX pCtx);
    88     int i_receiveURIData(PRECVDATACTX pCtx);
     86    int i_receiveData(PRECVDATACTX pCtx, RTMSINTERVAL msTimeout);
     87    int i_receiveRawData(PRECVDATACTX pCtx, RTMSINTERVAL msTimeout);
     88    int i_receiveURIData(PRECVDATACTX pCtx, RTMSINTERVAL msTimeout);
    8989    int i_updateProcess(PRECVDATACTX pCtx, uint32_t cbDataAdd);
    9090
  • trunk/src/VBox/Main/src-client/GuestDnDPrivate.cpp

    r55512 r55539  
    413413            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_HG_REQ_DATA == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    414414
    415             setFormat(pCBData->pszFormat);
    416             rc = notifyAboutGuestResponse();
     415            if (   pCBData->cbFormat == 0
     416                || pCBData->cbFormat >  _64K)
     417            {
     418                rc = VERR_INVALID_PARAMETER;
     419            }
     420            else
     421            {
     422                setFormat(pCBData->pszFormat);
     423
     424                rc = VINF_SUCCESS;
     425            }
     426
     427            int rc2 = notifyAboutGuestResponse();
     428            if (RT_SUCCESS(rc))
     429                rc = rc2;
    417430            break;
    418431        }
     
    440453            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_ACK_PENDING == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    441454
    442             setFormat    (pCBData->pszFormat);
    443             setDefAction (pCBData->uDefAction);
    444             setAllActions(pCBData->uAllActions);
    445 
    446             rc = notifyAboutGuestResponse();
     455            if (   pCBData->cbFormat == 0
     456                || pCBData->cbFormat >  _64K)
     457            {
     458                rc = VERR_INVALID_PARAMETER;
     459            }
     460            else
     461            {
     462                setFormat    (pCBData->pszFormat);
     463                setDefAction (pCBData->uDefAction);
     464                setAllActions(pCBData->uAllActions);
     465
     466                rc = VINF_SUCCESS;
     467            }
     468
     469            int rc2 = notifyAboutGuestResponse();
     470            if (RT_SUCCESS(rc))
     471                rc = rc2;
    447472            break;
    448473        }
  • trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp

    r55525 r55539  
    229229/////////////////////////////////////////////////////////////////////////////
    230230
    231 HRESULT GuestDnDSource::dragIsPending(ULONG uScreenId,
    232                                       std::vector<com::Utf8Str> &aFormats,
    233                                       std::vector<DnDAction_T> &aAllowedActions,
    234                                       DnDAction_T *aDefaultAction)
     231HRESULT GuestDnDSource::dragIsPending(ULONG uScreenId, std::vector<com::Utf8Str> &aFormats,
     232                                      std::vector<DnDAction_T> &aAllowedActions, DnDAction_T *aDefaultAction)
    235233{
    236234#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
     
    282280    if (RT_FAILURE(rc))
    283281        hr = setError(VBOX_E_IPRT_ERROR,
    284                       tr("Error retrieving drag'n drop pending status (%Rrc)\n"), rc);
     282                      tr("Error retrieving drag and drop pending status (%Rrc)\n"), rc);
    285283
    286284    LogFlowFunc(("hr=%Rhrc, defaultAction=0x%x\n", hr, defaultAction));
     
    289287}
    290288
    291 HRESULT GuestDnDSource::drop(const com::Utf8Str &aFormat,
    292                              DnDAction_T aAction, ComPtr<IProgress> &aProgress)
     289HRESULT GuestDnDSource::drop(const com::Utf8Str &aFormat, DnDAction_T aAction, ComPtr<IProgress> &aProgress)
    293290{
    294291#if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH)
     
    308305        return S_OK;
    309306
     307    /* Note: At the moment we only support one transfer at a time. */
    310308    if (ASMAtomicReadBool(&mData.mfDropIsPending))
    311309        return setError(E_INVALIDARG, tr("Another drop operation already is in progress"));
     
    313311    ASMAtomicWriteBool(&mData.mfDropIsPending, true);
    314312
    315     HRESULT hr = S_OK;
    316 
    317     /* Note: At the moment we only support one response at a time. */
     313    /* Dito. */
    318314    GuestDnDResponse *pResp = GuestDnDInst()->response();
    319     if (pResp)
    320     {
    321         pResp->resetProgress(m_pGuest);
    322 
    323         int rc;
    324 
    325         try
    326         {
    327             mData.mRecvCtx.mpSource = this;
    328             mData.mRecvCtx.mpResp   = pResp;
    329             mData.mRecvCtx.mFormat  = aFormat;
    330 
    331             RecvDataTask *pTask = new RecvDataTask(this, &mData.mRecvCtx);
    332             AssertReturn(pTask->isOk(), pTask->getRC());
    333 
    334             rc = RTThreadCreate(NULL, GuestDnDSource::i_receiveDataThread,
     315    AssertPtr(pResp);
     316
     317    HRESULT hr = pResp->resetProgress(m_pGuest);
     318    if (FAILED(hr))
     319        return hr;
     320
     321    try
     322    {
     323        mData.mRecvCtx.mIsActive = false;
     324        mData.mRecvCtx.mpSource  = this;
     325        mData.mRecvCtx.mpResp    = pResp;
     326        mData.mRecvCtx.mFormat   = aFormat;
     327
     328        RecvDataTask *pTask = new RecvDataTask(this, &mData.mRecvCtx);
     329        AssertReturn(pTask->isOk(), pTask->getRC());
     330
     331        RTTHREAD recvThread;
     332        int rc = RTThreadCreate(&recvThread, GuestDnDSource::i_receiveDataThread,
    335333                                (void *)pTask, 0, RTTHREADTYPE_MAIN_WORKER, 0, "dndSrcRcvData");
    336             if (RT_SUCCESS(rc))
    337             {
    338                 hr = pResp->queryProgressTo(aProgress.asOutParam());
    339                 ComAssertComRC(hr);
    340 
    341                 /* Note: pTask is now owned by the worker thread. */
    342             }
    343         }
    344         catch(std::bad_alloc &)
    345         {
    346             rc = VERR_NO_MEMORY;
    347         }
    348 
    349         /*if (RT_FAILURE(vrc)) @todo SetError(...) */
    350     }
    351     /** @todo SetError(...) */
    352 
    353     ASMAtomicWriteBool(&mData.mfDropIsPending, false);
     334        if (RT_SUCCESS(rc))
     335        {
     336            hr = pResp->queryProgressTo(aProgress.asOutParam());
     337            ComAssertComRC(hr);
     338
     339            /* Note: pTask is now owned by the worker thread. */
     340        }
     341        else
     342            hr = setError(VBOX_E_IPRT_ERROR, tr("Starting thread failed (%Rrc)"), rc);
     343    }
     344    catch(std::bad_alloc &)
     345    {
     346        hr = setError(E_OUTOFMEMORY);
     347    }
     348
     349    /* Note: mData.mfDropIsPending will be set to false again by i_receiveDataThread. */
    354350
    355351    LogFlowFunc(("Returning hr=%Rhrc\n", hr));
     
    680676#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
    681677
    682 int GuestDnDSource::i_receiveData(PRECVDATACTX pCtx)
     678int GuestDnDSource::i_receiveData(PRECVDATACTX pCtx, RTMSINTERVAL msTimeout)
    683679{
    684680    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     
    691687    AssertPtr(pCtx->mpResp);
    692688
     689    /* Is this context already in receiving state? */
     690    if (ASMAtomicReadBool(&pCtx->mIsActive))
     691        return VERR_WRONG_ORDER;
     692
    693693    ASMAtomicWriteBool(&pCtx->mIsActive, true);
    694694
     
    697697        return rc;
    698698
     699    /*
     700     * Reset any old data.
     701     */
    699702    pCtx->mData.vecData.clear();
    700703    pCtx->mData.cbToProcess = 0;
    701704    pCtx->mData.cbProcessed = 0;
    702705
    703     do
    704     {
    705         /* Reset any old data. */
    706         pResp->reset();
    707         pResp->resetProgress(m_pGuest);
    708 
    709         /* Set the format we are going to retrieve to have it around
    710          * when retrieving the data later. */
    711         pResp->setFormat(pCtx->mFormat);
    712 
    713         bool fHasURIList = DnDMIMENeedsDropDir(pCtx->mFormat.c_str(), pCtx->mFormat.length());
    714         LogFlowFunc(("strFormat=%s, uAction=0x%x, fHasURIList=%RTbool\n", pCtx->mFormat.c_str(), pCtx->mAction, fHasURIList));
    715 
    716         if (fHasURIList)
    717         {
    718             rc = i_receiveURIData(pCtx);
    719         }
    720         else
    721         {
    722             rc = i_receiveRawData(pCtx);
    723         }
    724 
    725     } while (0);
     706    pResp->reset();
     707    pResp->resetProgress(m_pGuest);
     708
     709    /* Set the format we are going to retrieve to have it around
     710     * when retrieving the data later. */
     711    pResp->setFormat(pCtx->mFormat);
     712
     713    bool fHasURIList = DnDMIMENeedsDropDir(pCtx->mFormat.c_str(), pCtx->mFormat.length());
     714    LogFlowFunc(("strFormat=%s, uAction=0x%x, fHasURIList=%RTbool\n", pCtx->mFormat.c_str(), pCtx->mAction, fHasURIList));
     715    if (fHasURIList)
     716    {
     717        rc = i_receiveURIData(pCtx, msTimeout);
     718    }
     719    else
     720    {
     721        rc = i_receiveRawData(pCtx, msTimeout);
     722    }
    726723
    727724    ASMAtomicWriteBool(&pCtx->mIsActive, false);
     
    747744    if (SUCCEEDED(autoCaller.rc()))
    748745    {
    749         rc = pSource->i_receiveData(pTask->getCtx());
     746        rc = pSource->i_receiveData(pTask->getCtx(), RT_INDEFINITE_WAIT);
    750747    }
    751748    else
     
    756753    if (pTask)
    757754        delete pTask;
     755
     756    ASMAtomicWriteBool(&pSource->mData.mfDropIsPending, false);
     757
    758758    return rc;
    759759}
    760760
    761 int GuestDnDSource::i_receiveRawData(PRECVDATACTX pCtx)
     761int GuestDnDSource::i_receiveRawData(PRECVDATACTX pCtx, RTMSINTERVAL msTimeout)
    762762{
    763763    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     
    807807             * wait event.
    808808             */
    809             LogFlowFunc(("Waiting for raw data callback ...\n"));
    810             rc = pCtx->mCallback.Wait(RT_INDEFINITE_WAIT);
     809            LogFlowFunc(("Waiting for raw data callback (%RU32ms timeout) ...\n", msTimeout));
     810            rc = pCtx->mCallback.Wait(msTimeout);
    811811            LogFlowFunc(("Raw callback done, rc=%Rrc\n", rc));
    812812        }
     
    827827}
    828828
    829 int GuestDnDSource::i_receiveURIData(PRECVDATACTX pCtx)
     829int GuestDnDSource::i_receiveURIData(PRECVDATACTX pCtx, RTMSINTERVAL msTimeout)
    830830{
    831831    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     
    888888             * wait event.
    889889             */
    890             LogFlowFunc(("Waiting for URI callback ...\n"));
    891             rc = pCtx->mCallback.Wait(RT_INDEFINITE_WAIT);
     890            LogFlowFunc(("Waiting for URI callback (%RU32ms timeout) ...\n", msTimeout));
     891            rc = pCtx->mCallback.Wait(msTimeout);
    892892            LogFlowFunc(("URI callback done, rc=%Rrc\n", rc));
    893893        }
  • trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp

    r55520 r55539  
    2222#include "GuestImpl.h"
    2323#include "GuestDnDTargetImpl.h"
    24 #include "VirtualBoxErrorInfoImpl.h"
    2524
    2625#include "Global.h"
     
    528527    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    529528
    530     HRESULT hr = S_OK;
    531     int vrc;
    532 
    533529    /* Note: At the moment we only support one response at a time. */
    534530    GuestDnDResponse *pResp = GuestDnDInst()->response();
    535     if (pResp)
    536     {
    537         pResp->resetProgress(m_pGuest);
    538 
    539         try
    540         {
    541             PSENDDATACTX pSendCtx = new SENDDATACTX;
    542             RT_BZERO(pSendCtx, sizeof(SENDDATACTX));
    543 
    544             pSendCtx->mpTarget      = this;
    545             pSendCtx->mpResp        = pResp;
    546             pSendCtx->mScreenID     = aScreenId;
    547             pSendCtx->mFormat       = aFormat;
    548             pSendCtx->mData.vecData = aData;
    549 
    550             SendDataTask *pTask = new SendDataTask(this, pSendCtx);
    551             AssertReturn(pTask->isOk(), pTask->getRC());
    552 
    553             vrc = RTThreadCreate(NULL, GuestDnDTarget::i_sendDataThread,
    554                                  (void *)pTask, 0, RTTHREADTYPE_MAIN_WORKER, 0, "dndTgtSndData");
    555             if (RT_SUCCESS(vrc))
    556             {
    557                 hr = pResp->queryProgressTo(aProgress.asOutParam());
    558                 ComAssertComRC(hr);
    559 
    560                 /* Note: pTask is now owned by the worker thread. */
    561             }
    562             else if (pSendCtx)
    563                 delete pSendCtx;
    564         }
    565         catch(std::bad_alloc &)
    566         {
    567             vrc = VERR_NO_MEMORY;
    568         }
    569 
    570         /*if (RT_FAILURE(vrc)) ** @todo SetError(...) */
    571     }
    572     /** @todo SetError(...) */
    573 
     531    AssertPtr(pResp);
     532
     533    HRESULT hr = pResp->resetProgress(m_pGuest);
     534    if (FAILED(hr))
     535        return hr;
     536
     537    try
     538    {
     539        PSENDDATACTX pSendCtx = new SENDDATACTX;
     540        RT_BZERO(pSendCtx, sizeof(SENDDATACTX));
     541
     542        pSendCtx->mpTarget      = this;
     543        pSendCtx->mpResp        = pResp;
     544        pSendCtx->mScreenID     = aScreenId;
     545        pSendCtx->mFormat       = aFormat;
     546        pSendCtx->mData.vecData = aData;
     547
     548        SendDataTask *pTask = new SendDataTask(this, pSendCtx);
     549        AssertReturn(pTask->isOk(), pTask->getRC());
     550
     551        RTTHREAD sendThread;
     552        int rc = RTThreadCreate(&sendThread, GuestDnDTarget::i_sendDataThread,
     553                                (void *)pTask, 0, RTTHREADTYPE_MAIN_WORKER, 0, "dndTgtSndData");
     554        if (RT_SUCCESS(rc))
     555        {
     556            hr = pResp->queryProgressTo(aProgress.asOutParam());
     557            ComAssertComRC(hr);
     558
     559            /* Note: pTask is now owned by the worker thread. */
     560        }
     561        else
     562            hr = setError(VBOX_E_IPRT_ERROR, tr("Starting thread failed (%Rrc)"), rc);
     563
     564        if (RT_FAILURE(rc))
     565            delete pSendCtx;
     566    }
     567    catch(std::bad_alloc &)
     568    {
     569        hr = setError(E_OUTOFMEMORY);
     570    }
     571
     572    LogFlowFunc(("Returning hr=%Rhrc\n", hr));
    574573    return hr;
    575574#endif /* VBOX_WITH_DRAG_AND_DROP */
     
    963962     * Register callbacks.
    964963     */
    965     /* Generic callbacks. */
     964    /* Guest callbacks. */
    966965    REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG);
    967966    REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_EVT_ERROR);
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