Пример #1
6
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;
	}
}
Пример #2
0
ar_archive *ar_open_7z_archive(ar_stream *stream)
{
    ar_archive *ar;
    ar_archive_7z *_7z;
    SRes res;

    if (!ar_seek(stream, 0, SEEK_SET))
        return NULL;

    ar = ar_open_archive(stream, sizeof(ar_archive_7z), _7z_close, _7z_parse_entry, _7z_get_name, _7z_uncompress, NULL, 0);
    if (!ar)
        return NULL;

    _7z = (ar_archive_7z *)ar;
    CSeekStream_CreateVTable(&_7z->in_stream, stream);
    LookToRead_CreateVTable(&_7z->look_stream, False);
    _7z->look_stream.realStream = &_7z->in_stream.super;
    LookToRead_Init(&_7z->look_stream);

#ifdef USE_7Z_CRC32
    CrcGenerateTable();
#endif

    SzArEx_Init(&_7z->data);
    res = SzArEx_Open(&_7z->data, &_7z->look_stream.s, &gSzAlloc, &gSzAlloc);
    if (res != SZ_OK) {
        if (res != SZ_ERROR_NO_ARCHIVE)
            warn("Invalid 7z archive (failed with error %d)", res);
        free(ar);
        return NULL;
    }

    return ar;
}
Пример #3
0
int CALLBACK
WinMain(HINSTANCE hInstance, HINSTANCE hInstNULL, LPSTR lpszCmdLine, int nCmdShow)
{
    setlocale(LC_ALL, "Russian");

    CrcGenerateTable();

    options_load();
    dialog_main(hInstance, NULL);
    return 0;
}
Memory* ElfInterface::CreateGnuDebugdataMemory() {
  if (gnu_debugdata_offset_ == 0 || gnu_debugdata_size_ == 0) {
    return nullptr;
  }

  // TODO: Only call these initialization functions once.
  CrcGenerateTable();
  Crc64GenerateTable();

  std::vector<uint8_t> src(gnu_debugdata_size_);
  if (!memory_->Read(gnu_debugdata_offset_, src.data(), gnu_debugdata_size_)) {
    gnu_debugdata_offset_ = 0;
    gnu_debugdata_size_ = static_cast<uint64_t>(-1);
    return nullptr;
  }

  ISzAlloc alloc;
  CXzUnpacker state;
  alloc.Alloc = [](void*, size_t size) { return malloc(size); };
  alloc.Free = [](void*, void* ptr) { return free(ptr); };

  XzUnpacker_Construct(&state, &alloc);

  std::unique_ptr<MemoryBuffer> dst(new MemoryBuffer);
  int return_val;
  size_t src_offset = 0;
  size_t dst_offset = 0;
  ECoderStatus status;
  dst->Resize(5 * gnu_debugdata_size_);
  do {
    size_t src_remaining = src.size() - src_offset;
    size_t dst_remaining = dst->Size() - dst_offset;
    if (dst_remaining < 2 * gnu_debugdata_size_) {
      dst->Resize(dst->Size() + 2 * gnu_debugdata_size_);
      dst_remaining += 2 * gnu_debugdata_size_;
    }
    return_val = XzUnpacker_Code(&state, dst->GetPtr(dst_offset), &dst_remaining, &src[src_offset],
                                 &src_remaining, CODER_FINISH_ANY, &status);
    src_offset += src_remaining;
    dst_offset += dst_remaining;
  } while (return_val == SZ_OK && status == CODER_STATUS_NOT_FINISHED);
  XzUnpacker_Free(&state);
  if (return_val != SZ_OK || !XzUnpacker_IsStreamWasFinished(&state)) {
    gnu_debugdata_offset_ = 0;
    gnu_debugdata_size_ = static_cast<uint64_t>(-1);
    return nullptr;
  }

  // Shrink back down to the exact size.
  dst->Resize(dst_offset);

  return dst.release();
}
Пример #5
0
value ml_sevenzip_init(value unit)
{
  CAMLparam1 (unit);

  CrcGenerateTable();

  allocImp.Alloc = SzAlloc;
  allocImp.Free = SzFree;
  allocTempImp.Alloc = SzAllocTemp;
  allocTempImp.Free = SzFreeTemp;

  CAMLreturn (Val_unit);
}
Пример #6
0
	C7zArchive(FileReader *file) : ArchiveStream(file)
	{
		if (g_CrcTable[1] == 0)
		{
			CrcGenerateTable();
		}
		file->Seek(0, SEEK_SET);
		LookToRead_CreateVTable(&LookStream, false);
		LookStream.realStream = &ArchiveStream.s;
		LookToRead_Init(&LookStream);
		SzArEx_Init(&DB);
		BlockIndex = 0xFFFFFFFF;
		OutBuffer = NULL;
		OutBufferSize = 0;
	}
