Windows NT 4.0 source code leak
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.

606 lines
17 KiB

4 years ago
  1. // TitleC.cpp -- Implementation for class CTitleCollection
  2. #include "StdAfx.h"
  3. #include "TextSet.h"
  4. #include "Tokens.h"
  5. #include "TitleC.h"
  6. #include "Memex.h"
  7. CTitleCollection *CTitleCollection::NewTitleCollection(CTextSet **papts, UINT ctsSlots, CPersist *pPersistRelations)
  8. {
  9. CTitleCollection *ptc= NULL;
  10. __try
  11. {
  12. ptc= New CTitleCollection();
  13. ptc->AttachParameters(papts, ctsSlots, pPersistRelations);
  14. }
  15. __finally
  16. {
  17. if (_abnormal_termination() && ptc)
  18. {
  19. delete ptc; ptc= NULL;
  20. }
  21. }
  22. return ptc;
  23. }
  24. CTitleCollection::CTitleCollection() :
  25. #ifdef _DEBUG
  26. CTokenList(FALSE, "TitleCollection")
  27. #else // _DEBUG
  28. CTokenList(FALSE)
  29. #endif // _DEBUG
  30. {
  31. m_ctsSlots = 0;
  32. m_cTitles = 0;
  33. m_patsi = NULL;
  34. m_paiTitleStart = NULL;
  35. m_pati = NULL;
  36. m_paptiSorted = NULL;
  37. m_paiCategoryMaps = NULL;
  38. m_pisActiveTitles = NULL;
  39. m_fFromFile = FALSE;
  40. }
  41. CTitleCollection::~CTitleCollection()
  42. {
  43. if (m_pati ) VFree(m_pati );
  44. if (m_paptiSorted ) VFree(m_paptiSorted );
  45. if (m_paiTitleStart ) VFree(m_paiTitleStart );
  46. if (m_paiCategoryMaps) VFree(m_paiCategoryMaps);
  47. if (m_pisActiveTitles) DetachRef(m_pisActiveTitles);
  48. if (m_patsi)
  49. {
  50. UINT c= m_ctsSlots;
  51. for (; c--; ) if (m_patsi[c].pts) DetachRef(m_patsi[c].pts);
  52. VFree(m_patsi);
  53. }
  54. }
  55. void CTitleCollection::AttachParameters(CTextSet **papts, UINT ctsSlots, CPersist *pPersistRelations)
  56. {
  57. m_fFromFile= BOOL(pPersistRelations);
  58. m_patsi= (PTextSetInfo) VAlloc(TRUE, ctsSlots * sizeof(TextSetInfo));
  59. m_ctsSlots = ctsSlots;
  60. UINT c;
  61. for (c= ctsSlots; c--; )
  62. {
  63. CTextSet *pts= papts[c];
  64. if (!pts) continue;
  65. InstallTextSet(c, pts);
  66. }
  67. if (m_fFromFile) ReconstructRelations(pPersistRelations);
  68. InvalidateRepresentatives(pPersistRelations);
  69. }
  70. typedef struct _TitleRelationHeader
  71. {
  72. UINT ctsSlots;
  73. UINT cTitles;
  74. } TitleRelationHeader, *PTitleRelationHeader;
  75. void CTitleCollection::ReconstructRelations(CPersist *pPersistRelations)
  76. {
  77. CTokenList::ConnectImage2(pPersistRelations, TRUE);
  78. // We set the PREVIOUSLY_PRESENT flag for every text set we encounter.
  79. // That's necessary to skip the call to ReconstructCollection in InvalidateRepresentatives.
  80. // For similar reasons we also set the PREVIOUSLY_ACTIVE flag.
  81. UINT c= m_ctsSlots;
  82. for (; c--; )
  83. {
  84. if (IsPresent(c)) m_patsi[c].fFlags |= PREVIOUSLY_PRESENT;
  85. if (IsActive (c)) m_patsi[c].fFlags |= PREVIOUSLY_ACTIVE;
  86. }
  87. ASSERT(!m_pisActiveTitles);
  88. AttachRef(m_pisActiveTitles, CIndicatorSet::NewIndicatorSet(m_cd, TRUE));
  89. BuildTitleStarts();
  90. PTitleRelationHeader ptrh= PTitleRelationHeader(pPersistRelations->ReserveTableSpace(sizeof(TitleRelationHeader)));
  91. ASSERT(m_ctsSlots == ptrh->ctsSlots && m_cTitles == ptrh->cTitles);
  92. m_paiCategoryMaps = PUINT(VAlloc(FALSE, m_cTitles * sizeof(UINT)));
  93. PDESCRIPTOR *ppd;
  94. for (c= m_cd, ppd= m_ppdSorted + m_cd; c--; )
  95. m_paiCategoryMaps[*--ppd - m_pd] = c;
  96. m_pati= (PTitleInfo) VAlloc(TRUE, m_cTitles * sizeof(TitleInfo));
  97. PTitleInfo pti = m_pati + m_cTitles;
  98. PTextSetInfo ptsi;
  99. for (ptsi= m_patsi + m_ctsSlots, c= m_ctsSlots; c--; )
  100. {
  101. if (!(PRESENT & (--ptsi)->fFlags)) continue;
  102. CTextSet *pts = ptsi->pts;
  103. CTokenList *ptl = pts->TitleList();
  104. UINT cd = pts->TopicCount();
  105. for (; cd--; )
  106. {
  107. (--pti)->iaTSSlot = c;
  108. pti ->iPartition = cd;
  109. }
  110. }
  111. }
  112. void CTitleCollection::BuildTitleStarts()
  113. {
  114. m_paiTitleStart= PUINT(VAlloc(FALSE, (m_ctsSlots + 1) * sizeof(UINT)));
  115. PUINT piStart = m_paiTitleStart;
  116. PTextSetInfo ptsi = m_patsi;
  117. UINT c = m_ctsSlots;
  118. for (m_cTitles= 0, *piStart++= 0; c--; ptsi++)
  119. {
  120. if (ptsi->fFlags & PRESENT)
  121. m_cTitles += ptsi->cd;
  122. *piStart++= m_cTitles;
  123. }
  124. }
  125. void CTitleCollection::ConstructCollection()
  126. {
  127. BuildTitleStarts();
  128. m_pati= (PTitleInfo) VAlloc(TRUE, m_cTitles * sizeof(TitleInfo));
  129. m_paptiSorted= (PTitleInfo *) VAlloc(FALSE, m_cTitles * sizeof(PTitleInfo));
  130. PTitleInfo pti = m_pati + m_cTitles;
  131. PTitleInfo *ppti = m_paptiSorted + m_cTitles;
  132. m_lcidSorting = LCID(-1); // an invalid LCID value
  133. BOOL fLCID_Initialed = FALSE;
  134. PTextSetInfo ptsi;
  135. UINT c;
  136. for (ptsi= m_patsi + m_ctsSlots, c= m_ctsSlots; c--; )
  137. {
  138. if (!(PRESENT & (--ptsi)->fFlags)) continue;
  139. CTextSet *pts= ptsi->pts;
  140. if (fLCID_Initialed)
  141. {
  142. if (m_lcidSorting != pts->SortingLCID())
  143. m_lcidSorting = LCID(-1);
  144. }
  145. else
  146. {
  147. m_lcidSorting = pts->SortingLCID();
  148. fLCID_Initialed = TRUE;
  149. }
  150. pts->SyncIndices();
  151. CTokenList *ptl= pts->TitleList();
  152. INT cbMaxTitle= ptl->MaxWidthToken();
  153. if (cbMaxTitle > m_cbMaxLength) m_cbMaxLength= cbMaxTitle;
  154. UINT cd = ptl->m_cd;
  155. PDESCRIPTOR *ppd = ptl->m_ppdSorted + cd;
  156. PTitleInfo ptiBase = pti -= cd;
  157. PDESCRIPTOR pdBase = ptl->m_pd;
  158. for (; cd--; )
  159. {
  160. PDESCRIPTOR pd = *--ppd;
  161. UINT iPartition = pd - pdBase;
  162. PTitleInfo ptiTarget = ptiBase + iPartition;
  163. ptiTarget->pd= pd;
  164. ptiTarget->iaTSSlot = c;
  165. ptiTarget->iPartition = iPartition;
  166. *--ppti= ptiTarget;
  167. }
  168. }
  169. CombineTitleLists(m_paptiSorted, m_paiTitleStart, m_ctsSlots, &ppti, &c);
  170. ASSERT(c == m_cTitles);
  171. if (m_ctsSlots > 1)
  172. {
  173. VFree(m_paptiSorted);
  174. m_paptiSorted= ppti;
  175. }
  176. if (m_paiCategoryMaps)
  177. {
  178. VFree(m_paiCategoryMaps);
  179. m_paiCategoryMaps= NULL;
  180. }
  181. }
  182. BOOL CTitleCollection::InvalidateRepresentatives(CPersist *pPersistRelations)
  183. {
  184. UINT fChanges = 0;
  185. UINT c;
  186. for (c= m_ctsSlots; c--; )
  187. {
  188. UINT fFlags= m_patsi[c].fFlags;
  189. ASSERT((fFlags & (PRESENT | ACTIVE)) != ACTIVE);
  190. fChanges |= (fFlags & CURRENT_STATE) ^ ((fFlags & PREVIOUS_STATE) >> TIME_SHIFT);
  191. }
  192. if (!fChanges) return TRUE;
  193. if (fChanges & PRESENT) ReconstructCollection();
  194. if (fChanges & ACTIVE || !m_paiCategoryMaps) ReconstructRepresentatives();
  195. PTextSetInfo ptsi= m_patsi;
  196. for (c= m_ctsSlots; c--; ++ptsi)
  197. {
  198. UINT fOptions= ptsi->fFlags & (PRESENT | ACTIVE);
  199. ptsi->fFlags &= ~(PRESENT | ACTIVE | PREVIOUSLY_PRESENT | PREVIOUSLY_ACTIVE);
  200. ptsi->fFlags |= fOptions | (fOptions << TIME_SHIFT);
  201. }
  202. return TRUE;
  203. }
  204. void CTitleCollection::ReconstructCollection()
  205. {
  206. if (!m_pati) { ConstructCollection(); return; }
  207. ASSERT(FALSE); // Collection Change to be completed...
  208. }
  209. void CTitleCollection::ConstructRepresentatives()
  210. {
  211. ASSERT(!m_paiCategoryMaps);
  212. UINT c = m_ctsSlots;
  213. PTextSetInfo ptsi = m_patsi;
  214. PTitleInfo *ppti;
  215. UINT cwcDisplayImages = 0;
  216. UINT cwcSortKeyImages = 0;
  217. for (c= m_cTitles, ppti= m_paptiSorted; c--; )
  218. {
  219. PDESCRIPTOR pd = (*ppti++)->pd;
  220. cwcDisplayImages += CwDisplay(pd);
  221. cwcSortKeyImages += CbImage (pd);
  222. }
  223. PWCHAR pwcDisplayImages = NULL;
  224. PWCHAR pwcSortKeyImages = NULL;
  225. PDESCRIPTOR pdTitles = NULL;
  226. PDESCRIPTOR *ppdSortedTitles = NULL;
  227. __try
  228. {
  229. ValidateHeap();
  230. pdTitles = PDESCRIPTOR (VAlloc(FALSE, (m_cTitles+1) * sizeof(DESCRIPTOR )));
  231. ppdSortedTitles = (PDESCRIPTOR *) VAlloc(FALSE, m_cTitles * sizeof(PDESCRIPTOR));
  232. pwcDisplayImages = PWCHAR(VAlloc(FALSE, cwcDisplayImages * sizeof(WCHAR)));
  233. pwcSortKeyImages = PWCHAR(VAlloc(FALSE, cwcSortKeyImages * sizeof(WCHAR)));
  234. ValidateHeap();
  235. PWCHAR pwcDisplay = pwcDisplayImages;
  236. PWCHAR pwcSortKey = pwcSortKeyImages;
  237. PDESCRIPTOR pd;
  238. PDESCRIPTOR *ppd;
  239. PTitleInfo pti;
  240. for (c= m_cTitles, pti= m_pati, pd= pdTitles; c--; pti++, pd++)
  241. {
  242. PDESCRIPTOR pdTS = pti->pd;
  243. pti->pd = pd;
  244. *pd = *pdTS;
  245. UINT cwcDisplay = CwDisplay(pdTS);
  246. UINT cwcSortKey = CbImage (pdTS);
  247. pd->iTextSet = pti->iaTSSlot;
  248. pd->pwDisplay = pwcDisplay;
  249. pd->pbImage = pwcSortKey;
  250. CopyMemory(pwcDisplay, pdTS->pwDisplay, cwcDisplay * sizeof(WCHAR));
  251. CopyMemory(pwcSortKey, pdTS->pbImage , cwcSortKey * sizeof(WCHAR));
  252. pwcDisplay += cwcDisplay;
  253. pwcSortKey += cwcSortKey;
  254. }
  255. ValidateHeap();
  256. pd->pwDisplay = pwcDisplay; // To set a limit on the length of the last display image.
  257. pd->pbImage = pwcSortKey; // To set a limit on the length of the last sort key.
  258. ValidateHeap();
  259. m_paiCategoryMaps = (PUINT) VAlloc(FALSE, m_cTitles * sizeof(UINT));
  260. #ifdef _DEBUG
  261. FillMemory(m_paiCategoryMaps, m_cTitles * sizeof(UINT), UCHAR(-1));
  262. #endif // _DEBUG
  263. for (c= m_cTitles, ppd= ppdSortedTitles + m_cTitles, ppti= m_paptiSorted + m_cTitles; c--; )
  264. {
  265. PDESCRIPTOR pd = (*--ppti)->pd;
  266. *--ppd = pd;
  267. m_paiCategoryMaps[pd - pdTitles] = c;
  268. }
  269. ValidateHeap();
  270. }
  271. __finally
  272. {
  273. if (_abnormal_termination())
  274. {
  275. if(pwcDisplayImages) { VFree(pwcDisplayImages); pwcDisplayImages = NULL; }
  276. if(pwcSortKeyImages) { VFree(pwcSortKeyImages); pwcSortKeyImages = NULL; }
  277. if(pdTitles ) { VFree(pdTitles ); pdTitles = NULL; }
  278. if(ppdSortedTitles ) { VFree(ppdSortedTitles ); ppdSortedTitles = NULL; }
  279. }
  280. }
  281. InitialTokenList(pwcDisplayImages, cwcDisplayImages, pdTitles,
  282. m_cTitles, m_lcidSorting, pwcSortKeyImages, cwcSortKeyImages,
  283. ppdSortedTitles, NULL
  284. );
  285. NotifyViewers (ShapeChange);
  286. NotifyInterface(ShapeChange);
  287. }
  288. void CTitleCollection::ReconstructRepresentatives()
  289. {
  290. if (!m_paiCategoryMaps) ConstructRepresentatives();
  291. ChangeRef(m_pisActiveTitles, CIndicatorSet::NewIndicatorSet(m_cd));
  292. PDESCRIPTOR *ppd;
  293. UINT c;
  294. for (c= m_cd, ppd= m_ppdSorted + m_cd; c--; )
  295. {
  296. if ((m_patsi[(*--ppd)->iTextSet].fFlags & ACTIVE))
  297. m_pisActiveTitles->RawSetBit(c);
  298. }
  299. m_pisActiveTitles->InvalidateCache();
  300. }
  301. #if 0
  302. WORD auCredits[] =
  303. {
  304. 0x2d30, 0x4420, 0x7665, 0x6c65, 0x706f, 0x656d, 0x746e, 0x5420, 0x6165,
  305. 0x206d, 0x002d, 0x5231, 0x6e6f, 0x4d20, 0x7275, 0x6172, 0x0079, 0x5231,
  306. 0x646f, 0x656e, 0x2079, 0x6f4b, 0x6e72, 0x3100, 0x6952, 0x6863, 0x7261,
  307. 0x2064, 0x614b, 0x7a74, 0x3100, 0x6f4a, 0x6e68, 0x4820, 0x6c61, 0x006c,
  308. 0x4b31, 0x6972, 0x6873, 0x616e, 0x4e20, 0x7261, 0x6465, 0x7964, 0x3100,
  309. 0x6152, 0x706c, 0x2068, 0x6157, 0x646c, 0x6e65, 0x3100, 0x794c, 0x6e6e,
  310. 0x4220, 0x6f72, 0x6e77, 0x6c65, 0x006c, 0x4d31, 0x6369, 0x6168, 0x6c65,
  311. 0x4620, 0x202e, 0x2e43, 0x4320, 0x6972, 0x6b63, 0x3100, 0x0020, 0x0032,
  312. 0x2d30, 0x5520, 0x6573, 0x2072, 0x6e49, 0x6574, 0x6672, 0x6361, 0x2065,
  313. 0x6544, 0x6973, 0x6e67, 0x2d20, 0x3100, 0x6f52, 0x206e, 0x754d, 0x7272,
  314. 0x7961, 0x3100, 0x6f52, 0x6e64, 0x7965, 0x4b20, 0x726f, 0x006e, 0x4731,
  315. 0x7961, 0x656c, 0x5020, 0x6369, 0x656b, 0x006e, 0x4931, 0x6572, 0x656e,
  316. 0x5020, 0x7361, 0x6574, 0x6e72, 0x6361, 0x006b, 0x5431, 0x6d61, 0x2069,
  317. 0x6542, 0x7475, 0x6c65, 0x3100, 0x7553, 0x617a, 0x206e, 0x614d, 0x6172,
  318. 0x6873, 0x0069, 0x4b31, 0x6e65, 0x2074, 0x7553, 0x6c6c, 0x7669, 0x6e61,
  319. 0x3100, 0x6550, 0x7274, 0x2061, 0x6f48, 0x6666, 0x616d, 0x006e, 0x4a31,
  320. 0x6e61, 0x2065, 0x6144, 0x6c69, 0x7965, 0x3100, 0x0020, 0x0032, 0x2d30,
  321. 0x4720, 0x6f6c, 0x6162, 0x696c, 0x617a, 0x6974, 0x6e6f, 0x2d20, 0x3100,
  322. 0x6f52, 0x206e, 0x754d, 0x7272, 0x7961, 0x3100, 0x6952, 0x6863, 0x7261,
  323. 0x2064, 0x614b, 0x7a74, 0x3100, 0x7341, 0x756d, 0x2073, 0x7246, 0x7965,
  324. 0x6174, 0x0067, 0x2031, 0x6120, 0x616b, 0x4420, 0x2e72, 0x5520, 0x696e,
  325. 0x6f63, 0x6564, 0x3100, 0x6f4c, 0x6972, 0x4820, 0x656f, 0x7472, 0x0068,
  326. 0x4331, 0x7461, 0x6568, 0x6972, 0x656e, 0x5720, 0x7369, 0x6973, 0x6b6e,
  327. 0x3100, 0x2e4b, 0x4420, 0x202e, 0x6843, 0x6e61, 0x0067, 0x2031, 0x3200,
  328. 0x3000, 0x202d, 0x6554, 0x7473, 0x6e69, 0x2067, 0x002d, 0x5431, 0x6d69,
  329. 0x4c20, 0x7765, 0x7369, 0x3100, 0x6152, 0x646e, 0x6c61, 0x206c, 0x7453,
  330. 0x6d69, 0x7370, 0x6e6f, 0x3100, 0x0020, 0x0032, 0x2d30, 0x4220, 0x7275,
  331. 0x6165, 0x6375, 0x6172, 0x7963, 0x4320, 0x6e6f, 0x7274, 0x6c6f, 0x2d20,
  332. 0x3100, 0x614d, 0x6972, 0x6e6f, 0x4820, 0x676f, 0x6e61, 0x3100, 0x694e,
  333. 0x6f63, 0x656c, 0x4d20, 0x7469, 0x6b73, 0x676f, 0x3100, 0x6952, 0x6b63,
  334. 0x5320, 0x6765, 0x6c61, 0x3100, 0x6154, 0x6d6d, 0x2079, 0x7453, 0x6565,
  335. 0x656c, 0x3100, 0x0020, 0x0032, 0x2d30, 0x5320, 0x6570, 0x6963, 0x6c61,
  336. 0x5420, 0x6168, 0x6b6e, 0x2073, 0x002d, 0x4331, 0x7268, 0x7369, 0x4d20,
  337. 0x7275, 0x6172, 0x2079, 0x3100, 0x6c45, 0x7a69, 0x6261, 0x7465, 0x2068,
  338. 0x6f4b, 0x6e72, 0x3100, 0x694c, 0x206e, 0x7548, 0x6e61, 0x0067, 0x5331,
  339. 0x7269, 0x7369, 0x6168, 0x4420, 0x6e6f, 0x6974, 0x6572, 0x6464, 0x0079,
  340. 0x2031, 0x3200, 0x0000, 0x6e45, 0x2064, 0x666f, 0x6420, 0x7461, 0x0061,
  341. 0x0000
  342. };
  343. UINT cnCode = 0;
  344. UINT cbData = sizeof(auCredits);
  345. UINT offData = 0;
  346. #endif // 0
  347. void CTitleCollection::RecordRelations(CPersist *pPersistDiskImage)
  348. {
  349. PUINT paiPermute= NULL;
  350. CTokenList::StoreImage2(pPersistDiskImage, TRUE);
  351. PTitleRelationHeader ptrh= (PTitleRelationHeader) (pPersistDiskImage->ReserveTableSpace(sizeof(TitleRelationHeader)));
  352. ptrh->ctsSlots = m_ctsSlots;
  353. ptrh->cTitles = m_cTitles;
  354. #if 0
  355. offData = pPersistDiskImage->NextOffset();
  356. cnCode = pPersistDiskImage->Encode(PBYTE(auCredits), cbData);
  357. #endif // 0
  358. }
  359. void CTitleCollection::CombineTitleLists(PTitleInfo *paptiSets, PUINT paiTitleStarts, UINT ctiSets,
  360. PTitleInfo **ppptiSorted, PUINT pcti
  361. )
  362. {
  363. PTitleInfo *paptiSortedLeft = NULL,
  364. *paptiSortedRight = NULL;
  365. PTitleInfo *paptiSortedResult= NULL;
  366. UINT cFirst = 0;
  367. UINT cSecond = 0;
  368. __try
  369. {
  370. if (ctiSets == 1)
  371. {
  372. *ppptiSorted = paptiSets + *paiTitleStarts;
  373. *pcti = *(paiTitleStarts + 1) - *paiTitleStarts;
  374. __leave;
  375. }
  376. UINT ctiLeft = 0,
  377. ctiRight = 0;
  378. cFirst = ctiSets / 2;
  379. cSecond = ctiSets - cFirst;
  380. CombineTitleLists(paptiSets, paiTitleStarts, cFirst, &paptiSortedLeft, &ctiLeft);
  381. CombineTitleLists(paptiSets, paiTitleStarts + cFirst, cSecond, &paptiSortedRight, &ctiRight);
  382. UINT ctiResult= ctiLeft + ctiRight;
  383. paptiSortedResult= (PTitleInfo *) VAlloc(FALSE, ctiResult * sizeof(PTitleInfo));
  384. MergeImageRefSets((PVOID *) paptiSortedResult, ctiResult,
  385. (PVOID *) paptiSortedLeft, ctiLeft,
  386. (PVOID *) paptiSortedRight, ctiRight,
  387. CompareTitleInfo
  388. );
  389. *ppptiSorted = paptiSortedResult; paptiSortedResult= NULL;
  390. *pcti = ctiResult;
  391. }
  392. __finally
  393. {
  394. if (paptiSortedLeft && cFirst > 1) { VFree(paptiSortedLeft ); paptiSortedLeft = NULL; }
  395. if (paptiSortedRight && cSecond > 1) { VFree(paptiSortedRight); paptiSortedRight = NULL; }
  396. if (_abnormal_termination() && paptiSortedResult)
  397. {
  398. VFree(paptiSortedResult); paptiSortedResult= NULL;
  399. }
  400. }
  401. }
  402. int __cdecl CTitleCollection::CompareTitleInfo(const void *pvL, const void *pvR)
  403. {
  404. return CompareImagesLR(&(*(const TitleInfo **) pvL)->pd, &(*(const TitleInfo **) pvR)->pd);
  405. }
  406. UINT CTitleCollection::MapToTitleLists(CIndicatorSet * pisTitles, PTitleInfo *paptiLists, UINT cLists)
  407. {
  408. PUINT paiBuffer= NULL;
  409. UINT cTitlesFound= 0;
  410. __try
  411. {
  412. ASSERT(cLists >= m_ctsSlots);
  413. UINT cTitles= pisTitles? pisTitles->SelectionCount() : m_cd;
  414. UINT cChunk= C_INDICES_CHUNK;
  415. if (cChunk > cTitles) cChunk= cTitles;
  416. paiBuffer= PUINT(VAlloc(FALSE, cChunk * sizeof(UINT)));
  417. ZeroMemory(paptiLists, cLists * sizeof(PTokenInfo));
  418. UINT iTitleFirst;
  419. for (iTitleFirst= 0; cTitles; iTitleFirst += cChunk, cTitles -= cChunk)
  420. {
  421. if (cChunk > cTitles) cChunk= cTitles;
  422. UINT c, i;
  423. PUINT pi;
  424. if (pisTitles) pisTitles->MarkedItems(iTitleFirst, PINT(paiBuffer), cChunk);
  425. else
  426. for (i= iTitleFirst, c= cChunk, pi= paiBuffer; c--; ) *pi++ = i++;
  427. for (c= cChunk, pi= paiBuffer + cChunk; c--; )
  428. {
  429. PTitleInfo pti= m_pati + (m_ppdSorted[*--pi] - m_pd);
  430. UINT iSlot= pti->iaTSSlot;
  431. ASSERT(m_patsi[iSlot].fFlags & PRESENT);
  432. if (!(ACTIVE & m_patsi[iSlot].fFlags)) continue;
  433. ++cTitlesFound;
  434. pti->ptiNext= paptiLists[iSlot];
  435. paptiLists[iSlot]= pti;
  436. }
  437. }
  438. }
  439. __finally
  440. {
  441. if (paiBuffer) { VFree(paiBuffer); paiBuffer= NULL; }
  442. }
  443. return cTitlesFound;
  444. }