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.

505 lines
10 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1998
  4. *
  5. * TITLE: IEnumItm.Cpp
  6. *
  7. * VERSION: 2.0
  8. *
  9. * AUTHOR: ReedB
  10. *
  11. * DATE: 30 July, 1998
  12. *
  13. * DESCRIPTION:
  14. * Implementation of CEnumWiaItem for the WIA device class driver.
  15. *
  16. *******************************************************************************/
  17. #include "precomp.h"
  18. #include "stiexe.h"
  19. #include "wiamindr.h"
  20. #include "ienumitm.h"
  21. /*******************************************************************************
  22. *
  23. * QueryInterface
  24. * AddRef
  25. * Release
  26. *
  27. * DESCRIPTION:
  28. * IUnknown Interface.
  29. *
  30. *******************************************************************************/
  31. HRESULT _stdcall CEnumWiaItem::QueryInterface(const IID& iid, void** ppv)
  32. {
  33. *ppv = NULL;
  34. if (iid == IID_IUnknown || iid == IID_IEnumWiaItem) {
  35. *ppv = (IEnumWiaItem*) this;
  36. } else {
  37. return E_NOINTERFACE;
  38. }
  39. AddRef();
  40. return (S_OK);
  41. }
  42. ULONG _stdcall CEnumWiaItem::AddRef()
  43. {
  44. InterlockedIncrement((long*) &m_cRef);
  45. return m_cRef;
  46. }
  47. ULONG _stdcall CEnumWiaItem::Release()
  48. {
  49. ULONG ulRefCount = m_cRef - 1;
  50. if (InterlockedDecrement((long*) &m_cRef) == 0) {
  51. delete this;
  52. return 0;
  53. }
  54. return ulRefCount;
  55. }
  56. /**************************************************************************\
  57. * CEnumWiaItem::CEnumWiaItem
  58. *
  59. * CEnumWiaItem constructor method.
  60. *
  61. * Arguments:
  62. *
  63. * None
  64. *
  65. * Return Value:
  66. *
  67. * Status
  68. *
  69. * History:
  70. *
  71. * 9/2/1998 Original Version
  72. *
  73. \**************************************************************************/
  74. CEnumWiaItem::CEnumWiaItem()
  75. {
  76. m_cRef = 0;
  77. m_ulIndex = 0;
  78. m_pInitialFolder = NULL;
  79. m_pCurrentItem = NULL;
  80. }
  81. /**************************************************************************\
  82. * CEnumWiaItem::Initialize
  83. *
  84. * CEnumWiaItem initialization method.
  85. *
  86. * Arguments:
  87. *
  88. * None
  89. *
  90. * Return Value:
  91. *
  92. * Status
  93. *
  94. * History:
  95. *
  96. * 9/2/1998 Original Version
  97. *
  98. \**************************************************************************/
  99. HRESULT CEnumWiaItem::Initialize(CWiaItem *pInitialFolder)
  100. {
  101. DBG_FN(CEnumWiaItem::Initialize);
  102. //
  103. // Validate parameters
  104. //
  105. if (!pInitialFolder) {
  106. DBG_ERR(("CEnumWiaItem::Initialize, NULL parameters"));
  107. return E_POINTER;
  108. }
  109. //
  110. // Verify that initial folder is a folder item.
  111. //
  112. LONG lFlags;
  113. pInitialFolder->GetItemType(&lFlags);
  114. if (!(lFlags & (WiaItemTypeFolder | WiaItemTypeHasAttachments))) {
  115. DBG_ERR(("CEnumWiaItem::Initialize, pInitialFolder is not a folder"));
  116. return E_INVALIDARG;
  117. }
  118. m_pInitialFolder = pInitialFolder;
  119. //
  120. // Get the initial folders tree entry.
  121. //
  122. CWiaTree *pCurFolderTree;
  123. pCurFolderTree = pInitialFolder->GetTreePtr();
  124. if (pCurFolderTree) {
  125. //
  126. // Get the first child item from the initial folder.
  127. //
  128. pCurFolderTree->GetFirstChildItem(&m_pCurrentItem);
  129. //
  130. // Ref count the root item.
  131. //
  132. m_pInitialFolder->AddRef();
  133. }
  134. else {
  135. DBG_ERR(("CEnumWiaItem::Initialize, initial folder doesn't have a tree entry"));
  136. return E_FAIL;
  137. }
  138. return S_OK;
  139. }
  140. /**************************************************************************\
  141. * CEnumWiaItem::~CEnumWiaItem
  142. *
  143. * CEnumWiaItem destructor method.
  144. *
  145. * Arguments:
  146. *
  147. * None
  148. *
  149. * Return Value:
  150. *
  151. * Status
  152. *
  153. * History:
  154. *
  155. * 9/2/1998 Original Version
  156. *
  157. \**************************************************************************/
  158. CEnumWiaItem::~CEnumWiaItem()
  159. {
  160. DBG_FN(CEnumWiaItem::~CEnumWiaItem);
  161. //
  162. // Decrement root item ref count.
  163. //
  164. if (m_pInitialFolder != NULL) {
  165. m_pInitialFolder->Release();
  166. m_pInitialFolder = NULL;
  167. }
  168. //
  169. // Set other members to empty since we're done with this enumerator.
  170. //
  171. m_ulIndex = 0;
  172. m_pInitialFolder = NULL;
  173. m_pCurrentItem = NULL;
  174. }
  175. /**************************************************************************\
  176. * CEnumWiaItem::Next
  177. *
  178. * Item enumerator, this enumerator only returns one item per call
  179. * Next_Proxy ensures that last parameter is non-NULL.
  180. *
  181. * Arguments:
  182. *
  183. * cItem - number requested
  184. * ppIWiaItem - returned interface pointers
  185. * pcItemFetched - returned number of objets (1 max)
  186. *
  187. * Return Value:
  188. *
  189. * status
  190. *
  191. * History:
  192. *
  193. * 9/2/1998 Original Version
  194. *
  195. \**************************************************************************/
  196. HRESULT _stdcall CEnumWiaItem::Next(
  197. ULONG cItem,
  198. IWiaItem **ppIWiaItem,
  199. ULONG *pcItemFetched)
  200. {
  201. DBG_FN(CEnumWiaItem::Next);
  202. HRESULT hr;
  203. ULONG i;
  204. //
  205. // Validate parameters
  206. //
  207. if (cItem == 0) {
  208. return S_OK;
  209. }
  210. if (! ppIWiaItem){
  211. DBG_ERR(("CEnumWiaItem::Next NULL input parameters"));
  212. return E_POINTER;
  213. }
  214. //
  215. // Clear the return values
  216. //
  217. *pcItemFetched = 0;
  218. ZeroMemory(ppIWiaItem, cItem * sizeof(IWiaItem *));
  219. //
  220. // Retrieve the requested items
  221. //
  222. for (i = 0; i < cItem; i++) {
  223. //
  224. // If m_pCurrentItem is NULL, then enumeration is complete
  225. //
  226. if (m_pCurrentItem == NULL) {
  227. hr = S_FALSE;
  228. break;
  229. }
  230. //
  231. // Get the next item from the tree and increment refernce count
  232. // before handing item pointer to the application.
  233. //
  234. hr = m_pCurrentItem->GetItemData((void **)(ppIWiaItem + i));
  235. if (hr == S_OK) {
  236. DBG_TRC(("CEnumWiaItem::Next, returning: 0x%08X", ppIWiaItem[i]));
  237. (ppIWiaItem[i])->AddRef();
  238. (*pcItemFetched)++;
  239. } else {
  240. break;
  241. }
  242. //
  243. // Advance item enumeration.
  244. //
  245. m_pCurrentItem->GetNextSiblingItem(&m_pCurrentItem);
  246. }
  247. if (FAILED(hr)) {
  248. //
  249. // Unwind from the error
  250. //
  251. for (i = 0; i < *pcItemFetched; i++) {
  252. ppIWiaItem[i]->Release();
  253. ppIWiaItem[i] = NULL;
  254. }
  255. }
  256. return hr;
  257. }
  258. /**************************************************************************\
  259. * CEnumWiaItem::Skip
  260. *
  261. * Skip to the next enumerated item.
  262. *
  263. * Arguments:
  264. *
  265. * cItem - number requested
  266. *
  267. * Return Value:
  268. *
  269. * status
  270. *
  271. * History:
  272. *
  273. * 9/2/1998 Original Version
  274. *
  275. \**************************************************************************/
  276. HRESULT _stdcall CEnumWiaItem::Skip(ULONG cItem)
  277. {
  278. DBG_FN(CEnumWiaItem::Skip);
  279. CWiaTree *pOld;
  280. pOld = m_pCurrentItem;
  281. while (m_pCurrentItem && (cItem != 0)) {
  282. m_pCurrentItem->GetNextSiblingItem(&m_pCurrentItem);
  283. cItem--;
  284. }
  285. //
  286. // If cItem != 0, then Skip request was too large, so restore
  287. // m_pCurrentItem and return S_FALSE.
  288. //
  289. if (cItem) {
  290. m_pCurrentItem = pOld;
  291. return S_FALSE;
  292. }
  293. return S_OK;
  294. }
  295. /**************************************************************************\
  296. * CEnumWiaItem::Reset
  297. *
  298. * Reset to the first enumerated item.
  299. *
  300. * Arguments:
  301. *
  302. * None
  303. *
  304. * Return Value:
  305. *
  306. * status
  307. *
  308. * History:
  309. *
  310. * 9/2/1998 Original Version
  311. *
  312. \**************************************************************************/
  313. HRESULT _stdcall CEnumWiaItem::Reset(void)
  314. {
  315. DBG_FN(CEnumWiaItem::Reset);
  316. CWiaTree *pCurFolderTree;
  317. pCurFolderTree = m_pInitialFolder->GetTreePtr();
  318. if (pCurFolderTree) {
  319. //
  320. // Get the first child item from the initial folder.
  321. //
  322. pCurFolderTree->GetFirstChildItem(&m_pCurrentItem);
  323. }
  324. else {
  325. DBG_ERR(("CEnumWiaItem::reset, initial folder doesn't have a tree entry"));
  326. return E_FAIL;
  327. }
  328. return S_OK;
  329. }
  330. /**************************************************************************\
  331. * CEnumWiaItem::Clone
  332. *
  333. * Clone the enumerator
  334. *
  335. * Arguments:
  336. *
  337. * ppIEnumWiaItem - Pointer to returned clone enumerator.
  338. *
  339. * Return Value:
  340. *
  341. * status
  342. *
  343. * History:
  344. *
  345. * 9/2/1998 Original Version
  346. *
  347. \**************************************************************************/
  348. HRESULT _stdcall CEnumWiaItem::Clone(IEnumWiaItem **ppIEnumWiaItem)
  349. {
  350. DBG_FN(CEnumWiaItem::Clone);
  351. HRESULT hr;
  352. CEnumWiaItem *pClone;
  353. *ppIEnumWiaItem = NULL;
  354. //
  355. // Create the clone
  356. //
  357. pClone = new CEnumWiaItem();
  358. if (!pClone) {
  359. DBG_ERR(("CEnumWiaItem::Clone new CEnumWiaItem failed"));
  360. return E_OUTOFMEMORY;
  361. }
  362. hr = pClone->Initialize(m_pInitialFolder);
  363. if (SUCCEEDED(hr)) {
  364. pClone->AddRef();
  365. pClone->m_pCurrentItem = m_pCurrentItem;
  366. *ppIEnumWiaItem = pClone;
  367. } else {
  368. delete pClone;
  369. }
  370. return hr;
  371. }
  372. /**************************************************************************\
  373. * GetCount
  374. *
  375. * Returns the number of elements stored in this enumerator.
  376. *
  377. * Arguments:
  378. *
  379. * pcelt - address of ULONG where to put the number of elements.
  380. *
  381. * Return Value:
  382. *
  383. * Status - S_OK if successful
  384. * E_FAIL if failed
  385. *
  386. * History:
  387. *
  388. * 05/07/99 Original Version
  389. *
  390. \**************************************************************************/
  391. HRESULT _stdcall CEnumWiaItem::GetCount(ULONG *pcelt)
  392. {
  393. DBG_FN(CEnumWiaItem::GetCount);
  394. CWiaTree *pCurFolderTree;
  395. CWiaTree *pCurrentItem;
  396. ULONG celt = 0;
  397. if (!m_pInitialFolder) {
  398. DBG_ERR(("CEnumWiaItem::GetCount, initial folder not set"));
  399. return E_POINTER;
  400. }
  401. pCurFolderTree = m_pInitialFolder->GetTreePtr();
  402. if (pCurFolderTree) {
  403. //
  404. // Loop through the items
  405. //
  406. for (pCurFolderTree->GetFirstChildItem(&pCurrentItem);
  407. pCurrentItem;
  408. pCurrentItem->GetNextSiblingItem(&pCurrentItem)) {
  409. celt++;
  410. }
  411. }
  412. else {
  413. DBG_ERR(("CEnumWiaItem::GetCount, initial folder doesn't have a tree entry"));
  414. return E_FAIL;
  415. }
  416. *pcelt = celt;
  417. return S_OK;
  418. }