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