VirtualBox

source: vbox/trunk/src/VBox/HostServices/common/client.cpp@ 105016

Last change on this file since 105016 was 98103, checked in by vboxsync, 20 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: 6.2 KB
Line 
1/* $Id: client.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * Base class for a host-guest service.
4 */
5
6/*
7 * Copyright (C) 2011-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#include <VBox/log.h>
29#include <VBox/hgcmsvc.h>
30
31#include <iprt/assert.h>
32#include <iprt/alloc.h>
33#include <iprt/cpp/utils.h>
34
35#include <VBox/HostServices/Service.h>
36
37using namespace HGCM;
38
39Client::Client(uint32_t idClient)
40 : m_idClient(idClient)
41 , m_fDeferred(false)
42{
43 RT_ZERO(m_Deferred);
44 RT_ZERO(m_SvcCtx);
45}
46
47Client::~Client(void)
48{
49
50}
51
52/**
53 * Completes a guest call by returning the control back to the guest side,
54 * together with a status code, internal version.
55 *
56 * @returns IPRT status code.
57 * @param hHandle Call handle to complete guest call for.
58 * @param rcOp Return code to return to the guest side.
59 */
60int Client::completeInternal(VBOXHGCMCALLHANDLE hHandle, int rcOp) RT_NOEXCEPT
61{
62 LogFlowThisFunc(("idClient=%RU32\n", m_idClient));
63
64 if ( m_SvcCtx.pHelpers
65 && m_SvcCtx.pHelpers->pfnCallComplete)
66 {
67 m_SvcCtx.pHelpers->pfnCallComplete(hHandle, rcOp);
68
69 reset();
70 return VINF_SUCCESS;
71 }
72
73 return VERR_NOT_AVAILABLE;
74}
75
76/**
77 * Resets the client's internal state.
78 */
79void Client::reset(void) RT_NOEXCEPT
80{
81 m_fDeferred = false;
82
83 RT_ZERO(m_Deferred);
84}
85
86/**
87 * Completes a guest call by returning the control back to the guest side,
88 * together with a status code.
89 *
90 * @returns IPRT status code.
91 * @param hHandle Call handle to complete guest call for.
92 * @param rcOp Return code to return to the guest side.
93 */
94int Client::Complete(VBOXHGCMCALLHANDLE hHandle, int rcOp /* = VINF_SUCCESS */) RT_NOEXCEPT
95{
96 return completeInternal(hHandle, rcOp);
97}
98
99/**
100 * Completes a deferred guest call by returning the control back to the guest side,
101 * together with a status code.
102 *
103 * @returns IPRT status code. VERR_INVALID_STATE if the client is not in deferred mode.
104 * @param rcOp Return code to return to the guest side.
105 */
106int Client::CompleteDeferred(int rcOp) RT_NOEXCEPT
107{
108 if (m_fDeferred)
109 {
110 Assert(m_Deferred.hHandle != NULL);
111
112 int rc = completeInternal(m_Deferred.hHandle, rcOp);
113 if (RT_SUCCESS(rc))
114 m_fDeferred = false;
115
116 return rc;
117 }
118
119 AssertMsg(m_fDeferred, ("Client %RU32 is not in deferred mode\n", m_idClient));
120 return VERR_INVALID_STATE;
121}
122
123/**
124 * Returns the HGCM call handle of the client.
125 *
126 * @returns HGCM handle.
127 */
128VBOXHGCMCALLHANDLE Client::GetHandle(void) const RT_NOEXCEPT
129{
130 return m_Deferred.hHandle;
131}
132
133/**
134 * Returns the HGCM call handle of the client.
135 *
136 * @returns HGCM handle.
137 */
138uint32_t Client::GetMsgType(void) const RT_NOEXCEPT
139{
140 return m_Deferred.uType;
141}
142
143uint32_t Client::GetMsgParamCount(void) const RT_NOEXCEPT
144{
145 return m_Deferred.cParms;
146}
147
148/**
149 * Returns the client's (HGCM) ID.
150 *
151 * @returns The client's (HGCM) ID.
152 */
153uint32_t Client::GetClientID(void) const RT_NOEXCEPT
154{
155 return m_idClient;
156}
157
158/**
159 * Returns whether the client currently is in deferred mode or not.
160 *
161 * @returns \c True if in deferred mode, \c False if not.
162 */
163bool Client::IsDeferred(void) const RT_NOEXCEPT
164{
165 return m_fDeferred;
166}
167
168/**
169 * Set the client's status to deferred, meaning that it does not return to the caller
170 * until CompleteDeferred() has been called.
171 *
172 * @returns VBox status code.
173 * @param hHandle Call handle to save.
174 * @param u32Function Function number to save.
175 * @param cParms Number of HGCM parameters to save.
176 * @param paParms HGCM parameters to save.
177 */
178void Client::SetDeferred(VBOXHGCMCALLHANDLE hHandle, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT
179{
180 LogFlowThisFunc(("uClient=%RU32\n", m_idClient));
181
182 m_fDeferred = true;
183
184 m_Deferred.hHandle = hHandle;
185 m_Deferred.uType = u32Function;
186 m_Deferred.cParms = cParms;
187 m_Deferred.paParms = paParms;
188}
189
190/**
191 * Sets the HGCM service context.
192 *
193 * @param SvcCtx Service context to set.
194 */
195void Client::SetSvcContext(const VBOXHGCMSVCTX &SvcCtx) RT_NOEXCEPT
196{
197 m_SvcCtx = SvcCtx;
198}
199
200/**
201 * Sets the deferred parameters to a specific message type and
202 * required parameters. That way the client can re-request that message with
203 * the right amount of parameters from the service.
204 *
205 * @returns IPRT status code.
206 * @param uMsg Message type (number) to set.
207 * @param cParms Number of parameters the message needs.
208 */
209int Client::SetDeferredMsgInfo(uint32_t uMsg, uint32_t cParms) RT_NOEXCEPT
210{
211 if (m_fDeferred)
212 {
213 if (m_Deferred.cParms < 2)
214 return VERR_INVALID_PARAMETER;
215
216 AssertPtrReturn(m_Deferred.paParms, VERR_BUFFER_OVERFLOW);
217
218 HGCMSvcSetU32(&m_Deferred.paParms[0], uMsg);
219 HGCMSvcSetU32(&m_Deferred.paParms[1], cParms);
220
221 return VINF_SUCCESS;
222 }
223
224 AssertFailed();
225 return VERR_INVALID_STATE;
226}
227
228/**
229 * Sets the deferred parameters to a specific message type and
230 * required parameters. That way the client can re-request that message with
231 * the right amount of parameters from the service.
232 *
233 * @returns IPRT status code.
234 * @param pMessage Message to get message type and required parameters from.
235 */
236int Client::SetDeferredMsgInfo(const Message *pMessage) RT_NOEXCEPT
237{
238 AssertPtrReturn(pMessage, VERR_INVALID_POINTER);
239 return SetDeferredMsgInfo(pMessage->GetType(), pMessage->GetParamCount());
240}
241
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