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.

466 lines
11 KiB

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