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.

215 lines
6.9 KiB

  1. // --------------------------------------------------------------------------------
  2. // FACTORY.CPP
  3. // Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  4. // --------------------------------------------------------------------------------
  5. #include "pch.hxx"
  6. #include "factory.h"
  7. #include "instance.h"
  8. #include "header.h"
  9. #include "ourguid.h"
  10. #include "msgtable.h"
  11. #include "envguid.h"
  12. #include "istore.h"
  13. #include "store.h"
  14. #include "note.h"
  15. #include "msoeobj.h"
  16. #include "..\imap\imapsync.h"
  17. #include "newsstor.h"
  18. #include "msgfldr.h"
  19. #include "store.h"
  20. #include "..\http\httpserv.h"
  21. #include <storsync.h>
  22. #include <ruleutil.h>
  23. #ifdef OE_MOM
  24. #include "..\om\session.h"
  25. #include "..\om\table.h"
  26. #endif
  27. // --------------------------------------------------------------------------------
  28. // Pretty
  29. // --------------------------------------------------------------------------------
  30. #define OBJTYPE0 0
  31. #define OBJTYPE1 OIF_ALLOWAGGREGATION
  32. //HRESULT CreateInstance_StoreNamespace(IUnknown *pUnkOuter, IUnknown **ppUnknown);
  33. // --------------------------------------------------------------------------------
  34. // Global Object Info Table
  35. // --------------------------------------------------------------------------------
  36. #define PFCI(_pfn) ((PFCREATEINSTANCE)_pfn)
  37. static CClassFactory g_rgFactory[] = {
  38. CClassFactory(&CLSID_MessageStore, OBJTYPE0, PFCI(CreateMessageStore)),
  39. CClassFactory(&CLSID_MigrateMessageStore, OBJTYPE0, PFCI(CreateMigrateMessageStore)),
  40. CClassFactory(&CLSID_StoreNamespace, OBJTYPE0, PFCI(CreateInstance_StoreNamespace)),
  41. CClassFactory(&CLSID_OEEnvelope, OBJTYPE0, PFCI(CreateInstance_Envelope)),
  42. CClassFactory(&CLSID_OENote, OBJTYPE0, PFCI(CreateOENote)),
  43. CClassFactory(&CLSID_MessageDatabase, OBJTYPE0, PFCI(CreateMsgDbExtension)),
  44. CClassFactory(&CLSID_FolderDatabase, OBJTYPE0, PFCI(CreateFolderDatabaseExt)),
  45. #ifdef OE_MOM
  46. CClassFactory(&CLSID_OESession, OBJTYPE1, PFCI(CreateInstance_OESession)),
  47. CClassFactory(&CLSID_OEMsgTable, OBJTYPE1, PFCI(CreateInstance_OEMsgTable)),
  48. #endif
  49. CClassFactory(&CLSID_OERulesManager, OBJTYPE0, PFCI(HrCreateRulesManager)),
  50. };
  51. // --------------------------------------------------------------------------------
  52. // DllGetClassObject
  53. // --------------------------------------------------------------------------------
  54. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
  55. {
  56. // Locals
  57. HRESULT hr=S_OK;
  58. ULONG i;
  59. // Trace
  60. TraceCall("DllGetClassObject");
  61. // Bad param
  62. if (ppv == NULL)
  63. {
  64. hr = TraceResult(E_INVALIDARG);
  65. goto exit;
  66. }
  67. // Find Object Class
  68. for (i=0; i<ARRAYSIZE(g_rgFactory); i++)
  69. {
  70. // Compare for clsids
  71. if (IsEqualCLSID(rclsid, *g_rgFactory[i].m_pclsid))
  72. {
  73. // Delegate to the factory
  74. IF_FAILEXIT(hr = g_rgFactory[i].QueryInterface(riid, ppv));
  75. // Done
  76. goto exit;
  77. }
  78. }
  79. // Otherwise, let the ATL creator have a shot
  80. if (SUCCEEDED(hr = _Module.GetClassObject(rclsid, riid, ppv)))
  81. goto exit;
  82. // Otherwise, no class
  83. hr = TraceResult(CLASS_E_CLASSNOTAVAILABLE);
  84. exit:
  85. // Done
  86. return hr;
  87. }
  88. // --------------------------------------------------------------------------------
  89. // CClassFactory::CClassFactory
  90. // --------------------------------------------------------------------------------
  91. CClassFactory::CClassFactory(CLSID const *pclsid, DWORD dwFlags, PFCREATEINSTANCE pfCreateInstance)
  92. : m_pclsid(pclsid), m_dwFlags(dwFlags), m_pfCreateInstance(pfCreateInstance)
  93. {
  94. }
  95. // --------------------------------------------------------------------------------
  96. // CClassFactory::QueryInterface
  97. // --------------------------------------------------------------------------------
  98. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, void **ppvObj)
  99. {
  100. // TraceCall
  101. TraceCall("CClassFactory::QueryInterface");
  102. // Invalid Arg
  103. if (NULL == ppvObj)
  104. return TraceResult(E_INVALIDARG);
  105. // IClassFactory or IUnknown
  106. if (!IsEqualIID(riid, IID_IClassFactory) && !IsEqualIID(riid, IID_IUnknown))
  107. return TraceResult(E_INVALIDARG);
  108. // Return the Class Facotry
  109. *ppvObj = (LPVOID)this;
  110. // Add Ref the dll
  111. g_pInstance->DllAddRef();
  112. // Done
  113. return S_OK;
  114. }
  115. // --------------------------------------------------------------------------------
  116. // CClassFactory::AddRef
  117. // --------------------------------------------------------------------------------
  118. STDMETHODIMP_(ULONG) CClassFactory::AddRef(void)
  119. {
  120. g_pInstance->DllAddRef();
  121. return 2;
  122. }
  123. // --------------------------------------------------------------------------------
  124. // CClassFactory::Release
  125. // --------------------------------------------------------------------------------
  126. STDMETHODIMP_(ULONG) CClassFactory::Release(void)
  127. {
  128. g_pInstance->DllRelease();
  129. return 1;
  130. }
  131. // --------------------------------------------------------------------------------
  132. // CClassFactory::CreateInstance
  133. // --------------------------------------------------------------------------------
  134. STDMETHODIMP CClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObj)
  135. {
  136. // Locals
  137. HRESULT hr=S_OK;
  138. IUnknown *pObject=NULL;
  139. // Trace
  140. TraceCall("CClassFactory::CreateInstance");
  141. // Bad param
  142. if (ppvObj == NULL)
  143. return TraceResult(E_INVALIDARG);
  144. // Init
  145. *ppvObj = NULL;
  146. // Verify that a controlling unknown asks for IUnknown
  147. if (NULL != pUnkOuter && IID_IUnknown != riid)
  148. return TraceResult(CLASS_E_NOAGGREGATION);
  149. // Can I do aggregaton
  150. if (pUnkOuter !=NULL && !(m_dwFlags & OIF_ALLOWAGGREGATION))
  151. return TraceResult(CLASS_E_NOAGGREGATION);
  152. // Create the object...
  153. CHECKHR(hr = (*m_pfCreateInstance)(pUnkOuter, &pObject));
  154. // Aggregated, then we know we're looking for an IUnknown, return pObject, otherwise, QI
  155. if (pUnkOuter)
  156. {
  157. // Matches Release after Exit
  158. pObject->AddRef();
  159. // Return pObject::IUnknown
  160. *ppvObj = (LPVOID)pObject;
  161. }
  162. // Otherwise
  163. else
  164. {
  165. // Get the interface requested from pObj
  166. IF_FAILEXIT(hr = pObject->QueryInterface(riid, ppvObj));
  167. }
  168. exit:
  169. // Cleanup
  170. SafeRelease(pObject);
  171. // Done
  172. Assert(FAILED(hr) ? NULL == *ppvObj : TRUE);
  173. return hr;
  174. }
  175. // --------------------------------------------------------------------------------
  176. // CClassFactory::LockServer
  177. // --------------------------------------------------------------------------------
  178. STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
  179. {
  180. return g_pInstance->LockServer(fLock);
  181. }