예제 #1
0
CArchive7Zip::~CArchive7Zip(void)
{
    if (archiveStream.File) {
        SzArDbExFree(&db, allocImp.Free);
        fclose(archiveStream.File);
    }
}
예제 #2
0
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);
}
예제 #3
0
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 */
예제 #4
0
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 */
예제 #5
0
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
}
예제 #6
0
파일: 7zMain.cpp 프로젝트: mixxit/solinia
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;
}
예제 #7
0
void SzClose()
{
	if(SzDb.Database.NumFiles > 0)
		SzArDbExFree(&SzDb, SzAllocImp.Free);
}
예제 #8
0
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;
	}
}
예제 #9
0
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 */
예제 #10
0
파일: unpack.c 프로젝트: Ando02/wubiuefi
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;
}
예제 #11
0
파일: archive_7z.cpp 프로젝트: WndSks/msys
/* Scoped deleter function for the 7-zip archive database */
static void SzArDbExDeleter(CArchiveDatabaseEx* db)
{
	SzArDbExFree(db, SzFree);
}
예제 #12
0
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;
}
예제 #13
0
파일: 7zMain.c 프로젝트: diegocr/7zUI
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;
}
예제 #14
0
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;
}
예제 #15
0
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;
}