Changeset 78474 in vbox for trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp
- Timestamp:
- May 13, 2019 7:44:15 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp
r78443 r78474 22 22 #define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD 23 23 #include <VBox/GuestHost/SharedClipboard-win.h> 24 #include <VBox/GuestHost/SharedClipboard-uri.h> 25 26 /** !!! HACK ALERT !!! Dynamically resolve functions! */ 27 #ifdef _WIN32_IE 28 #undef _WIN32_IE 29 #define _WIN32_IE 0x0501 30 #endif 24 31 25 32 #include <iprt/win/windows.h> 26 #include <new> /* For bad_alloc. */27 33 #include <iprt/win/shlobj.h> 34 #include <iprt/win/shlwapi.h> 28 35 29 36 #include <iprt/path.h> … … 32 39 #include <iprt/utf16.h> 33 40 41 #include <VBox/err.h> 34 42 #include <VBox/log.h> 35 43 36 44 VBoxClipboardWinDataObject::VBoxClipboardWinDataObject(LPFORMATETC pFormatEtc, LPSTGMEDIUM pStgMed, ULONG cFormats) 37 : mStatus(Uninitialized), 38 mRefCount(1), 39 mcFormats(0), 40 mpvData(NULL), 41 mcbData(0) 45 : mStatus(Uninitialized) 46 , mRefCount(0) 47 , mcFormats(0) 48 , muClientID(0) 42 49 { 43 50 HRESULT hr; 44 51 45 ULONG cFixedFormats = 1;46 ULONG cAllFormats = cFormats + cFixedFormats;52 const ULONG cFixedFormats = 3; /* CFSTR_FILEDESCRIPTORA + CFSTR_FILEDESCRIPTORW + CFSTR_FILECONTENTS */ 53 const ULONG cAllFormats = cFormats + cFixedFormats; 47 54 48 55 try … … 52 59 mpStgMedium = new STGMEDIUM[cAllFormats]; 53 60 RT_BZERO(mpStgMedium, sizeof(STGMEDIUM) * cAllFormats); 61 62 /** @todo Do we need CFSTR_FILENAME / CFSTR_SHELLIDLIST here? */ 63 64 /* 65 * Register fixed formats. 66 */ 67 68 /* IStream interface, implemented in ClipboardStreamImpl-win.cpp. */ 69 registerFormat(&mpFormatEtc[FormatIndex_FileDescriptorA], 70 RegisterClipboardFormat(CFSTR_FILEDESCRIPTORA)); 71 registerFormat(&mpFormatEtc[FormatIndex_FileDescriptorW], 72 RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW)); 73 registerFormat(&mpFormatEtc[FormatIndex_FileContents], 74 RegisterClipboardFormat(CFSTR_FILECONTENTS), 75 TYMED_ISTREAM, 0 /* lIndex */); 54 76 55 77 /* … … 66 88 LogFlowFunc(("Format %RU32: cfFormat=%RI16, tyMed=%RU32, dwAspect=%RU32\n", 67 89 i, pFormatEtc[i].cfFormat, pFormatEtc[i].tymed, pFormatEtc[i].dwAspect)); 68 mpFormatEtc[ i] = pFormatEtc[i];69 mpStgMedium[ i] = pStgMed[i];90 mpFormatEtc[cFixedFormats + i] = pFormatEtc[i]; 91 mpStgMedium[cFixedFormats + i] = pStgMed[i]; 70 92 } 71 93 } … … 80 102 if (SUCCEEDED(hr)) 81 103 { 82 int rc2 = RTSemEventCreate(&mEventDropped); 83 AssertRC(rc2); 84 85 /* 86 * Register fixed formats. 87 */ 88 #if 0 89 /* CF_HDROP. */ 90 RegisterFormat(&mpFormatEtc[cFormats], CF_HDROP); 91 mpStgMedium[cFormats++].tymed = TYMED_HGLOBAL; 92 93 /* IStream. */ 94 RegisterFormat(&mpFormatEtc[cFormats++], 95 RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR)); 96 RegisterFormat(&mpFormatEtc[cFormats++], 97 RegisterClipboardFormat(CFSTR_FILECONTENTS), 98 TYMED_ISTREAM, 0 /* lIndex */); 99 100 /* Required for e.g. Windows Media Player. */ 101 RegisterFormat(&mpFormatEtc[cFormats++], 102 RegisterClipboardFormat(CFSTR_FILENAME)); 103 RegisterFormat(&mpFormatEtc[cFormats++], 104 RegisterClipboardFormat(CFSTR_FILENAMEW)); 105 RegisterFormat(&mpFormatEtc[cFormats++], 106 RegisterClipboardFormat(CFSTR_SHELLIDLIST)); 107 RegisterFormat(&mpFormatEtc[cFormats++], 108 RegisterClipboardFormat(CFSTR_SHELLIDLISTOFFSET)); 109 #endif 110 mcFormats = cFormats; 104 mcFormats = cAllFormats; 111 105 mStatus = Initialized; 112 106 } 113 107 114 LogFlowFunc(("c Formats=%RU32, hr=%Rhrc\n", cFormats, hr));108 LogFlowFunc(("cAllFormats=%RU32, hr=%Rhrc\n", cAllFormats, hr)); 115 109 } 116 110 117 111 VBoxClipboardWinDataObject::~VBoxClipboardWinDataObject(void) 118 112 { 113 if (mpStream) 114 mpStream->Release(); 115 119 116 if (mpFormatEtc) 120 117 delete[] mpFormatEtc; … … 123 120 delete[] mpStgMedium; 124 121 125 if (mpvData)126 RTMemFree(mpvData);127 128 122 LogFlowFunc(("mRefCount=%RI32\n", mRefCount)); 129 123 } … … 135 129 STDMETHODIMP_(ULONG) VBoxClipboardWinDataObject::AddRef(void) 136 130 { 137 return InterlockedIncrement(&mRefCount); 131 LONG lCount = InterlockedIncrement(&mRefCount); 132 LogFlowFunc(("lCount=%RI32\n", lCount)); 133 return lCount; 138 134 } 139 135 … … 141 137 { 142 138 LONG lCount = InterlockedDecrement(&mRefCount); 139 LogFlowFunc(("lCount=%RI32\n", mRefCount)); 143 140 if (lCount == 0) 144 141 { … … 164 161 *ppvObject = 0; 165 162 return E_NOINTERFACE; 163 } 164 165 int VBoxClipboardWinDataObject::copyToHGlobal(const void *pvData, size_t cbData, UINT fFlags, HGLOBAL *phGlobal) 166 { 167 AssertPtrReturn(phGlobal, VERR_INVALID_POINTER); 168 169 HGLOBAL hGlobal = GlobalAlloc(fFlags, cbData); 170 if (!hGlobal) 171 return VERR_NO_MEMORY; 172 173 void *pvAlloc = GlobalLock(hGlobal); 174 if (pvAlloc) 175 { 176 CopyMemory(pvAlloc, pvData, cbData); 177 GlobalUnlock(hGlobal); 178 179 *phGlobal = hGlobal; 180 181 return VINF_SUCCESS; 182 } 183 184 GlobalFree(hGlobal); 185 return VERR_ACCESS_DENIED; 186 } 187 188 int VBoxClipboardWinDataObject::createFileGroupDescriptor(const SharedClipboardURIList &URIList, HGLOBAL *phGlobal) 189 { 190 // AssertReturn(URIList.GetRootCount(), VERR_INVALID_PARAMETER); 191 AssertPtrReturn(phGlobal, VERR_INVALID_POINTER); 192 193 int rc; 194 195 const size_t cItems = 2; URIList.GetRootCount(); 196 const size_t cbFGD = sizeof(FILEGROUPDESCRIPTOR) + sizeof(FILEDESCRIPTOR) * (cItems - 1); 197 198 LogFunc(("cItmes=%zu\n", cItems)); 199 200 FILEGROUPDESCRIPTOR *pFGD = (FILEGROUPDESCRIPTOR *)RTMemAlloc(cbFGD); 201 if (pFGD) 202 { 203 pFGD->cItems = (UINT)cItems; 204 205 206 FILEDESCRIPTOR *pFD = &pFGD->fgd[0]; 207 RT_BZERO(pFD, sizeof(FILEDESCRIPTOR)); 208 209 RTStrPrintf(pFD->cFileName, sizeof(pFD->cFileName), "barbaz.txt\n"); 210 211 #if 1 212 pFD->dwFlags = FD_ATTRIBUTES | FD_FILESIZE | FD_PROGRESSUI; 213 pFD->dwFileAttributes = FILE_ATTRIBUTE_NORMAL; // FILE_ATTRIBUTE_DIRECTORY; 214 215 uint64_t cbSize = _1M; 216 217 pFD->nFileSizeHigh = RT_HI_U32(cbSize); 218 pFD->nFileSizeLow = RT_LO_U32(cbSize); 219 #else 220 pFD->dwFlags = FD_ATTRIBUTES | FD_CREATETIME | FD_ACCESSTIME | FD_WRITESTIME | FD_FILESIZE; 221 pFD->dwFileAttributes = 222 pFD->ftCreationTime = 223 pFD->ftLastAccessTime = 224 pFD->ftLastWriteTime = 225 pFD->nFileSizeHigh = 226 pFD->nFileSizeLow = 227 #endif 228 229 230 231 pFD = &pFGD->fgd[1]; 232 RT_BZERO(pFD, sizeof(FILEDESCRIPTOR)); 233 234 RTStrPrintf(pFD->cFileName, sizeof(pFD->cFileName), "barbaz_dir\n"); 235 236 #if 1 237 pFD->dwFlags = FD_ATTRIBUTES | FD_PROGRESSUI; 238 pFD->dwFileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY; 239 #else 240 pFD->dwFlags = FD_ATTRIBUTES | FD_CREATETIME | FD_ACCESSTIME | FD_WRITESTIME | FD_FILESIZE; 241 pFD->dwFileAttributes = 242 pFD->ftCreationTime = 243 pFD->ftLastAccessTime = 244 pFD->ftLastWriteTime = 245 pFD->nFileSizeHigh = 246 pFD->nFileSizeLow = 247 #endif 248 249 250 rc = copyToHGlobal(pFGD, cbFGD, GMEM_MOVEABLE, phGlobal); 251 } 252 else 253 rc = VERR_NO_MEMORY; 254 255 return rc; 166 256 } 167 257 … … 180 270 AssertPtrReturn(pMedium, DV_E_FORMATETC); 181 271 272 LogFlowFuncEnter(); 273 182 274 ULONG lIndex; 183 if (! LookupFormatEtc(pFormatEtc, &lIndex)) /* Format supported? */275 if (!lookupFormatEtc(pFormatEtc, &lIndex)) /* Format supported? */ 184 276 return DV_E_FORMATETC; 185 277 if (lIndex >= mcFormats) /* Paranoia. */ 186 return DV_E_ FORMATETC;278 return DV_E_LINDEX; 187 279 188 280 LPFORMATETC pThisFormat = &mpFormatEtc[lIndex]; … … 196 288 HRESULT hr = DV_E_FORMATETC; /* Play safe. */ 197 289 198 LogFlowFunc(("mStatus=%ld\n", mStatus)); 199 if (mStatus == Dropping) 200 { 201 LogRel2(("Clipboard: Waiting for drop event ...\n")); 202 int rc2 = RTSemEventWait(mEventDropped, RT_INDEFINITE_WAIT); 203 LogFlowFunc(("rc2=%Rrc, mStatus=%ld\n", rc2, mStatus)); RT_NOREF(rc2); 204 } 205 206 if (mStatus == Dropped) 207 { 208 LogRel2(("Clipboard: Drop event received\n")); 209 LogRel3(("Clipboard: cfFormat=%RI16, sFormat=%s, tyMed=%RU32, dwAspect=%RU32\n", 210 pThisFormat->cfFormat, VBoxClipboardWinDataObject::ClipboardFormatToString(pFormatEtc->cfFormat), 211 pThisFormat->tymed, pThisFormat->dwAspect)); 212 LogRel3(("Clipboard: Got strFormat=%s, pvData=%p, cbData=%RU32\n", 213 mstrFormat.c_str(), mpvData, mcbData)); 214 215 /* 216 * Initialize default values. 217 */ 290 LogRel3(("Clipboard: cfFormat=%RI16, sFormat=%s, tyMed=%RU32, dwAspect=%RU32 -> lIndex=%u\n", 291 pThisFormat->cfFormat, VBoxClipboardWinDataObject::ClipboardFormatToString(pFormatEtc->cfFormat), 292 pThisFormat->tymed, pThisFormat->dwAspect, lIndex)); 293 294 /* 295 * Initialize default values. 296 */ 297 pMedium->tymed = pThisFormat->tymed; 298 pMedium->pUnkForRelease = NULL; /* Caller is responsible for deleting the data. */ 299 300 switch (lIndex) 301 { 302 case FormatIndex_FileDescriptorA: 303 { 304 LogFlowFunc(("FormatIndex_FileDescriptorA\n")); 305 306 SharedClipboardURIList mURIList; 307 // mURIList.AppendURIPath() 308 309 HGLOBAL hGlobal; 310 int rc = createFileGroupDescriptor(mURIList, &hGlobal); 311 if (RT_SUCCESS(rc)) 312 { 313 pMedium->tymed = TYMED_HGLOBAL; 314 pMedium->hGlobal = hGlobal; 315 316 hr = S_OK; 317 } 318 break; 319 } 320 321 case FormatIndex_FileDescriptorW: 322 LogFlowFunc(("FormatIndex_FileDescriptorW\n")); 323 break; 324 325 case FormatIndex_FileContents: 326 { 327 LogFlowFunc(("FormatIndex_FileContents\n")); 328 329 hr = VBoxClipboardWinStreamImpl::Create(&mpStream); 330 if (SUCCEEDED(hr)) 331 { 332 /* Hand over the stream to the caller. */ 333 pMedium->tymed = TYMED_ISTREAM; 334 pMedium->pstm = mpStream; 335 } 336 337 break; 338 } 339 340 default: 341 break; 342 } 343 344 /* Error handling; at least return some basic data. */ 345 if (FAILED(hr)) 346 { 347 LogFunc(("Failed; copying medium ...\n")); 348 218 349 pMedium->tymed = pThisFormat->tymed; 219 350 pMedium->pUnkForRelease = NULL; 220 221 /*222 * URI list handling.223 */224 if (mstrFormat.equalsIgnoreCase("text/uri-list"))225 {226 int rc = VINF_SUCCESS;227 228 RTCList<RTCString> lstFilesURI = RTCString((char*)mpvData, mcbData).split("\r\n");229 RTCList<RTCString> lstFiles;230 for (size_t i = 0; i < lstFilesURI.size(); i++)231 {232 char *pszFilePath = RTUriFilePath(lstFilesURI.at(i).c_str());233 if (pszFilePath)234 {235 lstFiles.append(pszFilePath);236 RTStrFree(pszFilePath);237 }238 else /* Unable to parse -- refuse entire request. */239 {240 lstFiles.clear();241 rc = VERR_INVALID_PARAMETER;242 break;243 }244 }245 246 size_t cFiles = lstFiles.size();247 if ( RT_SUCCESS(rc)248 && cFiles)249 {250 #ifdef DEBUG251 LogFlowFunc(("Files (%zu)\n", cFiles));252 for (size_t i = 0; i < cFiles; i++)253 LogFlowFunc(("\tFile: %s\n", lstFiles.at(i).c_str()));254 #endif255 256 #if 0257 if ( (pFormatEtc->tymed & TYMED_ISTREAM)258 && (pFormatEtc->dwAspect == DVASPECT_CONTENT)259 && (pFormatEtc->cfFormat == CF_FILECONTENTS))260 {261 262 }263 else if ( (pFormatEtc->tymed & TYMED_HGLOBAL)264 && (pFormatEtc->dwAspect == DVASPECT_CONTENT)265 && (pFormatEtc->cfFormat == CF_FILEDESCRIPTOR))266 {267 268 }269 else if ( (pFormatEtc->tymed & TYMED_HGLOBAL)270 && (pFormatEtc->cfFormat == CF_PREFERREDDROPEFFECT))271 {272 HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, sizeof(DWORD));273 DWORD *pdwEffect = (DWORD *)GlobalLock(hData);274 AssertPtr(pdwEffect);275 *pdwEffect = DROPEFFECT_COPY;276 GlobalUnlock(hData);277 278 pMedium->hGlobal = hData;279 pMedium->tymed = TYMED_HGLOBAL;280 }281 else282 #endif283 if ( (pFormatEtc->tymed & TYMED_HGLOBAL)284 && (pFormatEtc->dwAspect == DVASPECT_CONTENT)285 && (pFormatEtc->cfFormat == CF_TEXT))286 {287 pMedium->hGlobal = GlobalAlloc(GHND, mcbData + 1);288 if (pMedium->hGlobal)289 {290 char *pcDst = (char *)GlobalLock(pMedium->hGlobal);291 memcpy(pcDst, mpvData, mcbData);292 pcDst[mcbData] = '\0';293 GlobalUnlock(pMedium->hGlobal);294 295 hr = S_OK;296 }297 }298 else if ( (pFormatEtc->tymed & TYMED_HGLOBAL)299 && (pFormatEtc->dwAspect == DVASPECT_CONTENT)300 && (pFormatEtc->cfFormat == CF_HDROP))301 {302 size_t cchFiles = 0; /* Number of ASCII characters. */303 for (size_t i = 0; i < cFiles; i++)304 {305 cchFiles += strlen(lstFiles.at(i).c_str());306 cchFiles += 1; /* Terminating '\0'. */307 }308 309 size_t cbBuf = sizeof(DROPFILES) + ((cchFiles + 1) * sizeof(RTUTF16));310 DROPFILES *pBuf = (DROPFILES *)RTMemAllocZ(cbBuf);311 if (pBuf)312 {313 pBuf->pFiles = sizeof(DROPFILES);314 pBuf->fWide = 1; /* We use unicode. Always. */315 316 uint8_t *pCurFile = (uint8_t *)pBuf + pBuf->pFiles;317 AssertPtr(pCurFile);318 319 for (size_t i = 0; i < cFiles && RT_SUCCESS(rc); i++)320 {321 size_t cchCurFile;322 PRTUTF16 pwszFile;323 rc = RTStrToUtf16(lstFiles.at(i).c_str(), &pwszFile);324 if (RT_SUCCESS(rc))325 {326 cchCurFile = RTUtf16Len(pwszFile);327 Assert(cchCurFile);328 memcpy(pCurFile, pwszFile, cchCurFile * sizeof(RTUTF16));329 RTUtf16Free(pwszFile);330 }331 else332 break;333 334 pCurFile += cchCurFile * sizeof(RTUTF16);335 336 /* Terminate current file name. */337 *pCurFile = L'\0';338 pCurFile += sizeof(RTUTF16);339 }340 341 if (RT_SUCCESS(rc))342 {343 *pCurFile = L'\0'; /* Final list terminator. */344 345 pMedium->tymed = TYMED_HGLOBAL;346 pMedium->pUnkForRelease = NULL;347 pMedium->hGlobal = GlobalAlloc( GMEM_ZEROINIT348 | GMEM_MOVEABLE349 | GMEM_DDESHARE, cbBuf);350 if (pMedium->hGlobal)351 {352 LPVOID pMem = GlobalLock(pMedium->hGlobal);353 if (pMem)354 {355 memcpy(pMem, pBuf, cbBuf);356 GlobalUnlock(pMedium->hGlobal);357 358 hr = S_OK;359 }360 }361 }362 363 RTMemFree(pBuf);364 }365 else366 rc = VERR_NO_MEMORY;367 }368 }369 370 if (RT_FAILURE(rc))371 hr = DV_E_FORMATETC;372 }373 /*374 * Plain text handling.375 */376 else if ( mstrFormat.equalsIgnoreCase("text/plain")377 || mstrFormat.equalsIgnoreCase("text/html")378 || mstrFormat.equalsIgnoreCase("text/plain;charset=utf-8")379 || mstrFormat.equalsIgnoreCase("text/plain;charset=utf-16")380 || mstrFormat.equalsIgnoreCase("text/richtext")381 || mstrFormat.equalsIgnoreCase("UTF8_STRING")382 || mstrFormat.equalsIgnoreCase("TEXT")383 || mstrFormat.equalsIgnoreCase("STRING"))384 {385 pMedium->hGlobal = GlobalAlloc(GHND, mcbData + 1);386 if (pMedium->hGlobal)387 {388 char *pcDst = (char *)GlobalLock(pMedium->hGlobal);389 memcpy(pcDst, mpvData, mcbData);390 pcDst[mcbData] = '\0';391 GlobalUnlock(pMedium->hGlobal);392 393 hr = S_OK;394 }395 }396 else397 LogRel(("Clipboard: Error: Format '%s' not implemented\n", mstrFormat.c_str()));398 }399 400 /* Error handling; at least return some basic data. */401 if (FAILED(hr))402 {403 LogFlowFunc(("Copying medium ...\n"));404 switch (pThisMedium->tymed)405 {406 407 case TYMED_HGLOBAL:408 pMedium->hGlobal = (HGLOBAL)OleDuplicateData(pThisMedium->hGlobal,409 pThisFormat->cfFormat, NULL);410 break;411 412 default:413 break;414 }415 416 pMedium->tymed = pThisFormat->tymed;417 pMedium->pUnkForRelease = NULL;418 351 } 419 352 420 353 if (hr == DV_E_FORMATETC) 421 LogRel(("Clipboard: Error handling format '%s' (%RU32 bytes)\n", mstrFormat.c_str(), mcbData));354 LogRel(("Clipboard: Error handling format\n")); 422 355 423 356 LogFlowFunc(("hr=%Rhrc\n", hr)); … … 437 370 RT_NOREF(pFormatEtc, pMedium); 438 371 LogFlowFunc(("\n")); 439 return DATA_E_FORMATETC;372 return E_NOTIMPL; 440 373 } 441 374 … … 450 383 { 451 384 LogFlowFunc(("\n")); 452 return ( LookupFormatEtc(pFormatEtc, NULL /* puIndex */)) ? S_OK : DV_E_FORMATETC;385 return (lookupFormatEtc(pFormatEtc, NULL /* puIndex */)) ? S_OK : DV_E_FORMATETC; 453 386 } 454 387 … … 466 399 { 467 400 RT_NOREF(pFormatEtc, pMedium, fRelease); 401 LogFlowFunc(("\n")); 402 468 403 return E_NOTIMPL; 469 404 } … … 501 436 } 502 437 438 #ifdef VBOX_WITH_SHARED_CLIPBOARD_WIN_ASYNC 439 /* 440 * IDataObjectAsyncCapability methods. 441 */ 442 443 STDMETHODIMP VBoxClipboardWinDataObject::EndOperation(HRESULT hResult, IBindCtx* pbcReserved, DWORD dwEffects) 444 { 445 RT_NOREF(hResult, pbcReserved, dwEffects); 446 return E_NOTIMPL; 447 } 448 449 STDMETHODIMP VBoxClipboardWinDataObject::GetAsyncMode(BOOL* pfIsOpAsync) 450 { 451 RT_NOREF(pfIsOpAsync); 452 return E_NOTIMPL; 453 } 454 455 STDMETHODIMP VBoxClipboardWinDataObject::InOperation(BOOL* pfInAsyncOp) 456 { 457 RT_NOREF(pfInAsyncOp); 458 return E_NOTIMPL; 459 } 460 461 STDMETHODIMP VBoxClipboardWinDataObject::SetAsyncMode(BOOL fDoOpAsync) 462 { 463 RT_NOREF(fDoOpAsync); 464 return E_NOTIMPL; 465 } 466 467 STDMETHODIMP VBoxClipboardWinDataObject::StartOperation(IBindCtx* pbcReserved) 468 { 469 RT_NOREF(pbcReserved); 470 return E_NOTIMPL; 471 } 472 #endif /* VBOX_WITH_SHARED_CLIPBOARD_WIN_ASYNC */ 473 503 474 /* 504 475 * Own stuff. 505 476 */ 506 477 507 int VBoxClipboardWinDataObject::Abort(void) 508 { 509 LogFlowFunc(("Aborting ...\n")); 510 mStatus = Aborted; 511 return RTSemEventSignal(mEventDropped); 478 int VBoxClipboardWinDataObject::Init(uint32_t idClient) 479 { 480 muClientID = idClient; 481 482 LogFlowFuncLeaveRC(VINF_SUCCESS); 483 return VINF_SUCCESS; 512 484 } 513 485 … … 595 567 } 596 568 597 bool VBoxClipboardWinDataObject:: LookupFormatEtc(LPFORMATETC pFormatEtc, ULONG *puIndex)569 bool VBoxClipboardWinDataObject::lookupFormatEtc(LPFORMATETC pFormatEtc, ULONG *puIndex) 598 570 { 599 571 AssertReturn(pFormatEtc, false); … … 622 594 } 623 595 624 /* static */ 625 HGLOBAL VBoxClipboardWinDataObject::MemDup(HGLOBAL hMemSource) 626 { 627 DWORD dwLen = GlobalSize(hMemSource); 628 AssertReturn(dwLen, NULL); 629 PVOID pvSource = GlobalLock(hMemSource); 630 if (pvSource) 631 { 632 PVOID pvDest = GlobalAlloc(GMEM_FIXED, dwLen); 633 if (pvDest) 634 memcpy(pvDest, pvSource, dwLen); 635 636 GlobalUnlock(hMemSource); 637 return pvDest; 638 } 639 640 return NULL; 641 } 642 643 void VBoxClipboardWinDataObject::RegisterFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat, 644 TYMED tyMed, LONG lIndex, DWORD dwAspect, 645 DVTARGETDEVICE *pTargetDevice) 596 void VBoxClipboardWinDataObject::registerFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat, 597 TYMED tyMed, LONG lIndex, DWORD dwAspect, 598 DVTARGETDEVICE *pTargetDevice) 646 599 { 647 600 AssertPtr(pFormatEtc); … … 657 610 } 658 611 659 void VBoxClipboardWinDataObject::SetStatus(Status status)660 {661 LogFlowFunc(("Setting status to %ld\n", status));662 mStatus = status;663 }664 665 int VBoxClipboardWinDataObject::Signal(const RTCString &strFormat,666 const void *pvData, uint32_t cbData)667 {668 int rc;669 670 if (cbData)671 {672 mpvData = RTMemAlloc(cbData);673 if (mpvData)674 {675 memcpy(mpvData, pvData, cbData);676 mcbData = cbData;677 rc = VINF_SUCCESS;678 }679 else680 rc = VERR_NO_MEMORY;681 }682 else683 rc = VINF_SUCCESS;684 685 if (RT_SUCCESS(rc))686 {687 mStatus = Dropped;688 mstrFormat = strFormat;689 }690 else691 {692 mStatus = Aborted;693 }694 695 /* Signal in any case. */696 LogRel2(("Clipboard: Signalling drop event\n"));697 698 int rc2 = RTSemEventSignal(mEventDropped);699 if (RT_SUCCESS(rc))700 rc = rc2;701 702 LogFunc(("mStatus=%RU32, rc=%Rrc\n", mStatus, rc));703 return rc;704 }705
Note:
See TracChangeset
for help on using the changeset viewer.