Changeset 55422 in vbox for trunk/src/VBox/HostServices/DragAndDrop/dndmanager.cpp
- Timestamp:
- Apr 24, 2015 1:52:33 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 99765
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/DragAndDrop/dndmanager.cpp
r50561 r55422 1 1 /* $Id$ */ 2 2 /** @file 3 * Drag and Drop manager .3 * Drag and Drop manager: Handling of DnD messages on the host side. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 2011-201 4Oracle Corporation7 * Copyright (C) 2011-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 34 34 35 35 /****************************************************************************** 36 * Private declarations *37 ******************************************************************************/38 39 typedef DECLCALLBACK(int) FNDNDPRIVATEPROGRESS(size_t cbDone, void *pvUser);40 typedef FNDNDPRIVATEPROGRESS *PFNDNDPRIVATEPROGRESS;41 42 /**43 * Internal DnD message class for informing the44 * guest about a new directory.45 *46 * @see DnDHGSendDataMessage47 */48 class DnDHGSendDirPrivate: public DnDMessage49 {50 public:51 52 DnDHGSendDirPrivate(DnDURIObject URIObject,53 PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser)54 : m_URIObject(URIObject)55 , m_pfnProgressCallback(pfnProgressCallback)56 , m_pvProgressUser(pvProgressUser)57 {58 RTCString strPath = m_URIObject.GetDestPath();59 LogFlowFunc(("strPath=%s (%zu)\n", strPath.c_str(), strPath.length()));60 61 VBOXHGCMSVCPARM paTmpParms[3];62 paTmpParms[0].setString(strPath.c_str());63 paTmpParms[1].setUInt32((uint32_t)(strPath.length() + 1));64 paTmpParms[2].setUInt32(m_URIObject.GetMode());65 66 m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_DIR, 3, paTmpParms);67 }68 69 public:70 71 int currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])72 {73 int rc = DnDMessage::currentMessage(uMsg, cParms, paParms);74 /* Advance progress info */75 if ( RT_SUCCESS(rc)76 && m_pfnProgressCallback)77 rc = m_pfnProgressCallback(m_URIObject.GetSize(), m_pvProgressUser);78 79 return rc;80 }81 82 protected:83 84 DnDURIObject m_URIObject;85 86 /* Progress stuff. */87 PFNDNDPRIVATEPROGRESS m_pfnProgressCallback;88 void *m_pvProgressUser;89 };90 91 /**92 * Internal DnD message class for informing the guest about a new file.93 *94 * @see DnDHGSendDataMessage95 */96 class DnDHGSendFilePrivate: public DnDMessage97 {98 public:99 100 DnDHGSendFilePrivate(DnDURIObject URIObject,101 PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser);102 virtual ~DnDHGSendFilePrivate(void);103 104 public:105 106 int currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);107 108 protected:109 110 DnDURIObject m_URIObject;111 /** Skeleton parameters for the next upcoming message in case112 * the file data didn't fit completely into the first one. */113 VBOXHGCMSVCPARM m_aSkelParms[5];114 115 /* Progress stuff. */116 PFNDNDPRIVATEPROGRESS m_pfnProgressCallback;117 void *m_pvProgressUser;118 };119 120 /**121 * Internal DnD message class for informing the guest about new drag & drop122 * data.123 *124 * @see DnDHGSendDataMessage125 */126 class DnDHGSendDataMessagePrivate: public DnDMessage127 {128 public:129 130 DnDHGSendDataMessagePrivate(uint32_t uMsg, uint32_t cParms,131 VBOXHGCMSVCPARM paParms[],132 PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser);133 int currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);134 135 protected:136 size_t m_cbSize;137 size_t m_cbDone;138 139 /* Progress stuff. */140 PFNDNDPRIVATEPROGRESS m_pfnProgressCallback;141 void *m_pvProgressUser;142 };143 144 /******************************************************************************145 * Implementation *146 ******************************************************************************/147 148 /******************************************************************************149 * DnDHGSendFilePrivate *150 ******************************************************************************/151 152 DnDHGSendFilePrivate::DnDHGSendFilePrivate(DnDURIObject URIObject,153 PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser)154 : m_URIObject(URIObject)155 , m_pfnProgressCallback(pfnProgressCallback)156 , m_pvProgressUser(pvProgressUser)157 {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);168 }169 170 DnDHGSendFilePrivate::~DnDHGSendFilePrivate(void)171 {172 }173 174 int DnDHGSendFilePrivate::currentMessage(uint32_t uMsg, uint32_t cParms,175 VBOXHGCMSVCPARM paParms[])176 {177 if (!m_pNextMsg)178 return VERR_NO_DATA;179 180 int rc = m_pNextMsg->getData(uMsg, cParms, paParms);181 clearNextMsg();182 if (RT_FAILURE(rc))183 return rc;184 185 uint32_t cbRead;186 if (RT_SUCCESS(rc))187 {188 /* Get buffer size + pointer to buffer from guest side. */189 uint32_t cbToRead = paParms[2].u.pointer.size; /* cbData */190 Assert(cbToRead);191 void *pvBuf = paParms[2].u.pointer.addr; /* pvData */192 AssertPtr(pvBuf);193 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 198 if (RT_LIKELY(RT_SUCCESS(rc)))199 {200 /* Tell the guest the actual size read. */201 paParms[3].setUInt32((uint32_t)cbRead); /* cbData */202 }203 }204 205 if (RT_SUCCESS(rc))206 {207 if (!m_URIObject.IsComplete())208 {209 try210 {211 /* More data needed to send over. Prepare the next message. */212 m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5 /* cParms */,213 m_aSkelParms);214 }215 catch(std::bad_alloc &)216 {217 rc = VERR_NO_MEMORY;218 }219 }220 221 /* Advance progress info. */222 if ( RT_SUCCESS(rc)223 && m_pfnProgressCallback)224 {225 rc = m_pfnProgressCallback(cbRead, m_pvProgressUser);226 }227 }228 229 return rc;230 }231 232 /******************************************************************************233 * DnDHGSendDataMessagePrivate *234 ******************************************************************************/235 236 DnDHGSendDataMessagePrivate::DnDHGSendDataMessagePrivate(uint32_t uMsg, uint32_t cParms,237 VBOXHGCMSVCPARM paParms[],238 PFNDNDPRIVATEPROGRESS pfnProgressCallback,239 void *pvProgressUser)240 : m_cbSize(paParms[4].u.uint32)241 , m_cbDone(0)242 , m_pfnProgressCallback(pfnProgressCallback)243 , m_pvProgressUser(pvProgressUser)244 {245 /* Create the initial data message. This might throw246 * a bad_alloc exception. */247 m_pNextMsg = new HGCM::Message(uMsg, cParms, paParms);248 }249 250 int DnDHGSendDataMessagePrivate::currentMessage(uint32_t uMsg, uint32_t cParms,251 VBOXHGCMSVCPARM paParms[])252 {253 /** @todo Don't copy the data parts ... just move the data pointer in254 * the original data ptr. */255 if (!m_pNextMsg)256 return VERR_NO_DATA;257 258 int rc = VINF_SUCCESS;259 260 HGCM::Message *pCurMsg = m_pNextMsg;261 AssertPtr(pCurMsg);262 263 m_pNextMsg = 0;264 rc = pCurMsg->getData(uMsg, cParms, paParms);265 266 /* Depending on the current message, the data pointer is on a267 * different position (HOST_DND_HG_SND_DATA=3;268 * HOST_DND_HG_SND_MORE_DATA=0). */269 int iPos = uMsg == DragAndDropSvc::HOST_DND_HG_SND_DATA ? 3 : 0;270 m_cbDone += paParms[iPos + 1].u.uint32;271 272 /* Info + data send already? */273 if (rc == VERR_BUFFER_OVERFLOW)274 {275 paParms[iPos + 1].u.uint32 = paParms[iPos].u.pointer.size;276 VBOXHGCMSVCPARM paTmpParms[2];277 void *pvOldData;278 uint32_t cOldData;279 pCurMsg->getParmPtrInfo(iPos, &pvOldData, &cOldData);280 paTmpParms[0].setPointer(static_cast<uint8_t*>(pvOldData) + paParms[iPos].u.pointer.size, cOldData - paParms[iPos].u.pointer.size);281 paTmpParms[1].setUInt32(cOldData - paParms[iPos].u.pointer.size);282 283 try284 {285 m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA, 2, paTmpParms);286 }287 catch(std::bad_alloc &)288 {289 rc = VERR_NO_MEMORY;290 }291 }292 293 if (pCurMsg)294 delete pCurMsg;295 296 /* Advance progress info. */297 if ( RT_SUCCESS(rc)298 && m_pfnProgressCallback)299 {300 rc = m_pfnProgressCallback(m_cbDone, m_pvProgressUser);301 }302 303 return rc;304 }305 306 /******************************************************************************307 * DnDHGSendDataMessage *308 ******************************************************************************/309 310 /*311 * This class is a meta message class. It doesn't consist of any own message312 * data, but handle the meta info, the data itself as well as any files or313 * directories which have to be transfered to the guest.314 */315 DnDHGSendDataMessage::DnDHGSendDataMessage(uint32_t uMsg, uint32_t cParms,316 VBOXHGCMSVCPARM paParms[],317 PFNDNDPROGRESS pfnProgressCallback,318 void *pvProgressUser)319 : m_cbTotal(0)320 , m_cbTransfered(0)321 , m_pfnProgressCallback(pfnProgressCallback)322 , m_pvProgressUser(pvProgressUser)323 {324 if (cParms < 5) /* Paranoia. */325 return;326 327 const char *pszFormat = static_cast<const char*>(paParms[1].u.pointer.addr);328 uint32_t cbFormat = paParms[1].u.pointer.size;329 330 int rc = VINF_SUCCESS;331 RTCString strNewURIs;332 333 /* Do we need to build up a file tree? */334 if (DnDMIMEHasFileURLs(pszFormat, cbFormat))335 {336 const char *pszList = static_cast<const char*>(paParms[3].u.pointer.addr);337 AssertPtr(pszList);338 uint32_t cbList = paParms[3].u.pointer.size;339 Assert(cbList);340 341 LogFlowFunc(("Old data (%RU32 bytes): '%s'\n", cbList, pszList));342 343 /* The list is separated by newline (even if only one file is listed). */344 RTCList<RTCString> lstURIOrg345 = RTCString(pszList, cbList).split("\r\n");346 if (!lstURIOrg.isEmpty())347 {348 rc = m_lstURI.AppendURIPathsFromList(lstURIOrg, 0 /* fFlags */);349 if (RT_SUCCESS(rc))350 {351 /* Add the total size of all meta data + files transferred to352 * the message's total byte count. */353 m_cbTotal += m_lstURI.TotalBytes();354 355 /* We have to change the actual DnD data. Remove any host paths and356 * just decode the filename into the new data. The Guest Additions will357 * add the correct path again before sending the DnD drop event to358 * some window. */359 strNewURIs = m_lstURI.RootToString();360 361 /* Note: We don't delete the old pointer here, cause this is done362 * by the caller. We just use the RTString data, which has the363 * scope of this ctor. This is enough cause the data is copied in364 * the DnDHGSendDataMessagePrivate anyway. */365 paParms[3].u.pointer.addr = (void *)strNewURIs.c_str();366 paParms[3].u.pointer.size = (uint32_t)(strNewURIs.length() + 1);367 paParms[4].u.uint32 = (uint32_t)(strNewURIs.length() + 1);368 369 LogFlowFunc(("Set new data (%RU32 bytes): '%s'\n",370 paParms[3].u.pointer.size,371 (const char*)paParms[3].u.pointer.addr));372 }373 }374 }375 376 /* Add the size of the data to the todo list. */377 m_cbTotal += paParms[4].u.uint32;378 LogFlowFunc(("cbTotal=%zu\n", m_cbTotal));379 380 /* The first message is the meta info for the data and the data itself. */381 m_pNextPathMsg = new DnDHGSendDataMessagePrivate(uMsg, cParms, paParms,382 &DnDHGSendDataMessage::progressCallback, this);383 }384 385 DnDHGSendDataMessage::~DnDHGSendDataMessage(void)386 {387 if (m_pNextPathMsg)388 delete m_pNextPathMsg;389 }390 391 HGCM::Message* DnDHGSendDataMessage::nextHGCMMessage(void)392 {393 if (!m_pNextPathMsg)394 return NULL;395 396 return m_pNextPathMsg->nextHGCMMessage();397 }398 399 int DnDHGSendDataMessage::currentMessageInfo(uint32_t *puMsg, uint32_t *pcParms)400 {401 if (!m_pNextPathMsg)402 return VERR_NO_DATA;403 404 return m_pNextPathMsg->currentMessageInfo(puMsg, pcParms);405 }406 407 int DnDHGSendDataMessage::currentMessage(uint32_t uMsg,408 uint32_t cParms, VBOXHGCMSVCPARM paParms[])409 {410 if (!m_pNextPathMsg)411 return VERR_NO_DATA;412 413 /* Fill the data out of our current queued message. */414 int rc = m_pNextPathMsg->currentMessage(uMsg, cParms, paParms);415 /* Has this message more data to deliver? */416 if (!m_pNextPathMsg->isMessageWaiting())417 {418 delete m_pNextPathMsg;419 m_pNextPathMsg = NULL;420 }421 422 /* File/directory data to send? */423 if (!m_pNextPathMsg)424 {425 if (m_lstURI.IsEmpty())426 return rc;427 428 /* Create new messages based on our internal path list. Currently429 * this could be directories or regular files. */430 const DnDURIObject &nextObj = m_lstURI.First();431 try432 {433 uint32_t fMode = nextObj.GetMode();434 LogFlowFunc(("Processing srcPath=%s, dstPath=%s, fMode=0x%x, cbSize=%RU32, fIsDir=%RTbool, fIsFile=%RTbool\n",435 nextObj.GetSourcePath().c_str(), nextObj.GetDestPath().c_str(),436 fMode, nextObj.GetSize(),437 RTFS_IS_DIRECTORY(fMode), RTFS_IS_FILE(fMode)));438 439 if (RTFS_IS_DIRECTORY(fMode))440 m_pNextPathMsg = new DnDHGSendDirPrivate(nextObj,441 &DnDHGSendDataMessage::progressCallback /* pfnProgressCallback */,442 this /* pvProgressUser */);443 else if (RTFS_IS_FILE(fMode))444 m_pNextPathMsg = new DnDHGSendFilePrivate(nextObj,445 &DnDHGSendDataMessage::progressCallback /* pfnProgressCallback */,446 this /* pvProgressUser */);447 else448 AssertMsgFailedReturn(("fMode=0x%x is not supported for srcPath=%s, dstPath=%s\n",449 fMode, nextObj.GetSourcePath().c_str(), nextObj.GetDestPath().c_str()),450 VERR_NO_DATA);451 452 m_lstURI.RemoveFirst();453 }454 catch(std::bad_alloc &)455 {456 rc = VERR_NO_MEMORY;457 }458 }459 460 return rc;461 }462 463 int DnDHGSendDataMessage::progressCallback(size_t cbDone, void *pvUser)464 {465 AssertPtrReturn(pvUser, VERR_INVALID_POINTER);466 467 DnDHGSendDataMessage *pSelf = static_cast<DnDHGSendDataMessage *>(pvUser);468 AssertPtr(pSelf);469 470 /* How many bytes are transfered already. */471 pSelf->m_cbTransfered += cbDone;472 473 /* Advance progress info. */474 int rc = VINF_SUCCESS;475 if ( pSelf->m_pfnProgressCallback476 && pSelf->m_cbTotal)477 {478 AssertMsg(pSelf->m_cbTransfered <= pSelf->m_cbTotal,479 ("More bytes transferred (%zu) than expected (%zu), cbDone=%zu\n",480 pSelf->m_cbTransfered, pSelf->m_cbTotal, cbDone));481 482 unsigned uPercentage = (unsigned)((uint64_t)pSelf->m_cbTransfered * 100 / pSelf->m_cbTotal);483 rc = pSelf->m_pfnProgressCallback(RT_MIN(uPercentage, 100),484 DragAndDropSvc::DND_PROGRESS_RUNNING,485 VINF_SUCCESS /* rc */, pSelf->m_pvProgressUser);486 }487 488 return rc;489 }490 491 /******************************************************************************492 36 * DnDManager * 493 37 ******************************************************************************/ 494 38 495 int DnDManager::addMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[] )39 int DnDManager::addMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[], bool fAppend /* = true */) 496 40 { 497 41 int rc = VINF_SUCCESS; 498 42 43 LogFlowFunc(("uMsg=%RU32, cParms=%RU32, fAppend=%RTbool\n", uMsg, cParms, fAppend)); 44 499 45 try 500 46 { 47 DnDMessage *pMessage = NULL; 48 501 49 switch (uMsg) 502 50 { … … 505 53 clear(); 506 54 LogFlowFunc(("HOST_DND_HG_EVT_ENTER\n")); 507 508 /* Verify parameter count and types. */509 if ( cParms != 7510 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */511 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */512 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */513 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */514 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */515 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR /* data */516 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */)517 rc = VERR_INVALID_PARAMETER;518 else519 {520 m_fOpInProcess = true;521 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);522 m_dndMessageQueue.append(pMessage);523 }524 55 break; 525 56 } … … 528 59 { 529 60 LogFlowFunc(("HOST_DND_HG_EVT_MOVE\n")); 530 531 /* Verify parameter count and types. */532 if ( cParms != 7533 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */534 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */535 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */536 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */537 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */538 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR /* data */539 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */)540 {541 rc = VERR_INVALID_PARAMETER;542 }543 else544 {545 m_fOpInProcess = true;546 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);547 m_dndMessageQueue.append(pMessage);548 }549 61 break; 550 62 } … … 553 65 { 554 66 LogFlowFunc(("HOST_DND_HG_EVT_LEAVE\n")); 555 556 /* Verify parameter count and types. */557 if (cParms != 0)558 rc = VERR_INVALID_PARAMETER;559 else560 {561 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);562 m_dndMessageQueue.append(pMessage);563 }564 565 m_fOpInProcess = false;566 67 break; 567 68 } … … 570 71 { 571 72 LogFlowFunc(("HOST_DND_HG_EVT_DROPPED\n")); 572 573 /* Verify parameter count and types. */ 574 if ( cParms != 7 575 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */ 576 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */ 577 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */ 578 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */ 579 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */ 580 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR /* data */ 581 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */) 582 { 583 rc = VERR_INVALID_PARAMETER; 584 } 585 else 586 { 587 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 588 m_dndMessageQueue.append(pMessage); 589 } 73 break; 74 } 75 76 case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL: 77 { 78 LogFlowFunc(("HOST_DND_HG_EVT_CANCEL\n")); 79 80 pMessage = new DnDHGCancelMessage(); 590 81 break; 591 82 } … … 594 85 { 595 86 LogFlowFunc(("HOST_DND_HG_SND_DATA\n")); 596 597 /* Verify parameter count and types. */ 598 if ( cParms != 5 599 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */ 600 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* format */ 601 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* format size */ 602 || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR /* data */ 603 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* data size */) 604 { 605 rc = VERR_INVALID_PARAMETER; 606 } 607 else 608 { 609 DnDHGSendDataMessage *pMessage = 610 new DnDHGSendDataMessage(uMsg, cParms, paParms, 611 m_pfnProgressCallback, m_pvProgressUser); 612 m_dndMessageQueue.append(pMessage); 613 } 87 break; 88 } 89 90 case DragAndDropSvc::HOST_DND_HG_SND_DIR: 91 { 92 LogFlowFunc(("HOST_DND_HG_SND_DIR\n")); 93 break; 94 } 95 96 /* New since protocol version 2 (VBox 5.0). */ 97 case DragAndDropSvc::HOST_DND_HG_SND_FILE_HDR: 98 { 99 LogFlowFunc(("HOST_DND_HG_SND_FILE_HDR\n")); 100 break; 101 } 102 103 case DragAndDropSvc::HOST_DND_HG_SND_FILE_DATA: 104 { 105 LogFlowFunc(("HOST_DND_HG_SND_FILE\n")); 106 107 /* No parameter verification here as, depending on the protocol version 108 * being used, the parameter count + types might change. */ 614 109 break; 615 110 } … … 625 120 { 626 121 rc = VERR_INVALID_PARAMETER; 627 }628 else629 {630 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);631 m_dndMessageQueue.append(pMessage);632 122 } 633 123 break; … … 646 136 rc = VERR_INVALID_PARAMETER; 647 137 } 648 else649 {650 try651 {652 DnDGenericMessage *pMessage653 = new DnDGenericMessage(uMsg, cParms, paParms);654 m_dndMessageQueue.append(pMessage);655 }656 catch(std::bad_alloc &)657 {658 rc = VERR_NO_MEMORY;659 }660 }661 138 break; 662 139 } … … 667 144 break; 668 145 } 146 147 if (!pMessage) /* Generic message needed? */ 148 pMessage = new DnDGenericMessage(uMsg, cParms, paParms); 149 150 if (fAppend) 151 m_dndMessageQueue.append(pMessage); 152 else 153 m_dndMessageQueue.prepend(pMessage); 669 154 } 670 155 catch(std::bad_alloc &) … … 692 177 AssertPtrReturn(pcParms, VERR_INVALID_POINTER); 693 178 694 int rc = VINF_SUCCESS; 695 179 int rc; 696 180 if (m_pCurMsg) 697 181 rc = m_pCurMsg->currentMessageInfo(puMsg, pcParms); … … 699 183 { 700 184 if (m_dndMessageQueue.isEmpty()) 701 {702 185 rc = VERR_NO_DATA; 703 // if (m_pfnProgressCallback)704 // m_pfnProgressCallback(100.0, DragAndDropSvc::DND_OP_CANCELLED, m_pvProgressUser);705 }706 186 else 707 187 rc = m_dndMessageQueue.first()->currentMessageInfo(puMsg, pcParms); … … 743 223 * callback about our exit. 744 224 */ 745 if ( RT_FAILURE(rc) 746 && m_pfnProgressCallback) 225 if (RT_FAILURE(rc)) 747 226 { 748 227 /* Clear any pending messages. */ … … 754 233 try 755 234 { 235 if (rc == VERR_CANCELLED) 236 LogFlowFunc(("Operation was cancelled\n")); 237 756 238 Assert(!m_pCurMsg); 757 239 m_pCurMsg = new DnDHGCancelMessage(); 758 m_pfnProgressCallback(100 /* Percent */, 759 rc == VERR_CANCELLED 760 ? DragAndDropSvc::DND_PROGRESS_CANCELLED 761 : DragAndDropSvc::DND_PROGRESS_ERROR, rc, m_pvProgressUser); 240 241 if (m_pfnProgressCallback) 242 { 243 LogFlowFunc(("Notifying host about aborting operation (%Rrc) ...\n", rc)); 244 m_pfnProgressCallback( rc == VERR_CANCELLED 245 ? DragAndDropSvc::DND_PROGRESS_CANCELLED 246 : DragAndDropSvc::DND_PROGRESS_ERROR, 247 100 /* Percent */, rc, 248 m_pvProgressUser); 249 } 762 250 } 763 251 catch(std::bad_alloc &) … … 776 264 { 777 265 delete m_pCurMsg; 778 m_pCurMsg = 0;266 m_pCurMsg = NULL; 779 267 } 780 268 … … 786 274 } 787 275 276 /** 277 * Triggers a rescheduling of the manager's message queue by setting the first 278 * message available in the queue as the current one to process. 279 * 280 * @return IPRT status code. VERR_NO_DATA if not message to process is available at 281 * the time of calling. 282 */ 283 int DnDManager::doReschedule(void) 284 { 285 LogFlowFunc(("Rescheduling ...\n")); 286 287 if (!m_dndMessageQueue.isEmpty()) 288 { 289 m_pCurMsg = m_dndMessageQueue.first(); 290 m_dndMessageQueue.removeFirst(); 291 292 return VINF_SUCCESS; 293 } 294 295 return VERR_NO_DATA; 296 } 297
Note:
See TracChangeset
for help on using the changeset viewer.