vbox6: shared clipboard service

The service is loaded dynamically VBoxSharedClipboard.so at runtime. The
VFS configuration mounts the shared object at /VBoxSharedClipboard.so as
the file is checked by contrib code before loading. An init
configuration in pkg/vbox6/runtime illustrates this and how to re-label
the VBoxSharedClipboard.so ROM to its real name
virtualbox6-sharedclipboard.lib.so.
This commit is contained in:
Christian Helmuth 2021-09-30 15:18:22 +02:00 committed by Norman Feske
parent 5aee693f70
commit 46ee872b50
23 changed files with 479 additions and 77 deletions

View File

@ -84,7 +84,6 @@ SRC_CC += Devices/Trace/DrvIfsTrace.cpp
SRC_CC += Devices/Trace/DrvIfsTrace-serial.cpp
SRC_CC += Devices/USB/DevOHCI.cpp
SRC_CC += Devices/USB/DrvVUSBRootHub.cpp
SRC_CC += Devices/USB/USBProxyDevice.cpp
SRC_CC += Devices/USB/VUSBDevice.cpp
SRC_CC += Devices/USB/VUSBSniffer.cpp
SRC_CC += Devices/USB/VUSBSnifferPcapNg.cpp

View File

@ -4,6 +4,7 @@ SRC_CC += VMM/VMMR3/CPUMDbg.cpp
SRC_CC += VMM/VMMR3/DBGF.cpp
SRC_CC += VMM/VMMR3/DBGFAddr.cpp
SRC_CC += VMM/VMMR3/DBGFDisas.cpp
SRC_CC += VMM/VMMR3/DBGFMem.cpp
SRC_CC += VMM/VMMR3/DBGFR3Trace.cpp
SRC_CC += VMM/VMMR3/DBGFReg.cpp

View File

@ -43,6 +43,7 @@ VBOX_CC_OPT += -DVBOX_WITH_GENERIC_SESSION_WATCHER
VBOX_CC_OPT += -DVBOX_WITH_NAT_SERVICE
VBOX_CC_OPT += -DVBOX_WITH_AUDIO_HDA_ASYNC_IO
VBOX_CC_OPT += -DVBOX_WITH_DRAG_AND_DROP
VBOX_CC_OPT += -DVBOX_WITH_SHARED_CLIPBOARD
include $(REP_DIR)/lib/mk/virtualbox6-debug.inc

View File

@ -62,6 +62,7 @@ SRC_CC += Main/src-server/HostNetworkInterfaceImpl.cpp
SRC_CC += Main/src-server/MediumIOImpl.cpp
SRC_CC += Main/src-server/DataStreamImpl.cpp
SRC_CC += Main/src-server/HostPower.cpp
SRC_CC += Main/src-server/generic/NetIf-generic.cpp
# use OS/2 version of 'pm::createHAL()' because it is empty
SRC_CC += Main/src-server/os2/PerformanceOs2.cpp

View File

