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.
 
 
 
 
 
 

818 lines
15 KiB

//*************************************************************
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1998
//
// File: smartptr.h
//
// Contents: Classes for smart pointers
//
// History: 7-Jun-99 SitaramR Created
//
// 2-Dec-99 LeonardM Major revision and cleanup.
//
//*************************************************************
#ifndef SMARTPTR_H
#define SMARTPTR_H
#include <comdef.h>
#include "userenv.h"
#pragma once
#pragma warning(disable:4284)
//*************************************************************
//
// Class: XPtrST
//
// Purpose: Smart pointer template to wrap pointers to a single type.
//
//*************************************************************
template<class T> class XPtrST
{
private:
XPtrST (const XPtrST<T>& x);
XPtrST<T>& operator=(const XPtrST<T>& x);
T* _p;
public:
XPtrST(T* p = NULL) : _p(p){}
~XPtrST(){ delete _p; }
T* operator->(){ return _p; }
T** operator&(){ return &_p; }
operator T*(){ return _p; }
void operator=(T* p)
{
if(_p)
{
delete _p;
}
_p = p;
}
T* Acquire()
{
T* p = _p;
_p = 0;
return p;
}
};
//*************************************************************
//
// Class: XPtrArray
//
// Purpose: Smart pointer template to wrap pointers to an array .
//
//*************************************************************
template<class T> class XPtrArray
{
private:
XPtrArray (const XPtrArray<T>& x);
XPtrArray<T>& operator=(const XPtrArray<T>& x);
T* _p;
public:
XPtrArray(T* p = NULL) : _p(p){}
~XPtrArray(){ delete[] _p; }
T* operator->(){ return _p; }
T** operator&(){ return &_p; }
operator T*(){ return _p; }
void operator=(T* p)
{
if(_p)
{
delete[] _p;
}
_p = p;
}
T* Acquire()
{
T* p = _p;
_p = 0;
return p;
}
};
//*************************************************************
//
// Class: XInterface
//
// Purpose: Smart pointer template for items Release()'ed, not ~'ed
//
//*************************************************************
template<class T> class XInterface
{
private:
XInterface(const XInterface<T>& x);
XInterface<T>& operator=(const XInterface<T>& x);
T* _p;
public:
XInterface(T* p = NULL) : _p(p){}
~XInterface()
{
if (_p)
{
_p->Release();
}
}
T* operator->(){ return _p; }
T** operator&(){ return &_p; }
operator T*(){ return _p; }
void operator=(T* p)
{
if (_p)
{
_p->Release();
}
_p = p;
}
T* Acquire()
{
T* p = _p;
_p = 0;
return p;
}
};
//*************************************************************
//
// Class: XBStr
//
// Purpose: Smart pointer class for BSTRs
//
//*************************************************************
class XBStr
{
private:
XBStr(const XBStr& x);
XBStr& operator=(const XBStr& x);
BSTR _p;
public:
XBStr(WCHAR* p = 0) : _p(0)
{
if(p)
{
_p = SysAllocString(p);
}
}
~XBStr()
{
SysFreeString(_p);
}
operator BSTR(){ return _p; }
void operator=(WCHAR* p)
{
SysFreeString(_p);
_p = p ? SysAllocString(p) : NULL;
}
BSTR Acquire()
{
BSTR p = _p;
_p = 0;
return p;
}
};
//*************************************************************
//
// Class: XSafeArray
//
// Purpose: Smart pointer class for SafeArrays
//
//*************************************************************
class XSafeArray
{
private:
XSafeArray(const XSafeArray& x);
XSafeArray& operator=(const XSafeArray& x);
SAFEARRAY* _p;
public:
XSafeArray(SAFEARRAY* p = 0) : _p(p){}
~XSafeArray()
{
if (_p)
{
SafeArrayDestroy(_p);
}
}
operator SAFEARRAY*(){ return _p; }
SAFEARRAY ** operator&(){ return &_p; }
void operator=(SAFEARRAY* p)
{
if(_p)
{
SafeArrayDestroy(_p);
}
_p = p;
}
SAFEARRAY* Acquire()
{
SAFEARRAY* p = _p;
_p = 0;
return p;
}
};
//*************************************************************
//
// Class: XVariant
//
// Purpose: Smart pointer class for Variants
//
//*************************************************************
class XVariant
{
private:
XVariant(const XVariant& x);
XVariant& operator=(const XVariant& x);
VARIANT* _p;
public:
XVariant(VARIANT* p = 0) : _p(p){}
~XVariant()
{
if (_p)
{
VariantClear(_p);
}
}
void operator=(VARIANT* p)
{
if(_p)
{
VariantClear(_p);
}
_p = p;
}
operator VARIANT*(){ return _p; }
VARIANT* Acquire()
{
VARIANT* p = _p;
_p = 0;
return p;
}
};
//*************************************************************
//
// Class: XPtrLF
//
// Purpose: Smart pointer template for pointers that should be LocalFree()'d
//
//*************************************************************
template <typename T> class XPtrLF
{
private:
XPtrLF(const XPtrLF<T>& x);
XPtrLF<T>& operator=(const XPtrLF<T>& x);
T* _p;
public:
XPtrLF(HLOCAL p = 0 ) :
_p((T*)p)
{
}
~XPtrLF()
{
if(_p)
{
LocalFree(_p);
}
}
T* operator->(){ return _p; }
T** operator&(){ return &_p; }
operator T*(){ return _p; }
void operator=(T* p)
{
if(_p)
{
LocalFree(_p);
}
_p = p;
}
T* Acquire()
{
T* p = _p;
_p = NULL;
return p;
}
};
//*************************************************************
//
// Class: XPtr
//
// Purpose: Smart pointer template for pointers that provide
// a custom free memory routine
//
//*************************************************************
typedef HLOCAL (__stdcall *PFNFREE)(HLOCAL);
//
// usage : XPtr<SID, FreeSid> xptrSid;
//
template <typename T, PFNFREE _f> class XPtr
{
private:
XPtr(const XPtr<T, _f>& x);
XPtr<T, _f>& operator=(const XPtr<T, _f>& x);
T* _p;
public:
XPtr( HLOCAL p = 0 ) :
_p( reinterpret_cast<T*>( p ) )
{
}
~XPtr()
{
if(_p)
{
_f(_p);
}
}
T* operator->(){ return _p; }
T** operator&(){ return &_p; }
operator T*(){ return _p; }
void operator=(T* p)
{
if(_p)
{
_f(_p);
}
_p = p;
}
T* Acquire()
{
T* p = _p;
_p = NULL;
return p;
}
};
//*************************************************************
//
// Class: XArray
//
// Purpose: Smart pointer template for pointers that provide
// a custom free memory routine
//
//*************************************************************
typedef HLOCAL (__stdcall *PFNARRAYFREE)(HLOCAL, int);
//
// usage : XArray<EXPLICIT_ACCESS, 10> xaExplicitAccess( FreeAccessArray );
//
template <typename T, int nElements> class XArray
{
private:
XArray(const XArray<T,nElements>& x);
XArray<T,nElements>& operator=(const XArray<T,nElements>& x);
T* _p;
int _n;
PFNARRAYFREE _f;
public:
XArray( PFNARRAYFREE pfnFree, HLOCAL p = 0 ) :
_p( reinterpret_cast<T*>( p ) ), _f( pfnFree ), _n( nElements )
{
}
~XArray()
{
if(_p)
{
_f(_p, _n);
}
}
T* operator->(){ return _p; }
T** operator&(){ return &_p; }
operator T*(){ return _p; }
void operator=(T* p)
{
if(_p)
{
_f(_p, _n);
}
_p = p;
}
T* Acquire()
{
T* p = _p, _p = 0;
return p;
}
};
//******************************************************************************
//
// Class:
//
// Description:
//
// History: 8/20/99 leonardm Created.
//
//******************************************************************************
class XHandle
{
private:
HANDLE _h;
public:
XHandle(HANDLE h = NULL) : _h(h) {}
~XHandle()
{
if(_h && _h != INVALID_HANDLE_VALUE)
{
CloseHandle(_h);
}
}
HANDLE* operator&(){return &_h;}
operator HANDLE(){return _h;}
void operator=(HANDLE h)
{
if(_h && _h != INVALID_HANDLE_VALUE)
{
CloseHandle(_h);
}
_h = h;
}
};
class XKey
{
private:
HKEY _h;
public:
XKey(HKEY h = NULL) : _h(h) {}
~XKey()
{
if(_h && _h != INVALID_HANDLE_VALUE)
{
RegCloseKey(_h);
}
}
HKEY* operator&(){return &_h;}
operator HKEY(){return _h;}
void operator=(HKEY h)
{
if(_h && _h != INVALID_HANDLE_VALUE)
{
RegCloseKey(_h);
}
_h = h;
}
};
class XCoInitialize
{
public:
XCoInitialize()
{
m_hr = CoInitializeEx( 0, COINIT_MULTITHREADED );
};
~XCoInitialize()
{
if ( SUCCEEDED( m_hr ) )
{
CoUninitialize();
}
};
HRESULT Status()
{
return m_hr;
};
private:
HRESULT m_hr;
};
class XImpersonate
{
public:
XImpersonate() :
m_hImpToken( 0 ),
m_hThreadToken( 0 ),
m_bRevertAttempted(FALSE),
m_bImpersonated(FALSE),
m_hr(S_OK)
{
m_hr = CoImpersonateClient();
if (SUCCEEDED(m_hr))
{
m_bImpersonated = TRUE;
}
};
XImpersonate( HANDLE hToken ) :
m_hImpToken( hToken ),
m_hThreadToken( 0 ),
m_bRevertAttempted(FALSE),
m_bImpersonated(FALSE),
m_hr(S_OK)
{
if (!OpenThreadToken( GetCurrentThread(), TOKEN_IMPERSONATE, TRUE, &m_hThreadToken )) {
if (GetLastError() != ERROR_NO_TOKEN )
{
m_hr = HRESULT_FROM_WIN32(GetLastError());
}
}
if (SUCCEEDED(m_hr)) {
if (!ImpersonateLoggedOnUser( hToken )) {
m_hr = HRESULT_FROM_WIN32(GetLastError());
}
else {
m_bImpersonated = TRUE;
}
}
};
HRESULT Revert()
{
if ( m_bImpersonated )
{
m_bRevertAttempted = TRUE;
if ( m_hImpToken )
{
if (!SetThreadToken( 0, m_hThreadToken)) {
m_hr = HRESULT_FROM_WIN32(GetLastError());
}
else {
m_bImpersonated = FALSE;
m_hr = S_OK;
}
}
else
{
m_hr = CoRevertToSelf();
if (SUCCEEDED(m_hr))
{
m_bImpersonated = FALSE;
}
}
}
return m_hr;
}
~XImpersonate()
{
HRESULT hr = S_OK;
if (!m_bRevertAttempted)
{
hr = Revert();
}
if (m_hThreadToken)
{
CloseHandle(m_hThreadToken);
}
if (FAILED(hr))
{
RaiseException(Status(),
EXCEPTION_NONCONTINUABLE,
0,
NULL);
}
};
HRESULT Status()
{
return m_hr;
};
private:
HRESULT m_hr;
XHandle m_hThreadToken;
HANDLE m_hImpToken; // we don't own this
BOOL m_bImpersonated;
BOOL m_bRevertAttempted;
};
//*************************************************************
//
// Class: XCriticalPolicySection
//
// Purpose: Smart pointer for freeing Group Policy critical section
//
//*************************************************************
class XCriticalPolicySection
{
private:
HANDLE _h;
public:
XCriticalPolicySection(HANDLE h = NULL) : _h(h){}
~XCriticalPolicySection()
{
if(_h)
{
LeaveCriticalPolicySection (_h);
}
}
void operator=(HANDLE h)
{
if(_h)
{
LeaveCriticalPolicySection (_h);
}
_h = h;
}
operator bool() {return _h ? true : false;}
};
// critical section smartptr
class XCritSec
{
public:
XCritSec()
{
lpCritSec = &CritSec;
__try {
if (!InitializeCriticalSectionAndSpinCount(&CritSec, 0x80001000)) {
lpCritSec = NULL;
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
// assumption, exception is out of memory
// this is used in spewing debug messages. so cannot add a debug spew.
lpCritSec = NULL;
}
}
~XCritSec()
{
if (lpCritSec)
DeleteCriticalSection(lpCritSec);
}
operator LPCRITICAL_SECTION(){return lpCritSec;}
private:
CRITICAL_SECTION CritSec;
LPCRITICAL_SECTION lpCritSec;
};
// enter and exit critical section
class XEnterCritSec
{
public:
XEnterCritSec(LPCRITICAL_SECTION lpCritSec) : m_lpCritSec( lpCritSec )
{
if (lpCritSec)
EnterCriticalSection(lpCritSec);
};
~XEnterCritSec()
{
if (m_lpCritSec)
LeaveCriticalSection(m_lpCritSec);
};
private:
LPCRITICAL_SECTION m_lpCritSec; // we don't own this
};
//////////////////////////////////////////////////////////////////////
// XLastError
//
//
// Sets the Last Error Correctly..
//////////////////////////////////////////////////////////////////////
class XLastError
{
private:
DWORD _e;
public:
XLastError(){_e = GetLastError();}
XLastError(DWORD e) : _e(e) {}
~XLastError(){SetLastError(_e);}
void operator=(DWORD e) {_e = e;}
operator DWORD() {return _e;}
};
#endif SMARTPTR_H