Changeset 50460 in vbox for trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp
- Timestamp:
- Feb 14, 2014 9:46:58 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp
r50305 r50460 39 39 40 40 #include "VBGLR3Internal.h" 41 #include "VBox/GuestHost/DragAndDrop.h" 41 42 #include "VBox/HostServices/DragAndDropSvc.h" 42 43 … … 47 48 * Todo: 48 49 * - Sending dirs/files in the G->H case 49 * - Maybe the EOL converting of text mime-types (not fully sure, eventually50 * - Maybe the EOL converting of text MIME types (not fully sure, eventually 50 51 * better done on the host side) 51 52 */ 52 53 static int vbglR3DnDPathSanitize(char *pszPath, size_t cbPath);54 53 55 54 /****************************************************************************** 56 55 * Private internal functions * 57 56 ******************************************************************************/ 58 59 static int vbglR3DnDCreateDropDir(char* pszDropDir, size_t cbSize)60 {61 AssertPtrReturn(pszDropDir, VERR_INVALID_POINTER);62 AssertReturn(cbSize, VERR_INVALID_PARAMETER);63 64 /** @todo On Windows we also could use the registry to override65 * this path, on Posix a dotfile and/or a guest property66 * can be used. */67 68 /* Get the users temp directory. Don't use the user's root directory (or69 * something inside it) because we don't know for how long/if the data will70 * be kept after the guest OS used it. */71 int rc = RTPathTemp(pszDropDir, cbSize);72 if (RT_FAILURE(rc))73 return rc;74 75 /* Append our base drop directory. */76 rc = RTPathAppend(pszDropDir, cbSize, "VirtualBox Dropped Files");77 if (RT_FAILURE(rc))78 return rc;79 80 /* Create it when necessary. */81 if (!RTDirExists(pszDropDir))82 {83 rc = RTDirCreateFullPath(pszDropDir, RTFS_UNIX_IRWXU);84 if (RT_FAILURE(rc))85 return rc;86 }87 88 /* The actually drop directory consist of the current time stamp and a89 * unique number when necessary. */90 char pszTime[64];91 RTTIMESPEC time;92 if (!RTTimeSpecToString(RTTimeNow(&time), pszTime, sizeof(pszTime)))93 return VERR_BUFFER_OVERFLOW;94 rc = vbglR3DnDPathSanitize(pszTime, sizeof(pszTime));95 if (RT_FAILURE(rc))96 return rc;97 98 rc = RTPathAppend(pszDropDir, cbSize, pszTime);99 if (RT_FAILURE(rc))100 return rc;101 102 /* Create it (only accessible by the current user) */103 return RTDirCreateUniqueNumbered(pszDropDir, cbSize, RTFS_UNIX_IRWXU, 3, '-');104 }105 57 106 58 static int vbglR3DnDQueryNextHostMessageType(uint32_t uClientId, uint32_t *puMsg, uint32_t *pcParms, bool fWait) … … 319 271 AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER); 320 272 273 if (!*pcbDataRecv) 274 return VERR_INVALID_PARAMETER; 275 321 276 /* Make a string list out of the uri data. */ 322 RTCList<RTCString> uriList = RTCString(static_cast<char*>(*ppvData), *pcbDataRecv - 1).split("\r\n"); 277 RTCList<RTCString> uriList = 278 RTCString(static_cast<char*>(*ppvData), *pcbDataRecv - 1).split("\r\n"); 323 279 if (uriList.isEmpty()) 324 280 return VINF_SUCCESS; … … 331 287 /* Create and query the (unique) drop target directory. */ 332 288 char pszDropDir[RTPATH_MAX]; 333 int rc = vbglR3DnDCreateDropDir(pszDropDir, sizeof(pszDropDir));289 int rc = DnDDirCreateDroppedFiles(pszDropDir, sizeof(pszDropDir)); 334 290 if (RT_FAILURE(rc)) 335 291 { … … 349 305 if (pszFilePath) 350 306 { 351 rc = vbglR3DnDPathSanitize(pszFilePath, strlen(pszFilePath));307 rc = DnDPathSanitize(pszFilePath, strlen(pszFilePath)); 352 308 if (RT_FAILURE(rc)) 353 309 break; 354 310 355 311 /** @todo Use RTPathJoin? */ 356 RTCString strFullPath = RTCString().printf("%s%c%s", pszDropDir, RTPATH_SLASH, pszFilePath); 312 RTCString strFullPath 313 = RTCString().printf("%s%c%s", pszDropDir, RTPATH_SLASH, pszFilePath); 357 314 char *pszNewUri = RTUriFileCreate(strFullPath.c_str()); 358 315 if (pszNewUri) … … 376 333 } 377 334 378 /* Lists for holding created files & directories in the case of a379 * rollback. */335 /* Lists for holding created files & directories 336 * in the case of a rollback. */ 380 337 RTCList<RTCString> guestDirList; 381 338 RTCList<RTCString> guestFileList; 382 char pszPath name[RTPATH_MAX];339 char pszPathName[RTPATH_MAX]; 383 340 uint32_t cbPathname = 0; 384 341 bool fLoop = RT_SUCCESS(rc); /* No error occurred yet? */ … … 396 353 uint32_t fMode = 0; 397 354 rc = vbglR3DnDHGProcessSendDirMessage(uClientId, 398 pszPath name,399 sizeof(pszPath name),355 pszPathName, 356 sizeof(pszPathName), 400 357 &cbPathname, 401 358 &fMode); 402 359 if (RT_SUCCESS(rc)) 403 rc = vbglR3DnDPathSanitize(pszPathname, sizeof(pszPathname));360 rc = DnDPathSanitize(pszPathName, sizeof(pszPathName)); 404 361 if (RT_SUCCESS(rc)) 405 362 { 406 char *pszNewDir = RTPathJoinA(pszDropDir, pszPath name);363 char *pszNewDir = RTPathJoinA(pszDropDir, pszPathName); 407 364 if (pszNewDir) 408 365 { … … 423 380 uint32_t fMode = 0; 424 381 rc = vbglR3DnDHGProcessSendFileMessage(uClientId, 425 pszPath name,426 sizeof(pszPath name),382 pszPathName, 383 sizeof(pszPathName), 427 384 &cbPathname, 428 385 pvTmpData, … … 431 388 &fMode); 432 389 if (RT_SUCCESS(rc)) 433 rc = vbglR3DnDPathSanitize(pszPathname, sizeof(pszPathname));390 rc = DnDPathSanitize(pszPathName, sizeof(pszPathName)); 434 391 if (RT_SUCCESS(rc)) 435 392 { 436 char *pszNewFile = RTPathJoinA(pszDropDir, pszPath name);393 char *pszNewFile = RTPathJoinA(pszDropDir, pszPathName); 437 394 if (pszNewFile) 438 395 { … … 666 623 { 667 624 /* Check if this is an URI event. If so, let VbglR3 do all the actual 668 * data transfer + file 625 * data transfer + file/directory creation internally without letting 669 626 * the caller know. 670 627 * … … 747 704 } 748 705 749 return rc;750 }751 752 static int vbglR3DnDPathSanitize(char *pszPath, size_t cbPath)753 {754 int rc = VINF_SUCCESS;755 #ifdef RT_OS_WINDOWS756 /* Filter out characters not allowed on Windows platforms, put in by757 RTTimeSpecToString(). */758 /** @todo Use something like RTPathSanitize() when available. Later. */759 RTUNICP aCpSet[] =760 { ' ', ' ', '(', ')', '-', '.', '0', '9', 'A', 'Z', 'a', 'z', '_', '_',761 0xa0, 0xd7af, '\0' };762 ssize_t cReplaced = RTStrPurgeComplementSet(pszPath, aCpSet, '_' /* Replacement */);763 if (cReplaced < 0)764 rc = VERR_INVALID_UTF8_ENCODING;765 #endif766 706 return rc; 767 707 } … … 886 826 break; 887 827 } 828 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 888 829 case DragAndDropSvc::HOST_DND_GH_REQ_PENDING: 889 830 { … … 908 849 break; 909 850 } 851 #endif 910 852 default: 853 { 854 pEvent->uType = uMsg; 855 911 856 rc = VERR_NOT_SUPPORTED; 912 857 break; 858 } 913 859 } 914 860 } … … 979 925 } 980 926 981 VBGLR3DECL(int) VbglR3DnDGHSendData(uint32_t u32ClientId, void *pvData, uint32_t cbData) 927 VBGLR3DECL(int) VbglR3DnDGHSendData(uint32_t u32ClientId, 928 void *pvData, uint32_t cbData) 982 929 { 983 930 AssertPtrReturn(pvData, VERR_INVALID_POINTER); … … 993 940 994 941 int rc = VINF_SUCCESS; 995 uint32_t cbMax = _ 1M; /** @todo Remove 1 MB limit. */942 uint32_t cbMax = _64K; /* Transfer max. 64K chunks per message. */ 996 943 uint32_t cbSent = 0; 997 944 998 945 while (cbSent < cbData) 999 946 { 1000 /* Initialize parameter */1001 947 uint32_t cbToSend = RT_MIN(cbData - cbSent, cbMax); 1002 948 Msg.pData.SetPtr(static_cast<uint8_t*>(pvData) + cbSent, cbToSend); 1003 /* Do request */ 949 1004 950 rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 1005 951 if (RT_SUCCESS(rc)) 1006 {1007 952 rc = Msg.hdr.result; 1008 /* Did the host cancel the event? */ 1009 if (rc == VERR_CANCELLED) 1010 break; 1011 } 1012 else 953 954 if (RT_FAILURE(rc)) 1013 955 break; 956 1014 957 cbSent += cbToSend; 1015 // RTThreadSleep(500); 1016 } 958 } 959 960 if (RT_SUCCESS(rc)) 961 Assert(cbSent == cbData); 1017 962 1018 963 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.