Changeset 49891 in vbox for trunk/src/VBox/HostServices/DragAndDrop/dndmanager.cpp
- Timestamp:
- Dec 12, 2013 8:09:20 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 91269
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/VBox-4.1 merged: 85944-85947,85949-85950,85953,86701,86728,87009 /branches/andy/draganddrop (added) merged: 90781-91268
- Property svn:mergeinfo changed
-
trunk/src/VBox
- Property svn:mergeinfo changed
/branches/andy/draganddrop/src/VBox (added) merged: 90781-91268
- Property svn:mergeinfo changed
-
trunk/src/VBox/HostServices/DragAndDrop/dndmanager.cpp
r44102 r49891 5 5 6 6 /* 7 * Copyright (C) 2011-201 2Oracle Corporation7 * Copyright (C) 2011-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 20 20 ******************************************************************************/ 21 21 22 #define LOG_GROUP LOG_GROUP_HGCM 22 #ifdef LOG_GROUP 23 #undef LOG_GROUP 24 #endif 25 #define LOG_GROUP LOG_GROUP_GUEST_DND 23 26 24 27 #include "dndmanager.h" … … 29 32 #include <iprt/path.h> 30 33 #include <iprt/uri.h> 31 32 #define VERBOSE 133 34 #if defined(VERBOSE) && defined(DEBUG_poetzsch)35 # include <iprt/stream.h>36 # define DO(s) RTPrintf s37 #else38 # define DO(s) do {} while(0)39 //# define DO(s) Log s40 #endif41 34 42 35 /****************************************************************************** … … 65 58 paTmpParms[1].setUInt32(m_strPath.length() + 1); 66 59 paTmpParms[2].setUInt32(fMode); 60 67 61 m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_DIR, 3, paTmpParms); 68 62 } … … 97 91 public: 98 92 DnDHGSendFilePrivate(const RTCString &strHostPath, const RTCString &strGuestPath, uint32_t fMode, uint64_t cbSize, PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser); 99 ~DnDHGSendFilePrivate();93 virtual ~DnDHGSendFilePrivate(); 100 94 101 95 int currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); … … 104 98 RTCString m_strHostPath; 105 99 RTCString m_strGuestPath; 106 uint64_t m_cb Size;107 uint64_t m_cb Done;100 uint64_t m_cbFileSize; 101 uint64_t m_cbFileProcessed; 108 102 RTFILE m_hCurFile; 109 103 VBOXHGCMSVCPARM m_paSkelParms[5]; … … 146 140 : m_strHostPath(strHostPath) 147 141 , m_strGuestPath(strGuestPath) 148 , m_cb Size(cbSize)149 , m_cb Done(0)142 , m_cbFileSize(cbSize) 143 , m_cbFileProcessed(0) 150 144 , m_hCurFile(0) 151 145 , m_pfnProgressCallback(pfnProgressCallback) … … 157 151 m_paSkelParms[3].setUInt32(0); 158 152 m_paSkelParms[4].setUInt32(fMode); 153 159 154 m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5, m_paSkelParms); 160 155 } … … 178 173 if (!m_hCurFile) 179 174 { 180 rc = RTFileOpen(&m_hCurFile, m_strHostPath.c_str(), RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_ALL); 181 if (RT_FAILURE(rc)) 182 return rc; 183 } 184 185 /* How big is the pointer provided by the guest? */ 186 uint32_t cbToRead = paParms[2].u.pointer.size; 175 /* Open files on the host with RTFILE_O_DENY_WRITE to prevent races where the host 176 * writes to the file while the guest transfers it over. */ 177 rc = RTFileOpen(&m_hCurFile, m_strHostPath.c_str(), 178 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE); 179 } 180 187 181 size_t cbRead; 188 rc = RTFileRead(m_hCurFile, paParms[2].u.pointer.addr, cbToRead, &cbRead); 189 if (RT_FAILURE(rc)) 190 { 191 /* On error, immediately close the file. */ 192 RTFileClose(m_hCurFile); 193 m_hCurFile = 0; 194 return rc; 195 } 196 m_cbDone += cbRead; 197 /* Tell the guest the actual size. */ 198 paParms[3].setUInt32(cbRead); 199 /* Check if we are done. */ 200 if (m_cbSize == m_cbDone) 201 { 202 RTFileClose(m_hCurFile); 203 m_hCurFile = 0; 204 } 205 else 206 { 207 /* More data! Prepare the next message. */ 208 m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5, m_paSkelParms); 209 } 210 211 /* Advance progress info */ 212 if ( RT_SUCCESS(rc) 213 && m_pfnProgressCallback) 214 rc = m_pfnProgressCallback(cbRead, m_pvProgressUser); 182 if (RT_SUCCESS(rc)) 183 { 184 /* Get buffer size + pointer to buffer from guest side. */ 185 uint32_t cbToRead = paParms[2].u.pointer.size; 186 Assert(cbToRead); 187 void *pvBuf = paParms[2].u.pointer.addr; 188 AssertPtr(pvBuf); 189 rc = RTFileRead(m_hCurFile, pvBuf, cbToRead, &cbRead); 190 if (RT_LIKELY(RT_SUCCESS(rc))) 191 { 192 /* Advance. */ 193 m_cbFileProcessed += cbRead; 194 Assert(m_cbFileProcessed <= m_cbFileSize); 195 196 /* Tell the guest the actual size. */ 197 paParms[3].setUInt32(cbRead); 198 } 199 } 200 201 if (RT_SUCCESS(rc)) 202 { 203 /* Check if we are done. */ 204 bool fDone = m_cbFileSize == m_cbFileProcessed; 205 if (!fDone) 206 { 207 try 208 { 209 /* More data! Prepare the next message. */ 210 m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5 /* cParms */, 211 m_paSkelParms); 212 } 213 catch(std::bad_alloc &) 214 { 215 rc = VERR_NO_MEMORY; 216 } 217 } 218 219 /* Advance progress info. */ 220 if ( RT_SUCCESS(rc) 221 && m_pfnProgressCallback) 222 rc = m_pfnProgressCallback(cbRead, m_pvProgressUser); 223 224 if ( fDone 225 || RT_FAILURE(rc)) 226 { 227 RTFileClose(m_hCurFile); 228 m_hCurFile = 0; 229 } 230 } 215 231 216 232 return rc; … … 241 257 242 258 HGCM::Message *pCurMsg = m_pNextMsg; 259 AssertPtr(pCurMsg); 260 243 261 m_pNextMsg = 0; 244 262 rc = pCurMsg->getData(uMsg, cParms, paParms); … … 258 276 paTmpParms[0].setPointer(static_cast<uint8_t*>(pvOldData) + paParms[iPos].u.pointer.size, cOldData - paParms[iPos].u.pointer.size); 259 277 paTmpParms[1].setUInt32(cOldData - paParms[iPos].u.pointer.size); 260 m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA, 2, paTmpParms); 261 } 278 279 try 280 { 281 m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA, 2, paTmpParms); 282 } 283 catch(std::bad_alloc &) 284 { 285 rc = VERR_NO_MEMORY; 286 } 287 } 288 262 289 delete pCurMsg; 263 290 … … 280 307 */ 281 308 DnDHGSendDataMessage::DnDHGSendDataMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[], PFNDNDPROGRESS pfnProgressCallback, void *pvProgressUser) 282 : m_cbAll(0)283 , m_cbTransfered(0)284 , m_pfnProgressCallback(pfnProgressCallback)285 , m_pvProgressUser(pvProgressUser)309 : m_cbAll(0) 310 , m_cbTransfered(0) 311 , m_pfnProgressCallback(pfnProgressCallback) 312 , m_pvProgressUser(pvProgressUser) 286 313 { 287 314 RTCString strNewUris; … … 289 316 if (hasFileUrls(static_cast<const char*>(paParms[1].u.pointer.addr), paParms[1].u.pointer.size)) 290 317 { 291 DO(("old data'%s'\n", (char*)paParms[3].u.pointer.addr));318 LogFlowFunc(("Old data: '%s'\n", (char*)paParms[3].u.pointer.addr)); 292 319 /* The list is separated by newline (Even if only one file is 293 320 * listed). */ 294 RTCList<RTCString> oldUriList = RTCString(static_cast<const char*>(paParms[3].u.pointer.addr), paParms[3].u.pointer.size).split("\r\n"); 321 RTCList<RTCString> oldUriList = RTCString(static_cast<const char*>(paParms[3].u.pointer.addr), 322 paParms[3].u.pointer.size).split("\r\n"); 295 323 if (!oldUriList.isEmpty()) 296 324 { … … 337 365 m_cbAll += paParms[4].u.uint32; 338 366 /* The first message is the meta info for the data and the data itself. */ 339 m_pNextPathMsg = new DnDHGSendDataMessagePrivate(uMsg, cParms, paParms, &DnDHGSendDataMessage::progressCallback, this); 340 341 DO(("new data '%s'\n", (char*)paParms[3].u.pointer.addr)); 342 DO(("cbAll: %u\n", m_cbAll)); 343 DO(("cbData: %u\n", paParms[4].u.uint32)); 367 m_pNextPathMsg = new DnDHGSendDataMessagePrivate(uMsg, cParms, paParms, 368 &DnDHGSendDataMessage::progressCallback, this); 369 370 LogFlowFunc(("new data '%s'\n", (char*)paParms[3].u.pointer.addr)); 371 LogFlowFunc(("cbAll: %zu\n", m_cbAll)); 372 LogFlowFunc(("cbData: %RU32\n", paParms[4].u.uint32)); 344 373 345 374 for (size_t i = 0; i < m_uriList.size(); ++i) 346 DO(("file: %s : %s - %o - %ld\n", m_uriList.at(i).m_strHostPath.c_str(), m_uriList.at(i).m_strGuestPath.c_str(), m_uriList.at(i).m_fMode, m_uriList.at(i).m_cbSize)); 375 LogFlowFunc(("file: %s : %s - %o - %ld\n", 376 m_uriList.at(i).m_strHostPath.c_str(), m_uriList.at(i).m_strGuestPath.c_str(), 377 m_uriList.at(i).m_fMode, m_uriList.at(i).m_cbSize)); 347 378 } 348 379 … … 391 422 * this could be directories or regular files. */ 392 423 PathEntry nextPath = m_uriList.first(); 393 if (RTFS_IS_DIRECTORY(nextPath.m_fMode)) 394 m_pNextPathMsg = new DnDHGSendDirPrivate(nextPath.m_strGuestPath, nextPath.m_fMode, nextPath.m_cbSize, &DnDHGSendDataMessage::progressCallback, this); 395 else if (RTFS_IS_FILE(nextPath.m_fMode)) 396 m_pNextPathMsg = new DnDHGSendFilePrivate(nextPath.m_strHostPath, nextPath.m_strGuestPath, nextPath.m_fMode, nextPath.m_cbSize, &DnDHGSendDataMessage::progressCallback, this); 397 else 398 AssertMsgFailedReturn(("type '%d' is not supported for path '%s'", nextPath.m_fMode, nextPath.m_strHostPath.c_str()), VERR_NO_DATA); 399 m_uriList.removeFirst(); 400 } 424 try 425 { 426 if (RTFS_IS_DIRECTORY(nextPath.m_fMode)) 427 m_pNextPathMsg = new DnDHGSendDirPrivate(nextPath.m_strGuestPath, 428 nextPath.m_fMode, nextPath.m_cbSize, 429 &DnDHGSendDataMessage::progressCallback, this); 430 else if (RTFS_IS_FILE(nextPath.m_fMode)) 431 m_pNextPathMsg = new DnDHGSendFilePrivate(nextPath.m_strHostPath, nextPath.m_strGuestPath, 432 nextPath.m_fMode, nextPath.m_cbSize, 433 &DnDHGSendDataMessage::progressCallback, this); 434 else 435 AssertMsgFailedReturn(("type '%d' is not supported for path '%s'", 436 nextPath.m_fMode, nextPath.m_strHostPath.c_str()), VERR_NO_DATA); 437 438 m_uriList.removeFirst(); 439 } 440 catch(std::bad_alloc &) 441 { 442 rc = VERR_NO_MEMORY; 443 } 444 } 445 401 446 return rc; 402 447 } … … 404 449 bool DnDHGSendDataMessage::hasFileUrls(const char *pcszFormat, size_t cbMax) const 405 450 { 406 DO(("format %s\n", pcszFormat));407 /* text/uri also an official variant? */451 LogFlowFunc(("format %s\n", pcszFormat)); 452 /** @todo text/uri also an official variant? */ 408 453 return RTStrNICmp(pcszFormat, "text/uri-list", cbMax) == 0 409 454 || RTStrNICmp(pcszFormat, "x-special/gnome-icon-list", cbMax) == 0; … … 435 480 m_uriList.append(PathEntry(pcszPath, &pcszPath[cbBaseLen], objInfo.Attr.fMode, cbSize)); 436 481 m_cbAll += cbSize; 437 DO(("cbFile: %u\n", cbSize));482 LogFlowFunc(("cbFile: %RU64\n", cbSize)); 438 483 439 484 PRTDIR hDir; … … 518 563 && pSelf->m_cbAll) 519 564 rc = pSelf->m_pfnProgressCallback((uint64_t)pSelf->m_cbTransfered * 100 / pSelf->m_cbAll, 520 DragAndDropSvc::DND_PROGRESS_RUNNING, pSelf->m_pvProgressUser);565 DragAndDropSvc::DND_PROGRESS_RUNNING, VINF_SUCCESS /* rc */, pSelf->m_pvProgressUser); 521 566 522 567 return rc; … … 530 575 { 531 576 int rc = VINF_SUCCESS; 532 switch (uMsg) 533 { 534 case DragAndDropSvc::HOST_DND_HG_EVT_ENTER: 535 { 536 clear(); 537 LogFlowFunc(("HOST_DND_HG_EVT_ENTER\n")); 538 DO(("HOST_DND_HG_EVT_ENTER\n")); 539 /* Verify parameter count and types. */ 540 if ( cParms != 7 541 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */ 542 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */ 543 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */ 544 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */ 545 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */ 546 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR /* data */ 547 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */) 548 rc = VERR_INVALID_PARAMETER; 549 else 550 { 551 m_fOpInProcess = true; 552 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 553 m_dndMessageQueue.append(pMessage); 554 } 555 break; 556 } 557 case DragAndDropSvc::HOST_DND_HG_EVT_MOVE: 558 { 559 LogFlowFunc(("HOST_DND_HG_EVT_MOVE\n")); 560 DO(("HOST_DND_HG_EVT_MOVE\n")); 561 /* Verify parameter count and types. */ 562 if ( cParms != 7 563 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */ 564 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */ 565 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */ 566 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */ 567 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */ 568 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR /* data */ 569 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */) 570 rc = VERR_INVALID_PARAMETER; 571 else 572 { 573 m_fOpInProcess = true; 574 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 575 m_dndMessageQueue.append(pMessage); 576 } 577 break; 578 } 579 case DragAndDropSvc::HOST_DND_HG_EVT_LEAVE: 580 { 581 LogFlowFunc(("HOST_DND_HG_EVT_LEAVE\n")); 582 DO(("HOST_DND_HG_EVT_LEAVE\n")); 583 584 /* Verify parameter count and types. */ 585 if (cParms != 0) 586 rc = VERR_INVALID_PARAMETER; 587 else 588 { 589 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 590 m_dndMessageQueue.append(pMessage); 591 } 592 m_fOpInProcess = false; 593 break; 594 } 595 case DragAndDropSvc::HOST_DND_HG_EVT_DROPPED: 596 { 597 LogFlowFunc(("HOST_DND_HG_EVT_DROPPED\n")); 598 DO(("HOST_DND_HG_EVT_DROPPED\n")); 599 /* Verify parameter count and types. */ 600 if ( cParms != 7 601 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */ 602 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */ 603 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */ 604 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */ 605 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */ 606 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR /* data */ 607 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */) 608 rc = VERR_INVALID_PARAMETER; 609 else 610 { 611 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 612 m_dndMessageQueue.append(pMessage); 613 } 614 break; 615 } 616 case DragAndDropSvc::HOST_DND_HG_SND_DATA: 617 { 618 LogFlowFunc(("HOST_DND_HG_SND_DATA\n")); 619 DO(("HOST_DND_HG_SND_DATA\n")); 620 621 /* Verify parameter count and types. */ 622 if ( cParms != 5 623 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */ 624 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* format */ 625 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* format size */ 626 || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR /* data */ 627 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* data size */) 628 rc = VERR_INVALID_PARAMETER; 629 else 630 { 631 DnDHGSendDataMessage *pMessage = new DnDHGSendDataMessage(uMsg, cParms, paParms, m_pfnProgressCallback, m_pvProgressUser); 632 m_dndMessageQueue.append(pMessage); 633 } 634 break; 635 } 636 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 637 case DragAndDropSvc::HOST_DND_GH_REQ_PENDING: 638 { 639 LogFlowFunc(("HOST_DND_GH_REQ_PENDING\n")); 640 DO(("HOST_DND_GH_REQ_PENDING\n")); 641 642 /* Verify parameter count and types. */ 643 if ( cParms != 1 644 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */) 645 rc = VERR_INVALID_PARAMETER; 646 else 647 { 648 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 649 m_dndMessageQueue.append(pMessage); 650 } 651 break; 652 } 653 case DragAndDropSvc::HOST_DND_GH_EVT_DROPPED: 654 { 655 LogFlowFunc(("HOST_DND_GH_EVT_DROPPED\n")); 656 DO(("HOST_DND_GH_EVT_DROPPED\n")); 657 658 /* Verify parameter count and types. */ 659 if ( cParms != 3 660 || paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* format */ 661 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* format size */ 662 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* action */) 663 rc = VERR_INVALID_PARAMETER; 664 else 665 { 666 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 667 m_dndMessageQueue.append(pMessage); 668 } 669 break; 670 } 671 #endif 672 default: rc = VERR_NOT_IMPLEMENTED; break; 577 578 try 579 { 580 switch (uMsg) 581 { 582 case DragAndDropSvc::HOST_DND_HG_EVT_ENTER: 583 { 584 clear(); 585 LogFlowFunc(("HOST_DND_HG_EVT_ENTER\n")); 586 587 /* Verify parameter count and types. */ 588 if ( cParms != 7 589 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */ 590 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */ 591 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */ 592 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */ 593 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */ 594 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR /* data */ 595 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */) 596 rc = VERR_INVALID_PARAMETER; 597 else 598 { 599 m_fOpInProcess = true; 600 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 601 m_dndMessageQueue.append(pMessage); 602 } 603 break; 604 } 605 case DragAndDropSvc::HOST_DND_HG_EVT_MOVE: 606 { 607 LogFlowFunc(("HOST_DND_HG_EVT_MOVE\n")); 608 609 /* Verify parameter count and types. */ 610 if ( cParms != 7 611 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */ 612 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */ 613 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */ 614 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */ 615 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */ 616 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR /* data */ 617 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */) 618 rc = VERR_INVALID_PARAMETER; 619 else 620 { 621 m_fOpInProcess = true; 622 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 623 m_dndMessageQueue.append(pMessage); 624 } 625 break; 626 } 627 case DragAndDropSvc::HOST_DND_HG_EVT_LEAVE: 628 { 629 LogFlowFunc(("HOST_DND_HG_EVT_LEAVE\n")); 630 631 /* Verify parameter count and types. */ 632 if (cParms != 0) 633 rc = VERR_INVALID_PARAMETER; 634 else 635 { 636 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 637 m_dndMessageQueue.append(pMessage); 638 } 639 m_fOpInProcess = false; 640 break; 641 } 642 case DragAndDropSvc::HOST_DND_HG_EVT_DROPPED: 643 { 644 LogFlowFunc(("HOST_DND_HG_EVT_DROPPED\n")); 645 646 /* Verify parameter count and types. */ 647 if ( cParms != 7 648 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */ 649 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */ 650 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */ 651 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */ 652 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */ 653 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR /* data */ 654 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */) 655 rc = VERR_INVALID_PARAMETER; 656 else 657 { 658 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 659 m_dndMessageQueue.append(pMessage); 660 } 661 break; 662 } 663 case DragAndDropSvc::HOST_DND_HG_SND_DATA: 664 { 665 LogFlowFunc(("HOST_DND_HG_SND_DATA\n")); 666 667 /* Verify parameter count and types. */ 668 if ( cParms != 5 669 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */ 670 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* format */ 671 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* format size */ 672 || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR /* data */ 673 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* data size */) 674 rc = VERR_INVALID_PARAMETER; 675 else 676 { 677 DnDHGSendDataMessage *pMessage = new DnDHGSendDataMessage(uMsg, cParms, paParms, m_pfnProgressCallback, m_pvProgressUser); 678 m_dndMessageQueue.append(pMessage); 679 } 680 break; 681 } 682 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 683 case DragAndDropSvc::HOST_DND_GH_REQ_PENDING: 684 { 685 LogFlowFunc(("HOST_DND_GH_REQ_PENDING\n")); 686 687 /* Verify parameter count and types. */ 688 if ( cParms != 1 689 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */) 690 rc = VERR_INVALID_PARAMETER; 691 else 692 { 693 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 694 m_dndMessageQueue.append(pMessage); 695 } 696 break; 697 } 698 case DragAndDropSvc::HOST_DND_GH_EVT_DROPPED: 699 { 700 LogFlowFunc(("HOST_DND_GH_EVT_DROPPED\n")); 701 702 /* Verify parameter count and types. */ 703 if ( cParms != 3 704 || paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* format */ 705 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* format size */ 706 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* action */) 707 rc = VERR_INVALID_PARAMETER; 708 else 709 { 710 try 711 { 712 DnDGenericMessage *pMessage 713 = new DnDGenericMessage(uMsg, cParms, paParms); 714 m_dndMessageQueue.append(pMessage); 715 } 716 catch(std::bad_alloc &) 717 { 718 rc = VERR_NO_MEMORY; 719 } 720 } 721 break; 722 } 723 #endif 724 default: 725 rc = VERR_NOT_IMPLEMENTED; 726 break; 727 } 728 } 729 catch(std::bad_alloc &) 730 { 731 rc = VERR_NO_MEMORY; 673 732 } 674 733 … … 710 769 } 711 770 712 DO(("next msg info: %d %d%Rrc\n", *puMsg, *pcParms, rc));771 LogFlowFunc(("Returning puMsg=%RU32, pcParms=%RU32, rc=%Rrc\n", *puMsg, *pcParms, rc)); 713 772 return rc; 714 773 } … … 716 775 int DnDManager::nextMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 717 776 { 777 LogFlowFunc(("uMsg=%RU32, cParms=%RU32\n", uMsg, cParms)); 778 718 779 if (!m_pCurMsg) 719 780 { 720 781 /* Check for pending messages in our queue. */ 721 782 if (m_dndMessageQueue.isEmpty()) 783 { 784 LogFlowFunc(("Message queue is empty, returning\n")); 722 785 return VERR_NO_DATA; 786 } 787 723 788 m_pCurMsg = m_dndMessageQueue.first(); 724 789 m_dndMessageQueue.removeFirst(); … … 727 792 /* Fetch the current message info */ 728 793 int rc = m_pCurMsg->currentMessage(uMsg, cParms, paParms); 729 /* If this message not provide any additional sub messages, clear it. */794 /* If this message doesn't provide any additional sub messages, clear it. */ 730 795 if (!m_pCurMsg->isMessageWaiting()) 796 { 797 delete m_pCurMsg; 798 m_pCurMsg = NULL; 799 } 800 801 /* 802 * If there was an error handling the current message or the user has canceled 803 * the operation, we need to cleanup all pending events and inform the progress 804 * callback about our exit. 805 */ 806 if ( RT_FAILURE(rc) 807 && m_pfnProgressCallback) 808 { 809 /* Clear any pending messages. */ 810 clear(); 811 812 /* Create a new cancel message to inform the guest + call 813 * the host whether the current transfer was canceled or aborted 814 * due to an error. */ 815 try 816 { 817 Assert(!m_pCurMsg); 818 m_pCurMsg = new DnDHGCancelMessage(); 819 m_pfnProgressCallback(100 /* Percent */, 820 rc == VERR_CANCELLED 821 ? DragAndDropSvc::DND_PROGRESS_CANCELLED 822 : DragAndDropSvc::DND_PROGRESS_ERROR, rc, m_pvProgressUser); 823 } 824 catch(std::bad_alloc &) 825 { 826 rc = VERR_NO_MEMORY; 827 } 828 } 829 830 LogFlowFunc(("Message processed with rc=%Rrc\n", rc)); 831 return rc; 832 } 833 834 void DnDManager::clear() 835 { 836 if (m_pCurMsg) 731 837 { 732 838 delete m_pCurMsg; 733 839 m_pCurMsg = 0; 734 840 } 735 736 /* If the user has canceled the operation, we need to cleanup all pending737 * events and inform the progress callback about our successful cleanup. */738 if ( rc == VERR_CANCELLED739 && m_pfnProgressCallback)740 {741 /* Clear any pending messages */742 clear();743 /* Create a new cancel message to inform the guest. */744 m_pCurMsg = new DnDHGCancelMessage();745 m_pfnProgressCallback(100, DragAndDropSvc::DND_PROGRESS_CANCELLED, m_pvProgressUser);746 }747 748 DO(("next msg: %d %d %Rrc\n", uMsg, cParms, rc));749 return rc;750 }751 752 void DnDManager::clear()753 {754 if (m_pCurMsg)755 {756 delete m_pCurMsg;757 m_pCurMsg = 0;758 }759 841 while (!m_dndMessageQueue.isEmpty()) 760 842 {
Note:
See TracChangeset
for help on using the changeset viewer.