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.
453 lines
11 KiB
453 lines
11 KiB
// Fax Common Functions Definitions
|
|
|
|
#ifndef __FAXCOMMON_H_
|
|
#define __FAXCOMMON_H_
|
|
|
|
#include "FaxStrings.h"
|
|
#include <new>
|
|
//
|
|
// Class: CComContainedObject2
|
|
// Author: ronenbar
|
|
// Date: 20-Dec-2001
|
|
//
|
|
// This is modified version of ATL's CComContainedObject.
|
|
// It implements IUnknown so the life time of an object inherited from
|
|
// it is managed by the controlling uknown (AddRef and Release are delegated to
|
|
// the controlling unknown.
|
|
// However, unlike the original class this class DOES NOT DELEGATE QueryInterface
|
|
// to the controlling IUnknown.
|
|
// This is useful when implementing a contained object which is returned via a container
|
|
// object method and not via its QueryInterface. I.e. the contrainer is not an aggregator
|
|
// but just want the embedded object life time to be managed by the container.
|
|
//
|
|
//
|
|
|
|
template <class Base> //Base must be derived from CComObjectRoot
|
|
class CComContainedObject2 : public Base
|
|
{
|
|
public:
|
|
typedef Base _BaseClass;
|
|
CComContainedObject2(void* pv) {m_pOuterUnknown = (IUnknown*)pv;}
|
|
#ifdef _ATL_DEBUG_INTERFACES
|
|
~CComContainedObject2()
|
|
{
|
|
_Module.DeleteNonAddRefThunk(_GetRawUnknown());
|
|
_Module.DeleteNonAddRefThunk(m_pOuterUnknown);
|
|
}
|
|
#endif
|
|
|
|
STDMETHOD_(ULONG, AddRef)() {return OuterAddRef();}
|
|
STDMETHOD_(ULONG, Release)() {return OuterRelease();}
|
|
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
|
|
{
|
|
HRESULT hr;
|
|
//
|
|
// Don't delegate QueryInterface to the control IUnknown
|
|
//
|
|
hr = _InternalQueryInterface(iid, ppvObject);
|
|
return hr;
|
|
}
|
|
template <class Q>
|
|
HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp)
|
|
{
|
|
return QueryInterface(__uuidof(Q), (void**)pp);
|
|
}
|
|
//GetControllingUnknown may be virtual if the Base class has declared
|
|
//DECLARE_GET_CONTROLLING_UNKNOWN()
|
|
IUnknown* GetControllingUnknown()
|
|
{
|
|
#ifdef _ATL_DEBUG_INTERFACES
|
|
IUnknown* p;
|
|
_Module.AddNonAddRefThunk(m_pOuterUnknown, _T("CComContainedObject2"), &p);
|
|
return p;
|
|
#else
|
|
return m_pOuterUnknown;
|
|
#endif
|
|
}
|
|
};
|
|
|
|
inline
|
|
HRESULT Fax_HRESULT_FROM_WIN32 (DWORD dwWin32Err)
|
|
{
|
|
if (dwWin32Err >= FAX_ERR_START && dwWin32Err <= FAX_ERR_END)
|
|
{
|
|
//
|
|
// Fax specific error code - make a HRESULT using FACILITY_ITF
|
|
//
|
|
return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, dwWin32Err);
|
|
}
|
|
else
|
|
{
|
|
return HRESULT_FROM_WIN32(dwWin32Err);
|
|
}
|
|
} // Fax_HRESULT_FROM_WIN32
|
|
|
|
//
|
|
//================ PRIVATE INTERFACE FOR FAX SERVER ===========================
|
|
//
|
|
MIDL_INTERFACE("80459F70-BBC8-4d68-8EAB-75516195EB02")
|
|
IFaxServerInner : public IUnknown
|
|
{
|
|
STDMETHOD(GetHandle)(/*[out, retval]*/ HANDLE* pFaxHandle) = 0;
|
|
};
|
|
|
|
|
|
//
|
|
//=========== TRANSLATION BETWEEN BOOL OF C++ AND BOOL OF VB ==============
|
|
//
|
|
#define bool2VARIANT_BOOL(b) ((b) ? VARIANT_TRUE : VARIANT_FALSE)
|
|
#define VARIANT_BOOL2bool(b) ((VARIANT_TRUE == (b)) ? true : false)
|
|
|
|
|
|
//
|
|
//================ INIT INNER private interface ===========================
|
|
//
|
|
MIDL_INTERFACE("D0C7F049-22C1-441c-A2F4-675CC53BDF81")
|
|
IFaxInitInner : public IUnknown
|
|
{
|
|
STDMETHOD(Init)(/*[in]*/ IFaxServerInner* pServer) = 0;
|
|
STDMETHOD(GetFaxHandle)(/*[out]*/ HANDLE *pFaxHandle) = 0;
|
|
};
|
|
|
|
|
|
//
|
|
//================== INIT INNER IMPLEMENTATION -- NO ADDREF ON SERVER ==================
|
|
//
|
|
#define MAX_LENGTH 50
|
|
|
|
class CFaxInitInner : public IFaxInitInner
|
|
{
|
|
public:
|
|
CFaxInitInner(TCHAR *tcObjectName) : m_pIFaxServerInner(NULL)
|
|
{
|
|
DBG_ENTER(_T("FAX INIT INNER::CREATE"), _T("ObjectName = %s"), tcObjectName);
|
|
_tcsncpy(m_tstrObjectName, tcObjectName, MAX_LENGTH);
|
|
|
|
}
|
|
|
|
~CFaxInitInner()
|
|
{
|
|
DBG_ENTER(_T("FAX INIT INNER::DESTROY"), _T("ObjectName = %s"), m_tstrObjectName);
|
|
}
|
|
|
|
STDMETHOD(Init)(/*[in]*/ IFaxServerInner* pServer);
|
|
STDMETHOD(GetFaxHandle)(/*[out]*/ HANDLE *pFaxHandle);
|
|
|
|
protected:
|
|
IFaxServerInner* m_pIFaxServerInner;
|
|
private:
|
|
TCHAR m_tstrObjectName[MAX_LENGTH];
|
|
};
|
|
|
|
|
|
//
|
|
//================== INIT INNER IMPLEMENTATION -- PLUS ADDREF ON SERVER ==================
|
|
//
|
|
class CFaxInitInnerAddRef : public CFaxInitInner
|
|
{
|
|
public:
|
|
CFaxInitInnerAddRef(TCHAR *tcObjectName) : CFaxInitInner(tcObjectName)
|
|
{}
|
|
|
|
~CFaxInitInnerAddRef()
|
|
{
|
|
if(m_pIFaxServerInner)
|
|
{
|
|
m_pIFaxServerInner->Release();
|
|
}
|
|
}
|
|
|
|
STDMETHOD(Init)(/*[in]*/ IFaxServerInner* pServer)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DBG_ENTER(_T("CFaxInitInnerAddRef::Init"));
|
|
hr = CFaxInitInner::Init(pServer);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
m_pIFaxServerInner->AddRef();
|
|
}
|
|
return hr;
|
|
};
|
|
};
|
|
|
|
|
|
//
|
|
//================ COMMON FUNCTONS ============================================
|
|
//
|
|
LPCTSTR GetErrorMsgId(HRESULT hRes);
|
|
HRESULT SystemTime2LocalDate(SYSTEMTIME sysTimeFrom, DATE *pdtTo);
|
|
HRESULT VarByteSA2Binary(VARIANT varFrom, BYTE **ppbData);
|
|
HRESULT Binary2VarByteSA(BYTE *pbDataFrom, VARIANT *pvarTo, DWORD dwLength);
|
|
HRESULT GetBstr(BSTR *pbstrTo, BSTR bstrFrom);
|
|
HRESULT GetVariantBool(VARIANT_BOOL *pbTo, VARIANT_BOOL bFrom);
|
|
HRESULT GetLong(long *plTo, long lFrom);
|
|
HRESULT SetExtensionProperty(IFaxServerInner *pServer, long lDeviceId, BSTR bstrGUID, VARIANT vProperty);
|
|
HRESULT GetExtensionProperty(IFaxServerInner *pServer, long lDeviceId, BSTR bstrGUID, VARIANT *pvProperty);
|
|
HRESULT GetBstrFromDwordlong(/*[in]*/ DWORDLONG dwlFrom, /*[out]*/ BSTR *pbstrTo);
|
|
|
|
//
|
|
//================== FAX SMART PTR -- BASE VERSION ==================================
|
|
//
|
|
template <typename T>
|
|
class CFaxPtrBase
|
|
{
|
|
private:
|
|
virtual void Free()
|
|
{
|
|
DBG_ENTER(_T("CFaxPtrBase::Free()"), _T("PTR:%ld"), p);
|
|
if (p)
|
|
{
|
|
FaxFreeBuffer(p);
|
|
p = NULL;
|
|
}
|
|
}
|
|
|
|
public:
|
|
CFaxPtrBase()
|
|
{
|
|
p = NULL;
|
|
}
|
|
|
|
virtual ~CFaxPtrBase()
|
|
{
|
|
Free();
|
|
}
|
|
|
|
T** operator&()
|
|
{
|
|
ATLASSERT(p==NULL);
|
|
return &p;
|
|
}
|
|
|
|
bool operator!() const
|
|
{
|
|
return (p == NULL);
|
|
}
|
|
|
|
operator T*() const
|
|
{
|
|
return (T*)p;
|
|
}
|
|
|
|
T* operator=(T* lp)
|
|
{
|
|
DBG_ENTER(_T("CFaxPtrBase::operator=()"));
|
|
Free();
|
|
p = lp;
|
|
return (T*)p;
|
|
}
|
|
|
|
T* Detach()
|
|
{
|
|
T* pt = p;
|
|
p = NULL;
|
|
return pt;
|
|
}
|
|
|
|
T* p;
|
|
};
|
|
|
|
//
|
|
//================== FAX SMART PTR -- FULL VERSION ==================================
|
|
//
|
|
template <typename T>
|
|
class CFaxPtr : public CFaxPtrBase<T>
|
|
{
|
|
public:
|
|
T* operator->() const
|
|
{
|
|
ATLASSERT(p!=NULL);
|
|
return (T*)p;
|
|
}
|
|
};
|
|
|
|
//
|
|
//======================== OBJECT HANDLER ======================================
|
|
//
|
|
template<typename ClassName, typename IfcType>
|
|
class CObjectHandler
|
|
{
|
|
public :
|
|
//
|
|
//=================== GET CONTAINED OBJECT =============================================
|
|
//
|
|
HRESULT GetContainedObject(IfcType **ppObject,
|
|
CComContainedObject2<ClassName> **ppInstanceVar,
|
|
IFaxServerInner *pServerInner)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DBG_ENTER (_T("CObjectHandler::GetContainedObject"), hr);
|
|
|
|
//
|
|
// Check that we have got a good ptr
|
|
//
|
|
if (::IsBadWritePtr(ppObject, sizeof(IfcType *)))
|
|
{
|
|
hr = E_POINTER;
|
|
CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr()"), hr);
|
|
return hr;
|
|
}
|
|
|
|
if (!*ppInstanceVar)
|
|
{
|
|
hr = CreateContainedObject(ppInstanceVar, pServerInner);
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
hr = (*ppInstanceVar)->QueryInterface(ppObject);
|
|
if (FAILED(hr))
|
|
{
|
|
hr = E_FAIL;
|
|
CALL_FAIL(GENERAL_ERR, _T("(*ppInstanceVar)->QueryInterface(ppObject)"), hr);
|
|
return hr;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
//=================== CREATE CONTAINED OBJECT =============================================
|
|
//
|
|
HRESULT CreateContainedObject(CComContainedObject2<ClassName> **ppObject, IFaxServerInner *pServerInner)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DBG_ENTER (_T("CObjectHandler::CreateObject"), hr);
|
|
|
|
//
|
|
// Create the Object
|
|
//
|
|
*ppObject = new (std::nothrow) CComContainedObject2<ClassName>(pServerInner);
|
|
if (!*ppObject)
|
|
{
|
|
//
|
|
// Failed to create the ppObject
|
|
//
|
|
hr = E_OUTOFMEMORY;
|
|
CALL_FAIL(MEM_ERR, _T("new CComContainedObject2<ClassName>(pServerInner)"), hr);
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Init the Object
|
|
//
|
|
hr = (*ppObject)->Init(pServerInner);
|
|
if (FAILED(hr))
|
|
{
|
|
//
|
|
// Failed to Init the Object
|
|
//
|
|
CALL_FAIL(GENERAL_ERR, _T("(*ppObject)->Init(pServerInner)"), hr);
|
|
return hr;
|
|
}
|
|
|
|
return hr;
|
|
};
|
|
|
|
//
|
|
//=================== GET OBJECT =============================================
|
|
//
|
|
HRESULT GetObject(IfcType **ppObject, IFaxServerInner *pServerInner)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DBG_ENTER (TEXT("CObjectHandler::GetObject"), hr);
|
|
|
|
//
|
|
// Check that we have got a good ptr
|
|
//
|
|
if (::IsBadWritePtr(ppObject, sizeof(IfcType *)))
|
|
{
|
|
hr = E_POINTER;
|
|
CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr()"), hr);
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Create new Object
|
|
//
|
|
CComPtr<IfcType> pObjectTmp;
|
|
hr = ClassName::Create(&pObjectTmp);
|
|
if (FAILED(hr))
|
|
{
|
|
CALL_FAIL(GENERAL_ERR, _T("ClassName::Create(&pObjectTmp)"), hr);
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Get IFaxInitInner Interface from the Object
|
|
//
|
|
CComQIPtr<IFaxInitInner> pObjectInit(pObjectTmp);
|
|
ATLASSERT(pObjectInit);
|
|
|
|
//
|
|
// Initialize the Object
|
|
//
|
|
hr = pObjectInit->Init(pServerInner);
|
|
if (FAILED(hr))
|
|
{
|
|
CALL_FAIL(GENERAL_ERR, _T("pObjectInit->Init(pServerInner)"), hr);
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Return the Object
|
|
//
|
|
hr = pObjectTmp.CopyTo(ppObject);
|
|
if (FAILED(hr))
|
|
{
|
|
CALL_FAIL(GENERAL_ERR, _T("CComPtr::CopyTo"), hr);
|
|
return hr;
|
|
}
|
|
return hr;
|
|
};
|
|
};
|
|
|
|
//
|
|
//====================== COLLECTION KILLER =========================================
|
|
//
|
|
template <typename ContainerType>
|
|
class CCollectionKiller
|
|
{
|
|
public:
|
|
STDMETHODIMP EmptyObjectCollection(ContainerType *pColl)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DBG_ENTER(_T("CCollectionKiller::EmptyObjectCollection"));
|
|
|
|
//
|
|
// Release all objects
|
|
//
|
|
ContainerType::iterator it = pColl->begin();
|
|
while ( it != pColl->end())
|
|
{
|
|
(*it++)->Release();
|
|
}
|
|
|
|
hr = ClearCollection(pColl);
|
|
return hr;
|
|
};
|
|
|
|
STDMETHODIMP ClearCollection(ContainerType *pColl)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DBG_ENTER(_T("CCollectionKiller::ClearCollection"), hr);
|
|
|
|
//
|
|
// Pop the Objects from the Collection
|
|
//
|
|
try
|
|
{
|
|
pColl->clear();
|
|
}
|
|
catch (exception &)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
CALL_FAIL(MEM_ERR, _T("pColl->clear()"), hr);
|
|
}
|
|
return hr;
|
|
};
|
|
};
|
|
|
|
#endif // __FAXCOMMON_H_
|