@ -25,11 +25,12 @@ SRC_CC += $(call all_cpp_files_of_sub_dir,Runtime/common/table/)
SRC_CC += $(call all_cpp_files_of_sub_dir,Runtime/generic/)
SRC_CC += $(call all_cpp_files_of_sub_dir,Runtime/r3/)
SRC_CC += Runtime/VBox/log-vbox.cpp
SRC_CC += Runtime/common/checksum/alt-md5.cpp
SRC_CC += Runtime/common/checksum/alt-sha512.cpp
SRC_CC += Runtime/common/checksum/crc16ccitt.cpp
SRC_CC += Runtime/common/checksum/crc32c.cpp
SRC_CC += Runtime/common/checksum/crc32.cpp
SRC_CC += Runtime/common/checksum/crc32c.cpp
SRC_CC += Runtime/common/checksum/ipv4.cpp
SRC_CC += Runtime/common/checksum/ipv6.cpp
SRC_CC += Runtime/common/checksum/sha512str.cpp
@ -37,6 +38,8 @@ SRC_CC += Runtime/common/dbg/dbgstackdumpself.cpp
SRC_CC += Runtime/common/fs/isovfs.cpp
SRC_CC += Runtime/common/ldr/ldr.cpp
SRC_CC += Runtime/common/ldr/ldrEx.cpp
SRC_CC += Runtime/common/ldr/ldrFile.cpp
SRC_CC += Runtime/common/ldr/ldrNative.cpp
SRC_CC += Runtime/common/net/macstr.cpp
SRC_CC += Runtime/common/net/netaddrstr2.cpp
SRC_CC += Runtime/common/sort/shellsort.cpp
@ -46,38 +49,41 @@ SRC_CC += Runtime/common/time/timesup.cpp
SRC_CC += Runtime/common/time/timesupref.cpp
SRC_CC += Runtime/common/vfs/vfsbase.cpp
SRC_CC += Runtime/common/vfs/vfschain.cpp
SRC_CC += Runtime/common/vfs/vfsprogress.cpp
SRC_CC += Runtime/common/vfs/vfsstddir.cpp
SRC_CC += Runtime/common/vfs/vfsstdfile.cpp
SRC_CC += Runtime/common/zip/zip.cpp
SRC_CC += Runtime/r3/freebsd/systemmem-freebsd.cpp
SRC_CC += Runtime/r3/generic/dirrel-r3-generic.cpp
SRC_CC += Runtime/r3/generic/semspinmutex-r3-generic.cpp
SRC_CC += Runtime/r3/posix/RTPathUserHome-posix.cpp
SRC_CC += Runtime/r3/posix/RTTimeNow-posix.cpp
SRC_CC += Runtime/r3/posix/allocex-r3-posix.cpp
SRC_CC += Runtime/r3/posix/dir-posix.cpp
SRC_CC += Runtime/r3/posix/env-posix.cpp
SRC_CC += Runtime/r3/posix/fileaio-posix.cpp
SRC_CC += Runtime/r3/posix/fileio2-posix.cpp
SRC_CC += Runtime/r3/posix/fileio-posix.cpp
SRC_CC += Runtime/r3/posix/fileio2-posix.cpp
SRC_CC += Runtime/r3/posix/fs-posix.cpp
SRC_CC += Runtime/r3/posix/fs2-posix.cpp
SRC_CC += Runtime/r3/posix/fs3-posix.cpp
SRC_CC += Runtime/r3/posix/fs-posix.cpp
SRC_CC += Runtime/r3/posix/path2-posix.cpp
SRC_CC += Runtime/r3/posix/ldrNative-posix.cpp
SRC_CC += Runtime/r3/posix/path-posix.cpp
SRC_CC += Runtime/r3/posix/path2-posix.cpp
SRC_CC += Runtime/r3/posix/pipe-posix.cpp
SRC_CC += Runtime/r3/posix/process-posix.cpp
SRC_CC += Runtime/r3/posix/rtmempage-exec-mmap-posix.cpp
SRC_CC += Runtime/r3/posix/RTPathUserHome-posix.cpp
SRC_CC += Runtime/r3/posix/RTTimeNow-posix.cpp
SRC_CC += Runtime/r3/posix/semeventmulti-posix.cpp
SRC_CC += Runtime/r3/posix/RTMemProtect-posix.cpp
SRC_CC += Runtime/r3/posix/semevent-posix.cpp
SRC_CC += Runtime/r3/posix/semeventmulti-posix.cpp
SRC_CC += Runtime/r3/posix/semmutex-posix.cpp
SRC_CC += Runtime/r3/posix/serialport-posix.cpp
SRC_CC += Runtime/r3/posix/symlink-posix.cpp
SRC_CC += Runtime/r3/posix/thread2-posix.cpp
SRC_CC += Runtime/r3/posix/thread-posix.cpp
SRC_CC += Runtime/r3/posix/thread2-posix.cpp
SRC_CC += Runtime/r3/posix/time-posix.cpp
SRC_CC += Runtime/r3/posix/tls-posix.cpp
SRC_CC += Runtime/r3/posix/utf8-posix.cpp
SRC_CC += Runtime/VBox/log-vbox.cpp
SRC_S += Runtime/common/asm/ASMAtomicCmpXchgExU64.asm
SRC_S += Runtime/common/asm/ASMAtomicCmpXchgU64.asm
SRC_S += Runtime/common/asm/ASMAtomicReadU64.asm

View File

@ -0,0 +1,19 @@
include $(REP_DIR)/lib/mk/virtualbox6-common.inc
SHARED_LIB = yes
SRC_CC += sharedclipboard.cc
SRC_CC += message.cpp
SRC_CC += VBoxSharedClipboardSvc.cpp
SRC_CC += clipboard-common.cpp
LIBS += stdcxx
INC_DIR += $(VBOX_DIR)/HostServices/SharedClipboard
CC_CXX_WARN_STRICT =
vpath sharedclipboard.cc $(REP_DIR)/src/virtualbox6/services
vpath message.cpp $(VBOX_DIR)/HostServices/common
vpath VBoxSharedClipboardSvc.cpp $(VBOX_DIR)/HostServices/SharedClipboard
vpath clipboard-common.cpp $(VBOX_DIR)/GuestHost/SharedClipboard

View File

@ -17,6 +17,7 @@ SRC_C += globals.c hash.c list.c parser.c parserInternals.c pattern.c
SRC_C += relaxng.c threads.c tree.c uri.c valid.c HTMLtree.c HTMLparser.c
SRC_C += SAX.c SAX2.c xmlIO.c xmlmemory.c xmlreader.c xmlregexp.c xmlschemas.c
SRC_C += xmlschemastypes.c xmlsave.c xmlstring.c xmlunicode.c xpath.c xpointer.c
SRC_C += xinclude.c
SRC_CC += Runtime/r3/xml.cpp
SRC_CC += Runtime/common/string/ministring.cpp

