VirtualBox

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

Last change on this file since 78401 was 78235, checked in by vboxsync, 6 years ago

HostServices/common/client.cpp: Disabled annoying assertion in DnD service when restoring w10 VM.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.1 KB
Line 
1/* $Id: client.cpp 78235 2019-04-20 23:49:50Z vboxsync $ */
2/** @file
3 * Base class for a host-guest service.
4 */
5
6/*
7 * Copyright (C) 2011-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include <VBox/log.h>
19#include <VBox/hgcmsvc.h>
20
21#include <iprt/assert.h>
22#include <iprt/alloc.h>
23#include <iprt/cpp/utils.h>
24
25#include <VBox/HostServices/Service.h>
26
27using namespace HGCM;
28
29Client::Client(uint32_t uClientID)
30 : m_uClientID(uClientID)
31 , m_uProtocolVer(0)
32 , m_fDeferred(false)
33{
34 RT_ZERO(m_Deferred);
35 RT_ZERO(m_SvcCtx);
36}
37
38Client::~Client(void)
39{
40
41}
42
43/**
44 * Completes a guest call by returning the control back to the guest side,
45 * together with a status code, internal version.
46 *
47 * @returns IPRT status code.
48 * @param hHandle Call handle to complete guest call for.
49 * @param rcOp Return code to return to the guest side.
50 */
51int Client::completeInternal(VBOXHGCMCALLHANDLE hHandle, int rcOp)
52{
53 LogFlowThisFunc(("uClientID=%RU32\n", m_uClientID));
54
55 if ( m_SvcCtx.pHelpers
56 && m_SvcCtx.pHelpers->pfnCallComplete)
57 {
58 m_SvcCtx.pHelpers->pfnCallComplete(hHandle, rcOp);
59
60 reset();
61 return VINF_SUCCESS;
62 }
63
64 return VERR_NOT_AVAILABLE;
65}
66
67/**
68 * Resets the client's internal state.
69 */
70void Client::reset(void)
71{
72 m_fDeferred = false;
73
74 RT_ZERO(m_Deferred);
75}
76
77/**
78 * Completes a guest call by returning the control back to the guest side,
79 * together with a status code.
80 *
81 * @returns IPRT status code.
82 * @param hHandle Call handle to complete guest call for.
83 * @param rcOp Return code to return to the guest side.
84 */
85int Client::Complete(VBOXHGCMCALLHANDLE hHandle, int rcOp /* = VINF_SUCCESS */)
86{
87 return completeInternal(hHandle, rcOp);
88}
89
90/**
91 * Completes a deferred guest call by returning the control back to the guest side,
92 * together with a status code.
93 *
94 * @returns IPRT status code. VERR_INVALID_STATE if the client is not in deferred mode.
95 * @param rcOp Return code to return to the guest side.
96 */
97int Client::CompleteDeferred(int rcOp)
98{
99 if (m_fDeferred)
100 {
101 Assert(m_Deferred.hHandle != NULL);
102
103 int rc = completeInternal(m_Deferred.hHandle, rcOp);
104 if (RT_SUCCESS(rc))
105 m_fDeferred = false;
106
107 return rc;
108 }
109
110 AssertMsg(m_fDeferred, ("Client %RU32 is not in deferred mode\n", m_uClientID));
111 return VERR_INVALID_STATE;
112}
113
114/**
115 * Returns the HGCM call handle of the client.
116 *
117 * @returns HGCM handle.
118 */
119VBOXHGCMCALLHANDLE Client::GetHandle(void) const
120{
121 return m_Deferred.hHandle;
122}
123
124/**
125 * Returns the HGCM call handle of the client.
126 *
127 * @returns HGCM handle.
128 */
129uint32_t Client::GetMsgType(void) const
130{
131 return m_Deferred.uType;
132}
133
134uint32_t Client::GetMsgParamCount(void) const
135{
136 return m_Deferred.cParms;
137}
138
139/**
140 * Returns the client's (HGCM) ID.
141 *
142 * @returns The client's (HGCM) ID.
143 */
144uint32_t Client::GetClientID(void) const
145{
146 return m_uClientID;
147}
148
149/**
150 * Returns the client's used protocol version.
151 *
152 * @returns Protocol version, or 0 if not set.
153 */
154uint32_t Client::GetProtocolVer(void) const
155{
156 return m_uProtocolVer;
157}
158
159/**
160 * Returns whether the client currently is in deferred mode or not.
161 *
162 * @returns \c True if in deferred mode, \c False if not.
163 */
164bool Client::IsDeferred(void) const
165{
166 return m_fDeferred;
167}
168
169/**
170 * Set the client's status to deferred, meaning that it does not return to the caller
171 * until CompleteDeferred() has been called.
172 */
173void Client::SetDeferred(VBOXHGCMCALLHANDLE hHandle, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
174{
175 LogFlowThisFunc(("uClient=%RU32\n", m_uClientID));
176
177#ifndef DEBUG_bird /** r=bird: This bugger triggers in the DnD service when restoring saved state. Not tested? */
178 AssertMsg(m_fDeferred == false, ("Client already in deferred mode\n"));
179#endif
180 m_fDeferred = true;
181
182 m_Deferred.hHandle = hHandle;
183 m_Deferred.uType = u32Function;
184 m_Deferred.cParms = cParms;
185 m_Deferred.paParms = paParms;
186}
187
188/**
189 * Sets the client's protocol version. The protocol version is purely optional and bound
190 * to a specific HGCM service.
191 *
192 * @param uVersion Version number to set.
193 */
194void Client::SetProtocolVer(uint32_t uVersion)
195{
196 m_uProtocolVer = uVersion;
197}
198
199/**
200 * Sets the HGCM service context.
201 *
202 * @param SvcCtx Service context to set.
203 */
204void Client::SetSvcContext(const VBOXHGCMSVCTX &SvcCtx)
205{
206 m_SvcCtx = SvcCtx;
207}
208
209/**
210 * Sets the deferred parameters to a specific message type and
211 * required parameters. That way the client can re-request that message with
212 * the right amount of parameters from the service.
213 *
214 * @returns IPRT status code.
215 * @param uMsg Message type (number) to set.
216 * @param cParms Number of parameters the message needs.
217 */
218int Client::SetDeferredMsgInfo(uint32_t uMsg, uint32_t cParms)
219{
220 if (m_fDeferred)
221 {
222 if (m_Deferred.cParms < 2)
223 return VERR_INVALID_PARAMETER;
224
225 AssertPtrReturn(m_Deferred.paParms, VERR_BUFFER_OVERFLOW);
226
227 HGCMSvcSetU32(&m_Deferred.paParms[0], uMsg);
228 HGCMSvcSetU32(&m_Deferred.paParms[1], cParms);
229
230 return VINF_SUCCESS;
231 }
232
233 AssertFailed();
234 return VERR_INVALID_STATE;
235}
236
237/**
238 * Sets the deferred parameters to a specific message type and
239 * required parameters. That way the client can re-request that message with
240 * the right amount of parameters from the service.
241 *
242 * @returns IPRT status code.
243 * @param pMessage Message to get message type and required parameters from.
244 */
245int Client::SetDeferredMsgInfo(const Message *pMessage)
246{
247 AssertPtrReturn(pMessage, VERR_INVALID_POINTER);
248 return SetDeferredMsgInfo(pMessage->GetType(), pMessage->GetParamCount());
249}
250
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