About the Specification

Reading the specification

This specification has been written for two groups of people; documentation authors and CHM capability implementors. We hope this specification will provide documentation authors all the resources they need to get the most out of its features and exploit the valuable undocumented features of HTML Help, whilst allowing them to skip over implementation details. Those who wish to implement alternative CHM compilers, decompilers and or viewers should find enough information to create such software.

This specification begins with a general introduction to HTML Help and proceeds to more specific technical information.

This specification has been designed for both screen and print media, with formatting and content tailored to the capabilities of the medium. For example in print media the location of external links are put in brackets after the text and internal links have chapter.section.subsection numbers instead. In electronic media various styles are used to convey contextual information.

All versions come with a tables of contents, a glossary and an index for quick access to information.

Organisation

This specification begins with a discussion of help systems in general, examines MS' help solutions and gives a breif introduction to HTML Help.

Following this is a broad discussion of the features of HTML Help.

A discussion of all the data files and MS' executable files involved in HTML Help follows this.

Following this is an in depth analysis of the formats of the data files.

This specification is concluded with miscellaneous topics and appendices.

Conventions

Please read the glossary as all abbreviations in the document that are used many times are defined there.

All binary data in all structures described in this document are little-endian, unless otherwise indicated.

Where part of a structure is variable length then the offset of the next item will be shown as +0.

BYTE, WORD & DWORD have their normal meanings (8, 16 & 32-bit integers) and QWORD indicates a 64-bit integer.

The FILETIME structure is a QWORD representing the number of 100-nanosecond intervals since January 1, 1601. This is one of three types of timestamps used in Windows.

The time_t structure is a DWORD representing the the number of seconds elapsed since midnight (00:00:00), January 1, 1970, coordinated universal time. This is the standard Unix timestamp, and is also used on Windows.

An LCID is a DWORD locale identifier made up of a language ID in the lower WORD and a sort ID in the upper WORD.

Bits | Explanation
0-9 | Primary Language ID
10-15 | Secondary Language ID
16-19 | Sort ID
20-31 | Reserved

A GUID is a "Globally Unique IDentifier". 0x10 bytes, arranged as 1 DWORD, 2 WORDs, and 8 BYTEs. It is based on UUIDs from DCE and is a combination of a timestamp, A clock sequence and related persistent state to deal with retrograde motion of clocks, A forcibly incremented counter to deal with high-frequency allocations, The truly globally unique IEEE machine identifier, obtained from a network card (the implementation does not require a network card; if no network card is present, a machine identifier can be synthesized from highly variable machine states and stored persistently).

This specification is extensively hyperlinked, which ensures that unknown concepts and reference information are only a click away. For those who prefer to read this specification as printed onto dead trees (or Marijuana) there is an glossary and index, all intradocument hyperlinks have chapter.section.subsection numbers and all external hyperlinks have the URLs printed.

The table below indicates the styles used to indicate various things.

Example(s) | Explanation
0x??000000, 0 (unknown), ?? | This style indicates that the highlighted information is unknown. Please let us know if you decipher any of the unknown information.
Custom tab | This style indicates the name of a variable in the [OPTIONS] section of the hhp file.
[WINDOWS] | This style indicates the name of a section in the hhp file.
ShowWindow | This style indicates a Win32 API.
MSDN | This style indicates a link to an external site.
<foo@bar.org> | This style indicates a link to an email address.
MVPs, 19??; Far, 19?? | This style indicates a citation(s).

Contributions

Big it up for (in order of time of contribution)

Name | Website | Contact | Contribution | Copyright
Pabs | http://pabs.zip.to | <pabs@zip.to> | Editor. Also reversed the internal files, gathered info from the net and wrote almost all the sections other than most of the $FIftiMain description. | Yes
Matthew Russotto | http://www.speakeasy.org/~russotto/ | <mrussotto@speakeasy.net> | Reversed the ITSF format & its LZX compression and publicly documented the ITSF format. | No
Olivier Sannier | http://obones.free.fr | <obones@meloo.com> | Publicly documented CHM Samples as used by the MSDN | No
Unknown | http://www.vivid-creations.com | Unknown | Provided just enough info in a Usenet message to allow the overall structure of CHS files to be reversed. | No
Jed Wing | http://66.93.236.84/~jedwin/ | <jedwin@ugcs.caltech.edu> | Completely reversed the $FIftiMain file and contributed the important, complicated details to the spec, which corrected my pathetic efforts. | Yes
Please send your fixes, suggestions, content & anything else to the Pabs

Copyright

This document is copyright © Pabs et al. All Rights Reserved.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being "GNU Free Documentation License" and with no Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".


Introduction

Help systems

Documentation. An essential part of any software. Plain human language description of complex software systems that helps non-programmers understand programs, how these programs work, their capabilities and how to achieve desired objectives using the software.

Good documentation is a boon to users, but bad documentation can be downright insulting. It is therefore essential that the users can easily find what they are looking for. To that end it should be organised in a logical manner, easily searchable, extensively linked and indexed.

Help systems vary widely between platforms and in time; man pages on unix, Info files on GNU/Linux, the MacOS help system, various systems for individual pieces of proprietry software, straight HTML, some failed attempts at cross-platform help, custom XML (e.g. DocBook) and several generations of help systems for MS' family of MS-DOS & Windows operating systems. DocBook already plays a huge role as a source format, mainly in book publishing and for software documentation on free/open *nix platforms, while the investment into web browsers during the browser wars and beyond has established HTML as a standard for end-product documentation, whether residing as individual files in a filesystem or inside a custom proprietry format. As a side note that is specification itself was written in DocBook XML and standard software was used to translate the source XML into the several formats that are available, including HTML Help.

MS' help systems

The table below shows the past, present & future of MS help systems.

MS' help systems MVPs, 19??; Far, 19??; Winterhoff, 19??
Name | Files/Extension(s) | Based on | Generation | Decompiler(s) | Compiler(s) | Viewer(s) | Specification(s)
QuickHelp | ??? | ??? | MS-DOS | ??? | ??? | ??? | ???
WinHelp | hlp, cnt, gid, fts, ftg, hpj, ann, bmk, WinHlp32.BMK | RTF | Previous. Win95 | helpdeco | HC30, HC31, HCP, HCRTF, HCW, MVC, MMVC, WMVC | WinHelp and MultiMedia Viewers | helpdeco docs, "The Windows Help File Format" from Dr. Dobbs Journal, Sep/Oct 1993 by Pete Davis
HTMLHelp | chm, chi, chq, chs, chw, its, col, hh.dat, hhcolreg.dat, hhp, hhc, hhk, hhs, stp | HTML | Current. Win98 - WinXP | chmtools, istorage, HHA/HHC/HHW, HH | HHA/HHC/HHW, hhm (not yet) | HH | This document, ITSF format
MS Help 2 | HxS, HxI, HxC, HxF, HxT, HxK, HxE, HxV, HxA | HTML | Next. Win?? | open convert lit ;) (modifications needed) | hxcomp | dox | ???
Help and Support Center (HSC) | ??? | ??? | Embrace & extend. WinXP | ??? | ??? | ??? | ???
More info on MS' help systems MVPs, 19??; Far, 19??; Winterhoff, 19??
Name | More info
QuickHelp | Back in the day of MS command lines before I was old enough to reach the keyboard.
WinHelp | This had some features (good & bad) not yet present in HTML Help; annotation, weird compression & searching, nasty RTF and a bit of a clunky UI.
HTMLHelp | The current generation of MS' help systems. Many of the features are not implemented in either the viewer, compiler, GUI authoring tools or a combination of all three. It is amazing what passes for 1.0 these days.
MS Help 2 | This would have been the finished version of HTML Help. Microsoft has decided not to release it, and instead focus on the help system for Windows Longhorn.
Help and Support Center (HSC) | An effort to integrate all help into one location (not unlike Unix man pages).

HTML Help

The current generation of MS help systems is known as HTML Help, probably because it uses HTML as a content format and in some of its other files. This was first introduced in August, 1997 http://www.helpware.net/htmlhelp/hh_info.htm and was distributed with Win98 and Win2K. It uses the IE browser engine, with a special ActiveX control to provide extra capabilities to HTML pages.

The content resides in self-contained files called "Compiled HTML Help file[s]" (CHM). The HTML Help viewer (HH), compiler (HHC) and most decompilers (e.g. istorage) use an IStorage interface to access the virtual filesystem in the file. The virtual filesystem will be discussed in a later chapter and section. It is interesting to note that most of the file data in the filesystem is compressed in one big chunk with LZX (an LZ77 based compressor). The GUI authoring tools are known as HTML Help Workshop (HHW), which calls MS' compiler (HHC), which loads a dll (HHA) to do all the work.

HTML Help includes quite a few features that are useful to both the documentation author and user; table of contents, index, full-text search, bookmarks, context-sensitivity, custom navigation tabs, merged help and a simple UI.

HTML Help links

  • official HTML Help website
  • HTML Help MVPs
  • far, lots of info
  • Keytools
  • ITStorage inteface definition
  • Matthew Russoto's CHM page
  • Jed Wing's chmlib
  • Jed Wing's KDE ms-its ioslave
  • Pabs' istorage
  • Pabs' istorage-make
  • Pabs' hhm
  • Pabs' chmdeco
  • Pabs' chmspec
  • Microsoft Help Authoring newsgroup (via google)
  • MSHelp2 yahoo group
  • HATT yahoo group
  • DelphiHHKit yahoo group


Discovery

This book was produced entirely by black-box reverse engineering; that is, the formats were determined by changing the input to the HTML Help compiler and observing the output produced. Stricly no dissasembly was involved.

Motives

The motive for writing this spec was the total lack of public documentation of the formats involved in CHM. There would of course be the specs Microsoft released to the W3C in an effort to make CHM a standard, but these were never made public AFAIK.

It was also hoped that the knowledge gained could be used to create CHM compilers for other platforms such as Linux, BSD and MacOS, so users of those platforms would not have to use Windows to create Windows documentation.

Print

If this book is ever printed we hope it is printed on either recycled paper or Marijuana, in safe inks and using a non-patented lay-flat binding.


HTML Help features

Preface

Many of the features of HH are incomplete in v1.x and it is hoped that the new Help 2 system, expected in 2003, will provide the complete versions of thse features, allowing for a richer documentation system.

Menu

This is a menu that provides all the same features as the toolbars, with a few more features; some stuff from IE, Define Subset & in the Help menu are MSDN Library Help & MSDN Online, which jump to a topic in the MSDN and to http://www.microsoft.com/msdn/. The other menu items are all accessible from other parts of the UI such as the toolbar & context menus and so the only reason for an author to include the menu would be to let the user access the Define Subset command, which can be useful for documentation containing information on a diverse range of topics, especially for the index & search tabs. The two MSDN menu items (that do nothing outside the MSDN) could confuse the user, however, and they may be removed through the use of an external dll using the Win32 menu manipulation functions. An example of this technique can be found at ???. It is probable that MS will fix this feature for Help 2.

Toolbar

The toolbar contains several very useful buttons and some that don't yet do anything - they just sit there looking stupid or do something one of the other buttons does. The useful buttons include: Hide/Show, Back, Forward, Stop, Refresh, Home, Locate, Options, Print, 2 jump buttons, Font, Next and Previous. Most of the buttons do what would be expected from their text/icons. The 2 jump buttons use predefined icons (a page with a world on it & the curvy Windows logo overlaid on a globe) and allow the help author to customise their jump location and text. The Previous and Next buttons jump to the previous and next topics according to the Contents tab.

Navigation pane

The navigation pane is to the left of the content pane & has several different tabs in it. These include Contents, Index, Search, Favourites, History (empty), Author (hinted at in htmlhelp.h, but currently can't seem to get it) & custom tabs.

Contents

The Contents tab is a tree structure of titles. Each title may contain other titles and or link to a topic file. It is used by authors to list all the contents of a help file.

Index

The Index tab is also a tree structure, but it usually is a list of words linked to topics. It is used by authors to list all concepts in the help file & is usually linked to context sensitivity.

Search

The search tab allows users to search topics for keywords. The advanced mode allows a user to search using boolean, wildcard, and nested expressions. A user can also limit the search to previous results, match similar words, or search topic titles only.

Favourites

This is a list of bookmarks the user can add topics to & remove topics from. It is stored in the hh.dat file.

Custom tabs

These are currently used in MS Office for the Answer Wizard and "enhanced" Index tabs, but they don't seem to work in HH & seem to require an different program provided by MS Office. No doubt MS has actually completed this technology but is withholding it from use by the general public, who rely on HH. Why they would do this is left as something for the reader to think up. Strangely enough it is possible to put custom tabs into the CHM, but the viewer architecture must not yet be complete since they are not displayed. Hopefully MS will provide this functionality in Help 2.

Information types

Information types are only semi-implemented in HH, but it is probable that MS will provide this functionality in full in Help 2. Information types allow authors to categorize topics and let users see only the topics that apply to them. For example topics might be classified on the basis of user experience, giving the category "User Experience" and the information types Luser, Hacker and Guru (for example). The user would then choose which topics to view according to their experience level.

Text popups

Popups are used mainly in dialog boxes when users request more information on a single control, usually using a right-click or a "What's This?" button. The popup mechanism provided by HH is limited to text popups only, while WinHelp popups were RTF like the rest of its topics. Hopefully Help 2 will provide the flexibility of HTML popups.

Context-sensitive help

This allows a program to open the topic in its help system that relates to a specific part of its user interface. For example all dialogs might have a Help button, which would display the topic related to that dialog when pressed.

Subsets

These are present in the MSDN, but not present in HHW or documented in the HHW help. The mode of their production is currently unknown. They seem to work similarly to information types. The user selects an active subset and only that subset is displayed in the contents and searched using the search tab. The index items that are not in the subset are grayed out & disabled. They only work for collections and are stored in CHS files.

Samples

This is another MSDN thing. It is only minimally documented by Olivier Sannier and in this document. Samples are sets of files (usually code) that can be provided inside or outside the CHM and copied to the users system through the HH ActiveX control.

Merged help

Merged help allows authors to separate their content into different files and have the content merged at runtime by the HH viewer into one cohesive unit, allowing several CHM files to act as one CHM. There are two mechanisms used with CHMs to achieve this; collections and CHM-based.

Collections

This involves an XML file with an extension of .col that contains information on the files to be merged at runtime. The advantage of this is that since the collection file is XML it can be easily modified to accomodate new pieces of documentation.

Merge Files

With this mechanism instructions in a CHM indicate that it should be merged with other CHMs. The advantage of this system is that modification is difficult. The inability to modify CHMs is useful where there is no need to change which files are merged very often.


Files

Preface

This chapter details the files involved in the production and use of HH content. The formats this chapter makes reference to are discussed in the next chapter, which discusses all the file formats.

Content

The content files contain the help topics, including HTML, images, stylesheets, scripts, samples and other files. These are known as Compiled HTML Help files or CHMs. They make use of the ITSF filesystem format.

CHI, CHW and CHQ files store merged Indexes, ALinks/KLinks and Search information respectfully for merged CHMs and collections of CHMs. They are located in the same folder as the CHM and have the ITSF format, but are usually not compressed, ensuring speedy access.

CHS files store information about the subsets that the user and or help author has created. They are located in the same folder as the CHM and have their own binary format.

The KPD files store information on how to update a CHM. It is used by the KeyUpdate ActiveX control by the KeyWorks.net people. WARNING: This is only BETA technology, so it is NOT guaranteed to be stable.

Authoring

HHP files are HTML Help Project files and store information on options, window types, merge info, a file list, text popups, information types, context-sensitive help, and subsets and are in INI format. Parts of the HHP format can be excised into text files and included from the HHP.

HHC files are HH Table of Contents files, store the Contents and are in Sitemap format.

HHK files are HH Index files, store the Index and are in Sitemap format.

HHS files are HH Samples files, store the samples information and are in INI format.

STP files are HH Stop-list files, store the words to be ignored when generating search data and are in text format.

ALI files are HH alias files, store context-sensitivity links and are in text format.

Settings

hh.dat stores the Favourites and Search history for each CHM file. It also caches window type information for each CHM. It is usually located in the users profile directory under "Application Data\Microsoft\HTML Help" and also has the ITSF format.

hhcolreg.dat stores information about collections on a system. It is an XML file and is usually located in the system help dir or in the "All Users" profile directory under "Application Data\Microsoft\HTML Help"


Formats

Preface

This section describes in great detail the formats of the various files involved in the production and use of HH.


ITSF format

Preface

This chapter an addon to Matthew Russotto's page; "Microsoft's HTML Help (.chm) format", which is available at http://www.speakeasy.org/~russotto/chm/chmformat.html. It details a few facts not included in that page.

Titbits

The LCID in the initial header is the LCID of the OS at the time of compilation, not the one stored in the HHP file. It is unknown whether or not this is the system LCID (from GetSystemDefaultLCID), the user LCID (from GetUserDefaultLCID) or the thread LCID (from GetThreadLocale). It is likely to be GetUserDefaultLCID since that is the function that ITSS.DLL depends on. If you have the facility to check this please let us know of the result.

The LCID in the directory header is from the program that compiled the ITSF, definately not the one stored in the HHP file or from the OS. On Win32 this LCID comes from ITSS.DLL (at offset 0xB306 in version 4.72.8085.0 of that file), which provides the GUID that follows it.

Between the chunk entries and the quickref entries is chunk length - ( num entries / n + !!( num entries % n ) ) * 2 bytes worth of free space. This usually contains the same data from the same offsets in the previous chunk, and can be zeroed out, with no effect on the decoder and a slight increase in the compressability of the file with zip/gzip/bzip2 & probably other crunchers. The free space is usually partial/junk chunk entries, free space and/or quickref entries.


The actual ITSF file is embedded in what appears to be an invalid executable file (not sure if MSDOS or PE)
It is an .its section
The exe also has a .rsrc section with a version resource

There seems to be a CAOL block before the ITSF initial header

Initial header:

char[4] ITSF
DWORD 4 (version number)
DWORD 32
DWORD 1
QWORD 9176
DWORD timestamp
DWORD LCID
{Header Section 0 integrated into initial header
DWORD 0x01fe (unknown)
DWORD 0 (unknown)
QWORD ITSF File Size
DWORD 0 (unknown)
DWORD 0 (unknown)
}
GUID
GUID

Directory ?:

IFCM Header: 32 bytes
AOLL Chunk: 512 bytes

IFCM Header: 32 bytes
AOLL Chunk: 8224 bytes
    contains same directory entries as in ITSF 2 & 3

Content section 0

Namelist file is the same

The format of the .its section is exactly the same as the .LIT format used by the MSReader ebook software, except without encryption & different internal files.
See the source code of a program called open convert lit for more info on the ITSF 4 format (+ .lit internal files)
It is availble at http://www.kyz.uklinux.net/convlit.php3


ITSF internal file formats

Preface

In this section, where the description of a file says that an item is an offset into another file, that file may be located in the same CHM, or it may be located in an accompanying CHI file.

The different types of ITSF files contain different internal files. The list below indicates which file types contain which internal files:

CHI
/#ITBITS, /#SYSTEM, /#IDXHDR, /#STRINGS, /#TOCIDX, /#TOPICS, /#URLSTR, /#URLTBL, /#WINDOWS, /$OBJINST, /$WWAssociativeLinks/BTree, /$WWAssociativeLinks/Data, /$WWAssociativeLinks/Map, /$WWAssociativeLinks/Property, /$WWKeywordLinks/BTree, /$WWKeywordLinks/Data, /$WWKeywordLinks/Map, /$WWKeywordLinks/Property
CHM
/#ITBITS, /#SYSTEM, /#IDXHDR, /#STRINGS, /#TOCIDX, /#TOPICS, /#URLSTR, /#URLTBL, /#IVB, /#SUBSETS, /#WINDOWS, /$FIftiMain, /$OBJINST, /$WWAssociativeLinks/BTree, /$WWAssociativeLinks/Data, /$WWAssociativeLinks/Map, /$WWAssociativeLinks/Property, /$WWKeywordLinks/BTree, /$WWKeywordLinks/Data, /$WWKeywordLinks/Map, /$WWKeywordLinks/Property
CHQ
/$FIftiMain, /$OBJINST, /$TitleMap
CHW
/$OBJINST, /$HHTitleMap, /$WWAssociativeLinks/BTREE, /$WWAssociativeLinks/DATA, /$WWAssociativeLinks/MAP, /$WWAssociativeLinks/PROPERTY, /$WWKeywordLinks/BTREE, /$WWKeywordLinks/DATA, /$WWKeywordLinks/MAP, /$WWKeywordLinks/PROPERTY
hh.dat
/Path/file.chm/windowtype, /Path/file.chm/AdvSearchUI/Keywords, /Path/file.chm/AdvSearchUI/Properties, /Path/file.chm/Bookmarks/v1/Count, /Path/file.chm/Bookmarks/v1/n/Topic, /Path/file.chm/Bookmarks/v1/n/Url
KPD
/#KEY_DATA, /#KEY_DELETED
Seen in HHA.dll or on the internet, but not seen in any ITSF files
/#GRPINF (see helpdeco docs by Manfred Winterhoff for a possible function), /#INFOTYPES (probably will be output when MS implements information types), /#URLS (probably a previous incarnation of the /#URLTBL + /#URLSTR combination), /#BSSC (8 bytes, based on something I saw in KeyTools.exe it might contain the version of RoboHelp used to create the CHM. If you have RoboHelp please check this out & be sure to send me your chm.)

Internal file formats

/#ITBITS

The files I have seen so far have been empty or filled with zero BYTEs so who knows. My guess is that it has something to do with information types. The file where it had a non-zero size (12 zero BYTEs in VOICESDK.CHI from the MSDN) also had a non-zero /#SYSTEM code 15 (Information type checksum) entry of 0xFFFFFFFF.

/#SYSTEM

Offset | Type | Comment/Value
0 | DWORD | Version number. 2 in files compiled with "Compatibility=1.0", 3 in files compiled with "Compatibility=1.1 or later"
4 | /#SYSTEM entries to the EOF

/#SYSTEM entries have the following format:

Offset | Type | Comment/Value
0 | WORD | code - see below for values & meanings
2 | WORD | length of data
4 | BYTEs | data

In the below list of the different codes the order of the codes in the /#SYSTEM file is 10, 9, 4, 2, 3, 16, 6, (5,0,1 or 0,1,5 - haven't been able to make files with all three), 7, 11, 12, 13, 14, 8 and lastly 15.

An eplanation for each of the /#SYSTEM codes
Code | Explanation
0 | Value of Contents file in [OPTIONS] section of the HHP file. NT
1 | Value of Index file in [OPTIONS] section of the HHP file. NT
2 | Value of Default topic in [OPTIONS] section of the HHP file. NT
3 | Value of Title in [OPTIONS] section of the HHP file. NT
4 28 (HHA Version 4.72.7294 and earlier) or 36 (HHA Version 4.72.8086 and later) byte structure:
Offset | Type | Comment/Value
0 | DWORD | LCID from the HHP file.
4 | DWORD | One if DBCS is in use.
8 | DWORD | One if full-text search is on.
0xC | DWORD | Non-zero if the file has KLinks.
0x10 | DWORD | Non-zero if the file has ALinks.
0x14 | QWORD | timestamp - Definately not a straightforward Win32 FILETIME structure. On odd hours it seems to be reduced by a factor of 15, compared to even hours.
0x1C | DWORD | 0/1 (unknown) Only dsmsdn.chi from the MSDN has 1 here. Perhaps 1 means it is the root chm of a collection?
0x20 | DWORD | 0 (unknown)
5 | Value of Default Window in [OPTIONS] section of the HHP file. NT
6 | Value of Compiled file in [OPTIONS] section of the HHP file. This is the lowercase of the stem of the CHM file name. If the name of the CHM is "..\bar\foo\ FOO-Bar . chm jimmy is a poo-bum" then this will be " foo-bar ". NT
7 | *DWORD present in files with "Binary Index=Yes". The entry in the /#URLTBL file that points to the sitemap index had the same first DWORD.
8 Rare. VOICESDK.CHM & CHI and WOSA.CHI from the MSDN have one. The abbreviations and explanations seem to be the same in WOSA.CHI & VOICESDK.CHM, except for 2 mistakes (one in VOICESDK.CHM & one in WOSA.CHI) that seem to be created by bugs in the compiler. Both were compiled by the same version of HHA (4.72.8086), so perhaps this version has some weird bug. Each entry is 16 BYTEs:
Offset | Type | Comment/Value
0 | DWORD | 0, 4 in some (unknown)
4 | DWORD | Offset in /#STRINGS file. An abbreviation.
8 | DWORD | 3 where 1st DWORD is 0, 5 where it is 4 (unknown)
0xC | DWORD | Offset in /#STRINGS file. An explanation of the abbreviation.
9 | The version/program that the CHM was compiled by - shown in the version dialog as "Compiled with %s" where %s is what is in this entry of the /#SYSTEM file. If compiled with the MS HTML Help Author dll then it will be something like "HHA Version 4.74.8702". It comes directly from the resource strings of HHA.dll (I saw it there in Unicode and successfully altered it). Beware that the text control in the version dialog that displays it is only so big and in some cases the string won't be displayed, & in other cases only part, depending apon the effect of wrapping, so if you write a compiler, be sure to test it and use a short name and version. Usually NT, but HH won't crash if it isn't.
10 | time_t timestamp (DWORD). Not sure of the start year yet.
11 | *DWORD present in files with "Binary TOC=Yes". The entry in the /#URLTBL file that points to the sitemap contents has the same first DWORD.
12 | *Number of information types (DWORD).
13 | *The /#IDXHDR file contains exactly the same bytes. See below for more info
14 Rare. The ones I saw were from MS Word 2000. My guess is that it is an MSOffice extension (or maybe not) that overrides the names & window types of the navigation tabs. DWORD number of windows to override, 2 ANSI/UTF-8 NT strings for each window. The first is the text for the tab & the second is probably the name of the window type to use. (eg 2, "&Answer Wizard\0MsoHelpAWDlg\0&Index\0MsoHelpKeyDlg\0")
These are from the Custom tab variables of the [OPTIONS] section of the HHP file. The resources from MSOHELP.EXE have a weird .reg file that gives the CLSIDs involved in the provision of these dialogs.
15 | *Information type checksum (DWORD). Unknown algorithm & data source.
16 | Value of Default Font in [OPTIONS] section of the HHP file. NT
17-65535 | Not yet seen. Please let us know if you see these.
*Not present in files with "Compatibility=1.0"

/#IDXHDR

This has exactly the same bytes as the code 13 entry in the /#SYSTEM file and is 4096 bytes long.

Offset | Type | Comment/Value
0 | char[4] | T#SM
4 | DWORD | Unknown timestamp/checksum
8 | DWORD | 1 (unknown)
0xC | DWORD | Number of topic nodes including the contents & index files
0x10 | DWORD | 0 (unknown)
0x14 | DWORD | Offset in the /#STRINGS file of the ImageList param of the "text/site properties" object of the sitemap contents (0/-1 = none)
0x18 | DWORD | 0 (unknown)
0x1C | DWORD | 1 if the value of the ImageType param of the "text/site properties" object of the sitemap contents is "Folder". 0 otherwise.
0x20 | DWORD | The value of the Background param of the "text/site properties" object of the sitemap contents
0x24 | DWORD | The value of the Foreground param of the "text/site properties" object of the sitemap contents
0x28 | DWORD | Offset in the /#STRINGS file of the Font param of the "text/site properties" object of the sitemap contents (0/-1 = none)
0x2C | DWORD | The value of the Window Styles param of the "text/site properties" object of the sitemap contents
0x30 | DWORD | The value of the ExWindow Styles param of the "text/site properties" object of the sitemap contents
0x34 | DWORD | Unknown. Often -1. Sometimes 0.
0x38 | DWORD | Offset in the /#STRINGS file of the FrameName param of the "text/site properties" object of the sitemap contents (0/-1 = none)
0x3C | DWORD | Offset in the /#STRINGS file of the WindowName param of the "text/site properties" object of the sitemap contents (0/-1 = none)
0x40 | DWORD | Number of information types.
0x44 | DWORD | Unknown. Often 1. Also 0, 3.
0x48 | DWORD | Number of files in the [MERGE FILES] list
0x4C | DWORD | Unknown. Often 0. Non-zero mostly in files with some files in the merge files list.
0x50 | DWORD[1004] | List of offsets in the /#STRINGS file that are the [MERGE FILES] list. Zero terminated, but don't count on it.

/#WINDOWS

This file contains information on the window types in the CHM. It has the following format:

Offset | Type | Comment/Value
0 | DWORD | Number of entries in the file
4 | DWORD | Size of each of the entries in the file (188 or 196)
8 | /#WINDOWS entries to the EOF

/#WINDOWS entries are basically HH_WINTYPE structures as specified in htmlhelp.h. Note the first DWORD can be used to specify different versions of this structure. Also note that the HHW docs show a different structure to htmlhelp.h. Therefore many CHM files need to be surveyed to find structures with sizes other than 188 or 196. In the description of /#WINDOWS entries below, Arg n means that that item is argument n of the window definition in the HHP file, either converted to a DWORD or to an offset in the indicated file:

The format of each /#WINDOWS entry.
Offset | Type | Comment/Value
0 | DWORD | Size of the entry (188 in CHMs compiled with "Compatibility=1.0", 196 in CHMs compiled with "Compatibility=1.1 or later")
4 | DWORD | 0 (unknown) - but htmlhelp.h indicates that this is "BOOL fUniCodeStrings; // IN/OUT: TRUE if all strings are in UNICODE"
8 | DWORD | Arg 0. Offset in /#STRINGS file.
0xC | DWORD | Which window properties are valid & are to be used for this window. See the table below.
0x10 | DWORD | Arg 10.
0x14 | DWORD | Arg 1. Offset in /#STRINGS file.
0x18 | DWORD | Arg 14.
0x1C | DWORD | Arg 15.
0x20 | RECT | Arg 13. Order left, top, right & bottom.
0x30 | DWORD | Arg 16.
0x34 | DWORD | 0 (unknown) - but htmlhelp.h indicates that this is "HWND hwndHelp; // OUT: window handle"
0x38 | DWORD | 0 (unknown) - but htmlhelp.h indicates that this is "HWND hwndCaller; // OUT: who called this window"
0x3C | DWORD | 0 (unknown) - but htmlhelp.h indicates that this is "HH_INFOTYPE* paInfoTypes; // IN: Pointer to an array of Information Types"
0x40 | DWORD | 0 (unknown) - but htmlhelp.h indicates that this is "HWND hwndToolBar; // OUT: toolbar window in tri-pane window"
0x44 | DWORD | 0 (unknown) - but htmlhelp.h indicates that this is "HWND hwndNavigation; // OUT: navigation window in tri-pane window"
0x48 | DWORD | 0 (unknown) - but htmlhelp.h indicates that this is "HWND hwndHTML; // OUT: window displaying HTML in tri-pane window"
0x4C | DWORD | Arg 11.
0x50 | BYTE[16] | 0 (unknown) - but htmlhelp.h indicates that this is a RECT that is "RECT rcHTML; // OUT: HTML window coordinates" & the HHW docs say "Specifies the coordinates of the Topic pane."
0x60 | DWORD | Arg 2. Offset in /#STRINGS file.
0x64 | DWORD | Arg 3. Offset in /#STRINGS file.
0x68 | DWORD | Arg 4. Offset in /#STRINGS file.
0x6C | DWORD | Arg 5. Offset in /#STRINGS file.
0x70 | DWORD | Arg 12.
0x74 | DWORD | Arg 17.
0x78 | DWORD | Arg 18.
0x7C | DWORD | Arg 19.
0x80 | DWORD | Arg 20.
0x84 | BYTE[20] | 0 (unknown) - but htmlhelp.h indicates that this is "BYTE tabOrder[HH_MAX_TABS + 1]; // IN/OUT: tab order: Contents, Index, Search, History, Favorites, Reserved 1-5, Custom tabs"
0x98 | DWORD | 0 (unknown) - but htmlhelp.h indicates that this is "int cHistory; // IN/OUT: number of history items to keep (default is 30)"
0x9C | DWORD | Arg 7. Offset in /#STRINGS file.
0xA0 | DWORD | Arg 9. Offset in /#STRINGS file.
0xA4 | DWORD | Arg 6. Offset in /#STRINGS file.
0xA8 | DWORD | Arg 8. Offset in /#STRINGS file.
0xAC | BYTE[16] | 0 (unknown) - but htmlhelp.h indicates that this is a RECT that is "RECT rcMinSize; // Minimum size for window (ignored in version 1)"
Everything after here is only present in CHMs compiled with "Compatibility=1.1 or later".
0xBC | DWORD | 0 (unknown) - but htmlhelp.h indicates that this is "int cbInfoTypes; // size of paInfoTypes;"
0xC0 | DWORD | 0 (unknown) - but htmlhelp.h indicates that this is "LPCTSTR pszCustomTabs; // multiple zero-terminated strings"
Flags used to specify which values are valid.
Value | Valid property
0x00000002 | Navigation Pane Style.
0x00000004 | Style Flags.
0x00000008 | Extended Style Flags.
0x00000010 | Initial Position.
0x00000020 | Navigation Pane Width.
0x00000040 | Show state.
0x00000080 | Info types.
0x00000100 | Buttons.
0x00000200 | Navigation Pane initially closed state.
0x00000400 | Tab pos.
0x00000800 | Tab order.
0x00001000 | History count.
0x00002000 | Default Pane.
0x?????00? | The rest of the values either do nothing or are unknown. Please let us know if you find out what the rest are.

/#STRINGS

This file is a list of ANSI/UTF-8 NT strings. The first is just a NIL character so that offsets to this file can specify zero & get a valid string. The strings are sliced up into blocks that are 4096 bytes in length. If a string crosses the end of a block then it will be cut off without a NT and repeated in full, with a NT, at the start of the next block. For eg "To customize the appearance of a contents file" might become "To customize the <block ending>To customize the appearance of a contents file" when there are 17 bytes left at the end of the block.

The strings are in this order; "\0", [WINDOWS] (Arg 0, Arg 1, Arg 7, Arg 9, Arg 2, Arg 3, Arg 4, Arg 5, Arg 6, Arg 8) #n..., Contents_0_Entry_title, Index_0_Keyword, Contents_Image_file, Contents_Font, Contents_Default_frame, Contents_Default_window, [MERGE FILES] #n...

/#TOCIDX

Present in files with a non-empty contents file, "Binary TOC=Yes" and "Compatibility=1.1 or later".

This file is made up of 0x1000 byte blocks, but this is only apparent because of extra bytes interrupting what would otherwise be a stream of 20/28 byte structs. If the other parts (DWORDS & 16 byte structs) didn't fit into these blocks then presumably this would show up in the other parts too.

The first block is the header:

/#TOCIDX header
Offset | Type | Comment/Value
0 | DWORD | 4096/header length/offset of #1 below
4 | DWORD | offset of #3 below
8 | DWORD | number of #3 below
0xC | DWORD | offset of #2 below
0x10 | BYTE[4080] | 0 (unknown)

The header is followed by the following different types of structs in the specified order:

  1. 20/28 byte structs (pages/books)
  2. list of dwords into /#TOPICS file
  3. 16 byte structs - links above stuff

First all the top level books/pages, then the next level, then the next & so on

20/28 byte structures
Offset | Type | Comment/Value
0 | WORD | 0 (unknown)
2 | WORD | Unknown
4 | DWORD | Seems to be a bit field: 0x2 is whether or not the New value is set to 1, 0x4 is set when the entry is a book/has children and 0x8 is set when the entry has a Local value. The other bits are unknown (0x1, 0x40, 0x100 are sometimes set on books).
8 | DWORD | Unknown. In some cases it is an index into the /#TOPICS file of the entry containing offsets to the title & filename.
0xC | DWORD | Offset to the parent book.
0x10 | DWORD | Offset to the next book/page in the current book/page.
The next two DWORDs are only present in books (28 byte structs)
0x14 | DWORD | Offset to the first child of the book.
0x18 | DWORD | 0 (unknown)
16 byte structures
Offset | Type | Comment/Value
0 | DWORD | Offset into #1 above.
4 | DWORD | Some kind of sequence number that is incremented by one and starts at 666. I swear :)
8 | DWORD | Offset into #2 above. Can contain RAM litter.
0xC | DWORD | Index in /#TOPICS file of the entry containing offsets to the title & filename. Can contain RAM litter.

