Changeset 50308 in vbox for trunk/src/VBox/HostServices
- Timestamp:
- Feb 3, 2014 2:20:52 PM (11 years ago)
- Location:
- trunk/src/VBox/HostServices/DragAndDrop
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/DragAndDrop/dndmanager.cpp
r49891 r50308 137 137 ******************************************************************************/ 138 138 139 DnDHGSendFilePrivate::DnDHGSendFilePrivate(const RTCString &strHostPath, const RTCString &strGuestPath, uint32_t fMode, uint64_t cbSize, PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser) 140 : m_strHostPath(strHostPath) 141 , m_strGuestPath(strGuestPath) 142 , m_cbFileSize(cbSize) 143 , m_cbFileProcessed(0) 144 , m_hCurFile(0) 145 , m_pfnProgressCallback(pfnProgressCallback) 146 , m_pvProgressUser(pvProgressUser) 139 DnDHGSendFilePrivate::DnDHGSendFilePrivate(const RTCString &strHostPath, const RTCString &strGuestPath, 140 uint32_t fMode, uint64_t cbSize, 141 PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser) 142 : m_strHostPath(strHostPath) 143 , m_strGuestPath(strGuestPath) 144 , m_cbFileSize(cbSize) 145 , m_cbFileProcessed(0) 146 , m_hCurFile(0) 147 , m_pfnProgressCallback(pfnProgressCallback) 148 , m_pvProgressUser(pvProgressUser) 147 149 { 148 150 m_paSkelParms[0].setString(m_strGuestPath.c_str()); … … 155 157 } 156 158 157 DnDHGSendFilePrivate::~DnDHGSendFilePrivate( )159 DnDHGSendFilePrivate::~DnDHGSendFilePrivate(void) 158 160 { 159 161 if (m_hCurFile) … … 161 163 } 162 164 163 int DnDHGSendFilePrivate::currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 165 int DnDHGSendFilePrivate::currentMessage(uint32_t uMsg, uint32_t cParms, 166 VBOXHGCMSVCPARM paParms[]) 164 167 { 165 168 if (!m_pNextMsg) … … 220 223 if ( RT_SUCCESS(rc) 221 224 && m_pfnProgressCallback) 225 { 222 226 rc = m_pfnProgressCallback(cbRead, m_pvProgressUser); 227 } 223 228 224 229 if ( fDone … … 237 242 ******************************************************************************/ 238 243 239 DnDHGSendDataMessagePrivate::DnDHGSendDataMessagePrivate(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[], PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser) 240 : m_cbSize(paParms[4].u.uint32) 241 , m_cbDone(0) 242 , m_pfnProgressCallback(pfnProgressCallback) 243 , m_pvProgressUser(pvProgressUser) 244 { 245 /* Create the initial data message. */ 244 DnDHGSendDataMessagePrivate::DnDHGSendDataMessagePrivate(uint32_t uMsg, uint32_t cParms, 245 VBOXHGCMSVCPARM paParms[], 246 PFNDNDPRIVATEPROGRESS pfnProgressCallback, 247 void *pvProgressUser) 248 : m_cbSize(paParms[4].u.uint32) 249 , m_cbDone(0) 250 , m_pfnProgressCallback(pfnProgressCallback) 251 , m_pvProgressUser(pvProgressUser) 252 { 253 /* Create the initial data message. This might throw 254 * a bad_alloc exception. */ 246 255 m_pNextMsg = new HGCM::Message(uMsg, cParms, paParms); 247 256 } 248 257 249 int DnDHGSendDataMessagePrivate::currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 250 { 251 /* Todo: don't copy the data parts ... just move the data pointer in 252 * the original data ptr. */ 258 int DnDHGSendDataMessagePrivate::currentMessage(uint32_t uMsg, uint32_t cParms, 259 VBOXHGCMSVCPARM paParms[]) 260 { 261 /** @todo Don't copy the data parts ... just move the data pointer in 262 * the original data ptr. */ 253 263 if (!m_pNextMsg) 254 264 return VERR_NO_DATA; … … 261 271 m_pNextMsg = 0; 262 272 rc = pCurMsg->getData(uMsg, cParms, paParms); 273 263 274 /* Depending on the current message, the data pointer is on a 264 275 * different position (HOST_DND_HG_SND_DATA=3; … … 266 277 int iPos = uMsg == DragAndDropSvc::HOST_DND_HG_SND_DATA ? 3 : 0; 267 278 m_cbDone += paParms[iPos + 1].u.uint32; 268 /* Info & data send already? */ 279 280 /* Info + data send already? */ 269 281 if (rc == VERR_BUFFER_OVERFLOW) 270 282 { … … 287 299 } 288 300 289 delete pCurMsg; 290 291 /* Advance progress info */ 301 if (pCurMsg) 302 delete pCurMsg; 303 304 /* Advance progress info. */ 292 305 if ( RT_SUCCESS(rc) 293 306 && m_pfnProgressCallback) 307 { 294 308 rc = m_pfnProgressCallback(m_cbDone, m_pvProgressUser); 309 } 295 310 296 311 return rc; … … 303 318 /* 304 319 * This class is a meta message class. It doesn't consist of any own message 305 * data, but handle the meta info, the data itself as well a ny files or320 * data, but handle the meta info, the data itself as well as any files or 306 321 * directories which have to be transfered to the guest. 307 322 */ 308 DnDHGSendDataMessage::DnDHGSendDataMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[], PFNDNDPROGRESS pfnProgressCallback, void *pvProgressUser) 323 DnDHGSendDataMessage::DnDHGSendDataMessage(uint32_t uMsg, uint32_t cParms, 324 VBOXHGCMSVCPARM paParms[], 325 PFNDNDPROGRESS pfnProgressCallback, 326 void *pvProgressUser) 309 327 : m_cbAll(0) 310 328 , m_cbTransfered(0) … … 312 330 , m_pvProgressUser(pvProgressUser) 313 331 { 314 RTCString strNewUris; 332 RTCString strNewURIs; 333 315 334 /* Check the format for any uri type. */ 316 if (hasFileUrls(static_cast<const char*>(paParms[1].u.pointer.addr), paParms[1].u.pointer.size)) 335 if (hasFileUrls(static_cast<const char*>(paParms[1].u.pointer.addr), 336 paParms[1].u.pointer.size)) 317 337 { 318 338 LogFlowFunc(("Old data: '%s'\n", (char*)paParms[3].u.pointer.addr)); 319 /* The list is separated by newline (Even if only one file is 320 * listed). */ 321 RTCList<RTCString> oldUriList = RTCString(static_cast<const char*>(paParms[3].u.pointer.addr), 322 paParms[3].u.pointer.size).split("\r\n"); 323 if (!oldUriList.isEmpty()) 324 { 325 RTCList<RTCString> newUriList; 326 for (size_t i = 0; i < oldUriList.size(); ++i) 327 { 328 const RTCString &strUri = oldUriList.at(i); 339 340 /* The list is separated by newline (even if only one file is listed). */ 341 RTCList<RTCString> lstURIOrg = RTCString(static_cast<const char*>(paParms[3].u.pointer.addr), 342 paParms[3].u.pointer.size).split("\r\n"); 343 if (!lstURIOrg.isEmpty()) 344 { 345 RTCList<RTCString> lstURINew; 346 for (size_t i = 0; i < lstURIOrg.size(); ++i) 347 { 348 const RTCString &strURI = lstURIOrg.at(i); 349 329 350 /* Query the path component of a file URI. If this hasn't a 330 * file scheme null is returned. */ 331 if (char *pszFilePath = RTUriFilePath(strUri.c_str(), URI_FILE_FORMAT_AUTO)) 351 * file scheme NULL is returned. */ 352 char *pszFilePath; 353 if (pszFilePath = RTUriFilePath(strURI.c_str(), URI_FILE_FORMAT_AUTO)) 332 354 { 333 355 /* Add the path to our internal file list (recursive in 334 356 * the case of a directory). */ 335 if (char *pszFilename = RTPathFilename(pszFilePath)) 357 char *pszFilename; 358 if (pszFilename = RTPathFilename(pszFilePath)) 336 359 { 337 char *pszNewU ri= RTUriFileCreate(pszFilename);338 if (pszNewU ri)360 char *pszNewURI = RTUriFileCreate(pszFilename); 361 if (pszNewURI) 339 362 { 340 newUriList.append(pszNewUri); 341 RTStrFree(pszNewUri); 363 lstURINew.append(pszNewURI); 364 RTStrFree(pszNewURI); 365 342 366 buildFileTree(pszFilePath, pszFilename - pszFilePath); 343 367 } 344 368 } 369 345 370 RTStrFree(pszFilePath); 346 371 } 347 else 348 newUriList.append(strUri); 349 } 372 else /* Just append the raw data. */ 373 lstURINew.append(strURI); 374 } 375 350 376 /* We have to change the actual DnD data. Remove any host paths and 351 377 * just decode the filename into the new data. The guest tools will 352 378 * add the correct path again, before sending the DnD drop event to 353 379 * some window. */ 354 strNewUris = RTCString::join(newUriList, "\r\n") + "\r\n"; 355 /* Remark: We don't delete the old pointer here, cause this is done 356 * by the caller. We just use the RTString data, which has the 357 * scope of this ctor. This is enough cause the data is copied in 358 * the DnDHGSendDataMessagePrivate anyway. */ 359 paParms[3].u.pointer.addr = (void*)strNewUris.c_str(); 360 paParms[3].u.pointer.size = strNewUris.length() + 1; 361 paParms[4].u.uint32 = strNewUris.length() + 1; 362 } 363 } 380 strNewURIs = RTCString::join(lstURINew, "\r\n") + "\r\n"; 381 382 /* Note: We don't delete the old pointer here, cause this is done 383 * by the caller. We just use the RTString data, which has the 384 * scope of this ctor. This is enough cause the data is copied in 385 * the DnDHGSendDataMessagePrivate anyway. */ 386 paParms[3].u.pointer.addr = (void*)strNewURIs.c_str(); 387 paParms[3].u.pointer.size = strNewURIs.length() + 1; 388 paParms[4].u.uint32 = strNewURIs.length() + 1; 389 } 390 } 391 364 392 /* Add the size of the data to the todo list. */ 365 393 m_cbAll += paParms[4].u.uint32; 394 366 395 /* The first message is the meta info for the data and the data itself. */ 367 396 m_pNextPathMsg = new DnDHGSendDataMessagePrivate(uMsg, cParms, paParms, 368 397 &DnDHGSendDataMessage::progressCallback, this); 369 398 #ifdef DEBUG 370 399 LogFlowFunc(("new data '%s'\n", (char*)paParms[3].u.pointer.addr)); 371 400 LogFlowFunc(("cbAll: %zu\n", m_cbAll)); … … 376 405 m_uriList.at(i).m_strHostPath.c_str(), m_uriList.at(i).m_strGuestPath.c_str(), 377 406 m_uriList.at(i).m_fMode, m_uriList.at(i).m_cbSize)); 378 } 379 380 DnDHGSendDataMessage::~DnDHGSendDataMessage() 407 #endif 408 } 409 410 DnDHGSendDataMessage::~DnDHGSendDataMessage(void) 381 411 { 382 412 if (m_pNextPathMsg) … … 384 414 } 385 415 386 HGCM::Message* DnDHGSendDataMessage::nextHGCMMessage( )416 HGCM::Message* DnDHGSendDataMessage::nextHGCMMessage(void) 387 417 { 388 418 if (!m_pNextPathMsg) … … 450 480 { 451 481 LogFlowFunc(("format %s\n", pcszFormat)); 482 452 483 /** @todo text/uri also an official variant? */ 453 return RTStrNICmp(pcszFormat, "text/uri-list", cbMax) == 0454 || RTStrNICmp(pcszFormat, "x-special/gnome-icon-list", cbMax) == 0;484 return ( RTStrNICmp(pcszFormat, "text/uri-list", cbMax) == 0 485 || RTStrNICmp(pcszFormat, "x-special/gnome-icon-list", cbMax) == 0); 455 486 } 456 487 … … 462 493 return rc; 463 494 464 /* These are the types we currently support. Symlinks are not directly 495 /* 496 * These are the types we currently support. Symlinks are not directly 465 497 * supported. First the guest could be an OS which doesn't support it and 466 498 * second the symlink could point to a file which is out of the base tree. 467 499 * Both things are hard to support. For now we just copy the target file in 468 * this case. */ 500 * this case. 501 */ 469 502 if (!( RTFS_IS_DIRECTORY(objInfo.Attr.fMode) 470 503 || RTFS_IS_FILE(objInfo.Attr.fMode) … … 476 509 if (rc == VERR_IS_A_DIRECTORY) 477 510 rc = VINF_SUCCESS; 511 478 512 if (RT_FAILURE(rc)) 479 513 return rc; 514 480 515 m_uriList.append(PathEntry(pcszPath, &pcszPath[cbBaseLen], objInfo.Attr.fMode, cbSize)); 481 516 m_cbAll += cbSize; … … 523 558 case RTDIRENTRYTYPE_FILE: 524 559 { 525 if (char *pszNewFile = RTStrAPrintf2("%s%c%s", pcszPath, RTPATH_DELIMITER, DirEntry.szName)) 560 char *pszNewFile; 561 if (pszNewFile = RTStrAPrintf2("%s%c%s", pcszPath, RTPATH_DELIMITER, DirEntry.szName)) 526 562 { 527 563 /* We need the size and the mode of the file. */ … … 533 569 if (RT_FAILURE(rc)) 534 570 break; 535 m_uriList.append(PathEntry(pszNewFile, &pszNewFile[cbBaseLen], objInfo1.Attr.fMode, cbSize)); 571 572 m_uriList.append(PathEntry(pszNewFile, &pszNewFile[cbBaseLen], 573 objInfo1.Attr.fMode, cbSize)); 536 574 m_cbAll += cbSize; 575 537 576 RTStrFree(pszNewFile); 538 577 } … … 541 580 break; 542 581 } 543 default: break; 544 } 545 } 582 583 default: 584 break; 585 } 586 } 587 546 588 RTDirClose(hDir); 547 589 … … 554 596 555 597 DnDHGSendDataMessage *pSelf = static_cast<DnDHGSendDataMessage *>(pvUser); 598 AssertPtr(pSelf); 556 599 557 600 /* How many bytes are transfered already. */ … … 562 605 if ( pSelf->m_pfnProgressCallback 563 606 && pSelf->m_cbAll) 607 { 564 608 rc = pSelf->m_pfnProgressCallback((uint64_t)pSelf->m_cbTransfered * 100 / pSelf->m_cbAll, 565 DragAndDropSvc::DND_PROGRESS_RUNNING, VINF_SUCCESS /* rc */, pSelf->m_pvProgressUser); 609 DragAndDropSvc::DND_PROGRESS_RUNNING, 610 VINF_SUCCESS /* rc */, pSelf->m_pvProgressUser); 611 } 566 612 567 613 return rc; … … 603 649 break; 604 650 } 651 605 652 case DragAndDropSvc::HOST_DND_HG_EVT_MOVE: 606 653 { … … 616 663 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR /* data */ 617 664 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */) 665 { 618 666 rc = VERR_INVALID_PARAMETER; 667 } 619 668 else 620 669 { … … 625 674 break; 626 675 } 676 627 677 case DragAndDropSvc::HOST_DND_HG_EVT_LEAVE: 628 678 { … … 637 687 m_dndMessageQueue.append(pMessage); 638 688 } 689 639 690 m_fOpInProcess = false; 640 691 break; 641 692 } 693 642 694 case DragAndDropSvc::HOST_DND_HG_EVT_DROPPED: 643 695 { … … 653 705 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR /* data */ 654 706 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */) 707 { 655 708 rc = VERR_INVALID_PARAMETER; 709 } 656 710 else 657 711 { … … 661 715 break; 662 716 } 717 663 718 case DragAndDropSvc::HOST_DND_HG_SND_DATA: 664 719 { … … 672 727 || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR /* data */ 673 728 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* data size */) 729 { 674 730 rc = VERR_INVALID_PARAMETER; 731 } 675 732 else 676 733 { 677 DnDHGSendDataMessage *pMessage = new DnDHGSendDataMessage(uMsg, cParms, paParms, m_pfnProgressCallback, m_pvProgressUser); 734 DnDHGSendDataMessage *pMessage = 735 new DnDHGSendDataMessage(uMsg, cParms, paParms, 736 m_pfnProgressCallback, m_pvProgressUser); 678 737 m_dndMessageQueue.append(pMessage); 679 738 } 680 739 break; 681 740 } 682 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 741 742 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 683 743 case DragAndDropSvc::HOST_DND_GH_REQ_PENDING: 684 744 { … … 688 748 if ( cParms != 1 689 749 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */) 750 { 690 751 rc = VERR_INVALID_PARAMETER; 752 } 691 753 else 692 754 { … … 696 758 break; 697 759 } 760 698 761 case DragAndDropSvc::HOST_DND_GH_EVT_DROPPED: 699 762 { … … 705 768 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* format size */ 706 769 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* action */) 770 { 707 771 rc = VERR_INVALID_PARAMETER; 772 } 708 773 else 709 774 { … … 721 786 break; 722 787 } 723 #endif 788 #endif /* VBOX_WITH_DRAG_AND_DROP_GH */ 789 724 790 default: 725 791 rc = VERR_NOT_IMPLEMENTED; … … 735 801 } 736 802 737 HGCM::Message* DnDManager::nextHGCMMessage( )803 HGCM::Message* DnDManager::nextHGCMMessage(void) 738 804 { 739 805 if (m_pCurMsg) 740 806 return m_pCurMsg->nextHGCMMessage(); 741 else 742 { 743 if (m_dndMessageQueue.isEmpty()) 744 return 0; 745 746 return m_dndMessageQueue.first()->nextHGCMMessage(); 747 } 807 808 if (m_dndMessageQueue.isEmpty()) 809 return NULL; 810 811 return m_dndMessageQueue.first()->nextHGCMMessage(); 748 812 } 749 813 … … 832 896 } 833 897 834 void DnDManager::clear( )898 void DnDManager::clear(void) 835 899 { 836 900 if (m_pCurMsg) … … 839 903 m_pCurMsg = 0; 840 904 } 905 841 906 while (!m_dndMessageQueue.isEmpty()) 842 907 { -
trunk/src/VBox/HostServices/DragAndDrop/dndmanager.h
r49891 r50308 105 105 { 106 106 public: 107 107 108 DnDHGSendDataMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[], PFNDNDPROGRESS pfnProgressCallback, void *pvProgressUser); 108 ~DnDHGSendDataMessage();109 110 HGCM::Message* nextHGCMMessage( );109 virtual ~DnDHGSendDataMessage(void); 110 111 HGCM::Message* nextHGCMMessage(void); 111 112 int currentMessageInfo(uint32_t *puMsg, uint32_t *pcParms); 112 113 int currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 113 114 114 bool isMessageWaiting( ) const { return !!m_pNextPathMsg; }115 bool isMessageWaiting(void) const { return !!m_pNextPathMsg; } 115 116 116 117 protected: 118 117 119 struct PathEntry 118 120 { 119 121 PathEntry(const RTCString &strHostPath, const RTCString &strGuestPath, uint32_t fMode, uint64_t cbSize) 120 : m_strHostPath(strHostPath)121 , m_strGuestPath(strGuestPath)122 , m_fMode(fMode)123 , m_cbSize(cbSize) {}122 : m_strHostPath(strHostPath) 123 , m_strGuestPath(strGuestPath) 124 , m_fMode(fMode) 125 , m_cbSize(cbSize) {} 124 126 RTCString m_strHostPath; 125 127 RTCString m_strGuestPath; … … 135 137 DnDMessage *m_pNextPathMsg; 136 138 137 /* Progress stuff*/139 /* Total size (in bytes). */ 138 140 size_t m_cbAll; 141 /* Transferred size (in bytes). */ 139 142 size_t m_cbTransfered; 140 143 PFNDNDPROGRESS m_pfnProgressCallback; -
trunk/src/VBox/HostServices/DragAndDrop/service.cpp
r50265 r50308 208 208 && modeGet() != VBOX_DRAG_AND_DROP_MODE_HOST_TO_GUEST) 209 209 { 210 LogFlowFunc((" => ignoring!\n"));210 LogFlowFunc(("Wrong DnD mode, ignoring request\n")); 211 211 break; 212 212 } … … 232 232 && modeGet() != VBOX_DRAG_AND_DROP_MODE_HOST_TO_GUEST) 233 233 { 234 LogFlowFunc((" => ignoring!\n"));234 LogFlowFunc(("Wrong DnD mode, ignoring request\n")); 235 235 break; 236 236 } … … 262 262 && modeGet() != VBOX_DRAG_AND_DROP_MODE_GUEST_TO_HOST) 263 263 { 264 LogFlowFunc((" => ignoring!\n"));264 LogFlowFunc(("Wrong DnD mode, ignoring request\n")); 265 265 break; 266 266 } … … 290 290 && modeGet() != VBOX_DRAG_AND_DROP_MODE_GUEST_TO_HOST) 291 291 { 292 LogFlowFunc((" => ignoring\n"));292 LogFlowFunc(("Wrong DnD mode, ignoring request\n")); 293 293 break; 294 294 } … … 315 315 && modeGet() != VBOX_DRAG_AND_DROP_MODE_GUEST_TO_HOST) 316 316 { 317 LogFlowFunc((" => ignoring!\n"));317 LogFlowFunc(("Wrong DnD mode, ignoring request\n")); 318 318 break; 319 319 }
Note:
See TracChangeset
for help on using the changeset viewer.