[STDUNK][PORTCLS][CMIDriver] Fix issue with operator new/delete
[reactos.git] / sdk / lib / drivers / sound / stdunk / cunknown.cpp
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