Changeset 49923 in vbox for trunk/src/VBox/Additions
- Timestamp:
- Dec 16, 2013 9:36:45 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp
r49891 r49923 51 51 */ 52 52 53 int vbglR3DnDPathSanitize(char *pszPath, size_t cbPath); 54 53 55 /****************************************************************************** 54 56 * Private internal functions * … … 90 92 if (!RTTimeSpecToString(RTTimeNow(&time), pszTime, sizeof(pszTime))) 91 93 return VERR_BUFFER_OVERFLOW; 92 #ifdef RT_OS_WINDOWS 93 /* Filter out characters not allowed on Windows platforms, put in by 94 RTTimeSpecToString(). */ 95 /** @todo Use something like RTPathSanitize() when available. Later. */ 96 RTUNICP aCpSet[] = 97 { ' ', ' ', '(', ')', '-', '.', '0', '9', 'A', 'Z', 'a', 'z', '_', '_', 98 0xa0, 0xd7af, '\0' }; 99 RTStrPurgeComplementSet(pszTime, aCpSet, '_' /* Replacement */); 100 #endif 94 rc = vbglR3DnDPathSanitize(pszTime, sizeof(pszTime)); 95 if (RT_FAILURE(rc)) 96 return rc; 101 97 102 98 rc = RTPathAppend(pszDropDir, cbSize, pszTime); … … 319 315 size_t *pcbDataRecv) 320 316 { 317 AssertPtrReturn(ppvData, VERR_INVALID_POINTER); 318 AssertPtrReturn(cbData, VERR_INVALID_PARAMETER); 319 AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER); 320 321 321 /* Make a string list out of the uri data. */ 322 322 RTCList<RTCString> uriList = RTCString(static_cast<char*>(*ppvData), *pcbDataRecv - 1).split("\r\n"); … … 324 324 return VINF_SUCCESS; 325 325 326 uint32_t cbTmpData = _1M * 10; 326 uint32_t cbTmpData = _1M * 10; /** @todo r=andy 10MB, uh, really?? */ 327 327 void *pvTmpData = RTMemAlloc(cbTmpData); 328 328 if (!pvTmpData) … … 346 346 /* Query the path component of a file URI. If this hasn't a 347 347 * file scheme, null is returned. */ 348 if (char *pszFilePath = RTUriFilePath(strUri.c_str(), URI_FILE_FORMAT_AUTO)) 349 { 348 char *pszFilePath = RTUriFilePath(strUri.c_str(), URI_FILE_FORMAT_AUTO); 349 if (pszFilePath) 350 { 351 rc = vbglR3DnDPathSanitize(pszFilePath, strlen(pszFilePath)); 352 if (RT_FAILURE(rc)) 353 break; 354 355 /** @todo Use RTPathJoin? */ 350 356 RTCString strFullPath = RTCString().printf("%s%c%s", pszDropDir, RTPATH_SLASH, pszFilePath); 351 357 char *pszNewUri = RTUriFileCreate(strFullPath.c_str()); … … 360 366 } 361 367 362 /* Cleanup the old data and write the new data back to the event. */ 363 RTMemFree(*ppvData); 364 RTCString newData = RTCString::join(guestUriList, "\r\n") + "\r\n"; 365 *ppvData = RTStrDupN(newData.c_str(), newData.length()); 366 *pcbDataRecv = newData.length() + 1; 368 if (RT_SUCCESS(rc)) 369 { 370 /* Cleanup the old data and write the new data back to the event. */ 371 RTMemFree(*ppvData); 372 RTCString newData = RTCString::join(guestUriList, "\r\n") + "\r\n"; 373 374 *ppvData = RTStrDupN(newData.c_str(), newData.length()); 375 *pcbDataRecv = newData.length() + 1; 376 } 367 377 368 378 /* Lists for holding created files & directories in the case of a … … 372 382 char pszPathname[RTPATH_MAX]; 373 383 uint32_t cbPathname = 0; 374 bool fLoop = true;375 do384 bool fLoop = RT_SUCCESS(rc); /* No error occurred yet? */ 385 while (fLoop) 376 386 { 377 387 uint32_t uNextMsg; … … 380 390 if (RT_SUCCESS(rc)) 381 391 { 382 switch (uNextMsg)392 switch (uNextMsg) 383 393 { 384 394 case DragAndDropSvc::HOST_DND_HG_SND_DIR: 385 {386 uint32_t fMode = 0;387 rc = vbglR3DnDHGProcessSendDirMessage(uClientId,388 pszPathname,389 sizeof(pszPathname),390 &cbPathname,391 &fMode);392 if (RT_SUCCESS(rc))393 395 { 394 char *pszNewDir = RTPathJoinA(pszDropDir, pszPathname); 395 rc = RTDirCreate(pszNewDir, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU, 0); 396 if (!guestDirList.contains(pszNewDir)) 397 guestDirList.append(pszNewDir); 398 } 399 break; 400 } 401 case DragAndDropSvc::HOST_DND_HG_SND_FILE: 402 { 403 uint32_t cbDataRecv; 404 uint32_t fMode = 0; 405 rc = vbglR3DnDHGProcessSendFileMessage(uClientId, 406 pszPathname, 407 sizeof(pszPathname), 408 &cbPathname, 409 pvTmpData, 410 cbTmpData, 411 &cbDataRecv, 412 &fMode); 413 if (RT_SUCCESS(rc)) 414 { 415 char *pszNewFile = RTPathJoinA(pszDropDir, pszPathname); 416 RTFILE hFile; 417 /** @todo r=andy Keep the file open and locked during the actual file transfer. Otherwise this will 418 * create all sorts of funny races because we don't know if the guest has 419 * modified the file in between the file data send calls. */ 420 rc = RTFileOpen(&hFile, pszNewFile, RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_DENY_ALL | RTFILE_O_OPEN_CREATE); 396 uint32_t fMode = 0; 397 rc = vbglR3DnDHGProcessSendDirMessage(uClientId, 398 pszPathname, 399 sizeof(pszPathname), 400 &cbPathname, 401 &fMode); 402 if (RT_SUCCESS(rc)) 403 rc = vbglR3DnDPathSanitize(pszPathname, sizeof(pszPathname)); 421 404 if (RT_SUCCESS(rc)) 422 405 { 423 rc = RTFileSeek(hFile, 0, RTFILE_SEEK_END, NULL);424 if ( RT_SUCCESS(rc))406 char *pszNewDir = RTPathJoinA(pszDropDir, pszPathname); 407 if (pszNewDir) 425 408 { 426 rc = RT FileWrite(hFile, pvTmpData, cbDataRecv, 0);427 /* Valid UNIX mode? */428 if ( RT_SUCCESS(rc)429 && (fMode & RTFS_UNIX_MASK)) 430 rc = RTFileSetMode(hFile, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR);409 rc = RTDirCreate(pszNewDir, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU, 0); 410 if (!guestDirList.contains(pszNewDir)) 411 guestDirList.append(pszNewDir); 412 413 RTStrFree(pszNewDir); 431 414 } 432 RTFileClose(hFile); 433 if (!guestFileList.contains(pszNewFile)) 434 guestFileList.append(pszNewFile); 415 else 416 rc = VERR_NO_MEMORY; 435 417 } 418 break; 436 419 } 437 break; 438 } 420 case DragAndDropSvc::HOST_DND_HG_SND_FILE: 421 { 422 uint32_t cbDataRecv; 423 uint32_t fMode = 0; 424 rc = vbglR3DnDHGProcessSendFileMessage(uClientId, 425 pszPathname, 426 sizeof(pszPathname), 427 &cbPathname, 428 pvTmpData, 429 cbTmpData, 430 &cbDataRecv, 431 &fMode); 432 if (RT_SUCCESS(rc)) 433 rc = vbglR3DnDPathSanitize(pszPathname, sizeof(pszPathname)); 434 if (RT_SUCCESS(rc)) 435 { 436 char *pszNewFile = RTPathJoinA(pszDropDir, pszPathname); 437 if (pszNewFile) 438 { 439 RTFILE hFile; 440 /** @todo r=andy Keep the file open and locked during the actual file transfer. Otherwise this will 441 * create all sorts of funny races because we don't know if the guest has 442 * modified the file in between the file data send calls. */ 443 rc = RTFileOpen(&hFile, pszNewFile, RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_DENY_ALL | RTFILE_O_OPEN_CREATE); 444 if (RT_SUCCESS(rc)) 445 { 446 rc = RTFileSeek(hFile, 0, RTFILE_SEEK_END, NULL); 447 if (RT_SUCCESS(rc)) 448 { 449 rc = RTFileWrite(hFile, pvTmpData, cbDataRecv, 0); 450 /* Valid UNIX mode? */ 451 if (RT_SUCCESS(rc) 452 && (fMode & RTFS_UNIX_MASK)) rc = RTFileSetMode(hFile, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR); 453 } 454 RTFileClose(hFile); 455 if (!guestFileList.contains(pszNewFile)) 456 guestFileList.append(pszNewFile); 457 } 458 459 RTStrFree(pszNewFile); 460 } 461 else 462 rc = VERR_NO_MEMORY; 463 } 464 break; 465 } 439 466 case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL: 440 { 441 rc = vbglR3DnDHGProcessCancelMessage(uClientId); 442 if (RT_SUCCESS(rc)) 443 rc = VERR_CANCELLED; 444 /* Break out of the loop. */ 445 } 467 { 468 rc = vbglR3DnDHGProcessCancelMessage(uClientId); 469 if (RT_SUCCESS(rc)) rc = VERR_CANCELLED; 470 /* Break out of the loop. */ 471 } 446 472 default: 447 473 fLoop = false; … … 451 477 else 452 478 { 453 if (rc == VERR_NO_DATA) 454 rc = VINF_SUCCESS; 479 if (rc == VERR_NO_DATA) rc = VINF_SUCCESS; 455 480 break; 456 481 } 457 458 } while (fLoop); 482 } /* while */ 459 483 460 484 RTMemFree(pvTmpData); … … 507 531 { 508 532 rc = Msg.hdr.result; 509 if ( 533 if (RT_SUCCESS(rc) 510 534 || rc == VERR_BUFFER_OVERFLOW) 511 535 { … … 715 739 } 716 740 741 return rc; 742 } 743 744 int vbglR3DnDPathSanitize(char *pszPath, size_t cbPath) 745 { 746 int rc = VINF_SUCCESS; 747 #ifdef RT_OS_WINDOWS 748 /* Filter out characters not allowed on Windows platforms, put in by 749 RTTimeSpecToString(). */ 750 /** @todo Use something like RTPathSanitize() when available. Later. */ 751 RTUNICP aCpSet[] = 752 { ' ', ' ', '(', ')', '-', '.', '0', '9', 'A', 'Z', 'a', 'z', '_', '_', 753 0xa0, 0xd7af, '\0' }; 754 ssize_t cReplaced = RTStrPurgeComplementSet(pszPath, aCpSet, '_' /* Replacement */); 755 if (cReplaced < 0) 756 rc = VERR_INVALID_UTF8_ENCODING; 757 #endif 717 758 return rc; 718 759 }
Note:
See TracChangeset
for help on using the changeset viewer.