VirtualBox

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


Ignore:
Timestamp:
Jul 23, 2020 8:12:42 AM (5 years ago)
Author:
vboxsync
Message:

DnD/Main: More fixes.

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

Legend:

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

    r85402 r85423  
    273273}
    274274
    275 int GuestDnDResponse::setProgress(unsigned uPercentage,
    276                                   uint32_t uStatus,
     275int GuestDnDResponse::setProgress(unsigned uPercentage, uint32_t uStatus,
    277276                                  int rcOp /* = VINF_SUCCESS */, const Utf8Str &strMsg /* = "" */)
    278277{
    279     RT_NOREF(rcOp);
    280     LogFlowFunc(("uStatus=%RU32, uPercentage=%RU32, rcOp=%Rrc, strMsg=%s\n",
    281                  uStatus, uPercentage, rcOp, strMsg.c_str()));
     278    LogFlowFunc(("uPercentage=%u, uStatus=%RU32, , rcOp=%Rrc, strMsg=%s\n",
     279                 uPercentage, uStatus, rcOp, strMsg.c_str()));
     280
     281    HRESULT hr = S_OK;
     282
     283    BOOL fCompleted = FALSE;
     284    BOOL fCanceled  = FALSE;
    282285
    283286    int rc = VINF_SUCCESS;
     287
    284288    if (!m_pProgress.isNull())
    285289    {
    286         BOOL fCompleted;
    287         HRESULT hr = m_pProgress->COMGETTER(Completed)(&fCompleted);
     290        hr = m_pProgress->COMGETTER(Completed)(&fCompleted);
    288291        AssertComRC(hr);
    289292
    290         BOOL fCanceled;
    291293        hr = m_pProgress->COMGETTER(Canceled)(&fCanceled);
    292294        AssertComRC(hr);
    293295
    294         LogFlowFunc(("Current: fCompleted=%RTbool, fCanceled=%RTbool\n", fCompleted, fCanceled));
    295 
    296         if (!fCompleted)
    297         {
    298             switch (uStatus)
     296        LogFlowFunc(("Progress fCompleted=%RTbool, fCanceled=%RTbool\n", fCompleted, fCanceled));
     297    }
     298
     299    switch (uStatus)
     300    {
     301        case DragAndDropSvc::DND_PROGRESS_ERROR:
     302        {
     303            LogRel(("DnD: Guest reported error %Rrc\n", rcOp));
     304
     305            if (   !m_pProgress.isNull()
     306                && !fCompleted)
     307                hr = m_pProgress->i_notifyComplete(VBOX_E_IPRT_ERROR,
     308                                                   COM_IIDOF(IGuest),
     309                                                   m_pParent->getComponentName(), strMsg.c_str());
     310            reset();
     311            break;
     312        }
     313
     314        case DragAndDropSvc::DND_PROGRESS_CANCELLED:
     315        {
     316            LogRel2(("DnD: Guest cancelled operation\n"));
     317
     318            if (   !m_pProgress.isNull()
     319                && !fCompleted)
    299320            {
    300                 case DragAndDropSvc::DND_PROGRESS_ERROR:
     321                hr = m_pProgress->Cancel();
     322                AssertComRC(hr);
     323                hr = m_pProgress->i_notifyComplete(S_OK);
     324                AssertComRC(hr);
     325            }
     326
     327            reset();
     328            break;
     329        }
     330
     331        case DragAndDropSvc::DND_PROGRESS_RUNNING:
     332            RT_FALL_THROUGH();
     333        case DragAndDropSvc::DND_PROGRESS_COMPLETE:
     334        {
     335            LogRel2(("DnD: Guest reporting running/completion status with %u%%\n", uPercentage));
     336
     337            if (   !m_pProgress.isNull()
     338                && !fCompleted)
     339            {
     340                hr = m_pProgress->SetCurrentOperationProgress(uPercentage);
     341                AssertComRC(hr);
     342                if (   uStatus     == DragAndDropSvc::DND_PROGRESS_COMPLETE
     343                    || uPercentage >= 100)
    301344                {
    302                     hr = m_pProgress->i_notifyComplete(VBOX_E_IPRT_ERROR,
    303                                                        COM_IIDOF(IGuest),
    304                                                        m_pParent->getComponentName(), strMsg.c_str());
    305                     reset();
    306                     break;
    307                 }
    308 
    309                 case DragAndDropSvc::DND_PROGRESS_CANCELLED:
    310                 {
    311                     hr = m_pProgress->Cancel();
    312                     AssertComRC(hr);
    313345                    hr = m_pProgress->i_notifyComplete(S_OK);
    314346                    AssertComRC(hr);
    315 
    316                     reset();
    317                     break;
    318347                }
    319 
    320                 case DragAndDropSvc::DND_PROGRESS_RUNNING:
    321                 case DragAndDropSvc::DND_PROGRESS_COMPLETE:
    322                 {
    323                     if (!fCanceled)
    324                     {
    325                         hr = m_pProgress->SetCurrentOperationProgress(uPercentage);
    326                         AssertComRC(hr);
    327                         if (   uStatus     == DragAndDropSvc::DND_PROGRESS_COMPLETE
    328                             || uPercentage >= 100)
    329                         {
    330                             hr = m_pProgress->i_notifyComplete(S_OK);
    331                             AssertComRC(hr);
    332                         }
    333                     }
    334                     break;
    335                 }
    336 
    337                 default:
    338                     break;
    339348            }
    340         }
    341 
     349            break;
     350        }
     351
     352        default:
     353            break;
     354    }
     355
     356    if (!m_pProgress.isNull())
     357    {
    342358        hr = m_pProgress->COMGETTER(Completed)(&fCompleted);
    343359        AssertComRC(hr);
     
    345361        AssertComRC(hr);
    346362
    347         LogFlowFunc(("New: fCompleted=%RTbool, fCanceled=%RTbool\n", fCompleted, fCanceled));
     363        LogFlowFunc(("Progress fCompleted=%RTbool, fCanceled=%RTbool\n", fCompleted, fCanceled));
    348364    }
    349365
     
    942958                 pData->cbExtra, pData->cbProcessed, pData->getRemaining(), cbDataAdd));
    943959
    944     if (!pResp)
     960    if (   !pResp
     961        || !cbDataAdd) /* Only update if something really changes. */
    945962        return VINF_SUCCESS;
    946963
     
    948965        pData->addProcessed(cbDataAdd);
    949966
    950     int rc = pResp->setProgress(pData->getPercentComplete(),
     967    const uint8_t uPercent = pData->getPercentComplete();
     968
     969    LogRel2(("DnD: Transfer %RU8%% complete\n", uPercent));
     970
     971    int rc = pResp->setProgress(uPercent,
    951972                                  pData->isComplete()
    952973                                ? DND_PROGRESS_COMPLETE
  • trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp

    r85402 r85423  
    648648        pSendCtx->pResp     = pResp;
    649649        pSendCtx->uScreenID = aScreenId;
    650         pSendCtx->strFmtReq = aFormat;
    651 
     650
     651        pSendCtx->Meta.strFmt = aFormat;
    652652        pSendCtx->Meta.add(aData);
    653653
     
    820820    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
    821821
    822     /** @todo Add support for multiple HOST_DND_HG_SND_DATA messages in case of more than 64K data! */
    823     if (pCtx->Meta.cbData > _64K)
    824         return VERR_NOT_IMPLEMENTED;
    825 
    826     const uint32_t cbFmt = (uint32_t)pCtx->Meta.strFmt.length() + 1; /* Include terminator. */
    827 
    828     LogFlowFunc(("cbFmt=%RU32, cbMeta=%RU32\n", cbFmt, pCtx->Meta.cbData));
    829 
    830     GuestDnDMsg Msg;
    831     Msg.setType(HOST_DND_HG_SND_DATA);
    832     if (m_DataBase.uProtocolVersion < 3)
    833     {
    834         Msg.setNextUInt32(pCtx->uScreenID);                                 /* uScreenId */
    835         Msg.setNextPointer(pCtx->Meta.strFmt.mutableRaw(), cbFmt);          /* pvFormat */
    836         Msg.setNextUInt32(cbFmt);                                           /* cbFormat */
    837         Msg.setNextPointer(pCtx->Meta.pvData, (uint32_t)pCtx->Meta.cbData); /* pvData */
    838         /* Fill in the current data block size to send.
    839          * Note: Only supports uint32_t. */
    840         Msg.setNextUInt32((uint32_t)pCtx->Meta.cbData);                     /* cbData */
    841     }
    842     else
    843     {
    844         Msg.setNextUInt32(0); /** @todo ContextID not used yet. */
    845         Msg.setNextPointer(pCtx->Meta.pvData, (uint32_t)pCtx->Meta.cbData); /* pvData */
    846         Msg.setNextUInt32((uint32_t)pCtx->Meta.cbData);                     /* cbData */
    847         Msg.setNextPointer(NULL, 0);                                        /** @todo pvChecksum; not used yet. */
    848         Msg.setNextUInt32(0);                                               /** @todo cbChecksum; not used yet. */
    849     }
    850 
    851     int rc = GUESTDNDINST()->hostCall(Msg.getType(), Msg.getCount(), Msg.getParms());
     822    uint8_t *pvData = (uint8_t *)pCtx->Meta.pvData;
     823    size_t   cbData = pCtx->Meta.cbData;
     824
     825    int rc = VINF_SUCCESS;
     826
     827    const size_t  cbFmt   = pCtx->Meta.strFmt.length() + 1; /* Include terminator. */
     828    const char   *pcszFmt = pCtx->Meta.strFmt.c_str();
     829
     830    LogFlowFunc(("uProto=%u, szFmt=%s, cbFmt=%RU32, cbData=%zu\n", m_DataBase.uProtocolVersion, pcszFmt, cbFmt, cbData));
     831
     832    LogRel2(("DnD: Sending meta data to guest as '%s' (%zu bytes)\n", pcszFmt, cbData));
     833
     834#ifdef DEBUG
     835    RTCList<RTCString> lstFilesURI = RTCString((char *)pvData, cbData).split("\r\n");
     836    LogFlowFunc(("lstFilesURI=%zu\n", lstFilesURI.size()));
     837    for (size_t i = 0; i < lstFilesURI.size(); i++)
     838        LogFlowFunc(("\t%s\n", lstFilesURI.at(i).c_str()));
     839#endif
     840
     841    uint8_t *pvChunk = pvData;
     842    size_t   cbChunk = RT_MIN(mData.mcbBlockSize, cbData);
     843    while (cbData)
     844    {
     845        GuestDnDMsg Msg;
     846        Msg.setType(HOST_DND_HG_SND_DATA);
     847
     848        if (m_DataBase.uProtocolVersion < 3)
     849        {
     850            Msg.setNextUInt32(pCtx->uScreenID);                                 /* uScreenId */
     851            Msg.setNextPointer(unconst(pcszFmt), (uint32_t)cbFmt);              /* pvFormat */
     852            Msg.setNextUInt32((uint32_t)cbFmt);                                 /* cbFormat */
     853            Msg.setNextPointer(pvChunk, (uint32_t)cbChunk);                     /* pvData */
     854            /* Fill in the current data block size to send.
     855             * Note: Only supports uint32_t. */
     856            Msg.setNextUInt32((uint32_t)cbChunk);                               /* cbData */
     857        }
     858        else
     859        {
     860            Msg.setNextUInt32(0); /** @todo ContextID not used yet. */
     861            Msg.setNextPointer(pvChunk, (uint32_t)cbChunk);                     /* pvData */
     862            Msg.setNextUInt32((uint32_t)cbChunk);                               /* cbData */
     863            Msg.setNextPointer(NULL, 0);                                        /** @todo pvChecksum; not used yet. */
     864            Msg.setNextUInt32(0);                                               /** @todo cbChecksum; not used yet. */
     865        }
     866
     867        rc = GUESTDNDINST()->hostCall(Msg.getType(), Msg.getCount(), Msg.getParms());
     868        if (RT_FAILURE(rc))
     869            break;
     870
     871        pvChunk += cbChunk;
     872        AssertBreakStmt(cbData >= cbChunk, VERR_BUFFER_UNDERFLOW);
     873        cbData  -= cbChunk;
     874    }
     875
    852876    if (RT_SUCCESS(rc))
    853877    {
    854         rc = updateProgress(pCtx, pCtx->pResp, pCtx->Meta.cbData);
     878        rc = updateProgress(pCtx, pCtx->pResp, (uint32_t)pCtx->Meta.cbData);
    855879        AssertRC(rc);
    856880    }
     
    875899    GuestDnDMsg Msg;
    876900    Msg.setType(HOST_DND_HG_SND_DATA_HDR);
     901
     902    LogRel2(("DnD: Sending meta data header to guest (%RU64 bytes total data, %RU32 bytes meta data, %RU64 objects)\n",
     903             pCtx->getTotal(), pCtx->Meta.cbData, pCtx->Transfer.cObjToProcess));
    877904
    878905    Msg.setNextUInt32(0);                                                /** @todo uContext; not used yet. */
     
    9761003                pMsg->setNextUInt64(cbSize);                         /* uSize */
    9771004
    978                 LogRel2(("DnD: Transferring host file '%s' to guest (%zu bytes, mode %#x)\n",
    979                          pcszSrcPath, cbSize, fMode));
     1005                LogRel2(("DnD: Transferring host file '%s' to guest (as '%s', %zu bytes, mode %#x)\n",
     1006                         pcszSrcPath, pcszDstPath, cbSize, fMode));
    9801007
    9811008                /** @todo Set progress object title to current file being transferred? */
     
    10511078    if (RT_SUCCESS(rc))
    10521079    {
    1053         pCtx->addProcessed(cbRead);
    1054 
    10551080        LogFlowFunc(("cbBufe=%zu, cbRead=%RU32\n", cbBuf, cbRead));
    10561081
     
    10741099        }
    10751100
     1101        int rc2 = updateProgress(pCtx, pCtx->pResp, (uint32_t)cbRead);
     1102        AssertRC(rc2);
     1103
     1104        /* DnDTransferObjectRead() will return VINF_EOF if reading is complete. */
     1105        if (rc == VINF_EOF)
     1106            rc = VINF_SUCCESS;
     1107
    10761108        if (DnDTransferObjectIsComplete(pObj)) /* Done reading? */
    1077         {
    10781109            LogRel2(("DnD: Transferring host file '%s' to guest complete\n", pcszSrcPath));
    1079 
    1080             /* DnDTransferObjectRead() returns VINF_EOF when finished reading the entire file,
    1081              * but we don't want this here -- so just set VINF_SUCCESS. */
    1082             rc = VINF_SUCCESS;
    1083         }
    10841110    }
    10851111    else
     
    10991125    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    11001126
    1101     LogFlowFunc(("pThis=%p, uMsg=%RU32\n", pThis, uMsg));
     1127    /* At the moment we only have one transfer list per transfer. */
     1128    PDNDTRANSFERLIST pList = &pCtx->Transfer.List;
     1129
     1130    LogFlowFunc(("pThis=%p, pList=%p, uMsg=%RU32\n", pThis, pList, uMsg));
    11021131
    11031132    int  rc      = VINF_SUCCESS;
     
    11261155                GuestDnDMsg *pMsg = new GuestDnDMsg();
    11271156
    1128                 rc = pThis->i_sendTransferDataLoop(pCtx, pMsg);
     1157                rc = pThis->i_sendTransferListObject(pCtx, pList, pMsg);
    11291158                if (rc == VINF_EOF) /* Transfer complete? */
    11301159                {
     
    11711200
    11721201            rc = pCtx->pResp->setProgress(100, DND_PROGRESS_ERROR, pCBData->rc,
    1173                                            GuestDnDTarget::i_guestErrorToString(pCBData->rc));
     1202                                          GuestDnDTarget::i_guestErrorToString(pCBData->rc));
    11741203            if (RT_SUCCESS(rc))
    11751204            {
     
    13541383         * Extract transfer list from current meta data.
    13551384         */
    1356         rc = DnDTransferListAppendPathsFromBuffer(&pCtx->Transfer.List, DNDTRANSFERLISTFMT_NATIVE,
    1357                                                   (const char *)pCtx->Meta.pvData, pCtx->Meta.cbData, "\n", DNDTRANSFERLIST_FLAGS_NONE);
     1385        rc = DnDTransferListAppendPathsFromBuffer(&pCtx->Transfer.List, DNDTRANSFERLISTFMT_URI,
     1386                                                  (const char *)pCtx->Meta.pvData, pCtx->Meta.cbData, DND_PATH_SEPARATOR,
     1387                                                  DNDTRANSFERLIST_FLAGS_RECURSIVE);
    13581388        if (RT_FAILURE(rc))
    13591389            break;
     
    13621392         * Update internal state to reflect everything we need to work with it.
    13631393         */
    1364         pCtx->cbExtra = DnDTransferListObjTotalBytes(&pCtx->Transfer.List);
     1394        pCtx->cbExtra               = DnDTransferListObjTotalBytes(&pCtx->Transfer.List);
     1395        /* cbExtra can be 0, if all files are of 0 bytes size. */
     1396        pCtx->Transfer.cObjToProcess = DnDTransferListObjCount(&pCtx->Transfer.List);
     1397        AssertBreakStmt(pCtx->Transfer.cObjToProcess, rc = VERR_INVALID_PARAMETER);
     1398
     1399        /* Update the meta data to have the current root transfer entries in the right shape. */
     1400        if (DnDMIMEHasFileURLs(pCtx->Meta.strFmt.c_str(), RTSTR_MAX))
     1401        {
     1402            /* Save original format we're still going to use after updating the actual meta data. */
     1403            Utf8Str strFmt = pCtx->Meta.strFmt;
     1404
     1405            /* Reset stale data. */
     1406            pCtx->Meta.reset();
     1407
     1408            void  *pvData;
     1409            size_t cbData;
     1410#ifdef DEBUG
     1411            rc = DnDTransferListGetRootsEx(&pCtx->Transfer.List, DNDTRANSFERLISTFMT_URI, "" /* pcszPathBase */,
     1412                                           "\n" /* pcszSeparator */, (char **)&pvData, &cbData);
     1413            AssertRCReturn(rc, rc);
     1414            LogFlowFunc(("URI data:\n%s", (char *)pvData));
     1415            RTMemFree(pvData);
     1416            cbData = 0;
     1417#endif
     1418            rc = DnDTransferListGetRoots(&pCtx->Transfer.List, DNDTRANSFERLISTFMT_URI,
     1419                                         (char **)&pvData, &cbData);
     1420            AssertRCReturn(rc, rc);
     1421
     1422            /* pCtx->Meta now owns the allocated data. */
     1423            pCtx->Meta.strFmt      = strFmt;
     1424            pCtx->Meta.pvData      = pvData;
     1425            pCtx->Meta.cbData      = cbData;
     1426            pCtx->Meta.cbAllocated = cbData;
     1427        }
    13651428
    13661429        /*
     
    14441507}
    14451508
    1446 int GuestDnDTarget::i_sendTransferDataLoop(GuestDnDSendCtx *pCtx, GuestDnDMsg *pMsg)
     1509/**
     1510 * Sends the next object of a transfer list to the guest.
     1511 *
     1512 * @returns VBox status code. VINF_EOF if the transfer list is complete.
     1513 * @param   pCtx                Send context to use.
     1514 * @param   pList               Transfer list to use.
     1515 * @param   pMsg                Message to store send data into.
     1516 */
     1517int GuestDnDTarget::i_sendTransferListObject(GuestDnDSendCtx *pCtx, PDNDTRANSFERLIST pList, GuestDnDMsg *pMsg)
    14471518{
    14481519    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     1520    AssertPtrReturn(pList, VERR_INVALID_POINTER);
    14491521    AssertPtrReturn(pMsg, VERR_INVALID_POINTER);
    14501522
    14511523    int rc = updateProgress(pCtx, pCtx->pResp);
    1452     AssertRC(rc);
    1453 
    1454     if (   pCtx->isComplete()
    1455         && pCtx->Transfer.isComplete())
    1456     {
     1524    AssertRCReturn(rc, rc);
     1525
     1526    if (pCtx->isComplete())
     1527    {
     1528        Assert(pCtx->Transfer.isComplete());
    14571529        return VINF_EOF;
    14581530    }
    14591531
    1460     PDNDTRANSFEROBJECT pObj = DnDTransferListObjGetFirst(&pCtx->Transfer.List);
    1461     if (!pObj)
    1462         return VERR_WRONG_ORDER;
     1532    PDNDTRANSFEROBJECT pObj = DnDTransferListObjGetFirst(pList);
     1533    AssertPtrReturn(pObj, VERR_WRONG_ORDER);
    14631534
    14641535    switch (DnDTransferObjectGetType(pObj))
     
    14771548    }
    14781549
    1479     if (   DnDTransferObjectIsComplete(pObj)
    1480         || RT_FAILURE(rc))
    1481         DnDTransferListObjRemoveFirst(&pCtx->Transfer.List);
     1550    if (   RT_SUCCESS(rc)
     1551        && DnDTransferObjectIsComplete(pObj))
     1552    {
     1553        DnDTransferListObjRemove(pList, pObj);
     1554        pObj = NULL;
     1555
     1556        AssertReturn(pCtx->Transfer.cObjProcessed + 1 <= pCtx->Transfer.cObjToProcess, VERR_WRONG_ORDER);
     1557        pCtx->Transfer.cObjProcessed++;
     1558
     1559        pCtx->Transfer.fObjState = DND_OBJ_STATE_NONE;
     1560    }
    14821561
    14831562    LogFlowFuncLeaveRC(rc);
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