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.

453 lines
11 KiB

  1. // Fax Common Functions Definitions
  2. #ifndef __FAXCOMMON_H_
  3. #define __FAXCOMMON_H_
  4. #include "FaxStrings.h"
  5. #include <new>
  6. //
  7. // Class: CComContainedObject2
  8. // Author: ronenbar
  9. // Date: 20-Dec-2001
  10. //
  11. // This is modified version of ATL's CComContainedObject.
  12. // It implements IUnknown so the life time of an object inherited from
  13. // it is managed by the controlling uknown (AddRef and Release are delegated to
  14. // the controlling unknown.
  15. // However, unlike the original class this class DOES NOT DELEGATE QueryInterface
  16. // to the controlling IUnknown.
  17. // This is useful when implementing a contained object which is returned via a container
  18. // object method and not via its QueryInterface. I.e. the contrainer is not an aggregator
  19. // but just want the embedded object life time to be managed by the container.
  20. //
  21. //
  22. template <class Base> //Base must be derived from CComObjectRoot
  23. class CComContainedObject2 : public Base
  24. {
  25. public:
  26. typedef Base _BaseClass;
  27. CComContainedObject2(void* pv) {m_pOuterUnknown = (IUnknown*)pv;}
  28. #ifdef _ATL_DEBUG_INTERFACES
  29. ~CComContainedObject2()
  30. {
  31. _Module.DeleteNonAddRefThunk(_GetRawUnknown());
  32. _Module.DeleteNonAddRefThunk(m_pOuterUnknown);
  33. }
  34. #endif
  35. STDMETHOD_(ULONG, AddRef)() {return OuterAddRef();}
  36. STDMETHOD_(ULONG, Release)() {return OuterRelease();}
  37. STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
  38. {
  39. HRESULT hr;
  40. //
  41. // Don't delegate QueryInterface to the control IUnknown
  42. //
  43. hr = _InternalQueryInterface(iid, ppvObject);
  44. return hr;
  45. }
  46. template <class Q>
  47. HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp)
  48. {
  49. return QueryInterface(__uuidof(Q), (void**)pp);
  50. }
  51. //GetControllingUnknown may be virtual if the Base class has declared
  52. //DECLARE_GET_CONTROLLING_UNKNOWN()
  53. IUnknown* GetControllingUnknown()
  54. {
  55. #ifdef _ATL_DEBUG_INTERFACES
  56. IUnknown* p;
  57. _Module.AddNonAddRefThunk(m_pOuterUnknown, _T("CComContainedObject2"), &p);
  58. return p;
  59. #else
  60. return m_pOuterUnknown;
  61. #endif
  62. }
  63. };
  64. inline
  65. HRESULT Fax_HRESULT_FROM_WIN32 (DWORD dwWin32Err)
  66. {
  67. if (dwWin32Err >= FAX_ERR_START && dwWin32Err <= FAX_ERR_END)
  68. {
  69. //
  70. // Fax specific error code - make a HRESULT using FACILITY_ITF
  71. //
  72. return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, dwWin32Err);
  73. }
  74. else
  75. {
  76. return HRESULT_FROM_WIN32(dwWin32Err);
  77. }
  78. } // Fax_HRESULT_FROM_WIN32
  79. //
  80. //================ PRIVATE INTERFACE FOR FAX SERVER ===========================
  81. //
  82. MIDL_INTERFACE("80459F70-BBC8-4d68-8EAB-75516195EB02")
  83. IFaxServerInner : public IUnknown
  84. {
  85. STDMETHOD(GetHandle)(/*[out, retval]*/ HANDLE* pFaxHandle) = 0;
  86. };
  87. //
  88. //=========== TRANSLATION BETWEEN BOOL OF C++ AND BOOL OF VB ==============
  89. //
  90. #define bool2VARIANT_BOOL(b) ((b) ? VARIANT_TRUE : VARIANT_FALSE)
  91. #define VARIANT_BOOL2bool(b) ((VARIANT_TRUE == (b)) ? true : false)
  92. //
  93. //================ INIT INNER private interface ===========================
  94. //
  95. MIDL_INTERFACE("D0C7F049-22C1-441c-A2F4-675CC53BDF81")
  96. IFaxInitInner : public IUnknown
  97. {
  98. STDMETHOD(Init)(/*[in]*/ IFaxServerInner* pServer) = 0;
  99. STDMETHOD(GetFaxHandle)(/*[out]*/ HANDLE *pFaxHandle) = 0;
  100. };
  101. //
  102. //================== INIT INNER IMPLEMENTATION -- NO ADDREF ON SERVER ==================
  103. //
  104. #define MAX_LENGTH 50
  105. class CFaxInitInner : public IFaxInitInner
  106. {
  107. public:
  108. CFaxInitInner(TCHAR *tcObjectName) : m_pIFaxServerInner(NULL)
  109. {
  110. DBG_ENTER(_T("FAX INIT INNER::CREATE"), _T("ObjectName = %s"), tcObjectName);
  111. _tcsncpy(m_tstrObjectName, tcObjectName, MAX_LENGTH);
  112. }
  113. ~CFaxInitInner()
  114. {
  115. DBG_ENTER(_T("FAX INIT INNER::DESTROY"), _T("ObjectName = %s"), m_tstrObjectName);
  116. }
  117. STDMETHOD(Init)(/*[in]*/ IFaxServerInner* pServer);
  118. STDMETHOD(GetFaxHandle)(/*[out]*/ HANDLE *pFaxHandle);
  119. protected:
  120. IFaxServerInner* m_pIFaxServerInner;
  121. private:
  122. TCHAR m_tstrObjectName[MAX_LENGTH];
  123. };
  124. //
  125. //================== INIT INNER IMPLEMENTATION -- PLUS ADDREF ON SERVER ==================
  126. //
  127. class CFaxInitInnerAddRef : public CFaxInitInner
  128. {
  129. public:
  130. CFaxInitInnerAddRef(TCHAR *tcObjectName) : CFaxInitInner(tcObjectName)
  131. {}
  132. ~CFaxInitInnerAddRef()
  133. {
  134. if(m_pIFaxServerInner)
  135. {
  136. m_pIFaxServerInner->Release();
  137. }
  138. }
  139. STDMETHOD(Init)(/*[in]*/ IFaxServerInner* pServer)
  140. {
  141. HRESULT hr = S_OK;
  142. DBG_ENTER(_T("CFaxInitInnerAddRef::Init"));
  143. hr = CFaxInitInner::Init(pServer);
  144. if (SUCCEEDED(hr))
  145. {
  146. m_pIFaxServerInner->AddRef();
  147. }
  148. return hr;
  149. };
  150. };
  151. //
  152. //================ COMMON FUNCTONS ============================================
  153. //
  154. LPCTSTR GetErrorMsgId(HRESULT hRes);
  155. HRESULT SystemTime2LocalDate(SYSTEMTIME sysTimeFrom, DATE *pdtTo);
  156. HRESULT VarByteSA2Binary(VARIANT varFrom, BYTE **ppbData);
  157. HRESULT Binary2VarByteSA(BYTE *pbDataFrom, VARIANT *pvarTo, DWORD dwLength);
  158. HRESULT GetBstr(BSTR *pbstrTo, BSTR bstrFrom);
  159. HRESULT GetVariantBool(VARIANT_BOOL *pbTo, VARIANT_BOOL bFrom);
  160. HRESULT GetLong(long *plTo, long lFrom);
  161. HRESULT SetExtensionProperty(IFaxServerInner *pServer, long lDeviceId, BSTR bstrGUID, VARIANT vProperty);
  162. HRESULT GetExtensionProperty(IFaxServerInner *pServer, long lDeviceId, BSTR bstrGUID, VARIANT *pvProperty);
  163. HRESULT GetBstrFromDwordlong(/*[in]*/ DWORDLONG dwlFrom, /*[out]*/ BSTR *pbstrTo);
  164. //
  165. //================== FAX SMART PTR -- BASE VERSION ==================================
  166. //
  167. template <typename T>
  168. class CFaxPtrBase
  169. {
  170. private:
  171. virtual void Free()
  172. {
  173. DBG_ENTER(_T("CFaxPtrBase::Free()"), _T("PTR:%ld"), p);
  174. if (p)
  175. {
  176. FaxFreeBuffer(p);
  177. p = NULL;
  178. }
  179. }
  180. public:
  181. CFaxPtrBase()
  182. {
  183. p = NULL;
  184. }
  185. virtual ~CFaxPtrBase()
  186. {
  187. Free();
  188. }
  189. T** operator&()
  190. {
  191. ATLASSERT(p==NULL);
  192. return &p;
  193. }
  194. bool operator!() const
  195. {
  196. return (p == NULL);
  197. }
  198. operator T*() const
  199. {
  200. return (T*)p;
  201. }
  202. T* operator=(T* lp)
  203. {
  204. DBG_ENTER(_T("CFaxPtrBase::operator=()"));
  205. Free();
  206. p = lp;
  207. return (T*)p;
  208. }
  209. T* Detach()
  210. {
  211. T* pt = p;
  212. p = NULL;
  213. return pt;
  214. }
  215. T* p;
  216. };
  217. //
  218. //================== FAX SMART PTR -- FULL VERSION ==================================
  219. //
  220. template <typename T>
  221. class CFaxPtr : public CFaxPtrBase<T>
  222. {
  223. public:
  224. T* operator->() const
  225. {
  226. ATLASSERT(p!=NULL);
  227. return (T*)p;
  228. }
  229. };
  230. //
  231. //======================== OBJECT HANDLER ======================================
  232. //
  233. template<typename ClassName, typename IfcType>
  234. class CObjectHandler
  235. {
  236. public :
  237. //
  238. //=================== GET CONTAINED OBJECT =============================================
  239. //
  240. HRESULT GetContainedObject(IfcType **ppObject,
  241. CComContainedObject2<ClassName> **ppInstanceVar,
  242. IFaxServerInner *pServerInner)
  243. {
  244. HRESULT hr = S_OK;
  245. DBG_ENTER (_T("CObjectHandler::GetContainedObject"), hr);
  246. //
  247. // Check that we have got a good ptr
  248. //
  249. if (::IsBadWritePtr(ppObject, sizeof(IfcType *)))
  250. {
  251. hr = E_POINTER;
  252. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr()"), hr);
  253. return hr;
  254. }
  255. if (!*ppInstanceVar)
  256. {
  257. hr = CreateContainedObject(ppInstanceVar, pServerInner);
  258. if (FAILED(hr))
  259. {
  260. return hr;
  261. }
  262. }
  263. hr = (*ppInstanceVar)->QueryInterface(ppObject);
  264. if (FAILED(hr))
  265. {
  266. hr = E_FAIL;
  267. CALL_FAIL(GENERAL_ERR, _T("(*ppInstanceVar)->QueryInterface(ppObject)"), hr);
  268. return hr;
  269. }
  270. return hr;
  271. }
  272. //
  273. //=================== CREATE CONTAINED OBJECT =============================================
  274. //
  275. HRESULT CreateContainedObject(CComContainedObject2<ClassName> **ppObject, IFaxServerInner *pServerInner)
  276. {
  277. HRESULT hr = S_OK;
  278. DBG_ENTER (_T("CObjectHandler::CreateObject"), hr);
  279. //
  280. // Create the Object
  281. //
  282. *ppObject = new (std::nothrow) CComContainedObject2<ClassName>(pServerInner);
  283. if (!*ppObject)
  284. {
  285. //
  286. // Failed to create the ppObject
  287. //
  288. hr = E_OUTOFMEMORY;
  289. CALL_FAIL(MEM_ERR, _T("new CComContainedObject2<ClassName>(pServerInner)"), hr);
  290. return hr;
  291. }
  292. //
  293. // Init the Object
  294. //
  295. hr = (*ppObject)->Init(pServerInner);
  296. if (FAILED(hr))
  297. {
  298. //
  299. // Failed to Init the Object
  300. //
  301. CALL_FAIL(GENERAL_ERR, _T("(*ppObject)->Init(pServerInner)"), hr);
  302. return hr;
  303. }
  304. return hr;
  305. };
  306. //
  307. //=================== GET OBJECT =============================================
  308. //
  309. HRESULT GetObject(IfcType **ppObject, IFaxServerInner *pServerInner)
  310. {
  311. HRESULT hr = S_OK;
  312. DBG_ENTER (TEXT("CObjectHandler::GetObject"), hr);
  313. //
  314. // Check that we have got a good ptr
  315. //
  316. if (::IsBadWritePtr(ppObject, sizeof(IfcType *)))
  317. {
  318. hr = E_POINTER;
  319. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr()"), hr);
  320. return hr;
  321. }
  322. //
  323. // Create new Object
  324. //
  325. CComPtr<IfcType> pObjectTmp;
  326. hr = ClassName::Create(&pObjectTmp);
  327. if (FAILED(hr))
  328. {
  329. CALL_FAIL(GENERAL_ERR, _T("ClassName::Create(&pObjectTmp)"), hr);
  330. return hr;
  331. }
  332. //
  333. // Get IFaxInitInner Interface from the Object
  334. //
  335. CComQIPtr<IFaxInitInner> pObjectInit(pObjectTmp);
  336. ATLASSERT(pObjectInit);
  337. //
  338. // Initialize the Object
  339. //
  340. hr = pObjectInit->Init(pServerInner);
  341. if (FAILED(hr))
  342. {
  343. CALL_FAIL(GENERAL_ERR, _T("pObjectInit->Init(pServerInner)"), hr);
  344. return hr;
  345. }
  346. //
  347. // Return the Object
  348. //
  349. hr = pObjectTmp.CopyTo(ppObject);
  350. if (FAILED(hr))
  351. {
  352. CALL_FAIL(GENERAL_ERR, _T("CComPtr::CopyTo"), hr);
  353. return hr;
  354. }
  355. return hr;
  356. };
  357. };
  358. //
  359. //====================== COLLECTION KILLER =========================================
  360. //
  361. template <typename ContainerType>
  362. class CCollectionKiller
  363. {
  364. public:
  365. STDMETHODIMP EmptyObjectCollection(ContainerType *pColl)
  366. {
  367. HRESULT hr = S_OK;
  368. DBG_ENTER(_T("CCollectionKiller::EmptyObjectCollection"));
  369. //
  370. // Release all objects
  371. //
  372. ContainerType::iterator it = pColl->begin();
  373. while ( it != pColl->end())
  374. {
  375. (*it++)->Release();
  376. }
  377. hr = ClearCollection(pColl);
  378. return hr;
  379. };
  380. STDMETHODIMP ClearCollection(ContainerType *pColl)
  381. {
  382. HRESULT hr = S_OK;
  383. DBG_ENTER(_T("CCollectionKiller::ClearCollection"), hr);
  384. //
  385. // Pop the Objects from the Collection
  386. //
  387. try
  388. {
  389. pColl->clear();
  390. }
  391. catch (exception &)
  392. {
  393. hr = E_OUTOFMEMORY;
  394. CALL_FAIL(MEM_ERR, _T("pColl->clear()"), hr);
  395. }
  396. return hr;
  397. };
  398. };
  399. #endif // __FAXCOMMON_H_