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.

386 lines
9.5 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. FaxInboundRoutingMethods.cpp
  5. Abstract:
  6. Implementation of CFaxInboundRoutingMethods Class.
  7. Author:
  8. Iv Garber (IvG) Jun, 2000
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "FaxComEx.h"
  13. #include "FaxInboundRoutingMethods.h"
  14. #include "FaxInboundRoutingMethod.h"
  15. //
  16. //================== SUPPORT ERROR INFO ========================================
  17. //
  18. STDMETHODIMP
  19. CFaxInboundRoutingMethods::InterfaceSupportsErrorInfo(
  20. REFIID riid
  21. )
  22. /*++
  23. Routine name : CFaxInboundRoutingMethods::InterfaceSupportsErrorInfo
  24. Routine description:
  25. ATL's implementation of Support Error Info.
  26. Author:
  27. Iv Garber (IvG), Jun, 2000
  28. Arguments:
  29. riid [in] - Reference to the Interface.
  30. Return Value:
  31. Standard HRESULT code
  32. --*/
  33. {
  34. static const IID* arr[] =
  35. {
  36. &IID_IFaxInboundRoutingMethods
  37. };
  38. for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
  39. {
  40. if (InlineIsEqualGUID(*arr[i],riid))
  41. return S_OK;
  42. }
  43. return S_FALSE;
  44. }
  45. //
  46. //==================== CREATE ========================================
  47. //
  48. HRESULT
  49. CFaxInboundRoutingMethods::Create (
  50. IFaxInboundRoutingMethods **ppMethods
  51. )
  52. /*++
  53. Routine name : CFaxInboundRoutingMethods::Create
  54. Routine description:
  55. Static function to create the Fax Inbound Routing Methods Collection Object
  56. Author:
  57. Iv Garber (IvG), Jun, 2000
  58. Arguments:
  59. ppMethods [out] -- the new Fax Inbound Routing Methods Collection Object
  60. Return Value:
  61. Standard HRESULT code
  62. --*/
  63. {
  64. HRESULT hr = S_OK;
  65. DBG_ENTER (TEXT("CFaxInboundRoutingMethods::Create"), hr);
  66. //
  67. // Create Instance of the Collection
  68. //
  69. CComObject<CFaxInboundRoutingMethods> *pClass;
  70. hr = CComObject<CFaxInboundRoutingMethods>::CreateInstance(&pClass);
  71. if (FAILED(hr))
  72. {
  73. CALL_FAIL(GENERAL_ERR, _T("CComObject<CFaxInboundRoutingMethods>::CreateInstance(&pClass)"), hr);
  74. return hr;
  75. }
  76. //
  77. // Return the desired Interface Ptr
  78. //
  79. hr = pClass->QueryInterface(ppMethods);
  80. if (FAILED(hr))
  81. {
  82. CALL_FAIL(GENERAL_ERR, _T("pClass->QueryInterface(ppMethods)"), hr);
  83. return hr;
  84. }
  85. return hr;
  86. } // CFaxInboundRoutingMethods::Create()
  87. //
  88. //============================= INIT ============================================
  89. //
  90. STDMETHODIMP
  91. CFaxInboundRoutingMethods::Init(
  92. IFaxServerInner *pServerInner
  93. )
  94. /*++
  95. Routine name : CFaxInboundRoutingMethods::Init
  96. Routine description:
  97. Initialize the Collection :
  98. 1) get from RPC all IR Methods,
  99. 2) create COM objects for each one,
  100. 3) AddRef() each object,
  101. 4) put the Ptrs to Objects into the STL::vector.
  102. Author:
  103. Iv Garber (IvG), Jun, 2000
  104. Arguments:
  105. pServerInner [in] - Ptr to the Fax Server.
  106. Return Value:
  107. Standard HRESULT code
  108. --*/
  109. {
  110. HRESULT hr = S_OK;
  111. DBG_ENTER(_T("CFaxInboundRoutingMethods::Init"), hr);
  112. //
  113. // Get Fax Server Handle
  114. //
  115. HANDLE faxHandle;
  116. hr = pServerInner->GetHandle(&faxHandle);
  117. ATLASSERT(SUCCEEDED(hr));
  118. if (faxHandle == NULL)
  119. {
  120. //
  121. // Fax Server is not connected
  122. //
  123. hr = Fax_HRESULT_FROM_WIN32(ERROR_NOT_CONNECTED);
  124. CALL_FAIL(GENERAL_ERR, _T("faxHandle == NULL"), hr);
  125. AtlReportError(CLSID_FaxInboundRoutingMethods, GetErrorMsgId(hr), IID_IFaxInboundRoutingMethods, hr);
  126. return hr;
  127. }
  128. //
  129. // Bring from the Server all Inbound Routing Methods
  130. //
  131. DWORD dwNum = 0;
  132. CFaxPtr<FAX_GLOBAL_ROUTING_INFO> pMethods;
  133. if (!FaxEnumGlobalRoutingInfo(faxHandle, &pMethods, &dwNum))
  134. {
  135. hr = Fax_HRESULT_FROM_WIN32(GetLastError());
  136. CALL_FAIL(GENERAL_ERR, _T("FaxEnumGlobalRoutingInfo(faxHandle, &pMethods, &dwNum)"), hr);
  137. AtlReportError(CLSID_FaxInboundRoutingMethods, GetErrorMsgId(hr), IID_IFaxInboundRoutingMethods, hr);
  138. return hr;
  139. }
  140. //
  141. // Fill the Collection with Objects
  142. //
  143. CComObject<CFaxInboundRoutingMethod> *pClass = NULL;
  144. CComPtr<IFaxInboundRoutingMethod> pObject = NULL;
  145. for (DWORD i=0 ; i<dwNum ; i++ )
  146. {
  147. //
  148. // Create IR Method Object
  149. //
  150. hr = CComObject<CFaxInboundRoutingMethod>::CreateInstance(&pClass);
  151. if (FAILED(hr) || (!pClass))
  152. {
  153. if (!pClass)
  154. {
  155. hr = E_OUTOFMEMORY;
  156. CALL_FAIL(MEM_ERR, _T("CComObject<CFaxInboundRoutingMethod>::CreateInstance(&pClass)"), hr);
  157. }
  158. else
  159. {
  160. CALL_FAIL(GENERAL_ERR, _T("CComObject<CFaxInboundRoutingMethod>::CreateInstance(&pClass)"), hr);
  161. }
  162. AtlReportError(CLSID_FaxInboundRoutingMethods, GetErrorMsgId(hr), IID_IFaxInboundRoutingMethods, hr);
  163. return hr;
  164. }
  165. //
  166. // Init the IR Method Object
  167. //
  168. hr = pClass->Init(&pMethods[i], pServerInner);
  169. if (FAILED(hr))
  170. {
  171. CALL_FAIL(GENERAL_ERR, _T("pClass->Init(&pMethods[i], pServerInner)"), hr);
  172. AtlReportError(CLSID_FaxInboundRoutingMethods, GetErrorMsgId(hr), IID_IFaxInboundRoutingMethods, hr);
  173. delete pClass;
  174. return hr;
  175. }
  176. //
  177. // Get Interface from the pClass.
  178. // This will make AddRef() on the Interface.
  179. // This is the Collection's AddRef, which is freed at Collection's Dtor.
  180. //
  181. hr = pClass->QueryInterface(&pObject);
  182. if (FAILED(hr) || (!pObject))
  183. {
  184. if (!pObject)
  185. {
  186. hr = E_FAIL;
  187. }
  188. CALL_FAIL(GENERAL_ERR, _T("pClass->QueryInterface(&pObject)"), hr);
  189. AtlReportError(CLSID_FaxInboundRoutingMethods, GetErrorMsgId(hr), IID_IFaxInboundRoutingMethods, hr);
  190. delete pClass;
  191. return hr;
  192. }
  193. //
  194. // Put the Object in the collection
  195. //
  196. try
  197. {
  198. m_coll.push_back(pObject);
  199. }
  200. catch (exception &)
  201. {
  202. hr = E_OUTOFMEMORY;
  203. AtlReportError(CLSID_FaxInboundRoutingMethods, IDS_ERROR_OUTOFMEMORY, IID_IFaxInboundRoutingMethods, hr);
  204. CALL_FAIL(MEM_ERR, _T("m_coll.push_back(pObject)"), hr);
  205. //
  206. // pObject will call Release(), which will delete the pClass
  207. //
  208. return hr;
  209. }
  210. //
  211. // We want to save the current AddRef() to Collection
  212. //
  213. pObject.Detach();
  214. }
  215. return hr;
  216. }
  217. //
  218. //============================= GET ITEM =========================================
  219. //
  220. STDMETHODIMP
  221. CFaxInboundRoutingMethods::get_Item(
  222. /*[in]*/ VARIANT vIndex,
  223. /*[out, retval]*/ IFaxInboundRoutingMethod **ppMethod
  224. )
  225. /*++
  226. Routine name : CFaxInboundRoutingMethods::get_Item
  227. Routine description:
  228. Return an Item from the Collection.
  229. Author:
  230. Iv Garber (IvG), Jun, 2000
  231. Arguments:
  232. vIndex [in] - Identifier of the Item to return.
  233. ppMethod [out] - the result value
  234. Return Value:
  235. Standard HRESULT code
  236. --*/
  237. {
  238. HRESULT hr = S_OK;
  239. DBG_ENTER(_T("CFaxInboundRoutingMethods::get_Item"), hr);
  240. //
  241. // Check the Ptr we have got
  242. //
  243. if (::IsBadWritePtr(ppMethod, sizeof(IFaxInboundRoutingMethod *)))
  244. {
  245. hr = E_POINTER;
  246. AtlReportError(CLSID_FaxInboundRoutingMethods, IDS_ERROR_INVALID_ARGUMENT, IID_IFaxInboundRoutingMethods, hr);
  247. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr(ppMethod)"), hr);
  248. return hr;
  249. }
  250. CComVariant var;
  251. if (vIndex.vt != VT_BSTR)
  252. {
  253. //
  254. // vIndex is not BSTR ==> convert to VT_I4
  255. //
  256. hr = var.ChangeType(VT_I4, &vIndex);
  257. if (SUCCEEDED(hr))
  258. {
  259. VERBOSE(DBG_MSG, _T("Parameter is Number : %d"), var.lVal);
  260. //
  261. // call default ATL's implementation
  262. //
  263. hr = ICollectionOnSTLImpl<IFaxInboundRoutingMethods, ContainerType,
  264. IFaxInboundRoutingMethod*, CollectionCopyType, EnumType>::get_Item(var.lVal, ppMethod);
  265. return hr;
  266. }
  267. }
  268. //
  269. // convert to BSTR
  270. //
  271. hr = var.ChangeType(VT_BSTR, &vIndex);
  272. if (FAILED(hr))
  273. {
  274. hr = E_INVALIDARG;
  275. AtlReportError(CLSID_FaxInboundRoutingMethods, IDS_ERROR_INVALID_ARGUMENT, IID_IFaxInboundRoutingMethods, hr);
  276. CALL_FAIL(GENERAL_ERR, _T("var.ChangeType(VT_BSTR, &vIndex)"), hr);
  277. return hr;
  278. }
  279. VERBOSE(DBG_MSG, _T("Parameter is String : %s"), var.bstrVal);
  280. ContainerType::iterator it = m_coll.begin();
  281. while (it != m_coll.end())
  282. {
  283. CComBSTR bstrGUID;
  284. hr = (*it)->get_GUID(&bstrGUID);
  285. if (FAILED(hr))
  286. {
  287. CALL_FAIL(GENERAL_ERR, _T("(*it)->get_GUID(&bstrGUID)"), hr);
  288. AtlReportError(CLSID_FaxInboundRoutingMethods, GetErrorMsgId(hr), IID_IFaxInboundRoutingMethods, hr);
  289. return hr;
  290. }
  291. if (_tcsicmp(bstrGUID, var.bstrVal) == 0)
  292. {
  293. //
  294. // found the desired Method
  295. //
  296. (*it)->AddRef();
  297. *ppMethod = *it;
  298. return hr;
  299. }
  300. it++;
  301. }
  302. //
  303. // desired Method is not found
  304. //
  305. hr = E_INVALIDARG;
  306. CALL_FAIL(GENERAL_ERR, _T("Method Is Not Found"), hr);
  307. AtlReportError(CLSID_FaxInboundRoutingMethods, IDS_ERROR_INVALIDMETHODGUID, IID_IFaxInboundRoutingMethods, hr);
  308. return hr;
  309. }