Changeset 55512 in vbox
- Timestamp:
- Apr 29, 2015 11:34:53 AM (9 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
-
include/VBox/GuestHost/DragAndDrop.h (modified) (3 diffs)
-
src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDrag.cpp (modified) (1 diff)
-
src/VBox/GuestHost/DragAndDrop/DnDURIList.cpp (modified) (4 diffs)
-
src/VBox/GuestHost/DragAndDrop/DnDURIObject.cpp (modified) (2 diffs)
-
src/VBox/Main/include/GuestDnDPrivate.h (modified) (9 diffs)
-
src/VBox/Main/include/GuestDnDSourceImpl.h (modified) (1 diff)
-
src/VBox/Main/src-client/GuestDnDPrivate.cpp (modified) (7 diffs)
-
src/VBox/Main/src-client/GuestDnDSourceImpl.cpp (modified) (29 diffs)
-
src/VBox/Main/src-client/GuestDnDTargetImpl.cpp (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/GuestHost/DragAndDrop.h
r55422 r55512 94 94 int OpenEx(const RTCString &strPath, Type enmType, Dest enmDest, uint64_t fMode = 0, uint32_t fFlags = 0); 95 95 int Read(void *pvBuf, size_t cbBuf, uint32_t *pcbRead); 96 void Reset(void); 96 97 int Write(const void *pvBuf, size_t cbBuf, uint32_t *pcbWritten); 97 98 … … 145 146 RTCString RootToString(const RTCString &strBasePath = "", const RTCString &strSeparator = "\r\n"); 146 147 size_t RootCount(void) { return m_lstRoot.size(); } 148 uint32_t TotalCount(void) { return m_cTotal; } 147 149 size_t TotalBytes(void) { return m_cbTotal; } 148 150 … … 159 161 /** List of all URI objects added. */ 160 162 RTCList<DnDURIObject> m_lstTree; 163 /** Total number of all URI objects. */ 164 uint32_t m_cTotal; 161 165 /** Total size of all URI objects, that is, the file 162 166 * size of all objects (in bytes). */ -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDrag.cpp
r52730 r55512 164 164 if (RT_SUCCESS(rc)) 165 165 { 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. */ 168 167 QVector<uint8_t> vecData = dndSource.ReceiveData(); 169 168 if (!vecData.isEmpty()) -
trunk/src/VBox/GuestHost/DragAndDrop/DnDURIList.cpp
r55422 r55512 35 35 36 36 DnDURIList::DnDURIList(void) 37 : m_cbTotal(0) 37 : m_cTotal(0) 38 , m_cbTotal(0) 38 39 { 39 40 } … … 78 79 pcszPath, &pcszPath[cbBaseLen], 79 80 objInfo.Attr.fMode, cbSize)); 81 m_cTotal++; 80 82 m_cbTotal += cbSize; 81 83 #ifdef DEBUG_andy … … 257 259 char *pszRoot = &pszFilePath[cbBase]; 258 260 m_lstRoot.append(pszRoot); 261 m_cTotal++; 259 262 #ifdef DEBUG_andy 260 263 LogFlowFunc(("pszFilePath=%s, pszFileName=%s, pszRoot=%s\n", … … 356 359 rc = DnDPathSanitize(pszFilePath, strlen(pszFilePath)); 357 360 if (RT_SUCCESS(rc)) 361 { 358 362 m_lstRoot.append(pszFilePath); 363 m_cTotal++; 364 } 359 365 360 366 RTStrFree(pszFilePath); -
trunk/src/VBox/GuestHost/DragAndDrop/DnDURIObject.cpp
r55422 r55512 198 198 if (RT_SUCCESS(rc)) 199 199 rc = RTFileGetSize(u.m_hFile, &m_cbSize); 200 if (RT_SUCCESS(rc)) 201 m_cbProcessed = 0; 200 202 } 201 203 else … … 340 342 } 341 343 344 void 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 342 356 int DnDURIObject::Write(const void *pvBuf, size_t cbBuf, uint32_t *pcbWritten) 343 357 { -
trunk/src/VBox/Main/include/GuestDnDPrivate.h
r55422 r55512 33 33 class Progress; 34 34 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; 35 class GuestDnDCallbackEvent 36 { 37 public: 38 39 GuestDnDCallbackEvent(void) 40 : mSemEvent(NIL_RTSEMEVENT) 41 , mRc(VINF_SUCCESS) { } 42 43 virtual ~GuestDnDCallbackEvent(void); 44 45 public: 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 55 protected: 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 */ 66 typedef 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; 38 76 39 77 /** … … 56 94 * This can be arbitrary data or an URI list. */ 57 95 GuestDnDData mData; 96 /** Callback event to use. */ 97 GuestDnDCallbackEvent mCallback; 58 98 /** Struct for keeping data required for URI list processing. */ 59 99 struct … … 61 101 /** List of all URI objects to send. */ 62 102 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;71 103 /** Pointer to scratch buffer to use for 72 104 * doing the actual chunk transfers. */ … … 99 131 * This can be arbitrary data or an URI list. */ 100 132 GuestDnDData mData; 101 /** Event semaphore to notify in case of callback completion. */102 RTSEMEVENT SemEvent;133 /** Callback event to use. */ 134 GuestDnDCallbackEvent mCallback; 103 135 /** Struct for keeping data required for URI list processing. */ 104 136 struct … … 111 143 /** Current object to receive. */ 112 144 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;119 145 /** List for holding created directories in the case of a rollback. */ 120 146 RTCList<RTCString> lstDirs; … … 299 325 uint32_t defAction(void) const { return m_defAction; } 300 326 301 void setDropDir(const Utf8Str &strDropDir) { m_strDropDir = strDropDir; }302 Utf8Str dropDir(void) const { return m_strDropDir; }303 304 327 void setFormat(const Utf8Str &strFormat) { m_strFormat = strFormat; } 305 328 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; }311 329 312 330 void reset(void); … … 338 356 Utf8Str m_strFormat; 339 357 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 files350 * and handling directories. */351 DnDURIObject m_URIObj;352 358 /** Pointer to IGuest parent object. */ 353 359 ComObjPtr<Guest> m_parent; … … 496 502 } 497 503 498 /** Static callbacks.499 * @{ */500 //static DECLCALLBACK(int) i_getNextMsgCallback(GuestDnDBase *pThis, uint32_t *puMsg, uint32_t *pcParms, PVBOXHGCMSVCPARM paParms);501 /** @} */502 503 504 protected: 504 505 … … 520 521 } mData; 521 522 }; 522 523 523 #endif /* ____H_GUESTDNDPRIVATE */ 524 524 -
trunk/src/VBox/Main/include/GuestDnDSourceImpl.h
r55422 r55512 87 87 int i_receiveRawData(PRECVDATACTX pCtx); 88 88 int i_receiveURIData(PRECVDATACTX pCtx); 89 90 protected: 91 92 int i_updateProcess(PRECVDATACTX pCtx, uint32_t cbDataAdd); 89 93 }; 90 94 -
trunk/src/VBox/Main/src-client/GuestDnDPrivate.cpp
r55424 r55512 160 160 */ 161 161 162 GuestDnDCallbackEvent::~GuestDnDCallbackEvent(void) 163 { 164 if (NIL_RTSEMEVENT != mSemEvent) 165 RTSemEventDestroy(mSemEvent); 166 } 167 168 int 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 179 int GuestDnDCallbackEvent::Notify(int rc) 180 { 181 mRc = rc; 182 return RTSemEventSignal(mSemEvent); 183 } 184 185 int GuestDnDCallbackEvent::Wait(RTMSINTERVAL msTimeout) 186 { 187 return RTSemEventWait(mSemEvent, msTimeout); 188 } 189 190 /////////////////////////////////////////////////////////////////////////////// 191 162 192 GuestDnDResponse::GuestDnDResponse(const ComObjPtr<Guest>& pGuest) 163 193 : m_EventSem(NIL_RTSEMEVENT) 164 194 , m_defAction(0) 165 195 , m_allActions(0) 166 , m_pvData(0)167 , m_cbData(0)168 , m_cbDataCurrent(0)169 , m_cbDataTotal(0)170 196 , m_parent(pGuest) 171 197 { … … 181 207 int rc = RTSemEventDestroy(m_EventSem); 182 208 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 else206 rc = VERR_NO_MEMORY;207 208 return rc;209 209 } 210 210 … … 252 252 LogFlowThisFuncEnter(); 253 253 254 m_defAction = 0;254 m_defAction = 0; 255 255 m_allActions = 0; 256 256 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 = ""; 269 258 } 270 259 … … 290 279 AssertComRC(hr); 291 280 } 292 else fCanceled = TRUE; 281 else 282 fCanceled = TRUE; 293 283 294 284 return RT_BOOL(fCanceled); … … 336 326 AssertComRC(hr); 337 327 338 LogFlowFunc((" fCompleted=%RTbool, fCanceled=%RTbool\n", fCompleted, fCanceled));328 LogFlowFunc(("Current: fCompleted=%RTbool, fCanceled=%RTbool\n", fCompleted, fCanceled)); 339 329 340 330 if (!fCompleted) … … 382 372 } 383 373 } 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)); 384 381 } 385 382 386 383 LogFlowFuncLeaveRC(vrc); 387 384 return vrc; 388 }389 390 int GuestDnDResponse::dataSetStatus(size_t cbDataAdd, size_t cbDataTotal /* = 0 */)391 {392 if (cbDataTotal)393 {394 #ifndef DEBUG_andy395 AssertMsg(m_cbDataTotal <= cbDataTotal, ("New data size must not be smaller (%zu) than old value (%zu)\n",396 cbDataTotal, m_cbDataTotal));397 #endif398 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 the419 * guest should first clean up stuff itself and than really confirm420 * 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;425 385 } 426 386 … … 839 799 return rc; 840 800 } 841 842 #if 0843 /**844 * Returns back information (message type + parameter count) of the current message in845 * the local outgoing message queue.846 *847 * @return IPRT status code.848 * @param pThis849 * @param puMsg850 * @param pcParms851 * @param paParms852 */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 #endif874 801 #endif /* VBOX_WITH_DRAG_AND_DROP */ 875 802 -
trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp
r55428 r55512 281 281 if (RT_FAILURE(rc)) 282 282 hr = setError(VBOX_E_IPRT_ERROR, 283 tr(" Unable to retrievedrag'n drop pending status (%Rrc)\n"), rc);283 tr("Error retrieving drag'n drop pending status (%Rrc)\n"), rc); 284 284 285 285 LogFlowFunc(("hr=%Rhrc, defaultAction=0x%x\n", hr, defaultAction)); … … 322 322 RT_BZERO(pRecvCtx, sizeof(RECVDATACTX)); 323 323 324 pRecvCtx->mpSource = this;325 pRecvCtx->mpResp = pResp;326 pRecvCtx->mFormat = aFormat;324 pRecvCtx->mpSource = this; 325 pRecvCtx->mpResp = pResp; 326 pRecvCtx->mFormat = aFormat; 327 327 328 328 RecvDataTask *pTask = new RecvDataTask(this, pRecvCtx); … … 368 368 HRESULT hr = S_OK; 369 369 370 #if 0 370 371 GuestDnDResponse *pResp = GuestDnDInst()->response(); 371 372 if (pResp) … … 419 420 else 420 421 hr = VBOX_E_INVALID_OBJECT_STATE; 422 #endif 421 423 422 424 LogFlowFunc(("Returning hr=%Rhrc\n", hr)); … … 448 450 rc = VERR_INVALID_PARAMETER; 449 451 } 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())); 453 455 rc = VERR_INVALID_PARAMETER; 454 456 } … … 456 458 if (RT_SUCCESS(rc)) 457 459 { 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)); 461 463 462 464 /* 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()) 465 467 { 466 468 bool fHasURIList = DnDMIMENeedsDropDir(pCtx->mFormat.c_str(), pCtx->mFormat.length()); 469 LogFlowFunc(("fHasURIList=%RTbool, cbTotalSize=%RU32\n", fHasURIList, cbTotalSize)); 467 470 if (fHasURIList) 468 471 { 469 LogFlowFunc(("Parsing URI data ...\n"));470 471 472 /* 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 */); 473 474 if (RT_SUCCESS(rc)) 474 475 { 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; 477 481 } 478 482 } 479 483 } 484 485 if (RT_SUCCESS(rc)) 486 rc = i_updateProcess(pCtx, cbData); 480 487 } 481 488 } … … 502 509 { 503 510 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 504 514 RTStrFree(pszDir); 505 515 } 506 516 else 507 517 rc = VERR_NO_MEMORY; 518 519 if (RT_SUCCESS(rc)) 520 rc = i_updateProcess(pCtx, cbPath); 508 521 509 522 LogFlowFuncLeaveRC(rc); … … 569 582 if (mData.mProtocolVersion >= 2) 570 583 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; 571 590 } 572 591 … … 611 630 rc = VERR_DISK_FULL; 612 631 } 632 633 if (RT_SUCCESS(rc)) 634 rc = i_updateProcess(pCtx, cbWritten); 613 635 } 614 636 … … 617 639 if (pCtx->mURI.objURI.IsComplete()) 618 640 { 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())); 620 646 rc = VINF_EOF; 621 647 } … … 634 660 { 635 661 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 636 637 int rc;638 662 639 663 GuestDnD *pInst = GuestDnDInst(); … … 646 670 ASMAtomicWriteBool(&pCtx->mIsActive, true); 647 671 648 /* Create event semaphore. */ 649 pCtx->SemEvent = NIL_RTSEMEVENT; 650 rc = RTSemEventCreate(&pCtx->SemEvent); 672 int rc = pCtx->mCallback.Reset(); 651 673 if (RT_FAILURE(rc)) 652 674 return rc; 653 675 654 pCtx->m URI.cbToProcess = 0;655 pCtx->m URI.cbProcessed= 0;656 pCtx->m URI.cProcessed= 0;676 pCtx->mData.vecData.clear(); 677 pCtx->mData.cbToProcess = 0; 678 pCtx->mData.cbProcessed = 0; 657 679 658 680 do … … 680 702 } while (0); 681 703 682 if (pCtx->SemEvent != NIL_RTSEMEVENT)683 {684 RTSemEventDestroy(pCtx->SemEvent);685 pCtx->SemEvent = NIL_RTSEMEVENT;686 }687 688 704 ASMAtomicWriteBool(&pCtx->mIsActive, false); 689 705 … … 709 725 { 710 726 rc = pSource->i_receiveData(pTask->getCtx()); 711 /* Nothing to do here anymore. */712 727 } 713 728 else 714 rc = VERR_COM_INVALID_OBJECT_STATE;729 rc = VERR_COM_INVALID_OBJECT_STATE; 715 730 716 731 LogFlowFunc(("pSource=%p returning rc=%Rrc\n", (GuestDnDSource *)pSource, rc)); 717 732 718 delete pTask; 733 if (pTask) 734 delete pTask; 719 735 return rc; 720 736 } … … 745 761 * Register callbacks. 746 762 */ 747 /* Guest callbacks. */763 REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_EVT_ERROR); 748 764 REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_SND_DATA); 749 765 … … 769 785 */ 770 786 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)); 773 789 } 774 790 … … 778 794 * Unregister callbacks. 779 795 */ 796 UNREGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_EVT_ERROR); 780 797 UNREGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_SND_DATA); 781 798 … … 813 830 */ 814 831 /* Guest callbacks. */ 832 REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_EVT_ERROR); 815 833 REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_SND_DATA); 816 834 REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_SND_DIR); … … 828 846 829 847 pCtx->mURI.strDropDir = szDropDir; /** @todo Keep directory handle open? */ 830 pResp->setDropDir(szDropDir);831 848 832 849 /* … … 849 866 */ 850 867 LogFlowFunc(("Waiting for URI callback ...\n")); 851 rc = RTSemEventWait(pCtx->SemEvent,RT_INDEFINITE_WAIT);868 rc = pCtx->mCallback.Wait(RT_INDEFINITE_WAIT); 852 869 LogFlowFunc(("URI callback done, rc=%Rrc\n", rc)); 853 870 } … … 858 875 * Unregister callbacks. 859 876 */ 877 UNREGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_EVT_ERROR); 860 878 UNREGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_SND_DATA); 861 879 UNREGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_SND_DIR); … … 898 916 899 917 int rc = VINF_SUCCESS; 918 bool fNotify = false; 900 919 901 920 switch (uMsg) … … 919 938 AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_EVT_ERROR == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 920 939 921 /* Cleanup. */922 940 pCtx->mpResp->reset(); 923 941 rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc); 942 if (RT_SUCCESS(rc)) 943 rc = pCBData->rc; 924 944 break; 925 945 } … … 931 951 932 952 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); 940 959 } 941 960 … … 956 975 957 976 int rc = VINF_SUCCESS; 977 bool fNotify = false; 958 978 959 979 switch (uMsg) … … 1015 1035 else /* Protocol v2 and up. */ 1016 1036 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 }1035 1037 break; 1036 1038 } … … 1042 1044 AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_EVT_ERROR == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 1043 1045 1044 /* Cleanup. */1045 1046 pCtx->mpResp->reset(); 1046 1047 rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc); 1048 if (RT_SUCCESS(rc)) 1049 rc = pCBData->rc; 1047 1050 break; 1048 1051 } … … 1054 1057 1055 1058 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); 1063 1075 } 1064 1076 … … 1067 1079 } 1068 1080 1081 int 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 499 499 } 500 500 else 501 rc = VERR_COM_INVALID_OBJECT_STATE;501 rc = VERR_COM_INVALID_OBJECT_STATE; 502 502 503 503 LogFlowFunc(("pTarget=%p returning rc=%Rrc\n", (GuestDnDTarget *)pTarget, rc)); 504 504 505 delete pTask; 505 if (pTask) 506 delete pTask; 506 507 return rc; 507 508 } … … 544 545 RT_BZERO(pSendCtx, sizeof(SENDDATACTX)); 545 546 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; 551 552 552 553 SendDataTask *pTask = new SendDataTask(this, pSendCtx); … … 628 629 GuestDnDMsg Msg; 629 630 630 size_t cbDataTotal = pCtx->mData. size();631 size_t cbDataTotal = pCtx->mData.vecData.size(); 631 632 DATA_IS_VALID_BREAK(cbDataTotal); 632 633 … … 636 637 Msg.setNextPointer((void *)pCtx->mFormat.c_str(), (uint32_t)pCtx->mFormat.length() + 1); 637 638 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); 639 640 Msg.setNextUInt32(cbDataTotal); 640 641 … … 696 697 LogFlowFunc(("Opening \"%s\" ...\n", strPathSrc.c_str())); 697 698 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 */); 699 700 } 700 701 701 702 bool fSendFileData = false; 702 if (RT_SUCCESS(rc)) 703 if (RT_SUCCESS(rc)) 703 704 { 704 705 if (mData.mProtocolVersion >= 2) 705 706 { 706 if (!fOpen) 707 if (!fOpen) 707 708 { 708 709 /* … … 787 788 if (RT_SUCCESS(rc)) 788 789 { 789 pCtx->m URI.cbProcessed += cbRead;790 pCtx->mData.cbProcessed += cbRead; 790 791 791 792 if (mData.mProtocolVersion <= 1) … … 824 825 825 826 int rc = VINF_SUCCESS; 827 bool fNotify = false; 826 828 827 829 switch (uMsg) … … 919 921 } 920 922 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); 929 927 } 930 928 … … 957 955 return rc; 958 956 957 rc = pCtx->mCallback.Reset(); 958 if (RT_FAILURE(rc)) 959 return rc; 960 959 961 #define UNREGISTER_CALLBACK(x) \ 960 962 rc = pCtx->mpResp->setCallback(x, NULL); \ … … 966 968 /* Generic callbacks. */ 967 969 REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG); 970 REGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_EVT_ERROR); 968 971 /* Host callbacks. */ 969 972 REGISTER_CALLBACK(DragAndDropSvc::HOST_DND_HG_SND_DIR); … … 980 983 pCtx->mURI.cbScratchBuf = m_cbBlockSize; 981 984 982 /* Create event semaphore. */983 pCtx->mURI.SemEvent = NIL_RTSEMEVENT;984 rc = RTSemEventCreate(&pCtx->mURI.SemEvent);985 if (RT_FAILURE(rc))986 break;987 988 985 /* 989 986 * Extract URI list from byte data. … … 991 988 DnDURIList &lstURI = pCtx->mURI.lstURI; /* Use the URI list from the context. */ 992 989 993 const char *pszList = (const char *)&pCtx->mData. front();990 const char *pszList = (const char *)&pCtx->mData.vecData.front(); 994 991 URI_DATA_IS_VALID_BREAK(pszList); 995 992 996 uint32_t cbList = pCtx->mData. size();993 uint32_t cbList = pCtx->mData.vecData.size(); 997 994 URI_DATA_IS_VALID_BREAK(cbList); 998 995 … … 1007 1004 break; 1008 1005 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(); 1012 1008 1013 1009 /* … … 1037 1033 */ 1038 1034 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)); 1041 1037 } 1042 1038 1043 1039 } while (0); 1044 1045 if (pCtx->mURI.SemEvent != NIL_RTSEMEVENT)1046 {1047 RTSemEventDestroy(pCtx->mURI.SemEvent);1048 pCtx->mURI.SemEvent = NIL_RTSEMEVENT;1049 }1050 1040 1051 1041 /* … … 1054 1044 /* Guest callbacks. */ 1055 1045 UNREGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG); 1046 UNREGISTER_CALLBACK(DragAndDropSvc::GUEST_DND_GH_EVT_ERROR); 1056 1047 /* Host callbacks. */ 1057 1048 UNREGISTER_CALLBACK(DragAndDropSvc::HOST_DND_HG_SND_DIR); … … 1081 1072 int rc; 1082 1073 1083 uint64_t cbTotal = pCtx->m URI.cbToProcess;1084 uint8_t uPercent = pCtx->m URI.cbProcessed * 100 / (cbTotal ? cbTotal : 1);1085 1086 LogFlowFunc(("%RU64 / %RU64 -- %RU8%%\n", pCtx->m URI.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)); 1087 1078 1088 1079 bool fComplete = (uPercent >= 100) || lstURI.IsEmpty();
Note:
See TracChangeset
for help on using the changeset viewer.

