Source code of Windows XP (NT5)
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.

486 lines
15 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999 - 1999
  6. //
  7. // File: collect.h
  8. //
  9. //--------------------------------------------------------------------------
  10. //*********************************************************************************************************************************************
  11. //
  12. // File: collect.h
  13. // Author: Donald Drake
  14. // Purpose: Defines classes to support titles, collections, locations and folders
  15. #ifndef _COLLECT_H
  16. #define _COLLECT_H
  17. #undef CLASS_IMPORT_EXPORT
  18. #ifdef HHCTRL // define this only when building the HHCtrl DLL
  19. #define CLASS_IMPORT_EXPORT /**/
  20. #else
  21. #ifdef HHSETUP // define this only when building the HHSetup DLL
  22. #define CLASS_IMPORT_EXPORT __declspec( dllexport )
  23. #else
  24. #define CLASS_IMPORT_EXPORT __declspec( dllimport )
  25. #endif
  26. #endif
  27. #ifndef HHCTRL
  28. #undef COUNT
  29. #define COUNT(x)
  30. #undef MI_COUNT
  31. #define MI_COUNT(x)
  32. #undef SI_COUNT
  33. #define SI_COUNT(x)
  34. #undef MI2_COUNT
  35. #define MI2_COUNT(x)
  36. #undef AUTO_CLASS_COUNT_CHECK
  37. #define AUTO_CLASS_COUNT_CHECK(x)
  38. #undef CHECK_CLASS_COUNT
  39. #define CHECK_CLASS_COUNT(x)
  40. #undef DUMP_CLASS_COUNT
  41. #define DUMP_CLASS_COUNT(x)
  42. #endif
  43. #ifdef HHCTRL
  44. #include "parserhh.h"
  45. #else
  46. #include "parser.h"
  47. #endif
  48. #define F_MSDN 0x0001
  49. #define F_TITLELOCAL 0x0002
  50. #define F_INDEXLOCAL 0x0004
  51. #define ENGLANGID 1033
  52. #define MAX_LEVELS 100
  53. typedef struct LocationHistory {
  54. CHAR * SampleLocation;
  55. CHAR * FileName;
  56. CHAR * IndexFileName;
  57. CHAR * QueryFileName;
  58. CHAR * LocationId;
  59. DWORD CollectionNumber;
  60. DWORD Version;
  61. DWORD LastPromptedVersion;
  62. BOOL bSupportsMerge;
  63. LocationHistory *pNext;
  64. CHAR * QueryLocation;
  65. } LOCATIONHISTORY;
  66. DWORD CLASS_IMPORT_EXPORT AllocSetValue(const CHAR *value, CHAR **dest);
  67. // forward declarations
  68. class CLocation;
  69. class CTitle;
  70. class CCollection;
  71. class CFolder;
  72. class CSlotLookupTable;
  73. class CExTitle;
  74. class CColList;
  75. typedef struct ListItem {
  76. void *pItem;
  77. ListItem *Next;
  78. } LISTITEM;
  79. class CLASS_IMPORT_EXPORT CPointerList {
  80. private:
  81. LISTITEM *m_pHead;
  82. public:
  83. CPointerList()
  84. {
  85. m_pHead = NULL;
  86. }
  87. ~CPointerList();
  88. void RemoveAll();
  89. LISTITEM *Add(void *);
  90. LISTITEM *First();
  91. LISTITEM *Next(LISTITEM *p) { return p->Next; }
  92. };
  93. #ifdef HHCTRL // define this only when building the HHCtrl DLL
  94. //
  95. // <mc>
  96. // This lookup table will facilitate a quick translation of a "slot" number into a CFolder* as well as a
  97. // HASH value into a CFolder*. This will be done using two DWORDS per CFolder object, one for the HASH value
  98. // and one for the CFolder*. After ALL the CFolders for a given collection have been created and this lookup
  99. // table is fully populated the SortAndAssignSlots() member will be called. This will sort the table by HASH
  100. // value and will assign the slot values back to the CFolders according to the sorted order. This will make
  101. // slot --> CFolder* lookup a simple array index and will also allow us to use a bsearch for the
  102. // HASH --> CFolder* lookup. Note that only leaf level CFolders have useful hash values, for the non leaf
  103. // CFolders we will assign a hash of -1, these items in the table will then appear at the end of the table
  104. // and will not interfear with a bsearch operation when translating a hash into a pSLT.
  105. // </mc>
  106. //
  107. class CSlotLookupTable
  108. {
  109. public:
  110. CSlotLookupTable();
  111. ~CSlotLookupTable();
  112. static int FASTCALL ltqs_callback(const void *elem1, const void *elem2);
  113. void AddValue(CFolder* pFolder);
  114. void SortAndAssignSlots(void);
  115. CFolder* HashToCFolder(HASH hash);
  116. CFolder* SlotToCFolder(DWORD dwSlot)
  117. {
  118. if ( dwSlot > 0 && dwSlot <= m_uiTotalCnt ) // Slot 0 reserved for error case.
  119. return m_pSLT[dwSlot].pCFolder;
  120. else
  121. return NULL;
  122. }
  123. private:
  124. struct _slt
  125. {
  126. HASH hash;
  127. CFolder* pCFolder;
  128. };
  129. struct _slt* m_pSLT;
  130. unsigned m_uiTotalAllocated;
  131. unsigned m_uiTotalCnt;
  132. unsigned m_uiHashCnt;
  133. };
  134. #endif
  135. class CLASS_IMPORT_EXPORT CFolder SI_COUNT(CFolder)
  136. {
  137. private:
  138. CHAR *Title; // name of the folder
  139. WCHAR *pwcTitle;
  140. DWORD Order;
  141. LANGID LangId;
  142. DWORD dwSlot;
  143. CExTitle* pExTitle;
  144. CFolder *pNext, *pKid, *pParent;
  145. //
  146. // This DWORD value is being added to support .CHM level subsetting.
  147. //
  148. WORD iLevel;
  149. WORD f_Filter: 1; // render into filter LB.
  150. WORD f_Available: 1; // render into Available LB.
  151. WORD f_F_Open: 1; // Expanded or closed ?
  152. WORD f_A_Open: 1; // Expanded or closed ?
  153. WORD f_HasHash: 1; // Does Node have a prefix hash ?
  154. WORD f_IsOrphan: 1; // Is this node an orphane ?
  155. WORD f_IsVisable: 1; // Indicates membership in the currently selected TOC subset.
  156. public:
  157. CFolder();
  158. ~CFolder();
  159. BOOL bIsVisable() { return (BOOL)f_IsVisable; }
  160. void SetTitle(const CHAR *);
  161. void SetTitle(const WCHAR *);
  162. void SetExTitlePtr(CExTitle* pTitle);
  163. CHAR *GetTitle() { return Title; }
  164. const WCHAR *GetTitleW();
  165. void SetLanguage(LANGID Id) { LangId = Id; }
  166. LANGID GetLanguage() { return LangId; }
  167. void SetOrder(DWORD);
  168. DWORD GetOrder();
  169. // Returns the next sibling folder given a folder entry
  170. CFolder * GetNextFolder();
  171. void SetNextFolder(CFolder *p) { pNext = p; }
  172. // Returns the first child of a given folder if it exists
  173. CFolder * GetFirstChildFolder();
  174. void SetFirstChildFolder(CFolder *p) { pKid = p; }
  175. // Add a new folder as child of a given folder
  176. CFolder * AddChildFolder(const CHAR *szName, DWORD Order, DWORD *pError, LANGID LangId = ENGLANGID);
  177. CFolder * AddChildFolder(const WCHAR *szName, DWORD Order, DWORD *pError, LANGID LangId = ENGLANGID);
  178. DWORD AddChildFolder(CFolder *newFolder);
  179. void SetParent(CFolder *p) { pParent = p; }
  180. CFolder * GetParent() { return pParent; }
  181. friend class CSlotLookupTable;
  182. friend class CDefineSS;
  183. friend class CStructuralSubset;
  184. };
  185. class CLASS_IMPORT_EXPORT CCollection SI_COUNT(CCollection)
  186. {
  187. public:
  188. CCollection();
  189. ~CCollection();
  190. void ConfirmTitles() { m_bConfirmTitles = TRUE; }
  191. void SetSampleLocation(const CHAR *);
  192. CHAR *GetSampleLocation();
  193. void SetMasterCHM(const CHAR *szName, LANGID Lang);
  194. BOOL GetMasterCHM(CHAR ** szName, LANGID *Lang);
  195. // Opens and loads the contents of the file into data structures
  196. DWORD Open(const CHAR * FileName);
  197. void SetSampleLocation(const WCHAR *);
  198. const WCHAR *GetSampleLocationW();
  199. void SetMasterCHM(const WCHAR *szName, LANGID Lang);
  200. BOOL GetMasterCHM(WCHAR ** szName, LANGID *Lang);
  201. // Opens and loads the contents of the file into data structures
  202. DWORD Open(const WCHAR * FileName);
  203. // Saves any changes made to the internal data structures to the file.
  204. DWORD Save();
  205. DWORD Close();
  206. void AddRef() { m_dwRef++; }
  207. DWORD GetVersion() { return m_dwVersion; }
  208. void SetVersion(DWORD dw) { m_dwVersion = dw; }
  209. // navigating the collection
  210. // Returns the first folder in the collection
  211. CFolder * GetRootFolder() { return m_pRootFolder; }
  212. CFolder * GetVisableRootFolder() { return m_pRootFolder->GetFirstChildFolder(); } // Returns the visable root.
  213. // Returns the first title
  214. CTitle * GetFirstTitle();
  215. // Locates a title based on id
  216. CTitle * FindTitle(const CHAR * Id, LANGID LangId = ENGLANGID);
  217. CTitle * FindTitle(const WCHAR * Id, LANGID LangId = ENGLANGID);
  218. // Try multiple LangIds, before failing.
  219. #ifdef HHCTRL
  220. CTitle * FindTitleNonExact(const CHAR * Id, LANGID LangId) ;
  221. #endif // #ifdef HHCTRL
  222. // Returns the first location
  223. CLocation* FirstLocation();
  224. // Finds a location based on a name
  225. CLocation * FindLocation(const CHAR * Name, UINT* puiVolumeOrder = NULL );
  226. // collection entry management
  227. CColList * FindCollection(CHAR *szFileName);
  228. CColList * AddCollection();
  229. void RemoveCollectionEntry(CHAR *szFileName);
  230. //Adds a new folder to the top level of the table of contents, with the given name and order and returns a pointer to that folder object. A return of NULL indicates a failure and pDWORD will be populated with one of above DWORD codes.
  231. CFolder * AddFolder(const CHAR * szName, DWORD Order, DWORD *pDWORD, LANGID LangId = ENGLANGID);
  232. DWORD DeleteFolder(CFolder *);
  233. //Adds a title based on the provided information.
  234. //A return of NULL indicates a failure and pDWORD will be
  235. //populated with one of above DWORD codes. Note: you must add or
  236. //find a CLocation object or pass null to indication no location is in
  237. // use (local file).
  238. CTitle * AddTitle(const CHAR * Id, const CHAR * FileName, const CHAR * IndexFile,
  239. const CHAR * Query, const CHAR *SampleLocation, LANGID Lang,
  240. UINT uiFlags, CLocation *pLocation, DWORD *pDWORD,
  241. BOOL bSupportsMerge = FALSE, const CHAR *QueryLocation = NULL);
  242. // Adds location based on the given information. A return of NULL indicates a failure and pDWORD will be populated with one of above DWORD codes.
  243. CLocation * AddLocation(const CHAR * Title, const CHAR * Path, const CHAR * Id, const CHAR * Volume, DWORD *pDWORD);
  244. CLocation * FindLocation(const WCHAR * Name, UINT* puiVolumeOrder = NULL );
  245. CFolder * AddFolder(const WCHAR * szName, DWORD Order, DWORD *pDWORD, LANGID LangId = ENGLANGID);
  246. CTitle * AddTitle(const WCHAR * Id, const WCHAR * FileName,
  247. const WCHAR * IndexFile, const WCHAR * Query,
  248. const WCHAR *SampleLocation, LANGID Lang, UINT uiFlags,
  249. CLocation *pLocation, DWORD *pDWORD,
  250. BOOL bSupportsMerge = FALSE, const WCHAR *QueryLocation = NULL);
  251. CLocation * AddLocation(const WCHAR * Title, const WCHAR * Path, const WCHAR * Id, const WCHAR * Volume, DWORD *pDWORD);
  252. DWORD RemoveCollection(BOOL bRemoveLocalFiles = FALSE);
  253. DWORD GetRefTitleCount() { return m_dwTitleRefCount; }
  254. // Merges the currently installed titles for the collection into the specified filename (path determined internally)
  255. BOOL MergeKeywords(CHAR * pwzFilename );
  256. BOOL MergeKeywords(WCHAR * pwzFilename );
  257. DWORD GetColNo() { return m_dwColNo; }
  258. PCSTR GetCollectionFileName(void) { return m_szFileName; }
  259. const WCHAR *GetCollectionFileNameW(void);
  260. BOOL IsDirty() { return m_bDirty;}
  261. void IncrementRefTitleCount() { m_dwTitleRefCount++; }
  262. void DecrementRefTitleCount() { m_dwTitleRefCount--; }
  263. void Dirty() { m_bDirty = TRUE; }
  264. LANGID GetLangId(const CHAR *FileName);
  265. LANGID GetLangId(const WCHAR *FileName);
  266. private: // functions
  267. DWORD AddRefedTitle(CFolder *pFolder);
  268. // removing objects
  269. DWORD DeleteTitle(CTitle *);
  270. void DeleteLocalFiles(LOCATIONHISTORY *pHist, CTitle *pTitle);
  271. DWORD DeleteLocation(CLocation *);
  272. DWORD CheckTitleRef(const CHAR *pId, const LANGID Lang);
  273. DWORD CheckTitleRef(const WCHAR *pId, const LANGID Lang);
  274. DWORD ParseFile(const CHAR *FileName);
  275. DWORD HandleCollection(CParseXML *parser, CHAR *sz);
  276. DWORD HandleCollectionEntry(CParseXML *parser, CHAR *sz);
  277. DWORD HandleFolder(CParseXML *parser, CHAR *token);
  278. DWORD HandleLocation(CParseXML *parser, CHAR *token);
  279. DWORD HandleTitle(CParseXML *parser, CHAR *token);
  280. void DeleteChildren(CFolder **p);
  281. void DeleteFolders(CFolder **p);
  282. BOOL WriteFolders(CFolder **p);
  283. BOOL WriteFolder(CFolder **p);
  284. DWORD AllocCopyValue(CParseXML *parser, CHAR *token, CHAR **dest);
  285. CTitle *NewTitle();
  286. CLocation *NewLocation();
  287. private:
  288. BOOL m_bRemoveLocalFiles;
  289. BOOL m_bRemoved;
  290. DWORD Release();
  291. CHAR * m_szFileName;
  292. WCHAR * m_pwcFileName;
  293. CHAR * m_szMasterCHM;
  294. WCHAR * m_pwcMasterCHM;
  295. CHAR * m_szSampleLocation;
  296. WCHAR * m_pwcSampleLocation;
  297. LANGID m_MasterLangId;
  298. CTitle * m_pFirstTitle;
  299. CTitle * m_pTitleTail;
  300. CLocation * m_pFirstLocation;
  301. CLocation * m_pLocationTail;
  302. CFolder *m_pRootFolder;
  303. DWORD m_locationnum;
  304. CFIFOString m_Strings;
  305. CFolder *m_pParents[MAX_LEVELS];
  306. DWORD m_dwCurLevel;
  307. DWORD m_dwLastLevel;
  308. DWORD m_dwNextColNo;
  309. DWORD m_dwColNo;
  310. DWORD m_dwTitleRefCount;
  311. BOOL m_bConfirmTitles;
  312. DWORD m_dwRef;
  313. DWORD m_dwVersion;
  314. HANDLE m_fh;
  315. BOOL m_bDirty;
  316. CColList *m_pColListHead;
  317. CColList *m_pColListTail;
  318. public:
  319. CPointerList m_RefTitles;
  320. BOOL m_bFailNoFile;
  321. BOOL m_bAllFilesDeleted;
  322. };
  323. class CColList
  324. {
  325. private:
  326. DWORD m_dwColNo;
  327. CHAR * m_szFileName;
  328. CColList *m_pNext;
  329. public:
  330. CColList();
  331. ~CColList();
  332. void SetColNo(DWORD dw) { m_dwColNo = dw; }
  333. void SetFileName(CHAR *szFileName);
  334. DWORD GetColNo() { return m_dwColNo; }
  335. CHAR *GetFileName() { return m_szFileName; }
  336. CColList *GetNext() { return m_pNext; }
  337. void SetNext(CColList *p) { m_pNext = p; }
  338. };
  339. class CLASS_IMPORT_EXPORT CTitle SI_COUNT(CTitle)
  340. {
  341. private:
  342. CHAR * Id; // Title identifier
  343. WCHAR *pwcId;
  344. LANGID Language; // language identifier
  345. CTitle *NextTitle; // pointer to the next title
  346. public:
  347. LOCATIONHISTORY *m_pHead, *m_pTail;
  348. void SetId(const CHAR *);
  349. void SetId(const WCHAR *);
  350. void SetLanguage(LANGID);
  351. CHAR * GetId();
  352. const WCHAR * GetIdW();
  353. LANGID GetLanguage();
  354. LOCATIONHISTORY *GetLocation(DWORD Index);
  355. CTitle* GetNextTitle();
  356. ~CTitle();
  357. CTitle();
  358. LOCATIONHISTORY *NewLocationHistory();
  359. DWORD AddLocationHistory(DWORD ColNo, const CHAR *FileName, const CHAR *IndexFile, const CHAR *Query, const CLocation *pLocation, const CHAR *Sample, const CHAR *QueryLocation, BOOL bSupportsMerge);
  360. DWORD AddLocationHistory(DWORD ColNo, const WCHAR *FileName, const WCHAR *IndexFile, const WCHAR *Query, const CLocation *pLocation, const WCHAR *Sample, const WCHAR *QueryLocation, BOOL bSupportsMerge);
  361. void SetNextTitle(CTitle *p) { NextTitle = p; }
  362. };
  363. class CLASS_IMPORT_EXPORT CLocation SI_COUNT(CLocation)
  364. {
  365. private:
  366. CHAR * Id;
  367. CHAR * Title; // Friendly name for the title
  368. CHAR * Path; // location of the device
  369. CHAR * Volume;
  370. WCHAR * pwcId;
  371. WCHAR * pwcTitle; // Friendly name for the title
  372. WCHAR * pwcPath; // location of the device
  373. WCHAR * pwcVolume;
  374. CLocation *NextLocation; // pointer to the next location if it exists
  375. public:
  376. DWORD m_ColNum;
  377. CLocation()
  378. {
  379. Id = NULL;
  380. Title = NULL;
  381. Path = NULL;
  382. Volume = NULL;
  383. NextLocation = NULL;
  384. pwcId = NULL;
  385. pwcTitle = NULL;
  386. pwcPath = NULL;
  387. pwcVolume = NULL;
  388. }
  389. ~CLocation()
  390. {
  391. if (Id)
  392. delete Id;
  393. if (Title)
  394. delete Title;
  395. if (Path)
  396. delete Path;
  397. if (Volume)
  398. delete Volume;
  399. if (pwcId)
  400. delete pwcId;
  401. if (pwcTitle)
  402. delete pwcTitle;
  403. if (pwcPath)
  404. delete pwcPath;
  405. if (pwcVolume)
  406. delete pwcVolume;
  407. }
  408. void SetNextLocation(CLocation *p) { NextLocation = p; }
  409. void SetId(const CHAR *);
  410. void SetTitle(const CHAR *);
  411. void SetPath(const CHAR *);
  412. void SetVolume(const CHAR *);
  413. CHAR * GetId() const;
  414. CHAR * GetTitle();
  415. CHAR * GetPath();
  416. CHAR * GetVolume();
  417. void SetId(const WCHAR *);
  418. void SetTitle(const WCHAR *);
  419. void SetPath(const WCHAR *);
  420. void SetVolume(const WCHAR *);
  421. const WCHAR * GetIdW();
  422. const WCHAR * GetTitleW();
  423. const WCHAR * GetPathW();
  424. const WCHAR * GetVolumeW();
  425. // Returns the next location
  426. CLocation *GetNextLocation();
  427. };
  428. #endif