Changeset 78501 in vbox
- Timestamp:
- May 14, 2019 11:36:25 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 10 edited
- 1 moved
-
include/VBox/GuestHost/SharedClipboard-uri.h (modified) (5 diffs)
-
include/VBox/GuestHost/SharedClipboard-win.h (modified) (3 diffs)
-
src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk (modified) (1 diff)
-
src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp (modified) (21 diffs)
-
src/VBox/GuestHost/SharedClipboard/ClipboardCache.cpp (moved) (moved from trunk/src/VBox/GuestHost/SharedClipboard/ClipboardFiles.cpp ) (10 diffs)
-
src/VBox/GuestHost/SharedClipboard/ClipboardPath.cpp (modified) (1 diff)
-
src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp (modified) (4 diffs)
-
src/VBox/HostServices/SharedClipboard/Makefile.kmk (modified) (1 diff)
-
src/VBox/HostServices/SharedClipboard/VBoxClipboard.h (modified) (4 diffs)
-
src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-uri.cpp (added)
-
src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-uri.h (added)
-
src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp (modified) (21 diffs)
-
src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/GuestHost/SharedClipboard-uri.h
r78440 r78501 32 32 33 33 #include <iprt/assert.h> 34 #include <iprt/critsect.h> 34 35 #include <iprt/fs.h> 35 36 … … 37 38 #include <iprt/cpp/ministring.h> 38 39 39 /** SharedClipboard DroppedFilesflags. */40 typedef uint32_t SHAREDCLIPBOARD DROPPEDFILEFLAGS;40 /** SharedClipboardCache flags. */ 41 typedef uint32_t SHAREDCLIPBOARDCACHEFLAGS; 41 42 42 43 /** No flags specified. */ 43 #define SHAREDCLIPBOARD DROPPEDFILE_FLAGS_NONE044 #define SHAREDCLIPBOARDCACHE_FLAGS_NONE 0 44 45 45 46 /** 46 * Class for maintaining a "dropped files" directory47 * Class for maintaining a Shared Clipboard cache 47 48 * on the host or guest. This will contain all received files & directories 48 * for a single Shared Clipboard "paste"operation.49 * for a single Shared Clipboard operation. 49 50 * 50 51 * In case of a failed Shared Clipboard operation this class can also 51 52 * perform a gentle rollback if required. 52 53 */ 53 class SharedClipboard DroppedFiles54 class SharedClipboardCache 54 55 { 55 56 56 57 public: 57 58 58 SharedClipboardDroppedFiles(void); 59 SharedClipboardDroppedFiles(const char *pszPath, SHAREDCLIPBOARDDROPPEDFILEFLAGS fFlags = SHAREDCLIPBOARDDROPPEDFILE_FLAGS_NONE); 60 virtual ~SharedClipboardDroppedFiles(void); 61 62 public: 59 SharedClipboardCache(void); 60 SharedClipboardCache(const char *pszPath, SHAREDCLIPBOARDCACHEFLAGS fFlags = SHAREDCLIPBOARDCACHE_FLAGS_NONE); 61 virtual ~SharedClipboardCache(void); 62 63 public: 64 65 uint16_t AddRef(void); 66 uint16_t Release(void); 67 68 int Lock(void); 69 int Unlock(void); 63 70 64 71 int AddFile(const char *pszFile); … … 66 73 int Close(void); 67 74 bool IsOpen(void) const; 68 int OpenEx(const char *pszPath, SHAREDCLIPBOARD DROPPEDFILEFLAGS fFlags = SHAREDCLIPBOARDDROPPEDFILE_FLAGS_NONE);69 int OpenTemp(SHAREDCLIPBOARD DROPPEDFILEFLAGS fFlags = SHAREDCLIPBOARDDROPPEDFILE_FLAGS_NONE);75 int OpenEx(const char *pszPath, SHAREDCLIPBOARDCACHEFLAGS fFlags = SHAREDCLIPBOARDCACHE_FLAGS_NONE); 76 int OpenTemp(SHAREDCLIPBOARDCACHEFLAGS fFlags = SHAREDCLIPBOARDCACHE_FLAGS_NONE); 70 77 const char *GetDirAbs(void) const; 71 78 int Reopen(void); … … 75 82 protected: 76 83 84 int initInternal(void); 85 int destroyInternal(void); 77 86 int closeInternal(void); 78 87 79 88 protected: 80 89 90 /** Number of references to this instance. */ 91 volatile uint16_t m_cRefs; 92 /** Critical section for serializing access. */ 93 RTCRITSECT m_CritSect; 81 94 /** Open flags. */ 82 95 uint32_t m_fOpen; … … 91 104 }; 92 105 93 int SharedClipboard SanitizeFilename(char *pszPath, size_t cbPath);106 int SharedClipboardPathSanitizeFilename(char *pszPath, size_t cbPath); 94 107 int SharedClipboardPathSanitize(char *pszPath, size_t cbPath); 95 108 -
trunk/include/VBox/GuestHost/SharedClipboard-win.h
r78474 r78501 37 37 # ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 38 38 # include <iprt/cpp/ministring.h> /* For RTCString. */ 39 # include <iprt/win/shlobj.h> /* For DROPFILES and friends. */ 39 40 # include <oleidl.h> 40 41 # endif … … 49 50 * Do *not* change the name, as this will break compatbility with other (legacy) applications! */ 50 51 #define VBOX_CLIPBOARD_WIN_REGFMT_HTML "HTML Format" 51 # ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST52 # define VBOX_CLIPBOARD_WIN_REGFMT_URI_LIST "VBoxURIList"53 #endif54 52 55 53 /** Default timeout (in ms) for passing down messages down the clipboard chain. */ … … 127 125 int VBoxClipboardWinRemoveFromCBChain(PVBOXCLIPBOARDWINCTX pCtx); 128 126 VOID CALLBACK VBoxClipboardWinChainPingProc(HWND hWnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult); 127 129 128 VBOXCLIPBOARDFORMAT VBoxClipboardWinClipboardFormatToVBox(UINT uFormat); 130 129 int VBoxClipboardWinGetFormats(PVBOXCLIPBOARDWINCTX pCtx, PVBOXCLIPBOARDFORMAT pfFormats); 131 130 131 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 132 int VBoxClipboardWinDropFilesToStringList(DROPFILES *pDropFiles, void **ppvData, size_t *pcbData); 133 #endif 134 135 int VBoxClipboardWinGetCFHTMLHeaderValue(const char *pszSrc, const char *pszOption, uint32_t *puValue); 136 bool VBoxClipboardWinIsCFHTML(const char *pszSource); 137 int VBoxClipboardWinConvertCFHTMLToMIME(const char *pszSource, const uint32_t cch, char **ppszOutput, uint32_t *pcbOutput); 138 int VBoxClipboardWinConvertMIMEToCFHTML(const char *pszSource, size_t cb, char **ppszOutput, uint32_t *pcbOutput); 139 132 140 # ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 133 141 class SharedClipboardURIList; 142 # ifndef FILEGROUPDESCRIPTOR 134 143 class FILEGROUPDESCRIPTOR; 144 # endif 135 145 136 146 class VBoxClipboardWinDataObject : public IDataObject //, public IDataObjectAsyncCapability -
trunk/src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk
r78476 r78501 56 56 ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 57 57 VBoxTray_SOURCES += \ 58 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardURIList.cpp \ 59 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardURIObject.cpp \ 60 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardPath.cpp \ 58 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardCache.cpp \ 61 59 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp \ 62 60 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardEnumFormatEtcImpl-win.cpp \ 63 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardStreamImpl-win.cpp 61 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardPath.cpp \ 62 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardStreamImpl-win.cpp \ 63 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardURIList.cpp \ 64 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardURIObject.cpp 64 65 endif 65 66 endif -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp
r78474 r78501 79 79 const PVBOXCLIPBOARDWINCTX pWinCtx = &pCtx->Win; 80 80 81 LRESULT rc = 0;81 LRESULT lresultRc = 0; 82 82 83 83 switch (msg) … … 87 87 if (GetClipboardOwner() != hwnd) 88 88 { 89 Log(("WM_CLIPBOARDUPDATE\n")); 90 91 /* Clipboard was updated by another application. */ 89 /* Clipboard was updated by another application. 90 * Report available formats to the host. */ 92 91 VBOXCLIPBOARDFORMATS fFormats; 93 int vboxrc = VBoxClipboardWinGetFormats(&pCtx->Win, &fFormats); 94 if (RT_SUCCESS(vboxrc)) 95 vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, fFormats); 92 int rc = VBoxClipboardWinGetFormats(&pCtx->Win, &fFormats); 93 if (RT_SUCCESS(rc)) 94 rc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, fFormats); 95 96 LogFunc(("WM_CLIPBOARDUPDATE: rc=%Rrc, fFormats=0x%x\n", rc, fFormats)); 96 97 } 98 else 99 LogFlowFunc(("WM_CLIPBOARDUPDATE: No change (VBoxTray is owner)\n")); 97 100 } 98 101 break; … … 102 105 if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) 103 106 { 104 rc = DefWindowProc(hwnd, msg, wParam, lParam);107 lresultRc = DefWindowProc(hwnd, msg, wParam, lParam); 105 108 break; 106 109 } … … 123 126 /* Pass the message further. */ 124 127 DWORD_PTR dwResult; 125 rc = SendMessageTimeout(pWinCtx->hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0,126 VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, &dwResult);127 if (! rc)128 rc = (LRESULT)dwResult;128 lresultRc = SendMessageTimeout(pWinCtx->hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, 129 VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, &dwResult); 130 if (!lresultRc) 131 lresultRc = (LRESULT)dwResult; 129 132 } 130 133 } … … 141 144 /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */ 142 145 VBOXCLIPBOARDFORMATS fFormats; 143 int vboxrc = VBoxClipboardWinGetFormats(pWinCtx, &fFormats);144 if (RT_SUCCESS( vboxrc))145 vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, fFormats);146 int rc = VBoxClipboardWinGetFormats(pWinCtx, &fFormats); 147 if (RT_SUCCESS(rc)) 148 rc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, fFormats); 146 149 } 147 150 … … 197 200 LogFunc(("WM_RENDERFORMAT: cfFormat=%u -> fFormat=0x%x\n", cfFormat, fFormat)); 198 201 199 if (fFormat != VBOX_SHARED_CLIPBOARD_FMT_NONE) 202 if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_NONE) 203 { 204 LogFunc(("WM_RENDERFORMAT: Unsupported format requested\n")); 205 VBoxClipboardWinClear(); 206 } 207 else 200 208 { 201 209 const uint32_t cbPrealloc = _4K; … … 214 222 { 215 223 /* Read the host data to the preallocated buffer. */ 216 int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cbPrealloc, &cb);217 LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n", vboxrc));218 219 if (RT_SUCCESS( vboxrc))224 int rc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cbPrealloc, &cb); 225 LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n", rc)); 226 227 if (RT_SUCCESS(rc)) 220 228 { 221 229 if (cb == 0) … … 245 253 /* Read the host data to the preallocated buffer. */ 246 254 uint32_t cbNew = 0; 247 vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cb, &cbNew);255 rc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cb, &cbNew); 248 256 LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n", 249 vboxrc, cb, cbNew));250 251 if (RT_SUCCESS( vboxrc)257 rc, cb, cbNew)); 258 259 if (RT_SUCCESS(rc) 252 260 && cbNew <= cb) 253 261 { … … 335 343 * windows is to be destroyed and therefore the guest side becomes inactive. 336 344 */ 337 int vboxrc = VBoxClipboardWinOpen(hwnd);338 if (RT_SUCCESS( vboxrc))345 int rc = VBoxClipboardWinOpen(hwnd); 346 if (RT_SUCCESS(rc)) 339 347 { 340 348 VBoxClipboardWinClear(); … … 351 359 LogFunc(("VBOX_WM_SHCLPB_SET_FORMATS: fFormats=0x%x\n", fFormats)); 352 360 353 int vboxrc = VBoxClipboardWinOpen(hwnd);354 if (RT_SUCCESS( vboxrc))361 int rc = VBoxClipboardWinOpen(hwnd); 362 if (RT_SUCCESS(rc)) 355 363 { 356 364 VBoxClipboardWinClear(); … … 366 374 hClip = SetClipboardData(CF_UNICODETEXT, NULL); 367 375 } 368 369 376 else if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 370 377 { … … 372 379 hClip = SetClipboardData(CF_DIB, NULL); 373 380 } 374 375 381 else if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_HTML) 376 382 { … … 380 386 hClip = SetClipboardData(cfFormat, NULL); 381 387 } 382 383 388 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 384 389 else if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST) … … 390 395 if (pWinCtx->URI.pDataObj) 391 396 { 392 int vboxrc = pWinCtx->URI.pDataObj->Init(pCtx->u32ClientID);393 if (RT_SUCCESS( vboxrc))397 rc = pWinCtx->URI.pDataObj->Init(pCtx->u32ClientID); 398 if (RT_SUCCESS(rc)) 394 399 { 395 400 VBoxClipboardWinClose(); … … 429 434 LogFlowFunc(("VBOX_WM_SHCLPB_READ_DATA: u32Formats=0x%x\n", u32Formats)); 430 435 431 int vboxrc = VBoxClipboardWinOpen(hwnd);432 if (RT_SUCCESS( vboxrc))436 int rc = VBoxClipboardWinOpen(hwnd); 437 if (RT_SUCCESS(rc)) 433 438 { 434 439 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 435 440 { 436 441 hClip = GetClipboardData(CF_DIB); 437 438 442 if (hClip != NULL) 439 443 { … … 441 445 if (lp != NULL) 442 446 { 443 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_BITMAP,444 lp, GlobalSize(hClip));447 rc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_BITMAP, 448 lp, GlobalSize(hClip)); 445 449 GlobalUnlock(hClip); 446 450 } … … 454 458 { 455 459 hClip = GetClipboardData(CF_UNICODETEXT); 456 457 460 if (hClip != NULL) 458 461 { 459 462 LPWSTR uniString = (LPWSTR)GlobalLock(hClip); 460 461 463 if (uniString != NULL) 462 464 { 463 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT,464 uniString, (lstrlenW(uniString) + 1) * 2);465 rc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, 466 uniString, (lstrlenW(uniString) + 1) * 2); 465 467 GlobalUnlock(hClip); 466 468 } … … 483 485 if (lp != NULL) 484 486 { 485 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_HTML,486 lp, GlobalSize(hClip));487 rc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_HTML, 488 lp, GlobalSize(hClip)); 487 489 GlobalUnlock(hClip); 488 490 } … … 497 499 else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST) 498 500 { 499 UINT format = RegisterClipboardFormat(VBOX_CLIPBOARD_WIN_REGFMT_URI_LIST); 500 if (format != 0) 501 /* The data data in CF_HDROP format, as the files are locally present and don't need to be 502 * presented as a IDataObject or IStream. */ 503 hClip = GetClipboardData(CF_HDROP); 504 if (hClip) 501 505 { 502 hClip = GetClipboardData(format);503 if (h Clip)506 HDROP hDrop = (HDROP)GlobalLock(hClip); 507 if (hDrop) 504 508 { 505 HDROP hDrop = (HDROP)GlobalLock(hClip); 506 if (hDrop) 507 { 508 /* vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_URI_LIST, 509 );*/ 510 GlobalUnlock(hClip); 511 } 512 else 513 { 514 hClip = NULL; 515 } 509 /* vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_URI_LIST, 510 );*/ 511 GlobalUnlock(hClip); 512 } 513 else 514 { 515 hClip = NULL; 516 516 } 517 517 } … … 543 543 default: 544 544 { 545 rc = DefWindowProc(hwnd, msg, wParam, lParam);545 lresultRc = DefWindowProc(hwnd, msg, wParam, lParam); 546 546 } 547 547 break; … … 549 549 550 550 #ifndef DEBUG_andy 551 LogFlowFunc(("vboxClipboardProcessMsg returned with rc = %ld\n", rc));551 LogFlowFunc(("vboxClipboardProcessMsg returned with lresultRc=%ld\n", lresultRc)); 552 552 #endif 553 return rc;553 return lresultRc; 554 554 } 555 555 -
trunk/src/VBox/GuestHost/SharedClipboard/ClipboardCache.cpp
r78500 r78501 1 1 /* $Id$ */ 2 2 /** @file 3 * Shared Clipboard - Directoryhandling.3 * Shared Clipboard - Cache handling. 4 4 */ 5 5 … … 23 23 #include <VBox/GuestHost/SharedClipboard-uri.h> 24 24 25 #include <iprt/asm.h> 25 26 #include <iprt/assert.h> 26 27 #include <iprt/dir.h> … … 33 34 #include <VBox/log.h> 34 35 35 SharedClipboardDroppedFiles::SharedClipboardDroppedFiles(void) 36 : m_fOpen(0) 37 , m_hDir(NULL) { } 38 39 SharedClipboardDroppedFiles::SharedClipboardDroppedFiles(const char *pszPath, 40 SHAREDCLIPBOARDURIDROPPEDFILEFLAGS fFlags /* = SHAREDCLIPBOARDURIDROPPEDFILE_FLAGS_NONE */) 41 : m_fOpen(0) 36 SharedClipboardCache::SharedClipboardCache(void) 37 : m_cRefs(0) 38 , m_fOpen(0) 42 39 , m_hDir(NULL) 43 40 { 44 OpenEx(pszPath, fFlags); 45 } 46 47 SharedClipboardDroppedFiles::~SharedClipboardDroppedFiles(void) 41 int rc = initInternal(); 42 if (RT_FAILURE(rc)) 43 throw rc; 44 } 45 46 SharedClipboardCache::SharedClipboardCache(const char *pszPath, 47 SHAREDCLIPBOARDCACHEFLAGS fFlags /* = SHAREDCLIPBOARDCACHE_FLAGS_NONE */) 48 : m_cRefs(0) 49 , m_fOpen(0) 50 , m_hDir(NULL) 51 { 52 int rc = initInternal(); 53 if (RT_SUCCESS(rc)) 54 rc = OpenEx(pszPath, fFlags); 55 56 if (RT_FAILURE(rc)) 57 throw rc; 58 } 59 60 SharedClipboardCache::~SharedClipboardCache(void) 48 61 { 49 62 /* Only make sure to not leak any handles and stuff, don't delete any 50 63 * directories / files here. */ 51 64 closeInternal(); 52 } 53 54 int SharedClipboardDroppedFiles::AddFile(const char *pszFile) 65 66 int rc = destroyInternal(); 67 AssertRC(rc); 68 } 69 70 /** 71 * Adds a reference to a Shared Clipboard cache. 72 * 73 * @returns New reference count. 74 */ 75 uint16_t SharedClipboardCache::AddRef(void) 76 { 77 return ASMAtomicIncU16(&m_cRefs); 78 } 79 80 /** 81 * Removes a reference from a Shared Clipboard cache. 82 * 83 * @returns New reference count. 84 */ 85 uint16_t SharedClipboardCache::Release(void) 86 { 87 Assert(m_cRefs); 88 return ASMAtomicDecU16(&m_cRefs); 89 } 90 91 /** 92 * Locks a Shared Clipboard cache. 93 * 94 * @returns VBox status code. 95 */ 96 int SharedClipboardCache::Lock(void) 97 { 98 return RTCritSectEnter(&m_CritSect); 99 } 100 101 /** 102 * Unlocks a Shared Clipboard cache. 103 * 104 * @returns VBox status code. 105 */ 106 int SharedClipboardCache::Unlock(void) 107 { 108 return RTCritSectLeave(&m_CritSect); 109 } 110 111 int SharedClipboardCache::AddFile(const char *pszFile) 55 112 { 56 113 AssertPtrReturn(pszFile, VERR_INVALID_POINTER); … … 61 118 } 62 119 63 int SharedClipboard DroppedFiles::AddDir(const char *pszDir)120 int SharedClipboardCache::AddDir(const char *pszDir) 64 121 { 65 122 AssertPtrReturn(pszDir, VERR_INVALID_POINTER); … … 70 127 } 71 128 72 int SharedClipboardDroppedFiles::closeInternal(void) 129 int SharedClipboardCache::initInternal(void) 130 { 131 return RTCritSectInit(&m_CritSect); 132 } 133 134 int SharedClipboardCache::destroyInternal(void) 135 { 136 return RTCritSectDelete(&m_CritSect); 137 } 138 139 int SharedClipboardCache::closeInternal(void) 73 140 { 74 141 int rc; … … 86 153 } 87 154 88 int SharedClipboard DroppedFiles::Close(void)155 int SharedClipboardCache::Close(void) 89 156 { 90 157 return closeInternal(); 91 158 } 92 159 93 const char *SharedClipboard DroppedFiles::GetDirAbs(void) const160 const char *SharedClipboardCache::GetDirAbs(void) const 94 161 { 95 162 return this->m_strPathAbs.c_str(); 96 163 } 97 164 98 bool SharedClipboard DroppedFiles::IsOpen(void) const165 bool SharedClipboardCache::IsOpen(void) const 99 166 { 100 167 return (this->m_hDir != NULL); 101 168 } 102 169 103 int SharedClipboard DroppedFiles::OpenEx(const char *pszPath, SHAREDCLIPBOARDURIDROPPEDFILEFLAGS fFlags /* = SHAREDCLIPBOARDURIDROPPEDFILE_FLAGS_NONE */)170 int SharedClipboardCache::OpenEx(const char *pszPath, SHAREDCLIPBOARDCACHEFLAGS fFlags /* = SHAREDCLIPBOARDCACHE_FLAGS_NONE */) 104 171 { 105 172 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); … … 168 235 } 169 236 170 int SharedClipboard DroppedFiles::OpenTemp(SHAREDCLIBOARDURIDROPPEDFILEFLAGS fFlags /* = SHAREDCLIPBOARDURIDROPPEDFILE_FLAGS_NONE */)237 int SharedClipboardCache::OpenTemp(SHAREDCLIPBOARDCACHEFLAGS fFlags /* = SHAREDCLIPBOARDCACHE_FLAGS_NONE */) 171 238 { 172 239 AssertReturn(fFlags == 0, VERR_INVALID_PARAMETER); /* Flags not supported yet. */ … … 185 252 } 186 253 187 int SharedClipboard DroppedFiles::Reset(bool fRemoveDropDir)254 int SharedClipboardCache::Reset(bool fRemoveDropDir) 188 255 { 189 256 int rc = closeInternal(); … … 205 272 } 206 273 207 int SharedClipboard DroppedFiles::Reopen(void)274 int SharedClipboardCache::Reopen(void) 208 275 { 209 276 if (this->m_strPathAbs.isEmpty()) … … 213 280 } 214 281 215 int SharedClipboard DroppedFiles::Rollback(void)282 int SharedClipboardCache::Rollback(void) 216 283 { 217 284 if (this->m_strPathAbs.isEmpty()) -
trunk/src/VBox/GuestHost/SharedClipboard/ClipboardPath.cpp
r78390 r78501 64 64 } 65 65 66 /** 67 * Sanitizes a given path regarding invalid / unhandled characters. 68 * Currently not implemented. 69 * 70 * @returns VBox status code. 71 * @param pszPath Path to sanitize. UTF-8. 72 * @param cbPath Size (in bytes) of the path to sanitize. 73 */ 66 74 int SharedClipboardPathSanitize(char *pszPath, size_t cbPath) 67 75 { 68 76 /** @todo */ 69 RT_NOREF 2(pszPath, cbPath);77 RT_NOREF(pszPath, cbPath); 70 78 return VINF_SUCCESS; 71 79 } -
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp
r78474 r78501 22 22 #include <iprt/thread.h> 23 23 24 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 25 # include <iprt/utf16.h> 26 #endif 27 24 28 #define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD 25 29 #include <VBox/log.h> 26 30 27 31 #include <VBox/GuestHost/SharedClipboard.h> 32 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 33 # include <VBox/GuestHost/SharedClipboard-uri.h> 34 #endif 28 35 #include <VBox/GuestHost/SharedClipboard-win.h> 29 36 #include <VBox/GuestHost/clipboard-helper.h> … … 277 284 } 278 285 286 /** 287 * Converts a (registered or standard) Windows clipboard format to a VBox clipboard format. 288 * 289 * @returns Converted VBox clipboard format, or VBOX_SHARED_CLIPBOARD_FMT_NONE if not found. 290 * @param uFormat Windows clipboard format to convert. 291 */ 279 292 VBOXCLIPBOARDFORMAT VBoxClipboardWinClipboardFormatToVBox(UINT uFormat) 280 293 { … … 284 297 switch (uFormat) 285 298 { 286 case CF_UNICODETEXT: 287 vboxFormat = VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; 288 break; 289 290 case CF_DIB: 291 vboxFormat = VBOX_SHARED_CLIPBOARD_FMT_BITMAP; 292 break; 293 294 default: 295 if (uFormat >= 0xC000) /** Formats registered with RegisterClipboardFormat() start at this index. */ 296 { 297 TCHAR szFormatName[256]; /** @todo r=andy Do we need Unicode support here as well? */ 298 int cActual = GetClipboardFormatName(uFormat, szFormatName, sizeof(szFormatName) / sizeof(TCHAR)); 299 if (cActual) 300 { 301 LogFunc(("szFormatName=%s\n", szFormatName)); 302 303 if (RTStrCmp(szFormatName, VBOX_CLIPBOARD_WIN_REGFMT_HTML) == 0) 304 vboxFormat = VBOX_SHARED_CLIPBOARD_FMT_HTML; 299 case CF_UNICODETEXT: 300 vboxFormat = VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; 301 break; 302 303 case CF_DIB: 304 vboxFormat = VBOX_SHARED_CLIPBOARD_FMT_BITMAP; 305 break; 306 305 307 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 306 else if (RTStrCmp(szFormatName, VBOX_CLIPBOARD_WIN_REGFMT_URI_LIST) == 0) 307 vboxFormat = VBOX_SHARED_CLIPBOARD_FMT_URI_LIST; 308 /* Handles file system entries which are locally present 309 * on source for transferring to the target. */ 310 case CF_HDROP: 311 vboxFormat = VBOX_SHARED_CLIPBOARD_FMT_URI_LIST; 312 break; 308 313 #endif 309 } 310 } 311 break; 312 } 313 314 315 default: 316 if (uFormat >= 0xC000) /** Formats registered with RegisterClipboardFormat() start at this index. */ 317 { 318 TCHAR szFormatName[256]; /** @todo r=andy Do we need Unicode support here as well? */ 319 int cActual = GetClipboardFormatName(uFormat, szFormatName, sizeof(szFormatName) / sizeof(TCHAR)); 320 if (cActual) 321 { 322 LogFlowFunc(("uFormat=%u -> szFormatName=%s\n", uFormat, szFormatName)); 323 324 if (RTStrCmp(szFormatName, VBOX_CLIPBOARD_WIN_REGFMT_HTML) == 0) 325 vboxFormat = VBOX_SHARED_CLIPBOARD_FMT_HTML; 326 } 327 } 328 break; 329 } 330 331 LogFlowFunc(("uFormat=%u -> vboxFormat=0x%x\n", uFormat, vboxFormat)); 314 332 return vboxFormat; 315 333 } … … 354 372 } 355 373 374 /** 375 * Extracts a field value from CF_HTML data. 376 * 377 * @returns VBox status code. 378 * @param pszSrc source in CF_HTML format. 379 * @param pszOption Name of CF_HTML field. 380 * @param puValue Where to return extracted value of CF_HTML field. 381 */ 382 int VBoxClipboardWinGetCFHTMLHeaderValue(const char *pszSrc, const char *pszOption, uint32_t *puValue) 383 { 384 AssertPtrReturn(pszSrc, VERR_INVALID_POINTER); 385 AssertPtrReturn(pszOption, VERR_INVALID_POINTER); 386 387 int rc = VERR_INVALID_PARAMETER; 388 389 const char *pszOptionValue = RTStrStr(pszSrc, pszOption); 390 if (pszOptionValue) 391 { 392 size_t cchOption = strlen(pszOption); 393 Assert(cchOption); 394 395 rc = RTStrToUInt32Ex(pszOptionValue + cchOption, NULL, 10, puValue); 396 } 397 return rc; 398 } 399 400 /** 401 * Check that the source string contains CF_HTML struct. 402 * 403 * @returns @c true if the @a pszSource string is in CF_HTML format. 404 * @param pszSource Source string to check. 405 */ 406 bool VBoxClipboardWinIsCFHTML(const char *pszSource) 407 { 408 return RTStrStr(pszSource, "Version:") != NULL 409 && RTStrStr(pszSource, "StartHTML:") != NULL; 410 } 411 412 /** 413 * Converts clipboard data from CF_HTML format to MIME clipboard format. 414 * 415 * Returns allocated buffer that contains html converted to text/html mime type 416 * 417 * @returns VBox status code. 418 * @param pszSource The input. 419 * @param cch The length of the input. 420 * @param ppszOutput Where to return the result. Free using RTMemFree. 421 * @param pcbOutput Where to the return length of the result (bytes/chars). 422 */ 423 int VBoxClipboardWinConvertCFHTMLToMIME(const char *pszSource, const uint32_t cch, char **ppszOutput, uint32_t *pcbOutput) 424 { 425 Assert(pszSource); 426 Assert(cch); 427 Assert(ppszOutput); 428 Assert(pcbOutput); 429 430 uint32_t offStart; 431 int rc = VBoxClipboardWinGetCFHTMLHeaderValue(pszSource, "StartFragment:", &offStart); 432 if (RT_SUCCESS(rc)) 433 { 434 uint32_t offEnd; 435 rc = VBoxClipboardWinGetCFHTMLHeaderValue(pszSource, "EndFragment:", &offEnd); 436 if (RT_SUCCESS(rc)) 437 { 438 if ( offStart > 0 439 && offEnd > 0 440 && offEnd > offStart 441 && offEnd <= cch) 442 { 443 uint32_t cchSubStr = offEnd - offStart; 444 char *pszResult = (char *)RTMemAlloc(cchSubStr + 1); 445 if (pszResult) 446 { 447 rc = RTStrCopyEx(pszResult, cchSubStr + 1, pszSource + offStart, cchSubStr); 448 if (RT_SUCCESS(rc)) 449 { 450 *ppszOutput = pszResult; 451 *pcbOutput = (uint32_t)(cchSubStr + 1); 452 rc = VINF_SUCCESS; 453 } 454 else 455 { 456 LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected EndFragment. rc = %Rrc\n", rc)); 457 RTMemFree(pszResult); 458 } 459 } 460 else 461 { 462 LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected EndFragment\n")); 463 rc = VERR_NO_MEMORY; 464 } 465 } 466 else 467 { 468 LogRelFlowFunc(("Error: CF_HTML out of bounds - offStart=%#x offEnd=%#x cch=%#x\n", offStart, offEnd, cch)); 469 rc = VERR_INVALID_PARAMETER; 470 } 471 } 472 else 473 { 474 LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected EndFragment. rc = %Rrc\n", rc)); 475 rc = VERR_INVALID_PARAMETER; 476 } 477 } 478 else 479 { 480 LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected StartFragment. rc = %Rrc\n", rc)); 481 rc = VERR_INVALID_PARAMETER; 482 } 483 484 return rc; 485 } 486 487 /** 488 * Converts source UTF-8 MIME HTML clipboard data to UTF-8 CF_HTML format. 489 * 490 * This is just encapsulation work, slapping a header on the data. 491 * 492 * It allocates [..] 493 * 494 * Calculations: 495 * Header length = format Length + (2*(10 - 5('%010d'))('digits')) - 2('%s') = format length + 8 496 * EndHtml = Header length + fragment length 497 * StartHtml = 105(constant) 498 * StartFragment = 141(constant) may vary if the header html content will be extended 499 * EndFragment = Header length + fragment length - 38(ending length) 500 * 501 * @param pszSource Source buffer that contains utf-16 string in mime html format 502 * @param cb Size of source buffer in bytes 503 * @param ppszOutput Where to return the allocated output buffer to put converted UTF-8 504 * CF_HTML clipboard data. This function allocates memory for this. 505 * @param pcbOutput Where to return the size of allocated result buffer in bytes/chars, including zero terminator 506 * 507 * @note output buffer should be free using RTMemFree() 508 * @note Everything inside of fragment can be UTF8. Windows allows it. Everything in header should be Latin1. 509 */ 510 int VBoxClipboardWinConvertMIMEToCFHTML(const char *pszSource, size_t cb, char **ppszOutput, uint32_t *pcbOutput) 511 { 512 Assert(ppszOutput); 513 Assert(pcbOutput); 514 Assert(pszSource); 515 Assert(cb); 516 517 /* construct CF_HTML formatted string */ 518 char *pszResult = NULL; 519 size_t cchFragment; 520 int rc = RTStrNLenEx(pszSource, cb, &cchFragment); 521 if (!RT_SUCCESS(rc)) 522 { 523 LogRelFlowFunc(("Error: invalid source fragment. rc = %Rrc\n")); 524 return VERR_INVALID_PARAMETER; 525 } 526 527 /* 528 @StartHtml - pos before <html> 529 @EndHtml - whole size of text excluding ending zero char 530 @StartFragment - pos after <!--StartFragment--> 531 @EndFragment - pos before <!--EndFragment--> 532 @note: all values includes CR\LF inserted into text 533 Calculations: 534 Header length = format Length + (3*6('digits')) - 2('%s') = format length + 16 (control value - 183) 535 EndHtml = Header length + fragment length 536 StartHtml = 105(constant) 537 StartFragment = 143(constant) 538 EndFragment = Header length + fragment length - 40(ending length) 539 */ 540 static const char s_szFormatSample[] = 541 /* 0: */ "Version:1.0\r\n" 542 /* 13: */ "StartHTML:000000101\r\n" 543 /* 34: */ "EndHTML:%0000009u\r\n" // END HTML = Header length + fragment length 544 /* 53: */ "StartFragment:000000137\r\n" 545 /* 78: */ "EndFragment:%0000009u\r\n" 546 /* 101: */ "<html>\r\n" 547 /* 109: */ "<body>\r\n" 548 /* 117: */ "<!--StartFragment-->" 549 /* 137: */ "%s" 550 /* 137+2: */ "<!--EndFragment-->\r\n" 551 /* 157+2: */ "</body>\r\n" 552 /* 166+2: */ "</html>\r\n"; 553 /* 175+2: */ 554 AssertCompile(sizeof(s_szFormatSample) == 175 + 2 + 1); 555 556 /* calculate parameters of CF_HTML header */ 557 size_t cchHeader = sizeof(s_szFormatSample) - 1; 558 size_t offEndHtml = cchHeader + cchFragment; 559 size_t offEndFragment = cchHeader + cchFragment - 38; /* 175-137 = 38 */ 560 pszResult = (char *)RTMemAlloc(offEndHtml + 1); 561 if (pszResult == NULL) 562 { 563 LogRelFlowFunc(("Error: Cannot allocate memory for result buffer. rc = %Rrc\n")); 564 return VERR_NO_MEMORY; 565 } 566 567 /* format result CF_HTML string */ 568 size_t cchFormatted = RTStrPrintf(pszResult, offEndHtml + 1, 569 s_szFormatSample, offEndHtml, offEndFragment, pszSource); 570 Assert(offEndHtml == cchFormatted); NOREF(cchFormatted); 571 572 #ifdef VBOX_STRICT 573 /* Control calculations. check consistency.*/ 574 static const char s_szStartFragment[] = "<!--StartFragment-->"; 575 static const char s_szEndFragment[] = "<!--EndFragment-->"; 576 577 /* check 'StartFragment:' value */ 578 const char *pszRealStartFragment = RTStrStr(pszResult, s_szStartFragment); 579 Assert(&pszRealStartFragment[sizeof(s_szStartFragment) - 1] - pszResult == 137); 580 581 /* check 'EndFragment:' value */ 582 const char *pszRealEndFragment = RTStrStr(pszResult, s_szEndFragment); 583 Assert((size_t)(pszRealEndFragment - pszResult) == offEndFragment); 584 #endif 585 586 *ppszOutput = pszResult; 587 *pcbOutput = (uint32_t)cchFormatted + 1; 588 Assert(*pcbOutput == cchFormatted + 1); 589 590 return VINF_SUCCESS; 591 } 592 593 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 594 /** 595 * Converts a DROPFILES (HDROP) structure to a string list, separated by \r\n. 596 * 597 * @returns VBox status code. 598 * @param pDropFiles Pointer to DROPFILES structure to convert. 599 * @param ppvData Where to return the converted (allocated) data on success. 600 * @param pcbData Size (in bytes) of the allocated data returned. 601 */ 602 int VBoxClipboardWinDropFilesToStringList(DROPFILES *pDropFiles, void **ppvData, size_t *pcbData) 603 { 604 AssertPtrReturn(pDropFiles, VERR_INVALID_POINTER); 605 AssertPtrReturn(ppvData, VERR_INVALID_POINTER); 606 AssertPtrReturn(pcbData, VERR_INVALID_POINTER); 607 608 /* Do we need to do Unicode stuff? */ 609 const bool fUnicode = RT_BOOL(pDropFiles->fWide); 610 611 /* Get the offset of the file list. */ 612 Assert(pDropFiles->pFiles >= sizeof(DROPFILES)); 613 614 /* Note: This is *not* pDropFiles->pFiles! DragQueryFile only 615 * will work with the plain storage medium pointer! */ 616 HDROP hDrop = (HDROP)(pDropFiles); 617 618 int rc = VINF_SUCCESS; 619 620 /* First, get the file count. */ 621 /** @todo Does this work on Windows 2000 / NT4? */ 622 char *pszFiles = NULL; 623 uint32_t cchFiles = 0; 624 UINT cFiles = DragQueryFile(hDrop, UINT32_MAX /* iFile */, NULL /* lpszFile */, 0 /* cchFile */); 625 626 LogFlowFunc(("Got %RU16 file(s), fUnicode=%RTbool\n", cFiles, fUnicode)); 627 628 for (UINT i = 0; i < cFiles; i++) 629 { 630 UINT cchFile = DragQueryFile(hDrop, i /* File index */, NULL /* Query size first */, 0 /* cchFile */); 631 Assert(cchFile); 632 633 if (RT_FAILURE(rc)) 634 break; 635 636 char *pszFileUtf8 = NULL; /* UTF-8 version. */ 637 UINT cchFileUtf8 = 0; 638 if (fUnicode) 639 { 640 /* Allocate enough space (including terminator). */ 641 WCHAR *pwszFile = (WCHAR *)RTMemAlloc((cchFile + 1) * sizeof(WCHAR)); 642 if (pwszFile) 643 { 644 const UINT cwcFileUtf16 = DragQueryFileW(hDrop, i /* File index */, 645 pwszFile, cchFile + 1 /* Include terminator */); 646 647 AssertMsg(cwcFileUtf16 == cchFile, ("cchFileUtf16 (%RU16) does not match cchFile (%RU16)\n", 648 cwcFileUtf16, cchFile)); 649 RT_NOREF(cwcFileUtf16); 650 651 rc = RTUtf16ToUtf8(pwszFile, &pszFileUtf8); 652 if (RT_SUCCESS(rc)) 653 { 654 cchFileUtf8 = (UINT)strlen(pszFileUtf8); 655 Assert(cchFileUtf8); 656 } 657 658 RTMemFree(pwszFile); 659 } 660 else 661 rc = VERR_NO_MEMORY; 662 } 663 else /* ANSI */ 664 { 665 /* Allocate enough space (including terminator). */ 666 pszFileUtf8 = (char *)RTMemAlloc((cchFile + 1) * sizeof(char)); 667 if (pszFileUtf8) 668 { 669 cchFileUtf8 = DragQueryFileA(hDrop, i /* File index */, 670 pszFileUtf8, cchFile + 1 /* Include terminator */); 671 672 AssertMsg(cchFileUtf8 == cchFile, ("cchFileUtf8 (%RU16) does not match cchFile (%RU16)\n", 673 cchFileUtf8, cchFile)); 674 } 675 else 676 rc = VERR_NO_MEMORY; 677 } 678 679 if (RT_SUCCESS(rc)) 680 { 681 LogFlowFunc(("\tFile: %s (cchFile=%RU16)\n", pszFileUtf8, cchFileUtf8)); 682 683 LogRel(("DnD: Adding guest file '%s'\n", pszFileUtf8)); 684 685 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, pszFileUtf8, cchFileUtf8); 686 if (RT_SUCCESS(rc)) 687 cchFiles += cchFileUtf8; 688 } 689 else 690 LogFunc(("Error handling file entry #%u, rc=%Rrc\n", i, rc)); 691 692 if (pszFileUtf8) 693 RTStrFree(pszFileUtf8); 694 695 if (RT_FAILURE(rc)) 696 break; 697 698 /* Add separation between filenames. 699 * Note: Also do this for the last element of the list. */ 700 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, "\r\n", 2 /* Bytes */); 701 if (RT_SUCCESS(rc)) 702 cchFiles += 2; /* Include \r\n */ 703 } 704 705 if (RT_SUCCESS(rc)) 706 { 707 cchFiles += 1; /* Add string termination. */ 708 uint32_t cbFiles = cchFiles * sizeof(char); 709 710 LogFlowFunc(("cFiles=%u, cchFiles=%RU32, cbFiles=%RU32, pszFiles=0x%p\n", 711 cFiles, cchFiles, cbFiles, pszFiles)); 712 713 /* Translate the list into URI elements. */ 714 SharedClipboardURIList lstURI; 715 rc = lstURI.AppendNativePathsFromList(pszFiles, cbFiles, 716 SHAREDCLIPBOARDURILIST_FLAGS_ABSOLUTE_PATHS); 717 if (RT_SUCCESS(rc)) 718 { 719 RTCString strRoot = lstURI.GetRootEntries(); 720 size_t cbRoot = strRoot.length() + 1; /* Include termination */ 721 722 void *pvData = RTMemAlloc(cbRoot); 723 if (pvData) 724 { 725 memcpy(pvData, strRoot.c_str(), cbRoot); 726 727 *ppvData = pvData; 728 *pcbData = cbRoot; 729 } 730 else 731 rc = VERR_NO_MEMORY; 732 } 733 } 734 735 LogFlowFunc(("Building CF_HDROP list rc=%Rrc, pszFiles=0x%p, cFiles=%RU16, cchFiles=%RU32\n", 736 rc, pszFiles, cFiles, cchFiles)); 737 738 if (pszFiles) 739 RTStrFree(pszFiles); 740 741 return rc; 742 } 743 #endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */ 744 -
trunk/src/VBox/HostServices/SharedClipboard/Makefile.kmk
r78440 r78501 45 45 ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 46 46 VBoxSharedClipboard_SOURCES += \ 47 VBoxSharedClipboardSvc-uri.cpp \ 48 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardPath.cpp \ 49 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardCache.cpp \ 47 50 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardURIList.cpp \ 48 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardURIObject.cpp \ 49 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardPath.cpp 51 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardURIObject.cpp 50 52 endif 51 53 if1of ($(KBUILD_TARGET), linux solaris freebsd) ## @todo X11 -
trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard.h
r78151 r78501 1 1 /* $Id$ */ 2 2 /** @file 3 * Shared Clipboard Service - Internal Header.3 * Shared Clipboard Service - Internal header. 4 4 */ 5 5 … … 36 36 uint32_t u32ClientID; 37 37 38 bool fAsync; /* Guest is waiting for a message. */ 39 bool fReadPending; /* The guest is waiting for data from the host */ 40 41 bool fMsgQuit; 42 bool fMsgReadData; 43 bool fMsgFormats; 38 /** The guest is waiting for a message. */ 39 bool fAsync; 40 /** The guest is waiting for data from the host */ 41 bool fReadPending; 42 /** Whether the host host has sent a quit message. */ 43 bool fHostMsgQuit; 44 /** Whether the host host has requested reading clipboard data from the guest. */ 45 bool fHostMsgReadData; 46 /** Whether the host host has reported its available formats. */ 47 bool fHostMsgFormats; 44 48 45 49 struct { … … 67 71 * The service functions. Locking is between the service thread and the platform dependent windows thread. 68 72 */ 69 void vboxSvcClipboardReportMsg (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Msg, uint32_t u32Formats);73 void vboxSvcClipboardReportMsg(VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Msg, uint32_t u32Formats); 70 74 void vboxSvcClipboardCompleteReadData(VBOXCLIPBOARDCLIENTDATA *pClient, int rc, uint32_t cbActual); 71 75 … … 73 77 * Platform dependent functions. 74 78 */ 75 int vboxClipboardInit (void);76 void vboxClipboardDestroy (void);79 int vboxClipboardInit(void); 80 void vboxClipboardDestroy(void); 77 81 78 int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient, bool fHeadless);79 void vboxClipboardDisconnect (VBOXCLIPBOARDCLIENTDATA *pClient);80 void vboxClipboardFormatAnnounce (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Formats);81 int vboxClipboardReadData (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Format, void *pv, uint32_t cb, uint32_t *pcbActual);82 void vboxClipboardWriteData (VBOXCLIPBOARDCLIENTDATA *pClient, void *pv, uint32_t cb, uint32_t u32Format);82 int vboxClipboardConnect(VBOXCLIPBOARDCLIENTDATA *pClient, bool fHeadless); 83 void vboxClipboardDisconnect(VBOXCLIPBOARDCLIENTDATA *pClient); 84 void vboxClipboardFormatAnnounce(VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Formats); 85 int vboxClipboardReadData(VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Format, void *pv, uint32_t cb, uint32_t *pcbActual); 86 void vboxClipboardWriteData(VBOXCLIPBOARDCLIENTDATA *pClient, void *pv, uint32_t cb, uint32_t u32Format); 83 87 84 88 int vboxClipboardSync (VBOXCLIPBOARDCLIENTDATA *pClient); -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp
r78440 r78501 52 52 * Internal Functions * 53 53 *********************************************************************************************************************************/ 54 static int ConvertCFHtmlToMime(const char *pszSource, const uint32_t cch, char **ppszOutput, uint32_t *pch); 55 static int ConvertMimeToCFHTML(const char *pszSource, size_t cb, char **ppszOutput, uint32_t *pcbOutput); 56 static bool IsWindowsHTML(const char *source); 57 static int vboxClipboardSyncInternal(PVBOXCLIPBOARDCONTEXT pCtx); 54 static int vboxClipboardWinSyncInternal(PVBOXCLIPBOARDCONTEXT pCtx); 58 55 59 56 struct _VBOXCLIPBOARDCONTEXT … … 122 119 123 120 if ( u32Format == VBOX_SHARED_CLIPBOARD_FMT_HTML 124 && IsWindowsHTML((const char *)pvSrc))121 && VBoxClipboardWinIsCFHTML((const char *)pvSrc)) 125 122 { 126 123 /** @todo r=bird: Why the double conversion? */ 127 124 char *pszBuf = NULL; 128 125 uint32_t cbBuf = 0; 129 int rc = ConvertCFHtmlToMime((const char *)pvSrc, cbSrc, &pszBuf, &cbBuf);126 int rc = VBoxClipboardWinConvertCFHTMLToMIME((const char *)pvSrc, cbSrc, &pszBuf, &cbBuf); 130 127 if (RT_SUCCESS(rc)) 131 128 { … … 176 173 static LRESULT CALLBACK vboxClipboardWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 177 174 { 178 LRESULT rc = 0;175 LRESULT lresultRc = 0; 179 176 180 177 const PVBOXCLIPBOARDCONTEXT pCtx = &g_ctx; … … 190 187 { 191 188 /* Clipboard was updated by another application, retrieve formats and report back. */ 192 int vboxrc = vboxClipboardSyncInternal(pCtx);193 AssertRC( vboxrc);189 int rc = vboxClipboardWinSyncInternal(pCtx); 190 AssertRC(rc); 194 191 } 195 192 } break; … … 201 198 if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) 202 199 { 203 rc = DefWindowProc(hwnd, msg, wParam, lParam);200 lresultRc = DefWindowProc(hwnd, msg, wParam, lParam); 204 201 break; 205 202 } … … 221 218 /* Pass the message further. */ 222 219 DWORD_PTR dwResult; 223 rc = SendMessageTimeout(pWinCtx->hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0,224 VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS,225 &dwResult);226 if (! rc)227 rc = (LRESULT)dwResult;220 lresultRc = SendMessageTimeout(pWinCtx->hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, 221 VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, 222 &dwResult); 223 if (!lresultRc) 224 lresultRc = (LRESULT)dwResult; 228 225 } 229 226 } … … 237 234 { 238 235 /* Clipboard was updated by another application, retrieve formats and report back. */ 239 int vboxrc = vboxClipboard SyncInternal(pCtx);236 int vboxrc = vboxClipboardWinSyncInternal(pCtx); 240 237 AssertRC(vboxrc); 241 238 } … … 244 241 { 245 242 LogFunc(("WM_DRAWCLIPBOARD next %p\n", pWinCtx->hWndNextInChain)); 243 246 244 /* Pass the message to next windows in the clipboard chain. */ 247 245 DWORD_PTR dwResult; 248 rc = SendMessageTimeout(pWinCtx->hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS,249 &dwResult);250 if (! rc)251 rc = dwResult;246 lresultRc = SendMessageTimeout(pWinCtx->hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, 247 &dwResult); 248 if (!lresultRc) 249 lresultRc = dwResult; 252 250 } 253 251 } break; … … 281 279 case WM_RENDERFORMAT: 282 280 { 281 LogFunc(("WM_RENDERFORMAT\n")); 282 283 283 /* Insert the requested clipboard format data into the clipboard. */ 284 VBOXCLIPBOARDFORMAT fFormat = VBOX_SHARED_CLIPBOARD_FMT_NONE; 285 286 UINT format = (UINT)wParam; 287 288 LogFunc(("WM_RENDERFORMAT: Format %u\n", format)); 289 290 switch (format) 291 { 292 case CF_UNICODETEXT: 293 fFormat |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; 294 break; 295 296 case CF_DIB: 297 fFormat |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP; 298 break; 299 300 default: 301 if (format >= 0xC000) 302 { 303 TCHAR szFormatName[256]; /** @todo r=andy Unicode, 256 is enough? */ 304 int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName) / sizeof (TCHAR)); 305 if (cActual) 306 { 307 if (RTStrCmp(szFormatName, "HTML Format") == 0) 308 fFormat |= VBOX_SHARED_CLIPBOARD_FMT_HTML; 309 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 310 if ( RTStrCmp(szFormatName, CFSTR_FILEDESCRIPTOR) == 0 311 || RTStrCmp(szFormatName, CFSTR_FILECONTENTS) == 0) 312 fFormat |= VBOX_SHARED_CLIPBOARD_FMT_URI_LIST; 313 #endif 314 } 315 } 316 break; 317 } 284 const UINT cfFormat = (UINT)wParam; 285 286 const VBOXCLIPBOARDFORMAT fFormat = VBoxClipboardWinClipboardFormatToVBox(cfFormat); 287 288 LogFunc(("WM_RENDERFORMAT: cfFormat=%u -> fFormat=0x%x\n", cfFormat, fFormat)); 318 289 319 290 if ( fFormat == VBOX_SHARED_CLIPBOARD_FMT_NONE … … 322 293 /* Unsupported clipboard format is requested. */ 323 294 LogFunc(("WM_RENDERFORMAT unsupported format requested or client is not active\n")); 324 EmptyClipboard();295 VBoxClipboardWinClear(); 325 296 } 326 297 else 327 298 { 328 int vboxrc = vboxClipboardReadDataFromClient(pCtx, fFormat);329 330 LogFunc(("vboxClipboardReadDataFromClient vboxrc = %d, pv %p, cb %d, u32Format %d\n",331 vboxrc, pCtx->pClient->data.pv, pCtx->pClient->data.cb, pCtx->pClient->data.u32Format));332 333 if ( RT_SUCCESS ( vboxrc)299 int rc = vboxClipboardReadDataFromClient(pCtx, fFormat); 300 301 LogFunc(("vboxClipboardReadDataFromClient rc = %Rrc, pv %p, cb %d, u32Format %d\n", 302 rc, pCtx->pClient->data.pv, pCtx->pClient->data.cb, pCtx->pClient->data.u32Format)); 303 304 if ( RT_SUCCESS (rc) 334 305 && pCtx->pClient->data.pv != NULL 335 306 && pCtx->pClient->data.cb > 0 … … 367 338 * size is 'cb' and format is 'format'. 368 339 */ 369 HANDLE hClip = SetClipboardData( format, hMem);340 HANDLE hClip = SetClipboardData(cfFormat, hMem); 370 341 371 342 LogFunc(("vboxClipboardHostEvent hClip %p\n", hClip)); … … 399 370 * windows is to be destroyed and therefore the guest side becomes inactive. 400 371 */ 401 int vboxrc = VBoxClipboardWinOpen(hwnd);402 if (RT_SUCCESS( vboxrc))372 int rc = VBoxClipboardWinOpen(hwnd); 373 if (RT_SUCCESS(rc)) 403 374 { 404 375 VBoxClipboardWinClear(); 405 376 VBoxClipboardWinClose(); 406 377 } 407 else408 {409 LogFlowFunc(("WM_RENDERALLFORMATS: error in open clipboard. hwnd: %x, rc: %Rrc\n", hwnd, vboxrc));410 }411 378 } break; 412 379 413 380 case VBOX_CLIPBOARD_WM_SET_FORMATS: 414 381 { 415 if (pCtx->pClient == NULL || pCtx->pClient->fMsgFormats) 382 if ( pCtx->pClient == NULL 383 || pCtx->pClient->fHostMsgFormats) 416 384 { 417 385 /* Host has pending formats message. Ignore the guest announcement, … … 423 391 424 392 /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */ 425 uint32_t u32Formats = (uint32_t)lParam;426 427 LogFunc(("VBOX_CLIPBOARD_WM_SET_FORMATS: u32Formats=%02X\n", u32Formats));428 429 int vboxrc = VBoxClipboardWinOpen(hwnd);430 if (RT_SUCCESS( vboxrc))393 VBOXCLIPBOARDFORMATS fFormats = (uint32_t)lParam; 394 395 LogFunc(("VBOX_CLIPBOARD_WM_SET_FORMATS: fFormats=%02X\n", fFormats)); 396 397 int rc = VBoxClipboardWinOpen(hwnd); 398 if (RT_SUCCESS(rc)) 431 399 { 432 400 VBoxClipboardWinClear(); 433 401 434 LogFunc(("VBOX_CLIPBOARD_WM_SET_FORMATS emptied clipboard\n")); 435 436 HANDLE hClip = NULL; 437 438 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 402 HANDLE hClip = NULL; 403 UINT cfFormat = 0; 404 405 /** @todo r=andy Only one clipboard format can be set at once, at least on Windows. */ 406 407 if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 408 { 439 409 hClip = SetClipboardData(CF_UNICODETEXT, NULL); 440 441 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 410 } 411 else if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 412 { 442 413 hClip = SetClipboardData(CF_DIB, NULL); 443 444 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML) 445 { 446 UINT format = RegisterClipboardFormat ("HTML Format"); 447 if (format != 0) 448 { 449 hClip = SetClipboardData (format, NULL); 450 } 414 } 415 else if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_HTML) 416 { 417 cfFormat = RegisterClipboardFormat(VBOX_CLIPBOARD_WIN_REGFMT_HTML); 418 if (cfFormat) 419 hClip = SetClipboardData(cfFormat, NULL); 451 420 } 452 421 453 422 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 454 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST) 455 { 456 UINT format = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR); 457 if (format) 458 hClip = SetClipboardData(format, NULL); 459 } 423 /** @todo */ 460 424 #endif 461 425 VBoxClipboardWinClose(); … … 480 444 { 481 445 LogFunc(("WM_ %p\n", msg)); 482 rc = DefWindowProc(hwnd, msg, wParam, lParam);483 } 484 } 485 486 LogFunc(("WM_ rc %d\n", rc));487 return rc;446 lresultRc = DefWindowProc(hwnd, msg, wParam, lParam); 447 } 448 } 449 450 LogFunc(("WM_ rc %d\n", lresultRc)); 451 return lresultRc; 488 452 } 489 453 … … 575 539 * @param pCtx Clipboard context to synchronize. 576 540 */ 577 static int vboxClipboard SyncInternal(PVBOXCLIPBOARDCONTEXT pCtx)541 static int vboxClipboardWinSyncInternal(PVBOXCLIPBOARDCONTEXT pCtx) 578 542 { 579 543 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 663 627 { 664 628 /* Sync the host clipboard content with the client. */ 665 return vboxClipboard SyncInternal(pClient->pCtx);629 return vboxClipboardWinSyncInternal(pClient->pCtx); 666 630 } 667 631 … … 783 747 else if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_HTML) 784 748 { 785 UINT format = RegisterClipboardFormat( "HTML Format");749 UINT format = RegisterClipboardFormat(VBOX_CLIPBOARD_WIN_REGFMT_HTML); 786 750 if (format != 0) 787 751 { … … 792 756 if (lp != NULL) 793 757 { 794 LogFunc(("CF_HTML\n")); 795 758 /** @todo r=andy Add data overflow handling. */ 796 759 vboxClipboardGetData(VBOX_SHARED_CLIPBOARD_FMT_HTML, lp, GlobalSize(hClip), 797 760 pv, cb, pcbActual); … … 813 776 { 814 777 hClip = GetClipboardData(CF_HDROP); 815 if (hClip != NULL) 778 if (hClip != NULL) /* Do we have data in CF_HDROP format? */ 816 779 { 817 780 LPVOID lp = GlobalLock(hClip); 818 781 if (lp) 819 782 { 820 /* Convert to a string list, separated by \r\n. */ 821 DROPFILES *pDropFiles = (DROPFILES *)hClip; 822 AssertPtr(pDropFiles); 823 824 /* Do we need to do Unicode stuff? */ 825 const bool fUnicode = RT_BOOL(pDropFiles->fWide); 826 827 /* Get the offset of the file list. */ 828 Assert(pDropFiles->pFiles >= sizeof(DROPFILES)); 829 830 /* Note: This is *not* pDropFiles->pFiles! DragQueryFile only 831 * will work with the plain storage medium pointer! */ 832 HDROP hDrop = (HDROP)(hClip); 833 834 /* First, get the file count. */ 835 /** @todo Does this work on Windows 2000 / NT4? */ 836 char *pszFiles = NULL; 837 uint32_t cchFiles = 0; 838 UINT cFiles = DragQueryFile(hDrop, UINT32_MAX /* iFile */, NULL /* lpszFile */, 0 /* cchFile */); 839 840 LogRel(("Shared Clipboard: Got %RU16 file(s), fUnicode=%RTbool\n", cFiles, fUnicode)); 841 842 for (UINT i = 0; i < cFiles; i++) 843 { 844 UINT cchFile = DragQueryFile(hDrop, i /* File index */, NULL /* Query size first */, 0 /* cchFile */); 845 Assert(cchFile); 846 847 if (RT_FAILURE(rc)) 848 break; 849 850 char *pszFileUtf8 = NULL; /* UTF-8 version. */ 851 UINT cchFileUtf8 = 0; 852 if (fUnicode) 853 { 854 /* Allocate enough space (including terminator). */ 855 WCHAR *pwszFile = (WCHAR *)RTMemAlloc((cchFile + 1) * sizeof(WCHAR)); 856 if (pwszFile) 857 { 858 const UINT cwcFileUtf16 = DragQueryFileW(hDrop, i /* File index */, 859 pwszFile, cchFile + 1 /* Include terminator */); 860 861 AssertMsg(cwcFileUtf16 == cchFile, ("cchFileUtf16 (%RU16) does not match cchFile (%RU16)\n", 862 cwcFileUtf16, cchFile)); 863 RT_NOREF(cwcFileUtf16); 864 865 rc = RTUtf16ToUtf8(pwszFile, &pszFileUtf8); 866 if (RT_SUCCESS(rc)) 867 { 868 cchFileUtf8 = (UINT)strlen(pszFileUtf8); 869 Assert(cchFileUtf8); 870 } 871 872 RTMemFree(pwszFile); 873 } 874 else 875 rc = VERR_NO_MEMORY; 876 } 877 else /* ANSI */ 878 { 879 /* Allocate enough space (including terminator). */ 880 pszFileUtf8 = (char *)RTMemAlloc((cchFile + 1) * sizeof(char)); 881 if (pszFileUtf8) 882 { 883 cchFileUtf8 = DragQueryFileA(hDrop, i /* File index */, 884 pszFileUtf8, cchFile + 1 /* Include terminator */); 885 886 AssertMsg(cchFileUtf8 == cchFile, ("cchFileUtf8 (%RU16) does not match cchFile (%RU16)\n", 887 cchFileUtf8, cchFile)); 888 } 889 else 890 rc = VERR_NO_MEMORY; 891 } 892 893 if (RT_SUCCESS(rc)) 894 { 895 LogFlowFunc(("\tFile: %s (cchFile=%RU16)\n", pszFileUtf8, cchFileUtf8)); 896 897 LogRel2(("Shared Clipboard: Adding host file '%s'\n", pszFileUtf8)); 898 899 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, pszFileUtf8, cchFileUtf8); 900 if (RT_SUCCESS(rc)) 901 cchFiles += cchFileUtf8; 902 } 903 else 904 LogRel(("Shared Clipboard: Error handling file entry #%u, rc=%Rrc\n", i, rc)); 905 906 if (pszFileUtf8) 907 RTStrFree(pszFileUtf8); 908 909 if (RT_FAILURE(rc)) 910 break; 911 912 /* Add separation between filenames. 913 * Note: Also do this for the last element of the list. */ 914 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, "\r\n", 2 /* Bytes */); 915 if (RT_SUCCESS(rc)) 916 cchFiles += 2; /* Include \r\n */ 917 } 918 783 void *pvTemp; 784 size_t cbTemp; 785 rc = VBoxClipboardWinDropFilesToStringList((DROPFILES *)lp, &pvTemp, &cbTemp); 919 786 if (RT_SUCCESS(rc)) 920 787 { 921 cchFiles += 1; /* Add string termination. */ 922 uint32_t cbFiles = cchFiles * sizeof(char); 923 924 LogFlowFunc(("cFiles=%u, cchFiles=%RU32, cbFiles=%RU32, pszFiles=0x%p\n", 925 cFiles, cchFiles, cbFiles, pszFiles)); 926 927 /* Translate the list into URI elements. */ 928 SharedClipboardURIList lstURI; 929 rc = lstURI.AppendNativePathsFromList(pszFiles, cbFiles, 930 SHAREDCLIPBOARDURILIST_FLAGS_ABSOLUTE_PATHS); 931 if (RT_SUCCESS(rc)) 788 if (cbTemp > cb) /** @todo Add overflow handling! */ 932 789 { 933 RTCString strRoot = lstURI.GetRootEntries(); 934 size_t cbRoot = strRoot.length() + 1; /* Include termination */ 935 936 if (cbRoot > cb) /** @todo Add overflow handling! */ 937 cbRoot = cb; /* Never copy more than the available buffer supplies. */ 938 939 memcpy(pv, strRoot.c_str(), cbRoot); 940 941 *pcbActual = (uint32_t)cbRoot; 790 AssertMsgFailed(("More data buffer needed -- fix this\n")); 791 cbTemp = cb; /* Never copy more than the available buffer supplies. */ 942 792 } 793 794 memcpy(pv, pvTemp, cbTemp); 795 796 RTMemFree(pvTemp); 797 798 *pcbActual = (uint32_t)cbTemp; 943 799 } 944 945 LogFlowFunc(("Building CF_HDROP list rc=%Rrc, pszFiles=0x%p, cFiles=%RU16, cchFiles=%RU32\n",946 rc, pszFiles, cFiles, cchFiles));947 948 if (pszFiles)949 RTStrFree(pszFiles);950 800 951 801 GlobalUnlock(hClip); … … 982 832 983 833 if ( u32Format == VBOX_SHARED_CLIPBOARD_FMT_HTML 984 && ! IsWindowsHTML((const char*)pv))834 && !VBoxClipboardWinIsCFHTML((const char*)pv)) 985 835 { 986 836 /* check that this is not already CF_HTML */ 987 837 uint32_t cbResult; 988 int rc = ConvertMimeToCFHTML((const char *)pv, cb, &pszResult, &cbResult);838 int rc = VBoxClipboardWinConvertMIMEToCFHTML((const char *)pv, cb, &pszResult, &cbResult); 989 839 if (RT_SUCCESS(rc)) 990 840 { … … 1015 865 } 1016 866 1017 1018 /**1019 * Extracts field value from CF_HTML struct1020 *1021 * @returns VBox status code1022 * @param pszSrc source in CF_HTML format1023 * @param pszOption Name of CF_HTML field1024 * @param puValue Where to return extracted value of CF_HTML field1025 */1026 static int GetHeaderValue(const char *pszSrc, const char *pszOption, uint32_t *puValue)1027 {1028 int rc = VERR_INVALID_PARAMETER;1029 1030 Assert(pszSrc);1031 Assert(pszOption);1032 1033 const char *pszOptionValue = RTStrStr(pszSrc, pszOption);1034 if (pszOptionValue)1035 {1036 size_t cchOption = strlen(pszOption);1037 Assert(cchOption);1038 1039 rc = RTStrToUInt32Ex(pszOptionValue + cchOption, NULL, 10, puValue);1040 }1041 return rc;1042 }1043 1044 1045 /**1046 * Check that the source string contains CF_HTML struct1047 *1048 * @param pszSource source string.1049 *1050 * @returns @c true if the @a pszSource string is in CF_HTML format1051 */1052 static bool IsWindowsHTML(const char *pszSource)1053 {1054 return RTStrStr(pszSource, "Version:") != NULL1055 && RTStrStr(pszSource, "StartHTML:") != NULL;1056 }1057 1058 1059 /**1060 * Converts clipboard data from CF_HTML format to MIME clipboard format.1061 *1062 * Returns allocated buffer that contains html converted to text/html mime type1063 *1064 * @returns VBox status code.1065 * @param pszSource The input.1066 * @param cch The length of the input.1067 * @param ppszOutput Where to return the result. Free using RTMemFree.1068 * @param pcbOutput Where to the return length of the result (bytes/chars).1069 */1070 static int ConvertCFHtmlToMime(const char *pszSource, const uint32_t cch, char **ppszOutput, uint32_t *pcbOutput)1071 {1072 Assert(pszSource);1073 Assert(cch);1074 Assert(ppszOutput);1075 Assert(pcbOutput);1076 1077 uint32_t offStart;1078 int rc = GetHeaderValue(pszSource, "StartFragment:", &offStart);1079 if (RT_SUCCESS(rc))1080 {1081 uint32_t offEnd;1082 rc = GetHeaderValue(pszSource, "EndFragment:", &offEnd);1083 if (RT_SUCCESS(rc))1084 {1085 if ( offStart > 01086 && offEnd > 01087 && offEnd > offStart1088 && offEnd <= cch)1089 {1090 uint32_t cchSubStr = offEnd - offStart;1091 char *pszResult = (char *)RTMemAlloc(cchSubStr + 1);1092 if (pszResult)1093 {1094 rc = RTStrCopyEx(pszResult, cchSubStr + 1, pszSource + offStart, cchSubStr);1095 if (RT_SUCCESS(rc))1096 {1097 *ppszOutput = pszResult;1098 *pcbOutput = (uint32_t)(cchSubStr + 1);1099 rc = VINF_SUCCESS;1100 }1101 else1102 {1103 LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected EndFragment. rc = %Rrc\n", rc));1104 RTMemFree(pszResult);1105 }1106 }1107 else1108 {1109 LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected EndFragment\n"));1110 rc = VERR_NO_MEMORY;1111 }1112 }1113 else1114 {1115 LogRelFlowFunc(("Error: CF_HTML out of bounds - offStart=%#x offEnd=%#x cch=%#x\n", offStart, offEnd, cch));1116 rc = VERR_INVALID_PARAMETER;1117 }1118 }1119 else1120 {1121 LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected EndFragment. rc = %Rrc\n", rc));1122 rc = VERR_INVALID_PARAMETER;1123 }1124 }1125 else1126 {1127 LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected StartFragment. rc = %Rrc\n", rc));1128 rc = VERR_INVALID_PARAMETER;1129 }1130 1131 return rc;1132 }1133 1134 1135 1136 /**1137 * Converts source UTF-8 MIME HTML clipboard data to UTF-8 CF_HTML format.1138 *1139 * This is just encapsulation work, slapping a header on the data.1140 *1141 * It allocates1142 *1143 * Calculations:1144 * Header length = format Length + (2*(10 - 5('%010d'))('digits')) - 2('%s') = format length + 81145 * EndHtml = Header length + fragment length1146 * StartHtml = 105(constant)1147 * StartFragment = 141(constant) may vary if the header html content will be extended1148 * EndFragment = Header length + fragment length - 38(ending length)1149 *1150 * @param pszSource Source buffer that contains utf-16 string in mime html format1151 * @param cb Size of source buffer in bytes1152 * @param ppszOutput Where to return the allocated output buffer to put converted UTF-81153 * CF_HTML clipboard data. This function allocates memory for this.1154 * @param pcbOutput Where to return the size of allocated result buffer in bytes/chars, including zero terminator1155 *1156 * @note output buffer should be free using RTMemFree()1157 * @note Everything inside of fragment can be UTF8. Windows allows it. Everything in header should be Latin1.1158 */1159 static int ConvertMimeToCFHTML(const char *pszSource, size_t cb, char **ppszOutput, uint32_t *pcbOutput)1160 {1161 Assert(ppszOutput);1162 Assert(pcbOutput);1163 Assert(pszSource);1164 Assert(cb);1165 1166 /* construct CF_HTML formatted string */1167 char *pszResult = NULL;1168 size_t cchFragment;1169 int rc = RTStrNLenEx(pszSource, cb, &cchFragment);1170 if (!RT_SUCCESS(rc))1171 {1172 LogRelFlowFunc(("Error: invalid source fragment. rc = %Rrc\n"));1173 return VERR_INVALID_PARAMETER;1174 }1175 1176 /*1177 @StartHtml - pos before <html>1178 @EndHtml - whole size of text excluding ending zero char1179 @StartFragment - pos after <!--StartFragment-->1180 @EndFragment - pos before <!--EndFragment-->1181 @note: all values includes CR\LF inserted into text1182 Calculations:1183 Header length = format Length + (3*6('digits')) - 2('%s') = format length + 16 (control value - 183)1184 EndHtml = Header length + fragment length1185 StartHtml = 105(constant)1186 StartFragment = 143(constant)1187 EndFragment = Header length + fragment length - 40(ending length)1188 */1189 static const char s_szFormatSample[] =1190 /* 0: */ "Version:1.0\r\n"1191 /* 13: */ "StartHTML:000000101\r\n"1192 /* 34: */ "EndHTML:%0000009u\r\n" // END HTML = Header length + fragment length1193 /* 53: */ "StartFragment:000000137\r\n"1194 /* 78: */ "EndFragment:%0000009u\r\n"1195 /* 101: */ "<html>\r\n"1196 /* 109: */ "<body>\r\n"1197 /* 117: */ "<!--StartFragment-->"1198 /* 137: */ "%s"1199 /* 137+2: */ "<!--EndFragment-->\r\n"1200 /* 157+2: */ "</body>\r\n"1201 /* 166+2: */ "</html>\r\n";1202 /* 175+2: */1203 AssertCompile(sizeof(s_szFormatSample) == 175 + 2 + 1);1204 1205 /* calculate parameters of CF_HTML header */1206 size_t cchHeader = sizeof(s_szFormatSample) - 1;1207 size_t offEndHtml = cchHeader + cchFragment;1208 size_t offEndFragment = cchHeader + cchFragment - 38; /* 175-137 = 38 */1209 pszResult = (char *)RTMemAlloc(offEndHtml + 1);1210 if (pszResult == NULL)1211 {1212 LogRelFlowFunc(("Error: Cannot allocate memory for result buffer. rc = %Rrc\n"));1213 return VERR_NO_MEMORY;1214 }1215 1216 /* format result CF_HTML string */1217 size_t cchFormatted = RTStrPrintf(pszResult, offEndHtml + 1,1218 s_szFormatSample, offEndHtml, offEndFragment, pszSource);1219 Assert(offEndHtml == cchFormatted); NOREF(cchFormatted);1220 1221 #ifdef VBOX_STRICT1222 /* Control calculations. check consistency.*/1223 static const char s_szStartFragment[] = "<!--StartFragment-->";1224 static const char s_szEndFragment[] = "<!--EndFragment-->";1225 1226 /* check 'StartFragment:' value */1227 const char *pszRealStartFragment = RTStrStr(pszResult, s_szStartFragment);1228 Assert(&pszRealStartFragment[sizeof(s_szStartFragment) - 1] - pszResult == 137);1229 1230 /* check 'EndFragment:' value */1231 const char *pszRealEndFragment = RTStrStr(pszResult, s_szEndFragment);1232 Assert((size_t)(pszRealEndFragment - pszResult) == offEndFragment);1233 #endif1234 1235 *ppszOutput = pszResult;1236 *pcbOutput = (uint32_t)cchFormatted + 1;1237 Assert(*pcbOutput == cchFormatted + 1);1238 1239 return VINF_SUCCESS;1240 }1241 -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp
r78442 r78501 86 86 87 87 #include "VBoxClipboard.h" 88 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 89 # include "VBoxSharedClipboardSvc-uri.h" 90 #endif 88 91 89 92 … … 200 203 { 201 204 /* Message priority is taken into account. */ 202 if (pClient->f MsgQuit)205 if (pClient->fHostMsgQuit) 203 206 { 204 207 LogFlowFunc(("vboxSvcClipboardReturnMsg: Quit\n")); 205 208 VBoxHGCMParmUInt32Set(&paParms[0], VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT); 206 209 VBoxHGCMParmUInt32Set(&paParms[1], 0); 207 pClient->f MsgQuit = false;208 } 209 else if (pClient->f MsgReadData)210 pClient->fHostMsgQuit = false; 211 } 212 else if (pClient->fHostMsgReadData) 210 213 { 211 214 uint32_t fFormat = 0; … … 218 221 else if (pClient->u32RequestedFormat & VBOX_SHARED_CLIPBOARD_FMT_HTML) 219 222 fFormat = VBOX_SHARED_CLIPBOARD_FMT_HTML; 223 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 224 else if (pClient->u32RequestedFormat & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST) 225 fFormat = VBOX_SHARED_CLIPBOARD_FMT_URI_LIST; 226 #endif 220 227 else 221 AssertStmt(pClient->u32RequestedFormat == 0, pClient->u32RequestedFormat = 0); 228 { 229 LogRel2(("Clipboard: Unsupported format from guest (0x%x), skipping\n", fFormat)); 230 pClient->u32RequestedFormat = 0; 231 } 222 232 pClient->u32RequestedFormat &= ~fFormat; 223 233 VBoxHGCMParmUInt32Set(&paParms[0], VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA); 224 234 VBoxHGCMParmUInt32Set(&paParms[1], fFormat); 225 235 if (pClient->u32RequestedFormat == 0) 226 pClient->f MsgReadData = false;227 } 228 else if (pClient->f MsgFormats)236 pClient->fHostMsgReadData = false; 237 } 238 else if (pClient->fHostMsgFormats) 229 239 { 230 240 LogFlowFunc(("vboxSvcClipboardReturnMsg: Formats %02X\n", pClient->u32AvailableFormats)); 231 241 VBoxHGCMParmUInt32Set(&paParms[0], VBOX_SHARED_CLIPBOARD_HOST_MSG_REPORT_FORMATS); 232 242 VBoxHGCMParmUInt32Set(&paParms[1], pClient->u32AvailableFormats); 233 pClient->f MsgFormats = false;243 pClient->fHostMsgFormats = false; 234 244 } 235 245 else … … 255 265 { 256 266 LogFlowFunc(("Quit\n")); 257 pClient->f MsgQuit = true;267 pClient->fHostMsgQuit = true; 258 268 } break; 259 269 case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA: … … 268 278 LogFlowFunc(("ReadData %02X\n", u32Formats)); 269 279 pClient->u32RequestedFormat = u32Formats; 270 pClient->f MsgReadData = true;280 pClient->fHostMsgReadData = true; 271 281 } break; 272 282 case VBOX_SHARED_CLIPBOARD_HOST_MSG_REPORT_FORMATS: … … 281 291 LogFlowFunc(("Formats %02X\n", u32Formats)); 282 292 pClient->u32AvailableFormats = u32Formats; 283 pClient->f MsgFormats = true;293 pClient->fHostMsgFormats = true; 284 294 } break; 285 295 default: … … 683 693 default: 684 694 { 695 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 696 rc = vboxClipboardSvcURIHandler(u32ClientID, pvClient, u32Function, cParms, paParms, tsArrival, 697 &fAsynchronousProcessing); 698 #else 685 699 rc = VERR_NOT_IMPLEMENTED; 700 #endif 686 701 } 687 702 } … … 772 787 773 788 default: 774 break; 789 { 790 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 791 rc = vboxClipboardSvcURIHostHandler(u32Function, cParms, paParms); 792 #endif 793 } break; 775 794 } 776 795 … … 786 805 { 787 806 SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTDATA, u32ClientID), /* for validation purposes */ 788 SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTDATA, f MsgQuit),789 SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTDATA, f MsgReadData),790 SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTDATA, f MsgFormats),807 SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTDATA, fHostMsgQuit), 808 SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTDATA, fHostMsgReadData), 809 SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTDATA, fHostMsgFormats), 791 810 SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTDATA, u32RequestedFormat), 792 811 SSMFIELD_ENTRY_TERM() … … 843 862 bool fAsync: 1; /* Guest is waiting for a message. */ 844 863 845 bool f MsgQuit: 1;846 bool f MsgReadData: 1;847 bool f MsgFormats: 1;864 bool fHostMsgQuit: 1; 865 bool fHostMsgReadData: 1; 866 bool fHostMsgFormats: 1; 848 867 849 868 struct … … 918 937 AssertRCReturn(rc, rc); 919 938 920 pClient->f MsgQuit = savedState.fMsgQuit;921 pClient->f MsgReadData = savedState.fMsgReadData;922 pClient->f MsgFormats = savedState.fMsgFormats;939 pClient->fHostMsgQuit = savedState.fHostMsgQuit; 940 pClient->fHostMsgReadData = savedState.fHostMsgReadData; 941 pClient->fHostMsgFormats = savedState.fHostMsgFormats; 923 942 pClient->u32RequestedFormat = savedState.u32RequestedFormat; 924 943 }
Note:
See TracChangeset
for help on using the changeset viewer.

