498 lines
12 KiB
C++
498 lines
12 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 1990-2001 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
ulibdef.hxx
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module contains primitive support for the ULIB class hierarchy
|
||
|
and it's clients. This support includes:
|
||
|
|
||
|
- type definitions
|
||
|
- manifest constants
|
||
|
- debugging support
|
||
|
- memory leakage support
|
||
|
- external references
|
||
|
|
||
|
Author:
|
||
|
|
||
|
David J. Gilman (davegi) 19-Oct-1990
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
ULIB, User Mode
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#if ! defined( _ULIBDEF_ )
|
||
|
|
||
|
#define _ULIBDEF_
|
||
|
|
||
|
extern "C" {
|
||
|
#include <stdlib.h>
|
||
|
};
|
||
|
|
||
|
// The ULIB_EXPORT macro marks functions that are to be
|
||
|
// exported. The source files for ULIB.DLL will have _ULIB_MEMBER_
|
||
|
// defined; clients will not.
|
||
|
//
|
||
|
#if defined ( _AUTOCHECK_ )
|
||
|
#define ULIB_EXPORT
|
||
|
#elif defined ( _ULIB_MEMBER_ )
|
||
|
#define ULIB_EXPORT __declspec(dllexport)
|
||
|
#else
|
||
|
#define ULIB_EXPORT __declspec(dllimport)
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
#pragma warning(disable:4091) // Symbol not defined
|
||
|
|
||
|
//
|
||
|
// Macros for defining types:
|
||
|
//
|
||
|
// - pointers (Ptype)
|
||
|
// - pointers to constants (PCtype)
|
||
|
// - references (Rtype)
|
||
|
// - references to constants (RCtype)
|
||
|
//
|
||
|
|
||
|
#define DEFINE_POINTER_TYPES( type ) \
|
||
|
typedef type* P##type; \
|
||
|
typedef const type* PC##type
|
||
|
|
||
|
#define DEFINE_REFERENCE_TYPES( type ) \
|
||
|
typedef type& R##type; \
|
||
|
typedef const type& RC##type
|
||
|
|
||
|
#define DEFINE_POINTER_AND_REFERENCE_TYPES( type ) \
|
||
|
DEFINE_POINTER_TYPES( type ); \
|
||
|
DEFINE_REFERENCE_TYPES( type )
|
||
|
|
||
|
#define DEFINE_TYPE( basetype, newtype ) \
|
||
|
typedef basetype newtype; \
|
||
|
DEFINE_POINTER_AND_REFERENCE_TYPES( newtype )
|
||
|
|
||
|
#define DECLARE_CLASS( c ) \
|
||
|
class c; \
|
||
|
DEFINE_POINTER_AND_REFERENCE_TYPES( c );\
|
||
|
extern PCCLASS_DESCRIPTOR c##_cd
|
||
|
|
||
|
//
|
||
|
// Primitive types.
|
||
|
//
|
||
|
|
||
|
DEFINE_TYPE( unsigned char, UCHAR );
|
||
|
DEFINE_TYPE( unsigned short,USHORT );
|
||
|
DEFINE_TYPE( unsigned long, ULONG );
|
||
|
|
||
|
DEFINE_TYPE( char, CCHAR );
|
||
|
DEFINE_TYPE( short, CSHORT );
|
||
|
DEFINE_TYPE( ULONG, CLONG );
|
||
|
|
||
|
DEFINE_TYPE( short, SSHORT );
|
||
|
DEFINE_TYPE( long, SLONG );
|
||
|
|
||
|
DEFINE_TYPE( UCHAR, BYTE );
|
||
|
DEFINE_TYPE( char, STR );
|
||
|
DEFINE_TYPE( UCHAR, BOOLEAN );
|
||
|
DEFINE_TYPE( int, INT );
|
||
|
DEFINE_TYPE( unsigned int, UINT );
|
||
|
|
||
|
#if !defined(_NATIVE_WCHAR_T_DEFINED)
|
||
|
DEFINE_TYPE(USHORT, WCHAR );
|
||
|
#else
|
||
|
typedef wchar_t WCHAR;
|
||
|
#endif
|
||
|
|
||
|
typedef WCHAR *LPWCH; // pwc
|
||
|
typedef WCHAR *LPWSTR; // pwsz, 0x0000 terminated UNICODE strings only
|
||
|
|
||
|
DEFINE_POINTER_AND_REFERENCE_TYPES( WCHAR );
|
||
|
|
||
|
DEFINE_TYPE( WCHAR, WSTR );
|
||
|
//DEFINE_TYPE( struct tagLC_ID, LC_ID );
|
||
|
|
||
|
//
|
||
|
// Augmented (beyond standard headers) VOID pointer types
|
||
|
//
|
||
|
|
||
|
DEFINE_POINTER_TYPES( VOID );
|
||
|
|
||
|
//
|
||
|
// Ulib specific, primitive types
|
||
|
//
|
||
|
|
||
|
DEFINE_TYPE( STR, CLASS_NAME );
|
||
|
DEFINE_TYPE( ULONG_PTR, CLASS_ID );
|
||
|
|
||
|
|
||
|
//
|
||
|
// Member and non-member function/data modifiers
|
||
|
//
|
||
|
|
||
|
#define CONST const
|
||
|
#define NONVIRTUAL
|
||
|
#define PURE = 0
|
||
|
#define STATIC static
|
||
|
#define VIRTUAL virtual
|
||
|
#define INLINE inline
|
||
|
// #define INLINE // hack to build for mips
|
||
|
#define FRIEND friend
|
||
|
|
||
|
//
|
||
|
// Argument modifiers
|
||
|
//
|
||
|
|
||
|
#define DEFAULT =
|
||
|
#define IN
|
||
|
#define OPTIONAL
|
||
|
#define OUT
|
||
|
#define INOUT
|
||
|
|
||
|
#if !defined(max)
|
||
|
#define max(a,b) (((a) > (b)) ? (a) : (b) )
|
||
|
#endif
|
||
|
|
||
|
#if !defined(min)
|
||
|
#define min(a,b) (((a) < (b)) ? (a) : (b) )
|
||
|
#endif
|
||
|
|
||
|
#if DBG==1
|
||
|
|
||
|
#define REGISTER
|
||
|
|
||
|
#else
|
||
|
|
||
|
#define REGISTER register
|
||
|
|
||
|
#endif // DBG
|
||
|
|
||
|
//
|
||
|
// External constants
|
||
|
//
|
||
|
|
||
|
extern CONST CLASS_ID NIL_CLASS_ID;
|
||
|
|
||
|
//
|
||
|
// GetFileName returns the file name portion of the supplied path name.
|
||
|
//
|
||
|
|
||
|
extern "C" {
|
||
|
#include <string.h>
|
||
|
};
|
||
|
|
||
|
inline
|
||
|
PCCHAR
|
||
|
GetFileName (
|
||
|
IN PCCHAR PathName
|
||
|
)
|
||
|
|
||
|
{
|
||
|
PCCHAR pch;
|
||
|
|
||
|
return((( pch = strrchr( PathName, '\\' )) != NULL ) ?
|
||
|
pch + 1 : PathName );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Cast (beProtocol) support
|
||
|
//
|
||
|
// If the ID of the passed object is equal to the ID in this class'
|
||
|
// CLASS_DESCRIPTOR, then the object is of this type and the Cast succeeds
|
||
|
// (i.e. returns Object) otherwise the Cast fails (i.e. returns NULL)
|
||
|
//
|
||
|
|
||
|
|
||
|
#define DECLARE_CAST_MEMBER_FUNCTION( type ) \
|
||
|
STATIC \
|
||
|
P##type \
|
||
|
Cast ( \
|
||
|
PCOBJECT Object \
|
||
|
)
|
||
|
|
||
|
|
||
|
#define DEFINE_CAST_MEMBER_FUNCTION( type ) \
|
||
|
P##type \
|
||
|
type::Cast ( \
|
||
|
PCOBJECT Object \
|
||
|
) \
|
||
|
{ \
|
||
|
if( Object && ( Object->QueryClassId( ) == \
|
||
|
type##_cd->QueryClassId( ))) { \
|
||
|
return(( P##type ) Object ); \
|
||
|
} else { \
|
||
|
return NULL; \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
#define DEFINE_EXPORTED_CAST_MEMBER_FUNCTION( type, export ) \
|
||
|
P##type \
|
||
|
export \
|
||
|
type::Cast ( \
|
||
|
PCOBJECT Object \
|
||
|
) \
|
||
|
{ \
|
||
|
if( Object && ( Object->QueryClassId( ) == \
|
||
|
type##_cd->QueryClassId( ))) { \
|
||
|
return(( P##type ) Object ); \
|
||
|
} else { \
|
||
|
return NULL; \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Constructor support
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// All classes have CLASS_DESCRIPTORS which are static and named
|
||
|
// after the class appended with the suffix _cd. They are passed stored in
|
||
|
// OBJECT and are set by the SetClassDescriptor function. The Construct
|
||
|
// For debugging purposes the class' name is stored in the CLASS_DESCRIPTOR.
|
||
|
// The Construct member function gas a no-op implementation in OBJECT and
|
||
|
// could be overloaded as a private member in any derived class.
|
||
|
//
|
||
|
|
||
|
#define DECLARE_CONSTRUCTOR( c ) \
|
||
|
NONVIRTUAL \
|
||
|
c ( \
|
||
|
)
|
||
|
|
||
|
#define DEFINE_CONSTRUCTOR( d, b ) \
|
||
|
PCCLASS_DESCRIPTOR d##_cd; \
|
||
|
d::d ( \
|
||
|
) : b( ) \
|
||
|
{ \
|
||
|
SetClassDescriptor( ##d##_cd ); \
|
||
|
Construct( ); \
|
||
|
}
|
||
|
|
||
|
#define DEFINE_EXPORTED_CONSTRUCTOR( d, b, e ) \
|
||
|
PCCLASS_DESCRIPTOR d##_cd; \
|
||
|
e d::d ( \
|
||
|
) : b( ) \
|
||
|
{ \
|
||
|
SetClassDescriptor( ##d##_cd ); \
|
||
|
Construct( ); \
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// Debug support.
|
||
|
//
|
||
|
// Use the Debug macros to invoke the following debugging functions.
|
||
|
//
|
||
|
// DebugAbort( str ) - Print a message and abort.
|
||
|
// DebugAssert( exp ) - Assert that an expression is TRUE. Abort if FALSE.
|
||
|
// DebugChkHeap( ) - Validate the heap. Abort if invalid.
|
||
|
// DebugPrint( str ) - Print a string including location (file/line)
|
||
|
// DebugPrintTrace(fmt, ...) - Printf.
|
||
|
//
|
||
|
#if DBG==1
|
||
|
|
||
|
#define DebugAbort( str ) \
|
||
|
DebugPrint( str ); \
|
||
|
ExitProcess( 99 )
|
||
|
|
||
|
#define DebugAssert( exp ) \
|
||
|
ASSERT( exp )
|
||
|
|
||
|
#define DebugCheckHeap( )
|
||
|
|
||
|
#define DebugPrint( str ) \
|
||
|
DebugPrintfReal ( "%s in file: %s on line: %d.\n", \
|
||
|
str, \
|
||
|
__FILE__, \
|
||
|
__LINE__ )
|
||
|
|
||
|
#define DebugPrintTrace( M ) DebugPrintfReal M
|
||
|
|
||
|
#if defined(RUN_ON_W2K)
|
||
|
#if defined(KdPrintEx)
|
||
|
#undef KdPrintEx
|
||
|
#endif
|
||
|
|
||
|
#define KdPrintEx( M ) DebugPrintfReal2 M
|
||
|
|
||
|
ULIB_EXPORT
|
||
|
VOID
|
||
|
DebugPrintfReal2(
|
||
|
IN ULONG ComponentId,
|
||
|
IN ULONG Level,
|
||
|
IN PCSTR Format,
|
||
|
IN ...
|
||
|
);
|
||
|
#endif
|
||
|
|
||
|
ULIB_EXPORT
|
||
|
VOID
|
||
|
DebugPrintfReal(
|
||
|
IN PCSTR Format,
|
||
|
IN ...
|
||
|
);
|
||
|
|
||
|
#define DebugPtrAssert( ptr ) \
|
||
|
ASSERT( ptr != NULL )
|
||
|
|
||
|
//
|
||
|
// UlibGlobalFlag is used to selectively enable debugging options at
|
||
|
// run-time.
|
||
|
//
|
||
|
|
||
|
extern ULONG UlibGlobalFlag;
|
||
|
|
||
|
#elif defined( _AUTOCHECK_DBG_ )
|
||
|
|
||
|
// Autocheck uses the system's DbgPrint function.
|
||
|
//
|
||
|
#define DebugPrint DbgPrint
|
||
|
#define DebugPrintTrace( M ) DbgPrint M
|
||
|
|
||
|
#define DebugAbort( str )
|
||
|
|
||
|
#define DebugAssert( exp )
|
||
|
|
||
|
#define DebugCheckHeap( )
|
||
|
|
||
|
#define DebugPtrAssert( ptr )
|
||
|
|
||
|
#if defined(RUN_ON_W2K)
|
||
|
#if defined(KdPrintEx)
|
||
|
#undef KdPrintEx
|
||
|
#endif
|
||
|
#define KdPrintEx( M ) DebugPrintfReal2 M
|
||
|
|
||
|
ULIB_EXPORT
|
||
|
VOID
|
||
|
DebugPrintfReal2(
|
||
|
IN ULONG ComponentId,
|
||
|
IN ULONG Level,
|
||
|
IN PCSTR Format,
|
||
|
IN ...
|
||
|
);
|
||
|
#endif // defined(RUN_ON_W2K)
|
||
|
|
||
|
#else // DBG == 0 and _AUTOCHECK_DBG_ not defined.
|
||
|
|
||
|
#define DebugAbort( str )
|
||
|
|
||
|
#define DebugAssert( exp )
|
||
|
|
||
|
#define DebugCheckHeap( )
|
||
|
|
||
|
#define DebugPrint( str )
|
||
|
|
||
|
#define DebugPrintTrace( M )
|
||
|
|
||
|
#define DebugPtrAssert( ptr )
|
||
|
|
||
|
#endif // DBG
|
||
|
|
||
|
//
|
||
|
// DELETE macro that NULLifizes the pointer to the deleted object.
|
||
|
//
|
||
|
|
||
|
// Undo any previous definitions of DELETE.
|
||
|
#undef DELETE
|
||
|
|
||
|
// #define DELETE(x) FREE(x), x = NULL;
|
||
|
|
||
|
#define DELETE( x ) \
|
||
|
delete x, x = NULL
|
||
|
|
||
|
#define DELETE_ARRAY( x ) \
|
||
|
delete [] x, x = NULL
|
||
|
|
||
|
#define NEW new
|
||
|
|
||
|
#define DumpStats
|
||
|
|
||
|
#if defined( _AUTOCHECK_ )
|
||
|
|
||
|
#define MAX_PATH 260
|
||
|
|
||
|
ULIB_EXPORT ULONG64 AutoChkFreeSpaceLeft();
|
||
|
|
||
|
ULIB_EXPORT PVOID AutoChkMalloc(ULONG);
|
||
|
#define MALLOC(bytes) (AutoChkMalloc(bytes))
|
||
|
|
||
|
INLINE
|
||
|
PVOID
|
||
|
NtlibZeroAlloc(
|
||
|
ULONG Size
|
||
|
)
|
||
|
{
|
||
|
PVOID Result;
|
||
|
|
||
|
Result = MALLOC( Size );
|
||
|
|
||
|
if( Result != NULL ) {
|
||
|
|
||
|
memset( Result, 0, Size );
|
||
|
}
|
||
|
|
||
|
return Result;
|
||
|
}
|
||
|
|
||
|
|
||
|
#define CALLOC(nitems, size) (NtlibZeroAlloc(nitems*size))
|
||
|
|
||
|
ULIB_EXPORT PVOID UlibRealloc(PVOID, ULONG);
|
||
|
|
||
|
#define REALLOC(p,s) UlibRealloc(p,s)
|
||
|
|
||
|
ULIB_EXPORT VOID AutoChkMFree(PVOID);
|
||
|
#define FREE(x) ((x) ? (AutoChkMFree(x), (x) = NULL) : 0)
|
||
|
|
||
|
#else // _AUTOCHECK_ not defined
|
||
|
|
||
|
#if defined( _NTAPI_ULIB_ )
|
||
|
|
||
|
#define MALLOC(bytes) (RtlAllocateHeap(RtlProcessHeap(), 0, bytes))
|
||
|
|
||
|
#define CALLOC(nitems, size) \
|
||
|
(RtlAllocateHeap(RtlProcessHeap(), 0, nitems*size))
|
||
|
|
||
|
ULIB_EXPORT PVOID UlibRealloc(PVOID, ULONG);
|
||
|
|
||
|
#define REALLOC(p,s) UlibRealloc(p,s)
|
||
|
|
||
|
#define FREE(x) ((x) ? (RtlFreeHeap(RtlProcessHeap(), 0, x), (x) = NULL) : 0)
|
||
|
|
||
|
#else
|
||
|
|
||
|
#define MALLOC(bytes) ((PVOID) LocalAlloc(0, bytes))
|
||
|
|
||
|
#define CALLOC(nitems, size) ((PVOID) LocalAlloc(LMEM_ZEROINIT, nitems*size))
|
||
|
|
||
|
ULIB_EXPORT PVOID UlibRealloc(PVOID, ULONG);
|
||
|
|
||
|
#define REALLOC(x, size) ((PVOID) LocalReAlloc(x, size, LMEM_MOVEABLE))
|
||
|
|
||
|
#define FREE(x) ((x) ? (LocalFree(x), (x) = NULL) : 0)
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif // _AUTOCHECK
|
||
|
|
||
|
#if !defined(_SETUP_LOADER_) && !defined(_AUTOCHECK_)
|
||
|
|
||
|
__inline void * __cdecl operator new(size_t x)
|
||
|
{
|
||
|
return(MALLOC(x));
|
||
|
}
|
||
|
|
||
|
__inline void __cdecl operator delete(void * x)
|
||
|
{
|
||
|
FREE(x);
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif // _ULIBDEF_
|