/#TOPICS

An index into this file can be converted to an offset in the /#URLTBL file, without reading this file using the following formula: offset = (index%341)*12 + index/341*4096

This file contains information on the topics present.

Each entry has the following format.

Offset | Type | Comment/Value
0 | DWORD | Offset into the tree in the /#TOCIDX file.
4 | DWORD | Offset in /#STRINGS file of the contents of the title tag or the Name param of the file in question. -1 = no title.
8 | DWORD | Offset in /#URLTBL of entry containing offset to /#URLSTR entry containing the URL.
0xC | WORD | 2 indicates not in contents, 6 indicates that it is in the contents, 0/4 something else (unknown)
0xE | WORD | 0, 2, 4, 8, 10, 12, 16, 32 (unknown)

/#URLSTR

This file is made up of 0x4000 byte blocks. If the last block is not filled then it will be smaller than 0x4000 bytes. The free space at the end of the blocks is filled with NUL bytes. The blocks contain the following elements one after another:

An unknown BYTE. So far this has been 0, 0x42 and in spechsdk.chi it was 0x49. Does not indicate presence/absence of URL/FrameName strings.

This is followed by pairs of URL, FrameName strings (both NT) from the HHC.

Then come all the Local strings from the HHC:

Offset | Type | Comment/Value
0 | DWORD | Offset of the URL for this topic.
4 | DWORD | Offset of the FrameName for this topic.
8 | ANSI/UTF-8 NT string that is the Local for this topic.

There is one way to tell where the end of the URL/FrameName pairs occurs: Repeat the following: read 2 DWORDs and if both are less than the current offset then this is the start of the Local strings else skip two NT strings.

/#URLTBL

An offset in this file can be converted to an index into the /#TOPICS file, without reading this file using the following formula: index = ((offset%4096)+((offset/4096)*4096-4))/12

Each 0x1000 byte block has the following format.

Offset | Type | Comment/Value
0 | DWORD[3][341] | 341 entries. 12 bytes each.
0xFFC | DWORD | 4096 (unknown) possibly the length of the block? That MS would pull this kind of shit is really annoying; they should have just put all the entries one after another, not stuffed in an arbitrary DWORD after every 4092 bytes. From this and other blockness I guess they are optimizing for the Wintel platform.

Each entry has the following format.

Offset | Type | Comment/Value
0 | DWORD | Unknown. I suspect that this is either some kind of unique ID or two WORDs.
4 | DWORD | Index of entry in /#TOPICS file.
8 | DWORD | Offset in /#URLSTR file of entry containing filename.

/#IVB

This is basically the [ALIAS] section of the HHP file.

