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.

146 lines
3.2 KiB

  1. #ifndef _UNK_H_
  2. #define _UNK_H_
  3. #include <objbase.h>
  4. typedef void (*COMFACTORYCB)(BOOL fIncrement);
  5. class CCOMBase
  6. {
  7. public:
  8. virtual HRESULT UnkInit() { return S_OK; }
  9. };
  10. struct INTFMAPENTRY
  11. {
  12. const IID* piid;
  13. DWORD dwOffset;
  14. };
  15. template <class CCOMBASE>
  16. class CUnkTmpl : public CCOMBASE
  17. {
  18. public:
  19. CUnkTmpl(IUnknown*) : _cRef(1) {}
  20. ~CUnkTmpl() { if (_cfcb) { _cfcb(FALSE); } }
  21. STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
  22. {
  23. HRESULT hres;
  24. if (IID_IUnknown == riid)
  25. {
  26. IUnknown* punk;
  27. *ppv = (IUnknown*)(((PBYTE)this) + _pintfmap[0].dwOffset);
  28. punk = (IUnknown*)(*ppv);
  29. punk->AddRef();
  30. hres = S_OK;
  31. }
  32. else
  33. {
  34. hres = _GetInterfaceFromMap(riid, ppv);
  35. }
  36. return hres;
  37. }
  38. STDMETHODIMP_(ULONG) AddRef() { return ::InterlockedIncrement(&_cRef); }
  39. STDMETHODIMP_(ULONG) Release()
  40. {
  41. #if DBG==1
  42. if ( 0 == _cRef )
  43. {
  44. DebugBreak( ); // ref counter problem
  45. }
  46. #endif
  47. ULONG cRef = ::InterlockedDecrement(&_cRef);
  48. if (!cRef)
  49. {
  50. delete this;
  51. }
  52. return cRef;
  53. }
  54. protected:
  55. HRESULT _GetInterfaceFromMap(REFIID riid, void** ppv)
  56. {
  57. HRESULT hres = E_NOINTERFACE;
  58. for (DWORD dw = 0; dw < _cintfmap; ++dw)
  59. {
  60. if (riid == *(_pintfmap[dw].piid))
  61. {
  62. IUnknown* punk = (IUnknown*)(((PBYTE)this) +
  63. _pintfmap[dw].dwOffset);
  64. punk->AddRef();
  65. *ppv = punk;
  66. hres = S_OK;
  67. break;
  68. }
  69. }
  70. return hres;
  71. }
  72. public:
  73. static HRESULT UnkCreateInstance(COMFACTORYCB cfcb,
  74. IUnknown* pUnknownOuter, IUnknown** ppunkNew)
  75. {
  76. HRESULT hres = E_OUTOFMEMORY;
  77. if (!_cfcb)
  78. {
  79. _cfcb = cfcb;
  80. }
  81. CUnkTmpl<CCOMBASE>* pNew = new CUnkTmpl<CCOMBASE>(pUnknownOuter);
  82. if (pNew)
  83. {
  84. hres = pNew->UnkInit();
  85. if (FAILED(hres))
  86. {
  87. delete pNew;
  88. }
  89. else
  90. {
  91. *ppunkNew = (IUnknown*)(((PBYTE)pNew) +
  92. pNew->_pintfmap[0].dwOffset);
  93. }
  94. }
  95. return hres;
  96. }
  97. private:
  98. LONG _cRef;
  99. static COMFACTORYCB _cfcb;
  100. static const INTFMAPENTRY* _pintfmap;
  101. static const DWORD _cintfmap;
  102. };
  103. // for now: begin
  104. #ifndef OFFSETOFCLASS
  105. //*** OFFSETOFCLASS -- (stolen from ATL)
  106. // we use STATIC_CAST not SAFE_CAST because the compiler gets confused
  107. // (it doesn't constant-fold the ,-op in SAFE_CAST so we end up generating
  108. // code for the table!)
  109. #define OFFSETOFCLASS(base, derived) \
  110. ((DWORD)(DWORD_PTR)(static_cast<base*>((derived*)8))-8)
  111. #endif
  112. // for now: end
  113. #define _INTFMAPENTRY(Cthis, Ifoo) \
  114. { (IID*) &IID_##Ifoo, OFFSETOFCLASS(Ifoo, Cthis) }
  115. #define _INTFMAPENTRY2(Cthis, Ifoo, Iimpl) \
  116. { (IID*) &IID_##Ifoo, OFFSETOFCLASS(Iimpl, Cthis) }
  117. #endif // _UNK_H_