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 + -
显示快捷键?