Kirill K. Smirnov : winhelp: Correctly deal with various TopicBlockSize/ Compression combinations. Simplify HLPFILE_Uncompress_Topic function.
Alexandre Julliard
julliard at winehq.org
Mon Dec 3 09:17:53 CST 2007
Module: wine
Branch: master
Commit: 1fdd01966c28301c9f76db3f66e8644baf67b4d7
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1fdd01966c28301c9f76db3f66e8644baf67b4d7
Author: Kirill K. Smirnov <lich at math.spbu.ru>
Date: Sat Dec 1 18:57:24 2007 +0300
winhelp: Correctly deal with various TopicBlockSize/Compression combinations. Simplify HLPFILE_Uncompress_Topic function.
---
programs/winhelp/hlpfile.c | 84 ++++++++++++++++++++++++++------------------
programs/winhelp/hlpfile.h | 3 ++
2 files changed, 53 insertions(+), 34 deletions(-)
diff --git a/programs/winhelp/hlpfile.c b/programs/winhelp/hlpfile.c
index 3c34a06..e94dbfd 100644
--- a/programs/winhelp/hlpfile.c
+++ b/programs/winhelp/hlpfile.c
@@ -3,6 +3,7 @@
*
* Copyright 1996 Ulrich Schmid
* 2002 Eric Pouech
+ * 2007 Kirill K. Smirnov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -337,9 +338,8 @@ static BOOL HLPFILE_DoReadHlpFile(HLPFILE *hlpfile, LPCSTR lpszPath)
{
BYTE* end;
- /* FIXME this depends on the blocksize, can be 2k in some cases */
- index = (ref - 0x0C) >> 14;
- offset = (ref - 0x0C) & 0x3fff;
+ index = (ref - 0x0C) / hlpfile->dsize;
+ offset = (ref - 0x0C) % hlpfile->dsize;
WINE_TRACE("ref=%08x => [%u/%u]\n", ref, index, offset);
@@ -1387,8 +1387,31 @@ static BOOL HLPFILE_SystemCommands(HLPFILE* hlpfile)
magic, major, minor, flags);
if (magic != 0x036C || major != 1)
{WINE_WARN("Wrong system header\n"); return FALSE;}
- if (minor <= 16) {WINE_WARN("too old file format (NIY)\n"); return FALSE;}
- if (flags & 8) {WINE_WARN("Unsupported yet page size\n"); return FALSE;}
+ if (minor <= 16)
+ {
+ hlpfile->tbsize = 0x800;
+ hlpfile->compressed = 0;
+ }
+ else if (flags == 0)
+ {
+ hlpfile->tbsize = 0x1000;
+ hlpfile->compressed = 0;
+ }
+ else if (flags == 4)
+ {
+ hlpfile->tbsize = 0x1000;
+ hlpfile->compressed = 1;
+ }
+ else
+ {
+ hlpfile->tbsize = 0x800;
+ hlpfile->compressed = 1;
+ }
+
+ if (hlpfile->compressed)
+ hlpfile->dsize = 0x4000;
+ else
+ hlpfile->dsize = hlpfile->tbsize - 0x0C;
hlpfile->version = minor;
hlpfile->flags = flags;
@@ -1654,29 +1677,27 @@ static BOOL HLPFILE_Uncompress_Topic(HLPFILE* hlpfile)
{
BYTE *buf, *ptr, *end, *newptr;
unsigned int i, newsize = 0;
+ unsigned int topic_size;
if (!HLPFILE_FindSubFile("|TOPIC", &buf, &end))
{WINE_WARN("topic0\n"); return FALSE;}
- switch (hlpfile->flags & (8|4))
+ buf += 9; /* Skip file header */
+ topic_size = end - buf;
+ if (hlpfile->compressed)
{
- case 8:
- WINE_FIXME("Unsupported format\n");
- return FALSE;
- case 4:
- buf += 9;
- topic.wMapLen = (end - buf - 1) / 0x1000 + 1;
-
+ topic.wMapLen = (topic_size - 1) / hlpfile->tbsize + 1;
+
for (i = 0; i < topic.wMapLen; i++)
{
- ptr = buf + i * 0x1000;
-
+ ptr = buf + i * hlpfile->tbsize;
+
/* I don't know why, it's necessary for printman.hlp */
if (ptr + 0x44 > end) ptr = end - 0x44;
- newsize += HLPFILE_UncompressedLZ77_Size(ptr + 0xc, min(end, ptr + 0x1000));
+ newsize += HLPFILE_UncompressedLZ77_Size(ptr + 0xc, min(end, ptr + hlpfile->tbsize));
}
-
+
topic.map = HeapAlloc(GetProcessHeap(), 0,
topic.wMapLen * sizeof(topic.map[0]) + newsize);
if (!topic.map) return FALSE;
@@ -1685,35 +1706,30 @@ static BOOL HLPFILE_Uncompress_Topic(HLPFILE* hlpfile)
for (i = 0; i < topic.wMapLen; i++)
{
- ptr = buf + i * 0x1000;
+ ptr = buf + i * hlpfile->tbsize;
if (ptr + 0x44 > end) ptr = end - 0x44;
topic.map[i] = newptr;
- newptr = HLPFILE_UncompressLZ77(ptr + 0xc, min(end, ptr + 0x1000), newptr);
+ newptr = HLPFILE_UncompressLZ77(ptr + 0xc, min(end, ptr + hlpfile->tbsize), newptr);
}
- break;
- case 0:
- /* basically, we need to copy the 0x1000 byte pages (removing the first 0x0C) in
- * one single are in memory
+ }
+ else
+ {
+ /* basically, we need to copy the TopicBlockSize byte pages
+ * (removing the first 0x0C) in one single area in memory
*/
-#define DST_LEN (0x1000 - 0x0C)
- buf += 9;
- newsize = end - buf;
- /* number of destination pages */
- topic.wMapLen = (newsize - 1) / DST_LEN + 1;
+ topic.wMapLen = (topic_size - 1) / hlpfile->tbsize + 1;
topic.map = HeapAlloc(GetProcessHeap(), 0,
- topic.wMapLen * (sizeof(topic.map[0]) + DST_LEN));
+ topic.wMapLen * (sizeof(topic.map[0]) + hlpfile->dsize));
if (!topic.map) return FALSE;
newptr = (BYTE*)(topic.map + topic.wMapLen);
- topic.end = newptr + newsize;
+ topic.end = newptr + topic_size;
for (i = 0; i < topic.wMapLen; i++)
{
- topic.map[i] = newptr + i * DST_LEN;
- memcpy(topic.map[i], buf + i * 0x1000 + 0x0C, DST_LEN);
+ topic.map[i] = newptr + i * hlpfile->dsize;
+ memcpy(topic.map[i], buf + i * hlpfile->tbsize + 0x0C, hlpfile->dsize);
}
-#undef DST_LEN
- break;
}
return TRUE;
}
diff --git a/programs/winhelp/hlpfile.h b/programs/winhelp/hlpfile.h
index 4d62cdd..3c6b6b9 100644
--- a/programs/winhelp/hlpfile.h
+++ b/programs/winhelp/hlpfile.h
@@ -141,6 +141,9 @@ typedef struct tagHlpFileFile
unsigned short version;
unsigned short flags;
+ unsigned short tbsize; /* topic block size */
+ unsigned short dsize; /* decompress size */
+ unsigned short compressed;
unsigned hasPhrases; /* Phrases or PhrIndex/PhrImage */
unsigned numBmps;
More information about the wine-cvs
mailing list