Changeset 50561 in vbox
- Timestamp:
- Feb 24, 2014 9:07:22 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/GuestHost/DragAndDrop.h
r50508 r50561 56 56 public: 57 57 58 RTCStringGetSourcePath(void) const { return m_strSrcPath; }59 RTCStringGetDestPath(void) const { return m_strDstPath; }58 const RTCString &GetSourcePath(void) const { return m_strSrcPath; } 59 const RTCString &GetDestPath(void) const { return m_strDstPath; } 60 60 uint32_t GetMode(void) const { return m_fMode; } 61 61 uint64_t GetSize(void) const { return m_cbSize; } … … 110 110 void RemoveFirst(void); 111 111 int RootFromURIData(const void *pvData, size_t cbData, uint32_t fFlags); 112 RTCString RootToString(const RTCString &strBasePath = "" );112 RTCString RootToString(const RTCString &strBasePath = "", const RTCString &strSeparator = "\r\n"); 113 113 size_t RootCount(void) { return m_lstRoot.size(); } 114 114 size_t TotalBytes(void) { return m_cbTotal; } -
trunk/include/VBox/HostServices/DragAndDropSvc.h
r50508 r50561 73 73 74 74 HOST_DND_HG_EVT_ENTER = 200, 75 HOST_DND_HG_EVT_MOVE ,76 HOST_DND_HG_EVT_LEAVE ,77 HOST_DND_HG_EVT_DROPPED ,78 HOST_DND_HG_EVT_CANCEL ,75 HOST_DND_HG_EVT_MOVE = 201, 76 HOST_DND_HG_EVT_LEAVE = 202, 77 HOST_DND_HG_EVT_DROPPED = 203, 78 HOST_DND_HG_EVT_CANCEL = 204, 79 79 /** Gets the actual MIME data, based on 80 80 * the format(s) specified by HOST_DND_HG_EVT_ENTER. */ 81 HOST_DND_HG_SND_DATA ,81 HOST_DND_HG_SND_DATA = 205, 82 82 /** Sent when the actual buffer for HOST_DND_HG_SND_DATA 83 83 * was too small, issued by the DnD host service. */ 84 HOST_DND_HG_SND_MORE_DATA ,84 HOST_DND_HG_SND_MORE_DATA = 206, 85 85 /** Directory entry to be handled on the guest. */ 86 HOST_DND_HG_SND_DIR ,86 HOST_DND_HG_SND_DIR = 207, 87 87 /** File entry to be handled on the guest. */ 88 HOST_DND_HG_SND_FILE ,88 HOST_DND_HG_SND_FILE = 208, 89 89 90 90 /* … … 101 101 102 102 HOST_DND_GH_RECV_DIR = 650, 103 HOST_DND_GH_RECV_FILE 103 HOST_DND_GH_RECV_FILE = 670 104 104 }; 105 105 … … 124 124 /** The guest requests the actual DnD data to be sent 125 125 * from the host. */ 126 GUEST_DND_HG_REQ_DATA ,127 GUEST_DND_HG_EVT_PROGRESS ,126 GUEST_DND_HG_REQ_DATA = 401, 127 GUEST_DND_HG_EVT_PROGRESS = 402, 128 128 129 129 /* G->H */ … … 135 135 GUEST_DND_GH_ACK_PENDING = 500, 136 136 /** 137 * Sends data of the requ sted MIME typeto the host. There can137 * Sends data of the requested format to the host. There can 138 138 * be more than one message if the actual data does not fit 139 139 * into one. 140 140 */ 141 GUEST_DND_GH_SND_DATA ,142 GUEST_DND_GH_EVT_ERROR ,141 GUEST_DND_GH_SND_DATA = 501, 142 GUEST_DND_GH_EVT_ERROR = 502, 143 143 144 144 GUEST_DND_GH_SND_DIR = 700, 145 GUEST_DND_GH_SND_FILE 145 GUEST_DND_GH_SND_FILE = 701 146 146 }; 147 147 … … 376 376 /** Total bytes to send. This can be more than 377 377 * the data block specified in pvData above, e.g. 378 * when sending over file objects . */378 * when sending over file objects afterwards. */ 379 379 HGCMFunctionParameter cbTotalBytes; /* OUT uint32_t */ 380 380 } VBOXDNDGHSENDDATAMSG; … … 417 417 418 418 /** 419 * GH Cancel Dataevent.420 * 421 * Used by: 422 * GUEST_DND_GH_EVT_ CANCEL419 * GH Error event. 420 * 421 * Used by: 422 * GUEST_DND_GH_EVT_ERROR 423 423 */ 424 424 HGCMFunctionParameter uRC; /* OUT uint32_t */ -
trunk/include/VBox/HostServices/Service.h
r44529 r50561 43 43 public: 44 44 Message(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[]) 45 : m_uMsg(0)46 , m_cParms(0)47 , m_paParms(0)45 : m_uMsg(0) 46 , m_cParms(0) 47 , m_paParms(0) 48 48 { 49 49 setData(uMsg, cParms, aParms); -
trunk/include/VBox/VBoxGuestLib.h
r50508 r50561 724 724 VBGLR3DECL(int) VbglR3DnDGHAcknowledgePending(uint32_t u32ClientId, uint32_t uDefAction, uint32_t uAllActions, const char* pcszFormats); 725 725 VBGLR3DECL(int) VbglR3DnDGHSendData(uint32_t u32ClientId, const char *pszFormat, void *pvData, uint32_t cbData); 726 VBGLR3DECL(int) VbglR3DnDGH ErrorEvent(uint32_t u32ClientId, int rcOp);726 VBGLR3DECL(int) VbglR3DnDGHSendError(uint32_t u32ClientId, int rcOp); 727 727 # endif /* VBOX_WITH_DRAG_AND_DROP_GH */ 728 728 /** @} */ -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp
r50508 r50561 60 60 VBoxDnDWnd::VBoxDnDWnd(void) 61 61 : hWnd(NULL), 62 uAllActions(DND_IGNORE_ACTION), 62 63 mfMouseButtonDown(false), 63 64 #ifdef VBOX_WITH_DRAG_AND_DROP_GH … … 69 70 { 70 71 RT_ZERO(startupInfo); 71 72 reset();73 72 } 74 73 … … 209 208 else 210 209 { 211 LogRel Func(("Unable to initialize OLE, hr=%Rhrc\n", hr));210 LogRel(("DnD: Unable to initialize OLE, hr=%Rhrc\n", hr)); 212 211 rc = VERR_COM_UNEXPECTED; 213 212 } … … 380 379 else if (mMode == GH) /* Guest to host. */ 381 380 { 382 //hide();383 384 381 /* Starting here VBoxDnDDropTarget should 385 382 * take over; was instantiated when registering … … 405 402 { 406 403 VBOXDNDEVENT *pEvent = (PVBOXDNDEVENT)lParam; 407 AssertPtr(pEvent); 404 if (!pEvent) 405 break; /* No event received, bail out. */ 408 406 409 407 LogFlowThisFunc(("Received uType=%RU32, uScreenID=%RU32\n", … … 416 414 { 417 415 LogFlowThisFunc(("HOST_DND_HG_EVT_ENTER\n")); 418 419 reset();420 421 mMode = HG;422 416 423 417 if (pEvent->Event.cbFormats) … … 484 478 LogFlowThisFunc(("HOST_DND_GH_REQ_PENDING\n")); 485 479 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 486 if ( mMode == Unknown 487 /* There can be more than one HOST_DND_GH_REQ_PENDING 488 * messages coming in. */ 489 || mMode == GH) 490 { 491 mMode = GH; 492 rc = OnGhIsDnDPending(pEvent->Event.uScreenId); 493 } 494 else 495 rc = VERR_WRONG_ORDER; 480 rc = OnGhIsDnDPending(pEvent->Event.uScreenId); 481 496 482 #else 497 483 rc = VERR_NOT_SUPPORTED; … … 504 490 LogFlowThisFunc(("HOST_DND_GH_EVT_DROPPED\n")); 505 491 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 506 if (mMode == GH) 507 { 508 rc = OnGhDropped(pEvent->Event.pszFormats, 509 pEvent->Event.cbFormats, 510 pEvent->Event.u.a.uDefAction); 511 } 512 else 513 rc = VERR_WRONG_ORDER; 514 #else 515 rc = VERR_NOT_SUPPORTED; 516 #endif 517 break; 518 } 519 520 case DragAndDropSvc::GUEST_DND_GH_EVT_ERROR: 521 { 522 LogFlowThisFunc(("GUEST_DND_GH_EVT_ERROR\n")); 523 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 524 reset(); 525 rc = VINF_SUCCESS; /** @todo GUEST_DND_GH_EVT_ERROR */ 526 #else 527 rc = VERR_NOT_SUPPORTED; 528 #endif 529 break; 530 } 531 532 case DragAndDropSvc::HOST_DND_GH_RECV_DIR: 533 { 534 LogFlowThisFunc(("HOST_DND_GH_RECV_DIR\n")); 535 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 536 if (mMode == GH) 537 { 538 rc = OnGhSendDir(pEvent->Event.pszFormats, 539 pEvent->Event.cbFormats, 540 pEvent->Event.u.a.uDefAction); 541 } 542 else 543 rc = VERR_WRONG_ORDER; 544 #else 545 rc = VERR_NOT_SUPPORTED; 546 #endif 547 break; 548 } 549 550 case DragAndDropSvc::HOST_DND_GH_RECV_FILE: 551 { 552 LogFlowThisFunc(("HOST_DND_GH_RECV_FILE\n")); 553 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 554 if (mMode == GH) 555 { 556 rc = OnGhSendFile(pEvent->Event.pszFormats, 557 pEvent->Event.cbFormats, 558 pEvent->Event.u.a.uDefAction); 559 } 560 else 561 rc = VERR_WRONG_ORDER; 492 rc = OnGhDropped(pEvent->Event.pszFormats, 493 pEvent->Event.cbFormats, 494 pEvent->Event.u.a.uDefAction); 562 495 #else 563 496 rc = VERR_NOT_SUPPORTED; … … 600 533 } 601 534 602 LogFlowThisFunc(("Processing event %RU32 resulted in rc=%Rrc\n",603 pEvent->Event.uType, rc));604 535 if (pEvent) 536 { 537 LogFlowThisFunc(("Processing event %RU32 resulted in rc=%Rrc\n", 538 pEvent->Event.uType, rc)); 539 605 540 RTMemFree(pEvent); 541 } 606 542 return 0; 607 543 } … … 702 638 int VBoxDnDWnd::OnHgEnter(const RTCList<RTCString> &lstFormats, uint32_t uAllActions) 703 639 { 640 if (mMode == GH) /* Wrong mode? Bail out. */ 641 return VERR_WRONG_ORDER; 642 704 643 #ifdef DEBUG 705 644 LogFlowThisFunc(("uActions=0x%x, lstFormats=%zu: ", uAllActions, lstFormats.size())); … … 708 647 LogFlow(("\n")); 709 648 #endif 649 650 reset(); 651 setMode(HG); 710 652 711 653 /* Save all allowed actions. */ … … 779 721 int VBoxDnDWnd::OnHgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t uAction) 780 722 { 781 LogFlowThisFunc(("u32xPos=%RU32, u32yPos=%RU32, uAction=0x%x\n", 782 u32xPos, u32yPos, uAction)); 783 784 int rc = mouseMove(u32xPos, u32yPos, MOUSEEVENTF_LEFTDOWN); 723 int rc; 785 724 786 725 uint32_t uActionNotify = DND_IGNORE_ACTION; 787 if (RT_SUCCESS(rc)) 788 rc = RTCritSectEnter(&mCritSect); 789 if (RT_SUCCESS(rc)) 790 { 791 if ( (Dragging == mState) 792 && startupInfo.pDropSource) 793 uActionNotify = startupInfo.pDropSource->GetCurrentAction(); 794 795 RTCritSectLeave(&mCritSect); 796 } 726 if (mMode == HG) 727 { 728 LogFlowThisFunc(("u32xPos=%RU32, u32yPos=%RU32, uAction=0x%x\n", 729 u32xPos, u32yPos, uAction)); 730 731 rc = mouseMove(u32xPos, u32yPos, MOUSEEVENTF_LEFTDOWN); 732 733 if (RT_SUCCESS(rc)) 734 rc = RTCritSectEnter(&mCritSect); 735 if (RT_SUCCESS(rc)) 736 { 737 if ( (Dragging == mState) 738 && startupInfo.pDropSource) 739 uActionNotify = startupInfo.pDropSource->GetCurrentAction(); 740 741 RTCritSectLeave(&mCritSect); 742 } 743 } 744 else /* Just acknowledge the operation with an ignore action. */ 745 rc = VINF_SUCCESS; 797 746 798 747 if (RT_SUCCESS(rc)) … … 809 758 int VBoxDnDWnd::OnHgLeave(void) 810 759 { 760 if (mMode == GH) /* Wrong mode? Bail out. */ 761 return VERR_WRONG_ORDER; 762 811 763 LogFlowThisFunc(("mMode=%ld, mState=%RU32\n", mMode, mState)); 812 764 LogRel(("DnD: Drag'n drop operation aborted\n")); … … 826 778 int VBoxDnDWnd::OnHgDrop(void) 827 779 { 780 if (mMode == GH) 781 return VERR_WRONG_ORDER; 782 828 783 LogFlowThisFunc(("mMode=%ld, mState=%RU32\n", mMode, mState)); 829 784 … … 917 872 mMode, mState, uScreenID)); 918 873 874 if (mMode == Unknown) 875 setMode(GH); 876 877 if (mMode != GH) 878 return VERR_WRONG_ORDER; 879 919 880 if (mState == Uninitialized) 920 reset(); 881 { 882 /* Nothing to do here yet. */ 883 mState = Initialized; 884 } 921 885 922 886 int rc; … … 954 918 955 919 if ( RT_SUCCESS(rc) 956 && (mState == Dragging))920 && mState == Dragging) 957 921 { 958 922 /** @todo Put this block into a function! */ … … 987 951 { 988 952 uDefAction = DND_COPY_ACTION; 953 /** @todo Support more than one action at a time. */ 989 954 uAllActions = uDefAction; 990 955 … … 993 958 rc = VbglR3DnDGHAcknowledgePending(mClientID, 994 959 uDefAction, uAllActions, strFormats.c_str()); 960 if (RT_FAILURE(rc)) 961 { 962 char szMsg[256]; /* Sizes according to MSDN. */ 963 char szTitle[64]; 964 965 /** @todo Add some translation macros here. */ 966 RTStrPrintf(szTitle, sizeof(szTitle), "VirtualBox Guest Additions Drag'n Drop"); 967 RTStrPrintf(szMsg, sizeof(szMsg), "Drag'n drop to the host either is not supported or disabled. " 968 "Pleas enable Guest to Host or Bidirectional drag'n drop mode " 969 "or re-install the VirtualBox Guest Additions."); 970 switch (rc) 971 { 972 case VERR_ACCESS_DENIED: 973 rc = hlpShowBalloonTip(ghInstance, ghwndToolWindow, ID_TRAYICON, 974 szMsg, szTitle, 975 15 * 1000 /* Time to display in msec */, NIIF_INFO); 976 AssertRC(rc); 977 break; 978 979 default: 980 break; 981 } 982 } 995 983 } 996 984 else … … 1010 998 LogFlowThisFunc(("mMode=%ld, mState=%ld, pDropTarget=0x%p, pszFormat=%s, uDefAction=0x%x\n", 1011 999 mMode, mState, pDropTarget, pszFormat, uDefAction)); 1012 1013 1000 int rc; 1014 if (mState == Dragging) 1015 { 1016 AssertPtr(pDropTarget); 1017 rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout in ms */); 1001 if (mMode == GH) 1002 { 1003 if (mState == Dragging) 1004 { 1005 AssertPtr(pDropTarget); 1006 rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout in ms */); 1007 1008 reset(); 1009 } 1010 else if (mState == Dropped) 1011 { 1012 rc = VINF_SUCCESS; 1013 } 1014 else 1015 rc = VERR_WRONG_ORDER; 1016 1018 1017 if (RT_SUCCESS(rc)) 1019 1018 { … … 1027 1026 LogFlowFunc(("Sent pvData=0x%p, cbData=%RU32, rc=%Rrc\n", 1028 1027 pvData, cbData, rc)); 1029 } 1030 1031 reset();1028 1029 1030 } 1032 1031 } 1033 1032 else 1034 1033 rc = VERR_WRONG_ORDER; 1035 1034 1036 LogFlowFuncLeaveRC(rc);1037 return rc;1038 }1039 1040 int VBoxDnDWnd::OnGhSendDir(const char *pszFormats, uint32_t cbFormats,1041 uint32_t uDefAction)1042 {1043 int rc = 0;1044 LogFlowFuncLeaveRC(rc);1045 return rc;1046 }1047 1048 int VBoxDnDWnd::OnGhSendFile(const char *pszFormats, uint32_t cbFormats,1049 uint32_t uDefAction)1050 {1051 int rc = 0;1052 1035 LogFlowFuncLeaveRC(rc); 1053 1036 return rc; … … 1213 1196 void VBoxDnDWnd::reset(void) 1214 1197 { 1215 LogFlowThisFunc(("Old mState=%ld\n", mState)); 1198 LogFlowThisFunc(("Resetting, old mMode=%ld, mState=%ld\n", 1199 mMode, mState)); 1216 1200 1217 1201 lstAllowedFormats.clear(); … … 1219 1203 uAllActions = DND_IGNORE_ACTION; 1220 1204 1221 mMode = Unknown; 1205 int rc2 = setMode(Unknown); 1206 AssertRC(rc2); 1207 1208 hide(); 1209 } 1210 1211 int VBoxDnDWnd::setMode(Mode enmMode) 1212 { 1213 LogFlowThisFunc(("Old mode=%ld, new mode=%ld\n", 1214 mMode, enmMode)); 1215 1216 mMode = enmMode; 1222 1217 mState = Initialized; 1218 1219 return VINF_SUCCESS; 1223 1220 } 1224 1221 … … 1425 1422 if (RT_FAILURE(rc2)) 1426 1423 LogFlowFunc(("Cancelling failed with rc=%Rrc\n", rc2)); 1424 break; 1427 1425 } 1428 1426 else … … 1433 1431 * don't support the stuff we do on the guest side, so make sure we 1434 1432 * don't process invalid messages forever. */ 1435 if (rc == VERR_INVALID_PARAMETER) 1436 cMsgSkippedInvalid++; 1437 if (cMsgSkippedInvalid > 3) 1433 if (cMsgSkippedInvalid++ > 3) 1438 1434 { 1439 Log FlowFunc(("Too many invalid/skipped messages from host, exiting ...\n"));1435 LogRel(("DnD: Too many invalid/skipped messages from host, exiting ...\n")); 1440 1436 break; 1441 1437 } 1438 1439 int rc2 = VbglR3DnDGHSendError(uClientID, rc); 1440 AssertRC(rc2); 1442 1441 } 1443 1442 … … 1445 1444 break; 1446 1445 1446 if (RT_FAILURE(rc)) /* Don't hog the CPU on errors. */ 1447 RTThreadSleep(1000 /* ms */); 1448 1447 1449 } while (true); 1448 1450 -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h
r50508 r50561 340 340 int OnGhIsDnDPending(uint32_t uScreenID); 341 341 int OnGhDropped(const char *pszFormat, uint32_t cbFormats, uint32_t uDefAction); 342 int OnGhSendDir(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);343 int OnGhSendFile(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);344 342 #endif 345 343 … … 353 351 354 352 int makeFullscreen(void); 355 void reset(void);356 353 int mouseMove(int x, int y, DWORD dwMouseInputFlags); 357 354 int mouseRelease(void); 355 void reset(void); 356 int setMode(Mode enmMode); 358 357 359 358 public: /** @todo Make protected! */ … … 396 395 /** The current state. */ 397 396 State mState; 397 bool mInFlight; 398 398 RTCString mFormatRequested; 399 399 RTCList<RTCString> mLstFormats; -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDropTarget.cpp
r50508 r50561 120 120 else 121 121 { 122 LogFlowFunc(("CF_HDROP not supported, hr=%Rhrc\n", hr));122 LogFlowFunc(("CF_HDROP not wanted, hr=%Rhrc\n", hr)); 123 123 124 124 /* So we couldn't retrieve the data in CF_HDROP format; try with 125 * CF_ TEXT formatnow. Rest stays the same. */126 fmtEtc.cfFormat = CF_ TEXT;125 * CF_UNICODETEXT + CF_TEXT formats now. Rest stays the same. */ 126 fmtEtc.cfFormat = CF_UNICODETEXT; 127 127 hr = pDataObject->QueryGetData(&fmtEtc); 128 if (hr != S_OK)128 if (hr == S_OK) 129 129 { 130 LogFlowFunc(("CF_TEXT not supported, hr=%Rhrc\n", hr)); 131 fmtEtc.cfFormat = 0; /* Mark it to not supported. */ 130 mFormats = "text/plain;charset=utf-8"; 132 131 } 133 132 else 134 133 { 135 mFormats = "text/plain;charset=utf-8"; 134 LogFlowFunc(("CF_UNICODETEXT not wanted, hr=%Rhrc\n", hr)); 135 136 fmtEtc.cfFormat = CF_TEXT; 137 hr = pDataObject->QueryGetData(&fmtEtc); 138 if (hr == S_OK) 139 { 140 mFormats = "text/plain;charset=utf-8"; 141 } 142 else 143 { 144 LogFlowFunc(("CF_TEXT not wanted, hr=%Rhrc\n", hr)); 145 fmtEtc.cfFormat = 0; /* Mark it to not supported. */ 146 } 136 147 } 137 148 } … … 306 317 switch (mFormatEtc.cfFormat) 307 318 { 308 /* Handling CF_TEXT means that the system already did some marshalling 309 * to convert RTF or unicode text to plain ANSI text. */ 319 case CF_UNICODETEXT: 320 { 321 AssertPtr(pvData); 322 size_t cbSize = GlobalSize(pvData); 323 LogFlowFunc(("CF_UNICODETEXT 0x%p got %zu bytes\n", pvData, cbSize)); 324 if (cbSize) 325 { 326 char *pszText = NULL; 327 rc = RTUtf16ToUtf8((PCRTUTF16)pvData, &pszText); 328 if (RT_SUCCESS(rc)) 329 { 330 mpvData = (void *)pszText; 331 mcbData = strlen(pszText) + 1; /* Include termination. */ 332 333 /* Note: Don't free data of pszText, mpvData now owns it. */ 334 } 335 } 336 337 break; 338 } 339 310 340 case CF_TEXT: 311 341 { … … 320 350 { 321 351 mpvData = (void *)pszText; 322 mcbData = strlen(pszText) + 1; 352 mcbData = strlen(pszText) + 1; /* Include termination. */ 353 354 /* Note: Don't free data of pszText, mpvData now owns it. */ 323 355 } 324 356 } … … 412 444 /* Add separation between filenames. 413 445 * Note: Also do this for the last element of the list. */ 414 if (i > 0) 415 { 416 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, 417 "\r\n", 2 /* Bytes */); 418 if (RT_SUCCESS(rc)) 419 cchFiles += 2; /* Include \r\n */ 420 } 446 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, 447 "\r\n", 2 /* Bytes */); 448 if (RT_SUCCESS(rc)) 449 cchFiles += 2; /* Include \r\n */ 421 450 } 422 451 -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp
r50508 r50561 278 278 279 279 /* Allocate temp buffer. */ 280 uint32_t cbTmpData = _ 1M * 10; /** @todo r=andy 10MB, uh, really?? */280 uint32_t cbTmpData = _64K; /** @todo Make this configurable? */ 281 281 void *pvTmpData = RTMemAlloc(cbTmpData); 282 282 if (!pvTmpData) … … 311 311 RTCList<RTCString> guestDirList; 312 312 RTCList<RTCString> guestFileList; 313 char pszPathName[RTPATH_MAX]; 314 uint32_t cbPathname = 0; 313 314 char szPathName[RTPATH_MAX]; 315 uint32_t cbPathName = 0; 316 315 317 bool fLoop = RT_SUCCESS(rc); /* No error occurred yet? */ 316 318 while (fLoop) … … 327 329 uint32_t fMode = 0; 328 330 rc = vbglR3DnDHGProcessSendDirMessage(uClientId, 329 pszPathName,330 sizeof( pszPathName),331 &cbPath name,331 szPathName, 332 sizeof(szPathName), 333 &cbPathName, 332 334 &fMode); 335 #ifdef DEBUG_andy 336 LogFlowFunc(("HOST_DND_HG_SND_DIR pszPathName=%s, cbPathName=%RU32, fMode=0x%x, rc=%Rrc\n", 337 szPathName, cbPathName, fMode, rc)); 338 #endif 333 339 if (RT_SUCCESS(rc)) 334 rc = DnDPathSanitize( pszPathName, sizeof(pszPathName));340 rc = DnDPathSanitize(szPathName, sizeof(szPathName)); 335 341 if (RT_SUCCESS(rc)) 336 342 { 337 char *pszNewDir = RTPathJoinA(pszDropDir, pszPathName);343 char *pszNewDir = RTPathJoinA(pszDropDir, szPathName); 338 344 if (pszNewDir) 339 345 { … … 354 360 uint32_t fMode = 0; 355 361 rc = vbglR3DnDHGProcessSendFileMessage(uClientId, 356 pszPathName,357 sizeof( pszPathName),358 &cbPath name,362 szPathName, 363 sizeof(szPathName), 364 &cbPathName, 359 365 pvTmpData, 360 366 cbTmpData, 361 367 &cbDataRecv, 362 368 &fMode); 369 #ifdef DEBUG_andy 370 LogFlowFunc(("HOST_DND_HG_SND_FILE pszPathName=%s, cbPathName=%RU32, pvData=0x%p, cbDataRecv=%RU32, fMode=0x%x, rc=%Rrc\n", 371 szPathName, cbPathName, pvTmpData, cbDataRecv, fMode, rc)); 372 #endif 363 373 if (RT_SUCCESS(rc)) 364 rc = DnDPathSanitize( pszPathName, sizeof(pszPathName));374 rc = DnDPathSanitize(szPathName, sizeof(szPathName)); 365 375 if (RT_SUCCESS(rc)) 366 376 { 367 char *psz NewFile = RTPathJoinA(pszDropDir, pszPathName);368 if (psz NewFile)377 char *pszPathAbs = RTPathJoinA(pszDropDir, szPathName); 378 if (pszPathAbs) 369 379 { 370 380 RTFILE hFile; … … 372 382 * create all sorts of funny races because we don't know if the guest has 373 383 * modified the file in between the file data send calls. */ 374 rc = RTFileOpen(&hFile, psz NewFile,384 rc = RTFileOpen(&hFile, pszPathAbs, 375 385 RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_DENY_ALL | RTFILE_O_OPEN_CREATE); 376 386 if (RT_SUCCESS(rc)) … … 386 396 rc = RTFileSetMode(hFile, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR); 387 397 } 398 388 399 RTFileClose(hFile); 389 if (!guestFileList.contains(pszNewFile)) 390 guestFileList.append(pszNewFile); 400 401 if (!guestFileList.contains(pszPathAbs)) 402 guestFileList.append(pszPathAbs); 391 403 } 392 393 RTStrFree(pszNewFile); 404 #ifdef DEBUG 405 else 406 LogFlowFunc(("Opening file failed with rc=%Rrc\n", rc)); 407 #endif 408 RTStrFree(pszPathAbs); 394 409 } 395 410 else … … 416 431 break; 417 432 } 433 434 if (RT_FAILURE(rc)) 435 break; 436 418 437 } /* while */ 419 438 … … 430 449 RTDirRemove(guestDirList.at(i).c_str()); 431 450 RTDirRemove(pszDropDir); 451 452 LogFlowFunc(("Failed with rc=%Rrc\n", rc)); 432 453 } 433 454 … … 473 494 rc = Msg.uScreenId.GetUInt32(puScreenId); AssertRC(rc); 474 495 rc = Msg.cFormat.GetUInt32(pcbFormatRecv); AssertRC(rc); 475 rc = Msg.cbData.GetUInt32(pcbDataTotal); 496 rc = Msg.cbData.GetUInt32(pcbDataTotal); AssertRC(rc); 476 497 477 498 AssertReturn(cbFormat >= *pcbFormatRecv, VERR_TOO_MUCH_DATA); … … 789 810 break; 790 811 } 812 case DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA: 813 case DragAndDropSvc::HOST_DND_HG_SND_DIR: 814 case DragAndDropSvc::HOST_DND_HG_SND_FILE: 815 { 816 pEvent->uType = uMsg; 817 818 /* All messages in this case are handled internally 819 * by vbglR3DnDHGProcessSendDataMessage() and must 820 * be specified by a preceding HOST_DND_HG_SND_DATA call. */ 821 rc = VERR_WRONG_ORDER; 822 break; 823 } 791 824 case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL: 792 825 { … … 1107 1140 rc = vbglR3DnDGHSendDataInternal(u32ClientId, pvData, cbData, 1108 1141 0 /* cbAdditionalData */); 1109 1110 return rc; 1111 } 1112 1113 VBGLR3DECL(int) VbglR3DnDGHErrorEvent(uint32_t u32ClientId, int rcOp) 1142 if (RT_FAILURE(rc)) 1143 { 1144 int rc2 = VbglR3DnDGHSendError(u32ClientId, rc); 1145 if (RT_SUCCESS(rc2)) 1146 rc2 = rc; 1147 } 1148 1149 return rc; 1150 } 1151 1152 VBGLR3DECL(int) VbglR3DnDGHSendError(uint32_t u32ClientId, int rcErr) 1114 1153 { 1115 1154 DragAndDropSvc::VBOXDNDGHEVTERRORMSG Msg; … … 1120 1159 Msg.hdr.cParms = 1; 1121 1160 1122 Msg.uRC.SetUInt32(rcOp); 1123 1124 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 1125 if (RT_SUCCESS(rc)) 1126 rc = Msg.hdr.result; 1127 1128 return rc; 1129 } 1130 1161 Msg.uRC.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */ 1162 1163 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 1164 if (RT_SUCCESS(rc)) 1165 rc = Msg.hdr.result; 1166 1167 LogFlowFunc(("Sending error %Rrc returned with rc=%Rrc\n", rcErr, rc)); 1168 return rc; 1169 } 1170 -
trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
r50478 r50561 1317 1317 /* Inform the host on error */ 1318 1318 if (RT_FAILURE(rc)) 1319 VbglR3DnDGH ErrorEvent(rc);1319 VbglR3DnDGHSendError(rc); 1320 1320 1321 1321 /* At this point, we have either successfully transfered any data or not. -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDataObject_win.cpp
r50508 r50561 231 231 if (mStatus == Dropped) 232 232 { 233 #ifdef VBOX_DND_DEBUG_FORMATS234 233 LogFlowFunc(("cfFormat=%RI16, sFormat=%s, tyMed=%RU32, dwAspect=%RU32\n", 235 234 pThisFormat->cfFormat, UIDnDDataObject::ClipboardFormatToString(pFormatEtc->cfFormat), … … 237 236 LogFlowFunc(("Got strFormat=%s, pvData=%p, cbData=%RU32\n", 238 237 mstrFormat.toAscii().constData(), mpvData, mcbData)); 239 #endif 238 240 239 QVariant::Type vaType; 241 240 QString strMIMEType; … … 256 255 vaType = QVariant::StringList; 257 256 } 258 #if 0 257 #if 0 /* More formats; not needed right now. */ 259 258 else if ( (pFormatEtc->tymed & TYMED_ISTREAM) 260 259 && (pFormatEtc->dwAspect == DVASPECT_CONTENT) … … 285 284 strMIMEType.toAscii().constData(), vaType)); 286 285 287 QVariant va; 288 int rc = mpParent->RetrieveData(strMIMEType, vaType, va); 286 int rc; 287 if (!mVaData.isValid()) 288 rc = mpParent->RetrieveData(strMIMEType, vaType, mVaData); 289 else 290 rc = VINF_SUCCESS; /* Data already retrieved. */ 291 289 292 if (RT_SUCCESS(rc)) 290 293 { 291 294 if ( strMIMEType.startsWith("text/uri-list") 292 295 /* One item. */ 293 && ( va.canConvert(QVariant::String)296 && ( mVaData.canConvert(QVariant::String) 294 297 /* Multiple items. */ 295 || va.canConvert(QVariant::StringList))298 || mVaData.canConvert(QVariant::StringList)) 296 299 ) 297 300 { 298 QStringList lstFilesURI = va.toStringList();301 QStringList lstFilesURI = mVaData.toStringList(); 299 302 QStringList lstFiles; 300 303 for (size_t i = 0; i < lstFilesURI.size(); i++) … … 326 329 327 330 size_t cbBuf = sizeof(DROPFILES) + ((cchFiles + 1) * sizeof(RTUTF16)); 328 DROPFILES *p Buf= (DROPFILES *)RTMemAllocZ(cbBuf);329 if (p Buf)331 DROPFILES *pDropFiles = (DROPFILES *)RTMemAllocZ(cbBuf); 332 if (pDropFiles) 330 333 { 331 p Buf->pFiles = sizeof(DROPFILES);332 p Buf->fWide = 1; /* We use unicode. Always. */333 334 uint8_t *pCurFile = (uint8_t *)p Buf + pBuf->pFiles;334 pDropFiles->pFiles = sizeof(DROPFILES); 335 pDropFiles->fWide = 1; /* We use unicode. Always. */ 336 337 uint8_t *pCurFile = (uint8_t *)pDropFiles + pDropFiles->pFiles; 335 338 AssertPtr(pCurFile); 336 339 … … 368 371 if (pMedium->hGlobal) 369 372 { 370 LPVOID p Mem = GlobalLock(pMedium->hGlobal);371 if (p Mem)373 LPVOID pvMem = GlobalLock(pMedium->hGlobal); 374 if (pvMem) 372 375 { 373 memcpy(p Mem, pBuf, cbBuf);376 memcpy(pvMem, pDropFiles, cbBuf); 374 377 GlobalUnlock(pMedium->hGlobal); 375 378 … … 383 386 } 384 387 385 RTMemFree(p Buf);388 RTMemFree(pDropFiles); 386 389 } 387 390 } 388 391 else if ( strMIMEType.startsWith("text/plain") 389 && va.canConvert(QVariant::String))392 && mVaData.canConvert(QVariant::String)) 390 393 { 391 394 bool fUnicode = pFormatEtc->cfFormat == CF_UNICODETEXT; 392 int cb ch = fUnicode395 int cbCh = fUnicode 393 396 ? sizeof(WCHAR) : sizeof(char); 394 397 395 QString strText = va.toString();396 size_t cbSrc = (strText.length() + 1) * cbch;398 QString strText = mVaData.toString(); 399 size_t cbSrc = strText.length() * cbCh; 397 400 Assert(cbSrc); 398 401 LPCVOID pvSrc = fUnicode … … 400 403 : (void *)strText.toAscii().constData(); 401 404 AssertPtr(pvSrc); 402 #ifdef DEBUG_andy 405 403 406 LogFlowFunc(("pvSrc=0x%p, cbSrc=%zu, cbch=%d, fUnicode=%RTbool\n", 404 pvSrc, cbSrc, cb ch, fUnicode));405 #endif 407 pvSrc, cbSrc, cbCh, fUnicode)); 408 406 409 pMedium->tymed = TYMED_HGLOBAL; 407 410 pMedium->pUnkForRelease = NULL; 408 411 pMedium->hGlobal = GlobalAlloc( GMEM_ZEROINIT 409 412 | GMEM_MOVEABLE 410 | GMEM_DDESHARE, cbSrc); 413 | GMEM_DDESHARE, 414 cbSrc); 411 415 if (pMedium->hGlobal) 412 416 { … … 423 427 } 424 428 else 425 hr = E_OUTOFMEMORY;429 hr = VERR_NO_MEMORY; 426 430 } 427 431 else … … 445 449 case TYMED_HGLOBAL: 446 450 pMedium->hGlobal = (HGLOBAL)OleDuplicateData(pThisMedium->hGlobal, 447 pThisFormat->cfFormat, NULL); 451 pThisFormat->cfFormat, 452 0 /* Flags */); 448 453 break; 449 454 … … 452 457 } 453 458 454 pMedium->tymed = p ThisFormat->tymed;459 pMedium->tymed = pFormatEtc->tymed; 455 460 pMedium->pUnkForRelease = NULL; 456 461 } 457 462 458 LogFlowFunc((" hr=%Rhrc\n", hr));463 LogFlowFunc(("Returning hr=%Rhrc\n", hr)); 459 464 return hr; 460 465 } -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDataObject_win.h
r50460 r50561 25 25 #include <QString> 26 26 #include <QStringList> 27 #include <QVariant> 27 28 28 29 /* Forward declarations: */ … … 92 93 QStringList mlstFormats; 93 94 QString mstrFormat; 95 /** The retrieved data as a QVariant. Needed 96 * for buffering in case a second format needs 97 * the same data, e.g. CF_TEXT and CF_UNICODETEXT. */ 98 QVariant mVaData; 99 /** The retrieved data as a raw buffer. */ 94 100 void *mpvData; 101 /** Raw buffer size (in bytes). */ 95 102 uint32_t mcbData; 96 103 }; -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDrag.cpp
r50460 r50561 89 89 HRESULT hr = ::DoDragDrop(pDataObject, pDropSource, 90 90 dwOKEffects, &dwEffect); 91 LogFlowThisFunc(("hr=%Rhrc, dwEffect=%RI32\n", hr, dwEffect)); 91 LogFlowThisFunc(("DoDragDrop ended with hr=%Rhrc, dwEffect=%RI32\n", 92 hr, dwEffect)); 92 93 93 94 if (pDropSource) … … 150 151 { 151 152 msgCenter().showModalProgressDialog(progress, 152 tr("Retrieving metadata ..."), ":/progress_dnd_gh_90px.png",153 tr("Retrieving data ..."), ":/progress_dnd_gh_90px.png", 153 154 m_pParent); 154 155 if (!progress.GetCanceled()) … … 161 162 { 162 163 /* After the data successfully arrived from the guest, we query it from Main. */ 163 QVector<uint8_t> data = guest.DragGHGetData();164 if (! data.isEmpty())164 QVector<uint8_t> vecData = guest.DragGHGetData(); 165 if (!vecData.isEmpty()) 165 166 { 166 167 switch (vaType) … … 168 169 case QVariant::String: 169 170 { 170 vaData = QVariant(QString(reinterpret_cast<const char*>( data.data())));171 vaData = QVariant(QString(reinterpret_cast<const char*>(vecData.constData()))); 171 172 break; 172 173 } … … 174 175 case QVariant::ByteArray: 175 176 { 176 QByteArray ba(reinterpret_cast<const char*>( data.constData()), data.size());177 QByteArray ba(reinterpret_cast<const char*>(vecData.constData()), vecData.size()); 177 178 vaData = QVariant(ba); 178 179 break; … … 181 182 case QVariant::StringList: 182 183 { 183 QString strData = QString(reinterpret_cast<const char*>( data.data()));184 QString strData = QString(reinterpret_cast<const char*>(vecData.constData())); 184 185 QStringList lstString = strData.split("\r\n", QString::SkipEmptyParts); 185 186 -
trunk/src/VBox/GuestHost/DragAndDrop/DnDURIList.cpp
r50508 r50561 183 183 184 184 /* End of file reached or error occurred? */ 185 if ( cbRead < cbToRead185 if ( m_cbProcessed == m_cbSize 186 186 || RT_FAILURE(rc)) 187 { 187 188 closeInternal(); 189 } 188 190 } 189 191 } … … 572 574 } 573 575 574 RTCString DnDURIList::RootToString(const RTCString &strBasePath /* = "" */) 576 RTCString DnDURIList::RootToString(const RTCString &strBasePath /* = "" */, 577 const RTCString &strSeparator /* = "\r\n" */) 575 578 { 576 579 RTCString strRet; … … 586 589 if (pszPathURI) 587 590 { 588 strRet += RTCString(pszPathURI) + "\r\n";591 strRet += RTCString(pszPathURI) + strSeparator; 589 592 RTStrFree(pszPathURI); 590 593 } 594 else 595 break; 591 596 RTStrFree(pszPath); 592 597 } … … 599 604 if (pszPathURI) 600 605 { 601 strRet += RTCString(pszPathURI) + "\r\n";606 strRet += RTCString(pszPathURI) + strSeparator; 602 607 RTStrFree(pszPathURI); 603 608 } -
trunk/src/VBox/HostServices/DragAndDrop/dndmanager.cpp
r50508 r50561 41 41 42 42 /** 43 * Internal DnD message class for informing the guest about a new directory. 43 * Internal DnD message class for informing the 44 * guest about a new directory. 44 45 * 45 46 * @see DnDHGSendDataMessage … … 55 56 , m_pvProgressUser(pvProgressUser) 56 57 { 58 RTCString strPath = m_URIObject.GetDestPath(); 59 LogFlowFunc(("strPath=%s (%zu)\n", strPath.c_str(), strPath.length())); 60 57 61 VBOXHGCMSVCPARM paTmpParms[3]; 58 paTmpParms[0].setString( m_URIObject.GetDestPath().c_str());59 paTmpParms[1].setUInt32((uint32_t)( m_URIObject.GetDestPath().length() + 1));62 paTmpParms[0].setString(strPath.c_str()); 63 paTmpParms[1].setUInt32((uint32_t)(strPath.length() + 1)); 60 64 paTmpParms[2].setUInt32(m_URIObject.GetMode()); 61 65 62 66 m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_DIR, 3, paTmpParms); 63 67 } 68 69 public: 64 70 65 71 int currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) … … 78 84 DnDURIObject m_URIObject; 79 85 80 /* Progress stuff */86 /* Progress stuff. */ 81 87 PFNDNDPRIVATEPROGRESS m_pfnProgressCallback; 82 88 void *m_pvProgressUser; … … 96 102 virtual ~DnDHGSendFilePrivate(void); 97 103 104 public: 105 98 106 int currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 99 107 … … 101 109 102 110 DnDURIObject m_URIObject; 103 VBOXHGCMSVCPARM m_paSkelParms[5]; 104 105 /* Progress stuff */ 111 /** Skeleton parameters for the next upcoming message in case 112 * the file data didn't fit completely into the first one. */ 113 VBOXHGCMSVCPARM m_aSkelParms[5]; 114 115 /* Progress stuff. */ 106 116 PFNDNDPRIVATEPROGRESS m_pfnProgressCallback; 107 117 void *m_pvProgressUser; … … 127 137 size_t m_cbDone; 128 138 129 /* Progress stuff */139 /* Progress stuff. */ 130 140 PFNDNDPRIVATEPROGRESS m_pfnProgressCallback; 131 141 void *m_pvProgressUser; … … 146 156 , m_pvProgressUser(pvProgressUser) 147 157 { 148 m_paSkelParms[0].setString(m_URIObject.GetDestPath().c_str()); 149 m_paSkelParms[1].setUInt32((uint32_t)(m_URIObject.GetDestPath().length() + 1)); 150 m_paSkelParms[2].setPointer(NULL, 0); 151 m_paSkelParms[3].setUInt32(0); 152 m_paSkelParms[4].setUInt32(m_URIObject.GetMode()); 153 154 m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5, m_paSkelParms); 158 LogFlowFunc(("strPath=%s (%zu)\n", 159 m_URIObject.GetDestPath().c_str(), m_URIObject.GetDestPath().length())); 160 161 m_aSkelParms[0].setString(m_URIObject.GetDestPath().c_str()); /* pvName */ 162 m_aSkelParms[1].setUInt32((uint32_t)(m_URIObject.GetDestPath().length() + 1)); /* cbName */ 163 m_aSkelParms[2].setPointer(NULL, 0); /* pvData */ 164 m_aSkelParms[3].setUInt32(0); /* cbData */ 165 m_aSkelParms[4].setUInt32(m_URIObject.GetMode()); /* fMode */ 166 167 m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5, m_aSkelParms); 155 168 } 156 169 … … 174 187 { 175 188 /* Get buffer size + pointer to buffer from guest side. */ 176 uint32_t cbToRead = paParms[2].u.pointer.size; 189 uint32_t cbToRead = paParms[2].u.pointer.size; /* cbData */ 177 190 Assert(cbToRead); 178 void *pvBuf = paParms[2].u.pointer.addr; 191 void *pvBuf = paParms[2].u.pointer.addr; /* pvData */ 179 192 AssertPtr(pvBuf); 180 193 181 194 rc = m_URIObject.Read(pvBuf, cbToRead, &cbRead); 195 LogFlowFunc(("Read %RU32 bytes (%RU32 bytes buffer) for \"%s\", rc=%Rrc\n", 196 cbRead, cbToRead, m_URIObject.GetDestPath().c_str(), rc)); 197 182 198 if (RT_LIKELY(RT_SUCCESS(rc))) 183 199 { 184 /* Tell the guest the actual size . */185 paParms[3].setUInt32((uint32_t)cbRead); 200 /* Tell the guest the actual size read. */ 201 paParms[3].setUInt32((uint32_t)cbRead); /* cbData */ 186 202 } 187 203 } … … 195 211 /* More data needed to send over. Prepare the next message. */ 196 212 m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5 /* cParms */, 197 m_ paSkelParms);213 m_aSkelParms); 198 214 } 199 215 catch(std::bad_alloc &) … … 323 339 Assert(cbList); 324 340 325 LogFlowFunc(("Old data : '%s'\n", pszList));341 LogFlowFunc(("Old data (%RU32 bytes): '%s'\n", cbList, pszList)); 326 342 327 343 /* The list is separated by newline (even if only one file is listed). */ … … 330 346 if (!lstURIOrg.isEmpty()) 331 347 { 332 rc = m_lstURI.Append NativePathsFromList(lstURIOrg, 0 /* fFlags */);348 rc = m_lstURI.AppendURIPathsFromList(lstURIOrg, 0 /* fFlags */); 333 349 if (RT_SUCCESS(rc)) 334 350 { … … 351 367 paParms[4].u.uint32 = (uint32_t)(strNewURIs.length() + 1); 352 368 353 LogFlowFunc(("Set new data: '%s'\n", (char*)paParms[3].u.pointer.addr)); 369 LogFlowFunc(("Set new data (%RU32 bytes): '%s'\n", 370 paParms[3].u.pointer.size, 371 (const char*)paParms[3].u.pointer.addr)); 354 372 } 355 373 } -
trunk/src/VBox/HostServices/DragAndDrop/service.cpp
r50508 r50561 72 72 { 73 73 public: 74 74 75 explicit DragAndDropService(PVBOXHGCMSVCHELPERS pHelpers) 75 : HGCM::AbstractService<DragAndDropService>(pHelpers)76 , m_pManager(0)77 , m_cClients(0)76 : HGCM::AbstractService<DragAndDropService>(pHelpers) 77 , m_pManager(0) 78 , m_cClients(0) 78 79 {} 79 80 … … 88 89 89 90 static DECLCALLBACK(int) progressCallback(uint32_t uPercentage, uint32_t uState, int rc, void *pvUser); 90 int hostMessage(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 91 void modeSet(uint32_t u32Mode); 91 int modeSet(uint32_t u32Mode); 92 92 inline uint32_t modeGet() { return m_u32Mode; }; 93 93 … … 110 110 pTable->pfnLoadState = NULL; /* construction done before restoring suffices */ 111 111 pTable->pfnRegisterExtension = svcRegisterExtension; 112 113 /* Drag'n drop mode is disabled by default. */ 112 114 modeSet(VBOX_DRAG_AND_DROP_MODE_OFF); 113 115 … … 117 119 } 118 120 119 int DragAndDropService::uninit( )121 int DragAndDropService::uninit(void) 120 122 { 121 123 delete m_pManager; … … 131 133 else 132 134 AssertMsgFailed(("Maximum number of clients reached\n")); 135 136 /* 137 * Clear the message queue as soon as a new clients connect 138 * to ensure that every client has the same state. 139 */ 140 if (m_pManager) 141 m_pManager->clear(); 142 133 143 return VINF_SUCCESS; 134 144 } … … 136 146 int DragAndDropService::clientDisconnect(uint32_t u32ClientID, void *pvClient) 137 147 { 138 /* Remove all waiters with this clientId. */148 /* Remove all waiters with this u32ClientID. */ 139 149 for (size_t i = 0; i < m_clientQueue.size(); ) 140 150 { … … 142 152 if (pClient->clientId() == u32ClientID) 143 153 { 144 m_pHelpers->pfnCallComplete(pClient->handle(), VERR_INTERRUPTED); 154 if (m_pHelpers) 155 m_pHelpers->pfnCallComplete(pClient->handle(), VERR_INTERRUPTED); 156 145 157 m_clientQueue.removeAt(i); 146 158 delete pClient; … … 153 165 } 154 166 155 void DragAndDropService::modeSet(uint32_t u32Mode) 156 { 167 int DragAndDropService::modeSet(uint32_t u32Mode) 168 { 169 /** @todo Validate mode. */ 157 170 switch (u32Mode) 158 171 { … … 166 179 default: 167 180 m_u32Mode = VBOX_DRAG_AND_DROP_MODE_OFF; 168 } 181 break; 182 } 183 184 return VINF_SUCCESS; 169 185 } 170 186 … … 222 238 if (!fIgnoreRequest) 223 239 { 224 rc = VINF_SUCCESS;225 240 switch (u32Function) 226 241 { … … 244 259 && paParms[2].u.uint32) /* Blocking? */ 245 260 { 246 m_clientQueue.append(new HGCM::Client(u32ClientID, callHandle, u32Function, cParms, paParms)); 261 m_clientQueue.append(new HGCM::Client(u32ClientID, callHandle, 262 u32Function, cParms, paParms)); 247 263 rc = VINF_HGCM_ASYNC_EXECUTE; 248 264 } … … 393 409 DragAndDropSvc::VBOXDNDCBEVTERRORDATA data; 394 410 data.hdr.u32Magic = DragAndDropSvc::CB_MAGIC_DND_GH_EVT_ERROR; 411 395 412 uint32_t rcOp; 396 413 paParms[0].getUInt32(&rcOp); 397 414 data.rc = rcOp; 415 398 416 if (m_pfnHostCallback) 399 417 rc = m_pfnHostCallback(m_pvHostData, u32Function, &data, sizeof(data)); … … 411 429 } 412 430 else 413 rc = VERR_ NOT_SUPPORTED;431 rc = VERR_ACCESS_DENIED; 414 432 415 433 /* If async execute is requested, we didn't notify the guest about 416 434 * completion. The client is queued into the waiters list and will be 417 435 * notified as soon as a new event is available. */ 418 if (rc != VINF_HGCM_ASYNC_EXECUTE) 436 if ( rc != VINF_HGCM_ASYNC_EXECUTE 437 && m_pHelpers) 438 { 419 439 m_pHelpers->pfnCallComplete(callHandle, rc); 440 } 441 420 442 LogFlowFunc(("Returning rc=%Rrc\n", rc)); 421 443 } 422 444 423 int DragAndDropService::hostMessage(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 424 { 425 int rc = VINF_SUCCESS; 426 #if 0 427 HGCM::Message *pMessage = new HGCM::Message(u32Function, cParms, paParms); 428 m_hostQueue.push(pMessage); 429 // bool fPush = true; 430 RTPrintf("client queue %u\n", m_clientQueue.size()); 431 RTPrintf("host queue %u\n", m_hostQueue.size()); 432 if (!m_clientQueue.empty()) 433 { 434 pMessage = m_hostQueue.front(); 435 HGCM::Client *pClient = m_clientQueue.front(); 436 /* Check if this was a request for getting the next host 437 * message. If so, return the message id and the parameter 438 * count. The message itself has to be queued. */ 439 if (pClient->message() == DragAndDropSvc::GUEST_GET_NEXT_HOST_MSG) 440 { 441 RTPrintf("client is waiting for next host msg\n"); 442 // rc = VERR_TOO_MUCH_DATA; 443 pClient->addMessageInfo(pMessage); 444 /* temp */ 445 // m_pHelpers->pfnCallComplete(pClient->handle(), rc); 446 // m_clientQueue.pop(); 447 // delete pClient; 448 } 449 else 450 { 451 RTPrintf("client is waiting for host msg (%d)\n", u32Function); 452 /* There is a request for a host message pending. Check 453 * if this is the correct message and if so deliver. If 454 * not the message will be queued. */ 455 rc = pClient->addMessage(pMessage); 456 m_hostQueue.pop(); 457 delete pMessage; 458 // if (RT_SUCCESS(rc)) 459 // fPush = false; 460 } 461 /* In any case mark this client request as done. */ 462 m_pHelpers->pfnCallComplete(pClient->handle(), rc); 463 m_clientQueue.pop_front(); 464 delete pClient; 465 } 466 // if (fPush) 467 // { 468 // RTPrintf("push message\n"); 469 // m_hostQueue.push(pMessage); 470 // } 471 // else 472 // delete pMessage; 473 #endif 474 475 return rc; 476 } 477 478 int DragAndDropService::hostCall(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 445 int DragAndDropService::hostCall(uint32_t u32Function, 446 uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 479 447 { 480 448 LogFlowFunc(("u32Function=%RU32, cParms=%RU32\n", u32Function, cParms)); 481 449 482 int rc = VINF_SUCCESS;450 int rc; 483 451 if (u32Function == DragAndDropSvc::HOST_DND_SET_MODE) 484 452 { … … 488 456 rc = VERR_INVALID_PARAMETER; 489 457 else 490 modeSet(paParms[0].u.uint32);458 rc = modeSet(paParms[0].u.uint32); 491 459 } 492 460 else if (modeGet() != VBOX_DRAG_AND_DROP_MODE_OFF) 493 461 { 494 rc = m_pManager->addMessage(u32Function, cParms, paParms); 495 if ( RT_SUCCESS(rc) 496 && !m_clientQueue.isEmpty()) 462 if (!m_clientQueue.isEmpty()) /* At least one client on the guest connected? */ 497 463 { 498 HGCM::Client *pClient = m_clientQueue.first(); 499 AssertPtr(pClient); 500 /* Check if this was a request for getting the next host 501 * message. If so, return the message id and the parameter 502 * count. The message itself has to be queued. */ 503 if (pClient->message() == DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG) 504 { 505 LogFlowFunc(("Client %RU32 is waiting for next host msg\n", pClient->clientId())); 506 507 uint32_t uMsg1; 508 uint32_t cParms1; 509 rc = m_pManager->nextMessageInfo(&uMsg1, &cParms1); 510 if (RT_SUCCESS(rc)) 511 { 512 pClient->addMessageInfo(uMsg1, cParms1); 513 m_pHelpers->pfnCallComplete(pClient->handle(), rc); 514 m_clientQueue.removeFirst(); 515 delete pClient; 516 } 517 else 518 AssertMsgFailed(("Should not happen!")); 464 rc = m_pManager->addMessage(u32Function, cParms, paParms); 465 if (RT_SUCCESS(rc)) 466 { 467 HGCM::Client *pClient = m_clientQueue.first(); 468 AssertPtr(pClient); 469 470 /* Check if this was a request for getting the next host 471 * message. If so, return the message id and the parameter 472 * count. The message itself has to be queued. */ 473 uint32_t uMsg = pClient->message(); 474 if (uMsg == DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG) 475 { 476 LogFlowFunc(("Client %RU32 is waiting for next host msg\n", pClient->clientId())); 477 478 uint32_t uMsg1; 479 uint32_t cParms1; 480 rc = m_pManager->nextMessageInfo(&uMsg1, &cParms1); 481 if (RT_SUCCESS(rc)) 482 { 483 pClient->addMessageInfo(uMsg1, cParms1); 484 if (m_pHelpers) 485 m_pHelpers->pfnCallComplete(pClient->handle(), rc); 486 487 m_clientQueue.removeFirst(); 488 delete pClient; 489 } 490 else 491 AssertMsgFailed(("m_pManager::nextMessageInfo failed with rc=%Rrc\n", rc)); 492 } 493 else 494 AssertMsgFailed(("Client ID=%RU32 in wrong state with uMsg=%RU32\n", 495 pClient->clientId(), uMsg)); 519 496 } 520 497 else 521 AssertMsgFailed(("Should not happen!")); 498 AssertMsgFailed(("Adding new message of type=%RU32 failed with rc=%Rrc\n", 499 u32Function, rc)); 522 500 } 523 // else 524 // AssertMsgFailed(("Should not happen %Rrc!", rc)); 501 else 502 { 503 /* Tell the host that the guest does not support drag'n drop. 504 * This might happen due to not installed Guest Additions or 505 * not running VBoxTray/VBoxClient. */ 506 rc = VERR_NOT_SUPPORTED; 507 } 508 } 509 else 510 { 511 /* Tell the host that a wrong drag'n drop mode is set. */ 512 rc = VERR_ACCESS_DENIED; 525 513 } 526 514 … … 534 522 535 523 DragAndDropService *pSelf = static_cast<DragAndDropService *>(pvUser); 524 AssertPtr(pSelf); 536 525 537 526 if (pSelf->m_pfnHostCallback) … … 545 534 data.rc = rc; 546 535 547 return pSelf->m_pfnHostCallback(pSelf->m_pvHostData, DragAndDropSvc::GUEST_DND_HG_EVT_PROGRESS, &data, sizeof(data)); 536 return pSelf->m_pfnHostCallback(pSelf->m_pvHostData, 537 DragAndDropSvc::GUEST_DND_HG_EVT_PROGRESS, 538 &data, sizeof(data)); 548 539 } 549 540 -
trunk/src/VBox/Main/src-client/GuestDnDImpl.cpp
r50508 r50561 239 239 DnDGuestResponse *response(void) const { return m_pDnDResponse; } 240 240 241 voidadjustCoords(ULONG uScreenId, ULONG *puX, ULONG *puY) const;242 voidhostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const;241 HRESULT adjustCoords(ULONG uScreenId, ULONG *puX, ULONG *puY) const; 242 int hostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const; 243 243 244 244 /* Static helpers. */ … … 310 310 int DnDGuestResponse::waitForGuestResponse(RTMSINTERVAL msTimeout /*= 500 */) 311 311 { 312 int vrc = RTSemEventWait(m_EventSem, msTimeout);312 int rc = RTSemEventWait(m_EventSem, msTimeout); 313 313 #ifdef DEBUG_andy 314 LogFlowFunc(("msTimeout=%RU32, rc=%Rrc\n", msTimeout, vrc));314 LogFlowFunc(("msTimeout=%RU32, rc=%Rrc\n", msTimeout, rc)); 315 315 #endif 316 return vrc;316 return rc; 317 317 } 318 318 … … 350 350 m_pvData = NULL; 351 351 } 352 353 352 m_cbData = 0; 353 354 m_cbDataCurrent = 0; 355 m_cbDataTotal = 0; 354 356 } 355 357 … … 377 379 { 378 380 BOOL fCompleted; 379 HRESULT rc= m_progress->COMGETTER(Completed)(&fCompleted);381 HRESULT hr = m_progress->COMGETTER(Completed)(&fCompleted); 380 382 if (!fCompleted) 381 383 { 382 384 if (uState == DragAndDropSvc::DND_PROGRESS_ERROR) 383 385 { 384 rc= m_progress->notifyComplete(E_FAIL,386 hr = m_progress->notifyComplete(E_FAIL, 385 387 COM_IIDOF(IGuest), 386 388 m_parent->getComponentName(), 387 389 m_parent->tr("Drag'n drop guest error (%Rrc)"), rcOp); 390 reset(); 388 391 } 389 392 else if (uState == DragAndDropSvc::DND_PROGRESS_CANCELLED) 390 393 { 391 rc = m_progress->Cancel(); 392 vrc = VERR_CANCELLED; 394 hr = m_progress->Cancel(); 395 if (SUCCEEDED(hr)) 396 vrc = VERR_CANCELLED; 397 398 reset(); 393 399 } 394 400 else /* uState == DragAndDropSvc::DND_PROGRESS_RUNNING */ 395 401 { 396 rc = m_progress->SetCurrentOperationProgress(uPercentage); 397 #ifndef DEBUG_andy 398 Assert(SUCCEEDED(rc)); 399 #endif 402 hr = m_progress->SetCurrentOperationProgress(uPercentage); 403 AssertComRC(hr); 400 404 if ( uState == DragAndDropSvc::DND_PROGRESS_COMPLETE 401 405 || uPercentage >= 100) 402 rc= m_progress->notifyComplete(S_OK);406 hr = m_progress->notifyComplete(S_OK); 403 407 } 408 } 409 } 410 411 return vrc; 412 } 413 414 int DnDGuestResponse::dataSetStatus(size_t cbDataAdd, size_t cbDataTotal /* = 0 */) 415 { 416 if (cbDataTotal) 417 { 404 418 #ifndef DEBUG_andy 405 Assert(SUCCEEDED(rc)); 419 AssertMsg(m_cbDataTotal <= cbDataTotal, ("New data size must not be smaller (%zu) than old value (%zu)\n", 420 cbDataTotal, m_cbDataTotal)); 406 421 #endif 407 } 408 } 409 410 return vrc; 411 } 412 413 int DnDGuestResponse::dataSetStatus(size_t cbDataAdd, size_t cbDataTotal /* = 0 */) 414 { 415 if (cbDataTotal) 416 { 417 AssertMsg(m_cbDataTotal <= cbDataTotal, ("New data size size must not be smaller (%zu) than old value (%zu)\n", 418 cbDataTotal, m_cbDataTotal)); 422 LogFlowFunc(("Updating total data size from %zu to %zu\n", m_cbDataTotal, cbDataTotal)); 419 423 m_cbDataTotal = cbDataTotal; 420 LogFlowFunc(("Updating total data size to: %zu\n", m_cbDataTotal));421 424 } 422 425 AssertMsg(m_cbDataTotal, ("m_cbDataTotal must not be <= 0\n")); … … 433 436 LogFlowFunc(("Updating transfer status (%zu/%zu), status=%ld\n", 434 437 m_cbDataCurrent, m_cbDataTotal, uStatus)); 435 #endif 436 438 #else 437 439 AssertMsg(m_cbDataCurrent <= m_cbDataTotal, 438 440 ("More data transferred (%RU32) than initially announced (%RU32)\n", 439 441 m_cbDataCurrent, m_cbDataTotal)); 440 442 #endif 441 443 int rc = setProgress(cPercentage, uStatus); 442 444 … … 455 457 } 456 458 457 voidGuestDnDPrivate::adjustCoords(ULONG uScreenId, ULONG *puX, ULONG *puY) const459 HRESULT GuestDnDPrivate::adjustCoords(ULONG uScreenId, ULONG *puX, ULONG *puY) const 458 460 { 459 461 /* For multi-monitor support we need to add shift values to the coordinates 460 462 * (depending on the screen number). */ 461 463 ComPtr<IDisplay> pDisplay; 462 HRESULT rc= p->mParent->COMGETTER(Display)(pDisplay.asOutParam());463 if (FAILED( rc))464 throw rc;464 HRESULT hr = p->mParent->COMGETTER(Display)(pDisplay.asOutParam()); 465 if (FAILED(hr)) 466 return hr; 465 467 466 468 ComPtr<IFramebuffer> pFramebuffer; 467 469 LONG xShift, yShift; 468 rc= pDisplay->GetFramebuffer(uScreenId, pFramebuffer.asOutParam(),470 hr = pDisplay->GetFramebuffer(uScreenId, pFramebuffer.asOutParam(), 469 471 &xShift, &yShift); 470 if (FAILED( rc))471 throw rc;472 if (FAILED(hr)) 473 return hr; 472 474 473 475 *puX += xShift; 474 476 *puY += yShift; 475 } 476 477 void GuestDnDPrivate::hostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const 478 { 479 VMMDev *vmmDev = NULL; 477 478 return hr; 479 } 480 481 int GuestDnDPrivate::hostCall(uint32_t u32Function, uint32_t cParms, 482 PVBOXHGCMSVCPARM paParms) const 483 { 484 VMMDev *pVMMDev = NULL; 480 485 { 481 486 /* Make sure mParent is valid, so set the read lock while using. … … 486 491 /* Forward the information to the VMM device. */ 487 492 AssertPtr(p->mParent); 488 vmmDev = p->mParent->getVMMDev();489 } 490 491 if (! vmmDev)493 pVMMDev = p->mParent->getVMMDev(); 494 } 495 496 if (!pVMMDev) 492 497 throw p->setError(VBOX_E_VM_ERROR, 493 498 p->tr("VMM device is not available (is the VM running?)")); 494 499 495 500 LogFlowFunc(("hgcmHostCall msg=%RU32, numParms=%RU32\n", u32Function, cParms)); 496 int vrc = vmmDev->hgcmHostCall("VBoxDragAndDropSvc",501 int rc = pVMMDev->hgcmHostCall("VBoxDragAndDropSvc", 497 502 u32Function, 498 503 cParms, paParms); 499 if (RT_FAILURE( vrc))500 { 501 LogFlowFunc(("hgcmHostCall error: %Rrc\n", vrc));504 if (RT_FAILURE(rc)) 505 { 506 LogFlowFunc(("hgcmHostCall error: %Rrc\n", rc)); 502 507 throw p->setError(VBOX_E_VM_ERROR, 503 p->tr("hgcmHostCall failed (%Rrc)"), vrc); 504 } 508 p->tr("hgcmHostCall failed (%Rrc)"), rc); 509 } 510 511 return rc; 505 512 } 506 513 … … 653 660 return S_OK; 654 661 655 HRESULT rc= S_OK;662 HRESULT hr = S_OK; 656 663 657 664 try … … 674 681 paParms); 675 682 676 DnDGuestResponse *p DnD= d->response();683 DnDGuestResponse *pResp = d->response(); 677 684 /* This blocks until the request is answered (or timeout). */ 678 if (p DnD->waitForGuestResponse() == VERR_TIMEOUT)685 if (pResp->waitForGuestResponse() == VERR_TIMEOUT) 679 686 return S_OK; 680 687 681 688 /* Copy the response info */ 682 *pResultAction = d->toMainAction(p DnD->defAction());689 *pResultAction = d->toMainAction(pResp->defAction()); 683 690 LogFlowFunc(("*pResultAction=%ld\n", *pResultAction)); 684 691 } 685 catch (HRESULT rc2)686 { 687 rc = rc2;688 } 689 690 return rc;692 catch (HRESULT hr2) 693 { 694 hr = hr2; 695 } 696 697 return hr; 691 698 } 692 699 … … 717 724 return S_OK; 718 725 719 HRESULT rc= S_OK;726 HRESULT hr = S_OK; 720 727 721 728 try … … 738 745 paParms); 739 746 740 DnDGuestResponse *p DnD= d->response();747 DnDGuestResponse *pResp = d->response(); 741 748 /* This blocks until the request is answered (or timeout). */ 742 if (p DnD->waitForGuestResponse() == VERR_TIMEOUT)749 if (pResp->waitForGuestResponse() == VERR_TIMEOUT) 743 750 return S_OK; 744 751 745 752 /* Copy the response info */ 746 *pResultAction = d->toMainAction(p DnD->defAction());753 *pResultAction = d->toMainAction(pResp->defAction()); 747 754 LogFlowFunc(("*pResultAction=%ld\n", *pResultAction)); 748 755 } 749 catch (HRESULT rc2)750 { 751 rc = rc2;752 } 753 754 return rc;756 catch (HRESULT hr2) 757 { 758 hr = hr2; 759 } 760 761 return hr; 755 762 } 756 763 … … 760 767 const ComObjPtr<Guest> &p = d->p; 761 768 762 HRESULT rc= S_OK;769 HRESULT hr = S_OK; 763 770 764 771 try … … 768 775 NULL); 769 776 770 DnDGuestResponse *p DnD= d->response();777 DnDGuestResponse *pResp = d->response(); 771 778 /* This blocks until the request is answered (or timeout). */ 772 p DnD->waitForGuestResponse();773 } 774 catch (HRESULT rc2)775 { 776 rc = rc2;777 } 778 779 return rc;779 pResp->waitForGuestResponse(); 780 } 781 catch (HRESULT hr2) 782 { 783 hr = hr2; 784 } 785 786 return hr; 780 787 } 781 788 … … 807 814 return S_OK; 808 815 809 HRESULT rc= S_OK;816 HRESULT hr = S_OK; 810 817 811 818 try … … 828 835 paParms); 829 836 830 DnDGuestResponse *p DnD= d->response();837 DnDGuestResponse *pResp = d->response(); 831 838 /* This blocks until the request is answered (or timeout). */ 832 if (p DnD->waitForGuestResponse() == VERR_TIMEOUT)839 if (pResp->waitForGuestResponse() == VERR_TIMEOUT) 833 840 return S_OK; 834 841 835 842 /* Copy the response info */ 836 *pResultAction = d->toMainAction(p DnD->defAction());837 Bstr(p DnD->format()).cloneTo(pstrFormat);843 *pResultAction = d->toMainAction(pResp->defAction()); 844 Bstr(pResp->format()).cloneTo(pstrFormat); 838 845 839 846 LogFlowFunc(("*pResultAction=%ld\n", *pResultAction)); 840 847 } 841 catch (HRESULT rc2)842 { 843 rc = rc2;844 } 845 846 return rc;848 catch (HRESULT hr2) 849 { 850 hr = hr2; 851 } 852 853 return hr; 847 854 } 848 855 … … 853 860 const ComObjPtr<Guest> &p = d->p; 854 861 855 HRESULT rc= S_OK;862 HRESULT hr = S_OK; 856 863 857 864 try … … 868 875 paParms[i++].setUInt32((uint32_t)sfaData.size()); 869 876 870 DnDGuestResponse *p DnD= d->response();877 DnDGuestResponse *pResp = d->response(); 871 878 /* Reset any old progress status. */ 872 p DnD->resetProgress(p);879 pResp->resetProgress(p); 873 880 874 881 /* Note: The actual data transfer of files/directoies is performed by the … … 879 886 880 887 /* Query the progress object to the caller. */ 881 p DnD->queryProgressTo(ppProgress);882 } 883 catch (HRESULT rc2)884 { 885 rc = rc2;886 } 887 888 return rc;888 pResp->queryProgressTo(ppProgress); 889 } 890 catch (HRESULT hr2) 891 { 892 hr = hr2; 893 } 894 895 return hr; 889 896 } 890 897 … … 901 908 *pDefaultAction = DragAndDropAction_Ignore; 902 909 903 HRESULT rc= S_OK;910 HRESULT hr = S_OK; 904 911 905 912 try … … 913 920 paParms); 914 921 915 DnDGuestResponse *pDnD = d->response();916 /* This blocks until the request is answered (or timeout). */917 if (p DnD->waitForGuestResponse() == VERR_TIMEOUT)922 /* This blocks until the request is answered (or timed out). */ 923 DnDGuestResponse *pResp = d->response(); 924 if (pResp->waitForGuestResponse() == VERR_TIMEOUT) 918 925 return S_OK; 919 926 920 if (isDnDIgnoreAction(p DnD->defAction()))927 if (isDnDIgnoreAction(pResp->defAction())) 921 928 return S_OK; 922 929 923 930 /* Fetch the default action to use. */ 924 *pDefaultAction = d->toMainAction(pDnD->defAction()); 925 /* Convert the formats strings to a vector of strings. */ 926 d->toFormatSafeArray(pDnD->format(), ComSafeArrayOutArg(formats)); 927 /* Convert the action bit field to a vector of actions. */ 928 d->toMainActions(pDnD->allActions(), ComSafeArrayOutArg(allowedActions)); 931 *pDefaultAction = d->toMainAction(pResp->defAction()); 932 d->toFormatSafeArray(pResp->format(), ComSafeArrayOutArg(formats)); 933 d->toMainActions(pResp->allActions(), ComSafeArrayOutArg(allowedActions)); 929 934 930 935 LogFlowFunc(("*pDefaultAction=0x%x\n", *pDefaultAction)); 931 936 } 932 catch (HRESULT rc2)933 { 934 rc = rc2;935 } 936 937 return rc;937 catch (HRESULT hr2) 938 { 939 hr = hr2; 940 } 941 942 return hr; 938 943 } 939 944 … … 957 962 pcszFormat, uAction, fNeedsDropDir)); 958 963 959 DnDGuestResponse *pDnD = d->response(); 960 AssertPtr(pDnD); 964 DnDGuestResponse *pResp = d->response(); 965 AssertPtr(pResp); 966 967 pResp->reset(); 961 968 962 969 if (fNeedsDropDir) … … 970 977 LogFlowFunc(("Dropped files directory on the host is: %s\n", szDropDir)); 971 978 972 p DnD->setDropDir(szDropDir);979 pResp->setDropDir(szDropDir); 973 980 } 974 981 … … 982 989 983 990 /* Reset any old data and the progress status. */ 984 p DnD->reset();985 p DnD->resetProgress(p);991 pResp->reset(); 992 pResp->resetProgress(p); 986 993 987 994 d->hostCall(DragAndDropSvc::HOST_DND_GH_EVT_DROPPED, … … 990 997 991 998 /* Query the progress object to the caller. */ 992 p DnD->queryProgressTo(ppProgress);993 } 994 catch (HRESULT rc2)995 { 996 hr = rc2;999 pResp->queryProgressTo(ppProgress); 1000 } 1001 catch (HRESULT hr2) 1002 { 1003 hr = hr2; 997 1004 } 998 1005 … … 1019 1026 1020 1027 Utf8Str strFormat = pResp->format(); 1021 LogFlowFunc(("strFormat=%s, strDropDir=%s\n",1022 strFormat.c_str(), pResp->dropDir().c_str()));1028 LogFlowFunc(("strFormat=%s, cbData=%zu, pvData=0x%p\n", 1029 strFormat.c_str(), cbData, pvData)); 1023 1030 1024 1031 if (DnDMIMEHasFileURLs(strFormat.c_str(), strFormat.length())) 1025 1032 { 1033 LogFlowFunc(("strDropDir=%s\n", pResp->dropDir().c_str())); 1034 1026 1035 DnDURIList lstURI; 1027 1036 int rc2 = lstURI.RootFromURIData(pvData, cbData, 0 /* fFlags */); … … 1029 1038 { 1030 1039 Utf8Str strURIs = lstURI.RootToString(pResp->dropDir()); 1031 if (sfaData.resize(strURIs.length())) 1032 memcpy(sfaData.raw(), strURIs.c_str(), strURIs.length()); 1040 size_t cbURIs = strURIs.length(); 1041 if (sfaData.resize(cbURIs + 1 /* Include termination */)) 1042 memcpy(sfaData.raw(), strURIs.c_str(), cbURIs); 1033 1043 else 1034 1044 hr = E_OUTOFMEMORY; … … 1049 1059 } 1050 1060 1051 LogFlowFunc(("cbData=%zu\n", cbData));1052 1053 1061 /* Detach in any case, regardless of data size. */ 1054 1062 sfaData.detachTo(ComSafeArrayOutArg(data));
Note:
See TracChangeset
for help on using the changeset viewer.