Commit 84f0968a authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

winhelp: Instead of loading all pages at once, allow to browse them one by one.

parent 7eba95de
...@@ -72,8 +72,8 @@ static BOOL HLPFILE_Uncompress_Topic(HLPFILE*); ...@@ -72,8 +72,8 @@ static BOOL HLPFILE_Uncompress_Topic(HLPFILE*);
static BOOL HLPFILE_GetContext(HLPFILE*); static BOOL HLPFILE_GetContext(HLPFILE*);
static BOOL HLPFILE_GetKeywords(HLPFILE*); static BOOL HLPFILE_GetKeywords(HLPFILE*);
static BOOL HLPFILE_GetMap(HLPFILE*); static BOOL HLPFILE_GetMap(HLPFILE*);
static BOOL HLPFILE_AddPage(HLPFILE*, BYTE*, BYTE*, unsigned); static BOOL HLPFILE_AddPage(HLPFILE*, BYTE*, BYTE*, unsigned, unsigned);
static BOOL HLPFILE_AddParagraph(HLPFILE*, BYTE *, BYTE*, unsigned*); static BOOL HLPFILE_SkipParagraph(HLPFILE*, BYTE *, BYTE*, unsigned*);
static void HLPFILE_Uncompress2(HLPFILE*, const BYTE*, const BYTE*, BYTE*, const BYTE*); static void HLPFILE_Uncompress2(HLPFILE*, const BYTE*, const BYTE*, BYTE*, const BYTE*);
static BOOL HLPFILE_Uncompress3(HLPFILE*, char*, const char*, const BYTE*, const BYTE*); static BOOL HLPFILE_Uncompress3(HLPFILE*, char*, const char*, const BYTE*, const BYTE*);
static void HLPFILE_UncompressRLE(const BYTE* src, const BYTE* end, BYTE** dst, unsigned dstsz); static void HLPFILE_UncompressRLE(const BYTE* src, const BYTE* end, BYTE** dst, unsigned dstsz);
...@@ -343,13 +343,13 @@ static BOOL HLPFILE_DoReadHlpFile(HLPFILE *hlpfile, LPCSTR lpszPath) ...@@ -343,13 +343,13 @@ static BOOL HLPFILE_DoReadHlpFile(HLPFILE *hlpfile, LPCSTR lpszPath)
switch (buf[0x14]) switch (buf[0x14])
{ {
case 0x02: case 0x02:
if (!HLPFILE_AddPage(hlpfile, buf, end, index * 0x8000L + offs)) return FALSE; if (!HLPFILE_AddPage(hlpfile, buf, end, ref, index * 0x8000L + offs)) return FALSE;
break; break;
case 0x01: case 0x01:
case 0x20: case 0x20:
case 0x23: case 0x23:
if (!HLPFILE_AddParagraph(hlpfile, buf, end, &len)) return FALSE; if (!HLPFILE_SkipParagraph(hlpfile, buf, end, &len)) return FALSE;
offs += len; offs += len;
break; break;
...@@ -377,7 +377,7 @@ static BOOL HLPFILE_DoReadHlpFile(HLPFILE *hlpfile, LPCSTR lpszPath) ...@@ -377,7 +377,7 @@ static BOOL HLPFILE_DoReadHlpFile(HLPFILE *hlpfile, LPCSTR lpszPath)
* *
* HLPFILE_AddPage * HLPFILE_AddPage
*/ */
static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned offset) static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned ref, unsigned offset)
{ {
HLPFILE_PAGE* page; HLPFILE_PAGE* page;
BYTE* title; BYTE* title;
...@@ -433,6 +433,7 @@ static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned off ...@@ -433,6 +433,7 @@ static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned off
page->first_macro = NULL; page->first_macro = NULL;
page->wNumber = GET_UINT(buf, 0x21); page->wNumber = GET_UINT(buf, 0x21);
page->offset = offset; page->offset = offset;
page->reference = ref;
page->browse_bwd = GET_UINT(buf, 0x19); page->browse_bwd = GET_UINT(buf, 0x19);
page->browse_fwd = GET_UINT(buf, 0x1D); page->browse_fwd = GET_UINT(buf, 0x1D);
...@@ -534,6 +535,28 @@ static unsigned short fetch_ushort(BYTE** ptr) ...@@ -534,6 +535,28 @@ static unsigned short fetch_ushort(BYTE** ptr)
return ret; return ret;
} }
/***********************************************************************
*
* HLPFILE_SkipParagraph
*/
static BOOL HLPFILE_SkipParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned* len)
{
BYTE *tmp;
if (!hlpfile->first_page) {WINE_WARN("no page\n"); return FALSE;};
if (buf + 0x19 > end) {WINE_WARN("header too small\n"); return FALSE;};
tmp = buf + 0x15;
if (buf[0x14] == 0x20 || buf[0x14] == 0x23)
{
fetch_long(&tmp);
*len = fetch_ushort(&tmp);
}
else *len = end-buf-15;
return TRUE;
}
/****************************************************************** /******************************************************************
* HLPFILE_DecompressGfx * HLPFILE_DecompressGfx
* *
...@@ -848,11 +871,10 @@ static HLPFILE_LINK* HLPFILE_AllocLink(int cookie, const char* str, LONG h ...@@ -848,11 +871,10 @@ static HLPFILE_LINK* HLPFILE_AllocLink(int cookie, const char* str, LONG h
/*********************************************************************** /***********************************************************************
* *
* HLPFILE_AddParagraph * HLPFILE_BrowseParagraph
*/ */
static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned* len) static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* page, BYTE *buf, BYTE* end)
{ {
HLPFILE_PAGE *page;
HLPFILE_PARAGRAPH *paragraph, **paragraphptr; HLPFILE_PARAGRAPH *paragraph, **paragraphptr;
UINT textsize; UINT textsize;
BYTE *format, *format_end; BYTE *format, *format_end;
...@@ -861,8 +883,6 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne ...@@ -861,8 +883,6 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne
unsigned short bits; unsigned short bits;
unsigned nc, ncol = 1; unsigned nc, ncol = 1;
if (!hlpfile->last_page) {WINE_WARN("no page\n"); return FALSE;};
page = hlpfile->last_page;
for (paragraphptr = &page->first_paragraph; *paragraphptr; for (paragraphptr = &page->first_paragraph; *paragraphptr;
paragraphptr = &(*paragraphptr)->next) /* Nothing */; paragraphptr = &(*paragraphptr)->next) /* Nothing */;
...@@ -876,10 +896,10 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne ...@@ -876,10 +896,10 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne
if (size > blocksize - datalen) if (size > blocksize - datalen)
{ {
/* need to decompress */ /* need to decompress */
if (hlpfile->hasPhrases) if (page->file->hasPhrases)
HLPFILE_Uncompress2(hlpfile, buf + datalen, end, (BYTE*)text, (BYTE*)text + size); HLPFILE_Uncompress2(page->file, buf + datalen, end, (BYTE*)text, (BYTE*)text + size);
else if (hlpfile->hasPhrases40) else if (page->file->hasPhrases40)
HLPFILE_Uncompress3(hlpfile, text, text + size, buf + datalen, end); HLPFILE_Uncompress3(page->file, text, text + size, buf + datalen, end);
else else
{ {
WINE_FIXME("Text size is too long, splitting\n"); WINE_FIXME("Text size is too long, splitting\n");
...@@ -898,9 +918,8 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne ...@@ -898,9 +918,8 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne
if (buf[0x14] == 0x20 || buf[0x14] == 0x23) if (buf[0x14] == 0x20 || buf[0x14] == 0x23)
{ {
fetch_long(&format); fetch_long(&format);
*len = fetch_ushort(&format); fetch_ushort(&format);
} }
else *len = end-buf-15;
if (buf[0x14] == 0x23) if (buf[0x14] == 0x23)
{ {
...@@ -1055,14 +1074,14 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne ...@@ -1055,14 +1074,14 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne
switch (GET_SHORT(format, 0)) switch (GET_SHORT(format, 0))
{ {
case 0: case 0:
HLPFILE_LoadGfxByIndex(hlpfile, GET_SHORT(format, 2), HLPFILE_LoadGfxByIndex(page->file, GET_SHORT(format, 2),
paragraph); paragraph);
break; break;
case 1: case 1:
WINE_FIXME("does it work ??? %x<%lu>#%u\n", WINE_FIXME("does it work ??? %x<%lu>#%u\n",
GET_SHORT(format, 0), GET_SHORT(format, 0),
size, GET_SHORT(format, 2)); size, GET_SHORT(format, 2));
HLPFILE_LoadGfxByAddr(hlpfile, format + 2, size - 4, HLPFILE_LoadGfxByAddr(page->file, format + 2, size - 4,
paragraph); paragraph);
break; break;
default: default:
...@@ -1115,7 +1134,7 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne ...@@ -1115,7 +1134,7 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne
WINE_WARN("jump topic 1 => %u\n", GET_UINT(format, 1)); WINE_WARN("jump topic 1 => %u\n", GET_UINT(format, 1));
HLPFILE_FreeLink(attributes.link); HLPFILE_FreeLink(attributes.link);
attributes.link = HLPFILE_AllocLink((*format & 1) ? hlp_link_link : hlp_link_popup, attributes.link = HLPFILE_AllocLink((*format & 1) ? hlp_link_link : hlp_link_popup,
hlpfile->lpszPath, page->file->lpszPath,
GET_UINT(format, 1)-16, GET_UINT(format, 1)-16,
1, -1); 1, -1);
...@@ -1129,7 +1148,7 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne ...@@ -1129,7 +1148,7 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne
case 0xE7: case 0xE7:
HLPFILE_FreeLink(attributes.link); HLPFILE_FreeLink(attributes.link);
attributes.link = HLPFILE_AllocLink((*format & 1) ? hlp_link_link : hlp_link_popup, attributes.link = HLPFILE_AllocLink((*format & 1) ? hlp_link_link : hlp_link_popup,
hlpfile->lpszPath, page->file->lpszPath,
GET_UINT(format, 1), GET_UINT(format, 1),
!(*format & 4), -1); !(*format & 4), -1);
format += 5; format += 5;
...@@ -1150,12 +1169,12 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne ...@@ -1150,12 +1169,12 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne
wnd = *ptr; wnd = *ptr;
/* fall through */ /* fall through */
case 0: case 0:
ptr = hlpfile->lpszPath; ptr = page->file->lpszPath;
break; break;
case 6: case 6:
for (wnd = hlpfile->numWindows - 1; wnd >= 0; wnd--) for (wnd = page->file->numWindows - 1; wnd >= 0; wnd--)
{ {
if (!strcmp(ptr, hlpfile->windows[wnd].name)) break; if (!strcmp(ptr, page->file->windows[wnd].name)) break;
} }
if (wnd == -1) if (wnd == -1)
WINE_WARN("Couldn't find window info for %s\n", ptr); WINE_WARN("Couldn't find window info for %s\n", ptr);
...@@ -1186,6 +1205,69 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne ...@@ -1186,6 +1205,69 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne
} }
/****************************************************************** /******************************************************************
* HLPFILE_BrowsePage
*
*/
BOOL HLPFILE_BrowsePage(HLPFILE_PAGE* page)
{
HLPFILE *hlpfile = page->file;
BYTE *buf, *end;
DWORD ref = page->reference;
unsigned index, old_index = -1, offset, count = 0;
do
{
if (hlpfile->version <= 16)
{
index = (ref - 0x0C) / hlpfile->dsize;
offset = (ref - 0x0C) % hlpfile->dsize;
}
else
{
index = (ref - 0x0C) >> 14;
offset = (ref - 0x0C) & 0x3FFF;
}
if (hlpfile->version <= 16 && index != old_index && index != 0)
{
/* we jumped to the next block, adjust pointers */
ref -= 12;
offset -= 12;
}
if (index >= hlpfile->topic_maplen) {WINE_WARN("maplen\n"); break;}
buf = hlpfile->topic_map[index] + offset;
if (buf + 0x15 >= hlpfile->topic_end) {WINE_WARN("extra\n"); break;}
end = min(buf + GET_UINT(buf, 0), hlpfile->topic_end);
if (index != old_index) {old_index = index;}
switch (buf[0x14])
{
case 0x02:
if (count++) goto done;
break;
case 0x01:
case 0x20:
case 0x23:
if (!HLPFILE_BrowseParagraph(page, buf, end)) return FALSE;
break;
default:
WINE_ERR("buf[0x14] = %x\n", buf[0x14]);
}
if (hlpfile->version <= 16)
{
ref += GET_UINT(buf, 0xc);
if (GET_UINT(buf, 0xc) == 0)
break;
}
else
ref = GET_UINT(buf, 0xc);
} while (ref != 0xffffffff);
done:
return TRUE;
}
/******************************************************************
* HLPFILE_ReadFont * HLPFILE_ReadFont
* *
* *
......
...@@ -94,6 +94,7 @@ typedef struct tagHlpFilePage ...@@ -94,6 +94,7 @@ typedef struct tagHlpFilePage
unsigned wNumber; unsigned wNumber;
unsigned offset; unsigned offset;
DWORD reference;
struct tagHlpFilePage* next; struct tagHlpFilePage* next;
struct tagHlpFilePage* prev; struct tagHlpFilePage* prev;
...@@ -196,3 +197,5 @@ void HLPFILE_FreeHlpFile(HLPFILE*); ...@@ -196,3 +197,5 @@ void HLPFILE_FreeHlpFile(HLPFILE*);
void* HLPFILE_BPTreeSearch(BYTE*, const void*, HLPFILE_BPTreeCompare); void* HLPFILE_BPTreeSearch(BYTE*, const void*, HLPFILE_BPTreeCompare);
void HLPFILE_BPTreeEnum(BYTE*, HLPFILE_BPTreeCallback cb, void *cookie); void HLPFILE_BPTreeEnum(BYTE*, HLPFILE_BPTreeCallback cb, void *cookie);
BOOL HLPFILE_BrowsePage(HLPFILE_PAGE*);
...@@ -584,6 +584,8 @@ BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, HLPFILE_WINDOWINFO* wi, ...@@ -584,6 +584,8 @@ BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, HLPFILE_WINDOWINFO* wi,
bPrimary = !lstrcmpi(wi->name, "main"); bPrimary = !lstrcmpi(wi->name, "main");
bPopup = !bPrimary && (wi->win_style & WS_POPUP); bPopup = !bPrimary && (wi->win_style & WS_POPUP);
if (page && !page->first_paragraph) HLPFILE_BrowsePage(page);
/* Initialize WINHELP_WINDOW struct */ /* Initialize WINHELP_WINDOW struct */
win = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, win = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(WINHELP_WINDOW) + strlen(wi->name) + 1); sizeof(WINHELP_WINDOW) + strlen(wi->name) + 1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment