Changeset 57500 in vbox for trunk/src/VBox
- Timestamp:
- Aug 21, 2015 4:54:50 PM (9 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp
r57372 r57500 414 414 if (pszPathAbs) 415 415 { 416 rc = RTDirCreate(pszPathAbs, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU, 0); 416 #ifdef RT_OS_WINDOWS 417 uint32_t fCreationMode = (fMode & RTFS_DOS_MASK) | RTFS_DOS_NT_NORMAL; 418 #else 419 uint32_t fCreationMode = (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU; 420 #endif 421 rc = RTDirCreate(pszPathAbs, fCreationMode, 0); 417 422 if (RT_SUCCESS(rc)) 418 423 rc = DnDDirDroppedAddDir(&dirDroppedFiles, pszPathAbs); … … 455 460 if ( RT_SUCCESS(rc) 456 461 && ( uNextMsg == DragAndDropSvc::HOST_DND_HG_SND_FILE_HDR 457 /* Protocol v1 always sends the file name, so try openingevery time. */462 /* Protocol v1 always sends the file name, so opening the file every time. */ 458 463 || pCtx->uProtocol <= 1) 459 464 ) … … 465 470 szPathName, cbPathName, fMode, cbFileSize)); 466 471 467 uint64_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_ ALL;472 uint64_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_WRITE; 468 473 if (pCtx->uProtocol <= 1) 469 474 fOpen |= RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND; … … 475 480 { 476 481 RTCString strPathAbs(pszPathAbs); 477 rc = objFile.OpenEx(strPathAbs, DnDURIObject::File, DnDURIObject::Target, fOpen, 478 (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR); 482 #ifdef RT_OS_WINDOWS 483 uint32_t fCreationMode = (fMode & RTFS_DOS_MASK) | RTFS_DOS_NT_NORMAL; 484 #else 485 uint32_t fCreationMode = (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR; 486 #endif 487 rc = objFile.OpenEx(strPathAbs, DnDURIObject::File, DnDURIObject::Target, fOpen, fCreationMode); 479 488 if (RT_SUCCESS(rc)) 480 489 { … … 927 936 rc = VINF_PERMISSION_DENIED; 928 937 929 /* Set the protocol version to use. */ 930 pCtx->uProtocol = 2; 931 932 Assert(Info.u32ClientID); 933 pCtx->uClientID = Info.u32ClientID; 938 if (RT_SUCCESS(rc)) 939 { 940 /* Set the protocol version to use. */ 941 pCtx->uProtocol = 2; 942 943 Assert(Info.u32ClientID); 944 pCtx->uClientID = Info.u32ClientID; 945 } 934 946 } 935 947 … … 941 953 * does not implement this command. 942 954 */ 943 DragAndDropSvc::VBOXDNDCONNECT PMSG Msg;955 DragAndDropSvc::VBOXDNDCONNECTMSG Msg; 944 956 RT_ZERO(Msg); 945 957 Msg.hdr.result = VERR_WRONG_ORDER; … … 1142 1154 { 1143 1155 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1156 AssertReturn(uStatus > DragAndDropSvc::DND_PROGRESS_UNKNOWN, VERR_INVALID_PARAMETER); 1144 1157 1145 1158 DragAndDropSvc::VBOXDNDHGEVTPROGRESSMSG Msg; … … 1147 1160 Msg.hdr.result = VERR_WRONG_ORDER; 1148 1161 Msg.hdr.u32ClientID = pCtx->uClientID; 1149 Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_HG_EVT_PROGRESS;1162 Msg.hdr.u32Function = uStatus; 1150 1163 Msg.hdr.cParms = 3; 1151 1164 -
trunk/src/VBox/GuestHost/DragAndDrop/DnDURIObject.cpp
r57372 r57500 364 364 Close(); 365 365 366 m_Type 367 m_strSrcPath 368 m_strTgtPath 369 m_fMode = 0;370 m_cbSize 371 m_cbProcessed 366 m_Type = Unknown; 367 m_strSrcPath = ""; 368 m_strTgtPath = ""; 369 m_fMode = 0; 370 m_cbSize = 0; 371 m_cbProcessed = 0; 372 372 } 373 373 -
trunk/src/VBox/Main/include/GuestDnDPrivate.h
r57469 r57500 91 91 92 92 /** 93 * Structure for keeping an URI object's context around. 94 */ 95 typedef struct GuestDnDURIObjCtx 96 { 97 GuestDnDURIObjCtx(void) 98 : pObjURI(NULL) 99 , fAllocated(false) 100 , fHeaderSent(false) { } 101 102 virtual ~GuestDnDURIObjCtx(void) 103 { 104 Reset(); 105 } 106 107 public: 108 109 void Reset(void) 110 { 111 if ( pObjURI 112 && fAllocated) 113 { 114 delete pObjURI; 115 } 116 117 pObjURI = NULL; 118 119 fAllocated = false; 120 fHeaderSent = false; 121 } 122 123 124 /** Pointer to current object being handled. */ 125 DnDURIObject *pObjURI; 126 /** Flag whether pObjURI needs deletion after use. */ 127 bool fAllocated; 128 /** Flag whether the object's file header has been sent already. */ 129 bool fHeaderSent; 130 /** @todo Add more statistics / information here. */ 131 132 } GuestDnDURIObjCtx; 133 134 /** 93 135 * Structure for keeping around URI (list) data. 94 136 */ … … 126 168 { 127 169 lstURI.Clear(); 128 obj URI.Close();170 objCtx.Reset(); 129 171 130 172 DnDDirDroppedFilesRollback(&mDropDir); … … 141 183 142 184 DNDDIRDROPPEDFILES mDropDir; 143 /** (Non-recursive) List of root URI objects to receive. */185 /** (Non-recursive) List of URI objects to handle. */ 144 186 DnDURIList lstURI; 145 /** Current object to receive. */ 146 DnDURIObject objURI; 187 /** Context to current object being handled. 188 * As we currently do all transfers one after another we 189 * only have one context at a time. */ 190 GuestDnDURIObjCtx objCtx; 147 191 148 192 protected: -
trunk/src/VBox/Main/include/GuestDnDSourceImpl.h
r57221 r57500 67 67 int i_onReceiveData(PRECVDATACTX pCtx, const void *pvData, uint32_t cbData, uint64_t cbTotalSize); 68 68 int i_onReceiveDir(PRECVDATACTX pCtx, const char *pszPath, uint32_t cbPath, uint32_t fMode); 69 int i_onReceiveFileHdr(PRECVDATACTX pCtx, const char *pszPath, uint32_t cbPath, uint64_t cbSize, uint32_t fMode, uint32_t fFlags);70 int i_onReceiveFileData(PRECVDATACTX pCtx, const void *pvData, uint32_t cbData);69 int i_onReceiveFileHdr(PRECVDATACTX pCtx, GuestDnDURIObjCtx *pObjCtx, const char *pszPath, uint32_t cbPath, uint64_t cbSize, uint32_t fMode, uint32_t fFlags); 70 int i_onReceiveFileData(PRECVDATACTX pCtx, GuestDnDURIObjCtx *pObjCtx, const void *pvData, uint32_t cbData); 71 71 /** @} */ 72 72 #endif -
trunk/src/VBox/Main/include/GuestDnDTargetImpl.h
r57221 r57500 85 85 int i_cancelOperation(void); 86 86 int i_sendData(PSENDDATACTX pCtx, RTMSINTERVAL msTimeout); 87 int i_sendDirectory(PSENDDATACTX pCtx, GuestDnD Msg *pMsg, DnDURIObject *pObject);88 int i_sendFile(PSENDDATACTX pCtx, GuestDnD Msg *pMsg, DnDURIObject *pObject);89 int i_sendFileData(PSENDDATACTX pCtx, GuestDnD Msg *pMsg, DnDURIObject *pObject);87 int i_sendDirectory(PSENDDATACTX pCtx, GuestDnDURIObjCtx *pObjCtx, GuestDnDMsg *pMsg); 88 int i_sendFile(PSENDDATACTX pCtx, GuestDnDURIObjCtx *pObjCtx, GuestDnDMsg *pMsg); 89 int i_sendFileData(PSENDDATACTX pCtx, GuestDnDURIObjCtx *pObjCtx, GuestDnDMsg *pMsg); 90 90 int i_sendURIData(PSENDDATACTX pCtx, RTMSINTERVAL msTimeout); 91 91 int i_sendRawData(PSENDDATACTX pCtx, RTMSINTERVAL msTimeout); -
trunk/src/VBox/Main/src-client/GuestDnDPrivate.cpp
r57295 r57500 421 421 422 422 if ( pCBData->cbFormat == 0 423 || pCBData->cbFormat > _64K)423 || pCBData->cbFormat > _64K) /** @todo Make the maximum size configurable? */ 424 424 { 425 425 rc = VERR_INVALID_PARAMETER; -
trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp
r57358 r57500 620 620 } 621 621 622 int GuestDnDSource::i_onReceiveFileHdr(PRECVDATACTX pCtx, const char *pszPath, uint32_t cbPath,622 int GuestDnDSource::i_onReceiveFileHdr(PRECVDATACTX pCtx, GuestDnDURIObjCtx *pObjCtx, const char *pszPath, uint32_t cbPath, 623 623 uint64_t cbSize, uint32_t fMode, uint32_t fFlags) 624 624 { 625 625 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 626 AssertPtrReturn(pObjCtx, VERR_INVALID_POINTER); 626 627 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 627 628 AssertReturn(cbPath, VERR_INVALID_PARAMETER); … … 635 636 do 636 637 { 637 if ( pCtx->mURI.objURI.IsOpen() 638 && !pCtx->mURI.objURI.IsComplete()) 639 { 640 AssertMsgFailed(("Object '%s' not complete yet\n", pCtx->mURI.objURI.GetDestPath().c_str())); 638 DnDURIObject *pObj = pObjCtx->pObjURI; 639 640 if ( pObj 641 && pObj->IsOpen() 642 && !pObj->IsComplete()) 643 { 644 AssertMsgFailed(("Object '%s' not complete yet\n", pObj->GetDestPath().c_str())); 641 645 rc = VERR_WRONG_ORDER; 642 646 break; 643 647 } 644 648 645 if (pCtx->mURI.objURI.IsOpen()) /* File already opened? */ 646 { 647 AssertMsgFailed(("Current opened object is '%s', close this first\n", pCtx->mURI.objURI.GetDestPath().c_str())); 649 if ( pObj 650 && pObj->IsOpen()) /* File already opened? */ 651 { 652 AssertMsgFailed(("Current opened object is '%s', close this first\n", pObj->GetDestPath().c_str())); 648 653 rc = VERR_WRONG_ORDER; 649 654 break; … … 674 679 LogFunc(("Rebased to: %s\n", pszPathAbs)); 675 680 676 /** @todo Add sparse file support based on fFlags? (Use Open(..., fFlags | SPARSE). */ 677 rc = pCtx->mURI.objURI.OpenEx(pszPathAbs, DnDURIObject::File, DnDURIObject::Target, 678 RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE, 679 (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR); 681 if ( pObj 682 && pObjCtx->fAllocated) 683 { 684 delete pObj; 685 pObj = NULL; 686 } 687 688 try 689 { 690 pObj = new DnDURIObject(); 691 692 pObjCtx->pObjURI = pObj; 693 pObjCtx->fAllocated = true; 694 } 695 catch (std::bad_alloc &) 696 { 697 rc = VERR_NO_MEMORY; 698 } 699 700 if (RT_SUCCESS(rc)) 701 { 702 /** @todo Add sparse file support based on fFlags? (Use Open(..., fFlags | SPARSE). */ 703 rc = pObj->OpenEx(pszPathAbs, DnDURIObject::File, DnDURIObject::Target, 704 RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE, 705 (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR); 706 } 707 680 708 if (RT_SUCCESS(rc)) 681 709 { 682 710 /* Note: Protocol v1 does not send any file sizes, so always 0. */ 683 711 if (mDataBase.mProtocolVersion >= 2) 684 rc = p Ctx->mURI.objURI.SetSize(cbSize);712 rc = pObj->SetSize(cbSize); 685 713 686 714 /** @todo Unescpae path before printing. */ 687 715 LogRel2(("DnD: Transferring guest file to host: %s (%RU64 bytes, mode 0x%x)\n", 688 p Ctx->mURI.objURI.GetDestPath().c_str(), pCtx->mURI.objURI.GetSize(), pCtx->mURI.objURI.GetMode()));716 pObj->GetDestPath().c_str(), pObj->GetSize(), pObj->GetMode())); 689 717 690 718 /** @todo Set progress object title to current file being transferred? */ 691 719 692 720 if (!cbSize) /* 0-byte file? Close again. */ 693 pCtx->mURI.objURI.Close(); 694 } 695 else 721 pObj->Close(); 722 } 723 724 if (RT_FAILURE(rc)) 696 725 { 697 726 LogRel2(("DnD: Error opening/creating guest file '%s' on host, rc=%Rrc\n", 698 p Ctx->mURI.objURI.GetDestPath().c_str(), rc));727 pObj->GetDestPath().c_str(), rc)); 699 728 break; 700 729 } … … 706 735 } 707 736 708 int GuestDnDSource::i_onReceiveFileData(PRECVDATACTX pCtx, const void *pvData, uint32_t cbData)737 int GuestDnDSource::i_onReceiveFileData(PRECVDATACTX pCtx, GuestDnDURIObjCtx *pObjCtx, const void *pvData, uint32_t cbData) 709 738 { 710 739 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 740 AssertPtrReturn(pObjCtx, VERR_INVALID_POINTER); 711 741 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 712 742 AssertReturn(cbData, VERR_INVALID_PARAMETER); … … 716 746 do 717 747 { 718 if (pCtx->mURI.objURI.IsComplete()) 719 { 720 LogFlowFunc(("Warning: Object '%s' already completed\n", pCtx->mURI.objURI.GetDestPath().c_str())); 748 DnDURIObject *pObj = pObjCtx->pObjURI; 749 if (!pObj) 750 { 751 rc = VERR_INVALID_PARAMETER; 752 break; 753 } 754 755 if (pObj->IsComplete()) 756 { 757 LogFlowFunc(("Warning: Object '%s' already completed\n", pObj->GetDestPath().c_str())); 721 758 rc = VERR_WRONG_ORDER; 722 759 break; 723 760 } 724 761 725 if (!p Ctx->mURI.objURI.IsOpen()) /* File opened on host? */726 { 727 LogFlowFunc(("Warning: Object '%s' not opened\n", p Ctx->mURI.objURI.GetDestPath().c_str()));762 if (!pObj->IsOpen()) /* File opened on host? */ 763 { 764 LogFlowFunc(("Warning: Object '%s' not opened\n", pObj->GetDestPath().c_str())); 728 765 rc = VERR_WRONG_ORDER; 729 766 break; … … 731 768 732 769 uint32_t cbWritten; 733 rc = p Ctx->mURI.objURI.Write(pvData, cbData, &cbWritten);770 rc = pObj->Write(pvData, cbData, &cbWritten); 734 771 if (RT_SUCCESS(rc)) 735 772 { … … 747 784 if (RT_SUCCESS(rc)) 748 785 { 749 if (p Ctx->mURI.objURI.IsComplete())786 if (pObj->IsComplete()) 750 787 { 751 788 /** @todo Sanitize path. */ 752 LogRel2(("DnD: File transfer to host complete: %s\n", p Ctx->mURI.objURI.GetDestPath().c_str()));789 LogRel2(("DnD: File transfer to host complete: %s\n", pObj->GetDestPath().c_str())); 753 790 rc = VINF_EOF; 754 791 755 /* Prepare URI object for next use. */ 756 pCtx->mURI.objURI.Reset(); 792 /* Deletion needed? */ 793 if (pObjCtx->fAllocated) 794 { 795 delete pObj; 796 pObj = NULL; 797 798 pObjCtx->fAllocated = false; 799 } 757 800 } 758 801 } … … 760 803 { 761 804 /** @todo What to do when the host's disk is full? */ 762 LogRel(("DnD: Error writing guest file to host to '%s': %Rrc\n", p Ctx->mURI.objURI.GetDestPath().c_str(), rc));805 LogRel(("DnD: Error writing guest file to host to '%s': %Rrc\n", pObj->GetDestPath().c_str(), rc)); 763 806 } 764 807 … … 1180 1223 AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_SND_FILE_HDR == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 1181 1224 1182 rc = pThis->i_onReceiveFileHdr(pCtx, pCBData->pszFilePath, pCBData->cbFilePath,1225 rc = pThis->i_onReceiveFileHdr(pCtx, &pCtx->mURI.objCtx, pCBData->pszFilePath, pCBData->cbFilePath, 1183 1226 pCBData->cbSize, pCBData->fMode, pCBData->fFlags); 1184 1227 break; … … 1200 1243 * appended data to the desired file. So just pass 0 as cbSize. 1201 1244 */ 1202 rc = pThis->i_onReceiveFileHdr(pCtx, 1245 rc = pThis->i_onReceiveFileHdr(pCtx, &pCtx->mURI.objCtx, 1203 1246 pCBData->u.v1.pszFilePath, pCBData->u.v1.cbFilePath, 1204 1247 0 /* cbSize */, pCBData->u.v1.fMode, 0 /* fFlags */); 1205 1248 if (RT_SUCCESS(rc)) 1206 rc = pThis->i_onReceiveFileData(pCtx, pCBData->pvData, pCBData->cbData);1249 rc = pThis->i_onReceiveFileData(pCtx, &pCtx->mURI.objCtx, pCBData->pvData, pCBData->cbData); 1207 1250 } 1208 1251 else /* Protocol v2 and up. */ 1209 rc = pThis->i_onReceiveFileData(pCtx, pCBData->pvData, pCBData->cbData);1252 rc = pThis->i_onReceiveFileData(pCtx, &pCtx->mURI.objCtx, pCBData->pvData, pCBData->cbData); 1210 1253 break; 1211 1254 } -
trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp
r57469 r57500 771 771 ASMAtomicWriteBool(&pCtx->mIsActive, false); 772 772 773 #undef DATA_IS_VALID_BREAK774 775 773 LogFlowFuncLeaveRC(rc); 776 774 return rc; 777 775 } 778 776 779 int GuestDnDTarget::i_sendDirectory(PSENDDATACTX pCtx, GuestDnDMsg *pMsg, DnDURIObject *pObject) 780 { 781 AssertPtrReturn(pObject, VERR_INVALID_POINTER); 777 int GuestDnDTarget::i_sendDirectory(PSENDDATACTX pCtx, GuestDnDURIObjCtx *pObjCtx, GuestDnDMsg *pMsg) 778 { 782 779 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 783 784 RTCString strPath = pObject->GetDestPath(); 780 AssertPtrReturn(pObjCtx, VERR_INVALID_POINTER); 781 AssertPtrReturn(pMsg, VERR_INVALID_POINTER); 782 783 DnDURIObject *pObj = pObjCtx->pObjURI; 784 AssertPtr(pObj); 785 786 RTCString strPath = pObj->GetDestPath(); 785 787 if (strPath.isEmpty()) 786 788 return VERR_INVALID_PARAMETER; … … 793 795 pMsg->setNextString(strPath.c_str()); /* path */ 794 796 pMsg->setNextUInt32((uint32_t)(strPath.length() + 1)); /* path length - note: Maximum is RTPATH_MAX on guest side. */ 795 pMsg->setNextUInt32(pObj ect->GetMode());/* mode */797 pMsg->setNextUInt32(pObj->GetMode()); /* mode */ 796 798 797 799 return VINF_SUCCESS; 798 800 } 799 801 800 int GuestDnDTarget::i_sendFile(PSENDDATACTX pCtx, GuestDnDMsg *pMsg, DnDURIObject *pObject) 801 { 802 AssertPtrReturn(pObject, VERR_INVALID_POINTER); 802 int GuestDnDTarget::i_sendFile(PSENDDATACTX pCtx, GuestDnDURIObjCtx *pObjCtx, GuestDnDMsg *pMsg) 803 { 803 804 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 804 805 RTCString strPathSrc = pObject->GetSourcePath(); 805 AssertPtrReturn(pObjCtx, VERR_INVALID_POINTER); 806 AssertPtrReturn(pMsg, VERR_INVALID_POINTER); 807 808 DnDURIObject *pObj = pObjCtx->pObjURI; 809 AssertPtr(pObj); 810 811 RTCString strPathSrc = pObj->GetSourcePath(); 806 812 if (strPathSrc.isEmpty()) 807 813 return VERR_INVALID_PARAMETER; … … 809 815 int rc = VINF_SUCCESS; 810 816 811 LogFlowFunc(("Sending \"%s\" (%RU32 bytes buffer)using protocol v%RU32 ...\n",812 strPathSrc.c_str(),mData.mcbBlockSize, mDataBase.mProtocolVersion));813 814 bool fOpen = pObject->IsOpen(); 815 if (! fOpen)816 { 817 Log FlowFunc(("Opening \"%s\" ...\n", strPathSrc.c_str()));818 rc = pObj ect->OpenEx(strPathSrc, DnDURIObject::File, DnDURIObject::Source,817 LogFlowFunc(("Sending file with %RU32 bytes buffer, using protocol v%RU32 ...\n", 818 mData.mcbBlockSize, mDataBase.mProtocolVersion)); 819 LogFlowFunc(("strPathSrc=%s, fIsOpen=%RTbool, cbSize=%RU64\n", strPathSrc.c_str(), pObj->IsOpen(), pObj->GetSize())); 820 821 if (!pObj->IsOpen()) 822 { 823 LogRel2(("DnD: Opening host file for transferring to guest: %s\n", strPathSrc.c_str())); 824 rc = pObj->OpenEx(strPathSrc, DnDURIObject::File, DnDURIObject::Source, 819 825 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE, 0 /* fFlags */); 820 826 if (RT_FAILURE(rc)) 821 LogRel(("DnD: Error opening host file \"%s\", rc=%Rrc\n", strPathSrc.c_str(), rc));822 } 823 824 bool fSend FileData = false;827 LogRel(("DnD: Error opening host file '%s', rc=%Rrc\n", strPathSrc.c_str(), rc)); 828 } 829 830 bool fSendData = false; 825 831 if (RT_SUCCESS(rc)) 826 832 { 827 833 if (mDataBase.mProtocolVersion >= 2) 828 834 { 829 if (! fOpen)835 if (!pObjCtx->fHeaderSent) 830 836 { 831 837 /* … … 835 841 */ 836 842 pMsg->setType(DragAndDropSvc::HOST_DND_HG_SND_FILE_HDR); 837 pMsg->setNextUInt32(0); /* contextID */838 rc = pMsg->setNextString(pObj ect->GetDestPath().c_str()); /* pvName */843 pMsg->setNextUInt32(0); /* uContextID */ 844 rc = pMsg->setNextString(pObj->GetDestPath().c_str()); /* pvName */ 839 845 AssertRC(rc); 840 pMsg->setNextUInt32((uint32_t)(pObj ect->GetDestPath().length() + 1)); /* cbName */846 pMsg->setNextUInt32((uint32_t)(pObj->GetDestPath().length() + 1)); /* cbName */ 841 847 pMsg->setNextUInt32(0); /* uFlags */ 842 pMsg->setNextUInt32(pObj ect->GetMode()); /* fMode */843 pMsg->setNextUInt64(pObj ect->GetSize()); /* uSize */848 pMsg->setNextUInt32(pObj->GetMode()); /* fMode */ 849 pMsg->setNextUInt64(pObj->GetSize()); /* uSize */ 844 850 845 851 LogFlowFunc(("Sending file header ...\n")); 846 852 LogRel2(("DnD: Transferring host file to guest: %s (%RU64 bytes, mode 0x%x)\n", 847 strPathSrc.c_str(), pObj ect->GetSize(), pObject->GetMode()));853 strPathSrc.c_str(), pObj->GetSize(), pObj->GetMode())); 848 854 849 855 /** @todo Set progress object title to current file being transferred? */ 856 857 pObjCtx->fHeaderSent = true; 850 858 } 851 859 else 852 860 { 853 861 /* File header was sent, so only send the actual file data. */ 854 fSend FileData = true;862 fSendData = true; 855 863 } 856 864 } … … 858 866 { 859 867 /* Always send the file data, every time. */ 860 fSend FileData = true;868 fSendData = true; 861 869 } 862 870 } 863 871 864 872 if ( RT_SUCCESS(rc) 865 && fSend FileData)866 { 867 rc = i_sendFileData(pCtx, p Msg, pObject);873 && fSendData) 874 { 875 rc = i_sendFileData(pCtx, pObjCtx, pMsg); 868 876 } 869 877 … … 872 880 } 873 881 874 int GuestDnDTarget::i_sendFileData(PSENDDATACTX pCtx, GuestDnDMsg *pMsg, DnDURIObject *pObject) 875 { 876 AssertPtrReturn(pObject, VERR_INVALID_POINTER); 882 int GuestDnDTarget::i_sendFileData(PSENDDATACTX pCtx, GuestDnDURIObjCtx *pObjCtx, GuestDnDMsg *pMsg) 883 { 877 884 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 885 AssertPtrReturn(pObjCtx, VERR_INVALID_POINTER); 878 886 AssertPtrReturn(pMsg, VERR_INVALID_POINTER); 887 888 DnDURIObject *pObj = pObjCtx->pObjURI; 889 AssertPtr(pObj); 879 890 880 891 GuestDnDResponse *pResp = pCtx->mpResp; … … 882 893 883 894 /** @todo Don't allow concurrent reads per context! */ 884 885 /* Something to transfer? */886 if ( pCtx->mURI.lstURI.IsEmpty()887 || !pCtx->mIsActive)888 {889 return VERR_WRONG_ORDER;890 }891 895 892 896 /* … … 901 905 if (mDataBase.mProtocolVersion <= 1) 902 906 { 903 pMsg->setNextString(pObj ect->GetDestPath().c_str()); /* pvName */904 pMsg->setNextUInt32((uint32_t)(pObj ect->GetDestPath().length() + 1)); /* cbName */907 pMsg->setNextString(pObj->GetDestPath().c_str()); /* pvName */ 908 pMsg->setNextUInt32((uint32_t)(pObj->GetDestPath().length() + 1)); /* cbName */ 905 909 } 906 910 else 907 911 { 908 912 /* Protocol version 2 also sends the context ID. Currently unused. */ 909 pMsg->setNextUInt32(0); 913 pMsg->setNextUInt32(0); /* context ID */ 910 914 } 911 915 912 916 uint32_t cbRead = 0; 913 917 914 int rc = pObj ect->Read(pCtx->mURI.GetBufferMutable(), pCtx->mURI.GetBufferSize(), &cbRead);918 int rc = pObj->Read(pCtx->mURI.GetBufferMutable(), pCtx->mURI.GetBufferSize(), &cbRead); 915 919 if (RT_SUCCESS(rc)) 916 920 { 917 921 pCtx->mData.cbProcessed += cbRead; 922 LogFlowFunc(("cbBufSize=%zu, cbRead=%RU32, cbProcessed=%RU64, rc=%Rrc\n", 923 pCtx->mURI.GetBufferSize(), cbRead, pCtx->mData.cbProcessed, rc)); 918 924 919 925 if (mDataBase.mProtocolVersion <= 1) 920 926 { 921 pMsg->setNextPointer(pCtx->mURI.GetBufferMutable(), cbRead); /* pvData */922 pMsg->setNextUInt32(cbRead); /* cbData */923 pMsg->setNextUInt32(pObj ect->GetMode());/* fMode */927 pMsg->setNextPointer(pCtx->mURI.GetBufferMutable(), cbRead); /* pvData */ 928 pMsg->setNextUInt32(cbRead); /* cbData */ 929 pMsg->setNextUInt32(pObj->GetMode()); /* fMode */ 924 930 } 925 931 else 926 932 { 927 pMsg->setNextPointer(pCtx->mURI.GetBufferMutable(), cbRead); /* pvData */ 928 pMsg->setNextUInt32(cbRead); /* cbData */ 929 } 930 931 if (pObject->IsComplete()) /* Done reading? */ 932 { 933 LogRel2(("DnD: File transfer to guest complete: %s\n", pObject->GetSourcePath().c_str())); 934 LogFlowFunc(("File \"%s\" complete\n", pObject->GetSourcePath().c_str())); 935 rc = VINF_EOF; 933 pMsg->setNextPointer(pCtx->mURI.GetBufferMutable(), cbRead); /* pvData */ 934 pMsg->setNextUInt32(cbRead); /* cbData */ 935 } 936 937 if (pObj->IsComplete()) /* Done reading? */ 938 { 939 LogRel2(("DnD: File transfer to guest complete: %s\n", pObj->GetSourcePath().c_str())); 940 LogFlowFunc(("File '%s' complete\n", pObj->GetSourcePath().c_str())); 941 942 /* DnDURIObject::Read() returns VINF_EOF when finished reading the entire fire, 943 * but we don't want this here -- so just override this with VINF_SUCCESS. */ 944 rc = VINF_SUCCESS; 936 945 } 937 946 } … … 952 961 LogFlowFunc(("pThis=%p, uMsg=%RU32\n", pThis, uMsg)); 953 962 954 int rc = VINF_SUCCESS; /* Will be reported back to guest. */ 955 956 int rcCallback = VINF_SUCCESS; /* rc for the callback. */ 963 int rc = VINF_SUCCESS; /* Will be reported back to guest. */ 964 int rcGuest; /* Contains error code from guest in case of VERR_GSTDND_GUEST_ERROR. */ 957 965 bool fNotify = false; 958 966 … … 971 979 972 980 rc = pThis->i_sendURIDataLoop(pCtx, pMsg); 973 if (RT_SUCCESS(rc)) 981 if (rc == VINF_EOF) /* Transfer complete? */ 982 { 983 LogFlowFunc(("Last URI item processed, bailing out\n")); 984 } 985 else if (RT_SUCCESS(rc)) 974 986 { 975 987 rc = pThis->msgQueueAdd(pMsg); … … 982 994 } 983 995 984 if (RT_FAILURE(rc)) 996 if ( RT_FAILURE(rc) 997 || rc == VINF_EOF) /* Transfer complete? */ 998 { 985 999 delete pMsg; 1000 pMsg = NULL; 1001 } 986 1002 } 987 1003 catch(std::bad_alloc & /*e*/) … … 1001 1017 1002 1018 if (RT_SUCCESS(pCBData->rc)) 1019 { 1020 AssertMsgFailed(("Guest has sent an error event but did not specify an actual error code\n")); 1003 1021 pCBData->rc = VERR_GENERAL_FAILURE; /* Make sure some error is set. */ 1022 } 1004 1023 1005 1024 rc = pCtx->mpResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc, 1006 1025 GuestDnDTarget::i_guestErrorToString(pCBData->rc)); 1007 1026 if (RT_SUCCESS(rc)) 1008 rcCallback = VERR_GSTDND_GUEST_ERROR; 1027 { 1028 rc = VERR_GSTDND_GUEST_ERROR; 1029 rcGuest = pCBData->rc; 1030 } 1009 1031 break; 1010 1032 } … … 1061 1083 } 1062 1084 1063 if ( RT_FAILURE(rc) 1064 || RT_FAILURE(rcCallback)) 1065 { 1066 fNotify = true; 1067 if (RT_SUCCESS(rcCallback)) 1068 rcCallback = rc; 1085 int rcToGuest = VINF_SUCCESS; /* Status which will be sent back to the guest. */ 1086 1087 /* 1088 * Resolve errors. 1089 */ 1090 switch (rc) 1091 { 1092 case VINF_SUCCESS: 1093 break; 1094 1095 case VINF_EOF: 1096 { 1097 LogRel2(("DnD: Transfer to guest complete\n")); 1098 1099 /* Complete operation on host side. */ 1100 fNotify = true; 1101 1102 /* The guest expects VERR_NO_DATA if the transfer is complete. */ 1103 rcToGuest = VERR_NO_DATA; 1104 break; 1105 } 1106 1107 case VERR_GSTDND_GUEST_ERROR: 1108 { 1109 LogRel(("DnD: Guest reported error %Rrc, aborting transfer to guest\n", rcGuest)); 1110 break; 1111 } 1112 1113 case VERR_CANCELLED: 1114 { 1115 LogRel2(("DnD: Transfer to guest canceled\n")); 1116 rcToGuest = VERR_CANCELLED; /* Also cancel on guest side. */ 1117 break; 1118 } 1119 1120 default: 1121 { 1122 LogRel(("DnD: Host error %Rrc occurred, aborting transfer to guest\n", rc)); 1123 rcToGuest = VERR_CANCELLED; /* Also cancel on guest side. */ 1124 break; 1125 } 1069 1126 } 1070 1127 1071 1128 if (RT_FAILURE(rc)) 1072 1129 { 1073 switch (rc)1074 {1075 case VERR_NO_DATA:1076 LogRel2(("DnD: Transfer to guest complete\n"));1077 break;1078 1079 case VERR_CANCELLED:1080 LogRel2(("DnD: Transfer to guest canceled\n"));1081 break;1082 1083 default:1084 LogRel(("DnD: Error %Rrc occurred, aborting transfer to guest\n", rc));1085 break;1086 }1087 1088 1130 /* Unregister this callback. */ 1089 1131 AssertPtr(pCtx->mpResp); 1090 1132 int rc2 = pCtx->mpResp->setCallback(uMsg, NULL /* PFNGUESTDNDCALLBACK */); 1091 1133 AssertRC(rc2); 1092 } 1093 1094 LogFlowFunc(("fNotify=%RTbool, rcCallback=%Rrc, rc=%Rrc\n", fNotify, rcCallback, rc)); 1134 1135 /* Let the waiter(s) know. */ 1136 fNotify = true; 1137 } 1138 1139 LogFlowFunc(("fNotify=%RTbool, rc=%Rrc, rcToGuest=%Rrc\n", fNotify, rc, rcToGuest)); 1095 1140 1096 1141 if (fNotify) 1097 1142 { 1098 int rc2 = pCtx->mCallback.Notify(rc Callback);1143 int rc2 = pCtx->mCallback.Notify(rc); /** @todo Also pass guest error back? */ 1099 1144 AssertRC(rc2); 1100 1145 } 1101 1146 1102 1147 LogFlowFuncLeaveRC(rc); 1103 return rc ; /* Tell the guest. */1148 return rcToGuest; /* Tell the guest. */ 1104 1149 } 1105 1150 … … 1164 1209 URI_DATA_IS_VALID_BREAK(!lstURIOrg.isEmpty()); 1165 1210 1166 uint32_t fFlags = DNDURILIST_FLAGS_KEEP_OPEN;1167 1168 rc = lstURI.AppendURIPathsFromList(lstURIOrg, fFlags);1211 /* Note: All files to be transferred will be kept open during the entire DnD 1212 * operation, also to keep the accounting right. */ 1213 rc = lstURI.AppendURIPathsFromList(lstURIOrg, DNDURILIST_FLAGS_KEEP_OPEN); 1169 1214 if (RT_SUCCESS(rc)) 1170 1215 LogFlowFunc(("URI root objects: %zu, total bytes (raw data to transfer): %zu\n", … … 1267 1312 1268 1313 if (fComplete) 1269 { 1270 LogFlowFunc(("Last URI item processed, bailing out\n")); 1271 return VERR_NO_DATA; 1272 } 1314 return VINF_EOF; 1273 1315 1274 1316 Assert(!lstURI.IsEmpty()); 1275 1317 DnDURIObject *pCurObj = lstURI.First(); 1318 1319 /* As we transfer all objects one after another at a time at the moment, 1320 * we only need one object context at the moment. */ 1321 GuestDnDURIObjCtx *pObjCtx = &pCtx->mURI.objCtx; 1322 1323 /* Assign the pointer of the current object to our context. */ 1324 pObjCtx->pObjURI = pCurObj; 1276 1325 1277 1326 uint32_t fMode = pCurObj->GetMode(); … … 1283 1332 if (RTFS_IS_DIRECTORY(fMode)) 1284 1333 { 1285 rc = i_sendDirectory(pCtx, p Msg, pCurObj);1334 rc = i_sendDirectory(pCtx, pObjCtx, pMsg); 1286 1335 } 1287 1336 else if (RTFS_IS_FILE(fMode)) 1288 1337 { 1289 rc = i_sendFile(pCtx, p Msg, pCurObj);1338 rc = i_sendFile(pCtx, pObjCtx, pMsg); 1290 1339 } 1291 1340 else
Note:
See TracChangeset
for help on using the changeset viewer.