Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
6.1 KiB

  1. // --------------------------------------------------------------------------------
  2. // Factory.cpp
  3. // Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  4. // Steven J. Bailey
  5. // --------------------------------------------------------------------------------
  6. #include "pch.hxx"
  7. #include "dllmain.h"
  8. #include "factory.h"
  9. #include "msoert.h"
  10. #include "mimeole.h"
  11. #include "envhost.h"
  12. // --------------------------------------------------------------------------------
  13. // Pretty
  14. // --------------------------------------------------------------------------------
  15. #define OBJTYPE0 0
  16. #define OBJTYPE1 OIF_ALLOWAGGREGATION
  17. // --------------------------------------------------------------------------------
  18. // Global Object Info Table
  19. // --------------------------------------------------------------------------------
  20. static CClassFactory g_rgFactory[] = {
  21. CClassFactory(&CLSID_GWEnvelopeHost, OBJTYPE0, (PFCREATEINSTANCE)GWNote_CreateInstance)
  22. };
  23. // --------------------------------------------------------------------------------
  24. // DllGetClassObject
  25. // --------------------------------------------------------------------------------
  26. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
  27. {
  28. // Locals
  29. HRESULT hr=S_OK;
  30. ULONG i;
  31. // Bad param
  32. if (ppv == NULL)
  33. {
  34. hr = TrapError(E_INVALIDARG);
  35. goto exit;
  36. }
  37. // No memory allocator
  38. if (NULL == g_pMalloc)
  39. {
  40. hr = TrapError(E_OUTOFMEMORY);
  41. goto exit;
  42. }
  43. // Find Object Class
  44. for (i=0; i<ARRAYSIZE(g_rgFactory); i++)
  45. {
  46. // Compare for clsids
  47. if (IsEqualCLSID(rclsid, *g_rgFactory[i].m_pclsid))
  48. {
  49. // Delegate to the factory
  50. CHECKHR(hr = g_rgFactory[i].QueryInterface(riid, ppv));
  51. // Done
  52. goto exit;
  53. }
  54. }
  55. // Otherwise, no class
  56. hr = TrapError(CLASS_E_CLASSNOTAVAILABLE);
  57. exit:
  58. // Done
  59. return hr;
  60. }
  61. // --------------------------------------------------------------------------------
  62. // CClassFactory::CClassFactory
  63. // --------------------------------------------------------------------------------
  64. CClassFactory::CClassFactory(CLSID const *pclsid, DWORD dwFlags, PFCREATEINSTANCE pfCreateInstance)
  65. : m_pclsid(pclsid), m_dwFlags(dwFlags), m_pfCreateInstance(pfCreateInstance)
  66. {
  67. }
  68. // --------------------------------------------------------------------------------
  69. // CClassFactory::QueryInterface
  70. // --------------------------------------------------------------------------------
  71. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, void **ppvObj)
  72. {
  73. // Invalid Arg
  74. if (NULL == ppvObj)
  75. return TrapError(E_INVALIDARG);
  76. // IClassFactory or IUnknown
  77. if (!IsEqualIID(riid, IID_IClassFactory) && !IsEqualIID(riid, IID_IUnknown))
  78. return TrapError(E_NOINTERFACE);
  79. // Return the Class Facotry
  80. *ppvObj = (LPVOID)this;
  81. // Add Ref the dll
  82. DllAddRef();
  83. // Done
  84. return S_OK;
  85. }
  86. // --------------------------------------------------------------------------------
  87. // CClassFactory::AddRef
  88. // --------------------------------------------------------------------------------
  89. STDMETHODIMP_(ULONG) CClassFactory::AddRef(void)
  90. {
  91. DllAddRef();
  92. return 2;
  93. }
  94. // --------------------------------------------------------------------------------
  95. // CClassFactory::Release
  96. // --------------------------------------------------------------------------------
  97. STDMETHODIMP_(ULONG) CClassFactory::Release(void)
  98. {
  99. DllRelease();
  100. return 1;
  101. }
  102. // --------------------------------------------------------------------------------
  103. // CClassFactory::CreateInstance
  104. // --------------------------------------------------------------------------------
  105. STDMETHODIMP CClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObj)
  106. {
  107. // Locals
  108. HRESULT hr=S_OK;
  109. IUnknown *pObject=NULL;
  110. // Bad param
  111. if (ppvObj == NULL)
  112. return TrapError(E_INVALIDARG);
  113. // Init
  114. *ppvObj = NULL;
  115. // Verify that a controlling unknown asks for IUnknown
  116. if (NULL != pUnkOuter && IID_IUnknown != riid)
  117. return TrapError(CLASS_E_NOAGGREGATION);
  118. // No memory allocator
  119. if (NULL == g_pMalloc)
  120. return TrapError(E_OUTOFMEMORY);
  121. // Can I do aggregaton
  122. if (pUnkOuter !=NULL && !(m_dwFlags & OIF_ALLOWAGGREGATION))
  123. return TrapError(CLASS_E_NOAGGREGATION);
  124. // Create the object...
  125. CHECKHR(hr = CreateObjectInstance(pUnkOuter, &pObject));
  126. // Aggregated, then we know we're looking for an IUnknown, return pObject, otherwise, QI
  127. if (pUnkOuter)
  128. {
  129. // Matches Release after Exit
  130. pObject->AddRef();
  131. // Return pObject::IUnknown
  132. *ppvObj = (LPVOID)pObject;
  133. }
  134. // Otherwise
  135. else
  136. {
  137. // Get the interface requested from pObj
  138. CHECKHR(hr = pObject->QueryInterface(riid, ppvObj));
  139. }
  140. exit:
  141. // Cleanup
  142. SafeRelease(pObject);
  143. // Done
  144. Assert(FAILED(hr) ? NULL == *ppvObj : TRUE);
  145. return hr;
  146. }
  147. // --------------------------------------------------------------------------------
  148. // CClassFactory::LockServer
  149. // --------------------------------------------------------------------------------
  150. STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
  151. {
  152. if (fLock) InterlockedIncrement(&g_cLock);
  153. else InterlockedDecrement(&g_cLock);
  154. return NOERROR;
  155. }
  156. // --------------------------------------------------------------------------------
  157. // GWNote_CreateInstance
  158. // --------------------------------------------------------------------------------
  159. HRESULT GWNote_CreateInstance(IUnknown* pUnkOuter, IUnknown** ppUnknown)
  160. {
  161. // Invalid Arg
  162. Assert(ppUnknown);
  163. // Initialize
  164. *ppUnknown = NULL;
  165. // Create me
  166. CEnvHost *pNew= new CEnvHost(pUnkOuter);
  167. if (NULL == pNew)
  168. return (E_OUTOFMEMORY);
  169. // Cast to unknown
  170. *ppUnknown = SAFECAST(pNew, IMsoEnvelopeHost *);
  171. // Done
  172. return S_OK;
  173. }