Changeset 81025 in vbox for trunk/src/VBox/Additions/WINNT/VBoxTray
- Timestamp:
- Sep 26, 2019 4:13:25 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp
r80993 r81025 60 60 /** Windows-specific context data. */ 61 61 SHCLWINCTX Win; 62 /** Thread handle for window thread. */ 63 RTTHREAD hThread; 64 /** Start indicator flag. */ 65 bool fStarted; 66 /** Shutdown indicator flag. */ 67 bool fShutdown; 62 68 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 63 69 /** Associated transfer data. */ … … 65 71 #endif 66 72 } SHCLCONTEXT, *PSHCLCONTEXT; 67 68 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS69 typedef struct _SHCLREADTHREADCTX70 {71 PSHCLCONTEXT pClipboardCtx;72 PSHCLTRANSFER pTransfer;73 } SHCLREADTHREADCTX, *PSHCLREADTHREADCTX;74 75 typedef struct _SHCLWRITETHREADCTX76 {77 PSHCLCONTEXT pClipboardCtx;78 PSHCLTRANSFER pTransfer;79 } SHCLWRITETHREADCTX, *PSHCLWRITETHREADCTX;80 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */81 73 82 74 … … 109 101 static void vboxClipboardTransferCallbackCleanup(PSHCLTRANSFERCALLBACKDATA pData) 110 102 { 103 LogFlowFuncEnter(); 104 111 105 PSHCLTRANSFERCTX pCtx = (PSHCLTRANSFERCTX)pData->pvUser; 112 106 AssertPtr(pCtx); … … 146 140 PSHCLCONTEXT pCtx = (PSHCLCONTEXT)pData->pvUser; 147 141 AssertPtr(pCtx); 148 149 LogFlowFunc(("pCtx=%p\n", pCtx)); 142 Assert(pData->cbUser == sizeof(SHCLCONTEXT)); 150 143 151 144 PSHCLTRANSFER pTransfer = pData->pTransfer; 152 145 AssertPtr(pTransfer); 153 146 147 const SHCLTRANSFERDIR enmDir = SharedClipboardTransferGetDir(pTransfer); 148 149 LogFlowFunc(("pCtx=%p, idTransfer=%RU16, enmDir=%RU32\n", pCtx, SharedClipboardTransferGetID(pTransfer), enmDir)); 150 154 151 int rc; 155 152 156 153 /* The guest wants to write local data to the host? */ 157 if ( SharedClipboardTransferGetDir(pTransfer)== SHCLTRANSFERDIR_WRITE)154 if (enmDir == SHCLTRANSFERDIR_WRITE) 158 155 { 159 156 Assert(SharedClipboardTransferGetSource(pTransfer) == SHCLSOURCE_LOCAL); /* Sanity. */ … … 194 191 } 195 192 /* The guest wants to read data from a remote source. */ 196 else if (SharedClipboardTransferGetDir(pTransfer) == SHCLTRANSFERDIR_READ) 197 { 198 /* The IDataObject must be created in our window thread, so post a message to it, which 199 * then in turn takes care of the creation. */ 200 ::PostMessage(pCtx->Win.hWnd, SHCL_WIN_WM_URI_TRANSFER_START, 201 0 /* wParm */, (LPARAM)pTransfer /* lParm */); 202 203 rc = VINF_SUCCESS; 193 else if (enmDir == SHCLTRANSFERDIR_READ) 194 { 195 Assert(SharedClipboardTransferGetSource(pTransfer) == SHCLSOURCE_REMOTE); /* Sanity. */ 196 197 rc = SharedClipboardWinTransferCreate(&pCtx->Win, pTransfer); 204 198 } 205 199 else 206 200 AssertFailedStmt(rc = VERR_NOT_SUPPORTED); 207 201 208 LogFlowFunc LeaveRC(rc);202 LogFlowFunc(("LEAVE: idTransfer=%RU16, rc=%Rrc\n", SharedClipboardTransferGetID(pTransfer), rc)); 209 203 return rc; 210 204 } … … 251 245 case WM_CLIPBOARDUPDATE: 252 246 { 253 LogFunc(("WM_CLIPBOARDUPDATE \n"));247 LogFunc(("WM_CLIPBOARDUPDATE: pWinCtx=%p\n", pWinCtx)); 254 248 255 249 int rc = RTCritSectEnter(&pWinCtx->CritSect); … … 269 263 * Report available formats to the host. */ 270 264 SHCLFORMATDATA Formats; 271 int rc = SharedClipboardWinGetFormats( &pCtx->Win, &Formats);265 int rc = SharedClipboardWinGetFormats(pWinCtx, &Formats); 272 266 if (RT_SUCCESS(rc)) 273 267 { … … 298 292 case WM_DRAWCLIPBOARD: 299 293 { 300 LogFlowFunc(("WM_DRAWCLIPBOARD \n"));294 LogFlowFunc(("WM_DRAWCLIPBOARD: pWinCtx=%p\n", pWinCtx)); 301 295 302 296 int rc = RTCritSectEnter(&pWinCtx->CritSect); … … 517 511 Assert(pEvent->enmType == VBGLR3CLIPBOARDEVENTTYPE_REPORT_FORMATS); 518 512 519 const SHCLFORMATS fFormats = 513 const SHCLFORMATS fFormats = pEvent->u.ReportedFormats.uFormats; 520 514 521 515 if (fFormats != VBOX_SHCL_FMT_NONE) /* Could arrive with some older GA versions. */ 522 516 { 523 int rc = SharedClipboardWinOpen(hwnd); 524 if (RT_SUCCESS(rc)) 525 { 526 SharedClipboardWinClear(); 527 528 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 529 if (fFormats & VBOX_SHCL_FMT_URI_LIST) 517 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 518 if (fFormats & VBOX_SHCL_FMT_URI_LIST) 519 { 520 LogFunc(("VBOX_SHCL_FMT_URI_LIST\n")); 521 522 /* 523 * Creating and starting the actual transfer will be done in vbglR3ClipboardTransferStart() as soon 524 * as the host announces the start of the transfer via a VBOX_SHCL_HOST_MSG_TRANSFER_STATUS message. 525 * Transfers always are controlled and initiated on the host side! 526 * 527 * So don't announce the transfer to the OS here yet. Don't touch the clipboard in any here; otherwise 528 * this will trigger a WM_DRAWCLIPBOARD or friends, which will result in fun bugs coming up. 529 */ 530 } 531 else 532 { 533 #endif 534 int rc = SharedClipboardWinOpen(hwnd); 535 if (RT_SUCCESS(rc)) 530 536 { 531 LogFunc(("VBOX_SHCL_FMT_URI_LIST\n")); 532 533 /* 534 * Creating and starting the actual transfer will be done in vbglR3ClipboardTransferStart() as soon 535 * as the host announces the start of the transfer via a VBOX_SHCL_HOST_MSG_TRANSFER_STATUS message. 536 * Transfers always are controlled and initiated on the host side! 537 * 538 * So don't announce the transfer to the OS here yet. 539 */ 537 SharedClipboardWinClear(); 538 539 rc = SharedClipboardWinAnnounceFormats(pWinCtx, fFormats); 540 540 } 541 else 542 { 543 #endif 544 rc = SharedClipboardWinAnnounceFormats(pWinCtx, fFormats); 545 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 546 } 547 #endif 541 548 542 SharedClipboardWinClose(); 549 } 543 544 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 545 } 546 #endif 550 547 } 551 548 … … 651 648 } 652 649 653 #if def VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS654 case SHCL_WIN_WM_ URI_TRANSFER_START:655 { 656 LogFunc(("SHCL_WIN_WM_ URI_TRANSFER_CREATE\n"));650 #if 0 651 case SHCL_WIN_WM_TRANSFER_START: 652 { 653 LogFunc(("SHCL_WIN_WM_TRANSFER_START\n")); 657 654 658 655 PSHCLTRANSFER pTransfer = (PSHCLTRANSFER)lParam; … … 661 658 Assert(SharedClipboardTransferGetSource(pTransfer) == SHCLSOURCE_REMOTE); /* Sanity. */ 662 659 663 int rc2 = SharedClipboardWinTransferCreate( &pCtx->Win, pTransfer);660 int rc2 = SharedClipboardWinTransferCreate(pWinCtx, pTransfer); 664 661 AssertRC(rc2); 665 662 break; … … 707 704 708 705 /* Register the Window Class. */ 709 WNDCLASSEX wc = { 0 }; 710 wc.cbSize = sizeof(WNDCLASSEX); 706 WNDCLASSEX wc; 707 RT_ZERO(wc); 708 709 wc.cbSize = sizeof(WNDCLASSEX); 711 710 712 711 if (!GetClassInfoEx(hInstance, s_szClipWndClassName, &wc)) … … 741 740 SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE); 742 741 743 SharedClipboardWinChainAdd(pWinCtx); 744 if (!SharedClipboardWinIsNewAPI(&pWinCtx->newAPI)) 745 pWinCtx->oldAPI.timerRefresh = SetTimer(pWinCtx->hWnd, 0, 10 * 1000 /* 10s */, NULL); 742 rc = SharedClipboardWinChainAdd(pWinCtx); 743 if (RT_SUCCESS(rc)) 744 { 745 if (!SharedClipboardWinIsNewAPI(&pWinCtx->newAPI)) 746 pWinCtx->oldAPI.timerRefresh = SetTimer(pWinCtx->hWnd, 0, 10 * 1000 /* 10s */, NULL); 747 } 746 748 } 747 749 } … … 751 753 } 752 754 755 static int vboxClipboardWindowThread(RTTHREAD hThread, void *pvUser) 756 { 757 PSHCLCONTEXT pCtx = (PSHCLCONTEXT)pvUser; 758 AssertPtr(pCtx); 759 760 HRESULT hr; 761 762 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 763 hr = OleInitialize(NULL); 764 if (FAILED(hr)) 765 { 766 LogRel(("Shared Clipboard: Initializing OLE in window thread failed (%Rhrc) -- file transfers unavailable\n", hr)); 767 /* Not critical, the rest of the clipboard might work. */ 768 } 769 else 770 LogRel(("Shared Clipboard: Initialized OLE in window thread\n")); 771 #endif 772 773 int rc = vboxClipboardCreateWindow(pCtx); 774 if (RT_FAILURE(rc)) 775 { 776 LogRel(("Shared Clipboard: Unable to create window, rc=%Rrc\n", rc)); 777 return rc; 778 } 779 780 pCtx->fStarted = true; /* Set started indicator. */ 781 782 int rc2 = RTThreadUserSignal(hThread); 783 bool fSignalled = RT_SUCCESS(rc2); 784 785 LogRel2(("Shared Clipboard: Window thread running\n")); 786 787 if (RT_SUCCESS(rc)) 788 { 789 for (;;) 790 { 791 MSG uMsg; 792 BOOL fRet; 793 while ((fRet = GetMessage(&uMsg, 0, 0, 0)) > 0) 794 { 795 TranslateMessage(&uMsg); 796 DispatchMessage(&uMsg); 797 } 798 Assert(fRet >= 0); 799 800 if (ASMAtomicReadBool(&pCtx->fShutdown)) 801 break; 802 803 /** @todo Immediately drop on failure? */ 804 } 805 } 806 807 if (!fSignalled) 808 { 809 rc2 = RTThreadUserSignal(hThread); 810 AssertRC(rc2); 811 } 812 813 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 814 OleSetClipboard(NULL); /* Make sure to flush the clipboard on destruction. */ 815 OleUninitialize(); 816 #endif 817 818 LogRel(("Shared Clipboard: Window thread ended\n")); 819 820 LogFlowFuncLeaveRC(rc); 821 return rc; 822 } 823 753 824 static void vboxClipboardDestroy(PSHCLCONTEXT pCtx) 754 825 { 755 826 AssertPtrReturnVoid(pCtx); 827 828 LogFlowFunc(("pCtx=%p\n", pCtx)); 829 830 LogRel2(("Shared Clipboard: Destroying ...\n")); 831 832 pCtx->fShutdown = true; 756 833 757 834 const PSHCLWINCTX pWinCtx = &pCtx->Win; … … 763 840 } 764 841 842 if (pCtx->hThread != NIL_RTTHREAD) 843 { 844 int rcThread = VERR_WRONG_ORDER; 845 int rc = RTThreadWait(pCtx->hThread, 60 * 1000 /* Timeout in ms */, &rcThread); 846 LogFlowFunc(("Waiting for thread resulted in %Rrc (thread exited with %Rrc)\n", 847 rc, rcThread)); 848 RT_NOREF(rc); 849 } 850 765 851 UnregisterClass(s_szClipWndClassName, pCtx->pEnv->hInstance); 766 852 767 853 SharedClipboardWinCtxDestroy(&pCtx->Win); 854 855 LogRel2(("Shared Clipboard: Destroyed\n")); 768 856 } 769 857 … … 797 885 } 798 886 799 pCtx->pEnv = pEnv; 887 pCtx->pEnv = pEnv; 888 pCtx->hThread = NIL_RTTHREAD; 889 pCtx->fStarted = false; 890 pCtx->fShutdown = false; 800 891 801 892 int rc = VINF_SUCCESS; 802 893 803 894 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 804 HRESULT hr = OleInitialize(NULL); 805 if (FAILED(hr)) 806 { 807 LogRel(("Shared Clipboard: Initializing OLE failed (%Rhrc) -- file transfers unavailable\n", hr)); 808 /* Not critical, the rest of the clipboard might work. */ 809 } 810 else 811 { 812 LogRel(("Shared Clipboard: Initialized OLE\n")); 813 814 /* Install callbacks. */ 815 RT_ZERO(pCtx->CmdCtx.Transfers.Callbacks); 816 817 pCtx->CmdCtx.Transfers.Callbacks.pvUser = pCtx; /* Assign context as user-provided callback data. */ 818 819 pCtx->CmdCtx.Transfers.Callbacks.pfnTransferInitialize = vboxClipboardOnTransferInitCallback; 820 pCtx->CmdCtx.Transfers.Callbacks.pfnTransferStart = vboxClipboardOnTransferStartCallback; 821 pCtx->CmdCtx.Transfers.Callbacks.pfnTransferComplete = vboxClipboardOnTransferCompleteCallback; 822 pCtx->CmdCtx.Transfers.Callbacks.pfnTransferError = vboxClipboardOnTransferErrorCallback; 823 } 895 /* Install callbacks. */ 896 RT_ZERO(pCtx->CmdCtx.Transfers.Callbacks); 897 898 pCtx->CmdCtx.Transfers.Callbacks.pvUser = pCtx; /* Assign context as user-provided callback data. */ 899 pCtx->CmdCtx.Transfers.Callbacks.cbUser = sizeof(SHCLCONTEXT); 900 901 pCtx->CmdCtx.Transfers.Callbacks.pfnTransferInitialize = vboxClipboardOnTransferInitCallback; 902 pCtx->CmdCtx.Transfers.Callbacks.pfnTransferStart = vboxClipboardOnTransferStartCallback; 903 pCtx->CmdCtx.Transfers.Callbacks.pfnTransferComplete = vboxClipboardOnTransferCompleteCallback; 904 pCtx->CmdCtx.Transfers.Callbacks.pfnTransferError = vboxClipboardOnTransferErrorCallback; 824 905 #endif 825 906 826 907 if (RT_SUCCESS(rc)) 827 908 { 828 /* Check if new Clipboard API is available. */829 909 rc = SharedClipboardWinCtxInit(&pCtx->Win); 830 910 if (RT_SUCCESS(rc)) … … 832 912 if (RT_SUCCESS(rc)) 833 913 { 834 rc = vboxClipboardCreateWindow(pCtx); 914 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 915 rc = SharedClipboardTransferCtxInit(&pCtx->TransferCtx); 916 #endif 835 917 if (RT_SUCCESS(rc)) 836 918 { 837 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 838 rc = SharedClipboardTransferCtxInit(&pCtx->TransferCtx); 919 /* Message pump thread for our proxy window. */ 920 rc = RTThreadCreate(&pCtx->hThread, vboxClipboardWindowThread, pCtx /* pvUser */, 921 0, RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE, 922 "shclwnd"); 839 923 if (RT_SUCCESS(rc)) 840 #endif 841 *ppInstance = pCtx; 924 { 925 int rc2 = RTThreadUserWait(pCtx->hThread, 30 * 1000 /* Timeout in ms */); 926 AssertRC(rc2); 927 928 if (!pCtx->fStarted) /* Did the thread fail to start? */ 929 rc = VERR_NOT_SUPPORTED; /* Report back Shared Clipboard as not being supported. */ 930 } 931 } 932 933 if (RT_SUCCESS(rc)) 934 { 935 *ppInstance = pCtx; 842 936 } 843 937 else 844 {845 938 VbglR3ClipboardDisconnectEx(&pCtx->CmdCtx); 846 } 847 } 848 } 939 } 940 } 941 942 if (RT_FAILURE(rc)) 943 LogRel(("Shared Clipboard: Unable to initialize, rc=%Rrc\n", rc)); 849 944 850 945 LogFlowFuncLeaveRC(rc); … … 856 951 AssertPtr(pInstance); 857 952 LogFlowFunc(("pInstance=%p\n", pInstance)); 858 859 HRESULT hr = OleInitialize(NULL);860 if (FAILED(hr))861 {862 LogRel(("Shared Clipboard: Initializing OLE in worker thread failed (%Rhrc) -- file transfers unavailable\n", hr));863 /* Not critical, the rest of the clipboard might work. */864 }865 953 866 954 /* … … 875 963 const PSHCLWINCTX pWinCtx = &pCtx->Win; 876 964 965 LogRel2(("Shared Clipboard: Worker loop running, using protocol v%RU32\n", pCtx->CmdCtx.uProtocolVer)); 966 967 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 968 HRESULT hr = OleInitialize(NULL); 969 if (FAILED(hr)) 970 { 971 LogRel(("Shared Clipboard: Initializing OLE in worker thread failed (%Rhrc) -- file transfers unavailable\n", hr)); 972 /* Not critical, the rest of the clipboard might work. */ 973 } 974 else 975 LogRel(("Shared Clipboard: Initialized OLE in worker thraed\n")); 976 #endif 977 877 978 int rc; 878 979 879 LogFlowFunc((" Using protocol%RU32\n", pCtx->CmdCtx.uProtocolVer));980 LogFlowFunc(("uProtocolVer=%RU32\n", pCtx->CmdCtx.uProtocolVer)); 880 981 881 982 uint32_t uMsg; … … 946 1047 if (RT_FAILURE(rc)) 947 1048 { 1049 LogFlowFunc(("Getting next event failed with %Rrc\n", rc)); 1050 948 1051 VbglR3ClipboardEventFree(pEvent); 949 1052 pEvent = NULL; … … 987 1090 case VBGLR3CLIPBOARDEVENTTYPE_QUIT: 988 1091 { 989 /* The host is terminating. */ 990 LogRel(("Shared Clipboard: Terminating ...\n")); 1092 LogRel2(("Shared Clipboard: Host requested termination\n")); 991 1093 ASMAtomicXchgBool(pfShutdown, true); 992 1094 break; … … 994 1096 995 1097 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 996 case VBGLR3CLIPBOARDEVENTTYPE_ URI_TRANSFER_STATUS:1098 case VBGLR3CLIPBOARDEVENTTYPE_TRANSFER_STATUS: 997 1099 { 998 1100 /* Nothing to do here. */ 1101 rc = VINF_SUCCESS; 999 1102 break; 1000 1103 } 1001 1104 #endif 1002 case VBGLR3CLIPBOARDEVENTTYPE_INVALID: 1105 case VBGLR3CLIPBOARDEVENTTYPE_NONE: 1106 { 1107 /* Nothing to do here. */ 1108 rc = VINF_SUCCESS; 1109 break; 1110 } 1111 1003 1112 default: 1004 1113 { 1005 /* Wait a bit before retrying. */ 1006 RTThreadSleep(1000); 1007 1008 rc = VERR_NOT_SUPPORTED; 1009 break; 1114 AssertMsgFailedBreakStmt(("Event type %RU32 not implemented\n", pEvent->enmType), rc = VERR_NOT_SUPPORTED); 1010 1115 } 1011 1116 } … … 1022 1127 } 1023 1128 1129 LogRel(("Shared Clipboard: Worker loop ended\n")); 1130 1024 1131 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 1025 1132 OleSetClipboard(NULL); /* Make sure to flush the clipboard on destruction. */ … … 1060 1167 1061 1168 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 1062 OleSetClipboard(NULL); /* Make sure to flush the clipboard on destruction. */1063 OleUninitialize();1064 1065 1169 SharedClipboardTransferCtxDestroy(&pCtx->TransferCtx); 1066 1170 #endif
Note:
See TracChangeset
for help on using the changeset viewer.