View File

@ -22,13 +22,15 @@ SRC_CC += xpcom/build/nsXPComInit.cpp
SRC_CC += xpcom/components/nsCategoryManager.cpp
SRC_CC += xpcom/components/nsComponentManager.cpp
SRC_CC += xpcom/components/nsNativeComponentLoader.cpp
SRC_CC += xpcom/components/nsServiceManagerObsolete.cpp
SRC_CC += xpcom/components/nsStaticComponentLoader.cpp
SRC_CC += xpcom/components/xcDll.cpp
SRC_CC += xpcom/glue/nsComponentManagerUtils.cpp
SRC_CC += xpcom/glue/nsCOMPtr.cpp
SRC_CC += xpcom/glue/nsComponentManagerUtils.cpp
SRC_CC += xpcom/glue/nsGenericFactory.cpp
SRC_CC += xpcom/glue/nsMemory.cpp
SRC_CC += xpcom/glue/nsWeakReference.cpp
SRC_CC += xpcom/io/SpecialSystemDirectory.cpp
SRC_CC += xpcom/io/nsAppFileLocationProvider.cpp
SRC_CC += xpcom/io/nsBinaryStream.cpp
SRC_CC += xpcom/io/nsDirectoryService.cpp
@ -43,10 +45,12 @@ SRC_CC += xpcom/string/src/nsObsoleteAStringThunk.cpp
SRC_CC += xpcom/string/src/nsPrintfCString.cpp
SRC_CC += xpcom/string/src/nsPromiseFlatString.cpp
SRC_CC += xpcom/string/src/nsReadableUtils.cpp
SRC_CC += xpcom/string/src/nsStringComparator.cpp
SRC_CC += xpcom/string/src/nsString.cpp
SRC_CC += xpcom/string/src/nsStringComparator.cpp
SRC_CC += xpcom/string/src/nsStringObsolete.cpp
SRC_CC += xpcom/string/src/nsSubstring.cpp
SRC_CC += xpcom/string/src/nsSubstringTuple.cpp
SRC_CC += xpcom/threads/TimerThread.cpp
SRC_CC += xpcom/threads/nsAutoLock.cpp
SRC_CC += xpcom/threads/nsEnvironment.cpp
SRC_CC += xpcom/threads/nsEventQueue.cpp
@ -54,7 +58,6 @@ SRC_CC += xpcom/threads/nsEventQueueService.cpp
SRC_CC += xpcom/threads/nsProcessCommon.cpp
SRC_CC += xpcom/threads/nsThread.cpp
SRC_CC += xpcom/threads/nsTimerImpl.cpp
SRC_CC += xpcom/threads/TimerThread.cpp
FILTERED_OUT_SRC_CC += xpcom/base/nsStackFrameWin.cpp
FILTERED_OUT_SRC_CC += xpcom/ds/nsPersistentProperties.cpp
@ -66,6 +69,7 @@ SRC_C += nsprpub/lib/ds/plarena.c
SRC_C += nsprpub/lib/libc/src/strccmp.c
SRC_C += nsprpub/lib/libc/src/strccmp.c
SRC_C += nsprpub/lib/libc/src/strcmp.c
SRC_C += nsprpub/lib/libc/src/strlen.c
SRC_C += nsprpub/lib/libc/src/strdup.c
SRC_C += nsprpub/pr/src/io/prfdcach.c
SRC_C += nsprpub/pr/src/io/priometh.c
@ -74,6 +78,7 @@ SRC_C += nsprpub/pr/src/io/prmmap.c
SRC_C += nsprpub/pr/src/io/prmwait.c
SRC_C += nsprpub/pr/src/io/prprf.c
SRC_C += nsprpub/pr/src/io/prstdio.c
SRC_C += nsprpub/pr/src/io/prscanf.c
SRC_C += nsprpub/pr/src/malloc/prmem.c
SRC_C += nsprpub/pr/src/md/prosdep.c
SRC_C += nsprpub/pr/src/md/unix/unix.c

View File

@ -1 +1 @@
aa4ee90f7171e1d540ed1c0b19f57088daab53c9
d64286974741fd9ed1936b7aedd270d8c12813d6

View File

