C7zip::C7zip (LPCSTR FileName) : m_FileSize(0), m_CurrentFile(-1), m_blockIndex(0xFFFFFFFF), m_outBuffer(0), m_outBufferSize(0), m_NotfyCallback(NotfyCallbackDefault), m_NotfyCallbackInfo(NULL), m_db(NULL), m_Opened(false) { memset(&m_FileName,0,sizeof(m_FileName)); memset(&m_archiveLookStream,0,sizeof(m_archiveLookStream)); m_db = new CSzArEx; memset(m_db,0,sizeof(CSzArEx)); m_archiveStream.s.Read = SzFileReadImp; m_archiveStream.s.Seek = SzFileSeekImp; m_allocImp.Alloc = AllocAllocImp; m_allocImp.Free = AllocFreeImp; m_allocTempImp.Alloc = AllocAllocImp; m_allocTempImp.Free = AllocFreeImp; InFile_Open(&m_archiveStream.file,FileName); if (m_archiveStream.file.handle == INVALID_HANDLE_VALUE) { //PrintError("can not open input file"); return; } m_FileSize = GetFileSize(m_archiveStream.file.handle,NULL); char drive[_MAX_DRIVE] ,dir[_MAX_DIR], ext[_MAX_EXT]; _splitpath( FileName, drive, dir, m_FileName, ext ); CrcGenerateTable(); SzArEx_Init(m_db); LookToRead_Init(&m_archiveLookStream); LookToRead_CreateVTable(&m_archiveLookStream, False); m_archiveLookStream.realStream = &m_archiveStream.s; SRes res = SzArEx_Open(m_db, &m_archiveLookStream.s, &m_allocImp, &m_allocTempImp); if (res == SZ_OK) { m_Opened = true; } else { //SzArEx_Open will delete the passed db if it fails m_db = NULL; } }
int Unseven(const char *filename, STRING **list) { CFileInStream archiveStream; CLookToRead lookStream; CSzArEx db; SRes res; ISzAlloc allocImp; ISzAlloc allocTempImp; UInt16 *temp = NULL; size_t tempSize = 0; Bool do_save = (globaldata.gd_inidata->archive_dir && *(globaldata.gd_inidata->archive_dir))? False : True; char *subdir = NULL; // UInt32 parents[NUM_PARENTS_MAX]; // printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n"); if (!filename || !*filename) return -1; // error #if defined(_WIN32) && !defined(USE_WINDOWS_FILE) && !defined(UNDER_CE) g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; #endif allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; #ifdef UNDER_CE if (InFile_OpenW(&archiveStream.file, L"\test.7z")) #else if (InFile_Open(&archiveStream.file, filename)) #endif { PrintError("can not open input file"); return -1; } FileInStream_CreateVTable(&archiveStream); LookToRead_CreateVTable(&lookStream, False); lookStream.realStream = &archiveStream.s; LookToRead_Init(&lookStream); CrcGenerateTable(); SzArEx_Init(&db); res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); if (res == SZ_OK) { UInt32 i; /* if you need cache, use these 3 variables. if you use external function, you can make these variable as static. */ UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ for (i = 0; i < db.NumFiles; i++) { size_t offset = 0; size_t outSizeProcessed = 0; // const CSzFileItem *f = db.Files + i; size_t len; unsigned isDir = SzArEx_IsDir(&db, i); len = SzArEx_GetFileNameUtf16(&db, i, NULL); // len = SzArEx_GetFullNameLen(&db, i); if (len > tempSize) { SzFree(NULL, temp); tempSize = len; temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0])); if (!temp) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&db, i, temp); /* { // progression output static char s[256]; snprintf(s, 255, _("Extracting (%d%%)"), ((i + 1) * 100) / db.NumFiles); HandleSemaphoreText(s, list, !i ? 1 : 0); }*/ if (isDir) ;//printf("/"); else { res = SzArEx_Extract(&db, &lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; } // write data to disk { CSzFile outFile; size_t processedSize; size_t j; UInt16 *name = (UInt16 *)temp; const UInt16 *destPath = (const UInt16 *)name; WRes wres; for (j = 0; name[j] != 0; j++) if (name[j] == '/') { name[j] = 0; MyCreateDir(name, &subdir, &do_save); name[j] = CHAR_PATH_SEPARATOR; } if (isDir) { MyCreateDir(destPath, &subdir, &do_save); //printf("\n"); continue; } if (do_save == False) continue; wres = OutFile_OpenUtf16(&outFile, destPath, &subdir, &do_save); if (wres == -1) continue; if (wres) { PrintError("can not open output file"); res = SZ_ERROR_FAIL; break; } processedSize = outSizeProcessed; if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed) { PrintError(_("can not write output file")); res = SZ_ERROR_FAIL; break; } if (File_Close(&outFile)) { PrintError(_("can not close output file")); res = SZ_ERROR_FAIL; break; } #ifdef USE_WINDOWS_FILE if (SzBitWithVals_Check(&db.Attribs, i)) SetFileAttributesW(destPath, db.Attribs.Vals[i]); #endif } //printf("\n"); } IAlloc_Free(&allocImp, outBuffer); } SzArEx_Free(&db, &allocImp); SzFree(NULL, temp); File_Close(&archiveStream.file); if (res == SZ_OK) { //printf("\nEverything is Ok\n"); return 0; } if (res == SZ_ERROR_UNSUPPORTED) PrintError(_("decoder doesn't support this archive")); else if (res == SZ_ERROR_MEM) PrintError(_("can not allocate memory")); else if (res == SZ_ERROR_CRC) PrintError(_("CRC error")); else printf("<br />ERROR #%d\n", res); return -1; }
struct VDir* VDirOpen7z(const char* path, int flags) { if (flags & O_WRONLY || flags & O_CREAT) { return 0; } struct VDir7z* vd = malloc(sizeof(struct VDir7z)); // What does any of this mean, Igor? if (InFile_Open(&vd->archiveStream.file, path)) { free(vd); return 0; } vd->allocImp.Alloc = SzAlloc; vd->allocImp.Free = SzFree; vd->allocTempImp.Alloc = SzAllocTemp; vd->allocTempImp.Free = SzFreeTemp; FileInStream_CreateVTable(&vd->archiveStream); LookToRead_CreateVTable(&vd->lookStream, False); vd->lookStream.realStream = &vd->archiveStream.s; LookToRead_Init(&vd->lookStream); CrcGenerateTable(); SzArEx_Init(&vd->db); SRes res = SzArEx_Open(&vd->db, &vd->lookStream.s, &vd->allocImp, &vd->allocTempImp); if (res != SZ_OK) { free(vd); return 0; } vd->dirent.index = 0; vd->dirent.utf8 = 0; vd->dirent.vd = vd; vd->dirent.d.name = _vde7zName; vd->d.close = _vd7zClose; vd->d.rewind = _vd7zRewind; vd->d.listNext = _vd7zListNext; vd->d.openFile = _vd7zOpenFile; return &vd->d; }
bool SzArchive::Open(const char* path) { SzArEx_Init(&szarchive); if (InFile_Open(&archiveStream.file, path)) return false; FileInStream_CreateVTable(&archiveStream); LookToRead2_CreateVTable(&lookStream, false); lookStream.buf = (Byte *)ISzAlloc_Alloc(&g_Alloc, kInputBufSize); if (lookStream.buf == NULL) return false; lookStream.bufSize = kInputBufSize; lookStream.realStream = &archiveStream.vt; LookToRead2_Init(&lookStream); if (!crc_tables_generated) { CrcGenerateTable(); crc_tables_generated = true; } SRes res = SzArEx_Open(&szarchive, &lookStream.vt, &g_Alloc, &g_Alloc); return (res == SZ_OK); }
static int sevenzip_parse_file_init(file_archive_transfer_t *state, const char *file) { struct sevenzip_context_t *sevenzip_context = (struct sevenzip_context_t*)sevenzip_stream_new(); if (state->archive_size < SEVENZIP_MAGIC_LEN) goto error; if (memcmp(state->data, SEVENZIP_MAGIC, SEVENZIP_MAGIC_LEN) != 0) goto error; state->stream = sevenzip_context; /* could not open 7zip archive? */ if (InFile_Open(&sevenzip_context->archiveStream.file, file)) goto error; FileInStream_CreateVTable(&sevenzip_context->archiveStream); LookToRead_CreateVTable(&sevenzip_context->lookStream, False); sevenzip_context->lookStream.realStream = &sevenzip_context->archiveStream.s; LookToRead_Init(&sevenzip_context->lookStream); CrcGenerateTable(); SzArEx_Init(&sevenzip_context->db); if (SzArEx_Open(&sevenzip_context->db, &sevenzip_context->lookStream.s, &sevenzip_context->allocImp, &sevenzip_context->allocTempImp) != SZ_OK) goto error; return 0; error: if (sevenzip_context) sevenzip_stream_free(sevenzip_context); return -1; }
static struct string_list *compressed_7zip_file_list_new( const char *path, const char* ext) { CFileInStream archiveStream; CLookToRead lookStream; CSzArEx db; ISzAlloc allocImp; ISzAlloc allocTempImp; size_t temp_size = 0; struct string_list *list = NULL; /* These are the allocation routines - currently using * the non-standard 7zip choices. */ allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; if (InFile_Open(&archiveStream.file, path)) { RARCH_ERR("Could not open %s as 7z archive.\n",path); return NULL; } list = string_list_new(); if (!list) { File_Close(&archiveStream.file); return NULL; } FileInStream_CreateVTable(&archiveStream); LookToRead_CreateVTable(&lookStream, False); lookStream.realStream = &archiveStream.s; LookToRead_Init(&lookStream); CrcGenerateTable(); SzArEx_Init(&db); if (SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp) == SZ_OK) { uint32_t i; struct string_list *ext_list = ext ? string_split(ext, "|"): NULL; SRes res = SZ_OK; uint16_t *temp = NULL; for (i = 0; i < db.db.NumFiles; i++) { union string_list_elem_attr attr; char infile[PATH_MAX_LENGTH]; const char *file_ext = NULL; size_t len = 0; bool supported_by_core = false; const CSzFileItem *f = db.db.Files + i; /* we skip over everything, which is a directory. */ if (f->IsDir) continue; len = SzArEx_GetFileNameUtf16(&db, i, NULL); if (len > temp_size) { free(temp); temp_size = len; temp = (uint16_t *)malloc(temp_size * sizeof(temp[0])); if (temp == 0) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&db, i, temp); res = utf16_to_char_string(temp, infile, sizeof(infile)) ? SZ_OK : SZ_ERROR_FAIL; file_ext = path_get_extension(infile); if (string_list_find_elem_prefix(ext_list, ".", file_ext)) supported_by_core = true; /* * Currently we only support files without subdirs in the archives. * Folders are not supported (differences between win and lin. * Archives within archives should imho never be supported. */ if (!supported_by_core) continue; attr.i = RARCH_COMPRESSED_FILE_IN_ARCHIVE; if (!string_list_append(list, infile, attr)) { res = SZ_ERROR_MEM; break; } } string_list_free(ext_list); free(temp); if (res != SZ_OK) { /* Error handling */ RARCH_ERR("Failed to open compressed_file: \"%s\"\n", path); string_list_free(list); list = NULL; } } SzArEx_Free(&db, &allocImp); File_Close(&archiveStream.file); return list; }
/* Extract the relative path (needle) from a 7z archive * (path) and allocate a buf for it to write it in. * If optional_outfile is set, extract to that instead * and don't allocate buffer. */ static int content_7zip_file_read( const char *path, const char *needle, void **buf, const char *optional_outfile) { CFileInStream archiveStream; CLookToRead lookStream; CSzArEx db; ISzAlloc allocImp; ISzAlloc allocTempImp; uint8_t *output = 0; long outsize = -1; /*These are the allocation routines. * Currently using the non-standard 7zip choices. */ allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; if (InFile_Open(&archiveStream.file, path)) { RARCH_ERR("Could not open %s as 7z archive\n.", path); return -1; } FileInStream_CreateVTable(&archiveStream); LookToRead_CreateVTable(&lookStream, False); lookStream.realStream = &archiveStream.s; LookToRead_Init(&lookStream); CrcGenerateTable(); SzArEx_Init(&db); if (SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp) == SZ_OK) { uint32_t i; bool file_found = false; uint16_t *temp = NULL; size_t temp_size = 0; uint32_t block_index = 0xFFFFFFFF; SRes res = SZ_OK; for (i = 0; i < db.db.NumFiles; i++) { size_t len; char infile[PATH_MAX_LENGTH]; size_t offset = 0; size_t outSizeProcessed = 0; const CSzFileItem *f = db.db.Files + i; /* We skip over everything which is not a directory. * FIXME: Why continue then if f->IsDir is true?*/ if (f->IsDir) continue; len = SzArEx_GetFileNameUtf16(&db, i, NULL); if (len > temp_size) { free(temp); temp_size = len; temp = (uint16_t *)malloc(temp_size * sizeof(temp[0])); if (temp == 0) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&db, i, temp); res = utf16_to_char_string(temp, infile, sizeof(infile)) ? SZ_OK : SZ_ERROR_FAIL; if (string_is_equal(infile, needle)) { size_t output_size = 0; RARCH_LOG_OUTPUT("Opened archive %s. Now trying to extract %s\n", path, needle); /* C LZMA SDK does not support chunked extraction - see here: * sourceforge.net/p/sevenzip/discussion/45798/thread/6fb59aaf/ * */ file_found = true; res = SzArEx_Extract(&db, &lookStream.s, i, &block_index, &output, &output_size, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; /* This goes to the error section. */ outsize = outSizeProcessed; if (optional_outfile != NULL) { const void *ptr = (const void*)(output + offset); if (!retro_write_file(optional_outfile, ptr, outsize)) { RARCH_ERR("Could not open outfilepath %s.\n", optional_outfile); res = SZ_OK; file_found = true; outsize = -1; } } else { /*We could either use the 7Zip allocated buffer, * or create our own and use it. * We would however need to realloc anyways, because RetroArch * expects a \0 at the end, therefore we allocate new, * copy and free the old one. */ *buf = malloc(outsize + 1); ((char*)(*buf))[outsize] = '\0'; memcpy(*buf,output + offset,outsize); } break; } } free(temp); IAlloc_Free(&allocImp, output); if (!(file_found && res == SZ_OK)) { /* Error handling */ if (!file_found) RARCH_ERR("File %s not found in %s\n", needle, path); RARCH_ERR("Failed to open compressed file inside 7zip archive.\n"); outsize = -1; } } SzArEx_Free(&db, &allocImp); File_Close(&archiveStream.file); return outsize; }
_7z_error _7z_file_open(const char *filename, _7z_file **_7z) { file_error err; _7z_error _7zerr = _7ZERR_NONE; _7z_file *new_7z; char *string; int cachenum; SRes res; /* ensure we start with a NULL result */ *_7z = NULL; /* see if we are in the cache, and reopen if so */ for (cachenum = 0; cachenum < ARRAY_LENGTH(_7z_cache); cachenum++) { _7z_file *cached = _7z_cache[cachenum]; /* if we have a valid entry and it matches our filename, use it and remove from the cache */ if (cached != NULL && cached->filename != NULL && strcmp(filename, cached->filename) == 0) { *_7z = cached; _7z_cache[cachenum] = NULL; return _7ZERR_NONE; } } /* allocate memory for the _7z_file structure */ new_7z = (_7z_file *)malloc(sizeof(*new_7z)); if (new_7z == NULL) return _7ZERR_OUT_OF_MEMORY; memset(new_7z, 0, sizeof(*new_7z)); new_7z->inited = false; new_7z->archiveStream.file._7z_currfpos = 0; err = osd_open(filename, OPEN_FLAG_READ, &new_7z->archiveStream.file._7z_osdfile, &new_7z->archiveStream.file._7z_length); if (err != FILERR_NONE) { _7zerr = _7ZERR_FILE_ERROR; goto error; } new_7z->allocImp.Alloc = SZipAlloc; new_7z->allocImp.Free = SZipFree; new_7z->allocTempImp.Alloc = SZipAlloc; new_7z->allocTempImp.Free = SZipFree; if (InFile_Open(&new_7z->archiveStream.file, filename)) { _7zerr = _7ZERR_FILE_ERROR; goto error; } FileInStream_CreateVTable(&new_7z->archiveStream); LookToRead_CreateVTable(&new_7z->lookStream, False); new_7z->lookStream.realStream = &new_7z->archiveStream.s; LookToRead_Init(&new_7z->lookStream); CrcGenerateTable(); SzArEx_Init(&new_7z->db); new_7z->inited = true; res = SzArEx_Open(&new_7z->db, &new_7z->lookStream.s, &new_7z->allocImp, &new_7z->allocTempImp); if (res != SZ_OK) { _7zerr = _7ZERR_FILE_ERROR; goto error; } new_7z->blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ new_7z->outBuffer = 0; /* it must be 0 before first call for each new archive. */ new_7z->outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ /* make a copy of the filename for caching purposes */ string = (char *)malloc(strlen(filename) + 1); if (string == NULL) { _7zerr = _7ZERR_OUT_OF_MEMORY; goto error; } strcpy(string, filename); new_7z->filename = string; *_7z = new_7z; return _7ZERR_NONE; error: free__7z_file(new_7z); return _7zerr; }
int MY_CDECL main(int numargs, char *args[]) { CFileInStream archiveStream; CLookToRead lookStream; CSzArEx db; SRes res; ISzAlloc allocImp; ISzAlloc allocTempImp; UInt16 *temp = NULL; size_t tempSize = 0; // UInt32 parents[NUM_PARENTS_MAX]; printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n"); if (numargs == 1) { printf( "Usage: 7zDec <command> <archive_name>\n\n" "<Commands>\n" " e: Extract files from archive (without using directory names)\n" " l: List contents of archive\n" " t: Test integrity of archive\n" " x: eXtract files with full paths\n"); return 0; } if (numargs < 3) { PrintError("incorrect command"); return 1; } #if defined(_WIN32) && !defined(USE_WINDOWS_FILE) && !defined(UNDER_CE) g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; #endif allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; #ifdef UNDER_CE if (InFile_OpenW(&archiveStream.file, L"\test.7z")) #else if (InFile_Open(&archiveStream.file, args[2])) #endif { PrintError("can not open input file"); return 1; } FileInStream_CreateVTable(&archiveStream); LookToRead_CreateVTable(&lookStream, False); lookStream.realStream = &archiveStream.s; LookToRead_Init(&lookStream); CrcGenerateTable(); SzArEx_Init(&db); res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); if (res == SZ_OK) { char *command = args[1]; int listCommand = 0, testCommand = 0, fullPaths = 0; if (strcmp(command, "l") == 0) listCommand = 1; else if (strcmp(command, "t") == 0) testCommand = 1; else if (strcmp(command, "e") == 0) { } else if (strcmp(command, "x") == 0) { fullPaths = 1; } else { PrintError("incorrect command"); res = SZ_ERROR_FAIL; } if (res == SZ_OK) { UInt32 i; /* if you need cache, use these 3 variables. if you use external function, you can make these variable as static. */ UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ for (i = 0; i < db.NumFiles; i++) { size_t offset = 0; size_t outSizeProcessed = 0; // const CSzFileItem *f = db.Files + i; size_t len; unsigned isDir = SzArEx_IsDir(&db, i); if (listCommand == 0 && isDir && !fullPaths) continue; len = SzArEx_GetFileNameUtf16(&db, i, NULL); // len = SzArEx_GetFullNameLen(&db, i); if (len > tempSize) { SzFree(NULL, temp); tempSize = len; temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0])); if (!temp) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&db, i, temp); /* if (SzArEx_GetFullNameUtf16_Back(&db, i, temp + len) != temp) { res = SZ_ERROR_FAIL; break; } */ if (listCommand) { char attr[8], s[32], t[32]; UInt64 fileSize; GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr); fileSize = SzArEx_GetFileSize(&db, i); UInt64ToStr(fileSize, s); if (SzBitWithVals_Check(&db.MTime, i)) ConvertFileTimeToString(&db.MTime.Vals[i], t); else { size_t j; for (j = 0; j < 19; j++) t[j] = ' '; t[j] = '\0'; } printf("%s %s %10s ", t, attr, s); res = PrintString(temp); if (res != SZ_OK) break; if (isDir) printf("/"); printf("\n"); continue; } fputs(testCommand ? "Testing ": "Extracting ", stdout); res = PrintString(temp); if (res != SZ_OK) break; if (isDir) printf("/"); else { res = SzArEx_Extract(&db, &lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; } if (!testCommand) { CSzFile outFile; size_t processedSize; size_t j; UInt16 *name = (UInt16 *)temp; const UInt16 *destPath = (const UInt16 *)name; for (j = 0; name[j] != 0; j++) if (name[j] == '/') { if (fullPaths) { name[j] = 0; MyCreateDir(name); name[j] = CHAR_PATH_SEPARATOR; } else destPath = name + j + 1; } if (isDir) { MyCreateDir(destPath); printf("\n"); continue; } else if (OutFile_OpenUtf16(&outFile, destPath)) { PrintError("can not open output file"); res = SZ_ERROR_FAIL; break; } processedSize = outSizeProcessed; if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed) { PrintError("can not write output file"); res = SZ_ERROR_FAIL; break; } if (File_Close(&outFile)) { PrintError("can not close output file"); res = SZ_ERROR_FAIL; break; } #ifdef USE_WINDOWS_FILE if (SzBitWithVals_Check(&db.Attribs, i)) SetFileAttributesW(destPath, db.Attribs.Vals[i]); #endif } printf("\n"); } IAlloc_Free(&allocImp, outBuffer); } } SzArEx_Free(&db, &allocImp); SzFree(NULL, temp); File_Close(&archiveStream.file); if (res == SZ_OK) { printf("\nEverything is Ok\n"); return 0; } if (res == SZ_ERROR_UNSUPPORTED) PrintError("decoder doesn't support this archive"); else if (res == SZ_ERROR_MEM) PrintError("can not allocate memory"); else if (res == SZ_ERROR_CRC) PrintError("CRC error"); else printf("\nERROR #%d\n", res); return 1; }
/*! * \brief * Decompresses a single file from a 7zip archive. * * \param archive_file * Path to the archive to extract the file from. * * \param file_name * The fine within the archive to extract. * * \param uncompressed_data * Reference parameter to set the uncompressed datas pointer to. * * \param uncompressed_data_size * Reference parameter to set the uncompressed data size to. * * \returns * Returns true if the decompresseion was successfull, otherwise returns false. * * Decompresses a single file from a 7zip archive. */ bool DecompressFileEntry(cstring archive_file, cstring file_name, byte*& uncompressed_data, size_t& uncompressed_data_size) { CFileInStream archive_stream; CLookToRead look_stream; CSzArEx archive_desc; SRes result; ISzAlloc alloc_imp; wchar_t wide_file_name[MAX_PATH] = L""; // open the archive for reading if (InFile_Open(&archive_stream.file, archive_file)) return false; // convert the search file name to a wide char string for comparison later if(-1 == swprintf_s(wide_file_name, MAX_PATH, L"%S", file_name)) return false; // set up the memory handling functions alloc_imp.Alloc = AllocFunc; alloc_imp.Free = FreeFunc; FileInStream_CreateVTable(&archive_stream); LookToRead_CreateVTable(&look_stream, False); look_stream.realStream = &archive_stream.s; LookToRead_Init(&look_stream); CrcGenerateTable(); SzArEx_Init(&archive_desc); result = SzArEx_Open(&archive_desc, &look_stream.s, &alloc_imp, &alloc_imp); if(result == SZ_OK) { int index = -1; // search for the file in the archive for (uint32 i = 0; (index == -1) && (i < archive_desc.db.NumFiles); i++) { if(archive_desc.db.Files[i].IsDir) continue; // get the name of the file in the archive uint32 name_length = SzArEx_GetFileNameUtf16(&archive_desc, i, NULL); wchar_t* archive_file_name = new wchar_t[name_length]; SzArEx_GetFileNameUtf16(&archive_desc, i, (UInt16*)archive_file_name); // compare the file names if(wcscmp(wide_file_name, archive_file_name) == 0) index = i; // delete allocated memory delete [] archive_file_name; } if(index > -1) { // file found, so decompress it result = Decompress(archive_stream, archive_desc, look_stream, index, uncompressed_data, uncompressed_data_size); } } SzArEx_Free(&archive_desc, &alloc_imp); File_Close(&archive_stream.file); return result == SZ_OK; }
CArchive7Zip::CArchive7Zip(const std::string& name) : CArchiveBase(name), isOpen(false) { blockIndex = 0xFFFFFFFF; outBuffer = NULL; outBufferSize = 0; allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; SzArEx_Init(&db); WRes wres = InFile_Open(&archiveStream.file, name.c_str()); if (wres) { boost::system::error_code e(wres, boost::system::get_system_category()); LogObject() << "Error opening " << name << ": " << e.message() << " (" << e.value() << ")"; return; } FileInStream_CreateVTable(&archiveStream); LookToRead_CreateVTable(&lookStream, False); lookStream.realStream = &archiveStream.s; LookToRead_Init(&lookStream); CrcGenerateTable(); SRes res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); if (res == SZ_OK) { isOpen = true; } else { isOpen = false; std::string error; switch (res) { case SZ_ERROR_FAIL: error = "Extracting failed"; break; case SZ_ERROR_CRC: error = "CRC error (archive corrupted?)"; break; case SZ_ERROR_INPUT_EOF: error = "Unexpected end of file (truncated?)"; break; case SZ_ERROR_MEM: error = "Out of memory"; break; case SZ_ERROR_UNSUPPORTED: error = "Unsupported archive"; break; case SZ_ERROR_NO_ARCHIVE: error = "Archive not found"; break; default: error = "Unknown error"; break; } LogObject() << "Error opening " << name << ": " << error; return; } // In 7zip talk, folders are pack-units (solid blocks), // not related to file-system folders. UInt64* folderUnpackSizes = new UInt64[db.db.NumFolders]; for (int fi = 0; fi < db.db.NumFolders; fi++) { folderUnpackSizes[fi] = SzFolder_GetUnpackSize(db.db.Folders + fi); } // Get contents of archive and store name->int mapping for (unsigned i = 0; i < db.db.NumFiles; ++i) { CSzFileItem* f = db.db.Files + i; if ((f->Size >= 0) && !f->IsDir) { std::string fileName = f->Name; FileData fd; fd.origName = fileName; fd.fp = i; fd.size = f->Size; fd.crc = (f->Size > 0) ? f->FileCRC : 0; const UInt32 folderIndex = db.FileIndexToFolderIndexMap[i]; if (folderIndex == ((UInt32)-1)) { // file has no folder assigned fd.unpackedSize = f->Size; fd.packedSize = f->Size; } else { fd.unpackedSize = folderUnpackSizes[folderIndex]; fd.packedSize = db.db.PackSizes[folderIndex]; } StringToLowerInPlace(fileName); fileData.push_back(fd); lcNameIndex[fileName] = fileData.size()-1; } } delete [] folderUnpackSizes; }
int main2(int numArgs, const char *args[], char *rs) { CFileSeqInStream inStream; CFileOutStream outStream; int res; int encodeMode = 0; Bool modeWasSet = False; const char *inputFile = NULL; const char *outputFile = "file.tmp"; int param; UInt64 fileSize; FileSeqInStream_CreateVTable(&inStream); File_Construct(&inStream.file); FileOutStream_CreateVTable(&outStream); File_Construct(&outStream.file); if (numArgs == 1) { PrintHelp(rs); return 0; } for (param = 1; param < numArgs; param++) { if (strcmp(args[param], "-e") == 0 || strcmp(args[param], "-d") == 0) { encodeMode = (args[param][1] == 'e'); modeWasSet = True; } else if (strcmp(args[param], "--f86") == 0) { mConType = X86Converter; } else if (strcmp(args[param], "-o") == 0 || strcmp(args[param], "--output") == 0) { if (numArgs < (param + 2)) { return PrintUserError(rs); } outputFile = args[++param]; } else if (strcmp(args[param], "--debug") == 0) { if (numArgs < (param + 2)) { return PrintUserError(rs); } // // For now we silently ignore this parameter to achieve command line // parameter compatibility with other build tools. // param++; } else if ( strcmp(args[param], "-h") == 0 || strcmp(args[param], "--help") == 0 ) { PrintHelp(rs); return 0; } else if ( strcmp(args[param], "-v") == 0 || strcmp(args[param], "--verbose") == 0 ) { // // For now we silently ignore this parameter to achieve command line // parameter compatibility with other build tools. // } else if ( strcmp(args[param], "-q") == 0 || strcmp(args[param], "--quiet") == 0 ) { mQuietMode = True; } else if (strcmp(args[param], "--version") == 0) { PrintVersion(rs); return 0; } else if (inputFile == NULL) { inputFile = args[param]; } else { return PrintUserError(rs); } } if ((inputFile == NULL) || !modeWasSet) { return PrintUserError(rs); } { size_t t4 = sizeof(UInt32); size_t t8 = sizeof(UInt64); if (t4 != 4 || t8 != 8) return PrintError(rs, "Incorrect UInt32 or UInt64"); } if (InFile_Open(&inStream.file, inputFile) != 0) return PrintError(rs, "Can not open input file"); if (OutFile_Open(&outStream.file, outputFile) != 0) return PrintError(rs, "Can not open output file"); File_GetLength(&inStream.file, &fileSize); if (encodeMode) { if (!mQuietMode) { printf("Encoding\n"); } res = Encode(&outStream.s, &inStream.s, fileSize); } else { if (!mQuietMode) { printf("Decoding\n"); } res = Decode(&outStream.s, &inStream.s, fileSize); } File_Close(&outStream.file); File_Close(&inStream.file); if (res != SZ_OK) { if (res == SZ_ERROR_MEM) return PrintError(rs, kCantAllocateMessage); else if (res == SZ_ERROR_DATA) return PrintError(rs, kDataErrorMessage); else if (res == SZ_ERROR_WRITE) return PrintError(rs, kCantWriteMessage); else if (res == SZ_ERROR_READ) return PrintError(rs, kCantReadMessage); return PrintErrorNumber(rs, res); } return 0; }
int MY_CDECL main(int numargs, char *args[]) { ISzAlloc allocImp; ISzAlloc allocTempImp; CFileInStream archiveStream; CLookToRead2 lookStream; CSzArEx db; SRes res; UInt16 *temp = NULL; size_t tempSize = 0; // UInt32 parents[NUM_PARENTS_MAX]; Print("\n7z Decoder " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n"); if (numargs == 1) { Print( "Usage: 7zDec <command> <archive_name>\n\n" "<Commands>\n" " e: Extract files from archive (without using directory names)\n" " l: List contents of archive\n" " t: Test integrity of archive\n" " x: eXtract files with full paths\n"); return 0; } if (numargs < 3) { PrintError("incorrect command"); return 1; } #if defined(_WIN32) && !defined(USE_WINDOWS_FILE) && !defined(UNDER_CE) g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; #endif allocImp = g_Alloc; allocTempImp = g_Alloc; #ifdef UNDER_CE if (InFile_OpenW(&archiveStream.file, L"\test.7z")) #else if (InFile_Open(&archiveStream.file, args[2])) #endif { PrintError("can not open input file"); return 1; } FileInStream_CreateVTable(&archiveStream); LookToRead2_CreateVTable(&lookStream, False); lookStream.buf = NULL; res = SZ_OK; { lookStream.buf = (Byte *)ISzAlloc_Alloc(&allocImp, kInputBufSize); if (!lookStream.buf) res = SZ_ERROR_MEM; else { lookStream.bufSize = kInputBufSize; lookStream.realStream = &archiveStream.vt; LookToRead2_Init(&lookStream); } } CrcGenerateTable(); SzArEx_Init(&db); if (res == SZ_OK) { res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp); } if (res == SZ_OK) { char *command = args[1]; int listCommand = 0, testCommand = 0, fullPaths = 0; if (strcmp(command, "l") == 0) listCommand = 1; else if (strcmp(command, "t") == 0) testCommand = 1; else if (strcmp(command, "e") == 0) { } else if (strcmp(command, "x") == 0) { fullPaths = 1; } else { PrintError("incorrect command"); res = SZ_ERROR_FAIL; } if (res == SZ_OK) { UInt32 i; /* if you need cache, use these 3 variables. if you use external function, you can make these variable as static. */ UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ for (i = 0; i < db.NumFiles; i++) { size_t offset = 0; size_t outSizeProcessed = 0; // const CSzFileItem *f = db.Files + i; size_t len; unsigned isDir = SzArEx_IsDir(&db, i); if (listCommand == 0 && isDir && !fullPaths) continue; len = SzArEx_GetFileNameUtf16(&db, i, NULL); // len = SzArEx_GetFullNameLen(&db, i); if (len > tempSize) { SzFree(NULL, temp); tempSize = len; temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0])); if (!temp) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&db, i, temp); /* if (SzArEx_GetFullNameUtf16_Back(&db, i, temp + len) != temp) { res = SZ_ERROR_FAIL; break; } */ if (listCommand) { char attr[8], s[32], t[32]; UInt64 fileSize; GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr); fileSize = SzArEx_GetFileSize(&db, i); UInt64ToStr(fileSize, s, 10); if (SzBitWithVals_Check(&db.MTime, i)) ConvertFileTimeToString(&db.MTime.Vals[i], t); else { size_t j; for (j = 0; j < 19; j++) t[j] = ' '; t[j] = '\0'; } Print(t); Print(" "); Print(attr); Print(" "); Print(s); Print(" "); res = PrintString(temp); if (res != SZ_OK) break; if (isDir) Print("/"); PrintLF(); continue; } Print(testCommand ? "Testing ": "Extracting "); res = PrintString(temp); if (res != SZ_OK) break; if (isDir) Print("/"); else { res = SzArEx_Extract(&db, &lookStream.vt, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; } if (!testCommand) { CSzFile outFile; size_t processedSize; size_t j; UInt16 *name = (UInt16 *)temp; const UInt16 *destPath = (const UInt16 *)name; for (j = 0; name[j] != 0; j++) if (name[j] == '/') { if (fullPaths) { name[j] = 0; MyCreateDir(name); name[j] = CHAR_PATH_SEPARATOR; } else destPath = name + j + 1; } if (isDir) { MyCreateDir(destPath); PrintLF(); continue; } else if (OutFile_OpenUtf16(&outFile, destPath)) { PrintError("can not open output file"); res = SZ_ERROR_FAIL; break; } processedSize = outSizeProcessed; if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed) { PrintError("can not write output file"); res = SZ_ERROR_FAIL; break; } #ifdef USE_WINDOWS_FILE { FILETIME mtime, ctime; FILETIME *mtimePtr = NULL; FILETIME *ctimePtr = NULL; if (SzBitWithVals_Check(&db.MTime, i)) { const CNtfsFileTime *t = &db.MTime.Vals[i]; mtime.dwLowDateTime = (DWORD)(t->Low); mtime.dwHighDateTime = (DWORD)(t->High); mtimePtr = &mtime; } if (SzBitWithVals_Check(&db.CTime, i)) { const CNtfsFileTime *t = &db.CTime.Vals[i]; ctime.dwLowDateTime = (DWORD)(t->Low); ctime.dwHighDateTime = (DWORD)(t->High); ctimePtr = &ctime; } if (mtimePtr || ctimePtr) SetFileTime(outFile.handle, ctimePtr, NULL, mtimePtr); } #endif if (File_Close(&outFile)) { PrintError("can not close output file"); res = SZ_ERROR_FAIL; break; } #ifdef USE_WINDOWS_FILE if (SzBitWithVals_Check(&db.Attribs, i)) { UInt32 attrib = db.Attribs.Vals[i]; /* p7zip stores posix attributes in high 16 bits and adds 0x8000 as marker. We remove posix bits, if we detect posix mode field */ if ((attrib & 0xF0000000) != 0) attrib &= 0x7FFF; SetFileAttributesW((LPCWSTR)destPath, attrib); } #endif } PrintLF(); } ISzAlloc_Free(&allocImp, outBuffer); } } SzFree(NULL, temp); SzArEx_Free(&db, &allocImp); ISzAlloc_Free(&allocImp, lookStream.buf); File_Close(&archiveStream.file); if (res == SZ_OK) { Print("\nEverything is Ok\n"); return 0; } if (res == SZ_ERROR_UNSUPPORTED) PrintError("decoder doesn't support this archive"); else if (res == SZ_ERROR_MEM) PrintError("can not allocate memory"); else if (res == SZ_ERROR_CRC) PrintError("CRC error"); else { char s[32]; UInt64ToStr(res, s, 0); PrintError(s); } return 1; }
bool Qt7zPackage::open() { if (m_p->m_isOpen) { return false; } SRes res; UInt16 *temp = NULL; size_t tempSize = 0; if (InFile_Open(&(m_p->m_archiveStream.file), m_p->m_packagePath.toUtf8().data())) { qDebug() << "Can not open file: " << m_p->m_packagePath; m_p->m_isOpen = false; return false; } FileInStream_CreateVTable(&(m_p->m_archiveStream)); LookToRead_CreateVTable(&(m_p->m_lookStream), False); m_p->m_lookStream.realStream = &(m_p->m_archiveStream.s); LookToRead_Init(&(m_p->m_lookStream)); CrcGenerateTable(); SzArEx_Init(&(m_p->m_db)); res = SzArEx_Open(&(m_p->m_db), &(m_p->m_lookStream.s), &(m_p->m_allocImp), &(m_p->m_allocTempImp)); if (res == SZ_OK) { for (UInt32 i = 0; i < m_p->m_db.db.NumFiles; i++) { size_t len = SzArEx_GetFileNameUtf16(&(m_p->m_db), i, NULL); if (len > tempSize) { SzFree(NULL, temp); tempSize = len; temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0])); if (temp == 0) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&(m_p->m_db), i, temp); // TODO: Codec? QString fileName = QString::fromUtf16(temp); m_p->m_fileNameList << fileName; const CSzFileItem &fileItem = m_p->m_db.db.Files[i]; Qt7zFileInfo fileInfo; fileInfo.fileName = fileName; fileInfo.arcName = m_p->m_packagePath; fileInfo.size = fileItem.Size; fileInfo.isDir = fileItem.IsDir; fileInfo.isCrcDefined = fileItem.CrcDefined; fileInfo.crc = fileItem.Crc; m_p->m_fileInfoList << fileInfo; if (res != SZ_OK) break; } } SzFree(NULL, temp); if (res == SZ_OK) { m_p->m_isOpen = true; return true; } else { m_p->m_isOpen = false; return false; } }
bool SZFilePack::open(const char* packFileName) { close(); UInt32 i; SRes res; UInt16 *temp = NULL; size_t tempSize = 0; CBuf buf; buf.data = new byte[MAX_PATH]; buf.size = MAX_PATH; mPackFileName = packFileName; if ( InFile_Open(&mArchiveStream.file, packFileName) ) { PrintError("can not open input file"); return false; } FileInStream_CreateVTable(&mArchiveStream); LookToRead_CreateVTable(&mLookStream, False); mLookStream.realStream = &mArchiveStream.s; LookToRead_Init(&mLookStream); CrcGenerateTable(); SzArEx_Init(&mDb); res = SzArEx_Open(&mDb, &mLookStream.s, &mAllocImp, &mAllocTempImp); if (res == SZ_OK) { for (i = 0; i < mDb.db.NumFiles; i++) { size_t len; const CSzFileItem *f = mDb.db.Files + i; if (f->IsDir) continue; len = SzArEx_GetFileNameUtf16(&mDb, i, NULL); if (len > tempSize) { SzFree(NULL, temp); tempSize = len; temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0])); if (temp == 0) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&mDb, i, temp); if (res != SZ_OK) break; // 保存所有文件的索引号到hash表中 res = Utf16_To_Char(&buf, temp, 0); if (res != SZ_OK) break; //名字转成小写 _strlwr((char*)buf.data); string key = (const char*)buf.data; mIndexMap[key] = i; } } SzFree(NULL, temp); delete[] buf.data; mIsPackOpened = true; return true; }