-/*\r
- ReactOS Kernel-Mode COM\r
- IUnknown implementations\r
-\r
- This file is in the public domain.\r
-\r
- AUTHORS\r
- Andrew Greenwood\r
-*/\r
-\r
-#ifndef STDUNK_H\r
-#define STDUNK_H\r
-\r
-#define STDUNK_TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))\r
-\r
-#include <punknown.h>\r
-\r
-/* ===============================================================\r
- INonDelegatingUnknown interface\r
-*/\r
-\r
-DECLARE_INTERFACE(INonDelegatingUnknown)\r
-{\r
- STDMETHOD_(NTSTATUS, NonDelegatingQueryInterface)( THIS_\r
- IN REFIID,\r
- OUT PVOID*) PURE;\r
-\r
- STDMETHOD_(ULONG, NonDelegatingAddRef)( THIS ) PURE;\r
- STDMETHOD_(ULONG, NonDelegatingRelease)( THIS ) PURE;\r
-};\r
-\r
-typedef INonDelegatingUnknown *PNONDELEGATINGUNKNOWN;\r
-\r
-\r
-/* ===============================================================\r
- CUnknown declaration / definition\r
-\r
- There are 2 variants for this, and I'm not sure if the C\r
- version is correct.\r
-*/\r
-\r
-#ifdef __cplusplus\r
-\r
-class CUnknown : public INonDelegatingUnknown\r
-{\r
- private :\r
- LONG m_ref_count;\r
- PUNKNOWN m_outer_unknown;\r
-\r
- public :\r
- /* CUnknown */\r
- CUnknown(PUNKNOWN pUnknownOuter);\r
- virtual ~CUnknown();\r
-\r
- PUNKNOWN GetOuterUnknown()\r
- { return m_outer_unknown; }\r
-\r
- /* INonDelegatingUnknown */\r
- STDMETHODIMP_(ULONG) NonDelegatingAddRef();\r
- STDMETHODIMP_(ULONG) NonDelegatingRelease();\r
-\r
- STDMETHODIMP_(NTSTATUS) NonDelegatingQueryInterface(\r
- REFIID rIID,\r
- PVOID* ppVoid);\r
-};\r
-\r
-#define DECLARE_STD_UNKNOWN() \\r
- STDMETHODIMP_(NTSTATUS) NonDelegatingQueryInterface( \\r
- REFIID iid, \\r
- PVOID* ppvObject); \\r
-\\r
- STDMETHODIMP_(NTSTATUS) QueryInterface( \\r
- REFIID riid, \\r
- void** ppv) \\r
- { \\r
- return GetOuterUnknown()->QueryInterface(riid, ppv); \\r
- } \\r
-\\r
- STDMETHODIMP_(ULONG) AddRef() \\r
- { \\r
- return GetOuterUnknown()->AddRef(); \\r
- } \\r
-\\r
- STDMETHODIMP_(ULONG) Release() \\r
- { \\r
- return GetOuterUnknown()->Release(); \\r
- }\r
-\r
-#define DEFINE_STD_CONSTRUCTOR(classname) \\r
- classname(PUNKNOWN outer_unknown) \\r
- : CUnknown(outer_unknown) \\r
- { }\r
-\r
-#else /* Not C++ - this is probably very buggy... */\r
-\r
-NTSTATUS\r
-STDMETHODCALLTYPE\r
-Unknown_QueryInterface(\r
- IUnknown* this,\r
- IN REFIID refiid,\r
- OUT PVOID* output);\r
-\r
-ULONG\r
-STDMETHODCALLTYPE\r
-Unknown_AddRef(\r
- IUnknown* unknown_this);\r
-\r
-ULONG\r
-STDMETHODCALLTYPE\r
-Unknown_Release(\r
- IUnknown* unknown_this);\r
-\r
-typedef struct CUnknown\r
-{\r
- union\r
- {\r
- IUnknown IUnknown;\r
- INonDelegatingUnknown INonDelegatingUnknown;\r
- };\r
-\r
- LONG m_ref_count;\r
- PUNKNOWN m_outer_unknown;\r
-} CUnknown;\r
-\r
-#endif /* __cplusplus */\r
-\r
-\r
-\r
-#ifdef __cplusplus\r
-\r
-\r
-/* ===============================================================\r
- Construction helpers\r
-*/\r
-\r
-#define QICAST(typename) \\r
- PVOID( (typename) (this) )\r
-\r
-#define QICASTUNKNOWN(typename) \\r
- PVOID( PUNKNOWN( (typename) (this) ) )\r
-\r
-#define STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, tag, base) \\r
- classname *new_ptr = new(pool_type, tag) classname(outer_unknown); \\r
-\\r
- if ( ! new_ptr ) \\r
- return STATUS_INSUFFICIENT_RESOURCES; \\r
-\\r
- *unknown = PUNKNOWN((base)(new_ptr)); \\r
- (*unknown)->AddRef(); \\r
- return STATUS_SUCCESS\r
-\r
-#define STD_CREATE_BODY_WITH_TAG(classname, unknown, outer_unknown, pool_type, tag, base) \\r
- STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, tag, PUNKNOWN)\r
-\r
-#define STD_CREATE_BODY_(classname, unknown, outer_unknown, pool_type, base) \\r
- STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, STDUNK_TAG('r','C','c','P'), base)\r
-\r
-#define STD_CREATE_BODY(classname, unknown, outer_unknown, pool_type) \\r
- STD_CREATE_BODY_(classname, unknown, outer_unknown, pool_type, PUNKNOWN)\r
-\r
-\r
-/* ===============================================================\r
- Custom "new" and "delete" C++ operators\r
-*/\r
-\r
-#ifndef _NEW_DELETE_OPERATORS_\r
-#define _NEW_DELETE_OPERATORS_\r
-\r
-inline PVOID\r
-KCOM_New(\r
- size_t size,\r
- POOL_TYPE pool_type,\r
- ULONG tag)\r
-{\r
- PVOID result;\r
-\r
- result = ExAllocatePoolWithTag(pool_type, size, tag);\r
-\r
- if ( result )\r
- RtlZeroMemory(result, size);\r
-\r
- return result;\r
-}\r
-\r
-inline PVOID\r
-operator new (\r
- size_t size,\r
- POOL_TYPE pool_type)\r
-{\r
- return KCOM_New(size, pool_type, STDUNK_TAG ('w','N','c','P'));\r
-}\r
-\r
-inline PVOID\r
-operator new (\r
- size_t size,\r
- POOL_TYPE pool_type,\r
- ULONG tag)\r
-{\r
- return KCOM_New(size, pool_type, tag);\r
-}\r
-\r
-inline void __cdecl\r
-operator delete(\r
- PVOID ptr)\r
-{\r
- ExFreePool(ptr);\r
-}\r
-\r
-#endif /* ALLOCATION_OPERATORS_DEFINED */\r
-\r
-\r
-#else /* Being compiled with C */\r
-\r
-\r
-#endif /* __cplusplus */\r
-\r
-#endif /* include guard */\r
+/*
+ ReactOS Kernel-Mode COM
+ IUnknown implementations
+
+ This file is in the public domain.
+
+ AUTHORS
+ Andrew Greenwood
+*/
+
+#ifndef STDUNK_H
+#define STDUNK_H
+
+#include <punknown.h>
+
+/* Helper macro to enable gcc's extension. */
+#ifndef __GNU_EXTENSION
+#ifdef __GNUC__
+#define __GNU_EXTENSION __extension__
+#else
+#define __GNU_EXTENSION
+#endif
+#endif
+
+/* ===============================================================
+ INonDelegatingUnknown interface
+*/
+
+DECLARE_INTERFACE(INonDelegatingUnknown)
+{
+ STDMETHOD_(NTSTATUS, NonDelegatingQueryInterface)( THIS_
+ IN REFIID,
+ OUT PVOID*) PURE;
+
+ STDMETHOD_(ULONG, NonDelegatingAddRef)( THIS ) PURE;
+ STDMETHOD_(ULONG, NonDelegatingRelease)( THIS ) PURE;
+};
+
+typedef INonDelegatingUnknown *PNONDELEGATINGUNKNOWN;
+
+
+/* ===============================================================
+ CUnknown declaration / definition
+
+ There are 2 variants for this, and I'm not sure if the C
+ version is correct.
+*/
+
+#ifdef __cplusplus
+
+class CUnknown : public INonDelegatingUnknown
+{
+ private :
+ LONG m_ref_count;
+ PUNKNOWN m_outer_unknown;
+
+ public :
+ /* CUnknown */
+ CUnknown(PUNKNOWN pUnknownOuter);
+ virtual ~CUnknown();
+
+ PUNKNOWN GetOuterUnknown()
+ { return m_outer_unknown; }
+
+ /* INonDelegatingUnknown */
+ STDMETHODIMP_(ULONG) NonDelegatingAddRef();
+ STDMETHODIMP_(ULONG) NonDelegatingRelease();
+
+ STDMETHODIMP_(NTSTATUS) NonDelegatingQueryInterface(
+ REFIID rIID,
+ PVOID* ppVoid);
+};
+
+#define DECLARE_STD_UNKNOWN() \
+ STDMETHODIMP_(NTSTATUS) NonDelegatingQueryInterface( \
+ REFIID iid, \
+ PVOID* ppvObject); \
+\
+ STDMETHODIMP_(NTSTATUS) QueryInterface( \
+ REFIID riid, \
+ void** ppv) \
+ { \
+ return GetOuterUnknown()->QueryInterface(riid, ppv); \
+ } \
+\
+ STDMETHODIMP_(ULONG) AddRef() \
+ { \
+ return GetOuterUnknown()->AddRef(); \
+ } \
+\
+ STDMETHODIMP_(ULONG) Release() \
+ { \
+ return GetOuterUnknown()->Release(); \
+ }
+
+#define DEFINE_STD_CONSTRUCTOR(classname) \
+ classname(PUNKNOWN outer_unknown) \
+ : CUnknown(outer_unknown) \
+ { }
+
+#else /* Not C++ - this is probably very buggy... */
+
+NTSTATUS
+STDMETHODCALLTYPE
+Unknown_QueryInterface(
+ IUnknown* this,
+ IN REFIID refiid,
+ OUT PVOID* output);
+
+ULONG
+STDMETHODCALLTYPE
+Unknown_AddRef(
+ IUnknown* unknown_this);
+
+ULONG
+STDMETHODCALLTYPE
+Unknown_Release(
+ IUnknown* unknown_this);
+
+typedef struct CUnknown
+{
+ __GNU_EXTENSION union
+ {
+ IUnknown IUnknown;
+ INonDelegatingUnknown INonDelegatingUnknown;
+ };
+
+ LONG m_ref_count;
+ PUNKNOWN m_outer_unknown;
+} CUnknown;
+
+#endif /* __cplusplus */
+
+
+
+#ifdef __cplusplus
+
+
+/* ===============================================================
+ Construction helpers
+*/
+
+#define QICAST(typename) \
+ PVOID( (typename) (this) )
+
+#define QICASTUNKNOWN(typename) \
+ PVOID( PUNKNOWN( (typename) (this) ) )
+
+#define STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, tag, base) \
+ classname *new_ptr = new(pool_type, tag) classname(outer_unknown); \
+\
+ if ( ! new_ptr ) \
+ return STATUS_INSUFFICIENT_RESOURCES; \
+\
+ *unknown = PUNKNOWN((base)(new_ptr)); \
+ (*unknown)->AddRef(); \
+ return STATUS_SUCCESS
+
+#define STD_CREATE_BODY_WITH_TAG(classname, unknown, outer_unknown, pool_type, tag, base) \
+ STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, tag, PUNKNOWN)
+
+#define STD_CREATE_BODY_(classname, unknown, outer_unknown, pool_type, base) \
+ STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, 'rCcP', base)
+
+#define STD_CREATE_BODY(classname, unknown, outer_unknown, pool_type) \
+ STD_CREATE_BODY_(classname, unknown, outer_unknown, pool_type, PUNKNOWN)
+
+
+/* ===============================================================
+ Custom "new" and "delete" C++ operators
+*/
+
+#ifndef _NEW_DELETE_OPERATORS_
+#define _NEW_DELETE_OPERATORS_
+
+inline PVOID
+KCOM_New(
+ size_t size,
+ POOL_TYPE pool_type,
+ ULONG tag)
+{
+ PVOID result;
+
+ result = ExAllocatePoolWithTag(pool_type, size, tag);
+
+ if ( result )
+ RtlZeroMemory(result, size);
+
+ return result;
+}
+
+inline PVOID
+operator new (
+ size_t size,
+ POOL_TYPE pool_type)
+{
+ return KCOM_New(size, pool_type, 'wNcP');
+}
+
+inline PVOID
+operator new (
+ size_t size,
+ POOL_TYPE pool_type,
+ ULONG tag)
+{
+ return KCOM_New(size, pool_type, tag);
+}
+
+inline void __cdecl
+operator delete(
+ PVOID ptr)
+{
+ ExFreePool(ptr);
+}
+
+#endif /* ALLOCATION_OPERATORS_DEFINED */
+
+
+#else /* Being compiled with C */
+
+
+#endif /* __cplusplus */
+
+#endif /* include guard */