Module: wine Branch: master Commit: e717dcc8fab3ba5e4a268371df34070018708274 URL: http://source.winehq.org/git/wine.git/?a=commit;h=e717dcc8fab3ba5e4a268371df...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Feb 22 22:51:36 2007 +0100
hhctrl.ocx: Rewrite reading strings from #STRINGS section.
---
dlls/hhctrl.ocx/chm.c | 123 +++++++++++++++++++++++++++------------------- dlls/hhctrl.ocx/hhctrl.h | 9 +++ 2 files changed, 82 insertions(+), 50 deletions(-)
diff --git a/dlls/hhctrl.ocx/chm.c b/dlls/hhctrl.ocx/chm.c index 2fad67c..9fc98c6 100644 --- a/dlls/hhctrl.ocx/chm.c +++ b/dlls/hhctrl.ocx/chm.c @@ -2,6 +2,7 @@ * CHM Utility API * * Copyright 2005 James Hawkins + * Copyright 2007 Jacek Caban * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,57 +21,55 @@
#include "hhctrl.h"
-/* Reads a string from the #STRINGS section in the CHM file */ -static LPWSTR CHM_ReadString(CHMInfo *pChmInfo, DWORD dwOffset) -{ - LARGE_INTEGER liOffset; - IStorage *pStorage = pChmInfo->pStorage; - IStream *pStream; - DWORD cbRead; - ULONG iPos; - DWORD dwSize; - LPSTR szString; - LPWSTR stringW; - - const int CB_READ_BLOCK = 64; - static const WCHAR stringsW[] = {'#','S','T','R','I','N','G','S',0}; +#include "wine/debug.h"
- dwSize = CB_READ_BLOCK; - szString = hhctrl_alloc(dwSize); +WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp);
- if (FAILED(IStorage_OpenStream(pStorage, stringsW, NULL, STGM_READ, 0, &pStream))) - return NULL; +#define BLOCK_BITS 12 +#define BLOCK_SIZE (1 << BLOCK_BITS) +#define BLOCK_MASK (BLOCK_SIZE-1)
- liOffset.QuadPart = dwOffset; - - if (FAILED(IStream_Seek(pStream, liOffset, STREAM_SEEK_SET, NULL))) - { - IStream_Release(pStream); +/* Reads a string from the #STRINGS section in the CHM file */ +static LPCSTR GetChmString(CHMInfo *chm, DWORD offset) +{ + if(!chm->strings_stream) return NULL; + + if(chm->strings_size <= (offset >> BLOCK_BITS)) { + if(chm->strings) + chm->strings = hhctrl_realloc_zero(chm->strings, + chm->strings_size = ((offset >> BLOCK_BITS)+1)*sizeof(char*)); + else + chm->strings = hhctrl_alloc_zero( + chm->strings_size = ((offset >> BLOCK_BITS)+1)*sizeof(char*)); + }
- while (SUCCEEDED(IStream_Read(pStream, szString, CB_READ_BLOCK, &cbRead))) - { - if (!cbRead) - return NULL; + if(!chm->strings[offset >> BLOCK_BITS]) { + LARGE_INTEGER pos; + DWORD read; + HRESULT hres;
- for (iPos = 0; iPos < cbRead; iPos++) - { - if (!szString[iPos]) - { - stringW = strdupAtoW(szString); - hhctrl_free(szString); - return stringW; - } + pos.QuadPart = offset & ~BLOCK_MASK; + hres = IStream_Seek(chm->strings_stream, pos, STREAM_SEEK_SET, NULL); + if(FAILED(hres)) { + WARN("Seek failed: %08x\n", hres); + return NULL; }
- dwSize *= 2; - szString = hhctrl_realloc(szString, dwSize); - szString += cbRead; + chm->strings[offset >> BLOCK_BITS] = hhctrl_alloc(BLOCK_SIZE); + + hres = IStream_Read(chm->strings_stream, chm->strings[offset >> BLOCK_BITS], + BLOCK_SIZE, &read); + if(FAILED(hres)) { + WARN("Read failed: %08x\n", hres); + hhctrl_free(chm->strings[offset >> BLOCK_BITS]); + chm->strings[offset >> BLOCK_BITS] = NULL; + return NULL; + } }
- /* didn't find a string */ - return NULL; + return chm->strings[offset >> BLOCK_BITS] + (offset & BLOCK_MASK); }
/* Loads the HH_WINTYPE data from the CHM file @@ -103,16 +102,16 @@ BOOL CHM_LoadWinTypeFromCHM(CHMInfo *pChmInfo, HH_WINTYPEW *pHHWinType) if (FAILED(hr)) goto done;
/* convert the #STRINGS offsets to actual strings */ - pHHWinType->pszType = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszType); - pHHWinType->pszCaption = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszCaption); - pHHWinType->pszToc = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszToc); - pHHWinType->pszIndex = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszIndex); - pHHWinType->pszFile = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszFile); - pHHWinType->pszHome = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszHome); - pHHWinType->pszJump1 = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszJump1); - pHHWinType->pszJump2 = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszJump2); - pHHWinType->pszUrlJump1 = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszUrlJump1); - pHHWinType->pszUrlJump2 = CHM_ReadString(pChmInfo, (DWORD)pHHWinType->pszUrlJump2); + pHHWinType->pszType = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszType)); + pHHWinType->pszCaption = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszCaption)); + pHHWinType->pszToc = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszToc)); + pHHWinType->pszIndex = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszIndex)); + pHHWinType->pszFile = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszFile)); + pHHWinType->pszHome = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszHome)); + pHHWinType->pszJump1 = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszJump1)); + pHHWinType->pszJump2 = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszJump2)); + pHHWinType->pszUrlJump1 = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszUrlJump1)); + pHHWinType->pszUrlJump2 = strdupAtoW(GetChmString(pChmInfo, (DWORD)pHHWinType->pszUrlJump2));
/* FIXME: pszCustomTabs is a list of multiple zero-terminated strings so ReadString won't * work in this case @@ -130,6 +129,10 @@ done: /* Opens the CHM file for reading */ BOOL CHM_OpenCHM(CHMInfo *pChmInfo, LPCWSTR szFile) { + HRESULT hres; + + static const WCHAR wszSTRINGS[] = {'#','S','T','R','I','N','G','S',0}; + pChmInfo->szFile = szFile;
if (FAILED(CoCreateInstance(&CLSID_ITStorage, NULL, CLSCTX_INPROC_SERVER, @@ -141,6 +144,16 @@ BOOL CHM_OpenCHM(CHMInfo *pChmInfo, LPCWSTR szFile) NULL, 0, &pChmInfo->pStorage))) return FALSE;
+ hres = IStorage_OpenStream(pChmInfo->pStorage, wszSTRINGS, NULL, STGM_READ, 0, + &pChmInfo->strings_stream); + if(FAILED(hres)) { + WARN("Could not open #STRINGS stream: %08x\n", hres); + return FALSE; + } + + pChmInfo->strings = NULL; + pChmInfo->strings_size = 0; + return TRUE; }
@@ -148,4 +161,14 @@ void CHM_CloseCHM(CHMInfo *pCHMInfo) { IITStorage_Release(pCHMInfo->pITStorage); IStorage_Release(pCHMInfo->pStorage); + IStream_Release(pCHMInfo->strings_stream); + + if(pCHMInfo->strings_size) { + int i; + + for(i=0; i<pCHMInfo->strings_size; i++) + hhctrl_free(pCHMInfo->strings[i]); + } + + hhctrl_free(pCHMInfo->strings); } diff --git a/dlls/hhctrl.ocx/hhctrl.h b/dlls/hhctrl.ocx/hhctrl.h index 4257687..355fc02 100644 --- a/dlls/hhctrl.ocx/hhctrl.h +++ b/dlls/hhctrl.ocx/hhctrl.h @@ -50,6 +50,10 @@ typedef struct CHMInfo IITStorage *pITStorage; IStorage *pStorage; LPCWSTR szFile; + + IStream *strings_stream; + char **strings; + DWORD strings_size; } CHMInfo;
@@ -87,6 +91,11 @@ static inline void *hhctrl_realloc(void *mem, size_t len) return HeapReAlloc(GetProcessHeap(), 0, mem, len); }
+static inline void *hhctrl_realloc_zero(void *mem, size_t len) +{ + return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len); +} + static inline BOOL hhctrl_free(void *mem) { return HeapFree(GetProcessHeap(), 0, mem);