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.

1015 lines
23 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Module: clist.h
  4. //
  5. // Description: list classes
  6. //
  7. //
  8. //@@BEGIN_MSINTERNAL
  9. // Development Team:
  10. // Mike McLaughlin
  11. //
  12. // History: Date Author Comment
  13. //
  14. //@@END_MSINTERNAL
  15. //---------------------------------------------------------------------------
  16. //
  17. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  18. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  19. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  20. // PURPOSE.
  21. //
  22. // Copyright (c) 1996-1999 Microsoft Corporation. All Rights Reserved.
  23. //
  24. //---------------------------------------------------------------------------
  25. //---------------------------------------------------------------------------
  26. // Macros
  27. //---------------------------------------------------------------------------
  28. #define FOR_EACH_LIST_ITEM(pl, p) { \
  29. PCLIST_ITEM pli; \
  30. for(pli = (pl)->GetListFirst(); \
  31. !(pl)->IsListEnd(pli); \
  32. pli = (pl)->GetListNext(pli)) { \
  33. p = (pl)->GetListData(pli); \
  34. (pl)->AssertList(p);
  35. #define FOR_EACH_LIST_ITEM_DELETE(pl, p) { \
  36. PCLIST_ITEM pli, pliNext; \
  37. for(pli = (pl)->GetListFirst(); !(pl)->IsListEnd(pli); pli = pliNext) { \
  38. pliNext = (pl)->GetListNext(pli); \
  39. p = (pl)->GetListData(pli); \
  40. (pl)->AssertList(p);
  41. #define DELETE_LIST_ITEM(pl) \
  42. pliNext = (pl)->GetListFirst();
  43. #define FOR_EACH_LIST_ITEM_BACKWARD(pl, p) { \
  44. PCLIST_ITEM pli; \
  45. for(pli = (pl)->GetListLast(); \
  46. !(pl)->IsListEnd(pli); \
  47. pli = (pl)->GetListPrevious(pli)) { \
  48. p = (pl)->GetListData(pli); \
  49. (pl)->AssertList(p);
  50. #define END_EACH_LIST_ITEM } }
  51. //---------------------------------------------------------------------------
  52. #define FOR_EACH_CLIST_ITEM(pl, p) { \
  53. for(p = (pl)->GetListFirst(); \
  54. !(pl)->IsListEnd(p); \
  55. p = (pl)->GetListNext(p)) { \
  56. Assert(p);
  57. #define FOR_EACH_CLIST_ITEM_DELETE(pl, p, type) { \
  58. type *pNext; \
  59. for(p = (pl)->GetListFirst(); !(pl)->IsListEnd(p); p = pNext) { \
  60. Assert(p); \
  61. pNext = (pl)->GetListNext(p);
  62. #define END_EACH_CLIST_ITEM } }
  63. //---------------------------------------------------------------------------
  64. // Abstract List Classes
  65. //---------------------------------------------------------------------------
  66. typedef class CList : public CObj
  67. {
  68. public:
  69. } CLIST, *PCLIST;
  70. typedef class CListItem : public CObj
  71. {
  72. public:
  73. } CLIST_ITEM, *PCLIST_ITEM;
  74. //---------------------------------------------------------------------------
  75. // Singlely Linked List
  76. //---------------------------------------------------------------------------
  77. typedef class CListSingle : public CList
  78. {
  79. friend class CListSingleItem;
  80. public:
  81. CListSingle()
  82. {
  83. m_plsiHead = NULL;
  84. };
  85. VOID DestroyList()
  86. {
  87. m_plsiHead = NULL;
  88. };
  89. BOOL IsLstEmpty()
  90. {
  91. Assert(this);
  92. return(m_plsiHead == NULL);
  93. };
  94. CListSingleItem *GetListFirst()
  95. {
  96. Assert(this);
  97. return(m_plsiHead);
  98. };
  99. BOOL IsListEnd(CListSingleItem *plsi)
  100. {
  101. Assert(this);
  102. return(plsi == NULL);
  103. };
  104. CListSingleItem *GetListData(CListSingleItem *plsi)
  105. {
  106. return plsi;
  107. }
  108. CListSingleItem *GetListNext(CListSingleItem *plsi);
  109. CListSingleItem **GetListEnd();
  110. ENUMFUNC EnumerateList(
  111. IN ENUMFUNC (CListSingleItem::*pfn)(
  112. )
  113. );
  114. ENUMFUNC EnumerateList(
  115. IN ENUMFUNC (CListSingleItem::*pfn)(
  116. PVOID pReference
  117. ),
  118. PVOID pReference
  119. );
  120. void ReverseList();
  121. protected:
  122. CListSingleItem *m_plsiHead;
  123. public:
  124. DefineSignature(0x2048534C); // LSH
  125. } CLIST_SINGLE, *PCLIST_SINGLE;
  126. //---------------------------------------------------------------------------
  127. typedef class CListSingleItem : public CListItem
  128. {
  129. friend class CListData;
  130. friend class CListSingle;
  131. public:
  132. CListSingleItem()
  133. {
  134. m_plsiNext = NULL;
  135. };
  136. VOID AddList(CListSingle *pls)
  137. {
  138. Assert(pls);
  139. Assert(this);
  140. ASSERT(m_plsiNext == NULL);
  141. m_plsiNext = pls->m_plsiHead;
  142. pls->m_plsiHead = this;
  143. };
  144. VOID AddListEnd(CListSingle *pls)
  145. {
  146. Assert(pls);
  147. Assert(this);
  148. ASSERT(m_plsiNext == NULL);
  149. *(pls->GetListEnd()) = this;
  150. };
  151. VOID RemoveList(CListSingle *pls);
  152. private:
  153. CListSingleItem *m_plsiNext;
  154. public:
  155. DefineSignature(0x2049534C); // LSI
  156. } CLIST_SINGLE_ITEM, *PCLIST_SINGLE_ITEM;
  157. inline CListSingleItem *
  158. CListSingle::GetListNext(CListSingleItem *plsi)
  159. {
  160. Assert(this);
  161. return plsi->m_plsiNext;
  162. }
  163. //---------------------------------------------------------------------------
  164. // Doublely Linked List
  165. //---------------------------------------------------------------------------
  166. typedef class CListDouble : public CList
  167. {
  168. friend class CListDoubleItem;
  169. public:
  170. CListDouble()
  171. {
  172. InitializeListHead(&m_leHead);
  173. };
  174. VOID DestroyList()
  175. {
  176. };
  177. BOOL IsLstEmpty()
  178. {
  179. Assert(this);
  180. return IsListEmpty(&m_leHead);
  181. };
  182. ULONG CountList();
  183. CListDoubleItem *GetListFirst();
  184. CListDoubleItem *GetListLast();
  185. BOOL IsListEnd(CListDoubleItem *pldi);
  186. CListDoubleItem *GetListNext(CListDoubleItem *pldi);
  187. CListDoubleItem *GetListPrevious(CListDoubleItem *pldi);
  188. CListDoubleItem *GetListData(CListDoubleItem *pldi)
  189. {
  190. return pldi;
  191. };
  192. ENUMFUNC EnumerateList(
  193. IN ENUMFUNC (CListDoubleItem::*pfn)(
  194. )
  195. );
  196. ENUMFUNC EnumerateList(
  197. IN ENUMFUNC (CListDoubleItem::*pfn)(
  198. PVOID pReference
  199. ),
  200. PVOID pReference
  201. );
  202. protected:
  203. LIST_ENTRY m_leHead;
  204. public:
  205. DefineSignature(0x2048424C); // LBH
  206. } CLIST_DOUBLE, *PCLIST_DOUBLE;
  207. //---------------------------------------------------------------------------
  208. typedef class CListDoubleItem : public CListItem
  209. {
  210. friend class CListDouble;
  211. public:
  212. VOID AddList(CListDouble *plb)
  213. {
  214. Assert(plb);
  215. Assert(this);
  216. ASSERT(m_le.Flink == NULL);
  217. ASSERT(m_le.Blink == NULL);
  218. InsertHeadList(&plb->m_leHead, &m_le);
  219. };
  220. VOID AddListEnd(CListDouble *plb)
  221. {
  222. Assert(plb);
  223. Assert(this);
  224. ASSERT(m_le.Flink == NULL);
  225. ASSERT(m_le.Blink == NULL);
  226. InsertTailList(&plb->m_leHead, &m_le);
  227. };
  228. VOID RemoveList()
  229. {
  230. Assert(this);
  231. ASSERT(m_le.Flink != NULL);
  232. ASSERT(m_le.Blink != NULL);
  233. RemoveEntryList(&m_le);
  234. m_le.Flink = NULL;
  235. m_le.Blink = NULL;
  236. };
  237. VOID RemoveListCheck()
  238. {
  239. Assert(this);
  240. if(m_le.Flink != NULL) {
  241. RemoveList();
  242. }
  243. };
  244. protected:
  245. LIST_ENTRY m_le;
  246. public:
  247. DefineSignature(0x2049424C); // LBI
  248. } CLIST_DOUBLE_ITEM, *PCLIST_DOUBLE_ITEM;
  249. inline CListDoubleItem *
  250. CListDouble::GetListFirst()
  251. {
  252. Assert(this);
  253. ASSERT(m_leHead.Flink != NULL);
  254. return CONTAINING_RECORD(m_leHead.Flink, CListDoubleItem, m_le);
  255. }
  256. inline CListDoubleItem *
  257. CListDouble::GetListLast()
  258. {
  259. Assert(this);
  260. ASSERT(m_leHead.Blink != NULL);
  261. return CONTAINING_RECORD(m_leHead.Blink, CListDoubleItem, m_le);
  262. }
  263. inline BOOL
  264. CListDouble::IsListEnd(CListDoubleItem *pldi)
  265. {
  266. Assert(this);
  267. return(&pldi->m_le == &m_leHead);
  268. }
  269. inline CListDoubleItem *
  270. CListDouble::GetListNext(CListDoubleItem *pldi)
  271. {
  272. Assert(this);
  273. ASSERT(pldi->m_le.Flink != NULL);
  274. return CONTAINING_RECORD(pldi->m_le.Flink, CListDoubleItem, m_le);
  275. }
  276. inline CListDoubleItem *
  277. CListDouble::GetListPrevious(CListDoubleItem *pldi)
  278. {
  279. Assert(this);
  280. ASSERT(pldi->m_le.Blink != NULL);
  281. return CONTAINING_RECORD(pldi->m_le.Blink, CListDoubleItem, m_le);
  282. }
  283. //---------------------------------------------------------------------------
  284. // Linked List of Data Pointers
  285. //---------------------------------------------------------------------------
  286. class CListDataItem;
  287. typedef class CListDataData : public CListSingleItem
  288. {
  289. friend class CListData;
  290. public:
  291. CListDataData(
  292. CListDataItem *pldi
  293. )
  294. {
  295. m_pldiData = pldi;
  296. };
  297. CListDataData(
  298. PVOID p
  299. )
  300. {
  301. m_pldiData = (CListDataItem *)p;
  302. };
  303. private:
  304. CListDataItem *m_pldiData;
  305. public:
  306. DefineSignature(0x2044444C); // LDD
  307. } CLIST_DATA_DATA, *PCLIST_DATA_DATA;
  308. //---------------------------------------------------------------------------
  309. typedef class CListData : public CListSingle
  310. {
  311. public:
  312. ~CListData()
  313. {
  314. CListData::DestroyList();
  315. };
  316. VOID DestroyList();
  317. ULONG CountList();
  318. CListDataData *GetListFirst()
  319. {
  320. Assert(this);
  321. return (CListDataData *)CListSingle::GetListFirst();
  322. };
  323. CListDataData *GetListNext(CListDataData *pldd)
  324. {
  325. Assert(this);
  326. return (CListDataData *)CListSingle::GetListNext(pldd);
  327. };
  328. CListDataItem *GetListData(CListDataData *pldd)
  329. {
  330. Assert(this);
  331. return pldd->m_pldiData;
  332. };
  333. CListDataItem *GetListFirstData()
  334. {
  335. Assert(this);
  336. return GetListData(GetListFirst());
  337. };
  338. ENUMFUNC EnumerateList(
  339. IN ENUMFUNC (CListDataItem::*pfn)(
  340. )
  341. );
  342. ENUMFUNC EnumerateList(
  343. IN ENUMFUNC (CListDataItem::*pfn)(
  344. PVOID pReference
  345. ),
  346. PVOID pReference
  347. );
  348. NTSTATUS CreateUniqueList(
  349. OUT CListData *pldOut,
  350. IN PVOID (*GetFunction)(
  351. IN PVOID pData
  352. ),
  353. IN BOOL (*CompareFunction)(
  354. IN PVOID pIn,
  355. IN PVOID pOut
  356. )
  357. );
  358. BOOL CheckDupList(
  359. PVOID p
  360. );
  361. NTSTATUS AddList(
  362. PVOID p
  363. );
  364. NTSTATUS AddListDup(
  365. PVOID p
  366. );
  367. NTSTATUS AddListEnd(
  368. PVOID p
  369. );
  370. NTSTATUS AddListOrdered(
  371. PVOID p,
  372. LONG lFieldOffset
  373. );
  374. VOID RemoveList(
  375. PVOID p
  376. );
  377. VOID JoinList(
  378. CListData *pld
  379. );
  380. private:
  381. CListDataData **GetListEnd()
  382. {
  383. return((CListDataData **)CListSingle::GetListEnd());
  384. };
  385. public:
  386. DefineSignature(0x2048444C); // LDH
  387. } CLIST_DATA, *PCLIST_DATA;
  388. //---------------------------------------------------------------------------
  389. typedef class CListDataItem : public CListItem
  390. {
  391. public:
  392. ENUMFUNC Destroy()
  393. {
  394. delete this;
  395. return(STATUS_CONTINUE);
  396. };
  397. BOOL CheckDupList(
  398. PCLIST_DATA pld
  399. )
  400. {
  401. Assert(this);
  402. return(pld->CheckDupList((PVOID)this));
  403. };
  404. NTSTATUS AddList(
  405. PCLIST_DATA pld
  406. )
  407. {
  408. Assert(this);
  409. return(pld->AddList((PVOID)this));
  410. };
  411. NTSTATUS AddListDup(
  412. PCLIST_DATA pld
  413. )
  414. {
  415. Assert(this);
  416. return(pld->AddListDup((PVOID)this));
  417. };
  418. NTSTATUS AddListEnd(
  419. PCLIST_DATA pld
  420. )
  421. {
  422. Assert(this);
  423. return(pld->AddListEnd((PVOID)this));
  424. };
  425. VOID RemoveList(
  426. PCLIST_DATA pld
  427. )
  428. {
  429. Assert(this);
  430. pld->RemoveList((PVOID)this);
  431. };
  432. DefineSignature(0x2049444C); // LDI
  433. } CLIST_DATA_ITEM, *PCLIST_DATA_ITEM;
  434. typedef PVOID (*UNIQUE_LIST_PFN)(PVOID);
  435. typedef BOOL (*UNIQUE_LIST_PFN2)(PVOID, PVOID);
  436. //---------------------------------------------------------------------------
  437. // Multi-Headed Linked List
  438. //---------------------------------------------------------------------------
  439. typedef class CListMultiData : public CListDoubleItem
  440. {
  441. friend class CListMulti;
  442. friend class CListMultiItem;
  443. public:
  444. CListMultiData(
  445. PVOID p
  446. )
  447. {
  448. m_plmiData = (CListMultiItem *)p;
  449. };
  450. ~CListMultiData()
  451. {
  452. CListMultiData::RemoveList();
  453. };
  454. VOID RemoveList()
  455. {
  456. Assert(this);
  457. CListDoubleItem::RemoveList();
  458. m_ldiItem.RemoveList();
  459. };
  460. private:
  461. CListDoubleItem m_ldiItem;
  462. CListMultiItem *m_plmiData;
  463. public:
  464. DefineSignature(0x20444d4C); // LMD
  465. } CLIST_MULTI_DATA, *PCLIST_MULTI_DATA;
  466. //---------------------------------------------------------------------------
  467. typedef class CListMulti : public CListDouble
  468. {
  469. friend class CListMultiItem;
  470. public:
  471. ~CListMulti()
  472. {
  473. CListMulti::DestroyList();
  474. };
  475. VOID DestroyList();
  476. ENUMFUNC EnumerateList(
  477. ENUMFUNC (CListMultiItem::*pfn)(
  478. )
  479. );
  480. ENUMFUNC EnumerateList(
  481. ENUMFUNC (CListMultiItem::*pfn)(
  482. PVOID pReference
  483. ),
  484. PVOID pReference
  485. );
  486. CListMultiData *GetListFirst()
  487. {
  488. Assert(this);
  489. return (CListMultiData *)CListDouble::GetListFirst();
  490. };
  491. CListMultiData *GetListLast()
  492. {
  493. Assert(this);
  494. return (CListMultiData *)CListDouble::GetListLast();
  495. };
  496. BOOL IsListEnd(CListMultiData *plmd)
  497. {
  498. Assert(this);
  499. return CListDouble::IsListEnd(plmd);
  500. };
  501. CListMultiData *GetListNext(CListMultiData *plmd)
  502. {
  503. Assert(this);
  504. return (CListMultiData *)CListDouble::GetListNext(plmd);
  505. };
  506. CListMultiData *GetListPrevious(CListMultiData *plmd)
  507. {
  508. Assert(this);
  509. return (CListMultiData *)CListDouble::GetListPrevious(plmd);
  510. };
  511. CListMultiItem *GetListData(CListMultiData *plmd)
  512. {
  513. Assert(this);
  514. return plmd->m_plmiData;
  515. };
  516. CListMultiItem *GetListFirstData()
  517. {
  518. Assert(this);
  519. return GetListData(GetListFirst());
  520. };
  521. BOOL CheckDupList(
  522. PVOID p
  523. );
  524. NTSTATUS AddList(
  525. PVOID p,
  526. CListMultiItem *plmi
  527. );
  528. NTSTATUS AddList(
  529. CListMultiItem *plmi
  530. )
  531. {
  532. Assert(this);
  533. return(AddList((PVOID)plmi, plmi));
  534. };
  535. NTSTATUS AddListEnd(
  536. PVOID p,
  537. CListMultiItem *plmi
  538. );
  539. NTSTATUS AddListEnd(
  540. CListMultiItem *plmi
  541. )
  542. {
  543. Assert(this);
  544. return(AddListEnd((PVOID)plmi, plmi));
  545. };
  546. NTSTATUS AddListOrdered(
  547. PVOID p,
  548. CListMultiItem *plmi,
  549. LONG lFieldOffset
  550. );
  551. NTSTATUS AddListOrdered(
  552. CListMultiItem *plmi,
  553. LONG lFieldOffset
  554. )
  555. {
  556. Assert(this);
  557. return(AddListOrdered((PVOID)plmi, plmi, lFieldOffset));
  558. };
  559. VOID RemoveList(
  560. PVOID p
  561. );
  562. VOID JoinList(
  563. CListMulti *plm
  564. );
  565. DefineSignature(0x20484D4C); // LMH
  566. } CLIST_MULTI, *PCLIST_MULTI;
  567. //---------------------------------------------------------------------------
  568. typedef class CListMultiItem : public CListDouble
  569. {
  570. public:
  571. ~CListMultiItem();
  572. BOOL CheckDupList(
  573. PCLIST_MULTI plm
  574. )
  575. {
  576. return(plm->CheckDupList((PVOID)this));
  577. };
  578. NTSTATUS AddList(
  579. PCLIST_MULTI plm
  580. )
  581. {
  582. Assert(plm);
  583. Assert(this);
  584. return(plm->AddList(this));
  585. };
  586. NTSTATUS AddListEnd(
  587. PCLIST_MULTI plm
  588. )
  589. {
  590. Assert(plm);
  591. Assert(this);
  592. return(plm->AddListEnd(this));
  593. };
  594. NTSTATUS AddListOrdered(
  595. PCLIST_MULTI plm,
  596. LONG lFieldOffset
  597. )
  598. {
  599. Assert(plm);
  600. Assert(this);
  601. return(plm->AddListOrdered(this, lFieldOffset));
  602. };
  603. VOID RemoveList(
  604. PCLIST_MULTI plm
  605. )
  606. {
  607. Assert(this);
  608. plm->RemoveList((PVOID)this);
  609. };
  610. DefineSignature(0x20494d4C); // LMI
  611. } CLIST_MULTI_ITEM, *PCLIST_MULTI_ITEM;
  612. //---------------------------------------------------------------------------
  613. // Templates
  614. //---------------------------------------------------------------------------
  615. template<class TYPE>
  616. class ListSingleDestroy : public CListSingle
  617. {
  618. public:
  619. ~ListSingleDestroy()
  620. {
  621. ListSingleDestroy::DestroyList();
  622. };
  623. VOID DestroyList()
  624. {
  625. ListSingleDestroy::EnumerateList(TYPE::Destroy);
  626. CListSingle::DestroyList();
  627. };
  628. VOID AssertList(TYPE *p)
  629. {
  630. Assert(p);
  631. };
  632. ENUMFUNC EnumerateList(
  633. IN ENUMFUNC (TYPE::*pfn)(
  634. )
  635. )
  636. {
  637. return CListSingle::EnumerateList(
  638. (ENUMFUNC (CListSingleItem::*)())pfn);
  639. };
  640. ENUMFUNC EnumerateList(
  641. IN ENUMFUNC (TYPE::*pfn)(
  642. PVOID pReference
  643. ),
  644. PVOID pReference
  645. )
  646. {
  647. return CListSingle::EnumerateList(
  648. (ENUMFUNC (CListSingleItem::*)(PVOID))pfn,
  649. pReference);
  650. };
  651. PCLIST_ITEM GetListFirst()
  652. {
  653. return CListSingle::GetListFirst();
  654. };
  655. BOOL IsListEnd(PCLIST_ITEM pli)
  656. {
  657. return CListSingle::IsListEnd((CListSingleItem *)pli);
  658. };
  659. PCLIST_ITEM GetListNext(PCLIST_ITEM pli)
  660. {
  661. return CListSingle::GetListNext((CListSingleItem *)pli);
  662. };
  663. TYPE *GetListData(PCLIST_ITEM pli)
  664. {
  665. return (TYPE *)CListSingle::GetListData((CListSingleItem *)pli);
  666. };
  667. TYPE *GetListFirstData()
  668. {
  669. return (TYPE *)CListSingle::GetListData(CListSingle::GetListFirst());
  670. };
  671. };
  672. //---------------------------------------------------------------------------
  673. //---------------------------------------------------------------------------
  674. template<class TYPE>
  675. class ListDouble : public CListDouble
  676. {
  677. public:
  678. VOID AssertList(TYPE *p)
  679. {
  680. Assert(p);
  681. };
  682. ENUMFUNC EnumerateList(
  683. IN ENUMFUNC (TYPE::*pfn)()
  684. )
  685. {
  686. return CListDouble::EnumerateList(
  687. (ENUMFUNC (CListDoubleItem::*)())pfn);
  688. };
  689. ENUMFUNC EnumerateList(
  690. IN ENUMFUNC (TYPE::*pfn)(
  691. PVOID pReference
  692. ),
  693. PVOID pReference
  694. )
  695. {
  696. return CListDouble::EnumerateList(
  697. (ENUMFUNC (CListDoubleItem::*)(PVOID))pfn,
  698. pReference);
  699. };
  700. PCLIST_ITEM GetListFirst()
  701. {
  702. return CListDouble::GetListFirst();
  703. };
  704. PCLIST_ITEM GetListLast()
  705. {
  706. return CListDouble::GetListLast();
  707. };
  708. BOOL IsListEnd(PCLIST_ITEM pli)
  709. {
  710. return CListDouble::IsListEnd((CListDoubleItem *)pli);
  711. };
  712. PCLIST_ITEM GetListNext(PCLIST_ITEM pli)
  713. {
  714. return CListDouble::GetListNext((CListDoubleItem *)pli);
  715. };
  716. PCLIST_ITEM GetListPrevious(PCLIST_ITEM pli)
  717. {
  718. return CListDouble::GetListPrevious((CListDoubleItem *)pli);
  719. };
  720. TYPE *GetListData(PCLIST_ITEM pli)
  721. {
  722. return (TYPE *)CListDouble::GetListData((CListDoubleItem *)pli);
  723. };
  724. };
  725. //---------------------------------------------------------------------------
  726. template<class TYPE>
  727. class ListDoubleDestroy : public ListDouble<TYPE>
  728. {
  729. public:
  730. ~ListDoubleDestroy()
  731. {
  732. ListDoubleDestroy::DestroyList();
  733. };
  734. VOID DestroyList()
  735. {
  736. ListDoubleDestroy::EnumerateList(TYPE::Destroy);
  737. CListDouble::DestroyList();
  738. };
  739. };
  740. //---------------------------------------------------------------------------
  741. template<class TYPE>
  742. class ListDoubleField : public CListDouble
  743. {
  744. public:
  745. VOID AssertList(TYPE *p)
  746. {
  747. Assert(p);
  748. };
  749. CListItem *GetListFirst()
  750. {
  751. return (CListItem *)CONTAINING_RECORD(
  752. CListDouble::GetListFirst(), TYPE, ldiNext);
  753. };
  754. BOOL IsListEnd(CListItem *pli)
  755. {
  756. return CListDouble::IsListEnd(&((TYPE *)pli)->ldiNext);
  757. };
  758. CListItem *GetListNext(CListItem *pli)
  759. {
  760. return (CListItem *)CONTAINING_RECORD(
  761. CListDouble::GetListNext(&((TYPE *)pli)->ldiNext), TYPE, ldiNext);
  762. };
  763. TYPE *GetListData(CListItem *pli)
  764. {
  765. return CONTAINING_RECORD(
  766. CListDouble::GetListData(&((TYPE *)pli)->ldiNext), TYPE, ldiNext);
  767. };
  768. };
  769. //---------------------------------------------------------------------------
  770. //---------------------------------------------------------------------------
  771. template<class TYPE>
  772. class ListDataAssertLess : public CListData
  773. {
  774. public:
  775. VOID AssertList(TYPE *p)
  776. {
  777. };
  778. PCLIST_ITEM GetListFirst()
  779. {
  780. return CListData::GetListFirst();
  781. };
  782. BOOL IsListEnd(PCLIST_ITEM pli)
  783. {
  784. return CListData::IsListEnd((CListDataData *)pli);
  785. };
  786. PCLIST_ITEM GetListNext(PCLIST_ITEM pli)
  787. {
  788. return CListData::GetListNext((CListDataData *)pli);
  789. };
  790. TYPE *GetListData(PCLIST_ITEM pli)
  791. {
  792. return (TYPE *)CListData::GetListData((CListDataData *)pli);
  793. };
  794. TYPE *GetListFirstData()
  795. {
  796. return (TYPE *)CListData::GetListFirstData();
  797. };
  798. NTSTATUS AddList(
  799. TYPE *p
  800. )
  801. {
  802. return CListData::AddList((PVOID)p);
  803. };
  804. NTSTATUS AddListDup(
  805. TYPE *p
  806. )
  807. {
  808. return CListData::AddListDup((PVOID)p);
  809. };
  810. NTSTATUS AddListEnd(
  811. TYPE *p
  812. )
  813. {
  814. return CListData::AddListEnd((PVOID)p);
  815. };
  816. NTSTATUS AddListOrdered(
  817. TYPE *p,
  818. LONG lFieldOffset
  819. )
  820. {
  821. return CListData::AddListOrdered((PVOID)p, lFieldOffset);
  822. };
  823. VOID RemoveList(
  824. TYPE *p
  825. )
  826. {
  827. CListData::RemoveList((PVOID)p);
  828. };
  829. };
  830. //---------------------------------------------------------------------------
  831. template<class TYPE>
  832. class ListData : public ListDataAssertLess<TYPE>
  833. {
  834. public:
  835. VOID AssertList(TYPE *p)
  836. {
  837. Assert(p);
  838. };
  839. ENUMFUNC EnumerateList(
  840. ENUMFUNC (TYPE::*pfn)()
  841. )
  842. {
  843. return CListData::EnumerateList((ENUMFUNC (CListDataItem::*)())pfn);
  844. };
  845. ENUMFUNC EnumerateList(
  846. ENUMFUNC (TYPE::*pfn)(
  847. PVOID pReference
  848. ),
  849. PVOID pReference
  850. )
  851. {
  852. return CListData::EnumerateList(
  853. (ENUMFUNC (CListDataItem::*)(PVOID))pfn,
  854. pReference);
  855. };
  856. };
  857. //---------------------------------------------------------------------------
  858. template<class TYPE>
  859. class ListDataDestroy : public ListData<TYPE>
  860. {
  861. public:
  862. ~ListDataDestroy()
  863. {
  864. ListDataDestroy::DestroyList();
  865. };
  866. VOID DestroyList()
  867. {
  868. ListDataDestroy::EnumerateList(TYPE::Destroy);
  869. CListData::DestroyList();
  870. };
  871. };
  872. //---------------------------------------------------------------------------
  873. //---------------------------------------------------------------------------
  874. template<class TYPE>
  875. class ListMulti : public CListMulti
  876. {
  877. public:
  878. VOID AssertList(TYPE *p)
  879. {
  880. Assert(p);
  881. };
  882. PCLIST_ITEM GetListFirst()
  883. {
  884. return CListMulti::GetListFirst();
  885. };
  886. PCLIST_ITEM GetListLast()
  887. {
  888. return CListMulti::GetListLast();
  889. };
  890. BOOL IsListEnd(PCLIST_ITEM pli)
  891. {
  892. return CListMulti::IsListEnd((CListMultiData *)pli);
  893. };
  894. PCLIST_ITEM GetListNext(PCLIST_ITEM pli)
  895. {
  896. return CListMulti::GetListNext((CListMultiData *)pli);
  897. };
  898. PCLIST_ITEM GetListPrevious(PCLIST_ITEM pli)
  899. {
  900. return CListMulti::GetListPrevious((CListMultiData *)pli);
  901. };
  902. TYPE *GetListData(PCLIST_ITEM pli)
  903. {
  904. return (TYPE *)CListMulti::GetListData((CListMultiData *)pli);
  905. };
  906. TYPE *GetListFirstData()
  907. {
  908. return (TYPE *)CListMulti::GetListFirstData();
  909. };
  910. ENUMFUNC EnumerateList(
  911. ENUMFUNC (TYPE::*pfn)()
  912. )
  913. {
  914. return CListMulti::EnumerateList((ENUMFUNC (CListMultiItem::*)())pfn);
  915. };
  916. ENUMFUNC EnumerateList(
  917. ENUMFUNC (TYPE::*pfn)(
  918. PVOID pReference
  919. ),
  920. PVOID pReference
  921. )
  922. {
  923. return CListMulti::EnumerateList(
  924. (ENUMFUNC (CListMultiItem::*)(PVOID))pfn,
  925. pReference);
  926. };
  927. };
  928. //---------------------------------------------------------------------------
  929. template<class TYPE>
  930. class ListMultiDestroy : public ListMulti<TYPE>
  931. {
  932. public:
  933. ~ListMultiDestroy()
  934. {
  935. ListMultiDestroy::DestroyList();
  936. };
  937. VOID DestroyList()
  938. {
  939. ListMultiDestroy::EnumerateList(TYPE::Destroy);
  940. CListMulti::DestroyList();
  941. };
  942. };
  943. //---------------------------------------------------------------------------
  944. // End of File: clist.h
  945. //---------------------------------------------------------------------------