Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

481 lines
21 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995.
//
// File: NOUTIL.hxx
//
// Contents: Definitions of utility stuff for use
//
// Classes: StdClassFactory
//
// Functions:
//
// Macros:
//
// History:
//
//----------------------------------------------------------------------------
#ifndef _NOUTIL_HXX_
#define _NOUTIL_HXX_
#include <formtrck.hxx>
//+---------------------------------------------------------------------
//
// Generally useful #defines and inline functions for OLE2.
//
//------------------------------------------------------------------------
// These are the major and minor version returned by OleBuildVersion
#define OLE_MAJ_VER 0x0003
#define OLE_MIN_VER 0x003A
//---------------------------------------------------------------
// SCODE and HRESULT macros
//---------------------------------------------------------------
#define OK(r) (SUCCEEDED(r))
#define NOTOK(r) (FAILED(r))
//---------------------------------------------------------------
// IUnknown
//---------------------------------------------------------------
#define ADsIncrement(__ul) InterlockedIncrement((long *) &__ul)
#define ADsDecrement(__ul) InterlockedDecrement((long *) &__ul)
#define DECLARE_ADs_IUNKNOWN_METHODS \
STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppv); \
STDMETHOD_(ULONG, AddRef) (void); \
STDMETHOD_(ULONG, Release) (void);
#define DECLARE_ADs_STANDARD_IUNKNOWN(cls) \
STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppv); \
ULONG _ulRefs; \
STDMETHOD_(ULONG, AddRef) (void) \
{ \
ADsIncrement(_ulRefs); \
return _ulRefs; \
} \
STDMETHOD_(ULONG, Release) (void) \
{ \
if (!ADsDecrement(_ulRefs)) \
{ \
ADsIncrement(_ulRefs); \
delete this; \
return 0; \
} \
return _ulRefs; \
}
#define DECLARE_ADs_DELEGATING_IUNKNOWN(cls) \
IUnknown * _pUnkOuter; \
STDMETHOD(QueryInterface) (REFIID iid, LPVOID * ppv) \
{ return _pUnkOuter->QueryInterface(iid, ppv); } \
STDMETHOD_(ULONG, AddRef) (void) \
{ return _pUnkOuter->AddRef(); } \
STDMETHOD_(ULONG, Release) (void) \
{ return _pUnkOuter->Release(); }
#define DECLARE_DELEGATING_REFCOUNTING \
IUnknown * _pUnkOuter; \
STDMETHOD_(ULONG, AddRef) (void) \
{ return _pUnkOuter->AddRef(); } \
STDMETHOD_(ULONG, Release) (void) \
{ return _pUnkOuter->Release(); }
#if DBG == 0
//
// Retail versions of these macros
//
#define DECLARE_ADs_PRIVATE_IUNKNOWN(cls) \
class PrivateUnknown : public IUnknown \
{ \
private: \
ULONG _ulRefs; \
cls * My##cls(void) \
{ return CONTAINING_RECORD(this, cls, _PrivUnk); } \
\
public: \
PrivateUnknown(void) \
{ _ulRefs = 1; } \
\
DECLARE_ADs_IUNKNOWN_METHODS \
}; \
friend class PrivateUnknown; \
PrivateUnknown _PrivUnk;
#define IMPLEMENT_ADs_PRIVATE_IUNKNOWN(cls) \
STDMETHODIMP_(ULONG) cls::PrivateUnknown::AddRef( ) \
{ \
ADsIncrement(_ulRefs); \
return _ulRefs; \
} \
STDMETHODIMP_(ULONG) cls::PrivateUnknown::Release( ) \
{ \
if (!ADsDecrement(_ulRefs)) \
{ \
ADsIncrement(_ulRefs); \
delete My##cls(); \
return 0; \
} \
return _ulRefs; \
}
#define DECLARE_ADs_COMPOUND_IUNKNOWN(cls) \
class PrivateUnknown : public IUnknown \
{ \
friend class cls; \
\
public: \
PrivateUnknown(void) \
{ _ulRefs = 1; _ulAllRefs = 1; } \
\
DECLARE_ADs_IUNKNOWN_METHODS \
\
private: \
ULONG _ulRefs; \
ULONG _ulAllRefs; \
\
cls * My##cls(void) \
{ return CONTAINING_RECORD(this, cls, _PrivUnk); } \
}; \
friend class PrivateUnknown; \
PrivateUnknown _PrivUnk; \
\
ULONG SubAddRef(void); \
ULONG SubRelease(void);
#define IMPLEMENT_ADs_COMPOUND_IUNKNOWN(cls) \
STDMETHODIMP_(ULONG) cls::PrivateUnknown::AddRef( ) \
{ \
ADsIncrement(_ulAllRefs); \
ADsIncrement(_ulRefs); \
return _ulRefs; \
} \
STDMETHODIMP_(ULONG) cls::PrivateUnknown::Release( ) \
{ \
if (!ADsDecrement(_ulRefs)) \
{ \
My##cls()->Passivate(); \
} \
if (!ADsDecrement(_ulAllRefs)) \
{ \
ADsIncrement(_ulAllRefs); \
delete My##cls(); \
return 0; \
} \
return _ulRefs; \
} \
ULONG cls::SubAddRef( ) \
{ \
return ADsIncrement(_PrivUnk._ulAllRefs); \
} \
ULONG cls::SubRelease( ) \
{ \
ULONG ul; \
\
ul = ADsDecrement(_PrivUnk._ulAllRefs); \
if (!ul) \
{ \
ADsIncrement(_PrivUnk._ulAllRefs); \
delete this; \
} \
\
return ul; \
}
#else // DBG == 0
//
// Debug versions of these macros
//
#define DECLARE_ADs_PRIVATE_IUNKNOWN(cls) \
class PrivateUnknown : protected ObjectTracker, \
public IUnknown \
{ \
private: \
cls * My##cls(void) \
{ return CONTAINING_RECORD(this, cls, _PrivUnk); } \
\
public: \
PrivateUnknown(void) \
{ _ulRefs = 1; TrackClassName(#cls); } \
\
DECLARE_ADs_IUNKNOWN_METHODS \
}; \
friend class PrivateUnknown; \
PrivateUnknown _PrivUnk;
#define IMPLEMENT_ADs_PRIVATE_IUNKNOWN(cls) \
STDMETHODIMP_(ULONG) cls::PrivateUnknown::AddRef( ) \
{ \
StdAddRef(); \
return _ulRefs; \
} \
STDMETHODIMP_(ULONG) cls::PrivateUnknown::Release( ) \
{ \
if (!StdRelease()) \
{ \
ADsIncrement(_ulRefs); \
delete My##cls(); \
return 0; \
} \
return _ulRefs; \
}
#define DECLARE_ADs_COMPOUND_IUNKNOWN(cls) \
class PrivateUnknown : protected ObjectTracker, \
public IUnknown \
{ \
friend class cls; \
\
public: \
PrivateUnknown(void) \
{ _ulNRefs = 1; _ulRefs = 1; TrackClassName(#cls); } \
\
DECLARE_ADs_IUNKNOWN_METHODS \
\
private: \
ULONG _ulNRefs; \
\
cls * My##cls(void) \
{ return CONTAINING_RECORD(this, cls, _PrivUnk); } \
}; \
friend class PrivateUnknown; \
PrivateUnknown _PrivUnk; \
\
ULONG SubAddRef(void); \
ULONG SubRelease(void);
#define IMPLEMENT_ADs_COMPOUND_IUNKNOWN(cls) \
STDMETHODIMP_(ULONG) cls::PrivateUnknown::AddRef( ) \
{ \
StdAddRef(); \
ADsIncrement(_ulNRefs); \
return _ulNRefs; \
} \
STDMETHODIMP_(ULONG) cls::PrivateUnknown::Release( ) \
{ \
if (!ADsDecrement(_ulNRefs)) \
{ \
My##cls()->Passivate(); \
} \
if (!StdRelease()) \
{ \
ADsIncrement(_ulRefs); \
delete My##cls(); \
return 0; \
} \
return _ulNRefs; \
} \
ULONG cls::SubAddRef( ) \
{ \
return _PrivUnk.StdAddRef(); \
} \
ULONG cls::SubRelease( ) \
{ \
ULONG ul; \
\
ul = _PrivUnk.StdRelease(); \
if (!ul) \
{ \
ADsIncrement(_PrivUnk._ulRefs); \
delete this; \
} \
\
return ul; \
}
#endif // DBG == 0
// The Detach method is no longer useful, now that we've
// removed the parent class pointer
#define DECLARE_ADs_SUBOBJECT_IUNKNOWN(cls, parent_cls, member) \
DECLARE_ADs_IUNKNOWN_METHODS \
parent_cls * My##parent_cls(void); \
void Detach(void) \
{ ; }
#define IMPLEMENT_ADs_SUBOBJECT_IUNKNOWN(cls, parent_cls, member) \
inline parent_cls * cls::My##parent_cls(void) \
{ \
return CONTAINING_RECORD(this, parent_cls, member); \
} \
STDMETHODIMP_(ULONG) cls::AddRef( ) \
{ return My##parent_cls()->SubAddRef(); } \
STDMETHODIMP_(ULONG) cls::Release( ) \
{ return My##parent_cls()->SubRelease(); }
//+------------------------------------------------------------------------
//
// NO_COPY *declares* the constructors and assignment operator for copying.
// By not *defining* these functions, you can prevent your class from
// accidentally being copied or assigned -- you will be notified by
// a linkage error.
//
//-------------------------------------------------------------------------
#define NO_COPY(cls) \
cls(const cls&); \
cls& operator=(const cls&);
//+---------------------------------------------------------------------
//
// Miscellaneous useful OLE helper and debugging functions
//
//----------------------------------------------------------------------
//
// Some convenient OLE-related definitions and declarations
//
typedef unsigned short far * LPUSHORT;
//REVIEW we are experimenting with a non-standard OLEMISC flag.
#define OLEMISC_STREAMABLE 1024
#include "misc.hxx"
#if DBG == 1
STDAPI_(void) PrintIID(DWORD dwFlags, REFIID riid);
#define TRACEIID(iid) PrintIID(DEB_TRACE, iid)
#else // DBG == 0
#define TRACEIID(iid)
#endif // DBG
//+---------------------------------------------------------------------
//
// Interface wrapper for tracing method invocations
//
//----------------------------------------------------------------------
#if DBG == 1
LPVOID WatchInterface(REFIID riid, LPVOID pv, LPWSTR lpstr);
#define WATCHINTERFACE(iid, p, lpstr) WatchInterface(iid, p, lpstr)
#else // DBG == 0
#define WATCHINTERFACE(iid, p, lpstr) (p)
#endif // DBG
//+---------------------------------------------------------------------
//
// Standard IClassFactory implementation
//
//----------------------------------------------------------------------
//+---------------------------------------------------------------
//
// Class: StdClassFactory
//
// Purpose: Standard implementation of a class factory object
//
// Notes: **************!!!!!!!!!!!!!!!!!*************
// TAKE NOTE --- The implementation of Release on this
// class does not perform a delete. This is so you can
// make the class factory a global static variable.
// Use the CDynamicCF class below for an object
// which is not global static data.
//
// ALSO - The refcount is initialized to 0, NOT 1!
//
//---------------------------------------------------------------
class StdClassFactory: public IClassFactory
{
public:
StdClassFactory(void) : _ulRefs(1) {};
// IUnknown methods
DECLARE_ADs_IUNKNOWN_METHODS;
// IClassFactory methods
STDMETHOD(LockServer) (BOOL fLock);
// CreateInstance is left pure virtual.
protected:
ULONG _ulRefs;
};
//+---------------------------------------------------------------------------
//
// Class: CDynamicCF (DYNCF)
//
// Purpose: Class factory which exists on the heap, and whose Release
// method does the normal thing.
//
// Interface: DECLARE_ADs_STANDARD_IUNKNOWN -- IUnknown methods
//
// LockServer -- Per IClassFactory.
// CDynamicCF -- ctor.
// ~CDynamicCF -- dtor.
//
// History: 6-22-94 adams Created
// 7-13-94 adams Moved from ADs\inc\dyncf.hxx
//
//----------------------------------------------------------------------------
class CDynamicCF: public IClassFactory
{
public:
// IUnknown methods
DECLARE_ADs_STANDARD_IUNKNOWN(CDynamicCF)
// IClassFactory methods
STDMETHOD(LockServer) (BOOL fLock);
protected:
CDynamicCF(void);
virtual ~CDynamicCF(void);
};
#endif //__NOUTILS_HXX_