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.

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