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.
 
 
 
 
 
 

391 lines
19 KiB

//____________________________________________________________________________
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1995 - 1996.
//
// File: macros.h
//
// Contents: Useful macros
//
// Macros: ARRAYLEN
//
// BREAK_ON_FAIL(hresult)
// BREAK_ON_FAIL(hresult)
//
// DECLARE_IUNKNOWN_METHODS
// DECLARE_STANDARD_IUNKNOWN
// IMPLEMENT_STANDARD_IUNKNOWN
//
// SAFE_RELEASE
//
// DECLARE_SAFE_INTERFACE_PTR_MEMBERS
//
// History: 6/3/1996 RaviR Created
// 7/23/1996 JonN Added exception handling macros
//
//____________________________________________________________________________
#ifndef _MACROS_H_
#define _MACROS_H_
//____________________________________________________________________________
//
// Macro: ARRAYLEN
//
// Purpose: To determine the length of an array.
//____________________________________________________________________________
//
#define ARRAYLEN(a) (sizeof(a) / sizeof((a)[0]))
//____________________________________________________________________________
//
// Macros: BREAK_ON_FAIL(hresult), BREAK_ON_ERROR(lastError)
//
// Purpose: To break out of a loop on error.
//____________________________________________________________________________
//
#define BREAK_ON_FAIL(hr) if (FAILED(hr)) { break; } else 1;
#define BREAK_ON_ERROR(lr) if (lr != ERROR_SUCCESS) { break; } else 1;
//____________________________________________________________________________
//
// Macros: DwordAlign(n)
//____________________________________________________________________________
//
#define DwordAlign(n) (((n) + 3) & ~3)
//____________________________________________________________________________
//
// Macros: SAFE_RELEASE
//____________________________________________________________________________
//
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(punk) \
if (punk != NULL) \
{ \
punk##->Release(); \
punk = NULL; \
} \
else \
{ \
TRACE(_T("Release called on NULL interface ptr")); \
}
#endif // SAFE_RELEASE
//____________________________________________________________________________
//
// Macro: DECLARE_IUNKNOWN_METHODS
//
// Purpose: This declares the set of IUnknown methods and is for
// general-purpose use inside classes that inherit from IUnknown
//____________________________________________________________________________
//
#define DECLARE_IUNKNOWN_METHODS \
STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj); \
STDMETHOD_(ULONG,AddRef) (void); \
STDMETHOD_(ULONG,Release) (void)
//____________________________________________________________________________
//
// Macro: DECLARE_STANDARD_IUNKNOWN
//
// Purpose: This is for use in declaring non-aggregatable objects. It
// declares the IUnknown methods and reference counter, m_ulRefs.
// m_ulRefs should be initialized to 1 in the constructor of
// the object
//____________________________________________________________________________
//
#define DECLARE_STANDARD_IUNKNOWN \
DECLARE_IUNKNOWN_METHODS; \
ULONG m_ulRefs
//____________________________________________________________________________
//
// Macro: IMPLEMENT_STANDARD_IUNKNOWN
//
// Purpose: Partial implementaion of standard IUnknown.
//
// Note: This does NOT implement QueryInterface, which must be
// implemented by each object
//____________________________________________________________________________
//
#define IMPLEMENT_STANDARD_IUNKNOWN(cls) \
STDMETHODIMP_(ULONG) cls##::AddRef() \
{ return InterlockedIncrement((LONG*)&m_ulRefs); } \
STDMETHODIMP_(ULONG) cls##::Release() \
{ ULONG ulRet = InterlockedDecrement((LONG*)&m_ulRefs); \
if (0 == ulRet) { delete this; } \
return ulRet; }
// ISSUE-2002/04/01-JonN This is not used, remove it
//____________________________________________________________________________
//
// Macro: DECLARE_SAFE_INTERFACE_PTR_MEMBERS(cls, Interface, m_iptr)
//
// Purpose: Make the interface ptr 'm_iptr' of interface type 'Interface'
// a safe pointer for the given class 'cls', by adding methods and
// overloading operators to manipulate the pointer m_iptr.
//
// History: 6/3/1996 RaviR Created
//
// Notes: Adds safe interface pointer member functions to the given
// class for the given OLE interface. 'm_iptr' is the member
// variable name of the interface ptr in the given class.
//
// The Copy function creates a valid additional copy of
// the captured pointer (following the AddRef/Release protocol)
// so can be used to hand out copies from a safe pointer declared
// as a member of some other class.
//
// The 'Transfer' function transfers the interface pointer, and
// invalidates its member value (by setting it to NULL).
//
// To release the existing interface ptr and set it to a new
// instance use the 'Set' member fuction. This method takes a
// parameter which specifies whether the new pointer should be
// AddRef'd, defaulting to TRUE.
//
// The following methods manipulate the interface pointer with
// out following the AddRef/Release protocol: Transfer, Attach
// and Detach.
//____________________________________________________________________________
//
#define DECLARE_SAFE_INTERFACE_PTR_MEMBERS(cls, Interface, m_iptr) \
\
public: \
cls##(Interface * iptr=NULL, BOOL fInc=TRUE) : m_iptr(iptr) \
{ \
if (fInc && (m_iptr != NULL)) \
{ \
m_iptr->AddRef(); \
} \
} \
\
~##cls##() \
{ \
if (m_iptr != NULL) \
{ \
m_iptr->Release(); \
m_iptr = NULL; \
} \
} \
\
inline BOOL IsNull(void) \
{ \
return (m_iptr == NULL); \
} \
\
void Transfer(Interface **piptr) \
{ \
*piptr = m_iptr; \
m_iptr = NULL; \
} \
\
void Copy(Interface **piptr) \
{ \
*piptr = m_iptr; \
if (m_iptr != NULL) \
m_iptr->AddRef(); \
} \
\
void Set(Interface* iptr, BOOL fInc = TRUE) \
{ \
if (m_iptr) \
{ \
m_iptr->Release(); \
} \
m_iptr = iptr; \
if (fInc && m_iptr) \
{ \
m_iptr->AddRef(); \
} \
} \
\
void SafeRelease(void) \
{ \
if (m_iptr) \
{ \
m_iptr->Release(); \
m_iptr = NULL; \
} \
} \
\
void SimpleRelease(void) \
{ \
ASSERT(m_iptr != NULL); \
m_iptr->Release(); \
m_iptr = NULL; \
} \
\
void Attach(Interface* iptr) \
{ \
ASSERT(m_iptr == NULL); \
m_iptr = iptr; \
} \
\
void Detach(void) \
{ \
m_iptr = NULL; \
} \
\
Interface * operator-> () { return m_iptr; } \
Interface& operator * () { return *m_iptr; } \
operator Interface *() { return m_iptr; } \
\
Interface ** operator &() \
{ \
ASSERT(m_iptr == NULL); \
return &m_iptr; \
} \
\
Interface *Self(void) { return m_iptr; } \
\
private: \
void operator= (const cls &) {;} \
cls(const cls &){;}
//____________________________________________________________________________
//
// Macro: EXCEPTION HANDLING MACROS
//
// Purpose: Provide standard macros for exception-handling in
// OLE servers.
//
// History: 7/23/1996 JonN Created
//
// Notes: Declare USE_HANDLE_MACROS("Component name") in each source
// file before these are used.
//
// These macros can only be used in function calls which return
// type HRESULT.
//
// Bracket routines which can generate exceptions
// with STANDARD_TRY and STANDARD_CATCH.
//
// Where these routines are COM methods requiring MFC
// support, use MFC_TRY and MFC_CATCH instead.
//____________________________________________________________________________
//
#define USE_HANDLE_MACROS(component) \
static TCHAR* You_forgot_to_declare_USE_HANDLE_MACROS = _T(component);
#define STANDARD_TRY \
try {
#define MFC_TRY \
AFX_MANAGE_STATE(AfxGetStaticModuleState( )); \
STANDARD_TRY
// ISSUE-2002/04/01-JonN remove ENDMETHOD_READBLOCK
//
// CODEWORK don't quite have ENDMETHOD_READBLOCK working yet
//
#ifdef DEBUG
#define ENDMETHOD_STRING \
"%s: The unexpected error can be identified as \"%s\" context %n\n"
#define ENDMETHOD_READBLOCK \
{ \
TCHAR szError[MAX_PATH]; \
UINT nHelpContext = 0; \
if ( e->GetErrorMessage( szError, MAX_PATH, &nHelpContext ) ) \
{ \
TRACE( ENDMETHOD_STRING, \
You_forgot_to_declare_USE_HANDLE_MACROS, \
szError, \
nHelpContext ); \
} \
}
#else
#define ENDMETHOD_READBLOCK
#endif
#define ERRSTRING_MEMORY "%s: An out-of-memory error occurred\n"
#define ERRSTRING_FILE "%s: File error 0x%lx occurred on file \"%s\"\n"
#define ERRSTRING_OLE "%s: OLE error 0x%lx occurred\n"
#define ERRSTRING_UNEXPECTED "%s: An unexpected error occurred\n"
#define BADPARM_STRING "%s: Bad string parameter\n"
#define BADPARM_POINTER "%s: Bad pointer parameter\n"
#define TRACEERR(s) TRACE( s, You_forgot_to_declare_USE_HANDLE_MACROS )
#define TRACEERR1(s,a) TRACE( s, You_forgot_to_declare_USE_HANDLE_MACROS,a )
#define TRACEERR2(s,a,b) TRACE( s, You_forgot_to_declare_USE_HANDLE_MACROS,a,b )
// Note that it is important to use "e->Delete();" and not "delete e;"
#define STANDARD_CATCH \
} \
catch (CMemoryException* e) \
{ \
TRACEERR( ERRSTRING_MEMORY ); \
ASSERT( FALSE ); \
e->Delete(); \
return E_OUTOFMEMORY; \
} \
catch (COleException* e) \
{ \
HRESULT hr = (HRESULT)e->Process(e); \
TRACEERR1( ERRSTRING_OLE, hr ); \
ASSERT( FALSE ); \
e->Delete(); \
ASSERT( FAILED(hr) ); \
return hr; \
} \
catch (CFileException* e) \
{ \
HRESULT hr = (HRESULT)e->m_lOsError; \
TRACEERR2( ERRSTRING_FILE, hr, e->m_strFileName ); \
ASSERT( FALSE ); \
e->Delete(); \
ASSERT( FAILED(hr) ); \
return hr; \
} \
catch (CException* e) \
{ \
TRACEERR( ERRSTRING_UNEXPECTED ); \
ASSERT( FALSE ); \
e->Delete(); \
return E_UNEXPECTED; \
}
#define MFC_CATCH \
STANDARD_CATCH
#define TEST_STRING_PARAM(x) \
if ( (x) != NULL && !AfxIsValidString(x) ) { \
TRACEERR( BADPARM_STRING ); return E_POINTER; }
#define TEST_NONNULL_STRING_PARAM(x) \
if ( !AfxIsValidString(x) ) { \
TRACEERR( BADPARM_STRING ); return E_POINTER; }
#define TEST_NONNULL_PTR_PARAM(x) \
if ( (x) == NULL || IsBadWritePtr((x),sizeof(x)) ) { \
TRACEERR( BADPARM_POINTER ); return E_POINTER; }
#endif // _MACROS_H_