Changeset 80444 in vbox for trunk/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp
- Timestamp:
- Aug 27, 2019 5:47:44 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp
r80285 r80444 22 22 #include <iprt/alloc.h> 23 23 #include <iprt/assert.h> 24 #include <iprt/semaphore.h> 24 25 #include <iprt/path.h> 25 26 … … 28 29 #include <VBox/GuestHost/clipboard-helper.h> 29 30 #include <VBox/HostServices/VBoxClipboardSvc.h> 31 32 33 /** 34 * Allocates a new event payload. 35 * 36 * @returns VBox status code. 37 * @param uID Event ID to associate payload to. 38 * @param pvData Data block to associate to this payload. 39 * @param cbData Size (in bytes) of data block to associate. 40 * @param ppPayload Where to store the allocated event payload on success. 41 */ 42 int SharedClipboardPayloadAlloc(uint32_t uID, const void *pvData, uint32_t cbData, 43 PSHAREDCLIPBOARDEVENTPAYLOAD *ppPayload) 44 { 45 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 46 AssertReturn (cbData, VERR_INVALID_PARAMETER); 47 48 PSHAREDCLIPBOARDEVENTPAYLOAD pPayload = 49 (PSHAREDCLIPBOARDEVENTPAYLOAD)RTMemAlloc(sizeof(SHAREDCLIPBOARDEVENTPAYLOAD)); 50 if (!pPayload) 51 return VERR_NO_MEMORY; 52 53 pPayload->pvData = RTMemAlloc(cbData); 54 if (pPayload->pvData) 55 { 56 memcpy(pPayload->pvData, pvData, cbData); 57 58 pPayload->cbData = cbData; 59 pPayload->uID = uID; 60 61 *ppPayload = pPayload; 62 63 return VINF_SUCCESS; 64 } 65 66 RTMemFree(pPayload); 67 return VERR_NO_MEMORY; 68 } 69 70 /** 71 * Frees an event payload. 72 * 73 * @returns VBox status code. 74 * @param pPayload Event payload to free. 75 */ 76 void SharedClipboardPayloadFree(PSHAREDCLIPBOARDEVENTPAYLOAD pPayload) 77 { 78 if (!pPayload) 79 return; 80 81 if (pPayload->pvData) 82 { 83 Assert(pPayload->cbData); 84 RTMemFree(pPayload->pvData); 85 pPayload->pvData = NULL; 86 } 87 88 pPayload->cbData = 0; 89 90 RTMemFree(pPayload); 91 pPayload = NULL; 92 } 93 94 int SharedClipboardEventCreate(PSHAREDCLIPBOARDEVENT pEvent, uint16_t uID) 95 { 96 AssertPtrReturn(pEvent, VERR_INVALID_POINTER); 97 98 LogFlowFunc(("Event %RU16\n", uID)); 99 100 int rc = RTSemEventCreate(&pEvent->hEventSem); 101 if (RT_SUCCESS(rc)) 102 { 103 pEvent->uID = uID; 104 pEvent->pPayload = NULL; 105 } 106 107 return rc; 108 } 109 110 void SharedClipboardEventDestroy(PSHAREDCLIPBOARDEVENT pEvent) 111 { 112 if (!pEvent) 113 return; 114 115 LogFlowFunc(("Event %RU16\n", pEvent->uID)); 116 117 if (pEvent->hEventSem != NIL_RTSEMEVENT) 118 { 119 RTSemEventDestroy(pEvent->hEventSem); 120 pEvent->hEventSem = NIL_RTSEMEVENT; 121 } 122 123 SharedClipboardPayloadFree(pEvent->pPayload); 124 125 pEvent->uID = 0; 126 } 127 128 int SharedClipboardEventSourceCreate(PSHAREDCLIPBOARDEVENTSOURCE pSource, uint16_t uID) 129 { 130 AssertPtrReturn(pSource, VERR_INVALID_POINTER); 131 132 LogFlowFunc(("pSource=%p, uID=%RU16\n", pSource, uID)); 133 134 int rc = VINF_SUCCESS; 135 136 RTListInit(&pSource->lstEvents); 137 138 pSource->uID = uID; 139 pSource->uEventIDNext = 1; /* Event ID 0 always is reserved (marks "unused"). */ 140 141 LogFlowFuncLeaveRC(rc); 142 return rc; 143 } 144 145 void SharedClipboardEventSourceDestroy(PSHAREDCLIPBOARDEVENTSOURCE pSource) 146 { 147 if (!pSource) 148 return; 149 150 LogFlowFunc(("ID=%RU16\n", pSource->uID)); 151 152 PSHAREDCLIPBOARDEVENT pEvIt; 153 PSHAREDCLIPBOARDEVENT pEvItNext; 154 RTListForEachSafe(&pSource->lstEvents, pEvIt, pEvItNext, SHAREDCLIPBOARDEVENT, Node) 155 { 156 SharedClipboardEventDestroy(pEvIt); 157 RTMemFree(pEvIt); 158 } 159 } 160 161 /** 162 * Generates a new event ID for a specific event source. 163 * 164 * @returns New event ID generated, or 0 on error. 165 * @param pSource Event source to generate event for. 166 */ 167 uint16_t SharedClipboardEventIDGenerate(PSHAREDCLIPBOARDEVENTSOURCE pSource) 168 { 169 AssertPtrReturn(pSource, 0); 170 171 LogFlowFunc(("uSource=%RU16: New event: %RU16\n", pSource->uID, pSource->uEventIDNext)); 172 return pSource->uEventIDNext++; /** @todo Improve this. */ 173 } 174 175 /** 176 * Returns a specific event of a event source. 177 * 178 * @returns Pointer to event if found, or NULL if not found. 179 * @param pSource Event source to get event from. 180 * @param uID Event ID to get. 181 */ 182 inline PSHAREDCLIPBOARDEVENT sharedClipboardEventGet(PSHAREDCLIPBOARDEVENTSOURCE pSource, uint16_t uID) 183 { 184 PSHAREDCLIPBOARDEVENT pEvIt; 185 RTListForEach(&pSource->lstEvents, pEvIt, SHAREDCLIPBOARDEVENT, Node) 186 { 187 if (pEvIt->uID == uID) 188 return pEvIt; 189 } 190 191 return NULL; 192 } 193 194 /** 195 * Registers an event. 196 * 197 * @returns VBox status code. 198 * @param pSource Event source to register event for. 199 * @param uID Event ID to register. 200 */ 201 int SharedClipboardEventRegister(PSHAREDCLIPBOARDEVENTSOURCE pSource, uint16_t uID) 202 { 203 AssertPtrReturn(pSource, VERR_INVALID_POINTER); 204 205 int rc; 206 207 LogFlowFunc(("uSource=%RU16, uEvent=%RU16\n", pSource->uID, uID)); 208 209 if (sharedClipboardEventGet(pSource, uID) == NULL) 210 { 211 PSHAREDCLIPBOARDEVENT pEvent 212 = (PSHAREDCLIPBOARDEVENT)RTMemAllocZ(sizeof(SHAREDCLIPBOARDEVENT)); 213 if (pEvent) 214 { 215 rc = SharedClipboardEventCreate(pEvent, uID); 216 if (RT_SUCCESS(rc)) 217 { 218 RTListAppend(&pSource->lstEvents, &pEvent->Node); 219 220 LogFlowFunc(("Event %RU16\n", uID)); 221 } 222 } 223 else 224 rc = VERR_NO_MEMORY; 225 } 226 else 227 rc = VERR_ALREADY_EXISTS; 228 229 #ifdef DEBUG_andy 230 AssertRC(rc); 231 #endif 232 233 LogFlowFuncLeaveRC(rc); 234 return rc; 235 } 236 237 /** 238 * Unregisters an event. 239 * 240 * @returns VBox status code. 241 * @param pSource Event source to unregister event for. 242 * @param uID Event ID to unregister. 243 */ 244 int SharedClipboardEventUnregister(PSHAREDCLIPBOARDEVENTSOURCE pSource, uint16_t uID) 245 { 246 AssertPtrReturn(pSource, VERR_INVALID_POINTER); 247 248 int rc; 249 250 LogFlowFunc(("uSource=%RU16, uEvent=%RU16\n", pSource->uID, uID)); 251 252 PSHAREDCLIPBOARDEVENT pEvent = sharedClipboardEventGet(pSource, uID); 253 if (pEvent) 254 { 255 LogFlowFunc(("Event %RU16\n", pEvent->uID)); 256 257 SharedClipboardEventDestroy(pEvent); 258 RTMemFree(pEvent); 259 260 RTListNodeRemove(&pEvent->Node); 261 262 rc = VINF_SUCCESS; 263 } 264 else 265 rc = VERR_NOT_FOUND; 266 267 AssertRC(rc); 268 269 LogFlowFuncLeaveRC(rc); 270 return rc; 271 } 272 273 /** 274 * Waits for an event to get signalled. 275 * 276 * @returns VBox status code. 277 * @param pSource Event source that contains the event to wait for. 278 * @param uID Event ID to wait for. 279 * @param uTimeoutMs Timeout (in ms) to wait. 280 * @param ppPayload Where to store the (allocated) event payload on success. Needs to be free'd with 281 * SharedClipboardPayloadFree(). 282 */ 283 int SharedClipboardEventWait(PSHAREDCLIPBOARDEVENTSOURCE pSource, uint16_t uID, RTMSINTERVAL uTimeoutMs, 284 PSHAREDCLIPBOARDEVENTPAYLOAD* ppPayload) 285 { 286 AssertPtrReturn(pSource, VERR_INVALID_POINTER); 287 288 LogFlowFuncEnter(); 289 290 int rc; 291 292 PSHAREDCLIPBOARDEVENT pEvent = sharedClipboardEventGet(pSource, uID); 293 if (pEvent) 294 { 295 rc = RTSemEventWait(pEvent->hEventSem, uTimeoutMs); 296 if (RT_SUCCESS(rc)) 297 { 298 *ppPayload = pEvent->pPayload; 299 300 pEvent->pPayload = NULL; 301 } 302 } 303 else 304 rc = VERR_NOT_FOUND; 305 306 LogFlowFuncLeaveRC(rc); 307 return rc; 308 } 309 310 /** 311 * Signals an event. 312 * 313 * @returns VBox status code. 314 * @param pSource Event source of event to signal. 315 * @param uID Event ID to signal. 316 * @param pPayload Event payload to associate. Takes ownership. Optional. 317 */ 318 int SharedClipboardEventSignal(PSHAREDCLIPBOARDEVENTSOURCE pSource, uint16_t uID, 319 PSHAREDCLIPBOARDEVENTPAYLOAD pPayload) 320 { 321 AssertPtrReturn(pSource, VERR_INVALID_POINTER); 322 323 int rc; 324 325 LogFlowFunc(("uSource=%RU16, uEvent=%RU16\n", pSource->uID, uID)); 326 327 PSHAREDCLIPBOARDEVENT pEvent = sharedClipboardEventGet(pSource, uID); 328 if (pEvent) 329 { 330 Assert(pEvent->pPayload == NULL); 331 332 pEvent->pPayload = pPayload; 333 334 rc = RTSemEventSignal(pEvent->hEventSem); 335 } 336 else 337 rc = VERR_NOT_FOUND; 338 339 #ifdef DEBUG_andy 340 AssertRC(rc); 341 #endif 342 343 LogFlowFuncLeaveRC(rc); 344 return rc; 345 } 346 347 /** 348 * Detaches a payload from an event. 349 * 350 * @returns VBox status code. 351 * @param pSource Event source of event to detach payload for. 352 * @param uID Event ID to detach payload for. 353 */ 354 void SharedClipboardEventPayloadDetach(PSHAREDCLIPBOARDEVENTSOURCE pSource, uint16_t uID) 355 { 356 AssertPtrReturnVoid(pSource); 357 358 LogFlowFunc(("uSource=%RU16, uEvent=%RU16\n", pSource->uID, uID)); 359 360 PSHAREDCLIPBOARDEVENT pEvent = sharedClipboardEventGet(pSource, uID); 361 if (pEvent) 362 { 363 pEvent->pPayload = NULL; 364 } 365 #ifdef DEBUG_andy 366 else 367 AssertMsgFailed(("uSource=%RU16, uEvent=%RU16\n", pSource->uID, uID)); 368 #endif 369 } 30 370 31 371 /** @todo use const where appropriate; delinuxify the code (*Lin* -> *Host*); use AssertLogRel*. */ … … 421 761 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT); 422 762 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA); 423 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_ REPORT_FORMATS);763 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS_WRITE); 424 764 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_TRANSFER_START); 425 765 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOT_LIST_HDR_READ); … … 453 793 switch (uMsg) 454 794 { 455 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_GUEST_FN_REPORT_FORMATS); 456 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_DATA); 457 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA); 795 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_GUEST_FN_GET_HOST_MSG_OLD); 796 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_GUEST_FN_FORMATS_WRITE); 797 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_GUEST_FN_DATA_READ); 798 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_GUEST_FN_DATA_WRITE); 799 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_GUEST_FN_CONNECT); 458 800 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_NOWAIT); 459 801 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_WAIT); … … 477 819 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_GUEST_FN_CANCEL); 478 820 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_GUEST_FN_ERROR); 479 RT_CASE_RET_STR(VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT);480 821 } 481 822 return "Unknown"; 482 823 } 824
Note:
See TracChangeset
for help on using the changeset viewer.