示例#1
0
/*
---------------------------------------
    创建文字绘制对象 (GDI 字体)
---------------------------------------
*/
static bool_t
qst_crh_winfont (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    leng_t      len;
    LOGFONTA    font;

    CR_NOUSE(parm);

    /* 参数解析 <Height> <FaceName> [Weight] [Width]
                [CharSet] [Quality] [Italic] [Underline]
                [StrikeOut] [Escapement] [Orientation] */
    if (argc < 3)
        return (FALSE);
    if (s_gdi_calls == NULL)
        return (FALSE);

    /* 填充字体生成结构 */
    struct_zero(&font, LOGFONTA);
    font.lfCharSet = DEFAULT_CHARSET;
    font.lfQuality = ANTIALIASED_QUALITY;
    font.lfHeight = (LONG)str2intxA(argv[1]);
    if ((len = str_lenA(argv[2])) >= LF_FACESIZE)
        len = LF_FACESIZE - 1;
    chr_cpyA(font.lfFaceName, argv[2], len);
    if (argc > 3)
        font.lfWeight = (LONG)str2intxA(argv[3]);
    if (argc > 4)
        font.lfWidth = (LONG)str2intxA(argv[4]);
    if (argc > 5)
        font.lfCharSet = (BYTE)str2intxA(argv[5]);
    if (argc > 6)
        font.lfQuality = (BYTE)str2intxA(argv[6]);
    if (argc > 7)
        font.lfItalic = (BYTE)str2intxA(argv[7]);
    if (argc > 8)
        font.lfUnderline = (BYTE)str2intxA(argv[8]);
    if (argc > 9)
        font.lfStrikeOut = (BYTE)str2intxA(argv[9]);
    if (argc > 10)
        font.lfEscapement = (LONG)str2intxA(argv[10]);
    if (argc > 11)
        font.lfOrientation = (LONG)str2intxA(argv[11]);

    /* 生成文字输出对象 */
    if (s_font != NULL)
        CR_VCALL(s_font)->release(s_font);
    s_font = s_gdi_calls->create_fontA(&font);
    if (s_font == NULL)
        return (FALSE);
    return (TRUE);
}
示例#2
0
/*
=======================================
    生成 FB 图形绘制接口
=======================================
*/
CR_API iGFX2_FB*
create_fb_canvas (
  __CR_IN__ const ansi_t*   fb
    )
{
    iGFX2_FB*   rett;

    /* 创建对象 */
    rett = struct_new(iGFX2_FB);
    if (rett == NULL)
        return (NULL);
    struct_zero(&rett->__back__, sIMAGE);

    /* 初始化 FB */
    if (fb == NULL)
        fb = "/dev/fb0";
    rett->m_file = open(fb, O_RDWR);
    if (rett->m_file < 0)
        return (NULL);
    if (ioctl(rett->m_file, FBIOGET_FSCREENINFO, &rett->m_finfo) < 0)
        goto _failure;
    if (ioctl(rett->m_file, FBIOGET_VSCREENINFO, &rett->m_vinfo) < 0)
        goto _failure;
    if (rett->m_vinfo.bits_per_pixel <= 8 ||
        rett->m_vinfo.red.msb_right || rett->m_vinfo.green.msb_right ||
        rett->m_vinfo.blue.msb_right)
        goto _failure;

    /* 填充参数结构 */
    rett->__back__.bpl = rett->m_finfo.line_length;
    if (rett->__back__.bpl % 16 == 0)
        rett->__back__.align = 16;
    else
    if (rett->__back__.bpl % 8 == 0)
        rett->__back__.align = 8;
    else
    if (rett->__back__.bpl % 4 == 0)
        rett->__back__.align = 4;
    rect_set_wh(&rett->__back__.clip_win, 0, 0, rett->m_vinfo.xres,
                 rett->m_vinfo.yres);
    struct_cpy(&rett->__back__.position, &rett->__back__.clip_win, sRECT);
    rett->__back__.size  = rett->__back__.bpl;
    rett->__back__.size *= rett->m_vinfo.yres;

    /* 识别颜色格式 */
    if (rett->m_vinfo.bits_per_pixel == 16) {
        if (rett->m_vinfo.red.length == 5 &&
            rett->m_vinfo.green.length == 6 &&
            rett->m_vinfo.blue.length == 5 &&
            rett->m_vinfo.red.offset == 11 &&
            rett->m_vinfo.green.offset == 5 &&
            rett->m_vinfo.blue.offset == 0) {
            rett->__back__.fmt = CR_ARGB565;
            rett->__vptr__ = &s_img16_vtbl;
        }
        else
        if (rett->m_vinfo.red.length == 5 &&
            rett->m_vinfo.green.length == 5 &&
            rett->m_vinfo.blue.length == 5 &&
            rett->m_vinfo.red.offset == 10 &&
            rett->m_vinfo.green.offset == 5 &&
            rett->m_vinfo.blue.offset == 0) {
            if (rett->m_vinfo.transp.length == 0) {
                rett->__back__.fmt = CR_ARGBX555;
                rett->__vptr__ = &s_img15_vtbl;
            }
            else {
                rett->__back__.fmt = CR_ARGB1555;
                rett->__vptr__ = &s_img17_vtbl;
            }
        }
        else
        if (rett->m_vinfo.red.length == 4 &&
            rett->m_vinfo.green.length == 4 &&
            rett->m_vinfo.blue.length == 4 &&
            rett->m_vinfo.red.offset == 8 &&
            rett->m_vinfo.green.offset == 4 &&
            rett->m_vinfo.blue.offset == 0) {
            rett->__back__.fmt = CR_ARGB4444;
            rett->__vptr__ = &s_img12_vtbl;
        }
        else {
            goto _failure;
        }
        rett->__back__.bpc = 2;
    }
    else
    if (rett->m_vinfo.bits_per_pixel == 32) {
        rett->__back__.bpc = 4;
        rett->__back__.fmt = CR_ARGB8888;
        rett->__vptr__ = &s_img32_vtbl;
    }
    else
    if (rett->m_vinfo.bits_per_pixel == 24) {
        rett->__back__.bpc = 3;
        rett->__back__.fmt = CR_ARGB888;
        rett->__vptr__ = &s_img24_vtbl;
    }
    else {
        goto _failure;
    }
    rett->__back__.data = (byte_t*)mem_malloc(rett->__back__.size + 16);
    if (rett->__back__.data == NULL)
        goto _failure;
    mem_zero(rett->__back__.data, rett->__back__.size);

    /* 映射前台缓冲 */
    rett->m_size = (uint_t)rett->__back__.size;
    rett->m_main = mmap(NULL, rett->m_size, PROT_READ | PROT_WRITE,
                        MAP_SHARED, rett->m_file, 0);
    if (rett->m_main == MAP_FAILED) {
        mem_free(rett->__back__.data);
        goto _failure;
    }
    mem_zero(rett->m_main, rett->m_size);
    return (rett);

_failure:
    close(rett->m_file);
    return (NULL);
}
示例#3
0
/*
=======================================
    生成 DX8 图形绘制接口
=======================================
*/
CR_API iGFX2_DX8M*
create_dx8_canvas (
  __CR_IN__ const sDX8_HDLE*    hdle,
  __CR_IN__ uint_t              scn_cw,
  __CR_IN__ uint_t              scn_ch,
  __CR_IN__ bool_t              full
    )
{
    RECT        rect;
    HRESULT     retc;
    sD3D8_TEXR* fill;
    iGFX2_DX8M* rett;

    /* 使用伪全屏 */
    if (full) {
        scn_cw = GetSystemMetrics(SM_CXSCREEN);
        scn_ch = GetSystemMetrics(SM_CYSCREEN);
        if (!SetWindowPos(hdle->hwnd, HWND_TOP, 0, 0,
                          scn_cw, scn_ch, SWP_SHOWWINDOW))
            return (NULL);
    }
    else if (scn_cw == 0 || scn_ch == 0)
    {
        /* 非法宽高, 获取窗口大小 */
        if (!GetClientRect(hdle->hwnd, &rect))
            return (NULL);
        scn_cw = rect.right;
        scn_ch = rect.bottom;
    }

    /* 生成对象 */
    rett = struct_new(iGFX2_DX8M);
    if (rett == NULL)
        return (NULL);
    struct_zero(&rett->__back__, sIMAGE);

    /* 创建 D3D8 设备 */
    if (hdle->main == NULL) {
        rett->m_main = hdle->call->create_main(hdle->hwnd, FALSE,
                            scn_cw, scn_ch, D3DFMT_UNKNOWN, D3DFMT_UNKNOWN,
                                        FALSE, D3DMULTISAMPLE_NONE);
        if (rett->m_main == NULL)
            goto _failure1;
    }
    else {
        rett->m_main = hdle->main;
    }

    /* 创建填充用的纹理 */
    fill = hdle->call->create_tex2(rett->m_main, 1, 1, D3DFMT_A8R8G8B8,
                                   D3DPOOL_MANAGED, 0, 1);
    if (fill == NULL)
        goto _failure2;
    rett->m_fill = (iGFX2*)create_dx8_bitmap(rett, fill, FALSE);
    if (rett->m_fill == NULL) {
        hdle->call->release_texr(fill);
        goto _failure2;
    }
    if (!CR_VCALL(rett->m_fill)->clear(rett->m_fill, 0xFFFFFFFFUL, 0))
        goto _failure3;

    /* 生成精灵绘制对象 */
    retc = D3DXCreateSprite(rett->m_main->dev, &rett->m_sprt);
    if (FAILED(retc))
        goto _failure3;

    /* 返回生成的对象 */
    rett->__vptr__ = &s_canvas_vtbl;
    struct_cpy(&rett->m_hdle, hdle, sDX8_HDLE);
    rect_set_wh(&rett->__back__.clip_win, 0, 0, scn_cw, scn_ch);
    struct_cpy(&rett->__back__.position, &rett->__back__.clip_win, sRECT);
    return (rett);

_failure3:
    CR_VCALL(rett->m_fill)->release(rett->m_fill);
_failure2:
    if (hdle->main == NULL)
        hdle->call->release_main(rett->m_main);
_failure1:
    mem_free(rett);
    return (NULL);
}
示例#4
0
/*
=======================================
    KrKr XP3 文件读取
=======================================
*/
CR_API sFMT_PRT*
load_krkr_xp3 (
    __CR_IO__ iDATIN*         datin,
    __CR_IN__ const sLOADER*  param
)
{
    int16u          idx;
    int16u          len;
    int32u          attr;
    int64u          tots;
    int64u          tsz1;
    int64u          tsz2;
    int64u          pksz;
    int64u          unsz;
    leng_t          back;
    sARRAY          list;
    byte_t*         info;
    byte_t*         pntr;
    wide_t*         name;
    sXP3_HDR        head;
    iPAK_XP3*       port;
    sFMT_PRT*       rett;
    sPAK_XP3_FILE   temp;

    /* 必须使用自己私有的读取接口 */
    datin = create_file_inX(param);
    if (datin == NULL)
        return (NULL);
    array_initT(&list, sPAK_XP3_FILE);
    list.free = xp3_free;

    /* 读取文件头信息 */
    if (!(CR_VCALL(datin)->geType(datin, &head, sXP3_HDR)))
        goto _failure1;
    if (mem_cmp(head.tag, "XP3\r\n \n\x1A\x8B\x67\x01", 11) != 0)
        goto _failure1;
    head.idx_pos = QWORD_LE(head.idx_pos);

    /* 读取文件索引表 */
    if (!CR_VCALL(datin)->seek64(datin, head.idx_pos, SEEK_SET))
        goto _failure1;
    if (!CR_VCALL(datin)->getb_no(datin, head.tag))
        goto _failure1;
    if (head.tag[0])
    {
        /* ZLib 压缩的索引表 */
        if (!CR_VCALL(datin)->getq_le(datin, &pksz))
            goto _failure1;
        if (!CR_VCALL(datin)->getq_le(datin, &unsz))
            goto _failure1;
        pntr = (byte_t*)mem_malloc64(pksz);
        if (pntr == NULL)
            goto _failure1;
        back = CR_VCALL(datin)->read(datin, pntr, (leng_t)pksz);
        if (back != (leng_t)pksz) {
            mem_free(pntr);
            goto _failure1;
        }
        info = (byte_t*)mem_malloc64(unsz);
        if (info == NULL) {
            mem_free(pntr);
            goto _failure1;
        }
        back = uncompr_zlib(info, (leng_t)unsz, pntr, (leng_t)pksz);
        mem_free(pntr);
        if (back != (leng_t)unsz)
            goto _failure2;
    }
    else
    {
        /* 直接读起索引表 */
        if (!CR_VCALL(datin)->getq_le(datin, &unsz))
            goto _failure1;
        info = (byte_t*)mem_malloc64(unsz);
        if (info == NULL)
            goto _failure1;
        back = CR_VCALL(datin)->read(datin, info, (leng_t)unsz);
        if (back != (leng_t)unsz)
            goto _failure2;
    }

    /* 设置加密类型 (如果有的话) */
    if (param->aprm != NULL &&
            *(byte_t*)param->aprm != 0x00)
        attr = PAK_FILE_ENC;
    else
        attr = 0;

    /* 加载文件信息表 */
    for (pntr = info, pksz = 0; pksz < unsz;)
    {
        /* "File" 数据块 */
        if (mem_cmp(pntr, "File", 4) != 0)
            break;
        mem_cpy(&tots, pntr + 4, sizeof(int64u));
        tots = QWORD_LE(tots);
        pntr += 12;
        pksz += 12;
        if (tots <= 12 + 22 + 12 + 28 || tots > unsz - pksz)
            goto _failure2;

        /* "info" 文件总信息 */
        if (mem_cmp(pntr, "info", 4) != 0)
            goto _failure2;
        mem_cpy(&tsz1, pntr + 4, sizeof(int64u));
        tsz1 = QWORD_LE(tsz1);
        pntr += 12;
        pksz += 12;
        if (tsz1 <= 22 || tsz1 > tots - 12 - 12 - 28)
            goto _failure2;

        /* 填充一些文件信息结构成员 */
        struct_zero(&temp, sPAK_XP3_FILE);
        mem_cpy(&temp.protect,   pntr +  0, sizeof(int32u));
        mem_cpy(&temp.base.size, pntr +  4, sizeof(int64u));
        mem_cpy(&temp.base.pack, pntr + 12, sizeof(int64u));
        temp.base.skip = sizeof(sPAK_XP3_FILE);
        temp.base.attr = attr;
        temp.protect   = DWORD_LE(temp.protect);
        temp.base.size = QWORD_LE(temp.base.size);
        temp.base.pack = QWORD_LE(temp.base.pack);

        /* 读取文件名 UTF-16 无\0结尾 */
        mem_cpy(&len, pntr + 20, sizeof(int16u));
        len = WORD_LE(len);
        if ((int64u)len > tsz1 - 22)
            goto _failure2;
        name = str_allocW(len + 1);
        if (name == NULL)
            goto _failure2;
        for (idx = 0; idx < len; idx++) {
            mem_cpy(&name[idx], pntr + 22 + ((leng_t)idx) * 2, 2);
            name[idx] = WORD_LE(name[idx]);
        }
        name[idx] = 0x0000;
        temp.base.name = utf16_to_utf8(name);
        mem_free(name);
        if (temp.base.name == NULL)
            goto _failure2;
        pntr += (leng_t)tsz1;
        pksz += (leng_t)tsz1;

        /* "segm" 文件分段信息 */
        if (mem_cmp(pntr, "segm", 4) != 0)
            goto _failure3;
        mem_cpy(&tsz2, pntr + 4, sizeof(int64u));
        tsz2 = QWORD_LE(tsz2);
        pntr += 12;
        pksz += 12;
        if (tsz2 < 28 || tsz2 % 28 != 0 ||
                tsz2 > tots - 12 - tsz1 - 12)
            goto _failure3;

        /* 读取所有分段信息 */
        temp.segm_lst = mem_talloc64(tsz2 / 28, sPAK_XP3_SEGM);
        if (temp.segm_lst == NULL)
            goto _failure3;
        temp.segm_cnt = (leng_t)(tsz2 / 28);
        mem_cpy(temp.segm_lst, pntr, (leng_t)tsz2);
        for (back = 0; back < temp.segm_cnt; back++) {
            temp.segm_lst[back].zlib   = DWORD_LE(temp.segm_lst[back].zlib);
            temp.segm_lst[back].offset = QWORD_LE(temp.segm_lst[back].offset);
            temp.segm_lst[back].unsize = QWORD_LE(temp.segm_lst[back].unsize);
            temp.segm_lst[back].pksize = QWORD_LE(temp.segm_lst[back].pksize);
            if (temp.segm_lst[back].unsize > temp.base.size)
                goto _failure4;
            if (temp.segm_lst[back].pksize > temp.base.pack)
                goto _failure4;
        }
        pntr += (leng_t)tsz2;
        pksz += (leng_t)tsz2;

        /* 其他非重要数据段 */
        if (tots > 12 + tsz1 + 12 + tsz2)
        {
            tots -= 12 + tsz1 + 12 + tsz2;

            /* "adlr" 附加数据 */
            if (mem_cmp(pntr, "adlr", 4) == 0) {
                if (tots < 16)
                    goto _failure4;
                mem_cpy(&temp.adlr_key, pntr + 4, sizeof(int32u));
                temp.adlr_key = DWORD_LE(temp.adlr_key);
            }
            pntr += (leng_t)tots;
            pksz += (leng_t)tots;
        }

        /* 用第一段设置剩下的成员 */
        temp.base.offs = temp.segm_lst[0].offset;
        if (temp.segm_lst[0].zlib) {
            if (attr == 0)
                temp.base.memo = "ZLib";
            else
                temp.base.memo = "ZLib + Encrypt";
            temp.base.attr |= PAK_FILE_CMP;
        }
        else {
            if (attr == 0)
                temp.base.memo = "Store";
            else
                temp.base.memo = "Encrypt";
        }

        /* 文件信息压入列表 */
        if (array_push_growT(&list, sPAK_XP3_FILE, &temp) == NULL)
            goto _failure4;
    }
    mem_free(info);

    /* 固定一下列表大小 */
    if (!array_no_growT(&list, sPAK_XP3_FILE))
        goto _failure1;

    /* 生成读包接口对象 */
    port = struct_new(iPAK_XP3);
    if (port == NULL)
        goto _failure1;
    port->m_file = datin;
    port->m_cnt = array_get_sizeT(&list, sPAK_XP3_FILE);
    port->pack.__filelst__ = array_get_dataT(&list, sPAK_FILE);
    port->pack.__vptr__ = &s_pack_vtbl;
    if (!pack_init_list((iPACKAGE*)port, TRUE)) {
        mem_free(port);
        goto _failure1;
    }

    /* 设置解密回调 (传入名称字符串) */
    if (attr != 0) {
        decode_setup(port, (ansi_t*)param->aprm);
    }
    else {
        port->decode_file = NULL;
        port->decode_block = NULL;
    }

    /* 返回读取的文件数据 */
    rett = struct_new(sFMT_PRT);
    if (rett == NULL) {
        iPAK_XP3_release((iPACKAGE*)port);
        return (NULL);
    }
    rett->type = CR_FMTZ_PRT;
    rett->port = (iPORT*)port;
    rett->more = "iPACKAGE";
    rett->infor = "KiriKiri2 XP3 Archive (XP3)";
    return (rett);

_failure4:
    mem_free(temp.segm_lst);
_failure3:
    mem_free(temp.base.name);
_failure2:
    mem_free(info);
_failure1:
    array_freeT(&list, sPAK_XP3_FILE);
    CR_VCALL(datin)->release(datin);
    return (NULL);
}
示例#5
0
/*
=======================================
    RAR 文件读取
=======================================
*/
CR_API sFMT_PRT*
load_rar (
  __CR_IO__ iDATIN*         datin,
  __CR_IN__ const sLOADER*  param
    )
{
    HANDLE                  rar;
    sARRAY                  list;
    int32u                  attr;
    sint_t                  retc;
    leng_t                  fpos;
    iPAK_RAR*               port;
    sFMT_PRT*               rett;
    sPAK_RAR_FILE           temp;
    RARHeaderDataEx         info;
    RAROpenArchiveDataEx    open;

    /* 只支持磁盘文件 */
    if (param->type != CR_LDR_ANSI &&
        param->type != CR_LDR_WIDE)
        return (NULL);

    /* 列表模式打开 RAR 文件 */
    struct_zero(&open, RAROpenArchiveDataEx);
    if (param->type == CR_LDR_ANSI)
        open.ArcName = (ansi_t*)param->name.ansi;
    else
        open.ArcNameW = (wide_t*)param->name.wide;
    open.OpenMode = RAR_OM_LIST;
    rar = RAROpenArchiveEx(&open);
    if (rar == NULL)
        return (NULL);
    if (param->aprm != NULL &&
        *(byte_t*)param->aprm != 0x00) {
        RARSetPassword(rar, (ansi_t*)param->aprm);
        attr = PAK_FILE_ENC;
    }
    else {
        attr = 0;
    }

    /* 开始逐个文件读取信息并定位 */
    array_initT(&list, sPAK_RAR_FILE);
    list.free = rar_free;
    struct_zero(&info, RARHeaderDataEx);
    for (fpos = 0; ; fpos++)
    {
        /* 读取一个文件记录头 */
        retc = RARReadHeaderEx(rar, &info);
        if (retc == ERAR_END_ARCHIVE)
            break;
        if (retc != ERAR_SUCCESS)
            goto _failure1;

        /* 目录文件不加入列表 */
        if (info.Flags & RHDF_DIRECTORY) {
            retc = RARProcessFile(rar, RAR_SKIP, NULL, NULL);
            if (retc != ERAR_SUCCESS)
                goto _failure1;
            continue;
        }

        /* 文件名统一使用 UTF-8 编码 */
        struct_zero(&temp, sPAK_RAR_FILE);
        temp.base.name = local_to_utf8(param->page, info.FileName);
        if (temp.base.name == NULL)
            goto _failure1;

        /* 设置公用文件属性 (偏移没有实际用处) */
        temp.base.skip = sizeof(sPAK_RAR_FILE);
        temp.base.attr = attr;
        temp.base.offs = 0;
        temp.base.pack = mk_size(info.PackSizeHigh, info.PackSize);
        temp.base.size = mk_size(info.UnpSizeHigh, info.UnpSize);
        if (info.Method != 0x30)
            temp.base.attr |= PAK_FILE_CMP;
        if (info.Flags & RHDF_ENCRYPTED)
            temp.base.attr |=  PAK_FILE_ENC;
        else
            temp.base.attr &= ~PAK_FILE_ENC;
        switch (info.Method)
        {
            case 0x30: temp.base.memo = "Storing";             break;
            case 0x31: temp.base.memo = "Fastest compression"; break;
            case 0x32: temp.base.memo = "Fast compression";    break;
            case 0x33: temp.base.memo = "Normal compression";  break;
            case 0x34: temp.base.memo = "Good compression";    break;
            case 0x35: temp.base.memo = "Best compression";    break;
            default:   temp.base.memo = "Unknown compression"; break;
        }

        /* 设置私有文件属性 */
        temp.id = fpos;
        temp.crc32 = (int32u)(info.FileCRC);
        temp.fattr = (int32u)(info.FileAttr);
        temp.ftime = (int16u)(info.FileTime & 0xFFFF);
        temp.fdate = (int16u)(info.FileTime >> 16);
        temp.htype = (int32u)(info.HashType);
        mem_cpy(temp.hash, info.Hash, sizeof(temp.hash));

        /* 文件信息压入列表 */
        if (array_push_growT(&list, sPAK_RAR_FILE, &temp) == NULL) {
            mem_free(temp.base.name);
            goto _failure1;
        }

        /* 跳过当前已读文件 */
        retc = RARProcessFile(rar, RAR_SKIP, NULL, NULL);
        if (retc != ERAR_SUCCESS && retc != ERAR_BAD_DATA)
            goto _failure1;
    }

    /* 固定一下列表大小 */
    if (!array_no_growT(&list, sPAK_RAR_FILE))
        goto _failure1;

    /* 生成读包接口对象 */
    port = struct_new(iPAK_RAR);
    if (port == NULL)
        goto _failure1;

    /* 保存需要用到的参数 */
    port->m_temp = NULL;
    if (attr == 0) {
        port->m_pass = NULL;
    }
    else {
        port->m_pass = str_dupA((ansi_t*)param->aprm);
        if (port->m_pass == NULL)
            goto _failure2;
    }
    if (param->type == CR_LDR_ANSI) {
        port->m_wide = NULL;
        port->m_ansi = str_dupA(param->name.ansi);
        if (port->m_ansi == NULL)
            goto _failure3;
    }
    else {
        port->m_ansi = NULL;
        port->m_wide = str_dupW(param->name.wide);
        if (port->m_wide == NULL)
            goto _failure3;
    }
    port->m_rar = NULL;
    port->m_cur = (leng_t)-1;
    port->m_cnt = array_get_sizeT(&list, sPAK_RAR_FILE);
    port->pack.__filelst__ = array_get_dataT(&list, sPAK_FILE);
    port->pack.__vptr__ = &s_pack_vtbl;
    if (!pack_init_list((iPACKAGE*)port, TRUE))
        goto _failure4;
    RARCloseArchive(rar);

    /* 返回读取的文件数据 */
    rett = struct_new(sFMT_PRT);
    if (rett == NULL) {
        iPAK_RAR_release((iPACKAGE*)port);
        return (NULL);
    }
    CR_NOUSE(datin);
    rett->type = CR_FMTZ_PRT;
    rett->port = (iPORT*)port;
    rett->more = "iPACKAGE";
    rett->infor = "Roshal ARchive (RAR)";
    return (rett);

_failure4:
    TRY_FREE(port->m_ansi);
    TRY_FREE(port->m_wide);
_failure3:
    TRY_FREE(port->m_pass);
_failure2:
    mem_free(port);
_failure1:
    array_freeT(&list, sPAK_RAR_FILE);
    RARCloseArchive(rar);
    return (NULL);
}
示例#6
0
/*
---------------------------------------
    读取文件数据
---------------------------------------
*/
static bool_t
iPAK_RAR_getFileData (
  __CR_IN__ iPACKAGE*   that,
  __CR_OT__ sBUFFER*    buff,
  __CR_IN__ int64u      index,
  __CR_IN__ bool_t      hash
    )
{
    sint_t                  rett;
    int64u                  size;
    void_t*                 data;
    iPAK_RAR*               real;
    sPAK_RAR_FILE*          item;
    RARHeaderDataEx         info;
    RAROpenArchiveDataEx    open;

    /* 定位文件索引 */
    CR_NOUSE(hash);
    real = (iPAK_RAR*)that;
    if (index >= real->m_cnt)
        return (FALSE);
    item = (sPAK_RAR_FILE*)real->pack.__filelst__;
    item += (leng_t)index;

    /* 获取文件数据 (0大小文件分配1个字节) */
    size = item->base.size;
    if (size == 0) {
        data = mem_malloc(1);
        if (data == NULL)
            return (FALSE);
        size = 1;
        *(byte_t*)data = 0x00;
    }
    else {
        real->m_temp = data = mem_malloc64(size);
        if (data == NULL)
            return (FALSE);

        /* RAR 只能顺序读取文件 */
        if (real->m_rar == NULL || item->id < real->m_cur)
        {
            /* 需要重新打开封包 */
            if (real->m_rar != NULL) {
                RARCloseArchive(real->m_rar);
                real->m_rar = NULL;
            }
            struct_zero(&open, RAROpenArchiveDataEx);
            if (real->m_ansi != NULL)
                open.ArcName = real->m_ansi;
            else
                open.ArcNameW = real->m_wide;
            open.OpenMode = RAR_OM_EXTRACT;
            open.Callback = rar_mem_copy;
            open.UserData = (LPARAM)(&real->m_temp);
            real->m_rar = RAROpenArchiveEx(&open);
            if (real->m_rar == NULL)
                goto _failure1;
            if (real->m_pass != NULL)
                RARSetPassword(real->m_rar, real->m_pass);
            real->m_cur = 0;
        }

        /* 定位到指定文件 */
        struct_zero(&info, RARHeaderDataEx);
        while (real->m_cur != item->id) {
            rett = RARReadHeaderEx(real->m_rar, &info);
            if (rett != ERAR_SUCCESS)
                goto _failure2;
            rett = RARProcessFile(real->m_rar, RAR_SKIP, NULL, NULL);
            if (rett != ERAR_SUCCESS && rett != ERAR_BAD_DATA)
                goto _failure2;
            real->m_cur += 1;
        }

        /* 测试目标文件就不会有磁盘操作了 */
        rett = RARReadHeaderEx(real->m_rar, &info);
        if (rett != ERAR_SUCCESS)
            goto _failure2;
        rett = RARProcessFile(real->m_rar, RAR_TEST, NULL, NULL);
        if (rett != ERAR_SUCCESS)
            goto _failure2;
        real->m_cur += 1;
    }

    /* 返回文件数据 */
    return (buffer_init(buff, data, (leng_t)size, TRUE));

_failure2:
    RARCloseArchive(real->m_rar);
    real->m_rar = NULL;
_failure1:
    real->m_cur = (leng_t)-1;
    mem_free(data);
    return (FALSE);
}
示例#7
0
/*
=======================================
    FMODEx 文件读取
=======================================
*/
CR_API sFMT_PRT*
load_fmodex (
  __CR_IO__ iDATIN*         datin,
  __CR_IN__ const sLOADER*  param
    )
{
    uint_t                  size;
    void_t*                 data;
    ansi_t*                 path;
    sFMT_PRT*               rett;
    FMOD_MODE               mode;
    iXMM_FMOD*              port;
    FMOD_SOUND*             sound;
    FMOD_RESULT             result;
    FMOD_CHANNEL*           channel;
    FMOD_CREATESOUNDEXINFO  ex_info;

    /* 必须先初始化 */
    if (s_fmodex == NULL)
        return (NULL);
    mode = FMOD_LOOP_OFF | FMOD_2D | FMOD_HARDWARE | FMOD_ACCURATETIME;

    /* 不支持文件区段功能 */
    switch (param->type)
    {
        case CR_LDR_ANSI:
            data = NULL;
            result = FMOD_System_CreateStream(s_fmodex, param->name.ansi,
                                              mode, NULL, &sound);
            break;

        case CR_LDR_WIDE:
            data = NULL;
            path = utf16_to_local(CR_LOCAL, param->name.wide);
            if (path == NULL)
                return (NULL);
            result = FMOD_System_CreateStream(s_fmodex, path, mode,
                                              NULL, &sound);
            mem_free(path);
            break;

        case CR_LDR_BUFF:
            if (cut_size(&size, param->buff.size))
                return (NULL);
            data = mem_dup(param->buff.data, param->buff.size);
            if (data == NULL)
                return (NULL);
            path = (ansi_t*)data;
            mode |= FMOD_OPENMEMORY;
            mem_zero(&ex_info, sizeof(ex_info));
            ex_info.cbsize = sizeof(ex_info);
            ex_info.length = size;
            result = FMOD_System_CreateStream(s_fmodex, path, mode,
                                              &ex_info, &sound);
            break;

        default:
            return (NULL);
    }

    /* 无法支持的格式 */
    if (result != FMOD_OK)
        goto _failure1;

    /* 生成播放通道对象 */
    result = FMOD_System_PlaySound(s_fmodex, FMOD_CHANNEL_FREE,
                                   sound, TRUE, &channel);
    if (result != FMOD_OK)
        goto _failure2;

    /* 生成媒体播放接口对象 */
    port = struct_new(iXMM_FMOD);
    if (port == NULL)
        goto _failure3;
    struct_zero(port, iXMM_FMOD);
    port->m_dat = data;
    port->m_snd = sound;
    port->m_chn = channel;
    if (!fmodex_info(port)) {
        iXMM_FMOD_release((iXMMEDIA*)port);
        return (NULL);
    }
    port->xmms.__volume__ = 100;
    port->xmms.__vptr__ = &s_xmms_vtbl;

    /* 返回读取的文件数据 */
    rett = struct_new(sFMT_PRT);
    if (rett == NULL) {
        iXMM_FMOD_release((iXMMEDIA*)port);
        return (NULL);
    }
    CR_NOUSE(datin);
    rett->type = CR_FMTZ_PRT;
    rett->port = (iPORT*)port;
    rett->more = "iXMMEDIA";
    rett->infor = port->m_inf;
    return (rett);

_failure3:
    FMOD_Channel_Stop(channel);
_failure2:
    FMOD_Sound_Release(sound);
_failure1:
    TRY_FREE(data);
    return (NULL);
}