Changeset 55640 in vbox
- Timestamp:
- May 4, 2015 12:38:57 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
-
include/VBox/GuestHost/DragAndDrop.h (modified) (7 diffs)
-
src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp (modified) (9 diffs)
-
src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp (modified) (1 diff)
-
src/VBox/GuestHost/DragAndDrop/DnDDir.cpp (modified) (4 diffs)
-
src/VBox/GuestHost/DragAndDrop/DnDURIList.cpp (modified) (5 diffs)
-
src/VBox/GuestHost/DragAndDrop/DnDURIObject.cpp (modified) (9 diffs)
-
src/VBox/HostServices/DragAndDrop/service.cpp (modified) (1 diff)
-
src/VBox/Main/include/GuestDnDPrivate.h (modified) (2 diffs)
-
src/VBox/Main/src-client/GuestDnDPrivate.cpp (modified) (1 diff)
-
src/VBox/Main/src-client/GuestDnDSourceImpl.cpp (modified) (9 diffs)
-
src/VBox/Main/src-client/GuestDnDTargetImpl.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/GuestHost/DragAndDrop.h
r55556 r55640 5 5 6 6 /* 7 * Copyright (C) 2014 Oracle Corporation7 * Copyright (C) 2014-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 30 30 #include <iprt/assert.h> 31 31 #include <iprt/cdefs.h> 32 #include <iprt/dir.h> 32 33 #include <iprt/err.h> 33 34 #include <iprt/file.h> … … 37 38 #include <iprt/cpp/ministring.h> 38 39 39 int DnDDirCreateDroppedFilesEx(const char *pszPath, char *pszDropDir, size_t cbDropDir); 40 int DnDDirCreateDroppedFiles(char *pszDropDir, size_t cbDropDir); 40 /** 41 * Structure for maintaining a "dropped files" directory 42 * on the host or guest. This will contain all received files & directories 43 * for a single transfer. 44 */ 45 typedef struct DNDDIRDROPPEDFILES 46 { 47 /** Directory handle for drop directory. */ 48 PRTDIR hDir; 49 /** Absolute path to drop directory. */ 50 RTCString strPathAbs; 51 /** List for holding created directories in the case of a rollback. */ 52 RTCList<RTCString> lstDirs; 53 /** List for holding created files in the case of a rollback. */ 54 RTCList<RTCString> lstFiles; 55 56 } DNDDIRDROPPEDFILES, *PDNDDIRDROPPEDFILES; 57 58 int DnDDirDroppedAddFile(PDNDDIRDROPPEDFILES pDir, const char *pszFile); 59 int DnDDirDroppedAddDir(PDNDDIRDROPPEDFILES pDir, const char *pszDir); 60 int DnDDirDroppedFilesCreateAndOpenEx(const char *pszPath, PDNDDIRDROPPEDFILES pDir); 61 int DnDDirDroppedFilesCreateAndOpenTemp(PDNDDIRDROPPEDFILES pDir); 62 int DnDDirDroppedFilesClose(PDNDDIRDROPPEDFILES pDir, bool fRemove); 63 const char *DnDDirDroppedFilesGetDirAbs(PDNDDIRDROPPEDFILES pDir); 64 int DnDDirDroppedFilesRollback(PDNDDIRDROPPEDFILES pDir); 41 65 42 66 bool DnDMIMEHasFileURLs(const char *pcszFormat, size_t cchFormatMax); … … 77 101 const RTCString &GetSourcePath(void) const { return m_strSrcPath; } 78 102 const RTCString &GetDestPath(void) const { return m_strTgtPath; } 79 uint32_t GetMode(void) const { return m_f CreationMode; }103 uint32_t GetMode(void) const { return m_fMode; } 80 104 uint64_t GetProcessed(void) const { return m_cbProcessed; } 81 105 uint64_t GetSize(void) const { return m_cbSize; } … … 91 115 bool IsComplete(void) const; 92 116 bool IsOpen(void) const; 93 int Open(Dest enmDest, uint64_t fOpen );94 int OpenEx(const RTCString &strPath, Type enmType, Dest enmDest, uint64_t f Mode = 0, uint32_t fFlags = 0);117 int Open(Dest enmDest, uint64_t fOpen, uint32_t fMode = 0); 118 int OpenEx(const RTCString &strPath, Type enmType, Dest enmDest, uint64_t fOpen = 0, uint32_t fMode = 0, uint32_t fFlags = 0); 95 119 int Read(void *pvBuf, size_t cbBuf, uint32_t *pcbRead); 96 120 void Reset(void); … … 110 134 RTCString m_strSrcPath; 111 135 RTCString m_strTgtPath; 112 /** File creationmode. */113 uint32_t m_f CreationMode;136 /** Object (file/directory) mode. */ 137 uint32_t m_fMode; 114 138 /** Size (in bytes) to read/write. */ 115 139 uint64_t m_cbSize; … … 144 168 void RemoveFirst(void); 145 169 int RootFromURIData(const void *pvData, size_t cbData, uint32_t fFlags); 146 RTCString RootToString(const RTCString &str BasePath= "", const RTCString &strSeparator = "\r\n");170 RTCString RootToString(const RTCString &strPathBase = "", const RTCString &strSeparator = "\r\n"); 147 171 size_t RootCount(void) { return m_lstRoot.size(); } 148 172 uint32_t TotalCount(void) { return m_cTotal; } -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp
r55571 r55640 372 372 void *pvTmpData = RTMemAlloc(cbTmpData); 373 373 if (!pvTmpData) 374 rc = VERR_NO_MEMORY; 375 376 /* Create and query the (unique) drop target directory. */ 374 return VERR_NO_MEMORY; 375 376 /* Create and query the (unique) drop target directory in the user's temporary directory. */ 377 DNDDIRDROPPEDFILES dirDroppedFiles; 378 const char *pszDropDir; 379 rc = DnDDirDroppedFilesCreateAndOpenTemp(&dirDroppedFiles); 380 if (RT_SUCCESS(rc)) 381 pszDropDir = DnDDirDroppedFilesGetDirAbs(&dirDroppedFiles); 382 377 383 DnDURIList lstURI; 378 char szDropDir[RTPATH_MAX];379 if (RT_SUCCESS(rc))380 rc = DnDDirCreateDroppedFiles(szDropDir, sizeof(szDropDir));381 382 if (RT_FAILURE(rc))383 {384 int rc2 = VbglR3DnDHGSetProgress(pCtx, DragAndDropSvc::DND_PROGRESS_ERROR, 100 /* Percent */, rc);385 AssertRC(rc2);386 387 if (pvTmpData)388 RTMemFree(pvTmpData);389 return rc;390 }391 392 /* Lists for holding created files & directories in the case of a rollback. */393 RTCList<RTCString> guestDirList;394 RTCList<RTCString> guestFileList;395 396 384 DnDURIObject objFile(DnDURIObject::File); 397 385 … … 405 393 uint32_t uNextMsg; 406 394 uint32_t cNextParms; 407 LogFlowFunc(("Waiting for new message ...\n"));408 395 rc = vbglR3DnDQueryNextHostMessageType(pCtx, &uNextMsg, &cNextParms, false /* fWait */); 409 396 if (RT_SUCCESS(rc)) … … 423 410 szPathName, cbPathName, fMode, rc)); 424 411 425 /* 426 * Important: HOST_DND_HG_SND_DIR sends the path (directory) name without URI specifications, that is, 427 * only the pure name! To match the accounting though we have to translate the pure name into 428 * a valid URI again. 429 * 430 ** @todo Fix this URI translation! 431 */ 432 RTCString strPath(szPathName); 433 if (RT_SUCCESS(rc)) 434 rc = objFile.RebaseURIPath(strPath); 435 if (RT_SUCCESS(rc)) 412 char *pszPathAbs = RTPathJoinA(pszDropDir, szPathName); 413 if (pszPathAbs) 436 414 { 437 rc = DnDPathSanitize(szPathName, sizeof(szPathName)); 438 char *pszNewDir = RTPathJoinA(szDropDir, szPathName); 439 if (pszNewDir) 415 rc = RTDirCreate(pszPathAbs, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU, 0); 416 if (RT_SUCCESS(rc)) 417 rc = DnDDirDroppedAddDir(&dirDroppedFiles, pszPathAbs); 418 419 RTStrFree(pszPathAbs); 420 } 421 else 422 rc = VERR_NO_MEMORY; 423 break; 424 } 425 case DragAndDropSvc::HOST_DND_HG_SND_FILE_HDR: 426 case DragAndDropSvc::HOST_DND_HG_SND_FILE_DATA: 427 { 428 if (uNextMsg == DragAndDropSvc::HOST_DND_HG_SND_FILE_HDR) 429 rc = vbglR3DnDHGProcessSendFileHdrMessage(pCtx, 430 szPathName, 431 sizeof(szPathName), 432 &fFlags, 433 &fMode, 434 &cbDataToRead); 435 else 436 rc = vbglR3DnDHGProcessSendFileMessage(pCtx, 437 szPathName, 438 sizeof(szPathName), 439 &cbPathName, 440 pvTmpData, 441 cbTmpData, 442 &cbDataRecv, 443 &fMode); 444 if ( RT_SUCCESS(rc) 445 && ( uNextMsg == DragAndDropSvc::HOST_DND_HG_SND_FILE_HDR 446 /* Protocol v1 always sends the file name, so try opening every time. */ 447 || pCtx->uProtocol <= 1) 448 ) 449 { 450 char *pszPathAbs = RTPathJoinA(pszDropDir, szPathName); 451 if (pszPathAbs) 440 452 { 441 rc = RTDirCreate(pszNewDir, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU, 0); 442 RTStrFree(pszNewDir); 453 LogFlowFunc(("Opening pszPathName=%s, cbPathName=%RU32, fMode=0x%x, cbSize=%RU64\n", 454 szPathName, cbPathName, fMode, cbDataToRead)); 455 456 uint64_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_ALL; 457 if (pCtx->uProtocol <= 1) 458 fOpen |= RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND; 459 else 460 fOpen |= RTFILE_O_CREATE_REPLACE; 461 462 /* Is there already a file open, e.g. in transfer? */ 463 if (!objFile.IsOpen()) 464 { 465 466 RTCString strPathAbs(pszPathAbs); 467 rc = objFile.OpenEx(strPathAbs, DnDURIObject::File, DnDURIObject::Target, fOpen, 468 (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR); 469 if (RT_SUCCESS(rc)) 470 { 471 rc = DnDDirDroppedAddFile(&dirDroppedFiles, strPathAbs.c_str()); 472 if (RT_SUCCESS(rc)) 473 { 474 cbDataWritten = 0; 475 476 if (pCtx->uProtocol >= 2) /* Set the expected file size. */ 477 objFile.SetSize(cbDataToRead); 478 } 479 } 480 } 481 else 482 rc = VERR_WRONG_ORDER; 483 484 RTStrFree(pszPathAbs); 443 485 } 444 486 else 445 487 rc = VERR_NO_MEMORY; 446 488 } 489 490 if ( RT_SUCCESS(rc) 491 && uNextMsg == DragAndDropSvc::HOST_DND_HG_SND_FILE_DATA) 492 { 493 bool fClose = false; 494 495 uint32_t cbWritten; 496 rc = objFile.Write(pvTmpData, cbDataRecv, &cbWritten); 447 497 if (RT_SUCCESS(rc)) 448 498 { 449 if (!guestDirList.contains(strPath)) 450 guestDirList.append(strPath); 451 } 452 } 453 break; 454 } 455 case DragAndDropSvc::HOST_DND_HG_SND_FILE_HDR: 456 { 457 rc = vbglR3DnDHGProcessSendFileHdrMessage(pCtx, 458 szPathName, 459 sizeof(szPathName), 460 &fFlags, 461 &fMode, 462 &cbDataToRead); 463 LogFlowFunc(("HOST_DND_HG_SND_FILE_HDR pszPathName=%s, fFlags=0x%x, fMode=0x%x, cbDataToRead=%RU64, rc=%Rrc\n", 464 szPathName, fFlags, fMode, cbDataToRead, rc)); 465 466 cbDataWritten = 0; 467 break; 468 } 469 case DragAndDropSvc::HOST_DND_HG_SND_FILE_DATA: 470 { 471 rc = vbglR3DnDHGProcessSendFileMessage(pCtx, 472 szPathName, 473 sizeof(szPathName), 474 &cbPathName, 475 pvTmpData, 476 cbTmpData, 477 &cbDataRecv, 478 &fMode); 479 LogFlowFunc(("HOST_DND_HG_SND_FILE_DATA pszPathName=%s, cbPathName=%RU32, pvData=0x%p, cbDataRecv=%RU32, fMode=0x%x, rc=%Rrc\n", 480 szPathName, cbPathName, pvTmpData, cbDataRecv, fMode, rc)); 481 482 /* 483 * Important: HOST_DND_HG_SND_FILE sends the path (directory) name without URI specifications, that is, 484 * only the pure name! To match the accounting though we have to translate the pure name into 485 * a valid URI again. 486 * 487 ** @todo Fix this URI translation! 488 */ 489 RTCString strPath(szPathName); 490 if (RT_SUCCESS(rc)) 491 rc = objFile.RebaseURIPath(strPath); 492 if (RT_SUCCESS(rc)) 493 { 494 rc = DnDPathSanitize(szPathName, sizeof(szPathName)); 495 if (RT_SUCCESS(rc)) 496 { 497 char *pszPathAbs = RTPathJoinA(szDropDir, szPathName); 498 if (pszPathAbs) 499 if (pCtx->uProtocol >= 2) 499 500 { 500 RTFILE hFile; 501 /** @todo r=andy Keep the file open and locked during the actual file transfer. Otherwise this will 502 * create all sorts of funny races because we don't know if the guest has 503 * modified the file in between the file data send calls. 504 * 505 * See HOST_DND_HG_SND_FILE_HDR for a good place to do this. */ 506 rc = RTFileOpen(&hFile, pszPathAbs, 507 RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_DENY_ALL | RTFILE_O_OPEN_CREATE); 508 if (RT_SUCCESS(rc)) 509 { 510 /** @todo r=andy Not very safe to assume that we were last appending to the current file. */ 511 rc = RTFileSeek(hFile, 0, RTFILE_SEEK_END, NULL); 512 if (RT_SUCCESS(rc)) 513 { 514 rc = RTFileWrite(hFile, pvTmpData, cbDataRecv, 0); 515 if (RT_SUCCESS(rc)) 516 { 517 if (fMode & RTFS_UNIX_MASK) /* Valid UNIX mode? */ 518 rc = RTFileSetMode(hFile, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR); 519 520 cbDataWritten += cbDataRecv; 521 Assert(cbDataWritten <= cbDataToRead); 522 } 523 } 524 525 RTFileClose(hFile); 526 527 if (!guestFileList.contains(pszPathAbs)) /* Add the file to (rollback) list. */ 528 guestFileList.append(pszPathAbs); 529 } 530 else 531 LogFlowFunc(("Opening file failed with rc=%Rrc\n", rc)); 532 533 RTStrFree(pszPathAbs); 501 /* Data transfer complete? Close the file. */ 502 fClose = objFile.IsComplete(); 534 503 } 535 504 else 536 rc = VERR_NO_MEMORY; 505 fClose = true; /* Always close the file after each chunk. */ 506 507 cbDataWritten += cbWritten; 508 Assert(cbDataWritten <= cbDataToRead); 509 } 510 511 if (fClose) 512 { 513 LogFlowFunc(("Closing file\n")); 514 objFile.Close(); 537 515 } 538 516 } … … 607 585 #endif 608 586 } 609 else610 {611 /* All URI data processed? */612 if (rc == VERR_NO_DATA)613 rc = VINF_SUCCESS;614 break;615 }616 587 617 588 if (RT_FAILURE(rc)) … … 622 593 LogFlowFunc(("Loop ended with %Rrc\n", rc)); 623 594 595 /* All URI data processed? */ 596 if (rc == VERR_NO_DATA) 597 rc = VINF_SUCCESS; 598 624 599 if (pvTmpData) 625 600 RTMemFree(pvTmpData); 626 601 627 /* Cleanup on failure or if the user has canceled the operation. */ 602 /* Cleanup on failure or if the user has canceled the operation or 603 * something else went wrong. */ 628 604 if (RT_FAILURE(rc)) 629 605 { 630 LogFlowFunc(("Rolling back ...\n")); 631 632 /* Rollback by removing any stuff created. */ 633 for (size_t i = 0; i < guestFileList.size(); ++i) 634 RTFileDelete(guestFileList.at(i).c_str()); 635 for (size_t i = 0; i < guestDirList.size(); ++i) 636 RTDirRemove(guestDirList.at(i).c_str()); 606 int rc2 = DnDDirDroppedFilesRollback(&dirDroppedFiles); 607 AssertRC(rc2); /* Not fatal, don't report back to host. */ 637 608 } 638 609 else … … 647 618 RTMemFree(pvData); 648 619 649 RTCString strData = lstURI.RootToString( szDropDir);620 RTCString strData = lstURI.RootToString(pszDropDir); 650 621 LogFlowFunc(("cbDataToRead: %zu -> %zu\n", cbDataToRead, strData.length() + 1)); 651 622 … … 663 634 } 664 635 665 /* Try removing the (empty) drop directory in any case. */ 666 int rc2 = RTDirRemove(szDropDir); 667 if (RT_FAILURE(rc2)) 668 LogFunc(("Warning: Unable to remove drop directory \"%s\": %Rrc\n", szDropDir, rc2)); 636 /* 637 * Close the dropped files directory. 638 * Don't try to remove it here, however, as the files are being needed 639 * by the client's drag'n drop operation lateron. 640 */ 641 int rc2 = DnDDirDroppedFilesClose(&dirDroppedFiles, false); 642 if (RT_FAILURE(rc2)) /* Not fatal, don't report back to host. */ 643 LogFlowFunc(("Closing dropped files directory failed with %Rrc\n", rc2)); 669 644 670 645 LogFlowFuncLeaveRC(rc); … … 872 847 AssertPtr(pcbFormatRecv); 873 848 if (DnDMIMEHasFileURLs(pszFormat, *pcbFormatRecv)) 849 { 874 850 rc = vbglR3DnDHGProcessURIMessages(pCtx, 875 851 puScreenId, … … 880 856 cbData, 881 857 pcbDataRecv); 858 } 882 859 else 883 860 rc = VERR_NOT_SUPPORTED; 861 862 if (RT_FAILURE(rc)) 863 { 864 if (RT_FAILURE(rc)) 865 { 866 int rc2 = VbglR3DnDHGSetProgress(pCtx, DragAndDropSvc::DND_PROGRESS_ERROR, 100 /* Percent */, rc); 867 AssertRC(rc2); 868 } 869 } 884 870 } 885 871 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
r55187 r55640 1443 1443 void UIMachineView::dragIsPending(void) 1444 1444 { 1445 /* At the moment we only support guest->host DnD. */1446 1445 /** @todo Add guest->guest DnD functionality here by getting 1447 1446 * the source of guest B (when copying from B to A). */ -
trunk/src/VBox/GuestHost/DragAndDrop/DnDDir.cpp
r50460 r55640 5 5 6 6 /* 7 * Copyright (C) 2014 Oracle Corporation7 * Copyright (C) 2014-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 27 27 #include <VBox/GuestHost/DragAndDrop.h> 28 28 29 int DnDDirCreateDroppedFilesEx(const char *pszPath, 30 char *pszDropDir, size_t cbDropDir) 29 int DnDDirDroppedAddFile(PDNDDIRDROPPEDFILES pDir, const char *pszFile) 30 { 31 AssertPtrReturn(pDir, VERR_INVALID_POINTER); 32 AssertPtrReturn(pszFile, VERR_INVALID_POINTER); 33 34 if (!pDir->lstFiles.contains(pszFile)) 35 pDir->lstFiles.append(pszFile); 36 return VINF_SUCCESS; 37 } 38 39 int DnDDirDroppedAddDir(PDNDDIRDROPPEDFILES pDir, const char *pszDir) 40 { 41 AssertPtrReturn(pDir, VERR_INVALID_POINTER); 42 AssertPtrReturn(pszDir, VERR_INVALID_POINTER); 43 44 if (!pDir->lstDirs.contains(pszDir)) 45 pDir->lstDirs.append(pszDir); 46 return VINF_SUCCESS; 47 } 48 49 int DnDDirDroppedFilesCreateAndOpenEx(const char *pszPath, PDNDDIRDROPPEDFILES pDir) 31 50 { 32 51 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 33 AssertPtrReturn(pszDropDir, VERR_INVALID_POINTER); 34 AssertReturn(cbDropDir, VERR_INVALID_PARAMETER); 52 AssertPtrReturn(pDir, VERR_INVALID_POINTER); 35 53 36 if (RTStrPrintf(pszDropDir, cbDropDir, "%s", pszPath) <= 0) 54 char pszDropDir[RTPATH_MAX]; 55 if (RTStrPrintf(pszDropDir, sizeof(pszDropDir), "%s", pszPath) <= 0) 37 56 return VERR_NO_MEMORY; 38 57 … … 42 61 43 62 /* Append our base drop directory. */ 44 int rc = RTPathAppend(pszDropDir, cbDropDir, "VirtualBox Dropped Files");63 int rc = RTPathAppend(pszDropDir, sizeof(pszDropDir), "VirtualBox Dropped Files"); /** @todo Make this tag configurable? */ 45 64 if (RT_FAILURE(rc)) 46 65 return rc; … … 64 83 return rc; 65 84 66 rc = RTPathAppend(pszDropDir, cbDropDir, pszTime);85 rc = RTPathAppend(pszDropDir, sizeof(pszDropDir), pszTime); 67 86 if (RT_FAILURE(rc)) 68 87 return rc; 69 88 70 89 /* Create it (only accessible by the current user) */ 71 return RTDirCreateUniqueNumbered(pszDropDir, cbDropDir, RTFS_UNIX_IRWXU, 3, '-'); 90 rc = RTDirCreateUniqueNumbered(pszDropDir, sizeof(pszDropDir), RTFS_UNIX_IRWXU, 3, '-'); 91 if (RT_SUCCESS(rc)) 92 { 93 PRTDIR phDir; 94 rc = RTDirOpen(&phDir, pszDropDir); 95 if (RT_SUCCESS(rc)) 96 { 97 pDir->hDir = phDir; 98 pDir->strPathAbs = pszDropDir; 99 } 100 } 101 102 return rc; 72 103 } 73 104 74 int DnDDir CreateDroppedFiles(char *pszDropDir, size_t cbDropDir)105 int DnDDirDroppedFilesCreateAndOpenTemp(PDNDDIRDROPPEDFILES pDir) 75 106 { 76 AssertPtrReturn(pszDropDir, VERR_INVALID_POINTER); 77 AssertReturn(cbDropDir, VERR_INVALID_PARAMETER); 107 AssertPtrReturn(pDir, VERR_INVALID_POINTER); 78 108 79 109 char szTemp[RTPATH_MAX]; 80 110 81 /* Get the user's temp directory. Don't use the user's root directory (or 111 /* 112 * Get the user's temp directory. Don't use the user's root directory (or 82 113 * something inside it) because we don't know for how long/if the data will 83 * be kept after the guest OS used it. */ 114 * be kept after the guest OS used it. 115 */ 84 116 int rc = RTPathTemp(szTemp, sizeof(szTemp)); 85 117 if (RT_FAILURE(rc)) 86 118 return rc; 87 119 88 return DnDDir CreateDroppedFilesEx(szTemp, pszDropDir, cbDropDir);120 return DnDDirDroppedFilesCreateAndOpenEx(szTemp, pDir); 89 121 } 90 122 123 int DnDDirDroppedFilesClose(PDNDDIRDROPPEDFILES pDir, bool fRemove) 124 { 125 AssertPtrReturn(pDir, VERR_INVALID_POINTER); 126 127 int rc = RTDirClose(pDir->hDir); 128 if (RT_SUCCESS(rc)) 129 { 130 pDir->lstDirs.clear(); 131 pDir->lstFiles.clear(); 132 133 if (fRemove) 134 { 135 /* Try removing the (empty) drop directory in any case. */ 136 rc = RTDirRemove(pDir->strPathAbs.c_str()); 137 if (RT_SUCCESS(rc)) /* Only clear if successfully removed. */ 138 pDir->strPathAbs = ""; 139 } 140 } 141 142 return rc; 143 } 144 145 const char *DnDDirDroppedFilesGetDirAbs(PDNDDIRDROPPEDFILES pDir) 146 { 147 AssertPtrReturn(pDir, NULL); 148 return pDir->strPathAbs.c_str(); 149 } 150 151 int DnDDirDroppedFilesRollback(PDNDDIRDROPPEDFILES pDir) 152 { 153 AssertPtrReturn(pDir, VERR_INVALID_POINTER); 154 155 if (pDir->strPathAbs.isEmpty()) 156 return VINF_SUCCESS; 157 158 int rc = VINF_SUCCESS; 159 int rc2; 160 161 /* Rollback by removing any stuff created. 162 * Note: Only remove empty directories, never ever delete 163 * anything recursive here! Steam (tm) knows best ... :-) */ 164 for (size_t i = 0; i < pDir->lstFiles.size(); i++) 165 { 166 rc2 = RTFileDelete(pDir->lstFiles.at(i).c_str()); 167 if (RT_SUCCESS(rc)) 168 rc = rc2; 169 } 170 171 for (size_t i = 0; i < pDir->lstDirs.size(); i++) 172 { 173 rc2 = RTDirRemove(pDir->lstDirs.at(i).c_str()); 174 if (RT_SUCCESS(rc)) 175 rc = rc2; 176 } 177 178 /* Try to remove the empty root dropped files directory as well. */ 179 rc2 = RTDirRemove(pDir->strPathAbs.c_str()); 180 if (RT_SUCCESS(rc)) 181 rc = rc2; 182 183 return rc; 184 } 185 -
trunk/src/VBox/GuestHost/DragAndDrop/DnDURIList.cpp
r55556 r55640 336 336 } 337 337 338 int DnDURIList::RootFromURIData(const void *pvData, size_t cbData, 339 uint32_t fFlags) 338 int DnDURIList::RootFromURIData(const void *pvData, size_t cbData, uint32_t fFlags) 340 339 { 341 340 AssertPtrReturn(pvData, VERR_INVALID_POINTER); … … 380 379 } 381 380 382 RTCString DnDURIList::RootToString(const RTCString &str BasePath/* = "" */,381 RTCString DnDURIList::RootToString(const RTCString &strPathBase /* = "" */, 383 382 const RTCString &strSeparator /* = "\r\n" */) 384 383 { … … 390 389 LogFlowFunc(("pszCurRoot=%s\n", pszCurRoot)); 391 390 #endif 392 if (str BasePath.isNotEmpty())393 { 394 char *pszPath = RTPathJoinA(str BasePath.c_str(), pszCurRoot);391 if (strPathBase.isNotEmpty()) 392 { 393 char *pszPath = RTPathJoinA(strPathBase.c_str(), pszCurRoot); 395 394 if (pszPath) 396 395 { … … 399 398 { 400 399 strRet += RTCString(pszPathURI) + strSeparator; 401 #ifdef DEBUG_andy402 400 LogFlowFunc(("URI: %s\n", strRet.c_str())); 403 #endif404 401 RTStrFree(pszPathURI); 405 402 } … … 417 414 { 418 415 strRet += RTCString(pszPathURI) + strSeparator; 419 #ifdef DEBUG_andy420 416 LogFlowFunc(("URI: %s\n", strRet.c_str())); 421 #endif422 417 RTStrFree(pszPathURI); 423 418 } -
trunk/src/VBox/GuestHost/DragAndDrop/DnDURIObject.cpp
r55556 r55640 37 37 DnDURIObject::DnDURIObject(void) 38 38 : m_Type(Unknown) 39 , m_f CreationMode(0)39 , m_fMode(0) 40 40 , m_cbSize(0) 41 41 , m_cbProcessed(0) … … 51 51 , m_strSrcPath(strSrcPath) 52 52 , m_strTgtPath(strDstPath) 53 , m_f CreationMode(fMode)53 , m_fMode(fMode) 54 54 , m_cbSize(cbSize) 55 55 , m_cbProcessed(0) … … 155 155 } 156 156 157 int DnDURIObject::Open(Dest enmDest, uint64_t fOpen )157 int DnDURIObject::Open(Dest enmDest, uint64_t fOpen /* = 0 */, uint32_t fMode /* = 0 */) 158 158 { 159 159 return OpenEx( enmDest == Source 160 160 ? m_strSrcPath : m_strTgtPath 161 , m_Type, enmDest, fOpen, 0 /* fFlag s*/);161 , m_Type, enmDest, fOpen, fMode, 0 /* fFlags */); 162 162 } 163 163 164 164 int DnDURIObject::OpenEx(const RTCString &strPath, Type enmType, Dest enmDest, 165 uint64_t fOpen /* = 0 */, uint32_t f Flags /* = 0 */)165 uint64_t fOpen /* = 0 */, uint32_t fMode /* = 0 */, uint32_t fFlags /* = 0 */) 166 166 { 167 167 int rc = VINF_SUCCESS; … … 198 198 if (RT_SUCCESS(rc)) 199 199 rc = RTFileGetSize(u.m_hFile, &m_cbSize); 200 if (RT_SUCCESS(rc) 201 && fMode) 202 { 203 rc = RTFileSetMode(u.m_hFile, fMode); 204 } 200 205 if (RT_SUCCESS(rc)) 201 206 { 202 LogFlowFunc(("cbSize=%RU64, fMode=%RU32\n", m_cbSize, m_f CreationMode));207 LogFlowFunc(("cbSize=%RU64, fMode=%RU32\n", m_cbSize, m_fMode)); 203 208 m_cbProcessed = 0; 204 209 } … … 293 298 case File: 294 299 { 295 bool fDone = false;296 297 300 rc = OpenEx(m_strSrcPath, File, Source, 298 301 /* Use some sensible defaults. */ … … 307 310 308 311 /* End of file reached or error occurred? */ 309 if (m_cbProcessed == m_cbSize) 312 if ( m_cbSize 313 && m_cbProcessed == m_cbSize) 310 314 { 311 315 rc = VINF_EOF; 312 fDone = true;313 316 } 314 317 } 315 else316 fDone = true;317 318 if (fDone)319 closeInternal();320 318 } 321 319 … … 351 349 m_strSrcPath = ""; 352 350 m_strTgtPath = ""; 353 m_f CreationMode = 0;351 m_fMode = 0; 354 352 m_cbSize = 0; 355 353 m_cbProcessed = 0; … … 369 367 case File: 370 368 { 371 bool fDone = false;372 373 369 rc = OpenEx(m_strTgtPath, File, Target, 374 370 /* Use some sensible defaults. */ … … 379 375 if (RT_SUCCESS(rc)) 380 376 m_cbProcessed += cbWritten; 381 else382 fDone = true;383 384 if (fDone)385 closeInternal();386 377 } 387 378 -
trunk/src/VBox/HostServices/DragAndDrop/service.cpp
r55549 r55640 712 712 if (m_clientMap.size()) /* At least one client on the guest connected? */ 713 713 { 714 /* 715 * Did the host call something which needs immediate processing? 716 * Prepend the message instead of appending to the command queue then. 717 */ 718 bool fAppend; 719 switch (u32Function) 720 { 721 /* Cancelling the drag'n drop operation has higher priority than 722 * processing already buffered messages. */ 723 case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL: 724 fAppend = false; 725 break; 726 727 default: 728 fAppend = true; 729 break; 730 } 731 732 /* 733 * If we prepending the message (instead of appending) this mean we need 734 * to re-schedule the message queue in order to get the new command executed as 735 * soon as possible. 736 */ 737 bool fReschedule = !fAppend; 738 739 rc = m_pManager->addMessage(u32Function, cParms, paParms, fAppend); 740 if ( RT_SUCCESS(rc) 741 && fReschedule) 742 { 743 rc = m_pManager->doReschedule(); 744 } 745 714 rc = m_pManager->addMessage(u32Function, cParms, paParms, true /* fAppend */); 746 715 if (RT_SUCCESS(rc)) 747 716 { -
trunk/src/VBox/Main/include/GuestDnDPrivate.h
r55571 r55640 106 106 void Reset(void) 107 107 { 108 strDropDir = "";109 108 lstURI.Clear(); 110 lstDirs.clear();111 lstFiles.clear();112 109 #if 0 /* Currently the scratch buffer will be maintained elswewhere. */ 113 110 if (pvScratchBuf) … … 123 120 } 124 121 125 int Rollback(void) 126 { 127 if (strDropDir.isEmpty()) 128 return VINF_SUCCESS; 129 130 int rc = VINF_SUCCESS; 131 int rc2; 132 133 /* Rollback by removing any stuff created. 134 * Note: Only remove empty directories, never ever delete 135 * anything recursive here! Steam (tm) knows best ... :-) */ 136 for (size_t i = 0; i < lstFiles.size(); i++) 137 { 138 rc2 = RTFileDelete(lstFiles.at(i).c_str()); 139 if (RT_SUCCESS(rc)) 140 rc = rc2; 141 } 142 143 for (size_t i = 0; i < lstDirs.size(); i++) 144 { 145 rc2 = RTDirRemove(lstDirs.at(i).c_str()); 146 if (RT_SUCCESS(rc)) 147 rc = rc2; 148 } 149 150 rc2 = RTDirRemove(strDropDir.c_str()); 151 if (RT_SUCCESS(rc)) 152 rc = rc2; 153 154 return rc; 155 } 156 157 /** Temporary drop directory on the host where to 158 * put the files sent from the guest. */ 159 com::Utf8Str strDropDir; 122 DNDDIRDROPPEDFILES mDropDir; 160 123 /** (Non-recursive) List of root URI objects to receive. */ 161 124 DnDURIList lstURI; 162 125 /** Current object to receive. */ 163 126 DnDURIObject objURI; 164 /** List for holding created directories in the case of a rollback. */165 RTCList<RTCString> lstDirs;166 /** List for holding created files in the case of a rollback. */167 RTCList<RTCString> lstFiles;168 127 /** Pointer to an optional scratch buffer to use for 169 128 * doing the actual chunk transfers. */ -
trunk/src/VBox/Main/src-client/GuestDnDPrivate.cpp
r55571 r55640 869 869 int GuestDnDBase::sendCancel(void) 870 870 { 871 LogFlowFunc(("Sending cancelation request to guest ...\n")); 872 873 GuestDnDMsg MsgCancel; 874 MsgCancel.setType(DragAndDropSvc::HOST_DND_HG_EVT_CANCEL); 875 876 return GuestDnDInst()->hostCall(MsgCancel.getType(), MsgCancel.getCount(), MsgCancel.getParms()); 871 LogFlowFunc(("Generating cancel request ...\n")); 872 873 int rc; 874 try 875 { 876 GuestDnDMsg *pMsgCancel = new GuestDnDMsg(); 877 pMsgCancel->setType(DragAndDropSvc::HOST_DND_HG_EVT_CANCEL); 878 879 rc = msgQueueAdd(pMsgCancel); 880 } 881 catch(std::bad_alloc & /*e*/) 882 { 883 rc = VERR_NO_MEMORY; 884 } 885 886 return rc; 877 887 } 878 888 -
trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp
r55571 r55640 225 225 } 226 226 227 // implementation of wrapped IDnD Targetmethods.227 // implementation of wrapped IDnDSource methods. 228 228 ///////////////////////////////////////////////////////////////////////////// 229 229 … … 277 277 } 278 278 279 if (RT_FAILURE(rc))280 hr = setError(VBOX_E_IPRT_ERROR,281 tr("Error retrieving drag and drop pending status (%Rrc)\n"), rc);282 283 279 LogFlowFunc(("hr=%Rhrc, defaultAction=0x%x\n", hr, defaultAction)); 284 280 return hr; … … 383 379 if (fHasURIList) 384 380 { 385 Utf8Str strURIs = pCtx->mURI.lstURI.RootToString( pCtx->mURI.strDropDir);381 Utf8Str strURIs = pCtx->mURI.lstURI.RootToString(RTCString(DnDDirDroppedFilesGetDirAbs(&pCtx->mURI.mDropDir))); 386 382 cbData = strURIs.length(); 387 383 … … 489 485 490 486 int rc; 491 char *pszDir = RTPathJoinA( pCtx->mURI.strDropDir.c_str(), pszPath);487 char *pszDir = RTPathJoinA(DnDDirDroppedFilesGetDirAbs(&pCtx->mURI.mDropDir), pszPath); 492 488 if (pszDir) 493 489 { … … 571 567 572 568 char pszPathAbs[RTPATH_MAX]; 573 rc = RTPathJoin(pszPathAbs, sizeof(pszPathAbs), pCtx->mURI.strDropDir.c_str(), pszPath);569 rc = RTPathJoin(pszPathAbs, sizeof(pszPathAbs), DnDDirDroppedFilesGetDirAbs(&pCtx->mURI.mDropDir), pszPath); 574 570 if (RT_FAILURE(rc)) 575 571 { … … 588 584 589 585 /** @todo Add sparse file support based on fFlags? (Use Open(..., fFlags | SPARSE). */ 590 /** @todo Add fMode to opening flags. */591 586 rc = pCtx->mURI.objURI.OpenEx(pszPathAbs, DnDURIObject::File, DnDURIObject::Target, 592 RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE); 587 RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE, 588 (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR); 593 589 if (RT_SUCCESS(rc)) 594 590 { … … 898 894 do 899 895 { 900 char szDropDir[RTPATH_MAX]; 901 rc = DnDDirCreateDroppedFiles(szDropDir, sizeof(szDropDir)); 902 LogFlowFunc(("rc=%Rrc, szDropDir=%s\n", rc, szDropDir)); 896 rc = DnDDirDroppedFilesCreateAndOpenTemp(&pCtx->mURI.mDropDir); 903 897 if (RT_FAILURE(rc)) 904 898 break; 905 906 pCtx->mURI.strDropDir = szDropDir; /** @todo Keep directory handle open? */ 899 LogFlowFunc(("strDropDir=%s\n", rc, DnDDirDroppedFilesGetDirAbs(&pCtx->mURI.mDropDir))); 900 if (RT_FAILURE(rc)) 901 break; 907 902 908 903 /* … … 936 931 #undef UNREGISTER_CALLBACK 937 932 933 int rc2; 934 938 935 if (rc == VERR_CANCELLED) 939 936 { 940 intrc2 = sendCancel();937 rc2 = sendCancel(); 941 938 AssertRC(rc2); 942 939 } … … 944 941 if (RT_FAILURE(rc)) 945 942 { 946 int rc2 = pCtx->mURI.Rollback(); /** @todo Inform user on rollback failure? */943 rc2 = DnDDirDroppedFilesRollback(&pCtx->mURI.mDropDir); /** @todo Inform user on rollback failure? */ 947 944 LogFlowFunc(("Rolling back ended with rc=%Rrc\n", rc2)); 948 945 } 946 947 rc2 = DnDDirDroppedFilesClose(&pCtx->mURI.mDropDir, RT_FAILURE(rc) ? true : false /* fRemove */); 948 if (RT_SUCCESS(rc)) 949 rc = rc2; 949 950 950 951 LogFlowFuncLeaveRC(rc); -
trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp
r55571 r55640 821 821 AssertReturn(DragAndDropSvc::CB_MAGIC_DND_HG_GET_NEXT_HOST_MSG == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 822 822 823 GuestDnDMsg *pMsg;824 823 try 825 824 { 826 pMsg = new GuestDnDMsg();825 GuestDnDMsg *pMsg = new GuestDnDMsg(); 827 826 828 827 rc = pThis->i_sendURIDataLoop(pCtx, pMsg);
Note:
See TracChangeset
for help on using the changeset viewer.

