3
3
* header file for "real" web server code.
5
* Copyright (C) 2006-2010 Oracle Corporation
5
* Copyright (C) 2006-2011 Oracle Corporation
7
7
* This file is part of VirtualBox Open Source Edition (OSE), as
8
8
* available from http://www.virtualbox.org. This file is free software;
41
41
/****************************************************************************
45
****************************************************************************/
47
// type used by gSOAP-generated code
48
typedef std::string WSDLT_ID; // combined managed object ref (session ID plus object ID)
49
typedef std::string vbox__uuid;
51
/****************************************************************************
45
55
****************************************************************************/
47
extern ComPtr<IVirtualBox> g_pVirtualBox;
48
57
extern bool g_fVerbose;
50
59
extern PRTSTREAM g_pstrLog;
52
61
extern util::WriteLockHandle *g_pAuthLibLockHandle;
53
62
extern util::WriteLockHandle *g_pSessionsLockHandle;
55
/****************************************************************************
59
****************************************************************************/
61
// type used by gSOAP-generated code
62
typedef std::string WSDLT_ID; // combined managed object ref (session ID plus object ID)
63
typedef std::string vbox__uuid;
64
extern const WSDLT_ID g_EmptyWSDLID;
65
66
/****************************************************************************
71
72
void RaiseSoapInvalidObjectFault(struct soap *soap, WSDLT_ID obj);
73
void RaiseSoapRuntimeFault(struct soap *soap, HRESULT apirc, IUnknown *pObj);
74
void RaiseSoapRuntimeFault2(struct soap *soap, HRESULT apirc, IUnknown *pObj, const com::Guid &iid);
77
* Template function called everywhere from methodmaps.cpp which calls
78
* RaiseSoapRuntimeFault2() with the correct COM interface ID.
84
void RaiseSoapRuntimeFault(struct soap *soap, HRESULT apirc, const ComPtr<T> &pObj)
86
RaiseSoapRuntimeFault2(soap, apirc, pObj, COM_IIDOF(T));
75
89
/****************************************************************************
118
132
~WebServiceSession();
120
134
int authenticate(const char *pcszUsername,
121
const char *pcszPassword);
135
const char *pcszPassword,
136
IVirtualBox **ppVirtualBox);
123
ManagedObjectRef* findRefFromPtr(const ComPtr<IUnknown> &pcu);
138
ManagedObjectRef* findRefFromPtr(const IUnknown *pObject);
125
140
uint64_t getID() const
127
142
return _uSessionID;
130
WSDLT_ID getSessionObject() const;
145
const WSDLT_ID& getSessionWSDLID() const;
156
171
// owning session:
157
172
WebServiceSession &_session;
160
ComPtr<IUnknown> _pObj;
161
const char *_pcszInterface;
175
IUnknown *_pobjUnknown; // pointer to IUnknown interface for this MOR
177
void *_pobjInterface; // pointer to COM interface represented by _guidInterface, for which this MOR
178
// was created; this may be an IUnknown or something more specific
179
com::Guid _guidInterface; // the interface which _pvObj represents
181
const char *_pcszInterface; // string representation of that interface (e.g. "IMachine")
171
191
ManagedObjectRef(WebServiceSession &session,
172
const char *pcszInterface,
173
const ComPtr<IUnknown> &obj);
192
IUnknown *pobjUnknown,
194
const com::Guid &guidInterface,
195
const char *pcszInterface);
174
196
~ManagedObjectRef();
181
ComPtr<IUnknown> getComPtr()
186
WSDLT_ID toWSDL() const;
204
* Returns the contained COM pointer and the UUID of the COM interface
209
const com::Guid& getPtr(void **ppobjInterface,
210
IUnknown **ppobjUnknown)
212
*ppobjInterface = _pobjInterface;
213
*ppobjUnknown = _pobjUnknown;
214
return _guidInterface;
218
* Returns the ID of this managed object reference to string
219
* form, for returning with SOAP data or similar.
221
* @return The ID in string form.
223
const WSDLT_ID& getWSDLID() const
187
228
const char* getInterfaceName() const
189
230
return _pcszInterface;
203
244
* Template function that resolves a managed object reference to a COM pointer
204
* of the template class T. Gets called from tons of generated code in
245
* of the template class T.
247
* This gets called only from tons of generated code in methodmaps.cpp to
248
* resolve objects in *input* parameters to COM methods (i.e. translate
249
* MOR strings to COM objects which should exist already).
207
251
* This is a template function so that we can support ComPtr's for arbitrary
208
252
* interfaces and automatically verify that the managed object reference on
209
* the internal stack actually is of the expected interface.
253
* the internal stack actually is of the expected interface. We also now avoid
254
* calling QueryInterface for the case that the interface desired by the caller
255
* is the same as the interface for which the MOR was originally created. In
256
* that case, the lookup is very fast.
212
259
* @param id in: integer managed object reference, as passed in by web service client
231
278
ManagedObjectRef *pRef;
232
279
if ((rc = ManagedObjectRef::findRefFromId(id, &pRef, fNullAllowed)))
233
281
RaiseSoapInvalidObjectFault(soap, id);
236
284
if (fNullAllowed && pRef == NULL)
286
WEBDEBUG((" %s(): returning NULL object as permitted\n", __FUNCTION__));
238
287
pComPtr.setNull();
242
// pRef->getComPtr returns a ComPtr<IUnknown>; by casting it to
243
// ComPtr<T>, we implicitly do a COM queryInterface() call
244
if (pComPtr = pRef->getComPtr())
291
const com::Guid &guidCaller = COM_IIDOF(T);
293
// pRef->getPtr returns both a void* for its specific interface pointer as well as a generic IUnknown*
295
IUnknown *pobjUnknown;
296
const com::Guid &guidInterface = pRef->getPtr(&pobjInterface, &pobjUnknown);
298
if (guidInterface == guidCaller)
300
// same interface: then no QueryInterface needed
301
WEBDEBUG((" %s(): returning original %s*=0x%lX (IUnknown*=0x%lX)\n", __FUNCTION__, pRef->getInterfaceName(), pobjInterface, pobjUnknown));
302
pComPtr = (T*)pobjInterface; // this calls AddRef() once
306
// QueryInterface tests whether p actually supports the templated T interface desired by caller
308
pobjUnknown->QueryInterface(guidCaller.ref(), (void**)&pT); // this adds a reference count
311
// assign to caller's ComPtr<T>; use asOutParam() to avoid adding another reference, QueryInterface() already added one
312
WEBDEBUG((" %s(): returning pointer 0x%lX for queried interface %RTuuid (IUnknown*=0x%lX)\n", __FUNCTION__, pT, guidCaller.raw(), pobjUnknown));
313
*(pComPtr.asOutParam()) = pT;
247
317
WEBDEBUG((" Interface not supported for object reference %s, which is of class %s\n", id.c_str(), pRef->getInterfaceName()));
248
318
rc = VERR_WEB_UNSUPPORTED_INTERFACE;
256
* Template function that creates a new managed object for the given COM
257
* pointer of the template class T. If a reference already exists for the
258
* given pointer, then that reference's ID is returned instead.
326
* Creates a new managed object for the given COM pointer. If a reference already exists
327
* for the given pointer, then that reference's ID is returned instead.
329
* This gets called from tons of generated code in methodmaps.cpp to
330
* resolve objects *returned* from COM methods (i.e. create MOR strings from COM objects
331
* which might have been newly created).
260
333
* @param idParent managed object reference of calling object; used to extract session ID
261
334
* @param pc COM object for which to create a reference
262
335
* @return existing or new managed object reference
264
337
template <class T>
265
WSDLT_ID createOrFindRefFromComPtr(const WSDLT_ID &idParent,
266
const char *pcszInterface,
338
const WSDLT_ID& createOrFindRefFromComPtr(const WSDLT_ID &idParent,
339
const char *pcszInterface,
269
342
// NULL comptr should return NULL MOR
272
WEBDEBUG((" createOrFindRefFromComPtr(): returning empty MOR for NULL %s pointer\n", pcszInterface));
345
WEBDEBUG((" createOrFindRefFromComPtr(): returning empty MOR for NULL COM pointer\n"));
346
return g_EmptyWSDLID;
276
349
util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
277
350
WebServiceSession *pSession;
278
351
if ((pSession = WebServiceSession::findSessionFromRef(idParent)))
280
// WEBDEBUG(("\n-- found session for %s\n", idParent.c_str()));
281
353
ManagedObjectRef *pRef;
282
if ( ((pRef = pSession->findRefFromPtr(pc)))
283
|| ((pRef = new ManagedObjectRef(*pSession, pcszInterface, pc)))
355
// we need an IUnknown pointer for the MOR
356
ComPtr<IUnknown> pobjUnknown = pc;
358
if ( ((pRef = pSession->findRefFromPtr(pobjUnknown)))
359
|| ((pRef = new ManagedObjectRef(*pSession,
360
pobjUnknown, // IUnknown *pobjUnknown
361
pc, // void *pobjInterface
285
return pRef->toWSDL();
365
return pRef->getWSDLID();
288
368
// session has expired, return an empty MOR instead of allocating a
289
369
// new reference which couldn't be used anyway.
370
return g_EmptyWSDLID;