ReactOS 0.4.16-dev-295-g4aee028
chm.c
Go to the documentation of this file.
1/*
2 * CHM Utility API
3 *
4 * Copyright 2005 James Hawkins
5 * Copyright 2007 Jacek Caban
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include "hhctrl.h"
23#include "stream.h"
24#ifdef __REACTOS__
25#include "resource.h"
26#endif
27
28#include "winreg.h"
29#include "shlwapi.h"
30#include "wine/debug.h"
31
33
34/* Reads a string from the #STRINGS section in the CHM file */
36{
37 LPCSTR str;
38
39 if(!chm->strings_stream)
40 return NULL;
41
42 if(chm->strings_size <= (offset >> BLOCK_BITS)) {
43 chm->strings_size = (offset >> BLOCK_BITS)+1;
44 if(chm->strings)
45 chm->strings = heap_realloc_zero(chm->strings,
46 chm->strings_size*sizeof(char*));
47 else
48 chm->strings = heap_alloc_zero(
49 chm->strings_size*sizeof(char*));
50
51 }
52
53 if(!chm->strings[offset >> BLOCK_BITS]) {
55 DWORD read;
57
58 pos.QuadPart = offset & ~BLOCK_MASK;
59 hres = IStream_Seek(chm->strings_stream, pos, STREAM_SEEK_SET, NULL);
60 if(FAILED(hres)) {
61 WARN("Seek failed: %08x\n", hres);
62 return NULL;
63 }
64
66
67 hres = IStream_Read(chm->strings_stream, chm->strings[offset >> BLOCK_BITS],
69 if(FAILED(hres)) {
70 WARN("Read failed: %08x\n", hres);
72 chm->strings[offset >> BLOCK_BITS] = NULL;
73 return NULL;
74 }
75 }
76
78 TRACE("offset %#x => %s\n", offset, debugstr_a(str));
79 return str;
80}
81
83{
85 DWORD ver=0xdeadbeef, read, buf_size;
86 char *buf;
88
89 struct {
90 WORD code;
91 WORD len;
92 } entry;
93
94 static const WCHAR wszSYSTEM[] = {'#','S','Y','S','T','E','M',0};
95
96 hres = IStorage_OpenStream(chm->pStorage, wszSYSTEM, NULL, STGM_READ, 0, &stream);
97 if(FAILED(hres)) {
98 WARN("Could not open #SYSTEM stream: %08x\n", hres);
99 return FALSE;
100 }
101
102 IStream_Read(stream, &ver, sizeof(ver), &read);
103 TRACE("version is %x\n", ver);
104
105 buf = heap_alloc(8*sizeof(DWORD));
106 buf_size = 8*sizeof(DWORD);
107
108 while(1) {
109 hres = IStream_Read(stream, &entry, sizeof(entry), &read);
110 if(hres != S_OK)
111 break;
112
113 if(entry.len > buf_size)
114 buf = heap_realloc(buf, buf_size=entry.len);
115
116 hres = IStream_Read(stream, buf, entry.len, &read);
117 if(hres != S_OK)
118 break;
119
120 switch(entry.code) {
121 case 0x0:
122 TRACE("TOC is %s\n", debugstr_an(buf, entry.len));
123 heap_free(chm->defToc);
124 chm->defToc = strdupnAtoW(buf, entry.len);
125 break;
126 case 0x2:
127 TRACE("Default topic is %s\n", debugstr_an(buf, entry.len));
128 heap_free(chm->defTopic);
129 chm->defTopic = strdupnAtoW(buf, entry.len);
130 break;
131 case 0x3:
132 TRACE("Title is %s\n", debugstr_an(buf, entry.len));
133 heap_free(chm->defTitle);
134 chm->defTitle = strdupnAtoW(buf, entry.len);
135 break;
136 case 0x4:
137 /* TODO: Currently only the Locale ID is loaded from this field */
138 TRACE("Locale is: %d\n", *(LCID*)&buf[0]);
139 if(!GetLocaleInfoW(*(LCID*)&buf[0], LOCALE_IDEFAULTANSICODEPAGE|LOCALE_RETURN_NUMBER,
140 (WCHAR *)&chm->codePage, sizeof(chm->codePage)/sizeof(WCHAR)))
141 chm->codePage = CP_ACP;
142 break;
143 case 0x5:
144 TRACE("Window name is %s\n", debugstr_an(buf, entry.len));
145 chm->defWindow = strdupnAtoW(buf, entry.len);
146 break;
147 case 0x6:
148 TRACE("Compiled file is %s\n", debugstr_an(buf, entry.len));
150 chm->compiledFile = strdupnAtoW(buf, entry.len);
151 break;
152 case 0x9:
153 TRACE("Version is %s\n", debugstr_an(buf, entry.len));
154 break;
155 case 0xa:
156 TRACE("Time is %08x\n", *(DWORD*)buf);
157 break;
158 case 0xc:
159 TRACE("Number of info types: %d\n", *(DWORD*)buf);
160 break;
161 case 0xf:
162 TRACE("Check sum: %x\n", *(DWORD*)buf);
163 break;
164 default:
165 TRACE("unhandled code %x, size %x\n", entry.code, entry.len);
166 }
167 }
168
169 heap_free(buf);
170 IStream_Release(stream);
171
172 return SUCCEEDED(hres);
173}
174
176{
177 IStream *ivb_stream;
178 DWORD size, read, i;
179 DWORD *buf;
180 LPCSTR ret = NULL;
182
183 static const WCHAR wszIVB[] = {'#','I','V','B',0};
184
185 hres = IStorage_OpenStream(chm->pStorage, wszIVB, NULL, STGM_READ, 0, &ivb_stream);
186 if(FAILED(hres)) {
187 WARN("Could not open #IVB stream: %08x\n", hres);
188 return NULL;
189 }
190
191 hres = IStream_Read(ivb_stream, &size, sizeof(size), &read);
192 if(FAILED(hres)) {
193 WARN("Read failed: %08x\n", hres);
194 IStream_Release(ivb_stream);
195 return NULL;
196 }
197
199 hres = IStream_Read(ivb_stream, buf, size, &read);
200 IStream_Release(ivb_stream);
201 if(FAILED(hres)) {
202 WARN("Read failed: %08x\n", hres);
203 heap_free(buf);
204 return NULL;
205 }
206
207 size /= 2*sizeof(DWORD);
208
209 for(i=0; i<size; i++) {
210 if(buf[2*i] == index) {
211 ret = GetChmString(chm, buf[2*i+1]);
212 break;
213 }
214 }
215
216 heap_free(buf);
217
218 TRACE("returning %s\n", debugstr_a(ret));
219 return strdupAtoW(ret);
220}
221
222/*
223 * Tests if the file <chmfile>.<ext> exists, used for loading Indices, Table of Contents, etc.
224 * when these files are not available from the HH_WINTYPE structure.
225 */
227{
228 static const WCHAR periodW[] = {'.',0};
229 IStorage *pStorage = info->pCHMInfo->pStorage;
230 IStream *pStream;
232 HRESULT hr;
233
234 filename = heap_alloc( (lstrlenW(info->pCHMInfo->compiledFile)
235 + lstrlenW(periodW) + lstrlenW(extW) + 1) * sizeof(WCHAR) );
236 lstrcpyW(filename, info->pCHMInfo->compiledFile);
237 lstrcatW(filename, periodW);
238 lstrcatW(filename, extW);
239 hr = IStorage_OpenStream(pStorage, filename, NULL, STGM_READ, 0, &pStream);
240 if (FAILED(hr))
241 {
243 return strdupAtoW("");
244 }
245 IStream_Release(pStream);
246 return filename;
247}
248
250{
251 if(*dst == NULL)
252 *dst = strdupW(src);
253 return *dst;
254}
255
257{
258 DWORD unhandled_params = src->fsValidMembers & ~(HHWIN_PARAM_PROPERTIES|HHWIN_PARAM_STYLES
263 HH_WINTYPEW *dst = &info->WinType;
264 DWORD merge = override ? src->fsValidMembers : src->fsValidMembers & ~dst->fsValidMembers;
265
266 if (unhandled_params)
267 FIXME("Unsupported fsValidMembers fields: 0x%x\n", unhandled_params);
268
269 dst->fsValidMembers |= merge;
270 if (dst->cbStruct == 0)
271 {
272 /* If the structure has not been filled in yet then use all of the values */
273 dst->cbStruct = sizeof(HH_WINTYPEW);
274 merge = ~0;
275 }
276 if (merge & HHWIN_PARAM_PROPERTIES) dst->fsWinProperties = src->fsWinProperties;
277 if (merge & HHWIN_PARAM_STYLES) dst->dwStyles = src->dwStyles;
278 if (merge & HHWIN_PARAM_EXSTYLES) dst->dwExStyles = src->dwExStyles;
279 if (merge & HHWIN_PARAM_RECT) dst->rcWindowPos = src->rcWindowPos;
280 if (merge & HHWIN_PARAM_NAV_WIDTH) dst->iNavWidth = src->iNavWidth;
281 if (merge & HHWIN_PARAM_SHOWSTATE) dst->nShowState = src->nShowState;
282 if (merge & HHWIN_PARAM_INFOTYPES) dst->paInfoTypes = src->paInfoTypes;
283 if (merge & HHWIN_PARAM_TB_FLAGS) dst->fsToolBarFlags = src->fsToolBarFlags;
284 if (merge & HHWIN_PARAM_EXPANSION) dst->fNotExpanded = src->fNotExpanded;
285 if (merge & HHWIN_PARAM_TABPOS) dst->tabpos = src->tabpos;
286 if (merge & HHWIN_PARAM_TABORDER) memcpy(dst->tabOrder, src->tabOrder, sizeof(src->tabOrder));
287 if (merge & HHWIN_PARAM_HISTORY_COUNT) dst->cHistory = src->cHistory;
288 if (merge & HHWIN_PARAM_CUR_TAB) dst->curNavType = src->curNavType;
289
290 /*
291 * Note: We assume that hwndHelp, hwndCaller, hwndToolBar, hwndNavigation, and hwndHTML cannot be
292 * modified by the user. rcHTML and rcMinSize are not currently supported, so don't bother to copy them.
293 */
294
295 dst->pszType = MergeChmString(src->pszType, &info->stringsW.pszType);
296 dst->pszFile = MergeChmString(src->pszFile, &info->stringsW.pszFile);
297 dst->pszToc = MergeChmString(src->pszToc, &info->stringsW.pszToc);
298 dst->pszIndex = MergeChmString(src->pszIndex, &info->stringsW.pszIndex);
299 dst->pszCaption = MergeChmString(src->pszCaption, &info->stringsW.pszCaption);
300 dst->pszHome = MergeChmString(src->pszHome, &info->stringsW.pszHome);
301 dst->pszJump1 = MergeChmString(src->pszJump1, &info->stringsW.pszJump1);
302 dst->pszJump2 = MergeChmString(src->pszJump2, &info->stringsW.pszJump2);
303 dst->pszUrlJump1 = MergeChmString(src->pszUrlJump1, &info->stringsW.pszUrlJump1);
304 dst->pszUrlJump2 = MergeChmString(src->pszUrlJump2, &info->stringsW.pszUrlJump2);
305
306 /* FIXME: pszCustomTabs is a list of multiple zero-terminated strings so ReadString won't
307 * work in this case
308 */
309#if 0
310 dst->pszCustomTabs = MergeChmString(src->pszCustomTabs, &info->pszCustomTabs);
311#endif
312}
313
315{
316 WCHAR *ret = NULL;
317
318 if(id)
319 ret = strdupAtoW(GetChmString(info->pCHMInfo, id));
320 return ret;
321}
322
323static inline void wintype_free(HH_WINTYPEW *wintype)
324{
325 heap_free((void *)wintype->pszType);
326 heap_free((void *)wintype->pszCaption);
327 heap_free(wintype->paInfoTypes);
328 heap_free((void *)wintype->pszToc);
329 heap_free((void *)wintype->pszIndex);
330 heap_free((void *)wintype->pszFile);
331 heap_free((void *)wintype->pszHome);
332 heap_free((void *)wintype->pszJump1);
333 heap_free((void *)wintype->pszJump2);
334 heap_free((void *)wintype->pszUrlJump1);
335 heap_free((void *)wintype->pszUrlJump2);
336 heap_free((void *)wintype->pszCustomTabs);
337}
338
339/* Loads the HH_WINTYPE data from the CHM file
340 *
341 * FIXME: There may be more than one window type in the file, so
342 * add the ability to choose a certain window type
343 */
345{
346 LARGE_INTEGER liOffset;
347 IStorage *pStorage = info->pCHMInfo->pStorage;
348 IStream *pStream = NULL;
349 HH_WINTYPEW wintype;
350 HRESULT hr;
351 DWORD cbRead;
352 BOOL ret = FALSE;
353
354 static const WCHAR empty[] = {0};
355 static const WCHAR toc_extW[] = {'h','h','c',0};
356 static const WCHAR index_extW[] = {'h','h','k',0};
357 static const WCHAR windowsW[] = {'#','W','I','N','D','O','W','S',0};
358
359 /* HH_WINTYPE as stored on disk. It's identical to HH_WINTYPE except that the pointer fields
360 have been changed to DWORDs, so that the layout on 64-bit remains unchanged. */
361 struct file_wintype
362 {
363 int cbStruct;
364 BOOL fUniCodeStrings;
365 DWORD pszType;
366 DWORD fsValidMembers;
367 DWORD fsWinProperties;
368 DWORD pszCaption;
369 DWORD dwStyles;
370 DWORD dwExStyles;
371 RECT rcWindowPos;
372 int nShowState;
373 DWORD hwndHelp;
374 DWORD hwndCaller;
375 DWORD paInfoTypes;
376 DWORD hwndToolBar;
377 DWORD hwndNavigation;
378 DWORD hwndHTML;
379 int iNavWidth;
380 RECT rcHTML;
381 DWORD pszToc;
382 DWORD pszIndex;
383 DWORD pszFile;
384 DWORD pszHome;
385 DWORD fsToolBarFlags;
386 BOOL fNotExpanded;
387 int curNavType;
388 int tabpos;
389 int idNotify;
390 BYTE tabOrder[HH_MAX_TABS+1];
391 int cHistory;
392 DWORD pszJump1;
393 DWORD pszJump2;
394 DWORD pszUrlJump1;
395 DWORD pszUrlJump2;
396 RECT rcMinSize;
397 int cbInfoTypes;
398 DWORD pszCustomTabs;
399 } file_wintype;
400
401 memset(&wintype, 0, sizeof(wintype));
402 wintype.cbStruct = sizeof(wintype);
403 wintype.fUniCodeStrings = TRUE;
404
405 hr = IStorage_OpenStream(pStorage, windowsW, NULL, STGM_READ, 0, &pStream);
406 if (SUCCEEDED(hr))
407 {
408 /* jump past the #WINDOWS header */
409 liOffset.QuadPart = sizeof(DWORD) * 2;
410
411 hr = IStream_Seek(pStream, liOffset, STREAM_SEEK_SET, NULL);
412 if (FAILED(hr)) goto done;
413
414 /* read the HH_WINTYPE struct data */
415 hr = IStream_Read(pStream, &file_wintype, sizeof(file_wintype), &cbRead);
416 if (FAILED(hr)) goto done;
417
418 /* convert the #STRINGS offsets to actual strings */
419 wintype.pszType = ConvertChmString(info, file_wintype.pszType);
420 wintype.fsValidMembers = file_wintype.fsValidMembers;
421 wintype.fsWinProperties = file_wintype.fsWinProperties;
422 wintype.pszCaption = ConvertChmString(info, file_wintype.pszCaption);
423 wintype.dwStyles = file_wintype.dwStyles;
424 wintype.dwExStyles = file_wintype.dwExStyles;
425 wintype.rcWindowPos = file_wintype.rcWindowPos;
426 wintype.nShowState = file_wintype.nShowState;
427 wintype.iNavWidth = file_wintype.iNavWidth;
428 wintype.rcHTML = file_wintype.rcHTML;
429 wintype.pszToc = ConvertChmString(info, file_wintype.pszToc);
430 wintype.pszIndex = ConvertChmString(info, file_wintype.pszIndex);
431 wintype.pszFile = ConvertChmString(info, file_wintype.pszFile);
432 wintype.pszHome = ConvertChmString(info, file_wintype.pszHome);
433 wintype.fsToolBarFlags = file_wintype.fsToolBarFlags;
434 wintype.fNotExpanded = file_wintype.fNotExpanded;
435 wintype.curNavType = file_wintype.curNavType;
436 wintype.tabpos = file_wintype.tabpos;
437 wintype.idNotify = file_wintype.idNotify;
438 memcpy(&wintype.tabOrder, file_wintype.tabOrder, sizeof(wintype.tabOrder));
439 wintype.cHistory = file_wintype.cHistory;
440 wintype.pszJump1 = ConvertChmString(info, file_wintype.pszJump1);
441 wintype.pszJump2 = ConvertChmString(info, file_wintype.pszJump2);
442 wintype.pszUrlJump1 = ConvertChmString(info, file_wintype.pszUrlJump1);
443 wintype.pszUrlJump2 = ConvertChmString(info, file_wintype.pszUrlJump2);
444 wintype.rcMinSize = file_wintype.rcMinSize;
445 wintype.cbInfoTypes = file_wintype.cbInfoTypes;
446 }
447 else
448 {
449 /* no defined window types so use (hopefully) sane defaults */
450 static const WCHAR defaultwinW[] = {'d','e','f','a','u','l','t','w','i','n','\0'};
451 wintype.pszType = strdupW(info->pCHMInfo->defWindow ? info->pCHMInfo->defWindow : defaultwinW);
452 wintype.pszToc = strdupW(info->pCHMInfo->defToc ? info->pCHMInfo->defToc : empty);
453 wintype.pszIndex = strdupW(empty);
454 wintype.fsValidMembers = 0;
456 wintype.dwStyles = WS_POPUP;
457 wintype.dwExStyles = 0;
458 wintype.nShowState = SW_SHOW;
460 }
461
462 /* merge the new data with any pre-existing HH_WINTYPE structure */
463 MergeChmProperties(&wintype, info, FALSE);
464 if (!info->WinType.pszCaption)
465#ifdef __REACTOS__
466 info->WinType.pszCaption = info->stringsW.pszCaption = (info->pCHMInfo->defTitle ? strdupW(info->pCHMInfo->defTitle) : HH_LoadString(IDS_DEFTITLE));
467#else
468 info->WinType.pszCaption = info->stringsW.pszCaption = strdupW(info->pCHMInfo->defTitle ? info->pCHMInfo->defTitle : empty);
469#endif
470 if (!info->WinType.pszFile)
471 info->WinType.pszFile = info->stringsW.pszFile = strdupW(info->pCHMInfo->defTopic ? info->pCHMInfo->defTopic : empty);
472 if (!info->WinType.pszToc)
473 info->WinType.pszToc = info->stringsW.pszToc = FindHTMLHelpSetting(info, toc_extW);
474 if (!info->WinType.pszIndex)
475 info->WinType.pszIndex = info->stringsW.pszIndex = FindHTMLHelpSetting(info, index_extW);
476
477 wintype_free(&wintype);
478 ret = TRUE;
479
480done:
481 if (pStream)
482 IStream_Release(pStream);
483
484 return ret;
485}
486
488{
489 static const WCHAR its_schema[] = {'i','t','s',':'};
490 static const WCHAR msits_schema[] = {'m','s','-','i','t','s',':'};
491 static const WCHAR mk_schema[] = {'m','k',':','@','M','S','I','T','S','t','o','r','e',':'};
492
493 if(!_wcsnicmp(its_schema, url, ARRAY_SIZE(its_schema)))
494 return url + ARRAY_SIZE(its_schema);
495 if(!_wcsnicmp(msits_schema, url, ARRAY_SIZE(msits_schema)))
496 return url + ARRAY_SIZE(msits_schema);
497 if(!_wcsnicmp(mk_schema, url, ARRAY_SIZE(mk_schema)))
498 return url + ARRAY_SIZE(mk_schema);
499
500 return url;
501}
502
504{
505 LPCWSTR ptr;
506 static const WCHAR separatorW[] = {':',':',0};
507
509
511 if(ptr) {
512 WCHAR chm_file[MAX_PATH];
513 WCHAR rel_path[MAX_PATH];
514 WCHAR base_path[MAX_PATH];
515 LPWSTR p;
516
517 lstrcpyW(base_path, base_file);
518 p = wcsrchr(base_path, '\\');
519 if(p)
520 *p = 0;
521
522 memcpy(rel_path, path, (ptr-path)*sizeof(WCHAR));
523 rel_path[ptr-path] = 0;
524
525 PathCombineW(chm_file, base_path, rel_path);
526
527 file->chm_file = strdupW(chm_file);
528 ptr += 2;
529 }else {
530 file->chm_file = strdupW(base_file);
531 ptr = path;
532 }
533
534 file->chm_index = strdupW(ptr);
535
536 TRACE("ChmFile = {%s %s}\n", debugstr_w(file->chm_file), debugstr_w(file->chm_index));
537}
538
540{
544
545 TRACE("%s (%s :: %s)\n", debugstr_w(parent_chm), debugstr_w(chm_file->chm_file),
546 debugstr_w(chm_file->chm_index));
547
548 if(parent_chm || chm_file->chm_file) {
549 hres = IITStorage_StgOpenStorage(info->pITStorage,
550 chm_file->chm_file ? chm_file->chm_file : parent_chm, NULL,
552 if(FAILED(hres)) {
553 WARN("Could not open storage: %08x\n", hres);
554 return NULL;
555 }
556 }else {
557 storage = info->pStorage;
558 IStorage_AddRef(info->pStorage);
559 }
560
561 hres = IStorage_OpenStream(storage, chm_file->chm_index, NULL, STGM_READ, 0, &stream);
562 IStorage_Release(storage);
563 if(FAILED(hres))
564 WARN("Could not open stream: %08x\n", hres);
565
566 return stream;
567}
568
569/*
570 * Retrieve a CHM document and parse the data from the <title> element to get the document's title.
571 */
573{
574 strbuf_t node, node_name, content;
575 WCHAR *document_title = NULL;
576 IStream *str = NULL;
580
581 TRACE("%s\n", debugstr_w(document));
582
583 storage = info->pStorage;
584 if(!storage) {
585 WARN("Could not open storage to obtain the title for a document.\n");
586 return NULL;
587 }
588 IStorage_AddRef(storage);
589
590 hres = IStorage_OpenStream(storage, document, NULL, STGM_READ, 0, &str);
591 IStorage_Release(storage);
592 if(FAILED(hres))
593 WARN("Could not open stream: %08x\n", hres);
594
598 strbuf_init(&node_name);
599
600 while(next_node(&stream, &node)) {
601 get_node_name(&node, &node_name);
602
603 TRACE("%s\n", node.buf);
604
605 if(!_strnicmp(node_name.buf, "title", -1)) {
606 if(next_content(&stream, &content) && content.len > 1)
607 {
608 document_title = strdupnAtoW(&content.buf[1], content.len-1);
609 FIXME("magic: %s\n", debugstr_w(document_title));
610 break;
611 }
612 }
613
615 }
616
619 strbuf_free(&node_name);
620 IStream_Release(str);
621
622 return document_title;
623}
624
625/* Opens the CHM file for reading */
627{
629 CHMInfo *ret;
630
631 static const WCHAR wszSTRINGS[] = {'#','S','T','R','I','N','G','S',0};
632
633 if (!(ret = heap_alloc_zero(sizeof(CHMInfo))))
634 return NULL;
635 ret->codePage = CP_ACP;
636
637 if (!(ret->szFile = strdupW(szFile))) {
638 heap_free(ret);
639 return NULL;
640 }
641
642 hres = CoCreateInstance(&CLSID_ITStorage, NULL, CLSCTX_INPROC_SERVER,
643 &IID_IITStorage, (void **) &ret->pITStorage) ;
644 if(FAILED(hres)) {
645 WARN("Could not create ITStorage: %08x\n", hres);
646 return CloseCHM(ret);
647 }
648
649 hres = IITStorage_StgOpenStorage(ret->pITStorage, szFile, NULL,
650 STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &ret->pStorage);
651 if(FAILED(hres)) {
652 WARN("Could not open storage: %08x\n", hres);
653 return CloseCHM(ret);
654 }
655 hres = IStorage_OpenStream(ret->pStorage, wszSTRINGS, NULL, STGM_READ, 0,
656 &ret->strings_stream);
657 if(FAILED(hres)) {
658 WARN("Could not open #STRINGS stream: %08x\n", hres);
659 /* It's not critical, so we pass */
660 }
661
662 if(!ReadChmSystem(ret)) {
663 WARN("Could not read #SYSTEM\n");
664 return CloseCHM(ret);
665 }
666
667 return ret;
668}
669
671{
672 if(chm->pITStorage)
673 IITStorage_Release(chm->pITStorage);
674
675 if(chm->pStorage)
676 IStorage_Release(chm->pStorage);
677
678 if(chm->strings_stream)
679 IStream_Release(chm->strings_stream);
680
681 if(chm->strings_size) {
682 DWORD i;
683
684 for(i=0; i<chm->strings_size; i++)
685 heap_free(chm->strings[i]);
686 }
687
688 heap_free(chm->strings);
689 heap_free(chm->defWindow);
690 heap_free(chm->defTitle);
691 heap_free(chm->defTopic);
692 heap_free(chm->defToc);
693 heap_free(chm->szFile);
695 heap_free(chm);
696
697 return NULL;
698}
_STLP_MOVE_TO_STD_NAMESPACE _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result)
Definition: _algo.c:1419
#define read
Definition: acwin.h:96
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static WCHAR * strdupW(const WCHAR *src)
Definition: main.c:92
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
CHMInfo * CloseCHM(CHMInfo *chm)
Definition: chm.c:670
LPWSTR FindContextAlias(CHMInfo *chm, DWORD index)
Definition: chm.c:175
static void wintype_free(HH_WINTYPEW *wintype)
Definition: chm.c:323
WCHAR * GetDocumentTitle(CHMInfo *info, LPCWSTR document)
Definition: chm.c:572
static WCHAR * ConvertChmString(HHInfo *info, DWORD id)
Definition: chm.c:314
LPCWSTR skip_schema(LPCWSTR url)
Definition: chm.c:487
static BOOL ReadChmSystem(CHMInfo *chm)
Definition: chm.c:82
CHMInfo * OpenCHM(LPCWSTR szFile)
Definition: chm.c:626
void SetChmPath(ChmPath *file, LPCWSTR base_file, LPCWSTR path)
Definition: chm.c:503
static LPCSTR GetChmString(CHMInfo *chm, DWORD offset)
Definition: chm.c:35
static WCHAR * FindHTMLHelpSetting(HHInfo *info, const WCHAR *extW)
Definition: chm.c:226
void MergeChmProperties(HH_WINTYPEW *src, HHInfo *info, BOOL override)
Definition: chm.c:256
BOOL LoadWinTypeFromCHM(HHInfo *info)
Definition: chm.c:344
IStream * GetChmStream(CHMInfo *info, LPCWSTR parent_chm, ChmPath *chm_file)
Definition: chm.c:539
static WCHAR * MergeChmString(LPCWSTR src, WCHAR **dst)
Definition: chm.c:249
#define BLOCK_SIZE
Definition: dlist.c:220
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
content
Definition: atl_ax.c:994
static void strbuf_init(strbuf *buf)
Definition: registrar.c:82
static const WCHAR empty[]
Definition: main.c:47
static WCHAR * strdupAtoW(const char *str)
Definition: main.c:65
#define wcsrchr
Definition: compat.h:16
#define CP_ACP
Definition: compat.h:109
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define MAX_PATH
Definition: compat.h:34
#define lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
static LPWSTR HH_LoadString(DWORD dwID)
Definition: help.c:177
void strbuf_free(strbuf_t *buf)
Definition: stream.c:38
BOOL next_node(stream_t *stream, strbuf_t *buf)
Definition: stream.c:140
BOOL next_content(stream_t *stream, strbuf_t *buf)
Definition: stream.c:105
void strbuf_zero(strbuf_t *buf)
Definition: stream.c:33
void stream_init(stream_t *stream, IStream *str)
Definition: stream.c:54
void get_node_name(strbuf_t *node, strbuf_t *name)
Definition: stream.c:88
#define BLOCK_MASK
Definition: stream.h:24
#define BLOCK_BITS
Definition: stream.h:22
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1666
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLsizeiptr size
Definition: glext.h:5919
GLenum src
Definition: glext.h:6340
GLuint index
Definition: glext.h:6031
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static LPWSTR strdupnAtoW(LPCSTR str, LONG lenA)
Definition: hhctrl.h:271
#define HH_MAX_TABS
Definition: htmlhelp.h:260
#define HHWIN_PARAM_CUR_TAB
Definition: htmlhelp.h:97
#define HHWIN_PARAM_EXSTYLES
Definition: htmlhelp.h:87
struct tagHH_WINTYPEW HH_WINTYPEW
@ HHWIN_NAVTYPE_TOC
Definition: htmlhelp.h:217
#define HHWIN_PARAM_TB_FLAGS
Definition: htmlhelp.h:92
#define HHWIN_PARAM_NAV_WIDTH
Definition: htmlhelp.h:89
#define HHWIN_PARAM_TABPOS
Definition: htmlhelp.h:94
#define HHWIN_PARAM_TABORDER
Definition: htmlhelp.h:95
#define HHWIN_PARAM_INFOTYPES
Definition: htmlhelp.h:91
#define HHWIN_PARAM_SHOWSTATE
Definition: htmlhelp.h:90
#define HHWIN_PARAM_PROPERTIES
Definition: htmlhelp.h:85
#define HHWIN_PROP_TRI_PANE
Definition: htmlhelp.h:60
#define HHWIN_PARAM_RECT
Definition: htmlhelp.h:88
#define HHWIN_PARAM_EXPANSION
Definition: htmlhelp.h:93
#define HHWIN_PARAM_STYLES
Definition: htmlhelp.h:86
#define HHWIN_PARAM_HISTORY_COUNT
Definition: htmlhelp.h:96
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
static const WCHAR separatorW[]
Definition: itemdlg.c:1561
static const WCHAR url[]
Definition: encode.c:1432
HRESULT hres
Definition: protocol.c:465
#define DWORD
Definition: nt_native.h:44
#define STGM_SHARE_DENY_WRITE
Definition: objbase.h:922
#define STGM_READ
Definition: objbase.h:917
#define PathCombineW
Definition: pathcch.h:317
#define WS_POPUP
Definition: pedump.c:616
const WCHAR * str
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
DWORD LCID
Definition: nls.h:13
Console I/O streams.
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
Definition: hhctrl.h:98
WCHAR * defTopic
Definition: hhctrl.h:109
IStorage * pStorage
Definition: hhctrl.h:100
UINT codePage
Definition: hhctrl.h:113
DWORD strings_size
Definition: hhctrl.h:105
WCHAR * defTitle
Definition: hhctrl.h:110
char ** strings
Definition: hhctrl.h:104
WCHAR * compiledFile
Definition: hhctrl.h:107
IITStorage * pITStorage
Definition: hhctrl.h:99
WCHAR * defToc
Definition: hhctrl.h:111
IStream * strings_stream
Definition: hhctrl.h:103
WCHAR * szFile
Definition: hhctrl.h:101
WCHAR * defWindow
Definition: hhctrl.h:108
Definition: hhctrl.h:54
LPWSTR chm_file
Definition: hhctrl.h:55
LPWSTR chm_index
Definition: hhctrl.h:56
Definition: hhctrl.h:185
Definition: inflate.c:139
Definition: fci.c:127
char * buf
Definition: stream.h:27
Definition: parse.h:23
LPCWSTR pszIndex
Definition: htmlhelp.h:359
BYTE tabOrder[HH_MAX_TABS+1]
Definition: htmlhelp.h:367
LPCWSTR pszJump1
Definition: htmlhelp.h:369
LPCWSTR pszHome
Definition: htmlhelp.h:361
DWORD dwStyles
Definition: htmlhelp.h:346
RECT rcWindowPos
Definition: htmlhelp.h:348
DWORD dwExStyles
Definition: htmlhelp.h:347
PHH_INFOTYPE paInfoTypes
Definition: htmlhelp.h:352
LPCWSTR pszToc
Definition: htmlhelp.h:358
DWORD fsToolBarFlags
Definition: htmlhelp.h:362
LPCWSTR pszJump2
Definition: htmlhelp.h:370
DWORD fsValidMembers
Definition: htmlhelp.h:343
LPCWSTR pszType
Definition: htmlhelp.h:342
LPCWSTR pszUrlJump2
Definition: htmlhelp.h:372
LPCWSTR pszFile
Definition: htmlhelp.h:360
LPCWSTR pszCaption
Definition: htmlhelp.h:345
DWORD fsWinProperties
Definition: htmlhelp.h:344
BOOL fUniCodeStrings
Definition: htmlhelp.h:341
BOOL fNotExpanded
Definition: htmlhelp.h:363
LPCWSTR pszUrlJump1
Definition: htmlhelp.h:371
RECT rcMinSize
Definition: htmlhelp.h:373
LPCWSTR pszCustomTabs
Definition: htmlhelp.h:375
LONGLONG QuadPart
Definition: typedefs.h:114
Definition: dlist.c:348
int ret
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:40
#define SW_SHOW
Definition: winuser.h:778
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193