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.

738 lines
15 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. FaxDeviceProvider.cpp
  5. Abstract:
  6. Implementation of CFaxDeviceProvider Class.
  7. Author:
  8. Iv Garber (IvG) Jun, 2000
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "FaxComEx.h"
  13. #include "FaxDeviceProvider.h"
  14. //
  15. //========================= GET UNIQUE NAME ========================================
  16. //
  17. STDMETHODIMP
  18. CFaxDeviceProvider::get_UniqueName(
  19. BSTR *pbstrUniqueName
  20. )
  21. /*++
  22. Routine name : CFaxDeviceProvider::get_UniqueName
  23. Routine description:
  24. Return Name of the Device Provider
  25. Author:
  26. Iv Garber (IvG), Jun, 2000
  27. Arguments:
  28. pbstrUniqueName [out] - Ptr to put the UniqueName
  29. Return Value:
  30. Standard HRESULT code
  31. --*/
  32. {
  33. HRESULT hr = S_OK;
  34. DBG_ENTER (TEXT("CFaxDeviceProvider::get_UniqueName"), hr);
  35. hr = GetBstr(pbstrUniqueName, m_bstrUniqueName);
  36. if (FAILED(hr))
  37. {
  38. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  39. return hr;
  40. }
  41. return hr;
  42. }
  43. //
  44. //========================= GET IMAGE NAME ========================================
  45. //
  46. STDMETHODIMP
  47. CFaxDeviceProvider::get_ImageName(
  48. BSTR *pbstrImageName
  49. )
  50. /*++
  51. Routine name : CFaxDeviceProvider::get_ImageName
  52. Routine description:
  53. Return Image Name of the Device Provider
  54. Author:
  55. Iv Garber (IvG), Jun, 2000
  56. Arguments:
  57. pbstrImageName [out] - Ptr to put the ImageName
  58. Return Value:
  59. Standard HRESULT code
  60. --*/
  61. {
  62. HRESULT hr = S_OK;
  63. DBG_ENTER (TEXT("CFaxDeviceProvider::get_ImageName"), hr);
  64. hr = GetBstr(pbstrImageName, m_bstrImageName);
  65. if (FAILED(hr))
  66. {
  67. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  68. return hr;
  69. }
  70. return hr;
  71. }
  72. //
  73. //========================= GET FRIENDLY NAME ========================================
  74. //
  75. STDMETHODIMP
  76. CFaxDeviceProvider::get_FriendlyName(
  77. BSTR *pbstrFriendlyName
  78. )
  79. /*++
  80. Routine name : CFaxDeviceProvider::get_FriendlyName
  81. Routine description:
  82. Return Friendly Name of the Device Provider
  83. Author:
  84. Iv Garber (IvG), Jun, 2000
  85. Arguments:
  86. pbstrFriendlyName [out] - Ptr to put the FriendlyName
  87. Return Value:
  88. Standard HRESULT code
  89. --*/
  90. {
  91. HRESULT hr = S_OK;
  92. DBG_ENTER (TEXT("CFaxDeviceProvider::get_FriendlyName"), hr);
  93. hr = GetBstr(pbstrFriendlyName, m_bstrFriendlyName);
  94. if (FAILED(hr))
  95. {
  96. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  97. return hr;
  98. }
  99. return hr;
  100. }
  101. //
  102. //========================= GET TAPI PROVIDER NAME ========================================
  103. //
  104. STDMETHODIMP
  105. CFaxDeviceProvider::get_TapiProviderName(
  106. BSTR *pbstrTapiProviderName
  107. )
  108. /*++
  109. Routine name : CFaxDeviceProvider::get_TapiProviderName
  110. Routine description:
  111. Return Tapi Provider Name of the Device Provider
  112. Author:
  113. Iv Garber (IvG), Jun, 2000
  114. Arguments:
  115. pbstrTapiProviderName [out] - Ptr to put the TapiProviderName
  116. Return Value:
  117. Standard HRESULT code
  118. --*/
  119. {
  120. HRESULT hr = S_OK;
  121. DBG_ENTER (TEXT("CFaxDeviceProvider::get_TapiProviderName"), hr);
  122. hr = GetBstr(pbstrTapiProviderName, m_bstrTapiProviderName);
  123. if (FAILED(hr))
  124. {
  125. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  126. return hr;
  127. }
  128. return hr;
  129. }
  130. //
  131. //===================== GET STATUS =========================================
  132. //
  133. STDMETHODIMP
  134. CFaxDeviceProvider::get_Status(
  135. FAX_PROVIDER_STATUS_ENUM *pStatus
  136. )
  137. /*++
  138. Routine name : CFaxDeviceProvider::get_Status
  139. Routine description:
  140. Return Status of the Device Provider
  141. Author:
  142. Iv Garber (IvG), Jun, 2000
  143. Arguments:
  144. pStatus [out] - Ptr to put Status value
  145. Return Value:
  146. Standard HRESULT code
  147. --*/
  148. {
  149. HRESULT hr = S_OK;
  150. DBG_ENTER (TEXT("CFaxDeviceProvider::get_Status"), hr);
  151. //
  152. // Check that we have got good Ptr
  153. //
  154. if (::IsBadWritePtr(pStatus, sizeof(FAX_PROVIDER_STATUS_ENUM)))
  155. {
  156. hr = E_POINTER;
  157. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr(pStatus, sizeof(FAX_PROVIDER_STATUS_ENUM))"), hr);
  158. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  159. return hr;
  160. }
  161. *pStatus = m_Status;
  162. return hr;
  163. }
  164. //
  165. //===================== GET INIT ERROR CODE =========================================
  166. //
  167. STDMETHODIMP
  168. CFaxDeviceProvider::get_InitErrorCode(
  169. long *plInitErrorCode
  170. )
  171. /*++
  172. Routine name : CFaxDeviceProvider::get_InitErrorCode
  173. Routine description:
  174. Return InitErrorCode of the Device Provider
  175. Author:
  176. Iv Garber (IvG), Jun, 2000
  177. Arguments:
  178. plInitErrorCode [out] - Ptr to put InitErrorCode value
  179. Return Value:
  180. Standard HRESULT code
  181. --*/
  182. {
  183. HRESULT hr = S_OK;
  184. DBG_ENTER (TEXT("CFaxDeviceProvider::get_InitErrorCode"), hr);
  185. hr = GetLong(plInitErrorCode, m_lLastError);
  186. if (FAILED(hr))
  187. {
  188. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  189. return hr;
  190. }
  191. return hr;
  192. }
  193. //
  194. //===================== GET DEBUG =========================================
  195. //
  196. STDMETHODIMP
  197. CFaxDeviceProvider::get_Debug(
  198. VARIANT_BOOL *pbDebug
  199. )
  200. /*++
  201. Routine name : CFaxDeviceProvider::get_Debug
  202. Routine description:
  203. Return if the Device Provider compiled in Debug version
  204. Author:
  205. Iv Garber (IvG), Jun, 2000
  206. Arguments:
  207. pbDebug [out] - Ptr to put Debug value
  208. Return Value:
  209. Standard HRESULT code
  210. --*/
  211. {
  212. HRESULT hr = S_OK;
  213. DBG_ENTER (TEXT("CFaxDeviceProvider::get_Debug"), hr);
  214. hr = GetVariantBool(pbDebug, m_bDebug);
  215. if (FAILED(hr))
  216. {
  217. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  218. return hr;
  219. }
  220. return hr;
  221. }
  222. //
  223. //===================== GET MAJOR BUILD =========================================
  224. //
  225. STDMETHODIMP
  226. CFaxDeviceProvider::get_MajorBuild(
  227. long *plMajorBuild
  228. )
  229. /*++
  230. Routine name : CFaxDeviceProvider::get_MajorBuild
  231. Routine description:
  232. Return MajorBuild of the Device Provider
  233. Author:
  234. Iv Garber (IvG), Jun, 2000
  235. Arguments:
  236. plMajorBuild [out] - Ptr to put MajorBuild value
  237. Return Value:
  238. Standard HRESULT code
  239. --*/
  240. {
  241. HRESULT hr = S_OK;
  242. DBG_ENTER (TEXT("CFaxDeviceProvider::get_MajorBuild"), hr);
  243. hr = GetLong(plMajorBuild, m_lMajorBuild);
  244. if (FAILED(hr))
  245. {
  246. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  247. return hr;
  248. }
  249. return hr;
  250. }
  251. //
  252. //===================== GET MINOR BUILD =========================================
  253. //
  254. STDMETHODIMP
  255. CFaxDeviceProvider::get_MinorBuild(
  256. long *plMinorBuild
  257. )
  258. /*++
  259. Routine name : CFaxDeviceProvider::get_MinorBuild
  260. Routine description:
  261. Return MinorBuild of the Device Provider
  262. Author:
  263. Iv Garber (IvG), Jun, 2000
  264. Arguments:
  265. plMinorBuild [out] - Ptr to put MinorBuild value
  266. Return Value:
  267. Standard HRESULT code
  268. --*/
  269. {
  270. HRESULT hr = S_OK;
  271. DBG_ENTER (TEXT("CFaxDeviceProvider::get_MinorBuild"), hr);
  272. hr = GetLong(plMinorBuild, m_lMinorBuild);
  273. if (FAILED(hr))
  274. {
  275. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  276. return hr;
  277. }
  278. return hr;
  279. }
  280. //
  281. //===================== GET MAJOR VERSION =========================================
  282. //
  283. STDMETHODIMP
  284. CFaxDeviceProvider::get_MajorVersion(
  285. long *plMajorVersion
  286. )
  287. /*++
  288. Routine name : CFaxDeviceProvider::get_MajorVersion
  289. Routine description:
  290. Return MajorVersion of the Device Provider
  291. Author:
  292. Iv Garber (IvG), Jun, 2000
  293. Arguments:
  294. plMajorVersion [out] - Ptr to put MajorVersion value
  295. Return Value:
  296. Standard HRESULT code
  297. --*/
  298. {
  299. HRESULT hr = S_OK;
  300. DBG_ENTER (TEXT("CFaxDeviceProvider::get_MajorVersion"), hr);
  301. hr = GetLong(plMajorVersion, m_lMajorVersion);
  302. if (FAILED(hr))
  303. {
  304. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  305. return hr;
  306. }
  307. return hr;
  308. }
  309. //
  310. //===================== GET MINOR VERSION =========================================
  311. //
  312. STDMETHODIMP
  313. CFaxDeviceProvider::get_MinorVersion(
  314. long *plMinorVersion
  315. )
  316. /*++
  317. Routine name : CFaxDeviceProvider::get_MinorVersion
  318. Routine description:
  319. Return MinorVersion of the Device Provider
  320. Author:
  321. Iv Garber (IvG), Jun, 2000
  322. Arguments:
  323. plMinorVersion [out] - Ptr to put MinorVersionvalue
  324. Return Value:
  325. Standard HRESULT code
  326. --*/
  327. {
  328. HRESULT hr = S_OK;
  329. DBG_ENTER (TEXT("CFaxDeviceProvider::get_MinorVersion"), hr);
  330. hr = GetLong(plMinorVersion, m_lMinorVersion);
  331. if (FAILED(hr))
  332. {
  333. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  334. return hr;
  335. }
  336. return hr;
  337. }
  338. //
  339. //===================== GET DEVICE IDS =========================================
  340. //
  341. STDMETHODIMP
  342. CFaxDeviceProvider::get_DeviceIds(
  343. /*[out, retval]*/ VARIANT *pvDeviceIds
  344. )
  345. /*++
  346. Routine name : CFaxDeviceProvider::get_DeviceIds
  347. Routine description:
  348. Return array of all device ids exposed by the Device Provider
  349. Author:
  350. Iv Garber (IvG), Jun, 2000
  351. Arguments:
  352. pvDeviceIds [out] - Ptr to put Variant containing Safearray of IDs
  353. Return Value:
  354. Standard HRESULT code
  355. --*/
  356. {
  357. HRESULT hr = S_OK;
  358. DBG_ENTER (TEXT("CFaxDeviceProvider::get_DeviceIds"), hr);
  359. //
  360. // Check that we can write to the given pointer
  361. //
  362. if (::IsBadWritePtr(pvDeviceIds, sizeof(VARIANT)))
  363. {
  364. hr = E_POINTER;
  365. AtlReportError(
  366. CLSID_FaxDeviceProvider,
  367. GetErrorMsgId(hr),
  368. IID_IFaxDeviceProvider,
  369. hr);
  370. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr(pvDeviceIds, sizeof(VARIANT))"), hr);
  371. return hr;
  372. }
  373. //
  374. // Allocate the safe array : vector of long
  375. //
  376. SAFEARRAY *psaResult;
  377. hr = SafeArrayCopy(m_psaDeviceIDs, &psaResult);
  378. if (FAILED(hr) || !psaResult)
  379. {
  380. if (!psaResult)
  381. {
  382. hr = E_OUTOFMEMORY;
  383. }
  384. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  385. CALL_FAIL(MEM_ERR, _T("SafeArrayCopy(m_psaDeviceIDs, &psaResult)"), hr);
  386. return hr;
  387. }
  388. //
  389. // Return the Safe Array inside the VARIANT we got
  390. //
  391. VariantInit(pvDeviceIds);
  392. pvDeviceIds->vt = VT_I4 | VT_ARRAY;
  393. pvDeviceIds->parray = psaResult;
  394. return hr;
  395. }
  396. //
  397. //==================== INIT ========================================
  398. //
  399. STDMETHODIMP
  400. CFaxDeviceProvider::Init(
  401. FAX_DEVICE_PROVIDER_INFO *pInfo,
  402. FAX_PORT_INFO_EX *pDevices,
  403. DWORD dwNum
  404. )
  405. /*++
  406. Routine name : CFaxDeviceProvider::Init
  407. Routine description:
  408. Initialize the Device Provider Object with given Information.
  409. Allocates memory and stores given pInfo.
  410. Find in the pDevices its own Devices, create Variant of SafeArray containing them.
  411. Author:
  412. Iv Garber (IvG), Jun, 2000
  413. Arguments:
  414. pInfo [in] -- the Info of the Device Provider Object
  415. pDevices [in] -- array of all available Devices
  416. dwNum [in] -- number of elements in pDevices array
  417. Return Value:
  418. Standard HRESULT code
  419. --*/
  420. {
  421. HRESULT hr = S_OK;
  422. DBG_ENTER (TEXT("CFaxDeviceProvider::Init"), hr);
  423. //
  424. // Copy the FAX_DEVICE_PROVIDER_INFO
  425. //
  426. m_Status = FAX_PROVIDER_STATUS_ENUM(pInfo->Status);
  427. m_lLastError = pInfo->dwLastError;
  428. if (!(pInfo->Version.bValid))
  429. {
  430. m_lMajorBuild = 0;
  431. m_lMinorBuild = 0;
  432. m_lMajorVersion = 0;
  433. m_lMinorVersion = 0;
  434. m_bDebug = VARIANT_FALSE;
  435. }
  436. else
  437. {
  438. m_lMajorBuild = pInfo->Version.wMajorBuildNumber;
  439. m_lMinorBuild = pInfo->Version.wMinorBuildNumber;
  440. m_lMajorVersion = pInfo->Version.wMajorVersion;
  441. m_lMinorVersion = pInfo->Version.wMinorVersion;
  442. m_bDebug = bool2VARIANT_BOOL((pInfo->Version.dwFlags & FAX_VER_FLAG_CHECKED) ? true : false);
  443. }
  444. m_bstrUniqueName = pInfo->lpctstrGUID;
  445. m_bstrImageName = pInfo->lpctstrImageName;
  446. m_bstrFriendlyName = pInfo->lpctstrFriendlyName;
  447. m_bstrTapiProviderName = pInfo->lpctstrProviderName;
  448. if ( (pInfo->lpctstrGUID && !m_bstrUniqueName) ||
  449. (pInfo->lpctstrFriendlyName && !m_bstrFriendlyName) ||
  450. (pInfo->lpctstrImageName && !m_bstrImageName) ||
  451. (pInfo->lpctstrProviderName && !m_bstrTapiProviderName) )
  452. {
  453. hr = E_OUTOFMEMORY;
  454. CALL_FAIL(MEM_ERR, _T("CComBSTR::operator=()"), hr);
  455. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  456. return hr;
  457. }
  458. //
  459. // count the devices of the Provider
  460. //
  461. DWORD dwCount = 0;
  462. for (DWORD i=0 ; i<dwNum ; i++ )
  463. {
  464. if ( _tcsicmp(pDevices[i].lpctstrProviderGUID, m_bstrUniqueName) == 0 )
  465. {
  466. dwCount++;
  467. }
  468. }
  469. //
  470. // Allocate the safe array : vector of long
  471. //
  472. m_psaDeviceIDs = ::SafeArrayCreateVector(VT_I4, 0, dwCount);
  473. if (m_psaDeviceIDs == NULL)
  474. {
  475. //
  476. // Not Enough Memory
  477. //
  478. hr = E_OUTOFMEMORY;
  479. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  480. CALL_FAIL(MEM_ERR, _T("::SafeArrayCreateVector(VT_I4, 0, dwCount)"), hr);
  481. return hr;
  482. }
  483. if ( dwCount>0 )
  484. {
  485. //
  486. // get Access to the elements of the Safe Array
  487. //
  488. DWORD *pdwElement;
  489. hr = ::SafeArrayAccessData(m_psaDeviceIDs, (void **) &pdwElement);
  490. if (FAILED(hr))
  491. {
  492. //
  493. // Failed to access safearray
  494. //
  495. hr = E_FAIL;
  496. CALL_FAIL(GENERAL_ERR, _T("::SafeArrayAccessData(m_psaDeviceIDs, &pdwElement)"), hr);
  497. AtlReportError(CLSID_FaxDeviceProvider, GetErrorMsgId(hr), IID_IFaxDeviceProvider, hr);
  498. return hr;
  499. }
  500. //
  501. // Fill the array with values
  502. //
  503. DWORD idx = 0;
  504. for ( i=0 ; i<dwNum ; i++ )
  505. {
  506. if ( _tcsicmp(pDevices[i].lpctstrProviderGUID, m_bstrUniqueName) == 0 )
  507. {
  508. pdwElement[idx] = pDevices[i].dwDeviceID;
  509. idx++;
  510. }
  511. }
  512. //
  513. // free the safearray from the access
  514. //
  515. hr = ::SafeArrayUnaccessData(m_psaDeviceIDs);
  516. if (FAILED(hr))
  517. {
  518. CALL_FAIL(GENERAL_ERR, _T("::SafeArrayUnaccessData(m_psaDeviceIDs)"), hr);
  519. }
  520. }
  521. return hr;
  522. }
  523. //
  524. //==================== SUPPORT ERROR INFO =============================================
  525. //
  526. STDMETHODIMP
  527. CFaxDeviceProvider::InterfaceSupportsErrorInfo(
  528. REFIID riid
  529. )
  530. /*++
  531. Routine name : CFaxDeviceProvider::InterfaceSupportsErrorInfo
  532. Routine description:
  533. ATL's implementation of Support Error Info.
  534. Author:
  535. Iv Garber (IvG), Jun, 2000
  536. Arguments:
  537. riid [in] - Reference to the Interface.
  538. Return Value:
  539. Standard HRESULT code
  540. --*/
  541. {
  542. static const IID* arr[] =
  543. {
  544. &IID_IFaxDeviceProvider
  545. };
  546. for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
  547. {
  548. if (InlineIsEqualGUID(*arr[i],riid))
  549. return S_OK;
  550. }
  551. return S_FALSE;
  552. }