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; }
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; }