/* $Id: VBoxGuestR3LibClipboard.cpp $ */ /** @file * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Clipboard. */ /* * Copyright (C) 2007-2019 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. * * The contents of this file may alternatively be used under the terms * of the Common Development and Distribution License Version 1.0 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the * VirtualBox OSE distribution, in which case the provisions of the * CDDL are applicable instead of those of the GPL. * * You may elect to license modified versions of this file under the * terms and conditions of either the GPL or the CDDL or both. */ /********************************************************************************************************************************* * Header Files * *********************************************************************************************************************************/ #include #include #include #include #include "VBoxGuestR3LibInternal.h" /** * Connects to the clipboard service. * * @returns VBox status code * @param pidClient Where to put the client id on success. The client id * must be passed to all the other clipboard calls. */ VBGLR3DECL(int) VbglR3ClipboardConnect(HGCMCLIENTID *pidClient) { int rc = VbglR3HGCMConnect("VBoxSharedClipboard", pidClient); if (rc == VERR_HGCM_SERVICE_NOT_FOUND) rc = VINF_PERMISSION_DENIED; return rc; } /** * Disconnect from the clipboard service. * * @returns VBox status code. * @param idClient The client id returned by VbglR3ClipboardConnect(). */ VBGLR3DECL(int) VbglR3ClipboardDisconnect(HGCMCLIENTID idClient) { return VbglR3HGCMDisconnect(idClient); } /** * Get a host message. * * This will block until a message becomes available. * * @returns VBox status code. * @param idClient The client id returned by VbglR3ClipboardConnect(). * @param pidMsg Where to store the message id. * @param pfFormats Where to store the format(s) the message applies to. */ VBGLR3DECL(int) VbglR3ClipboardGetHostMsg(HGCMCLIENTID idClient, uint32_t *pidMsg, uint32_t *pfFormats) { VBoxClipboardGetHostMsg Msg; VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG, 2); VbglHGCMParmUInt32Set(&Msg.msg, 0); VbglHGCMParmUInt32Set(&Msg.formats, 0); int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); if (RT_SUCCESS(rc)) { int rc2 = VbglHGCMParmUInt32Get(&Msg.msg, pidMsg); if (RT_SUCCESS(rc)) { rc2 = VbglHGCMParmUInt32Get(&Msg.formats, pfFormats); if (RT_SUCCESS(rc2)) return rc; } rc = rc2; } *pidMsg = UINT32_MAX - 1; *pfFormats = UINT32_MAX; return rc; } /** * Reads data from the host clipboard. * * @returns VBox status code. * @retval VINF_BUFFER_OVERFLOW If there is more data available than the caller provided buffer space for. * * @param idClient The client id returned by VbglR3ClipboardConnect(). * @param fFormat The format we're requesting the data in. * @param pv Where to store the data. * @param cb The size of the buffer pointed to by pv. * @param pcb The actual size of the host clipboard data. May be larger than cb. */ VBGLR3DECL(int) VbglR3ClipboardReadData(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb, uint32_t *pcb) { VBoxClipboardReadData Msg; VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_READ_DATA, 3); VbglHGCMParmUInt32Set(&Msg.format, fFormat); VbglHGCMParmPtrSet(&Msg.ptr, pv, cb); VbglHGCMParmUInt32Set(&Msg.size, 0); int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); if (RT_SUCCESS(rc)) { uint32_t cbActual; int rc2 = VbglHGCMParmUInt32Get(&Msg.size, &cbActual); if (RT_SUCCESS(rc2)) { *pcb = cbActual; if (cbActual > cb) return VINF_BUFFER_OVERFLOW; return rc; } rc = rc2; } return rc; } /** * Advertises guest clipboard formats to the host. * * @returns VBox status code. * @param idClient The client id returned by VbglR3ClipboardConnect(). * @param fFormats The formats to advertise. */ VBGLR3DECL(int) VbglR3ClipboardReportFormats(HGCMCLIENTID idClient, uint32_t fFormats) { VBoxClipboardFormats Msg; VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_FORMATS, 1); VbglHGCMParmUInt32Set(&Msg.formats, fFormats); return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); } /** * Send guest clipboard data to the host. * * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA message * from the host. * * @returns VBox status code. * @param idClient The client id returned by VbglR3ClipboardConnect(). * @param fFormat The format of the data. * @param pv The data. * @param cb The size of the data. */ VBGLR3DECL(int) VbglR3ClipboardWriteData(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb) { VBoxClipboardWriteData Msg; VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA, 2); VbglHGCMParmUInt32Set(&Msg.format, fFormat); VbglHGCMParmPtrSet(&Msg.ptr, pv, cb); return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); }