VirtualBox

Ignore:
Timestamp:
Nov 17, 2017 7:55:33 PM (7 years ago)
Author:
vboxsync
Message:

Main: Outlined a possible plan B for the VBoxSDS stuff.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/win/svcmain.cpp

    r69500 r69729  
    138138
    139139
     140#ifdef VBOX_WITH_SDS_PLAN_B
     141
     142/**
     143 * Custom class factory for the VirtualBox singleton.
     144 *
     145 * The implementation of CreateInstance is found in win/svcmain.cpp.
     146 */
     147class VirtualBoxClassFactory : public ATL::CComClassFactory
     148{
     149private:
     150    /** Tri state: 0=uninitialized or initializing; 1=success; -1=failure.
     151     * This will be updated after both m_hrcCreate and m_pObj have been set. */
     152    volatile int32_t    m_iState;
     153    /** The result of the instantiation attempt. */
     154    HRESULT             m_hrcCreate;
     155    /** The IUnknown of the VirtualBox object/interface we're working with. */
     156    IUnknown           *m_pObj;
     157
     158public:
     159    VirtualBoxClassFactory() : m_iState(0), m_hrcCreate(S_OK), m_pObj(NULL) { }
     160    virtual ~VirtualBoxClassFactory()
     161    {
     162        if (m_pObj)
     163        {
     164            m_pObj->Release();
     165            m_pObj = NULL;
     166        }
     167        /** @todo Need to check if this is okay wrt COM termination. */
     168        i_deregisterWithSds();
     169    }
     170
     171    // IClassFactory
     172    STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, void **ppvObj);
     173
     174    // IVBoxSVC
     175    STDMETHOD(GetVirtualBox)(IUnknown **ppOtherObj);
     176
     177private:
     178    HRESULT VirtualBoxClassFactory::i_registerWithSds(IUnknown **ppOtherVirtualBox);
     179    void    VirtualBoxClassFactory::i_deregisterWithSds(void);
     180};
     181
     182
     183HRESULT VirtualBoxClassFactory::i_registerWithSds(IUnknown **ppOtherVirtualBox)
     184{
     185    *ppOtherVirtualBox = NULL;
     186    return S_OK;
     187}
     188
     189
     190void VirtualBoxClassFactory::i_deregisterWithSds(void)
     191{
     192    Log(("VirtualBoxClassFactory::i_deregisterWithSds\n"));
     193}
     194
     195
     196STDMETHODIMP VirtualBoxClassFactory::GetVirtualBox(IUnknown **ppUnkVirtualBox)
     197{
     198    IUnknown *pObj = m_pObj;
     199    if (pObj)
     200    {
     201        /** @todo Do we need to do something regarding server locking?  Hopefully COM
     202         *        deals with that........... */
     203        pObj->AddRef();
     204        *ppUnkVirtualBox = pObj;
     205        Log(("VirtualBoxClassFactory::GetVirtualBox: S_OK - %p\n", pObj));
     206        return S_OK;
     207    }
     208    *ppUnkVirtualBox = NULL;
     209    Log(("VirtualBoxClassFactory::GetVirtualBox: E_FAIL\n"));
     210    return E_FAIL;
     211}
     212
     213
     214/**
     215 * Custom class factory impl for the VirtualBox singleton.
     216 *
     217 * This will consult with VBoxSDS on whether this VBoxSVC instance should
     218 * provide the actual VirtualBox instance or just forward the instance from
     219 * some other SVC instance.
     220 *
     221 * @param   pUnkOuter       This must be NULL.
     222 * @param   riid            Reference to the interface ID to provide.
     223 * @param   ppvObj          Where to return the pointer to the riid instance.
     224 *
     225 * @return  COM status code.
     226 */
     227STDMETHODIMP VirtualBoxClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void **ppvObj)
     228{
     229    HRESULT hrc = E_POINTER;
     230    if (ppvObj != NULL)
     231    {
     232        *ppvObj = NULL;
     233        // no aggregation for singletons
     234        AssertReturn(pUnkOuter == NULL, CLASS_E_NOAGGREGATION);
     235
     236        /*
     237         * We must make sure there is only one instance around.
     238         * So, we check without locking and then again after locking.
     239         */
     240        if (ASMAtomicReadS32(&m_iState) == 0)
     241        {
     242            Lock();
     243            __try
     244            {
     245                if (ASMAtomicReadS32(&m_iState) == 0)
     246                {
     247                    /*
     248                     * lock the module to indicate activity
     249                     * (necessary for the monitor shutdown thread to correctly
     250                     * terminate the module in case when CreateInstance() fails)
     251                     */
     252                    ATL::_pAtlModule->Lock();
     253                    __try
     254                    {
     255                        /*
     256                         * Now we need to connect to VBoxSDS to register ourselves.
     257                         */
     258                        IUnknown *pOtherVirtualBox = NULL;
     259                        m_hrcCreate = hrc = i_registerWithSds(&pOtherVirtualBox);
     260                        if (SUCCEEDED(hrc) && pOtherVirtualBox)
     261                            m_pObj = pOtherVirtualBox;
     262                        else if (SUCCEEDED(hrc))
     263                        {
     264                            ATL::_pAtlModule->Lock();
     265                            ATL::CComObjectCached<VirtualBox> *p;
     266                            m_hrcCreate = hrc = ATL::CComObjectCached<VirtualBox>::CreateInstance(&p);
     267                            if (SUCCEEDED(hrc))
     268                            {
     269                                m_hrcCreate = hrc = p->QueryInterface(IID_IUnknown, (void **)&m_pObj);
     270                                if (FAILED(hrc))
     271                                {
     272                                    delete p;
     273                                    i_deregisterWithSds();
     274                                    m_pObj = NULL;
     275                                }
     276                            }
     277                        }
     278                        ASMAtomicWriteS32(&m_iState, SUCCEEDED(hrc) ? 1 : -1);
     279                    }
     280                    __finally
     281                    {
     282                        ATL::_pAtlModule->Unlock();
     283                    }
     284                }
     285            }
     286            __finally
     287            {
     288                if (ASMAtomicReadS32(&m_iState) == 0)
     289                {
     290                    ASMAtomicWriteS32(&m_iState, -1);
     291                    if (SUCCEEDED(m_hrcCreate))
     292                        m_hrcCreate = E_FAIL;
     293                }
     294                Unlock();
     295            }
     296        }
     297
     298        /*
     299         * Query the requested interface from the IUnknown one we're keeping around.
     300         */
     301        if (m_hrcCreate == S_OK)
     302            hrc = m_pObj->QueryInterface(riid, ppvObj);
     303        else
     304            hrc = m_hrcCreate;
     305    }
     306    return hrc;
     307}
     308
     309#endif /* VBOX_WITH_SDS_PLAN_B */
     310
     311
    140312BEGIN_OBJECT_MAP(ObjectMap)
    141313    OBJECT_ENTRY(CLSID_VirtualBox, VirtualBox)
     
    146318HINSTANCE g_hInstance = NULL;
    147319#define MAIN_WND_CLASS L"VirtualBox Interface"
     320
    148321
    149322/*
Note: See TracChangeset for help on using the changeset viewer.

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