VirtualBox

Ignore:
Timestamp:
May 13, 2019 7:44:15 AM (6 years ago)
Author:
vboxsync
Message:

Shared Clipboard/URI: Update.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp

    r78443 r78474  
    2222#define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD
    2323#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
    2431
    2532#include <iprt/win/windows.h>
    26 #include <new> /* For bad_alloc. */
    2733#include <iprt/win/shlobj.h>
     34#include <iprt/win/shlwapi.h>
    2835
    2936#include <iprt/path.h>
     
    3239#include <iprt/utf16.h>
    3340
     41#include <VBox/err.h>
    3442#include <VBox/log.h>
    3543
    3644VBoxClipboardWinDataObject::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)
    4249{
    4350    HRESULT hr;
    4451
    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;
    4754
    4855    try
     
    5259        mpStgMedium = new STGMEDIUM[cAllFormats];
    5360        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 */);
    5476
    5577        /*
     
    6688                LogFlowFunc(("Format %RU32: cfFormat=%RI16, tyMed=%RU32, dwAspect=%RU32\n",
    6789                             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];
    7092            }
    7193        }
     
    80102    if (SUCCEEDED(hr))
    81103    {
    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;
    111105        mStatus   = Initialized;
    112106    }
    113107
    114     LogFlowFunc(("cFormats=%RU32, hr=%Rhrc\n", cFormats, hr));
     108    LogFlowFunc(("cAllFormats=%RU32, hr=%Rhrc\n", cAllFormats, hr));
    115109}
    116110
    117111VBoxClipboardWinDataObject::~VBoxClipboardWinDataObject(void)
    118112{
     113    if (mpStream)
     114        mpStream->Release();
     115
    119116    if (mpFormatEtc)
    120117        delete[] mpFormatEtc;
     
    123120        delete[] mpStgMedium;
    124121
    125     if (mpvData)
    126         RTMemFree(mpvData);
    127 
    128122    LogFlowFunc(("mRefCount=%RI32\n", mRefCount));
    129123}
     
    135129STDMETHODIMP_(ULONG) VBoxClipboardWinDataObject::AddRef(void)
    136130{
    137     return InterlockedIncrement(&mRefCount);
     131    LONG lCount = InterlockedIncrement(&mRefCount);
     132    LogFlowFunc(("lCount=%RI32\n", lCount));
     133    return lCount;
    138134}
    139135
     
    141137{
    142138    LONG lCount = InterlockedDecrement(&mRefCount);
     139    LogFlowFunc(("lCount=%RI32\n", mRefCount));
    143140    if (lCount == 0)
    144141    {
     
    164161    *ppvObject = 0;
    165162    return E_NOINTERFACE;
     163}
     164
     165int 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
     188int 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;
    166256}
    167257
     
    180270    AssertPtrReturn(pMedium, DV_E_FORMATETC);
    181271
     272    LogFlowFuncEnter();
     273
    182274    ULONG lIndex;
    183     if (!LookupFormatEtc(pFormatEtc, &lIndex)) /* Format supported? */
     275    if (!lookupFormatEtc(pFormatEtc, &lIndex)) /* Format supported? */
    184276        return DV_E_FORMATETC;
    185277    if (lIndex >= mcFormats) /* Paranoia. */
    186         return DV_E_FORMATETC;
     278        return DV_E_LINDEX;
    187279
    188280    LPFORMATETC pThisFormat = &mpFormatEtc[lIndex];
     
    196288    HRESULT hr = DV_E_FORMATETC; /* Play safe. */
    197289
    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
    218349        pMedium->tymed          = pThisFormat->tymed;
    219350        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 DEBUG
    251                 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 #endif
    255 
    256 #if 0
    257                 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                 else
    282 #endif
    283                 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                             else
    332                                 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_ZEROINIT
    348                                                            | GMEM_MOVEABLE
    349                                                            | 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                     else
    366                         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         else
    397             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;
    418351    }
    419352
    420353    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"));
    422355
    423356    LogFlowFunc(("hr=%Rhrc\n", hr));
     
    437370    RT_NOREF(pFormatEtc, pMedium);
    438371    LogFlowFunc(("\n"));
    439     return DATA_E_FORMATETC;
     372    return E_NOTIMPL;
    440373}
    441374
     
    450383{
    451384    LogFlowFunc(("\n"));
    452     return (LookupFormatEtc(pFormatEtc, NULL /* puIndex */)) ? S_OK : DV_E_FORMATETC;
     385    return (lookupFormatEtc(pFormatEtc, NULL /* puIndex */)) ? S_OK : DV_E_FORMATETC;
    453386}
    454387
     
    466399{
    467400    RT_NOREF(pFormatEtc, pMedium, fRelease);
     401    LogFlowFunc(("\n"));
     402
    468403    return E_NOTIMPL;
    469404}
     
    501436}
    502437
     438#ifdef VBOX_WITH_SHARED_CLIPBOARD_WIN_ASYNC
     439/*
     440 * IDataObjectAsyncCapability methods.
     441 */
     442
     443STDMETHODIMP VBoxClipboardWinDataObject::EndOperation(HRESULT hResult, IBindCtx* pbcReserved, DWORD dwEffects)
     444{
     445     RT_NOREF(hResult, pbcReserved, dwEffects);
     446     return E_NOTIMPL;
     447}
     448
     449STDMETHODIMP VBoxClipboardWinDataObject::GetAsyncMode(BOOL* pfIsOpAsync)
     450{
     451     RT_NOREF(pfIsOpAsync);
     452     return E_NOTIMPL;
     453}
     454
     455STDMETHODIMP VBoxClipboardWinDataObject::InOperation(BOOL* pfInAsyncOp)
     456{
     457     RT_NOREF(pfInAsyncOp);
     458     return E_NOTIMPL;
     459}
     460
     461STDMETHODIMP VBoxClipboardWinDataObject::SetAsyncMode(BOOL fDoOpAsync)
     462{
     463     RT_NOREF(fDoOpAsync);
     464     return E_NOTIMPL;
     465}
     466
     467STDMETHODIMP VBoxClipboardWinDataObject::StartOperation(IBindCtx* pbcReserved)
     468{
     469     RT_NOREF(pbcReserved);
     470     return E_NOTIMPL;
     471}
     472#endif /* VBOX_WITH_SHARED_CLIPBOARD_WIN_ASYNC */
     473
    503474/*
    504475 * Own stuff.
    505476 */
    506477
    507 int VBoxClipboardWinDataObject::Abort(void)
    508 {
    509     LogFlowFunc(("Aborting ...\n"));
    510     mStatus = Aborted;
    511     return RTSemEventSignal(mEventDropped);
     478int VBoxClipboardWinDataObject::Init(uint32_t idClient)
     479{
     480    muClientID = idClient;
     481
     482    LogFlowFuncLeaveRC(VINF_SUCCESS);
     483    return VINF_SUCCESS;
    512484}
    513485
     
    595567}
    596568
    597 bool VBoxClipboardWinDataObject::LookupFormatEtc(LPFORMATETC pFormatEtc, ULONG *puIndex)
     569bool VBoxClipboardWinDataObject::lookupFormatEtc(LPFORMATETC pFormatEtc, ULONG *puIndex)
    598570{
    599571    AssertReturn(pFormatEtc, false);
     
    622594}
    623595
    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)
     596void VBoxClipboardWinDataObject::registerFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat,
     597                                                TYMED tyMed, LONG lIndex, DWORD dwAspect,
     598                                                DVTARGETDEVICE *pTargetDevice)
    646599{
    647600    AssertPtr(pFormatEtc);
     
    657610}
    658611
    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         else
    680             rc = VERR_NO_MEMORY;
    681     }
    682     else
    683         rc = VINF_SUCCESS;
    684 
    685     if (RT_SUCCESS(rc))
    686     {
    687         mStatus    = Dropped;
    688         mstrFormat = strFormat;
    689     }
    690     else
    691     {
    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.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette