diff --git a/programs/winhelp/hlpfile.c b/programs/winhelp/hlpfile.c index 2aafaf6644d..88cfabbf2dd 100644 --- a/programs/winhelp/hlpfile.c +++ b/programs/winhelp/hlpfile.c @@ -76,18 +76,6 @@ static struct HLPFILE_LINK* link; } attributes; -/* - * Compare function type for HLPFILE_BPTreeSearch function. - * - * PARAMS - * p [I] pointer to testing block (key + data) - * key [I] pointer to key value to look for - * leaf [I] whether this function called for index of leaf page - * next [O] pointer to pointer to next block - */ -typedef int (*HLPFILE_BPTreeCompare)(void *p, const void *key, - int leaf, void **next); - static BOOL HLPFILE_DoReadHlpFile(HLPFILE*, LPCSTR); static BOOL HLPFILE_ReadFileToBuffer(HFILE); static BOOL HLPFILE_FindSubFile(LPCSTR name, BYTE**, BYTE**); @@ -106,8 +94,6 @@ static BOOL HLPFILE_Uncompress3(char*, const char*, const BYTE*, const BYTE*); static void HLPFILE_UncompressRLE(const BYTE* src, const BYTE* end, BYTE** dst, unsigned dstsz); static BOOL HLPFILE_ReadFont(HLPFILE* hlpfile); -static void* HLPFILE_BPTreeSearch(BYTE*, const void*, HLPFILE_BPTreeCompare); - /*********************************************************************** * * HLPFILE_PageByNumber @@ -1924,8 +1910,8 @@ static void HLPFILE_UncompressRLE(const BYTE* src, const BYTE* end, BYTE** dst, * Pointer to block identified by key, or NULL if failure. * */ -static void* HLPFILE_BPTreeSearch(BYTE* buf, const void* key, - HLPFILE_BPTreeCompare comp) +void* HLPFILE_BPTreeSearch(BYTE* buf, const void* key, + HLPFILE_BPTreeCompare comp) { unsigned magic; unsigned page_size; @@ -1970,6 +1956,54 @@ static void* HLPFILE_BPTreeSearch(BYTE* buf, const void* key, return NULL; } +/************************************************************************** + * HLPFILE_BPTreeEnum + * + * Enumerates elements in B+ tree. + * + * PARAMS + * buf [I] pointer to the embedded file structured as a B+ tree + * cb [I] compare function + * cookie [IO] cookie for cb function + */ +void HLPFILE_BPTreeEnum(BYTE* buf, HLPFILE_BPTreeCallback cb, void* cookie) +{ + unsigned magic; + unsigned page_size; + unsigned cur_page; + unsigned level; + BYTE *pages, *ptr, *newptr; + int i, entries; + + magic = GET_USHORT(buf, 9); + if (magic != 0x293B) + { + WINE_ERR("Invalid magic in B+ tree: 0x%x\n", magic); + return; + } + page_size = GET_USHORT(buf, 9+4); + cur_page = GET_USHORT(buf, 9+26); + level = GET_USHORT(buf, 9+32); + pages = buf + 9 + 38; + while (--level > 0) + { + ptr = pages + cur_page*page_size; + cur_page = GET_USHORT(ptr, 4); + } + while (cur_page != 0xFFFF) + { + ptr = pages + cur_page*page_size; + entries = GET_SHORT(ptr, 2); + ptr += 8; + for (i = 0; i < entries; i++) + { + cb(ptr, (void **)&newptr, cookie); + ptr = newptr; + } + cur_page = GET_USHORT(pages+cur_page*page_size, 6); + } +} + /*********************************************************************** * diff --git a/programs/winhelp/hlpfile.h b/programs/winhelp/hlpfile.h index c7e643e785d..8c9e2013060 100644 --- a/programs/winhelp/hlpfile.h +++ b/programs/winhelp/hlpfile.h @@ -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 @@ -150,6 +151,28 @@ typedef struct tagHlpFileFile HLPFILE_WINDOWINFO* windows; } HLPFILE; +/* + * Compare function type for HLPFILE_BPTreeSearch function. + * + * PARAMS + * p [I] pointer to testing block (key + data) + * key [I] pointer to key value to look for + * leaf [I] whether this function called for index of leaf page + * next [O] pointer to pointer to next block + */ +typedef int (*HLPFILE_BPTreeCompare)(void *p, const void *key, + int leaf, void **next); + +/* + * Callback function type for HLPFILE_BPTreeEnum function. + * + * PARAMS + * p [I] pointer to data block + * next [O] pointer to pointer to next block + * cookie [IO] cookie data + */ +typedef void (*HLPFILE_BPTreeCallback)(void *p, void **next, void *cookie); + HLPFILE* HLPFILE_ReadHlpFile(LPCSTR lpszPath); HLPFILE_PAGE* HLPFILE_Contents(HLPFILE* hlpfile); HLPFILE_PAGE* HLPFILE_PageByHash(HLPFILE* hlpfile, LONG lHash); @@ -158,3 +181,6 @@ HLPFILE_PAGE* HLPFILE_PageByOffset(HLPFILE* hlpfile, LONG offset); LONG HLPFILE_Hash(LPCSTR lpszContext); void HLPFILE_FreeLink(HLPFILE_LINK* link); void HLPFILE_FreeHlpFile(HLPFILE*); + +void* HLPFILE_BPTreeSearch(BYTE*, const void*, HLPFILE_BPTreeCompare); +void HLPFILE_BPTreeEnum(BYTE*, HLPFILE_BPTreeCallback cb, void *cookie);