Source code of Windows XP (NT5)
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.

147 lines
3.0 KiB

  1. #include "shole.h"
  2. #include "ids.h"
  3. #include "scguid.h"
  4. #define DECL_CRTFREE
  5. #include <crtfree.h>
  6. LONG g_cRefThisDll = 0; // per-instance
  7. STDAPI_(void) DllAddRef(void)
  8. {
  9. InterlockedIncrement(&g_cRefThisDll);
  10. }
  11. STDAPI_(void) DllRelease(void)
  12. {
  13. InterlockedDecrement(&g_cRefThisDll);
  14. }
  15. class CMyClassFactory : public IClassFactory
  16. {
  17. public:
  18. CMyClassFactory(REFCLSID rclsid);
  19. ~CMyClassFactory() { DllRelease(); }
  20. // IUnKnown
  21. virtual HRESULT __stdcall QueryInterface(REFIID,void **);
  22. virtual ULONG __stdcall AddRef(void);
  23. virtual ULONG __stdcall Release(void);
  24. // IClassFactory
  25. virtual HRESULT __stdcall CreateInstance(
  26. IUnknown *pUnkOuter, REFIID riid, void **ppvObject);
  27. virtual HRESULT __stdcall LockServer(BOOL fLock);
  28. protected:
  29. UINT _cRef;
  30. CLSID _clsid;
  31. };
  32. CMyClassFactory::CMyClassFactory(REFCLSID rclsid) : _cRef(1), _clsid(rclsid)
  33. {
  34. DllAddRef();
  35. }
  36. HRESULT CMyClassFactory::QueryInterface(REFIID riid, void **ppvObject)
  37. {
  38. HRESULT hres;
  39. if (IsEqualGUID(riid, IID_IClassFactory) || IsEqualGUID(riid, IID_IUnknown)) {
  40. _cRef++;
  41. *ppvObject = (LPCLASSFACTORY)this;
  42. hres = NOERROR;
  43. }
  44. else
  45. {
  46. *ppvObject = NULL;
  47. hres = ResultFromScode(E_NOINTERFACE);
  48. }
  49. return hres;
  50. }
  51. ULONG CMyClassFactory::AddRef(void)
  52. {
  53. return ++_cRef;
  54. }
  55. ULONG CMyClassFactory::Release(void)
  56. {
  57. if (--_cRef>0) {
  58. return _cRef;
  59. }
  60. delete this;
  61. return 0;
  62. }
  63. HRESULT CMyClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
  64. {
  65. if (pUnkOuter)
  66. return CLASS_E_NOAGGREGATION;
  67. LPUNKNOWN punk;
  68. HRESULT hres;
  69. if (IsEqualGUID(_clsid, CLSID_CScrapData))
  70. {
  71. hres = CScrapData_CreateInstance(&punk);
  72. }
  73. #ifdef FEATURE_SHELLEXTENSION
  74. else if (IsEqualGUID(_clsid, CLSID_CTemplateFolder))
  75. {
  76. hres = CTemplateFolder_CreateInstance(&punk);
  77. }
  78. else if (IsEqualGUID(_clsid, CLSID_CScrapExt))
  79. {
  80. hres = CScrapExt_CreateInstance(&punk);
  81. }
  82. #endif
  83. else
  84. {
  85. return E_UNEXPECTED;
  86. }
  87. if (SUCCEEDED(hres))
  88. {
  89. hres = punk->QueryInterface(riid, ppvObject);
  90. punk->Release();
  91. }
  92. return hres;
  93. }
  94. HRESULT CMyClassFactory::LockServer(BOOL fLock)
  95. {
  96. return S_OK;
  97. }
  98. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppvOut)
  99. {
  100. if (IsEqualGUID(rclsid,CLSID_CScrapData)
  101. #ifdef FEATURE_SHELLEXTENSION
  102. || IsEqualGUID(rclsid,CLSID_CTemplateFolder)
  103. || IsEqualGUID(rclsid,CLSID_CScrapExt)
  104. #endif
  105. )
  106. {
  107. CMyClassFactory *pmycls = new CMyClassFactory(rclsid);
  108. if (pmycls)
  109. {
  110. HRESULT hres = pmycls->QueryInterface(riid, ppvOut);
  111. pmycls->Release();
  112. return hres;
  113. }
  114. return E_OUTOFMEMORY;
  115. }
  116. return CLASS_E_CLASSNOTAVAILABLE;
  117. }
  118. STDAPI DllCanUnloadNow(void)
  119. {
  120. if (g_cRefThisDll)
  121. {
  122. return S_FALSE;
  123. }
  124. DebugMsg(DM_TRACE, TEXT("sc TR - DllCanUnloadNow returning S_OK (bye, bye...)"));
  125. return S_OK;
  126. }