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.

479 lines
15 KiB

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