Changeset 80845 in vbox for trunk/src/VBox/GuestHost/SharedClipboard
- Timestamp:
- Sep 17, 2019 9:05:21 AM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 133415
- Location:
- trunk/src/VBox/GuestHost/SharedClipboard
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp
r80664 r80845 406 406 */ 407 407 int SharedClipboardWinDataObject::createFileGroupDescriptorFromTransfer(PSHCLURITRANSFER pTransfer, 408 bool fUnicode, HGLOBAL *phGlobal)408 bool fUnicode, HGLOBAL *phGlobal) 409 409 { 410 410 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER); -
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp
r80662 r80845 180 180 RTListForEachSafe(&pSource->lstEvents, pEvIt, pEvItNext, SHCLEVENT, Node) 181 181 { 182 RTListNodeRemove(&pEvIt->Node); 183 182 184 SharedClipboardEventDestroy(pEvIt); 185 183 186 RTMemFree(pEvIt); 187 pEvIt = NULL; 184 188 } 185 189 … … 199 203 200 204 LogFlowFunc(("uSource=%RU16: New event: %RU16\n", pSource->uID, pSource->uEventIDNext)); 201 return pSource->uEventIDNext++; /** @todo Handle rollovers? */ 205 206 pSource->uEventIDNext++; 207 if (pSource->uEventIDNext == VBOX_SHARED_CLIPBOARD_MAX_EVENTS) 208 pSource->uEventIDNext = 0; 209 210 return pSource->uEventIDNext; 202 211 } 203 212 … … 235 244 236 245 return 0; 246 } 247 248 /** 249 * Detaches a payload from an event, internal version. 250 * 251 * @param pEvent Event to detach payload for. 252 */ 253 static void sharedClipboardEventPayloadDetachInternal(PSHCLEVENT pEvent) 254 { 255 AssertPtrReturnVoid(pEvent); 256 257 pEvent->pPayload = NULL; 237 258 } 238 259 … … 324 345 * @param uTimeoutMs Timeout (in ms) to wait. 325 346 * @param ppPayload Where to store the (allocated) event payload on success. Needs to be free'd with 326 * SharedClipboardPayloadFree(). 347 * SharedClipboardPayloadFree(). Optional. 327 348 */ 328 349 int SharedClipboardEventWait(PSHCLEVENTSOURCE pSource, SHCLEVENTID uID, RTMSINTERVAL uTimeoutMs, … … 330 351 { 331 352 AssertPtrReturn(pSource, VERR_INVALID_POINTER); 353 /** ppPayload is optional. */ 332 354 333 355 LogFlowFuncEnter(); … … 341 363 if (RT_SUCCESS(rc)) 342 364 { 343 *ppPayload = pEvent->pPayload; 344 345 pEvent->pPayload = NULL; 365 if (ppPayload) 366 { 367 *ppPayload = pEvent->pPayload; 368 369 /* Make sure to detach payload here, as the caller now owns the data. */ 370 sharedClipboardEventPayloadDetachInternal(pEvent); 371 } 346 372 } 347 373 } … … 402 428 if (pEvent) 403 429 { 404 pEvent->pPayload = NULL;430 sharedClipboardEventPayloadDetachInternal(pEvent); 405 431 } 406 432 #ifdef DEBUG_andy … … 803 829 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA); 804 830 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS_REPORT); 805 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_TRANSFER_STA RT);831 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_TRANSFER_STATUS); 806 832 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOT_LIST_HDR_READ); 807 833 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOT_LIST_HDR_WRITE); -
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-uri.cpp
r80662 r80845 23 23 #include <iprt/list.h> 24 24 #include <iprt/path.h> 25 #include <iprt/rand.h> 25 26 #include <iprt/semaphore.h> 26 27 … … 1040 1041 1041 1042 /** 1042 * Initializes an URI clipboard transfer struct. 1043 * 1044 * @returns VBox status code. 1045 * @param enmDir Specifies the transfer direction of this transfer. 1046 * @param enmSource Specifies the data source of the transfer. 1043 * Creates an URI clipboard transfer. 1044 * 1045 * @returns VBox status code. 1047 1046 * @param ppTransfer Where to return the created URI transfer struct. 1048 1047 * Must be destroyed by SharedClipboardURITransferDestroy(). 1049 1048 */ 1050 int SharedClipboardURITransferCreate(SHCLURITRANSFERDIR enmDir, SHCLSOURCE enmSource, 1051 PSHCLURITRANSFER *ppTransfer) 1049 int SharedClipboardURITransferCreate(PSHCLURITRANSFER *ppTransfer) 1052 1050 { 1053 1051 AssertPtrReturn(ppTransfer, VERR_INVALID_POINTER); … … 1063 1061 pTransfer->State.uID = 0; 1064 1062 pTransfer->State.enmStatus = SHCLURITRANSFERSTATUS_NONE; 1065 pTransfer->State.enmDir = enmDir;1066 pTransfer->State.enmSource = enmSource;1063 pTransfer->State.enmDir = SHCLURITRANSFERDIR_UNKNOWN; 1064 pTransfer->State.enmSource = SHCLSOURCE_INVALID; 1067 1065 1068 1066 LogFlowFunc(("enmDir=%RU32, enmSource=%RU32\n", pTransfer->State.enmDir, pTransfer->State.enmSource)); … … 1094 1092 RTListInit(&pTransfer->lstRoots); 1095 1093 1096 *ppTransfer = pTransfer; 1097 1098 if (RT_FAILURE(rc)) 1094 RT_ZERO(pTransfer->Events); 1095 1096 if (RT_SUCCESS(rc)) 1097 { 1098 *ppTransfer = pTransfer; 1099 } 1100 else 1099 1101 { 1100 1102 if (pTransfer) … … 1154 1156 } 1155 1157 1158 /** 1159 * Initializes an URI transfer object. 1160 * 1161 * @returns VBox status code. 1162 * @param pTransfer Transfer to initialize. 1163 * @param uID ID to use for the transfer. Can be set to 0 if not important. 1164 * @param enmDir Specifies the transfer direction of this transfer. 1165 * @param enmSource Specifies the data source of the transfer. 1166 */ 1167 int SharedClipboardURITransferInit(PSHCLURITRANSFER pTransfer, 1168 uint32_t uID, SHCLURITRANSFERDIR enmDir, SHCLSOURCE enmSource) 1169 { 1170 pTransfer->State.uID = uID; 1171 pTransfer->State.enmDir = enmDir; 1172 pTransfer->State.enmSource = enmSource; 1173 1174 int rc = SharedClipboardEventSourceCreate(&pTransfer->Events, pTransfer->State.uID); 1175 1176 LogFlowFuncLeaveRC(rc); 1177 return rc; 1178 } 1179 1156 1180 int SharedClipboardURITransferOpen(PSHCLURITRANSFER pTransfer) 1157 1181 { … … 1183 1207 * @param hList List handle of the list to get handle info for. 1184 1208 */ 1185 inline PSHCLURILISTHANDLEINFO sharedClipboardURITransferListGet(PSHCLURITRANSFER pTransfer, 1186 SHCLLISTHANDLE hList) 1209 inline PSHCLURILISTHANDLEINFO sharedClipboardURITransferListGet(PSHCLURITRANSFER pTransfer, SHCLLISTHANDLE hList) 1187 1210 { 1188 1211 PSHCLURILISTHANDLEINFO pIt; … … 1330 1353 { 1331 1354 if (RTDirIsValid(pInfo->u.Local.hDir)) 1355 { 1332 1356 RTDirClose(pInfo->u.Local.hDir); 1357 pInfo->u.Local.hDir = NIL_RTDIR; 1358 } 1333 1359 break; 1334 1360 } … … 1370 1396 { 1371 1397 uint64_t cbSize = 0; 1372 int rc = RTFileQuerySize (pszPath, &cbSize);1398 int rc = RTFileQuerySizeByPath(pszPath, &cbSize); 1373 1399 if (RT_SUCCESS(rc)) 1374 1400 { … … 2195 2221 2196 2222 /** 2223 * Returns the transfer's ID. 2224 * 2225 * @returns The transfer's ID. 2226 * @param pTransfer URI clipboard transfer to return ID for. 2227 */ 2228 SHCLURITRANSFERID SharedClipboardURITransferGetID(PSHCLURITRANSFER pTransfer) 2229 { 2230 AssertPtrReturn(pTransfer, 0); 2231 2232 return pTransfer->State.uID; 2233 } 2234 2235 /** 2197 2236 * Returns the transfer's source. 2198 2237 * … … 2297 2336 if (pTransfer->Thread.fStarted) /* Did the thread indicate that it started correctly? */ 2298 2337 { 2299 pTransfer->State.enmStatus = SHCLURITRANSFERSTATUS_ RUNNING;2338 pTransfer->State.enmStatus = SHCLURITRANSFERSTATUS_STARTED; 2300 2339 } 2301 2340 else … … 2352 2391 2353 2392 pURI->cRunning = 0; 2354 pURI->cMaxRunning = 1; /* For now we only support one transfer per client at a time. */ 2355 2356 #ifdef DEBUG_andy 2357 pURI->cMaxRunning = UINT32_MAX; 2358 #endif 2393 pURI->cMaxRunning = UINT16_MAX; 2394 2395 RT_ZERO(pURI->bmTransferIds); 2396 2359 2397 SharedClipboardURICtxReset(pURI); 2360 2398 } … … 2408 2446 2409 2447 /** 2410 * Adds a new URI transfer to an clipboard URI transfer. 2411 * 2412 * @returns VBox status code. 2413 * @param pURI URI clipboard context to add transfer to. 2414 * @param pTransfer Pointer to URI clipboard transfer to add. 2415 */ 2416 int SharedClipboardURICtxTransferAdd(PSHCLURICTX pURI, PSHCLURITRANSFER pTransfer) 2448 * Returns a specific URI transfer, internal version. 2449 * 2450 * @returns URI transfer, or NULL if not found. 2451 * @param pURI URI clipboard context to return transfer for. 2452 * @param uID ID of the transfer to return. 2453 */ 2454 static PSHCLURITRANSFER sharedClipboardURICtxGetTransferInternal(PSHCLURICTX pURI, uint32_t uID) 2455 { 2456 PSHCLURITRANSFER pTransfer; 2457 RTListForEach(&pURI->List, pTransfer, SHCLURITRANSFER, Node) /** @todo Slow, but works for now. */ 2458 { 2459 if (pTransfer->State.uID == uID) 2460 return pTransfer; 2461 } 2462 2463 return NULL; 2464 } 2465 2466 /** 2467 * Returns a specific URI transfer. 2468 * 2469 * @returns URI transfer, or NULL if not found. 2470 * @param pURI URI clipboard context to return transfer for. 2471 * @param uID ID of the transfer to return. 2472 */ 2473 PSHCLURITRANSFER SharedClipboardURICtxGetTransfer(PSHCLURICTX pURI, uint32_t uID) 2474 { 2475 return sharedClipboardURICtxGetTransferInternal(pURI, uID); 2476 } 2477 2478 /** 2479 * Returns the number of running URI transfers. 2480 * 2481 * @returns Number of running transfers. 2482 * @param pURI URI clipboard context to return number for. 2483 */ 2484 uint32_t SharedClipboardURICtxGetRunningTransfers(PSHCLURICTX pURI) 2485 { 2486 AssertPtrReturn(pURI, 0); 2487 return pURI->cRunning; 2488 } 2489 2490 /** 2491 * Returns the number of total URI transfers. 2492 * 2493 * @returns Number of total transfers. 2494 * @param pURI URI clipboard context to return number for. 2495 */ 2496 uint32_t SharedClipboardURICtxGetTotalTransfers(PSHCLURICTX pURI) 2497 { 2498 AssertPtrReturn(pURI, 0); 2499 return pURI->cTransfers; 2500 } 2501 2502 /** 2503 * Registers an URI transfer with an URI context, i.e. allocates a transfer ID. 2504 * 2505 * @return VBox status code. 2506 * @retval VERR_SHCLPB_MAX_TRANSFERS_REACHED if the maximum of concurrent transfers 2507 * is reached. 2508 * @param pURI URI clipboard context to register transfer to. 2509 * @param pTransfer Transfer to register. 2510 * @param pidTransfer Where to return the transfer ID on success. Optional. 2511 */ 2512 int SharedClipboardURICtxTransferRegister(PSHCLURICTX pURI, PSHCLURITRANSFER pTransfer, uint32_t *pidTransfer) 2417 2513 { 2418 2514 AssertPtrReturn(pURI, VERR_INVALID_POINTER); 2419 2515 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER); 2420 2421 LogFlowFuncEnter(); 2422 2423 if (pURI->cRunning == pURI->cMaxRunning) 2516 /* pidTransfer is optional. */ 2517 2518 /* 2519 * Pick a random bit as starting point. If it's in use, search forward 2520 * for a free one, wrapping around. We've reserved both the zero'th and 2521 * max-1 IDs. 2522 */ 2523 uint32_t idTransfer = RTRandU32Ex(1, VBOX_SHARED_CLIPBOARD_MAX_TRANSFERS - 2); 2524 2525 if (!ASMBitTestAndSet(&pURI->bmTransferIds[0], idTransfer)) 2526 { /* likely */ } 2527 else if (pURI->cTransfers < VBOX_SHARED_CLIPBOARD_MAX_TRANSFERS - 2 /* First and last are not used */) 2528 { 2529 /* Forward search. */ 2530 int iHit = ASMBitNextClear(&pURI->bmTransferIds[0], VBOX_SHARED_CLIPBOARD_MAX_TRANSFERS, idTransfer); 2531 if (iHit < 0) 2532 iHit = ASMBitFirstClear(&pURI->bmTransferIds[0], VBOX_SHARED_CLIPBOARD_MAX_TRANSFERS); 2533 AssertLogRelMsgReturn(iHit >= 0, ("Transfer count: %RU16\n", pURI->cTransfers), VERR_SHCLPB_MAX_TRANSFERS_REACHED); 2534 idTransfer = iHit; 2535 AssertLogRelMsgReturn(!ASMBitTestAndSet(&pURI->bmTransferIds[0], idTransfer), ("idObject=%#x\n", idTransfer), VERR_INTERNAL_ERROR_2); 2536 } 2537 else 2538 { 2539 LogFunc(("Maximum number of transfers reached (%RU16 transfers)\n", pURI->cTransfers)); 2424 2540 return VERR_SHCLPB_MAX_TRANSFERS_REACHED; 2541 } 2542 2543 Log2Func(("pTransfer=%p, idTransfer=%RU32 (%RU16 transfers)\n", pTransfer, idTransfer, pURI->cTransfers)); 2425 2544 2426 2545 RTListAppend(&pURI->List, &pTransfer->Node); 2427 2546 2428 2547 pURI->cTransfers++; 2429 LogFlowFunc(("cTransfers=%RU32, cRunning=%RU32\n", pURI->cTransfers, pURI->cRunning)); 2548 2549 if (pidTransfer) 2550 *pidTransfer = idTransfer; 2430 2551 2431 2552 return VINF_SUCCESS; … … 2433 2554 2434 2555 /** 2435 * Removes an URI transfer from a clipboard URI transfer. 2436 * 2437 * @returns VBox status code. 2438 * @param pURI URI clipboard context to remove transfer from. 2439 * @param pTransfer Pointer to URI clipboard transfer to remove. 2440 */ 2441 int SharedClipboardURICtxTransferRemove(PSHCLURICTX pURI, PSHCLURITRANSFER pTransfer) 2442 { 2443 AssertPtrReturn(pURI, VERR_INVALID_POINTER); 2444 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER); 2445 2446 LogFlowFuncEnter(); 2447 2448 2449 int rc = SharedClipboardURITransferDestroy(pTransfer); 2450 if (RT_SUCCESS(rc)) 2556 * Registers an URI transfer with an URI context by specifying an ID for the transfer. 2557 * 2558 * @return VBox status code. 2559 * @retval VERR_ALREADY_EXISTS if a transfer with the given ID already exists. 2560 * @retval VERR_SHCLPB_MAX_TRANSFERS_REACHED if the maximum of concurrent transfers for this context has been reached. 2561 * @param pURI URI clipboard context to register transfer to. 2562 * @param pTransfer Transfer to register. 2563 * @param idTransfer Transfer ID to use for registration. 2564 */ 2565 int SharedClipboardURICtxTransferRegisterByIndex(PSHCLURICTX pURI, PSHCLURITRANSFER pTransfer, uint32_t idTransfer) 2566 { 2567 LogFlowFunc(("cTransfers=%RU16, idTransfer=%RU32\n", pURI->cTransfers, idTransfer)); 2568 2569 if (pURI->cTransfers < VBOX_SHARED_CLIPBOARD_MAX_TRANSFERS - 2 /* First and last are not used */) 2570 { 2571 if (!ASMBitTestAndSet(&pURI->bmTransferIds[0], idTransfer)) 2572 { 2573 RTListAppend(&pURI->List, &pTransfer->Node); 2574 2575 pURI->cTransfers++; 2576 return VINF_SUCCESS; 2577 } 2578 2579 return VERR_ALREADY_EXISTS; 2580 } 2581 2582 LogFunc(("Maximum number of transfers reached (%RU16 transfers)\n", pURI->cTransfers)); 2583 return VERR_SHCLPB_MAX_TRANSFERS_REACHED; 2584 } 2585 2586 /** 2587 * Unregisters a transfer from an URI clipboard context. 2588 * 2589 * @retval VINF_SUCCESS on success. 2590 * @retval VERR_NOT_FOUND if the transfer ID was not found. 2591 * @param pURI URI clipboard context to unregister transfer from. 2592 * @param idTransfer Transfer ID to unregister. 2593 */ 2594 int SharedClipboardURICtxTransferUnregister(PSHCLURICTX pURI, uint32_t idTransfer) 2595 { 2596 int rc = VINF_SUCCESS; 2597 AssertMsgStmt(ASMBitTestAndClear(&pURI->bmTransferIds, idTransfer), ("idTransfer=%#x\n", idTransfer), rc = VERR_NOT_FOUND); 2598 2599 PSHCLURITRANSFER pTransfer = sharedClipboardURICtxGetTransferInternal(pURI, idTransfer); 2600 if (pTransfer) 2451 2601 { 2452 2602 RTListNodeRemove(&pTransfer->Node); 2453 2603 2454 RTMemFree(pTransfer); 2455 pTransfer = NULL; 2456 } 2457 2458 LogFlowFuncLeaveRC(rc); 2459 return rc; 2460 } 2461 2462 /** 2463 * Returns a specific URI transfer, internal version. 2464 * 2465 * @returns URI transfer, or NULL if not found. 2466 * @param pURI URI clipboard context to return transfer for. 2467 * @param uIdx Index of the transfer to return. 2468 */ 2469 static PSHCLURITRANSFER sharedClipboardURICtxGetTransferInternal(PSHCLURICTX pURI, uint32_t uIdx) 2470 { 2471 AssertReturn(uIdx == 0, NULL); /* Only one transfer allowed at the moment. */ 2472 return RTListGetFirst(&pURI->List, SHCLURITRANSFER, Node); 2473 } 2474 2475 /** 2476 * Returns a specific URI transfer. 2477 * 2478 * @returns URI transfer, or NULL if not found. 2479 * @param pURI URI clipboard context to return transfer for. 2480 * @param uIdx Index of the transfer to return. 2481 */ 2482 PSHCLURITRANSFER SharedClipboardURICtxGetTransfer(PSHCLURICTX pURI, uint32_t uIdx) 2483 { 2484 return sharedClipboardURICtxGetTransferInternal(pURI, uIdx); 2485 } 2486 2487 /** 2488 * Returns the number of running URI transfers. 2489 * 2490 * @returns Number of running transfers. 2491 * @param pURI URI clipboard context to return number for. 2492 */ 2493 uint32_t SharedClipboardURICtxGetRunningTransfers(PSHCLURICTX pURI) 2494 { 2495 AssertPtrReturn(pURI, 0); 2496 return pURI->cRunning; 2497 } 2498 2499 /** 2500 * Returns the number of total URI transfers. 2501 * 2502 * @returns Number of total transfers. 2503 * @param pURI URI clipboard context to return number for. 2504 */ 2505 uint32_t SharedClipboardURICtxGetTotalTransfers(PSHCLURICTX pURI) 2506 { 2507 AssertPtrReturn(pURI, 0); 2508 return pURI->cTransfers; 2604 Assert(pURI->cTransfers); 2605 pURI->cTransfers--; 2606 } 2607 else 2608 rc = VERR_NOT_FOUND; 2609 2610 LogFlowFunc(("idTransfer=%RU32, rc=%Rrc\n", idTransfer, rc)); 2611 return rc; 2509 2612 } 2510 2613 … … 2525 2628 RTListForEachSafe(&pURI->List, pTransfer, pTransferNext, SHCLURITRANSFER, Node) 2526 2629 { 2527 if (SharedClipboardURITransferGetStatus(pTransfer) != SHCLURITRANSFERSTATUS_ RUNNING)2630 if (SharedClipboardURITransferGetStatus(pTransfer) != SHCLURITRANSFERSTATUS_STARTED) 2528 2631 { 2529 2632 SharedClipboardURITransferDestroy(pTransfer); … … 2841 2944 } 2842 2945 2946 /** 2947 * Translates a Shared Clipboard transfer status (SHCLURITRANSFERSTATUS_XXX) into a string. 2948 * 2949 * @returns Transfer status string name. 2950 * @param uStatus The transfer status to translate. 2951 */ 2952 const char *VBoxClipboardTransferStatusToStr(uint32_t uStatus) 2953 { 2954 switch (uStatus) 2955 { 2956 RT_CASE_RET_STR(SHCLURITRANSFERSTATUS_NONE); 2957 RT_CASE_RET_STR(SHCLURITRANSFERSTATUS_READY); 2958 RT_CASE_RET_STR(SHCLURITRANSFERSTATUS_STARTED); 2959 RT_CASE_RET_STR(SHCLURITRANSFERSTATUS_STOPPED); 2960 RT_CASE_RET_STR(SHCLURITRANSFERSTATUS_CANCELED); 2961 RT_CASE_RET_STR(SHCLURITRANSFERSTATUS_KILLED); 2962 RT_CASE_RET_STR(SHCLURITRANSFERSTATUS_ERROR); 2963 } 2964 return "Unknown"; 2965 } -
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp
r80664 r80845 106 106 const DWORD dwLastErr = GetLastError(); 107 107 if (dwLastErr == ERROR_CLIPBOARD_NOT_OPEN) 108 rc = VERR_INVALID_STATE; 108 { 109 rc = VINF_SUCCESS; /* Not important, so just report success instead. */ 110 } 109 111 else 112 { 110 113 rc = RTErrConvertFromWin32(dwLastErr); 111 112 LogFunc(("Failed with %Rrc (0x%x)\n", rc, dwLastErr));114 LogFunc(("Failed with %Rrc (0x%x)\n", rc, dwLastErr)); 115 } 113 116 } 114 117 else … … 147 150 148 151 /** 152 * Initializes a Shared Clipboard Windows context. 153 * 154 * @returns VBox status code. 155 * @param pWinCtx Shared Clipboard Windows context to initialize. 156 */ 157 int SharedClipboardWinCtxInit(PSHCLWINCTX pWinCtx) 158 { 159 int rc = RTCritSectInit(&pWinCtx->CritSect); 160 if (RT_SUCCESS(rc)) 161 { 162 /* Check that new Clipboard API is available. */ 163 rc = SharedClipboardWinCheckAndInitNewAPI(&pWinCtx->newAPI); 164 if (RT_SUCCESS(rc)) 165 { 166 pWinCtx->hWnd = NULL; 167 pWinCtx->hWndClipboardOwnerUs = NULL; 168 pWinCtx->hWndNextInChain = NULL; 169 } 170 } 171 172 LogFlowFuncLeaveRC(rc); 173 return rc; 174 } 175 176 /** 177 * Destroys a Shared Clipboard Windows context. 178 * 179 * @param pWinCtx Shared Clipboard Windows context to destroy. 180 */ 181 void SharedClipboardWinCtxDestroy(PSHCLWINCTX pWinCtx) 182 { 183 if (!pWinCtx) 184 return; 185 186 if (RTCritSectIsInitialized(&pWinCtx->CritSect)) 187 { 188 int rc2 = RTCritSectDelete(&pWinCtx->CritSect); 189 AssertRC(rc2); 190 } 191 } 192 193 /** 149 194 * Checks and initializes function pointer which are required for using 150 195 * the new clipboard API. … … 299 344 */ 300 345 LRESULT SharedClipboardWinChainPassToNext(PSHCLWINCTX pWinCtx, 301 UINT msg, WPARAM wParam, LPARAM lParam)346 UINT msg, WPARAM wParam, LPARAM lParam) 302 347 { 303 348 LogFlowFuncEnter(); … … 874 919 * where another application could own the clipboard (open), and thus the call to 875 920 * OleSetClipboard() will fail. Needs (better) fixing. */ 921 HRESULT hr = S_OK; 922 876 923 for (unsigned uTries = 0; uTries < 3; uTries++) 877 924 { 878 HRESULT hr = OleSetClipboard(pWinURITransferCtx->pDataObj); 879 if (SUCCEEDED(hr)) 925 /* Make sure to enter the critical section before setting the clipboard data, as otherwise WM_CLIPBOARDUPDATE 926 * might get called *before* we had the opportunity to set pWinCtx->hWndClipboardOwnerUs below. */ 927 rc = RTCritSectEnter(&pWinCtx->CritSect); 928 if (RT_SUCCESS(rc)) 880 929 { 881 /* 882 * Calling OleSetClipboard() changed the clipboard owner, which in turn will let us receive 883 * a WM_CLIPBOARDUPDATE message. To not confuse ourselves with our own clipboard owner changes, 884 * save a new window handle and deal with it in WM_CLIPBOARDUPDATE. 885 */ 886 pWinCtx->hWndClipboardOwnerUs = GetClipboardOwner(); 887 break; 930 hr = OleSetClipboard(pWinURITransferCtx->pDataObj); 931 if (SUCCEEDED(hr)) 932 { 933 Assert(OleIsCurrentClipboard(pWinURITransferCtx->pDataObj) == S_OK); /* Sanity. */ 934 935 /* 936 * Calling OleSetClipboard() changed the clipboard owner, which in turn will let us receive 937 * a WM_CLIPBOARDUPDATE message. To not confuse ourselves with our own clipboard owner changes, 938 * save a new window handle and deal with it in WM_CLIPBOARDUPDATE. 939 */ 940 pWinCtx->hWndClipboardOwnerUs = GetClipboardOwner(); 941 942 rc = RTCritSectLeave(&pWinCtx->CritSect); 943 AssertRC(rc); 944 break; 945 } 888 946 } 889 else 890 { 891 rc = VERR_ACCESS_DENIED; /** @todo Fudge; fix this. */ 892 LogRel(("Shared Clipboard: Failed with %Rhrc when setting data object to clipboard\n", hr)); 893 RTThreadSleep(100); /* Wait a bit. */ 894 } 947 948 rc = RTCritSectLeave(&pWinCtx->CritSect); 949 AssertRCBreak(rc); 950 951 LogFlowFunc(("Failed with %Rhrc (try %u/3)\n", hr, uTries + 1)); 952 RTThreadSleep(500); /* Wait a bit. */ 953 } 954 955 if (FAILED(hr)) 956 { 957 rc = VERR_ACCESS_DENIED; /** @todo Fudge; fix this. */ 958 LogRel(("Shared Clipboard: Failed with %Rhrc when setting data object to clipboard\n", hr)); 895 959 } 896 960 }
Note:
See TracChangeset
for help on using the changeset viewer.