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.

413 lines
10 KiB

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