@ -64,6 +64,7 @@ VBOX_MAIN_SRV += HostImpl GraphicsAdapterImpl RecordingScreenSettingsImpl
VBOX_MAIN_SRV += HostDnsService HostNetworkInterfaceImpl MediumIOImpl
VBOX_MAIN_SRV += DataStreamImpl HostPower ProgressProxyImpl
VBOX_MAIN_SRV += os2/PerformanceOs2 ClientWatcher
VBOX_MAIN_SRV += generic/NetIf-generic
VBOX_MAIN_INC := AdditionsFacilityImpl AudioAdapterImpl AuthLibrary
VBOX_MAIN_INC += AutoCaller AutostartDb AutoStateDep BandwidthControlImpl
@ -99,7 +100,7 @@ VBOX_MAIN_INC += RecordingScreenSettingsImpl DataStreamImpl
VBOX_MAIN_INC += GuestDnDSourceImpl GuestDnDTargetImpl GuestDnDPrivate
VBOX_MAIN_INC += VirtualBoxBase VirtualBoxErrorInfoImpl
VBOX_SRC_VBOX := VMM Devices Runtime GuestHost/HGSMI GuestHost/DragAndDrop
VBOX_SRC_VBOX := VMM Devices Runtime GuestHost
VBOX_SRC_VBOX += Storage Disassembler
VBOX_SRC_VBOX += HostDrivers/Support
VBOX_SRC_VBOX += HostServices/SharedFolders Main/xml/Settings.cpp

View File

@ -55,6 +55,7 @@
<oss name="dsp"/>
<dir name="pipe"> <pipe/> </dir>
<dir name="shared"> <fs label="shared" writeable="yes"/> </dir>
<rom name="VBoxSharedClipboard.so"/>
<fs writeable="yes"/>
</vfs>
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc" pipe="/pipe">
@ -76,6 +77,8 @@
<service name="ROM" label="usb_devices"> <parent label="usb_devices"/> </service>
<service name="ROM" label="capslock"> <parent label="capslock"/> </service>
<service name="ROM" label="platform_info"> <parent label="platform_info"/> </service>
<service name="ROM" label="VBoxSharedClipboard.so">
<parent label="virtualbox6-sharedclipboard.lib.so"/> </service>
<service name="Nic"> <parent/> </service>
<service name="Report" label="shape"> <parent label="shape"/> </service>
<service name="ROM" label="clipboard"> <parent label="clipboard"/> </service>
@ -100,6 +103,7 @@
<rom label="vfs.lib.so"/>
<rom label="vfs_oss.lib.so"/>
<rom label="vfs_pipe.lib.so"/>
<rom label="virtualbox6-sharedclipboard.lib.so"/>
</content>
</runtime>

View File

