VirtualBox

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

Last change on this file since 100619 was 100619, checked in by vboxsync, 11 months ago

Shared Clipboard: Made the Main host service dispatcher a bit more flexible so that it returns VERR_NOT_SUPPORTED if certain commands are not being handled. See comment(s) for details. bugref:9437

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.5 KB
Line 
1/* $Id: GuestShClPrivate.cpp 100619 2023-07-18 08:06:24Z vboxsync $ */
2/** @file
3 * Private Shared Clipboard code.
4 */
5
6/*
7 * Copyright (C) 2023 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{
63 LogFlowFuncEnter();
64
65 RT_ZERO(m_SvcExtVRDP);
66
67 int vrc = RTCritSectInit(&m_CritSect);
68 if (RT_FAILURE(vrc))
69 throw vrc;
70}
71
72GuestShCl::~GuestShCl(void)
73{
74 uninit();
75}
76
77/**
78 * Uninitializes the Shared Clipboard management object.
79 */
80void GuestShCl::uninit(void)
81{
82 LogFlowFuncEnter();
83
84 if (RTCritSectIsInitialized(&m_CritSect))
85 RTCritSectDelete(&m_CritSect);
86
87 RT_ZERO(m_SvcExtVRDP);
88}
89
90/**
91 * Locks the Shared Clipboard management object.
92 *
93 * @returns VBox status code.
94 */
95int GuestShCl::lock(void)
96{
97 int vrc = RTCritSectEnter(&m_CritSect);
98 AssertRC(vrc);
99 return vrc;
100}
101
102/**
103 * Unlocks the Shared Clipboard management object.
104 *
105 * @returns VBox status code.
106 */
107int GuestShCl::unlock(void)
108{
109 int vrc = RTCritSectLeave(&m_CritSect);
110 AssertRC(vrc);
111 return vrc;
112}
113
114/**
115 * Registers a Shared Clipboard service extension.
116 *
117 * @returns VBox status code.
118 * @param pfnExtension Service extension to register.
119 * @param pvExtension User-supplied data pointer. Optional.
120 */
121int GuestShCl::RegisterServiceExtension(PFNHGCMSVCEXT pfnExtension, void *pvExtension)
122{
123 AssertPtrReturn(pfnExtension, VERR_INVALID_POINTER);
124
125 lock();
126
127 PSHCLSVCEXT pExt = &this->m_SvcExtVRDP; /* Currently we only have one extension only. */
128
129 Assert(pExt->pfnExt == NULL);
130
131 pExt->pfnExt = pfnExtension;
132 pExt->pvExt = pvExtension;
133
134 unlock();
135
136 return VINF_SUCCESS;
137}
138
139/**
140 * Unregisters a Shared Clipboard service extension.
141 *
142 * @returns VBox status code.
143 * @param pfnExtension Service extension to unregister.
144 */
145int GuestShCl::UnregisterServiceExtension(PFNHGCMSVCEXT pfnExtension)
146{
147 AssertPtrReturn(pfnExtension, VERR_INVALID_POINTER);
148
149 lock();
150
151 PSHCLSVCEXT pExt = &this->m_SvcExtVRDP; /* Currently we only have one extension only. */
152
153 AssertReturnStmt(pExt->pfnExt == pfnExtension, unlock(), VERR_INVALID_PARAMETER);
154 AssertPtr(pExt->pfnExt);
155
156 RT_BZERO(pExt, sizeof(SHCLSVCEXT));
157
158 unlock();
159
160 return VINF_SUCCESS;
161}
162
163/**
164 * Sends a (blocking) message to the host side of the host service.
165 *
166 * @returns VBox status code.
167 * @param u32Function HGCM message ID to send.
168 * @param cParms Number of parameters to send.
169 * @param paParms Array of parameters to send. Must match \c cParms.
170 */
171int GuestShCl::hostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const
172{
173 /* Forward the information to the VMM device. */
174 AssertPtr(m_pConsole);
175 VMMDev *pVMMDev = m_pConsole->i_getVMMDev();
176 if (!pVMMDev)
177 return VERR_COM_OBJECT_NOT_FOUND;
178
179 return pVMMDev->hgcmHostCall("VBoxSharedClipboard", u32Function, cParms, paParms);
180}
181
182/**
183 * Reports an error by setting the error info and also informs subscribed listeners.
184 *
185 * @returns VBox status code.
186 * @param pcszId ID (name) of the clipboard. Can be NULL if not being used.
187 * @param vrc Result code (IPRT-style) to report.
188 * @param pcszMsgFmt Error message to report.
189 * @param ... Format string for \a pcszMsgFmt.
190 */
191int GuestShCl::reportError(const char *pcszId, int vrc, const char *pcszMsgFmt, ...)
192{
193 /* pcszId can be NULL. */
194 AssertReturn(pcszMsgFmt && *pcszMsgFmt != '\0', E_INVALIDARG);
195
196 va_list va;
197 va_start(va, pcszMsgFmt);
198
199 Utf8Str strMsg;
200 int const vrc2 = strMsg.printfVNoThrow(pcszMsgFmt, va);
201 if (RT_FAILURE(vrc2))
202 {
203 va_end(va);
204 return vrc2;
205 }
206
207 va_end(va);
208
209 if (pcszId)
210 LogRel(("Shared Clipboard (%s): %s (%Rrc)\n", pcszId, strMsg.c_str(), vrc));
211 else
212 LogRel(("Shared Clipboard: %s (%Rrc)\n", strMsg.c_str(), vrc));
213
214 m_pConsole->i_onClipboardError(pcszId, strMsg.c_str(), vrc);
215
216 return VINF_SUCCESS;
217}
218
219/**
220 * Static main dispatcher function to handle callbacks from the Shared Clipboard host service.
221 *
222 * @returns VBox status code.
223 * @retval VERR_NOT_SUPPORTED if the extension didn't handle the requested function. This will invoke the regular backend then.
224 * @param pvExtension Pointer to service extension.
225 * @param u32Function Callback HGCM message ID.
226 * @param pvParms Pointer to optional data provided for a particular message. Optional.
227 * @param cbParms Size (in bytes) of \a pvParms.
228 */
229/* static */
230DECLCALLBACK(int) GuestShCl::hgcmDispatcher(void *pvExtension, uint32_t u32Function,
231 void *pvParms, uint32_t cbParms)
232{
233 LogFlowFunc(("pvExtension=%p, u32Function=%RU32, pvParms=%p, cbParms=%RU32\n",
234 pvExtension, u32Function, pvParms, cbParms));
235
236 GuestShCl *pThis = reinterpret_cast<GuestShCl*>(pvExtension);
237 AssertPtrReturn(pThis, VERR_INVALID_POINTER);
238
239 PSHCLEXTPARMS pParms = (PSHCLEXTPARMS)pvParms;
240 /* pParms might be NULL, depending on the message. */
241
242 int vrc;
243
244 switch (u32Function)
245 {
246 case VBOX_CLIPBOARD_EXT_FN_ERROR:
247 {
248 vrc = pThis->reportError(pParms->u.Error.pszId, pParms->u.Error.rc, pParms->u.Error.pszMsg);
249 break;
250 }
251
252 default:
253 vrc = VERR_NOT_SUPPORTED;
254 break;
255 }
256
257 PSHCLSVCEXT const pExt = &pThis->m_SvcExtVRDP; /* Currently we have one extension only. */
258
259 if (pExt->pfnExt) /* Overwrite rc if we have an extension present. */
260 vrc = pExt->pfnExt(pExt->pvExt, u32Function, pvParms, cbParms);
261
262 LogFlowFuncLeaveRC(vrc);
263 return vrc; /* Goes back to host service. */
264}
265#endif /* VBOX_WITH_SHARED_CLIPBOARD */
266
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use