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.

497 lines
16 KiB

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