Changeset 50561 in vbox for trunk/src/VBox/HostServices/DragAndDrop
- Timestamp:
- Feb 24, 2014 9:07:22 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 92425
- Location:
- trunk/src/VBox/HostServices/DragAndDrop
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note:
See TracChangeset
for help on using the changeset viewer.