vboxweb.h revision dc09cb937d0a66e030b4d7bef88dec429f41e060
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * vboxweb.h:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * header file for "real" web server code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Copyright (C) 2006-2010 Oracle Corporation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * General Public License (GPL) as published by the Free Software
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync */
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync/****************************************************************************
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync *
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * debug macro
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ****************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid WebLog(const char *pszFormat, ...);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define WEBDEBUG(a) if (g_fVerbose) { WebLog a; }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef DEBUG
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define LOG_GROUP LOG_GROUP_WEBSERVICE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <VBox/log.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync#include <VBox/com/VirtualBox.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <VBox/com/Guid.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <VBox/com/AutoLock.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <VBox/err.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync#include <iprt/stream.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <string>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/****************************************************************************
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * typedefs
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ****************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// type used by gSOAP-generated code
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef std::string WSDLT_ID; // combined managed object ref (session ID plus object ID)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef std::string vbox__uuid;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync/****************************************************************************
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * global variables
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ****************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncextern ComPtr<IVirtualBox> g_pVirtualBox;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncextern bool g_fVerbose;
afed5ab737f4aacfae3fe73776f40e989190a7cavboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncextern PRTSTREAM g_pstrLog;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncextern util::WriteLockHandle *g_pAuthLibLockHandle;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncextern util::WriteLockHandle *g_pSessionsLockHandle;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncextern const WSDLT_ID g_EmptyWSDLID;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
0174432b2b1a760b89840ba696f7ba51def65dddvboxsync/****************************************************************************
2daaccf68be3773aee600c5c3e48bcf5401418a6vboxsync *
0174432b2b1a760b89840ba696f7ba51def65dddvboxsync * SOAP exceptions
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ****************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid RaiseSoapInvalidObjectFault(struct soap *soap, WSDLT_ID obj);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid RaiseSoapRuntimeFault(struct soap *soap, HRESULT apirc, IUnknown *pObj);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/****************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * conversion helpers
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ****************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstd::string ConvertComString(const com::Bstr &bstr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstd::string ConvertComString(const com::Guid &bstr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/****************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * managed object reference classes
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ****************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsyncclass WebServiceSessionPrivate;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncclass ManagedObjectRef;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * An instance of this gets created for every client that logs onto the
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync * webservice (via the special IWebsessionManager::logon() SOAP API) and
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * maintains the managed object references for that session.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsyncclass WebServiceSession
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync friend class ManagedObjectRef;
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync private:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint64_t _uSessionID;
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync WebServiceSessionPrivate *_pp; // opaque data struct (defined in vboxweb.cpp)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool _fDestructing;
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ManagedObjectRef *_pISession;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync time_t _tLastObjectLookup;
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync // hide the copy constructor because we're not copyable
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync WebServiceSession(const WebServiceSession &copyFrom);
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync public:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync WebServiceSession();
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ~WebServiceSession();
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync int authenticate(const char *pcszUsername,
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync const char *pcszPassword);
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync ManagedObjectRef* findRefFromPtr(const IUnknown *pObject);
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync uint64_t getID() const
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync {
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync return _uSessionID;
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync }
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const WSDLT_ID& getSessionWSDLID() const;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync void touch();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync time_t getLastObjectLookup() const
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync {
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync return _tLastObjectLookup;
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync }
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync static WebServiceSession* findSessionFromRef(const WSDLT_ID &id);
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync void DumpRefs();
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync};
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync/**
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync * ManagedObjectRef is used to map COM pointers to object IDs
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync * within a session. Such object IDs are 64-bit integers.
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync *
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync * When a webservice method call is invoked on an object, it
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync * has an opaque string called a "managed object reference". Such
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync * a string consists of a session ID combined with an object ID.
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync *
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync */
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsyncclass ManagedObjectRef
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync{
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync protected:
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync // owning session:
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync WebServiceSession &_session;
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync IUnknown *_pobjUnknown; // pointer to IUnknown interface for this MOR
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync void *_pobjInterface; // pointer to COM interface represented by _guidInterface, for which this MOR
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync // was created; this may be an IUnknown or something more specific
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync com::Guid _guidInterface; // the interface which _pvObj represents
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync const char *_pcszInterface; // string representation of that interface (e.g. "IMachine")
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync
26824086a3f6b36cd911058f1d9b4c0b944706fbvboxsync // keys:
26824086a3f6b36cd911058f1d9b4c0b944706fbvboxsync uint64_t _id;
26824086a3f6b36cd911058f1d9b4c0b944706fbvboxsync uintptr_t _ulp;
68ef804c4ec232c58e2c03c8fc6afe3765c5c0d1vboxsync
68ef804c4ec232c58e2c03c8fc6afe3765c5c0d1vboxsync // long ID as string
68ef804c4ec232c58e2c03c8fc6afe3765c5c0d1vboxsync WSDLT_ID _strID;
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync public:
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync ManagedObjectRef(WebServiceSession &session,
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync IUnknown *pobjUnknown,
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync void *pobjInterface,
26824086a3f6b36cd911058f1d9b4c0b944706fbvboxsync const com::Guid &guidInterface,
26824086a3f6b36cd911058f1d9b4c0b944706fbvboxsync const char *pcszInterface);
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync ~ManagedObjectRef();
b8aaccdbdd143967110d499670605dd7ff6ecc72vboxsync
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync uint64_t getID()
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return _id;
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Returns the contained COM pointer and the UUID of the COM interface
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * which it supports.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const com::Guid& getPtr(void **ppobjInterface,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IUnknown **ppobjUnknown)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *ppobjInterface = _pobjInterface;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *ppobjUnknown = _pobjUnknown;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return _guidInterface;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Returns the ID of this managed object reference to string
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * form, for returning with SOAP data or similar.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return The ID in string form.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const WSDLT_ID& getWSDLID() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return _strID;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const char* getInterfaceName() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
b1c3cdef473df2fbc621d5da81acc82dbfb8a11avboxsync return _pcszInterface;
a11c569636fa6838bd423f4631a9660a5a84204bvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync static int findRefFromId(const WSDLT_ID &id,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ManagedObjectRef **pRef,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool fNullAllowed);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync static ManagedObjectRef* findFromPtr(ComPtr<IUnknown> pcu);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync static ManagedObjectRef* create(const WSDLT_ID &idParent,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ComPtr<IUnknown> pcu);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync};
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Template function that resolves a managed object reference to a COM pointer
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * of the template class T.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
3ecf9412133496b2aeb090cfd33a286404ec59fbvboxsync * This gets called only from tons of generated code in methodmaps.cpp to
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * resolve objects in *input* parameters to COM methods (i.e. translate
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * MOR strings to COM objects which should exist already).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This is a template function so that we can support ComPtr's for arbitrary
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * interfaces and automatically verify that the managed object reference on
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the internal stack actually is of the expected interface. We also now avoid
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * calling QueryInterface for the case that the interface desired by the caller
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * is the same as the interface for which the MOR was originally created. In
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * that case, the lookup is very fast.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param soap
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param id in: integer managed object reference, as passed in by web service client
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pComPtr out: reference to COM pointer object that receives the com pointer,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * if SOAP_OK is returned
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param fNullAllowed in: if true, then this func returns a NULL COM pointer if an
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * empty MOR is passed in (i.e. NULL pointers are allowed). If false,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * then this fails; this will be false when called for the "this"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * argument of method calls, which really shouldn't be NULL.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return error code or SOAP_OK if no error
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctemplate <class T>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncint findComPtrFromId(struct soap *soap,
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync const WSDLT_ID &id,
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync ComPtr<T> &pComPtr,
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync bool fNullAllowed)
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync{
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync // findRefFromId requires thelock
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync int rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ManagedObjectRef *pRef;
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync if ((rc = ManagedObjectRef::findRefFromId(id, &pRef, fNullAllowed)))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // error:
576d4214137bce409cdcf01e8df4a0bca5e0b2d1vboxsync RaiseSoapInvalidObjectFault(soap, id);
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync else
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (fNullAllowed && pRef == NULL)
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync WEBDEBUG((" %s(): returning NULL object as permitted\n", __FUNCTION__));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pComPtr.setNull();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const com::Guid &guidCaller = COM_IIDOF(T);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // pRef->getPtr returns both a void* for its specific interface pointer as well as a generic IUnknown*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync void *pobjInterface;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IUnknown *pobjUnknown;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const com::Guid &guidInterface = pRef->getPtr(&pobjInterface, &pobjUnknown);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (guidInterface == guidCaller)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // same interface: then no QueryInterface needed
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync WEBDEBUG((" %s(): returning original %s*=0x%lX (IUnknown*=0x%lX)\n", __FUNCTION__, pRef->getInterfaceName(), pobjInterface, pobjUnknown));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pComPtr = (T*)pobjInterface; // this calls AddRef() once
e3058907e95856baada756f4bc59dafc1ce6c6b4vboxsync return 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync // QueryInterface tests whether p actually supports the templated T interface desired by caller
9782b553bdb12385214a3ac596aff1476bcb7cbdvboxsync T *pT;
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync pobjUnknown->QueryInterface(guidCaller, (void**)&pT); // this adds a reference count
576d4214137bce409cdcf01e8df4a0bca5e0b2d1vboxsync if (pT)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // assign to caller's ComPtr<T>; use asOutParam() to avoid adding another reference, QueryInterface() already added one
576d4214137bce409cdcf01e8df4a0bca5e0b2d1vboxsync WEBDEBUG((" %s(): returning pointer 0x%lX for queried interface %RTuuid (IUnknown*=0x%lX)\n", __FUNCTION__, pT, guidCaller.raw(), pobjUnknown));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *(pComPtr.asOutParam()) = pT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync WEBDEBUG((" Interface not supported for object reference %s, which is of class %s\n", id.c_str(), pRef->getInterfaceName()));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = VERR_WEB_UNSUPPORTED_INTERFACE;
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync RaiseSoapInvalidObjectFault(soap, id); // @todo better message
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Creates a new managed object for the given COM pointer. If a reference already exists
da936e0446fb2b56b813d5d938f1dfc6e4bf8b13vboxsync * for the given pointer, then that reference's ID is returned instead.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
247b55faa8d054157f2481e68caca36f4dc9542cvboxsync * This gets called from tons of generated code in methodmaps.cpp to
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * resolve objects *returned* from COM methods (i.e. create MOR strings from COM objects
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * which might have been newly created).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync * @param idParent managed object reference of calling object; used to extract session ID
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync * @param pc COM object for which to create a reference
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync * @return existing or new managed object reference
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync */
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsynctemplate <class T>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncconst WSDLT_ID& createOrFindRefFromComPtr(const WSDLT_ID &idParent,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const char *pcszInterface,
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync ComPtr<T> &pc)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // NULL comptr should return NULL MOR
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pc.isNull())
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync WEBDEBUG((" createOrFindRefFromComPtr(): returning empty MOR for NULL COM pointer\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return g_EmptyWSDLID;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
533ffcb943c4af2c5fe6385d816d0ba3eda9383bvboxsync util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
da936e0446fb2b56b813d5d938f1dfc6e4bf8b13vboxsync WebServiceSession *pSession;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ((pSession = WebServiceSession::findSessionFromRef(idParent)))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ManagedObjectRef *pRef;
247b55faa8d054157f2481e68caca36f4dc9542cvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // we need an IUnknown pointer for the MOR
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ComPtr<IUnknown> pobjUnknown = pc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync if ( ((pRef = pSession->findRefFromPtr(pobjUnknown)))
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync || ((pRef = new ManagedObjectRef(*pSession,
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync pobjUnknown, // IUnknown *pobjUnknown
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync pc, // void *pobjInterface
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync COM_IIDOF(T),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pcszInterface)))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync )
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync return pRef->getWSDLID();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // session has expired, return an empty MOR instead of allocating a
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // new reference which couldn't be used anyway.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return g_EmptyWSDLID;
533ffcb943c4af2c5fe6385d816d0ba3eda9383bvboxsync}
533ffcb943c4af2c5fe6385d816d0ba3eda9383bvboxsync