VirtualBox

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

最後變更 在這個檔案從74205是 74205,由 vboxsync 提交於 7 年 前

DnD/HostService: Refactored out more code to the common client and message classes, added documentation (also about deferred client states).

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

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