Пример #7
0
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;
}
Пример #8
0
static void initArchives()
{
    CrcGenerateTable();

    registerArc7z();

    registerCodecBCJ();
    registerCodecBCJ2();
    registerCodecLZMA();
    registerCodecLZMA2();

    registerCodecDelta();
    registerCodecBranch();
    registerCodecByteSwap();

    NArchive::NXz::registerArcxz();
    NArchive::NSplit::registerArcSplit();
    NArchive::NLzma::NLzmaAr::registerArcLzma();
    NArchive::NLzma::NLzma86Ar::registerArcLzma86();
}
Пример #9
0
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;
}
Пример #10
0
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);
}
Пример #11
0
void ExtractPayload(const void* payload, size_t payloadSize, const WCHAR* prefix)
{
	CMemInStream memStream;
	MemInStream_Init(&memStream, payload, payloadSize);

	CrcGenerateTable();

	ISzAlloc alloc = { SzAlloc, SzFree };
	CSzArEx db;
	SzArEx_Init(&db);
	SRes res = SzArEx_Open(&db, &memStream.s, &alloc, &alloc);
	if (res != SZ_OK)
	{
		SzArEx_Free(&db, &alloc);
		return;
	}

	WCHAR buffer[MAX_PATH];
	UInt32 blockIndex = 0xFFFFFFFF;
	Byte* outBuffer = 0;
	size_t outBufferSize = 0;

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

		SzArEx_GetFileNameUtf16(&db, i, (UInt16*)buffer);
		WCHAR* destPath = buffer;
		if (wcsncmp(destPath, prefix, 3) == 0 ||
			wcsncmp(destPath, L"ALL", 3) == 0)
		{
			// Skip the prefix (X64/X32/ALL) and the path separater.
			destPath += 4;
		}
		else
		{
			// This file isn't for this arch.
			continue;
		}

		if (!f->IsDir)
		{
			res = SzArEx_Extract(
				&db, &memStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset,
				&outSizeProcessed, &alloc, &alloc);
			if (res != SZ_OK)
			{
				break;
			}
		}

		for (size_t j = 0; destPath[j] != L'\0'; ++j)
		{
			if (destPath[j] == L'/')
			{
				destPath[j] = L'\0';
				CreateDirectory(destPath, NULL);
				destPath[j] = CHAR_PATH_SEPARATOR;
			}
		}

		if (f->IsDir)
		{
			CreateDirectory(destPath, NULL);
			continue;
		}

		CSzFile outFile;
		if (OutFile_OpenW(&outFile, destPath))
		{
			res = SZ_ERROR_FAIL;
			break;
		}
		size_t processedSize = outSizeProcessed;
		if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 ||
			processedSize != outSizeProcessed)
		{
			res = SZ_ERROR_FAIL;
			break;
		}
		if (File_Close(&outFile))
		{
			res = SZ_ERROR_FAIL;
			break;
		}

		if (f->AttribDefined) SetFileAttributesW(destPath, f->Attrib);
	}

	IAlloc_Free(&alloc, outBuffer);
	SzArEx_Free(&db, &alloc);

	if (res == SZ_OK)
	{
		// Success.
	}
}
Пример #12
0
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;
}
Пример #13
0
ASM(LONG) sz_GetInfo(REG(a0, struct xadArchiveInfo *ai),
REG(a6, struct xadMasterBase *xadMasterBase))
#endif
{
#ifdef __amigaos4__
    IExec = (struct ExecIFace *)(*(struct ExecBase **)4)->MainInterface;

    newlibbase = OpenLibrary("newlib.library", 52);
    if(newlibbase)
        INewlib = GetInterface(newlibbase, "main", 1, NULL);
#elif defined(__AROS__)
	if(!(aroscbase = OpenLibrary("arosc.library", 41)))
		return(XADERR_RESOURCE);
#else
 SysBase = *(struct ExecBase **)4;
#endif

	ai->xai_PrivateClient = xadAllocVec(sizeof(struct xad7zprivate),MEMF_PRIVATE | MEMF_CLEAR);
	struct xad7zprivate *xad7z = ai->xai_PrivateClient;
  struct xadFileInfo *fi;
	long err=XADERR_OK;
	long res=SZ_OK;
	size_t namelen;
	UBYTE *namebuf; // was UWORD
  CFileXadInStream *archiveStream = &xad7z->archiveStream;
  CSzArEx *db = &xad7z->db;       /* 7z archive database structure */
  ISzAlloc allocImp;           /* memory functions for main pool */
  ISzAlloc allocTempImp;       /* memory functions for temporary pool */
	CLookToRead *lookStream = &xad7z->lookStream;

  allocImp.Alloc = SzAlloc;
  allocImp.Free = SzFree;
  allocTempImp.Alloc = SzAllocTemp;
  allocTempImp.Free = SzFreeTemp;

  archiveStream->ai = ai;
#ifdef __amigaos4__
  archiveStream->IxadMaster = IxadMaster;
#else
  archiveStream->xadMasterBase = xadMasterBase;
#endif
  archiveStream->InStream.Read = SzFileReadImp;
  archiveStream->InStream.Seek = SzFileSeekImp;

	if(namebuf = AllocVec(1024, MEMF_PRIVATE))
	{

  LookToRead_CreateVTable(lookStream, False);
  lookStream->realStream = (ISeekInStream *)&archiveStream->InStream;
  LookToRead_Init(lookStream);

	xad7z->blockIndex = 0xfffffff;
	xad7z->outBuffer = 0;
	xad7z->outBufferSize = 0;

  CrcGenerateTable();
  SzArEx_Init(db);
  res = SzArEx_Open(db, &lookStream->s, &allocImp, &allocTempImp);

	if(res == SZ_OK)
    {
      UInt32 i;

      for (i = 0; i < db->db.NumFiles; i++)
      {
    fi = (struct xadFileInfo *) xadAllocObjectA(XADOBJ_FILEINFO, NULL);
    if (!fi) return(XADERR_NOMEMORY);
        CSzFileItem *f = db->db.Files + i;
		fi->xfi_DataPos = 0; //ai->xai_InPos; // i
		fi->xfi_Size = f->Size;

	namelen = SzArEx_GetFileNameUtf16(db, i, namebuf); // &
    if (!(fi->xfi_FileName = xadConvertName(CHARSET_HOST,
#if defined(__AROS__) && (AROS_BIG_ENDIAN == 0)
							XAD_CHARACTERSET, CHARSET_UNICODE_UCS2_LITTLEENDIAN,
#else
							XAD_CHARACTERSET, CHARSET_UNICODE_UCS2_BIGENDIAN,
#endif
							XAD_STRINGSIZE, namelen,
							XAD_CSTRING, namebuf, // no *
							TAG_DONE))) return(XADERR_NOMEMORY);

    xadConvertDates(XAD_DATEAMIGA,ConvertFileTime(&f->MTime),
					XAD_GETDATEXADDATE,&fi->xfi_Date,
					TAG_DONE);

      fi->xfi_CrunchSize  = 0; //(long) (db->Database.PackSizes[i] << 32); //fi->xfi_Size;

	fi->xfi_Flags = 0;
		if(f->IsDir)
		{
			fi->xfi_Flags |= XADFIF_DIRECTORY;
		}

		 if ((err = xadAddFileEntryA(fi, ai, NULL))) return(XADERR_NOMEMORY);
      }
    }
	FreeVec(namebuf);
	}

	return(sztoxaderr(res));
}
Пример #14
0
struct CCRCTableInit { CCRCTableInit() { CrcGenerateTable(); } } g_CRCTableInit;
Пример #15
0
	int SzExtractFromBuf(const void* pBuf, unsigned int nBufLength, wchar_t* cUnPackPath, DWORD dwPathLength)
	{
		if(pBuf==NULL || nBufLength<=0)
			return 1;

		SRes res = SZ_OK;
		CBufInStream archiveStream;
		CLookToRead lookStream;
		CSzArEx db;
		ISzAlloc allocImp;
		ISzAlloc allocTempImp;
		const char *errorMessage = NULL;

		wchar_t path[MAX_PATH * 3 + 2] = {0};
		size_t pathLen = wcslen(cUnPackPath);
		wcscpy_s(path,MAX_PATH * 3 + 2, cUnPackPath);

		if (cUnPackPath[pathLen - 1] != '\\') 
		{ 
			wcscat_s(path, L"\\");
			pathLen = wcslen(path);
		}


		CrcGenerateTable();

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

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

		BufInStream_CreateVTable(&archiveStream);
		LookToRead_CreateVTable(&lookStream, False);

		
		if (InBuf_Init(&archiveStream.buf, pBuf, nBufLength) != 0)
		{
			errorMessage = "can not open input file";
			res = SZ_ERROR_FAIL;
		}
		else
		{
			UInt64 pos = 0;
			if (!FindSignature(&archiveStream.buf, &pos))
				res = SZ_ERROR_FAIL;
			else if (InBuf_Seek(&archiveStream.buf, (Int64 *)&pos, SZ_SEEK_SET) != 0)
				res = SZ_ERROR_FAIL;
			if (res != 0)
				errorMessage = "Can't find 7z archive";
		}

		if (res == SZ_OK)
		{
			lookStream.realStream = &archiveStream.s;
			LookToRead_Init(&lookStream);
		}

		SzArEx_Init(&db);
		if (res == SZ_OK)
		{
			res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
		}
		if (res == SZ_OK)
		{
			UInt32 executeFileIndex = (UInt32)(Int32)-1;
			UInt32 minPrice = 1 << 30;
			UInt32 i;
			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.db.NumFiles; i++)
			{
				size_t offset = 0;
				size_t outSizeProcessed = 0;
				const CSzFileItem *f = db.db.Files + i;
				size_t len;
				wchar_t *temp;
				len = SzArEx_GetFileNameUtf16(&db, i, NULL);

				if (len >= MAX_PATH)
				{
					res = SZ_ERROR_FAIL;
					break;
				}

				temp = path + pathLen;

				SzArEx_GetFileNameUtf16(&db, i, reinterpret_cast<UInt16*>(temp));
				{
					res = SzArEx_Extract(&db, &lookStream.s, i,
						&blockIndex, &outBuffer, &outBufferSize,
						&offset, &outSizeProcessed,
						&allocImp, &allocTempImp);
					if (res != SZ_OK)
						break;
				}
				{
					CSzFile outFile;
					size_t processedSize;
					size_t j;
					size_t nameStartPos = 0;
					for (j = 0; temp[j] != 0; j++)
					{
						if (temp[j] == '/')
						{
							temp[j] = 0;
							MyCreateDir(path);
							temp[j] = CHAR_PATH_SEPARATOR;
							nameStartPos = j + 1;
						}
					}

					if (f->IsDir)
					{
						MyCreateDir(path);
						continue;
					}
					else
					{

						if (DoesFileOrDirExist(path))
						{
							errorMessage = "Duplicate file";
							res = SZ_ERROR_FAIL;
							break;
						}
						if (OutFile_OpenW(&outFile, path))
						{
							errorMessage = "Can't open output file";
							res = SZ_ERROR_FAIL;
							break;
						}
					}
					processedSize = outSizeProcessed;
					if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
					{
						errorMessage = "Can't write output file";
						res = SZ_ERROR_FAIL;
					}

#ifdef USE_WINDOWS_FILE
					if (f->MTimeDefined)
					{
						FILETIME mTime;
						mTime.dwLowDateTime = f->MTime.Low;
						mTime.dwHighDateTime = f->MTime.High;
						SetFileTime(outFile.handle, NULL, NULL, &mTime);
					}
#endif

					{
						SRes res2 = File_Close(&outFile);
						if (res != SZ_OK)
							break;
						if (res2 != SZ_OK)
						{
							res = res2;
							break;
						}
					}
#ifdef USE_WINDOWS_FILE
					if (f->AttribDefined)
						SetFileAttributesW(path, f->Attrib);
#endif
				}
			}
			IAlloc_Free(&allocImp, outBuffer);
		}
		SzArEx_Free(&db, &allocImp);

		if (res == SZ_OK)
		{
			_tcscpy_s(cUnPackPath, dwPathLength, path);
			return 0;
		}
		else
			return 1;
	}
