Example #1
0
/**
 * Stop registered services.
 *
 * @return  IPRT status code.
 */
static void vbclStopServices(void)
{
    unsigned int iServiceId = 0;

    VBoxClientVerbose(1, "Stopping services...\n");
    for (iServiceId = 0; iServiceId < RT_ELEMENTS(g_aServices); iServiceId++)
    {
        VBoxClientVerbose(1, "Stopping service: %s\n", g_aServices[iServiceId].pszName);
        int rc = (g_aServices[iServiceId].pfnStop)();
        if (RT_FAILURE(rc))
            VBoxClientVerbose(1, "unable to stop service: %s (%Rrc)\n", g_aServices[iServiceId].pszName, rc);
    }
    VBoxClientVerbose(1, "Services stop completed\n");
}
/**
 * Paste buffer into guest clipboard.
 *
 * @param   pPasteboard    Guest PasteBoard reference.
 * @param   pData          Data to be pasted.
 * @param   cbDataSize     The size of *pData.
 * @param   fFormat        Buffer data format.
 * @param   fClear         Whether or not clear guest clipboard before insert data.
 *
 * @returns IPRT status code.
 */
static int vbclClipboardGuestPasteData(PasteboardRef pPasteboard, UInt8 *pData, CFIndex cbDataSize, CFStringRef sFormat, bool fClear)
{
    PasteboardItemID    itemId   = (PasteboardItemID)1;
    CFDataRef           textData = NULL;
    OSStatus            rc;

    /* Ignoring sunchronization flags here */
    PasteboardSynchronize(pPasteboard);

    if (fClear)
    {
        rc = PasteboardClear(pPasteboard);
        AssertReturn(rc == noErr, VERR_NOT_SUPPORTED);
    }

    /* Create a CData object which we could pass to the pasteboard */
    if ((textData = CFDataCreate(kCFAllocatorDefault, pData, cbDataSize)))
    {
        /* Put the Utf-8 version to the pasteboard */
        rc = PasteboardPutItemFlavor(pPasteboard, itemId, sFormat, textData, 0);
        CFRelease(textData);
        if (rc != noErr)
        {
            VBoxClientVerbose(3, "unable to put data into guest's clipboard: %d\n", rc);
            return VERR_GENERAL_FAILURE;
        }
    }
    else
        return VERR_NO_MEMORY;

    /* Synchronize updated content */
    PasteboardSynchronize(pPasteboard);

    return VINF_SUCCESS;
}
Example #3
0
/**
 * Start registered services.
 *
 * @return  IPRT status code.
 */
static int vbclStartServices(void)
{
    int rc;
    unsigned int iServiceId = 0;

    VBoxClientVerbose(1, "Starting services...\n");
    for (iServiceId = 0; iServiceId < RT_ELEMENTS(g_aServices); iServiceId++)
    {
        VBoxClientVerbose(1, "Starting service: %s\n", g_aServices[iServiceId].pszName);
        rc = (g_aServices[iServiceId].pfnStart)();
        if (RT_FAILURE(rc))
        {
            VBoxClientVerbose(1, "unable to start service: %s (%Rrc)\n", g_aServices[iServiceId].pszName, rc);
            VBoxClientVerbose(1, "Rolling back..\n");

            /* Stop running services */
            do
            {
                VBoxClientVerbose(1, "Stopping service: %s\n", g_aServices[iServiceId].pszName);
                int rcStop = (g_aServices[iServiceId].pfnStop)();
                if (RT_FAILURE(rcStop))
                    VBoxClientVerbose(1, "unable to stop service: %s (%Rrc)\n", g_aServices[iServiceId].pszName, rcStop);
            } while (--iServiceId != 0);

            break;
        }
    }

    if (RT_SUCCESS(rc))
        VBoxClientVerbose(1, "Services start completed.\n");

    return rc;
}
/**
 * Read host's clipboard buffer and put its content to guest clipboard.
 *
 * @param   u32ClientId    Host connection.
 * @param   pPasteboard    Guest PasteBoard reference.
 * @param   fFormats       List of data formats (bit field) received from host.
 *
 * @returns IPRT status code.
 */
