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.

732 lines
17 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. FaxOutboundRoutingGroups.cpp
  5. Abstract:
  6. Implementation of CFaxOutboundRoutingGroups class.
  7. Author:
  8. Iv Garber (IvG) Jun, 2000
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "FaxComEx.h"
  13. #include "FaxOutboundRoutingGroups.h"
  14. #include "FaxOutboundRoutingGroup.h"
  15. //
  16. //================= FIND GROUP =======================================================
  17. //
  18. STDMETHODIMP
  19. CFaxOutboundRoutingGroups::FindGroup(
  20. /*[in]*/ VARIANT vIndex,
  21. /*[out]*/ ContainerType::iterator &it
  22. )
  23. /*++
  24. Routine name : CFaxOutboundRoutingGroups::FindGroup
  25. Routine description:
  26. Find Group by given Variant : either Group Name either Group Index in the Collection
  27. Author:
  28. Iv Garber (IvG), Jun, 2000
  29. Arguments:
  30. vIndex [in] - the Key to Find the Group
  31. it [out] - the found Group Iterator
  32. Return Value:
  33. Standard HRESULT code
  34. --*/
  35. {
  36. HRESULT hr = S_OK;
  37. DBG_ENTER(_T("CFaxOutboundRoutingGroups::FindGroup"), hr);
  38. CComVariant var;
  39. if (vIndex.vt != VT_BSTR)
  40. {
  41. //
  42. // vIndex is not BSTR ==> convert to VT_I4
  43. //
  44. hr = var.ChangeType(VT_I4, &vIndex);
  45. if (SUCCEEDED(hr))
  46. {
  47. VERBOSE(DBG_MSG, _T("Parameter is Number : %d"), var.lVal);
  48. //
  49. // Check the Range of the Index
  50. //
  51. if (var.lVal > m_coll.size() || var.lVal < 1)
  52. {
  53. //
  54. // Invalid Index
  55. //
  56. hr = E_INVALIDARG;
  57. AtlReportError(CLSID_FaxOutboundRoutingGroups, IDS_ERROR_OUTOFRANGE, IID_IFaxOutboundRoutingGroups, hr);
  58. CALL_FAIL(GENERAL_ERR, _T("lIndex < 1 || lIndex > m_coll.size()"), hr);
  59. return hr;
  60. }
  61. //
  62. // Find the Group Object to Remove
  63. //
  64. it = m_coll.begin() + var.lVal - 1;
  65. return hr;
  66. }
  67. }
  68. //
  69. // We didnot success to convert the var to Number
  70. // So, try to convert it to the STRING
  71. //
  72. hr = var.ChangeType(VT_BSTR, &vIndex);
  73. if (FAILED(hr))
  74. {
  75. hr = E_INVALIDARG;
  76. AtlReportError(CLSID_FaxOutboundRoutingGroups, IDS_ERROR_INVALID_ARGUMENT, IID_IFaxOutboundRoutingGroups, hr);
  77. CALL_FAIL(GENERAL_ERR, _T("var.ChangeType(VT_BSTR, &vIndex)"), hr);
  78. return hr;
  79. }
  80. VERBOSE(DBG_MSG, _T("Parameter is String : %s"), var.bstrVal);
  81. CComBSTR bstrName;
  82. it = m_coll.begin();
  83. while (it != m_coll.end())
  84. {
  85. hr = (*it)->get_Name(&bstrName);
  86. if (FAILED(hr))
  87. {
  88. CALL_FAIL(GENERAL_ERR, _T("(*it)->get_Name(&bstrName)"), hr);
  89. AtlReportError(CLSID_FaxOutboundRoutingGroups, IDS_ERROR_INVALID_ARGUMENT, IID_IFaxOutboundRoutingGroups, hr);
  90. return hr;
  91. }
  92. if (_tcsicmp(bstrName, var.bstrVal) == 0)
  93. {
  94. //
  95. // found the desired OR Group
  96. //
  97. return hr;
  98. }
  99. it++;
  100. }
  101. hr = E_INVALIDARG;
  102. CALL_FAIL(GENERAL_ERR, _T("Group Is Not Found"), hr);
  103. AtlReportError(CLSID_FaxOutboundRoutingGroups, IDS_ERROR_INVALID_ARGUMENT, IID_IFaxOutboundRoutingGroups, hr);
  104. return hr;
  105. }
  106. //
  107. //===================== ADD GROUP =================================================
  108. //
  109. STDMETHODIMP
  110. CFaxOutboundRoutingGroups::AddGroup(
  111. /*[in]*/ FAX_OUTBOUND_ROUTING_GROUP *pInfo,
  112. /*[out]*/ IFaxOutboundRoutingGroup **ppNewGroup
  113. )
  114. /*++
  115. Routine name : CFaxOutboundRoutingGroups::AddGroup
  116. Routine description:
  117. Create new Group Object and add it to the Collection.
  118. If ppNewGroup is NOT NULL, return in it ptr to the new Group Object.
  119. Author:
  120. Iv Garber (IvG), Jun, 2000
  121. Arguments:
  122. pInfo [in] - Ptr to the Group's Data
  123. ppNewGroup [out] - Ptr to the new Group Object
  124. Return Value:
  125. Standard HRESULT code
  126. --*/
  127. {
  128. HRESULT hr = S_OK;
  129. DBG_ENTER(_T("CFaxOutboundRoutingGroups::AddGroup"), hr);
  130. //
  131. // Create Group Object
  132. //
  133. CComObject<CFaxOutboundRoutingGroup> *pClass = NULL;
  134. hr = CComObject<CFaxOutboundRoutingGroup>::CreateInstance(&pClass);
  135. if (FAILED(hr) || (!pClass))
  136. {
  137. if (!pClass)
  138. {
  139. hr = E_OUTOFMEMORY;
  140. CALL_FAIL(MEM_ERR, _T("CComObject<CFaxOutboundRoutingGroup>::CreateInstance(&pClass)"), hr);
  141. }
  142. else
  143. {
  144. CALL_FAIL(GENERAL_ERR, _T("CComObject<CFaxOutboundRoutingGroup>::CreateInstance(&pClass)"), hr);
  145. }
  146. AtlReportError(CLSID_FaxOutboundRoutingGroups, GetErrorMsgId(hr), IID_IFaxOutboundRoutingGroups, hr);
  147. return hr;
  148. }
  149. //
  150. // Init the Group Object
  151. //
  152. hr = pClass->Init(pInfo, m_pIFaxServerInner);
  153. if (FAILED(hr))
  154. {
  155. CALL_FAIL(GENERAL_ERR, _T("pClass->Init(pInfo, m_pIFaxServerInner)"), hr);
  156. AtlReportError(CLSID_FaxOutboundRoutingGroups, GetErrorMsgId(hr), IID_IFaxOutboundRoutingGroups, hr);
  157. delete pClass;
  158. return hr;
  159. }
  160. //
  161. // Get Interface from the pClass.
  162. // This will make AddRef() on the Interface.
  163. // This is the Collection's AddRef, which is freed at Collection's Dtor.
  164. //
  165. CComPtr<IFaxOutboundRoutingGroup> pObject = NULL;
  166. hr = pClass->QueryInterface(&pObject);
  167. if (FAILED(hr) || (!pObject))
  168. {
  169. if (!pObject)
  170. {
  171. hr = E_FAIL;
  172. }
  173. CALL_FAIL(GENERAL_ERR, _T("pClass->QueryInterface(&pObject)"), hr);
  174. AtlReportError(CLSID_FaxOutboundRoutingGroups, GetErrorMsgId(hr), IID_IFaxOutboundRoutingGroups, hr);
  175. delete pClass;
  176. return hr;
  177. }
  178. //
  179. // Put the Object in the collection
  180. //
  181. try
  182. {
  183. m_coll.push_back(pObject);
  184. }
  185. catch (exception &)
  186. {
  187. hr = E_OUTOFMEMORY;
  188. AtlReportError(CLSID_FaxOutboundRoutingGroups, IDS_ERROR_OUTOFMEMORY, IID_IFaxOutboundRoutingGroups, hr);
  189. CALL_FAIL(MEM_ERR, _T("m_coll.push_back(pObject)"), hr);
  190. //
  191. // pObject will call Release(), which will delete the pClass
  192. //
  193. return hr;
  194. }
  195. //
  196. // We want to save the current AddRef() to Collection
  197. //
  198. pObject.Detach();
  199. //
  200. // Return new Group Object, if required
  201. //
  202. if (ppNewGroup)
  203. {
  204. if (::IsBadWritePtr(ppNewGroup, sizeof(IFaxOutboundRoutingGroup *)))
  205. {
  206. hr = E_POINTER;
  207. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr(ppNewGroup, sizeof(IFaxOutboundRoutingGroup *))"), hr);
  208. return hr;
  209. }
  210. else
  211. {
  212. *ppNewGroup = m_coll.back();
  213. (*ppNewGroup)->AddRef();
  214. }
  215. }
  216. return hr;
  217. }
  218. //
  219. //================= ADD =======================================================
  220. //
  221. STDMETHODIMP
  222. CFaxOutboundRoutingGroups::Add(
  223. /*[in]*/ BSTR bstrName,
  224. /*[out, retval]*/ IFaxOutboundRoutingGroup **ppGroup
  225. )
  226. /*++
  227. Routine name : CFaxOutboundRoutingGroups::Add
  228. Routine description:
  229. Add new Group to the Groups Collection
  230. Author:
  231. Iv Garber (IvG), Jun, 2000
  232. Arguments:
  233. bstrName [in] - Name of the new Group
  234. ppGroup [out] - the Group Object
  235. Return Value:
  236. Standard HRESULT code
  237. --*/
  238. {
  239. HRESULT hr = S_OK;
  240. DBG_ENTER(_T("CFaxOutboundRoutingGroups::Add"), hr, _T("Name=%s"), bstrName);
  241. //
  242. // Check if the Name is valid
  243. //
  244. if (!bstrName)
  245. {
  246. hr = E_INVALIDARG;
  247. CALL_FAIL(GENERAL_ERR, _T("Empty Group Name"), hr);
  248. AtlReportError(CLSID_FaxOutboundRoutingGroups, IDS_ERROR_INVALID_ARGUMENT, IID_IFaxOutboundRoutingGroups, hr);
  249. return hr;
  250. }
  251. if (_tcsicmp(bstrName, ROUTING_GROUP_ALL_DEVICES) == 0)
  252. {
  253. //
  254. // Cannot Add the "All Devices" Group
  255. //
  256. hr = E_INVALIDARG;
  257. CALL_FAIL(GENERAL_ERR, _T("All Devices Group"), hr);
  258. AtlReportError(CLSID_FaxOutboundRoutingGroups, IDS_ERROR_ALLDEVICESGROUP, IID_IFaxOutboundRoutingGroups, hr);
  259. return hr;
  260. }
  261. //
  262. // Get Fax Server Handle
  263. //
  264. HANDLE faxHandle;
  265. hr = m_pIFaxServerInner->GetHandle(&faxHandle);
  266. ATLASSERT(SUCCEEDED(hr));
  267. if (faxHandle == NULL)
  268. {
  269. //
  270. // Fax Server is not connected
  271. //
  272. hr = Fax_HRESULT_FROM_WIN32(ERROR_NOT_CONNECTED);
  273. CALL_FAIL(GENERAL_ERR, _T("faxHandle == NULL"), hr);
  274. AtlReportError(CLSID_FaxOutboundRoutingGroups, IDS_ERROR_INVALID_ARGUMENT, IID_IFaxOutboundRoutingGroups, hr);
  275. return hr;
  276. }
  277. //
  278. // Add the Group to the Fax Server
  279. //
  280. if (!FaxAddOutboundGroup(faxHandle, bstrName))
  281. {
  282. hr = Fax_HRESULT_FROM_WIN32(GetLastError());
  283. CALL_FAIL(GENERAL_ERR, _T("FaxAddOutboundGroup(faxHandle, bstrName)"), hr);
  284. AtlReportError(CLSID_FaxOutboundRoutingGroups, GetErrorMsgId(hr), IID_IFaxOutboundRoutingGroups, hr);
  285. return hr;
  286. }
  287. //
  288. // Add the Group to the Collection
  289. //
  290. FAX_OUTBOUND_ROUTING_GROUP groupData;
  291. groupData.dwNumDevices = 0;
  292. groupData.dwSizeOfStruct = sizeof(FAX_OUTBOUND_ROUTING_GROUP);
  293. groupData.lpctstrGroupName = bstrName;
  294. groupData.lpdwDevices = NULL;
  295. groupData.Status = FAX_GROUP_STATUS_EMPTY;
  296. hr = AddGroup(&groupData, ppGroup);
  297. return hr;
  298. }
  299. //
  300. //================= REMOVE =======================================================
  301. //
  302. STDMETHODIMP
  303. CFaxOutboundRoutingGroups::Remove(
  304. /*[in]*/ VARIANT vIndex
  305. )
  306. /*++
  307. Routine name : CFaxOutboundRoutingGroups::Remove
  308. Routine description:
  309. Remove Group by the given key
  310. Author:
  311. Iv Garber (IvG), Jun, 2000
  312. Arguments:
  313. vIndex [in] - the Key to Find the Group to Remove
  314. Return Value:
  315. Standard HRESULT code
  316. --*/
  317. {
  318. HRESULT hr = S_OK;
  319. DBG_ENTER(_T("CFaxOutboundRoutingGroups::Remove"), hr);
  320. //
  321. // Find the Group
  322. //
  323. ContainerType::iterator it;
  324. hr = FindGroup(vIndex, it);
  325. if (FAILED(hr))
  326. {
  327. return hr;
  328. }
  329. //
  330. // Take the Name of the Group
  331. //
  332. CComBSTR bstrName;
  333. hr = (*it)->get_Name(&bstrName);
  334. if (FAILED(hr))
  335. {
  336. AtlReportError(CLSID_FaxOutboundRoutingGroups, GetErrorMsgId(hr), IID_IFaxOutboundRoutingGroups, hr);
  337. CALL_FAIL(GENERAL_ERR, _T("(*it)->get_Name(&bstrName)"), hr);
  338. return hr;
  339. }
  340. //
  341. // Check that Name is valid
  342. //
  343. if (_tcsicmp(bstrName, ROUTING_GROUP_ALL_DEVICES) == 0)
  344. {
  345. //
  346. // Cannot Remove "All Devices" Group
  347. //
  348. hr = E_INVALIDARG;
  349. CALL_FAIL(GENERAL_ERR, _T("All Devices Group"), hr);
  350. AtlReportError(CLSID_FaxOutboundRoutingGroups, IDS_ERROR_ALLDEVICESGROUP, IID_IFaxOutboundRoutingGroups, hr);
  351. return hr;
  352. }
  353. //
  354. // Get Fax Server Handle
  355. //
  356. HANDLE faxHandle;
  357. hr = m_pIFaxServerInner->GetHandle(&faxHandle);
  358. ATLASSERT(SUCCEEDED(hr));
  359. if (faxHandle == NULL)
  360. {
  361. //
  362. // Fax Server is not connected
  363. //
  364. hr = Fax_HRESULT_FROM_WIN32(ERROR_NOT_CONNECTED);
  365. CALL_FAIL(GENERAL_ERR, _T("faxHandle == NULL"), hr);
  366. AtlReportError(CLSID_FaxOutboundRoutingGroups, IDS_ERROR_INVALID_ARGUMENT, IID_IFaxOutboundRoutingGroups, hr);
  367. return hr;
  368. }
  369. //
  370. // Remove from Fax Server
  371. //
  372. if (!FaxRemoveOutboundGroup(faxHandle, bstrName))
  373. {
  374. hr = Fax_HRESULT_FROM_WIN32(GetLastError());
  375. CALL_FAIL(GENERAL_ERR, _T("FaxRemoveOutboundGroup(faxHandle, bstrName)"), hr);
  376. AtlReportError(CLSID_FaxOutboundRoutingGroups, GetErrorMsgId(hr), IID_IFaxOutboundRoutingGroups, hr);
  377. return hr;
  378. }
  379. //
  380. // If successed, remove from our collection as well
  381. //
  382. try
  383. {
  384. m_coll.erase(it);
  385. }
  386. catch(exception &)
  387. {
  388. //
  389. // Failed to remove the Group
  390. //
  391. hr = E_OUTOFMEMORY;
  392. AtlReportError(CLSID_FaxOutboundRoutingGroups, GetErrorMsgId(hr), IID_IFaxOutboundRoutingGroups, hr);
  393. CALL_FAIL(MEM_ERR, _T("m_coll.erase(it)"), hr);
  394. return hr;
  395. }
  396. return hr;
  397. }
  398. //
  399. //==================== GET ITEM ===================================================
  400. //
  401. STDMETHODIMP
  402. CFaxOutboundRoutingGroups::get_Item(
  403. /*[in]*/ VARIANT vIndex,
  404. /*[out, retval]*/ IFaxOutboundRoutingGroup **ppGroup
  405. )
  406. /*++
  407. Routine name : CFaxOutboundRoutingGroups::get_Item
  408. Routine description:
  409. Return Item from the Collection either by Group Name either by its Index inside the Collection.
  410. Author:
  411. Iv Garber (IvG), Jun, 2000
  412. Arguments:
  413. vIndex [in] - Group Name or Item Index
  414. ppGroup [out] - the resultant Group Object
  415. Return Value:
  416. Standard HRESULT code
  417. --*/
  418. {
  419. HRESULT hr = S_OK;
  420. DBG_ENTER(_T("CFaxOutboundRoutingGroups::get_Item"), hr);
  421. //
  422. // Check the Ptr we have got
  423. //
  424. if (::IsBadWritePtr(ppGroup, sizeof(IFaxOutboundRoutingGroup *)))
  425. {
  426. hr = E_POINTER;
  427. AtlReportError(CLSID_FaxOutboundRoutingGroups, IDS_ERROR_INVALID_ARGUMENT, IID_IFaxOutboundRoutingGroups, hr);
  428. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr(ppGroup, sizeof(IFaxOutboundRoutingGroup *))"), hr);
  429. return hr;
  430. }
  431. //
  432. // Find the Group
  433. //
  434. ContainerType::iterator it;
  435. hr = FindGroup(vIndex, it);
  436. if (FAILED(hr))
  437. {
  438. return hr;
  439. };
  440. //
  441. // Return it to Caller
  442. //
  443. (*it)->AddRef();
  444. *ppGroup = *it;
  445. return hr;
  446. }
  447. //
  448. //==================== INIT ===================================================
  449. //
  450. STDMETHODIMP
  451. CFaxOutboundRoutingGroups::Init(
  452. /*[in]*/ IFaxServerInner *pServer
  453. )
  454. /*++
  455. Routine name : CFaxOutboundRoutingGroups::Init
  456. Routine description:
  457. Initialize the Groups Collection : create all Group Objects.
  458. Author:
  459. Iv Garber (IvG), Jun, 2000
  460. Arguments:
  461. pServer [in] - Ptr to the Fax Server Object.
  462. Return Value:
  463. Standard HRESULT code
  464. --*/
  465. {
  466. HRESULT hr = S_OK;
  467. DBG_ENTER(_T("CFaxOutboundRoutingGroups::Init"), hr);
  468. //
  469. // First, set the Ptr to the Server
  470. //
  471. hr = CFaxInitInnerAddRef::Init(pServer);
  472. if (FAILED(hr))
  473. {
  474. return hr;
  475. }
  476. //
  477. // Get Fax Handle
  478. //
  479. HANDLE faxHandle;
  480. hr = m_pIFaxServerInner->GetHandle(&faxHandle);
  481. ATLASSERT(SUCCEEDED(hr));
  482. if (faxHandle == NULL)
  483. {
  484. //
  485. // Fax Server is not connected
  486. //
  487. hr = Fax_HRESULT_FROM_WIN32(ERROR_NOT_CONNECTED);
  488. CALL_FAIL(GENERAL_ERR, _T("faxHandle == NULL"), hr);
  489. AtlReportError(CLSID_FaxOutboundRoutingGroups, GetErrorMsgId(hr), IID_IFaxOutboundRoutingGroups, hr);
  490. return hr;
  491. }
  492. //
  493. // Call Server to Return all OR Groups
  494. //
  495. CFaxPtr<FAX_OUTBOUND_ROUTING_GROUP> pGroups;
  496. DWORD dwNum = 0;
  497. if (!FaxEnumOutboundGroups(faxHandle, &pGroups, &dwNum))
  498. {
  499. hr = Fax_HRESULT_FROM_WIN32(GetLastError());
  500. CALL_FAIL(GENERAL_ERR, _T("FaxEnumOutboundGroups(faxHandle, &pGroups, &dwNum)"), hr);
  501. AtlReportError(CLSID_FaxOutboundRoutingGroups, GetErrorMsgId(hr), IID_IFaxOutboundRoutingGroups, hr);
  502. return hr;
  503. }
  504. //
  505. // Fill the Collection with Objects
  506. //
  507. for (DWORD i=0 ; i<dwNum ; i++ )
  508. {
  509. hr = AddGroup(&pGroups[i]);
  510. if (FAILED(hr))
  511. {
  512. return hr;
  513. }
  514. }
  515. return hr;
  516. }
  517. //
  518. //==================== CREATE ========================================
  519. //
  520. HRESULT
  521. CFaxOutboundRoutingGroups::Create (
  522. /*[out, retval]*/IFaxOutboundRoutingGroups **ppGroups
  523. )
  524. /*++
  525. Routine name : CFaxOutboundRoutingGroups::Create
  526. Routine description:
  527. Static function to create the Fax Outbound Routing Groups Collection Object
  528. Author:
  529. Iv Garber (IvG), Jun, 2000
  530. Arguments:
  531. ppGroups [out] -- the new Fax OR Groups Collection Object
  532. Return Value:
  533. Standard HRESULT code
  534. --*/
  535. {
  536. HRESULT hr = S_OK;
  537. DBG_ENTER (_T("CFaxOutboundRoutingGroups::Create"), hr);
  538. //
  539. // Create Instance of the Collection
  540. //
  541. CComObject<CFaxOutboundRoutingGroups> *pClass;
  542. hr = CComObject<CFaxOutboundRoutingGroups>::CreateInstance(&pClass);
  543. if (FAILED(hr))
  544. {
  545. CALL_FAIL(GENERAL_ERR, _T("CComObject<CFaxOutboundRoutingGroups>::CreateInstance(&pClass)"), hr);
  546. return hr;
  547. }
  548. //
  549. // Return the desired Interface Ptr
  550. //
  551. hr = pClass->QueryInterface(ppGroups);
  552. if (FAILED(hr))
  553. {
  554. CALL_FAIL(GENERAL_ERR, _T("pClass->QueryInterface(ppGroups)"), hr);
  555. return hr;
  556. }
  557. return hr;
  558. } // CFaxOutboundRoutingGroups::Create()
  559. //
  560. //===================== SUPPORT ERROR INFO ======================================
  561. //
  562. STDMETHODIMP
  563. CFaxOutboundRoutingGroups::InterfaceSupportsErrorInfo(
  564. REFIID riid
  565. )
  566. /*++
  567. Routine name : CFaxOutboundRoutingGroups::InterfaceSupportsErrorInfo
  568. Routine description:
  569. ATL's implementation of the ISupportErrorInfo Interface.
  570. Author:
  571. Iv Garber (IvG), Jun, 2000
  572. Arguments:
  573. riid [in] - Reference to the Interface
  574. Return Value:
  575. Standard HRESULT code
  576. --*/
  577. {
  578. static const IID* arr[] =
  579. {
  580. &IID_IFaxOutboundRoutingGroups
  581. };
  582. for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
  583. {
  584. if (InlineIsEqualGUID(*arr[i],riid))
  585. return S_OK;
  586. }
  587. return S_FALSE;
  588. }