Пример #16
0
_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;
}
Пример #17
0
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;
}
Пример #18
0
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;
    }
}
Пример #19
0
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;
}
Пример #20
0
int auxio_load_archive(const char *filename, unsigned char **dataout, int *datasize, int *dataoffset, const char *filetoload, char *outname)
{
	FILE *f;
	unsigned char idbuf[4];
	int filesFound = 0;
	std::vector<char *> filelist;	// list of files we can load in this archive

	// default case: outname is filename
	if (outname)
	{
		strcpy(outname, filename);
	}

	f = fopen(filename, "rb");

	if (!f)
	{
		return 0;	// no good
	}

	fread(idbuf, 4, 1, f);
	fclose(f);

//	printf("ID bytes %c %c %x %x\n", idbuf[0], idbuf[1], idbuf[2], idbuf[3]);

	if ((idbuf[0] == 'P') && (idbuf[1] == 'K') && (idbuf[2] == 0x03) && (idbuf[3] == 0x04))
	{	// it's zip
		unzFile zipArchive;
		char file_name[1024];
		unz_file_info info;
		int nlen;
		int ret = 0;

		zipArchive = unzOpen(filename);

		if (!zipArchive)
		{
			return 0;
		}

		unzGoToFirstFile(zipArchive);
		
		for (;;)
		{
			if (unzGetCurrentFileInfo(zipArchive, &info, file_name, 1024, NULL, 0, NULL, 0) == UNZ_OK)
			{
				if (filetoload != NULL)
				{
					if (!strcasecmp(filetoload, file_name))
					{
						int length;
						unsigned char *buffer;

						unzOpenCurrentFile(zipArchive);
					
						length = info.uncompressed_size;
						buffer = (unsigned char *)malloc(length);

				    		ret = unzReadCurrentFile(zipArchive, buffer, length);

						if (ret != length)
						{
							free(buffer);
							return 0;
						}

						unzCloseCurrentFile(zipArchive);
						unzClose(zipArchive);

						*datasize = length;
						*dataout = buffer;
						*dataoffset = 0;

						return 1;
					}
				}
				else
				{
					if (checkExtension(file_name))
					{
						char *tmpstr;

						tmpstr = (char *)malloc(strlen(file_name)+1);
						strcpy(tmpstr, file_name);

						// add to the file list
						filelist.push_back(tmpstr);
						filesFound++;
					}
				}
			}
			else
			{
				break;
			}

			ret = unzGoToNextFile(zipArchive);

			if (ret == UNZ_END_OF_LIST_OF_FILE)
			{
				break;
			}

			if (ret != UNZ_OK)
			{
				unzClose(zipArchive);
				return 0;
			}
		}

		unzClose(zipArchive);
	}
	else if ((idbuf[0] == '7') && (idbuf[1] == 'z') && (idbuf[2] == 0xbc) && (idbuf[3] == 0xaf)) 
	{	// it's 7zip
		CFileInStream archiveStream;
		SRes res;
		CSzArEx db;              /* 7z archive database structure */
		ISzAlloc allocImp;       /* memory functions for main pool */
		ISzAlloc allocTempImp;   /* memory functions for temporary pool */

		archiveStream.File = fopen(filename, "rb");
		if (!archiveStream.File)
		{
			return 0;
		}

		archiveStream.InStream.Read = SzFileReadImp;
		archiveStream.InStream.Seek = SzFileSeekImp;

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

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

		// init 7zip internals
		CrcGenerateTable();
		SzArEx_Init(&db);

		res = SzArEx_Open(&db, &archiveStream.InStream, &allocImp, &allocTempImp);
		if (res == SZ_OK)
		{
			int i;

			for (i = 0; i < db.db.NumFiles; i++)
			{
				CSzFileItem *item = db.db.Files + i;

				if (!item->IsDirectory)
				{
					if (filetoload != NULL)
					{
						if (!strcasecmp(filetoload, item->Name))
						{
							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) */
							size_t offset;
							size_t outSizeProcessed;

							res = SzAr_Extract(&db, &archiveStream.InStream, i, 
							        &blockIndex, &outBuffer, &outBufferSize, 
							        &offset, &outSizeProcessed, 
							        &allocImp, &allocTempImp);
						
							if (res == SZ_OK)
							{
								SzArEx_Free(&db, &allocImp);
								fclose(archiveStream.File);

								*datasize = (int)outBufferSize;
								*dataout = (unsigned char *)outBuffer;
								*dataoffset = (int)offset;

								return 1;
							}
							else
							{
								std::cout << "Error extracting 7zip!\n";
							}
						}
					}

					if (checkExtension(item->Name))
					{
						char *tmpstr;

						tmpstr = (char *)malloc(strlen(item->Name)+1);
						strcpy(tmpstr, item->Name);

						// add to the file list
						filelist.push_back(tmpstr);
						filesFound++;
					}
				}
			}

			SzArEx_Free(&db, &allocImp);
			fclose(archiveStream.File);
		}
	}
	else if ((idbuf[0] == 'R') && (idbuf[1] == 'a') && (idbuf[2] == 'r') && (idbuf[3] == '!')) 
	{	// it's rar 
		
	}

	// if we found any files and weren't forced to load them, handle accordingly
	if (filesFound)
	{
		// only 1 file found, just run it
		if (filesFound == 1)
		{
			char fname[512];
			
			strcpy(fname, filelist[0]);

			free(filelist[0]);
			filelist.clear();

			strcpy(outname, fname);

			return auxio_load_archive(filename, dataout, datasize, dataoffset, fname, NULL); 
		}
		else	// multiple files we can handle found, give the user a choice
		{
			int sel;
			char fname[512];

			filepicker = create_archselect();
			tree = lookup_widget(filepicker, "archtree");
			gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW (tree), FALSE);
			g_signal_connect(G_OBJECT(tree), "button_press_event", G_CALLBACK(check_list_double), NULL);

			// set up our tree store
			treestore = gtk_tree_store_new(1, G_TYPE_STRING);

			// attach the store to the tree	
			gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(treestore));

			// create a cell renderer using the stock text one
			renderer = gtk_cell_renderer_text_new();

			// create a display column using the renderer
			column = gtk_tree_view_column_new_with_attributes ("NES file",
		                                                   renderer,
		                                                   "text", 0,
		                                                   NULL);

			// add the display column and renderer to the tree view
			gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);

			// get the selection object too
			selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
	
			// add the filenames
			for (int fn = 0; fn < filelist.size(); fn++)
			{
				gtk_tree_store_insert(treestore, &treeiters[fn], NULL, 999999);
				gtk_tree_store_set(treestore, &treeiters[fn], 0, filelist[fn], -1);
			}

			gtk_widget_show(filepicker);

			run_picker = true;
			cancelled = false;
			while (run_picker)
			{
				gtk_main_iteration_do(FALSE);
			}

			sel = find_current_selection();

			gtk_widget_destroy(filepicker);

			// was something picked?
			if ((sel != -1) && (!cancelled))
			{
				strcpy(fname, filelist[sel]);
			}

			// free all the temp filenames
			for (int fn = 0; fn < filelist.size(); fn++)
			{
				free(filelist[fn]);
			}

			// and wipe the vector
			filelist.clear();

			if ((sel != -1) && (!cancelled))
			{
				if (outname)
				{
					strcpy(outname, fname);
				}

				return auxio_load_archive(filename, dataout, datasize, dataoffset, fname, NULL); 
			}
		}
	}

	return 0;
}
Пример #21
0
int main(int argc, char *argv[])
{
	struct timeval start_time, end_time;
	struct sigaction handler;
	double seconds,total_time; // for timers
	bool lrzcat = false;
	int c, i;
	int hours,minutes;
	extern int optind;
	char *eptr; /* for environment */

        control = &base_control;

	initialise_control(control);

	if (strstr(argv[0], "lrunzip"))
		control->flags |= FLAG_DECOMPRESS;
	else if (strstr(argv[0], "lrzcat")) {
		control->flags |= FLAG_DECOMPRESS | FLAG_STDOUT;
		lrzcat = true;
	}

	/* generate crc table */
	CrcGenerateTable();

	/* Get Preloaded Defaults from lrzip.conf
	 * Look in ., $HOME/.lrzip/, /etc/lrzip.
	 * If LRZIP=NOCONFIG is set, then ignore config
	 */
	eptr = getenv("LRZIP");
	if (eptr == NULL)
		read_config(control);
	else if (!strstr(eptr,"NOCONFIG"))
		read_config(control);

	while ((c = getopt_long(argc, argv, "bcdDefghHiklL:nN:o:O:p:qS:tTUm:vVw:z?", long_options, &i)) != -1) {
		switch (c) {
		case 'b':
			if (control->flags & FLAG_NOT_LZMA)
				failure("Can only use one of -l, -b, -g, -z or -n\n");
			control->flags |= FLAG_BZIP2_COMPRESS;
			break;
		case 'c':
			control->flags |= FLAG_CHECK;
			control->flags |= FLAG_HASH;
			break;
		case 'd':
			control->flags |= FLAG_DECOMPRESS;
			break;
		case 'D':
			control->flags &= ~FLAG_KEEP_FILES;
			break;
		case 'e':
			control->flags |= FLAG_ENCRYPT;
			break;
		case 'f':
			control->flags |= FLAG_FORCE_REPLACE;
			break;
		case 'g':
			if (control->flags & FLAG_NOT_LZMA)
				failure("Can only use one of -l, -b, -g, -z or -n\n");
			control->flags |= FLAG_ZLIB_COMPRESS;
			break;
		case 'h':
		case '?':
			usage();
			return -1;
		case 'H':
			control->flags |= FLAG_HASH;
			break;
		case 'i':
			control->flags |= FLAG_INFO;
			break;
		case 'k':
			control->flags |= FLAG_KEEP_BROKEN;
			break;
		case 'l':
			if (control->flags & FLAG_NOT_LZMA)
				failure("Can only use one of -l, -b, -g, -z or -n\n");
			control->flags |= FLAG_LZO_COMPRESS;
			break;
		case 'L':
			control->compression_level = atoi(optarg);
			if (control->compression_level < 1 || control->compression_level > 9)
				failure("Invalid compression level (must be 1-9)\n");
			break;
		case 'm':
			control->ramsize = atol(optarg) * 1024 * 1024 * 100;
			break;
		case 'n':
			if (control->flags & FLAG_NOT_LZMA)
				failure("Can only use one of -l, -b, -g, -z or -n\n");
			control->flags |= FLAG_NO_COMPRESS;
			break;
		case 'N':
			control->nice_val = atoi(optarg);
			if (control->nice_val < -20 || control->nice_val > 19)
				failure("Invalid nice value (must be -20..19)\n");
			break;
		case 'o':
			if (control->outdir)
				failure("Cannot have -o and -O together\n");
			if (unlikely(STDOUT))
				failure("Cannot specify an output filename when outputting to stdout\n");
			control->outname = optarg;
			control->suffix = "";
			break;
		case 'O':
			if (control->outname)	/* can't mix -o and -O */
				failure("Cannot have options -o and -O together\n");
			if (unlikely(STDOUT))
				failure("Cannot specify an output directory when outputting to stdout\n");
			control->outdir = malloc(strlen(optarg) + 2);
			if (control->outdir == NULL)
				fatal("Failed to allocate for outdir\n");
			strcpy(control->outdir,optarg);
			if (strcmp(optarg+strlen(optarg) - 1, "/")) 	/* need a trailing slash */
				strcat(control->outdir, "/");
			break;
		case 'p':
			control->threads = atoi(optarg);
			if (control->threads < 1)
				failure("Must have at least one thread\n");
			break;
		case 'q':
			control->flags &= ~FLAG_SHOW_PROGRESS;
			break;
		case 'S':
			if (control->outname)
				failure("Specified output filename already, can't specify an extension.\n");
			if (unlikely(STDOUT))
				failure("Cannot specify a filename suffix when outputting to stdout\n");
			control->suffix = optarg;
			break;
		case 't':
			if (control->outname)
				failure("Cannot specify an output file name when just testing.\n");
			if (!KEEP_FILES)
				failure("Doubt that you want to delete a file when just testing.\n");
			control->flags |= FLAG_TEST_ONLY;
			break;
		case 'T':
			control->flags &= ~FLAG_THRESHOLD;
			break;
		case 'U':
			control->flags |= FLAG_UNLIMITED;
			break;
		case 'v':
			/* set verbosity flag */
			if (!(control->flags & FLAG_VERBOSITY) && !(control->flags & FLAG_VERBOSITY_MAX))
				control->flags |= FLAG_VERBOSITY;
			else if ((control->flags & FLAG_VERBOSITY)) {
				control->flags &= ~FLAG_VERBOSITY;
				control->flags |= FLAG_VERBOSITY_MAX;
			}
			break;
		case 'V':
			print_output("lrzip version %s\n", PACKAGE_VERSION);
			exit(0);
			break;
		case 'w':
			control->window = atol(optarg);
			break;
		case 'z':
			if (control->flags & FLAG_NOT_LZMA)
				failure("Can only use one of -l, -b, -g, -z or -n\n");
			control->flags |= FLAG_ZPAQ_COMPRESS;
			break;
		}
	}

	argc -= optind;
	argv += optind;

	if (control->outname && argc > 1)
		failure("Cannot specify output filename with more than 1 file\n");

	if (VERBOSE && !SHOW_PROGRESS) {
		print_err("Cannot have -v and -q options. -v wins.\n");
		control->flags |= FLAG_SHOW_PROGRESS;
	}

	if (UNLIMITED && control->window) {
		print_err("If -U used, cannot specify a window size with -w.\n");
		control->window = 0;
	}

	if (argc < 1)
		control->flags |= FLAG_STDIN;

	if (UNLIMITED && STDIN) {
		print_err("Cannot have -U and stdin, unlimited mode disabled.\n");
		control->flags &= ~FLAG_UNLIMITED;
	}

	setup_overhead(control);

	/* Set the main nice value to half that of the backend threads since
	 * the rzip stage is usually the rate limiting step */
	if (control->nice_val > 0 && !NO_COMPRESS) {
		if (unlikely(setpriority(PRIO_PROCESS, 0, control->nice_val / 2) == -1))
			print_err("Warning, unable to set nice value\n");
	} else {
		if (unlikely(setpriority(PRIO_PROCESS, 0, control->nice_val) == -1))
			print_err("Warning, unable to set nice value\n");
	}

	/* One extra iteration for the case of no parameters means we will default to stdin/out */
	for (i = 0; i <= argc; i++) {
		if (i < argc)
			control->infile = argv[i];
		else if (!(i == 0 && STDIN))
			break;
		if (control->infile) {
			if ((strcmp(control->infile, "-") == 0))
				control->flags |= FLAG_STDIN;
			else {
				struct stat infile_stat;

				stat(control->infile, &infile_stat);
				if (unlikely(S_ISDIR(infile_stat.st_mode)))
					failure("lrzip only works directly on FILES.\n"
					"Use lrztar or pipe through tar for compressing directories.\n");
			}
		}

		if (INFO && STDIN)
			failure("Will not get file info from STDIN\n");

		if ((control->outname && (strcmp(control->outname, "-") == 0)) ||
			/* If no output filename is specified, and we're using
			 * stdin, use stdout */
			(!control->outname && STDIN) || lrzcat ) {
				control->flags |= FLAG_STDOUT;
				control->outFILE = stdout;
				control->msgout = stderr;
				register_outputfile(control, control->msgout);
		}

		if (lrzcat) {
			control->msgout = stderr;
			control->outFILE = stdout;
			register_outputfile(control, control->msgout);
		}

		if (!STDOUT) {
			control->msgout = stdout;
			register_outputfile(control, control->msgout);
		}

		if (STDIN)
			control->inFILE = stdin;
		/* Implement signal handler only once flags are set */
		sigemptyset(&handler.sa_mask);
		handler.sa_flags = 0;
		handler.sa_handler = &sighandler;
		sigaction(SIGTERM, &handler, 0);
		sigaction(SIGINT, &handler, 0);

		if (!FORCE_REPLACE) {
			if (STDIN && isatty(fileno((FILE *)stdin))) {
				print_err("Will not read stdin from a terminal. Use -f to override.\n");
				usage();
				exit (1);
			}
			if (!TEST_ONLY && STDOUT && isatty(fileno((FILE *)stdout))) {
				print_err("Will not write stdout to a terminal. Use -f to override.\n");
				usage();
				exit (1);
			}
		}

		if (CHECK_FILE) {
			if (!DECOMPRESS) {
				print_err("Can only check file written on decompression.\n");
				control->flags &= ~FLAG_CHECK;
			} else if (STDOUT) {
				print_err("Can't check file written when writing to stdout. Checking disabled.\n");
				control->flags &= ~FLAG_CHECK;
			}
		}

		setup_ram(control);
		show_summary();

		gettimeofday(&start_time, NULL);

		if (unlikely(STDIN && ENCRYPT))
			failure("Unable to work from STDIN while reading password\n");

		memcpy(&local_control, &base_control, sizeof(rzip_control));
		if (DECOMPRESS || TEST_ONLY)
			decompress_file(&local_control);
		else if (INFO)
			get_fileinfo(&local_control);
		else
			compress_file(&local_control);

		/* compute total time */
		gettimeofday(&end_time, NULL);
		total_time = (end_time.tv_sec + (double)end_time.tv_usec / 1000000) -
			      (start_time.tv_sec + (double)start_time.tv_usec / 1000000);
		hours = (int)total_time / 3600;
		minutes = (int)(total_time / 60) % 60;
		seconds = total_time - hours * 3600 - minutes * 60;
		if (!INFO)
			print_progress("Total time: %02d:%02d:%05.2f\n", hours, minutes, seconds);
	}

	return 0;
}
Пример #22
0
/* Extract all the files from a 7-zip archive to the specified location, with
 * callbacks. "file" is the path to the file to unpack, "base" is the location
 * to extract to, "before_entry_callback" is a function to call right before
 * each entry is unpacked, and "create_callback" is a function to call right
 * after each entry has been unpacked. Both callback functions' arguments are as
 * follows: the path (relative to base) of the entry, and an int that is nonzero
 * if the entry is a directory.
 */