int vbclClipboardForwardToGuest(uint32_t u32ClientId, PasteboardRef pPasteboard, uint32_t fFormats)
{
    int       rc = VERR_INVALID_PARAMETER;
    void     *pData;
    uint32_t  cbDataSize, cbMemSize;
    uint32_t  fFormatsInternal = fFormats;

    /* Walk across all item(s) formats */
    while (fFormatsInternal)
    {
        if (fFormatsInternal & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
        {
            VBoxClientVerbose(3, "found VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT: %d\n", fFormatsInternal);

            rc = vbclClipboardReadHostData(u32ClientId, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, &pData, &cbDataSize, &cbMemSize);
            if (RT_SUCCESS(rc))
            {
                /* Store data in guest buffer */
                rc = vbclClipboardGuestPasteText(pPasteboard, pData, cbDataSize);

                /* Release occupied resources */
                vbclClipboardReleaseHostData(&pData, cbMemSize);
            }

            fFormatsInternal &= ~((uint32_t)VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
        }

        else if (fFormatsInternal & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
        {
            VBoxClientVerbose(3, "found VBOX_SHARED_CLIPBOARD_FMT_BITMAP: %d\n", fFormatsInternal);

            rc = vbclClipboardReadHostData(u32ClientId, VBOX_SHARED_CLIPBOARD_FMT_BITMAP, &pData, &cbDataSize, &cbMemSize);
            if (RT_SUCCESS(rc))
            {
                /* Store data in guest buffer */
                rc = vbclClipboardGuestPastePicture(pPasteboard, pData, cbDataSize);

                /* Release occupied resources */
                vbclClipboardReleaseHostData(&pData, cbMemSize);
            }

            fFormatsInternal &= ~((uint32_t)VBOX_SHARED_CLIPBOARD_FMT_BITMAP);
        }

        else if (fFormatsInternal & VBOX_SHARED_CLIPBOARD_FMT_HTML)
        {
            VBoxClientVerbose(3, "found VBOX_SHARED_CLIPBOARD_FMT_HTML: %d\n", fFormatsInternal);

            rc = vbclClipboardReadHostData(u32ClientId, VBOX_SHARED_CLIPBOARD_FMT_HTML, &pData, &cbDataSize, &cbMemSize);
            if (RT_SUCCESS(rc))
            {
                /* Store data in guest buffer */
                rc = vbclClipboardGuestPasteData(pPasteboard, (UInt8 *)pData, cbDataSize, kUTTypeHTML, true);

                /* Release occupied resources */
                vbclClipboardReleaseHostData(&pData, cbMemSize);
            }

            fFormatsInternal &= ~((uint32_t)VBOX_SHARED_CLIPBOARD_FMT_HTML);
        }

        else
        {
            VBoxClientVerbose(3, "received data in unsupported format: %d\n", fFormats);
            break;
        }
    }

    return rc;
}
/**
 * Walk through pasteboard items and report currently available item types.
 *
 * @param   pPasteboard         Reference to guest Pasteboard.
 * @returns Available formats bit field.
 */
uint32_t vbclClipboardGetAvailableFormats(PasteboardRef pPasteboard)
{
    uint32_t  fFormats = 0;
    ItemCount cItems   = 0;
    ItemCount iItem;
    OSStatus  rc;

#define VBOXCL_ADD_FORMAT_IF_PRESENT(a_kDarwinFmt, a_fVBoxFmt) \
    if (PasteboardCopyItemFlavorData(pPasteboard, iItemID, a_kDarwinFmt, &flavorData) == noErr) \
    { \
        fFormats |= (uint32_t)a_fVBoxFmt; \
        CFRelease(flavorData); \
    }

    rc = PasteboardGetItemCount(pPasteboard, &cItems);
    AssertReturn((rc == noErr) && (cItems > 0), fFormats);

    for (iItem = 1; iItem <= cItems; iItem++)
    {
        PasteboardItemID iItemID;
        CFDataRef        flavorData;

        rc = PasteboardGetItemIdentifier(pPasteboard, iItem, &iItemID);
        if (rc == noErr)
        {
            VBOXCL_ADD_FORMAT_IF_PRESENT(kUTTypeUTF16PlainText, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
            VBOXCL_ADD_FORMAT_IF_PRESENT(kUTTypeUTF8PlainText,  VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
            VBOXCL_ADD_FORMAT_IF_PRESENT(kUTTypeBMP,            VBOX_SHARED_CLIPBOARD_FMT_BITMAP     );
            VBOXCL_ADD_FORMAT_IF_PRESENT(kUTTypeHTML,           VBOX_SHARED_CLIPBOARD_FMT_HTML       );

#ifdef CLIPBOARD_DUMP_CONTENT_FORMATS
            CFArrayRef  flavorTypeArray;
            CFIndex     flavorCount;
            CFStringRef flavorType;

            rc = PasteboardCopyItemFlavors(pPasteboard, iItemID, &flavorTypeArray);
            if (rc == noErr)
            {
                VBoxClientVerbose(3, "SCAN..\n");
                flavorCount = CFArrayGetCount(flavorTypeArray);
                VBoxClientVerbose(3, "SCAN (%d)..\n", (int)flavorCount);
                for(CFIndex flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++)
                {
                    VBoxClientVerbose(3, "SCAN #%d..\n", (int)flavorIndex);
                    flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex);

                    CFDataRef flavorData1;
                    rc = PasteboardCopyItemFlavorData(pPasteboard, iItemID, flavorType, &flavorData1);
                    if (rc == noErr)
                    {
                        VBoxClientVerbose(3, "Found: %s, size: %d\n", (char *)CFStringGetCStringPtr(flavorType, kCFStringEncodingMacRoman), (int)CFDataGetLength(flavorData1));
                        CFRelease(flavorData1);
                    }
                }
                VBoxClientVerbose(3, "SCAN COMPLETE\n");
                CFRelease(flavorTypeArray);
            }
#endif /* CLIPBOARD_DUMP_CONTENT_FORMATS */
        }
    }

#undef VBOXCL_ADD_FORMAT_IF_PRESENT

    return fFormats;
}
/**
 * Read guest's clipboard buffer and forward its content to host.
 *
 * @param   u32ClientId    Host clipboard connection.
 * @param   pPasteboard    Guest PasteBoard reference.
 * @param   fFormats       List of data formats (bit field) received from host.
 *
 * @returns IPRT status code.
 */
int vbclClipboardForwardToHost(uint32_t u32ClientId, PasteboardRef pPasteboard, uint32_t fFormats)
{
    int       rc = VINF_SUCCESS;

    void     *pvData  = NULL;
    uint32_t  cbData  = 0;
    uint32_t  cbAlloc = 0;

    VBoxClientVerbose(3, "vbclClipboardForwardToHost: %d\n", fFormats);

    /* Walk across all item(s) formats */
    uint32_t  fFormatsLeft = fFormats;
    while (fFormatsLeft)
    {
        if (fFormatsLeft & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
        {
            VBoxClientVerbose(3, "requested VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT: %d\n", fFormats);

            RTUTF16 *pUtf16Str = NULL;

            /* First, try to get UTF16 encoded buffer */
            rc = vbclClipboardReadGuestData(pPasteboard, kUTTypeUTF16PlainText, &pvData, &cbData, &cbAlloc);
            if (RT_SUCCESS(rc))
            {
                rc = RTUtf16DupEx(&pUtf16Str, (PRTUTF16)pvData, 0);
                if (RT_FAILURE(rc))
                    pUtf16Str = NULL;
            }
            else /* Failed to get UTF16 buffer */
            {
                /* Then, try to get UTF8 encoded buffer */
                rc = vbclClipboardReadGuestData(pPasteboard, kUTTypeUTF8PlainText, &pvData, &cbData, &cbAlloc);
                if (RT_SUCCESS(rc))
                {
                    rc = RTStrToUtf16((const char *)pvData, &pUtf16Str);
                    if (RT_FAILURE(rc))
                        pUtf16Str = NULL;
                }
            }

            /* Finally, we got UTF16 encoded buffer */
            if (RT_SUCCESS(rc))
            {
                rc = vbclClipboardHostPasteText(u32ClientId, (PRTUTF16)pvData, cbData);

                if (pUtf16Str)
                {
                    RTUtf16Free(pUtf16Str);
                    pUtf16Str = NULL;
                }

                vbclClipboardReleaseGuestData(&pvData, cbAlloc);
            }
            else
            {
                /* No data found or error occurred: send empty buffer */
                rc = vbclClipboardHostPasteData(u32ClientId, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, NULL, 0);
            }

            fFormatsLeft &= ~(uint32_t)VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
        }

        else if (fFormatsLeft & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
        {
            VBoxClientVerbose(3, "requested VBOX_SHARED_CLIPBOARD_FMT_BITMAP: %d\n", fFormats);

            rc = vbclClipboardReadGuestData(pPasteboard, kUTTypeBMP, &pvData, &cbData, &cbAlloc);
            if (RT_SUCCESS(rc))
            {
                rc = vbclClipboardHostPasteBitmap(u32ClientId, pvData, cbData);
                vbclClipboardReleaseGuestData(&pvData, cbAlloc);
            }
            else
            {
                /* No data found or error occurred: send empty buffer */
                rc = vbclClipboardHostPasteData(u32ClientId, VBOX_SHARED_CLIPBOARD_FMT_BITMAP, NULL, 0);
            }

            fFormatsLeft &= ~(uint32_t)VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
        }

        else if (fFormatsLeft & VBOX_SHARED_CLIPBOARD_FMT_HTML)
        {
            VBoxClientVerbose(3, "requested VBOX_SHARED_CLIPBOARD_FMT_HTML: %d\n", fFormats);

            rc = vbclClipboardReadGuestData(pPasteboard, kUTTypeHTML, &pvData, &cbData, &cbAlloc);
            if (RT_SUCCESS(rc))
            {
                rc = vbclClipboardHostPasteData(u32ClientId, VBOX_SHARED_CLIPBOARD_FMT_HTML, pvData, cbData);
                vbclClipboardReleaseGuestData(&pvData, cbAlloc);
            }
            else
            {
                /* No data found or error occurred: send empty buffer */
                rc = vbclClipboardHostPasteData(u32ClientId, VBOX_SHARED_CLIPBOARD_FMT_HTML, NULL, 0);
            }

            fFormatsLeft &= ~(uint32_t)VBOX_SHARED_CLIPBOARD_FMT_HTML;
        }

        else
        {
            VBoxClientVerbose(3, "requested data in unsupported format: %#x\n", fFormatsLeft);
            break;
        }
    }

    return rc; /** @todo r=bird: If there are multiple formats available, which rc is returned here? Does it matter? */
}