-
Notifications
You must be signed in to change notification settings - Fork 2
/
stdunk.cpp
114 lines (94 loc) · 2.81 KB
/
stdunk.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*****************************************************************************
* stdunk.cpp - standard unknown implementation
*****************************************************************************
* Copyright (c) 1997-2000 Microsoft Corporation. All Rights Reserved.
*
*/
#include "portcls.h"
#include "stdunk.h"
/*****************************************************************************
* CUnknown implementation
*/
/*****************************************************************************
* CUnknown::CUnknown()
*****************************************************************************
* Constructor.
*/
CUnknown::CUnknown(PUNKNOWN pUnknownOuter)
: m_lRefCount(0)
{
if (pUnknownOuter)
{
m_pUnknownOuter = pUnknownOuter;
}
else
{
m_pUnknownOuter = PUNKNOWN(dynamic_cast<PNONDELEGATINGUNKNOWN>(this));
}
}
/*****************************************************************************
* CUnknown::~CUnknown()
*****************************************************************************
* Destructor.
*/
CUnknown::~CUnknown(void)
{
}
/*****************************************************************************
* INonDelegatingUnknown implementation
*/
/*****************************************************************************
* CUnknown::NonDelegatingAddRef()
*****************************************************************************
* Register a new reference to the object without delegating to the outer
* unknown.
*/
STDMETHODIMP_(ULONG) CUnknown::NonDelegatingAddRef(void)
{
ASSERT(m_lRefCount >= 0);
InterlockedIncrement(&m_lRefCount);
return ULONG(m_lRefCount);
}
/*****************************************************************************
* CUnknown::NonDelegatingRelease()
*****************************************************************************
* Release a reference to the object without delegating to the outer unknown.
*/
STDMETHODIMP_(ULONG) CUnknown::NonDelegatingRelease(void)
{
ASSERT(m_lRefCount > 0);
if (InterlockedDecrement(&m_lRefCount) == 0)
{
m_lRefCount++;
delete this;
return 0;
}
return ULONG(m_lRefCount);
}
/*****************************************************************************
* CUnknown::NonDelegatingQueryInterface()
*****************************************************************************
* Obtains an interface.
*/
STDMETHODIMP_(NTSTATUS) CUnknown::NonDelegatingQueryInterface
(
_In_ REFIID rIID,
_COM_Outptr_ PVOID * ppVoid
)
{
ASSERT(ppVoid);
if (IsEqualGUIDAligned(rIID,IID_IUnknown))
{
*ppVoid = PVOID(PUNKNOWN(this));
}
else
{
*ppVoid = NULL;
}
if (*ppVoid)
{
PUNKNOWN(*ppVoid)->AddRef();
return STATUS_SUCCESS;
}
return STATUS_INVALID_PARAMETER;
}