⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hhc.c

📁 CHM decompiler is a program that converts the internal files of CHM files back into the HHP, HHC, an
💻 C
字号:
/*chmdeco -- extract files from ITS/CHM files and decompile CHM filesCopyright (C) 2003 PabsThis program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free Software Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA, 02111-1307, USA or visit:http://www.gnu.org*//*hhc.c - this module implements recreating the .hhc file from the #TOCIDX fileIt was written by Pabs.*//* System headers */#include <stdio.h>#include <sys/types.h>#include <errno.h>#include <stdlib.h>#include <string.h>#include <unistd.h>/* Local headers */#include "chmdeco.h"#include "common.h"#include "convert.h"#include "sitemap.h"#include "strings.h"#include "hhc.h"FILE* tocidx = NULL;FILE* hhc = NULL;bool print_tree( void );void recreate_hhc( void ){	bool got_text_site_properties = false;	bool got_tree = false;	bool got_valid_prop = false;	/* FIXME: go through the #WINDOWS file & look for a window type with a contents file? */	char* cf = Contents_file ? Contents_file : HHC_FILE_NAME;	/* FIXME: when there is no HHC don't output it */	hhc = recreate( cf );	if( hhc ){		char* ImageList; DWORD ImageType, Background, Foreground;		char* Font; DWORD Window_Styles, ExWindow_Styles;		char* FrameName; char* WindowName;		FILE* idxhdr;		/* Grab some sitemap properties */		errno = 0;		idxhdr = fopen("#IDXHDR","rb");		if( idxhdr ){			BYTE hhc_text_site_properties[11*4];			fseek( idxhdr, 0x14, SEEK_SET );			if( fread(hhc_text_site_properties,sizeof(hhc_text_site_properties),1,idxhdr) ){				BYTE* b = hhc_text_site_properties;				got_text_site_properties = true;				ImageList = get_string( get_DWORD(b) );				ImageType = get_DWORD(b+8);				Background = get_DWORD(b+0xC);				Foreground = get_DWORD(b+0x10);				Font = get_string( get_DWORD(b+0x14) );				Window_Styles = get_DWORD(b+0x18);				ExWindow_Styles = get_DWORD(b+0x1C);				FrameName = get_string( get_DWORD(b+0x24) );				WindowName = get_string( get_DWORD(b+0x28) );			} else				fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#IDXHDR", strerror(errno) );			FCLOSE( idxhdr );		} else if( errno && errno != ENOENT )			fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#IDXHDR", strerror(errno) );		fputs(SITEMAP_HEADER,hhc);		/* There is also Auto Generated, which cannot yet be determined*/		/* if( Auto_TOC ) fputs( "\t<param name=\"Auto Generated\" value=\"Yes\">", hhc ); */		/* FIXME: some of these are buggy when there was no TOC */		if( got_text_site_properties && (FrameName || WindowName || ImageList || ExWindow_Styles != 0xFFFFFFFF || Window_Styles != 0xFFFFFFFF || Background != 0xFFFFFFFF || Foreground != 0xFFFFFFFF || ImageType || Font) ){			got_valid_prop = true;			fputs( "<OBJECT type=\"text/site properties\">\r\n", hhc );				if( print_entity_refs ){					if( FrameName ){						fputs( "\t<param name=\"FrameName\" value=\"", hhc );						print_with_entity_refs( hhc, FrameName );						fputs( "\">\r\n", hhc );						FREE(FrameName);					}					if( WindowName ){						fputs( "\t<param name=\"WindowName\" value=\"", hhc );						print_with_entity_refs( hhc, WindowName );						fputs( "\">\r\n", hhc );						FREE(WindowName);					}					if( ImageList ){						fputs( "\t<param name=\"ImageList\" value=\"", hhc );						print_with_entity_refs( hhc, ImageList );						fputs( "\">\r\n", hhc );						FREE(ImageList);					}				} else {					if( FrameName ){ fprintf( hhc, "\t<param name=\"FrameName\" value=\"%s\">\r\n", FrameName ); FREE(FrameName); }					if( WindowName ){ fprintf( hhc, "\t<param name=\"WindowName\" value=\"%s\">\r\n", WindowName ); FREE(WindowName); }					if( ImageList ){ fprintf( hhc, "\t<param name=\"ImageList\" value=\"%s\">\r\n", ImageList ); FREE(ImageList); }				}				if( Background != 0xFFFFFFFF ) fprintf( hhc, "\t<param name=\"Background\" value=\"0x%x\">\r\n", Background );				if( Foreground != 0xFFFFFFFF ) fprintf( hhc, "\t<param name=\"Foreground\" value=\"0x%x\">\r\n", Foreground );				if( ExWindow_Styles != 0xFFFFFFFF ) fprintf( hhc, "\t<param name=\"ExWindow Styles\" value=\"0x%x\">\r\n", ExWindow_Styles );				if( Window_Styles != 0xFFFFFFFF ) fprintf( hhc, "\t<param name=\"Window Styles\" value=\"0x%x\">\r\n", Window_Styles );				if( ImageType ) fputs( "\t<param name=\"ImageType\" value=\"Folder\">\r\n", hhc );				if( Font ){					/* No \t for some reason */					if( print_entity_refs ){						fputs( "<param name=\"Font\" value=\"", hhc );						print_with_entity_refs( hhc, Font );						fputs( "\">\r\n", hhc );					} else fprintf( hhc, "<param name=\"Font\" value=\"%s\">\r\n", Font );					FREE(Font);				}			fputs( "</OBJECT>\r\n", hhc );		}		fputs("<UL>\r\n",hhc);		/* Print the TOC tree, grabbing stuff from the topics files */		errno = 0;		tocidx = fopen("#TOCIDX","rb");		if( tocidx ){			DWORD tree;			if( read_DWORD(tocidx,&tree) ){				fseek( tocidx, tree, SEEK_SET );				if( open_sitemap() ){					depth = 1;					/* WARNING: recursion */					got_tree = print_tree();					close_sitemap();				}			} else				fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#TOCIDX", strerror(errno) );			FCLOSE( tocidx );		} else if( errno && errno != ENOENT )			fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#TOCIDX", strerror(errno) );		fputs( SITEMAP_FOOTER, hhc );		FCLOSE( hhc );	} else		fprintf( stderr, "%s: %s/%s/%s: %s\n", PROGNAME, input, "#recreated", cf, strerror(errno) );	/* Nothing useful */	if( !got_valid_prop && !got_tree ){		chdir( "#recreated" );		remove( cf );		chdir( ".." );	}}#define New  2#define BOOK 4BYTE entry[20];/* Recurse through the binary toc, ret false if none printed */bool print_tree( void ){	bool ret = false;	DWORD next = 0;	do {		if( fread(entry,20,1,tocidx) ){			DWORD flags = get_DWORD(entry+4);			DWORD topics_index = get_DWORD(entry+8);			/* FIXME: If we didn't ignore offset to parent we may be able to make this a loop instead of recursive */			/* DWORD parent = get_DWORD(entry+0xC); */			next = get_DWORD(entry+0x10);			DEPTHPUT(hhc); fputs("<LI> <OBJECT type=\"text/sitemap\">\r\n",hhc);			/* This does the work of printing the right topic name etc */			ret = print_topics_entry(hhc,topics_index) || ret;			if( flags & New ){				DEPTHPUT(hhc); fputs("\t<param name=\"New\" value=\"1\">\r\n",hhc);			}			DEPTHPUT(hhc); fputs("\t</OBJECT>\r\n",hhc);			/* Possibly some children */			if( flags & BOOK ){				if( fread(entry,8,1,tocidx) ){					DWORD child = get_DWORD(entry);					if(child){						/* Got children */						fseek(tocidx,child,SEEK_SET);						DEPTHPUT(hhc); fputs("<UL>\r\n",hhc); depth++;						print_tree();						depth--; DEPTHPUT(hhc); fputs("</UL>\r\n",hhc);					}				} else {					next = 0;					fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#TOCIDX", strerror(errno) );				}			}			/* In case there were children */			if(next) fseek(tocidx,next,SEEK_SET);		} else {			fprintf( stderr, "%s: %s/%s: %s\n", PROGNAME, input, "#TOCIDX", strerror(errno) );			break;		}	} while(next);	return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -