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.

181 lines
5.3 KiB

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