Пример #1
0
char *pm9screw_ext_fopen(FILE *fp)
{
	struct stat stat_buf;
	char *datap, *newdatap, *result;
	int datalen, newdatalen;
	int cryptkey_len = sizeof pm9screw_mycryptkey / 2;
	int i;

#ifdef WIN32
	fstat(_fileno(fp), &stat_buf);
#else
	fstat(fileno(fp), &stat_buf);
#endif

	datalen = stat_buf.st_size - PM9SCREW_LEN;
	datap = (char*)malloc(datalen);
	memset(datap, 0, datalen);
	fread(datap, datalen, 1, fp);
	fclose(fp);

	for(i = 0; i < datalen; i++) {
		datap[i] = (char)pm9screw_mycryptkey[(datalen - i) % cryptkey_len] ^ (~(datap[i]));
	}
	newdatap = zdecode(datap, datalen, &newdatalen);

	result = "";

	free(datap);
	//free(newdatap);

	return newdatap;
}
Пример #2
0
static int ZipReadCurrentFile(Zip* file, void* buf, unsigned int len)
{
	int err = _ZIP_OK;
	unsigned int iread = 0;
	_zip* s;
	zipFileInfoInternal* pfileinzipreadinfo;

	if(file == NULL)
		return _ZIP_PARAM_ERROR;

	s = (_zip*)file;
	pfileinzipreadinfo = s->currentzipfileinfo;

	if(pfileinzipreadinfo == NULL)
		return _ZIP_PARAM_ERROR;

	if((pfileinzipreadinfo->buffer == NULL))
		return _ZIP_EOF_LIST;

	if(len == 0)
		return 0;

	pfileinzipreadinfo->stream.next_out = (Bytef*)buf;

	pfileinzipreadinfo->stream.avail_out = (unsigned int)len;

	if(len > pfileinzipreadinfo->restreaduncompressed)
		pfileinzipreadinfo->stream.avail_out = (unsigned int)pfileinzipreadinfo->restreaduncompressed;

	while(pfileinzipreadinfo->stream.avail_out > 0)
	{
		if((pfileinzipreadinfo->stream.avail_in == 0) && (pfileinzipreadinfo->restreadcompressed > 0))
		{
			unsigned int ureadthis = _ZIP_BUFFER_SIZE;

			if(pfileinzipreadinfo->restreadcompressed < ureadthis)
				ureadthis = (unsigned int)pfileinzipreadinfo->restreadcompressed;

			if(ureadthis == 0)
				return _ZIP_EOF;

			if(fseek(pfileinzipreadinfo->file, pfileinzipreadinfo->posinzip + pfileinzipreadinfo->bytebeforezip, SEEK_SET) != 0)
				return _ZIP_ERRNO;

			if(fread(pfileinzipreadinfo->buffer, ureadthis, 1, pfileinzipreadinfo->file) != 1)
				return _ZIP_ERRNO;

			if(s->encrypted)
			{
				unsigned int i;

				for(i = 0;i < ureadthis;i++)
					pfileinzipreadinfo->buffer[i] = zdecode(s->keys, s->crc32tab, pfileinzipreadinfo->buffer[i]);
			}

			pfileinzipreadinfo->posinzip += ureadthis;

			pfileinzipreadinfo->restreadcompressed -= ureadthis;

			pfileinzipreadinfo->stream.next_in = (Bytef*)pfileinzipreadinfo->buffer;
			pfileinzipreadinfo->stream.avail_in = (unsigned int)ureadthis;
		}

		if(pfileinzipreadinfo->compressionmethod == 0)
		{
			unsigned int udocopy, i;

			if((pfileinzipreadinfo->stream.avail_in == 0) && (pfileinzipreadinfo->restreadcompressed == 0))
				return (iread == 0) ? _ZIP_EOF : iread;

			if(pfileinzipreadinfo->stream.avail_out < pfileinzipreadinfo->stream.avail_in)
				udocopy = pfileinzipreadinfo->stream.avail_out;
			else
				udocopy = pfileinzipreadinfo->stream.avail_in;

			for(i = 0;i < udocopy; i++)
				*(pfileinzipreadinfo->stream.next_out + i) = *(pfileinzipreadinfo->stream.next_in + i);

			pfileinzipreadinfo->crc32 = crc32(pfileinzipreadinfo->crc32, pfileinzipreadinfo->stream.next_out, udocopy);
			pfileinzipreadinfo->restreaduncompressed -= udocopy;
			pfileinzipreadinfo->stream.avail_in -= udocopy;
			pfileinzipreadinfo->stream.avail_out -= udocopy;
			pfileinzipreadinfo->stream.next_out += udocopy;
			pfileinzipreadinfo->stream.next_in += udocopy;
			pfileinzipreadinfo->stream.total_out += udocopy;
			iread += udocopy;
		}
		else
		{
			unsigned long utotaloutbefore, utotaloutafter;
			const Bytef *bufbefore;
			unsigned long uoutthis;
			int flush = Z_SYNC_FLUSH;

			utotaloutbefore = pfileinzipreadinfo->stream.total_out;
			bufbefore = pfileinzipreadinfo->stream.next_out;

			err = inflate(&pfileinzipreadinfo->stream, flush);

			utotaloutafter = pfileinzipreadinfo->stream.total_out;
			uoutthis = utotaloutafter - utotaloutbefore;

			pfileinzipreadinfo->crc32 = crc32(pfileinzipreadinfo->crc32, bufbefore, (unsigned int)(uoutthis));

			pfileinzipreadinfo->restreaduncompressed -= uoutthis;

			iread += (unsigned int)(utotaloutafter - utotaloutbefore);

			if(err == Z_STREAM_END)
				return (iread == 0) ? _ZIP_EOF : iread;

			if(err != Z_OK)
				break;
		}
	}

	if(err == Z_OK)
		return iread;

	return err;
}
Пример #3
0
static int ZipOpenCurrentFile(Zip* file, const char *password)
{
	int err = _ZIP_OK;
	int store;
	unsigned int isizevar;
	_zip* s;
	zipFileInfoInternal* pfileinzipreadinfo;
	unsigned long localextrafieldoffset;
	unsigned int localextrafieldsize;

	char source[12];

	if(file == NULL)
		return _ZIP_PARAM_ERROR;

	s = (_zip*)file;

	if(!s->currentfileok)
		return _ZIP_PARAM_ERROR;

	if(s->currentzipfileinfo != NULL)
		ZipCloseCurrentFile(file);

	if(ZipCheckCurrentFileCoherencyHeader(s, &isizevar, &localextrafieldoffset, &localextrafieldsize) != _ZIP_OK)
		return _ZIP_BAD_FILE;

	pfileinzipreadinfo = (zipFileInfoInternal*) MallocPatch(sizeof(zipFileInfoInternal));

	if(pfileinzipreadinfo == NULL)
		return _ZIP_INTERNAL_ERROR;

	pfileinzipreadinfo->buffer = (char*)MallocPatch(_ZIP_BUFFER_SIZE);
	pfileinzipreadinfo->localextrafieldoffset = localextrafieldoffset;
	pfileinzipreadinfo->localextrafieldsize = localextrafieldsize;
	pfileinzipreadinfo->localextrafieldpos = 0;

	if(pfileinzipreadinfo->buffer == NULL)
	{
		FreePatch(pfileinzipreadinfo);
		return _ZIP_INTERNAL_ERROR;
	}

	pfileinzipreadinfo->streaminitialised = 0;

	if((s->currentfileinfo.compressionmethod != 0) && (s->currentfileinfo.compressionmethod != Z_DEFLATED))
		err = _ZIP_BAD_FILE;

	store = s->currentfileinfo.compressionmethod == 0;

	pfileinzipreadinfo->crc32wait = s->currentfileinfo.crc;
	pfileinzipreadinfo->crc32 = 0;
	pfileinzipreadinfo->compressionmethod = s->currentfileinfo.compressionmethod;
	pfileinzipreadinfo->file = s->file;
	pfileinzipreadinfo->bytebeforezip = s->bytebeforezip;

	pfileinzipreadinfo->stream.total_out = 0;

	if(!store)
	{
		pfileinzipreadinfo->stream.zalloc = (alloc_func)0;
		pfileinzipreadinfo->stream.zfree = (free_func)0;
		pfileinzipreadinfo->stream.opaque = (voidpf)0;

		err = inflateInit2(&pfileinzipreadinfo->stream, -MAX_WBITS);

		if(err == Z_OK)
			pfileinzipreadinfo->streaminitialised = 1;
	}

	pfileinzipreadinfo->restreadcompressed = s->currentfileinfo.compressedsize;
	pfileinzipreadinfo->restreaduncompressed = s->currentfileinfo.uncompressedsize;

	pfileinzipreadinfo->posinzip = s->currentfileinfointernal.currentfileoffset + _ZIP_LOCALHEADER_SIZE + isizevar;

	pfileinzipreadinfo->stream.avail_in = (unsigned int)0;

	s->currentzipfileinfo = pfileinzipreadinfo;

	if(password != NULL)
	{
		int i;
		s->crc32tab = get_crc_table();
		ZipInitKeys(password, s->keys, s->crc32tab);

		if(fseek(pfileinzipreadinfo->file, s->currentzipfileinfo->posinzip + s->currentzipfileinfo->bytebeforezip, SEEK_SET) != 0)
		{
			FreePatch(pfileinzipreadinfo->buffer);
			FreePatch(pfileinzipreadinfo);

			return _ZIP_INTERNAL_ERROR;
		}

		if(fread(source, 1, 12, pfileinzipreadinfo->file) < 12)
		{
			FreePatch(pfileinzipreadinfo->buffer);
			FreePatch(pfileinzipreadinfo);

			return _ZIP_INTERNAL_ERROR;
		}

		for(i = 0; i < 12; i++)
			zdecode(s->keys, s->crc32tab, source[i]);

		s->currentzipfileinfo->posinzip += 12;
		s->encrypted = 1;
	}

	return _ZIP_OK;
}
Пример #4
0
/*
  Open for reading data the current file in the zipfile.
  If there is no error and the file is opened, the return value is UNZ_OK.
*/
int ZEXPORT unzOpenCurrentFile3 (
    unzFile file,
    int* method,
    int* level,
    int raw,
    const char* password)
{
    int err=UNZ_OK;
    uInt iSizeVar;
    unz_s* s;
    file_in_zip_read_info_s* pfile_in_zip_read_info;
    uLong offset_local_extrafield;  /* offset of the local extra field */
    uInt  size_local_extrafield;    /* size of the local extra field */
#    ifndef NOUNCRYPT
    char source[12];
#    else
    if (password != NULL)
        return UNZ_PARAMERROR;
#    endif

    if (file==NULL)
        return UNZ_PARAMERROR;
    s=(unz_s*)file;
    if (!s->current_file_ok)
        return UNZ_PARAMERROR;

    if (s->pfile_in_zip_read != NULL)
        unzCloseCurrentFile(file);

    if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
                &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
        return UNZ_BADZIPFILE;

    pfile_in_zip_read_info = (file_in_zip_read_info_s*)
                                        ALLOC(sizeof(file_in_zip_read_info_s));
    if (pfile_in_zip_read_info==NULL)
        return UNZ_INTERNALERROR;

    pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
    pfile_in_zip_read_info->pos_local_extrafield=0;
    pfile_in_zip_read_info->raw=raw;

    if (pfile_in_zip_read_info->read_buffer==NULL)
    {
        TRYFREE(pfile_in_zip_read_info);
        return UNZ_INTERNALERROR;
    }

    pfile_in_zip_read_info->stream_initialised=0;

    if (method!=NULL)
        *method = (int)s->cur_file_info.compression_method;

    if (level!=NULL)
    {
        *level = 6;
        switch (s->cur_file_info.flag & 0x06)
        {
          case 6 : *level = 1; break;
          case 4 : *level = 2; break;
          case 2 : *level = 9; break;
        }
    }

    if ((s->cur_file_info.compression_method!=0) &&
        (s->cur_file_info.compression_method!=Z_DEFLATED))
        err=UNZ_BADZIPFILE;

    pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
    pfile_in_zip_read_info->crc32=0;
    pfile_in_zip_read_info->compression_method =
            s->cur_file_info.compression_method;
    pfile_in_zip_read_info->filestream=s->filestream;
    pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
    pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;

    pfile_in_zip_read_info->stream.total_out = 0;

    if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
        (!raw))
    {
      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
      pfile_in_zip_read_info->stream.zfree = (free_func)0;
      pfile_in_zip_read_info->stream.opaque = (voidpf)0;
      pfile_in_zip_read_info->stream.next_in = (Bytef*)0;
      pfile_in_zip_read_info->stream.avail_in = 0;

      err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
      if (err == Z_OK)
        pfile_in_zip_read_info->stream_initialised=1;
      else
      {
        TRYFREE(pfile_in_zip_read_info);
        return err;
      }
        /* windowBits is passed < 0 to tell that there is no zlib header.
         * Note that in this case inflate *requires* an extra "dummy" byte
         * after the compressed stream in order to complete decompression and
         * return Z_STREAM_END.
         * In unzip, i don't wait absolutely Z_STREAM_END because I known the
         * size of both compressed and uncompressed data
         */
    }
    pfile_in_zip_read_info->rest_read_compressed =
            s->cur_file_info.compressed_size ;
    pfile_in_zip_read_info->rest_read_uncompressed =
            s->cur_file_info.uncompressed_size ;


    pfile_in_zip_read_info->pos_in_zipfile =
            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
              iSizeVar;

    pfile_in_zip_read_info->stream.avail_in = (uInt)0;

    s->pfile_in_zip_read = pfile_in_zip_read_info;

