예제 #1
0
int main(int argc, char *argv[]) {
	void *grf;
	if (argc != 2) {
		fprintf(stderr, "Arguments: %s out_file\n", argv[0]);
		return 1;
	}
	grf = grf_new(argv[1], true);
	if (grf == NULL) {
		fprintf(stderr, "Could not write to %s\n", argv[1]);
		return 2;
	}
	recurse_scan_add(grf, "data");
	grf_free(grf);
	return 0;
}
예제 #2
0
BOOL
main_unpack(CHAR *patch_file, struct MemoryStruct *patch, CHAR *grf)
{
    CHAR mes[256];

    CMemInStream memory_stream;
    CLookToRead lookStream;
    CSzArEx db;
    SRes res;
    ISzAlloc allocImp;
    ISzAlloc allocTempImp;

    memory_stream.buf = patch->memory;
    memory_stream.ptr = memory_stream.buf;
    memory_stream.size = patch->size;

    memory_stream.s.Read = &lzma_memory_read;
    memory_stream.s.Seek = &lzma_memory_seek;

    sprintf_s(mes, sizeof(mes), "Распаковка: %s...", patch_file);
    dialog_set_status(mes);

    LookToRead_CreateVTable(&lookStream, False);
    lookStream.realStream = &memory_stream.s;
    LookToRead_Init(&lookStream);

    allocImp.Alloc = SzAlloc;
    allocImp.Free = SzFree;

    allocTempImp.Alloc = SzAllocTemp;
    allocTempImp.Free = SzFreeTemp;

    SzArEx_Init(&db);
    res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
    if (res == SZ_OK)
    {
        UInt32 i;
        UInt32 blockIndex = 0xFFFFFFFF;
        Byte *outBuffer = 0;
        size_t outBufferSize = 0;
        void *grf_handle;

        // if we are working with grf we should
        // open grf-file first
        if (grf != NULL)
        {
            grf_handle = grf_load(grf, TRUE);
            if (grf_handle == NULL)
                grf_handle = grf_new(grf, TRUE);
            if (grf_handle == NULL)
            {
                SzArEx_Free(&db, &allocImp);
                sprintf_s(mes, sizeof(mes), "Невозможно ни открыть, ни создать GRF-файл: %s", grf);
                dialog_set_status(mes);
                return RES_FAIL;
            }
        }

        for (i = 0; i < db.db.NumFiles; i++)
        {
            BOOL res;
            size_t offset;
            size_t outSizeProcessed;
            CSzFileItem *f = db.db.Files + i;

            if (!f->IsDir)
            {
                res = SzAr_Extract(&db, &lookStream.s, i,
                    &blockIndex, &outBuffer, &outBufferSize,
                    &offset, &outSizeProcessed,
                    &allocImp, &allocTempImp);

                if (res != SZ_OK)
                    break;
            }

            res = (grf != NULL)
                ? main_target_grf(grf_handle, (WCHAR *)f->Name, f->IsDir, outBuffer + offset, outSizeProcessed)
                : main_target_fs((WCHAR *)f->Name, f->IsDir, outBuffer + offset, outSizeProcessed);

            if (res)
            {
                IAlloc_Free(&allocImp, outBuffer);
                SzArEx_Free(&db, &allocImp);
                return RES_FAIL;
            }
        }

        // if we're working with grf
        // close it
        if (grf != NULL)
            grf_free(grf_handle);

        IAlloc_Free(&allocImp, outBuffer);
    }

    SzArEx_Free(&db, &allocImp);

    if (res != SZ_OK)
    {
        if (res == SZ_ERROR_UNSUPPORTED)
            sprintf_s(mes, sizeof(mes), "Ошибка распаковки %s: Архив не поддерживается", patch_file);
        else if (res == SZ_ERROR_MEM)
            sprintf_s(mes, sizeof(mes), "Ошибка распаковки %s: Невозможно зарезервировать память", patch_file);
        else if (res == SZ_ERROR_CRC)
            sprintf_s(mes, sizeof(mes), "Ошибка распаковки %s: ошибка CRC", patch_file);
        else
            sprintf_s(mes, sizeof(mes), "Ошибка распаковки %s: ошибка #%d", patch_file, res);
        dialog_set_status(mes);
        return RES_FAIL;
    }

    return RES_OK;
}