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.
 
 
 
 
 
 

393 lines
12 KiB

//============================================================================
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: std.h
//
// History:
//
// 03/15/97 Kenn Takara Created.
//
// Declarations for some common code/macros.
//============================================================================
#ifndef _STD_H_
#define _STD_H_
#if _MSC_VER >= 1000 // VC 5.0 or later
#pragma once
#endif
#ifndef _DBGUTIL_H
#include "dbgutil.h"
#endif
#include "malloc.h"
#ifndef TFSCORE_API
#define TFSCORE_API(type) __declspec( dllexport ) type FAR PASCAL
#define TFSCORE_APIV(type) __declspec( dllexport ) type FAR CDECL
#endif
#define hrOK HRESULT(0)
#define hrTrue HRESULT(0)
#define hrFalse ResultFromScode(S_FALSE)
#define hrFail ResultFromScode(E_FAIL)
#define hrNotImpl ResultFromScode(E_NOTIMPL)
#define hrNoInterface ResultFromScode(E_NOINTERFACE)
#define hrNoMem ResultFromScode(E_OUTOFMEMORY)
#define OffsetOf(s,m) (size_t)( (char *)&(((s *)0)->m) - (char *)0 )
#define EmbeddorOf(C,m,p) ((C *)(((char *)p) - OffsetOf(C,m)))
#define DimensionOf(rgx) (sizeof((rgx)) / sizeof(*(rgx)))
/*!--------------------------------------------------------------------------
DeclareSP, DeclareSPBasic
DeclareSRG, DeclareSRGBasic
DeclareSPT, DeclareSPTBasic
DeclareSPM, DeclareSPMBasic
These macros declare 'smart' pointers. Smart pointers behave like
normal pointers with the exception that a smart pointer destructor
frees the thing it is pointing at and assignment to a non-null smart
pointer is not allowed.
The DeclareSxx macros differ by how the generated smart pointer frees
the memory:
Macro Free Smart Pointer Type
====================== ============ ==================
DeclareSP(TAG, Type) delete p; SPTAG
DeclareSRG(TAG, Type) delete [] p; SRGTAG
DeclareSPT(TAG, Type) TMemFree(p); SPTTAG
DeclareSPM(TAG, Type) MMemFree(p); SPMTAG
NOTE: use the 'Basic' variants (DeclareSPBasic, etc) for pointer to
non-struct types (e.g. char, int, etc).
Smart pointers have two methods:
void SPTAG::Free()
Free and then null the internally maintained pointer.
Type *SPTAG::Transfer()
Transfers pointer ownership to caller. The internally
maintained pointer is cleared on exit.
Author: GaryBu
---------------------------------------------------------------------------*/
#define DeclareSP(TAG,Type) DeclareSmartPointer(SP##TAG,Type,delete m_p)
#define DeclareSRG(TAG,Type) DeclareSmartPointer(SRG##TAG,Type,delete [] m_p)
#define DeclareSPT(TAG,Type) DeclareSmartPointer(SPT##TAG,Type,TMemFree(m_p))
#define DeclareSPM(TAG,Type) DeclareSmartPointer(SPM##TAG,Type,MMemFree(m_p))
#define DeclareSPBasic(TAG,Type)\
DeclareSPPrivateBasic(SP##TAG,Type, delete m_p)
#define DeclareSRGBasic(TAG,Type)\
DeclareSPPrivateBasic(SRG##TAG,Type, delete [] m_p)
#define DeclareSPTBasic(TAG,Type)\
DeclareSPPrivateBasic(SPT##TAG,Type,TMemFree(m_p))
#define DeclareSPMBasic(TAG,Type)\
DeclareSPPrivateBasic(SPM##TAG,Type,MMemFree(m_p))
#define DeclareSPPrivateCore(klass, Type, free)\
class klass \
{\
public:\
klass() { m_p = 0; }\
klass(Type *p) { m_p = p; }\
~klass() { free; }\
operator Type*() const { return m_p; }\
Type &operator*() const { return *m_p; }\
Type &operator[](int i) const { return m_p[i]; }\
Type &nth(int i) const { return m_p[i]; }\
Type **operator &() { Assert(!m_p); return &m_p; }\
Type *operator=(Type *p){ Assert(!m_p); return m_p = p; }\
Type *Transfer() { Type *p = m_p; m_p = 0; return p; }\
void Free() { free; m_p = 0; }\
private:\
void *operator=(const klass &);\
klass(const klass &);\
Type *m_p;
#define DeclareSPPrivateBasic(klass, Type, free)\
DeclareSPPrivateCore(klass, Type, free)\
};
/*!--------------------------------------------------------------------------
DeclareSPBasicEx
Variant of smart pointers that allows an extra member variable.
The klassFree parameter lets you supply an alias for Free().
An example is IPropertyAccess and StdRowEditingTable:
DeclareSPPrivateBasicEx(SPIPropertyAccess,IPropertyAccess,
m_pex->ReleaseContext(m_p), StdRowEditingTable, ReleaseContext)
SPIPropertyAccess sppac(pstdtable);
sppac = pstdtable->GetContext(0);
...use spfc...
sppac.ReleaseContext();
Author: KennT
---------------------------------------------------------------------------*/
#define DeclareSPBasicEx(klass, Type, free, klassEx, klassFree)\
DeclareSPPrivateCore(klass, Type, free)\
public:\
klass(klassEx *pex) \
{\
m_p = 0; m_pex=pex; } \
void klassFree() \
{ Free(); } \
private:\
klassEx *m_pex; \
};
#define DeclareSmartPointer(klass, Type, free)\
DeclareSPPrivateCore(klass, Type, free)\
public:\
Type * operator->() const { return m_p; }\
};
TFSCORE_API(HRESULT) HrQueryInterface(IUnknown *punk, REFIID iid, LPVOID *ppv);
template <class T, const IID *piid>
class ComSmartPointer
{
public:
typedef T _PtrClass;
ComSmartPointer() {p=NULL;}
~ComSmartPointer() { Release(); }
// set p to NULL before releasing, this fixes a subtle bug
// A has a ptr to B, B has a ptr to A
// A gets told to release B
// A calls spB.Release();
// in spB.Release(), B gets destructed and calls spA.Release()
// in spA.Release(), A gets destructed and calls spB.Release()
// since the ptr in spB has not been set to NULL (which is bad
// since B has already gone away).
void Release() {T* pTemp = p; if (p) { p=NULL; pTemp->Release(); }}
operator T*() {return (T*)p;}
T& operator*() {Assert(p!=NULL); return *p; }
T** operator&() { Assert(p==NULL); return &p; }
T* operator->() { Assert(p!=NULL); return p; }
T* operator=(T* lp){ Release(); p = lp; return p;}
T* operator=(const ComSmartPointer<T,piid>& lp)
{
if (p)
p->Release();
p = lp.p;
return p;
}
void Set(T* lp) { Release(); p = lp; if (p) p->AddRef(); }
T * Transfer() { T* pTemp=p; p=NULL; return pTemp; }
BOOL operator!(){return (p == NULL) ? TRUE : FALSE;}
void Query(IUnknown *punk)
{ HrQuery(punk); }
HRESULT HrQuery(IUnknown *punk)
{ return ::HrQueryInterface(punk, *piid, (LPVOID *) &p); }
T* p;
private:
// These methods should NEVER get called.
ComSmartPointer(T* lp);
ComSmartPointer(const ComSmartPointer<T,piid>& lp);
};
// Interface utilities
TFSCORE_API(void) SetI(IUnknown * volatile *punkL, IUnknown *punkR);
TFSCORE_API(void) ReleaseI(IUnknown *punk);
// Utilities for dealing with embedded classes
#define DeclareEmbeddedInterface(interface, base) \
class E##interface : public interface \
{ \
public: \
Declare##base##Members(IMPL) \
Declare##interface##Members(IMPL) \
} m_##interface; \
friend class E##interface;
#define ImplementEmbeddedUnknown(embeddor, interface) \
STDMETHODIMP embeddor::E##interface::QueryInterface(REFIID iid,void **ppv)\
{ \
return EmbeddorOf(embeddor,m_##interface,this)->QueryInterface(iid,ppv);\
} \
STDMETHODIMP_(ULONG) embeddor::E##interface::AddRef() \
{ \
return EmbeddorOf(embeddor, m_##interface, this)->AddRef(); \
} \
STDMETHODIMP_(ULONG) embeddor::E##interface::Release() \
{ \
return EmbeddorOf(embeddor, m_##interface, this)->Release(); \
}
#define ImplementEmbeddedUnknownNoRefCount(embeddor, interface) \
STDMETHODIMP embeddor::E##interface::QueryInterface(REFIID iid,void **ppv)\
{ \
return EmbeddorOf(embeddor,m_##interface,this)->QueryInterface(iid,ppv);\
}
#define EMPrologIsolated(embeddor, interface, method) \
embeddor *pThis = EmbeddorOf(embeddor, m_##interface, this);
#define ImplementIsolatedUnknown(embeddor, interface) \
STDMETHODIMP embeddor::E##interface::QueryInterface(REFIID iid,void **ppv)\
{ \
EMPrologIsolated(embeddor, interface, QueryInterface); \
Assert(!FHrSucceeded(pThis->QueryInterface(IID_##interface, ppv))); \
*ppv = 0; \
if (iid == IID_IUnknown) *ppv = (IUnknown *) this; \
else if (iid == IID_##interface) *ppv = (interface *) this; \
else return ResultFromScode(E_NOINTERFACE); \
((IUnknown *) *ppv)->AddRef(); \
return HRESULT_OK; \
} \
STDMETHODIMP_(ULONG) embeddor::E##interface::AddRef() \
{ \
EMPrologIsolated(embeddor, interface, AddRef) \
return 1; \
} \
STDMETHODIMP_(ULONG) embeddor::E##interface::Release() \
{ \
EMPrologIsolated(embeddor, interface, Release) \
return 1; \
}
#define InitPThis(embeddor, object)\
embeddor *pThis = EmbeddorOf(embeddor, m_##object, this);\
/*---------------------------------------------------------------------------
Implements the controlling IUnknown interface for the inner object
of an aggregation.
---------------------------------------------------------------------------*/
#define IMPLEMENT_AGGREGATION_IUNKNOWN(klass) \
STDMETHODIMP_(ULONG) klass::AddRef() \
{ \
Assert(m_pUnknownOuter); \
return m_pUnknownOuter->AddRef(); \
} \
STDMETHODIMP_(ULONG) klass::Release() \
{ \
Assert(m_pUnknownOuter); \
return m_pUnknownOuter->Release(); \
} \
STDMETHODIMP klass::QueryInterface(REFIID riid, LPVOID *ppv) \
{ \
Assert(m_pUnknownOuter); \
return m_pUnknownOuter->QueryInterface(riid, ppv); \
} \
/*---------------------------------------------------------------------------
Declares the non-delegating IUnknown implementation in a class.
---------------------------------------------------------------------------*/
#define DECLARE_AGGREGATION_NONDELEGATING_IUNKNOWN(klass) \
class ENonDelegatingIUnknown : public IUnknown \
{ \
public: \
DeclareIUnknownMembers(IMPL) \
} m_ENonDelegatingIUnknown; \
friend class ENonDelegatingIUnknown; \
IUnknown *m_pUnknownOuter; \
/*---------------------------------------------------------------------------
Implements the non-delegating IUnknown for a class.
---------------------------------------------------------------------------*/
#define IMPLEMENT_AGGREGATION_NONDELEGATING_ADDREFRELEASE(klass,interface) \
STDMETHODIMP_(ULONG) klass::ENonDelegatingIUnknown::AddRef() \
{ \
InitPThis(klass, ENonDelegatingIUnknown); \
return InterlockedIncrement(&(pThis->m_cRef)); \
} \
STDMETHODIMP_(ULONG) klass::ENonDelegatingIUnknown::Release() \
{ \
InitPThis(klass, ENonDelegatingIUnknown); \
if (0 == InterlockedDecrement(&(pThis->m_cRef))) \
{ \
delete pThis; \
return 0; \
} \
return pThis->m_cRef; \
} \
#define IMPLEMENT_AGGREGATION_NONDELEGATING_IUNKNOWN(klass,interface) \
IMPLEMENT_AGGREGATION_NONDELEGATING_ADDREFRELEASE(klass,interface) \
STDMETHODIMP klass::ENonDelegatingIUnknown::QueryInterface(REFIID riid, LPVOID *ppv) \
{ \
InitPThis(klass, ENonDelegatingIUnknown); \
if (ppv == NULL) \
return E_INVALIDARG; \
*ppv = NULL; \
if (riid == IID_IUnknown) \
*ppv = (IUnknown *) this; \
else if (riid == IID_##interface) \
*ppv = (interface *) pThis; \
else \
return E_NOINTERFACE; \
((IUnknown *)*ppv)->AddRef(); \
return hrOK; \
} \
/*---------------------------------------------------------------------------
Standard TRY/CATCH wrappers for the COM interfaces
---------------------------------------------------------------------------*/
#define COM_PROTECT_TRY \
try
#define COM_PROTECT_ERROR_LABEL Error: ;\
#ifdef DEBUG
#define COM_PROTECT_CATCH \
catch(CException *pe) \
{ \
hr = COleException::Process(pe); \
} \
catch(...) \
{ \
hr = E_FAIL; \
}
#else
#define COM_PROTECT_CATCH \
catch(CException *pe) \
{ \
hr = COleException::Process(pe); \
} \
catch(...) \
{ \
hr = E_FAIL; \
}
#endif
/*---------------------------------------------------------------------------
Some useful smart pointers
---------------------------------------------------------------------------*/
DeclareSPPrivateBasic(SPSZ, TCHAR, delete[] m_p);
DeclareSPPrivateBasic(SPWSZ, WCHAR, delete[] m_p);
DeclareSPPrivateBasic(SPASZ, char, delete[] m_p);
DeclareSPPrivateBasic(SPBYTE, BYTE, delete m_p);
typedef ComSmartPointer<IUnknown, &IID_IUnknown> SPIUnknown;
typedef ComSmartPointer<IStream, &IID_IStream> SPIStream;
typedef ComSmartPointer<IPersistStreamInit, &IID_IPersistStreamInit> SPIPersistStreamInit;
#endif // _STD_H_