VirtualBox

Changeset 55512 in vbox


Ignore:
Timestamp:
Apr 29, 2015 11:34:53 AM (9 years ago)
Author:
vboxsync
Message:

DnD: Bugfixes, cleanup, spelling.

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/GuestHost/DragAndDrop.h

    r55422 r55512  
    9494    int OpenEx(const RTCString &strPath, Type enmType, Dest enmDest, uint64_t fMode = 0, uint32_t fFlags = 0);
    9595    int Read(void *pvBuf, size_t cbBuf, uint32_t *pcbRead);
     96    void Reset(void);
    9697    int Write(const void *pvBuf, size_t cbBuf, uint32_t *pcbWritten);
    9798
     
    145146    RTCString RootToString(const RTCString &strBasePath = "", const RTCString &strSeparator = "\r\n");
    146147    size_t RootCount(void) { return m_lstRoot.size(); }
     148    uint32_t TotalCount(void) { return m_cTotal; }
    147149    size_t TotalBytes(void) { return m_cbTotal; }
    148150
     
    159161    /** List of all URI objects added. */
    160162    RTCList<DnDURIObject>  m_lstTree;
     163    /** Total number of all URI objects. */
     164    uint32_t               m_cTotal;
    161165    /** Total size of all URI objects, that is, the file
    162166     *  size of all objects (in bytes). */
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDrag.cpp

    r52730 r55512  
    164164            if (RT_SUCCESS(rc))
    165165            {
    166                 /* After we successfully retrieved data from
    167                 * the source, we query it from Main. */
     166                /* After we successfully retrieved data from the source we query it from Main. */
    168167                QVector<uint8_t> vecData = dndSource.ReceiveData();
    169168                if (!vecData.isEmpty())
  • trunk/src/VBox/GuestHost/DragAndDrop/DnDURIList.cpp

    r55422 r55512  
    3535
    3636DnDURIList::DnDURIList(void)
    37     : m_cbTotal(0)
     37    : m_cTotal(0)
     38    , m_cbTotal(0)
    3839{
    3940}
     
    7879                                  pcszPath, &pcszPath[cbBaseLen],
    7980                                  objInfo.Attr.fMode, cbSize));
     81    m_cTotal++;
    8082    m_cbTotal += cbSize;
    8183#ifdef DEBUG_andy
     
    257259                char *pszRoot = &pszFilePath[cbBase];
    258260                m_lstRoot.append(pszRoot);
     261                m_cTotal++;
    259262#ifdef DEBUG_andy
    260263                LogFlowFunc(("pszFilePath=%s, pszFileName=%s, pszRoot=%s\n",
     
    356359            rc = DnDPathSanitize(pszFilePath, strlen(pszFilePath));
    357360            if (RT_SUCCESS(rc))
     361            {
    358362                m_lstRoot.append(pszFilePath);
     363                m_cTotal++;
     364            }
    359365
    360366            RTStrFree(pszFilePath);
  • trunk/src/VBox/GuestHost/DragAndDrop/DnDURIObject.cpp

    r55422 r55512  
    198198                    if (RT_SUCCESS(rc))
    199199                        rc = RTFileGetSize(u.m_hFile, &m_cbSize);
     200                    if (RT_SUCCESS(rc))
     201                        m_cbProcessed = 0;
    200202                }
    201203                else
     
    340342}
    341343
     344void DnDURIObject::Reset(void)
     345{
     346    Close();
     347
     348    m_Type        = Unknown;
     349    m_strSrcPath  = "";
     350    m_strTgtPath  = "";
     351    m_fMode       = 0;
     352    m_cbSize      = 0;
     353    m_cbProcessed = 0;
     354}
     355
    342356int DnDURIObject::Write(const void *pvBuf, size_t cbBuf, uint32_t *pcbWritten)
    343357{
  • trunk/src/VBox/Main/include/GuestDnDPrivate.h

    r55422 r55512  
    3333class Progress;
    3434
    35 /** Array (vector) of guest DnD data. This might be an URI list, according
    36  *  to the format being set. */
    37 typedef std::vector<BYTE> GuestDnDData;
     35class GuestDnDCallbackEvent
     36{
     37public:
     38
     39    GuestDnDCallbackEvent(void)
     40        : mSemEvent(NIL_RTSEMEVENT)
     41        , mRc(VINF_SUCCESS) { }
     42
     43    virtual ~GuestDnDCallbackEvent(void);
     44
     45public:
     46
     47    int Reset(void);
     48
     49    int Notify(int rc);
     50
     51    int Result(void) const { return mRc; }
     52
     53    int Wait(RTMSINTERVAL msTimeout);
     54
     55protected:
     56
     57    /** Event semaphore to notify on error/completion. */
     58    RTSEMEVENT mSemEvent;
     59    /** Callback result. */
     60    int        mRc;
     61};
     62
     63/**
     64 * Structure for keeping the (URI) data to be sent/received.
     65 */
     66typedef struct GuestDnDData
     67{
     68    /** Array (vector) of guest DnD data. This might be an URI list, according
     69     *  to the format being set. */
     70    std::vector<BYTE>         vecData;
     71    /** Overall size (in bytes) of data to send. */
     72    uint64_t                  cbToProcess;
     73    /** Overall size (in bytes) of processed file data. */
     74    uint64_t                  cbProcessed;
     75} GuestDnDData;
    3876
    3977/**
     
    5694     *  This can be arbitrary data or an URI list. */
    5795    GuestDnDData                        mData;
     96    /** Callback event to use. */
     97    GuestDnDCallbackEvent               mCallback;
    5898    /** Struct for keeping data required for URI list processing. */
    5999    struct
     
    61101        /** List of all URI objects to send. */
    62102        DnDURIList                      lstURI;
    63         /** Event semaphore to notify in case of callback completion. */
    64         RTSEMEVENT                      SemEvent;
    65         /** Overall size (in bytes) of data to send. */
    66         uint64_t                        cbToProcess;
    67         /** Overall number of processed URI objects. */
    68         uint32_t                        cProcessed;
    69         /** Overall size (in bytes) of processed file data. */
    70         uint64_t                        cbProcessed;
    71103        /** Pointer to scratch buffer to use for
    72104         *  doing the actual chunk transfers. */
     
    99131     *  This can be arbitrary data or an URI list. */
    100132    GuestDnDData                        mData;
    101     /** Event semaphore to notify in case of callback completion. */
    102     RTSEMEVENT                          SemEvent;
     133    /** Callback event to use. */
     134    GuestDnDCallbackEvent               mCallback;
    103135    /** Struct for keeping data required for URI list processing. */
    104136    struct
     
    111143        /** Current object to receive. */
    112144        DnDURIObject                    objURI;
    113         /** Overall size (in bytes) of data to send. */
    114         uint64_t                        cbToProcess;
    115         /** Overall number of processed URI objects. */
    116         uint32_t                        cProcessed;
    117         /** Overall size (in bytes) of processed file data. */
    118         uint64_t                        cbProcessed;
    119145        /** List for holding created directories in the case of a rollback. */
    120146        RTCList<RTCString>              lstDirs;
     
    299325    uint32_t defAction(void) const { return m_defAction; }
    300326
    301     void setDropDir(const Utf8Str &strDropDir) { m_strDropDir = strDropDir; }
    302     Utf8Str dropDir(void) const { return m_strDropDir; }
    303 
    304327    void setFormat(const Utf8Str &strFormat) { m_strFormat = strFormat; }
    305328    Utf8Str format(void) const { return m_strFormat; }
    306 
    307     int dataAdd(const void *pvData, uint32_t cbData, uint32_t *pcbCurSize);
    308     int dataSetStatus(size_t cbDataAdd, size_t cbDataTotal = 0);
    309     const void *data(void) { return m_pvData; }
    310     size_t size(void) const { return m_cbData; }
    311329
    312330    void reset(void);
     
    338356    Utf8Str               m_strFormat;
    339357
    340     /** The actual MIME data.*/
    341     void                 *m_pvData;
    342     /** Size (in bytes) of MIME data. */
    343     uint32_t              m_cbData;
    344 
    345     size_t                m_cbDataCurrent;
    346     size_t                m_cbDataTotal;
    347     /** Dropped files directory on the host. */
    348     Utf8Str               m_strDropDir;
    349     /** URI object to use for reading/writing from/to files
    350      *  and handling directories. */
    351     DnDURIObject          m_URIObj;
    352358    /** Pointer to IGuest parent object. */
    353359    ComObjPtr<Guest>      m_parent;
     
    496502    }
    497503
    498     /** Static callbacks.
    499      * @{ */
    500     //static DECLCALLBACK(int) i_getNextMsgCallback(GuestDnDBase *pThis, uint32_t *puMsg, uint32_t *pcParms, PVBOXHGCMSVCPARM paParms);
    501     /** @}  */
    502 
    503504protected:
    504505
     
    520521    } mData;
    521522};
    522 
    523523#endif /* ____H_GUESTDNDPRIVATE */
    524524
  • trunk/src/VBox/Main/include/GuestDnDSourceImpl.h

    r55422 r55512  
    8787    int i_receiveRawData(PRECVDATACTX pCtx);
    8888    int i_receiveURIData(PRECVDATACTX pCtx);
     89
     90protected:
     91
     92    int i_updateProcess(PRECVDATACTX pCtx, uint32_t cbDataAdd);
    8993};
    9094
  • trunk/src/VBox/Main/src-client/GuestDnDPrivate.cpp

    r55424 r55512  
    160160 */
    161161
     162GuestDnDCallbackEvent::~GuestDnDCallbackEvent(void)
     163{
     164    if (NIL_RTSEMEVENT != mSemEvent)
     165        RTSemEventDestroy(mSemEvent);
     166}
     167
     168int GuestDnDCallbackEvent::Reset(void)
     169{
     170    int rc = VINF_SUCCESS;
     171
     172    if (NIL_RTSEMEVENT == mSemEvent)
     173        rc = RTSemEventCreate(&mSemEvent);
     174
     175    mRc = VINF_SUCCESS;
     176    return rc;
     177}
     178
     179int GuestDnDCallbackEvent::Notify(int rc)
     180{
     181    mRc = rc;
     182    return RTSemEventSignal(mSemEvent);
     183}
     184
     185int GuestDnDCallbackEvent::Wait(RTMSINTERVAL msTimeout)
     186{
     187    return RTSemEventWait(mSemEvent, msTimeout);
     188}
     189
     190///////////////////////////////////////////////////////////////////////////////
     191
    162192GuestDnDResponse::GuestDnDResponse(const ComObjPtr<Guest>& pGuest)
    163193    : m_EventSem(NIL_RTSEMEVENT)
    164194    , m_defAction(0)
    165195    , m_allActions(0)
    166     , m_pvData(0)
    167     , m_cbData(0)
    168     , m_cbDataCurrent(0)
    169     , m_cbDataTotal(0)
    170196    , m_parent(pGuest)
    171197{
     
    181207    int rc = RTSemEventDestroy(m_EventSem);
    182208    AssertRC(rc);
    183 }
    184 
    185 int GuestDnDResponse::dataAdd(const void *pvData, uint32_t cbData,
    186                               uint32_t *pcbCurSize)
    187 {
    188     AssertPtrReturn(pvData, VERR_INVALID_POINTER);
    189     AssertReturn(cbData, VERR_INVALID_PARAMETER);
    190     /* pcbCurSize is optional. */
    191 
    192     int rc = VINF_SUCCESS;
    193 
    194     /** @todo Make reallocation scheme a bit smarter here. */
    195     m_pvData = RTMemRealloc(m_pvData, m_cbData + cbData);
    196     if (m_pvData)
    197     {
    198         memcpy(&static_cast<uint8_t*>(m_pvData)[m_cbData],
    199                pvData, cbData);
    200         m_cbData += cbData;
    201 
    202         if (pcbCurSize)
    203             *pcbCurSize = m_cbData;
    204     }
    205     else
    206         rc = VERR_NO_MEMORY;
    207 
    208     return rc;
    209209}
    210210
     
    252252    LogFlowThisFuncEnter();
    253253
    254     m_defAction = 0;
     254    m_defAction  = 0;
    255255    m_allActions = 0;
    256256
    257     m_strDropDir = "";
    258     m_strFormat = "";
    259 
    260     if (m_pvData)
    261     {
    262         RTMemFree(m_pvData);
    263         m_pvData = NULL;
    264     }
    265 
    266     m_cbData        = 0;
    267     m_cbDataCurrent = 0;
    268     m_cbDataTotal   = 0;
     257    m_strFormat  = "";
    269258}
    270259
     
    290279        AssertComRC(hr);
    291280    }
    292     else fCanceled = TRUE;
     281    else
     282        fCanceled = TRUE;
    293283
    294284    return RT_BOOL(fCanceled);
     
    336326        AssertComRC(hr);
    337327
    338         LogFlowFunc(("fCompleted=%RTbool, fCanceled=%RTbool\n", fCompleted, fCanceled));
     328        LogFlowFunc(("Current: fCompleted=%RTbool, fCanceled=%RTbool\n", fCompleted, fCanceled));
    339329
    340330        if (!fCompleted)
     
    382372            }
    383373        }
     374
     375        hr = m_progress->COMGETTER(Completed)(&fCompleted);
     376        AssertComRC(hr);
     377        hr = m_progress->COMGETTER(Canceled)(&fCanceled);
     378        AssertComRC(hr);
     379
     380        LogFlowFunc(("New: fCompleted=%RTbool, fCanceled=%RTbool\n", fCompleted, fCanceled));
    384381    }
    385382
    386383    LogFlowFuncLeaveRC(vrc);
    387384    return vrc;
    388 }
    389 
    390 int GuestDnDResponse::dataSetStatus(size_t cbDataAdd, size_t cbDataTotal /* = 0 */)
    391 {
    392     if (cbDataTotal)
    393     {
    394 #ifndef DEBUG_andy
    395         AssertMsg(m_cbDataTotal <= cbDataTotal, ("New data size must not be smaller (%zu) than old value (%zu)\n",
    396                                                  cbDataTotal, m_cbDataTotal));
    397 #endif
    398         LogFlowFunc(("Updating total data size from %zu to %zu\n", m_cbDataTotal, cbDataTotal));
    399         m_cbDataTotal = cbDataTotal;
    400     }
    401     AssertMsg(m_cbDataTotal, ("m_cbDataTotal must not be <= 0\n"));
    402 
    403     m_cbDataCurrent += cbDataAdd;
    404     unsigned int cPercentage = RT_MIN(m_cbDataCurrent * 100.0 / m_cbDataTotal, 100);
    405 
    406     /** @todo Don't use anonymous enums (uint32_t). */
    407     uint32_t uStatus = DragAndDropSvc::DND_PROGRESS_RUNNING;
    408     Assert(m_cbDataCurrent <= m_cbDataTotal);
    409     if (m_cbDataCurrent >= m_cbDataTotal) uStatus = DragAndDropSvc::DND_PROGRESS_COMPLETE;
    410 
    411     LogFlowFunc(("Updating transfer status (%zu/%zu), status=%ld\n", m_cbDataCurrent, m_cbDataTotal, uStatus));
    412     AssertMsg(m_cbDataCurrent <= m_cbDataTotal,
    413               ("More data transferred (%zu) than initially announced (%zu), cbDataAdd=%zu\n",
    414                m_cbDataCurrent, m_cbDataTotal, cbDataAdd));
    415 
    416     int rc = setProgress(cPercentage, uStatus);
    417 
    418     /** @todo For now we instantly confirm the cancel. Check if the
    419      *        guest should first clean up stuff itself and than really confirm
    420      *        the cancel request by an extra message. */
    421     if (rc == VERR_CANCELLED) rc = setProgress(100, DragAndDropSvc::DND_PROGRESS_CANCELLED);
    422 
    423     LogFlowFuncLeaveRC(rc);
    424     return rc;
    425385}
    426386
     
    839799    return rc;
    840800}
    841 
    842 #if 0
    843 /**
    844  * Returns back information (message type + parameter count) of the current message in
    845  * the local outgoing message queue.
    846  *
    847  * @return  IPRT status code.
    848  * @param   pThis
    849  * @param   puMsg
    850  * @param   pcParms
    851  * @param   paParms
    852  */
    853 /* static */
    854 DECLCALLBACK(int) GuestDnDBase::i_getNextMsgCallback(GuestDnDBase *pThis, uint32_t *puMsg,
    855                                                      uint32_t *pcParms, PVBOXHGCMSVCPARM paParms)
    856 {
    857     AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
    858     AssertPtrReturn(puMsg,   VERR_INVALID_POINTER);
    859     AssertPtrReturn(pcParms, VERR_INVALID_POINTER);
    860     AssertPtrReturn(paParms, VERR_INVALID_POINTER);
    861 
    862     if (pThis->mData.m_lstOutgoing.empty())
    863         return VERR_NO_DATA;
    864 
    865     GuestDnDMsg *pMsg = pThis->mData.m_lstOutgoing.front();
    866     AssertPtr(pMsg);
    867 
    868     *puMsg   = pMsg->uMsg;
    869     *pcParms = pMsg->cParms;
    870 
    871     return VINF_SUCCESS;
    872 }
    873 #endif
    874801#endif /* VBOX_WITH_DRAG_AND_DROP */
    875802
  • trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp

    r55428 r55512  
    281281    if (RT_FAILURE(rc))
    282282        hr = setError(VBOX_E_IPRT_ERROR,
    283                       tr("Unable to retrieve drag'n drop pending status (%Rrc)\n"), rc);
     283                      tr("Error retrieving drag'n drop pending status (%Rrc)\n"), rc);
    284284
    285285    LogFlowFunc(("hr=%Rhrc, defaultAction=0x%x\n", hr, defaultAction));
     
    322322            RT_BZERO(pRecvCtx, sizeof(RECVDATACTX));
    323323
    324             pRecvCtx->mpSource  = this;
    325             pRecvCtx->mpResp    = pResp;
    326             pRecvCtx->mFormat   = aFormat;
     324            pRecvCtx->mpSource = this;
     325            pRecvCtx->mpResp   = pResp;
     326            pRecvCtx->mFormat  = aFormat;
    327327
    328328            RecvDataTask *pTask = new RecvDataTask(this, pRecvCtx);
     
    368368    HRESULT hr = S_OK;
    369369
     370#if 0
    370371    GuestDnDResponse *pResp = GuestDnDInst()->response();
    371372    if (pResp)
     
    419420    else
    420421        hr = VBOX_E_INVALID_OBJECT_STATE;
     422#endif
    421423
    422424    LogFlowFunc(("Returning hr=%Rhrc\n", hr));
     
    448450            rc = VERR_INVALID_PARAMETER;
    449451        }
    450         else if (cbData < pCtx->mData.size())
    451         {
    452             AssertMsgFailed(("New size (%RU64) is smaller than current size (%zu)\n", cbTotalSize, pCtx->mData.size()));
     452        else if (cbData < pCtx->mData.vecData.size())
     453        {
     454            AssertMsgFailed(("New size (%RU64) is smaller than current size (%zu)\n", cbTotalSize, pCtx->mData.vecData.size()));
    453455            rc = VERR_INVALID_PARAMETER;
    454456        }
     
    456458        if (RT_SUCCESS(rc))
    457459        {
    458             pCtx->mData.insert(pCtx->mData.begin(), (BYTE *)pvData, (BYTE *)pvData + cbData);
    459 
    460             LogFlowFunc(("mDataSize=%zu\n", pCtx->mData.size()));
     460            pCtx->mData.vecData.insert(pCtx->mData.vecData.begin(), (BYTE *)pvData, (BYTE *)pvData + cbData);
     461
     462            LogFlowFunc(("vecDataSize=%zu, cbData=%RU32, cbTotalSize=%RU64\n", pCtx->mData.vecData.size(), cbData, cbTotalSize));
    461463
    462464            /* Data transfer complete? */
    463             Assert(cbData <= pCtx->mData.size());
    464             if (cbData == pCtx->mData.size())
     465            Assert(cbData <= pCtx->mData.vecData.size());
     466            if (cbData == pCtx->mData.vecData.size())
    465467            {
    466468                bool fHasURIList = DnDMIMENeedsDropDir(pCtx->mFormat.c_str(), pCtx->mFormat.length());
     469                LogFlowFunc(("fHasURIList=%RTbool, cbTotalSize=%RU32\n", fHasURIList, cbTotalSize));
    467470                if (fHasURIList)
    468471                {
    469                     LogFlowFunc(("Parsing URI data ...\n"));
    470 
    471472                    /* Try parsing the data as URI list. */
    472                     rc = pCtx->mURI.lstURI.RootFromURIData(&pCtx->mData[0], pCtx->mData.size(), 0 /* uFlags */);
     473                    rc = pCtx->mURI.lstURI.RootFromURIData(&pCtx->mData.vecData[0], pCtx->mData.vecData.size(), 0 /* uFlags */);
    473474                    if (RT_SUCCESS(rc))
    474475                    {
    475                         pCtx->mURI.cbProcessed = 0;
    476                         pCtx->mURI.cbToProcess = cbTotalSize;
     476                        pCtx->mData.cbProcessed = 0;
     477
     478                        /* Assign new total size which also includes all paths + file
     479                         * data to receive from the guest. */
     480                        pCtx->mData.cbToProcess = cbTotalSize;
    477481                    }
    478482                }
    479483            }
     484
     485            if (RT_SUCCESS(rc))
     486                rc = i_updateProcess(pCtx, cbData);
    480487        }
    481488    }
     
    502509    {
    503510        rc = RTDirCreateFullPath(pszDir, fMode);
     511        if (RT_FAILURE(rc))
     512            LogRel2(("DnD: Error creating guest directory \"%s\" on the host, rc=%Rrc\n", pszDir, rc));
     513
    504514        RTStrFree(pszDir);
    505515    }
    506516    else
    507517         rc = VERR_NO_MEMORY;
     518
     519    if (RT_SUCCESS(rc))
     520        rc = i_updateProcess(pCtx, cbPath);
    508521
    509522    LogFlowFuncLeaveRC(rc);
     
    569582            if (mData.mProtocolVersion >= 2)
    570583                rc = pCtx->mURI.objURI.SetSize(cbSize);
     584        }
     585        else
     586        {
     587            LogRel2(("DnD: Error opening/creating guest file \"%s\" on host, rc=%Rrc\n",
     588                     pCtx->mURI.objURI.GetDestPath().c_str(), rc));
     589            break;
    571590        }
    572591
     
    611630                rc = VERR_DISK_FULL;
    612631            }
     632
     633            if (RT_SUCCESS(rc))
     634                rc = i_updateProcess(pCtx, cbWritten);
    613635        }
    614636
     
    617639            if (pCtx->mURI.objURI.IsComplete())
    618640            {
    619                 LogRel2(("DnD: File transfer to host complete: %s", pCtx->mURI.objURI.GetDestPath().c_str()));
     641                /* Prepare URI object for next use. */
     642                pCtx->mURI.objURI.Reset();
     643
     644                /** @todo Sanitize path. */
     645                LogRel2(("DnD: File transfer to host complete: %s\n", pCtx->mURI.objURI.GetDestPath().c_str()));
    620646                rc = VINF_EOF;
    621647            }
     
    634660{
    635661    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
    636 
    637     int rc;
    638662
    639663    GuestDnD *pInst = GuestDnDInst();
     
    646670    ASMAtomicWriteBool(&pCtx->mIsActive, true);
    647671
    648     /* Create event semaphore. */
    649     pCtx->SemEvent = NIL_RTSEMEVENT;
    650     rc = RTSemEventCreate(&pCtx->SemEvent);
     672    int rc = pCtx->mCallback.Reset();
    651673    if (RT_FAILURE(rc))
    652674        return rc;
    653675
    654     pCtx->mURI.cbToProcess = 0;
    655     pCtx->mURI.cbProcessed = 0;
    656     pCtx->mURI.cProcessed = 0;
     676    pCtx->mData.vecData.clear();
     677    pCtx->mData.cbToProcess = 0;
     678    pCtx->mData.cbProcessed = 0;
    657679
    658680    do
     
    680702    } while (0);
    681703
    682     if (pCtx->SemEvent != NIL_RTSEMEVENT)
    683     {
    684         RTSemEventDestroy(pCtx->SemEvent);
    685         pCtx->SemEvent = NIL_RTSEMEVENT;
    686     }
    687 
    688704    ASMAtomicWriteBool(&pCtx->mIsActive, false);
    689705
     
    709725    {
    710726        rc = pSource->i_receiveData(pTask->getCtx());
    711         /* Nothing to do here anymore. */
    712727    }
    713728    else
    714          rc = VERR_COM_INVALID_OBJECT_STATE;
     729        rc = VERR_COM_INVALID_OBJECT_STATE;
    715730
    716731    LogFlowFunc(("pSource=%p returning rc=%Rrc\n", (GuestDnDSource *)pSource, rc));
    717732
    718     delete pTask;
     733    if (pTask)
     734        delete pTask;
    719735    return rc;
    720736}
     
    745761     * Register callbacks.
    746762     */
    747     /* Guest callbacks. */
     763    REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_EVT_ERROR);
    748764    REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_SND_DATA);
    749765
     
    769785             */
    770786            LogFlowFunc(("Waiting for raw data callback ...\n"));
    771             rc = RTSemEventWait(pCtx->SemEvent, RT_INDEFINITE_WAIT);
    772             LogFlowFunc(("Raw data callback done\n"));
     787            rc = pCtx->mCallback.Wait(RT_INDEFINITE_WAIT);
     788            LogFlowFunc(("Raw callback done, rc=%Rrc\n", rc));
    773789        }
    774790
     
    778794     * Unregister callbacks.
    779795     */
     796    UNREGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_EVT_ERROR);
    780797    UNREGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_SND_DATA);
    781798
     
    813830     */
    814831    /* Guest callbacks. */
     832    REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_EVT_ERROR);
    815833    REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_SND_DATA);
    816834    REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_SND_DIR);
     
    828846
    829847        pCtx->mURI.strDropDir = szDropDir; /** @todo Keep directory handle open? */
    830         pResp->setDropDir(szDropDir);
    831848
    832849        /*
     
    849866             */
    850867            LogFlowFunc(("Waiting for URI callback ...\n"));
    851             rc = RTSemEventWait(pCtx->SemEvent, RT_INDEFINITE_WAIT);
     868            rc = pCtx->mCallback.Wait(RT_INDEFINITE_WAIT);
    852869            LogFlowFunc(("URI callback done, rc=%Rrc\n", rc));
    853870        }
     
    858875     * Unregister callbacks.
    859876     */
     877    UNREGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_EVT_ERROR);
    860878    UNREGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_SND_DATA);
    861879    UNREGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_SND_DIR);
     
    898916
    899917    int rc = VINF_SUCCESS;
     918    bool fNotify = false;
    900919
    901920    switch (uMsg)
     
    919938            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_EVT_ERROR == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    920939
    921             /* Cleanup. */
    922940            pCtx->mpResp->reset();
    923941            rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc);
     942            if (RT_SUCCESS(rc))
     943                rc = pCBData->rc;
    924944            break;
    925945        }
     
    931951
    932952    if (RT_FAILURE(rc))
    933     {
    934         if (pCtx->SemEvent != NIL_RTSEMEVENT)
    935         {
    936             LogFlowFunc(("Signalling ...\n"));
    937             int rc2 = RTSemEventSignal(pCtx->SemEvent);
    938             AssertRC(rc2);
    939         }
     953        fNotify = true;
     954
     955    if (fNotify)
     956    {
     957        int rc2 = pCtx->mCallback.Notify(rc);
     958        AssertRC(rc2);
    940959    }
    941960
     
    956975
    957976    int rc = VINF_SUCCESS;
     977    bool fNotify = false;
    958978
    959979    switch (uMsg)
     
    10151035            else /* Protocol v2 and up. */
    10161036                rc = pThis->i_onReceiveFileData(pCtx, pCBData->pvData, pCBData->cbData);
    1017 
    1018             /* Current file done? */
    1019             if (rc == VINF_EOF)
    1020             {
    1021                 /* Remove it from the list. */
    1022                 pCtx->mURI.lstURI.RemoveFirst();
    1023 
    1024                 if (pCtx->mURI.lstURI.IsEmpty()) /* Current file processed? Check if there's more. */
    1025                 {
    1026                     /* Let waiters know. */
    1027                     if (pCtx->SemEvent != NIL_RTSEMEVENT)
    1028                     {
    1029                         LogFlowFunc(("Signalling ...\n"));
    1030                         int rc2 = RTSemEventSignal(pCtx->SemEvent);
    1031                         AssertRC(rc2);
    1032                     }
    1033                 }
    1034             }
    10351037            break;
    10361038        }
     
    10421044            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_EVT_ERROR == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    10431045
    1044             /* Cleanup. */
    10451046            pCtx->mpResp->reset();
    10461047            rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc);
     1048            if (RT_SUCCESS(rc))
     1049                rc = pCBData->rc;
    10471050            break;
    10481051        }
     
    10541057
    10551058    if (RT_FAILURE(rc))
    1056     {
    1057         if (pCtx->SemEvent != NIL_RTSEMEVENT)
    1058         {
    1059             LogFlowFunc(("Signalling ...\n"));
    1060             int rc2 = RTSemEventSignal(pCtx->SemEvent);
    1061             AssertRC(rc2);
    1062         }
     1059        fNotify = true;
     1060
     1061    /* All URI data processed? */
     1062    if (pCtx->mData.cbProcessed >= pCtx->mData.cbToProcess)
     1063    {
     1064        Assert(pCtx->mData.cbProcessed == pCtx->mData.cbToProcess);
     1065        fNotify = true;
     1066    }
     1067
     1068    LogFlowFunc(("cbProcessed=%RU64, cbToProcess=%RU64, fNotify=%RTbool\n",
     1069                 pCtx->mData.cbProcessed, pCtx->mData.cbToProcess, fNotify));
     1070
     1071    if (fNotify)
     1072    {
     1073        int rc2 = pCtx->mCallback.Notify(rc);
     1074        AssertRC(rc2);
    10631075    }
    10641076
     
    10671079}
    10681080
     1081int GuestDnDSource::i_updateProcess(PRECVDATACTX pCtx, uint32_t cbDataAdd)
     1082{
     1083    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     1084
     1085    pCtx->mData.cbProcessed += cbDataAdd;
     1086    Assert(pCtx->mData.cbProcessed <= pCtx->mData.cbToProcess);
     1087
     1088    int64_t cbTotal  = pCtx->mData.cbToProcess;
     1089    uint8_t uPercent = pCtx->mData.cbProcessed * 100 / (cbTotal ? cbTotal : 1);
     1090
     1091    int rc = pCtx->mpResp->setProgress(uPercent,
     1092                                         uPercent >= 100
     1093                                       ? DragAndDropSvc::DND_PROGRESS_COMPLETE
     1094                                       : DragAndDropSvc::DND_PROGRESS_RUNNING);
     1095    return rc;
     1096}
     1097
  • trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp

    r55459 r55512  
    499499    }
    500500    else
    501          rc = VERR_COM_INVALID_OBJECT_STATE;
     501        rc = VERR_COM_INVALID_OBJECT_STATE;
    502502
    503503    LogFlowFunc(("pTarget=%p returning rc=%Rrc\n", (GuestDnDTarget *)pTarget, rc));
    504504
    505     delete pTask;
     505    if (pTask)
     506        delete pTask;
    506507    return rc;
    507508}
     
    544545            RT_BZERO(pSendCtx, sizeof(SENDDATACTX));
    545546
    546             pSendCtx->mpTarget  = this;
    547             pSendCtx->mpResp    = pResp;
    548             pSendCtx->mScreenID = aScreenId;
    549             pSendCtx->mFormat   = aFormat;
    550             pSendCtx->mData    = aData;
     547            pSendCtx->mpTarget      = this;
     548            pSendCtx->mpResp        = pResp;
     549            pSendCtx->mScreenID     = aScreenId;
     550            pSendCtx->mFormat       = aFormat;
     551            pSendCtx->mData.vecData = aData;
    551552
    552553            SendDataTask *pTask = new SendDataTask(this, pSendCtx);
     
    628629            GuestDnDMsg Msg;
    629630
    630             size_t cbDataTotal = pCtx->mData.size();
     631            size_t cbDataTotal = pCtx->mData.vecData.size();
    631632            DATA_IS_VALID_BREAK(cbDataTotal);
    632633
     
    636637            Msg.setNextPointer((void *)pCtx->mFormat.c_str(), (uint32_t)pCtx->mFormat.length() + 1);
    637638            Msg.setNextUInt32((uint32_t)pCtx->mFormat.length() + 1);
    638             Msg.setNextPointer((void*)&pCtx->mData.front(), (uint32_t)cbDataTotal);
     639            Msg.setNextPointer((void*)&pCtx->mData.vecData.front(), (uint32_t)cbDataTotal);
    639640            Msg.setNextUInt32(cbDataTotal);
    640641
     
    696697        LogFlowFunc(("Opening \"%s\" ...\n", strPathSrc.c_str()));
    697698        rc = aFile.OpenEx(strPathSrc, DnDURIObject::File, DnDURIObject::Source,
    698                           RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE, 0 /* fFlags */);           
     699                          RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE, 0 /* fFlags */);
    699700    }
    700701
    701702    bool fSendFileData = false;
    702     if (RT_SUCCESS(rc)) 
     703    if (RT_SUCCESS(rc))
    703704    {
    704705        if (mData.mProtocolVersion >= 2)
    705706        {
    706             if (!fOpen) 
     707            if (!fOpen)
    707708            {
    708709                /*
     
    787788    if (RT_SUCCESS(rc))
    788789    {
    789         pCtx->mURI.cbProcessed += cbRead;
     790        pCtx->mData.cbProcessed += cbRead;
    790791
    791792        if (mData.mProtocolVersion <= 1)
     
    824825
    825826    int rc = VINF_SUCCESS;
     827    bool fNotify = false;
    826828
    827829    switch (uMsg)
     
    919921    }
    920922
    921     if (RT_FAILURE(rc))
    922     {
    923         if (pCtx->mURI.SemEvent != NIL_RTSEMEVENT)
    924         {
    925             LogFlowFunc(("Signalling ...\n"));
    926             int rc2 = RTSemEventSignal(pCtx->mURI.SemEvent);
    927             AssertRC(rc2);
    928         }
     923    if (fNotify)
     924    {
     925        int rc2 = pCtx->mCallback.Notify(rc);
     926        AssertRC(rc2);
    929927    }
    930928
     
    957955        return rc;
    958956
     957    rc = pCtx->mCallback.Reset();
     958    if (RT_FAILURE(rc))
     959        return rc;
     960
    959961#define UNREGISTER_CALLBACK(x) \
    960962    rc = pCtx->mpResp->setCallback(x, NULL); \
     
    966968    /* Generic callbacks. */
    967969    REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG);
     970    REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_EVT_ERROR);
    968971    /* Host callbacks. */
    969972    REGISTER_CALLBACK(DragAndDropSvc::HOST_DND_HG_SND_DIR);
     
    980983        pCtx->mURI.cbScratchBuf = m_cbBlockSize;
    981984
    982         /* Create event semaphore. */
    983         pCtx->mURI.SemEvent = NIL_RTSEMEVENT;
    984         rc = RTSemEventCreate(&pCtx->mURI.SemEvent);
    985         if (RT_FAILURE(rc))
    986             break;
    987 
    988985        /*
    989986         * Extract URI list from byte data.
     
    991988        DnDURIList &lstURI = pCtx->mURI.lstURI; /* Use the URI list from the context. */
    992989
    993         const char *pszList = (const char *)&pCtx->mData.front();
     990        const char *pszList = (const char *)&pCtx->mData.vecData.front();
    994991        URI_DATA_IS_VALID_BREAK(pszList);
    995992
    996         uint32_t cbList = pCtx->mData.size();
     993        uint32_t cbList = pCtx->mData.vecData.size();
    997994        URI_DATA_IS_VALID_BREAK(cbList);
    998995
     
    10071004            break;
    10081005
    1009         pCtx->mURI.cbProcessed = 0;
    1010         pCtx->mURI.cProcessed  = 0;
    1011         pCtx->mURI.cbToProcess = lstURI.TotalBytes();
     1006        pCtx->mData.cbProcessed = 0;
     1007        pCtx->mData.cbToProcess = lstURI.TotalBytes();
    10121008
    10131009        /*
     
    10371033             */
    10381034            LogFlowFunc(("Waiting for URI callback ...\n"));
    1039             rc = RTSemEventWait(pCtx->mURI.SemEvent, RT_INDEFINITE_WAIT);
    1040             LogFlowFunc(("URI callback done\n"));
     1035            rc = pCtx->mCallback.Wait(RT_INDEFINITE_WAIT);
     1036            LogFlowFunc(("URI callback done, rc=%Rrc\n", rc));
    10411037        }
    10421038
    10431039    } while (0);
    1044 
    1045      if (pCtx->mURI.SemEvent != NIL_RTSEMEVENT)
    1046      {
    1047          RTSemEventDestroy(pCtx->mURI.SemEvent);
    1048          pCtx->mURI.SemEvent = NIL_RTSEMEVENT;
    1049      }
    10501040
    10511041    /*
     
    10541044    /* Guest callbacks. */
    10551045    UNREGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG);
     1046    UNREGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_EVT_ERROR);
    10561047    /* Host callbacks. */
    10571048    UNREGISTER_CALLBACK(DragAndDropSvc::HOST_DND_HG_SND_DIR);
     
    10811072    int rc;
    10821073
    1083     uint64_t cbTotal = pCtx->mURI.cbToProcess;
    1084     uint8_t uPercent = pCtx->mURI.cbProcessed * 100 / (cbTotal ? cbTotal : 1);
    1085 
    1086     LogFlowFunc(("%RU64 / %RU64 -- %RU8%%\n", pCtx->mURI.cbProcessed, cbTotal, uPercent));
     1074    uint64_t cbTotal = pCtx->mData.cbToProcess;
     1075    uint8_t uPercent = pCtx->mData.cbProcessed * 100 / (cbTotal ? cbTotal : 1);
     1076
     1077    LogFlowFunc(("%RU64 / %RU64 -- %RU8%%\n", pCtx->mData.cbProcessed, cbTotal, uPercent));
    10871078
    10881079    bool fComplete = (uPercent >= 100) || lstURI.IsEmpty();
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