Offset | Type | Comment/Value
0 | DWORD | Size of the file minus 4 (num entries = (filelen-4)/8)
4 | /#IVB entries to the EOF

/#IVB entries have the following format.

Offset | Type | Comment/Value
0 | DWORD | The value of the alias
4 | DWORD | Offset in /#STRINGS file of the file to show

/#SUBSETS

This file is present when the [SUBSETS] section is present in the HHP file.

Offset | Type | Comment/Value
0 | WORD | 0 (unknown)
2 | WORD | Number of bytes taken up by the subset entries.

The subset entries currently seem to be garbage left over from previous usage of the same memory locations. Based on the number of bytes per non-whitespace line in the [SUBSETS] section each subset entry is 12 BYTEs in length.

/$FIftiMain

The majority of this description was contributed and or corrected by Jed Wing.

Empty when "Full-text search=No" or when no HTML files have been indexed. Holds the full-text search information. If you have a word longer than 99 characters in a HTML file then it seems the indexing routines will die during indexing of that file and then skip on to the next one. All word sorting, processing and storage is done case-insensitively and is not case-preserving. Note that files without ".h" in their names will not contribute keywords to this fast-search index. The function of this file seems to be to store the locations of the words found in the HTML files, so the search code can quickly find where those words occur.

This file is yet another tree, more similar to the ITSP directory than the BTree file.

This file makes use of 2 ways of encoding integers in variable length fields: the so called scale and root method and a variant of the ENCINT method used in the PMGL/PMGI directory chunks. For the ENCINTs in this file the bytes are stored least significant first (little endian), whereas in the PMGL/PMGI chunks they are stored most significant first (big endian).

The scale and root method needs two parameters, which I'll call s (scale) and r (root size). In the context of /$FIftiMain files, s always appears to be '2', but any other power of 2 could also work (and might be used in some rare cases). The encoding is as follows:

The integer is encoded as two parts, p (prefix) and q (actual bits). p determines how many bits are stored, as well as implicitly determining the high-order bit of the integer. To encode an integer, p starts out as a single 0. If the integer fits in r bits, you're done. If the integer fits in r+1 bits (i.e. r-th bit is set, counting from 0), prepend a 1 to the p and store the low r bits of the integer in q. Otherwise, while the integer does not fit in the allotted space, prepend a bit to p, and increase the size of q by one bit. It's hard to see from the description, but an example will make it more clear. Using s=2, r=3:

value   p  q
0:      0 000
1:      0 001
2:      0 010
..
7:      0 111
8:     10 000
9:     10 001
10:    10 010
..
15:    10 111
16:   110 0000
17:   110 0001
18:   110 0010
..
30:   110 1110
31:   110 1111
32:  1110 00000
33:  1110 00001
34:  1110 00010
..
62:  1110 11110
63:  1110 11111
64: 11110 000000

and so on.

A scale other than 2 has never been seen, so it is hard to say how s/r encoding works when s=4, etc. The following is how it might work using s=4, r=2:

value  p (base 2) q (base 4)
0:             0 00
1:             0 01
..
14:            0 32
15:            0 33
16:           10 00
17:           10 01
..
30:           10 32
31:           10 33
32:          110 000
33:          110 001
..

