1 /*
2     ReactOS Kernel-Mode COM
3     IUnknown implementations
4 
5     LICENSE
6         Please see COPYING in the top-level directory for license information.
7 
8     AUTHORS
9         Andrew Greenwood
10 */
11 
12 #include <stdunk.h>
13 
14 inline
15 PVOID
16 KCOM_New(
17     size_t size,
18     POOL_TYPE pool_type,
19     ULONG tag)
20 {
21     PVOID result;
22 
23     result = ExAllocatePoolWithTag(pool_type, size, tag);
24 
25     if (result)
26         RtlZeroMemory(result, size);
27 
28     return result;
29 }
30 
31 PVOID
32 __cdecl
33 operator new(
34     size_t size,
35     POOL_TYPE pool_type)
36 {
37     return KCOM_New(size, pool_type, 'wNcP');
38 }
39 
40 PVOID
41 __cdecl
42 operator new(
43     size_t size,
44     POOL_TYPE pool_type,
45     ULONG tag)
46 {
47     return KCOM_New(size, pool_type, tag);
48 }
49 
50 void
51 __cdecl
52 operator delete(
53     PVOID ptr)
54 {
55     ExFreePool(ptr);
56 }
57 
58 void
59 __cdecl
60 operator delete(
61     PVOID ptr, UINT_PTR)
62 {
63     ExFreePool(ptr);
64 }
65 
66 CUnknown::CUnknown(PUNKNOWN outer_unknown)
67 {
68     m_ref_count = 0;
69 
70     if ( outer_unknown )
71         m_outer_unknown = outer_unknown;
72     else
73         m_outer_unknown = PUNKNOWN(dynamic_cast<PNONDELEGATINGUNKNOWN>(this));
74 }
75 
76 CUnknown::~CUnknown()
77 {
78 }
79 
80 STDMETHODIMP_(ULONG)
81 CUnknown::NonDelegatingAddRef()
82 {
83     InterlockedIncrement(&m_ref_count);
84     return m_ref_count;
85 }
86 
87 STDMETHODIMP_(ULONG)
88 CUnknown::NonDelegatingRelease()
89 {
90     if ( InterlockedDecrement(&m_ref_count) == 0 )
91     {
92         m_ref_count ++;
93         delete this;
94         return 0;
95     }
96 
97     return m_ref_count;
98 }
99 
100 STDMETHODIMP_(NTSTATUS)
101 CUnknown::NonDelegatingQueryInterface(
102     IN  REFIID iid,
103     PVOID* ppVoid)
104 {
105     /* FIXME */
106     #if 0
107     if ( IsEqualGUID(iid, IID_IUnknown) )   /* TODO: Aligned? */
108         *ppVoid = PVOID(PUNKNOWN(this));
109     else
110         *ppVoid = NULL;
111     #endif
112 
113     if ( *ppVoid )
114     {
115         PUNKNOWN(*ppVoid)->AddRef();
116         return STATUS_SUCCESS;
117     }
118 
119     return STATUS_INVALID_PARAMETER;
120 }
121 
122 #if __GNUC__
123 extern "C" void __cxa_pure_virtual() { ASSERT(FALSE); }
124 #endif
125