int un7z
 (const char* file,
  const char* base,
  int (*before_entry_callback)(const char*, int),
  void (*create_callback)(const char*, int))
{
	// Create and fill out our reader object
	FileInStream instream;
	instream.sz_stream.Read = SzFileReadImp;
	instream.sz_stream.Seek = SzFileSeekImp;
	instream.filep = fopen(file, "rb");
	if (!instream.filep)
	{
		archive_seterror("failed to open file '%s' for reading", file);
		return -1;
	}
	// Close the FILE* when we leave this scope
	RefType< FILE >::Ref fcloser(instream.filep, fclose);

	CrcGenerateTable();

	CArchiveDatabaseEx db;
	SzArDbExInit(&db);
	// Free up the database when we leave this scope
	RefType< CArchiveDatabaseEx >::Ref db_deleter(&db, SzArDbExDeleter);

	// Set up 7-zip's memory allocation scheme (uses the default allocators)
	ISzAlloc allocImp, allocTempImp;
	allocImp.Alloc = SzAlloc;
	allocImp.Free = SzFree;
	allocTempImp.Alloc = SzAllocTemp;
	allocTempImp.Free = SzFreeTemp;

	// Open the archive
	if (SzArchiveOpen(&instream.sz_stream, &db, &allocImp, &allocTempImp)
	 != SZ_OK)
	{
		archive_seterror("7zlib couldn't open '%s' as a 7z archive", file);
		return -1;
	}

	// Update progress total
	num_files_in_cur_op = db.Database.NumFiles;

	// Set up 7-zip's "cache" variables
	UInt32 blockIndex = 0xFFFFFFFF;
	Byte *outBuffer = 0;
	size_t outBufferSize = 0;
	// Delete the buffer when we leave this scope
	RefType< Byte >::Ref outbuf_deleter(outBuffer, OutBufferDeleter);

	// Iterate and extract entries
	for (unsigned i = 0; i < db.Database.NumFiles; i++)
	{
		// Update progress
		cur_file_in_op_index = i;

		CFileItem* cur_file = &db.Database.Files[i];
		
		// Call before-extraction callback
		if (before_entry_callback)
		{
			int cbres = before_entry_callback(cur_file->Name, cur_file->IsDirectory);
			if (cbres != 0)
			{
				archive_seterror("7zlib failed to unzip '%s': cancelled from "
				 "callback", cur_file->Name);
				return cbres;
			}
		}

		// Get the full path to output
		std::string out_path = std::string(base) + "/" + cur_file->Name;

		// If entry is a directory, merely create the directory
		if (cur_file->IsDirectory)
		{
			if (!makedir(base, cur_file->Name))
			{
				archive_seterror("couldn't create directory '%s'",
				 out_path.c_str());
				return -1;
			}
		}
		// If entry is a file, extract it
		else
		{
			size_t offset, outSizeProcessed;
			// 7-zip seems to encourage getting the whole file in one blow
			SZ_RESULT res = SzExtract(&instream.sz_stream, &db, i, &blockIndex,
			 &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp,
			 &allocTempImp);
			if (res == SZE_CRC_ERROR)
			{
				archive_seterror("bad CRC for file '%s' in '%s'",
				 cur_file->Name, file);
				return -1;
			}
			else if (res != SZ_OK)
			{
				archive_seterror("7zlib failed to unpack file '%s' in '%s'",
				 cur_file->Name, file);
				return -1;
			}

			bool was_created = false;
			// If the output file already exists, make sure we can write over it
			if (chmod(out_path.c_str(), _S_IREAD|_S_IWRITE) != 0)
				was_created = true;

			// Open the output file for writing
			FILE* outfile = fopen(out_path.c_str(), "wb");
			if (!outfile)
			{
				// Couldn't open it -- make sure its parent directory exists
				size_t p = std::string(cur_file->Name).find_last_of("/\\", std::string::npos);
				if (p != std::string::npos)
				{
					makedir(base, std::string(cur_file->Name).substr(0, p).c_str());
					outfile = fopen(out_path.c_str(), "wb");
				}
			}
			if (!outfile)
			{
				// Still couldn't open it; error out
				archive_seterror("couldn't open '%s' for writing",
				 out_path.c_str());
				return -1;
			}

			// Write out the whole file and then close it
			int written = fwrite(outBuffer + offset, 1, outSizeProcessed,
			 outfile);
			fclose(outfile);
			if (written <= 0
			 || static_cast< size_t >(written) != outSizeProcessed)
			{
				// At this point we have an empty output file; remove it
				remove(out_path.c_str());
				archive_seterror("failed to write %d bytes to '%s'",
				 outSizeProcessed, out_path.c_str());
				return -1;
			}
		}

		// Set stored attributes
		if (cur_file->AreAttributesDefined)
			SetFileAttributes(out_path.c_str(), cur_file->Attributes);

		// Call after-creation callback
		create_callback(cur_file->Name, cur_file->IsDirectory ? 1 : 0);
	}

	return 0;
}
Пример #23
0
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;
}
Пример #24
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;
}
Пример #25
0
/* 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;
}
Пример #26
0
		/*!
		 * \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;
		}
Пример #27
0
 CCRCTableInit() { CrcGenerateTable(); }
Пример #28
0
int main(int numargs, char *args[]) {
	FILE *archiveFile;
	CLookToRead archiveStream;
	CSzArEx db;
	int res;
	
	
	if (numargs != 3) {
		return 1;
	}
	if ((archiveFile = fopen(args[1], "r")) == NULL) {
		return 2;
	}
	if (!directoryExists(args[2])) {
		return 4;		
	}
	
	int outPathLen = strlen(args[2]);
	int maxPathLen = 5;
	int pathLen;
	char *outputPath;
	
	outputPath = malloc(outPathLen + maxPathLen + 1);
	memcpy(outputPath, args[2], outPathLen);
	if (outputPath[outPathLen - 1] != '/') {
		outputPath[outPathLen] = '/';
		outPathLen++;
		maxPathLen--; 
	}
	
	
	archiveStream.file = &archiveFile;
	LookToRead_Init(&archiveStream);
	
	CrcGenerateTable();
	
	SzArEx_Init(&db);
	res = SzArEx_Open(&db, &archiveStream);
	if (res == SZ_OK) {
		UInt32 i;
		
		UInt32 blockIndex;
		Byte *outBuffer = 0;
		size_t outBufferSize;
		
		for (i = 0; i < db.db.NumFiles; i++) {
			size_t offset;
			size_t outSizeProcessed;
			CSzFileItem *f = db.db.Files + i;
			
			pathLen = strlen(f->Name);
			if (pathLen > maxPathLen) {
				maxPathLen = pathLen * 2;
				outputPath = realloc(outputPath, outPathLen + maxPathLen + 1);
			}
			memcpy(outputPath + outPathLen, f->Name, pathLen + 1);
			
			mode_t fileMode;
			if (f->AttribDefined && f->Attrib & 0x8000) {
				fileMode = f->Attrib >> 16;
			} else {
Пример #29
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 */
Пример #30
0
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  #ifdef UNDER_CE
  LPWSTR
  #else
  LPSTR
  #endif
  lpCmdLine, int nCmdShow)
