Changeset 100204 in vbox for trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp
- Timestamp:
- Jun 19, 2023 9:11:37 AM (18 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp
r98103 r100204 26 26 */ 27 27 28 #define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD29 28 #include <VBox/GuestHost/SharedClipboard.h> 30 29 … … 40 39 #endif 41 40 41 #ifdef LOG_GROUP 42 # undef LOG_GROUP 43 #endif 44 #define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD 42 45 #include <VBox/log.h> 43 46 … … 48 51 #include <VBox/GuestHost/SharedClipboard-win.h> 49 52 #include <VBox/GuestHost/clipboard-helper.h> 53 54 55 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 56 int SharedClipboardWinTransferDropFilesToStringList(DROPFILES *pDropFiles, char **ppszList, uint32_t *pcbList); 57 #endif 50 58 51 59 … … 833 841 * a separate WM_RENDERFORMAT message. 834 842 * 835 * @returns VBox status code. VERR_NOT_SUPPORTED if the format is not supported / handled. 843 * @returns VBox status code. 844 * @retval VERR_NOT_SUPPORTED if *all* format(s) is/are not supported / handled. 836 845 * @param pWinCtx Windows context to use. 837 846 * @param fFormats Clipboard format(s) to announce. … … 841 850 LogFunc(("fFormats=0x%x\n", fFormats)); 842 851 852 /* Make sure that if VBOX_SHCL_FMT_URI_LIST is announced, we don't announced anything else. 853 * This otherwise this will trigger a WM_DRAWCLIPBOARD or friends, which will result in fun bugs coming up. */ 854 AssertReturn(( !(fFormats & VBOX_SHCL_FMT_URI_LIST) 855 || (fFormats & VBOX_SHCL_FMT_URI_LIST) == VBOX_SHCL_FMT_URI_LIST), VERR_INVALID_PARAMETER); 843 856 /* 844 857 * Set the clipboard formats. … … 846 859 static struct 847 860 { 861 /** VBox format to handle. */ 848 862 uint32_t fVBoxFormat; 863 /** Native Windows format to use. 864 * Set to 0 if unused / needs special handling. */ 849 865 UINT uWinFormat; 850 const char *pszWinFormat; 866 /** Own registered format. Set to NULL if not used / applicable. */ 867 const char *pszRegFormat; 851 868 const char *pszLog; 852 869 } s_aFormats[] = 853 870 { 854 871 { VBOX_SHCL_FMT_UNICODETEXT, CF_UNICODETEXT, NULL, "CF_UNICODETEXT" }, 872 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 873 /* We don't announce anything here for an URI list to the Windows clipboard, as we later have to 874 * initialize our custom IDataObject and set it via OleSetClipboard(). */ 875 { VBOX_SHCL_FMT_URI_LIST, 0, NULL, "SHCL_URI_LIST" }, 876 #endif 855 877 { VBOX_SHCL_FMT_BITMAP, CF_DIB, NULL, "CF_DIB" }, 856 { VBOX_SHCL_FMT_HTML, 0, SHCL_WIN_REGFMT_HTML, "SHCL_WIN_REGFMT_HTML" } ,878 { VBOX_SHCL_FMT_HTML, 0, SHCL_WIN_REGFMT_HTML, "SHCL_WIN_REGFMT_HTML" } 857 879 }; 880 858 881 unsigned cSuccessfullySet = 0; 859 882 SHCLFORMATS fFormatsLeft = fFormats; … … 863 886 if (fFormatsLeft & s_aFormats[i].fVBoxFormat) 864 887 { 865 Log Func(("%s\n", s_aFormats[i].pszLog));888 LogRel2(("Shared Clipboard: Announcing format '%s' to clipboard\n", s_aFormats[i].pszLog)); 866 889 fFormatsLeft &= ~s_aFormats[i].fVBoxFormat; 867 890 868 /* Reg format if needed: */ 869 UINT uWinFormat = s_aFormats[i].uWinFormat; 891 UINT uWinFormat = 0; 892 if (s_aFormats[i].pszRegFormat) /* See if we have (special) registered format. */ 893 { 894 uWinFormat = RegisterClipboardFormat(s_aFormats[i].pszRegFormat); 895 AssertContinue(uWinFormat != 0); 896 } 897 else /* Native format. */ 898 uWinFormat = s_aFormats[i].uWinFormat; 899 900 /* Any native format set? If not, just skip it (as successful). */ 870 901 if (!uWinFormat) 871 902 { 872 uWinFormat = RegisterClipboardFormat(s_aFormats[i].pszWinFormat);873 AssertContinue(uWinFormat != 0);903 cSuccessfullySet++; 904 continue; 874 905 } 875 906 … … 903 934 else if (RT_SUCCESS(rc) && fFormatsLeft != 0) 904 935 { 905 Log Func(("Unsupported formats: %#x (%#x)\n", fFormatsLeft, fFormats));936 LogRel(("Shared Clipboard: Unable to announce unsupported/invalid formats: %#x (%#x)\n", fFormatsLeft, fFormats)); 906 937 rc = VERR_NOT_SUPPORTED; 907 938 } … … 917 948 * a separate WM_RENDERFORMAT message. 918 949 * 919 * @returns VBox status code. VERR_NOT_SUPPORTED if the format is not supported / handled.950 * @returns VBox status code. 920 951 * @param pWinCtx Windows context to use. 921 952 * @param fFormats Clipboard format(s) to announce. … … 1003 1034 1004 1035 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 1005 1006 /** 1007 * Creates an Shared Clipboard transfer by announcing transfer data (via IDataObject) to Windows. 1036 /** 1037 * Creates an Shared Clipboard transfer by announcing transfer data (via IDataObject) to Windows. 1008 1038 * 1009 1039 * This creates the necessary IDataObject + IStream implementations and initiates the actual transfers required for getting … … 1012 1042 * @returns VBox status code. 1013 1043 * @param pWinCtx Windows context to use. 1014 * @param pTransferCtxCtx Transfer contextto use. 1015 * @param pTransfer Shared Clipboard transfer to use. 1016 */ 1017 int SharedClipboardWinTransferCreate(PSHCLWINCTX pWinCtx, PSHCLTRANSFER pTransfer) 1018 { 1019 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER); 1020 1021 LogFlowFunc(("pWinCtx=%p\n", pWinCtx)); 1022 1023 AssertReturn(pTransfer->pvUser == NULL, VERR_WRONG_ORDER); 1044 * @param pCtx Shared Clipboard context to use. 1045 * Needed for the data object to communicate with the main window thread. 1046 * @param pCallbacks Callbacks table to use. 1047 */ 1048 int SharedClipboardWinTransferCreateAndSetDataObject(PSHCLWINCTX pWinCtx, PSHCLCONTEXT pCtx, PSHCLCALLBACKS pCallbacks) 1049 { 1050 AssertPtrReturn(pWinCtx, VERR_INVALID_POINTER); 1051 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 1052 AssertPtrReturn(pCallbacks, VERR_INVALID_POINTER); 1024 1053 1025 1054 /* Make sure to enter the critical section before setting the clipboard data, as otherwise WM_CLIPBOARDUPDATE … … 1028 1057 if (RT_SUCCESS(rc)) 1029 1058 { 1059 if (pWinCtx->pDataObjInFlight == NULL) 1060 { 1061 SharedClipboardWinDataObject *pObj = new SharedClipboardWinDataObject(); 1062 if (pObj) 1063 { 1064 rc = pObj->Init(pCtx); 1065 if (RT_SUCCESS(rc)) 1066 { 1067 if (RT_SUCCESS(rc)) 1068 pObj->SetCallbacks(pCallbacks); 1069 1070 if (RT_SUCCESS(rc)) 1071 pWinCtx->pDataObjInFlight = pObj; 1072 } 1073 } 1074 else 1075 rc = VERR_NO_MEMORY; 1076 } 1077 1078 if (RT_SUCCESS(rc)) 1079 { 1080 SharedClipboardWinClose(); 1081 /* Note: Clipboard must be closed first before calling OleSetClipboard(). */ 1082 1083 /** @todo There is a potential race between SharedClipboardWinClose() and OleSetClipboard(), 1084 * where another application could own the clipboard (open), and thus the call to 1085 * OleSetClipboard() will fail. Needs (better) fixing. */ 1086 HRESULT hr = S_OK; 1087 1088 for (unsigned uTries = 0; uTries < 3; uTries++) 1089 { 1090 hr = OleSetClipboard(pWinCtx->pDataObjInFlight); 1091 if (SUCCEEDED(hr)) 1092 { 1093 Assert(OleIsCurrentClipboard(pWinCtx->pDataObjInFlight) == S_OK); /* Sanity. */ 1094 1095 /* 1096 * Calling OleSetClipboard() changed the clipboard owner, which in turn will let us receive 1097 * a WM_CLIPBOARDUPDATE message. To not confuse ourselves with our own clipboard owner changes, 1098 * save a new window handle and deal with it in WM_CLIPBOARDUPDATE. 1099 */ 1100 pWinCtx->hWndClipboardOwnerUs = GetClipboardOwner(); 1101 1102 LogFlowFunc(("hWndClipboardOwnerUs=%p\n", pWinCtx->hWndClipboardOwnerUs)); 1103 break; 1104 } 1105 1106 LogFlowFunc(("Failed with %Rhrc (try %u/3)\n", hr, uTries + 1)); 1107 RTThreadSleep(500); /* Wait a bit. */ 1108 } 1109 1110 if (FAILED(hr)) 1111 { 1112 rc = VERR_ACCESS_DENIED; /** @todo Fudge; fix this. */ 1113 LogRel(("Shared Clipboard: Failed with %Rhrc when setting data object to clipboard\n", hr)); 1114 } 1115 } 1116 1117 int rc2 = RTCritSectLeave(&pWinCtx->CritSect); 1118 AssertRC(rc2); 1119 } 1120 1121 LogFlowFuncLeaveRC(rc); 1122 return rc; 1123 } 1124 1125 #if 0 1126 /** 1127 * Creates an Shared Clipboard transfer by announcing transfer data (via IDataObject) to Windows. 1128 * 1129 * This creates the necessary IDataObject + IStream implementations and initiates the actual transfers required for getting 1130 * the meta data. Whether or not the actual (file++) transfer(s) are happening is up to the user (at some point) later then. 1131 * 1132 * @returns VBox status code. 1133 * @param pWinCtx Windows context to use. 1134 * @param pTransferCtxCtx Transfer contextto use. 1135 * @param pTransfer Shared Clipboard transfer to use. 1136 */ 1137 int SharedClipboardWinTransferCreate(PSHCLWINCTX pWinCtx, PSHCLTRANSFER pTransfer) 1138 { 1139 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER); 1140 1141 LogFlowFunc(("pWinCtx=%p\n", pWinCtx)); 1142 1143 AssertReturn(pTransfer->pvUser == NULL, VERR_WRONG_ORDER); 1144 1145 /* Make sure to enter the critical section before setting the clipboard data, as otherwise WM_CLIPBOARDUPDATE 1146 * might get called *before* we had the opportunity to set pWinCtx->hWndClipboardOwnerUs below. */ 1147 int rc = RTCritSectEnter(&pWinCtx->CritSect); 1148 if (RT_SUCCESS(rc)) 1149 { 1030 1150 SharedClipboardWinTransferCtx *pWinURITransferCtx = new SharedClipboardWinTransferCtx(); 1031 1151 if (pWinURITransferCtx) … … 1034 1154 pTransfer->cbUser = sizeof(SharedClipboardWinTransferCtx); 1035 1155 1036 pWinURITransferCtx->pDataObj = new SharedClipboardWinDataObject( pTransfer);1156 pWinURITransferCtx->pDataObj = new SharedClipboardWinDataObject(); 1037 1157 if (pWinURITransferCtx->pDataObj) 1038 1158 { 1039 rc = pWinURITransferCtx->pDataObj->Init( );1159 rc = pWinURITransferCtx->pDataObj->Init(pCtx); 1040 1160 if (RT_SUCCESS(rc)) 1041 1161 { … … 1090 1210 return rc; 1091 1211 } 1212 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ 1092 1213 1093 1214 /** … … 1133 1254 * @param pTransfer Transfer to get roots for. 1134 1255 */ 1135 int SharedClipboardWin GetRoots(PSHCLWINCTX pWinCtx, PSHCLTRANSFER pTransfer)1256 int SharedClipboardWinTransferGetRootsFromClipboard(PSHCLWINCTX pWinCtx, PSHCLTRANSFER pTransfer) 1136 1257 { 1137 1258 AssertPtrReturn(pWinCtx, VERR_INVALID_POINTER); … … 1151 1272 if (hDrop) 1152 1273 { 1153 char *p apszList = NULL;1274 char *pszList = NULL; 1154 1275 uint32_t cbList; 1155 rc = SharedClipboardWin DropFilesToStringList((DROPFILES *)hDrop, &papszList, &cbList);1276 rc = SharedClipboardWinTransferDropFilesToStringList((DROPFILES *)hDrop, &pszList, &cbList); 1156 1277 1157 1278 GlobalUnlock(hClip); … … 1159 1280 if (RT_SUCCESS(rc)) 1160 1281 { 1161 rc = ShClTransferRootsSet(pTransfer, 1162 papszList, cbList + 1 /* Include termination */); 1163 RTStrFree(papszList); 1282 rc = ShClTransferRootsInitFromStringList(pTransfer, pszList, cbList); 1283 RTStrFree(pszList); 1164 1284 } 1165 1285 } … … 1179 1299 1180 1300 /** 1181 * Converts a DROPFILES (HDROP) structure to a string list, separated by \r\n.1301 * Converts a DROPFILES (HDROP) structure to a string list, separated by SHCL_TRANSFER_URI_LIST_SEP_STR. 1182 1302 * Does not do any locking on the input data. 1183 1303 * 1184 1304 * @returns VBox status code. 1185 1305 * @param pDropFiles Pointer to DROPFILES structure to convert. 1186 * @param papszList Where to store the allocated string list. 1306 * @param ppszList Where to store the allocated string list on success. 1307 * Needs to be free'd with RTStrFree(). 1187 1308 * @param pcbList Where to store the size (in bytes) of the allocated string list. 1188 */ 1189 int SharedClipboardWinDropFilesToStringList(DROPFILES *pDropFiles, char **papszList, uint32_t *pcbList) 1309 * Includes zero terminator. 1310 */ 1311 int SharedClipboardWinTransferDropFilesToStringList(DROPFILES *pDropFiles, char **ppszList, uint32_t *pcbList) 1190 1312 { 1191 1313 AssertPtrReturn(pDropFiles, VERR_INVALID_POINTER); 1192 AssertPtrReturn(p apszList,VERR_INVALID_POINTER);1314 AssertPtrReturn(ppszList, VERR_INVALID_POINTER); 1193 1315 AssertPtrReturn(pcbList, VERR_INVALID_POINTER); 1194 1316 … … 1293 1415 /* Add separation between filenames. 1294 1416 * Note: Also do this for the last element of the list. */ 1295 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, "\r\n", 2 /* Bytes */);1417 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, SHCL_TRANSFER_URI_LIST_SEP_STR, 2 /* Bytes */); 1296 1418 if (RT_SUCCESS(rc)) 1297 cchFiles += 2; /* Include \r\n*/1419 cchFiles += 2; /* Include SHCL_TRANSFER_URI_LIST_SEP_STR */ 1298 1420 } 1299 1421 … … 1306 1428 cFiles, cchFiles, cbFiles, pszFiles)); 1307 1429 1308 *p apszList = pszFiles;1430 *ppszList = pszFiles; 1309 1431 *pcbList = cbFiles; 1310 1432 } … … 1318 1440 return rc; 1319 1441 } 1320 1321 1442 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ 1322 1443
Note:
See TracChangeset
for help on using the changeset viewer.