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.
 
 
 
 
 
 

86 lines
2.9 KiB

// --------------------------------------------------------------------------------
// 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;
}