VirtualBox

Changeset 78474 in vbox for trunk/src/VBox/Additions


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

Shared Clipboard/URI: Update.

Location:
trunk/src/VBox/Additions/WINNT/VBoxTray
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk

    r78466 r78474  
    4242        VBoxHelpers.cpp \
    4343        VBoxTray.rc
    44 VBoxTray_USES.win = vboximportchecker
     44#VBoxTray_USES.win = vboximportchecker                  # !!! HACK ALERT !!! Fix this by using dynamic imports!
    4545VBoxTray_VBOX_IMPORT_CHECKER.win.x86 = nt4 #nt350
    4646VBoxTray_VBOX_IMPORT_CHECKER.win.amd64 = xp64
    4747ifdef VBOX_WITH_SHARED_CLIPBOARD
    4848 VBoxTray_DEFS     += \
    49         VBOX_WITH_SHARED_CLIPBOARD \
     49        $(if $(VBOX_WITH_SHARED_CLIPBOARD),VBOX_WITH_SHARED_CLIPBOARD,) \
    5050        $(if $(VBOX_WITH_SHARED_CLIPBOARD_URI_LIST),VBOX_WITH_SHARED_CLIPBOARD_URI_LIST,)
    5151 VBoxTray_SOURCES  += \
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp

    r78440 r78474  
    2929#include <VBox/GuestHost/SharedClipboard.h>
    3030#include <VBox/GuestHost/SharedClipboard-win.h>
     31#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     32# include <VBox/GuestHost/SharedClipboard-uri.h>
     33#endif
    3134#include <strsafe.h>
    3235
    3336#include <VBox/log.h>
     37
     38
     39#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     40/** !!! HACK ALERT !!! Dynamically resolve functions! */
     41#ifdef _WIN32_IE
     42#undef _WIN32_IE
     43#define _WIN32_IE 0x0501
     44#endif
     45#include <iprt/win/shlobj.h>
     46#include <iprt/win/shlwapi.h>
     47#endif
    3448
    3549
     
    5872
    5973
     74
    6075static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    6176{
     
    7085        case WM_CLIPBOARDUPDATE:
    7186        {
    72            Log(("WM_CLIPBOARDUPDATE\n"));
    73 
    7487           if (GetClipboardOwner() != hwnd)
    7588           {
     89               Log(("WM_CLIPBOARDUPDATE\n"));
     90
    7691               /* Clipboard was updated by another application. */
    77                uint32_t uFormats;
    78                int vboxrc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats);
     92               VBOXCLIPBOARDFORMATS fFormats;
     93               int vboxrc = VBoxClipboardWinGetFormats(&pCtx->Win, &fFormats);
    7994               if (RT_SUCCESS(vboxrc))
    80                    vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats);
     95                   vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, fFormats);
    8196           }
    8297        }
     
    119134        case WM_DRAWCLIPBOARD:
    120135        {
    121            LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pWinCtx->hWnd));
    122 
    123            if (GetClipboardOwner() != hwnd)
    124            {
     136            LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pWinCtx->hWnd));
     137
     138            if (GetClipboardOwner() != hwnd)
     139            {
    125140               /* Clipboard was updated by another application. */
    126141               /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */
    127                uint32_t uFormats;
    128                int vboxrc = VBoxClipboardWinGetFormats(pWinCtx, &uFormats);
     142               VBOXCLIPBOARDFORMATS fFormats;
     143               int vboxrc = VBoxClipboardWinGetFormats(pWinCtx, &fFormats);
    129144               if (RT_SUCCESS(vboxrc))
    130                    vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats);
    131            }
    132 
    133            if (pWinCtx->hWndNextInChain)
    134            {
     145                   vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, fFormats);
     146            }
     147
     148            if (pWinCtx->hWndNextInChain)
     149            {
    135150               /* Pass the message to next windows in the clipboard chain. */
    136151               SendMessageTimeout(pWinCtx->hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, NULL);
    137            }
     152            }
    138153        }
    139154        break;
     
    141156        case WM_TIMER:
    142157        {
    143            if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI))
    144                break;
    145 
    146            HWND hViewer = GetClipboardViewer();
    147 
    148            /* Re-register ourselves in the clipboard chain if our last ping
     158            if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI))
     159                break;
     160
     161            HWND hViewer = GetClipboardViewer();
     162
     163            /* Re-register ourselves in the clipboard chain if our last ping
    149164            * timed out or there seems to be no valid chain. */
    150            if (!hViewer || pWinCtx->oldAPI.fCBChainPingInProcess)
    151            {
    152                VBoxClipboardWinRemoveFromCBChain(pWinCtx);
    153                VBoxClipboardWinAddToCBChain(pWinCtx);
    154            }
    155 
    156            /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
     165            if (!hViewer || pWinCtx->oldAPI.fCBChainPingInProcess)
     166            {
     167                VBoxClipboardWinRemoveFromCBChain(pWinCtx);
     168                VBoxClipboardWinAddToCBChain(pWinCtx);
     169            }
     170
     171            /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
    157172            * processed by ourselves to the chain. */
    158            pWinCtx->oldAPI.fCBChainPingInProcess = TRUE;
    159 
    160            hViewer = GetClipboardViewer();
    161            if (hViewer)
    162                SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pWinCtx->hWndNextInChain, (LPARAM)pWinCtx->hWndNextInChain,
    163                                    VBoxClipboardWinChainPingProc, (ULONG_PTR)pWinCtx);
     173            pWinCtx->oldAPI.fCBChainPingInProcess = TRUE;
     174
     175            hViewer = GetClipboardViewer();
     176            if (hViewer)
     177                SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pWinCtx->hWndNextInChain, (LPARAM)pWinCtx->hWndNextInChain,
     178                                    VBoxClipboardWinChainPingProc, (ULONG_PTR)pWinCtx);
    164179        }
    165180        break;
     
    167182        case WM_CLOSE:
    168183        {
    169            /* Do nothing. Ignore the message. */
     184            /* Do nothing. Ignore the message. */
    170185        }
    171186        break;
     
    173188        case WM_RENDERFORMAT:
    174189        {
    175            /* Insert the requested clipboard format data into the clipboard. */
    176            uint32_t fFormat = VBOX_SHARED_CLIPBOARD_FMT_NONE;
    177 
    178            const UINT cfFormat = (UINT)wParam;
    179            switch (cfFormat)
    180            {
    181               case CF_UNICODETEXT:
    182                   fFormat = VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
    183                   break;
    184 
    185               case CF_DIB:
    186                   fFormat = VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
    187                   break;
    188 
    189 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    190               case CF_HDROP:
    191                   fFormat = VBOX_SHARED_CLIPBOARD_FMT_URI_LIST;
    192                   break;
    193 #endif
    194               default:
    195                   if (cfFormat >= 0xC000) /** @todo r=andy Explain. */
    196                   {
    197                       TCHAR szFormatName[256]; /** @todo r=andy Do we need Unicode support here as well? */
    198 
    199                       int cActual = GetClipboardFormatName(cfFormat, szFormatName, sizeof(szFormatName) / sizeof(TCHAR));
    200                       if (cActual)
    201                       {
    202                           if (strcmp(szFormatName, "HTML Format") == 0)
    203                               fFormat = VBOX_SHARED_CLIPBOARD_FMT_HTML;
    204                       }
    205                   }
    206                   break;
    207            }
    208 
    209            LogFunc(("WM_RENDERFORMAT: format=%u -> fFormat=0x%x\n", cfFormat, fFormat));
    210 
    211            if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_NONE)
    212            {
    213                /* Unsupported clipboard format is requested. */
    214                LogRel(("Clipboard: Unsupported clipboard format requested (0x%x)\n", fFormat));
    215                VBoxClipboardWinClear();
    216            }
    217 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    218            else if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
    219            {
    220 
    221            }
    222 #endif
    223            else
    224            {
    225                const uint32_t cbPrealloc = _4K;
    226                uint32_t cb = 0;
    227 
    228                /* Preallocate a buffer, most of small text transfers will fit into it. */
    229                HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc);
    230                LogFlowFunc(("Preallocated handle hMem = %p\n", hMem));
    231 
    232                if (hMem)
    233                {
    234                    void *pMem = GlobalLock(hMem);
    235                    LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));
    236 
    237                    if (pMem)
    238                    {
    239                        /* Read the host data to the preallocated buffer. */
    240                        int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cbPrealloc, &cb);
    241                        LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n",  vboxrc));
    242 
    243                        if (RT_SUCCESS(vboxrc))
    244                        {
    245                            if (cb == 0)
    246                            {
    247                                /* 0 bytes returned means the clipboard is empty.
    248                                 * Deallocate the memory and set hMem to NULL to get to
    249                                 * the clipboard empty code path. */
    250                                GlobalUnlock(hMem);
    251                                GlobalFree(hMem);
    252                                hMem = NULL;
    253                            }
    254                            else if (cb > cbPrealloc)
    255                            {
    256                                GlobalUnlock(hMem);
    257 
    258                                /* The preallocated buffer is too small, adjust the size. */
    259                                hMem = GlobalReAlloc(hMem, cb, 0);
    260                                LogFlowFunc(("Reallocated hMem = %p\n", hMem));
    261 
    262                                if (hMem)
    263                                {
    264                                    pMem = GlobalLock(hMem);
    265                                    LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));
    266 
    267                                    if (pMem)
    268                                    {
    269                                        /* Read the host data to the preallocated buffer. */
    270                                        uint32_t cbNew = 0;
    271                                        vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cb, &cbNew);
    272                                        LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n", vboxrc, cb, cbNew));
    273 
    274                                        if (RT_SUCCESS(vboxrc) && cbNew <= cb)
    275                                        {
    276                                            cb = cbNew;
    277                                        }
    278                                        else
    279                                        {
    280                                            GlobalUnlock(hMem);
    281                                            GlobalFree(hMem);
    282                                            hMem = NULL;
    283                                        }
    284                                    }
    285                                    else
    286                                    {
    287                                        GlobalFree(hMem);
    288                                        hMem = NULL;
    289                                    }
    290                                }
    291                            }
    292 
    293                            if (hMem)
    294                            {
    295                                /* pMem is the address of the data. cb is the size of returned data. */
    296                                /* Verify the size of returned text, the memory block for clipboard
    297                                 * must have the exact string size.
    298                                 */
    299                                if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
    300                                {
    301                                    size_t cbActual = 0;
    302                                    HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual);
    303                                    if (FAILED(hrc))
    304                                    {
    305                                        /* Discard invalid data. */
    306                                        GlobalUnlock(hMem);
    307                                        GlobalFree(hMem);
    308                                        hMem = NULL;
    309                                    }
    310                                    else
    311                                    {
    312                                        /* cbActual is the number of bytes, excluding those used
    313                                         * for the terminating null character.
    314                                         */
    315                                        cb = (uint32_t)(cbActual + 2);
    316                                    }
    317                                }
    318                            }
    319 
    320                            if (hMem)
    321                            {
    322                                GlobalUnlock(hMem);
    323 
    324                                hMem = GlobalReAlloc(hMem, cb, 0);
    325                                LogFlowFunc(("Reallocated hMem = %p\n", hMem));
    326 
    327                                if (hMem)
    328                                {
    329                                    /* 'hMem' contains the host clipboard data.
    330                                     * size is 'cb' and format is 'format'. */
    331                                    HANDLE hClip = SetClipboardData(cfFormat, hMem);
    332                                    LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip));
    333 
    334                                    if (hClip)
    335                                    {
    336                                        /* The hMem ownership has gone to the system. Finish the processing. */
    337                                        break;
    338                                    }
    339 
    340                                    /* Cleanup follows. */
    341                                }
    342                            }
    343                        }
    344                        if (hMem)
    345                            GlobalUnlock(hMem);
    346                    }
    347                    if (hMem)
    348                        GlobalFree(hMem);
    349                }
    350 
    351                /* Something went wrong. */
    352                VBoxClipboardWinClear();
    353            }
     190            LogFunc(("WM_RENDERFORMAT\n"));
     191
     192            /* Insert the requested clipboard format data into the clipboard. */
     193            const UINT cfFormat = (UINT)wParam;
     194
     195            const VBOXCLIPBOARDFORMAT fFormat = VBoxClipboardWinClipboardFormatToVBox(cfFormat);
     196
     197            LogFunc(("WM_RENDERFORMAT: cfFormat=%u -> fFormat=0x%x\n", cfFormat, fFormat));
     198
     199            if (fFormat != VBOX_SHARED_CLIPBOARD_FMT_NONE)
     200            {
     201                const uint32_t cbPrealloc = _4K;
     202                uint32_t cb = 0;
     203
     204                /* Preallocate a buffer, most of small text transfers will fit into it. */
     205                HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc);
     206                LogFlowFunc(("Preallocated handle hMem = %p\n", hMem));
     207
     208                if (hMem)
     209                {
     210                    void *pMem = GlobalLock(hMem);
     211                    LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));
     212
     213                    if (pMem)
     214                    {
     215                        /* 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))
     220                        {
     221                            if (cb == 0)
     222                            {
     223                                /* 0 bytes returned means the clipboard is empty.
     224                                 * Deallocate the memory and set hMem to NULL to get to
     225                                 * the clipboard empty code path. */
     226                                GlobalUnlock(hMem);
     227                                GlobalFree(hMem);
     228                                hMem = NULL;
     229                            }
     230                            else if (cb > cbPrealloc)
     231                            {
     232                                GlobalUnlock(hMem);
     233
     234                                /* The preallocated buffer is too small, adjust the size. */
     235                                hMem = GlobalReAlloc(hMem, cb, 0);
     236                                LogFlowFunc(("Reallocated hMem = %p\n", hMem));
     237
     238                                if (hMem)
     239                                {
     240                                    pMem = GlobalLock(hMem);
     241                                    LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));
     242
     243                                    if (pMem)
     244                                    {
     245                                        /* Read the host data to the preallocated buffer. */
     246                                        uint32_t cbNew = 0;
     247                                        vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cb, &cbNew);
     248                                        LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n",
     249                                                     vboxrc, cb, cbNew));
     250
     251                                        if (RT_SUCCESS(vboxrc)
     252                                            && cbNew <= cb)
     253                                        {
     254                                            cb = cbNew;
     255                                        }
     256                                        else
     257                                        {
     258                                            GlobalUnlock(hMem);
     259                                            GlobalFree(hMem);
     260                                            hMem = NULL;
     261                                        }
     262                                    }
     263                                    else
     264                                    {
     265                                        GlobalFree(hMem);
     266                                        hMem = NULL;
     267                                    }
     268                                }
     269                            }
     270
     271                            if (hMem)
     272                            {
     273                                /* pMem is the address of the data. cb is the size of returned data. */
     274                                /* Verify the size of returned text, the memory block for clipboard
     275                                 * must have the exact string size.
     276                                 */
     277                                if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
     278                                {
     279                                    size_t cbActual = 0;
     280                                    HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual);
     281                                    if (FAILED(hrc))
     282                                    {
     283                                        /* Discard invalid data. */
     284                                        GlobalUnlock(hMem);
     285                                        GlobalFree(hMem);
     286                                        hMem = NULL;
     287                                    }
     288                                    else
     289                                    {
     290                                        /* cbActual is the number of bytes, excluding those used
     291                                         * for the terminating null character.
     292                                         */
     293                                        cb = (uint32_t)(cbActual + 2);
     294                                    }
     295                                }
     296                            }
     297
     298                            if (hMem)
     299                            {
     300                                GlobalUnlock(hMem);
     301
     302                                hMem = GlobalReAlloc(hMem, cb, 0);
     303                                LogFlowFunc(("Reallocated hMem = %p\n", hMem));
     304
     305                                if (hMem)
     306                                {
     307                                    /* 'hMem' contains the host clipboard data.
     308                                     * size is 'cb' and format is 'format'. */
     309                                    HANDLE hClip = SetClipboardData(cfFormat, hMem);
     310                                    LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip));
     311
     312                                    if (hClip)
     313                                    {
     314                                        /* The hMem ownership has gone to the system. Finish the processing. */
     315                                        break;
     316                                    }
     317
     318                                    /* Cleanup follows. */
     319                                }
     320                            }
     321                        }
     322                        if (hMem)
     323                            GlobalUnlock(hMem);
     324                    }
     325                    if (hMem)
     326                        GlobalFree(hMem);
     327                }
     328            }
    354329        }
    355330        break;
     
    357332        case WM_RENDERALLFORMATS:
    358333        {
    359            /* Do nothing. The clipboard formats will be unavailable now, because the
     334            /* Do nothing. The clipboard formats will be unavailable now, because the
    360335            * windows is to be destroyed and therefore the guest side becomes inactive.
    361336            */
     337            int vboxrc = VBoxClipboardWinOpen(hwnd);
     338            if (RT_SUCCESS(vboxrc))
     339            {
     340               VBoxClipboardWinClear();
     341               VBoxClipboardWinClose();
     342            }
     343        }
     344        break;
     345
     346        case VBOX_CLIPBOARD_WM_SET_FORMATS:
     347        {
     348           /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */
     349           VBOXCLIPBOARDFORMATS fFormats = (uint32_t)lParam;
     350
     351           LogFunc(("VBOX_WM_SHCLPB_SET_FORMATS: fFormats=0x%x\n", fFormats));
     352
    362353           int vboxrc = VBoxClipboardWinOpen(hwnd);
    363354           if (RT_SUCCESS(vboxrc))
    364355           {
    365356               VBoxClipboardWinClear();
     357
     358               HANDLE hClip    = NULL;
     359               UINT   cfFormat = 0;
     360
     361               /** @todo r=andy Only one clipboard format can be set at once, at least on Windows. */
     362
     363               if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
     364               {
     365                   LogFunc(("VBOX_WM_SHCLPB_SET_FORMATS: CF_UNICODETEXT\n"));
     366                   hClip = SetClipboardData(CF_UNICODETEXT, NULL);
     367               }
     368
     369               else if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
     370               {
     371                   LogFunc(("VBOX_WM_SHCLPB_SET_FORMATS: CF_DIB\n"));
     372                   hClip = SetClipboardData(CF_DIB, NULL);
     373               }
     374
     375               else if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
     376               {
     377                   LogFunc(("VBOX_WM_SHCLPB_SET_FORMATS: VBOX_CLIPBOARD_WIN_REGFMT_HTML\n"));
     378                   cfFormat = RegisterClipboardFormat(VBOX_CLIPBOARD_WIN_REGFMT_HTML);
     379                   if (cfFormat != 0)
     380                       hClip = SetClipboardData(cfFormat, NULL);
     381               }
     382
     383#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     384               else if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
     385               {
     386                   LogFunc(("VBOX_WM_SHCLPB_SET_FORMATS: VBOX_CLIPBOARD_WIN_REGFMT_URI_LIST\n"));
     387                   if (pWinCtx->URI.pDataObj == NULL) /* Only allow one transfer at a time. */
     388                   {
     389                       pWinCtx->URI.pDataObj = new VBoxClipboardWinDataObject(/* No additional formats needed right now */);
     390                       if (pWinCtx->URI.pDataObj)
     391                       {
     392                           int vboxrc = pWinCtx->URI.pDataObj->Init(pCtx->u32ClientID);
     393                           if (RT_SUCCESS(vboxrc))
     394                           {
     395                               VBoxClipboardWinClose();
     396                               /* Note: Clipboard must be closed first before calling OleSetClipboard(). */
     397
     398                               /** @todo There is a potential race between VBoxClipboardWinClose() and OleSetClipboard(),
     399                                *        where another application could own the clipboard (open), and thus the call to
     400                                *        OleSetClipboard() will fail. Needs fixing. */
     401
     402                               HRESULT hr = OleSetClipboard(pWinCtx->URI.pDataObj);
     403                               if (FAILED(hr))
     404                                   LogRel(("Clipboard: Failed with %Rhrc when setting data object to clipboard\n", hr));
     405                           }
     406                       }
     407                   }
     408               }
     409#endif
     410               else
     411                   LogRel(("Clipboard: Unsupported format(s) (0x%x), skipping\n", fFormats));
     412
     413               /** @todo Implement more flexible clipboard precedence for supported formats. */
     414
    366415               VBoxClipboardWinClose();
     416               /* Note: Clipboard must be closed first before calling OleSetClipboard(). */
     417
     418               LogFunc(("VBOX_WM_SHCLPB_SET_FORMATS: cfFormat=%u, lastErr=%ld\n", cfFormat, GetLastError()));
    367419           }
    368420        }
    369421        break;
    370422
    371         case VBOX_CLIPBOARD_WM_SET_FORMATS:
    372         {
    373            /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */
    374            VBOXCLIPBOARDFORMATS fFormats = (uint32_t)lParam;
    375 
    376            LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: fFormats=0x%x\n", fFormats));
    377 
    378            int vboxrc = VBoxClipboardWinOpen(hwnd);
    379            if (RT_SUCCESS(vboxrc))
    380            {
    381                VBoxClipboardWinClear();
    382 
    383                HANDLE hClip = NULL;
    384 
    385                if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
    386                    hClip = SetClipboardData(CF_UNICODETEXT, NULL);
    387 
    388                if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
    389                    hClip = SetClipboardData(CF_DIB, NULL);
    390 
    391                if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
    392                {
    393                    UINT format = RegisterClipboardFormat("HTML Format");
    394                    if (format != 0)
    395                        hClip = SetClipboardData(format, NULL);
    396                }
    397 
    398 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    399                if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
    400                    hClip = SetClipboardData(CF_HDROP, NULL);
    401 #endif
    402 
    403                /** @todo Implement more flexible clipboard precedence for supported formats. */
    404 
    405                if (hClip == NULL)
    406                    LogRel(("Clipboard: Unsupported format(s) from host (0x%x), ignoring\n", fFormats));
    407 
    408                VBoxClipboardWinClose();
    409 
    410                LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: hClip=%p, lastErr=%ld\n", hClip, GetLastError()));
    411            }
    412         }
    413         break;
    414 
    415423        case VBOX_CLIPBOARD_WM_READ_DATA:
    416424        {
    417            /* Send data in the specified format to the host. */
    418            uint32_t u32Formats = (uint32_t)lParam;
    419            HANDLE hClip = NULL;
    420 
    421            LogFlowFunc(("VBOX_WM_SHCLPB_READ_DATA: u32Formats=0x%x\n", u32Formats));
    422 
    423            int vboxrc = VBoxClipboardWinOpen(hwnd);
    424            if (RT_SUCCESS(vboxrc))
    425            {
     425            /* Send data in the specified format to the host. */
     426            uint32_t u32Formats = (uint32_t)lParam;
     427            HANDLE hClip = NULL;
     428
     429            LogFlowFunc(("VBOX_WM_SHCLPB_READ_DATA: u32Formats=0x%x\n", u32Formats));
     430
     431            int vboxrc = VBoxClipboardWinOpen(hwnd);
     432            if (RT_SUCCESS(vboxrc))
     433            {
    426434               if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
    427435               {
     
    465473               else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
    466474               {
    467                    UINT format = RegisterClipboardFormat("HTML Format");
     475                   UINT format = RegisterClipboardFormat(VBOX_CLIPBOARD_WIN_REGFMT_HTML);
    468476                   if (format != 0)
    469477                   {
     
    489497               else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
    490498               {
    491                    hClip = GetClipboardData(CF_HDROP);
    492                    if (hClip)
     499                   UINT format = RegisterClipboardFormat(VBOX_CLIPBOARD_WIN_REGFMT_URI_LIST);
     500                   if (format != 0)
    493501                   {
    494                        HDROP hDrop = (HDROP)GlobalLock(hClip);
    495                        if (hDrop)
     502                       hClip = GetClipboardData(format);
     503                       if (hClip)
    496504                       {
    497        /*                    vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_URI_LIST,
    498                                                              );*/
    499                            GlobalUnlock(hClip);
    500                        }
    501                        else
    502                        {
    503                            hClip = NULL;
     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                           }
    504516                       }
    505517                   }
     
    507519#endif
    508520               VBoxClipboardWinClose();
    509            }
    510 
    511            if (hClip == NULL)
    512            {
     521            }
     522
     523            if (hClip == NULL)
     524            {
    513525               /* Requested clipboard format is not available, send empty data. */
    514                VbglR3ClipboardWriteData(pCtx->u32ClientID, 0, NULL, 0);
    515            }
     526               VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_NONE, NULL, 0);
     527            }
    516528        }
    517529        break;
     
    519531        case WM_DESTROY:
    520532        {
    521            VBoxClipboardWinRemoveFromCBChain(pWinCtx);
    522            if (pWinCtx->oldAPI.timerRefresh)
     533            VBoxClipboardWinRemoveFromCBChain(pWinCtx);
     534            if (pWinCtx->oldAPI.timerRefresh)
    523535               KillTimer(pWinCtx->hWnd, 0);
    524            /*
     536            /*
    525537            * don't need to call PostQuitMessage cause
    526538            * the VBoxTray already finished a message loop
     
    531543        default:
    532544        {
    533            rc = DefWindowProc(hwnd, msg, wParam, lParam);
     545            rc = DefWindowProc(hwnd, msg, wParam, lParam);
    534546        }
    535547        break;
     
    643655    }
    644656
     657#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     658    HRESULT hr = OleInitialize(NULL);
     659    if (FAILED(hr))
     660    {
     661        LogRel(("Clipboard: Initializing OLE failed (%Rhrc) -- file transfers unavailable\n"));
     662        /* Not critical, the rest of the clipboard might work. */
     663    }
     664    else
     665        LogRel(("Clipboard: Initialized OLE\n"));
     666#endif
     667
    645668    RT_BZERO(pCtx, sizeof(VBOXCLIPBOARDCONTEXT));
    646669
     
    782805    vboxClipboardDestroy(pCtx);
    783806    RT_BZERO(pCtx, sizeof(VBOXCLIPBOARDCONTEXT));
     807
     808#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST_ASF
     809    OleSetClipboard(NULL); /* Make sure to flush the clipboard on destruction. */
     810    OleUninitialize();
     811#endif
    784812
    785813    return;
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