@ -82,15 +82,63 @@ int USBFilterMatchRated (PCUSBFILTER, PCUSBFILTER) STOP
#include "USBProxyBackend.h"
USBProxyBackendFreeBSD::USBProxyBackendFreeBSD() STOP
USBProxyBackendFreeBSD::~USBProxyBackendFreeBSD() { }
int USBProxyBackendFreeBSD::captureDevice(HostUSBDevice*) STOP
PUSBDEVICE USBProxyBackendFreeBSD::getDevices() STOP
int USBProxyBackendFreeBSD::init(USBProxyService*, com::Utf8Str const&, com::Utf8Str const&, bool) STOP
int USBProxyBackendFreeBSD::interruptWait() STOP
bool USBProxyBackendFreeBSD::isFakeUpdateRequired() STOP
int USBProxyBackendFreeBSD::releaseDevice(HostUSBDevice*) STOP
void USBProxyBackendFreeBSD::uninit() STOP
int USBProxyBackendFreeBSD::wait(unsigned int) STOP
USBProxyBackend::USBProxyBackend() STOP
USBProxyBackend::~USBProxyBackend() { }
HRESULT USBProxyBackend::FinalConstruct() STOP
HRESULT USBProxyBackend::FinalConstruct() STOP
int USBProxyBackend::captureDevice(HostUSBDevice*) STOP
void USBProxyBackend::captureDeviceCompleted(HostUSBDevice*, bool) STOP
void USBProxyBackend::deviceAdded(ComObjPtr<HostUSBDevice>&, USBDEVICE*) STOP
PUSBDEVICE USBProxyBackend::getDevices() STOP
HRESULT USBProxyBackend::getName(com::Utf8Str&) STOP
HRESULT USBProxyBackend::getType(com::Utf8Str&) STOP
bool USBProxyBackend::i_isDevReEnumerationRequired() STOP
int USBProxyBackend::init(USBProxyService*, com::Utf8Str const&, com::Utf8Str const&, bool) STOP
void * USBProxyBackend::insertFilter(USBFILTER const*) STOP
int USBProxyBackend::interruptWait() STOP
bool USBProxyBackend::isFakeUpdateRequired() STOP
int USBProxyBackend::releaseDevice(HostUSBDevice*) STOP
void USBProxyBackend::releaseDeviceCompleted(HostUSBDevice*, bool) STOP
void USBProxyBackend::removeFilter(void*) STOP
void USBProxyBackend::serviceThreadInit() STOP
void USBProxyBackend::serviceThreadTerm() STOP
void USBProxyBackend::uninit() STOP
int USBProxyBackend::wait(unsigned int) STOP
com::Utf8Str const &USBProxyBackend::i_getAddress() STOP
com::Utf8Str const &USBProxyBackend::i_getBackend() STOP
com::Utf8Str const &USBProxyBackend::i_getId() STOP
USBProxyBackendUsbIp::USBProxyBackendUsbIp() STOP
USBProxyBackendUsbIp::~USBProxyBackendUsbIp() { }
int USBProxyBackendUsbIp::captureDevice(HostUSBDevice*) STOP
PUSBDEVICE USBProxyBackendUsbIp::getDevices() STOP
int USBProxyBackendUsbIp::init(USBProxyService*, com::Utf8Str const&, com::Utf8Str const&, bool) STOP
int USBProxyBackendUsbIp::interruptWait() STOP
bool USBProxyBackendUsbIp::isFakeUpdateRequired() STOP
int USBProxyBackendUsbIp::releaseDevice(HostUSBDevice*) STOP
void USBProxyBackendUsbIp::uninit() STOP
int USBProxyBackendUsbIp::wait(unsigned int) STOP
/* AudioDriver.cpp */
#include "AudioDriver.h"
AudioDriver::AudioDriver(Console *) STOP
AudioDriver::~AudioDriver() { }
/* USBProxyService.cpp */
@ -164,8 +212,7 @@ HRESULT CloudProviderManager::getProviders(std::vector<ComPtr<ICloudProvider>,
#include "netif.h"
int NetIfGetLinkSpeed(const char *, uint32_t *) STOP
int NetIfGetState(const char *, NETIFSTATUS *) STOP
int NetIfRemoveHostOnlyNetworkInterface(VirtualBox *, const Guid &, IProgress **) STOP
int NetIfGetConfigByName(PNETIFINFO) STOP
int NetIfList(std::__cxx11::list<ComObjPtr<HostNetworkInterface>,
std::allocator<ComObjPtr<HostNetworkInterface> > >&) { return VINF_SUCCESS; }
@ -195,12 +242,6 @@ HRESULT MachineMoveVM::init() STOP
void MachineMoveVM::i_MoveVMThreadTask(MachineMoveVM *) STOP
/* NetIf-generic.cpp */
int NetIfCreateHostOnlyNetworkInterface(VirtualBox *, IHostNetworkInterface **,
IProgress **, const char *) STOP
/* HostDnsServiceResolvConf.cpp */
#include <string>
@ -408,3 +449,15 @@ int pgmR3InitSavedState(PVM, uint64_t) { return VINF_SUCCESS; }
#include "nsProxyRelease.h"
NS_COM nsresult NS_ProxyRelease(nsIEventTarget *target, nsISupports *doomed, PRBool alwaysProxy) STOP
/* SUPR3HardenedVerify.cpp */
#include "SUPLibInternal.h"
DECLHIDDEN(int) supR3HardenedRecvPreInitData(PCSUPPREINITDATA) STOP
/* VBoxXPCOMImpImp.c */
void *_ZTV14nsGetInterface = nullptr;

View File

@ -1,37 +0,0 @@
/*
* \brief Support to link libraries statically supposed to be dynamic
* \author Alexander Boettcher
* \author Christian Helmuth
* \date 2014-05-13
*/
/*
* Copyright (C) 2014-2021 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
/* Genode includes */
#include <util/string.h>
/* VirtualBox includes */
#include <iprt/err.h>
#include <iprt/ldr.h>
#include <VBox/hgcmsvc.h>
extern "C" {
int RTLdrLoad(const char *pszFilename, PRTLDRMOD phLdrMod)
{
Genode::error("shared library '", pszFilename, "' not supported");
return VERR_NOT_SUPPORTED;
}
RTDECL(const char *) RTLdrGetSuff(void)
{
return ".so";
}
} /* extern "C" */

View File

@ -25,4 +25,6 @@ namespace Network { void init(Genode::Env &); }
namespace Xhci { void init(Genode::Env &); }
namespace Services { void init(Genode::Env &); }
#endif /* _INIT_H_ */

View File

@ -44,6 +44,15 @@ int aio_suspend(const struct aiocb * const aiocb_list[],
int nitems, const struct timespec *timeout) STOP
int lio_listio(int mode, struct aiocb *const aiocb_list[],
int nitems, struct sigevent *sevp) STOP
int gethostbyname_r(const char *name,
struct hostent *ret, char *buf, size_t buflen,
struct hostent **result, int *h_errnop) STOP
int gethostbyname2_r(const char *name, int af,
struct hostent *ret, char *buf, size_t buflen,
struct hostent **result, int *h_errnop) STOP
int getprotobynumber_r(int proto,
struct protoent *result_buf, char *buf,
size_t buflen, struct protoent **result) STOP
} /* extern "C" */

