Changeset 59842 in vbox
- Timestamp:
- Feb 26, 2016 10:50:00 AM (9 years ago)
- Location:
- trunk/src/VBox/Main/src-client
- Files:
-
- 2 edited
-
GuestDnDPrivate.cpp (modified) (4 diffs)
-
GuestDnDSourceImpl.cpp (modified) (22 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/GuestDnDPrivate.cpp
r58330 r59842 6 6 7 7 /* 8 * Copyright (C) 2011-201 5Oracle Corporation8 * Copyright (C) 2011-2016 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 641 641 for (size_t i = 0; i < lstFormatsWanted.size(); i++) 642 642 { 643 /* Only keep allowed format types. */643 /* Only keep supported format types. */ 644 644 if (std::find(lstFormatsSupported.begin(), 645 645 lstFormatsSupported.end(), lstFormatsWanted.at(i)) != lstFormatsSupported.end()) … … 927 927 int GuestDnDBase::sendCancel(void) 928 928 { 929 int rc; 930 try 931 { 932 GuestDnDMsg *pMsgCancel = new GuestDnDMsg(); 933 pMsgCancel->setType(DragAndDropSvc::HOST_DND_HG_EVT_CANCEL); 934 935 rc = msgQueueAdd(pMsgCancel); 936 } 937 catch(std::bad_alloc & /*e*/) 938 { 939 rc = VERR_NO_MEMORY; 940 } 929 int rc = GuestDnDInst()->hostCall(HOST_DND_HG_EVT_CANCEL, 930 0 /* cParms */, NULL /* paParms */); 941 931 942 932 LogFlowFunc(("Generated cancelling request, rc=%Rrc\n", rc)); … … 975 965 976 966 int rc; 967 968 LogFlowFunc(("msTimeout=%RU32\n", msTimeout)); 977 969 978 970 uint64_t tsStart = RTTimeMilliTS(); -
trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp
r58519 r59842 5 5 6 6 /* 7 * Copyright (C) 2014-201 5Oracle Corporation7 * Copyright (C) 2014-2016 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 257 257 258 258 /* Default is ignoring the action. */ 259 DnDAction_T defaultAction = DnDAction_Ignore; 259 if (aDefaultAction) 260 *aDefaultAction = DnDAction_Ignore; 260 261 261 262 HRESULT hr = S_OK; … … 275 276 bool fFetchResult = true; 276 277 277 rc = pResp->waitForGuestResponse( 5000 /* Timeout in ms */);278 rc = pResp->waitForGuestResponse(100 /* Timeout in ms */); 278 279 if (RT_FAILURE(rc)) 279 280 fFetchResult = false; … … 286 287 if (fFetchResult) 287 288 { 288 defaultAction = GuestDnD::toMainAction(pResp->defAction());289 aAllowedActions = GuestDnD::toMainActions(pResp->allActions());290 291 289 /* 292 290 * In the GuestDnDSource case the source formats are from the guest, … … 295 293 * which are not supported by the host. 296 294 */ 297 aFormats = GuestDnD::toFilteredFormatList(m_lstFmtSupported, pResp->formats()); 298 299 /* Save the (filtered) formats. */ 300 m_lstFmtOffered = aFormats; 301 302 if (m_lstFmtOffered.size()) 295 GuestDnDMIMEList lstFiltered = GuestDnD::toFilteredFormatList(m_lstFmtSupported, pResp->formats()); 296 if (lstFiltered.size()) 303 297 { 304 LogRelMax(3, ("DnD: Offered formats:\n")); 305 for (size_t i = 0; i < m_lstFmtOffered.size(); i++) 306 LogRelMax(3, ("DnD:\tFormat #%zu: %s\n", i, m_lstFmtOffered.at(i).c_str())); 298 LogRel3(("DnD: Host offered the following formats:\n")); 299 for (size_t i = 0; i < lstFiltered.size(); i++) 300 LogRel3(("DnD:\tFormat #%zu: %s\n", i, lstFiltered.at(i).c_str())); 301 302 aFormats = lstFiltered; 303 aAllowedActions = GuestDnD::toMainActions(pResp->allActions()); 304 if (aDefaultAction) 305 *aDefaultAction = GuestDnD::toMainAction(pResp->defAction()); 306 307 /* Apply the (filtered) formats list. */ 308 m_lstFmtOffered = lstFiltered; 307 309 } 308 310 else 309 LogRelMax(3, ("DnD: No compatible format between guest and host found, drag and drop to host not possible\n")); 310 } 311 312 LogFlowFunc(("fFetchResult=%RTbool, defaultAction=0x%x, allActions=0x%x\n", 313 fFetchResult, defaultAction, pResp->allActions())); 314 315 if (aDefaultAction) 316 *aDefaultAction = defaultAction; 311 LogRel2(("DnD: Negotiation of formats between guest and host failed, drag and drop to host not possible\n")); 312 } 313 314 LogFlowFunc(("fFetchResult=%RTbool, allActions=0x%x\n", fFetchResult, pResp->allActions())); 317 315 } 318 316 … … 330 328 AutoCaller autoCaller(this); 331 329 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 330 331 LogFunc(("aFormat=%s, aAction=%RU32\n", aFormat.c_str(), aAction)); 332 332 333 333 /* Input validation. */ … … 379 379 } 380 380 381 //this function delete pTask in case of exceptions, so there is no need in the call of delete operator 381 /* This function delete pTask in case of exceptions, 382 * so there is no need in the call of delete operator. */ 382 383 hr = pTask->createThread(&threadRcv); 383 384 … … 651 652 } 652 653 } 654 else /* Raw data. */ 655 rc = updateProgress(pData, pCtx->mpResp, cbData); 653 656 } 654 657 } … … 790 793 } 791 794 } 792 793 /* 794 * Create new intermediate object to work with. 795 */ 796 rc = objCtx.createIntermediate(); 795 else 796 { 797 /* 798 * Create new intermediate object to work with. 799 */ 800 rc = objCtx.createIntermediate(); 801 } 802 797 803 if (RT_SUCCESS(rc)) 798 804 { 799 805 pObj = objCtx.getObj(); 806 AssertPtr(pObj); 800 807 801 808 const char *pszDroppedFilesDir = pCtx->mURI.getDroppedFiles().GetDirAbs(); 809 AssertPtr(pszDroppedFilesDir); 802 810 803 811 char pszPathAbs[RTPATH_MAX]; … … 963 971 * Do we need to receive a different format than initially requested? 964 972 * 965 * For example, receiving a file link as "text/plain" requires still to receive973 * For example, receiving a file link as "text/plain" requires still to receive 966 974 * the file from the guest as "text/uri-list" first, then pointing to 967 975 * the file path on the host in the "text/plain" data returned. 968 976 */ 969 977 970 /* Plain text needed? */ 971 if (pCtx->mFmtReq.equalsIgnoreCase("text/plain")) 978 bool fFoundFormat = true; /* Whether we've found a common format between host + guest. */ 979 980 LogFlowFunc(("mFmtReq=%s, mFmtRecv=%s, mAction=0x%x\n", 981 pCtx->mFmtReq.c_str(), pCtx->mFmtRecv.c_str(), pCtx->mAction)); 982 983 /* Plain text wanted? */ 984 if ( pCtx->mFmtReq.equalsIgnoreCase("text/plain") 985 || pCtx->mFmtReq.equalsIgnoreCase("text/plain;charset=utf-8")) 972 986 { 973 987 /* Did the guest offer a file? Receive a file instead. */ 974 988 if (GuestDnD::isFormatInFormatList("text/uri-list", pCtx->mFmtOffered)) 975 989 pCtx->mFmtRecv = "text/uri-list"; 990 /* Guest only offers (plain) text. */ 991 else 992 pCtx->mFmtRecv = "text/plain;charset=utf-8"; 976 993 977 994 /** @todo Add more conversions here. */ 978 995 } 979 980 if (pCtx->mFmtRecv.isEmpty()) 981 pCtx->mFmtRecv = pCtx->mFmtReq; 982 983 if (!pCtx->mFmtRecv.equals(pCtx->mFmtReq)) 984 LogRel3(("DnD: Requested data in format '%s', receiving in intermediate format '%s' now\n", 985 pCtx->mFmtReq.c_str(), pCtx->mFmtRecv.c_str())); 986 987 /* 988 * Call the appropriate receive handler based on the data format to handle. 989 */ 990 bool fHasURIList = DnDMIMENeedsDropDir(pCtx->mFmtRecv.c_str(), pCtx->mFmtRecv.length()); 991 LogFlowFunc(("strFormatReq=%s, strFormatRecv=%s, uAction=0x%x, fHasURIList=%RTbool\n", 992 pCtx->mFmtReq.c_str(), pCtx->mFmtRecv.c_str(), pCtx->mAction, fHasURIList)); 993 994 if (fHasURIList) 995 { 996 rc = i_receiveURIData(pCtx, msTimeout); 997 } 998 else 999 { 1000 rc = i_receiveRawData(pCtx, msTimeout); 996 /* File(s) wanted? */ 997 else if (pCtx->mFmtReq.equalsIgnoreCase("text/uri-list")) 998 { 999 /* Does the guest support sending files? */ 1000 if (GuestDnD::isFormatInFormatList("text/uri-list", pCtx->mFmtOffered)) 1001 pCtx->mFmtRecv = "text/uri-list"; 1002 else /* Bail out. */ 1003 fFoundFormat = false; 1004 } 1005 1006 if (fFoundFormat) 1007 { 1008 Assert(!pCtx->mFmtReq.isEmpty()); 1009 Assert(!pCtx->mFmtRecv.isEmpty()); 1010 1011 if (!pCtx->mFmtRecv.equals(pCtx->mFmtReq)) 1012 LogRel3(("DnD: Requested data in format '%s', receiving in intermediate format '%s' now\n", 1013 pCtx->mFmtReq.c_str(), pCtx->mFmtRecv.c_str())); 1014 1015 /* 1016 * Call the appropriate receive handler based on the data format to handle. 1017 */ 1018 bool fURIData = DnDMIMENeedsDropDir(pCtx->mFmtRecv.c_str(), pCtx->mFmtRecv.length()); 1019 if (fURIData) 1020 { 1021 rc = i_receiveURIData(pCtx, msTimeout); 1022 } 1023 else 1024 { 1025 rc = i_receiveRawData(pCtx, msTimeout); 1026 } 1027 } 1028 else /* Just inform the user (if verbose release logging is enabled). */ 1029 { 1030 LogRel2(("DnD: The guest does not support format '%s':\n", pCtx->mFmtReq.c_str())); 1031 LogRel2(("DnD: Guest offered the following formats:\n")); 1032 for (size_t i = 0; i < pCtx->mFmtOffered.size(); i++) 1033 LogRel2(("DnD:\tFormat #%zu: %s\n", i, pCtx->mFmtOffered.at(i).c_str())); 1001 1034 } 1002 1035 … … 1040 1073 1041 1074 int rc; 1075 1076 LogFlowFuncEnter(); 1042 1077 1043 1078 GuestDnDResponse *pResp = pCtx->mpResp; … … 1053 1088 return rc; 1054 1089 1055 #define UNREGISTER_CALLBACK(x) \ 1056 rc = pCtx->mpResp->setCallback(x, NULL); \ 1057 AssertRC(rc); 1090 #define UNREGISTER_CALLBACK(x) \ 1091 { \ 1092 int rc2 = pResp->setCallback(x, NULL); \ 1093 AssertRC(rc2); \ 1094 } 1058 1095 1059 1096 /* … … 1063 1100 REGISTER_CALLBACK(GUEST_DND_DISCONNECT); 1064 1101 REGISTER_CALLBACK(GUEST_DND_GH_EVT_ERROR); 1102 if (mDataBase.m_uProtocolVersion >= 3) 1103 REGISTER_CALLBACK(GUEST_DND_GH_SND_DATA_HDR); 1065 1104 REGISTER_CALLBACK(GUEST_DND_GH_SND_DATA); 1066 1105 … … 1096 1135 UNREGISTER_CALLBACK(GUEST_DND_DISCONNECT); 1097 1136 UNREGISTER_CALLBACK(GUEST_DND_GH_EVT_ERROR); 1137 if (mDataBase.m_uProtocolVersion >= 3) 1138 UNREGISTER_CALLBACK(GUEST_DND_GH_SND_DATA_HDR); 1098 1139 UNREGISTER_CALLBACK(GUEST_DND_GH_SND_DATA); 1099 1140 … … 1105 1146 if (rc == VERR_CANCELLED) 1106 1147 { 1107 int rc2 = pCtx->mpResp->setProgress(100, DND_PROGRESS_CANCELLED , VINF_SUCCESS);1148 int rc2 = pCtx->mpResp->setProgress(100, DND_PROGRESS_CANCELLED); 1108 1149 AssertRC(rc2); 1109 1150 … … 1127 1168 1128 1169 int rc; 1170 1171 LogFlowFuncEnter(); 1129 1172 1130 1173 GuestDnDResponse *pResp = pCtx->mpResp; … … 1220 1263 if (rc == VERR_CANCELLED) 1221 1264 { 1222 rc2 = pCtx->mpResp->setProgress(100, DND_PROGRESS_CANCELLED , VINF_SUCCESS);1265 rc2 = pCtx->mpResp->setProgress(100, DND_PROGRESS_CANCELLED); 1223 1266 AssertRC(rc2); 1224 1267 … … 1260 1303 1261 1304 int rcCallback = VINF_SUCCESS; /* rc for the callback. */ 1262 bool fNotify = false;1305 bool fNotify = false; 1263 1306 1264 1307 switch (uMsg) … … 1303 1346 1304 1347 if (RT_SUCCESS(pCBData->rc)) 1348 { 1349 AssertMsgFailed(("Received guest error with no error code set\n")); 1305 1350 pCBData->rc = VERR_GENERAL_FAILURE; /* Make sure some error is set. */ 1306 1307 rc = pCtx->mpResp->setProgress(100, DND_PROGRESS_ERROR, pCBData->rc, 1308 GuestDnDSource::i_guestErrorToString(pCBData->rc)); 1351 } 1352 else if (pCBData->rc == VERR_WRONG_ORDER) 1353 { 1354 rc = pCtx->mpResp->setProgress(100, DND_PROGRESS_CANCELLED); 1355 } 1356 else 1357 rc = pCtx->mpResp->setProgress(100, DND_PROGRESS_ERROR, pCBData->rc, 1358 GuestDnDSource::i_guestErrorToString(pCBData->rc)); 1359 1360 LogRel3(("DnD: Guest reported data transfer error: %Rrc\n", pCBData->rc)); 1361 1309 1362 if (RT_SUCCESS(rc)) 1310 1363 rcCallback = VERR_GSTDND_GUEST_ERROR; … … 1317 1370 } 1318 1371 1372 if ( RT_FAILURE(rc) 1373 || RT_FAILURE(rcCallback)) 1374 { 1375 fNotify = true; 1376 if (RT_SUCCESS(rcCallback)) 1377 rcCallback = rc; 1378 } 1379 1319 1380 if (RT_FAILURE(rc)) 1320 1381 { 1321 int rc2 = pCtx->mCBEvent.Notify(rc); 1382 switch (rc) 1383 { 1384 case VERR_NO_DATA: 1385 LogRel2(("DnD: Data transfer to host complete\n")); 1386 break; 1387 1388 case VERR_CANCELLED: 1389 LogRel2(("DnD: Data transfer to host canceled\n")); 1390 break; 1391 1392 default: 1393 LogRel(("DnD: Error %Rrc occurred, aborting data transfer to host\n", rc)); 1394 break; 1395 } 1396 1397 /* Unregister this callback. */ 1398 AssertPtr(pCtx->mpResp); 1399 int rc2 = pCtx->mpResp->setCallback(uMsg, NULL /* PFNGUESTDNDCALLBACK */); 1400 AssertRC(rc2); 1401 } 1402 1403 /* All data processed? */ 1404 if (pCtx->mData.isComplete()) 1405 fNotify = true; 1406 1407 LogFlowFunc(("cbProcessed=%RU64, cbToProcess=%RU64, fNotify=%RTbool, rcCallback=%Rrc, rc=%Rrc\n", 1408 pCtx->mData.getProcessed(), pCtx->mData.getTotal(), fNotify, rcCallback, rc)); 1409 1410 if (fNotify) 1411 { 1412 int rc2 = pCtx->mCBEvent.Notify(rcCallback); 1322 1413 AssertRC(rc2); 1323 1414 } … … 1430 1521 1431 1522 if (RT_SUCCESS(pCBData->rc)) 1523 { 1524 AssertMsgFailed(("Received guest error with no error code set\n")); 1432 1525 pCBData->rc = VERR_GENERAL_FAILURE; /* Make sure some error is set. */ 1433 1434 rc = pCtx->mpResp->setProgress(100, DND_PROGRESS_ERROR, pCBData->rc, 1435 GuestDnDSource::i_guestErrorToString(pCBData->rc)); 1526 } 1527 else if (pCBData->rc == VERR_WRONG_ORDER) 1528 { 1529 rc = pCtx->mpResp->setProgress(100, DND_PROGRESS_CANCELLED); 1530 } 1531 else 1532 rc = pCtx->mpResp->setProgress(100, DND_PROGRESS_ERROR, pCBData->rc, 1533 GuestDnDSource::i_guestErrorToString(pCBData->rc)); 1534 1535 LogRel3(("DnD: Guest reported file transfer error: %Rrc\n", pCBData->rc)); 1536 1436 1537 if (RT_SUCCESS(rc)) 1437 1538 rcCallback = VERR_GSTDND_GUEST_ERROR; … … 1457 1558 { 1458 1559 case VERR_NO_DATA: 1459 LogRel2(("DnD: Transfer to host complete\n"));1560 LogRel2(("DnD: File transfer to host complete\n")); 1460 1561 break; 1461 1562 1462 1563 case VERR_CANCELLED: 1463 LogRel2(("DnD: Transfer to host canceled\n"));1564 LogRel2(("DnD: File transfer to host canceled\n")); 1464 1565 break; 1465 1566 1466 1567 default: 1467 LogRel(("DnD: Error %Rrc occurred, aborting transfer to host\n", rc));1568 LogRel(("DnD: Error %Rrc occurred, aborting file transfer to host\n", rc)); 1468 1569 break; 1469 1570 }
Note:
See TracChangeset
for help on using the changeset viewer.

