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.

156 lines
3.2 KiB

  1. #ifndef _COMBASE_HPP
  2. #define _COMBASE_HPP
  3. //
  4. // Macros for incrementing or decrementing global component count
  5. //
  6. extern HINSTANCE globalInstanceHandle;
  7. extern LONG globalComponentCount;
  8. #define IncrementGlobalComponentCount() \
  9. InterlockedIncrement(&globalComponentCount)
  10. #define DecrementGlobalComponentCount() \
  11. InterlockedDecrement(&globalComponentCount)
  12. //
  13. // Template for implementing IUnknown interface
  14. //
  15. // NOTES:
  16. // 1. We can only handle objects that one interface other than IUnknown.
  17. // 2. We do not support aggregation.
  18. //
  19. template <class I> class IUnknownBase : public I
  20. {
  21. public:
  22. // Constructor: notice that when an object is first
  23. // created, its reference count is set to 1.
  24. IUnknownBase<I>()
  25. {
  26. refCount = 1;
  27. }
  28. // Query interface: note that we can only handle
  29. // objects that one interface other than IUnknown.
  30. STDMETHOD(QueryInterface)(REFIID riid, VOID** ppv)
  31. {
  32. if (riid == IID_IUnknown)
  33. *ppv = static_cast<IUnknown*>(this);
  34. else if (riid == __uuidof(I))
  35. *ppv = static_cast<I*>(this);
  36. else
  37. {
  38. *ppv = NULL;
  39. return E_NOINTERFACE;
  40. }
  41. reinterpret_cast<IUnknown*>(*ppv)->AddRef();
  42. return S_OK;
  43. }
  44. // Increment reference count
  45. STDMETHOD_(ULONG, AddRef)(VOID)
  46. {
  47. return InterlockedIncrement(&refCount);
  48. }
  49. // Decrement reference count
  50. STDMETHOD_(ULONG, Release)(VOID)
  51. {
  52. ULONG count = InterlockedDecrement(&refCount);
  53. if (count == 0)
  54. delete this;
  55. return count;
  56. }
  57. private:
  58. LONG refCount;
  59. };
  60. //
  61. // Template for implementing IClassFactory interface
  62. //
  63. template <class T> class IFactoryBase
  64. : public IUnknownBase<IClassFactory>
  65. {
  66. public:
  67. // NOTE: We don't count class factory objects in globalComponentCount.
  68. // This means that the existence of a running class factory is not
  69. // guaranteed to keep a server loaded in memory.
  70. // Create a new instance of the component
  71. STDMETHOD(CreateInstance)(IUnknown* outer, REFIID riid, VOID** ppv)
  72. {
  73. // We don't support aggregation
  74. if (outer != NULL)
  75. return CLASS_E_NOAGGREGATION;
  76. // Instantiate a new object
  77. T* obj = new T;
  78. if (obj == NULL)
  79. return E_OUTOFMEMORY;
  80. // Get the requested interface
  81. HRESULT hr = obj->QueryInterface(riid, ppv);
  82. obj->Release();
  83. return hr;
  84. }
  85. // Lock/unlock the component server DLL
  86. STDMETHOD(LockServer)(BOOL lock)
  87. {
  88. if (lock)
  89. {
  90. IncrementGlobalComponentCount();
  91. }
  92. else
  93. {
  94. DecrementGlobalComponentCount();
  95. }
  96. return S_OK;
  97. }
  98. };
  99. //
  100. // Helper function for registering and unregistering a component
  101. //
  102. struct ComponentRegData
  103. {
  104. const CLSID* clsid;
  105. const WCHAR* compName;
  106. const WCHAR* progID;
  107. const WCHAR* progIDNoVer;
  108. };
  109. HRESULT
  110. RegisterComponent(
  111. const ComponentRegData& regdata,
  112. BOOL registerIt
  113. );
  114. #endif // !_COMBASE_HPP