Changeset 69729 in vbox for trunk/src/VBox/Main/src-server/win
- Timestamp:
- Nov 17, 2017 7:55:33 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/win/svcmain.cpp
r69500 r69729 138 138 139 139 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 */ 147 class VirtualBoxClassFactory : public ATL::CComClassFactory 148 { 149 private: 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 158 public: 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 177 private: 178 HRESULT VirtualBoxClassFactory::i_registerWithSds(IUnknown **ppOtherVirtualBox); 179 void VirtualBoxClassFactory::i_deregisterWithSds(void); 180 }; 181 182 183 HRESULT VirtualBoxClassFactory::i_registerWithSds(IUnknown **ppOtherVirtualBox) 184 { 185 *ppOtherVirtualBox = NULL; 186 return S_OK; 187 } 188 189 190 void VirtualBoxClassFactory::i_deregisterWithSds(void) 191 { 192 Log(("VirtualBoxClassFactory::i_deregisterWithSds\n")); 193 } 194 195 196 STDMETHODIMP 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 */ 227 STDMETHODIMP 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 140 312 BEGIN_OBJECT_MAP(ObjectMap) 141 313 OBJECT_ENTRY(CLSID_VirtualBox, VirtualBox) … … 146 318 HINSTANCE g_hInstance = NULL; 147 319 #define MAIN_WND_CLASS L"VirtualBox Interface" 320 148 321 149 322 /*
Note:
See TracChangeset
for help on using the changeset viewer.