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.

426 lines
14 KiB

  1. // Copyright (C) Microsoft Corporation 1996-1997, All Rights reserved.
  2. //*********************************************************************************************************************************************
  3. //
  4. // File: toc.h
  5. // Author: Donald Drake
  6. // Purpose: Defines classes to support populating the table of contents
  7. #if _MSC_VER > 1000
  8. #pragma once
  9. #endif
  10. #ifndef _TOC_H
  11. #define _TOC_H
  12. #include "cinfotyp.h"
  13. #include "system.h"
  14. #include "collect.h"
  15. #include "hhtypes.h"
  16. #include "fs.h"
  17. #include "subfile.h"
  18. #include "state.h"
  19. #include "csubset.h"
  20. //#include "subset.h" // Structural subsets
  21. #include "hhfinder.h"
  22. #define MAX_OPEN_TITLES 25
  23. //#define DUMPTOC 1
  24. #ifdef DUMPTOC
  25. #include <stdio.h>
  26. #endif
  27. // Persist keys. Declared in toc.cpp
  28. //
  29. extern const char g_szFTSKey[];
  30. extern const char g_szIndexKey[];
  31. extern const char g_szTOCKey[];
  32. class CExTitle;
  33. class CExFolderNode;
  34. class CExTitleNode;
  35. class CExMergedTitleNode;
  36. class CExNode;
  37. class CTreeNode;
  38. class CFullTextSearch;
  39. class CTitleFTS;
  40. class CSearchHighlight;
  41. class CPagedSubfile;
  42. class CTitleDatabase;
  43. class CSSList;
  44. extern CExCollection* g_pCurrentCollection;
  45. //[ZERO IDXHDR] The IDX Header subfile may be zero length, because some early version of HHCTRL
  46. // didn't write it out. We need to make sure that we have an IDX header before we try to use it.
  47. // If we don't we will crash.
  48. #define IDXHEADER_UNINITIALIZED (0xFFFFFFFF)
  49. //class CExTitle: public CSubfileGroupList
  50. class CExTitle SI_COUNT(CExTitle)
  51. {
  52. friend class CPagedSubfile;
  53. public:
  54. void _CExTitle();
  55. CExTitle(CTitle* p, DWORD ColNo, CExCollection* pCollection);
  56. CExTitle(const CHAR* pszFileName, CExCollection* pCollection);
  57. ~CExTitle();
  58. inline BOOL Init() { int bReturn = TRUE; if( !isOpen() ) bReturn = OpenTitle(); return bReturn; }
  59. inline CTitleInformation* GetInfo() { if( Init() ) return m_pInfo; else return NULL; }
  60. inline CTitleInformation2* GetInfo2() { return m_pInfo2; }
  61. inline BOOL isOpen(void) { return m_bOpen; }
  62. inline CFileSystem* GetTitleIdxFileSystem(void) { if(!m_bOpen) OpenTitle(); return m_pCFileSystem; }
  63. inline void SetNodeOffsetInParentTitle(DWORD dw) { m_dwNodeOffsetInParentTitle = dw;}
  64. inline DWORD GetNodeOffsetInParentTitle() { return m_dwNodeOffsetInParentTitle; }
  65. inline CExTitle* GetNext() { return m_pNext; }
  66. inline void SetNext(CExTitle* p) { m_pNext = p; }
  67. IDXHEADER* GetIdxHeaderStruct() { ASSERT(IsIdxHeaderValid()); return m_pIdxHeader;}
  68. DWORD GetTopicCount() { ASSERT(IsIdxHeaderValid()); return m_pIdxHeader->cTopics;}
  69. BOOL IsIdxHeaderValid() { if(m_pIdxHeader) return (BOOL)m_pIdxHeader->cTopics; else return FALSE; }
  70. CTitle* GetCTitle() { return m_pTitle; }
  71. CFileSystem* GetFileSystem(void) { return m_pCFileSystem; }
  72. LOCATIONHISTORY* GetUsedLocation() { return m_pUsedLocation; }
  73. BOOL isChiFile(void) { return m_fIsChiFile; }
  74. const unsigned int* GetITBits(DWORD dwOffsBits);
  75. BOOL OpenTitle();
  76. void CloseTitle();
  77. BOOL exOpenFile(const CHAR* pszContent, const CHAR* pszIndex = NULL);
  78. BOOL InfoTypeFilter(CSubSet* pSubSet, DWORD dwTopic);
  79. const unsigned int* GetTopicITBits(DWORD dwTN);
  80. HRESULT GetRootNode(TOC_FOLDERNODE* pNode);
  81. DWORD GetRootSlot(void);
  82. HRESULT GetNode(DWORD iNode, TOC_FOLDERNODE* pNode);
  83. const CHAR* GetFileName();
  84. const CHAR* GetPathName();
  85. const CHAR* GetQueryName();
  86. const CHAR* GetIndexFileName();
  87. const CHAR* GetCurrentAttachmentName();
  88. const CHAR* SetCurrentAttachmentName( const CHAR* pszAttachmentPathName );
  89. HRESULT GetTopicName( DWORD dwTopic, CHAR* pszTitle, int cb );
  90. HRESULT GetTopicName( DWORD dwTopic, WCHAR* pwszTitle, int cch );
  91. HRESULT GetTopicLocation(DWORD dwTopic, CHAR* pszLocation, int cb);
  92. HRESULT GetTopicLocation(DWORD dwTopic, WCHAR* pwszLocation, int cch);
  93. HRESULT GetUrlTocSlot(const CHAR* pszURL, DWORD* pdwSlot, DWORD* pdwTopicNumber);
  94. HRESULT GetTopicURL(DWORD dwTopic, CHAR* pszURL, int cb, BOOL bFull = TRUE );
  95. const CHAR* GetString( DWORD dwOffset );
  96. HRESULT GetString( DWORD dwOffset, CStr* pcsz );
  97. HRESULT GetString( DWORD dwOffset, CHAR* psz, int cb );
  98. HRESULT GetString( DWORD dwOffset, CWStr* pcsz );
  99. HRESULT GetString( DWORD dwOffset, WCHAR* pwsz, int cb );
  100. HRESULT GetURLTreeNode(const CHAR* pszURL, CTreeNode** ppTreeNode, BOOL b = TRUE);
  101. HRESULT GetVolumeOrder( UINT* puiVolumeOrder, UINT uiFileType = HHRMS_TYPE_TITLE );
  102. HRESULT ConvertURL( const CHAR* pszURLIn, CHAR* pszURLOut );
  103. HRESULT Slot2TreeNode(DWORD dwSlot, CTreeNode** ppTreeNode);
  104. HRESULT URL2Topic(const CHAR* pszURL, TOC_TOPIC* pTopic, DWORD* pdwTN = NULL);
  105. BOOL FindUsedLocation();
  106. BOOL EnsureChmChiMatch( CHAR* pszChm = NULL );
  107. HRESULT ResolveContextId(DWORD id, CHAR** ppszURL);
  108. inline CStr& GetContentFileName() { return m_ContentFileName; }
  109. // data members should always be private!
  110. CTitleFTS* m_pTitleFTS;
  111. CTitle* m_pTitle;
  112. CExCollection* m_pCollection;
  113. HASH m_dwHash;
  114. int m_ITCnt;
  115. //
  116. // Support for VB style "super chms"
  117. //
  118. CExTitle* m_pKid;
  119. CExTitle* m_pNextKid;
  120. CExTitle* m_pParent;
  121. private:
  122. HRESULT GetTopicData(DWORD dwTopic, TOC_TOPIC* pTopicData);
  123. CStr m_ContentFileName;
  124. CStr m_IndexFileName;
  125. TOCIDX_HDR* m_pHeader; // Header of #TOCIDX system subfile.
  126. IDXHEADER* m_pIdxHeader; // Global header information for entire .CHM/.CHI file.
  127. LOCATIONHISTORY* m_pUsedLocation;
  128. BOOL m_bOpen;
  129. CExTitle* m_pNext;
  130. DWORD m_dwColNo;
  131. DWORD m_dwNodeOffsetInParentTitle;
  132. BOOL m_fIsChiFile;
  133. BOOL m_bIsValidTitle;
  134. BOOL m_bChiChmChecked;
  135. MAPPED_ID* m_pMapIds;
  136. int m_cMapIds;
  137. //
  138. // Tome FS object (.chm/.chi) and Cached subfile objects.
  139. //
  140. CFileSystem* m_pCFileSystem;
  141. CPagedSubfile* m_pTocNodes;
  142. CPagedSubfile* m_pTopics;
  143. CPagedSubfile* m_pStrTbl;
  144. CPagedSubfile* m_pUrlTbl;
  145. CPagedSubfile* m_pUrlStrings;
  146. CPagedSubfile* m_pITBits;
  147. CTitleInformation* m_pInfo;
  148. CTitleInformation2* m_pInfo2;
  149. UINT m_uiVolumeOrder;
  150. char m_szAttachmentPathName[MAX_PATH];
  151. };
  152. class CExCollection SI_COUNT(CExCollection)
  153. {
  154. public:
  155. CExCollection(CHmData* phmData, const CHAR* pszFile, BOOL bSingleTitle = TRUE);
  156. virtual ~CExCollection();
  157. BOOL InitCollection();
  158. #ifdef CHIINDEX
  159. BOOL InitCollection( const TCHAR * FullPath, const TCHAR * szMasterChmFn );
  160. #endif
  161. BOOL InitFTSKeyword();
  162. CHmData* m_phmData;
  163. DWORD GetRefedTitleCount();
  164. BOOL IsBinaryTOC(const CHAR* pszToc);
  165. void GetOpenSlot(CExTitle* p);
  166. CTreeNode* GetRootNode();
  167. CTreeNode* GetPrev(CTreeNode* pTreeNode, DWORD* pdwSlot = NULL);
  168. CTreeNode* GetNext(CTreeNode* pTreeNode, DWORD* pdwSlot = NULL);
  169. CTreeNode* GetNextTopicNode(CTreeNode* pTreeNode, DWORD* pdwSlot = NULL);
  170. HRESULT Sync(CPointerList* pHier, const CHAR* pszURL = NULL);
  171. HRESULT GetCurrentTocNode(CTreeNode** ppTreeNode) { if (m_pCurrTitle) return m_pCurrTitle->Slot2TreeNode(m_dwCurrSlot, ppTreeNode); else return E_FAIL ;}
  172. CExTitle* GetFirstTitle() { return m_pHeadTitles; }
  173. CExTitle* GetMasterTitle() { return m_pMasterTitle; }
  174. CExTitle* GetCurSyncExTitle() { return m_pCurrTitle; }
  175. CExTitle* FindTitle(const CHAR* pszId, LANGID LangId);
  176. // Try multiple LangIds before failing
  177. CExTitle* FindTitleNonExact(const CHAR* pszId, LANGID LangId);
  178. CLocation* FindLocation(CHAR* pszId);
  179. void CheckForTitleChild(CFolder* p, BOOL *pbFound);
  180. CTreeNode* CheckForTitleNode(CFolder* );
  181. void GetMergedTitles(CExTitle* );
  182. BOOL IsSingleTitle() { return m_bSingleTitle; }
  183. CFolder* FindTitleFolder(CExTitle* pTitle);
  184. const CHAR* GetPathName() const {
  185. return m_phmData->GetCompiledFile(); }
  186. HRESULT URL2ExTitle(const CHAR* pszURL, CExTitle** ppTitle);
  187. const CHAR* GetUserCHSLocalStoragePathnameByLanguage();
  188. const CHAR* GetUserCHSLocalStoragePathname();
  189. const CHAR* GetLocalStoragePathname( const CHAR* pszExt );
  190. BOOL UpdateLocation( const CHAR* pszLocId, const CHAR* pszNewPath, const CHAR* pszNewVolume = NULL, const CHAR* pszNewTitle = NULL);
  191. void GetChildURLS(CTreeNode* pNode, CTable *pTable);
  192. void UpdateTopicSlot(DWORD dwSlot, DWORD dwTN, CExTitle* pTitle);
  193. void SetTopicSlot(DWORD dwSlot, DWORD dwTN, CExTitle* pTitle) { m_dwCurrSlot = (dwSlot ? dwSlot : m_dwCurrSlot), m_dwCurrTN = dwTN, m_pCurrTitle = pTitle ? pTitle : m_pCurrTitle; }
  194. CExTitle* TitleFromChmName(const CHAR* pszChmName);
  195. void InitStructuralSubsets(void);
  196. //
  197. // State API's
  198. //
  199. CState* GetState(void) { return m_pstate; }
  200. HRESULT OpenState(const CHAR* pszName, DWORD dwAccess = (STGM_READWRITE | STGM_SHARE_DENY_WRITE)) { return m_pstate->Open(pszName, dwAccess); }
  201. void CloseState(void) { m_pstate->Close(); }
  202. HRESULT ReadState(void* pData, DWORD cb, DWORD* pcbRead) { return m_pstate->Read(pData, cb, pcbRead); }
  203. DWORD WriteState(const void* pData, DWORD cb) { return m_pstate->Write(pData, cb); }
  204. // data members should always be private!
  205. CFullTextSearch* m_pFullTextSearch;
  206. CSearchHighlight* m_pSearchHighlight;
  207. CTitleDatabase* m_pDatabase;
  208. CSubSets *m_pSubSets; // SubSets of information types, instantiated in system.cpp::ReadSystemFiles()
  209. CSSList* m_pSSList; // List of structural subsets.
  210. CSlotLookupTable* m_pCSlt; // Pointer to the slot lookup table.
  211. CCollection m_Collection;
  212. CStr m_csFile;
  213. private:
  214. const CHAR* SetWordWheelPathname( const CHAR* pszWordWheelPathname );
  215. CTreeNode* GetLastChild(CTreeNode* pTreeNode, DWORD* pdwSlot = NULL);
  216. BOOL ValidateTitle(CExTitle* pExTitle, BOOL bDupCheckOnly = FALSE);
  217. CExTitle* m_pHeadTitles;
  218. CExTitle* m_pMasterTitle;
  219. BOOL m_bSingleTitle;
  220. CHAR* m_szWordWheelPathname;
  221. CExTitle* m_MaxOpenTitles[MAX_OPEN_TITLES];
  222. DWORD m_dwLastSlot;
  223. //
  224. // Topic centricity work below. !!!! Don't ever even consider relying on m_pCurrTitle for any thing !!!!
  225. // this is only here to make make topic centricity work more robustly.
  226. //
  227. DWORD m_dwCurrSlot;
  228. DWORD m_dwCurrTN;
  229. CExTitle* m_pCurrTitle;
  230. //
  231. // Support for persistance via hh.dat
  232. //
  233. CState* m_pstate;
  234. #ifdef DUMPTOC
  235. void DumpNode(CTreeNode**);
  236. FILE* m_fh;
  237. BOOL m_bRoot;
  238. DWORD m_dwLevel;
  239. #endif
  240. };
  241. class CSubSet;
  242. #define EXFOLDERNODE 1
  243. #define EXTITLENODE 2
  244. #define EXNODE 3
  245. #define EXMERGEDNODE 4
  246. class CTreeNode SI_COUNT(CTreeNode)
  247. {
  248. public:
  249. CTreeNode();
  250. virtual ~CTreeNode();
  251. BYTE GetObjType() { return m_ObjType; }
  252. void SetObjType(BYTE x) { m_ObjType = x; }
  253. virtual DWORD GetType() = 0;
  254. virtual HRESULT GetTopicName( CHAR* pszTitle, int cb ) = 0;
  255. virtual HRESULT GetTopicName( WCHAR* pwszTitle, int cch ) = 0;
  256. virtual CTreeNode* GetFirstChild(DWORD* pdwSlot = NULL) = 0;
  257. virtual CTreeNode* GetNextSibling(TOC_FOLDERNODE* pAltNode = NULL, DWORD* pdwSlot = NULL) = 0;
  258. virtual CTreeNode* GetParent(DWORD* pdwSlot = NULL, BOOL bDirectParent = FALSE) = 0;
  259. virtual BOOL HasChildren() = 0;
  260. inline virtual BOOL IsNew() { return FALSE; }
  261. virtual BOOL GetURL(CHAR* pszURL, unsigned cb, BOOL bFull = TRUE);
  262. DWORD GetLastError();
  263. CTreeNode* GetExNode(TOC_FOLDERNODE* pNode, CExTitle* pTitle);
  264. BOOL Compare(CTreeNode* pOtherNode);
  265. // data members should always be private!
  266. BYTE m_Expanded;
  267. private:
  268. void SetError(DWORD dw);
  269. BYTE m_ObjType;
  270. DWORD m_Error;
  271. };
  272. //The GetType function can return one of the follow defines:
  273. #define VIRTUALROOT 0 // a node that contains the top level nodes of the tree, not part of the tree
  274. #define XMLFOLDER 1 // a folder defined in the collection file
  275. #define TITLE 2 // a title which is leaf node of the xml tree
  276. #define FOLDER 3 // a folder defined in a title
  277. #define CONTAINER 4 // a folder that is also a topic
  278. #define TOPIC 5 // a topic
  279. #define BOGUS_FOLDER 6 // a folder that is not a topic and has no kids. Bogus!
  280. class CExFolderNode : MI_COUNT(CExFolderNode)
  281. public CTreeNode
  282. {
  283. public:
  284. CExFolderNode( CFolder*, CExCollection* );
  285. virtual ~CExFolderNode();
  286. inline virtual DWORD GetType() { return XMLFOLDER; }
  287. virtual HRESULT GetTopicName( CHAR* pszTitle, int cb );
  288. virtual HRESULT GetTopicName( WCHAR* pwszTitle, int cch );
  289. inline virtual BOOL HasChildren() { return TRUE; }
  290. virtual CTreeNode* GetFirstChild(DWORD* pdwSlot);
  291. virtual CTreeNode* GetNextSibling(TOC_FOLDERNODE* pAltNode = NULL, DWORD* pdwSlot = NULL);
  292. virtual CTreeNode* GetParent(DWORD* pdwSlot = NULL, BOOL bDirectParent = FALSE);
  293. inline CFolder* GetFolder() { return m_pFolder; }
  294. private:
  295. CFolder* m_pFolder;
  296. CExCollection* m_pCollection;
  297. };
  298. class CExTitleNode : // MI_COUNT(CExTitleNode)
  299. public CTreeNode
  300. {
  301. public:
  302. CExTitleNode( CExTitle* , CFolder* );
  303. // virtual ~CExTitleNode();
  304. inline virtual DWORD GetType() { return TITLE; }
  305. inline virtual HRESULT GetTopicName( CHAR* pszTitle, int cb ) { return NULL; }
  306. inline virtual HRESULT GetTopicName( WCHAR* pwszTitle, int cch ) { return NULL; }
  307. virtual CTreeNode* GetFirstChild(DWORD* pdwSlot = NULL);
  308. virtual CTreeNode* GetNextSibling(TOC_FOLDERNODE* pAltNode = NULL, DWORD* pdwSlot = NULL);
  309. virtual CTreeNode* GetParent(DWORD* pdwSlot = NULL, BOOL bDirectParent = FALSE);
  310. inline virtual BOOL HasChildren() { return TRUE; }
  311. CExTitle* GetTitle() { return m_pTitle; }
  312. CFolder* GetFolder() { return m_pFolder; }
  313. private:
  314. CFolder* m_pFolder;
  315. CExTitle* m_pTitle;
  316. };
  317. class CExNode : MI_COUNT(CExNode)
  318. public CTreeNode
  319. {
  320. public:
  321. CExNode(TOC_FOLDERNODE* p, CExTitle* pTitle);
  322. // virtual ~CExNode();
  323. virtual BOOL GetURL(CHAR* pszURL, unsigned cb, BOOL bFull = TRUE);
  324. virtual DWORD GetType();
  325. virtual HRESULT GetTopicName( CHAR* pszTitle, int cb );
  326. virtual HRESULT GetTopicName( WCHAR* pwszTitle, int cch );
  327. virtual CTreeNode* GetFirstChild(DWORD* pdwSlot = NULL);
  328. virtual CTreeNode* GetNextSibling(TOC_FOLDERNODE* pAltNode = NULL, DWORD* pdwSlot = NULL);
  329. virtual CTreeNode* GetParent(DWORD* pdwSlot = NULL, BOOL bDirectParent = FALSE);
  330. inline virtual BOOL HasChildren() { return m_Node.dwFlags & TOC_HAS_CHILDREN; }
  331. inline virtual BOOL IsNew() { return m_Node.dwFlags & TOC_NEW_NODE; }
  332. inline CExTitle* GetTitle() { return m_pTitle; }
  333. // data members should always be private!
  334. TOC_FOLDERNODE m_Node;
  335. private:
  336. CExTitle* m_pTitle;
  337. };
  338. class CExMergedTitleNode : MI_COUNT(CExMergedTitleNode)
  339. public CExNode
  340. {
  341. public:
  342. CExMergedTitleNode( TOC_FOLDERNODE* pFolderNode, CExTitle* pTitle );
  343. virtual ~CExMergedTitleNode();
  344. inline virtual DWORD GetType() { return TITLE; }
  345. virtual CTreeNode* GetFirstChild( DWORD* pdwSlot = NULL );
  346. };
  347. // Helper functions
  348. #endif // _TOC_H