VirtualBox

source: vbox/trunk/src/VBox/Main/webservice/vboxweb.h@ 30676

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

Main: back out r63429

  • 屬性 filesplitter.c 設為 Makefile.kmk
  • 屬性 svn:eol-style 設為 native
檔案大小: 12.2 KB
 
1/*
2 * vboxweb.h:
3 * header file for "real" web server code.
4 *
5 * Copyright (C) 2006-2010 Oracle Corporation
6 *
7 * This file is part of VirtualBox Open Source Edition (OSE), as
8 * available from http://www.alldomusa.eu.org. This file is free software;
9 * you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License (GPL) as published by the Free Software
11 * Foundation, in version 2 as it comes in the "COPYING" file of the
12 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
14 */
15
16/****************************************************************************
17 *
18 * debug macro
19 *
20 ****************************************************************************/
21
22void WebLog(const char *pszFormat, ...);
23
24#define WEBDEBUG(a) if (g_fVerbose) { WebLog a; }
25
26#ifdef DEBUG
27#define LOG_GROUP LOG_GROUP_WEBSERVICE
28#include <VBox/log.h>
29#endif
30
31#include <VBox/com/VirtualBox.h>
32#include <VBox/com/Guid.h>
33#include <VBox/com/AutoLock.h>
34
35#include <VBox/err.h>
36
37#include <iprt/stream.h>
38
39#include <string>
40
41/****************************************************************************
42 *
43 * typedefs
44 *
45 ****************************************************************************/
46
47// type used by gSOAP-generated code
48typedef std::string WSDLT_ID; // combined managed object ref (session ID plus object ID)
49typedef std::string vbox__uuid;
50
51/****************************************************************************
52 *
53 * global variables
54 *
55 ****************************************************************************/
56
57extern ComPtr<IVirtualBox> g_pVirtualBox;
58extern bool g_fVerbose;
59
60extern PRTSTREAM g_pstrLog;
61
62extern util::WriteLockHandle *g_pAuthLibLockHandle;
63extern util::WriteLockHandle *g_pSessionsLockHandle;
64
65extern const WSDLT_ID g_EmptyWSDLID;
66
67/****************************************************************************
68 *
69 * SOAP exceptions
70 *
71 ****************************************************************************/
72
73void RaiseSoapInvalidObjectFault(struct soap *soap, WSDLT_ID obj);
74
75void RaiseSoapRuntimeFault(struct soap *soap, HRESULT apirc, IUnknown *pObj);
76
77/****************************************************************************
78 *
79 * conversion helpers
80 *
81 ****************************************************************************/
82
83std::string ConvertComString(const com::Bstr &bstr);
84
85std::string ConvertComString(const com::Guid &bstr);
86
87/****************************************************************************
88 *
89 * managed object reference classes
90 *
91 ****************************************************************************/
92
93class WebServiceSessionPrivate;
94class ManagedObjectRef;
95
96/**
97 * An instance of this gets created for every client that logs onto the
98 * webservice (via the special IWebsessionManager::logon() SOAP API) and
99 * maintains the managed object references for that session.
100 */
101class WebServiceSession
102{
103 friend class ManagedObjectRef;
104
105 private:
106 uint64_t _uSessionID;
107 WebServiceSessionPrivate *_pp; // opaque data struct (defined in vboxweb.cpp)
108 bool _fDestructing;
109
110 ManagedObjectRef *_pISession;
111
112 time_t _tLastObjectLookup;
113
114 // hide the copy constructor because we're not copyable
115 WebServiceSession(const WebServiceSession &copyFrom);
116
117 public:
118 WebServiceSession();
119
120 ~WebServiceSession();
121
122 int authenticate(const char *pcszUsername,
123 const char *pcszPassword);
124
125 ManagedObjectRef* findRefFromPtr(const IUnknown *pObject);
126
127 uint64_t getID() const
128 {
129 return _uSessionID;
130 }
131
132 const WSDLT_ID& getSessionWSDLID() const;
133
134 void touch();
135
136 time_t getLastObjectLookup() const
137 {
138 return _tLastObjectLookup;
139 }
140
141 static WebServiceSession* findSessionFromRef(const WSDLT_ID &id);
142
143 void DumpRefs();
144};
145
146/**
147 * ManagedObjectRef is used to map COM pointers to object IDs
148 * within a session. Such object IDs are 64-bit integers.
149 *
150 * When a webservice method call is invoked on an object, it
151 * has an opaque string called a "managed object reference". Such
152 * a string consists of a session ID combined with an object ID.
153 *
154 */
155class ManagedObjectRef
156{
157 protected:
158 // owning session:
159 WebServiceSession &_session;
160
161
162 IUnknown *_pobjUnknown; // pointer to IUnknown interface for this MOR
163
164 void *_pobjInterface; // pointer to COM interface represented by _guidInterface, for which this MOR
165 // was created; this may be an IUnknown or something more specific
166 com::Guid _guidInterface; // the interface which _pvObj represents
167
168 const char *_pcszInterface; // string representation of that interface (e.g. "IMachine")
169
170 // keys:
171 uint64_t _id;
172 uintptr_t _ulp;
173
174 // long ID as string
175 WSDLT_ID _strID;
176
177 public:
178 ManagedObjectRef(WebServiceSession &session,
179 IUnknown *pobjUnknown,
180 void *pobjInterface,
181 const com::Guid &guidInterface,
182 const char *pcszInterface);
183 ~ManagedObjectRef();
184
185 uint64_t getID()
186 {
187 return _id;
188 }
189
190 /**
191 * Returns the contained COM pointer and the UUID of the COM interface
192 * which it supports.
193 * @param
194 * @return
195 */
196 const com::Guid& getPtr(void **ppobjInterface,
197 IUnknown **ppobjUnknown)
198 {
199 *ppobjInterface = _pobjInterface;
200 *ppobjUnknown = _pobjUnknown;
201 return _guidInterface;
202 }
203
204 /**
205 * Returns the ID of this managed object reference to string
206 * form, for returning with SOAP data or similar.
207 *
208 * @return The ID in string form.
209 */
210 const WSDLT_ID& getWSDLID() const
211 {
212 return _strID;
213 }
214
215 const char* getInterfaceName() const
216 {
217 return _pcszInterface;
218 }
219
220 static int findRefFromId(const WSDLT_ID &id,
221 ManagedObjectRef **pRef,
222 bool fNullAllowed);
223
224 static ManagedObjectRef* findFromPtr(ComPtr<IUnknown> pcu);
225 static ManagedObjectRef* create(const WSDLT_ID &idParent,
226 ComPtr<IUnknown> pcu);
227
228};
229
230/**
231 * Template function that resolves a managed object reference to a COM pointer
232 * of the template class T.
233 *
234 * This gets called only from tons of generated code in methodmaps.cpp to
235 * resolve objects in *input* parameters to COM methods (i.e. translate
236 * MOR strings to COM objects which should exist already).
237 *
238 * This is a template function so that we can support ComPtr's for arbitrary
239 * interfaces and automatically verify that the managed object reference on
240 * the internal stack actually is of the expected interface. We also now avoid
241 * calling QueryInterface for the case that the interface desired by the caller
242 * is the same as the interface for which the MOR was originally created. In
243 * that case, the lookup is very fast.
244 *
245 * @param soap
246 * @param id in: integer managed object reference, as passed in by web service client
247 * @param pComPtr out: reference to COM pointer object that receives the com pointer,
248 * if SOAP_OK is returned
249 * @param fNullAllowed in: if true, then this func returns a NULL COM pointer if an
250 * empty MOR is passed in (i.e. NULL pointers are allowed). If false,
251 * then this fails; this will be false when called for the "this"
252 * argument of method calls, which really shouldn't be NULL.
253 * @return error code or SOAP_OK if no error
254 */
255template <class T>
256int findComPtrFromId(struct soap *soap,
257 const WSDLT_ID &id,
258 ComPtr<T> &pComPtr,
259 bool fNullAllowed)
260{
261 // findRefFromId requires thelock
262 util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
263
264 int rc;
265 ManagedObjectRef *pRef;
266 if ((rc = ManagedObjectRef::findRefFromId(id, &pRef, fNullAllowed)))
267 // error:
268 RaiseSoapInvalidObjectFault(soap, id);
269 else
270 {
271 if (fNullAllowed && pRef == NULL)
272 {
273 WEBDEBUG((" %s(): returning NULL object as permitted\n", __FUNCTION__));
274 pComPtr.setNull();
275 return 0;
276 }
277
278 const com::Guid &guidCaller = COM_IIDOF(T);
279
280 // pRef->getPtr returns both a void* for its specific interface pointer as well as a generic IUnknown*
281 void *pobjInterface;
282 IUnknown *pobjUnknown;
283 const com::Guid &guidInterface = pRef->getPtr(&pobjInterface, &pobjUnknown);
284
285 if (guidInterface == guidCaller)
286 {
287 // same interface: then no QueryInterface needed
288 WEBDEBUG((" %s(): returning original %s*=0x%lX (IUnknown*=0x%lX)\n", __FUNCTION__, pRef->getInterfaceName(), pobjInterface, pobjUnknown));
289 pComPtr = (T*)pobjInterface; // this calls AddRef() once
290 return 0;
291 }
292
293 // QueryInterface tests whether p actually supports the templated T interface desired by caller
294 T *pT;
295 pobjUnknown->QueryInterface(guidCaller, (void**)&pT); // this adds a reference count
296 if (pT)
297 {
298 // assign to caller's ComPtr<T>; use asOutParam() to avoid adding another reference, QueryInterface() already added one
299 WEBDEBUG((" %s(): returning pointer 0x%lX for queried interface %RTuuid (IUnknown*=0x%lX)\n", __FUNCTION__, pT, guidCaller.raw(), pobjUnknown));
300 *(pComPtr.asOutParam()) = pT;
301 return 0;
302 }
303
304 WEBDEBUG((" Interface not supported for object reference %s, which is of class %s\n", id.c_str(), pRef->getInterfaceName()));
305 rc = VERR_WEB_UNSUPPORTED_INTERFACE;
306 RaiseSoapInvalidObjectFault(soap, id); // @todo better message
307 }
308
309 return rc;
310}
311
312/**
313 * Creates a new managed object for the given COM pointer. If a reference already exists
314 * for the given pointer, then that reference's ID is returned instead.
315 *
316 * This gets called from tons of generated code in methodmaps.cpp to
317 * resolve objects *returned* from COM methods (i.e. create MOR strings from COM objects
318 * which might have been newly created).
319 *
320 * @param idParent managed object reference of calling object; used to extract session ID
321 * @param pc COM object for which to create a reference
322 * @return existing or new managed object reference
323 */
324template <class T>
325const WSDLT_ID& createOrFindRefFromComPtr(const WSDLT_ID &idParent,
326 const char *pcszInterface,
327 ComPtr<T> &pc)
328{
329 // NULL comptr should return NULL MOR
330 if (pc.isNull())
331 {
332 WEBDEBUG((" createOrFindRefFromComPtr(): returning empty MOR for NULL COM pointer\n"));
333 return g_EmptyWSDLID;
334 }
335
336 util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
337 WebServiceSession *pSession;
338 if ((pSession = WebServiceSession::findSessionFromRef(idParent)))
339 {
340 ManagedObjectRef *pRef;
341
342 // we need an IUnknown pointer for the MOR
343 ComPtr<IUnknown> pobjUnknown = pc;
344
345 if ( ((pRef = pSession->findRefFromPtr(pobjUnknown)))
346 || ((pRef = new ManagedObjectRef(*pSession,
347 pobjUnknown, // IUnknown *pobjUnknown
348 pc, // void *pobjInterface
349 COM_IIDOF(T),
350 pcszInterface)))
351 )
352 return pRef->getWSDLID();
353 }
354
355 // session has expired, return an empty MOR instead of allocating a
356 // new reference which couldn't be used anyway.
357 return g_EmptyWSDLID;
358}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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