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.

503 lines
11 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1998
  4. *
  5. * TITLE: IEnumWFI.Cpp
  6. *
  7. * VERSION: 2.1
  8. *
  9. * AUTHOR: ByronC
  10. *
  11. * DATE: 20 Mar, 1998
  12. * 08/10/1999 - Converted from IEnumWiaFormatInfo to IEnumWIA_FORMAT_INFO
  13. *
  14. * DESCRIPTION:
  15. * Implementation of IEnumWIA_FORMAT_INFO interface for
  16. * WIA device class driver server.
  17. *
  18. *******************************************************************************/
  19. #include "precomp.h"
  20. #include "stiexe.h"
  21. #include "wiamindr.h"
  22. #include "coredbg.h"
  23. #include "ienumwfi.h"
  24. #include "helpers.h"
  25. /********************************************************************************\
  26. *
  27. * AllocCopyWFI
  28. *
  29. * DESCRIPTION:
  30. * Allocates and copies an array of WIA_FORMAT_INFO structures.
  31. *
  32. * Arguments:
  33. *
  34. * ulCount - the number of elements to copy
  35. * pwfiIn - pointer to the WIA_FORMAT_INFO structures
  36. *
  37. * Return Value:
  38. *
  39. * Pointer to the newly created array.
  40. * History:
  41. *
  42. * 10/04/99 Original Version
  43. *
  44. \********************************************************************************/
  45. WIA_FORMAT_INFO *AllocCopyWFI(
  46. ULONG ulCount,
  47. WIA_FORMAT_INFO *pwfiIn)
  48. {
  49. DBG_FN(::AllocCopyWFI);
  50. if (!ulCount) {
  51. return NULL;
  52. }
  53. WIA_FORMAT_INFO *pwfi = (WIA_FORMAT_INFO*) CoTaskMemAlloc(sizeof(WIA_FORMAT_INFO) * ulCount);
  54. if (pwfi) {
  55. for (ULONG i = 0; i < ulCount; i++) {
  56. //
  57. // Copy the structure
  58. //
  59. memcpy(&pwfi[i], &pwfiIn[i], sizeof(WIA_FORMAT_INFO));
  60. }
  61. }
  62. else {
  63. DBG_ERR(("CEnumWiaFormatInfo : AllocCopyFe, unable to allocate WIA_FORMAT_INFO buffer"));
  64. }
  65. return pwfi;
  66. }
  67. /*******************************************************************************
  68. *
  69. * CEnumWiaFormatInfo
  70. *
  71. * DESCRIPTION:
  72. * CEnumWiaFormatInfo Constructor.
  73. *
  74. * History:
  75. *
  76. * 10/04/99 Original Version
  77. *
  78. \********************************************************************************/
  79. CEnumWiaFormatInfo::CEnumWiaFormatInfo()
  80. {
  81. m_cRef = 0;
  82. m_iCur = 0;
  83. m_cFormatInfo = 0;
  84. m_pFormatInfo = NULL;
  85. m_pCWiaItem = NULL;
  86. }
  87. /********************************************************************************\
  88. *
  89. * Initialize
  90. *
  91. * DESCRIPTION:
  92. * Sets up the enumerator. It makes a call down to the driver for the
  93. * information needed for the enumeration.
  94. *
  95. * Arguments:
  96. *
  97. * pWiaItem - A pointer to the calling item.
  98. * pWiaMiniDrv - A pointer to the corresponding mini driver
  99. * lFlags - flags
  100. *
  101. * Return Value:
  102. *
  103. * status
  104. *
  105. * History:
  106. *
  107. * 10/04/99 Original Version
  108. *
  109. \********************************************************************************/
  110. HRESULT CEnumWiaFormatInfo::Initialize(
  111. CWiaItem *pWiaItem)
  112. {
  113. DBG_FN(CEnumWiaFormatInfo::Initialize);
  114. HRESULT hr = E_FAIL;
  115. WIA_FORMAT_INFO *pFormat;
  116. m_iCur = 0;
  117. m_cFormatInfo = 0;
  118. m_pCWiaItem = pWiaItem;
  119. //
  120. // Make call to driver. Driver returns an array of WIA_FORMAT_INFO.
  121. //
  122. LONG lFlags = 0;
  123. {
  124. LOCK_WIA_DEVICE _LWD(pWiaItem, &hr);
  125. if(SUCCEEDED(hr)) {
  126. hr = m_pCWiaItem->m_pActiveDevice->m_DrvWrapper.WIA_drvGetWiaFormatInfo((BYTE*)pWiaItem,
  127. lFlags,
  128. &m_cFormatInfo,
  129. &pFormat,
  130. &(pWiaItem->m_lLastDevErrVal));
  131. }
  132. }
  133. if (SUCCEEDED(hr)) {
  134. //
  135. // Check that the count we get back is valid. Zero elements is supported.
  136. //
  137. if (m_cFormatInfo < 0) {
  138. m_cFormatInfo = 0;
  139. DBG_ERR(("CEnumWiaFormatInfo::Initialize, drvGetWiaFormatInfo returned invalid count"));
  140. return E_FAIL;
  141. }
  142. //
  143. // Check whether pointer received is valid
  144. //
  145. if (IsBadReadPtr(pFormat, sizeof(WIA_FORMAT_INFO)*m_cFormatInfo)) {
  146. DBG_ERR(("CEnumWiaFormatInfo::Initialize, drvGetWiaFormatInfo returned invalid pointer"));
  147. return E_POINTER;
  148. }
  149. //
  150. // Make a local copy in case minidriver goes away.
  151. //
  152. m_pFormatInfo = AllocCopyWFI(m_cFormatInfo, pFormat);
  153. } else {
  154. DBG_ERR(("CEnumWiaFormatInfo::Initialize, Error calling driver: drvGetWiaFormatInfo failed"));
  155. }
  156. return hr;
  157. }
  158. /********************************************************************************\
  159. *
  160. * ~CEnumWiaFormatInfo
  161. *
  162. * DESCRIPTION:
  163. *
  164. * Destructor. Frees up the m_prgfe structure, if it was allocated
  165. *
  166. * History:
  167. *
  168. * 10/04/99 Original Version
  169. *
  170. \********************************************************************************/
  171. CEnumWiaFormatInfo::~CEnumWiaFormatInfo()
  172. {
  173. DBG_FN(CEnumWiaFormatInfo::~CEnumWiaFormatInfo);
  174. if (NULL!=m_pFormatInfo) {
  175. //
  176. // Free our local copy of the device's WIA_FORMAT_INFOs
  177. //
  178. CoTaskMemFree(m_pFormatInfo);
  179. }
  180. m_cRef = 0;
  181. m_iCur = 0;
  182. m_cFormatInfo = 0;
  183. m_pFormatInfo = NULL;
  184. m_pCWiaItem = NULL;
  185. }
  186. /*******************************************************************************
  187. *
  188. * QueryInterface
  189. * AddRef
  190. * Release
  191. *
  192. * DESCRIPTION:
  193. * CEnumWiaFormatInfo IUnknown Interface.
  194. *
  195. * PARAMETERS:
  196. *
  197. *******************************************************************************/
  198. HRESULT _stdcall CEnumWiaFormatInfo::QueryInterface(const IID& iid, void** ppv)
  199. {
  200. *ppv = NULL;
  201. if (iid == IID_IUnknown || iid == IID_IEnumWIA_FORMAT_INFO) {
  202. *ppv = (IEnumWIA_FORMAT_INFO*) this;
  203. } else {
  204. return E_NOINTERFACE;
  205. }
  206. AddRef();
  207. return S_OK;
  208. }
  209. ULONG _stdcall CEnumWiaFormatInfo::AddRef()
  210. {
  211. InterlockedIncrement((long*) &m_cRef);
  212. return m_cRef;
  213. }
  214. ULONG _stdcall CEnumWiaFormatInfo::Release()
  215. {
  216. ULONG ulRefCount = m_cRef - 1;
  217. if (InterlockedDecrement((long*) &m_cRef) == 0) {
  218. delete this;
  219. return 0;
  220. }
  221. return ulRefCount;
  222. }
  223. /**************************************************************************\
  224. * Next
  225. *
  226. * Device capability enumerator, this enumerator returns an array of
  227. * WIA_FORMAT_INFO structs.
  228. * Next_Proxy ensures that last parameter is non-NULL.
  229. *
  230. * Arguments:
  231. *
  232. * cwfi - number requested.
  233. * pwfi - WIA_FORMAT_INFO returned in this array
  234. * pcwfi - returned number of entries written. NULLs are
  235. * ignored.
  236. *
  237. * Return Value:
  238. *
  239. * Status
  240. *
  241. * History:
  242. *
  243. * 10/04/99 Original Version
  244. *
  245. \**************************************************************************/
  246. HRESULT _stdcall CEnumWiaFormatInfo::Next(
  247. ULONG cwfi,
  248. WIA_FORMAT_INFO *pwfi,
  249. ULONG *pcwfi)
  250. {
  251. DBG_FN(CEnumWiaFormatInfo::Next);
  252. HRESULT hr;
  253. ULONG ulCount;
  254. ULONG cReturn = 0L;
  255. //
  256. // Parameter validation.
  257. //
  258. if (NULL == m_pFormatInfo) {
  259. return S_FALSE;
  260. }
  261. *pcwfi = 0L;
  262. //
  263. // Check if the current index indicates that we've already been through
  264. // all the elements.
  265. //
  266. if (m_iCur >= (ULONG)m_cFormatInfo) {
  267. return S_FALSE;
  268. }
  269. //
  270. // Check that the requested number of elements exist. If not,
  271. // set ulCount to the remaining number of elements.
  272. //
  273. if (cwfi > (m_cFormatInfo - m_iCur)) {
  274. ulCount = m_cFormatInfo - m_iCur;
  275. } else {
  276. ulCount = cwfi;
  277. }
  278. //
  279. // Copy the structres into the return
  280. //
  281. for (ULONG i = 0; i < ulCount; i++) {
  282. //
  283. // Make the copy
  284. //
  285. memcpy(&pwfi[i], &m_pFormatInfo[m_iCur++], sizeof(WIA_FORMAT_INFO));
  286. }
  287. *pcwfi = ulCount;
  288. //
  289. // Return S_FALSE if we returned less elements than requested
  290. //
  291. if (ulCount < cwfi) {
  292. return S_FALSE;
  293. }
  294. return S_OK;
  295. }
  296. /**************************************************************************\
  297. * Skip
  298. *
  299. * Skips WIA_FORMAT_INFOs in the enumeration.
  300. *
  301. * Arguments:
  302. *
  303. * celt - number of items to skip.
  304. *
  305. * Return Value:
  306. *
  307. * status
  308. *
  309. * History:
  310. *
  311. * 12/04/99 Original Version
  312. *
  313. \**************************************************************************/
  314. HRESULT _stdcall CEnumWiaFormatInfo::Skip(ULONG cwfi)
  315. {
  316. DBG_FN(CEnumWiaFormatInfo::Skip);
  317. if ((((m_iCur + cwfi) >= (ULONG)m_cFormatInfo))
  318. || (NULL == m_pFormatInfo)) {
  319. return S_FALSE;
  320. }
  321. m_iCur+= cwfi;
  322. return S_OK;
  323. }
  324. /**************************************************************************\
  325. * EnumDC::Reset
  326. *
  327. * Resets the enumeration to the first element
  328. *
  329. * Arguments:
  330. *
  331. *
  332. * Return Value:
  333. *
  334. * status
  335. *
  336. * History:
  337. *
  338. * 16/03/99 Original Version
  339. *
  340. \**************************************************************************/
  341. HRESULT _stdcall CEnumWiaFormatInfo::Reset(void)
  342. {
  343. DBG_FN(CEnumWiaFormatInfo::Reset);
  344. m_iCur = 0;
  345. return S_OK;
  346. }
  347. /**************************************************************************\
  348. * Clone
  349. *
  350. * Creates another IEnumWIA_FORMAT_INFO enumeration object and returns an
  351. * interface pointer to it.
  352. *
  353. * Arguments:
  354. *
  355. * ppIEnum - Address that receives the new enumeration object
  356. *
  357. * Return Value:
  358. *
  359. *
  360. * History:
  361. *
  362. * 16/03/99 Original Version
  363. *
  364. \**************************************************************************/
  365. HRESULT _stdcall CEnumWiaFormatInfo::Clone(IEnumWIA_FORMAT_INFO **ppIEnum)
  366. {
  367. DBG_FN(CEnumWiaFormatInfo::Clone);
  368. HRESULT hr;
  369. CEnumWiaFormatInfo *pClone;
  370. *ppIEnum = NULL;
  371. //
  372. // Create the clone
  373. //
  374. pClone = new CEnumWiaFormatInfo();
  375. if (!pClone) {
  376. return E_OUTOFMEMORY;
  377. }
  378. hr = pClone->Initialize(m_pCWiaItem);
  379. if (SUCCEEDED(hr)) {
  380. pClone->AddRef();
  381. pClone->m_iCur = m_iCur;
  382. *ppIEnum = pClone;
  383. } else {
  384. DBG_ERR(("CEnumWiaFormatInfo::Clone, Initialization failed"));
  385. delete pClone;
  386. }
  387. return hr;
  388. }
  389. /**************************************************************************\
  390. * GetCount
  391. *
  392. * Returns the number of elements stored in this enumerator.
  393. *
  394. * Arguments:
  395. *
  396. * pcelt - address of ULONG where to put the number of elements.
  397. *
  398. * Return Value:
  399. *
  400. * Status - S_OK if successful
  401. * E_FAIL if failed
  402. *
  403. * History:
  404. *
  405. * 05/07/99 Original Version
  406. *
  407. \**************************************************************************/
  408. HRESULT _stdcall CEnumWiaFormatInfo::GetCount(ULONG *pcelt)
  409. {
  410. DBG_FN(CEnumWiaFormatInfo::GetCount);
  411. *pcelt = 0;
  412. //
  413. // Check that we actually have a FORMAETC list and that the count
  414. // has a non-zero value.
  415. //
  416. if(m_cFormatInfo && m_pFormatInfo) {
  417. *pcelt = m_cFormatInfo;
  418. return S_OK;
  419. }
  420. return E_FAIL;
  421. }