#endif
{
  CFileInStream archiveStream;
  CLookToRead lookStream;
  CSzArEx db;
  SRes res = SZ_OK;
  ISzAlloc allocImp;
  ISzAlloc allocTempImp;
  WCHAR sfxPath[MAX_PATH + 2];
  WCHAR path[MAX_PATH * 3 + 2];
  #ifndef UNDER_CE
  WCHAR workCurDir[MAX_PATH + 32];
  #endif
  size_t pathLen;
  DWORD winRes;
  const wchar_t *cmdLineParams;
  const char *errorMessage = NULL;
  Bool useShellExecute = True;
  DWORD exitCode = 0;

  LoadSecurityDlls();

  #ifdef _CONSOLE
  SetConsoleCtrlHandler(HandlerRoutine, TRUE);
  #else
  UNUSED_VAR(hInstance);
  UNUSED_VAR(hPrevInstance);
  UNUSED_VAR(lpCmdLine);
  UNUSED_VAR(nCmdShow);
  #endif

  CrcGenerateTable();

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

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

  FileInStream_CreateVTable(&archiveStream);
  LookToRead_CreateVTable(&lookStream, False);
 
  winRes = GetModuleFileNameW(NULL, sfxPath, MAX_PATH);
  if (winRes == 0 || winRes > MAX_PATH)
    return 1;
  {
    cmdLineParams = GetCommandLineW();
    #ifndef UNDER_CE
    {
      Bool quoteMode = False;
      for (;; cmdLineParams++)
      {
        wchar_t c = *cmdLineParams;
        if (c == L'\"')
          quoteMode = !quoteMode;
        else if (c == 0 || (c == L' ' && !quoteMode))
          break;
      }
    }
    #endif
  }

  {
    unsigned i;
    DWORD d;
    winRes = GetTempPathW(MAX_PATH, path);
    if (winRes == 0 || winRes > MAX_PATH)
      return 1;
    pathLen = wcslen(path);
    d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId();
    
    for (i = 0;; i++, d += GetTickCount())
    {
      if (i >= 100)
      {
        res = SZ_ERROR_FAIL;
        break;
      }
      wcscpy(path + pathLen, L"7z");

      {
        wchar_t *s = path + wcslen(path);
        UInt32 value = d;
        unsigned k;
        for (k = 0; k < 8; k++)
        {
          unsigned t = value & 0xF;
          value >>= 4;
          s[7 - k] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
        }
        s[k] = '\0';
      }

      if (DoesFileOrDirExist(path))
        continue;
      if (CreateDirectoryW(path, NULL))
      {
        wcscat(path, WSTRING_PATH_SEPARATOR);
        pathLen = wcslen(path);
        break;
      }
      if (GetLastError() != ERROR_ALREADY_EXISTS)
      {
        res = SZ_ERROR_FAIL;
        break;
      }
    }
    
    #ifndef UNDER_CE
    wcscpy(workCurDir, path);
    #endif
    if (res != SZ_OK)
      errorMessage = "Can't create temp folder";
  }

  if (res != SZ_OK)
  {
    if (!errorMessage)
      errorMessage = "Error";
    PrintErrorMessage(errorMessage);
    return 1;
  }

  if (InFile_OpenW(&archiveStream.file, sfxPath) != 0)
  {
    errorMessage = "can not open input file";
    res = SZ_ERROR_FAIL;
  }
  else
  {
    UInt64 pos = 0;
    if (!FindSignature(&archiveStream.file, &pos))
      res = SZ_ERROR_FAIL;
    else if (File_Seek(&archiveStream.file, (Int64 *)&pos, SZ_SEEK_SET) != 0)
      res = SZ_ERROR_FAIL;
    if (res != 0)
      errorMessage = "Can't find 7z archive";
  }

  if (res == SZ_OK)
  {
    lookStream.realStream = &archiveStream.s;
    LookToRead_Init(&lookStream);
  }

  SzArEx_Init(&db);
  if (res == SZ_OK)
  {
    res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
  }
  
  if (res == SZ_OK)
  {
    UInt32 executeFileIndex = (UInt32)(Int32)-1;
    UInt32 minPrice = 1 << 30;
    UInt32 i;
    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;
      WCHAR *temp;

      if (SzArEx_GetFileNameUtf16(&db, i, NULL) >= MAX_PATH)
      {
        res = SZ_ERROR_FAIL;
        break;
      }
      
      temp = path + pathLen;
      
      SzArEx_GetFileNameUtf16(&db, i, temp);
      {
        res = SzArEx_Extract(&db, &lookStream.s, i,
          &blockIndex, &outBuffer, &outBufferSize,
          &offset, &outSizeProcessed,
          &allocImp, &allocTempImp);
        if (res != SZ_OK)
          break;
      }
      {
        CSzFile outFile;
        size_t processedSize;
        size_t j;
        size_t nameStartPos = 0;
        for (j = 0; temp[j] != 0; j++)
        {
          if (temp[j] == '/')
          {
            temp[j] = 0;
            MyCreateDir(path);
            temp[j] = CHAR_PATH_SEPARATOR;
            nameStartPos = j + 1;
          }
        }

        if (SzArEx_IsDir(&db, i))
        {
          MyCreateDir(path);
          continue;
        }
        else
        {
          unsigned extLen;
          const WCHAR *name = temp + nameStartPos;
          unsigned len = (unsigned)wcslen(name);
          unsigned nameLen = FindExt(temp + nameStartPos, &extLen);
          unsigned extPrice = FindItem(kExts, sizeof(kExts) / sizeof(kExts[0]), name + len - extLen, extLen);
          unsigned namePrice = FindItem(kNames, sizeof(kNames) / sizeof(kNames[0]), name, nameLen);

          unsigned price = namePrice + extPrice * 64 + (nameStartPos == 0 ? 0 : (1 << 12));
          if (minPrice > price)
          {
            minPrice = price;
            executeFileIndex = i;
            useShellExecute = (extPrice != k_EXE_ExtIndex);
          }
         
          if (DoesFileOrDirExist(path))
          {
            errorMessage = "Duplicate file";
            res = SZ_ERROR_FAIL;
            break;
          }
          if (OutFile_OpenW(&outFile, path))
          {
            errorMessage = "Can't open output file";
            res = SZ_ERROR_FAIL;
            break;
          }
        }
  
        processedSize = outSizeProcessed;
        if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
        {
          errorMessage = "Can't write output file";
          res = SZ_ERROR_FAIL;
        }
        
        #ifdef USE_WINDOWS_FILE
        if (SzBitWithVals_Check(&db.MTime, i))
        {
          const CNtfsFileTime *t = db.MTime.Vals + i;
          FILETIME mTime;
          mTime.dwLowDateTime = t->Low;
          mTime.dwHighDateTime = t->High;
          SetFileTime(outFile.handle, NULL, NULL, &mTime);
        }
        #endif
        
        {
          SRes res2 = File_Close(&outFile);
          if (res != SZ_OK)
            break;
          if (res2 != SZ_OK)
          {
            res = res2;
            break;
          }
        }
        #ifdef USE_WINDOWS_FILE
        if (SzBitWithVals_Check(&db.Attribs, i))
          SetFileAttributesW(path, db.Attribs.Vals[i]);
        #endif
      }
    }

    if (res == SZ_OK)
    {
      if (executeFileIndex == (UInt32)(Int32)-1)
      {
        errorMessage = "There is no file to execute";
        res = SZ_ERROR_FAIL;
      }
      else
      {
        WCHAR *temp = path + pathLen;
        UInt32 j;
        SzArEx_GetFileNameUtf16(&db, executeFileIndex, temp);
        for (j = 0; temp[j] != 0; j++)
          if (temp[j] == '/')
            temp[j] = CHAR_PATH_SEPARATOR;
      }
    }
    IAlloc_Free(&allocImp, outBuffer);
  }
  SzArEx_Free(&db, &allocImp);

  File_Close(&archiveStream.file);

  if (res == SZ_OK)
  {
    HANDLE hProcess = 0;
    
    #ifndef UNDER_CE
    WCHAR oldCurDir[MAX_PATH + 2];
    oldCurDir[0] = 0;
    {
      DWORD needLen = GetCurrentDirectory(MAX_PATH + 1, oldCurDir);
      if (needLen == 0 || needLen > MAX_PATH)
        oldCurDir[0] = 0;
      SetCurrentDirectory(workCurDir);
    }
    #endif
    
    if (useShellExecute)
    {
      SHELLEXECUTEINFO ei;
      UINT32 executeRes;
      BOOL success;
      
      memset(&ei, 0, sizeof(ei));
      ei.cbSize = sizeof(ei);
      ei.lpFile = path;
      ei.fMask = SEE_MASK_NOCLOSEPROCESS
          #ifndef UNDER_CE
          | SEE_MASK_FLAG_DDEWAIT
          #endif
          /* | SEE_MASK_NO_CONSOLE */
          ;
      if (wcslen(cmdLineParams) != 0)
        ei.lpParameters = cmdLineParams;
      ei.nShow = SW_SHOWNORMAL; /* SW_HIDE; */
      success = ShellExecuteEx(&ei);
      executeRes = (UINT32)(UINT_PTR)ei.hInstApp;
      if (!success || (executeRes <= 32 && executeRes != 0))  /* executeRes = 0 in Windows CE */
        res = SZ_ERROR_FAIL;
      else
        hProcess = ei.hProcess;
    }
    else
    {
      STARTUPINFOW si;
      PROCESS_INFORMATION pi;
      WCHAR cmdLine[MAX_PATH * 3];

      wcscpy(cmdLine, path);
      wcscat(cmdLine, cmdLineParams);
      memset(&si, 0, sizeof(si));
      si.cb = sizeof(si);
      if (CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == 0)
        res = SZ_ERROR_FAIL;
      else
      {
        CloseHandle(pi.hThread);
        hProcess = pi.hProcess;
      }
    }
    
    if (hProcess != 0)
    {
      WaitForSingleObject(hProcess, INFINITE);
      if (!GetExitCodeProcess(hProcess, &exitCode))
        exitCode = 1;
      CloseHandle(hProcess);
    }
    
    #ifndef UNDER_CE
    SetCurrentDirectory(oldCurDir);
    #endif
  }

  path[pathLen] = L'\0';
  RemoveDirWithSubItems(path);

  if (res == SZ_OK)
    return (int)exitCode;
  
  {
    if (res == SZ_ERROR_UNSUPPORTED)
      errorMessage = "Decoder doesn't support this archive";
    else if (res == SZ_ERROR_MEM)
      errorMessage = "Can't allocate required memory";
    else if (res == SZ_ERROR_CRC)
      errorMessage = "CRC error";
    else
    {
      if (!errorMessage)
        errorMessage = "ERROR";
    }
 
    if (errorMessage)
      PrintErrorMessage(errorMessage);
  }
  return 1;
}