and so on. (i.e. a base-4 digit is added each time, meaning two bits added each time. In binary that looks like:

value         p   q
0:             0 0000
1:             0 0001
..
14:            0 1110
15:            0 1111
16:           10 0000
17:           10 0001
..
30:           10 1110
31:           10 1111
32:          110 000000
33:          110 000001
..

Of course, this is all wild speculation, since examples with s other than 2 haven't been seen... But the codes do work this way (i.e. prepending a 1 to the prefix multiplies the additive value 'b' by s and adds another log2(s) bits.)

The file begins with a header that is 0x400 bytes in length.

Offset | Type | Comment/Value
0 | BYTE[4] | 0x00 0x00 0x28 0x00 (unknown)
4 | DWORD | Number of HTML files indexed after any automatic splitting.
8 | DWORD | Offset to the last word tree block (4096 less than the file length)
0xC | DWORD | 0 (unknown)
0x10 | DWORD | The number of "leaf node" pages in the file.
0x14 | DWORD | Offset to the last word tree block (4096 less than the file length)
0x18 | WORD | Depth of the tree of blocks (i.e. 1 if only leaf nodes, 2 if there is a non-leaf node page to index among the leaf nodes, 3 if there are 2 levels of index node chunks, but could theoretically be even deeper.
0x1A | DWORD | 7 (unknown)
0x1E | BYTE | Scale for encoding of "document index" in Word Location Code (WLC) entries
0x1F | BYTE | Root size for encoding of "document index" in WLC entries
0x20 | BYTE | Scale for encoding of "code count" in WLC entries
0x21 | BYTE | Root size for encoding of "code count" in WLC entries
0x22 | BYTE | Scale for encoding of "location codes" in WLC entries
0x23 | BYTE | Root size for encoding of "location codes" in WLC entries
0x24 | BYTE[10] | 0 (unknown)
0x2E | DWORD | Length of the word tree blocks (4096).
0x32 | DWORD | 0/1 (unknown)
0x36 | DWORD | Word index of the last duplicate.
0x3A | DWORD | Character index of the last duplicate. From the first character of the first word. The whitespace after tags is not included. &amp; type things are counted as one character. Line endings are not counted in this.
0x3E | DWORD | Length of the longest word in the list not including NT (maximum of 99).
0x42 | DWORD | Number of words including duplicates.
0x46 | DWORD | Number of words not including duplicates.
0x4A | DWORD | The total length of all the words including duplicates is this DWORD plus the next one. It is unknown how the split is performed.
0x4E | DWORD | This one is usually smaller than the previous one.
0x52 | DWORD | Total length of all the words not including duplicates.
0x56 | DWORD | Length of unused/null bytes at the end of the word block (if only 1 block, more than total if > 1 block - possibly some free space in WLC blocks).
0x5A | DWORD | 0 (unknown)
0x5E | DWORD | One less than the number of HTML files indexed (not entirely sure)
0x62 | BYTE[24] | 0 (unknown)
0x7A | DWORD | Windows code page identifier (usually 1252 - Windows 3.1 US (ANSI))
0x7E | DWORD | LCID from the HHP file.
0x82 | BYTE[894] | 0 (unknown)

The header is followed by pairs of variable size WLC (scale and root encoded) blocks and leaf node chunks (in that order).

Each WLC entry is made up of bit fields packed as tightly as possible. Each entry, however, is right-padded with 0s to a full byte. The fields are encoded as the scale and root variable-length integer format described above, with the parameters taken from the initial header. "Delta coding" is also used in a couple of places to reduce the size of the codes -- that is, the first value is stored verbatim, and subsequent values are stored as a delta or difference from the previous value.

WLC entries
Encoding(s) | Name/Comment
r/s and delta (across the various entries for a single word) | Document index - indicates in which document this entry is for by way of an index into the #TOPICS file.
r/s | Code count - the number of times that the word this entry specifies is used in the specified topic.
r/s and delta (within each WLC entry) | A sequence of location codes - these are the word indices (zero based) where this word occurs in the specified topic.

The leaf and index node chunks are 4096 bytes in length. They begin with a header followed by entries.

Leaf node header
Offset | Type | Comment/Value
0 | DWORD | Offset to the next leaf node chunk. 0 if this is the last leaf node chunk.
4 | WORD | 0 (unknown)
6 | WORD | Length of free space at the end of the current leaf node chunk.

This is followed by leaf node entries:

Leaf node entries
Offset | Type | Comment/Value
0 | BYTE | Length of the word/partial word in this entry plus one. Maximum of 100.
1 | BYTE | Position in the word where characters are placed.
2 | BYTEs | Length-1 bytes make up the word or part of the word. Maximum of 99 BYTEs. Not NT
+0 | BYTE | Context (0 for body tag, 1 for title tag, other values are unknown)
+1 | ENCINT | Number of WLC entries.
+0 | DWORD | Offset in this file of the WLC entries for this word.
+4 | WORD | 0 (unknown)
+6 | ENCINT | Number of bytes used by the WLC entries for this word.

This is all fairly complex, so an example will be extremely useful here. This example is taken from a copy of 'windows.chm', the system documentation apparently distributed with some version of Windows 98:

Hex dump of two leaf node entries:

000223d:                                        02 00 31  ...0...........1
0002240: 00 0a 03 04 00 00 00 00 1d 01 01 01 01 20 04 00  ............. ..
0002250: 00 00 00 03

The fields of these two entries are as follows:

Leaf node entries
Field | 1st entry | 2nd entry
New length | 2 | 1
Old length | 0 | 1
Name | "1" |
Context | 0 | 1
Num WLC ents | 0xA | 1
Offset | 0x403 | 0x420
Unknown | 0 | 0
WLCs length | 0x1D | 3

Scanning over to offset 0x403 in the file, we see:

0000403:          f9 f4 60 86 b8 ea 6a 00 ed 78 00 2d c0
0000410: f8 d7 28 2c f0 f6 dc c8 ce 66 61 80 87 02 00 00
0000420: f9 f4 40

Broken out, these WLC entries are:

1          <10, 1027, 29>:  f9 f4 60 86 b8 ea 6a 00 ed 78 00 2d c0 f8 d7 28
                            2c f0 f6 dc c8 ce 66 61 80 87 02 00 00
1 (TITLE)  <1, 1056, 3>:    f9 f4 40

Now, the parameters for the WLC in this file are 2/2, 2/1, 2/5. Here is a quick reference table for the codes:

p       value       q (bits)

2/1:
0:      0-1         1
10:     2-3         1
110:    4-7         2
1110:   8-15        3
11110:  16-31       4
111110: 32-63       5

2/2:
0:      0-3         2
10:     4-7         2
110:    8-15        3
1110:   16-31       4
11110:  32-63       5
111110: 64-127      6

2/5:
0:      0-31        5
10:     32-63       5
110:    64-127      6
1110:   128-255     7
11110:  256-511     8
111110: 512-1023    9

Let's start with the short one, since it's very simple:

f9 f4 40 => 1111 1001 1111 0100 0100 0000

2/2 Document index: 111110 011111 => 64 + 31 => Document #95
2/1 Code count:     0 1           => 1
2/5 Location codes: 0 00100       => 4       => Word #4
    padding:        0000

So, in document #95, word #4 is a '1' which is in the title. Now, the ordering of the documents is provided by the '#URLTBL' and '#URLSTR' files. Looking up document #95 in there (0-based indexing!), we see the file is 'internet_account.htm', in which, the first non-markup text is:

<title>Dial-Up Networking: Step 1</title>

0: dial
1: up
2: networking
3: step
4: 1

Now, the next one is a little more complicated. I won't go over it in as much detail, but I'll just break it out quickly. It contains 10 entries:

(111110 011111) ( 0 1) (   0 00110  )             0000
(    10 00    ) ( 0 1) (  10 10111  )             000
(  1110 1010  ) ( 0 1) (  10 10100  )             0000000
(  1110 1101  ) ( 0 1) (1110 0000000)             000
(     0 01    ) ( 0 1) (  10 11100  )             0000
(111110 001101) ( 0 1) ( 110 010100 )             0
(     0 01    ) ( 0 1) (  10 01111  )             0000
( 11110 11011 ) ( 0 1) ( 110 011001 )             000
(   110 011   ) (10 0) ( 110 011001 ) ( 10 00011) 0000000
(    10 00    ) ( 0 1) ( 110 000001 )             0
                                                  00000000 00000000

Parsing those entries, we get:

WLC entries
Document number | Word numbers
95 | 6
95+4 = 99 | 55
99+26 = 125 | 52
125+29 = 154 | 128
154+1 = 155 | 60
155+77 = 232 | 84
232+1 = 233 | 47
233+59 = 292 | 89
292+11 = 303 | 89 and 89+35 = 124
303+4 = 307 | 65

Picking one at random, say, Document #303 with 2 hits, we open up windows_netsetup_netwin.htm, from which I've generated a wordlist containing all of the words in order:

  0: To(TITLE)
  1: set(TITLE)
  2: up(TITLE)
  ..
  ..
 86: client
 87: follow
 88: steps
 89: 1
 90: 3
 ..
122: follow
123: steps
124: 1
125: 3
126: and
 ..

And we can see the word '1' shows up in precisely the 89th and 124th spots.

After the WLC blocks and the leaf node chunks comes the index node chunk (for a depth of 2). For higher tree depths the index node blocks are interspersed with the listing node blocks, similarly to how the PMGL/PMGI chunks are laid out in the directory of the ITSF format. The method of splitting used is likely the same space filling method used in the directory. The index node header is just a WORD indicating the length of free space at the end of the current index node chunk.

Index node entries
Offset | Type | Comment/Value
0 | BYTE | One more than the length of the word/partial word in this entry.
1 | BYTE | Position in the word where characters are placed.
2 | BYTEs | Length-1 bytes make up the word or part of the word. Not NT
+0 | DWORD | Offset of the leaf node chunk whose last entry is this word.
+4 | WORD | 0 (unknown)

Words in the node chunks are made up of the following characters stored as is: 0x01 (buggy), 0-9, a-z, _, 0xDE, 0xFE. Bytes are converted and stored as pre the table below. Character entity references of the form &#9660; are truncated to BYTEs and translated as per the table below. Character entity references of the form &amp; are treated as whitespace, except for the the latin characters, which are converted as per the table below.

Conversions
Before | After
A-Z | a-z
0x8A, 0x9A | s
0x8C, 0x9C | oe
0x9F, 0xDD, 0xFD, 0xFF, &Yacute;, &yacute;, &yuml; | y
0xC0-0xC5, 0xE0-0xE5, &Agrave;, &Agrave;, &Aacute;, &Acirc;, &Atilde;, &Auml;, &Aring;, &agrave;, &aacute;, &acirc;, &atilde;, &auml;, &aring; | a
0xC6, 0xE6, &AElig;, &aelig; | ae
0xC7, 0xE7, &Ccedil;, &ccedil; | c
0xC8-0xCB, 0xE8-0xEB, &Egrave;, &Eacute;, &Ecirc;, &Euml;, &egrave;, &eacute;, &ecirc;, &euml; | e
0xCC-0xCF, 0xEC-0xEF, &Igrave;, &Iacute;, &Icirc;, &Iuml;, &igrave;, &iacute;, &icirc;, &iuml; | i
0xD0, &ETH; | d
0xD1, 0xF1, &ntilde;, &Ntilde; | n
0xD2-0xD8, 0xF0, 0xF2-0xF8, &eth;, &Ograve;, &Oacute;, &Ocirc;, &Otilde;, &Ouml;, &Oslash;, &ograve;, &oacute;, &ocirc;, &otilde;, &ouml;, &oslash; | o
0xD9-0xDC, 0xF9-0xFC, &Ugrave;, &Uacute;, &Ucirc;, &Uuml;, &ugrave;, &uacute;, &ucirc;, &uuml; | u
0xDF, &szlig; | ss
&thorn; | 0xFE
&THORN; | 0xDE

These conversons may depend on the system codepage, character set, font and language set in the HHP file (I'm just guessing here).

There are a few bugs:

An 0x01 in a word causes the first whitespace character at the end of the word to be included in the word and if the next character is non-whitespace the word is joined to the next word. If the word begins with 0-9 then the word is terminated before the 0x01 and a new word begins at the 0x01. This bug affects the fields in the initial header.
For example:
"abcd0x1efghi-foobar" is converted to "abcd0x1efghi-foobar".
"abcd0x1efghi- foobar" is converted to "abcd0x1efghi-" and "foobar".
"0bcd0x1efghi-foobar" is converted to "0bcd" and "0x1efghi-foobar".
"0bcd0x1efghi- foobar" is converted to "0bcd", "0x1efghi-" and "foobar".

Weird bug where if the word is 16 characters in length then the word is doubled plus the first 7 chars in length.

There is a weird feature that if a word starts with 0-9 then it may contain multiple periods (0x2E = '.') or commas (0x2C = ',') embedded in the word before the non-period, non-comma word terminating character. I think this feature is so that the user can search for version numbers or numbers with a decimal point or thousands separator in them. Note that commas are removed from the word, while periods are not. For example "v1.1.234.5......,6" will become "v1" and "1.234.5......6".

Weird bug involving words ending in single quote (') being forgotten when the same word is also normal and also ending in a period (.).

There are probably many more hidden bugs and features in the word converter (I think its the the ITIR.StdWordBreaker class in ITIRCL.DLL).

/$OBJINST

From the name and the number of GUIDs present I guess it has something to do with ActiveX objects. Seems like it can be deleted without major consequence.

Offset | Type | Comment/Value
0 | DWORD | 0x04000000 (unknown)
4 | DWORD | Number of entries

This is followed by an listing, and each listing entry is as follows

Offset | Type | Comment/Value
0 | DWORD | Offset of the entry in this file
4 | DWORD | Length of the entry

The listing is followed by the entries one after another at offsets specified in the listing.

There are 2 known types of entries. The first seems to be made up of up to 3 different sub entries. The second is a 36 BYTE structure.

The first entry
Offset | Type | Comment/Value
0 | GUID | {4662DAAF-D393-11D0-9A56-00C04FB68BF7}
0x10 | DWORD | 0x04000000 (unknown) Possibly a big-endian version number of the class that the GUID refers to.
0x14 | DWORD | Unknown. Methinks bitflags that somehow affect the size of entries that have the 0x04000000 DWORD, like each bit specifies the presence/absence of a specific subentry.
0x18 | DWORD | Windows code page identifier (usually 1252 - Windows 3.1 US (ANSI))
0x1C | DWORD | LCID from the HHP file.
0x20 | BYTEs | Unknown
+0 | Entries

I haven't been able to find any files without the data for bits 0 & 1 so I can't really say exactly how big the header is and which bytes are part of the bit 0 block and which are part of the bit 1 block. Together, though, bits 0 & 1 account for a large bulk of repeatedly increasing byte blocks of 10 bytes each, plus something else at the end. I suspect that the repeats are for bit 0 and the stuff at the end is bit 1. As to the function of these two bits blocks, well there are no GUIDs and no other clues, so who knows.

bit 2. Only present when "Full text search stop list file" has been specified in the HHP.
Offset | Type | Comment/Value
0 | char[4] | ""(\0
4 | DWORD | Length in bytes of the entries not including the last zero word.
8 | BYTE[32] | 0 (unknown)
0x28 | Entries. The last entry has a zero length word.
bit 2 entries
Offset | Type | Comment/Value
0 | WORD | Length of the word
2 | char[length] | ANSI/UTF-8 string from the stop list file, may be uniqified & sorted reverse alphabetically. Not NT.
bit 3
Offset | Type | Comment/Value
0 | GUID | {8FA0D5A8-DEDF-11D0-9A61-00C04FB68BF7}
0x10 | DWORD | 0x04000000 (unknown) Possibly a big-endian version number of the class that the GUID refers to.
0x14 | DWORD | 1 (unknown)
0x18 | DWORD | Windows code page identifier (usually 1252 - Windows 3.1 US (ANSI))
0x1C | DWORD | LCID from the HHP file.
0x20 | DWORD | 0 (unknown)
The second entry
Offset | Type | Comment/Value
0 | GUID | {4662DAB0-D393-11D0-9A56-00C04FB68B66}
0x10 | DWORD | 666 (May represent the version of the class that the GUID refers to)
0x14 | DWORD | Windows code page identifier (usually 1252 - Windows 3.1 US (ANSI))
0x18 | DWORD | LCID from the HHP file.
0x1C | DWORD | Unknown. Almost always 10031. Also 66631 (accessib.chm from the MSDN).
0x20 | DWORD | 0 (unknown)

/$WWAssociativeLinks/* & /$WWKeywordLinks/*

The files in the /$WWAssociativeLinks and /$WWKeywordLinks directories have the same formats. The maximum total length (including parents) of an entry in one of these files is 488 characters (including NT). HHW complains about and refuses to output any that are greater than this length.

The /$WWKeywordLinks dir specifies the contents of the Index navigation pane & the /$WWAssociativeLinks dir specifies the Alinks.

/$WW*Links/BTree

In CHW files this is named BTREE and in CHI/CHM files it is named BTree.

This file has a 76 byte header, then 2048 byte blocks. First come all the listing blocks, then all the index blocks. This file is similar to the directory entries in the ITSF format, except that the index blocks are at the end instead of interspersed with the listing blocks. All block indices below are zero based. This file forms a tree, with the last (index mostly) block being the root of the tree. If there is more than one level of index blocks then the root block will have two children; the first in the block header and the second in the entry. WARNING: just as in the ITSF directory there can be garbage in the free space, so respect that first WORD and use it. I'm not yet sure how the listing blocks are split up, though it is probably the same as the ITSF directory (space filling).

BTree header
Offset | Type | Comment/Value
0 | char[2] | ;) (0x3B 0x29) (signature)*
2 | WORD | *Flags. Bit 0x2 always 1. Bit 0x0400 1 if directory?? (this is always on)
4 | WORD | Size of the blocks (2048)
6 BYTE[16] Always X44. *says it is a string describing format of data
'L' = DWORD (indexed)
'F' = NUL-terminated string (indexed)
'i' = NUL-terminated string (indexed)
'2' = WORD
'4' = DWORD
'z' = NUL-terminated string
'!' = DWORD count value, count/8 * record
    DWORD filenumber
    DWORD TopicOffset
0x16 | DWORD | 0 (unknown)
0x1A | DWORD | Index of the last listing block in the file.
0x1E | DWORD | Index of the root block in the file.
0x22 | DWORD | -1 (unknown)
0x26 | DWORD | Number of blocks
0x2A | WORD | The depth of the tree of blocks (1 if no index blocks, 2 one level of index blocks, ...)
0x2C | DWORD | Number of keywords in the file.
0x30 | DWORD | Windows code page identifier (usually 1252 - Windows 3.1 US (ANSI))
0x34 | DWORD | LCID from the HHP file.
0x38 | DWORD | 0 if this a BTREE and is part of a CHW file, 1 if it is a BTree and is part of a CHI or CHM file
0x3C | DWORD | Unknown. Almost always 10031. Also 66631 (accessib.chm, ieeula.chm, iesupp.chm, iexplore.chm, msoe.chm, mstask.chm, ratings.chm, wab.chm).
0x40 | DWORD | 0 (unknown)
0x44 | DWORD | 0 (unknown)
0x48 | DWORD | 0 (unknown)
*These were guessed from the documentation provided with helpdeco by Manfred Winterhoff.
BTree listing blocks header
Offset | Type | Comment/Value
0 | WORD | Length of free space at the end of the block.
2 | WORD | Number of entries in the block.
4 | DWORD | Index of the previous block. -1 if this is the first listing block.
8 | DWORD | Index of the next block. -1 if this is the last listing block.
BTree listing block entries
Offset | Type | Comment/Value
0 | WCHARs | Value of the first Name entry from the HHK UTF-16/UCS-2. If this is a sub-keyword, then this will be all the parent keywords, including this one, separated by ", ". UTF-16/UCS-2 NT.
+0 | WORD | 2 if this keyword is a See Also keyword, 0 if it is not.
+2 | WORD | Depth of this entry into the tree.
+4 | DWORD | Character index of the last keyword in the ", " separated list.
+8 | DWORD | 0 (unknown)
+0xC | DWORD | Number of Name, Local pairs
+0x10 | DWORDs or WCHARs | DWORDs:Index into the /#TOPICS file. UTF-16/UCS-2 NT string: The value of the See Also string.
+0 | DWORD | Mostly 1 (unknown)
+4 | DWORD | Zero based index of this entry in the file (not block). Increments by 13 (each entry is 13 more than the last).
BTree index blocks header
Offset | Type | Comment/Value
0 | WORD | Length of free space at the end of the block.
2 | WORD | Number of entries in the block.
4 | DWORD | Index of a child block.
BTree index block entries
Offset | Type | Comment/Value
0 | WCHARs | Value of the first Name entry from the HHK. If this is a sub-keyword, then this will be all the parent keywords, including this one, separated by ", ". UTF-16/UCS-2 NT.
+0 | WORD | 2 if this keyword is a See Also keyword, 0 if it is not.
+2 | WORD | Depth of this entry into the tree.
+4 | DWORD | Character index of the last keyword in the ", " separated list.
+8 | DWORD | 0 (unknown)
+0xC | DWORD | Number of Name, Local pairs
+0x10 | DWORDs or WCHARs | DWORDs:Index into the /#TOPICS file. UTF-16/UCS-2 NT string: The value of the See Also string.
+0 | DWORD | Index of a child block. If it is a listing block then it is the one that starts with the keyword at the start of this entry

/$WW*Links/Data

In CHW files this is named DATA and in CHI/CHM files it is named Data.

This file contains entries that are 13 bytes in length. All known entries have thus far contained the following bytes: 00000000 05000000 80000000 00. AFAICS this file is useless.

/$WW*Links/Map

In CHW files this is named MAP and in CHI/CHM files it is named Map.

Begins with a WORD indicating the number of entries in the file (also the number of listing blocks in the BTree file). Each entry is 2 DWORDs. The first is a cumulative sum of the number of keywords in the BTree listing blocks & the second is a consecutively increasing index number. Both start at zero.

/$WW*Links/Property

In CHW files this is named PROPERTY and in CHI/CHM files it is named Property.

If there are no links of this type in the CHM then this will be a zero DWORD. Othewise it contains the following DWORDs: 0, 0, 0, 0xC, 1, 1, 0, 0. AFAICS this file is pretty much useless.

/$HHTitleMap

The file begins with a WORD indicating the number of entries.

Each entry has the following format:

Offset | Type | Comment/Value
0 | WORD | Length of the file stem.
2 | BYTEs | File stem. ANSI/UTF-8 string. Not NT.
+0 | DWORD | Unknown.
+4 | DWORD | Unknown. Same value as previous DWORD.
+8 | DWORD | LCID of the specified file.

/$TitleMap

The file begins with a WORD indicating the number of entries.

Each entry is 68 BYTEs in length and has the following format:

Offset | Type | Comment/Value
0 | BYTE[25] | File stem. ANSI/UTF-8 NT fixed length string.
0x19 | BYTE[25] | Unknown. Seems to be RAM litter, but contains paths, file names, zero bytes, DWORDs and mixtures.
0x32 | WORD | An index number that begins at 1 and is incremented by 1 for each entry.
0x34 | DWORD | Unknown.
0x38 | DWORD | Unknown. Same value as previous DWORD.
0x3C | DWORD | LCID of the specified file.
0x40 | DWORD | Number of topic nodes including the contents & index files in the specified file.

/Path/file.chm/windowtype

It is a cache of user customized bits of the windowtype entry from the /#WINDOWS file of the \Path\file.chm CHM file.

Offset | Type | Comment/Value
0 | DWORD | Size of the file in bytes (44)
4 | Signed DWORD | Position of the left edge of the window.
8 | Signed DWORD | Position of the top edge of the window.
0xC | Signed DWORD | Position of the right edge of the window.
0x10 | Signed DWORD | Position of the bottom edge of the window.
0x14 | DWORD | Width of the navigation pane in pixels.
0x18 | DWORD | Non-zero if search highlight is on.
0x1C | DWORD | Unknown. Not font size, printing options or show state.
0x20 | DWORD | Non-zero if there is no text of the toolbar buttons.
0x24 | DWORD | Non-zero if the navigation pane is initially closed.
0x28 | DWORD | Which navigation tab is currently open.

/Path/file.chm/AdvSearchUI/Keywords

UTF-16/UCS-2 NT string. Each search item is separated by a UTF-16/UCS-2 Line Feed character. The string is followed by an unknown WORD.

/Path/file.chm/AdvSearchUI/Properties

DWORD. Only the lowest 3 bits are used. "Match similar words" is controlled by bit 0. "Search titles only" is controlled by bit 1. "Search previous results" is controlled by bit 2. Note that since previous search results are not stored anywhere as yet HH will uncheck the "Search previous results" checkbox even if its bit is on. IMHO this is a bug: HH should automatically search the whole file if there are no previous results and the checkbox is checked.

/Path/file.chm/Bookmarks/v1/Count

A DWORD indicating the number of favourites stored for the \Path\file.chm CHM file.

/Path/file.chm/Bookmarks/v1/n/Topic

An NT UTF-16/UCS-2 string showing the topic name of bookmark number n (n is zero based).

/Path/file.chm/Bookmarks/v1/n/Url

An NT UTF-16/UCS-2 string showing the URL of bookmark number n (n is zero based). It is a fully qualified path into the \Path\file.chm CHM file.

/#KEY_DELETED

A set of ANSI/UTF-8 NT strings indicating which internal files have been deleted in the new file. Names use backslash (\) instead of forward slash (/) & don't have an initial slash.

/#KEY_DATA

Offset | Type | Comment/Value
0 | DWORD[8] | Unknown.
0x20 | DWORD | Length of the name of the old chm.
0x24 | BYTEs | Name of the old chm. ANSI/UTF-8 NT.

Please let us know if you find any other internal files, figure out formats of any internal files or find out what unknown parts of the above files do. Any and all contributions will be fully attributed and, if necessary, co-copyright given.


CHS format

The CHS format consists of an 80 byte header:

Offset | Type | Comment/Value
0 | BYTE[4] | 79 56 34 12 (signature)
4 | DWORD | 0 (unknown)
8 | DWORD | Number of subset entries (could also be QWORD, or even WORD or BYTE).
0xC | DWORD | 0 (unknown)
0x10 | BYTE[51] | Name of the currently selected subset or "(Entire Collection)" if no subset is selected
0x43 | BYTE[13] | Unknown. May be a timestamp(s) or junk data.

… followed by the subset entries repeated to the end of the file:

Offset | Type | Comment/Value
0 | DWORD | Number of DWORDs at the end of the entry. Length of each entry = 4*this+112
4 | BYTE[51] | Name of the subset. ANSI NT string. After the NIL terminator the rest of the 51 BYTEs are filled with garbage. This should not be "New" or "(Entire Collection)" since some fugly bugs will result.
0x37 | BYTE[57] | Unknown. Seems to be an ANSI NT string that is an abbreviation of some kind - eg VC, MSDN, VSS etc
0x70 | DWORDs | Subset contents info (unknown format - each DWORD represents a single leaf node, they are unique within a collection & they don't seem to change if you delete the CHS & recreate the subset). Please let us know if you figure out how these DWORDs specify which CHMs to use.

Ensure that the number of subsets as stored in the header is not greater than the actual number of subset entries in the file, since on Win95 at least HH will not open the HH viewer, but cause a lot of disk activity & crash/freeze Win95.


XML formats

Preface

XML is a derivative of SGML, and is used for stuctured storage of content and metadata.

The XML files are valid except for a couple of problems; there is no doctype at the beginning and where attributes have a numerical value, they are not surrounded in quotation marks.

None of the tags contain any content; they only have sub-tags and attributes. It is the attributes which store content, and all the attributes are named "value".

The XML files are used to implement the Collections feature. Each COL file specifies a single collection and hhcolreg.dat is used to store data on all collections on a machine.

There are three tags in hhctrl.ocx, that are yet to be seen in any of the XML formats; findmergedchms, showhomepage and homepage. At a guess these are likely to be meta-data tags from the COL format.


COL format

The col xml format describes individual collections of individual chm files that are used to group content into aggregations.

You can access a DTD that describes this XML format or read on for a more human-oriented description.

The outer element is XML, immediately inside this is the HTMLHelpCollection element, which is the true container for the other elements.

First in the HTMLHelpCollection element come several meta-data elements:

Meta-data elements
Element | Explanation
masterchm | The file-name stem of the main chm of the collection.
masterlangid | The numerical value of the main language, presumably that of the chm listed in the masterchm element.
samplelocation | This has only been empty. Presumably the location that stores the samples.
collectionnum | Which collection this is in the collection registry file (hhcolreg.dat). Numeric.
refcount | Presumably a reference count that stores how many times this collection is linked into other collections or into hhcolreg.dat.
version | Presumably the DTD version for this particular collection.

These are followed by a Folders element, which contains a single Folder element.

Each Folder element contains a TitleString element, a FolderOrder element (numerical) and 0 or more Folder elements. The value attribute of the TitleString element contains the string to display in the contents pane and the value attribute of the FolderOrder element stores the order in which its parent Folder element is put into the contents pane at the current Folder depth. If two Folder elements with the same parent have the same value attribute of the FolderOrder element then the one that occurs earlier in the file will come first in the contents pane.

Terminal Folder elements have TitleString elements with a value attribute of the form "=chmstem", where chmstem is the file-name stem of a chm file. Terminal Folder elements also have a LangId element whose value attribute is a numerical language identifier.


hhcolreg.dat format

hhcolreg.dat stores information on collections on the machine.

You can access a DTD that describes this XML format or read on for a more humane description.

The outer element is XML, immediately inside this is the HTMLHelpDocInfo element, which is the true container for the other elements.

First in the HTMLHelpDocInfo element comes the meta-data element NextCollectionId. The value attribute of this element stores the value that the ColNum of the next Collection will have if another collection is ever added.

Then come the following three container elements; Collections, Locations and DocCompilations.

The Collections element contains any number of Collection elements. Each Collection element contains a single ColNum element and a single ColName element. The value attribute of the ColNum element stores a unique number that identifies the collection. The value attribute of the ColName element stores the full path to the .col file for this collection.

The Locations element contains any number of Location elements. Each Location element contains one of each of the LocColNum, LocName, TitleString, LocPath and Volume elements. The table below explains the content and purpose of the value attribute of each of these elements.

Location sub-elements
Element | Explanation
LocColNum | The value attribute of the ColNum element of the Collection element that this Location element applies to.
LocName | The name of this Location element. This is used in sub-elements of the LocationHistory element.
TitleString | This is displayed in a dialog box when the user is prompted to insert the required media because it is not accessible by hh.
LocPath | The full path where the location can be accessed.
Volume | The volume label of the filesystem that the LocPath is stored on.

The DocCompilations element contains any number of DocCompilation elements. Each DocCompilation element contains one of each of the DocCompId, DocCompLanguage and LocationHistory elements. The value attribute of the DocCompId element stores an identifier which is used in terminal Folder elements in the col files and is usually the stem of the CHM/CHI file for this element. The value attribute of the DocCompLanguage element stores the LCID. The LocationHistory element contains one of each of the ColNum, TitleLocation, IndexLocation, QueryLocation, LocationRef, Version, LastPromptedVersion, TitleSampleLocation, TitleQueryLocation and SupportsMerge elements, which are all described in the table below.

LocationHistory sub-elements
Element | Explanation
ColNum | The collection number this DocCompilation is part of.
TitleLocation | The full path to the CHM.
IndexLocation | The full path to the CHI.
QueryLocation | The full path to the CHQ.
LocationRef | The LocName where the CHM/CHI are stored.
Version | Numeric. Presumably a version of CHM.
LastPromptedVersion | 0. Presumably the last Version that was installed before the previous one.
TitleSampleLocation | The LocName where the samples for this CHM are stored.
TitleQueryLocation | The LocName where the CHQ is stored.
SupportsMerge | Numeric. Presumably whether or not the CHM has the other type of merging.


INI formats

INI files are text files with CRLF line endings. They are divided into uniquely named sections. The beginning each of section is denoted by a line of the following form: "[section type]" where section type is a series of words. Each section type is followed by lines up to the next section that specify data for that section and each different section type may have a different format.

There are two main types of format following the section type:
Each line is variable=value[,value]…
Each line is a just an EOL terminated string.

Also any line beginning with a semicolon (;) is a comment and will be ignored. NOTE that the author (who has since left MS) of MS' chm compiler (HHC & HHA) has said that it is only safe to put comments before any section names have been specified (ie at the start of the file). Tests with HHW 1.3 (HHA Version 4.74.8702), however indicate that it is safe to put comments on any line. This may not be true for older versions, however.

Definitions

The following variables are used below in the description of values in the different format descriptions:

bool
Yes|No
decimal number
(0|1|2|3|4|5|6|7|8|9)…
hex number
0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|A|B|C|D|E|F)…
number
hex number|decimal number
string
Any character (usually alphanumerics plus underscore) repeated up to the terminator (usually EOL, also '=' or '"')
path
Similar to string, but a file with the same name should exist


HTML Help Project (HHP) format

Preface

This is documentation on the HHP format used by MS' HTML Help Workshop (HHW) to compile CHM files. There are various titbits of info out there on the web, in Usenet & in the docs for various programs. So far I have not found a complete reference for this format.

This is file has the INI format.

HHW dies if any line is 1024 or more characters (not including CRLF).

Sections

[OPTIONS]

This is a variable=value section sorted by variable name (using memcmp), except for Custom tab, which occurs at the end.

If you find out their meaning or find any more please tell us about them.
Explanations for all the different [OPTIONS] that are displayed and preserved by HHW.
Variable & type | Explanation | Recommended setting | Default
Auto Index=bool |  |  | No
Auto TOC=number | WARNING: HHW modifies your HHC file if you specify this. IMO this is a bug: HHW should just slurp through a pipe or temporary file. |  | No
Binary Index=bool |  | Yes | Yes
Binary TOC=bool |  | Yes | No
CITATION=string
COMPRESS=number
COPYRIGHT=string
Compatibility=1.0|1.1 or later | Anything other than 1.0 is treated as 1.1 or later | 1.1 or later | 1.1 or later
Compiled file=path |  |  | hhp stem.chm
Contents file=path | The name HHW gives to new files is "Table of Contents.hhc" |
Create CHI file=bool |  |  | No
DBCS=bool | If you find any thing about this please tell us. |  |  | No
Default Font=string, number, number
Default Window=string | There is no default, but when you add a window definition HHW will change this.
Default topic=path | If there are any files in the [FILES] section then the default for this option will be the first one. |  |
Display compile notes=bool |  |
Display compile progress=bool |  |
Enhanced decompilation=bool |  |  | No
Error log file=path |  |  |
Flat=bool |  | No | No
Full text search stop list file=path |  |
Full-text search=bool |  | Yes | No
IGNORE=string
Index file=path | The name HHW gives to new files is "Index.hhk" |
Language=hex number string |  |  | OS ?thread?user?system? LCID.
PREFIX=string
Sample Staging Path=path | This must be "samples" or any upper-case variation of it or this feature will NOT work. |
Sample list file=path |  |
TMPDIR=string
Title=string |  |
Custom tab="string", string | Can put multiple lines of this option to define more than one custom tab.
???=??? | The following were strings in hha.dll & were accepted by HHW, but it didn't display or preserve them: Word Breaker, PredefinedSubsets, EnableStructuralSubsetting, FTS for untitled topics, Information Types=path, Index separators, DAT FILE, URL ROOT, REPLACE, VERSION, WARNING, ROOT, BUILD, BMROOT

[WINDOWS]

This is a variable=value section sorted by order of addition.

Each line has the following format:

string="string", "path", "path", "path", "path", "path", "string", "path", "string", number, number, [number, number, number, number], number, number, number, number, number, number, number

Summary of the arguments for each [WINDOWS] entry.
Argument number | Explanation
0 | The window type.
1 | The title bar text.
2 | The TOC file.
3 | The Index file.
4 | The Default file.
5 | The file shown when the Home button is pressed.
6 | The file shown when the Jump 1 button is pressed.
7 | The text of the Jump 1 button.
8 | The file shown when the Jump 2 button is pressed.
9 | The text of the Jump 2 button.
10 | A bit feild of navigation pane styles.
11 | Width of the navigation pane in pixels.
12 | A bit field of the buttons to show.
13 | Initial position of the window on the screen: [left, top, right, bottom].
14 | Style Flags. As set in the Win32 SetWindowLong & CreateWindow APIs.
15 | Extended Style Flags. As set in the Win32 SetWindowLong & CreateWindowEx APIs.
16 | Window show state. As set in the Win32 ShowWindow API. SW_HIDE works well - don't use it. The following are buggy in HH 1.31: SW_SHOWMINIMIZED, SW_MINIMIZE, SW_SHOWMINNOACTIVE - grey toolbars, no nav pane or HTML display when unminimized; SW_MAXIMIZE - maximizes the navigation pane, if present; SW_FORCEMINIMIZE - works same as SW_HIDE, when should just minimize.
17 | Whether or not the navigation pane is initially closed. 1 = closed, 0 = open
18 | The default navigation pane. 0 = TOC, 1 = Index, 2 = Search, 3 = Favorites, 4 = History (not implemented by HH), 5 = Author, 11-19 = Custom panes.
19 | Where the navigation pane tabs should be. 0 = Top, 1 = Left, 2 = Bottom & anything else makes the tabs appear to be behind the pane.
20 | ID to send in WM_NOTIFY messages.
?? | HHW currently accepts only 21 arguments. If you find any more please tell us about them.
Buttons to put in the HH toolbar.
Value | Explanation | Recommended setting
0x00000002 | Hide/Show button hides/shows the navigation pane. | On
0x00000004 | Back button. | On
0x00000008 | Forward button. | On
0x00000010 | Stop button. | On
0x00000020 | Refresh button. | On
0x00000040 | Home button. | On
0x00000080 | Next button. Not implemented by HH. | Off
0x00000100 | Previous button. Not implemented by HH. | Off
0x00000200 | Notes button. Not implemented by HH. | Off
0x00000400 | Contents button. Not implemented by HH. | Off
0x00000800 | Locate button. Jumps to the current topic in the contents pane. | On
0x00001000 | Options button. | On
0x00002000 | Print button. | On
0x00004000 | Index button. Not implemented by HH. | Off
0x00008000 | Search button. Not implemented by HH. | Off
0x00010000 | History button. Not implemented by HH. | Off
0x00020000 | Favorites button. Not implemented by HH. | Off
0x00040000 | Jump 1 button. Customisable text - Arg 7. | Either
0x00080000 | Jump 2 button. Customisable text - Arg 9. | Either
0x00100000 | Font button. Changes the size of the text shown in the IE HTML display pane. | On
0x00200000 | Next button. Jumps to the next topic in the contents pane. Requires "Binary TOC=Yes". | On
0x00400000 | Previous button. Jumps to the previous topic in the contents pane. Requires "Binary TOC=Yes". | On
0x???0000? | The rest of the buttons either do nothing or are unknown. If you find out what others do please tell us.
Navigation pane styles.
Value | Explanation | Recommended setting
0x00000001 | Automatically hide/show tri-pane window: when the help window has focus the navigation pane is visible, otherwise it is hidden. | Off
0x00000002 | Keep the help window on top. | Off
0x00000004 | No title bar | Off
0x00000008 | No default window styles (only HH_WINTYPE.dwStyles) | Either
0x00000010 | No default extended window styles (only HH_WINTYPE.dwExStyles) | Either
0x00000020 | Use a tri-pane window | On
0x00000040 | No text on toolbar buttons | On
0x00000080 | Post WM_QUIT message when window closes | Off
0x00000100 | When the current topic changes automatically sync contents and index. | On
0x00000200 | Send tracking notification messages | Off
0x00000400 | Include search tab in navigation pane | On
0x00000800 | Include history tab in navigation pane | Off
0x00001000 | Include favorites tab in navigation pane | On
0x00002000 | Put current HTML title in title bar | On
0x00004000 | Only display the navigation window | Off
0x00008000 | Don't display a toolbar | Off
0x00010000 | MSDN Menu | Off
0x00020000 | Advanced FTS UI. | On
0x00040000 | After initial creation, user controls window size/position | On
0x00080000 | Use custom tab #1 | Off
0x00100000 | Use custom tab #2 | Off
0x00200000 | Use custom tab #3 | Off
0x00400000 | Use custom tab #4 | Off
0x00800000 | Use custom tab #5 | Off
0x01000000 | Use custom tab #6 | Off
0x02000000 | Use custom tab #7 | Off
0x04000000 | Use custom tab #8 | Off
0x08000000 | Use custom tab #9 | Off
0x10000000 | The window type has a margin | On
0x?0000000 | The rest of the navigation pane styles either do nothing or are unknown. If you find out what others do please tell us.

[MERGE FILES]

This is a list of CHMs to merge this one with. See the Merge Files feature in the Features list for more information. Help 2 will only use Collections to merge CHMs. HHA Version 4.74.8702 will crash if there are more than 1148 entries in the merge files list (could be a mem thing, but probably not). Note that the internal file formats only allow storage of 1004 entries in the internal binary merge files list. Any lines that begin with a comment character (;), after any whitespace, are ignored. Any whitespace at the end or start of a filename is stripped away.

[FILES]

This is a list of files that should be compiled into the CHM by the compiler. Files linked to from the TOC or Index or other HTML files will also be compiled into the CHM. It is known that Help 2 will only compile files listed to be put in the CHM.

[TEXT POPUPS]

This is a list of text files and header files that contain the text for various popups that can be displayed using the Popup command of the HH ActiveX control.

[INFOTYPES]

It is unknown how this section is formatted since the current version of HHW refuses to output anything in this section. I guess that the help viewer doesn't yet implement this feature. If you find a past or future version that does output this section please let us know.

[MAP]

Each line has the following format:

#define string number
or
#include path

[ALIAS]

This is a variable=value section sorted by the numerical value of the variable.

Each line has the following format:

number|string=path ; This is a comment
or
#include path

[SUBSETS]

It is unknown how this section is formatted since the current version of HHW refuses to output this section. I guess that the help viewer doesn't yet implement this feature. If you find a past or future version that does output this section please let us know.


HTML Help Samples (HHS) format

Preface

HHS files are used by MS' HTML Help Workshop (HHW) to compile samples into .chm files. At the time of writing there was a single titbit of info out there on the web.

Below is an example of a hhs file

[Example1]
ID=Example1
DistributionMediaDestination=MyProject\Example1
DefaultClientCopyDestination=\MyProject\Example1
SourceLocation=Samples\Example1\


Sitemap (HTML) formats

These formats are based on HTML and use the following doctype:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">

The <HEAD> tag contains a <meta> tag providing information on the program that generated the files and a comment indicating the version of the file. e.g.:

<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
<!-- Sitemap 1.0 -->

The <BODY> tag contains an <OBJECT> tag that stores properties of the file in <param> tags, followed by a <UL> tag, whose <LI> tags have <OBJECT> tags that store the properties of the Contents/Index items in <param> tags. e.g.:

<BODY>
<OBJECT type="text/site properties">
    <param name="Property Name" value="Property Value">
    …
</OBJECT>
<UL>
    <LI> <OBJECT type="text/sitemap">
        <param name="Property Name" value="Property Value">
        …
        </OBJECT>
    …
</UL>
</BODY>

Note that the Property Names and Property Values and tags are not case-sensitive, but HHW will always write all three in the default capitilization, when appropriate.

Note that the tags are mostly in uppercase and the <LI> tag is not closed; this is in compliance with the doctype.

Some properties that were seen in HHA.dll that may or may not be used are Background Image, NumberImages, InformationTypeDecl, Secondary, Icon, Display, Keyword, Instruction, Section Title, Favorites, QueryType, SendEvent, SendMessage, HHI, Inclusive & Exclusive.


HTML Help Contents (HHC) format

The order of global properties is as follows:
[FrameName]
[WindowName]
[Information Types]
[ImageList]
[Image Width]
[Color Mask]
[Background]
[Foreground]
[ExWindow Styles]
[Window Styles]
[ImageType]
[Font]

Property | Example value | Explanation
FrameName | left | This is used where the topics should open in a specific HTML frame.
WindowName | main | This is used where the topics should open in a specific window.
ImageList | foobar.bmp | Path of a BMP that stores multiple images of the same size in a horizontal array.
Image Width | 16 | The width of the images in the ImageList file. HHW is buggy with respect to this; it ignores what is in the file, only ever displays 20 in the GUI and preserves the value in the file.
Color Mask | 0xFF | Only output by FAR. Has an effect on Foreground & Background colours. Unknown.
Background | 0xffffff | Colour of the background of the TOC window. White default. In hex format.
Foreground | 0x0 | Colour of the text of the TOC window (window & page names). Black default. In hex format.
ExWindow Styles | 0x6300 | Win32 extended window style DWORD. In hex format.
Window Styles | 0xc01627 | Win32 window style DWORD. In hex format.
ImageType | Folder | When using standard images (ImageList is not present), causes different icons to be used. Normally headings use a book icon & pages have a page icon with a question mark on it. If this property is "Folder" then headings will use a Folder icon and pages will have a page icon with horizontal lines on it.
Font | Times New Roman,8,0 | Font name, font size, character set.
Auto Generated | Yes | Output when the HHC has been automatically generated by HHW during the compilation process when Auto TOC is present in the HHP.

The information types are also stored in the global properties and their order is as follows:
((SaveType|SaveHidden|SaveExclusive)
SaveTypeDesc)...
[(Category
CategoryDesc
((Type|TypeHidden|TypeExclusive)
TypeDesc)...)...]

Property | Example value | Explanation
SaveType | Manager | Declares an information type as Inclusive.
SaveHidden | Code monkey | Declares an information type as Hidden.
SaveExclusive | Engineer | Declares an information type as Exclusive.
SaveTypeDesc | A professional of the engineering discipline. | Describes the previously declared information type.
Category | Experience level | Declares a category.
CategoryDesc | How knowledgeable you are. | Describes the previously declared category.
Type | Luser | Denotes an information type that belongs to the previously declared category as an Inclusive type.
TypeHidden | Hacker | Denotes an information type that belongs to the previously declared category as a Hidden type.
TypeExclusive | Guru | Denotes an information type that belongs to the previously declared category as an Exclusive type.
TypeDesc | A programmer of great talent. | Describes the previously denoted information type.

The order of the item properties is as follows: Merge | ([Name] ([Type...] [Local] [URL])... [FrameName] [WindowName] [Comment] [New] [ImageNumber])

Property | Example value | Explanation
Name |  | What is displayed in the Contents.
Local |  | The
URL |  |
ImageNumber |  | The image to display for this item.
New |  | When an auto image is being used this increases the image number by 1 so that this image [ [image] ] is seemingly added to the image.
Comment |  |
FrameName |  |
WindowName |  |
Type |  |
Merge |  |


HTML Help index (HHK) format

The order of global properties is as follows:
[FrameName]
[WindowName]
[Font]

Property | Example value | Explanation
FrameName | left | This is used where the topics should open in a specific HTML frame.
WindowName | main | This is used where the topics should open in a specific window.
Font | Times New Roman,8,0 | Font name, font size, character set.

The information types are also stored in the global properties and occur before the properties above, but they are not preserved by HHW. Their order is as follows:
((SaveType|SaveHidden|SaveExclusive)
SaveTypeDesc)...
[(Category
CategoryDesc
((Type|TypeHidden|TypeExclusive)
TypeDesc)...)...]

Property | Example value | Explanation
SaveType | Manager | Declares an information type as Inclusive.
SaveHidden | Code monkey | Declares an information type as Hidden.
SaveExclusive | Engineer | Declares an information type as Exclusive.
SaveTypeDesc | A professional of the engineering discipline. | Describes the previously declared information type.
Category | Experience level | Declares a category.
CategoryDesc | How knowledgeable you are. | Describes the previously declared category.
Type | Luser | Denotes an information type that belongs to the previously declared category as an Inclusive type.
TypeHidden | Hacker | Denotes an information type that belongs to the previously declared category as a Hidden type.
TypeExclusive | Guru | Denotes an information type that belongs to the previously declared category as an Exclusive type.
TypeDesc | One who knows everything. | Describes the previously denoted information type.

The order of the item properties is as follows: Merge | ([Name] ([Name] [Type...] [Local [URL] | See Also])... [FrameName] [WindowName] [Comment])

Property | Example value | Explanation
Name | ITSF format | The first instance is the keyword string to be displayed in the index.
Type | Experience Level::Luser | Category::Type
Local | itsf.html | The file to load when the user selects the index item.
URL |  | Should not be present unless Local also is. In the HHW GUI it is an "Alternate URL". Not sure what it does though.
See Also | ITSF internal file formats | When the user double-clicks the index item the Index control will jump to the Index entry whose keyword is the value of this param. Mutually exclusive with the Local [URL] pair.
FrameName | left | The frame to open the topic in.
WindowName | main | The window to open the topic in.
Comment |  | Dunno what this does.
Merge |  |


Other formats

This section describes some other formats used in authoring CHMs

Alias files

var=file

Text popup files

.topic number
text

Defines a text popup

.comment text

the line is stripped from the text popup file before archiving

Header files

#define var num

Full text search stop list file

List of words that are excluded from the $FIftiMain file


This section deals with the registry data associated with GUIDs that are part of the CHM system. To verify the details & check unknown GUIDs you will need access to the registry.

If your admin doesn't let you use either of the registry editors then you can just edit them using a hex editor. Create a copy of either editor and replace DisableRegistryTools with something of equal length like FuckMicro$oftSuxShit using a hex editor. Note that might be in Unicode. If you do this remember to search for the following GUIDs. Alternatively if regedit.exe is executable you can just dump the whole registry with regedit /a dump.reg HKEY_CLASSES_ROOT for example.

The following GUIDs are not present in the Windows registry. If you do see them please send in a .reg file.

{7C01FD10-7BAA-11D0-9E0C-00A0C922E6EC} and {7C01FD11-7BAA-11D0-9E0C-00A0C922E6EC} are present in the ITSF initial header. {7FC28940-9D31-11D0-9B27-00A0C91E9C7C} is present as part of a filename in the ITSF directory.

The following GUIDs are present in the Windows registry under HKCR\CLSID. If yours are any different please send in the differences.

{5D02926A-212E-11D0-9DF9-00A0C922E6EC}

From: ITSF directory header.
Description: Microsoft InfoTech IStorage System
NotInsertable
InprocServer32: ITSS.DLL
ThreadingModel: Both
VersionIndependentProgID: MSITFS
ProgID: MSITFS1.0

{4662DAAF-D393-11D0-9A56-00C04FB68BF7}

From: $OBJINST internal file.
InprocServer32: ITIRCL.DLL
ThreadingModel: Both
VersionIndependentProgID: ITIR.StdWordBreaker
ProgID: ITIR.StdWordBreaker.4

{4662DAB0-D393-11D0-9A56-00C04FB68B66}

From: $OBJINST internal file.
InprocServer32: HHCTRL.OCX
ThreadingModel: Both
VersionIndependentProgID: HHCtrl.SystemSort
ProgID: HHCtrl.SystemSort.666

{8FA0D5A8-DEDF-11D0-9A61-00C04FB68BF7}

From: $OBJINST internal file.
InprocServer32: ITIRCL.DLL
ThreadingModel: Both
VersionIndependentProgID: ITIR.EngStemmer
ProgID: ITIR.EngStemmer.4


/$FXFtiAttribute/
/$FXFtiAttribute/BTREE
/$FXFtiAttribute/DATA
/$FXFtiAttribute/PROPERTY
/$FXFtiMain/
/$FXFtiMain/BTREE
/$FXFtiMain/DATA
/$FXFtiMain/PROPERTY
/$Index/$ATTRNAME
/$Index/$PROPBAG
/$Index/$STRINGS
/$Index/$SYSTEM
/$Index/$TOC/
/$Index/$TOC/$TestCol
/$Index/$TOPICATTR
/$Index/$TOPICS
/$Index/$URLSTR
/$Index/$URLTBL
/$Index/$VTAIDX
/$Index/K/
/$Index/K/$LEAVES
/$Index/NamedUrlIndex/
/$Index/NamedUrlIndex/$LEAVES
/$OBJINST
::DataSpace/NameList
::DataSpace/Storage/MSCompressed/Content
::DataSpace/Storage/MSCompressed/ControlData
::DataSpace/Storage/MSCompressed/SpanInfo
::DataSpace/Storage/MSCompressed/Transform/List
::DataSpace/Storage/MSCompressed/Transform/{0A9007C6-4076-11D3-8789-0000F8105754}/InstanceData/
::DataSpace/Storage/MSCompressed/Transform/{0A9007C6-4076-11D3-8789-0000F8105754}/InstanceData/ResetTable
::Transform/{0A9007C6-4076-11D3-8789-0000F8105754}/


Glossary

HTML
HyperText Markup Language
XML
eXtensible Markup Language
SGML
Standard Generalized Markup Language
MS
Microsoft
MS-DOS
MS Disk Operating System
Windows
MS' GUI successor to MS-DOS
*nix
Refers to all the modern Unices; Linux, OpenBSD, FreeBSD, NetBSD, the Hurd, Solaris & MacOS X.
NT
NIL terminated. Refers to the tradition of ending strings with a zero character.
HH
HTML Help


content - chm & its
update - kpd
merged:
    index - chi
    awords/kwords - chw
    search info - chq
subsets - chs
collection defn - col
window properties, bookmarks & search history - hh.dat
collections - hhcolreg.dat
Authoring:
    project - hhp
    contents - hhc
    index - hhk
    samples - hhs
    stop list file - stp
    info types - hhi

system code 8 - abbreviations & explanations
hhc
    ImageList
    Font
    FrameName
    WindowName
    Name
[MERGE FILES]
windows
    args 0,1,2,3,4,5,6,7,8,9
[ALIAS]

HHA Version 4.72.7294
HHA Version 4.72.8086
HHA Version 4.72.8135
HHA Version 4.72.8140
HHA Version 4.73.8198
HHA Version 4.74.8702
HHA Version 4.74.9301

        hhcolreg.dat
DocCompilation
DocCompilations
Location
Locations
HTMLHelpDocInfo
<NextCollectionId value=%d/>
Collection
Collections
XML
<TitleString value="%s"/>
<LocColNum value=%d/>
<Volume value="%s"/>
<LocPath value="%s"/>
<LocName value="%s"/>
<ColNum value=%d/>
<LastPromptedVersion value=%ld/>
<Version value=%ld/>
<LocationRef value="%s"/>
<IndexLocation value="%s"/>
<TitleQueryLocation value="%s"/>
<QueryLocation value="%s"/>
<TitleLocation value="%s"/>
LocationHistory
<SupportsMerge value=%d/>
<DocCompLanguage value=%d/>
<TitleSampleLocation value="%s"/>
<DocCompId value="%s"/>
<ColNum value=%d/>
<ColName value="%s"/>

        *.col
Folder
Folders
HTMLHelpCollection
XML
collectionnum
version
refcount
masterlangid
samplelocation
masterchm
LangId
FolderOrder
<TitleString value="%s"/>

        Unknown
findmergedchms
showhomepage
homepage


GNU Free Documentation License

Version 1.1, March 2000

Copyright (C) 2000  Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

0. PREAMBLE

The purpose of this License is to make a manual, textbook, or other written document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

1. APPLICABILITY AND DEFINITIONS

This License applies to any manual or other work that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you".

A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (For example, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License.

The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License.

A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, whose contents can be viewed and edited directly and straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup has been designed to thwart or discourage subsequent modification by readers is not Transparent. A copy that is not "Transparent" is called "Opaque".

Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML designed for human modification. Opaque formats include PostScript, PDF, proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML produced by some word processors for output purposes only.

The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.

2. VERBATIM COPYING

You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

You may also lend copies, under the same conditions stated above, and you may publicly display copies.

3. COPYING IN QUANTITY

If you publish printed copies of the Document numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a publicly-accessible computer-network location containing a complete Transparent copy of the Document, free of added material, which the general network-using public has access to download anonymously at no charge using public-standard network protocols. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

4. MODIFICATIONS

You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

  • A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
  • B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has less than five).
  • C. State on the Title page the name of the publisher of the Modified Version, as the publisher.
  • D. Preserve all the copyright notices of the Document.
  • E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
  • F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
  • G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.
  • H. Include an unaltered copy of this License.
  • I. Preserve the section entitled "History", and its title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
  • J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
  • K. In any section entitled "Acknowledgements" or "Dedications", preserve the section's title, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
  • L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
  • M. Delete any section entitled "Endorsements". Such a section may not be included in the Modified Version.
  • N. Do not retitle any existing section as "Endorsements" or to conflict in title with any Invariant Section.

If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.

You may add a section entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties--for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

5. COMBINING DOCUMENTS

You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice.

The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

In the combination, you must combine any sections entitled "History" in the various original documents, forming one section entitled "History"; likewise combine any sections entitled "Acknowledgements", and any sections entitled "Dedications". You must delete all sections entitled "Endorsements."

6. COLLECTIONS OF DOCUMENTS

You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

7. AGGREGATION WITH INDEPENDENT WORKS

A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, does not as a whole count as a Modified Version of the Document, provided no compilation copyright is claimed for the compilation. Such a compilation is called an "aggregate", and this License does not apply to the other self-contained works thus compiled with the Document, on account of their being thus compiled, if they are not themselves derivative works of the Document.

If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one quarter of the entire aggregate, the Document's Cover Texts may be placed on covers that surround only the Document within the aggregate. Otherwise they must appear on covers around the whole aggregate.

8. TRANSLATION

Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License provided that you also include the original English version of this License. In case of a disagreement between the translation and the original English version of this License, the original English version will prevail.

9. TERMINATION

You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

10. FUTURE REVISIONS OF THIS LICENSE

The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.

Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.

How to use this License for your documents

To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

      Copyright (c)  YEAR  YOUR NAME.
      Permission is granted to copy, distribute and/or modify this document
      under the terms of the GNU Free Documentation License, Version 1.1
      or any later version published by the Free Software Foundation;
      with the Invariant Sections being LIST THEIR TITLES, with the
      Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
      A copy of the license is included in the section entitled "GNU
      Free Documentation License".

If you have no Invariant Sections, write "with no Invariant Sections" instead of saying which ones are invariant. If you have no Front-Cover Texts, write "no Front-Cover Texts" instead of "Front-Cover Texts being LIST"; likewise for Back-Cover Texts.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.


 AdvSearchUI AdvSearchUI/Keywords AdvSearchUI/Properties Bookmarks Bookmarks/v1 Bookmarks/v1/0 Bookmarks/v1/0/Topic Bookmarks/v1/0/Url Bookmarks/v1/Count


HTML Help (HH) (Preliminary) Unofficial Specification

Cover page
This version (2002-?-?)
http://bonedaddy.net/pabs3/hhm/chmspec/2002-?-?/
Latest version
http://bonedaddy.net/pabs3/hhm/chmspec/latest/
Formats
DocBook source archive (ZIP), DocBook source archive (TAR), HTML, HTML archive (ZIP), HTML archive (TAR), GNU Info archive (TAR), PDF, CHM, Debian DocBook src package,
Editor(s)
Pabs <pabs@zip.to>
Authors
See author list

Copyright © 2002 Pabs et al., All Rights Reserved.

Abstract

This is documentation on MS' current generation of help systems (HTML Help). HTML Help is a documentation system from MS that relies on HTML, XML and a filesystem that is used in storing multiple HTML & other files in a single file and involves LZX compression.

Status of this document

This is the initial release of this unofficial specification document. It is being released to gather feedback and further information on the current knowledge base relating to MS' help formats and systems.

This is an unofficial document produced by people not employed by MS without the permission or knowledge of MS. We hope that MS can see the value in this exercise and restrain their lawyers.

Every effort has been made to document each bit of the relevant formats and ensure that the documentation is accurate. However this effort is not yet complete and help is still needed to find meaning amongst the bits.

It is our hope that, in time, the documentation will be complete and, with luck, work may begin on the documentation of MS' other help systems.

Dedication

This specification is dedicated to the humble NDA, which poked RMS enough to start GNU and trigger a whole new generation of innovation.

It is also dedicated to paranoid proprietary software authors for indirectly training reverse engineers worldwide.

Table of Contents

Chapters

  1. About the Specification
  2. Introduction
  3. Features
    1. Menu
    2. Toolbar
    3. Navigation pane
      1. Contents
      2. Index
      3. Search
      4. Favourites
      5. Custom tabs
    4. Information types
    5. Text popups
    6. Context-sensitive help
    7. Subsets
    8. Samples
    9. Merged help
      1. Collections
      2. Merge Files
  4. Files
    1. Content
    2. Authoring
    3. Settings
  5. Formats
    1. ITSF format
    2. ITSF internal file formats
    3. CHS format
    4. XML formats
      1. COL format
      2. hhcolreg.dat format
    5. INI formats
      1. HTML Help Project (HHP) format
      2. HTML Help Samples (HHS) format
      3. SFL format
    6. Sitemap (HTML) formats
      1. HTML Help Contents (HHC) format
      2. HTML Help index (HHK) format
    7. Other formats
      1. Alias files
      2. Text popup files
      3. Header files
      4. Full text search stop list file (STP)
  6. Miscellaneous
    1. LZX compression
    2. GUIDs
    3. Implementations
    4. Optimisation
    5. MS Office Custom tabs
    6. HtmlHelp API
    7. ActiveX control API
    8. HH.exe command line
    9. Registry locations
    10. Undocumented HHW
    11. Links
    12. Help 2

Appendices

  1. Test suite
  • References
  • Glossary
  • Index
  • GFDL