Changeset 78171 in vbox
- Timestamp:
- Apr 17, 2019 4:03:40 PM (6 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp
r78151 r78171 20 20 * Header Files * 21 21 *********************************************************************************************************************************/ 22 # 22 #define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD 23 23 #include "VBoxTray.h" 24 24 #include "VBoxHelpers.h" … … 69 69 case WM_CLIPBOARDUPDATE: 70 70 { 71 Log(("WM_CLIPBOARDUPDATE\n")); 72 73 if (GetClipboardOwner() != hwnd) 74 { 75 /* Clipboard was updated by another application. */ 76 uint32_t uFormats; 77 int vboxrc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats); 78 if (RT_SUCCESS(vboxrc)) 79 vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats); 80 } 81 } break; 71 Log(("WM_CLIPBOARDUPDATE\n")); 72 73 if (GetClipboardOwner() != hwnd) 74 { 75 /* Clipboard was updated by another application. */ 76 uint32_t uFormats; 77 int vboxrc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats); 78 if (RT_SUCCESS(vboxrc)) 79 vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats); 80 } 81 } 82 break; 82 83 83 84 case WM_CHANGECBCHAIN: 84 85 { 85 if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) 86 { 87 rc = DefWindowProc(hwnd, msg, wParam, lParam); 88 break; 89 } 90 91 HWND hWndRemoved = (HWND)wParam; 92 HWND hWndNext = (HWND)lParam; 93 94 LogFlowFunc(("WM_CHANGECBCHAIN: hWndRemoved=%p, hWndNext=%p, hWnd=%p\n", hWndRemoved, hWndNext, pWinCtx->hWnd)); 95 96 if (hWndRemoved == pWinCtx->hWndNextInChain) 97 { 98 /* The window that was next to our in the chain is being removed. 99 * Relink to the new next window. */ 100 pWinCtx->hWndNextInChain = hWndNext; 101 } 102 else 103 { 104 if (pWinCtx->hWndNextInChain) 105 { 106 /* Pass the message further. */ 107 DWORD_PTR dwResult; 108 rc = SendMessageTimeout(pWinCtx->hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, 109 VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, &dwResult); 110 if (!rc) 111 rc = (LRESULT) dwResult; 112 } 113 } 114 } break; 86 if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) 87 { 88 rc = DefWindowProc(hwnd, msg, wParam, lParam); 89 break; 90 } 91 92 HWND hWndRemoved = (HWND)wParam; 93 HWND hWndNext = (HWND)lParam; 94 95 LogFlowFunc(("WM_CHANGECBCHAIN: hWndRemoved=%p, hWndNext=%p, hWnd=%p\n", hWndRemoved, hWndNext, pWinCtx->hWnd)); 96 97 if (hWndRemoved == pWinCtx->hWndNextInChain) 98 { 99 /* The window that was next to our in the chain is being removed. 100 * Relink to the new next window. */ 101 pWinCtx->hWndNextInChain = hWndNext; 102 } 103 else 104 { 105 if (pWinCtx->hWndNextInChain) 106 { 107 /* Pass the message further. */ 108 DWORD_PTR dwResult; 109 rc = SendMessageTimeout(pWinCtx->hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, 110 VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, &dwResult); 111 if (!rc) 112 rc = (LRESULT)dwResult; 113 } 114 } 115 } 116 break; 115 117 116 118 case WM_DRAWCLIPBOARD: 117 119 { 118 LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pWinCtx->hWnd)); 119 120 if (GetClipboardOwner() != hwnd) 121 { 122 /* Clipboard was updated by another application. */ 123 /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */ 124 uint32_t uFormats; 125 int vboxrc = VBoxClipboardWinGetFormats(pWinCtx, &uFormats); 126 if (RT_SUCCESS(vboxrc)) 127 vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats); 128 } 129 130 if (pWinCtx->hWndNextInChain) 131 { 132 /* Pass the message to next windows in the clipboard chain. */ 133 SendMessageTimeout(pWinCtx->hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, NULL); 134 } 135 } break; 120 LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pWinCtx->hWnd)); 121 122 if (GetClipboardOwner() != hwnd) 123 { 124 /* Clipboard was updated by another application. */ 125 /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */ 126 uint32_t uFormats; 127 int vboxrc = VBoxClipboardWinGetFormats(pWinCtx, &uFormats); 128 if (RT_SUCCESS(vboxrc)) 129 vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats); 130 } 131 132 if (pWinCtx->hWndNextInChain) 133 { 134 /* Pass the message to next windows in the clipboard chain. */ 135 SendMessageTimeout(pWinCtx->hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, NULL); 136 } 137 } 138 break; 136 139 137 140 case WM_TIMER: 138 141 { 139 if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) 140 break; 141 142 HWND hViewer = GetClipboardViewer(); 143 144 /* Re-register ourselves in the clipboard chain if our last ping 145 * timed out or there seems to be no valid chain. */ 146 if (!hViewer || pWinCtx->oldAPI.fCBChainPingInProcess) 147 { 148 VBoxClipboardWinRemoveFromCBChain(pWinCtx); 149 VBoxClipboardWinAddToCBChain(pWinCtx); 150 } 151 152 /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be 153 * processed by ourselves to the chain. */ 154 pWinCtx->oldAPI.fCBChainPingInProcess = TRUE; 155 156 hViewer = GetClipboardViewer(); 157 if (hViewer) 158 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pWinCtx->hWndNextInChain, (LPARAM)pWinCtx->hWndNextInChain, 159 VBoxClipboardWinChainPingProc, (ULONG_PTR)pWinCtx); 160 } break; 142 if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) 143 break; 144 145 HWND hViewer = GetClipboardViewer(); 146 147 /* Re-register ourselves in the clipboard chain if our last ping 148 * timed out or there seems to be no valid chain. */ 149 if (!hViewer || pWinCtx->oldAPI.fCBChainPingInProcess) 150 { 151 VBoxClipboardWinRemoveFromCBChain(pWinCtx); 152 VBoxClipboardWinAddToCBChain(pWinCtx); 153 } 154 155 /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be 156 * processed by ourselves to the chain. */ 157 pWinCtx->oldAPI.fCBChainPingInProcess = TRUE; 158 159 hViewer = GetClipboardViewer(); 160 if (hViewer) 161 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pWinCtx->hWndNextInChain, (LPARAM)pWinCtx->hWndNextInChain, 162 VBoxClipboardWinChainPingProc, (ULONG_PTR)pWinCtx); 163 } 164 break; 161 165 162 166 case WM_CLOSE: 163 167 { 164 /* Do nothing. Ignore the message. */ 165 } break; 168 /* Do nothing. Ignore the message. */ 169 } 170 break; 166 171 167 172 case WM_RENDERFORMAT: 168 173 { 169 /* Insert the requested clipboard format data into the clipboard. */ 170 uint32_t u32Format = 0; 171 UINT format = (UINT)wParam; 172 173 LogFlowFunc(("WM_RENDERFORMAT, format = %x\n", format)); 174 switch (format) 175 { 176 case CF_UNICODETEXT: 177 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; 178 break; 179 180 case CF_DIB: 181 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP; 182 break; 183 184 default: 185 if (format >= 0xC000) 186 { 187 TCHAR szFormatName[256]; 188 189 int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR)); 190 if (cActual) 191 { 192 if (strcmp (szFormatName, "HTML Format") == 0) 193 { 194 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML; 195 } 196 } 197 } 198 break; 199 } 200 201 if (u32Format == 0) 202 { 203 /* Unsupported clipboard format is requested. */ 204 LogFlowFunc(("Unsupported clipboard format requested: %ld\n", u32Format)); 205 VBoxClipboardWinClear(); 206 } 207 else 208 { 209 const uint32_t cbPrealloc = 4096; /** @todo r=andy Make it dynamic for supporting larger text buffers! */ 210 uint32_t cb = 0; 211 212 /* Preallocate a buffer, most of small text transfers will fit into it. */ 213 HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc); 214 LogFlowFunc(("Preallocated handle hMem = %p\n", hMem)); 215 216 if (hMem) 217 { 218 void *pMem = GlobalLock(hMem); 219 LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem))); 220 221 if (pMem) 222 { 223 /* Read the host data to the preallocated buffer. */ 224 int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cbPrealloc, &cb); 225 LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n", vboxrc)); 226 227 if (RT_SUCCESS(vboxrc)) 228 { 229 if (cb == 0) 230 { 231 /* 0 bytes returned means the clipboard is empty. 232 * Deallocate the memory and set hMem to NULL to get to 233 * the clipboard empty code path. */ 234 GlobalUnlock(hMem); 235 GlobalFree(hMem); 236 hMem = NULL; 237 } 238 else if (cb > cbPrealloc) 239 { 240 GlobalUnlock(hMem); 241 242 /* The preallocated buffer is too small, adjust the size. */ 243 hMem = GlobalReAlloc(hMem, cb, 0); 244 LogFlowFunc(("Reallocated hMem = %p\n", hMem)); 245 246 if (hMem) 247 { 248 pMem = GlobalLock(hMem); 249 LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem))); 250 251 if (pMem) 252 { 253 /* Read the host data to the preallocated buffer. */ 254 uint32_t cbNew = 0; 255 vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cb, &cbNew); 256 LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n", vboxrc, cb, cbNew)); 257 258 if (RT_SUCCESS (vboxrc) && cbNew <= cb) 259 { 260 cb = cbNew; 261 } 262 else 263 { 264 GlobalUnlock(hMem); 265 GlobalFree(hMem); 266 hMem = NULL; 267 } 268 } 269 else 270 { 271 GlobalFree(hMem); 272 hMem = NULL; 273 } 274 } 275 } 276 277 if (hMem) 278 { 279 /* pMem is the address of the data. cb is the size of returned data. */ 280 /* Verify the size of returned text, the memory block for clipboard 281 * must have the exact string size. 282 */ 283 if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 284 { 285 size_t cbActual = 0; 286 HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual); 287 if (FAILED (hrc)) 288 { 289 /* Discard invalid data. */ 290 GlobalUnlock(hMem); 291 GlobalFree(hMem); 292 hMem = NULL; 293 } 294 else 295 { 296 /* cbActual is the number of bytes, excluding those used 297 * for the terminating null character. 298 */ 299 cb = (uint32_t)(cbActual + 2); 300 } 301 } 302 } 303 304 if (hMem) 305 { 306 GlobalUnlock(hMem); 307 308 hMem = GlobalReAlloc(hMem, cb, 0); 309 LogFlowFunc(("Reallocated hMem = %p\n", hMem)); 310 311 if (hMem) 312 { 313 /* 'hMem' contains the host clipboard data. 314 * size is 'cb' and format is 'format'. */ 315 HANDLE hClip = SetClipboardData(format, hMem); 316 LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip)); 317 318 if (hClip) 319 { 320 /* The hMem ownership has gone to the system. Finish the processing. */ 321 break; 322 } 323 324 /* Cleanup follows. */ 325 } 326 } 327 } 328 if (hMem) 329 GlobalUnlock(hMem); 330 } 331 if (hMem) 332 GlobalFree(hMem); 333 } 334 335 /* Something went wrong. */ 336 VBoxClipboardWinClear(); 337 } 338 } break; 174 /* Insert the requested clipboard format data into the clipboard. */ 175 uint32_t u32Format = 0; 176 UINT format = (UINT)wParam; 177 178 LogFlowFunc(("WM_RENDERFORMAT, format = %x\n", format)); 179 switch (format) 180 { 181 case CF_UNICODETEXT: 182 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; 183 break; 184 185 case CF_DIB: 186 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP; 187 break; 188 189 default: 190 if (format >= 0xC000) 191 { 192 TCHAR szFormatName[256]; 193 194 int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName) / sizeof(TCHAR)); 195 if (cActual) 196 { 197 if (strcmp(szFormatName, "HTML Format") == 0) 198 { 199 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML; 200 } 201 } 202 } 203 break; 204 } 205 206 if (u32Format == 0) 207 { 208 /* Unsupported clipboard format is requested. */ 209 LogFlowFunc(("Unsupported clipboard format requested: %ld\n", u32Format)); 210 VBoxClipboardWinClear(); 211 } 212 else 213 { 214 const uint32_t cbPrealloc = 4096; /** @todo r=andy Make it dynamic for supporting larger text buffers! */ 215 uint32_t cb = 0; 216 217 /* Preallocate a buffer, most of small text transfers will fit into it. */ 218 HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc); 219 LogFlowFunc(("Preallocated handle hMem = %p\n", hMem)); 220 221 if (hMem) 222 { 223 void *pMem = GlobalLock(hMem); 224 LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem))); 225 226 if (pMem) 227 { 228 /* Read the host data to the preallocated buffer. */ 229 int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cbPrealloc, &cb); 230 LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n", vboxrc)); 231 232 if (RT_SUCCESS(vboxrc)) 233 { 234 if (cb == 0) 235 { 236 /* 0 bytes returned means the clipboard is empty. 237 * Deallocate the memory and set hMem to NULL to get to 238 * the clipboard empty code path. */ 239 GlobalUnlock(hMem); 240 GlobalFree(hMem); 241 hMem = NULL; 242 } 243 else if (cb > cbPrealloc) 244 { 245 GlobalUnlock(hMem); 246 247 /* The preallocated buffer is too small, adjust the size. */ 248 hMem = GlobalReAlloc(hMem, cb, 0); 249 LogFlowFunc(("Reallocated hMem = %p\n", hMem)); 250 251 if (hMem) 252 { 253 pMem = GlobalLock(hMem); 254 LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem))); 255 256 if (pMem) 257 { 258 /* Read the host data to the preallocated buffer. */ 259 uint32_t cbNew = 0; 260 vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cb, &cbNew); 261 LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n", vboxrc, cb, cbNew)); 262 263 if (RT_SUCCESS(vboxrc) && cbNew <= cb) 264 { 265 cb = cbNew; 266 } 267 else 268 { 269 GlobalUnlock(hMem); 270 GlobalFree(hMem); 271 hMem = NULL; 272 } 273 } 274 else 275 { 276 GlobalFree(hMem); 277 hMem = NULL; 278 } 279 } 280 } 281 282 if (hMem) 283 { 284 /* pMem is the address of the data. cb is the size of returned data. */ 285 /* Verify the size of returned text, the memory block for clipboard 286 * must have the exact string size. 287 */ 288 if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 289 { 290 size_t cbActual = 0; 291 HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual); 292 if (FAILED(hrc)) 293 { 294 /* Discard invalid data. */ 295 GlobalUnlock(hMem); 296 GlobalFree(hMem); 297 hMem = NULL; 298 } 299 else 300 { 301 /* cbActual is the number of bytes, excluding those used 302 * for the terminating null character. 303 */ 304 cb = (uint32_t)(cbActual + 2); 305 } 306 } 307 } 308 309 if (hMem) 310 { 311 GlobalUnlock(hMem); 312 313 hMem = GlobalReAlloc(hMem, cb, 0); 314 LogFlowFunc(("Reallocated hMem = %p\n", hMem)); 315 316 if (hMem) 317 { 318 /* 'hMem' contains the host clipboard data. 319 * size is 'cb' and format is 'format'. */ 320 HANDLE hClip = SetClipboardData(format, hMem); 321 LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip)); 322 323 if (hClip) 324 { 325 /* The hMem ownership has gone to the system. Finish the processing. */ 326 break; 327 } 328 329 /* Cleanup follows. */ 330 } 331 } 332 } 333 if (hMem) 334 GlobalUnlock(hMem); 335 } 336 if (hMem) 337 GlobalFree(hMem); 338 } 339 340 /* Something went wrong. */ 341 VBoxClipboardWinClear(); 342 } 343 } 344 break; 339 345 340 346 case WM_RENDERALLFORMATS: 341 347 { 342 /* Do nothing. The clipboard formats will be unavailable now, because the 343 * windows is to be destroyed and therefore the guest side becomes inactive. 344 */ 345 int vboxrc = VBoxClipboardWinOpen(hwnd); 346 if (RT_SUCCESS(vboxrc)) 347 { 348 VBoxClipboardWinClear(); 349 VBoxClipboardWinClose(); 350 } 351 } break; 348 /* Do nothing. The clipboard formats will be unavailable now, because the 349 * windows is to be destroyed and therefore the guest side becomes inactive. 350 */ 351 int vboxrc = VBoxClipboardWinOpen(hwnd); 352 if (RT_SUCCESS(vboxrc)) 353 { 354 VBoxClipboardWinClear(); 355 VBoxClipboardWinClose(); 356 } 357 } 358 break; 352 359 353 360 case VBOX_CLIPBOARD_WM_SET_FORMATS: 354 361 { 355 /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */ 356 uint32_t u32Formats = (uint32_t)lParam; 357 358 LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: u32Formats=0x%x\n", u32Formats)); 359 360 int vboxrc = VBoxClipboardWinOpen(hwnd); 361 if (RT_SUCCESS(vboxrc)) 362 { 363 VBoxClipboardWinClear(); 364 365 HANDLE hClip = NULL; 366 367 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 368 hClip = SetClipboardData(CF_UNICODETEXT, NULL); 369 370 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 371 hClip = SetClipboardData(CF_DIB, NULL); 372 373 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML) 374 { 375 UINT format = RegisterClipboardFormat ("HTML Format"); 376 if (format != 0) 377 hClip = SetClipboardData(format, NULL); 378 } 379 380 VBoxClipboardWinClose(); 381 382 LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: hClip=%p, lastErr=%ld\n", hClip, GetLastError())); 383 } 384 } break; 362 /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */ 363 uint32_t u32Formats = (uint32_t)lParam; 364 365 LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: u32Formats=0x%x\n", u32Formats)); 366 367 int vboxrc = VBoxClipboardWinOpen(hwnd); 368 if (RT_SUCCESS(vboxrc)) 369 { 370 VBoxClipboardWinClear(); 371 372 HANDLE hClip = NULL; 373 374 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 375 hClip = SetClipboardData(CF_UNICODETEXT, NULL); 376 377 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 378 hClip = SetClipboardData(CF_DIB, NULL); 379 380 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML) 381 { 382 UINT format = RegisterClipboardFormat("HTML Format"); 383 if (format != 0) 384 hClip = SetClipboardData(format, NULL); 385 } 386 387 VBoxClipboardWinClose(); 388 389 LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: hClip=%p, lastErr=%ld\n", hClip, GetLastError())); 390 } 391 } 392 break; 385 393 386 394 case VBOX_CLIPBOARD_WM_READ_DATA: 387 395 { 388 /* Send data in the specified format to the host. */ 389 uint32_t u32Formats = (uint32_t)lParam; 390 HANDLE hClip = NULL; 391 392 LogFlowFunc(("VBOX_WM_SHCLPB_READ_DATA: u32Formats=0x%x\n", u32Formats)); 393 394 int vboxrc = VBoxClipboardWinOpen(hwnd); 395 if (RT_SUCCESS(vboxrc)) 396 { 397 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 398 { 399 hClip = GetClipboardData(CF_DIB); 400 401 if (hClip != NULL) 402 { 403 LPVOID lp = GlobalLock(hClip); 404 if (lp != NULL) 405 { 406 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_BITMAP, 407 lp, GlobalSize(hClip)); 408 GlobalUnlock(hClip); 409 } 410 else 411 { 412 hClip = NULL; 413 } 414 } 415 } 416 else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 417 { 418 hClip = GetClipboardData(CF_UNICODETEXT); 419 420 if (hClip != NULL) 421 { 422 LPWSTR uniString = (LPWSTR)GlobalLock(hClip); 423 424 if (uniString != NULL) 425 { 426 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, 427 uniString, (lstrlenW(uniString) + 1) * 2); 428 GlobalUnlock(hClip); 429 } 430 else 431 { 432 hClip = NULL; 433 } 434 } 435 } 436 else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML) 437 { 438 UINT format = RegisterClipboardFormat ("HTML Format"); 439 if (format != 0) 440 { 441 hClip = GetClipboardData(format); 442 if (hClip != NULL) 443 { 444 LPVOID lp = GlobalLock(hClip); 445 446 if (lp != NULL) 447 { 448 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_HTML, 449 lp, GlobalSize(hClip)); 450 GlobalUnlock(hClip); 451 } 452 else 453 { 454 hClip = NULL; 455 } 456 } 457 } 458 } 459 460 VBoxClipboardWinClose(); 461 } 462 463 if (hClip == NULL) 464 { 465 /* Requested clipboard format is not available, send empty data. */ 466 VbglR3ClipboardWriteData(pCtx->u32ClientID, 0, NULL, 0); 467 } 468 } break; 396 /* Send data in the specified format to the host. */ 397 uint32_t u32Formats = (uint32_t)lParam; 398 HANDLE hClip = NULL; 399 400 LogFlowFunc(("VBOX_WM_SHCLPB_READ_DATA: u32Formats=0x%x\n", u32Formats)); 401 402 int vboxrc = VBoxClipboardWinOpen(hwnd); 403 if (RT_SUCCESS(vboxrc)) 404 { 405 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 406 { 407 hClip = GetClipboardData(CF_DIB); 408 409 if (hClip != NULL) 410 { 411 LPVOID lp = GlobalLock(hClip); 412 if (lp != NULL) 413 { 414 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_BITMAP, 415 lp, GlobalSize(hClip)); 416 GlobalUnlock(hClip); 417 } 418 else 419 { 420 hClip = NULL; 421 } 422 } 423 } 424 else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 425 { 426 hClip = GetClipboardData(CF_UNICODETEXT); 427 428 if (hClip != NULL) 429 { 430 LPWSTR uniString = (LPWSTR)GlobalLock(hClip); 431 432 if (uniString != NULL) 433 { 434 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, 435 uniString, (lstrlenW(uniString) + 1) * 2); 436 GlobalUnlock(hClip); 437 } 438 else 439 { 440 hClip = NULL; 441 } 442 } 443 } 444 else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML) 445 { 446 UINT format = RegisterClipboardFormat("HTML Format"); 447 if (format != 0) 448 { 449 hClip = GetClipboardData(format); 450 if (hClip != NULL) 451 { 452 LPVOID lp = GlobalLock(hClip); 453 454 if (lp != NULL) 455 { 456 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_HTML, 457 lp, GlobalSize(hClip)); 458 GlobalUnlock(hClip); 459 } 460 else 461 { 462 hClip = NULL; 463 } 464 } 465 } 466 } 467 468 VBoxClipboardWinClose(); 469 } 470 471 if (hClip == NULL) 472 { 473 /* Requested clipboard format is not available, send empty data. */ 474 VbglR3ClipboardWriteData(pCtx->u32ClientID, 0, NULL, 0); 475 } 476 } 477 break; 469 478 470 479 case WM_DESTROY: 471 480 { 472 VBoxClipboardWinRemoveFromCBChain(pWinCtx); 473 if (pWinCtx->oldAPI.timerRefresh) 474 KillTimer(pWinCtx->hWnd, 0); 475 /* 476 * don't need to call PostQuitMessage cause 477 * the VBoxTray already finished a message loop 478 */ 479 } break; 481 VBoxClipboardWinRemoveFromCBChain(pWinCtx); 482 if (pWinCtx->oldAPI.timerRefresh) 483 KillTimer(pWinCtx->hWnd, 0); 484 /* 485 * don't need to call PostQuitMessage cause 486 * the VBoxTray already finished a message loop 487 */ 488 } 489 break; 480 490 481 491 default: 482 492 { 483 rc = DefWindowProc(hwnd, msg, wParam, lParam); 484 } 493 rc = DefWindowProc(hwnd, msg, wParam, lParam); 494 } 495 break; 485 496 } 486 497 … … 660 671 switch (u32Msg) 661 672 { 662 case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS: 663 { 664 /* The host has announced available clipboard formats. 665 * Forward the information to the window, so it can later 666 * respond to WM_RENDERFORMAT message. */ 667 ::PostMessage(pWinCtx->hWnd, VBOX_CLIPBOARD_WM_SET_FORMATS, 0, u32Formats); 668 } break; 669 670 case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA: 671 { 672 /* The host needs data in the specified format. */ 673 ::PostMessage(pWinCtx->hWnd, VBOX_CLIPBOARD_WM_READ_DATA, 0, u32Formats); 674 } break; 675 676 case VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT: 677 { 678 /* The host is terminating. */ 679 LogRel(("Clipboard: Terminating ...\n")); 680 ASMAtomicXchgBool(pfShutdown, true); 681 } break; 682 683 default: 684 { 685 LogFlowFunc(("Unsupported message from host, message=%RU32\n", u32Msg)); 686 687 /* Wait a bit before retrying. */ 688 RTThreadSleep(1000); 689 } break; 673 case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS: 674 { 675 /* The host has announced available clipboard formats. 676 * Forward the information to the window, so it can later 677 * respond to WM_RENDERFORMAT message. */ 678 ::PostMessage(pWinCtx->hWnd, VBOX_CLIPBOARD_WM_SET_FORMATS, 0, u32Formats); 679 } 680 break; 681 682 case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA: 683 { 684 /* The host needs data in the specified format. */ 685 ::PostMessage(pWinCtx->hWnd, VBOX_CLIPBOARD_WM_READ_DATA, 0, u32Formats); 686 } 687 break; 688 689 case VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT: 690 { 691 /* The host is terminating. */ 692 LogRel(("Clipboard: Terminating ...\n")); 693 ASMAtomicXchgBool(pfShutdown, true); 694 } 695 break; 696 697 default: 698 { 699 LogFlowFunc(("Unsupported message from host, message=%RU32\n", u32Msg)); 700 701 /* Wait a bit before retrying. */ 702 RTThreadSleep(1000); 703 } 704 break; 690 705 } 691 706 } -
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp
r78151 r78171 134 134 if (RT_SUCCESS(rc)) 135 135 { 136 rc = RTLdrGetSymbol(hUser32, "AddClipboardFormatListener", (void **)&pAPI->pfnAddClipboardFormatListener);136 rc = RTLdrGetSymbol(hUser32, "AddClipboardFormatListener", (void **)&pAPI->pfnAddClipboardFormatListener); 137 137 if (RT_SUCCESS(rc)) 138 138 { 139 rc = RTLdrGetSymbol(hUser32, "RemoveClipboardFormatListener", (void **)&pAPI->pfnRemoveClipboardFormatListener);139 rc = RTLdrGetSymbol(hUser32, "RemoveClipboardFormatListener", (void **)&pAPI->pfnRemoveClipboardFormatListener); 140 140 } 141 141 -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp
r78170 r78171 103 103 } 104 104 #else /* !LOG_ENABLED */ 105 # define vboxClipboardDump(__pv, __cb, __format) do { NOREF(__pv); NOREF(__cb); NOREF(__format); } while (0)105 # define vboxClipboardDump(__pv, __cb, __format) do { NOREF(__pv); NOREF(__cb); NOREF(__format); } while (0) 106 106 #endif /* !LOG_ENABLED */ 107 107 108 108 /** @todo Someone please explain the protocol wrt overflows... */ 109 static void vboxClipboardGetData 110 109 static void vboxClipboardGetData(uint32_t u32Format, const void *pvSrc, uint32_t cbSrc, 110 void *pvDst, uint32_t cbDst, uint32_t *pcbActualDst) 111 111 { 112 112 LogFlow(("vboxClipboardGetData cbSrc = %d, cbDst = %d\n", cbSrc, cbDst)); 113 113 114 if ( 114 if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_HTML 115 115 && IsWindowsHTML((const char *)pvSrc)) 116 116 { … … 118 118 char *pszBuf = NULL; 119 119 uint32_t cbBuf = 0; 120 int rc = ConvertCFHtmlToMime((const char *)pvSrc, cbSrc, &pszBuf, &cbBuf);120 int rc = ConvertCFHtmlToMime((const char *)pvSrc, cbSrc, &pszBuf, &cbBuf); 121 121 if (RT_SUCCESS(rc)) 122 122 { … … 152 152 } 153 153 154 static int vboxClipboardReadDataFromClient 154 static int vboxClipboardReadDataFromClient(VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Format) 155 155 { 156 156 Assert(pCtx->pClient); … … 160 160 LogFlow(("vboxClipboardReadDataFromClient u32Format = %02X\n", u32Format)); 161 161 162 ResetEvent 163 164 vboxSvcClipboardReportMsg 162 ResetEvent(pCtx->hRenderEvent); 163 164 vboxSvcClipboardReportMsg(pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA, u32Format); 165 165 166 166 DWORD ret = WaitForSingleObject(pCtx->hRenderEvent, INFINITE); … … 475 475 } 476 476 477 DECLCALLBACK(int) VBoxClipboardThread 477 DECLCALLBACK(int) VBoxClipboardThread(RTTHREAD hThreadSelf, void *pvUser) 478 478 { 479 479 RT_NOREF2(hThreadSelf, pvUser); … … 508 508 { 509 509 /* Create the window. */ 510 pWinCtx->hWnd = CreateWindowEx 511 512 513 510 pWinCtx->hWnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST, 511 s_szClipWndClassName, s_szClipWndClassName, 512 WS_POPUPWINDOW, 513 -200, -200, 100, 100, NULL, NULL, hInstance, NULL); 514 514 if (pWinCtx->hWnd == NULL) 515 515 { … … 547 547 if (atomWindowClass != 0) 548 548 { 549 UnregisterClass 549 UnregisterClass(s_szClipWndClassName, hInstance); 550 550 atomWindowClass = 0; 551 551 } … … 579 579 * Public platform dependent functions. 580 580 */ 581 int vboxClipboardInit 581 int vboxClipboardInit(void) 582 582 { 583 583 int rc = VINF_SUCCESS; … … 590 590 g_ctx.hRenderEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 591 591 592 rc = RTThreadCreate 593 594 595 if (RT_FAILURE 596 { 597 CloseHandle 592 rc = RTThreadCreate(&g_ctx.hThread, VBoxClipboardThread, NULL, 65536, 593 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLIP"); 594 595 if (RT_FAILURE(rc)) 596 { 597 CloseHandle(g_ctx.hRenderEvent); 598 598 } 599 599 … … 601 601 } 602 602 603 void vboxClipboardDestroy 603 void vboxClipboardDestroy(void) 604 604 { 605 605 Log(("vboxClipboardDestroy\n")); … … 607 607 if (g_ctx.Win.hWnd) 608 608 { 609 PostMessage 610 } 611 612 CloseHandle 609 PostMessage(g_ctx.Win.hWnd, WM_CLOSE, 0, 0); 610 } 611 612 CloseHandle(g_ctx.hRenderEvent); 613 613 614 614 /* Wait for the window thread to terminate. */ 615 RTThreadWait 615 RTThreadWait(g_ctx.hThread, RT_INDEFINITE_WAIT, NULL); 616 616 617 617 g_ctx.hThread = NIL_RTTHREAD; 618 618 } 619 619 620 int vboxClipboardConnect 620 int vboxClipboardConnect(VBOXCLIPBOARDCLIENTDATA *pClient, bool fHeadless) 621 621 { 622 622 NOREF(fHeadless); … … 634 634 635 635 /* Sync the host clipboard content with the client. */ 636 vboxClipboardSync 636 vboxClipboardSync(pClient); 637 637 638 638 return VINF_SUCCESS; 639 639 } 640 640 641 int vboxClipboardSync 641 int vboxClipboardSync(VBOXCLIPBOARDCLIENTDATA *pClient) 642 642 { 643 643 /* Sync the host clipboard content with the client. */ … … 645 645 } 646 646 647 void vboxClipboardDisconnect 647 void vboxClipboardDisconnect(VBOXCLIPBOARDCLIENTDATA *pClient) 648 648 { 649 649 RT_NOREF1(pClient); … … 653 653 } 654 654 655 void vboxClipboardFormatAnnounce 655 void vboxClipboardFormatAnnounce(VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Formats) 656 656 { 657 657 AssertPtrReturnVoid(pClient); … … 661 661 * The guest announces formats. Forward to the window thread. 662 662 */ 663 PostMessage 663 PostMessage(pClient->pCtx->Win.hWnd, WM_USER, 0, u32Formats); 664 664 } 665 665 … … 694 694 } 695 695 696 int vboxClipboardReadData 696 int vboxClipboardReadData(VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Format, void *pv, uint32_t cb, uint32_t *pcbActual) 697 697 { 698 698 AssertPtrReturn(pClient, VERR_INVALID_POINTER); … … 715 715 if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 716 716 { 717 hClip = GetClipboardData 717 hClip = GetClipboardData(CF_DIB); 718 718 719 719 if (hClip != NULL) 720 720 { 721 LPVOID lp = GlobalLock 721 LPVOID lp = GlobalLock(hClip); 722 722 723 723 if (lp != NULL) … … 725 725 LogFunc(("CF_DIB\n")); 726 726 727 vboxClipboardGetData (VBOX_SHARED_CLIPBOARD_FMT_BITMAP, lp, GlobalSize(hClip),728 727 vboxClipboardGetData(VBOX_SHARED_CLIPBOARD_FMT_BITMAP, lp, GlobalSize(hClip), 728 pv, cb, pcbActual); 729 729 730 730 GlobalUnlock(hClip); … … 742 742 if (hClip != NULL) 743 743 { 744 LPWSTR uniString = (LPWSTR)GlobalLock 744 LPWSTR uniString = (LPWSTR)GlobalLock(hClip); 745 745 746 746 if (uniString != NULL) … … 748 748 LogFunc(("CF_UNICODETEXT\n")); 749 749 750 vboxClipboardGetData (VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, uniString, (lstrlenW(uniString) + 1) * 2,751 750 vboxClipboardGetData(VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, uniString, (lstrlenW(uniString) + 1) * 2, 751 pv, cb, pcbActual); 752 752 753 753 GlobalUnlock(hClip); … … 761 761 else if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_HTML) 762 762 { 763 UINT format = RegisterClipboardFormat 763 UINT format = RegisterClipboardFormat("HTML Format"); 764 764 765 765 if (format != 0) 766 766 { 767 hClip = GetClipboardData 767 hClip = GetClipboardData(format); 768 768 769 769 if (hClip != NULL) 770 770 { 771 LPVOID lp = GlobalLock 771 LPVOID lp = GlobalLock(hClip); 772 772 773 773 if (lp != NULL) … … 775 775 LogFunc(("CF_HTML\n")); 776 776 777 vboxClipboardGetData (VBOX_SHARED_CLIPBOARD_FMT_HTML, lp, GlobalSize(hClip),778 777 vboxClipboardGetData(VBOX_SHARED_CLIPBOARD_FMT_HTML, lp, GlobalSize(hClip), 778 pv, cb, pcbActual); 779 779 LogRelFlowFunc(("Raw HTML clipboard data from host :")); 780 DumpHtml((char *)pv, cb);780 DumpHtml((char *)pv, cb); 781 781 GlobalUnlock(hClip); 782 782 } … … 799 799 { 800 800 /* Reply with empty data. */ 801 vboxClipboardGetData 802 801 vboxClipboardGetData(0, NULL, 0, 802 pv, cb, pcbActual); 803 803 } 804 804 … … 806 806 } 807 807 808 void vboxClipboardWriteData 808 void vboxClipboardWriteData(VBOXCLIPBOARDCLIENTDATA *pClient, void *pv, uint32_t cb, uint32_t u32Format) 809 809 { 810 810 LogFlow(("vboxClipboardWriteData\n")); … … 888 888 static bool IsWindowsHTML(const char *pszSource) 889 889 { 890 return RTStrStr(pszSource, "Version:") != NULL891 && RTStrStr(pszSource, "StartHTML:") != NULL;890 return RTStrStr(pszSource, "Version:") != NULL 891 && RTStrStr(pszSource, "StartHTML:") != NULL; 892 892 } 893 893 … … 1037 1037 /* 166+2: */ "</html>\r\n"; 1038 1038 /* 175+2: */ 1039 AssertCompile(sizeof(s_szFormatSample) == 175 +2+1);1039 AssertCompile(sizeof(s_szFormatSample) == 175 + 2 + 1); 1040 1040 1041 1041 /* calculate parameters of CF_HTML header */ -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp
r78164 r78171 110 110 111 111 112 static void VBoxHGCMParmUInt32Set 112 static void VBoxHGCMParmUInt32Set(VBOXHGCMSVCPARM *pParm, uint32_t u32) 113 113 { 114 114 pParm->type = VBOX_HGCM_SVC_PARM_32BIT; … … 116 116 } 117 117 118 static int VBoxHGCMParmUInt32Get 118 static int VBoxHGCMParmUInt32Get(VBOXHGCMSVCPARM *pParm, uint32_t *pu32) 119 119 { 120 120 if (pParm->type == VBOX_HGCM_SVC_PARM_32BIT) … … 136 136 #endif 137 137 138 static int VBoxHGCMParmPtrGet 138 static int VBoxHGCMParmPtrGet(VBOXHGCMSVCPARM *pParm, void **ppv, uint32_t *pcb) 139 139 { 140 140 if (pParm->type == VBOX_HGCM_SVC_PARM_PTR) … … 149 149 150 150 151 static uint32_t vboxSvcClipboardMode 151 static uint32_t vboxSvcClipboardMode(void) 152 152 { 153 153 return g_u32Mode; … … 168 168 } 169 169 170 static void vboxSvcClipboardModeSet 170 static void vboxSvcClipboardModeSet(uint32_t u32Mode) 171 171 { 172 172 switch (u32Mode) … … 186 186 bool VBoxSvcClipboardLock(void) 187 187 { 188 return RT_SUCCESS(RTCritSectEnter 188 return RT_SUCCESS(RTCritSectEnter(&critsect)); 189 189 } 190 190 … … 197 197 * Executed under the clipboard lock. 198 198 */ 199 static bool vboxSvcClipboardReturnMsg 199 static bool vboxSvcClipboardReturnMsg(VBOXCLIPBOARDCLIENTDATA *pClient, VBOXHGCMSVCPARM paParms[]) 200 200 { 201 201 /* Message priority is taken into account. */ … … 203 203 { 204 204 LogRelFlow(("vboxSvcClipboardReturnMsg: Quit\n")); 205 VBoxHGCMParmUInt32Set 206 VBoxHGCMParmUInt32Set 205 VBoxHGCMParmUInt32Set(&paParms[0], VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT); 206 VBoxHGCMParmUInt32Set(&paParms[1], 0); 207 207 pClient->fMsgQuit = false; 208 208 } … … 221 221 AssertStmt(pClient->u32RequestedFormat == 0, pClient->u32RequestedFormat = 0); 222 222 pClient->u32RequestedFormat &= ~fFormat; 223 VBoxHGCMParmUInt32Set 224 VBoxHGCMParmUInt32Set 223 VBoxHGCMParmUInt32Set(&paParms[0], VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA); 224 VBoxHGCMParmUInt32Set(&paParms[1], fFormat); 225 225 if (pClient->u32RequestedFormat == 0) 226 226 pClient->fMsgReadData = false; … … 229 229 { 230 230 LogRelFlow(("vboxSvcClipboardReturnMsg: Formats %02X\n", pClient->u32AvailableFormats)); 231 VBoxHGCMParmUInt32Set 232 VBoxHGCMParmUInt32Set 231 VBoxHGCMParmUInt32Set(&paParms[0], VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS); 232 VBoxHGCMParmUInt32Set(&paParms[1], pClient->u32AvailableFormats); 233 233 pClient->fMsgFormats = false; 234 234 } … … 244 244 } 245 245 246 void vboxSvcClipboardReportMsg 246 void vboxSvcClipboardReportMsg(VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Msg, uint32_t u32Formats) 247 247 { 248 248 AssertPtrReturnVoid(pClient); … … 293 293 { 294 294 /* The client waits for a response. */ 295 bool fMessageReturned = vboxSvcClipboardReturnMsg 295 bool fMessageReturned = vboxSvcClipboardReturnMsg(pClient, pClient->async.paParms); 296 296 297 297 /* Make a copy of the handle. */ … … 309 309 { 310 310 LogRelFlow(("vboxSvcClipboardReportMsg: CallComplete\n")); 311 g_pHelpers->pfnCallComplete 311 g_pHelpers->pfnCallComplete(callHandle, VINF_SUCCESS); 312 312 } 313 313 } … … 319 319 } 320 320 321 static int svcInit 322 { 323 int rc = RTCritSectInit 324 325 if (RT_SUCCESS 326 { 327 vboxSvcClipboardModeSet 328 329 rc = vboxClipboardInit 321 static int svcInit(void) 322 { 323 int rc = RTCritSectInit(&critsect); 324 325 if (RT_SUCCESS(rc)) 326 { 327 vboxSvcClipboardModeSet(VBOX_SHARED_CLIPBOARD_MODE_OFF); 328 329 rc = vboxClipboardInit(); 330 330 331 331 /* Clean up on failure, because 'svnUnload' will not be called 332 332 * if the 'svcInit' returns an error. 333 333 */ 334 if (RT_FAILURE 335 { 336 RTCritSectDelete 334 if (RT_FAILURE(rc)) 335 { 336 RTCritSectDelete(&critsect); 337 337 } 338 338 } … … 341 341 } 342 342 343 static DECLCALLBACK(int) svcUnload 344 { 345 vboxClipboardDestroy 346 RTCritSectDelete 343 static DECLCALLBACK(int) svcUnload(void *) 344 { 345 vboxClipboardDestroy(); 346 RTCritSectDelete(&critsect); 347 347 return VINF_SUCCESS; 348 348 } … … 352 352 * to the guest side. 353 353 */ 354 static DECLCALLBACK(int) svcDisconnect 354 static DECLCALLBACK(int) svcDisconnect(void *, uint32_t u32ClientID, void *pvClient) 355 355 { 356 356 VBOXCLIPBOARDCLIENTDATA *pClient = (VBOXCLIPBOARDCLIENTDATA *)pvClient; … … 358 358 LogRel2(("svcDisconnect: u32ClientID = %d\n", u32ClientID)); 359 359 360 vboxSvcClipboardReportMsg 360 vboxSvcClipboardReportMsg(pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT, 0); 361 361 362 362 vboxSvcClipboardCompleteReadData(pClient, VERR_NO_DATA, 0); 363 363 364 vboxClipboardDisconnect 365 366 memset (pClient, 0, sizeof(*pClient));364 vboxClipboardDisconnect(pClient); 365 366 memset(pClient, 0, sizeof(*pClient)); 367 367 368 368 g_pClient = NULL; … … 371 371 } 372 372 373 static DECLCALLBACK(int) svcConnect 373 static DECLCALLBACK(int) svcConnect(void *, uint32_t u32ClientID, void *pvClient, uint32_t fRequestor, bool fRestoring) 374 374 { 375 375 RT_NOREF(fRequestor, fRestoring); … … 389 389 390 390 /* Register the client. */ 391 memset (pClient, 0, sizeof(*pClient));391 memset(pClient, 0, sizeof(*pClient)); 392 392 393 393 pClient->u32ClientID = u32ClientID; 394 394 395 rc = vboxClipboardConnect 396 397 if (RT_SUCCESS 395 rc = vboxClipboardConnect(pClient, VBoxSvcClipboardGetHeadless()); 396 397 if (RT_SUCCESS(rc)) 398 398 { 399 399 g_pClient = pClient; … … 405 405 } 406 406 407 static DECLCALLBACK(void) svcCall 408 409 410 411 412 413 414 407 static DECLCALLBACK(void) svcCall(void *, 408 VBOXHGCMCALLHANDLE callHandle, 409 uint32_t u32ClientID, 410 void *pvClient, 411 uint32_t u32Function, 412 uint32_t cParms, 413 VBOXHGCMSVCPARM paParms[], 414 uint64_t tsArrival) 415 415 { 416 416 RT_NOREF_PV(tsArrival); … … 690 690 if (!fAsynchronousProcessing) 691 691 { 692 g_pHelpers->pfnCallComplete 692 g_pHelpers->pfnCallComplete(callHandle, rc); 693 693 } 694 694 } … … 712 712 if (fReadPending) 713 713 { 714 VBoxHGCMParmUInt32Set 715 g_pHelpers->pfnCallComplete 714 VBoxHGCMParmUInt32Set(&paParms[2], cbActual); 715 g_pHelpers->pfnCallComplete(callHandle, rc); 716 716 } 717 717 } … … 720 720 * We differentiate between a function handler for the guest and one for the host. 721 721 */ 722 static DECLCALLBACK(int) svcHostCall 723 724 725 722 static DECLCALLBACK(int) svcHostCall(void *, 723 uint32_t u32Function, 724 uint32_t cParms, 725 VBOXHGCMSVCPARM paParms[]) 726 726 { 727 727 int rc = VINF_SUCCESS; 728 728 729 729 LogRel2(("svcHostCall: fn = %d, cParms = %d, pparms = %d\n", 730 u32Function, cParms, paParms));730 u32Function, cParms, paParms)); 731 731 732 732 switch (u32Function) … … 802 802 * Pending requests, if any, will be completed in svcDisconnect. 803 803 */ 804 LogRel2 804 LogRel2(("svcSaveState: u32ClientID = %d\n", u32ClientID)); 805 805 806 806 VBOXCLIPBOARDCLIENTDATA *pClient = (VBOXCLIPBOARDCLIENTDATA *)pvClient; … … 808 808 /* This field used to be the length. We're using it as a version field 809 809 with the high bit set. */ 810 SSMR3PutU32 (pSSM, UINT32_C(0x80000002));811 int rc = SSMR3PutStructEx 812 AssertRCReturn 810 SSMR3PutU32(pSSM, UINT32_C(0x80000002)); 811 int rc = SSMR3PutStructEx(pSSM, pClient, sizeof(*pClient), 0 /*fFlags*/, &g_aClipboardClientDataFields[0], NULL); 812 AssertRCReturn(rc, rc); 813 813 814 814 #else /* UNIT_TEST */ … … 844 844 bool fMsgFormats: 1; 845 845 846 struct { 846 struct 847 { 847 848 VBOXHGCMCALLHANDLE callHandle; 848 849 VBOXHGCMSVCPARM *paParms; 849 850 } async; 850 851 851 struct { 852 void *pv; 853 uint32_t cb; 854 uint32_t u32Format; 852 struct 853 { 854 void *pv; 855 uint32_t cb; 856 uint32_t u32Format; 855 857 } data; 856 858 … … 864 866 #ifndef UNIT_TEST 865 867 RT_NOREF(uVersion); 866 LogRel2 868 LogRel2(("svcLoadState: u32ClientID = %d\n", u32ClientID)); 867 869 868 870 VBOXCLIPBOARDCLIENTDATA *pClient = (VBOXCLIPBOARDCLIENTDATA *)pvClient; 869 871 870 872 /* Existing client can not be in async state yet. */ 871 Assert 873 Assert(!pClient->fAsync); 872 874 873 875 /* Save the client ID for data validation. */ … … 877 879 /* Restore the client data. */ 878 880 uint32_t lenOrVer; 879 int rc = SSMR3GetU32 880 AssertRCReturn 881 if (lenOrVer == UINT32_C 882 { 883 rc = SSMR3GetStructEx 884 AssertRCReturn 885 } 886 else if (lenOrVer == (SSMR3HandleHostBits 881 int rc = SSMR3GetU32(pSSM, &lenOrVer); 882 AssertRCReturn(rc, rc); 883 if (lenOrVer == UINT32_C(0x80000002)) 884 { 885 rc = SSMR3GetStructEx(pSSM, pClient, sizeof(*pClient), 0 /*fFlags*/, &g_aClipboardClientDataFields[0], NULL); 886 AssertRCReturn(rc, rc); 887 } 888 else if (lenOrVer == (SSMR3HandleHostBits(pSSM) == 64 ? 72U : 48U)) 887 889 { 888 890 /** … … 907 909 908 910 CLIPSAVEDSTATEDATA savedState; 909 RT_ZERO 910 rc = SSMR3GetStructEx 911 912 AssertRCReturn 911 RT_ZERO(savedState); 912 rc = SSMR3GetStructEx(pSSM, &savedState, sizeof(savedState), SSMSTRUCT_FLAGS_MEM_BAND_AID, 913 &s_aClipSavedStateDataFields30[0], NULL); 914 AssertRCReturn(rc, rc); 913 915 914 916 pClient->fMsgQuit = savedState.fMsgQuit; … … 919 921 else 920 922 { 921 LogRel 923 LogRel(("Client data size mismatch: got %#x\n", lenOrVer)); 922 924 return VERR_SSM_DATA_UNIT_FORMAT_CHANGED; 923 925 } … … 926 928 if (pClient->u32ClientID != u32ClientIDOld) 927 929 { 928 LogRel 930 LogRel(("Client ID mismatch: expected %d, got %d\n", u32ClientIDOld, pClient->u32ClientID)); 929 931 pClient->u32ClientID = u32ClientIDOld; 930 932 return VERR_SSM_DATA_UNIT_FORMAT_CHANGED; … … 932 934 933 935 /* Actual host data are to be reported to guest (SYNC). */ 934 vboxClipboardSync 936 vboxClipboardSync(pClient); 935 937 936 938 #else /* UNIT_TEST*/ … … 940 942 } 941 943 942 static DECLCALLBACK(int) extCallback 944 static DECLCALLBACK(int) extCallback(uint32_t u32Function, uint32_t u32Format, void *pvData, uint32_t cbData) 943 945 { 944 946 RT_NOREF2(pvData, cbData); … … 987 989 988 990 parms.u.pfnCallback = extCallback; 989 g_pfnExtension (g_pvExtension, VBOX_CLIPBOARD_EXT_FN_SET_CALLBACK, &parms, sizeof(parms));991 g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_SET_CALLBACK, &parms, sizeof(parms)); 990 992 } 991 993 else … … 994 996 { 995 997 parms.u.pfnCallback = NULL; 996 g_pfnExtension (g_pvExtension, VBOX_CLIPBOARD_EXT_FN_SET_CALLBACK, &parms, sizeof(parms));998 g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_SET_CALLBACK, &parms, sizeof(parms)); 997 999 } 998 1000 … … 1019 1021 LogRel2(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version)); 1020 1022 1021 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)1023 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE) 1022 1024 || ptable->u32Version != VBOX_HGCM_SVC_VERSION) 1023 1025 { … … 1028 1030 g_pHelpers = ptable->pHelpers; 1029 1031 1030 ptable->cbClient = sizeof 1032 ptable->cbClient = sizeof(VBOXCLIPBOARDCLIENTDATA); 1031 1033 1032 1034 ptable->pfnUnload = svcUnload; … … 1042 1044 1043 1045 /* Service specific initialization. */ 1044 rc = svcInit 1046 rc = svcInit(); 1045 1047 } 1046 1048 } -
trunk/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardServiceHost.cpp
r78155 r78171 121 121 2, parms, 0); 122 122 RTTESTI_CHECK_RC(call.rc, VERR_TRY_AGAIN); /* This should get updated only when the guest call completes. */ 123 vboxSvcClipboardReportMsg 124 123 vboxSvcClipboardReportMsg(&g_Client, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA, 124 VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT); 125 125 RTTESTI_CHECK(parms[0].u.uint32 == VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA); 126 126 RTTESTI_CHECK(parms[1].u.uint32 == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT); … … 133 133 RTTestISub("Testing FN_GET_HOST_MSG, one format, no waiting guest calls."); 134 134 RT_ZERO(g_Client); 135 vboxSvcClipboardReportMsg 136 135 vboxSvcClipboardReportMsg(&g_Client, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA, 136 VBOX_SHARED_CLIPBOARD_FMT_HTML); 137 137 HGCMSvcSetU32(&parms[0], 0); 138 138 HGCMSvcSetU32(&parms[1], 0); … … 156 156 2, parms, 0); 157 157 RTTESTI_CHECK_RC(call.rc, VERR_TRY_AGAIN); /* This should get updated only when the guest call completes. */ 158 vboxSvcClipboardReportMsg 159 158 vboxSvcClipboardReportMsg(&g_Client, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA, 159 VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT | VBOX_SHARED_CLIPBOARD_FMT_HTML); 160 160 RTTESTI_CHECK(parms[0].u.uint32 == VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA); 161 161 RTTESTI_CHECK(parms[1].u.uint32 == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT); … … 174 174 RTTestISub("Testing FN_GET_HOST_MSG, two formats, no waiting guest calls."); 175 175 RT_ZERO(g_Client); 176 vboxSvcClipboardReportMsg 177 176 vboxSvcClipboardReportMsg(&g_Client, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA, 177 VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT | VBOX_SHARED_CLIPBOARD_FMT_HTML); 178 178 HGCMSvcSetU32(&parms[0], 0); 179 179 HGCMSvcSetU32(&parms[1], 0); … … 274 274 275 275 int vboxClipboardInit() { return VINF_SUCCESS; } 276 void vboxClipboardDestroy() { }277 void vboxClipboardDisconnect(_VBOXCLIPBOARDCLIENTDATA *) { AssertFailed(); }278 int vboxClipboardConnect(_VBOXCLIPBOARDCLIENTDATA *, bool)276 void vboxClipboardDestroy() { } 277 void vboxClipboardDisconnect(_VBOXCLIPBOARDCLIENTDATA *) { AssertFailed(); } 278 int vboxClipboardConnect(_VBOXCLIPBOARDCLIENTDATA *, bool) 279 279 { AssertFailed(); return VERR_WRONG_ORDER; } 280 void vboxClipboardFormatAnnounce(_VBOXCLIPBOARDCLIENTDATA *, unsigned int)280 void vboxClipboardFormatAnnounce(_VBOXCLIPBOARDCLIENTDATA *, unsigned int) 281 281 { AssertFailed(); } 282 int vboxClipboardReadData(_VBOXCLIPBOARDCLIENTDATA *, unsigned int, void*, unsigned int, unsigned int*)282 int vboxClipboardReadData(_VBOXCLIPBOARDCLIENTDATA *, unsigned int, void *, unsigned int, unsigned int *) 283 283 { AssertFailed(); return VERR_WRONG_ORDER; } 284 void vboxClipboardWriteData(_VBOXCLIPBOARDCLIENTDATA *, void*, unsigned int, unsigned int) { AssertFailed(); }285 int vboxClipboardSync(_VBOXCLIPBOARDCLIENTDATA *)284 void vboxClipboardWriteData(_VBOXCLIPBOARDCLIENTDATA *, void *, unsigned int, unsigned int) { AssertFailed(); } 285 int vboxClipboardSync(_VBOXCLIPBOARDCLIENTDATA *) 286 286 { AssertFailed(); return VERR_WRONG_ORDER; }
Note:
See TracChangeset
for help on using the changeset viewer.