Changeset 1103 in vbox
- Timestamp:
- Feb 28, 2007 1:03:10 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 18999
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/HostServices/VBoxClipboardSvc.h
r1 r1103 28 28 #include <VBox/hgcmsvc.h> 29 29 30 #define VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE 1 31 30 /* 31 * The mode of operations. 32 */ 32 33 #define VBOX_SHARED_CLIPBOARD_MODE_OFF 0 33 34 #define VBOX_SHARED_CLIPBOARD_MODE_HOST_TO_GUEST 1 … … 35 36 #define VBOX_SHARED_CLIPBOARD_MODE_BIDIRECTIONAL 3 36 37 37 #define VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT 0 38 #define VBOX_SHARED_CLIPBOARD_FMT_BITMAP 1 38 /* 39 * Supported data formats. Bit mask. 40 */ 41 #define VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT 0x01 42 #define VBOX_SHARED_CLIPBOARD_FMT_BITMAP 0x02 39 43 40 #define VBOX_SHARED_CLIPBOARD_FN_QUERY_MODE 1 41 #define VBOX_SHARED_CLIPBOARD_FN_HOST_EVENT_CANCEL 2 42 #define VBOX_SHARED_CLIPBOARD_FN_HOST_EVENT_QUERY 3 43 #define VBOX_SHARED_CLIPBOARD_FN_HOST_EVENT_READ 4 44 #define VBOX_SHARED_CLIPBOARD_FN_SEND_DATA 5 44 /* 45 * The service functions which are callable by host. 46 */ 47 #define VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE 1 45 48 49 /* 50 * The service functions which are called by guest. 51 */ 52 /* Call host and wait blocking for an host event VBOX_SHARED_CLIPBOARD_HOST_MSG_* */ 53 #define VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG 1 54 /* Send list of available formats to host. */ 55 #define VBOX_SHARED_CLIPBOARD_FN_FORMATS 2 56 /* Obtain data in specified format from host. */ 57 #define VBOX_SHARED_CLIPBOARD_FN_READ_DATA 3 58 /* Send data in requested format to host. */ 59 #define VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA 4 60 61 /* 62 * The host messages for the guest. 63 */ 64 #define VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT 1 65 #define VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA 2 66 #define VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS 3 67 68 /* 69 * HGCM parameter structures. 70 */ 46 71 #pragma pack (1) 47 typedef struct _VBoxClipboard QueryMode72 typedef struct _VBoxClipboardGetHostMsg 48 73 { 49 74 VBoxGuestHGCMCallInfo hdr; 50 75 51 HGCMFunctionParameter mode; /* OUT uint32_t */ 76 /* VBOX_SHARED_CLIPBOARD_HOST_MSG_* */ 77 HGCMFunctionParameter msg; /* OUT uint32_t */ 52 78 53 } VBoxClipboardQueryMode; 79 /* VBOX_SHARED_CLIPBOARD_FMT_*, depends on the 'msg'. */ 80 HGCMFunctionParameter formats; /* OUT uint32_t */ 81 } VBoxClipboardGetHostMsg; 54 82 55 typedef struct _VBoxClipboard HostEventCancel83 typedef struct _VBoxClipboardFormats 56 84 { 57 85 VBoxGuestHGCMCallInfo hdr; 58 } VBoxClipboardHostEventCancel;59 86 60 typedef struct _VBoxClipboardHostEventQuery 87 /* VBOX_SHARED_CLIPBOARD_FMT_* */ 88 HGCMFunctionParameter formats; /* OUT uint32_t */ 89 } VBoxClipboardFormats; 90 91 typedef struct _VBoxClipboardReadData 61 92 { 62 93 VBoxGuestHGCMCallInfo hdr; 63 94 64 HGCMFunctionParameter format; /* OUT uint32_t */ 95 /* Requested format. */ 96 HGCMFunctionParameter format; /* IN uint32_t */ 65 97 98 /* The data buffer. */ 99 HGCMFunctionParameter ptr; /* IN linear pointer. */ 100 101 /* Size of returned data, if > ptr->cb, then no data was 102 * actually transferred and the guest must repeat the call. 103 */ 66 104 HGCMFunctionParameter size; /* OUT uint32_t */ 67 } VBoxClipboardHostEventQuery; 105 106 } VBoxClipboardReadData; 68 107 69 typedef struct _VBoxClipboard HostEventRead108 typedef struct _VBoxClipboardWriteData 70 109 { 71 110 VBoxGuestHGCMCallInfo hdr; 72 111 73 HGCMFunctionParameter ptr; /* OUT linear pointer. */ 74 } VBoxClipboardHostEventRead; 75 76 typedef struct _VBoxClipboardSendData 77 { 78 VBoxGuestHGCMCallInfo hdr; 79 112 /* Returned format as requested in the VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA message. */ 80 113 HGCMFunctionParameter format; /* IN uint32_t */ 81 114 115 /* Data. */ 82 116 HGCMFunctionParameter ptr; /* IN linear pointer. */ 83 } VBoxClipboard SendData;117 } VBoxClipboardWriteData; 84 118 #pragma pack () 85 119 -
trunk/src/VBox/Additions/WINNT/VBoxService/VBoxClipboard.cpp
r9 r1103 22 22 #include <VBox/HostServices/VBoxClipboardSvc.h> 23 23 24 #include <iprt/crc64.h>25 26 //#define LOG_ENABLED24 // #include <iprt/crc64.h> 25 26 #define LOG_ENABLED 27 27 28 28 #ifdef LOG_ENABLED … … 55 55 #endif /* LOG_ENABLED */ 56 56 57 57 58 typedef struct _VBOXCLIPBOARDCONTEXT 58 59 { … … 61 62 uint32_t u32ClientID; 62 63 63 uint32_t u32Mode;64 65 64 ATOM atomWindowClass; 66 65 … … 69 68 HWND hwndNextInChain; 70 69 71 HANDLE hHostEvent;72 73 bool fOperational;74 75 uint32_t u32LastSentFormat;76 uint64_t u64LastSentCRC64;70 // bool fOperational; 71 72 // uint32_t u32LastSentFormat; 73 // uint64_t u64LastSentCRC64; 74 75 bool fAnnouncing; 77 76 78 77 } VBOXCLIPBOARDCONTEXT; 79 78 79 80 80 static char gachWindowClassName[] = "VBoxSharedClipboardClass"; 81 81 82 #define VBOX_INIT_CALL(a, b) do { \ 83 (a)->hdr.result = VINF_SUCCESS; \ 84 (a)->hdr.u32ClientID = pCtx->u32ClientID; \ 85 (a)->hdr.u32Function = b; \ 86 (a)->hdr.cParms = (sizeof (*a) - sizeof ((a)->hdr)) / sizeof (HGCMFunctionParameter); \ 82 83 #define VBOX_INIT_CALL(__a, __b, __c) do { \ 84 (__a)->hdr.result = VINF_SUCCESS; \ 85 (__a)->hdr.u32ClientID = (__c)->u32ClientID; \ 86 (__a)->hdr.u32Function = (__b); \ 87 (__a)->hdr.cParms = (sizeof (*(__a)) - sizeof ((__a)->hdr)) / sizeof (HGCMFunctionParameter); \ 87 88 } while (0) 88 89 89 static bool vboxClipboardIsSameAsLastSent (VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Format, 90 void *pv, uint32_t cb) 91 { 92 uint64_t u64CRC = RTCrc64 (pv, cb); 93 94 if ( pCtx->u32LastSentFormat == u32Format 95 && pCtx->u64LastSentCRC64 == u64CRC) 96 { 97 return true; 98 } 99 100 pCtx->u64LastSentCRC64 = u64CRC; 101 pCtx->u32LastSentFormat = u32Format; 102 103 return false; 104 } 90 91 //static bool vboxClipboardIsSameAsLastSent (VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Format, 92 // void *pv, uint32_t cb) 93 //{ 94 // uint64_t u64CRC = RTCrc64 (pv, cb); 95 // 96 // if ( pCtx->u32LastSentFormat == u32Format 97 // && pCtx->u64LastSentCRC64 == u64CRC) 98 // { 99 // return true; 100 // } 101 // 102 // pCtx->u64LastSentCRC64 = u64CRC; 103 // pCtx->u32LastSentFormat = u32Format; 104 // 105 // return false; 106 //} 105 107 106 108 static int vboxClipboardConnect (VBOXCLIPBOARDCONTEXT *pCtx) … … 204 206 } 205 207 206 static int vboxClipboard QueryMode (VBOXCLIPBOARDCONTEXT *pCtx)207 { 208 VBoxClipboard QueryModeparms;209 210 VBOX_INIT_CALL(&parms, VBOX_SHARED_CLIPBOARD_FN_ QUERY_MODE);211 212 VBoxHGCMParmUInt32Set (&parms. mode, 0);208 static int vboxClipboardReportFormats (VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Formats) 209 { 210 VBoxClipboardFormats parms; 211 212 VBOX_INIT_CALL(&parms, VBOX_SHARED_CLIPBOARD_FN_FORMATS, pCtx); 213 214 VBoxHGCMParmUInt32Set (&parms.formats, u32Formats); 213 215 214 216 int rc = vboxCall (pCtx->pEnv->hDriver, &parms, sizeof (parms)); … … 217 219 { 218 220 rc = parms.hdr.result; 219 220 if (VBOX_SUCCESS (rc))221 {222 rc = VBoxHGCMParmUInt32Get (&parms.mode, &pCtx->u32Mode);223 224 dprintf (("vboxClipboardQueryMode: Mode = %d, rc = %d\n", pCtx->u32Mode, rc));225 }226 221 } 227 222 … … 229 224 } 230 225 231 static int vboxClipboardHostEventCancel (VBOXCLIPBOARDCONTEXT *pCtx) 232 { 233 VBoxClipboardHostEventCancel parms; 234 235 VBOX_INIT_CALL(&parms, VBOX_SHARED_CLIPBOARD_FN_HOST_EVENT_CANCEL); 236 237 int rc = vboxCall (pCtx->pEnv->hDriver, &parms, sizeof (parms)); 238 239 if (VBOX_SUCCESS (rc)) 240 { 241 rc = parms.hdr.result; 242 } 243 244 return rc; 245 } 246 247 static int vboxClipboardHostEventRead (VBOXCLIPBOARDCONTEXT *pCtx, void *pv, uint32_t cb) 248 { 249 if (!VirtualLock (pv, cb)) 226 static int vboxClipboardReadData (VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Format, void *pv, uint32_t cb, uint32_t *pcbActual) 227 { 228 if (cb > 0 && !VirtualLock (pv, cb)) 250 229 { 251 230 dprintf (("vboxClipboardHostEventRead: VirtualLock failed\n")); … … 253 232 } 254 233 255 VBoxClipboardHostEventRead parms; 256 257 VBOX_INIT_CALL(&parms, VBOX_SHARED_CLIPBOARD_FN_HOST_EVENT_READ); 258 259 VBoxHGCMParmPtrSet (&parms.ptr, pv, cb); 234 VBoxClipboardReadData parms; 235 236 VBOX_INIT_CALL(&parms, VBOX_SHARED_CLIPBOARD_FN_READ_DATA, pCtx); 237 238 VBoxHGCMParmUInt32Set (&parms.format, u32Format); 239 VBoxHGCMParmPtrSet (&parms.ptr, pv, cb); 240 VBoxHGCMParmUInt32Set (&parms.size, 0); 260 241 261 242 int rc = vboxCall (pCtx->pEnv->hDriver, &parms, sizeof (parms)); … … 264 245 { 265 246 rc = parms.hdr.result; 266 } 267 268 VirtualUnlock (pv, cb); 269 270 return rc; 271 } 272 273 static int vboxClipboardSendData (VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Format, 274 void *pv, uint32_t cb) 275 { 276 if (vboxClipboardIsSameAsLastSent (pCtx, u32Format, pv, cb)) 277 { 278 dprintf (("vboxClipboardSendData: The data to be sent are the same as the last sent.\n")); 279 return VINF_SUCCESS; 280 } 281 282 if (!VirtualLock (pv, cb)) 283 { 284 dprintf (("vboxClipboardSendData: VirtualLock failed\n")); 285 return VERR_NOT_SUPPORTED; 286 } 287 288 VBoxClipboardSendData parms; 289 290 VBOX_INIT_CALL(&parms, VBOX_SHARED_CLIPBOARD_FN_SEND_DATA); 291 292 VBoxHGCMParmUInt32Set (&parms.format, u32Format); 293 VBoxHGCMParmPtrSet (&parms.ptr, pv, cb); 294 295 int rc = vboxCall (pCtx->pEnv->hDriver, &parms, sizeof (parms)); 296 297 if (VBOX_SUCCESS (rc)) 298 { 299 rc = parms.hdr.result; 300 } 301 302 VirtualUnlock (pv, cb); 303 304 return rc; 305 } 306 307 308 static void vboxClipboardSendDIB (VBOXCLIPBOARDCONTEXT *pCtx) 309 { 310 HANDLE hClip = GetClipboardData (CF_DIB); 311 312 if (hClip != NULL) 313 { 314 LPVOID lp = GlobalLock (hClip); 315 316 if (lp != NULL) 317 { 318 vboxClipboardSendData (pCtx, VBOX_SHARED_CLIPBOARD_FMT_BITMAP, 319 lp, GlobalSize (hClip)); 320 321 GlobalUnlock(hClip); 322 } 323 } 324 } 325 326 static void vboxClipboardSendBitmap (VBOXCLIPBOARDCONTEXT *pCtx) 327 { 328 /* Request DIB format anyway. The system will convert the available CF_BITMAP to CF_DIB. */ 329 vboxClipboardSendDIB (pCtx); 330 } 331 332 static void vboxClipboardSendUnicodeText (VBOXCLIPBOARDCONTEXT *pCtx) 333 { 334 HANDLE hClip = GetClipboardData(CF_UNICODETEXT); 335 336 if (hClip != NULL) 337 { 338 LPWSTR uniString = (LPWSTR)GlobalLock (hClip); 339 340 if (uniString != NULL) 341 { 342 vboxClipboardSendData (pCtx, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, 343 uniString, (lstrlenW (uniString) + 1) * 2); 344 345 GlobalUnlock(hClip); 346 } 347 } 348 } 349 350 static void vboxClipboardSendText (VBOXCLIPBOARDCONTEXT *pCtx) 351 { 352 /* Request UNICODE format anyway. The system will convert the available CF_TEXT to CF_UNICODE. */ 353 vboxClipboardSendUnicodeText (pCtx); 354 } 355 356 static void vboxClipboardGuestEvent (VBOXCLIPBOARDCONTEXT *pCtx) 357 { 358 if ( pCtx->u32Mode != VBOX_SHARED_CLIPBOARD_MODE_GUEST_TO_HOST 359 && pCtx->u32Mode != VBOX_SHARED_CLIPBOARD_MODE_BIDIRECTIONAL) 360 { 361 /* The host will not accept the clipboard data anyway. */ 362 return; 363 } 364 365 if (OpenClipboard (pCtx->hwnd)) 366 { 367 int cFormats = CountClipboardFormats (); 368 369 if (cFormats > 0) 370 { 371 dprintf (("vboxClipboardGuestEvent: cFormats = %d\n", cFormats)); 372 373 static UINT aFormatPriorityList[] = 374 { 375 CF_UNICODETEXT, 376 CF_TEXT, 377 CF_DIB, 378 CF_BITMAP 379 }; 380 381 int iFormat = GetPriorityClipboardFormat (aFormatPriorityList, ELEMENTS (aFormatPriorityList)); 382 383 switch (iFormat) 384 { 385 case CF_TEXT: 247 248 if (VBOX_SUCCESS (rc)) 249 { 250 uint32_t u32Size; 251 252 rc = VBoxHGCMParmUInt32Get (&parms.size, &u32Size); 253 254 dprintf (("vboxClipboardReadData: actual size = %d, rc = %d\n", u32Size, rc)); 255 256 if (VBOX_SUCCESS (rc)) 257 { 258 if (pcbActual) 386 259 { 387 dprintf(("CF_TEXT\n")); 388 389 vboxClipboardSendText (pCtx); 390 } break; 391 392 case CF_UNICODETEXT: 393 { 394 dprintf(("CF_UNICODETEXT\n")); 395 396 vboxClipboardSendUnicodeText (pCtx); 397 } break; 398 399 case CF_BITMAP: 400 { 401 dprintf(("CF_BITMAP\n")); 402 403 vboxClipboardSendBitmap (pCtx); 404 } break; 405 406 case CF_DIB: 407 { 408 dprintf(("CF_DIB\n")); 409 410 vboxClipboardSendDIB (pCtx); 411 } break; 412 413 default: 414 { 415 dprintf(("not supported %d\n", iFormat)); 416 } 417 } 418 } 419 420 CloseClipboard (); 421 } 422 } 423 424 static void vboxClipboardHostEvent (VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Format, uint32_t u32Size) 425 { 426 if ( pCtx->u32Mode != VBOX_SHARED_CLIPBOARD_MODE_HOST_TO_GUEST 427 && pCtx->u32Mode != VBOX_SHARED_CLIPBOARD_MODE_BIDIRECTIONAL) 428 { 429 /* The guest should not accept the clipboard data anyway. */ 430 vboxClipboardHostEventCancel (pCtx); 431 432 return; 433 } 434 435 dprintf(("vboxClipboardHostEvent u32Size %d\n", u32Size)); 436 437 if (u32Size > 0) 438 { 439 HANDLE hMem = GlobalAlloc (GMEM_DDESHARE | GMEM_MOVEABLE, u32Size); 440 441 dprintf(("vboxClipboardHostEvent hMem %p\n", hMem)); 442 443 if (hMem) 444 { 445 void *pMem = GlobalLock (hMem); 446 447 dprintf(("vboxClipboardHostEvent pMem %p, GlobalSize %d\n", pMem, GlobalSize (hMem))); 448 449 if (pMem) 450 { 451 /* Read the host data and cancel the transaction. */ 452 int rc = vboxClipboardHostEventRead (pCtx, pMem, u32Size); 453 454 dprintf(("vboxClipboardHostEvent read %d\n", rc)); 455 456 if (VBOX_SUCCESS (rc)) 457 { 458 /* Data was read from the host and transaction was cancelled. 459 * Return from the code branch without calling cancel event. 460 */ 461 HANDLE hClip = 0; 462 463 /* Remember the last data that goes to the clipboard. 464 * That will prevent sending the same data back to the client. 465 */ 466 vboxClipboardIsSameAsLastSent (pCtx, u32Format, pMem, u32Size); 467 468 /* The memory must be unlocked before the Clipboard is closed. */ 469 GlobalUnlock (hMem); 470 471 /* 'pMem' contains the host clipboard data. 472 * size is 'u32Size' and format is 'u32Format'. 473 */ 474 if (OpenClipboard (pCtx->hwnd)) 475 { 476 EmptyClipboard(); 477 478 if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 479 { 480 dprintf(("vboxClipboardHostEvent VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT\n")); 481 hClip = SetClipboardData (CF_UNICODETEXT, hMem); 482 } 483 else if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 484 { 485 dprintf(("vboxClipboardHostEvent VBOX_SHARED_CLIPBOARD_FMT_BiTMAP\n")); 486 hClip = SetClipboardData (CF_DIB, hMem); 487 } 488 489 CloseClipboard(); 490 491 dprintf(("vboxClipboardHostEvent hClip %p\n", hClip)); 492 } 493 else 494 { 495 dprintf(("vboxClipboardHostEvent failed to open clipboard\n")); 496 } 497 498 if (!hClip) 499 { 500 /* Failed to set the clipboard data. */ 501 GlobalFree (hMem); 502 } 503 else 504 { 505 /* The hMem ownership has gone to the system. Nothing to do. */ 506 } 507 508 return; 260 *pcbActual = u32Size; 509 261 } 510 262 else 511 263 { 512 GlobalUnlock (hMem); 264 if (u32Size != cb) 265 { 266 rc = VERR_INVALID_PARAMETER; 267 } 513 268 } 514 269 } 515 516 GlobalFree (hMem); 517 } 518 } 519 else 520 { 521 if (OpenClipboard (pCtx->hwnd)) 522 { 523 EmptyClipboard(); 524 CloseClipboard(); 525 } 526 } 527 528 vboxClipboardHostEventCancel (pCtx); 529 530 return; 270 } 271 } 272 273 if (cb > 0) 274 { 275 VirtualUnlock (pv, cb); 276 } 277 278 return rc; 279 } 280 281 static int vboxClipboardWriteData (VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Format, 282 void *pv, uint32_t cb) 283 { 284 // if (vboxClipboardIsSameAsLastSent (pCtx, u32Format, pv, cb)) 285 // { 286 // dprintf (("vboxClipboardWriteData: The data to be sent are the same as the last sent.\n")); 287 // return VINF_SUCCESS; 288 // } 289 290 if (!VirtualLock (pv, cb)) 291 { 292 dprintf (("vboxClipboardWriteData: VirtualLock failed\n")); 293 return VERR_NOT_SUPPORTED; 294 } 295 296 VBoxClipboardWriteData parms; 297 298 VBOX_INIT_CALL(&parms, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA, pCtx); 299 300 VBoxHGCMParmUInt32Set (&parms.format, u32Format); 301 VBoxHGCMParmPtrSet (&parms.ptr, pv, cb); 302 303 int rc = vboxCall (pCtx->pEnv->hDriver, &parms, sizeof (parms)); 304 305 if (VBOX_SUCCESS (rc)) 306 { 307 rc = parms.hdr.result; 308 } 309 310 VirtualUnlock (pv, cb); 311 312 return rc; 313 } 314 315 static void vboxClipboardChanged (VBOXCLIPBOARDCONTEXT *pCtx) 316 { 317 /* Query list of available formats and report to host. */ 318 if (OpenClipboard (pCtx->hwnd)) 319 { 320 uint32_t u32Formats = 0; 321 322 UINT format = 0; 323 324 while ((format = EnumClipboardFormats (format)) != 0) 325 { 326 switch (format) 327 { 328 case CF_UNICODETEXT: 329 case CF_TEXT: 330 u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; 331 break; 332 333 case CF_DIB: 334 case CF_BITMAP: 335 u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP; 336 break; 337 338 default: 339 break; 340 } 341 } 342 343 CloseClipboard (); 344 345 vboxClipboardReportFormats (pCtx, u32Formats); 346 } 531 347 } 532 348 … … 565 381 dprintf (("vboxClipboardProcessMsg: WM_DRAWCLIPBOARD, hwnd %p\n", pCtx->hwnd)); 566 382 567 vboxClipboardGuestEvent (pCtx); 383 if (!pCtx->fAnnouncing) 384 { 385 vboxClipboardChanged (pCtx); 386 } 568 387 569 388 /* Pass the message to next windows in the clipboard chain. */ … … 574 393 { 575 394 /* Do nothing. Ignore the message. */ 395 } break; 396 397 case WM_RENDERFORMAT: 398 { 399 /* Insert the requested clipboard format data into the clipboard. */ 400 uint32_t u32Format = 0; 401 402 UINT format = (UINT)wParam; 403 404 switch (format) 405 { 406 case CF_UNICODETEXT: 407 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; 408 break; 409 410 case CF_DIB: 411 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP; 412 break; 413 414 default: 415 break; 416 } 417 418 if (u32Format == 0) 419 { 420 /* Unsupported clipboard format is requested. */ 421 EmptyClipboard (); 422 } 423 else 424 { 425 /* Query the size of available data. */ 426 uint32_t cb = 0; 427 428 int vboxrc = vboxClipboardReadData (pCtx, u32Format, NULL, 0, &cb); 429 430 dprintf(("vboxClipboardReadData vboxrc = %d, cb = %d\n", vboxrc, cb)); 431 432 if (VBOX_SUCCESS (vboxrc) && cb > 0) 433 { 434 HANDLE hMem = GlobalAlloc (GMEM_DDESHARE | GMEM_MOVEABLE, cb); 435 436 dprintf(("hMem %p\n", hMem)); 437 438 if (hMem) 439 { 440 void *pMem = GlobalLock (hMem); 441 442 dprintf(("pMem %p, GlobalSize %d\n", pMem, GlobalSize (hMem))); 443 444 if (pMem) 445 { 446 /* Read the host data. */ 447 vboxrc = vboxClipboardReadData (pCtx, u32Format, pMem, cb, NULL); 448 449 dprintf(("vboxClipboardReadData vboxrc %d\n", vboxrc)); 450 451 if (VBOX_SUCCESS (vboxrc)) 452 { 453 // /* Remember the which data was transferred. */ 454 // vboxClipboardIsSameAsLastSent (pCtx, u32Format, pMem, cb); 455 456 /* The memory must be unlocked before inserting to the Clipboard. */ 457 GlobalUnlock (hMem); 458 459 /* 'hMem' contains the host clipboard data. 460 * size is 'cb' and format is 'format'. 461 */ 462 HANDLE hClip = SetClipboardData (format, hMem); 463 464 dprintf(("WM_RENDERFORMAT hClip %p\n", hClip)); 465 466 if (hClip) 467 { 468 /* The hMem ownership has gone to the system. Finish the processsing. */ 469 break; 470 } 471 472 /* Cleanup follows. */ 473 } 474 else 475 { 476 GlobalUnlock (hMem); 477 } 478 } 479 480 GlobalFree (hMem); 481 } 482 } 483 484 /* Something went wrong. */ 485 EmptyClipboard (); 486 } 487 } break; 488 489 case WM_RENDERALLFORMATS: 490 { 491 /* Do nothing. The clipboard formats will be unavailable now, because the 492 * windows is to be destroyed and therefore the guest side becomes inactive. 493 */ 494 if (OpenClipboard (hwnd)) 495 { 496 EmptyClipboard(); 497 498 CloseClipboard(); 499 } 500 } break; 501 502 case WM_USER: 503 { 504 /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */ 505 uint32_t u32Formats = (uint32_t)lParam; 506 507 /* Prevent the WM_DRAWCLIPBOARD processing. */ 508 pCtx->fAnnouncing = true; 509 510 if (OpenClipboard (hwnd)) 511 { 512 EmptyClipboard(); 513 514 HANDLE hClip = NULL; 515 516 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 517 { 518 dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT\n")); 519 hClip = SetClipboardData (CF_UNICODETEXT, NULL); 520 } 521 522 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 523 { 524 dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n")); 525 hClip = SetClipboardData (CF_DIB, NULL); 526 } 527 528 CloseClipboard(); 529 530 dprintf(("window proc WM_USER: hClip %p\n", hClip)); 531 } 532 else 533 { 534 dprintf(("window proc WM_USER: failed to open clipboard\n")); 535 } 536 537 pCtx->fAnnouncing = false; 538 } break; 539 540 case WM_USER + 1: 541 { 542 /* Send data in the specified format to the host. */ 543 uint32_t u32Formats = (uint32_t)lParam; 544 545 HANDLE hClip = NULL; 546 547 if (OpenClipboard (hwnd)) 548 { 549 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 550 { 551 hClip = GetClipboardData (CF_DIB); 552 553 if (hClip != NULL) 554 { 555 LPVOID lp = GlobalLock (hClip); 556 557 if (lp != NULL) 558 { 559 dprintf(("CF_DIB\n")); 560 561 vboxClipboardWriteData (pCtx, VBOX_SHARED_CLIPBOARD_FMT_BITMAP, 562 lp, GlobalSize (hClip)); 563 564 GlobalUnlock(hClip); 565 } 566 else 567 { 568 hClip = NULL; 569 } 570 } 571 } 572 else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 573 { 574 hClip = GetClipboardData(CF_UNICODETEXT); 575 576 if (hClip != NULL) 577 { 578 LPWSTR uniString = (LPWSTR)GlobalLock (hClip); 579 580 if (uniString != NULL) 581 { 582 dprintf(("CF_UNICODETEXT\n")); 583 584 vboxClipboardWriteData (pCtx, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, 585 uniString, (lstrlenW (uniString) + 1) * 2); 586 587 GlobalUnlock(hClip); 588 } 589 else 590 { 591 hClip = NULL; 592 } 593 } 594 } 595 596 CloseClipboard (); 597 } 598 599 if (hClip == NULL) 600 { 601 /* Requested clipboard format is not available, send empty data. */ 602 vboxClipboardWriteData (pCtx, 0, NULL, 0); 603 } 576 604 } break; 577 605 … … 668 696 dprintf (("VboxClipboardInit\n")); 669 697 670 if (!gCtx.pEnv) 671 { 672 memset (&gCtx, 0, sizeof (gCtx)); 673 674 gCtx.pEnv = pEnv; 675 676 rc = vboxClipboardConnect (&gCtx); 698 if (gCtx.pEnv) 699 { 700 /* Clipboard was already initialized. 2 or more instances are not supported. */ 701 return VERR_NOT_SUPPORTED; 702 } 703 704 memset (&gCtx, 0, sizeof (gCtx)); 705 706 gCtx.pEnv = pEnv; 707 708 rc = vboxClipboardConnect (&gCtx); 709 710 if (VBOX_SUCCESS (rc)) 711 { 712 rc = vboxClipboardInit (&gCtx); 713 714 dprintf (("vboxClipboardInit: rc = %d\n", rc)); 677 715 678 716 if (VBOX_SUCCESS (rc)) 679 717 { 680 rc = vboxClipboardQueryMode (&gCtx); 681 682 if (VBOX_SUCCESS (rc)) 683 { 684 rc = vboxClipboardInit (&gCtx); 685 686 dprintf (("vboxClipboardInit: rc = %d\n", rc)); 687 688 if (VBOX_SUCCESS (rc)) 689 { 690 /* Host to Guest direction requires the thread. */ 691 if ( gCtx.u32Mode == VBOX_SHARED_CLIPBOARD_MODE_HOST_TO_GUEST 692 || gCtx.u32Mode == VBOX_SHARED_CLIPBOARD_MODE_BIDIRECTIONAL) 693 { 694 *pfStartThread = true; 695 } 696 } 697 } 718 /* Always start the thread for host messages. */ 719 *pfStartThread = true; 698 720 } 699 721 } … … 716 738 717 739 dprintf(("VBoxClipboardThread\n")); 718 719 HANDLE hHostEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 720 721 /* The thread waits for incoming data from the host. 722 * Register an event notification. 723 */ 740 741 /* Open the new driver instance to not interfere with other callers. */ 742 HANDLE hDriver = CreateFile(VBOXGUEST_DEVICE_NAME, 743 GENERIC_READ | GENERIC_WRITE, 744 FILE_SHARE_READ | FILE_SHARE_WRITE, 745 NULL, 746 OPEN_EXISTING, 747 FILE_ATTRIBUTE_NORMAL, 748 NULL); 749 750 /* The thread waits for incoming messages from the host. */ 724 751 for (;;) 725 752 { 726 uint32_t u32Format; 727 uint32_t u32Size; 728 729 VBoxClipboardHostEventQuery parms; 730 731 VBOX_INIT_CALL(&parms, VBOX_SHARED_CLIPBOARD_FN_HOST_EVENT_QUERY); 732 733 VBoxHGCMParmUInt32Set (&parms.format, 0); 734 VBoxHGCMParmUInt32Set (&parms.size, 0); 753 VBoxClipboardGetHostMsg parms; 754 755 VBOX_INIT_CALL(&parms, VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG, pCtx); 756 757 VBoxHGCMParmUInt32Set (&parms.msg, 0); 758 VBoxHGCMParmUInt32Set (&parms.formats, 0); 735 759 736 760 DWORD cbReturned; 737 761 738 if (!DeviceIoControl ( pCtx->pEnv->hDriver,762 if (!DeviceIoControl (hDriver, 739 763 IOCTL_VBOXGUEST_HGCM_CALL, 740 764 &parms, sizeof (parms), … … 743 767 NULL)) 744 768 { 745 dprintf(("Failed to call the driver for host event\n"));769 dprintf(("Failed to call the driver for host message.\n")); 746 770 747 771 /* Wait a bit before retrying. */ … … 758 782 if (VBOX_SUCCESS (rc)) 759 783 { 760 rc = VBoxHGCMParmUInt32Get (&parms.format, &u32Format); 784 uint32_t u32Msg; 785 uint32_t u32Formats; 786 787 rc = VBoxHGCMParmUInt32Get (&parms.msg, &u32Msg); 761 788 762 789 if (VBOX_SUCCESS (rc)) 763 790 { 764 rc = VBoxHGCMParmUInt32Get (&parms. size, &u32Size);791 rc = VBoxHGCMParmUInt32Get (&parms.formats, &u32Formats); 765 792 766 793 if (VBOX_SUCCESS (rc)) 767 794 { 768 vboxClipboardHostEvent (pCtx, u32Format, u32Size); 795 dprintf(("vboxClipboardHostEvent u32Msg %d, u32Formats %d\n", u32Msg, u32Formats)); 796 797 switch (u32Msg) 798 { 799 case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS: 800 { 801 /* The host has announced available clipboard formats. 802 * Forward the information to the window, so it can later 803 * respond to WM_RENDERFORMAT message. 804 */ 805 ::PostMessage (pCtx->hwnd, WM_USER, 0, u32Formats); 806 } break; 807 case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA: 808 { 809 /* The host needs data in the specified format. 810 */ 811 ::PostMessage (pCtx->hwnd, WM_USER + 1, 0, u32Formats); 812 } break; 813 case VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT: 814 { 815 /* The host is terminating. 816 */ 817 rc = VERR_INTERRUPTED; 818 } break; 819 default: 820 { 821 dprintf(("Unsupported message from host!!!")); 822 } 823 } 769 824 } 770 825 } 771 826 } 827 828 if (rc == VERR_INTERRUPTED) 829 { 830 /* Wait for termination event. */ 831 WaitForSingleObject(pCtx->pEnv->hStopEvent, INFINITE); 832 break; 833 } 834 835 if (VBOX_FAILURE (rc)) 836 { 837 /* Wait a bit before retrying. */ 838 if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 1000) == WAIT_OBJECT_0) 839 { 840 break; 841 } 842 843 continue; 844 } 772 845 773 846 dprintf(("processed host event rc = %d\n", rc)); 774 847 } 848 849 CloseHandle (hDriver); 775 850 776 851 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.