#    ifndef NOUNCRYPT
    if (password != NULL)
    {
        int i;
        s->pcrc_32_tab = get_crc_table();
        init_keys(password,s->keys,s->pcrc_32_tab);
        if (ZSEEK(s->z_filefunc, s->filestream,
                  s->pfile_in_zip_read->pos_in_zipfile +
                     s->pfile_in_zip_read->byte_before_the_zipfile,
                  SEEK_SET)!=0)
            return UNZ_INTERNALERROR;
        if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
            return UNZ_INTERNALERROR;

        for (i = 0; i<12; i++)
            zdecode(s->keys,s->pcrc_32_tab,source[i]);

        s->pfile_in_zip_read->pos_in_zipfile+=12;
        s->encrypted=1;
    }
#    endif


    return UNZ_OK;
}
Пример #5
0
/*
  Read bytes from the current file.
  buf contain buffer where data must be copied
  len the size of buf.

  return the number of byte copied if somes bytes are copied
  return 0 if the end of file was reached
  return <0 with error code if there is an error
    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
*/
int ZEXPORT unzReadCurrentFile  (
    unzFile file,
    voidp buf,
    unsigned len)
{
    int err=UNZ_OK;
    uInt iRead = 0;
    unz_s* s;
    file_in_zip_read_info_s* pfile_in_zip_read_info;
    if (file==NULL)
        return UNZ_PARAMERROR;
    s=(unz_s*)file;
    pfile_in_zip_read_info=s->pfile_in_zip_read;

    if (pfile_in_zip_read_info==NULL)
        return UNZ_PARAMERROR;


    if (pfile_in_zip_read_info->read_buffer == NULL)
        return UNZ_END_OF_LIST_OF_FILE;
    if (len==0)
        return 0;

    pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;

    pfile_in_zip_read_info->stream.avail_out = (uInt)len;

    if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
        (!(pfile_in_zip_read_info->raw)))
        pfile_in_zip_read_info->stream.avail_out =
            (uInt)pfile_in_zip_read_info->rest_read_uncompressed;

    if ((len>pfile_in_zip_read_info->rest_read_compressed+
           pfile_in_zip_read_info->stream.avail_in) &&
         (pfile_in_zip_read_info->raw))
        pfile_in_zip_read_info->stream.avail_out =
            (uInt)pfile_in_zip_read_info->rest_read_compressed+
            pfile_in_zip_read_info->stream.avail_in;

    while (pfile_in_zip_read_info->stream.avail_out>0)
    {
        if ((pfile_in_zip_read_info->stream.avail_in==0) &&
            (pfile_in_zip_read_info->rest_read_compressed>0))
        {
            uInt uReadThis = UNZ_BUFSIZE;
            if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
                uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
            if (uReadThis == 0)
                return UNZ_EOF;
            if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
                      pfile_in_zip_read_info->filestream,
                      pfile_in_zip_read_info->pos_in_zipfile +
                         pfile_in_zip_read_info->byte_before_the_zipfile,
                         ZLIB_FILEFUNC_SEEK_SET)!=0)
                return UNZ_ERRNO;
            if (ZREAD(pfile_in_zip_read_info->z_filefunc,
                      pfile_in_zip_read_info->filestream,
                      pfile_in_zip_read_info->read_buffer,
                      uReadThis)!=uReadThis)
                return UNZ_ERRNO;