View File

@ -474,6 +474,7 @@ void Libc::Component::construct(Libc::Env &env)
Sup::init(env);
Xhci::init(env);
Services::init(env);
try {
static Main main(env);

View File

@ -0,0 +1,28 @@
/*
* \brief Service backend helper
* \author Christian Helmuth
* \date 2021-09-01
*
* This module stores the Genode environment reference for service shared
* objects that require Genode connections (e.g., shared-clipboard reports
* and ROMs).
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
/* Genode includes */
#include <base/env.h>
/* local includes */
#include <services/services.h>
static Genode::Env *genode_env;
Genode::Env & Services::env() { return *genode_env; }
void Services::init(Genode::Env &env) { genode_env = &env; }

View File

@ -0,0 +1,26 @@
/*
* \brief Service backend
* \author Christian Helmuth
* \date 2021-09-01
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _SERVICES__SERVICES_H_
#define _SERVICES__SERVICES_H_
namespace Genode { struct Env; }
namespace Services {
void init(Genode::Env &);
Genode::Env & env();
}
#endif /* _SERVICES__SERVICES_H_ */

View File

@ -0,0 +1,261 @@
/*
* \brief Shared-clipboard service backend
* \author Christian Helmuth
* \date 2021-09-01
*
* Note, the text strings exchanged with the upper-layers (and therefore the
* guest) must be null-terminated and sizes have to include the terminator.
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
/* Genode includes */
#include <base/env.h>
#include <base/attached_rom_dataspace.h>
#include <os/reporter.h>
#include <libc/component.h>
/* VirtualBox includes */
#include <iprt/utf16.h>
#include <VBoxSharedClipboardSvc-internal.h>
#include <VBox/GuestHost/clipboard-helper.h>
/* local includes */
#include "services.h"
using namespace Genode;
namespace {
class Clipboard
{
private:
Env &_env;
Attached_rom_dataspace _rom { _env, "clipboard" };
Expanding_reporter _report { _env, "clipboard", "clipboard" };
SHCLCLIENT *_client { nullptr };
Signal_handler<Clipboard> _rom_sigh {
_env.ep(), *this, &Clipboard::_handle_rom_changed };
void _handle_rom_changed()
{
Libc::with_libc([&] () { ShClSvcImplSync(_client); });
}
public:
struct Guard;
Clipboard(Env &env) : _env(env)
{
_rom.sigh(_rom_sigh);
}
SHCLCLIENT * client() const { return _client; }
int connect(SHCLCLIENT *client)
{
if (_client) {
warning("shared clipboard: only one client supported");
return VERR_NOT_SUPPORTED;
}
_client = client;
return VINF_SUCCESS;
}
void disconnect(SHCLCLIENT *client)
{
if (client != _client) {
warning("shared clipboard: unknown client on disconnect");
return;
}
_client = nullptr;
}
void report(char const *content)
{
try {
_report.generate([&] (Reporter::Xml_generator &xml) {
xml.append_sanitized(content); });
} catch (...) {
error("shared clipboard: could not report new content");
}
}
template <typename FN>
void with_content(FN const &fn)
{
_rom.update();
if (!_rom.valid())
return;
size_t size = _rom.xml().content_size();
char *content = (char *)RTMemAlloc(size + 1);
size = _rom.xml().decoded_content(content, size);
/* add null terminator */
content[size] = 0;
fn(content, size + 1);
RTMemFree(content);
}
};
struct Clipboard::Guard
{
Guard() { ShClSvcLock(); }
~Guard() { ShClSvcUnlock(); }
};
Constructible<Clipboard> clipboard;
} /* unnamed namespace */
int ShClSvcImplReadData(PSHCLCLIENT, PSHCLCLIENTCMDCTX, SHCLFORMAT fFormat, void *pv, uint32_t cb, unsigned int *cb_out)
{
if (!(fFormat & VBOX_SHCL_FMT_UNICODETEXT))
return VERR_NOT_IMPLEMENTED;
Clipboard::Guard guard;
int rc = VINF_SUCCESS;
*cb_out = 0;
clipboard->with_content([&] (char const *utf8_string, size_t utf8_size) {
PRTUTF16 utf16_string = (PRTUTF16)pv;
size_t utf16_chars = cb/sizeof(RTUTF16);
rc = RTStrToUtf16Ex(utf8_string, utf8_size, &utf16_string, utf16_chars, &utf16_chars);
/* VERR_BUFFER_OVERFLOW is handled by the guest if cb < cb_out */
if (rc == VERR_BUFFER_OVERFLOW)
rc = VINF_SUCCESS;
if (RT_SUCCESS(rc)) {
/* the protocol requires cb_out to include the null terminator */
*cb_out = (utf16_chars + 1)*sizeof(RTUTF16);
}
});
return rc;
}
int ShClSvcImplWriteData(PSHCLCLIENT, PSHCLCLIENTCMDCTX, SHCLFORMAT fFormat, void *pv, uint32_t cb)
{
if (!(fFormat & VBOX_SHCL_FMT_UNICODETEXT))
return VERR_NOT_IMPLEMENTED;
Clipboard::Guard guard;
PCRTUTF16 const utf16_string = (PCRTUTF16)pv;
char *utf8_string;
/* allocates buffer and converts string (incl. null terminator) */
int rc = RTUtf16ToUtf8(utf16_string, &utf8_string);
if (RT_FAILURE(rc))
return VINF_SUCCESS;
clipboard->report(utf8_string);
RTStrFree(utf8_string);
/*
* We send a format report to guest as the global clipboard was changed by
* this operation. This generates a feedback loop to keep the host and
* guest clipboards in sync.
*/
return ShClSvcHostReportFormats(clipboard->client(), VBOX_SHCL_FMT_UNICODETEXT);
}
/**
* The guest is taking possession of the shared clipboard
*/
int ShClSvcImplFormatAnnounce(PSHCLCLIENT pClient, SHCLFORMATS fFormats)
{
/* eagerly request data from the guest */
return ShClSvcDataReadRequest(pClient, fFormats, NULL /* pidEvent */);
}
/**
* Synchronize contents of the host clipboard with the guest
*
* Called by HGCM svc layer on svcConnect() and svcLoadState() (after resume)
* as well as on clipboard ROM update.
*/
int ShClSvcImplSync(PSHCLCLIENT pClient)
{
Clipboard::Guard guard;
if (!clipboard->client())
return VINF_NO_CHANGE;
if (pClient != clipboard->client()) {
warning("shared clipboard: client mismatch on sync");
return VINF_NO_CHANGE;
}
return ShClSvcHostReportFormats(clipboard->client(), VBOX_SHCL_FMT_UNICODETEXT);
}
int ShClSvcImplDisconnect(PSHCLCLIENT pClient)
{
Clipboard::Guard guard;
clipboard->disconnect(pClient);
return VINF_SUCCESS;
}
int ShClSvcImplConnect(PSHCLCLIENT pClient, bool /* fHeadless */)
{
Clipboard::Guard guard;
int const rc = clipboard->connect(pClient);
if (RT_FAILURE(rc))
return rc;
/* send initial format report to guest */
return ShClSvcHostReportFormats(clipboard->client(), VBOX_SHCL_FMT_UNICODETEXT);
}
int ShClSvcImplInit(VBOXHGCMSVCFNTABLE *)
{
try {
clipboard.construct(Services::env());
return VINF_SUCCESS;
} catch (...) {
return VERR_NOT_SUPPORTED;
}
}
void ShClSvcImplDestroy()
{
clipboard.destruct();
}

View File

@ -0,0 +1,3 @@
TARGET = dummy-virtualbox6-services
LIBS += virtualbox6-sharedclipboard

View File

@ -9,10 +9,10 @@ include $(REP_DIR)/lib/mk/virtualbox6-common.inc
CC_WARN += -Wall
SRC_CC := main.cc drivers.cc
SRC_CC += libc.cc unimpl.cc dummies.cc pdm.cc devices.cc nem.cc dynlib.cc
SRC_CC += libc.cc unimpl.cc dummies.cc pdm.cc devices.cc nem.cc
SRC_CC += pthread.cc network.cc devxhci.cc
SRC_CC += sup.cc sup_sem.cc sup_gmm.cc sup_drv.cc sup_vm.cc sup_vcpu.cc sup_gim.cc
SRC_CC += HostServices/common/message.cpp
SRC_CC += HostServices/common/message.cpp services/services.cc
LIBS += base
LIBS += stdcxx
@ -22,10 +22,20 @@ LIBS += qemu-usb
CC_OPT_main = -Wno-multistatement-macros
CC_OPT += -DProgress=ClientProgress
LIB_MK_FILES := $(notdir $(wildcard $(REP_DIR)/lib/mk/virtualbox6-*.mk) \
$(wildcard $(REP_DIR)/lib/mk/spec/x86_64/virtualbox6-*.mk))
LIBS += $(LIB_MK_FILES:.mk=)
LIBS += virtualbox6-dis
LIBS += virtualbox6-sup
LIBS += virtualbox6-devices
LIBS += virtualbox6-vmm
LIBS += virtualbox6-main
LIBS += virtualbox6-xpcom
LIBS += virtualbox6-liblzf
LIBS += virtualbox6-xml
LIBS += virtualbox6-bios
LIBS += virtualbox6-zlib
LIBS += virtualbox6-storage
LIBS += virtualbox6-runtime
LIBS += virtualbox6-apiwrap
LIBS += virtualbox6-client
INC_DIR += $(call select_from_repositories,src/lib/libc)
INC_DIR += $(call select_from_repositories,src/lib/libc)/spec/x86_64
@ -44,6 +54,9 @@ INC_DIR += $(VIRTUALBOX_DIR)/include/VBox/Graphics
# search path to 'scan_code_set_1.h'
INC_DIR += $(call select_from_repositories,src/drivers/ps2)
# export VirtualBox symbols to shared objects (e.g., VBoxSharedClipboard.so)
LD_OPT = --export-dynamic
LIBS += blit
vpath %.cc $(REP_DIR)/src/virtualbox6/

View File

@ -27,7 +27,6 @@ DUMMY(DBGFR3CoreWrite)
DUMMY(DBGFR3LogModifyDestinations)
DUMMY(DBGFR3LogModifyFlags)
DUMMY(DBGFR3LogModifyGroups)
DUMMY(DBGFR3PagingDumpEx)
DUMMY(DBGFR3ReportBugCheck)
DUMMY(DBGFR3StackWalkBegin)
DUMMY(DBGFR3StackWalkBeginEx)
@ -56,6 +55,9 @@ DUMMY(PGMR3MappingsUnfix)
DUMMY(PGMR3SharedModuleCheckAll)
DUMMY(PGMR3SharedModuleRegister)
DUMMY(PGMR3SharedModuleUnregister)
DUMMY(RTCrStoreCertAddFromDir)
DUMMY(RTCrStoreCertAddFromFile)
DUMMY(RTCrStoreCreateInMem)
DUMMY(RTDbgAsLineByAddr)
DUMMY(RTDbgAsLockExcl)
DUMMY(RTDbgAsModuleByIndex)
@ -79,9 +81,8 @@ DUMMY(RTDbgSymbolDup)
DUMMY(RTDbgSymbolFree)
DUMMY(RTFileQueryFsSizes)
DUMMY(RTFsIsoMakerCmdEx)
DUMMY(RTLdrLoadAppPriv)
DUMMY(RTLdrLoadEx)
DUMMY(RTProcCreate)
DUMMY(RTProcCreateEx)
DUMMY(RTZipXarFsStreamFromIoStream)
DUMMY(SELMR3GetSelectorInfo)
DUMMY(SUPGetCpuHzFromGipForAsyncMode)
@ -92,12 +93,17 @@ DUMMY(VDIfTcpNetInstDefaultDestroy)
/* xpcom */
DUMMY(_MD_CreateUnixProcess)
DUMMY(_MD_CreateUnixProcessDetached)
DUMMY(_MD_DetachUnixProcess)
DUMMY(_MD_KillUnixProcess)
DUMMY(_MD_WaitUnixProcess)
DUMMY(PR_FindSymbol)
DUMMY(PR_GetIdentitiesLayer)
DUMMY(PR_LoadLibrary)
DUMMY(PR_LoadLibraryWithFlags)
DUMMY(_PR_MapOptionName)
DUMMY(PR_UnloadLibrary)
DUMMY(_PR_CleanupLayerCache)
DUMMY(_PR_MakeNativeIPCName)
DUMMY(_PR_MapOptionName)
DUMMY(_PR_ShutdownLinker)
} /* extern "C" */

