VirtualBox

Changeset 78440 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 7, 2019 5:44:31 PM (6 years ago)
Author:
vboxsync
Message:

Shared Clipboard/URI: Update.

Location:
trunk/src/VBox
Files:
3 added
5 edited

Legend:

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

    r78307 r78440  
    5252        VBoxClipboard.cpp \
    5353        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp
     54 ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     55 VBoxTray_SOURCES  += \
     56        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardURIList.cpp \
     57        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardURIObject.cpp \
     58        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardPath.cpp \
     59        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp \
     60        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardEnumFormatEtcImpl-win.cpp \
     61        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardStreamImpl-win.cpp
     62 endif
    5463endif
    5564ifdef VBOX_WITH_DRAG_AND_DROP
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp

    r78317 r78440  
    174174        {
    175175           /* Insert the requested clipboard format data into the clipboard. */
    176            uint32_t u32Format = 0;
    177            UINT format = (UINT)wParam;
    178 
    179            LogFlowFunc(("WM_RENDERFORMAT, format = %x\n", format));
    180            switch (format)
     176           uint32_t fFormat = VBOX_SHARED_CLIPBOARD_FMT_NONE;
     177
     178           const UINT cfFormat = (UINT)wParam;
     179           switch (cfFormat)
    181180           {
    182181              case CF_UNICODETEXT:
    183                   u32Format |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
     182                  fFormat = VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
    184183                  break;
    185184
    186185              case CF_DIB:
    187                   u32Format |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
     186                  fFormat = VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
    188187                  break;
    189188
     189#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     190              case CF_HDROP:
     191                  fFormat = VBOX_SHARED_CLIPBOARD_FMT_URI_LIST;
     192                  break;
     193#endif
    190194              default:
    191                   if (format >= 0xC000)
     195                  if (cfFormat >= 0xC000) /** @todo r=andy Explain. */
    192196                  {
    193                       TCHAR szFormatName[256];
    194 
    195                       int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName) / sizeof(TCHAR));
     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));
    196200                      if (cActual)
    197201                      {
    198202                          if (strcmp(szFormatName, "HTML Format") == 0)
    199                           {
    200                               u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
    201                           }
     203                              fFormat = VBOX_SHARED_CLIPBOARD_FMT_HTML;
    202204                      }
    203205                  }
     
    205207           }
    206208
    207            if (u32Format == 0)
     209           LogFunc(("WM_RENDERFORMAT: format=%u -> fFormat=0x%x\n", cfFormat, fFormat));
     210
     211           if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_NONE)
    208212           {
    209213               /* Unsupported clipboard format is requested. */
    210                LogFlowFunc(("Unsupported clipboard format requested: %ld\n", u32Format));
     214               LogRel(("Clipboard: Unsupported clipboard format requested (0x%x)\n", fFormat));
    211215               VBoxClipboardWinClear();
    212216           }
     217#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     218           else if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
     219           {
     220
     221           }
     222#endif
    213223           else
    214224           {
    215                const uint32_t cbPrealloc = 4096; /** @todo r=andy Make it dynamic for supporting larger text buffers! */
     225               const uint32_t cbPrealloc = _4K;
    216226               uint32_t cb = 0;
    217227
     
    228238                   {
    229239                       /* Read the host data to the preallocated buffer. */
    230                        int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cbPrealloc, &cb);
     240                       int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cbPrealloc, &cb);
    231241                       LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n",  vboxrc));
    232242
     
    259269                                       /* Read the host data to the preallocated buffer. */
    260270                                       uint32_t cbNew = 0;
    261                                        vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cb, &cbNew);
     271                                       vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cb, &cbNew);
    262272                                       LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n", vboxrc, cb, cbNew));
    263273
     
    287297                                * must have the exact string size.
    288298                                */
    289                                if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
     299                               if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
    290300                               {
    291301                                   size_t cbActual = 0;
     
    319329                                   /* 'hMem' contains the host clipboard data.
    320330                                    * size is 'cb' and format is 'format'. */
    321                                    HANDLE hClip = SetClipboardData(format, hMem);
     331                                   HANDLE hClip = SetClipboardData(cfFormat, hMem);
    322332                                   LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip));
    323333
     
    362372        {
    363373           /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */
    364            uint32_t u32Formats = (uint32_t)lParam;
    365 
    366            LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: u32Formats=0x%x\n", u32Formats));
     374           VBOXCLIPBOARDFORMATS fFormats = (uint32_t)lParam;
     375
     376           LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: fFormats=0x%x\n", fFormats));
    367377
    368378           int vboxrc = VBoxClipboardWinOpen(hwnd);
     
    373383               HANDLE hClip = NULL;
    374384
    375                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
     385               if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
    376386                   hClip = SetClipboardData(CF_UNICODETEXT, NULL);
    377387
    378                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
     388               if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
    379389                   hClip = SetClipboardData(CF_DIB, NULL);
    380390
    381                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
     391               if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
    382392               {
    383393                   UINT format = RegisterClipboardFormat("HTML Format");
     
    387397
    388398#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    389                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
     399               if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
    390400                   hClip = SetClipboardData(CF_HDROP, NULL);
    391401#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
    392408               VBoxClipboardWinClose();
    393409
     
    479495                       if (hDrop)
    480496                       {
    481                            vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_URI_LIST,
    482                                                              );
     497       /*                    vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_URI_LIST,
     498                                                             );*/
    483499                           GlobalUnlock(hClip);
    484500                       }
     
    681697                break;
    682698
    683             LogFlowFunc(("Error getting host message, rc=%Rrc\n", rc));
     699            LogFunc(("Error getting host message, rc=%Rrc\n", rc));
    684700
    685701            if (*pfShutdown)
     
    701717                    * respond to WM_RENDERFORMAT message. */
    702718                   ::PostMessage(pWinCtx->hWnd, VBOX_CLIPBOARD_WM_SET_FORMATS, 0, u32Formats);
    703                }
    704719                   break;
     720               }
    705721
    706722               case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA:
     
    708724                   /* The host needs data in the specified format. */
    709725                   ::PostMessage(pWinCtx->hWnd, VBOX_CLIPBOARD_WM_READ_DATA, 0, u32Formats);
    710                }
    711726                   break;
     727               }
    712728
    713729               case VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT:
     
    716732                   LogRel(("Clipboard: Terminating ...\n"));
    717733                   ASMAtomicXchgBool(pfShutdown, true);
    718                }
    719734                   break;
     735               }
    720736
    721737               default:
     
    725741                   /* Wait a bit before retrying. */
    726742                   RTThreadSleep(1000);
    727                }
    728743                   break;
     744               }
    729745            }
    730746        }
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp

    r78393 r78440  
    2222#include <iprt/thread.h>
    2323
     24#define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD
    2425#include <VBox/log.h>
     26
    2527#include <VBox/GuestHost/SharedClipboard.h>
    2628#include <VBox/GuestHost/SharedClipboard-win.h>
     
    275277    AssertPtrReturn(puFormats, VERR_INVALID_POINTER);
    276278
    277     if (!pCtx)
    278     {
    279         *puFormats = 0;
    280         return VINF_SUCCESS;
    281     }
    282 
    283     uint32_t uFormats = 0;
     279    uint32_t uFormats = VBOX_SHARED_CLIPBOARD_FMT_NONE;
    284280
    285281    /* Query list of available formats and report to host. */
     
    336332    }
    337333    else
     334    {
     335        LogFlowFunc(("uFormats = 0x%08X\n", uFormats));
    338336        *puFormats = uFormats;
    339 
    340     return rc;
    341 }
    342 
     337    }
     338
     339    return rc;
     340}
     341
  • trunk/src/VBox/HostServices/SharedClipboard/Makefile.kmk

    r78307 r78440  
    4343        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp \
    4444        darwin-pasteboard.cpp
     45ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     46 VBoxSharedClipboard_SOURCES += \
     47        $(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
     50endif
    4551if1of ($(KBUILD_TARGET), linux solaris freebsd) ## @todo X11
    4652 ifndef VBOX_HEADLESS
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp

    r78317 r78440  
    2525#include <VBox/HostServices/VBoxClipboardSvc.h>
    2626#include <VBox/GuestHost/SharedClipboard-win.h>
     27#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     28# include <VBox/GuestHost/SharedClipboard-uri.h>
     29#endif
    2730
    2831#include <iprt/alloc.h>
     
    3033#include <iprt/asm.h>
    3134#include <iprt/assert.h>
     35#include <iprt/ldr.h>
     36#include <iprt/semaphore.h>
    3237#include <iprt/thread.h>
    33 #include <iprt/ldr.h>
    3438#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    3539# include <iprt/utf16.h>
     
    5862    RTTHREAD                 hThread;
    5963    /** Event which gets triggered if the host clipboard needs to render its data. */
    60     HANDLE                   hRenderEvent;
     64    RTSEMEVENT               hRenderEvent;
    6165    /** Structure for keeping and communicating with client data (from the guest). */
    6266    PVBOXCLIPBOARDCLIENTDATA pClient;
     
    115119                                 void *pvDst, uint32_t cbDst, uint32_t *pcbActualDst)
    116120{
    117     LogFlow(("vboxClipboardGetData cbSrc = %d, cbDst = %d\n", cbSrc, cbDst));
     121    LogFlowFunc(("cbSrc = %d, cbDst = %d\n", cbSrc, cbDst));
    118122
    119123    if (   u32Format == VBOX_SHARED_CLIPBOARD_FMT_HTML
     
    139143            *pcbActualDst = 0;
    140144    }
    141 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    142     if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
    143     {
    144         /* Convert data to URI list. */
    145     }
    146 #endif
    147145    else
    148146    {
     
    163161}
    164162
    165 static int vboxClipboardReadDataFromClient(VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Format)
     163static int vboxClipboardReadDataFromClient(VBOXCLIPBOARDCONTEXT *pCtx, VBOXCLIPBOARDFORMAT fFormat)
    166164{
    167165    Assert(pCtx->pClient);
     
    169167    Assert(pCtx->pClient->data.pv == NULL && pCtx->pClient->data.cb == 0 && pCtx->pClient->data.u32Format == 0);
    170168
    171     LogFlow(("vboxClipboardReadDataFromClient u32Format = %02X\n", u32Format));
    172 
    173     ResetEvent(pCtx->hRenderEvent);
    174 
    175     vboxSvcClipboardReportMsg(pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA, u32Format);
    176 
    177     DWORD ret = WaitForSingleObject(pCtx->hRenderEvent, INFINITE);
    178     LogFlow(("vboxClipboardReadDataFromClient wait completed, ret 0x%08X, err %d\n",
    179              ret, GetLastError())); NOREF(ret);
    180 
    181     return VINF_SUCCESS;
     169    LogFlowFunc(("fFormat=%02X\n", fFormat));
     170
     171    vboxSvcClipboardReportMsg(pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA, fFormat);
     172
     173    return RTSemEventWait(pCtx->hRenderEvent, 30 * 1000 /* Timeout in ms */);
    182174}
    183175
     
    193185        case WM_CLIPBOARDUPDATE:
    194186        {
    195             Log(("WM_CLIPBOARDUPDATE\n"));
     187            LogFunc(("WM_CLIPBOARDUPDATE\n"));
    196188
    197189            if (GetClipboardOwner() != hwnd)
     
    205197        case WM_CHANGECBCHAIN:
    206198        {
    207             Log(("WM_CHANGECBCHAIN\n"));
     199            LogFunc(("WM_CHANGECBCHAIN\n"));
    208200
    209201            if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI))
     
    240232        case WM_DRAWCLIPBOARD:
    241233        {
    242             Log(("WM_DRAWCLIPBOARD\n"));
     234            LogFunc(("WM_DRAWCLIPBOARD\n"));
    243235
    244236            if (GetClipboardOwner() != hwnd)
     
    251243            if (pWinCtx->hWndNextInChain)
    252244            {
    253                 Log(("WM_DRAWCLIPBOARD next %p\n", pWinCtx->hWndNextInChain));
     245                LogFunc(("WM_DRAWCLIPBOARD next %p\n", pWinCtx->hWndNextInChain));
    254246                /* Pass the message to next windows in the clipboard chain. */
    255247                DWORD_PTR dwResult;
     
    290282        {
    291283            /* Insert the requested clipboard format data into the clipboard. */
    292             uint32_t u32Format = 0;
     284            VBOXCLIPBOARDFORMAT fFormat = VBOX_SHARED_CLIPBOARD_FMT_NONE;
    293285
    294286            UINT format = (UINT)wParam;
    295287
    296             Log(("WM_RENDERFORMAT: Format %u\n", format));
     288            LogFunc(("WM_RENDERFORMAT: Format %u\n", format));
    297289
    298290            switch (format)
    299291            {
    300292                case CF_UNICODETEXT:
    301                     u32Format |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
     293                    fFormat |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
    302294                    break;
    303295
    304296                case CF_DIB:
    305                     u32Format |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
     297                    fFormat |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
    306298                    break;
    307299
     
    314306                        {
    315307                            if (RTStrCmp(szFormatName, "HTML Format") == 0)
    316                                 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
     308                                fFormat |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
    317309#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    318310                            if (   RTStrCmp(szFormatName, CFSTR_FILEDESCRIPTOR) == 0
    319311                                || RTStrCmp(szFormatName, CFSTR_FILECONTENTS) == 0)
    320                                 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_URI_LIST;
     312                                fFormat |= VBOX_SHARED_CLIPBOARD_FMT_URI_LIST;
    321313#endif
    322314                        }
     
    325317            }
    326318
    327             if (u32Format == 0 || pCtx->pClient == NULL)
     319            if (   fFormat       == VBOX_SHARED_CLIPBOARD_FMT_NONE
     320                || pCtx->pClient == NULL)
    328321            {
    329322                /* Unsupported clipboard format is requested. */
    330                 Log(("WM_RENDERFORMAT unsupported format requested or client is not active.\n"));
    331                 EmptyClipboard ();
     323                LogFunc(("WM_RENDERFORMAT unsupported format requested or client is not active\n"));
     324                EmptyClipboard();
    332325            }
    333326            else
    334327            {
    335                 int vboxrc = vboxClipboardReadDataFromClient(pCtx, u32Format);
     328                int vboxrc = vboxClipboardReadDataFromClient(pCtx, fFormat);
    336329
    337330                LogFunc(("vboxClipboardReadDataFromClient vboxrc = %d, pv %p, cb %d, u32Format %d\n",
     
    341334                    && pCtx->pClient->data.pv != NULL
    342335                    && pCtx->pClient->data.cb > 0
    343                     && pCtx->pClient->data.u32Format == u32Format)
     336                    && pCtx->pClient->data.u32Format == fFormat)
    344337                {
    345338                    HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, pCtx->pClient->data.cb);
     
    355348                        if (pMem)
    356349                        {
    357                             Log(("WM_RENDERFORMAT setting data\n"));
     350                            LogFunc(("WM_RENDERFORMAT setting data\n"));
    358351
    359352                            if (pCtx->pClient->data.pv)
     
    401394        case WM_RENDERALLFORMATS:
    402395        {
    403             Log(("WM_RENDERALLFORMATS\n"));
     396            LogFunc(("WM_RENDERALLFORMATS\n"));
    404397
    405398            /* Do nothing. The clipboard formats will be unavailable now, because the
     
    414407            else
    415408            {
    416                 LogFlow(("vboxClipboardWndProc: WM_RENDERALLFORMATS: error in open clipboard. hwnd: %x, rc: %Rrc\n", hwnd, vboxrc));
     409                LogFlowFunc(("WM_RENDERALLFORMATS: error in open clipboard. hwnd: %x, rc: %Rrc\n", hwnd, vboxrc));
    417410            }
    418411        } break;
     
    425418                 * because host clipboard has more priority.
    426419                 */
    427                 Log(("VBOX_CLIPBOARD_WM_SET_FORMATS ignored\n"));
     420                LogFunc(("VBOX_CLIPBOARD_WM_SET_FORMATS ignored\n"));
    428421                break;
    429422            }
     
    432425            uint32_t u32Formats = (uint32_t)lParam;
    433426
    434             Log(("VBOX_CLIPBOARD_WM_SET_FORMATS: u32Formats=%02X\n", u32Formats));
     427            LogFunc(("VBOX_CLIPBOARD_WM_SET_FORMATS: u32Formats=%02X\n", u32Formats));
    435428
    436429            int vboxrc = VBoxClipboardWinOpen(hwnd);
     
    439432                VBoxClipboardWinClear();
    440433
    441                 Log(("VBOX_CLIPBOARD_WM_SET_FORMATS emptied clipboard\n"));
     434                LogFunc(("VBOX_CLIPBOARD_WM_SET_FORMATS emptied clipboard\n"));
    442435
    443436                HANDLE hClip = NULL;
     
    486479        default:
    487480        {
    488             Log(("WM_ %p\n", msg));
     481            LogFunc(("WM_ %p\n", msg));
    489482            rc = DefWindowProc(hwnd, msg, wParam, lParam);
    490483        }
    491484    }
    492485
    493     Log(("WM_ rc %d\n", rc));
     486    LogFunc(("WM_ rc %d\n", rc));
    494487    return rc;
    495488}
     
    497490DECLCALLBACK(int) VBoxClipboardThread(RTTHREAD hThreadSelf, void *pvUser)
    498491{
    499     RT_NOREF2(hThreadSelf, pvUser);
     492    RT_NOREF(hThreadSelf, pvUser);
     493
    500494    /* Create a window and make it a clipboard viewer. */
    501495    int rc = VINF_SUCCESS;
    502496
    503     LogFlow(("VBoxClipboardThread\n"));
     497    LogFlowFuncEnter();
    504498
    505499    const PVBOXCLIPBOARDCONTEXT pCtx    = &g_ctx;
     
    522516    if (atomWindowClass == 0)
    523517    {
    524         Log(("Failed to register window class\n"));
     518        LogFunc(("Failed to register window class\n"));
    525519        rc = VERR_NOT_SUPPORTED;
    526520    }
     
    534528        if (pWinCtx->hWnd == NULL)
    535529        {
    536             Log(("Failed to create window\n"));
     530            LogFunc(("Failed to create window\n"));
    537531            rc = VERR_NOT_SUPPORTED;
    538532        }
     
    559553            */
    560554            Assert(msgret >= 0);
    561             Log(("VBoxClipboardThread Message loop finished. GetMessage returned %d, message id: %d \n", msgret, msg.message));
     555            LogFunc(("Message loop finished. GetMessage returned %d, message id: %d \n", msgret, msg.message));
    562556        }
    563557    }
     
    578572 * formats to the guest.
    579573 *
    580  * @returns VBox status code.
     574 * @returns VBox status code, VINF_NO_CHANGE if no synchronization was required.
    581575 * @param   pCtx                Clipboard context to synchronize.
    582576 */
     
    585579    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
    586580
    587     if (pCtx->pClient == NULL) /* If we don't have any client data (yet), bail out. */
    588         return VINF_SUCCESS;
    589 
    590     uint32_t uFormats;
    591     int rc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats);
    592     if (RT_SUCCESS(rc))
    593         vboxSvcClipboardReportMsg(pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_REPORT_FORMATS, uFormats);
    594 
     581    int rc;
     582
     583    if (pCtx->pClient)
     584    {
     585        uint32_t uFormats;
     586        rc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats);
     587        if (RT_SUCCESS(rc))
     588            vboxSvcClipboardReportMsg(pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_REPORT_FORMATS, uFormats);
     589    }
     590    else /* If we don't have any client data (yet), bail out. */
     591        rc = VINF_NO_CHANGE;
     592
     593    LogFlowFuncLeaveRC(rc);
    595594    return rc;
    596595}
     
    601600int vboxClipboardInit(void)
    602601{
    603     int rc = VINF_SUCCESS;
    604 
    605     RT_ZERO(g_ctx);
     602    RT_ZERO(g_ctx); /* Be careful not messing up non-POD types! */
    606603
    607604    /* Check that new Clipboard API is available. */
    608605    VBoxClipboardWinCheckAndInitNewAPI(&g_ctx.Win.newAPI);
    609606
    610     g_ctx.hRenderEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    611 
    612     rc = RTThreadCreate(&g_ctx.hThread, VBoxClipboardThread, NULL, _64K /* Stack size */,
    613                         RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLIP");
     607    int rc = RTSemEventCreate(&g_ctx.hRenderEvent);
     608    if (RT_SUCCESS(rc))
     609    {
     610        rc = RTThreadCreate(&g_ctx.hThread, VBoxClipboardThread, NULL, _64K /* Stack size */,
     611                            RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLIP");
     612    }
    614613
    615614    if (RT_FAILURE(rc))
    616     {
    617         CloseHandle(g_ctx.hRenderEvent);
    618     }
     615        RTSemEventDestroy(g_ctx.hRenderEvent);
    619616
    620617    return rc;
     
    623620void vboxClipboardDestroy(void)
    624621{
    625     Log(("vboxClipboardDestroy\n"));
     622    LogFlowFuncEnter();
    626623
    627624    if (g_ctx.Win.hWnd)
     
    630627    }
    631628
    632     CloseHandle(g_ctx.hRenderEvent);
     629    int rc = RTSemEventDestroy(g_ctx.hRenderEvent);
     630    AssertRC(rc);
    633631
    634632    /* Wait for the window thread to terminate. */
    635     RTThreadWait(g_ctx.hThread, RT_INDEFINITE_WAIT, NULL);
     633    rc = RTThreadWait(g_ctx.hThread, 30 * 1000 /* Timeout in ms */, NULL);
     634    if (RT_FAILURE(rc))
     635        LogRel(("Shared Clipboard: Waiting for window thread termination failed with rc=%Rrc\n", rc));
    636636
    637637    g_ctx.hThread = NIL_RTTHREAD;
     
    640640int vboxClipboardConnect(VBOXCLIPBOARDCLIENTDATA *pClient, bool fHeadless)
    641641{
    642     NOREF(fHeadless);
    643     Log(("vboxClipboardConnect\n"));
     642    RT_NOREF(fHeadless);
     643
     644    LogFlowFuncEnter();
    644645
    645646    if (g_ctx.pClient != NULL)
     
    667668void vboxClipboardDisconnect(VBOXCLIPBOARDCLIENTDATA *pClient)
    668669{
    669     RT_NOREF1(pClient);
    670     Log(("vboxClipboardDisconnect\n"));
     670    RT_NOREF(pClient);
     671
     672    LogFlowFuncEnter();
    671673
    672674    g_ctx.pClient = NULL;
     
    684686}
    685687
    686 int DumpHtml(const char *pszSrc, size_t cb)
     688#ifdef VBOX_STRICT
     689static int vboxClipboardDbgDumpHtml(const char *pszSrc, size_t cb)
    687690{
    688691    size_t cchIgnored = 0;
     
    701704            }
    702705            else
    703                 Log(("Error in copying string.\n"));
    704             Log(("Removed \\r\\n: %s\n", pszBuf));
     706                LogFunc(("Error in copying string\n"));
     707            LogFunc(("Removed \\r\\n: %s\n", pszBuf));
    705708            RTMemFree(pszBuf);
    706709        }
     
    708711        {
    709712            rc = VERR_NO_MEMORY;
    710             Log(("Not enough memory to allocate buffer.\n"));
     713            LogFunc(("Not enough memory to allocate buffer\n"));
    711714        }
    712715    }
    713716    return rc;
    714717}
     718#endif
    715719
    716720int vboxClipboardReadData(VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Format, void *pv, uint32_t cb, uint32_t *pcbActual)
     
    719723    AssertPtrReturn(pClient->pCtx, VERR_INVALID_POINTER);
    720724
    721     LogFlow(("vboxClipboardReadData: u32Format = %02X\n", u32Format));
     725    LogFlowFunc(("u32Format=%02X\n", u32Format));
    722726
    723727    HANDLE hClip = NULL;
     
    731735    if (RT_SUCCESS(rc))
    732736    {
    733         LogFunc(("Clipboard opened.\n"));
     737        LogFunc(("Clipboard opened\n"));
    734738
    735739        if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
    736740        {
    737741            hClip = GetClipboardData(CF_DIB);
    738 
    739742            if (hClip != NULL)
    740743            {
     
    759762        {
    760763            hClip = GetClipboardData(CF_UNICODETEXT);
    761 
    762764            if (hClip != NULL)
    763765            {
     
    782784        {
    783785            UINT format = RegisterClipboardFormat("HTML Format");
    784 
    785786            if (format != 0)
    786787            {
    787788                hClip = GetClipboardData(format);
    788 
    789789                if (hClip != NULL)
    790790                {
    791791                    LPVOID lp = GlobalLock(hClip);
    792 
    793792                    if (lp != NULL)
    794793                    {
     
    797796                        vboxClipboardGetData(VBOX_SHARED_CLIPBOARD_FMT_HTML, lp, GlobalSize(hClip),
    798797                                             pv, cb, pcbActual);
    799                         LogRelFlowFunc(("Raw HTML clipboard data from host :"));
    800                         DumpHtml((char *)pv, cb);
     798#ifdef VBOX_STRICT
     799                        LogFlowFunc(("Raw HTML clipboard data from host:"));
     800                        vboxClipboardDbgDumpHtml((char *)pv, cb);
     801#endif
    801802                        GlobalUnlock(hClip);
    802803                    }
     
    811812        else if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
    812813        {
    813     #if 0
    814             UINT format = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
    815             if (format)
    816             {
    817                 hClip = GetClipboardData(format);
    818                 if (hClip != NULL)
     814            hClip = GetClipboardData(CF_HDROP);
     815            if (hClip != NULL)
     816            {
     817                LPVOID lp = GlobalLock(hClip);
     818                if (lp)
    819819                {
    820                     LPVOID lp = GlobalLock(hClip);
    821 
    822                     if (lp != NULL)
     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++)
    823843                    {
    824                         LogFunc(("CF_HTML\n"));
    825 
    826                         vboxClipboardGetData(VBOX_SHARED_CLIPBOARD_FMT_HTML, lp, GlobalSize(hClip),
    827                                              pv, cb, pcbActual);
    828                         LogRelFlowFunc(("Raw HTML clipboard data from host :"));
    829                         DumpHtml((char *)pv, cb);
    830                         GlobalUnlock(hClip);
    831                     }
    832                     else
    833                     {
    834                         hClip = NULL;
    835                     }
    836                 }
    837             }
    838     #else
    839             /* Convert to a string list, separated by \r\n. */
    840             DROPFILES *pDropFiles = (DROPFILES *)hClip;
    841             AssertPtr(pDropFiles);
    842 
    843             /* Do we need to do Unicode stuff? */
    844             const bool fUnicode = RT_BOOL(pDropFiles->fWide);
    845 
    846             /* Get the offset of the file list. */
    847             Assert(pDropFiles->pFiles >= sizeof(DROPFILES));
    848 
    849             /* Note: This is *not* pDropFiles->pFiles! DragQueryFile only
    850              *       will work with the plain storage medium pointer! */
    851             HDROP hDrop = (HDROP)(hClip);
    852 
    853             /* First, get the file count. */
    854             /** @todo Does this work on Windows 2000 / NT4? */
    855             char *pszFiles = NULL;
    856             uint32_t cchFiles = 0;
    857             UINT cFiles = DragQueryFile(hDrop, UINT32_MAX /* iFile */, NULL /* lpszFile */, 0 /* cchFile */);
    858 
    859             LogRel(("DnD: Got %RU16 file(s), fUnicode=%RTbool\n", cFiles, fUnicode));
    860 
    861             for (UINT i = 0; i < cFiles; i++)
    862             {
    863                 UINT cchFile = DragQueryFile(hDrop, i /* File index */, NULL /* Query size first */, 0 /* cchFile */);
    864                 Assert(cchFile);
    865 
    866                 if (RT_FAILURE(rc))
    867                     break;
    868 
    869                 char *pszFileUtf8 = NULL; /* UTF-8 version. */
    870                 UINT cchFileUtf8 = 0;
    871                 if (fUnicode)
    872                 {
    873                     /* Allocate enough space (including terminator). */
    874                     WCHAR *pwszFile = (WCHAR *)RTMemAlloc((cchFile + 1) * sizeof(WCHAR));
    875                     if (pwszFile)
    876                     {
    877                         const UINT cwcFileUtf16 = DragQueryFileW(hDrop, i /* File index */,
    878                                                                  pwszFile, cchFile + 1 /* Include terminator */);
    879 
    880                         AssertMsg(cwcFileUtf16 == cchFile, ("cchFileUtf16 (%RU16) does not match cchFile (%RU16)\n",
    881                                                             cwcFileUtf16, cchFile));
    882                         RT_NOREF(cwcFileUtf16);
    883 
    884                         rc = RTUtf16ToUtf8(pwszFile, &pszFileUtf8);
     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
    885893                        if (RT_SUCCESS(rc))
    886894                        {
    887                             cchFileUtf8 = (UINT)strlen(pszFileUtf8);
    888                             Assert(cchFileUtf8);
     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;
    889902                        }
    890 
    891                         RTMemFree(pwszFile);
     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 */
    892917                    }
    893                     else
    894                         rc = VERR_NO_MEMORY;
     918
     919                    if (RT_SUCCESS(rc))
     920                    {
     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))
     932                        {
     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;
     942                        }
     943                    }
     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
     951                    GlobalUnlock(hClip);
    895952                }
    896                 else /* ANSI */
    897                 {
    898                     /* Allocate enough space (including terminator). */
    899                     pszFileUtf8 = (char *)RTMemAlloc((cchFile + 1) * sizeof(char));
    900                     if (pszFileUtf8)
    901                     {
    902                         cchFileUtf8 = DragQueryFileA(hDrop, i /* File index */,
    903                                                      pszFileUtf8, cchFile + 1 /* Include terminator */);
    904 
    905                         AssertMsg(cchFileUtf8 == cchFile, ("cchFileUtf8 (%RU16) does not match cchFile (%RU16)\n",
    906                                                            cchFileUtf8, cchFile));
    907                     }
    908                     else
    909                         rc = VERR_NO_MEMORY;
    910                 }
    911 
    912                 if (RT_SUCCESS(rc))
    913                 {
    914                     LogFlowFunc(("\tFile: %s (cchFile=%RU16)\n", pszFileUtf8, cchFileUtf8));
    915 
    916                     LogRel(("DnD: Adding guest file '%s'\n", pszFileUtf8));
    917 
    918                     rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, pszFileUtf8, cchFileUtf8);
    919                     if (RT_SUCCESS(rc))
    920                         cchFiles += cchFileUtf8;
    921                 }
    922                 else
    923                     LogRel(("DnD: Error handling file entry #%u, rc=%Rrc\n", i, rc));
    924 
    925                 if (pszFileUtf8)
    926                     RTStrFree(pszFileUtf8);
    927 
    928                 if (RT_FAILURE(rc))
    929                     break;
    930 
    931                 /* Add separation between filenames.
    932                  * Note: Also do this for the last element of the list. */
    933                 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, "\r\n", 2 /* Bytes */);
    934                 if (RT_SUCCESS(rc))
    935                     cchFiles += 2; /* Include \r\n */
    936             }
    937 
    938             if (RT_SUCCESS(rc))
    939             {
    940                 cchFiles += 1; /* Add string termination. */
    941                 uint32_t cbFiles = cchFiles * sizeof(char);
    942 
    943                 LogFlowFunc(("cFiles=%u, cchFiles=%RU32, cbFiles=%RU32, pszFiles=0x%p\n",
    944                              cFiles, cchFiles, cbFiles, pszFiles));
    945 
    946                 /* Translate the list into URI elements. */
    947                 DnDURIList lstURI;
    948                 rc = lstURI.AppendNativePathsFromList(pszFiles, cbFiles,
    949                                                       DNDURILIST_FLAGS_ABSOLUTE_PATHS);
    950                 if (RT_SUCCESS(rc))
    951                 {
    952                     RTCString strRoot = lstURI.GetRootEntries();
    953                     size_t cbRoot = strRoot.length() + 1; /* Include termination */
    954 
    955                     mpvData = RTMemAlloc(cbRoot);
    956                     if (mpvData)
    957                     {
    958                         memcpy(mpvData, strRoot.c_str(), cbRoot);
    959                         mcbData = cbRoot;
    960                     }
    961                     else
    962                         rc = VERR_NO_MEMORY;
    963                 }
    964             }
    965 
    966             LogFlowFunc(("Building CF_HDROP list rc=%Rrc, pszFiles=0x%p, cFiles=%RU16, cchFiles=%RU32\n",
    967                          rc, pszFiles, cFiles, cchFiles));
    968 
    969             if (pszFiles)
    970                 RTStrFree(pszFiles);
    971             break;
    972     #endif /* 0 */
     953            }
    973954        }
    974955#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
    975956        VBoxClipboardWinClose();
    976957    }
    977     else
    978     {
    979         LogFunc(("vboxClipboardReadData: failed to open clipboard, rc: %Rrc\n", rc));
    980     }
    981958
    982959    if (hClip == NULL)
    983960    {
    984961        /* Reply with empty data. */
    985         vboxClipboardGetData(0, NULL, 0,
    986                              pv, cb, pcbActual);
    987     }
    988 
    989     return VINF_SUCCESS;
     962        vboxClipboardGetData(0, NULL, 0, pv, cb, pcbActual);
     963    }
     964
     965    return VINF_SUCCESS; /** @todo r=andy Return rc here? */
    990966}
    991967
    992968void vboxClipboardWriteData(VBOXCLIPBOARDCLIENTDATA *pClient, void *pv, uint32_t cb, uint32_t u32Format)
    993969{
    994     LogFlow(("vboxClipboardWriteData\n"));
     970    LogFlowFuncEnter();
    995971
    996972    /*
     
    10321008    }
    10331009
    1034     SetEvent(pClient->pCtx->hRenderEvent);
     1010    AssertPtr(pClient->pCtx);
     1011    int rc = RTSemEventSignal(pClient->pCtx->hRenderEvent);
     1012    AssertRC(rc);
     1013
     1014    /** @todo Return rc. */
    10351015}
    10361016
     
    11271107                else
    11281108                {
    1129                     LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected EndFragment.\n"));
     1109                    LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected EndFragment\n"));
    11301110                    rc = VERR_NO_MEMORY;
    11311111                }
     
    11391119        else
    11401120        {
    1141             LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected EndFragment. rc = %Rrc.\n", rc));
     1121            LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected EndFragment. rc = %Rrc\n", rc));
    11421122            rc = VERR_INVALID_PARAMETER;
    11431123        }
     
    11451125    else
    11461126    {
    1147         LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected StartFragment. rc = %Rrc.\n", rc));
     1127        LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected StartFragment. rc = %Rrc\n", rc));
    11481128        rc = VERR_INVALID_PARAMETER;
    11491129    }
     
    11901170    if (!RT_SUCCESS(rc))
    11911171    {
    1192         LogRelFlowFunc(("Error: invalid source fragment. rc = %Rrc.\n"));
     1172        LogRelFlowFunc(("Error: invalid source fragment. rc = %Rrc\n"));
    11931173        return VERR_INVALID_PARAMETER;
    11941174    }
     
    12301210    if (pszResult == NULL)
    12311211    {
    1232         LogRelFlowFunc(("Error: Cannot allocate memory for result buffer. rc = %Rrc.\n"));
     1212        LogRelFlowFunc(("Error: Cannot allocate memory for result buffer. rc = %Rrc\n"));
    12331213        return VERR_NO_MEMORY;
    12341214    }
     
    12591239    return VINF_SUCCESS;
    12601240}
     1241
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