Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
// --------------------------------------------------------------------------------
// Privunk.h
// Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
// --------------------------------------------------------------------------------
#include "pch.hxx"
#include "msoert.h"
#include "privunk.h"
// --------------------------------------------------------------------------------
// CPrivateUnknown::CPrivateUnknown
// --------------------------------------------------------------------------------
CPrivateUnknown::CPrivateUnknown(IUnknown *pUnkOuter) { m_pUnkOuter = pUnkOuter ? pUnkOuter : &m_cUnkInner; }
// --------------------------------------------------------------------------------
// CPrivateUnknown::SetOuter
// --------------------------------------------------------------------------------
void CPrivateUnknown::SetOuter(IUnknown *pUnkOuter) { // Must have an outer, and should not have been aggregated yet...
Assert(pUnkOuter && m_pUnkOuter == &m_cUnkInner);
// Save pUnkOuter
m_pUnkOuter = pUnkOuter; }
// --------------------------------------------------------------------------------
// CPrivateUnknown::CUnkInner::QueryInterface
// --------------------------------------------------------------------------------
HRESULT CPrivateUnknown::CUnkInner::QueryInterface(REFIID riid, LPVOID * ppvObj) { // I can handle the unknown
if (IsEqualIID(riid, IID_IUnknown)) { // Return IUnknown
*ppvObj = SAFECAST(this, IUnknown *);
// Increment Ref Count
InterlockedIncrement(&m_cRef);
// Done
return S_OK; }
// Get my parent (computes the offset of the parent's base address)
CPrivateUnknown *pParent = IToClass(CPrivateUnknown, m_cUnkInner, this);
// Dispatch to PrivateQueryInterface
return pParent->PrivateQueryInterface(riid, ppvObj); }
// --------------------------------------------------------------------------------
// CPrivateUnknown::CUnkInner::AddRef
// --------------------------------------------------------------------------------
ULONG CPrivateUnknown::CUnkInner::AddRef(void) { return InterlockedIncrement(&m_cRef); }
// --------------------------------------------------------------------------------
// CPrivateUnknown::CUnkInner::Release
// --------------------------------------------------------------------------------
ULONG CPrivateUnknown::CUnkInner::Release(void) { // Decrement Internal Reference Count
LONG cRef = InterlockedDecrement(&m_cRef);
// No dead yet...
if (cRef > 0) return (ULONG)cRef;
// Some groovy, mystical, disco stuff
// protect against cached pointers bumping us up then down
m_cRef = 1000;
// Get the parent
CPrivateUnknown* pParent = IToClass(CPrivateUnknown, m_cUnkInner, this);
// Kill the parent
delete pParent;
// Done
return 0; }
|