Changeset 79497 in vbox for trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp
- Timestamp:
- Jul 3, 2019 1:28:33 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp
r79366 r79497 34 34 #include <iprt/win/shlwapi.h> 35 35 36 #include <iprt/err.h> 36 37 #include <iprt/path.h> 37 38 #include <iprt/semaphore.h> … … 121 122 m_enmStatus = Initialized; 122 123 123 int rc2 = RTSemEventCreate(&m_Event MetaDataComplete);124 int rc2 = RTSemEventCreate(&m_EventListComplete); 124 125 AssertRC(rc2); 126 rc2 = RTSemEventCreate(&m_EventTransferComplete); 127 AssertRC(rc2); 125 128 } 126 129 … … 130 133 VBoxClipboardWinDataObject::~VBoxClipboardWinDataObject(void) 131 134 { 132 RTSemEventDestroy(m_EventMetaDataComplete); 135 RTSemEventDestroy(m_EventListComplete); 136 RTSemEventDestroy(m_EventTransferComplete); 133 137 134 138 if (m_pStream) … … 216 220 } 217 221 222 /* static */ 223 224 /** 225 * Thread for reading URI data. 226 * The data object needs the (high level, root) URI listing at the time of ::GetData(), so we need 227 * to block and wait until we have this data (via this thread) and continue. 228 * 229 * @returns VBox status code. 230 * @param ThreadSelf Thread handle. Unused at the moment. 231 * @param pvUser Pointer to user-provided data. Of type VBoxClipboardWinDataObject. 232 */ 233 DECLCALLBACK(int) VBoxClipboardWinDataObject::readThread(RTTHREAD ThreadSelf, void *pvUser) 234 { 235 RT_NOREF(ThreadSelf); 236 237 LogFlowFuncEnter(); 238 239 VBoxClipboardWinDataObject *pThis = (VBoxClipboardWinDataObject *)pvUser; 240 241 PSHAREDCLIPBOARDURITRANSFER pTransfer = pThis->m_pTransfer; 242 AssertPtr(pTransfer); 243 244 pTransfer->Thread.fStarted = true; 245 246 RTThreadUserSignal(RTThreadSelf()); 247 248 int rc = SharedClipboardURITransferOpen(pTransfer); 249 if (RT_SUCCESS(rc)) 250 { 251 VBOXCLIPBOARDLISTHDR Hdr; 252 rc = SharedClipboardURIListHdrInit(&Hdr); 253 if (RT_SUCCESS(rc)) 254 { 255 VBOXCLIPBOARDLISTHANDLE hList; 256 rc = SharedClipboardURITransferListOpen(pTransfer, &Hdr, &hList); 257 if (RT_SUCCESS(rc)) 258 { 259 LogFlowFunc(("hList=%RU64, cTotalObjects=%RU64, cbTotalSize=%RU64\n\n", 260 hList, Hdr.cTotalObjects, Hdr.cbTotalSize)); 261 262 for (uint64_t i = 0; i < Hdr.cTotalObjects; i++) 263 { 264 VBOXCLIPBOARDLISTENTRY Entry; 265 rc = SharedClipboardURITransferListRead(pTransfer, hList, &Entry); 266 if (RT_SUCCESS(rc)) 267 { 268 269 } 270 else 271 break; 272 273 if (pTransfer->Thread.fStop) 274 break; 275 } 276 277 if (RT_SUCCESS(rc)) 278 { 279 /* 280 * Signal the "list complete" event so that this data object can return (valid) data via ::GetData(). 281 * This in turn then will create IStream instances (by the OS) for each file system object to handle. 282 */ 283 int rc2 = RTSemEventSignal(pThis->m_EventListComplete); 284 AssertRC(rc2); 285 286 LogFlowFunc(("Waiting for transfer to complete ...\n")); 287 288 /* Transferring stuff can take a while, so don't use any timeout here. */ 289 rc2 = RTSemEventWait(pThis->m_EventTransferComplete, RT_INDEFINITE_WAIT); 290 AssertRC(rc2); 291 } 292 293 SharedClipboardURITransferListClose(pTransfer, hList); 294 } 295 296 SharedClipboardURIListHdrDestroy(&Hdr); 297 } 298 299 SharedClipboardURITransferClose(pTransfer); 300 } 301 302 LogFlowFuncLeaveRC(rc); 303 return rc; 304 } 305 218 306 /** 219 307 * Creates a FILEGROUPDESCRIPTOR object from a given URI transfer and stores the result into an HGLOBAL object. … … 232 320 LogFlowFuncEnter(); 233 321 234 SharedClipboardURIList *pURIList = SharedClipboardURITransferGetList(pTransfer);235 if (!pURIList)236 return VERR_WRONG_ORDER;237 238 322 const size_t cbFileGroupDescriptor = fUnicode ? sizeof(FILEGROUPDESCRIPTORW) : sizeof(FILEGROUPDESCRIPTORA); 239 323 const size_t cbFileDescriptor = fUnicode ? sizeof(FILEDESCRIPTORW) : sizeof(FILEDESCRIPTORA); 240 324 241 const UINT cItems = (UINT)pURIList->GetRootCount(); /** @todo UINT vs. uint64_t */ 325 const UINT cItems = (UINT)0; /** @todo UINT vs. uint64_t */ 326 if (!cItems) 327 return VERR_NOT_FOUND; 328 242 329 const size_t cbFGD = cbFileGroupDescriptor + (cbFileDescriptor * (cItems - 1)); 243 330 … … 254 341 255 342 char *pszFileSpec = NULL; 256 343 #if 0 257 344 for (UINT i = 0; i < cItems; i++) 258 345 { … … 326 413 #endif 327 414 } 415 #endif 328 416 329 417 if (pszFileSpec) … … 393 481 #endif 394 482 { 395 int rc = SharedClipboardURITransferPrepare(m_pTransfer); 396 if (RT_SUCCESS(rc)) 483 const bool fUnicode = lIndex == FormatIndex_FileDescriptorW; 484 485 LogFlowFunc(("FormatIndex_FileDescriptor%s\n", fUnicode ? "W" : "A")); 486 487 int rc; 488 489 /* The caller can call GetData() several times, so make sure we don't do the same transfer multiple times. */ 490 if (SharedClipboardURITransferGetStatus(m_pTransfer) == SHAREDCLIPBOARDURITRANSFERSTATUS_NONE) 397 491 { 398 const bool fUnicode = lIndex == FormatIndex_FileDescriptorW; 399 400 LogFlowFunc(("FormatIndex_FileDescriptor%s\n", fUnicode ? "W" : "A")); 401 402 /* Start the transfer asynchronously in a separate thread. */ 403 rc = SharedClipboardURITransferRun(m_pTransfer, true /* fAsync */); 492 rc = SharedClipboardURITransferPrepare(m_pTransfer); 404 493 if (RT_SUCCESS(rc)) 405 494 { 406 /* Wait for the meta data to arrive. */ 407 LogFlowFunc(("Waiting for meta data to arrive ...\n")); 408 rc = RTSemEventWait(m_EventMetaDataComplete, 30 * 1000 /* 30s timeout */); 495 /* Start the transfer asynchronously in a separate thread. */ 496 rc = SharedClipboardURITransferRun(m_pTransfer, &VBoxClipboardWinDataObject::readThread, this); 409 497 if (RT_SUCCESS(rc)) 410 498 { 411 HGLOBAL hGlobal;412 rc = createFileGroupDescriptorFromTransfer(m_pTransfer, fUnicode, &hGlobal);499 LogFunc(("Waiting for listing to arrive ...\n")); 500 rc = RTSemEventWait(m_EventListComplete, 5 * 60 * 1000 /* 5 min timeout */); 413 501 if (RT_SUCCESS(rc)) 414 502 { 415 pMedium->tymed = TYMED_HGLOBAL; 416 pMedium->hGlobal = hGlobal; 417 /* Note: hGlobal now is being owned by pMedium / the caller. */ 418 419 hr = S_OK; 503 LogFunc(("Listing complete\n")); 504 505 HGLOBAL hGlobal; 506 rc = createFileGroupDescriptorFromTransfer(m_pTransfer, fUnicode, &hGlobal); 507 if (RT_SUCCESS(rc)) 508 { 509 pMedium->tymed = TYMED_HGLOBAL; 510 pMedium->hGlobal = hGlobal; 511 /* Note: hGlobal now is being owned by pMedium / the caller. */ 512 513 hr = S_OK; 514 } 420 515 } 421 516 } 422 517 } 423 424 if (RT_FAILURE(rc))425 LogRel(("Shared Clipboard: Data object unable to receive meta data, rc=%Rrc\n", rc));426 518 } 519 else 520 rc = VERR_ALREADY_EXISTS; 521 522 if (RT_FAILURE(rc)) 523 LogRel(("Shared Clipboard: Data object unable to get data, rc=%Rrc\n", rc)); 524 427 525 break; 428 526 } … … 588 686 LogFlowFuncLeaveRC(VINF_SUCCESS); 589 687 return VINF_SUCCESS; 590 }591 592 DECLCALLBACK(void) VBoxClipboardWinDataObject::OnMetaDataComplete(PSHAREDCLIPBOARDURITRANSFER pTransfer)593 {594 LogFlowFuncEnter();595 596 AssertReturnVoid(pTransfer == m_pTransfer);597 598 int rc2 = RTSemEventSignal(m_EventMetaDataComplete);599 AssertRC(rc2);600 688 } 601 689
Note:
See TracChangeset
for help on using the changeset viewer.