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.

120 lines
2.4 KiB

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