View File

@ -16,12 +16,6 @@
static bool const debug = true;
#include <SpecialSystemDirectory.h>
nsresult GetSpecialSystemDirectory(SystemDirectories, nsILocalFile**) STOP
void StartupSpecialSystemDirectory() { }
#include <nsFastLoadService.h>
nsresult nsFastLoadService::Create(nsISupports*, nsID const&, void**) STOP
@ -40,6 +34,7 @@ nsresult nsPersistentProperties::Create(nsISupports*, nsID const&, void**) STOP
#include <nsProxyEventPrivate.h>
nsresult nsProxyObjectManager::Create(nsISupports*, nsID const&, void**) STOP
void nsProxyObjectManager::Shutdown() STOP
#include <nsScriptableInputStream.h>
@ -55,12 +50,16 @@ nsresult nsStringInputStreamConstructor(nsISupports*, nsID const&, void**) STOP
#include <xptinfo.h>
nsIInterfaceInfoManager *XPTI_GetInterfaceInfoManager() { return nullptr; }
void XPTI_FreeInterfaceInfoManager() { }
extern "C" {
#include <_freebsd.h>
#include <primpl.h>
PRBool _pr_ipv6_is_present;
PRBool _pr_push_ipv6toipv4_layer;
void _MD_EarlyInit(void) { }
void _PR_InitCPUs(void) { }
void _pr_init_ipv6(void) { }