Changeset 55549 in vbox for trunk/src/VBox/Main/src-client
- Timestamp:
- Apr 30, 2015 12:28:26 PM (10 years ago)
- Location:
- trunk/src/VBox/Main/src-client
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/GuestDnDPrivate.cpp
r55539 r55549 261 261 { 262 262 m_progress.setNull(); 263 HRESULT rc = m_progress.createObject(); 264 if (SUCCEEDED(rc)) 265 { 266 rc = m_progress->init(static_cast<IGuest *>(pParent), 263 264 HRESULT hr = m_progress.createObject(); 265 if (SUCCEEDED(hr)) 266 { 267 hr = m_progress->init(static_cast<IGuest *>(pParent), 267 268 Bstr(pParent->tr("Dropping data")).raw(), 268 269 TRUE /* aCancelable */); 269 270 } 270 return rc; 271 272 return hr; 271 273 } 272 274 … … 734 736 GuestDnDBase::GuestDnDBase(void) 735 737 { 738 mDataBase.mfTransferIsPending = false; 739 740 /* 741 * Initialize public attributes. 742 */ 736 743 m_strFormats = GuestDnDInst()->defaultFormats(); 737 744 } -
trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp
r55539 r55549 101 101 * how to do something, so try to negogiate a sensible value here later. */ 102 102 mData.mcbBlockSize = _64K; /** @todo Make this configurable. */ 103 mData.mfDropIsPending = false;104 103 105 104 LogFlowThisFunc(("\n")); … … 293 292 #else /* VBOX_WITH_DRAG_AND_DROP */ 294 293 294 AutoCaller autoCaller(this); 295 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 296 295 297 /* Input validation. */ 296 298 if (RT_UNLIKELY((aFormat.c_str()) == NULL || *(aFormat.c_str()) == '\0')) 297 299 return setError(E_INVALIDARG, tr("No drop format specified")); 298 300 299 AutoCaller autoCaller(this);300 if (FAILED(autoCaller.rc())) return autoCaller.rc();301 302 301 uint32_t uAction = GuestDnD::toHGCMAction(aAction); 303 /* If there is no usable action, ignore this request. */ 304 if (isDnDIgnoreAction(uAction)) 302 if (isDnDIgnoreAction(uAction)) /* If there is no usable action, ignore this request. */ 305 303 return S_OK; 306 304 307 305 /* Note: At the moment we only support one transfer at a time. */ 308 if (ASMAtomicReadBool(&mData .mfDropIsPending))306 if (ASMAtomicReadBool(&mDataBase.mfTransferIsPending)) 309 307 return setError(E_INVALIDARG, tr("Another drop operation already is in progress")); 310 308 311 ASMAtomicWriteBool(&mData .mfDropIsPending, true);309 ASMAtomicWriteBool(&mDataBase.mfTransferIsPending, true); 312 310 313 311 /* Dito. */ … … 329 327 AssertReturn(pTask->isOk(), pTask->getRC()); 330 328 331 RTTHREAD recvThread; 332 int rc = RTThreadCreate(&recvThread, GuestDnDSource::i_receiveDataThread, 329 int rc = RTThreadCreate(NULL, GuestDnDSource::i_receiveDataThread, 333 330 (void *)pTask, 0, RTTHREADTYPE_MAIN_WORKER, 0, "dndSrcRcvData"); 334 331 if (RT_SUCCESS(rc)) … … 347 344 } 348 345 349 /* Note: mData .mfDropIsPending will be set to false again by i_receiveDataThread. */346 /* Note: mDataBase.mfTransferIsPending will be set to false again by i_receiveDataThread. */ 350 347 351 348 LogFlowFunc(("Returning hr=%Rhrc\n", hr)); … … 365 362 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 366 363 367 if (ASMAtomicReadBool(&mData.mfDropIsPending)) 368 return setError(E_INVALIDARG, tr("Current drop operation still running")); 364 /* Don't allow receiving the actual data until our transfer 365 * actually is complete. */ 366 if (ASMAtomicReadBool(&mDataBase.mfTransferIsPending)) 367 return setError(E_INVALIDARG, tr("Current drop operation still in progress")); 369 368 370 369 PRECVDATACTX pCtx = &mData.mRecvCtx; … … 507 506 { 508 507 /* 509 * BUG: Protocol v1 does *not* send root directory names in URI format,510 * however, if this is a root URI directory (which came with the initial511 * GUEST_DND_GH_SND_DATA message(s)) the total data announced was for512 * root directory names which came in URI format, as an URI list.508 * Protocols v1/v2 do *not* send root element names (files/directories) 509 * in URI format. The initial GUEST_DND_GH_SND_DATA message(s) however 510 * did take those element names into account, but *with* URI decoration 511 * when it comes to communicating the total bytes being sent. 513 512 * 514 * So construct an URI path locally to keep the accounting right. 513 * So translate the path into a valid URI path and add the resulting 514 * length (+ "\r\n" and termination) to the total bytes received 515 * to keep the accounting right. 515 516 */ 516 517 char *pszPathURI = RTUriCreate("file" /* pszScheme */, "/" /* pszAuthority */, … … 593 594 { 594 595 /** @todo Unescpae path before printing. */ 595 LogRel2(("DnD: Transferring file to host: %s\n", pCtx->mURI.objURI.GetDestPath().c_str()));596 LogRel2(("DnD: Transferring guest file to host: %s\n", pCtx->mURI.objURI.GetDestPath().c_str())); 596 597 597 598 /* Note: Protocol v1 does not send any file sizes, so always 0. */ … … 604 605 else 605 606 { 606 LogRel2(("DnD: Error opening/creating guest file \"%s\"on host, rc=%Rrc\n",607 LogRel2(("DnD: Error opening/creating guest file '%s' on host, rc=%Rrc\n", 607 608 pCtx->mURI.objURI.GetDestPath().c_str(), rc)); 608 609 break; 610 } 611 612 if (mDataBase.mProtocolVersion <= 2) 613 { 614 /* 615 * Protocols v1/v2 do *not* send root element names (files/directories) 616 * in URI format. The initial GUEST_DND_GH_SND_DATA message(s) however 617 * did take those element names into account, but *with* URI decoration 618 * when it comes to communicating the total bytes being sent. 619 * 620 * So translate the path into a valid URI path and add the resulting 621 * length (+ "\r\n" and termination) to the total bytes received 622 * to keep the accounting right. 623 */ 624 char *pszPathURI = RTUriCreate("file" /* pszScheme */, "/" /* pszAuthority */, 625 pszPath /* pszPath */, 626 NULL /* pszQuery */, NULL /* pszFragment */); 627 if (pszPathURI) 628 { 629 bool fHasPath = RTPathHasPath(pszPath); /* Use original data received. */ 630 if (!fHasPath) /* Root path? */ 631 { 632 cbPath = strlen(pszPathURI); 633 cbPath += 3; /* Include "\r" + "\n" + termination -- see above. */ 634 635 rc = i_updateProcess(pCtx, cbPath); 636 } 637 638 LogFlowFunc(("URI pszPathURI=%s, fHasPath=%RTbool, cbPath=%RU32\n", pszPathURI, fHasPath, cbPath)); 639 RTStrFree(pszPathURI); 640 } 641 else 642 { 643 rc = VERR_NO_MEMORY; 644 break; 645 } 609 646 } 610 647 … … 667 704 } 668 705 else 669 LogRel(("DnD: Error : Can't writeguest file to host to \"%s\": %Rrc\n", pCtx->mURI.objURI.GetDestPath().c_str(), rc));706 LogRel(("DnD: Error writing guest file to host to \"%s\": %Rrc\n", pCtx->mURI.objURI.GetDestPath().c_str(), rc)); 670 707 671 708 } while (0); … … 749 786 rc = VERR_COM_INVALID_OBJECT_STATE; 750 787 788 ASMAtomicWriteBool(&pSource->mDataBase.mfTransferIsPending, false); 789 751 790 LogFlowFunc(("pSource=%p returning rc=%Rrc\n", (GuestDnDSource *)pSource, rc)); 752 791 753 792 if (pTask) 754 793 delete pTask; 755 756 ASMAtomicWriteBool(&pSource->mData.mfDropIsPending, false);757 758 794 return rc; 759 795 } … … 939 975 940 976 int rc = VINF_SUCCESS; 941 bool fNotify = false;942 977 943 978 switch (uMsg) … … 974 1009 975 1010 if (RT_FAILURE(rc)) 976 fNotify = true;977 978 if (fNotify)979 1011 { 980 1012 int rc2 = pCtx->mCallback.Notify(rc); -
trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp
r55539 r55549 496 496 else 497 497 rc = VERR_COM_INVALID_OBJECT_STATE; 498 499 ASMAtomicWriteBool(&pTarget->mDataBase.mfTransferIsPending, false); 498 500 499 501 LogFlowFunc(("pTarget=%p returning rc=%Rrc\n", (GuestDnDTarget *)pTarget, rc)); … … 521 523 #else /* VBOX_WITH_DRAG_AND_DROP */ 522 524 523 /** @todo Add input validation. */524 /** @todo Check if another sendData() call currently is being processed. */525 526 525 AutoCaller autoCaller(this); 527 526 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 528 527 529 /* Note: At the moment we only support one response at a time. */ 528 /* Input validation. */ 529 if (RT_UNLIKELY((aFormat.c_str()) == NULL || *(aFormat.c_str()) == '\0')) 530 return setError(E_INVALIDARG, tr("No data format specified")); 531 if (RT_UNLIKELY(!aData.size())) 532 return setError(E_INVALIDARG, tr("No data to send specified")); 533 534 /* Note: At the moment we only support one transfer at a time. */ 535 if (ASMAtomicReadBool(&mDataBase.mfTransferIsPending)) 536 return setError(E_INVALIDARG, tr("Another send operation already is in progress")); 537 538 ASMAtomicWriteBool(&mDataBase.mfTransferIsPending, true); 539 540 /* Dito. */ 530 541 GuestDnDResponse *pResp = GuestDnDInst()->response(); 531 542 AssertPtr(pResp); … … 549 560 AssertReturn(pTask->isOk(), pTask->getRC()); 550 561 551 RTTHREAD sendThread; 552 int rc = RTThreadCreate(&sendThread, GuestDnDTarget::i_sendDataThread, 562 int rc = RTThreadCreate(NULL, GuestDnDTarget::i_sendDataThread, 553 563 (void *)pTask, 0, RTTHREADTYPE_MAIN_WORKER, 0, "dndTgtSndData"); 554 564 if (RT_SUCCESS(rc)) … … 569 579 hr = setError(E_OUTOFMEMORY); 570 580 } 581 582 /* Note: mDataBase.mfTransferIsPending will be set to false again by i_sendDataThread. */ 571 583 572 584 LogFlowFunc(("Returning hr=%Rhrc\n", hr)); … … 608 620 609 621 ASMAtomicWriteBool(&pCtx->mIsActive, true); 622 623 /* Clear all remaining outgoing messages. */ 624 mDataBase.mListOutgoing.clear(); 610 625 611 626 do … … 694 709 rc = aFile.OpenEx(strPathSrc, DnDURIObject::File, DnDURIObject::Source, 695 710 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE, 0 /* fFlags */); 711 if (RT_FAILURE(rc)) 712 LogRel2(("DnD: Error opening host file \"%s\", rc=%Rrc\n", strPathSrc.c_str(), rc)); 696 713 } 697 714 … … 718 735 719 736 LogFlowFunc(("Sending file header ...\n")); 737 LogRel2(("DnD: Transferring host file to guest: %s (%RU64 bytes, mode 0x%x)\n", 738 strPathSrc.c_str(), aFile.GetSize(), aFile.GetMode())); 720 739 } 721 740 else … … 800 819 if (aFile.IsComplete()) /* Done reading? */ 801 820 { 821 LogRel2(("DnD: File transfer to guest complete: %s\n", aFile.GetSourcePath().c_str())); 802 822 LogFlowFunc(("File \"%s\" complete\n", aFile.GetSourcePath().c_str())); 803 823 rc = VINF_EOF; … … 821 841 822 842 int rc = VINF_SUCCESS; 823 bool fNotify = false;824 843 825 844 switch (uMsg) … … 849 868 850 869 if (RT_FAILURE(rc)) 851 {852 if (rc == VERR_NO_DATA) /* All URI objects processed? */853 {854 /* Unregister this callback. */855 AssertPtr(pCtx->mpResp);856 int rc2 = pCtx->mpResp->setCallback(uMsg, NULL /* PFNGUESTDNDCALLBACK */);857 if (RT_FAILURE(rc2))858 LogFlowFunc(("Error: Unable to unregister callback for message %RU32, rc=%Rrc\n", uMsg, rc2));859 }860 861 870 delete pMsg; 862 }863 871 } 864 872 catch(std::bad_alloc & /*e*/) … … 866 874 rc = VERR_NO_MEMORY; 867 875 } 876 break; 877 } 878 case DragAndDropSvc::GUEST_DND_GH_EVT_ERROR: 879 { 880 DragAndDropSvc::PVBOXDNDCBEVTERRORDATA pCBData = reinterpret_cast<DragAndDropSvc::PVBOXDNDCBEVTERRORDATA>(pvParms); 881 AssertPtr(pCBData); 882 AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBEVTERRORDATA) == cbParms, VERR_INVALID_PARAMETER); 883 AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_EVT_ERROR == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 884 885 pCtx->mpResp->reset(); 886 rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc); 887 if (RT_SUCCESS(rc)) 888 rc = pCBData->rc; 868 889 break; 869 890 } … … 917 938 } 918 939 919 if (fNotify) 920 { 921 int rc2 = pCtx->mCallback.Notify(rc); 940 if (RT_FAILURE(rc)) 941 { 942 switch (rc) 943 { 944 case VERR_NO_DATA: 945 LogRel2(("DnD: Transfer complete\n")); 946 break; 947 948 case VERR_CANCELLED: 949 LogRel2(("DnD: Transfer canceled\n")); 950 break; 951 952 default: 953 LogRel(("DnD: Error %Rrc occurred, aborting transfer\n", rc)); 954 break; 955 } 956 957 /* Unregister this callback. */ 958 AssertPtr(pCtx->mpResp); 959 int rc2 = pCtx->mpResp->setCallback(uMsg, NULL /* PFNGUESTDNDCALLBACK */); 960 AssertRC(rc2); 961 962 /* Notify waiters. */ 963 rc2 = pCtx->mCallback.Notify(rc); 922 964 AssertRC(rc2); 923 965 }
Note:
See TracChangeset
for help on using the changeset viewer.