hlpfile.c

来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 2,066 行 · 第 1/5 页

C
2,066
字号
        }    }    page->lpszTitle[titlesize] = '\0';    if (hlpfile->first_page)    {        HLPFILE_PAGE  *p;        for (p = hlpfile->first_page; p->next; p = p->next);        page->prev = p;        p->next    = page;    }    else    {        hlpfile->first_page = page;        page->prev = NULL;    }    page->file            = hlpfile;    page->next            = NULL;    page->first_paragraph = NULL;    page->first_macro     = NULL;    page->wNumber         = GET_UINT(buf, 0x21);    page->offset          = offset;    page->browse_bwd = GET_UINT(buf, 0x19);    page->browse_fwd = GET_UINT(buf, 0x1D);    WINE_TRACE("Added page[%d]: title='%s' %08x << %08x >> %08x\n",               page->wNumber, page->lpszTitle,                page->browse_bwd, page->offset, page->browse_fwd);    memset(&attributes, 0, sizeof(attributes));    /* now load macros */    ptr = page->lpszTitle + strlen(page->lpszTitle) + 1;    while (ptr < page->lpszTitle + titlesize)    {        unsigned len = strlen(ptr);        char*    macro_str;        WINE_TRACE("macro: %s\n", ptr);        macro = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_MACRO) + len + 1);        macro->lpszMacro = macro_str = (char*)(macro + 1);        memcpy(macro_str, ptr, len + 1);        /* FIXME: shall we really link macro in reverse order ??         * may produce strange results when played at page opening         */        macro->next = page->first_macro;        page->first_macro = macro;        ptr += len + 1;    }    return TRUE;}static long fetch_long(BYTE** ptr){    long        ret;    if (*(*ptr) & 1)    {        ret = (*(unsigned long*)(*ptr) - 0x80000000L) / 2;        (*ptr) += 4;    }    else    {        ret = (*(unsigned short*)(*ptr) - 0x8000) / 2;        (*ptr) += 2;    }    return ret;}static unsigned long fetch_ulong(BYTE** ptr){    unsigned long        ret;    if (*(*ptr) & 1)    {        ret = *(unsigned long*)(*ptr) / 2;        (*ptr) += 4;    }    else    {        ret = *(unsigned short*)(*ptr) / 2;        (*ptr) += 2;    }    return ret;}    static short fetch_short(BYTE** ptr){    short       ret;    if (*(*ptr) & 1)    {        ret = (*(unsigned short*)(*ptr) - 0x8000) / 2;        (*ptr) += 2;    }    else    {        ret = (*(unsigned char*)(*ptr) - 0x80) / 2;        (*ptr)++;    }    return ret;}static unsigned short fetch_ushort(BYTE** ptr){    unsigned short ret;    if (*(*ptr) & 1)    {        ret = *(unsigned short*)(*ptr) / 2;        (*ptr) += 2;    }    else    {        ret = *(unsigned char*)(*ptr) / 2;        (*ptr)++;    }    return ret;}/****************************************************************** *		HLPFILE_DecompressGfx * * Decompress the data part of a bitmap or a metafile */static BYTE*    HLPFILE_DecompressGfx(BYTE* src, unsigned csz, unsigned sz, BYTE packing){    BYTE*       dst;    BYTE*       tmp;    BYTE*       tmp2;    unsigned    sz77;    WINE_TRACE("Unpacking (%d) from %u bytes to %u bytes\n", packing, csz, sz);    switch (packing)    {    case 0: /* uncompressed */        if (sz != csz)            WINE_WARN("Bogus gfx sizes (uncompressed): %u / %u\n", sz, csz);        dst = src;        break;    case 1: /* RunLen */        tmp = dst = HeapAlloc(GetProcessHeap(), 0, sz);        if (!dst) return NULL;        HLPFILE_UncompressRLE(src, src + csz, &tmp, sz);        if (tmp - dst != sz)            WINE_WARN("Bogus gfx sizes (RunLen): %u/%u\n", tmp - dst, sz);        break;    case 2: /* LZ77 */        sz77 = HLPFILE_UncompressedLZ77_Size(src, src + csz);        dst = HeapAlloc(GetProcessHeap(), 0, sz77);        if (!dst) return NULL;        HLPFILE_UncompressLZ77(src, src + csz, dst);        if (sz77 != sz)            WINE_WARN("Bogus gfx sizes (LZ77): %u / %u\n", sz77, sz);        break;    case 3: /* LZ77 then RLE */        sz77 = HLPFILE_UncompressedLZ77_Size(src, src + csz);        tmp = HeapAlloc(GetProcessHeap(), 0, sz77);        if (!tmp) return FALSE;        HLPFILE_UncompressLZ77(src, src + csz, tmp);        dst = tmp2 = HeapAlloc(GetProcessHeap(), 0, sz);        if (!dst) return FALSE;        HLPFILE_UncompressRLE(tmp, tmp + sz77, &tmp2, sz);        if (tmp2 - dst != sz)            WINE_WARN("Bogus gfx sizes (LZ77+RunLen): %u / %u\n", tmp2 - dst, sz);        HeapFree(GetProcessHeap(), 0, tmp);        break;    default:        WINE_FIXME("Unsupported packing %u\n", packing);        return NULL;    }    return dst;}/****************************************************************** *		HLPFILE_LoadBitmap * * */static BOOL HLPFILE_LoadBitmap(BYTE* beg, BYTE type, BYTE pack,                                HLPFILE_PARAGRAPH* paragraph){    BYTE*               ptr;    BYTE*               pict_beg;    BITMAPINFO*         bi;    unsigned long       off, csz;    HDC                 hdc;    bi = HeapAlloc(GetProcessHeap(), 0, sizeof(*bi));    if (!bi) return FALSE;    ptr = beg + 2; /* for type and pack */    bi->bmiHeader.biSize          = sizeof(bi->bmiHeader);    bi->bmiHeader.biXPelsPerMeter = fetch_ulong(&ptr);    bi->bmiHeader.biYPelsPerMeter = fetch_ulong(&ptr);    bi->bmiHeader.biPlanes        = fetch_ushort(&ptr);    bi->bmiHeader.biBitCount      = fetch_ushort(&ptr);    bi->bmiHeader.biWidth         = fetch_ulong(&ptr);    bi->bmiHeader.biHeight        = fetch_ulong(&ptr);    bi->bmiHeader.biClrUsed       = fetch_ulong(&ptr);    bi->bmiHeader.biClrImportant  = fetch_ulong(&ptr);    bi->bmiHeader.biCompression   = BI_RGB;    if (bi->bmiHeader.biBitCount > 32) WINE_FIXME("Unknown bit count %u\n", bi->bmiHeader.biBitCount);    if (bi->bmiHeader.biPlanes != 1) WINE_FIXME("Unsupported planes %u\n", bi->bmiHeader.biPlanes);    bi->bmiHeader.biSizeImage = (((bi->bmiHeader.biWidth * bi->bmiHeader.biBitCount + 31) & ~31) / 8) * bi->bmiHeader.biHeight;    WINE_TRACE("planes=%d bc=%d size=(%d,%d)\n",               bi->bmiHeader.biPlanes, bi->bmiHeader.biBitCount,                bi->bmiHeader.biWidth, bi->bmiHeader.biHeight);    csz = fetch_ulong(&ptr);    fetch_ulong(&ptr); /* hotspot size */    off = GET_UINT(ptr, 0);     ptr += 4;    /* GET_UINT(ptr, 0); hotspot offset */ ptr += 4;        /* now read palette info */    if (type == 0x06)    {        unsigned nc = bi->bmiHeader.biClrUsed;        unsigned i;                /* not quite right, especially for bitfields type of compression */        if (!nc && bi->bmiHeader.biBitCount <= 8)            nc = 1 << bi->bmiHeader.biBitCount;                bi = HeapReAlloc(GetProcessHeap(), 0, bi, sizeof(*bi) + nc * sizeof(RGBQUAD));        if (!bi) return FALSE;        for (i = 0; i < nc; i++)        {            bi->bmiColors[i].rgbBlue     = ptr[0];            bi->bmiColors[i].rgbGreen    = ptr[1];            bi->bmiColors[i].rgbRed      = ptr[2];            bi->bmiColors[i].rgbReserved = 0;            ptr += 4;        }    }    pict_beg = HLPFILE_DecompressGfx(beg + off, csz, bi->bmiHeader.biSizeImage, pack);        paragraph->u.gfx.u.bmp.hBitmap = CreateDIBitmap(hdc = GetDC(0), &bi->bmiHeader,                                                     CBM_INIT, pict_beg,                                                     bi, DIB_RGB_COLORS);    ReleaseDC(0, hdc);          if (!paragraph->u.gfx.u.bmp.hBitmap)        WINE_ERR("Couldn't create bitmap\n");        HeapFree(GetProcessHeap(), 0, bi);    if (pict_beg != beg + off) HeapFree(GetProcessHeap(), 0, pict_beg);    return TRUE;}/****************************************************************** *		HLPFILE_LoadMetaFile * * */static BOOL     HLPFILE_LoadMetaFile(BYTE* beg, BYTE pack, HLPFILE_PARAGRAPH* paragraph){    BYTE*               ptr;    unsigned long       size, csize;    unsigned long       off, hsoff;    BYTE*               bits;    LPMETAFILEPICT      lpmfp;    WINE_TRACE("Loading metafile\n");    ptr = beg + 2; /* for type and pack */    lpmfp = &paragraph->u.gfx.u.mfp;    lpmfp->mm = fetch_ushort(&ptr); /* mapping mode */    lpmfp->xExt = GET_USHORT(ptr, 0);    lpmfp->yExt = GET_USHORT(ptr, 2);    ptr += 4;    size = fetch_ulong(&ptr); /* decompressed size */    csize = fetch_ulong(&ptr); /* compressed size */    fetch_ulong(&ptr); /* hotspot size */    off = GET_UINT(ptr, 0);    hsoff = GET_UINT(ptr, 4);    ptr += 8;    WINE_TRACE("sz=%lu csz=%lu (%d,%d) offs=%lu/%u,%lu\n",               size, csize, lpmfp->xExt, lpmfp->yExt, off, ptr - beg, hsoff);    bits = HLPFILE_DecompressGfx(beg + off, csize, size, pack);    if (!bits) return FALSE;    paragraph->cookie = para_metafile;    lpmfp->hMF = SetMetaFileBitsEx(size, bits);    if (!lpmfp->hMF)        WINE_FIXME("Couldn't load metafile\n");    if (bits != beg + off) HeapFree(GetProcessHeap(), 0, bits);    return TRUE;}/****************************************************************** *		HLPFILE_LoadGfxByAddr * * */static  BOOL    HLPFILE_LoadGfxByAddr(HLPFILE *hlpfile, BYTE* ref,                                      unsigned long size,                                       HLPFILE_PARAGRAPH* paragraph){    unsigned    i, numpict;    numpict = GET_USHORT(ref, 2);    WINE_TRACE("Got picture magic=%04x #=%d\n",                GET_USHORT(ref, 0), numpict);    for (i = 0; i < numpict; i++)    {        BYTE*   beg;        BYTE*   ptr;        BYTE    type, pack;        WINE_TRACE("Offset[%d] = %x\n", i, GET_UINT(ref, (1 + i) * 4));        beg = ptr = ref + GET_UINT(ref, (1 + i) * 4);        type = *ptr++;        pack = *ptr++;                switch (type)        {        case 5: /* device dependent bmp */        case 6: /* device independent bmp */            HLPFILE_LoadBitmap(beg, type, pack, paragraph);            break;        case 8:             HLPFILE_LoadMetaFile(beg, pack, paragraph);            break;        default: WINE_FIXME("Unknown type %u\n", type); return FALSE;        }        /* FIXME: hotspots */        /* FIXME: implement support for multiple picture format */        if (numpict != 1) WINE_FIXME("Supporting only one bitmap format per logical bitmap (for now). Using first format\n");        break;    }    return TRUE;}/****************************************************************** *		HLPFILE_LoadGfxByIndex * * */static  BOOL    HLPFILE_LoadGfxByIndex(HLPFILE *hlpfile, unsigned index,                                        HLPFILE_PARAGRAPH* paragraph){    char        tmp[16];    BYTE        *ref, *end;    BOOL        ret;    WINE_TRACE("Loading picture #%d\n", index);    if (index < hlpfile->numBmps && hlpfile->bmps[index] != NULL)    {        paragraph->u.gfx.u.bmp.hBitmap = hlpfile->bmps[index];        return TRUE;    }    sprintf(tmp, "|bm%u", index);    if (!HLPFILE_FindSubFile(tmp, &ref, &end)) {WINE_WARN("no sub file\n"); return FALSE;}    ref += 9;    ret = HLPFILE_LoadGfxByAddr(hlpfile, ref, end - ref, paragraph);    /* cache bitmap */    if (ret && paragraph->cookie == para_bitmap)    {        if (index >= hlpfile->numBmps)        {            hlpfile->numBmps = index + 1;	    if (hlpfile->bmps)        	hlpfile->bmps = HeapReAlloc(GetProcessHeap(), 0, hlpfile->bmps,                                         hlpfile->numBmps * sizeof(hlpfile->bmps[0]));	    else	    	hlpfile->bmps = HeapAlloc(GetProcessHeap(), 0,                                         hlpfile->numBmps * sizeof(hlpfile->bmps[0]));        }        hlpfile->bmps[index] = paragraph->u.gfx.u.bmp.hBitmap;    }    return ret;}/****************************************************************** *		HLPFILE_AllocLink * * */static HLPFILE_LINK*       HLPFILE_AllocLink(int cookie, const char* str, LONG hash,                                             BOOL clrChange, unsigned wnd){    HLPFILE_LINK*  link;    char*          link_str;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?