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.

203 lines
5.4 KiB

  1. /*****************************************************************************
  2. *
  3. * ftpcf.cpp - IClassFactory interface
  4. *
  5. *****************************************************************************/
  6. #include "priv.h"
  7. #include "ftpwebvw.h"
  8. #include "msieftp.h"
  9. // msieftp.dll is unexpectedly getting unloaded and I believe the cause is defview not obaying threading rules.
  10. // Therefore I hold an extra ref to keep our instance in process. This will not be an issue since the amount
  11. // of global state msieftp uses in a process is very small. The problem comes from shell32!CCallBack::CallCB(),
  12. // which is called by CDefView::OnDeactivate.
  13. HINSTANCE g_hInstanceThisLeak = NULL;
  14. /*****************************************************************************
  15. *
  16. * CFtpFactory
  17. *
  18. *
  19. *****************************************************************************/
  20. class CFtpFactory : public IClassFactory
  21. {
  22. public:
  23. //////////////////////////////////////////////////////
  24. // Public Interfaces
  25. //////////////////////////////////////////////////////
  26. // *** IUnknown ***
  27. virtual STDMETHODIMP_(ULONG) AddRef(void);
  28. virtual STDMETHODIMP_(ULONG) Release(void);
  29. virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
  30. // *** IClassFactory ***
  31. virtual STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject);
  32. virtual STDMETHODIMP LockServer(BOOL fLock);
  33. public:
  34. CFtpFactory(REFCLSID rclsid);
  35. ~CFtpFactory(void);
  36. // Friend Functions
  37. friend HRESULT CFtpFactory_Create(REFCLSID rclsid, REFIID riid, LPVOID * ppvObj);
  38. protected:
  39. int m_cRef;
  40. CLSID m_rclsid;
  41. };
  42. /*****************************************************************************
  43. * IClassFactory::CreateInstance
  44. *****************************************************************************/
  45. HRESULT CFtpFactory::CreateInstance(IUnknown * punkOuter, REFIID riid, LPVOID * ppvObj)
  46. {
  47. HRESULT hres = ResultFromScode(REGDB_E_CLASSNOTREG);
  48. if (!g_hInstanceThisLeak)
  49. {
  50. g_hInstanceThisLeak = LoadLibrary(TEXT("msieftp.dll"));
  51. }
  52. if (!punkOuter)
  53. {
  54. if (IsEqualIID(m_rclsid, CLSID_FtpFolder))
  55. hres = CFtpFolder_Create(riid, ppvObj);
  56. else if (IsEqualIID(m_rclsid, CLSID_FtpWebView))
  57. hres = CFtpWebView_Create(riid, ppvObj);
  58. else if (IsEqualIID(m_rclsid, CLSID_FtpInstaller))
  59. hres = CFtpInstaller_Create(riid, ppvObj);
  60. else if (IsEqualIID(m_rclsid, CLSID_FtpDataObject))
  61. hres = CFtpObj_Create(riid, ppvObj);
  62. else
  63. ASSERT(0); // What are you looking for?
  64. }
  65. else
  66. { // Does anybody support aggregation any more?
  67. hres = ResultFromScode(CLASS_E_NOAGGREGATION);
  68. }
  69. if (FAILED(hres) && ppvObj)
  70. {
  71. *ppvObj = NULL; // Be Robust. NT #355186
  72. }
  73. return hres;
  74. }
  75. /*****************************************************************************
  76. *
  77. * IClassFactory::LockServer
  78. *
  79. * Locking the server is identical to
  80. * creating an object and not releasing it until you want to unlock
  81. * the server.
  82. *
  83. *****************************************************************************/
  84. HRESULT CFtpFactory::LockServer(BOOL fLock)
  85. {
  86. if (fLock)
  87. DllAddRef();
  88. else
  89. DllRelease();
  90. return S_OK;
  91. }
  92. /*****************************************************************************
  93. *
  94. * CFtpFactory_Create
  95. *
  96. *****************************************************************************/
  97. HRESULT CFtpFactory_Create(REFCLSID rclsid, REFIID riid, LPVOID * ppvObj)
  98. {
  99. HRESULT hres;
  100. if (GetShdocvwVersion() < 5)
  101. {
  102. // Check if we are running under older IE's and fail so that
  103. // side by side IE4, IE5 can work
  104. hres = ResultFromScode(E_NOINTERFACE);
  105. }
  106. else if (IsEqualIID(riid, IID_IClassFactory))
  107. {
  108. *ppvObj = (LPVOID) new CFtpFactory(rclsid);
  109. hres = (*ppvObj) ? S_OK : E_OUTOFMEMORY;
  110. }
  111. else
  112. hres = ResultFromScode(E_NOINTERFACE);
  113. return hres;
  114. }
  115. /****************************************************\
  116. Constructor
  117. \****************************************************/
  118. CFtpFactory::CFtpFactory(REFCLSID rclsid) : m_cRef(1)
  119. {
  120. m_rclsid = rclsid;
  121. DllAddRef();
  122. LEAK_ADDREF(LEAK_CFtpFactory);
  123. }
  124. /****************************************************\
  125. Destructor
  126. \****************************************************/
  127. CFtpFactory::~CFtpFactory()
  128. {
  129. DllRelease();
  130. LEAK_DELREF(LEAK_CFtpFactory);
  131. }
  132. //===========================
  133. // *** IUnknown Interface ***
  134. //===========================
  135. ULONG CFtpFactory::AddRef()
  136. {
  137. m_cRef++;
  138. return m_cRef;
  139. }
  140. ULONG CFtpFactory::Release()
  141. {
  142. ASSERT(m_cRef > 0);
  143. m_cRef--;
  144. if (m_cRef > 0)
  145. return m_cRef;
  146. delete this;
  147. return 0;
  148. }
  149. HRESULT CFtpFactory::QueryInterface(REFIID riid, void **ppvObj)
  150. {
  151. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
  152. {
  153. *ppvObj = SAFECAST(this, IClassFactory *);
  154. }
  155. else
  156. {
  157. TraceMsg(TF_FTPQI, "CFtpFactory::QueryInterface() failed.");
  158. *ppvObj = NULL;
  159. return E_NOINTERFACE;
  160. }
  161. AddRef();
  162. return S_OK;
  163. }