/* * Help Access Library * A Library to access the contents of Windows Help files. * * Copyright (C) 1995-2000 Bernd Herd, http://www.herdsoft.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ENUMTTL.C ------------------------------------------ * @doc * @module ENUMTTL.C | * Code to enumerate the list of Titles in a .HLP or .MVB * File. * * Help Access Library Project. * *-----------------------------------------------------*/ #include #include #include #include #include #include "hlpacces.h" BOOL LOCAL nEnumerateTitles(NPIFSFILE ifsfile, TITLEENUMPROC fnTitleEnumProc, LPARAM lParam); BOOL LOCAL nEnumeratePage(NPIFSFILE ifsfile, int PageCount, int CurrentLevel, int PageSize, int CurrPage, TITLEENUMPROC fnTitleEnumProc, LPARAM lParam); /* @func BOOL | HlpEnumTitles | * * This Function enumerates the List of titles to the application-Given * callback Function. * * @comm As the Group-Definition Contained in a Media Viewer 2.0-File is * not itself stored in the TTLBTREE internal File, this Function will * not emit group strings. The Function can be used to * retrieve these strings for one or all topics. * * @rdesc * TRUE if the Function was Successfull * FALSE else */ BOOL WINAPI DLLEXP HlpEnumTitles( HIFS ifs, // @parm Handle to a opened File-System opened by TITLEENUMPROC fnTitleEnumProc, // @parm Application-Defined Callback-Procedure to be called for every topic found in the help file LPARAM lParam) // @parm Aplication-defined parameter to be transfered to the Callback-function { BOOL Success=FALSE; NPIFSFILE ifsfile = IFSOpenFile(ifs, "|TTLBTREE"); if (ifsfile) { Success = nEnumerateTitles(ifsfile, fnTitleEnumProc, lParam); IFSCloseFile(ifsfile); } return Success; } /* nEnumerateTopic * * Does the buch of Work to do enumeration */ BOOL LOCAL nEnumerateTitles(NPIFSFILE ifsfile, TITLEENUMPROC fnTitleEnumProc, LPARAM lParam) { BOOL Success; BTREEHEADER BTreeHdr; DWORD dwSize; UINT PageCount; //--------- Read Title B-Tree header ------------------ IFSReadFile(ifsfile, &BTreeHdr, sizeof(BTreeHdr)); dwSize = IFSSeekFile(ifsfile, 0L, 2); PageCount = (UINT) (dwSize/leword(BTreeHdr.PageSize)); // printf("# PageCount:%u NLevels: %u NSplits: %u PageSize: %u Total Entries:%ld\n\n", PageCount, BTreeHdr.NLevels, BTreeHdr.NSplits, BTreeHdr.PageSize, BTreeHdr.TotalBtreeEntries); Success = nEnumeratePage(ifsfile, PageCount, leword(BTreeHdr.NLevels)-1, leword(BTreeHdr.PageSize), leword(BTreeHdr.RootPage), fnTitleEnumProc, lParam); return Success; } #pragma pack(1) typedef struct { LEWORD PageNo; LEDWORD TopicOffset; } BTREEINDEXENTRY; #pragma pack() BOOL LOCAL nEnumeratePage(NPIFSFILE ifsfile, int PageCount, int CurrentLevel, int PageSize, int CurrPage, TITLEENUMPROC fnTitleEnumProc, LPARAM lParam) { BOOL Success = FALSE; DWORD loc = sizeof(BTREEHEADER) + PageSize * (DWORD) CurrPage; NPSTR page = (NPSTR) LocalAlloc(LPTR, PageSize), next; BTREENODEHEADER NodeHeader; BTREEINDEXENTRY NEAR *CurrIndexEntry; int i; if (page) { //----------- Read Page ---------------------------------------- IFSSeekFile(ifsfile, loc, 0); if (PageSize == IFSReadFile(ifsfile, page, PageSize)) { memcpy(&NodeHeader, page, sizeof(NodeHeader)); //--------- Are we in a Node or in a leaf? ------------------- if (CurrentLevel > 0) { //-- We're in a node, search for next sub-node or leaf -- for (i=0 , Success=TRUE, CurrIndexEntry = (BTREEINDEXENTRY NEAR *) (page+sizeof(BTREEINDEXHEADER)); i1 ? 2 : 1) && Success; ++i ,++CurrIndexEntry) //------- We're currently in a node, so recurse down... ---- Success &= nEnumeratePage(ifsfile, PageCount, CurrentLevel-1, PageSize, leword(CurrIndexEntry->PageNo), fnTitleEnumProc, lParam); } else //--------- Enumerate Page contents -------------------------- for (Success=TRUE, next=page+sizeof(BTREENODEHEADER), i=0; Success &&i