stdunk.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. ReactOS Kernel-Mode COM
  3. IUnknown implementations
  4. This file is in the public domain.
  5. AUTHORS
  6. Andrew Greenwood
  7. */
  8. #ifndef STDUNK_H
  9. #define STDUNK_H
  10. #include <punknown.h>
  11. /* ===============================================================
  12. INonDelegatingUnknown interface
  13. */
  14. DECLARE_INTERFACE(INonDelegatingUnknown)
  15. {
  16. STDMETHOD_(NTSTATUS, NonDelegatingQueryInterface)( THIS_
  17. IN REFIID,
  18. OUT PVOID*) PURE;
  19. STDMETHOD_(ULONG, NonDelegatingAddRef)( THIS ) PURE;
  20. STDMETHOD_(ULONG, NonDelegatingRelease)( THIS ) PURE;
  21. };
  22. typedef INonDelegatingUnknown *PNONDELEGATINGUNKNOWN;
  23. /* ===============================================================
  24. CUnknown declaration / definition
  25. There are 2 variants for this, and I'm not sure if the C
  26. version is correct.
  27. */
  28. #ifdef __cplusplus
  29. class CUnknown : public INonDelegatingUnknown
  30. {
  31. private :
  32. LONG m_ref_count;
  33. PUNKNOWN m_outer_unknown;
  34. public :
  35. /* CUnknown */
  36. CUnknown(PUNKNOWN pUnknownOuter);
  37. virtual ~CUnknown();
  38. PUNKNOWN GetOuterUnknown()
  39. { return m_outer_unknown; }
  40. /* INonDelegatingUnknown */
  41. STDMETHODIMP_(ULONG) NonDelegatingAddRef();
  42. STDMETHODIMP_(ULONG) NonDelegatingRelease();
  43. STDMETHODIMP_(NTSTATUS) NonDelegatingQueryInterface(
  44. REFIID rIID,
  45. PVOID* ppVoid);
  46. };
  47. #define DECLARE_STD_UNKNOWN() \
  48. STDMETHODIMP_(NTSTATUS) NonDelegatingQueryInterface( \
  49. REFIID iid, \
  50. PVOID* ppvObject); \
  51. \
  52. STDMETHODIMP_(NTSTATUS) QueryInterface( \
  53. REFIID riid, \
  54. void** ppv) \
  55. { \
  56. return GetOuterUnknown()->QueryInterface(riid, ppv); \
  57. } \
  58. \
  59. STDMETHODIMP_(ULONG) AddRef() \
  60. { \
  61. return GetOuterUnknown()->AddRef(); \
  62. } \
  63. \
  64. STDMETHODIMP_(ULONG) Release() \
  65. { \
  66. return GetOuterUnknown()->Release(); \
  67. }
  68. #define DEFINE_STD_CONSTRUCTOR(classname) \
  69. classname(PUNKNOWN outer_unknown) \
  70. : CUnknown(outer_unknown) \
  71. { }
  72. #else /* Not C++ - this is probably very buggy... */
  73. NTSTATUS
  74. STDMETHODCALLTYPE
  75. Unknown_QueryInterface(
  76. IUnknown* this,
  77. IN REFIID refiid,
  78. OUT PVOID* output);
  79. ULONG
  80. STDMETHODCALLTYPE
  81. Unknown_AddRef(
  82. IUnknown* unknown_this);
  83. ULONG
  84. STDMETHODCALLTYPE
  85. Unknown_Release(
  86. IUnknown* unknown_this);
  87. typedef struct CUnknown
  88. {
  89. __GNU_EXTENSION union
  90. {
  91. IUnknown IUnknown;
  92. INonDelegatingUnknown INonDelegatingUnknown;
  93. };
  94. LONG m_ref_count;
  95. PUNKNOWN m_outer_unknown;
  96. } CUnknown;
  97. #endif /* __cplusplus */
  98. #ifdef __cplusplus
  99. /* ===============================================================
  100. Construction helpers
  101. */
  102. #define QICAST(typename) \
  103. PVOID( (typename) (this) )
  104. #define QICASTUNKNOWN(typename) \
  105. PVOID( PUNKNOWN( (typename) (this) ) )
  106. #define STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, tag, base) \
  107. classname *new_ptr = new(pool_type, tag) classname(outer_unknown); \
  108. \
  109. if ( ! new_ptr ) \
  110. return STATUS_INSUFFICIENT_RESOURCES; \
  111. \
  112. *unknown = PUNKNOWN((base)(new_ptr)); \
  113. (*unknown)->AddRef(); \
  114. return STATUS_SUCCESS
  115. #define STD_CREATE_BODY_WITH_TAG(classname, unknown, outer_unknown, pool_type, tag, base) \
  116. STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, tag, PUNKNOWN)
  117. #define STD_CREATE_BODY_(classname, unknown, outer_unknown, pool_type, base) \
  118. STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, 'rCcP', base)
  119. #define STD_CREATE_BODY(classname, unknown, outer_unknown, pool_type) \
  120. STD_CREATE_BODY_(classname, unknown, outer_unknown, pool_type, PUNKNOWN)
  121. /* ===============================================================
  122. Custom "new" and "delete" C++ operators
  123. */
  124. #ifndef _NEW_DELETE_OPERATORS_
  125. #define _NEW_DELETE_OPERATORS_
  126. inline PVOID
  127. KCOM_New(
  128. size_t size,
  129. POOL_TYPE pool_type,
  130. ULONG tag)
  131. {
  132. PVOID result;
  133. result = ExAllocatePoolWithTag(pool_type, size, tag);
  134. if ( result )
  135. RtlZeroMemory(result, size);
  136. return result;
  137. }
  138. inline PVOID
  139. operator new (
  140. size_t size,
  141. POOL_TYPE pool_type)
  142. {
  143. return KCOM_New(size, pool_type, 'wNcP');
  144. }
  145. inline PVOID
  146. operator new (
  147. size_t size,
  148. POOL_TYPE pool_type,
  149. ULONG tag)
  150. {
  151. return KCOM_New(size, pool_type, tag);
  152. }
  153. inline void __cdecl
  154. operator delete(
  155. PVOID ptr)
  156. {
  157. ExFreePool(ptr);
  158. }
  159. #endif /* ALLOCATION_OPERATORS_DEFINED */
  160. #else /* Being compiled with C */
  161. #endif /* __cplusplus */
  162. #endif /* include guard */