CArchive7Zip::~CArchive7Zip(void) { if (archiveStream.File) { SzArDbExFree(&db, allocImp.Free); fclose(archiveStream.File); } }
void SzUninit(void* ctx) { SzContext* archiveStream = (SzContext*)ctx; if (archiveStream->File) { archiveStream->allocImp.Free(archiveStream->outBuffer); SzArDbExFree(&archiveStream->db, archiveStream->allocImp.Free); fclose(archiveStream->File); } if (archiveStream->archive) free(archiveStream->archive); free(ctx); }
static void LZMA_closeArchive(void *opaque) { LZMAarchive *archive = (LZMAarchive *) opaque; #if 0 /* !!! FIXME: you shouldn't have to do this. */ PHYSFS_uint32 fileIndex = 0, numFiles = archive->db.Database.NumFiles; for (fileIndex = 0; fileIndex < numFiles; fileIndex++) { LZMA_fileClose(&archive->files[fileIndex]); } /* for */ #endif SzArDbExFree(&archive->db, SzFreePhysicsFS); archive->stream.io->destroy(archive->stream.io); lzma_archive_exit(archive); } /* LZMA_closeArchive */
static void LZMA_dirClose(dvoid *opaque) { LZMAarchive *archive = (LZMAarchive *) opaque; LZMAentry *entry = archive->firstEntry; LZMAentry *tmpEntry = entry; while (entry != NULL) { tmpEntry = entry->next; LZMA_fileClose(entry); entry = tmpEntry; } /* while */ SzArDbExFree(&archive->db, SzFreePhysicsFS); __PHYSFS_platformClose(archive->stream.File); /* Free the cache which might have been allocated by LZMA_read() */ allocator.Free(archive->folder); allocator.Free(archive); } /* LZMA_dirClose */
C7zip::~C7zip (void) { if (m_db) { delete m_db; m_db = NULL; } #ifdef tofix SetNotificationCallback(NULL,NULL); SzArDbExFree(&m_db, m_allocImp.Free); if (m_archiveStream.File) { fclose(m_archiveStream.File); } if (m_outBuffer) { m_allocImp.Free(m_outBuffer); } #endif }
int main(int numargs, char *args[]) { CFileInStream archiveStream; CArchiveDatabaseEx db; SZ_RESULT res; ISzAlloc allocImp; ISzAlloc allocTempImp; printf("\n7z ANSI-C Decoder 4.43 Copyright (c) 1999-2006 Igor Pavlov 2006-06-04\n"); if (numargs == 1) { printf( "\nUsage: 7zDec <command> <archive_name>\n\n" "<Commands>\n" " e: Extract files from archive\n" " l: List contents of archive\n" " t: Test integrity of archive\n"); return 0; } if (numargs < 3) { PrintError("incorrect command"); return 1; } archiveStream.File = fopen(args[2], "rb"); if (archiveStream.File == 0) { PrintError("can not open input file"); return 1; } archiveStream.InStream.Read = SzFileReadImp; archiveStream.InStream.Seek = SzFileSeekImp; allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; InitCrcTable(); SzArDbExInit(&db); res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp); if (res == SZ_OK) { char *command = args[1]; int listCommand = 0; int testCommand = 0; int extractCommand = 0; if (strcmp(command, "l") == 0) listCommand = 1; if (strcmp(command, "t") == 0) testCommand = 1; else if (strcmp(command, "e") == 0) extractCommand = 1; if (listCommand) { UInt32 i; for (i = 0; i < db.Database.NumFiles; i++) { CFileItem *f = db.Database.Files + i; printf("%10d %s\n", (int)f->Size, f->Name); } } else if (testCommand || extractCommand) { 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) */ printf("\n"); for (i = 0; i < db.Database.NumFiles; i++) { size_t offset; size_t outSizeProcessed; CFileItem *f = db.Database.Files + i; if (f->IsDirectory) printf("Directory "); else printf(testCommand ? "Testing ": "Extracting"); printf(" %s", f->Name); if (f->IsDirectory) { printf("\n"); continue; } res = SzExtract(&archiveStream.InStream, &db, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; if (!testCommand) { FILE *outputHandle; size_t processedSize; char *fileName = f->Name; size_t nameLen = strlen(f->Name); for (; nameLen > 0; nameLen--) if (f->Name[nameLen - 1] == '/') { fileName = f->Name + nameLen; break; } outputHandle = fopen(fileName, "wb+"); if (outputHandle == 0) { PrintError("can not open output file"); res = SZE_FAIL; break; } processedSize = fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle); if (processedSize != outSizeProcessed) { PrintError("can not write output file"); res = SZE_FAIL; break; } if (fclose(outputHandle)) { PrintError("can not close output file"); res = SZE_FAIL; break; } } printf("\n"); } allocImp.Free(outBuffer); } else { PrintError("incorrect command"); res = SZE_FAIL; } } SzArDbExFree(&db, allocImp.Free); fclose(archiveStream.File); if (res == SZ_OK) { printf("\nEverything is Ok\n"); return 0; } if (res == SZE_OUTOFMEMORY) PrintError("can not allocate memory"); else printf("\nERROR #%d\n", res); return 1; }
void SzClose() { if(SzDb.Database.NumFiles > 0) SzArDbExFree(&SzDb, SzAllocImp.Free); }
int SzExtractContent(void* ctx, char* archive, char* filename, void** pbuf) { SzContext* archiveStream = (SzContext*)ctx; FILE* fp = 0; SZ_RESULT res; if (!archiveStream->archive || strcmp(archive, archiveStream->archive)) { fp = fopen(archive, "rb"); if (!fp) return -1; } if (archiveStream->File) { if (!archive || fp) { archiveStream->allocImp.Free(archiveStream->outBuffer); SzArDbExFree(&archiveStream->db, archiveStream->allocImp.Free); fclose(archiveStream->File); archiveStream->File = 0; archiveStream->outBuffer = 0; /* it must be 0 before first call for each new archive. */ archiveStream->outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ if (archiveStream->archive) { free(archiveStream->archive); archiveStream->archive = 0; } } } if (!archive) return -1; if (!archiveStream->File) { archiveStream->File = fp; archiveStream->InStream.Read = SzFileReadImp; archiveStream->InStream.Seek = SzFileSeekImp; archiveStream->allocImp.Alloc = SzAlloc; archiveStream->allocImp.Free = SzFree; archiveStream->allocTempImp.Alloc = SzAllocTemp; archiveStream->allocTempImp.Free = SzFreeTemp; InitCrcTable(); SzArDbExInit(&archiveStream->db); res = SzArchiveOpen(&archiveStream->InStream, &archiveStream->db, &archiveStream->allocImp, &archiveStream->allocTempImp); if (res != SZ_OK) { SzArDbExFree(&archiveStream->db, archiveStream->allocImp.Free); fclose(archiveStream->File); archiveStream->File = 0; return -1; } archiveStream->archive = _strdup(archive); } if (filename) { 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) */ for (i = 0; i < archiveStream->db.Database.NumFiles; i++) { size_t offset; size_t outSizeProcessed; CFileItem *f = archiveStream->db.Database.Files + i; if (f->IsDirectory) { // is directory continue; } if (strcmp(f->Name, filename)) { // not matched continue; } res = SzExtract(&archiveStream->InStream, &archiveStream->db, i, &blockIndex, &archiveStream->outBuffer, &archiveStream->outBufferSize, &offset, &outSizeProcessed, &archiveStream->allocImp, &archiveStream->allocTempImp); if (res != SZ_OK) return -1; if (pbuf) *pbuf = (void*)(archiveStream->outBuffer + offset); return (int)outSizeProcessed; } return -1; } else { return archiveStream->db.Database.NumFiles; } }
static void *LZMA_openArchive(PHYSFS_Io *io, const char *name, int forWriting) { PHYSFS_uint8 sig[k7zSignatureSize]; size_t len = 0; LZMAarchive *archive = NULL; assert(io != NULL); /* shouldn't ever happen. */ BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL); if (io->read(io, sig, k7zSignatureSize) != k7zSignatureSize) return 0; BAIL_IF_MACRO(!TestSignatureCandidate(sig), PHYSFS_ERR_UNSUPPORTED, NULL); BAIL_IF_MACRO(!io->seek(io, 0), ERRPASS, NULL); archive = (LZMAarchive *) allocator.Malloc(sizeof (LZMAarchive)); BAIL_IF_MACRO(archive == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL); lzma_archive_init(archive); archive->stream.io = io; CrcGenerateTable(); SzArDbExInit(&archive->db); if (lzma_err(SzArchiveOpen(&archive->stream.inStream, &archive->db, &archive->stream.allocImp, &archive->stream.allocTempImp)) != SZ_OK) { SzArDbExFree(&archive->db, SzFreePhysicsFS); lzma_archive_exit(archive); return NULL; /* Error is set by lzma_err! */ } /* if */ len = archive->db.Database.NumFiles * sizeof (LZMAfile); archive->files = (LZMAfile *) allocator.Malloc(len); if (archive->files == NULL) { SzArDbExFree(&archive->db, SzFreePhysicsFS); lzma_archive_exit(archive); BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL); } /* * Init with 0 so we know when a folder is already cached * Values will be set by LZMA_openRead() */ memset(archive->files, 0, len); len = archive->db.Database.NumFolders * sizeof (LZMAfolder); archive->folders = (LZMAfolder *) allocator.Malloc(len); if (archive->folders == NULL) { SzArDbExFree(&archive->db, SzFreePhysicsFS); lzma_archive_exit(archive); BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL); } /* * Init with 0 so we know when a folder is already cached * Values will be set by LZMA_read() */ memset(archive->folders, 0, len); if(!lzma_files_init(archive)) { SzArDbExFree(&archive->db, SzFreePhysicsFS); lzma_archive_exit(archive); BAIL_MACRO(PHYSFS_ERR_OTHER_ERROR, NULL); } return archive; } /* LZMA_openArchive */
int unpack(char archive[512]) { UInt32 i; CFileInStream archive_stream; CArchiveDatabaseEx db; SZ_RESULT res; ISzAlloc alloc_imp; ISzAlloc alloc_temp_imp; #ifdef DEBUG printf("extracting %s...\n", archive); #endif archive_stream.File = open_file_r(archive); if (archive_stream.File == 0) { print_error("can not open input file"); return 1; } archive_stream.InStream.Read = read_file_imp; archive_stream.InStream.Seek = seek_file_imp; alloc_imp.Alloc = SzAlloc; alloc_imp.Free = SzFree; alloc_temp_imp.Alloc = SzAllocTemp; alloc_temp_imp.Free = SzFreeTemp; CrcGenerateTable(); //SEEK OFFSET size_t offset; offset = seek_beginning_of_archive(&archive_stream); //INIT DB SzArDbExInit(&db); //SET THE OFFSET g_offset = offset; seek_file_imp(&archive_stream.InStream, 0); //seek to beginning of file including offset res = SzArchiveOpen(&archive_stream.InStream, &db, &alloc_imp, &alloc_temp_imp); #ifdef DEBUG printf("res = %i\n",res); #endif if (res == SZ_OK) { /* if you need cache, use these 3 variables. if you use external function, you can make these variable as static. */ UInt32 block_index = 0xFFFFFFFF; /* it can have any value before first call (if out_buffer = 0) */ Byte *out_buffer = 0; /* it must be 0 before first call for each new archive. */ size_t out_buffer_size = 0; /* it can have any value before first call (if out_buffer = 0) */ //~ for (i = db.Database.NumFolders-1; i >0; i--) //~ { //~ CFileItem *f = db.Database.Folders + i; //~ if (!f->IsDirectory){ //~ } else { //~ } //~ } for (i = db.Database.NumFiles-1; i >0; i--) { CFileItem *f = db.Database.Files + i; if (!f->IsDirectory){ continue; } #ifdef DEBUG printf("Creating directory %s", f->Name); #endif if (create_directory(f->Name) != 0) { print_error("can not create directory"); } #ifdef DEBUG printf("\n"); #endif } for (i = 0; i < db.Database.NumFiles; i++) { CFileItem *f = db.Database.Files + i; #ifdef DEBUG printf("Extracting %s\n %d %s", f->Name, i, f->IsDirectory); #endif if (f->IsDirectory){ continue; } size_t out_size_processed; #ifdef DEBUG printf("Extracting %s\n", f->Name); #endif res = SzExtract(&archive_stream.InStream, &db, i, &block_index, &out_buffer, &out_buffer_size, &offset, &out_size_processed, &alloc_imp, &alloc_temp_imp); if (res != SZ_OK) break; MY_FILE_HANDLE output_handle = open_file_w(f->Name); if (output_handle == 0) { print_error("can not open output file"); res = SZE_FAIL; break; } size_t processed_size; processed_size = write_file(output_handle, out_buffer + offset, out_size_processed); if (processed_size != out_size_processed) { print_error("can not write output file"); res = SZE_FAIL; break; } if (close_file(output_handle)) { print_error("can not close output file"); res = SZE_FAIL; break; } #ifdef DEBUG printf("\n"); #endif } alloc_imp.Free(out_buffer); } SzArDbExFree(&db, alloc_imp.Free); close_file(archive_stream.File); if (res == SZ_OK) { #ifdef DEBUG printf("\nEverything is Ok\n"); #endif return 0; } if (res == (SZ_RESULT)SZE_NOTIMPL) print_error("decoder doesn't support this archive"); else if (res == (SZ_RESULT)SZE_OUTOFMEMORY) print_error("can not allocate memory"); else if (res == (SZ_RESULT)SZE_CRC_ERROR) print_error("CRC error"); else print_error("Unknown error"); //TBD print res return 1; }
/* Scoped deleter function for the 7-zip archive database */ static void SzArDbExDeleter(CArchiveDatabaseEx* db) { SzArDbExFree(db, SzFree); }
int SzParse(char * filepath, int method) { int nbfiles = 0; // save the offset and the length of this file inside the archive stream structure SzArchiveStream.offset = filelist[selection].offset; SzArchiveStream.len = filelist[selection].length; SzArchiveStream.pos = 0; // open file switch (method) { case METHOD_SD: case METHOD_USB: fatfile = fopen (filepath, "rb"); if(!fatfile) return 0; break; case METHOD_SMB: smbfile = OpenSMBFile(filepath); if(!smbfile) return 0; break; } // set szMethod to current chosen load method szMethod = method; // set handler functions for reading data from FAT/SMB/DVD SzArchiveStream.InStream.Read = SzFileReadImp; SzArchiveStream.InStream.Seek = SzFileSeekImp; // set default 7Zip SDK handlers for allocation and freeing memory SzAllocImp.Alloc = SzAlloc; SzAllocImp.Free = SzFree; SzAllocTempImp.Alloc = SzAllocTemp; SzAllocTempImp.Free = SzFreeTemp; // prepare CRC and 7Zip database structures InitCrcTable(); SzArDbExInit(&SzDb); // open the archive SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp, &SzAllocTempImp); if (SzRes != SZ_OK) { SzDisplayError(SzRes); // free memory used by the 7z SDK SzClose(); } else // archive opened successfully { if(SzDb.Database.NumFiles > 0) { // Parses the 7z into a full file listing // erase all previous entries memset(&filelist, 0, sizeof(FILEENTRIES) * MAXFILES); // add '..' folder in case the user wants exit the 7z strncpy(filelist[0].displayname, "..", 2); filelist[0].flags = 1; filelist[0].offset = dvddir; filelist[0].length = dvddirlength; // get contents and parse them into file list structure unsigned int SzI, SzJ; SzJ = 1; for (SzI = 0; SzI < SzDb.Database.NumFiles; SzI++) { SzF = SzDb.Database.Files + SzI; // skip directories if (SzF->IsDirectory) continue; // do not exceed MAXFILES to avoid possible buffer overflows if (SzJ == (MAXFILES - 1)) break; // parse information about this file to the dvd file list structure strncpy(filelist[SzJ].filename, SzF->Name, MAXJOLIET); // copy joliet name (useless...) filelist[SzJ].filename[MAXJOLIET] = 0; // terminate string strncpy(filelist[SzJ].displayname, SzF->Name, MAXDISPLAY+1); // crop name for display filelist[SzJ].length = SzF->Size; // filesize filelist[SzJ].offset = SzI; // the extraction function identifies the file with this number filelist[SzJ].flags = 0; // only files will be displayed (-> no flags) SzJ++; } // update maxfiles and select the first entry offset = selection = 0; nbfiles = SzJ; } else { SzArDbExFree(&SzDb, SzAllocImp.Free); } } // close file switch (method) { case METHOD_SD: case METHOD_USB: fclose(fatfile); break; case METHOD_SMB: SMB_CloseFile (smbfile); break; } return nbfiles; }
int _7zArchive( STRPTR filename, int mode ) { CFileInStream archiveStream; CArchiveDatabaseEx db; SZ_RESULT res; ISzAlloc allocImp; ISzAlloc allocTempImp; archiveStream.File = Open( filename, MODE_OLDFILE); if (!archiveStream.File) { PrintError("Unable to open archive!"); goto done; } archiveStream.InStream.zRead = SzFileReadImp; archiveStream.InStream.zSeek = SzFileSeekImp; allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; InitCrcTable(); SzArDbExInit(&db); res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp); if (res == SZ_OK) { if( G->CliUsage ) { ShowProgramInfo ( ); Printf("\n%s archive %s\n", (long)((mode == 1) ? "Listing":((mode == 2) ? "Testing":"Extracting")), (long) FilePart( filename )); } if ( mode == 1 ) // LIST mode { UInt32 i; if( G->CliUsage ) { Printf("\n%7s%9s%14s%7s%8s\n",(long)"Date",(long)"Time",(long)"Size",(long)"CRC",(long)"Name"); for( i = 0; i < 60 ; i++ ) PutStr("-"); PutStr("\n"); } for (i = 0; i < db.Database.NumFiles; i++) { CFileItem *f = db.Database.Files + i; if( G->CliUsage ) { UBYTE date[20]; ItemTime( f, date, sizeof(date), FALSE ); Printf("%s%11ld %08lx %s\n", (long)date, (long)f->Size, f->IsFileCRCDefined ? f->FileCRC:0, (long)f->Name); } else NListInsert((APTR) f ); } } else { 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) if( G->CliUsage ) PutStr("\n"); for (i = 0; i < db.Database.NumFiles; i++) { size_t offset; size_t outSizeProcessed; CFileItem *f = db.Database.Files + i; if( G->CliUsage ) { #if 0 if (f->IsDirectory) PutStr("Directory"); else Printf("%12s",(long)((mode == 2) ? "Testing":"Extracting")); Printf(" %s", (long)f->Name); #else if (!f->IsDirectory) Printf("%12s %s",(long)((mode == 2) ? "Testing":"Extracting"), (long)f->Name); #endif } else { STATIC UBYTE msg[256]; SNPrintf( msg, sizeof(msg)-1, "%12s %s", (mode == 2) ? "Testing":"Extracting", f->Name ); GaugeUpdate( msg, i*100/db.Database.NumFiles ); } if (f->IsDirectory) { // if( G->CliUsage ) // PutStr("\n"); continue; } res = SzExtract(&archiveStream.InStream, &db, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; if ( mode == 3 ) // EXTRACT mode { BPTR outputHandle; UInt32 processedSize; MakeDir( f->Name ); // creates ALL Directories pointing to this file outputHandle = Open( f->Name, MODE_NEWFILE ); if (outputHandle == 0) { PrintError("Unable to open output file!"); res = SZE_FAIL; break; } processedSize = Write(outputHandle, outBuffer + offset, outSizeProcessed); if (processedSize != outSizeProcessed) { PrintError("Cannot write to output file!"); res = SZE_FAIL; break; } Close(outputHandle); SetFileTimeToFile( f ); } if( G->CliUsage ) PutStr("\n"); } allocImp.Free(outBuffer); } } SzArDbExFree(&db, allocImp.Free); Close(archiveStream.File); if (res == SZ_OK) { if( G->CliUsage ) Printf("\n%s\n", (long)"Everything is Ok"); else GaugeUpdate("Everything is Ok", 0 ); return 0; } #if 0 if (res == SZE_OUTOFMEMORY) PrintError("can not allocate memory"); else if( G->CliUsage ) Printf("\nERROR #%ld\n", res); #else PrintError(SzErrorString( res )); #endif if( ! G->CliUsage ) GaugeUpdate("error %ld procesing archive", res ); done: return 1; }
int SzParse(char * filepath, int method) { if(!filepath) return 0; int nbfiles = 0; // save the length/offset of this file unsigned int filelen = browserList[browser.selIndex].length; u64 fileoff = browserList[browser.selIndex].offset; // setup archive stream SzArchiveStream.offset = 0; SzArchiveStream.len = filelen; SzArchiveStream.pos = 0; // open file switch (method) { case METHOD_SD: case METHOD_USB: case METHOD_SMB: file = fopen (filepath, "rb"); if(!file) return 0; break; case METHOD_DVD: SwitchDVDFolder(filepath); break; } // set szMethod to current chosen load method szMethod = method; // set handler functions for reading data from SD/USB/SMB/DVD SzArchiveStream.InStream.Read = SzFileReadImp; SzArchiveStream.InStream.Seek = SzFileSeekImp; // set default 7Zip SDK handlers for allocation and freeing memory SzAllocImp.Alloc = SzAlloc; SzAllocImp.Free = SzFree; SzAllocTempImp.Alloc = SzAllocTemp; SzAllocTempImp.Free = SzFreeTemp; // prepare CRC and 7Zip database structures InitCrcTable(); SzArDbExInit(&SzDb); // open the archive SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp, &SzAllocTempImp); if (SzRes != SZ_OK) { SzDisplayError(SzRes); // free memory used by the 7z SDK SzClose(); } else // archive opened successfully { if(SzDb.Database.NumFiles > 0) { // Parses the 7z into a full file listing // reset browser ResetBrowser(); // add '..' folder in case the user wants exit the 7z strncpy(browserList[0].displayname, "..", 2); browserList[0].isdir = 1; browserList[0].offset = fileoff; browserList[0].length = filelen; // get contents and parse them into file list structure unsigned int SzI, SzJ; SzJ = 1; for (SzI = 0; SzI < SzDb.Database.NumFiles; SzI++) { SzF = SzDb.Database.Files + SzI; // skip directories if (SzF->IsDirectory) continue; BROWSERENTRY * newBrowserList = (BROWSERENTRY *)realloc(browserList, (SzJ+1) * sizeof(BROWSERENTRY)); if(!newBrowserList) // failed to allocate required memory { ResetBrowser(); WaitPrompt("Out of memory: too many files!"); nbfiles = 0; break; } else { browserList = newBrowserList; } memset(&(browserList[SzJ]), 0, sizeof(BROWSERENTRY)); // clear the new entry // parse information about this file to the dvd file list structure strncpy(browserList[SzJ].filename, SzF->Name, MAXJOLIET); // copy joliet name (useless...) strncpy(browserList[SzJ].displayname, SzF->Name, MAXDISPLAY); // crop name for display browserList[SzJ].length = SzF->Size; // filesize browserList[SzJ].offset = SzI; // the extraction function identifies the file with this number browserList[SzJ].isdir = 0; // only files will be displayed (-> no flags) SzJ++; } nbfiles = SzJ; } else { SzArDbExFree(&SzDb, SzAllocImp.Free); } } // close file switch (method) { case METHOD_SD: case METHOD_USB: case METHOD_SMB: fclose(file); break; } return nbfiles; }
int main(int numargs, char *args[]) { CFileInStream archiveStream; CArchiveDatabaseEx db; SZ_RESULT res; ISzAlloc allocImp; ISzAlloc allocTempImp; printf("\n7z ANSI-C Decoder 4.48 Copyright (c) 1999-2007 Igor Pavlov 2007-06-21\n"); if (numargs == 1) { printf( "\nUsage: 7zDec <command> <archive_name>\n\n" "<Commands>\n" " e: Extract files from archive\n" " l: List contents of archive\n" " t: Test integrity of archive\n"); return 0; } if (numargs < 3) { PrintError("incorrect command"); return 1; } archiveStream.File = #ifdef USE_WINDOWS_FUNCTIONS CreateFile(args[2], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (archiveStream.File == INVALID_HANDLE_VALUE) #else archiveStream.File = fopen(args[2], "rb"); if (archiveStream.File == 0) #endif { PrintError("can not open input file"); return 1; } archiveStream.InStream.Read = SzFileReadImp; archiveStream.InStream.Seek = SzFileSeekImp; allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; CrcGenerateTable(); SzArDbExInit(&db); res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp); if (res == SZ_OK) { char *command = args[1]; int listCommand = 0; int testCommand = 0; int extractCommand = 0; if (strcmp(command, "l") == 0) listCommand = 1; if (strcmp(command, "t") == 0) testCommand = 1; else if (strcmp(command, "e") == 0) extractCommand = 1; if (listCommand) { UInt32 i; for (i = 0; i < db.Database.NumFiles; i++) { CFileItem *f = db.Database.Files + i; char s[32], t[32]; ConvertNumberToString(f->Size, s); if (f->IsLastWriteTimeDefined) ConvertFileTimeToString(&f->LastWriteTime, t); else strcpy(t, " "); printf("%10s %s %s\n", s, t, f->Name); } } else if (testCommand || extractCommand) { 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) */ printf("\n"); for (i = 0; i < db.Database.NumFiles; i++) { size_t offset; size_t outSizeProcessed; CFileItem *f = db.Database.Files + i; if (f->IsDirectory) printf("Directory "); else printf(testCommand ? "Testing ": "Extracting"); printf(" %s", f->Name); if (f->IsDirectory) { printf("\n"); continue; } res = SzExtract(&archiveStream.InStream, &db, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; if (!testCommand) { MY_FILE_HANDLE outputHandle; size_t processedSize; char *fileName = f->Name; size_t nameLen = strlen(f->Name); for (; nameLen > 0; nameLen--) if (f->Name[nameLen - 1] == '/') { fileName = f->Name + nameLen; break; } outputHandle = #ifdef USE_WINDOWS_FUNCTIONS CreateFile(fileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (outputHandle == INVALID_HANDLE_VALUE) #else fopen(fileName, "wb+"); if (outputHandle == 0) #endif { PrintError("can not open output file"); res = SZE_FAIL; break; } processedSize = MyWriteFile(outputHandle, outBuffer + offset, outSizeProcessed); if (processedSize != outSizeProcessed) { PrintError("can not write output file"); res = SZE_FAIL; break; } if (MyCloseFile(outputHandle)) { PrintError("can not close output file"); res = SZE_FAIL; break; } } printf("\n"); } allocImp.Free(outBuffer); } else { PrintError("incorrect command"); res = SZE_FAIL; } } SzArDbExFree(&db, allocImp.Free); MyCloseFile(archiveStream.File); if (res == SZ_OK) { printf("\nEverything is Ok\n"); return 0; } if (res == (SZ_RESULT)SZE_NOTIMPL) PrintError("decoder doesn't support this archive"); else if (res == (SZ_RESULT)SZE_OUTOFMEMORY) PrintError("can not allocate memory"); else if (res == (SZ_RESULT)SZE_CRC_ERROR) PrintError("CRC error"); else printf("\nERROR #%d\n", res); return 1; }