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.
 
 
 
 
 
 

384 lines
11 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1997.
//
// File: myhandle.hxx
//
// Contents: handle classes
//
// Classes: CAutoHandle, CFileHandle, CFindHandle, RegKeyHandle
// CAutoHandleTemplate<DWORD,BOOL (*)(HANDLE)>
//
// Functions:
//
// Coupling:
//
// Notes:
//
// History: 1-15-1997 ericne Created
//
//----------------------------------------------------------------------------
#ifndef _CMYHANDLE
#define _CMYHANDLE
#include <crtdbg.h>
#ifndef NEW
#define NEW new
#endif
#define NOT_NULL_OR_INVALID( h ) ( (h) && ~((UINT_PTR)(h)) )
//+---------------------------------------------------------------------------
//
// Class: autohandle_base
//
// Purpose: factor out code common to all handles
//
// Interface: operator== --
// operator!= --
// operator== --
// operator!= --
// operator== --
// operator!= --
// autohandle_base --
// ~autohandle_base --
// IsWrongHandle --
// m_handle --
//
// History: 5-13-1998 ericne Created
//
// Notes:
//
//----------------------------------------------------------------------------
class autohandle_base
{
public:
// Comparison operators
inline bool operator==( const autohandle_base & right ) const
{
#ifdef _DEBUG
if( IsWrongHandle( right.m_handle ) )
_RPT1( _CRT_ASSERT, "Bad handle comparison detected!"
" this = %p", this );
#endif
return ( m_handle == right.m_handle );
}
inline bool operator!=( const autohandle_base & right ) const
{
return ! operator==( right );
}
// For comparisons with HANDLE types, including INVALID_HANDLE_VALUE
friend inline bool operator==( const HANDLE left,
const autohandle_base & right )
{
return right.operator==( left );
}
friend inline bool operator!=( const HANDLE left,
const autohandle_base & right )
{
return ! right.operator==( left );
}
inline bool operator==( const HANDLE right ) const
{
#ifdef _DEBUG
if( IsWrongHandle( right ) )
_RPT1( _CRT_ASSERT, "Bad handle comparison detected!"
" this = %p", this );
#endif
return ( m_handle == right );
}
inline bool operator!=( const HANDLE right ) const
{
return ! operator==( right );
}
// These are for comparisons with NULL
friend inline bool operator==( const int left,
const autohandle_base & right )
{
return right.operator==( left );
}
friend inline int operator!=( const int left,
const autohandle_base & right )
{
return ! right.operator==( left );
}
inline bool operator==( const int right ) const
{
#ifdef _DEBUG
if( IsWrongHandle( (HANDLE)right ) )
_RPT1( _CRT_ASSERT, "Bad handle comparison detected!"
" this = %p", this );
#endif
return ( m_handle == (HANDLE)right );
}
inline bool operator!=( const int right ) const
{
return ! operator==( right );
}
protected:
autohandle_base( HANDLE h ) : m_handle( h ) {}
virtual ~autohandle_base() {}
virtual bool IsWrongHandle( const HANDLE ) const = 0;
HANDLE m_handle;
};
//+---------------------------------------------------------------------------
//
// Class: basic_autohandle ()
//
// Purpose: To simplify the use of handles, and to prevent handle leaks
//
// Interface:
//
// History: 1-15-1997 ericne Created
//
// Notes: It is a template on UINT_PTR instead of HANDLE because you
// cannot template on a void pointer. The second template
// argument is the function to call in the destructor.
//
//----------------------------------------------------------------------------
template< UINT_PTR H, BOOL (*CLOSE)(HANDLE) >
class basic_autohandle : public autohandle_base
{
public:
basic_autohandle( const HANDLE ToCopy = (HANDLE)H )
: autohandle_base( ToCopy ),
m_pulRefCount( NULL )
{
if( NOT_NULL_OR_INVALID( m_handle ) )
m_pulRefCount = NEW LONG(1);
#ifdef _DEBUG
if( IsWrongHandle( ToCopy ) )
_RPT1( _CRT_ASSERT, "Bad handle assignment detected!"
" this = %p", this );
#endif
}
basic_autohandle( const basic_autohandle<H,CLOSE>& ToCopy )
: autohandle_base( ToCopy.m_handle ),
m_pulRefCount( ToCopy.m_pulRefCount )
{
if( NOT_NULL_OR_INVALID( m_handle ) )
{
_ASSERT( NULL != m_pulRefCount );
(void)AddRef();
}
#ifdef _DEBUG
if( IsWrongHandle( ToCopy.m_handle ) )
_RPT1( _CRT_ASSERT, "Bad handle assignment detected!"
" this = %p", this );
#endif
}
virtual ~basic_autohandle()
{
(void)Release();
}
basic_autohandle<H,CLOSE> & operator=(
const basic_autohandle<H,CLOSE> & ToCopy )
{
if( ( this != &ToCopy ) && ( m_handle != ToCopy.m_handle ) )
{
this->basic_autohandle<H,CLOSE>::~basic_autohandle<H,CLOSE>();
this->basic_autohandle<H,CLOSE>::basic_autohandle<H,CLOSE>(ToCopy);
}
return *this;
}
basic_autohandle<H,CLOSE> & operator=( const HANDLE ToCopy )
{
if( m_handle != ToCopy )
{
this->basic_autohandle<H,CLOSE>::~basic_autohandle<H,CLOSE>();
this->basic_autohandle<H,CLOSE>::basic_autohandle<H,CLOSE>(ToCopy);
}
return *this;
}
inline HANDLE GetHandle()
{
return m_handle;
}
//
// These are for controlling the reference count on the handle
// These should not be needed usually, since the other members
// maintain the ref count. Use Release to Close a handle before
// the handle object goes out of scope
//
ULONG AddRef()
{
if( NULL == m_pulRefCount )
return 0;
return InterlockedIncrement( m_pulRefCount );
}
ULONG Release()
{
if( NULL == m_pulRefCount )
return 0;
ULONG ulToReturn = InterlockedDecrement( m_pulRefCount );
if( 0 == ulToReturn )
{
if( NOT_NULL_OR_INVALID( m_handle ) )
{
if( ! CLOSE( m_handle ) )
_RPT1( _CRT_WARN, "Failed to close a handle. GetLast"
"Error() returned 0x%08X", GetLastError() );
m_handle = (HANDLE)H;
}
delete m_pulRefCount;
m_pulRefCount = NULL;
}
return ulToReturn;
}
protected:
virtual bool IsWrongHandle( const HANDLE ToCopy ) const
{
return( ~H == (UINT_PTR)ToCopy );
}
LONG * m_pulRefCount;
};
//
// These are the most commonly used handles
//
// The AutoHandle has a default value of NULL ( 0 ) and calls CloseHandle
typedef basic_autohandle< (UINT_PTR) NULL, CloseHandle > CAutoHandle;
// The FileHandle has a default value of INVALID_HANDLE_VALUE ( -1 )
// and calls CloseHandle
typedef basic_autohandle< (UINT_PTR) INVALID_HANDLE_VALUE, CloseHandle >
CFileHandle;
// The FindHandle has a default value of INVALID_HANDLE_VALUE ( -1 )
// and calls FindClose
typedef basic_autohandle< (UINT_PTR) INVALID_HANDLE_VALUE, FindClose >
CFindHandle;
//+---------------------------------------------------------------------------
//
// Class: RegKeyHandle ()
//
// Purpose: Smart registry key handle which closes itself when it
// goes out of scope.
//
// Interface:
//
// History: 11-08-1996 ericne Created
//
// Notes:
//
//----------------------------------------------------------------------------
class RegKeyHandle
{
public:
RegKeyHandle() : m_hKey( NULL ) {}
RegKeyHandle( const HKEY& hKey ) : m_hKey( hKey ) {}
~RegKeyHandle()
{
if( NOT_NULL_OR_INVALID( m_hKey ) )
{
LONG lRetVal = RegCloseKey( m_hKey );
if( lRetVal != ERROR_SUCCESS )
_RPT1( _CRT_WARN, "RegCloseKey returned 0x%08X\r\n",
lRetVal );
}
m_hKey = NULL;
}
RegKeyHandle & operator=( const RegKeyHandle & hKey )
{
if( ( this != &hKey ) && ( m_hKey != hKey.m_hKey ) )
{
this->RegKeyHandle::~RegKeyHandle();
this->RegKeyHandle::RegKeyHandle( hKey );
}
return *this;
}
RegKeyHandle & operator=( const HKEY & hKey )
{
if( m_hKey != hKey )
{
this->RegKeyHandle::~RegKeyHandle();
this->RegKeyHandle::RegKeyHandle( hKey );
}
return *this;
}
operator HKEY()
{
return m_hKey;
}
operator PHKEY()
{
return &m_hKey;
}
bool operator==( const int right )
{
return (int)( (void *const)right == m_hKey );
}
bool operator!=( const int right )
{
return (int)( (void *const)right != m_hKey );
}
friend bool operator==( const int left, const RegKeyHandle & right )
{
return( (void *const)left == right.m_hKey );
}
friend bool operator!=( const int left, const RegKeyHandle & right )
{
return( (void *const)left != right.m_hKey );
}
private:
HKEY m_hKey;
};
#endif