VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/GuestShClPrivate.cpp@ 107044

Last change on this file since 107044 was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1/* $Id: GuestShClPrivate.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * Private Shared Clipboard code.
4 */
5
6/*
7 * Copyright (C) 2023-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD
29#include "LoggingNew.h"
30
31#include "GuestImpl.h"
32#include "AutoCaller.h"
33
34#ifdef VBOX_WITH_SHARED_CLIPBOARD
35# include "ConsoleImpl.h"
36# include "ProgressImpl.h"
37# include "GuestShClPrivate.h"
38
39# include <iprt/semaphore.h>
40# include <iprt/cpp/utils.h>
41
42# include <VMMDev.h>
43
44# include <VBox/GuestHost/SharedClipboard.h>
45# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
46# include <VBox/GuestHost/SharedClipboard-transfers.h>
47# endif
48# include <VBox/HostServices/VBoxClipboardSvc.h>
49# include <VBox/HostServices/VBoxClipboardExt.h>
50# include <VBox/version.h>
51
52
53/*********************************************************************************************************************************
54 * GuestShCl implementation. *
55 ********************************************************************************************************************************/
56
57/** Static (Singleton) instance of the Shared Clipboard management object. */
58GuestShCl* GuestShCl::s_pInstance = NULL;
59
60GuestShCl::GuestShCl(Console *pConsole)
61 : m_pConsole(pConsole)
62 , m_pfnExtCallback(NULL)
63{
64 LogFlowFuncEnter();
65
66 RT_ZERO(m_SvcExtVRDP);
67
68 int vrc = RTCritSectInit(&m_CritSect);
69 if (RT_FAILURE(vrc))
70 throw vrc;
71}
72
73GuestShCl::~GuestShCl(void)
74{
75 uninit();
76}
77
78/**
79 * Uninitializes the Shared Clipboard management object.
80 */
81void GuestShCl::uninit(void)
82{
83 LogFlowFuncEnter();
84
85 if (RTCritSectIsInitialized(&m_CritSect))
86 RTCritSectDelete(&m_CritSect);
87
88 RT_ZERO(m_SvcExtVRDP);
89
90 m_pfnExtCallback = NULL;
91}
92
93/**
94 * Locks the Shared Clipboard management object.
95 *
96 * @returns VBox status code.
97 */
98int GuestShCl::lock(void)
99{
100 int vrc = RTCritSectEnter(&m_CritSect);
101 AssertRC(vrc);
102 return vrc;
103}
104
105/**
106 * Unlocks the Shared Clipboard management object.
107 *
108 * @returns VBox status code.
109 */
110int GuestShCl::unlock(void)
111{
112 int vrc = RTCritSectLeave(&m_CritSect);
113 AssertRC(vrc);
114 return vrc;
115}
116
117/**
118 * Registers a Shared Clipboard service extension.
119 *
120 * @returns VBox status code.
121 * @param pfnExtension Service extension to register.
122 * @param pvExtension User-supplied data pointer. Optional.
123 */
124int GuestShCl::RegisterServiceExtension(PFNHGCMSVCEXT pfnExtension, void *pvExtension)
125{
126 AssertPtrReturn(pfnExtension, VERR_INVALID_POINTER);
127 /* pvExtension is optional. */
128
129 lock();
130
131 LogFlowFunc(("m_pfnExtCallback=%p\n", this->m_pfnExtCallback));
132
133 PSHCLSVCEXT pExt = &this->m_SvcExtVRDP; /* Currently we only have one extension only. */
134
135 Assert(pExt->pfnExt == NULL);
136
137 pExt->pfnExt = pfnExtension;
138 pExt->pvExt = pvExtension;
139 pExt->pfnExtCallback = this->m_pfnExtCallback; /* Assign callback function. Optional and can be NULL. */
140
141 if (pExt->pfnExtCallback)
142 {
143 /* Make sure to also give the extension the ability to use the callback. */
144 SHCLEXTPARMS parms;
145 RT_ZERO(parms);
146
147 parms.u.SetCallback.pfnCallback = pExt->pfnExtCallback;
148
149 /* ignore rc, callback is optional */ pExt->pfnExt(pExt->pvExt,
150 VBOX_CLIPBOARD_EXT_FN_SET_CALLBACK, &parms, sizeof(parms));
151 }
152
153 unlock();
154
155 return VINF_SUCCESS;
156}
157
158/**
159 * Unregisters a Shared Clipboard service extension.
160 *
161 * @returns VBox status code.
162 * @param pfnExtension Service extension to unregister.
163 */
164int GuestShCl::UnregisterServiceExtension(PFNHGCMSVCEXT pfnExtension)
165{
166 AssertPtrReturn(pfnExtension, VERR_INVALID_POINTER);
167
168 lock();
169
170 PSHCLSVCEXT pExt = &this->m_SvcExtVRDP; /* Currently we only have one extension only. */
171
172 AssertReturnStmt(pExt->pfnExt == pfnExtension, unlock(), VERR_INVALID_PARAMETER);
173 AssertPtr(pExt->pfnExt);
174
175 /* Unregister the callback (setting to NULL). */
176 SHCLEXTPARMS parms;
177 RT_ZERO(parms);
178
179 /* ignore rc, callback is optional */ pExt->pfnExt(pExt->pvExt,
180 VBOX_CLIPBOARD_EXT_FN_SET_CALLBACK, &parms, sizeof(parms));
181
182 RT_BZERO(pExt, sizeof(SHCLSVCEXT));
183
184 unlock();
185
186 return VINF_SUCCESS;
187}
188
189/**
190 * Sends a (blocking) message to the host side of the host service.
191 *
192 * @returns VBox status code.
193 * @param u32Function HGCM message ID to send.
194 * @param cParms Number of parameters to send.
195 * @param paParms Array of parameters to send. Must match \c cParms.
196 */
197int GuestShCl::hostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const
198{
199 /* Forward the information to the VMM device. */
200 AssertPtr(m_pConsole);
201 VMMDev *pVMMDev = m_pConsole->i_getVMMDev();
202 if (!pVMMDev)
203 return VERR_COM_OBJECT_NOT_FOUND;
204
205 return pVMMDev->hgcmHostCall("VBoxSharedClipboard", u32Function, cParms, paParms);
206}
207
208/**
209 * Reports an error by setting the error info and also informs subscribed listeners.
210 *
211 * @returns VBox status code.
212 * @param pcszId ID (name) of the clipboard. Can be NULL if not being used.
213 * @param vrc Result code (IPRT-style) to report.
214 * @param pcszMsgFmt Error message to report.
215 * @param ... Format string for \a pcszMsgFmt.
216 */
217int GuestShCl::reportError(const char *pcszId, int vrc, const char *pcszMsgFmt, ...)
218{
219 /* pcszId can be NULL. */
220 AssertReturn(pcszMsgFmt && *pcszMsgFmt != '\0', E_INVALIDARG);
221
222 va_list va;
223 va_start(va, pcszMsgFmt);
224
225 Utf8Str strMsg;
226 int const vrc2 = strMsg.printfVNoThrow(pcszMsgFmt, va);
227 if (RT_FAILURE(vrc2))
228 {
229 va_end(va);
230 return vrc2;
231 }
232
233 va_end(va);
234
235 if (pcszId)
236 LogRel(("Shared Clipboard (%s): %s (%Rrc)\n", pcszId, strMsg.c_str(), vrc));
237 else
238 LogRel(("Shared Clipboard: %s (%Rrc)\n", strMsg.c_str(), vrc));
239
240 m_pConsole->i_onClipboardError(pcszId, strMsg.c_str(), vrc);
241
242 return VINF_SUCCESS;
243}
244
245/**
246 * Static main dispatcher function to handle callbacks from the Shared Clipboard host service.
247 *
248 * @returns VBox status code.
249 * @retval VERR_NOT_SUPPORTED if the extension didn't handle the requested function. This will invoke the regular backend then.
250 * @param pvExtension Pointer to service extension.
251 * @param u32Function Callback HGCM message ID.
252 * @param pvParms Pointer to optional data provided for a particular message. Optional.
253 * @param cbParms Size (in bytes) of \a pvParms.
254 */
255/* static */
256DECLCALLBACK(int) GuestShCl::hgcmDispatcher(void *pvExtension, uint32_t u32Function,
257 void *pvParms, uint32_t cbParms)
258{
259 LogFlowFunc(("pvExtension=%p, u32Function=%RU32, pvParms=%p, cbParms=%RU32\n",
260 pvExtension, u32Function, pvParms, cbParms));
261
262 GuestShCl *pThis = reinterpret_cast<GuestShCl*>(pvExtension);
263 AssertPtrReturn(pThis, VERR_INVALID_POINTER);
264
265 PSHCLEXTPARMS pParms = (PSHCLEXTPARMS)pvParms;
266 /* pParms might be NULL, depending on the message. */
267
268 int vrc;
269
270 switch (u32Function)
271 {
272 case VBOX_CLIPBOARD_EXT_FN_SET_CALLBACK:
273 pThis->m_pfnExtCallback = pParms->u.SetCallback.pfnCallback;
274 vrc = VINF_SUCCESS;
275 break;
276
277 case VBOX_CLIPBOARD_EXT_FN_ERROR:
278 {
279 vrc = pThis->reportError(pParms->u.Error.pszId, pParms->u.Error.rc, pParms->u.Error.pszMsg);
280 break;
281 }
282
283 default:
284 vrc = VERR_NOT_SUPPORTED;
285 break;
286 }
287
288 PSHCLSVCEXT const pExt = &pThis->m_SvcExtVRDP; /* Currently we have one extension only. */
289
290 if (pExt->pfnExt) /* Overwrite rc if we have an extension present. */
291 vrc = pExt->pfnExt(pExt->pvExt, u32Function, pvParms, cbParms);
292
293 LogFlowFuncLeaveRC(vrc);
294 return vrc; /* Goes back to host service. */
295}
296#endif /* VBOX_WITH_SHARED_CLIPBOARD */
297
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette