Exemple #1
0
/*
---------------------------------------
    释放接口
---------------------------------------
*/
static void_t
iPAK_RAR_release (
  __CR_IN__ iPACKAGE*   that
    )
{
    leng_t          idx;
    iPAK_RAR*       real;
    sPAK_RAR_FILE*  list;

    pack_free_list(that);
    real = (iPAK_RAR*)that;
    list = (sPAK_RAR_FILE*)real->pack.__filelst__;
    if (list != NULL) {
        for (idx = 0; idx < real->m_cnt; idx++) {
            mem_free(list[idx].base.find);
            mem_free(list[idx].base.name);
        }
        mem_free(list);
    }
    if (real->m_rar != NULL)
        RARCloseArchive(real->m_rar);
    TRY_FREE(real->m_ansi);
    TRY_FREE(real->m_wide);
    TRY_FREE(real->m_pass);
    mem_free(that);
}
Exemple #2
0
/* tries opening a file in a temporary win structure, and displays errors if unable */
int
board_load_popup (window_board_t *win, int append, char *filename)
{
	int i;
	int ret = 0;
	window_board_t *win1 = calloc (1, sizeof (window_board_t));

	if (board_load (win1, filename)) {
		if (append) {
			int n = win->n_boards;
			for (i = 0; i < win1->n_boards; i++)
				board_window_append_board (win, win1->boards[i]);
			if (win->n_boards > n) /* set to first new board */
				win->cur = n;
		} else {
			MOVE_PTR (win->filename, win1->filename);
			MOVE_PTR (win->title, win1->title);
			MOVE_PTR (win->subtitle, win1->subtitle);
			MOVE_PTR (win->team1, win1->team1);
			MOVE_PTR (win->team2, win1->team2);

			for (i = 0; i < win->n_boards; i++)
				if (win->boards[i])
					board_free (win->boards[i]);
			win->boards = win1->boards;
			win->n_boards = win1->n_boards;
			win->n_boards_alloc = win1->n_boards_alloc;
			win->cur = 0;
		}

		card_window_update(win->boards[win->cur]->dealt_cards);
		show_board(win->boards[win->cur], REDRAW_FULL);
		recently_used_add (filename);

		ret = 1;
	} else {
		GtkWidget *error = gtk_message_dialog_new (GTK_WINDOW (win->window),
				GTK_DIALOG_DESTROY_WITH_PARENT,
				GTK_MESSAGE_ERROR,
				GTK_BUTTONS_CLOSE,
				_("Error loading file '%s': %s"),
				filename, g_strerror (errno));
		gtk_dialog_run (GTK_DIALOG (error));
		gtk_widget_destroy (error);
	}

	TRY_FREE (win1->filename);
	TRY_FREE (win1->title);
	TRY_FREE (win1->subtitle);
	TRY_FREE (win1->team1);
	TRY_FREE (win1->team2);
	free (win1);

	return ret;
}
Exemple #3
0
/*
=======================================
    读入配置文件
=======================================
*/
CR_API void_t
qst_load_cfg (
  __CR_OT__ sQCOM_conf* cfgs
    )
{
    sINIu*  ini;
    ansi_t* str;

    /* 加载配置文件 */
    TRY_FREE(cfgs->font_face);
    str = file_load_as_strA(QST_PATH_CONFIG WIN_ICONF);
    if (str == NULL)
        goto _load_defs;
    ini = ini_parseU(str);
    mem_free(str);
    if (ini == NULL)
        goto _load_defs;

    /* 读入配置参数 */
    cfgs->color = ini_key_intx32U("qcom::color", 0xFFC0C0C0UL, ini);
    cfgs->bkcolor = ini_key_intx32U("qcom::bkcolor", 0xFF000000UL, ini);
    cfgs->font_size = ini_key_intxU("qcom::font_size", 12, ini);
    cfgs->font_face = ini_key_stringU("qcom::font_face", ini);
    ini_closeU(ini);
    return;

_load_defs:
    cfgs->color = 0xFFC0C0C0UL;
    cfgs->bkcolor = 0xFF000000UL;
    cfgs->font_size = 12;
    cfgs->font_face = NULL;
}
Exemple #4
0
/*
---------------------------------------
    文件单元释放回调
---------------------------------------
*/
static void_t
rar_free (
  __CR_IN__ void_t* obj
    )
{
    sPAK_RAR_FILE*  unit;

    unit = (sPAK_RAR_FILE*)obj;
    TRY_FREE(unit->base.find);
    mem_free(unit->base.name);
}
Exemple #5
0
/*
---------------------------------------
    文件单元释放回调
---------------------------------------
*/
static void_t
xp3_free (
    __CR_IN__ void_t* obj
)
{
    sPAK_XP3_FILE*  unit;

    unit = (sPAK_XP3_FILE*)obj;
    mem_free(unit->segm_lst);
    TRY_FREE(unit->base.find);
    mem_free(unit->base.name);
}
Exemple #6
0
/*
---------------------------------------
    释放接口
---------------------------------------
*/
static void_t
iXMM_FMOD_release (
  __CR_IN__ iXMMEDIA*   that
    )
{
    iXMM_FMOD*  real;

    real = (iXMM_FMOD*)that;
    FMOD_Channel_Stop(real->m_chn);
    FMOD_Sound_Release(real->m_snd);
    TRY_FREE(real->m_dat);
    mem_free(that);
}
Exemple #7
0
/*
=======================================
    主程序
=======================================
*/
int main (int argc, char *argv[])
{
    fbuf_t file;
    const ansi_t *root;

    /* 建立 CrHack 系统 */
    if (!set_app_type(CR_APP_CUI))
        return (QST_ERROR);

    /* 参数解析 [搜索根目录] */
    if (argc < 1) {
        printf("filehash [directory]\n");
        return (QST_ERROR);
    }

    /* 生成性能测试对象 */
    s_profile = timer_new();

    /* 生成输出文件 */
    file_deleteA("__hash__.old");
    file_renameA("__hash__.old", "__hash__.txt");
    file = file_buf_openA("__hash__.txt", CR_FO_WO);
    if (file == NULL) {
        printf("can't create output file\n");
        return (QST_ERROR);
    }

    /* 枚举所有文件 */
    if (argc == 1)
        root = "";
    else
        root = argv[1];
    s_rdata = NULL;
    mem_info(&s_total, &s_avail);
    s_total = (s_total * 618) / 1000;
    file_searchA(root, TRUE, FALSE, FALSE, "*.*", hasher, file);

    /* 释放内存 */
    file_buf_close(file);
    timer_del(s_profile);
    TRY_FREE(s_rdata);
    return (QST_OKAY);
}
Exemple #8
0
/*
---------------------------------------
    打开 UDPv4 通讯接口
---------------------------------------
*/
static bool_t
qst_com_udpv4 (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    uint_t      port;
    socket_t    netw;

    /* 参数解析 <目标地址> <端口号> */
    if (argc < 3)
        return (FALSE);
    port = str2intxA(argv[2]);
    if (port > 65535)
        return (FALSE);

    sQstComm*   ctx = (sQstComm*)parm;

    /* 关闭当前接口并打开 UDPv4 连接 */
    netw = client_udp_open(argv[1], (int16u)port);
    if (netw == NULL)
        return (FALSE);
    socket_set_timeout(netw, QCOM_SNDTOUT, QCOM_CUTDOWN);

    /* 设置工作参数 */
    qst_com_close(parm, argc, argv);
    ctx->comm.obj.netw = netw;
    ctx->comm.send = qst_udpv4_send;

    /* 启动接收线程 */
    ctx->comm.thrd = thread_new(0, qst_udpv4_main, parm, FALSE);
    if (ctx->comm.thrd == NULL) {
        socket_close(netw);
        return (FALSE);
    }
    TRY_FREE(ctx->comm.title);
    ctx->comm.title = str_fmtA(" - UDPv4 \"%s\", %u", argv[1], port);
    qst_update_title(ctx);
    return (TRUE);
}
Exemple #9
0
/*
---------------------------------------
    设置通讯接收模式
---------------------------------------
*/
static bool_t
qst_com_rtype (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    static ansi_t*  name = NULL;

    /* 参数解析 <接收模式/插件名称> [函数名称] */
    if (argc < 2)
        return (FALSE);

    sQstComm*   ctx = (sQstComm*)parm;
    CTextOper*  opr = (CTextOper*)ctx->oper;

    _ENTER_COM_SINGLE_
    if (str_cmpA(argv[1], "text") == 0) {
        ctx->comm.text = TRUE;
        ctx->comm.render = qst_txt_show;
        ctx->comm.rtype = "text";
    }
    else
    if (str_cmpA(argv[1], "html") == 0) {
        ctx->comm.text = TRUE;
        ctx->comm.render = qst_htm_show;
        ctx->comm.rtype = "html";
    }
    else
    if (str_cmpA(argv[1], "hex") == 0) {
        ctx->comm.text = FALSE;
        ctx->comm.render = qst_hex_show;
        ctx->comm.rtype = "hex";
    }
    else
    if (str_cmpA(argv[1], "ansi") == 0) {
        qst_csi_clear();
        ctx->comm.text = TRUE;
        ctx->comm.render = qst_csi_show;
        ctx->comm.rtype = "ansi";
    }
    else
    {
        sbin_t          sbin;
        plugin_render_t func;

        /* 使用外部插件 */
        if (argc < 3)
            goto _failure;
        sbin = sbin_loadA(argv[1]);
        if (sbin == NULL)
            goto _failure;
        func = sbin_exportT(sbin, argv[2], plugin_render_t);
        if (func == NULL) {
            sbin_unload(sbin);
            goto _failure;
        }
        ctx->comm.text = FALSE;
        ctx->comm.render = func;
        TRY_FREE(name);
        name = str_fmtA("%s|%s", argv[1], argv[2]);
        ctx->comm.rtype = (name == NULL) ? "null" : name;
    }
    opr->clear();
    _LEAVE_COM_SINGLE_
    qst_update_title(ctx);
    return (TRUE);

_failure:
    _LEAVE_COM_SINGLE_
    return (FALSE);
}
Exemple #10
0
/*
---------------------------------------
    设置通讯发送模式
---------------------------------------
*/
static bool_t
qst_com_stype (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    static ansi_t*  name = NULL;

    /* 参数解析 <发送模式/插件名称> [函数名称] */
    if (argc < 2)
        return (FALSE);

    sQstComm*   ctx = (sQstComm*)parm;

    if (str_cmpA(argv[1], "text") == 0) {
        ctx->comm.tran = NULL;
        ctx->comm.stype = "text";
    }
    else
    if (str_cmpA(argv[1], "hex") == 0) {
        ctx->comm.tran = qst_hex_tran;
        ctx->comm.stype = "hex";
    }
    else
    if (str_cmpA(argv[1], "esc") == 0) {
        ctx->comm.tran = qst_esc_tran;
        ctx->comm.stype = "esc";
    }
    else
    if (str_cmpA(argv[1], "dos") == 0) {
        ctx->comm.tran = qst_dos_tran;
        ctx->comm.stype = "dos";
    }
    else
    if (str_cmpA(argv[1], "unix") == 0) {
        ctx->comm.tran = qst_unx_tran;
        ctx->comm.stype = "unix";
    }
    else
    if (str_cmpA(argv[1], "mac") == 0) {
        ctx->comm.tran = qst_mac_tran;
        ctx->comm.stype = "mac";
    }
    else
    {
        sbin_t          sbin;
        plugin_tran_t   func;

        /* 使用外部插件 */
        if (argc < 3)
            return (FALSE);
        sbin = sbin_loadA(argv[1]);
        if (sbin == NULL)
            return (FALSE);
        func = sbin_exportT(sbin, argv[2], plugin_tran_t);
        if (func == NULL) {
            sbin_unload(sbin);
            return (FALSE);
        }
        ctx->comm.tran = func;
        TRY_FREE(name);
        name = str_fmtA("%s|%s", argv[1], argv[2]);
        ctx->comm.stype = (name == NULL) ? "null" : name;
    }
    qst_update_title(ctx);
    return (TRUE);
}
Exemple #11
0
/*
---------------------------------------
    打开 RS232 通讯接口
---------------------------------------
*/
static bool_t
qst_com_rs232 (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    int32u  baud;
    uint_t  port, bits;
    uint_t  stop, parity;
    /* --------------- */
    const ansi_t*   sstop;
    const ansi_t*   sparity;

    /* 参数解析 <串口号> [波特率] [数据位] [校验位] [停止位] */
    if (argc < 2)
        return (FALSE);
    bits = 8;
    baud = 115200UL;
    stop = CR_SIO_STOP10;
    parity = CR_SIO_NOP;
    sstop = "1";
    sparity = "no";
    port = str2intxA(argv[1]);
    if (argc > 2) {
        baud = str2intx32A(argv[2]);
        if (argc > 3) {
            bits = str2intxA(argv[3]);
            if (argc > 4) {
                sparity = argv[4];
                if (str_cmpA(argv[4], "no") == 0)
                    parity = CR_SIO_NOP;
                else
                if (str_cmpA(argv[4], "odd") == 0)
                    parity = CR_SIO_ODD;
                else
                if (str_cmpA(argv[4], "even") == 0)
                    parity = CR_SIO_EVEN;
                else
                if (str_cmpA(argv[4], "mark") == 0)
                    parity = CR_SIO_MARK;
                else
                if (str_cmpA(argv[4], "space") == 0)
                    parity = CR_SIO_SPCE;
                else
                    sparity = "no";
                if (argc > 5) {
                    sstop = argv[5];
                    if (str_cmpA(argv[5], "1") == 0)
                        stop = CR_SIO_STOP10;
                    else
                    if (str_cmpA(argv[5], "1.5") == 0)
                        stop = CR_SIO_STOP15;
                    else
                    if (str_cmpA(argv[5], "2") == 0)
                        stop = CR_SIO_STOP20;
                    else
                        sstop = "1";
                }
            }
        }
    }

    sQstComm*   ctx = (sQstComm*)parm;

    /* 关闭当前接口并打开串口 */
    if (!sio_open(port))
        return (FALSE);
    sio_setup(port, baud, bits, parity, stop);
    sio_set_buffer(port, 1024, 1024);
    sio_set_rd_timeout(port, 0, 0, QCOM_CUTDOWN);
    sio_set_wr_timeout(port, 0, QCOM_SNDTOUT);
    sio_clear_error(port);
    sio_flush(port, CR_SIO_FLU_RT);

    /* 设置工作参数 */
    qst_com_close(parm, argc, argv);
    ctx->comm.obj.port = port;
    ctx->comm.send = qst_rs232_send;

    /* 启动接收线程 */
    ctx->comm.thrd = thread_new(0, qst_rs232_main, parm, FALSE);
    if (ctx->comm.thrd == NULL) {
        sio_close(port);
        return (FALSE);
    }
    TRY_FREE(ctx->comm.title);
    ctx->comm.title = str_fmtA(" - COM%u, %u, %u, %s, %s",
                            port, baud, bits, sparity, sstop);
    qst_update_title(ctx);
    return (TRUE);
}
Exemple #12
0
/*
=======================================
    主程序
=======================================
*/
int main (int argc, char *argv[])
{
    CR_NOUSE(argc);
    CR_NOUSE(argv);

    /* 建立 CrHack 系统 */
    if (!set_app_type(CR_APP_CUI))
        return (QST_ERROR);
    SetConsoleTitleA(WIN_TITLE);

    sint_t  x1, y1;
    uint_t  ww, hh;

    /* 初始化窗口 */
    s_hcui = GetStdHandle(STD_OUTPUT_HANDLE);
    if (s_hcui == INVALID_HANDLE_VALUE)
        return (QST_ERROR);
    s_hwnd = GetConsoleWindow();
    if (s_hwnd == NULL)
        return (QST_ERROR);
    misc_desk_init(WIN_ICONF, &x1, &y1, &ww, &hh,
                   QSRV_DEF_WIDTH, QSRV_DEF_HEIGHT);
    misc_cui_setwin(s_hwnd, s_hcui, x1, y1, ww, hh);

    sINIu*  ini;
    uint_t  temp;
    ansi_t* text;
    int16u  port = QST_DEF_PORT;
    ansi_t* addr = QST_DEF_ADDR;
    uint_t  count = QST_DEF_CLIENT;

    /* 读取参数 */
    text = file_load_as_strA(QST_CFG_STARTUP);
    if (text != NULL) {
        ini = ini_parseU(text);
        mem_free(text);
        text = NULL;
        if (ini != NULL) {
            text = ini_key_stringU("serv::bind", ini);
            if (text != NULL)
                addr = text;
            temp = ini_key_intxU("serv::port", QST_DEF_PORT, ini);
            if (temp > 1024 && temp < 32768)
                port = (int16u)temp;
            temp = ini_key_intxU("serv::count", QST_DEF_CLIENT, ini);
            if (temp > 0 && temp <= QST_MAX_CLIENT)
                count = temp;
            ini_closeU(ini);
        }
    }

    socket_t    serv;
    sQstWork*   work;

    /* 建立工作单元组 */
    work = qst_wrk_create(count);
    if (work == NULL)
        return (QST_ERROR);

    /* 初始化网络 */
    if (!socket_init())
        return (QST_ERROR);
    serv = server_tcp_open(addr, port);
    TRY_FREE(text);
    if (serv == NULL)
        return (QST_ERROR);

    /* 初始化锁 */
    mtlock_init(&s_qst_lck_shw);
    mtlock_init(&s_qst_lck_wrk);

    int16u  logo_color;

    /* 建立颜色值 */
    logo_color = cui_make_attr(0, CR_CUI_TEXT_LIGHT |
                        CR_CUI_TEXT_GREEN | CR_CUI_TEXT_RED |
                        CR_CUI_TEXT_BLUE);
    s_qst_clr_cin = cui_make_attr(0, CR_CUI_TEXT_LIGHT |
                        CR_CUI_TEXT_GREEN | CR_CUI_TEXT_RED);
    s_qst_clr_say = cui_make_attr(0, CR_CUI_TEXT_LIGHT |
                        CR_CUI_TEXT_GREEN);
    s_qst_clr_out = cui_make_attr(0, CR_CUI_TEXT_LIGHT |
                        CR_CUI_TEXT_RED);
    /* 工作循环 */
    cui_set_color(logo_color);
    printf("######################################\n");
    printf("##    QUESTLAB BROADCAST SERVER     ##\n");
    printf("######################################\n");
    while (!s_quit)
    {
        ansi_t*     ptr;
        bool_t      okay;
        ansi_t*     name;
        socket_t    netw;

        /* 接受一个客户端 */
        netw = server_tcp_accept(serv);
        if (netw == NULL)
            continue;

        /* 接收客户端名称 */
        socket_set_timeout(netw, -1, QST_TCP_TOUT);
        name = netw_cmd_recv(netw);
        if (name == NULL) {
            socket_close(netw);
            continue;
        }

        /* 客户端名称过滤 */
        if (str_lenA(name) > QST_MAX_NAME) {
            netw_ack_send(netw, FALSE);
            netw_cli_close(netw);
            mem_free(name);
            continue;
        }
        ptr = name;
        okay = TRUE;
        while (*ptr != NIL) {
            if (is_cntrlA(*ptr++)) {
                okay = FALSE;
                break;
            }
        }
        if (!okay) {
            netw_ack_send(netw, FALSE);
            netw_cli_close(netw);
            mem_free(name);
            continue;
        }

        /* 启动一个工作单元 */
        if (!qst_wrk_wakeup(work, name, netw, qst_srv_main)) {
            netw_cli_close(netw);
            mem_free(name);
            continue;
        }
    }
    return (QST_OKAY);
}
Exemple #13
0
/*
=======================================
    TGL IPAC 文件读取
=======================================
*/
CR_API sFMT_PRT*
load_tgl_ipac (
  __CR_IO__ iDATIN*         datin,
  __CR_IN__ const sLOADER*  param
    )
{
    int16u      idx;
    int16u      cnt;
    int32u      offs;
    int32u      size;
    sFMT_PRT*   rett;
    sIPAC_HDR   head;
    iPAK_IPAC*  port;
    sPAK_FILE*  list;
    ansi_t      str[17];

    /* 必须使用自己私有的读取接口 */
    datin = create_file_inX(param);
    if (datin == NULL)
        return (NULL);

    /* 读取 & 检查头部 */
    if (!(CR_VCALL(datin)->geType(datin, &head, sIPAC_HDR)))
        goto _failure1;
    if (head.magic != mk_tag4("IPAC"))
        goto _failure1;

    /* 分配子文件属性表 */
    cnt = WORD_LE(head.count);
    if (cnt != 0) {
        list = mem_talloc(cnt, sPAK_FILE);
        if (list == NULL)
            goto _failure1;
        str[16] = CR_AC(NIL);
        mem_tzero(list, cnt, sPAK_FILE);
    }
    else {
        list = NULL;    /* 支持空的包文件 */
    }

    /* 加载文件信息表 */
    for (idx = 0; idx < cnt; idx++)
    {
        /* 读取文件名不保证\0结尾 */
        if (CR_VCALL(datin)->read(datin, str, 16) != 16)
            goto _failure2;

        /* 文件的包内偏移和大小 */
        if (!CR_VCALL(datin)->getd_le(datin, &offs))
            goto _failure2;
        if (!CR_VCALL(datin)->getd_le(datin, &size))
            goto _failure2;

        /* 文件名统一使用 UTF-8 编码 */
        list[idx].name = local_to_utf8(param->page, str);
        if (list[idx].name == NULL)
            goto _failure2;

        /* 设置公用文件属性 */
        list[idx].skip = sizeof(sPAK_FILE);
        list[idx].attr = 0;
        list[idx].offs = offs;
        list[idx].pack = size;
        list[idx].size = size;
        list[idx].memo = "Store";
    }

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

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

_failure2:
    if (list != NULL) {
        for (cnt = 0; cnt < idx; cnt++) {
            TRY_FREE(list[cnt].find);
            mem_free(list[cnt].name);
        }
        mem_free(list);
    }
_failure1:
    CR_VCALL(datin)->release(datin);
    return (NULL);
}
Exemple #14
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);
}
Exemple #15
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);
}