Sweden-Number/programs/winhelp/hlpfile.c

990 lines
23 KiB
C
Raw Normal View History

Release 960506 Mon May 6 12:56:26 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [DEVELOPERS-HINTS] Added paragraph on naming conventions for Win16/Win32/Winelib. * [controls/menu.c] Create a default system menu that is the same for all windows instead of making a copy every time. * [include/wintypes.h] Added WINELIB_NAME and DECL_WINELIB_TYPE macros. Added xx16 and xx32 definitions for most types. General clean-up. * [memory/global.c] [memory/local.c] [*/*] Renamed Global and Local heap functions to xxx16. Added all xxx32 versions of the same functions. * [memory/selector.c] Mask out lower bits of selector in FreeSelector(). * [misc/lstr.c] Fixed wvsprintf(). * [windows/class.c] Changed the class structure to make Win32 support easier. * [windows/defwnd.c] Added handling of WM_INITMENUPOPUP for system menu to gray out invalid options. * [windows/winpos.c] Bug fix: the WINDOSPOS structure pointer in WM_NCCALCSIZE must be a SEGPTR. Sun May 5 03:51:26 1996 Huw D. M. Davies <h.davies1@physics.oxford.ac.uk> * [memory/local.c] Implementation of moveable and (rudimentary) support for discardable local memory, plus several bug fixes. Sat May 4 18:33:35 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de> * [include/windows.h] [windows/win.c] [if1632/user.spec] FindWindowEx() implemented (someone reported it was missing for FrameMaker 4.1). * [if1632/kernel32.spec] [if1632/user32.spec] [win32/memory.c] [win32/resource.c] Misc small stubs/small functions which bring win95 binaries further down the road. (IsBadCodePtr, LocalReAlloc,GetCursorPos) Small fix in WIN32_LoadAcceleratorsA. Fri May 3 19:43:12 1996 Frans van Dorsselaer <dorssel@rulhm1.LeidenUniv.nl> * [controls/edit.c] [controls/EDIT.TODO] Changed / fixed some types and typecasts. Fixed the scrollbar reset after WM_SETHANDLE / WM_SETTEXT. Added heap initialization in WM_CREATE. Fri May 3 19:30:02 1996 Greg Kreider <kreider@natlab.research.philips.com> * [controls/combo.c] [controls/listbox.c] Pass WM_[HV]SCROLL to listbox, but not combo. Don't try to redraw non-existant scroll bars (changes dwStyle flags). Combo box gets border. Combo box includes button (otherwise button won't trigger dropdown). Proper border around RectButton. Check size consistancy of combo, listbox, and button after resizing or before painting. These routines still aren't completely correct. Localize size checks in separate routines. Listboxes are white. Thu May 2 19:21:23 1996 Albrecht Kleine <kleine@ak.sax.de> * [controls/combo.c][include/commdlg.h][include/commdlg.c] [resources/sysres_De.rc][resources/sysres_En.rc] Introduced ChooseFont dialog, but needed some patches in handling of comboboxes with edit controls. Tue Apr 30 00:33:27 1996 Ulrich Schmid <uschmid@mail.hh.provi.de> * [programs/winhelp/*] Added a help viewer and a simple `.hlp' to `.sgml' converter. Mon Apr 29 14:17:57 1996 Tristan Tarrant <tst@sthinc.demon.co.uk> * [resources/sysres_*.rc] [misc/shell.c] Modified size of "About" dialog boxes. Sat Apr 27 18:10:11 Martin von Loewis <loewis@informatik.hu-berlin.de> * [if1632/Makefile.in][loader/builtin.c] crtdll.spec, ntdll.spec, wsock32.spec: new files. * [loader/pe_image.c] Fix error message if import by ordinal failed.
1996-05-06 18:06:24 +02:00
/*
* Help Viewer
*
* Copyright 1996 Ulrich Schmid
*/
#include <stdio.h>
#include <windows.h>
#include "winhelp.h"
static void Report(LPCSTR str)
{
#if 0
fprintf(stderr, "%s\n", str);
#endif
}
#define GET_USHORT(buffer, i)\
(((BYTE)((buffer)[(i)]) + 0x100 * (BYTE)((buffer)[(i)+1])))
#define GET_SHORT(buffer, i)\
(((BYTE)((buffer)[(i)]) + 0x100 * (signed char)((buffer)[(i)+1])))
#define GET_UINT(buffer, i)\
GET_USHORT(buffer, i) + 0x10000 * GET_USHORT(buffer, i+2)
static BOOL HLPFILE_DoReadHlpFile(HLPFILE*, LPCSTR);
static BOOL HLPFILE_ReadFileToBuffer(HFILE);
static BOOL HLPFILE_FindSubFile(LPCSTR name, BYTE**, BYTE**);
static VOID HLPFILE_SystemCommands(HLPFILE*);
static BOOL HLPFILE_Uncompress1_Phrases();
static BOOL HLPFILE_Uncompress1_Topic();
static BOOL HLPFILE_GetContext(HLPFILE*);
static BOOL HLPFILE_AddPage(HLPFILE*, BYTE*, BYTE*);
static BOOL HLPFILE_AddParagraph(HLPFILE*, BYTE *, BYTE*);
static UINT HLPFILE_Uncompressed2_Size(BYTE*, BYTE*);
static VOID HLPFILE_Uncompress2(BYTE**, BYTE*, BYTE*);
static HLPFILE *first_hlpfile = 0;
static HGLOBAL hFileBuffer;
static BYTE *file_buffer;
static struct
{
UINT num;
BYTE *buf;
HGLOBAL hBuffer;
} phrases;
static struct
{
BYTE **map;
BYTE *end;
UINT wMapLen;
HGLOBAL hMap;
HGLOBAL hBuffer;
} topic;
static struct
{
UINT bDebug;
UINT wFont;
UINT wIndent;
UINT wHSpace;
UINT wVSpace;
UINT wVBackSpace;
HLPFILE_LINK link;
} attributes;
/***********************************************************************
*
* HLPFILE_Contents
*/
HLPFILE_PAGE *HLPFILE_Contents(LPCSTR lpszPath)
{
HLPFILE *hlpfile = HLPFILE_ReadHlpFile(lpszPath);
if (!hlpfile) return(0);
return(hlpfile->first_page);
}
/***********************************************************************
*
* HLPFILE_PageByNumber
*/
HLPFILE_PAGE *HLPFILE_PageByNumber(LPCSTR lpszPath, UINT wNum)
{
HLPFILE_PAGE *page;
HLPFILE *hlpfile = HLPFILE_ReadHlpFile(lpszPath);
if (!hlpfile) return(0);
for (page = hlpfile->first_page; page && wNum; page = page->next) wNum--;
return page;
}
/***********************************************************************
*
* HLPFILE_HlpFilePageByHash
*/
HLPFILE_PAGE *HLPFILE_PageByHash(LPCSTR lpszPath, LONG lHash)
{
INT i;
UINT wNum;
HLPFILE_PAGE *page;
HLPFILE *hlpfile = HLPFILE_ReadHlpFile(lpszPath);
if (!hlpfile) return(0);
for (i = 0; i < hlpfile->wContextLen; i++)
if (hlpfile->Context[i].lHash == lHash) break;
if (i >= hlpfile->wContextLen)
{
HLPFILE_FreeHlpFile(hlpfile);
return(0);
}
wNum = hlpfile->Context[i].wPage;
for (page = hlpfile->first_page; page && wNum; page = page->next) wNum--;
return page;
}
/***********************************************************************
*
* HLPFILE_Hash
*/
LONG HLPFILE_Hash(LPCSTR lpszContext)
{
LONG lHash = 0;
CHAR c;
while((c = *lpszContext++))
{
CHAR x = 0;
if (c >= 'A' && c <= 'Z') x = c - 'A' + 17;
if (c >= 'a' && c <= 'z') x = c - 'a' + 17;
if (c >= '1' && c <= '9') x = c - '0';
if (c == '0') x = 10;
if (c == '.') x = 12;
if (c == '_') x = 13;
if (x) lHash = lHash * 43 + x;
}
return lHash;
}
/***********************************************************************
*
* HLPFILE_ReadHlpFile
*/
HLPFILE *HLPFILE_ReadHlpFile(LPCSTR lpszPath)
{
HGLOBAL hHlpFile;
HLPFILE *hlpfile;
for (hlpfile = first_hlpfile; hlpfile; hlpfile = hlpfile->next)
if (!lstrcmp(hlpfile->lpszPath, lpszPath))
{
hlpfile->wRefCount++;
return(hlpfile);
}
hHlpFile = GlobalAlloc(GMEM_FIXED, sizeof(HLPFILE) + lstrlen(lpszPath) + 1);
if (!hHlpFile) return(0);
hlpfile = GlobalLock(hHlpFile);
hlpfile->hSelf = hHlpFile;
hlpfile->wRefCount = 1;
hlpfile->hTitle = 0;
hlpfile->hContext = 0;
hlpfile->wContextLen = 0;
hlpfile->first_page = 0;
hlpfile->first_macro = 0;
hlpfile->prev = 0;
hlpfile->next = first_hlpfile;
first_hlpfile = hlpfile;
if (hlpfile->next) hlpfile->next->prev = hlpfile;
hlpfile->lpszPath = GlobalLock(hHlpFile);
hlpfile->lpszPath += sizeof(HLPFILE);
lstrcpy(hlpfile->lpszPath, (SEGPTR) lpszPath);
phrases.hBuffer = topic.hBuffer = hFileBuffer = 0;
if (!HLPFILE_DoReadHlpFile(hlpfile, lpszPath))
{
HLPFILE_FreeHlpFile(hlpfile);
hlpfile = 0;
}
if (phrases.hBuffer) GlobalFree(phrases.hBuffer);
if (topic.hBuffer) GlobalFree(topic.hBuffer);
if (topic.hMap) GlobalFree(topic.hMap);
if (hFileBuffer) GlobalFree(hFileBuffer);
return(hlpfile);
}
/***********************************************************************
*
* HLPFILE_DoReadHlpFile
*/
static BOOL HLPFILE_DoReadHlpFile(HLPFILE *hlpfile, LPCSTR lpszPath)
{
BOOL ret;
HFILE hFile;
OFSTRUCT ofs;
BYTE *buf;
hFile=OpenFile(lpszPath, &ofs, OF_READ | OF_SEARCH);
if (hFile == HFILE_ERROR) return FALSE;
ret = HLPFILE_ReadFileToBuffer(hFile);
_lclose(hFile);
if (!ret) return FALSE;
HLPFILE_SystemCommands(hlpfile);
if (!HLPFILE_Uncompress1_Phrases()) return FALSE;
if (!HLPFILE_Uncompress1_Topic()) return FALSE;
buf = topic.map[0] + 0xc;
while(buf + 0xc < topic.end)
{
BYTE *end = MIN(buf + GET_UINT(buf, 0), topic.end);
UINT next, index, offset;
switch (buf[0x14])
{
case 0x02:
if (!HLPFILE_AddPage(hlpfile, buf, end)) return(FALSE);
break;
case 0x20:
if (!HLPFILE_AddParagraph(hlpfile, buf, end)) return(FALSE);
break;
case 0x23:
if (!HLPFILE_AddParagraph(hlpfile, buf, end)) return(FALSE);
break;
default:
fprintf(stderr, "buf[0x14] = %x\n", buf[0x14]);
}
next = GET_UINT(buf, 0xc);
if (next == 0xffffffff) break;
index = next >> 14;
offset = next & 0x3fff;
if (index > topic.wMapLen) {Report("maplen"); break;}
buf = topic.map[index] + offset;
}
return(HLPFILE_GetContext(hlpfile));
}
/***********************************************************************
*
* HLPFILE_AddPage
*/
static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end)
{
HGLOBAL hPage;
HLPFILE_PAGE *page, **pageptr;
BYTE *title;
UINT titlesize;
for (pageptr = &hlpfile->first_page; *pageptr; pageptr = &(*pageptr)->next)
/* Nothing */;
if (buf + 0x31 > end) {Report("page1"); return(FALSE);};
title = buf + GET_UINT(buf, 0x10);
if (title > end) {Report("page2"); return(FALSE);};
titlesize = HLPFILE_Uncompressed2_Size(title, end);
hPage = GlobalAlloc(GMEM_FIXED, sizeof(HLPFILE_PAGE) + titlesize);
if (!hPage) return FALSE;
page = *pageptr = GlobalLock(hPage);
pageptr = &page->next;
page->hSelf = hPage;
page->file = hlpfile;
page->next = 0;
page->first_paragraph = 0;
page->lpszTitle = GlobalLock(hPage);
page->lpszTitle += sizeof(HLPFILE_PAGE);
HLPFILE_Uncompress2(&title, end, page->lpszTitle);
page->wNumber = GET_UINT(buf, 0x21);
attributes.bDebug = 0;
attributes.wFont = 0;
attributes.wVSpace = 0;
attributes.wVBackSpace = 0;
attributes.wHSpace = 0;
attributes.wIndent = 0;
attributes.link.lpszPath = 0;
return TRUE;
}
/***********************************************************************
*
* HLPFILE_AddParagraph
*/
static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end)
{
HGLOBAL hParagraph;
HLPFILE_PAGE *page;
HLPFILE_PARAGRAPH *paragraph, **paragraphptr;
UINT textsize;
BYTE *format, *text;
BOOL format_header = TRUE;
BOOL format_end = FALSE;
UINT mask, i;
if (!hlpfile->first_page) {Report("paragraph1"); return(FALSE);};
for (page = hlpfile->first_page; page->next; page = page->next) /* Nothing */;
for (paragraphptr = &page->first_paragraph; *paragraphptr;
paragraphptr = &(*paragraphptr)->next) /* Nothing */;
if (buf + 0x19 > end) {Report("paragraph2"); return(FALSE);};
if (buf[0x14] == 0x02) return TRUE;
text = buf + GET_UINT(buf, 0x10);
switch (buf[0x14])
{
case 0x20:
format = buf + 0x18;
while (*format) format++;
format += 4;
break;
case 0x23:
format = buf + 0x2b;
if (buf[0x17] & 1) format++;
break;
default:
Report("paragraph3");
return FALSE;
}
while (text < end)
{
if (format_header)
{
format_header = FALSE;
mask = GET_USHORT(format, 0);
mask &= 0x3ff;
format += 2;
for (i = 0; i < 10; i++, mask = mask >> 1)
{
if (mask & 1)
{
BOOL twoargs = FALSE;
CHAR prefix0 = ' ';
CHAR prefix1 = '*';
if (i == 9 && !twoargs)
{
switch (*format++)
{
default:
prefix0 = prefix1 = '?';
break;
case 0x82:
prefix0 = prefix1 = 'x';
break;
case 0x84:
prefix0 = prefix1 = 'X';
twoargs = TRUE;
}
}
if (*format & 1)
switch(*format)
{
default:
format += 2;
break;
}
else
switch(*format)
{
default:
format++;
break;
case 0x08:
format += 3;
break;
}
if (twoargs) format += (*format & 1) ? 2 : 1;
}
}
}
for (; !format_header && text < end && format < end && !*text; text++)
{
switch(*format)
{
case 0x80:
attributes.wFont = GET_USHORT(format, 1);
format += 3;
break;
case 0x81:
attributes.wVSpace++;
format += 1;
break;
case 0x82:
attributes.wVSpace += 2 - attributes.wVBackSpace;
attributes.wVBackSpace = 0;
attributes.wIndent = 0;
format += 1;
break;
case 0x83:
attributes.wIndent++;
format += 1;
break;
case 0x84:
format += 3;
break;
case 0x86:
case 0x87:
case 0x88:
format += 9;
break;
case 0x89:
attributes.wVBackSpace++;
format += 1;
break;
case 0xa9:
format += 2;
break;
case 0xe2:
case 0xe3:
attributes.link.lpszPath = hlpfile->lpszPath;
attributes.link.lHash = GET_UINT(format, 1);
attributes.link.bPopup = !(*format & 1);
format += 5;
break;
case 0xea:
attributes.link.lpszPath = format + 8;
attributes.link.lHash = GET_UINT(format, 4);
attributes.link.bPopup = !(*format & 1);
format += 3 + GET_USHORT(format, 1);
break;
case 0xff:
if (buf[0x14] != 0x23 || GET_USHORT(format, 1) == 0xffff)
{
if (format_end) Report("format_end");
format_end = TRUE;
break;
}
else
{
format_header = TRUE;
format += 10;
break;
}
default:
Report("format");
format++;
}
}
if (text > end || format > end) {Report("paragraph_end"); return(FALSE);};
if (text == end && !format_end) Report("text_end");
if (text == end) break;
textsize = HLPFILE_Uncompressed2_Size(text, end);
hParagraph = GlobalAlloc(GMEM_FIXED, sizeof(HLPFILE_PARAGRAPH) + textsize);
if (!hParagraph) return FALSE;
paragraph = *paragraphptr = GlobalLock(hParagraph);
paragraphptr = &paragraph->next;
paragraph->hSelf = hParagraph;
paragraph->next = 0;
paragraph->link = 0;
paragraph->lpszText = GlobalLock(hParagraph);
paragraph->lpszText += sizeof(HLPFILE_PARAGRAPH);
HLPFILE_Uncompress2(&text, end, paragraph->lpszText);
paragraph->bDebug = attributes.bDebug;
paragraph->wFont = attributes.wFont;
paragraph->wVSpace = attributes.wVSpace;
paragraph->wHSpace = attributes.wHSpace;
paragraph->wIndent = attributes.wIndent;
if (attributes.link.lpszPath)
{
LPSTR ptr;
HGLOBAL handle = GlobalAlloc(GMEM_FIXED, sizeof(HLPFILE_LINK) +
strlen(attributes.link.lpszPath) + 1);
if (!handle) return FALSE;
paragraph->link = GlobalLock(handle);
paragraph->link->hSelf = handle;
ptr = GlobalLock(handle);
ptr += sizeof(HLPFILE_LINK);
lstrcpy(ptr, (LPSTR) attributes.link.lpszPath);
paragraph->link->lpszPath = ptr;
paragraph->link->lHash = attributes.link.lHash;
paragraph->link->bPopup = attributes.link.bPopup;
}
attributes.bDebug = 0;
attributes.wVSpace = 0;
attributes.wHSpace = 0;
attributes.link.lpszPath = 0;
}
return TRUE;
}
/***********************************************************************
*
* HLPFILE_ReadFileToBuffer
*/
static BOOL HLPFILE_ReadFileToBuffer(HFILE hFile)
{
BYTE header[16], dummy[1];
UINT size;
if (_hread(hFile, header, 16) != 16) {Report("header"); return(FALSE);};
size = GET_UINT(header, 12);
hFileBuffer = GlobalAlloc(GMEM_FIXED, size + 1);
if (!hFileBuffer) return FALSE;
file_buffer = GlobalLock(hFileBuffer);
memcpy(file_buffer, header, 16);
if (_hread(hFile, file_buffer + 16, size - 16) != size - 16)
{Report("filesize1"); return(FALSE);};
if (_hread(hFile, dummy, 1) != 0) Report("filesize2");
file_buffer[size] = '0';
return TRUE;
}
/***********************************************************************
*
* HLPFILE_FindSubFile
*/
static BOOL HLPFILE_FindSubFile(LPCSTR name, BYTE **subbuf, BYTE **subend)
{
BYTE *root = file_buffer + GET_UINT(file_buffer, 4);
BYTE *end = file_buffer + GET_UINT(file_buffer, 12);
BYTE *ptr = root + 0x37;
while (ptr < end && ptr[0] == 0x7c)
{
BYTE *fname = ptr + 1;
ptr += strlen(ptr) + 1;
if (!lstrcmpi(fname, name))
{
*subbuf = file_buffer + GET_UINT(ptr, 0);
*subend = *subbuf + GET_UINT(*subbuf, 0);
if (file_buffer > *subbuf || *subbuf > *subend || *subend >= end)
{
Report("subfile");
return FALSE;
}
return TRUE;
}
else ptr += 4;
}
return FALSE;
}
/***********************************************************************
*
* HLPFILE_SystemCommands
*/
static VOID HLPFILE_SystemCommands(HLPFILE* hlpfile)
{
BYTE *buf, *ptr, *end;
HGLOBAL handle;
HLPFILE_MACRO *macro, **m;
LPSTR p;
hlpfile->lpszTitle = "";
if (!HLPFILE_FindSubFile("SYSTEM", &buf, &end)) return;
for (ptr = buf + 0x15; ptr + 4 <= end; ptr += GET_USHORT(ptr, 2) + 4)
{
switch (GET_USHORT(ptr, 0))
{
case 1:
if (hlpfile->hTitle) {Report("title"); break;}
hlpfile->hTitle = GlobalAlloc(GMEM_FIXED, strlen(ptr + 4) + 1);
if (!hlpfile->hTitle) return;
hlpfile->lpszTitle = GlobalLock(hlpfile->hTitle);
lstrcpy(hlpfile->lpszTitle, ptr + 4);
break;
case 2:
if (GET_USHORT(ptr, 2) != 1 || ptr[4] != 0) Report("system2");
break;
case 3:
if (GET_USHORT(ptr, 2) != 4 || GET_UINT(ptr, 4) != 0) Report("system3");
break;
case 4:
handle = GlobalAlloc(GMEM_FIXED, sizeof(HLPFILE_MACRO) + lstrlen(ptr + 4) + 1);
if (!handle) break;
macro = GlobalLock(handle);
macro->hSelf = handle;
p = GlobalLock(handle);
p += sizeof(HLPFILE_MACRO);
lstrcpy(p, (LPSTR) ptr + 4);
macro->lpszMacro = p;
macro->next = 0;
for (m = &hlpfile->first_macro; *m; m = &(*m)->next);
*m = macro;
break;
default:
Report("system");
}
}
}
/***********************************************************************
*
* HLPFILE_Uncompressed1_Size
*/
static INT HLPFILE_Uncompressed1_Size(BYTE *ptr, BYTE *end)
{
INT i, newsize = 0;
while (ptr < end)
{
INT mask=*ptr++;
for (i = 0; i < 8 && ptr < end; i++, mask = mask >> 1)
{
if (mask & 1)
{
INT code = GET_USHORT(ptr, 0);
INT len = 3 + (code >> 12);
newsize += len;
ptr += 2;
}
else newsize++, ptr++;
}
}
return(newsize);
}
/***********************************************************************
*
* HLPFILE_Uncompress1
*/
static BYTE *HLPFILE_Uncompress1(BYTE *ptr, BYTE *end, BYTE *newptr)
{
INT i;
while (ptr < end)
{
INT mask=*ptr++;
for (i = 0; i < 8 && ptr < end; i++, mask = mask >> 1)
{
if (mask & 1)
{
INT code = GET_USHORT(ptr, 0);
INT len = 3 + (code >> 12);
INT offset = code & 0xfff;
hmemcpy(newptr, newptr - offset - 1, len);
newptr += len;
ptr += 2;
}
else *newptr++ = *ptr++;
}
}
return(newptr);
}
/***********************************************************************
*
* HLPFILE_Uncompress1_Phrases
*/
static BOOL HLPFILE_Uncompress1_Phrases()
{
UINT i, num, newsize;
BYTE *buf, *end, *newbuf;
if (!HLPFILE_FindSubFile("Phrases", &buf, &end)) {Report("phrases0"); return FALSE;}
num = phrases.num = GET_USHORT(buf, 9);
if (buf + 2 * num + 0x13 >= end) {Report("uncompress1a"); return(FALSE);};
newsize = 2 * num + 2;
newsize += HLPFILE_Uncompressed1_Size(buf + 0x13 + 2 * num, end);
phrases.hBuffer = GlobalAlloc(GMEM_FIXED, newsize);
if (!phrases.hBuffer) return FALSE;
newbuf = phrases.buf = GlobalLock(phrases.hBuffer);
hmemcpy(newbuf, buf + 0x11, 2 * num + 2);
HLPFILE_Uncompress1(buf + 0x13 + 2 * num, end, newbuf + 2 * num + 2);
for (i = 0; i < num; i++)
{
INT i0 = GET_USHORT(newbuf, 2 * i);
INT i1 = GET_USHORT(newbuf, 2 * i + 2);
if (i1 < i0 || i1 > newsize) {Report("uncompress1b"); return(FALSE);};
}
return TRUE;
}
/***********************************************************************
*
* HLPFILE_Uncompress1_Topic
*/
static BOOL HLPFILE_Uncompress1_Topic()
{
BYTE *buf, *ptr, *end, *newptr;
INT i, newsize = 0;
if (!HLPFILE_FindSubFile("TOPIC", &buf, &end)) {Report("topic0"); return FALSE;}
buf += 9;
topic.wMapLen = (end - buf - 1) / 0x1000 + 1;
for (i = 0; i < topic.wMapLen; i++)
{
ptr = buf + i * 0x1000;
/* I don't know why, it's necessary for printman.hlp */
if (ptr + 0x44 > end) ptr = end - 0x44;
newsize += HLPFILE_Uncompressed1_Size(ptr + 0xc, MIN(end, ptr + 0x1000));
}
topic.hMap = GlobalAlloc(GMEM_FIXED, topic.wMapLen * sizeof(topic.map[0]));
topic.hBuffer = GlobalAlloc(GMEM_FIXED, newsize);
if (!topic.hMap || !topic.hBuffer) return FALSE;
topic.map = GlobalLock(topic.hMap);
newptr = GlobalLock(topic.hBuffer);
topic.end = newptr + newsize;
for (i = 0; i < topic.wMapLen; i++)
{
ptr = buf + i * 0x1000;
if (ptr + 0x44 > end) ptr = end - 0x44;
topic.map[i] = newptr - 0xc;
newptr = HLPFILE_Uncompress1(ptr + 0xc, MIN(end, ptr + 0x1000), newptr);
}
return TRUE;
}
/***********************************************************************
*
* HLPFILE_Uncompressed2_Size
*/
static UINT HLPFILE_Uncompressed2_Size(BYTE *ptr, BYTE *end)
{
UINT wSize = 0;
while (ptr < end && *ptr)
{
if (*ptr >= 0x20)
wSize++, ptr++;
else
{
BYTE *phptr, *phend;
UINT code = 0x100 * ptr[0] + ptr[1];
UINT index = (code - 0x100) / 2;
BOOL space = code & 1;
if (index < phrases.num)
{
phptr = phrases.buf + GET_USHORT(phrases.buf, 2 * index);
phend = phrases.buf + GET_USHORT(phrases.buf, 2 * index + 2);
if (phend < phptr) Report("uncompress2a");
wSize += phend - phptr;
if (space) wSize++;
}
else Report("uncompress2b");
ptr += 2;
}
}
return(wSize + 1);
}
/***********************************************************************
*
* HLPFILE_Uncompress2
*/
static VOID HLPFILE_Uncompress2(BYTE **pptr, BYTE *end, BYTE *newptr)
{
BYTE *ptr = *pptr;
while (ptr < end && *ptr)
{
if (*ptr >= 0x20)
*newptr++ = *ptr++;
else
{
BYTE *phptr, *phend;
UINT code = 0x100 * ptr[0] + ptr[1];
UINT index = (code - 0x100) / 2;
BOOL space = code & 1;
phptr = phrases.buf + GET_USHORT(phrases.buf, 2 * index);
phend = phrases.buf + GET_USHORT(phrases.buf, 2 * index + 2);
hmemcpy(newptr, phptr, phend - phptr);
newptr += phend - phptr;
if (space) *newptr++ = ' ';
ptr += 2;
}
}
*newptr = '\0';
*pptr = ptr;
}
/***********************************************************************
*
* HLPFILE_GetContext
*/
static BOOL HLPFILE_GetContext(HLPFILE *hlpfile)
{
UINT i, j, clen, tlen;
BYTE *cbuf, *cptr, *cend, *tbuf, *tptr, *tend;
if (!HLPFILE_FindSubFile("CONTEXT", &cbuf, &cend)) {Report("context0"); return FALSE;}
if (cbuf + 0x37 > cend) {Report("context1"); return(FALSE);};
clen = GET_UINT(cbuf, 0x2b);
if (cbuf + 0x37 + 8 * hlpfile->wContextLen > cend) {Report("context2"); return(FALSE);};
if (!HLPFILE_FindSubFile("TTLBTREE", &tbuf, &tend)) {Report("ttlb0"); return FALSE;}
if (tbuf + 0x37 > tend) {Report("ttlb1"); return(FALSE);};
tlen = GET_UINT(tbuf, 0x2b);
hlpfile->hContext = GlobalAlloc(GMEM_FIXED, clen * sizeof(HLPFILE_CONTEXT));
if (!hlpfile->hContext) return FALSE;
hlpfile->Context = GlobalLock(hlpfile->hContext);
hlpfile->wContextLen = clen;
cptr = cbuf + 0x37;
for (i = 0; i < clen; i++, cptr += 8)
{
tptr = tbuf + 0x37;
for (j = 0; j < tlen; j++, tptr += 5 + strlen(tptr + 4))
{
if (tptr + 4 >= tend) {Report("ttlb2"); return(FALSE);};
if (GET_UINT(tptr, 0) == GET_UINT(cptr, 4)) break;
}
if (j >= tlen)
{
Report("ttlb3");
j = 0;
}
hlpfile->Context[i].lHash = GET_UINT(cptr, 0);
hlpfile->Context[i].wPage = j;
}
return TRUE;
}
/***********************************************************************
*
* HLPFILE_DeleteParagraph
*/
static VOID HLPFILE_DeleteParagraph(HLPFILE_PARAGRAPH* paragraph)
{
if (!paragraph) return;
if (paragraph->link) GlobalFree(paragraph->link->hSelf);
HLPFILE_DeleteParagraph(paragraph->next);
GlobalFree(paragraph->hSelf);
}
/***********************************************************************
*
* DeletePage
*/
static VOID HLPFILE_DeletePage(HLPFILE_PAGE* page)
{
if (!page) return;
HLPFILE_DeletePage(page->next);
HLPFILE_DeleteParagraph(page->first_paragraph);
GlobalFree(page->hSelf);
}
/***********************************************************************
*
* DeleteMacro
*/
static VOID HLPFILE_DeleteMacro(HLPFILE_MACRO* macro)
{
if (!macro) return;
HLPFILE_DeleteMacro(macro->next);
GlobalFree(macro->hSelf);
}
/***********************************************************************
*
* HLPFILE_FreeHlpFile
*/
VOID HLPFILE_FreeHlpFile(HLPFILE* hlpfile)
{
if (!hlpfile) return;
if (--hlpfile->wRefCount) return;
if (hlpfile->next) hlpfile->next->prev = hlpfile->prev;
if (hlpfile->prev) hlpfile->prev->next = hlpfile->next;
else first_hlpfile = 0;
HLPFILE_DeletePage(hlpfile->first_page);
HLPFILE_DeleteMacro(hlpfile->first_macro);
Release 960521 Tue May 21 14:06:07 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [controls/button.c] Made ButtonWndProc a 32-bit window procedure. * [controls/desktop.c] Made DesktopWndProc a 32-bit window procedure. Added handling of WM_SETCURSOR. * [controls/menu.c] Allocate menu items and strings on the 32-bit system heap. Implemented Win32 versions for ChangeMenu, InsertMenu, ModifyMenu, AppendMenu and LoadMenuIndirect. * [controls/widgets.c] Added possibility to have 32-bit built-in classes. * [files/drive.c] Implemented GetLogicalDrive() and GetLogicalDriveStrings(). * [misc/spy.c] [include/spy.h] Added support for spying Win32 messages. * [loader/builtin.c] Fixed bug in -dll option parsing. * [memory/local.c] Added back the change by Huw D. M. Davies to free the block in LocalRealloc() before allocating the new one. * [objects/bitmap.c] [objects/cursoricon.c] [objects/oembitmap.c] Fixed bug in bitmap size that caused memory corruption for 24bpp. * [windows/defwnd.c] Implemented Win32 version of DefWindowProc(). * [windows/dialog.c] Implemented Win32 version of SendDlgItemMessage, Get/SetDlgItemText and Get/SetDlgItemInt. * [windows/mdi.c] Implemented Win32 version of DefFrameProc() and DefMDIChildProc(). Don't make a copy of the OBM bitmaps for every MDI window. * [windows/message.c] Implemented Win32 version of SendMessage(). * [windows/winproc.c] [windows/class.c] [windows/win.c] New scheme for 32-bit window procedures to replace aliases. All 32-bit window procedure get a 16-bit address pointing to a WINDOWPROC structure. Implemented Ansi<->Unicode translation for CallWindowProc(). Added translation of WM_DRAWITEM between Win16 and Win32. * [windows/win.c] [include/callback.h] Added ugly hack to build CREATESTRUCT on the stack when sending WM_NCCREATE. Implemented Win32 version of Get/SetWindowWord/Long and Get/SetWindowText. Fri May 17 10:20:16 1996 Albrecht Kleine <kleine@ak.sax.de> * [controls/button.c] Avoid gray text on gray background in disabled push buttons using a b/w raster and some raster operations (PatBlt,BitBlt). * [objects/text.c] DrawText(): don't draw an underbar anymore if DT_CALCRECT is set.
1996-05-21 17:01:41 +02:00
if (hlpfile->hContext) GlobalFree(hlpfile->hContext);
if (hlpfile->hTitle) GlobalFree(hlpfile->hTitle);
Release 960506 Mon May 6 12:56:26 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [DEVELOPERS-HINTS] Added paragraph on naming conventions for Win16/Win32/Winelib. * [controls/menu.c] Create a default system menu that is the same for all windows instead of making a copy every time. * [include/wintypes.h] Added WINELIB_NAME and DECL_WINELIB_TYPE macros. Added xx16 and xx32 definitions for most types. General clean-up. * [memory/global.c] [memory/local.c] [*/*] Renamed Global and Local heap functions to xxx16. Added all xxx32 versions of the same functions. * [memory/selector.c] Mask out lower bits of selector in FreeSelector(). * [misc/lstr.c] Fixed wvsprintf(). * [windows/class.c] Changed the class structure to make Win32 support easier. * [windows/defwnd.c] Added handling of WM_INITMENUPOPUP for system menu to gray out invalid options. * [windows/winpos.c] Bug fix: the WINDOSPOS structure pointer in WM_NCCALCSIZE must be a SEGPTR. Sun May 5 03:51:26 1996 Huw D. M. Davies <h.davies1@physics.oxford.ac.uk> * [memory/local.c] Implementation of moveable and (rudimentary) support for discardable local memory, plus several bug fixes. Sat May 4 18:33:35 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de> * [include/windows.h] [windows/win.c] [if1632/user.spec] FindWindowEx() implemented (someone reported it was missing for FrameMaker 4.1). * [if1632/kernel32.spec] [if1632/user32.spec] [win32/memory.c] [win32/resource.c] Misc small stubs/small functions which bring win95 binaries further down the road. (IsBadCodePtr, LocalReAlloc,GetCursorPos) Small fix in WIN32_LoadAcceleratorsA. Fri May 3 19:43:12 1996 Frans van Dorsselaer <dorssel@rulhm1.LeidenUniv.nl> * [controls/edit.c] [controls/EDIT.TODO] Changed / fixed some types and typecasts. Fixed the scrollbar reset after WM_SETHANDLE / WM_SETTEXT. Added heap initialization in WM_CREATE. Fri May 3 19:30:02 1996 Greg Kreider <kreider@natlab.research.philips.com> * [controls/combo.c] [controls/listbox.c] Pass WM_[HV]SCROLL to listbox, but not combo. Don't try to redraw non-existant scroll bars (changes dwStyle flags). Combo box gets border. Combo box includes button (otherwise button won't trigger dropdown). Proper border around RectButton. Check size consistancy of combo, listbox, and button after resizing or before painting. These routines still aren't completely correct. Localize size checks in separate routines. Listboxes are white. Thu May 2 19:21:23 1996 Albrecht Kleine <kleine@ak.sax.de> * [controls/combo.c][include/commdlg.h][include/commdlg.c] [resources/sysres_De.rc][resources/sysres_En.rc] Introduced ChooseFont dialog, but needed some patches in handling of comboboxes with edit controls. Tue Apr 30 00:33:27 1996 Ulrich Schmid <uschmid@mail.hh.provi.de> * [programs/winhelp/*] Added a help viewer and a simple `.hlp' to `.sgml' converter. Mon Apr 29 14:17:57 1996 Tristan Tarrant <tst@sthinc.demon.co.uk> * [resources/sysres_*.rc] [misc/shell.c] Modified size of "About" dialog boxes. Sat Apr 27 18:10:11 Martin von Loewis <loewis@informatik.hu-berlin.de> * [if1632/Makefile.in][loader/builtin.c] crtdll.spec, ntdll.spec, wsock32.spec: new files. * [loader/pe_image.c] Fix error message if import by ordinal failed.
1996-05-06 18:06:24 +02:00
GlobalFree(hlpfile->hSelf);
}
/***********************************************************************
*
* FreeHlpFilePage
*/
VOID HLPFILE_FreeHlpFilePage(HLPFILE_PAGE* page)
{
if (!page) return;
HLPFILE_FreeHlpFile(page->file);
}
/* Local Variables: */
/* c-file-style: "GNU" */
/* End: */