#            ifndef NOUNCRYPT
            if(s->encrypted)
            {
                uInt i;
                for(i=0;i<uReadThis;i++)
                  pfile_in_zip_read_info->read_buffer[i] =
                      zdecode(s->keys,s->pcrc_32_tab,
                              pfile_in_zip_read_info->read_buffer[i]);
            }
#            endif


            pfile_in_zip_read_info->pos_in_zipfile += uReadThis;

            pfile_in_zip_read_info->rest_read_compressed-=uReadThis;

            pfile_in_zip_read_info->stream.next_in =
                (Bytef*)pfile_in_zip_read_info->read_buffer;
            pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
        }

        if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
        {
            uInt uDoCopy,i ;

            if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
                (pfile_in_zip_read_info->rest_read_compressed == 0))
                return (iRead==0) ? UNZ_EOF : iRead;

            if (pfile_in_zip_read_info->stream.avail_out <
                            pfile_in_zip_read_info->stream.avail_in)
                uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
            else
                uDoCopy = pfile_in_zip_read_info->stream.avail_in ;

            for (i=0;i<uDoCopy;i++)
                *(pfile_in_zip_read_info->stream.next_out+i) =
                        *(pfile_in_zip_read_info->stream.next_in+i);

            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
                                pfile_in_zip_read_info->stream.next_out,
                                uDoCopy);
            pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
            pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
            pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
            pfile_in_zip_read_info->stream.next_out += uDoCopy;
            pfile_in_zip_read_info->stream.next_in += uDoCopy;
            pfile_in_zip_read_info->stream.total_out += uDoCopy;
            iRead += uDoCopy;
        }
        else
        {
            uLong uTotalOutBefore,uTotalOutAfter;
            const Bytef *bufBefore;
            uLong uOutThis;
            int flush=Z_SYNC_FLUSH;

            uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
            bufBefore = pfile_in_zip_read_info->stream.next_out;

            /*
            if ((pfile_in_zip_read_info->rest_read_uncompressed ==
                     pfile_in_zip_read_info->stream.avail_out) &&
                (pfile_in_zip_read_info->rest_read_compressed == 0))
                flush = Z_FINISH;
            */
            err=inflate(&pfile_in_zip_read_info->stream,flush);

            if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
              err = Z_DATA_ERROR;

            uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
            uOutThis = uTotalOutAfter-uTotalOutBefore;

            pfile_in_zip_read_info->crc32 =
                crc32(pfile_in_zip_read_info->crc32,bufBefore,
                        (uInt)(uOutThis));

            pfile_in_zip_read_info->rest_read_uncompressed -=
                uOutThis;

            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);

            if (err==Z_STREAM_END)
                return (iRead==0) ? UNZ_EOF : iRead;
            if (err!=Z_OK)
                break;
        }
    }

    if (err==Z_OK)
        return iRead;
    return err;
}
Пример #6
0
main(int argc, char**argv)
{
    FILE    *fp;
    struct  stat stat_buf;
    char    *datap, *newdatap, buf[PM9SCREW_LEN + 1];
    int     datalen, newdatalen;
    int     cryptkey_len = sizeof pm9screw_mycryptkey / 2;
    char    srcfilename[256];
    int     i;

    if (argc != 2) {
        fprintf(stderr, "Usage: filename.\n");
        exit(0);
    }

    fp = fopen(argv[1], "r");

    if (fp == NULL) {
        fprintf(stderr, "File %s not found.\n", argv[1]);
        exit(0);
    }

    fread(buf, PM9SCREW_LEN, 1, fp);

    if (memcmp(buf, PM9SCREW, PM9SCREW_LEN) != 0) {        
        fclose(fp);
        fprintf(stderr, "Can not decode file %s.\n", argv[1]);
        exit(0);        
    }

    fstat(fileno(fp), &stat_buf);
    datalen = stat_buf.st_size - PM9SCREW_LEN;
    datap = (char*)malloc(datalen);
    fread(datap, datalen, 1, fp);
    fclose(fp);  

    for(i=0; i<datalen; i++) {
        datap[i] = (char)pm9screw_mycryptkey[(datalen - i) % cryptkey_len] ^ (~(datap[i]));
    }

    newdatap = zdecode(datap, datalen, &newdatalen);

    sprintf(srcfilename, "%s.src", argv[1]);

    fp = fopen(srcfilename, "w");

    if (fp == NULL) {
        fprintf(stderr, "Decoded file %s can not be saved.\n", srcfilename);
        exit(0);
    }
    else {
        fprintf(stderr, "Decoded file %s saved.\n", srcfilename);
    }

    fwrite(newdatap, newdatalen, 1, fp);
    fclose(fp); 
    free(newdatap);
    free(datap);

    return 0;
}
Пример #7
0
/*
Read bytes from the current file.
buf contain buffer where data must be copied
len the size of buf.

return the number of byte copied if somes bytes are copied
return 0 if the end of file was reached
return <0 with error code if there is an error
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
 */
extern int ZEXPORT unzReadCurrentFile(unzFile file, void *buf, DWORD len)
{
  int err = UNZ_OK;
  DWORD iRead = 0;
  unz_s *s;

  file_in_zip_read_info_s *pfile_in_zip_read_info;

  if (file == NULL)
  {
    return UNZ_PARAMERROR;
  }

  s = (unz_s*)file;
  pfile_in_zip_read_info = s->pfile_in_zip_read;

  if (pfile_in_zip_read_info == NULL)
  {
    return UNZ_PARAMERROR;
  }

  if ((pfile_in_zip_read_info->read_buffer == NULL))
  {
    return UNZ_END_OF_LIST_OF_FILE;
  }

  if (len == 0)
  {
    return 0;
  }

  pfile_in_zip_read_info->stream.next_out = (BYTE*)buf;
  pfile_in_zip_read_info->stream.avail_out = (DWORD)len;

  if (len > pfile_in_zip_read_info->rest_read_uncompressed)
  {
    pfile_in_zip_read_info->stream.avail_out = (DWORD)pfile_in_zip_read_info->rest_read_uncompressed;
  }

  while (pfile_in_zip_read_info->stream.avail_out > 0)
  {
    if ((pfile_in_zip_read_info->stream.avail_in == 0) && (pfile_in_zip_read_info->rest_read_compressed > 0))
    {
      DWORD uReadThis = UNZ_BUFSIZE;
      if (pfile_in_zip_read_info->rest_read_compressed < uReadThis)
      {
        uReadThis = (DWORD)pfile_in_zip_read_info->rest_read_compressed;
      }
      if (uReadThis == 0)
      {
        return UNZ_EOF;
      }
      if (ZSEEK(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile, SEEK_SET) != 0)
      {
        return UNZ_ERRNO;
      }
      if (ZREAD(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->read_buffer, uReadThis) != uReadThis)
      {
        return UNZ_ERRNO;
      }

      #ifndef NOUNCRYPT
        if (s->encrypted)
        {
          DWORD i;
          for (i = 0; i < uReadThis; i++)
          {
            pfile_in_zip_read_info->read_buffer[i] = zdecode(s->keys, s->pcrc_32_tab, pfile_in_zip_read_info->read_buffer[i]);
          }
        }
      #endif

      pfile_in_zip_read_info->pos_in_zipfile += uReadThis;

      pfile_in_zip_read_info->rest_read_compressed -= uReadThis;

      pfile_in_zip_read_info->stream.next_in = (BYTE*)pfile_in_zip_read_info->read_buffer;
      pfile_in_zip_read_info->stream.avail_in = (DWORD)uReadThis;
    }

    if ((pfile_in_zip_read_info->compression_method == 0) || (pfile_in_zip_read_info->raw))
    {
      DWORD uDoCopy, i;

      if ((pfile_in_zip_read_info->stream.avail_in == 0) && (pfile_in_zip_read_info->rest_read_compressed == 0))
      {
        return (iRead == 0) ? UNZ_EOF : iRead;
      }

      if (pfile_in_zip_read_info->stream.avail_out < pfile_in_zip_read_info->stream.avail_in)
      {
        uDoCopy = pfile_in_zip_read_info->stream.avail_out;
      }
      else
      {
        uDoCopy = pfile_in_zip_read_info->stream.avail_in;
      }

      for (i = 0; i < uDoCopy; i++)
      {
        *(pfile_in_zip_read_info->stream.next_out + i) = *(pfile_in_zip_read_info->stream.next_in + i);
      }

      pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, pfile_in_zip_read_info->stream.next_out, uDoCopy);
      pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy;
      pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
      pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
      pfile_in_zip_read_info->stream.next_out += uDoCopy;
      pfile_in_zip_read_info->stream.next_in += uDoCopy;
      pfile_in_zip_read_info->stream.total_out += uDoCopy;
      iRead += uDoCopy;
    }
    else
    {
      DWORD uTotalOutBefore, uTotalOutAfter;
      const BYTE *bufBefore;
      DWORD uOutThis;
      int flush = Z_SYNC_FLUSH;

      uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
      bufBefore = pfile_in_zip_read_info->stream.next_out;

      err = inflate(&pfile_in_zip_read_info->stream, flush);

      uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
      uOutThis = uTotalOutAfter - uTotalOutBefore;

      pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, bufBefore, (DWORD)(uOutThis));

      pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;

      iRead += (DWORD)(uTotalOutAfter - uTotalOutBefore);

      if (err == Z_STREAM_END)
      {
        return (iRead == 0) ? UNZ_EOF : iRead;
      }

      if (err != Z_OK)
      {
        break;
      }
    }
  }

  if (err == Z_OK)
  {
    return iRead;
  }
  return err;
}