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
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
|
|
|