hlpfile.c
来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 2,066 行 · 第 1/5 页
C
2,066 行
switch (hlpfile->flags & (8|4)) { case 8: WINE_FIXME("Unsupported format\n"); return FALSE; case 4: 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_UncompressedLZ77_Size(ptr + 0xc, min(end, ptr + 0x1000)); } topic.map = HeapAlloc(GetProcessHeap(), 0, topic.wMapLen * sizeof(topic.map[0]) + newsize); if (!topic.map) return FALSE; newptr = (BYTE*)(topic.map + topic.wMapLen); 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; newptr = HLPFILE_UncompressLZ77(ptr + 0xc, min(end, ptr + 0x1000), newptr); } break; case 0: /* basically, we need to copy the 0x1000 byte pages (removing the first 0x0C) in * one single are in memory */#define DST_LEN (0x1000 - 0x0C) buf += 9; newsize = end - buf; /* number of destination pages */ topic.wMapLen = (newsize - 1) / DST_LEN + 1; topic.map = HeapAlloc(GetProcessHeap(), 0, topic.wMapLen * (sizeof(topic.map[0]) + DST_LEN)); if (!topic.map) return FALSE; newptr = (BYTE*)(topic.map + topic.wMapLen); topic.end = newptr + newsize; for (i = 0; i < topic.wMapLen; i++) { topic.map[i] = newptr + i * DST_LEN; memcpy(topic.map[i], buf + i * 0x1000 + 0x0C, DST_LEN); }#undef DST_LEN break; } return TRUE;}/*********************************************************************** * * HLPFILE_Uncompress2 */static void HLPFILE_Uncompress2(const BYTE *ptr, const BYTE *end, BYTE *newptr, const BYTE *newend){ BYTE *phptr, *phend; UINT code; UINT index; while (ptr < end && newptr < newend) { if (!*ptr || *ptr >= 0x10) *newptr++ = *ptr++; else { code = 0x100 * ptr[0] + ptr[1]; index = (code - 0x100) / 2; phptr = (BYTE*)phrases.buffer + phrases.offsets[index]; phend = (BYTE*)phrases.buffer + phrases.offsets[index + 1]; if (newptr + (phend - phptr) > newend) { WINE_FIXME("buffer overflow %p > %p for %d bytes\n", newptr, newend, phend - phptr); return; } memcpy(newptr, phptr, phend - phptr); newptr += phend - phptr; if (code & 1) *newptr++ = ' '; ptr += 2; } } if (newptr > newend) WINE_FIXME("buffer overflow %p > %p\n", newptr, newend);}/****************************************************************** * HLPFILE_Uncompress3 * * */static BOOL HLPFILE_Uncompress3(char* dst, const char* dst_end, const BYTE* src, const BYTE* src_end){ int idx, len; for (; src < src_end; src++) { if ((*src & 1) == 0) { idx = *src / 2; if (idx > phrases.num) { WINE_ERR("index in phrases %d/%d\n", idx, phrases.num); len = 0; } else { len = phrases.offsets[idx + 1] - phrases.offsets[idx]; if (dst + len <= dst_end) memcpy(dst, &phrases.buffer[phrases.offsets[idx]], len); } } else if ((*src & 0x03) == 0x01) { idx = (*src + 1) * 64; idx += *++src; if (idx > phrases.num) { WINE_ERR("index in phrases %d/%d\n", idx, phrases.num); len = 0; } else { len = phrases.offsets[idx + 1] - phrases.offsets[idx]; if (dst + len <= dst_end) memcpy(dst, &phrases.buffer[phrases.offsets[idx]], len); } } else if ((*src & 0x07) == 0x03) { len = (*src / 8) + 1; if (dst + len <= dst_end) memcpy(dst, src + 1, len); src += len; } else { len = (*src / 16) + 1; if (dst + len <= dst_end) memset(dst, ((*src & 0x0F) == 0x07) ? ' ' : 0, len); } dst += len; } if (dst > dst_end) WINE_ERR("buffer overflow (%p > %p)\n", dst, dst_end); return TRUE;}/****************************************************************** * HLPFILE_UncompressRLE * * */static void HLPFILE_UncompressRLE(const BYTE* src, const BYTE* end, BYTE** dst, unsigned dstsz){ BYTE ch; BYTE* sdst = *dst + dstsz; while (src < end) { ch = *src++; if (ch & 0x80) { ch &= 0x7F; if ((*dst) + ch <= sdst) memcpy(*dst, src, ch); src += ch; } else { if ((*dst) + ch <= sdst) memset(*dst, (char)*src, ch); src++; } *dst += ch; } if (*dst != sdst) WINE_WARN("Buffer X-flow: d(%u) instead of d(%u)\n", *dst - (sdst - dstsz), dstsz);}/****************************************************************** * HLPFILE_EnumBTreeLeaves * * */static void HLPFILE_EnumBTreeLeaves(const BYTE* buf, const BYTE* end, unsigned (*fn)(const BYTE*, void*), void* user){ unsigned psize, pnext; unsigned num, nlvl; const BYTE* ptr; num = GET_UINT(buf, 9 + 34); psize = GET_USHORT(buf, 9 + 4); nlvl = GET_USHORT(buf, 9 + 32); pnext = GET_USHORT(buf, 9 + 26); WINE_TRACE("BTree: #entries=%u pagSize=%u #levels=%u #pages=%u root=%u struct%16s\n", num, psize, nlvl, GET_USHORT(buf, 9 + 30), pnext, buf + 9 + 6); if (!num) return; while (--nlvl > 0) { ptr = (buf + 9 + 38) + pnext * psize; WINE_TRACE("BTree: (index[%u]) unused=%u #entries=%u <%u\n", pnext, GET_USHORT(ptr, 0), GET_USHORT(ptr, 2), GET_USHORT(ptr, 4)); pnext = GET_USHORT(ptr, 4); } while (pnext != 0xFFFF) { const BYTE* node_page; unsigned short limit; node_page = ptr = (buf + 9 + 38) + pnext * psize; limit = GET_USHORT(ptr, 2); WINE_TRACE("BTree: (leaf [%u]) unused=%u #entries=%u <%u >%u\n", pnext, GET_USHORT(ptr, 0), limit, GET_USHORT(ptr, 4), GET_USHORT(ptr, 6)); ptr += 8; while (limit--) ptr += (fn)(ptr, user); pnext = GET_USHORT(node_page, 6); }}struct myfncb { HLPFILE* hlpfile; int i;};static unsigned myfn(const BYTE* ptr, void* user){ struct myfncb* m = user; m->hlpfile->Context[m->i].lHash = GET_UINT(ptr, 0); m->hlpfile->Context[m->i].offset = GET_UINT(ptr, 4); m->i++; return 8;}/*********************************************************************** * * HLPFILE_GetContext */static BOOL HLPFILE_GetContext(HLPFILE *hlpfile){ BYTE *cbuf, *cend; struct myfncb m; unsigned clen; if (!HLPFILE_FindSubFile("|CONTEXT", &cbuf, &cend)) {WINE_WARN("context0\n"); return FALSE;} clen = GET_UINT(cbuf, 0x2b); hlpfile->Context = HeapAlloc(GetProcessHeap(), 0, clen * sizeof(HLPFILE_CONTEXT)); if (!hlpfile->Context) return FALSE; hlpfile->wContextLen = clen; m.hlpfile = hlpfile; m.i = 0; HLPFILE_EnumBTreeLeaves(cbuf, cend, myfn, &m); return TRUE;}/*********************************************************************** * * HLPFILE_GetMap */static BOOL HLPFILE_GetMap(HLPFILE *hlpfile){ BYTE *cbuf, *cend; unsigned entries, i; if (!HLPFILE_FindSubFile("|CTXOMAP", &cbuf, &cend)) {WINE_WARN("no map section\n"); return FALSE;} entries = GET_USHORT(cbuf, 9); hlpfile->Map = HeapAlloc(GetProcessHeap(), 0, entries * sizeof(HLPFILE_MAP)); if (!hlpfile->Map) return FALSE; hlpfile->wMapLen = entries; for (i = 0; i < entries; i++) { hlpfile->Map[i].lMap = GET_UINT(cbuf+11,i*8); hlpfile->Map[i].offset = GET_UINT(cbuf+11,i*8+4); } return TRUE;}/****************************************************************** * HLPFILE_DeleteLink * * */void HLPFILE_FreeLink(HLPFILE_LINK* link){ if (link && !--link->wRefCount) HeapFree(GetProcessHeap(), 0, link);}/*********************************************************************** * * HLPFILE_DeleteParagraph */static void HLPFILE_DeleteParagraph(HLPFILE_PARAGRAPH* paragraph){ HLPFILE_PARAGRAPH* next; while (paragraph) { next = paragraph->next; if (paragraph->cookie == para_metafile) DeleteMetaFile(paragraph->u.gfx.u.mfp.hMF); HLPFILE_FreeLink(paragraph->link); HeapFree(GetProcessHeap(), 0, paragraph); paragraph = next; }}/*********************************************************************** * * DeleteMacro */static void HLPFILE_DeleteMacro(HLPFILE_MACRO* macro){ HLPFILE_MACRO* next; while (macro) { next = macro->next; HeapFree(GetProcessHeap(), 0, macro); macro = next; }}/*********************************************************************** * * DeletePage */static void HLPFILE_DeletePage(HLPFILE_PAGE* page){ HLPFILE_PAGE* next; while (page) { next = page->next; HLPFILE_DeleteParagraph(page->first_paragraph); HLPFILE_DeleteMacro(page->first_macro); HeapFree(GetProcessHeap(), 0, page); page = next; }}/*********************************************************************** * * HLPFILE_FreeHlpFile */void HLPFILE_FreeHlpFile(HLPFILE* hlpfile){ unsigned i; if (!hlpfile || --hlpfile->wRefCount > 0) return; if (hlpfile->next) hlpfile->next->prev = hlpfile->prev; if (hlpfile->prev) hlpfile->prev->next = hlpfile->next; else first_hlpfile = hlpfile->next; if (hlpfile->numFonts) { for (i = 0; i < hlpfile->numFonts; i++) { DeleteObject(hlpfile->fonts[i].hFont); } HeapFree(GetProcessHeap(), 0, hlpfile->fonts); } if (hlpfile->numBmps) { for (i = 0; i < hlpfile->numBmps; i++) { DeleteObject(hlpfile->bmps[i]); } HeapFree(GetProcessHeap(), 0, hlpfile->bmps); } HLPFILE_DeletePage(hlpfile->first_page); HLPFILE_DeleteMacro(hlpfile->first_macro); if (hlpfile->numWindows) HeapFree(GetProcessHeap(), 0, hlpfile->windows); HeapFree(GetProcessHeap(), 0, hlpfile->Context); HeapFree(GetProcessHeap(), 0, hlpfile->Map); HeapFree(GetProcessHeap(), 0, hlpfile->lpszTitle); HeapFree(GetProcessHeap(), 0, hlpfile->lpszCopyright); HeapFree(GetProcessHeap(), 0, hlpfile);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?