Changeset 85371 in vbox for trunk/src/VBox/Additions
- Timestamp:
- Jul 17, 2020 10:02:58 AM (4 years ago)
- Location:
- trunk/src/VBox/Additions
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp
r85121 r85371 1068 1068 int VBoxDnDWnd::OnHgDataReceive(PVBGLR3GUESTDNDMETADATA pMeta) 1069 1069 { 1070 LogFlowThisFunc(("mState=%ld, enmMetaType=%RU32, cbMeta=%RU32\n", mState, pMeta->enmType, pMeta->cbMeta)); 1071 1072 mState = Dropped; 1073 1074 int rc = VINF_SUCCESS; 1075 if (pMeta->pvMeta) 1076 { 1077 Assert(pMeta->cbMeta); 1078 rc = RTCritSectEnter(&mCritSect); 1070 LogFlowThisFunc(("mState=%ld, enmMetaType=%RU32\n", mState, pMeta->enmType)); 1071 1072 int rc = RTCritSectEnter(&mCritSect); 1073 if (RT_SUCCESS(rc)) 1074 { 1075 mState = Dropped; 1076 1077 if (startupInfo.pDataObject) 1078 { 1079 switch (pMeta->enmType) 1080 { 1081 case VBGLR3GUESTDNDMETADATATYPE_RAW: 1082 { 1083 AssertBreakStmt(pMeta->u.Raw.pvMeta != NULL, rc = VERR_INVALID_POINTER); 1084 AssertBreakStmt(pMeta->u.Raw.cbMeta, rc = VERR_INVALID_PARAMETER); 1085 1086 rc = startupInfo.pDataObject->Signal(mFormatRequested, pMeta->u.Raw.pvMeta, pMeta->u.Raw.cbMeta); 1087 break; 1088 } 1089 1090 case VBGLR3GUESTDNDMETADATATYPE_URI_LIST: 1091 { 1092 LogRel2(("DnD: URI transfer root directory is '%s'\n", DnDTransferListGetRootPathAbs(&pMeta->u.URI.Transfer))); 1093 1094 char *pszBuf; 1095 size_t cbBuf; 1096 /* Note: The transfer list already has its root set to a temporary directory, so no need to set/add a new 1097 * path base here. */ 1098 rc = DnDTransferListGetRootsEx(&pMeta->u.URI.Transfer, DNDTRANSFERLISTFMT_NATIVE, NULL /* pszPathBase */, 1099 DND_PATH_SEPARATOR, &pszBuf, &cbBuf); 1100 if (RT_SUCCESS(rc)) 1101 { 1102 rc = startupInfo.pDataObject->Signal(mFormatRequested, pszBuf, cbBuf); 1103 RTStrFree(pszBuf); 1104 } 1105 break; 1106 } 1107 1108 default: 1109 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED); 1110 break; 1111 } 1112 } 1113 else 1114 rc = VERR_NOT_FOUND; 1115 1116 int rc2 = mouseRelease(); 1079 1117 if (RT_SUCCESS(rc)) 1080 { 1081 if (startupInfo.pDataObject) 1082 rc = startupInfo.pDataObject->Signal(mFormatRequested, pMeta->pvMeta, pMeta->cbMeta); 1083 else 1084 rc = VERR_NOT_FOUND; 1085 1086 RTCritSectLeave(&mCritSect); 1087 } 1088 } 1089 1090 int rc2 = mouseRelease(); 1091 if (RT_SUCCESS(rc)) 1092 rc = rc2; 1118 rc = rc2; 1119 1120 RTCritSectLeave(&mCritSect); 1121 } 1093 1122 1094 1123 LogFlowFuncLeaveRC(rc); -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h
r85121 r85371 71 71 int Abort(void); 72 72 void SetStatus(Status status); 73 int Signal(const RTCString &strFormat, const void *pvData, uint32_t cbData);73 int Signal(const RTCString &strFormat, const void *pvData, size_t cbData); 74 74 75 75 protected: … … 88 88 RTCString mstrFormat; 89 89 void *mpvData; 90 uint32_tmcbData;90 size_t mcbData; 91 91 }; 92 92 -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDataObject.cpp
r82968 r85371 229 229 * URI list handling. 230 230 */ 231 if ( mstrFormat.equalsIgnoreCase("text/uri-list"))231 if (DnDMIMEHasFileURLs(mstrFormat.c_str(), RTSTR_MAX)) 232 232 { 233 int rc = VINF_SUCCESS; 234 235 RTCList<RTCString> lstFilesURI = RTCString((char*)mpvData, mcbData).split("\r\n"); 236 RTCList<RTCString> lstFiles; 237 for (size_t i = 0; i < lstFilesURI.size(); i++) 238 { 239 char *pszFilePath = RTUriFilePath(lstFilesURI.at(i).c_str()); 240 if (pszFilePath) 241 { 242 lstFiles.append(pszFilePath); 243 RTStrFree(pszFilePath); 244 } 245 else /* Unable to parse -- refuse entire request. */ 246 { 247 lstFiles.clear(); 248 rc = VERR_INVALID_PARAMETER; 249 break; 250 } 251 } 252 253 size_t cFiles = lstFiles.size(); 233 char **papszFiles; 234 size_t cFiles; 235 int rc = RTStrSplit((const char *)mpvData, mcbData, DND_PATH_SEPARATOR, &papszFiles, &cFiles); 254 236 if ( RT_SUCCESS(rc) 255 237 && cFiles) 256 238 { 257 #ifdef DEBUG 258 LogFlowFunc(("Files (%zu)\n", cFiles)); 239 LogRel2(("DnD: Files (%zu)\n", cFiles)); 259 240 for (size_t i = 0; i < cFiles; i++) 260 LogFlowFunc(("\tFile: %s\n", lstFiles.at(i).c_str())); 261 #endif 241 LogRel2(("\tDnD: File '%s'\n", papszFiles[i])); 262 242 263 243 #if 0 … … 310 290 for (size_t i = 0; i < cFiles; i++) 311 291 { 312 cchFiles += strlen( lstFiles.at(i).c_str());292 cchFiles += strlen(papszFiles[i]); 313 293 cchFiles += 1; /* Terminating '\0'. */ 314 294 } … … 328 308 size_t cchCurFile; 329 309 PRTUTF16 pwszFile; 330 rc = RTStrToUtf16( lstFiles.at(i).c_str(), &pwszFile);310 rc = RTStrToUtf16(papszFiles[i], &pwszFile); 331 311 if (RT_SUCCESS(rc)) 332 312 { … … 373 353 rc = VERR_NO_MEMORY; 374 354 } 355 356 for (size_t i = 0; i < cFiles; ++i) 357 RTStrFree(papszFiles[i]); 358 RTMemFree(papszFiles); 375 359 } 376 360 … … 671 655 672 656 int VBoxDnDDataObject::Signal(const RTCString &strFormat, 673 const void *pvData, uint32_t cbData)657 const void *pvData, size_t cbData) 674 658 { 675 659 int rc; -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDropTarget.cpp
r82968 r85371 28 28 #include "VBox/HostServices/DragAndDropSvc.h" 29 29 30 #include <iprt/path.h> 30 31 #include <iprt/utf16.h> 31 32 #include <VBox/log.h> … … 451 452 LogRel(("DnD: Adding guest file '%s'\n", pszFileUtf8)); 452 453 453 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, pszFileUtf8, cchFileUtf8);454 454 if (RT_SUCCESS(rc)) 455 cchFiles += cchFileUtf8; 455 { 456 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, pszFileUtf8, cchFileUtf8); 457 if (RT_SUCCESS(rc)) 458 cchFiles += cchFileUtf8; 459 } 456 460 } 457 else 461 462 if (RT_FAILURE(rc)) 458 463 LogRel(("DnD: Error handling file entry #%u, rc=%Rrc\n", i, rc)); 459 464 460 if (pszFileUtf8) 461 RTStrFree(pszFileUtf8); 465 RTStrFree(pszFileUtf8); 462 466 463 467 if (RT_FAILURE(rc)) … … 479 483 cFiles, cchFiles, cbFiles, pszFiles)); 480 484 481 /* Translate the list into URI elements. */ 482 DnDURIList lstURI; 483 rc = lstURI.AppendNativePathsFromList(pszFiles, cbFiles, 484 DNDURILIST_FLAGS_ABSOLUTE_PATHS); 485 if (RT_SUCCESS(rc)) 486 { 487 RTCString strRoot = lstURI.GetRootEntries(); 488 size_t cbRoot = strRoot.length() + 1; /* Include termination */ 489 490 mpvData = RTMemAlloc(cbRoot); 491 if (mpvData) 492 { 493 memcpy(mpvData, strRoot.c_str(), cbRoot); 494 mcbData = cbRoot; 495 } 496 else 497 rc = VERR_NO_MEMORY; 498 } 485 mpvData = pszFiles; 486 mcbData = cbFiles; 499 487 } 500 501 LogFlowFunc(("Building CF_HDROP list rc=%Rrc, pszFiles=0x%p, cFiles=%RU16, cchFiles=%RU32\n", 502 rc, pszFiles, cFiles, cchFiles)); 503 504 if (pszFiles) 488 else 489 { 505 490 RTStrFree(pszFiles); 491 pszFiles = NULL; 492 } 493 494 LogFlowFunc(("Building CF_HDROP list rc=%Rrc, cFiles=%RU16, cchFiles=%RU32\n", 495 rc, cFiles, cchFiles)); 506 496 break; 507 497 } -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp
r85121 r85371 154 154 static VBOXSERVICEINFO g_aServices[] = 155 155 { 156 { &g_SvcDescClipboard, NIL_RTTHREAD, NULL, false, false, false, false, true }156 {&g_SvcDescDnD, NIL_RTTHREAD, NULL, false, false, false, false, true } 157 157 }; 158 158 #else -
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibDragAndDrop.cpp
r85029 r85371 349 349 * @param pDroppedFiles Dropped files object to use for maintaining the file creation / locking. 350 350 */ 351 static int vbglR3DnDHGRecvURIData(PVBGLR3GUESTDNDCMDCTX pCtx, PVBOXDNDSNDDATAHDR pDataHdr, DnDDroppedFiles *pDroppedFiles)351 static int vbglR3DnDHGRecvURIData(PVBGLR3GUESTDNDCMDCTX pCtx, PVBOXDNDSNDDATAHDR pDataHdr, PDNDDROPPEDFILES pDroppedFiles) 352 352 { 353 353 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 384 384 * Create and query the (unique) drop target directory in the user's temporary directory. 385 385 */ 386 int rc = pDroppedFiles->OpenTemp(0 /* fFlags */);386 int rc = DnDDroppedFilesOpenTemp(pDroppedFiles, 0 /* fFlags */); 387 387 if (RT_FAILURE(rc)) 388 388 { … … 391 391 } 392 392 393 const char *pszDropDir = pDroppedFiles->GetDirAbs();393 const char *pszDropDir = DnDDroppedFilesGetDirAbs(pDroppedFiles); 394 394 AssertPtr(pszDropDir); 395 395 … … 397 397 * Enter the main loop of retieving files + directories. 398 398 */ 399 DnDURIObject objFile; 399 DNDTRANSFEROBJECT objCur; 400 RT_ZERO(objCur); 400 401 401 402 char szPathName[RTPATH_MAX] = { 0 }; … … 424 425 &cbPathName, 425 426 &fMode); 426 LogFlowFunc(("HOST_DND_HG_SND_DIR pszPathName=%s, cbPathName=%RU32, fMode=0x%x, rc=%Rrc\n", 427 LogFlowFunc(("HOST_DND_HG_SND_DIR: " 428 "pszPathName=%s, cbPathName=%RU32, fMode=0x%x, rc=%Rrc\n", 427 429 szPathName, cbPathName, fMode, rc)); 428 430 … … 437 439 rc = RTDirCreate(pszPathAbs, fCreationMode, 0); 438 440 if (RT_SUCCESS(rc)) 439 rc = pDroppedFiles->AddDir(pszPathAbs);441 rc = DnDDroppedFilesAddDir(pDroppedFiles, pszPathAbs); 440 442 441 443 if (RT_SUCCESS(rc)) … … 452 454 } 453 455 case HOST_DND_HG_SND_FILE_HDR: 456 RT_FALL_THROUGH(); 454 457 case HOST_DND_HG_SND_FILE_DATA: 455 458 { … … 489 492 490 493 /* Is there already a file open, e.g. in transfer? */ 491 if (! objFile.IsOpen())494 if (!DnDTransferObjectIsOpen(&objCur)) 492 495 { 493 RTCString strPathAbs(pszPathAbs);494 496 #ifdef RT_OS_WINDOWS 495 497 uint32_t fCreationMode = (fMode & RTFS_DOS_MASK) | RTFS_DOS_NT_NORMAL; … … 497 499 uint32_t fCreationMode = (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR; 498 500 #endif 499 rc = objFile.Init(DnDURIObject::Type_File, strPathAbs); 501 rc = DnDTransferObjectInit(&objCur, DNDTRANSFEROBJTYPE_FILE, 502 pszDropDir /* Source (base) path */, szPathName /* Destination path */); 500 503 if (RT_SUCCESS(rc)) 501 504 { 502 rc = objFile.Open(fOpen, fCreationMode);505 rc = DnDTransferObjectOpen(&objCur, fOpen, fCreationMode, DNDTRANSFEROBJECT_FLAGS_NONE); 503 506 if (RT_SUCCESS(rc)) 504 507 { 505 rc = pDroppedFiles->AddFile(strPathAbs.c_str());508 rc = DnDDroppedFilesAddFile(pDroppedFiles, pszPathAbs); 506 509 if (RT_SUCCESS(rc)) 507 510 { 508 511 cbFileWritten = 0; 509 objFile.SetSize(cbFileSize);512 DnDTransferObjectSetSize(&objCur, cbFileSize); 510 513 } 511 514 } … … 514 517 else 515 518 { 516 AssertMsgFailed(("ObjType=%RU32\n", objFile.GetType()));519 AssertMsgFailed(("ObjType=%RU32\n", DnDTransferObjectGetType(&objCur))); 517 520 rc = VERR_WRONG_ORDER; 518 521 } … … 529 532 { 530 533 uint32_t cbChunkWritten; 531 rc = objFile.Write(pvChunk, cbChunkRead, &cbChunkWritten);534 rc = DnDTransferObjectWrite(&objCur, pvChunk, cbChunkRead, &cbChunkWritten); 532 535 if (RT_SUCCESS(rc)) 533 536 { 534 LogFlowFunc(("HOST_DND_HG_SND_FILE_DATA "537 LogFlowFunc(("HOST_DND_HG_SND_FILE_DATA: " 535 538 "cbChunkRead=%RU32, cbChunkWritten=%RU32, cbFileWritten=%RU64 cbFileSize=%RU64\n", 536 539 cbChunkRead, cbChunkWritten, cbFileWritten + cbChunkWritten, cbFileSize)); … … 544 547 545 548 /* Data transfer complete? Close the file. */ 546 bool fClose = objFile.IsComplete();549 bool fClose = DnDTransferObjectIsComplete(&objCur); 547 550 if (fClose) 548 551 { … … 557 560 { 558 561 LogFlowFunc(("Closing file\n")); 559 objFile.Close();562 DnDTransferObjectDestroy(&objCur); 560 563 } 561 564 … … 604 607 if (RT_FAILURE(rc)) 605 608 { 606 objFile.Close();607 pDroppedFiles->Rollback();609 DnDTransferObjectDestroy(&objCur); 610 DnDDroppedFilesRollback(pDroppedFiles); 608 611 } 609 612 else 610 613 { 611 /** @todo Compare the URIlist with the dirs/files we really transferred. */614 /** @todo Compare the transfer list with the dirs/files we really transferred. */ 612 615 /** @todo Implement checksum verification, if any. */ 613 616 } … … 618 621 * by the client's drag'n drop operation lateron. 619 622 */ 620 int rc2 = pDroppedFiles->Reset(false /* fRemoveDropDir */);623 int rc2 = DnDDroppedFilesReset(pDroppedFiles, false /* fRemoveDropDir */); 621 624 if (RT_FAILURE(rc2)) /* Not fatal, don't report back to host. */ 622 625 LogFlowFunc(("Closing dropped files directory failed with %Rrc\n", rc2)); … … 805 808 /** 806 809 * Host -> Guest 807 * Main function for receiving the actual DnD data from the host, extended version. 808 * 809 * @returns IPRT status code. 810 * @param pCtx DnD context to use. 811 * @param pEnmType Where to store the meta data type. Optional. 812 * @param ppvData Returns the received meta data. Needs to be free'd by the caller. Optional. 813 * @param pcbData Where to store the size (in bytes) of the received meta data. Optional. 814 */ 815 static int vbglR3DnDHGRecvDataMainEx(PVBGLR3GUESTDNDCMDCTX pCtx, 816 VBGLR3GUESTDNDMETADATATYPE *pEnmType, 817 void **ppvData, 818 uint32_t *pcbData) 810 * Main function for receiving the actual DnD data from the host. 811 * 812 * @returns IPRT status code. 813 * @param pCtx DnD context to use. 814 * @param pMeta Where to store the actual meta data received from the host. 815 */ 816 static int vbglR3DnDHGRecvDataMain(PVBGLR3GUESTDNDCMDCTX pCtx, 817 PVBGLR3GUESTDNDMETADATA pMeta) 819 818 { 820 819 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 821 /* The rest is optional. */820 AssertPtrReturn(pMeta, VERR_INVALID_POINTER); 822 821 823 822 VBOXDNDDATAHDR dataHdr; … … 831 830 return VERR_NO_MEMORY; 832 831 833 DnDURIList lstURI; 834 DnDDroppedFiles droppedFiles; 832 DNDDROPPEDFILES droppedFiles; 835 833 836 834 void *pvData = NULL; … … 855 853 Assert(cbData); 856 854 857 rc = lstURI.SetFromURIData(pvData, cbData, 0 /* fFlags */); 855 /* Use the dropped files directory as the root directory for the current transfer. */ 856 rc = DnDTransferListInit(&pMeta->u.URI.Transfer, DnDDroppedFilesGetDirAbs(&droppedFiles)); 858 857 if (RT_SUCCESS(rc)) 859 rc = vbglR3DnDHGRecvURIData(pCtx, &dataHdr, &droppedFiles);860 861 if (RT_SUCCESS(rc)) /** @todo Remove this block as soon as we hand in DnDURIList. */862 858 { 863 if (pvData) 864 { 865 /* Reuse data buffer to fill in the transformed URI file list. */ 866 RTMemFree(pvData); 867 pvData = NULL; 868 } 869 870 RTCString strData = lstURI.GetRootEntries(droppedFiles.GetDirAbs()); 871 Assert(!strData.isEmpty()); 872 873 cbData = strData.length() + 1; 874 LogFlowFunc(("URI list has %zu bytes\n", cbData)); 875 876 pvData = RTMemAlloc(cbData); 877 if (pvData) 878 { 879 memcpy(pvData, strData.c_str(), cbData); 880 881 if (pEnmType) 882 *pEnmType = VBGLR3GUESTDNDMETADATATYPE_URI_LIST; 883 } 884 else 885 rc = VERR_NO_MEMORY; 859 rc = DnDTransferListAppendPathsFromBuffer(&pMeta->u.URI.Transfer, DNDTRANSFERLISTFMT_URI, (const char *)pvData, cbData, 860 DND_PATH_SEPARATOR, 0 /* fFlags */); 861 if (RT_SUCCESS(rc)) 862 rc = vbglR3DnDHGRecvURIData(pCtx, &dataHdr, &droppedFiles); 886 863 } 887 864 } 888 865 else /* Raw data. */ 889 866 { 890 if (pEnmType) 891 *pEnmType = VBGLR3GUESTDNDMETADATATYPE_RAW; 867 pMeta->enmType = VBGLR3GUESTDNDMETADATATYPE_RAW; 892 868 } 893 869 } … … 898 874 if (RT_SUCCESS(rc)) 899 875 { 900 if ( pvData 901 && cbData) 902 { 903 if (pcbData) 904 *pcbData = cbData; 905 if (ppvData) 906 *ppvData = pvData; 907 else 908 RTMemFree(pvData); 909 } 876 910 877 } 911 878 else if ( RT_FAILURE(rc) … … 921 888 922 889 LogFlowFuncLeaveRC(rc); 923 return rc;924 }925 926 /**927 * Host -> Guest928 * Main function for receiving the actual DnD data from the host.929 *930 * @returns IPRT status code.931 * @param pCtx DnD context to use.932 * @param pMeta Where to store the actual meta data received from the host.933 */934 static int vbglR3DnDHGRecvDataMain(PVBGLR3GUESTDNDCMDCTX pCtx,935 PVBGLR3GUESTDNDMETADATA pMeta)936 {937 AssertPtrReturn(pMeta, VERR_INVALID_POINTER);938 939 int rc = vbglR3DnDHGRecvDataMainEx(pCtx,940 &pMeta->enmType,941 &pMeta->pvMeta,942 &pMeta->cbMeta);943 890 return rc; 944 891 } … … 1300 1247 { 1301 1248 PVBGLR3GUESTDNDMETADATA pMeta = &pEvent->u.HG_Received.Meta; 1302 if (pMeta->pvMeta)1249 switch (pMeta->enmType) 1303 1250 { 1304 Assert(pMeta->cbMeta); 1305 RTMemFree(pMeta->pvMeta); 1306 pMeta->cbMeta = 0; 1251 case VBGLR3GUESTDNDMETADATATYPE_RAW: 1252 { 1253 if (pMeta->u.Raw.pvMeta) 1254 { 1255 Assert(pMeta->u.Raw.cbMeta); 1256 RTMemFree(pMeta->u.Raw.pvMeta); 1257 pMeta->u.Raw.cbMeta = 0; 1258 } 1259 break; 1260 } 1261 1262 case VBGLR3GUESTDNDMETADATATYPE_URI_LIST: 1263 { 1264 DnDTransferListDestroy(&pMeta->u.URI.Transfer); 1265 break; 1266 } 1267 1268 default: 1269 break; 1307 1270 } 1308 1271 break; … … 1503 1466 * @returns IPRT status code. 1504 1467 * @param pCtx DnD context to use. 1505 * @param pObj URIobject containing the directory to send.1506 */ 1507 static int vbglR3DnDGHSendDir(PVBGLR3GUESTDNDCMDCTX pCtx, D nDURIObject*pObj)1468 * @param pObj transfer object containing the directory to send. 1469 */ 1470 static int vbglR3DnDGHSendDir(PVBGLR3GUESTDNDCMDCTX pCtx, DNDTRANSFEROBJECT *pObj) 1508 1471 { 1509 1472 AssertPtrReturn(pObj, VERR_INVALID_POINTER); 1510 1473 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1511 AssertReturn(pObj->GetType() == DnDURIObject::Type_Directory, VERR_INVALID_PARAMETER); 1512 1513 RTCString strPath = pObj->GetPath(); 1514 LogFlowFunc(("strDir=%s (%zu), fMode=0x%x\n", 1515 strPath.c_str(), strPath.length(), pObj->GetMode())); 1516 1517 if (strPath.length() > RTPATH_MAX) 1474 AssertReturn(DnDTransferObjectGetType(pObj) == DNDTRANSFEROBJTYPE_DIRECTORY, VERR_INVALID_PARAMETER); 1475 1476 const char *pcszPath = DnDTransferObjectGetDestPath(pObj); 1477 const size_t cchPath = RTStrNLen(pcszPath, RTPATH_MAX); 1478 const RTFMODE fMode = DnDTransferObjectGetMode(pObj); 1479 1480 LogFlowFunc(("strDir=%s (%zu), fMode=0x%x\n", pcszPath, cchPath, fMode)); 1481 1482 if (cchPath > RTPATH_MAX) /* Can't happen, but check anyway. */ 1518 1483 return VERR_INVALID_PARAMETER; 1519 1520 const uint32_t cbPath = (uint32_t)strPath.length() + 1; /* Include termination. */1521 1484 1522 1485 HGCMMsgGHSendDir Msg; … … 1524 1487 /** @todo Context ID not used yet. */ 1525 1488 Msg.u.v3.uContext.SetUInt32(0); 1526 Msg.u.v3.pvName.SetPtr((void *) strPath.c_str(), (uint32_t)cbPath);1527 Msg.u.v3.cbName.SetUInt32((uint32_t)c bPath);1528 Msg.u.v3.fMode.SetUInt32( pObj->GetMode());1489 Msg.u.v3.pvName.SetPtr((void *)pcszPath, (uint32_t)cchPath); 1490 Msg.u.v3.cbName.SetUInt32((uint32_t)cchPath + 1); /* Include termination. */ 1491 Msg.u.v3.fMode.SetUInt32(fMode); 1529 1492 1530 1493 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); … … 1537 1500 * @returns IPRT status code. 1538 1501 * @param pCtx DnD context to use. 1539 * @param pObj URIobject containing the file to send.1540 */ 1541 static int vbglR3DnDGHSendFile(PVBGLR3GUESTDNDCMDCTX pCtx, DnDURIObject *pObj)1502 * @param pObj Transfer object containing the file to send. 1503 */ 1504 static int vbglR3DnDGHSendFile(PVBGLR3GUESTDNDCMDCTX pCtx, PDNDTRANSFEROBJECT pObj) 1542 1505 { 1543 1506 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1544 1507 AssertPtrReturn(pObj, VERR_INVALID_POINTER); 1545 AssertReturn( pObj->GetType() == DnDURIObject::Type_File, VERR_INVALID_PARAMETER);1546 AssertReturn( pObj->IsOpen(),VERR_INVALID_STATE);1508 AssertReturn(DnDTransferObjectGetType(pObj) == DNDTRANSFEROBJTYPE_FILE, VERR_INVALID_PARAMETER); 1509 AssertReturn(DnDTransferObjectIsOpen(pObj), VERR_INVALID_STATE); 1547 1510 1548 1511 uint32_t cbBuf = _64K; /** @todo Make this configurable? */ … … 1551 1514 return VERR_NO_MEMORY; 1552 1515 1553 RTCString strPath = pObj->GetPath(); 1554 1555 LogFlowFunc(("strFile=%s (%zu), cbSize=%RU64, fMode=0x%x\n", strPath.c_str(), strPath.length(), 1556 pObj->GetSize(), pObj->GetMode())); 1516 const char *pcszPath = DnDTransferObjectGetDestPath(pObj); 1517 const size_t cchPath = RTStrNLen(pcszPath, RTPATH_MAX); 1518 const uint64_t cbSize = DnDTransferObjectGetSize(pObj); 1519 const RTFMODE fMode = DnDTransferObjectGetMode(pObj); 1520 1521 LogFlowFunc(("strFile=%s (%zu), cbSize=%RU64, fMode=0x%x\n", pcszPath, cchPath, cbSize, fMode)); 1557 1522 1558 1523 HGCMMsgGHSendFileHdr MsgHdr; 1559 1524 VBGL_HGCM_HDR_INIT(&MsgHdr.hdr, pCtx->uClientID, GUEST_DND_GH_SND_FILE_HDR, 6); 1560 1525 MsgHdr.uContext.SetUInt32(0); /* Context ID; unused at the moment. */ 1561 MsgHdr.pvName.SetPtr((void *) strPath.c_str(), (uint32_t)(strPath.length() + 1));1562 MsgHdr.cbName.SetUInt32((uint32_t)( strPath.length() + 1));1526 MsgHdr.pvName.SetPtr((void *)pcszPath, (uint32_t)(cchPath + 1)); /* Include termination. */ 1527 MsgHdr.cbName.SetUInt32((uint32_t)(cchPath + 1)); /* Ditto. */ 1563 1528 MsgHdr.uFlags.SetUInt32(0); /* Flags; unused at the moment. */ 1564 MsgHdr.fMode.SetUInt32( pObj->GetMode());/* File mode */1565 MsgHdr.cbTotal.SetUInt64( pObj->GetSize());/* File size (in bytes). */1529 MsgHdr.fMode.SetUInt32(fMode); /* File mode */ 1530 MsgHdr.cbTotal.SetUInt64(cbSize); /* File size (in bytes). */ 1566 1531 1567 1532 int rc = VbglR3HGCMCall(&MsgHdr.hdr, sizeof(MsgHdr)); … … 1580 1545 Msg.u.v3.cbChecksum.SetUInt32(0); 1581 1546 1582 uint64_t cbToReadTotal = pObj->GetSize();1547 uint64_t cbToReadTotal = cbSize; 1583 1548 uint64_t cbWrittenTotal = 0; 1584 1549 while (cbToReadTotal) … … 1587 1552 uint32_t cbRead = 0; 1588 1553 if (cbToRead) 1589 rc = pObj->Read(pvBuf, cbToRead, &cbRead);1554 rc = DnDTransferObjectRead(pObj, pvBuf, cbToRead, &cbRead); 1590 1555 1591 1556 LogFlowFunc(("cbToReadTotal=%RU64, cbToRead=%RU32, cbRead=%RU32, rc=%Rrc\n", … … 1612 1577 cbWrittenTotal += cbRead; 1613 1578 1614 LogFlowFunc(("%RU64/%RU64 -- %RU8%%\n", cbWrittenTotal, pObj->GetSize(), cbWrittenTotal * 100 / pObj->GetSize()));1579 LogFlowFunc(("%RU64/%RU64 -- %RU8%%\n", cbWrittenTotal, cbSize, cbWrittenTotal * 100 / cbSize)); 1615 1580 }; 1616 1581 } … … 1624 1589 /** 1625 1590 * Guest -> Host 1626 * Utility function to send a n URIobject from guest to the host.1627 * 1628 * @returns IPRT status code. 1629 * @param pCtx DnD context to use. 1630 * @param pObj URIobject to send from guest to the host.1631 */ 1632 static int vbglR3DnDGHSendURIObject(PVBGLR3GUESTDNDCMDCTX pCtx, DnDURIObject *pObj)1591 * Utility function to send a transfer object from guest to the host. 1592 * 1593 * @returns IPRT status code. 1594 * @param pCtx DnD context to use. 1595 * @param pObj Transfer object to send from guest to the host. 1596 */ 1597 static int vbglR3DnDGHSendURIObject(PVBGLR3GUESTDNDCMDCTX pCtx, PDNDTRANSFEROBJECT pObj) 1633 1598 { 1634 1599 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1637 1602 int rc; 1638 1603 1639 switch (pObj->GetType()) 1640 { 1641 case DnDURIObject::Type_Directory: 1604 const DNDTRANSFEROBJTYPE enmType = DnDTransferObjectGetType(pObj); 1605 1606 switch (enmType) 1607 { 1608 case DNDTRANSFEROBJTYPE_DIRECTORY: 1642 1609 rc = vbglR3DnDGHSendDir(pCtx, pObj); 1643 1610 break; 1644 1611 1645 case D nDURIObject::Type_File:1612 case DNDTRANSFEROBJTYPE_FILE: 1646 1613 rc = vbglR3DnDGHSendFile(pCtx, pObj); 1647 1614 break; 1648 1615 1649 1616 default: 1650 AssertMsgFailed(("Object type %ld not implemented\n", pObj->GetType()));1617 AssertMsgFailed(("Object type %ld not implemented\n", enmType)); 1651 1618 rc = VERR_NOT_IMPLEMENTED; 1652 1619 break; … … 1682 1649 /** 1683 1650 * Guest -> Host 1684 * Utility function to send URI data from guest to the host. 1685 * 1686 * @returns IPRT status code. 1687 * @param pCtx DnD context to use. 1688 * @param pvData Block to URI data to send. 1689 * @param cbData Size (in bytes) of URI data to send. 1690 */ 1691 static int vbglR3DnDGHSendURIData(PVBGLR3GUESTDNDCMDCTX pCtx, const void *pvData, size_t cbData) 1692 { 1693 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1694 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 1695 AssertReturn(cbData, VERR_INVALID_PARAMETER); 1696 1697 RTCList<RTCString> lstPaths = 1698 RTCString((const char *)pvData, cbData).split("\r\n"); 1699 1700 /** @todo Add symlink support (DNDURILIST_FLAGS_RESOLVE_SYMLINKS) here. */ 1701 /** @todo Add lazy loading (DNDURILIST_FLAGS_LAZY) here. */ 1702 uint32_t fFlags = DNDURILIST_FLAGS_KEEP_OPEN; 1703 1704 DnDURIList lstURI; 1705 int rc = lstURI.AppendURIPathsFromList(lstPaths, fFlags); 1651 * Utility function to send transfer data from guest to the host. 1652 * 1653 * @returns IPRT status code. 1654 * @param pCtx DnD context to use. 1655 * @param pTransferList Dnd transfer list to send. 1656 */ 1657 static int vbglR3DnDGHSendTransferData(PVBGLR3GUESTDNDCMDCTX pCtx, PDNDTRANSFERLIST pTransferList) 1658 { 1659 AssertPtrReturn(pCtx,VERR_INVALID_POINTER); 1660 AssertPtrReturn(pTransferList, VERR_INVALID_POINTER); 1661 1662 /* 1663 * Send the (meta) data; in case of URIs it's the root entries of a 1664 * transfer list the host needs to know upfront to set up the drag'n drop operation. 1665 */ 1666 char *pszList = NULL; 1667 size_t cbList; 1668 int rc = DnDTransferListGetRoots(pTransferList, DNDTRANSFERLISTFMT_URI, &pszList, &cbList); 1669 if (RT_FAILURE(rc)) 1670 return rc; 1671 1672 void *pvURIList = (void *)pszList; 1673 uint32_t cbURLIist = (uint32_t)cbList; 1674 1675 /* The total size also contains the size of the meta data. */ 1676 uint64_t cbTotal = cbURLIist; 1677 cbTotal += DnDTransferListObjTotalBytes(pTransferList); 1678 1679 /* We're going to send a transfer list in text format. */ 1680 const char szMetaFmt[] = "text/uri-list"; 1681 const uint32_t cbMetaFmt = (uint32_t)strlen(szMetaFmt) + 1; /* Include termination. */ 1682 1683 VBOXDNDDATAHDR dataHdr; 1684 dataHdr.uFlags = 0; /* Flags not used yet. */ 1685 dataHdr.cbTotal = cbTotal; 1686 dataHdr.cbMeta = cbURLIist; 1687 dataHdr.pvMetaFmt = (void *)szMetaFmt; 1688 dataHdr.cbMetaFmt = cbMetaFmt; 1689 dataHdr.cObjects = DnDTransferListObjCount(pTransferList); 1690 1691 rc = vbglR3DnDGHSendDataInternal(pCtx, pvURIList, cbURLIist, &dataHdr); 1692 1706 1693 if (RT_SUCCESS(rc)) 1707 1694 { 1708 /* 1709 * Send the (meta) data; in case of URIs it's the (non-recursive) file/directory 1710 * URI list the host needs to know upfront to set up the drag'n drop operation. 1711 */ 1712 RTCString strRootDest = lstURI.GetRootEntries(); 1713 if (strRootDest.isNotEmpty()) 1695 while (DnDTransferListObjCount(pTransferList)) 1714 1696 { 1715 void *pvURIList = (void *)strRootDest.c_str(); /* URI root list. */ 1716 uint32_t cbURLIist = (uint32_t)strRootDest.length() + 1; /* Include string termination. */ 1717 1718 /* The total size also contains the size of the meta data. */ 1719 uint64_t cbTotal = cbURLIist; 1720 cbTotal += lstURI.GetTotalBytes(); 1721 1722 /* We're going to send an URI list in text format. */ 1723 const char szMetaFmt[] = "text/uri-list"; 1724 const uint32_t cbMetaFmt = (uint32_t)strlen(szMetaFmt) + 1; /* Include termination. */ 1725 1726 VBOXDNDDATAHDR dataHdr; 1727 dataHdr.uFlags = 0; /* Flags not used yet. */ 1728 dataHdr.cbTotal = cbTotal; 1729 dataHdr.cbMeta = cbURLIist; 1730 dataHdr.pvMetaFmt = (void *)szMetaFmt; 1731 dataHdr.cbMetaFmt = cbMetaFmt; 1732 dataHdr.cObjects = lstURI.GetTotalCount(); 1733 1734 rc = vbglR3DnDGHSendDataInternal(pCtx, 1735 pvURIList, cbURLIist, &dataHdr); 1736 } 1737 else 1738 rc = VERR_INVALID_PARAMETER; 1739 } 1740 1741 if (RT_SUCCESS(rc)) 1742 { 1743 while (!lstURI.IsEmpty()) 1744 { 1745 DnDURIObject *pNextObj = lstURI.First(); 1746 1747 rc = vbglR3DnDGHSendURIObject(pCtx, pNextObj); 1697 PDNDTRANSFEROBJECT pObj = DnDTransferListObjGetFirst(pTransferList); 1698 1699 rc = vbglR3DnDGHSendURIObject(pCtx, pObj); 1748 1700 if (RT_FAILURE(rc)) 1749 1701 break; 1750 1702 1751 lstURI.RemoveFirst();1703 DnDTransferListObjRemoveFirst(pTransferList); 1752 1704 } 1705 1706 Assert(DnDTransferListObjCount(pTransferList) == 0); 1753 1707 } 1754 1708 … … 1779 1733 if (DnDMIMEHasFileURLs(pszFormat, strlen(pszFormat))) 1780 1734 { 1781 /* Send file data. */ 1782 rc = vbglR3DnDGHSendURIData(pCtx, pvData, cbData); 1735 DNDTRANSFERLIST lstTransfer; 1736 rc = DnDTransferListInit(&lstTransfer, NULL /* pcszRootPathAbs */); 1737 if (RT_SUCCESS(rc)) 1738 { 1739 /** @todo Add symlink support (DNDTRANSFERLIST_FLAGS_RESOLVE_SYMLINKS) here. */ 1740 /** @todo Add lazy loading (DNDTRANSFERLIST_FLAGS_LAZY) here. */ 1741 const DNDTRANSFERLISTFLAGS fFlags = DNDTRANSFERLIST_FLAGS_KEEP_OPEN; 1742 1743 rc = DnDTransferListAppendPathsFromBuffer(&lstTransfer, DNDTRANSFERLISTFMT_NATIVE, (const char *)pvData, cbData, 1744 DND_PATH_SEPARATOR, fFlags); 1745 if (RT_SUCCESS(rc)) 1746 rc = vbglR3DnDGHSendTransferData(pCtx, &lstTransfer); 1747 DnDTransferListDestroy(&lstTransfer); 1748 } 1783 1749 } 1784 1750 else -
trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
r82968 r85371 549 549 int hgMove(uint32_t uPosX, uint32_t uPosY, VBOXDNDACTION dndActionDefault); 550 550 int hgDrop(uint32_t uPosX, uint32_t uPosY, VBOXDNDACTION dndActionDefault); 551 int hgDataReceive(PVBGLR3GUESTDNDMETADATA pMeta Data);551 int hgDataReceive(PVBGLR3GUESTDNDMETADATA pMeta); 552 552 553 553 /* X11 helpers. */ … … 1900 1900 * 1901 1901 * @returns IPRT status code. 1902 * @param pMeta DataPointer to meta data from host.1903 */ 1904 int DragInstance::hgDataReceive(PVBGLR3GUESTDNDMETADATA pMeta Data)1902 * @param pMeta Pointer to meta data from host. 1903 */ 1904 int DragInstance::hgDataReceive(PVBGLR3GUESTDNDMETADATA pMeta) 1905 1905 { 1906 1906 LogFlowThisFunc(("enmMode=%RU32, enmState=%RU32\n", m_enmMode, m_enmState)); 1907 LogFlowThisFunc(("enmMeta DataType=%RU32\n", pMetaData->enmType));1907 LogFlowThisFunc(("enmMetaType=%RU32\n", pMeta->enmType)); 1908 1908 1909 1909 if ( m_enmMode != HG … … 1913 1913 } 1914 1914 1915 if ( pMetaData->pvMeta == NULL 1916 || pMetaData->cbMeta == 0) 1917 { 1918 return VERR_INVALID_PARAMETER; 1919 } 1920 1921 int rc = VINF_SUCCESS; 1922 1923 const void *pvData = pMetaData->pvMeta; 1924 const uint32_t cbData = pMetaData->cbMeta; 1915 void *pvData = NULL; 1916 size_t cbData = 0; 1917 1918 int rc; 1919 1920 switch (pMeta->enmType) 1921 { 1922 case VBGLR3GUESTDNDMETADATATYPE_RAW: 1923 { 1924 AssertBreakStmt(pMeta->u.Raw.pvMeta != NULL, rc = VERR_INVALID_POINTER); 1925 pvData = pMeta->u.Raw.pvMeta; 1926 AssertBreakStmt(pMeta->u.Raw.cbMeta, rc = VERR_INVALID_PARAMETER); 1927 cbData = pMeta->u.Raw.cbMeta; 1928 1929 rc = VINF_SUCCESS; 1930 break; 1931 } 1932 1933 case VBGLR3GUESTDNDMETADATATYPE_URI_LIST: 1934 { 1935 VBClLogInfo(("URI transfer root directory is '%s'\n", DnDTransferListGetRootPathAbs(&pMeta->u.URI.Transfer))); 1936 1937 /* Note: The transfer list already has its root set to a temporary directory, so no need to set/add a new 1938 * path base here. */ 1939 rc = DnDTransferListGetRootsEx(&pMeta->u.URI.Transfer, DNDTRANSFERLISTFMT_NATIVE, NULL /* pszPathBase */, 1940 DND_PATH_SEPARATOR, (char **)&pvData, &cbData); 1941 break; 1942 } 1943 1944 default: 1945 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED); 1946 break; 1947 } 1948 1949 if (RT_FAILURE(rc)) 1950 return rc; 1925 1951 1926 1952 /* … … 1928 1954 * be on the guest, so proceed working on communicating with the target window. 1929 1955 */ 1930 VBClLogInfo("Received %RU32 bytes of URI listmeta data from host\n", cbData);1956 VBClLogInfo("Received %RU32 bytes of meta data from host\n", cbData); 1931 1957 1932 1958 /* Destroy any old data. */
Note:
See TracChangeset
for help on using the changeset viewer.