utiles_v2017/_zip.cpp

798 lines
18 KiB
C++
Raw Blame History

#include "stdafx.h"
#include "_zip.h"
#include "igt_error.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
//*****************************************************************************************************
Cigt_zip::Cigt_zip(void)
{
nivel_compresion=6;
uf=NULL;
zf=NULL;
igt_err=new Cigt_error();
borrar_error=TRUE;
nombre_zip[0]='\0';
}
//*****************************************************************************************************
Cigt_zip::Cigt_zip(Cigt_error *err)
{
nombre_zip[0]='\0';
nivel_compresion=6;
uf=NULL;
zf=NULL;
borrar_error=FALSE;
igt_err=err;
}
//*****************************************************************************************************
Cigt_zip::~Cigt_zip(void)
{
cierra_zip();
if (borrar_error&&igt_err)
{
delete igt_err;
}
igt_err=NULL;
}
//*****************************************************************************************************
int Cigt_zip::isLargeFile(char* filename )
{
int largeFile = 0;
ZPOS64_T pos = 0;
FILE* pFile = fopen64(filename, "rb");
if(pFile != NULL)
{
int n = fseeko64(pFile, 0, SEEK_END);
pos = ftello64(pFile);
if(pos >= 0xffffffff)
largeFile = 1;
fclose(pFile);
}
return largeFile;
}
//**************************************************************************************************************
BOOL Cigt_zip::abre_zip( char *filename, int parametro )
{
int esc;
zlib_filefunc64_def ffunc;
fill_win32_filefunc64A(&ffunc);
if (parametro==READ)
{
cierra_zip_uf();
uf = new unzFile();
*uf = unzOpen2_64(filename,&ffunc);
if (uf==NULL)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
return FALSE;
}
strcpy(nombre_zip,filename);
return TRUE;
}
if (parametro==OWERWRITE)
{
esc=0;
}
else
esc=2;
cierra_zip_zf();
zf= new zipFile();
*zf = zipOpen2_64(filename,esc,NULL,&ffunc);//
if (zf == NULL)//
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
return FALSE;
}
strcpy(nombre_zip,filename);
return TRUE;
}
//*****************************************************************************
BOOL Cigt_zip::addfile(char *newfile, char *dir_in_zip )
{
FILE *fin;
int err=0,size_read=0;
int zip64=0;
zip_fileinfo zi;
unsigned long crcFile=0;
char *password=NULL;
int size_buf = WRITEBUFFERSIZE;
if (!zf)
{
igt_err->pon_error("Cigt_zip","puntero del handle nulo",-1);
Cigt_error::pon_winerror("Cigt_zip",igt_err);
return FALSE;
}
void *buf = (void*)malloc(size_buf);
zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
zi.dosDate = 0;
zi.internal_fa = 0;
zi.external_fa = 0;
filetime(newfile,&zi.tmz_date,(long*)&zi.dosDate);
err = getFileCrc(newfile,buf,size_buf,&crcFile);//preparamos crc
zip64 = isLargeFile(newfile);
err = zipOpenNewFileInZip3_64(*zf,dir_in_zip,&zi,
NULL,0,NULL,0,NULL /* comment*/,
8,nivel_compresion,0,
-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
password,crcFile, zip64);//preparamos el zip
if (err != ZIP_OK)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
}
else
{
fin = fopen64(newfile,"rb");//abre el archivo a meter en zip
if (fin==NULL)
{
err=ZIP_ERRNO;
//printf("error in opening %s for reading\n",newfile);
}
}
if (err == ZIP_OK)
{
do// bucle para escribir el archivo en zip
{
err = ZIP_OK;
size_read = (int)fread(buf,1,size_buf,fin);//leemos parte
if (size_read < size_buf)
if (feof(fin)==0)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
err = ZIP_ERRNO;
}
if (size_read>0)
{
err = zipWriteInFileInZip (*zf,buf,size_read);
if (err<0)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
err = ZIP_ERRNO;
}
}
} while ((err == ZIP_OK) && (size_read>0));
}
if (fin)
fclose(fin);//cierra el archivo metido
if (buf)
{
free(buf);
}
if (err<0)//si errores
return FALSE;
return TRUE;
}
//*****************************************************************************************************
BOOL Cigt_zip::cierra_zip_zf()
{
int errclose= ZIP_OK;
if(zf)
{
errclose = zipClose(*zf,NULL);
if (errclose != ZIP_OK)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
return FALSE;
}
zf=NULL;
}
return TRUE;
}
//*****************************************************************************************************
/* calculate the CRC32 of a file,
because to encrypt a file, we need known the CRC32 of the file before */
int Cigt_zip::getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
{
unsigned long calculate_crc=0;
int err=ZIP_OK;
FILE * fin = fopen64(filenameinzip,"rb");
unsigned long size_read = 0;
unsigned long total_read = 0;
if (fin==NULL)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
err = ZIP_ERRNO;
}
if (err == ZIP_OK)
do
{
err = ZIP_OK;
size_read = (int)fread(buf,1,size_buf,fin);
if (size_read < size_buf)
if (feof(fin)==0)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
err = ZIP_ERRNO;
}
if (size_read>0)
calculate_crc = crc32(calculate_crc,(Bytef*)buf,size_read);
total_read += size_read;
} while ((err == ZIP_OK) && (size_read>0));
if (fin)
fclose(fin);
*result_crc=calculate_crc;
//printf("file %s crc %lx\n", filenameinzip, calculate_crc);
return err;
}
//*****************************************************************************************************
int Cigt_zip::filetime( char *f, tm_zip *tmzip, long *dt_ )
{
uLong *dt=(uLong *)dt_;
int ret = 0;
{
FILETIME ftLocal;
HANDLE hFind;
WIN32_FIND_DATAA ff32;
hFind = FindFirstFileA(f,&ff32);
if (hFind != INVALID_HANDLE_VALUE)
{
FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
FindClose(hFind);
ret = 1;
}
}
return ret;
}
//*****************************************************************************************************
BOOL Cigt_zip::cierra_zip()
{
BOOL resul;
resul=cierra_zip_uf();
return cierra_zip_zf() && resul;
}
//*****************************************************************************************************
BOOL Cigt_zip::descomprimir(char *file, char *fileout,BYTE **bufex,int *nb )
{
FILE *fout=NULL;
int err = UNZ_OK;
int mb;
BYTE (*bufsal)[];
bufsal=NULL;
int size_buf=0;
const char* password=NULL;
//zlib_filefunc64_def ffunc;
void *buf;
unz_file_info64 file_info;
char path_inzip[256];
if (!uf)
{
igt_err->pon_error("Cigt_zip","Error al descomprimir: puntero del handle uf nulo",-1);
return FALSE;
}
//int ret_value = do_extract_onefile(uf, file, 0, 0, "\0");
if (unzLocateFile(uf,file,CASESENSITIVITY)!=UNZ_OK)//comprueba que esta el archivo en el zip
{
char str[250];
sprintf(str,"Cigt_zip","Error al descomprimir: el archivo %s no se encuentra en el zip",file);
igt_err->pon_error("Cigt_zip",str,-1);
return FALSE;
}
err = unzGetCurrentFileInfo64(uf,&file_info,path_inzip,sizeof(path_inzip),NULL,0,NULL,0);
if (err!=UNZ_OK)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
return FALSE;
}
size_buf = WRITEBUFFERSIZE;
buf = (void*)malloc(size_buf);
if (buf==NULL)
{
char str[256];
sprintf(str,"Cigt_zip","Error al descomprimir: no se puede reservar memoria para buf de %ld bytes",size_buf);
igt_err->pon_error("Cigt_zip",str,-1);
return FALSE;
}
err = unzOpenCurrentFilePassword(uf,password);
if (err!=UNZ_OK)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
return FALSE;
}
if (fileout)
fout=fopen64(fileout,"wb");
else
{
*nb=0;
mb=WRITEBUFFERSIZE*5;
bufsal = (BYTE (*)[])malloc(mb);
}
/* some zipfile don't contain directory alone before file */
if (fout!=NULL||!fileout)
{
do//bucle para escribir archivo
{
err = unzReadCurrentFile(uf,buf,size_buf);
if (err<0)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
break;
}
if (err>0)
if(fileout)
{
if (fwrite(buf,err,1,fout)!=1)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
err=UNZ_ERRNO;
break;
}
}
else
{
if ((*nb+err)>=mb)
{
mb+=WRITEBUFFERSIZE*5;
bufsal=(BYTE(*)[])realloc(bufsal,mb);
}
memcpy(&(*bufsal)[*nb],buf,err);
*nb+=err;
}
}
while (err>0);
}
if (fout)
fclose(fout);
free(buf);
if (err==UNZ_OK)
{
if (fileout)
{
change_file_date(fileout,file_info.dosDate,
file_info.tmu_date);
}
else
{
*bufex=(BYTE*)bufsal;
}
return TRUE;
}
if (bufsal)
{
free(bufsal);
}
return FALSE;
}
//*****************************************************************************************************
BOOL Cigt_zip::descomprimir()
{
int n;
Zip_struct (*contenido)[];
contenido= (Zip_struct(*)[])listar(&n);
if (n<=0)
return FALSE;
for (int i=0; i<n;i++)
{
if (!descomprimir2file((*contenido)[i].nombre))
{
free(contenido);
return FALSE;
}
}
free(contenido);
return TRUE;
}
//*****************************************************************************************************
void Cigt_zip::change_file_date(const char *filename,uLong dosdate,tm_unz tmu_date)
{
HANDLE hFile;
FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE,
0,NULL,OPEN_EXISTING,0,NULL);
GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
LocalFileTimeToFileTime(&ftLocal,&ftm);
SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
CloseHandle(hFile);
}
//*****************************************************************************************************
BOOL Cigt_zip::descomprimir2file( char *file,char *fileout )
{
if (fileout)
return descomprimir(file,fileout,NULL,NULL);
return FALSE;
}
//*****************************************************************************************************
BOOL Cigt_zip::descomprimir2file( char *file )
{
char fileout[256];
int i;
int j;
strcpy(fileout,nombre_zip);
for (i=strlen(fileout);i>=0;i--)
{
if(fileout[i]=='\\')
{
fileout[i]='\\';
i++;
fileout[i]='\0';
break;
}
}
if (i<0)
i=0;
for(j=0; *(file+j); j++)
{
if (*(file+j)=='\\')
{
*(fileout+j+i)='\0';
if(!crea_dir(fileout))
{
return FALSE;
}
}
*(fileout+j+i)=*(file+j);
}
*(fileout+j+i)='\0';
return descomprimir2file(file,fileout);
}
//*****************************************************************************************************
BOOL Cigt_zip::descomprimir2buff(char *file,BYTE **buf,int *nb )
{
return descomprimir(file,NULL,buf,nb);
}
//*****************************************************************************************************
Zip_struct* Cigt_zip::listar(int* n)
{
int err = UNZ_OK;
//zlib_filefunc64_def ffunc;
unz_file_info64 file_info;
uLong i;
unz_global_info64 gi;
//char path_inzip[256];
*n=0;
Zip_struct (*salida)[];
salida=NULL;
err = unzGetGlobalInfo64(uf,&gi);
if (err!=UNZ_OK)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
}
if (gi.number_entry<=0)
{
igt_err->pon_error("Cigt_zip","Error en listar: en n<>mero de archivos del zip es <=0");
return NULL;
}
salida=(Zip_struct(*)[])malloc(sizeof(Zip_struct)*gi.number_entry);
*n=gi.number_entry;
for (i=0;i<gi.number_entry;i++)
{
err = unzGetCurrentFileInfo64(uf,&file_info,(*salida)[i].nombre,sizeof((*salida)[i].nombre),NULL,0,NULL,0);
if (err!=UNZ_OK)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
break;
}
if (file_info.uncompressed_size>0)
{
(*salida)[i].ratio = (int)((file_info.compressed_size*100)/file_info.uncompressed_size);
(*salida)[i].size_descom=(int)file_info.uncompressed_size;
}
else
{
(*salida)[i].ratio = 0;
(*salida)[i].size_descom=0;
}
/* display a '*' if the file is crypted */
if ((file_info.flag & 1) != 0)
(*salida)[i].encript=TRUE;
else
(*salida)[i].encript=FALSE;
(*salida)[i].compresion=file_info.compression_method;
(*salida)[i].size=file_info.compressed_size;
if ((i+1)<gi.number_entry)
{
err = unzGoToNextFile(uf);
if (err!=UNZ_OK)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
break;
}
}
}
return (Zip_struct *)salida;
}
//*****************************************************************************************************
BOOL Cigt_zip::cierra_zip_uf()
{
int err=UNZ_OK;
if (uf)
{
err = unzCloseCurrentFile (uf);
if (err!=UNZ_OK)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
return FALSE;
}
uf=NULL;
}
return TRUE;
}
//*****************************************************************************************************
BOOL Cigt_zip::crea_dir( char *dir )
{
int k;
int err=mkdir(dir);
if (err<0)
{
k=errno;
if(k!=EEXIST)
{
igt_err->pon_error("Cigt_zip","Error al crear carpeta: carpeta no encontrada",k);
return FALSE;
}
}
return TRUE;
}
//*****************************************************************************************************
BOOL Cigt_zip::abre_zip_temp()
{
char szTempFileName[256];
char lpTempPathBuffer[256];
//char chBuffer[512];
//LPCTSTR errMsg;
DWORD dwRetVal = 0;
// Gets the temp path env string (no guarantee it's a valid path).
dwRetVal = GetTempPath(MAX_PATH, // length of the buffer
lpTempPathBuffer); // buffer for path
if (dwRetVal > MAX_PATH || (dwRetVal == 0))
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
return FALSE;
}
// Generates a temporary file name.
dwRetVal = GetTempFileName(lpTempPathBuffer, // directory for tmp files
"DEMO", // temp file name prefix
0, // create unique name
szTempFileName); // buffer for name
if (dwRetVal == 0)
{
Cigt_error::pon_winerror("Cigt_zip",igt_err);
return FALSE;
}
return abre_zip(szTempFileName,OWERWRITE);
}
//*****************************************************************************************************
BOOL lista_file_dir( char *dir,Cstr_array *lista_file, Cigt_error *err)
{
return lista_file_dir(dir,NULL,lista_file,err);
/*
BOOL poner_error;
char str[256];
//int k;
WIN32_FIND_DATA filedat;
HANDLE hfile;
if (err)
poner_error=TRUE;
else
poner_error=FALSE;
if (!lista_file)
{
err->pon_error("lista_file_dir","Puntero de lista_file nulo",-1);
return FALSE;
}
strcpy(str,dir);
if (str[strlen(str)-1] != '\\')
strcat(str,"\\");
strcat(str,"*.*");
hfile = FindFirstFile(str,&filedat);
if (hfile != INVALID_HANDLE_VALUE)//existe dir
{
// existe el dir
do
{
if ((strcmp(filedat.cFileName,".") != 0) &&
(strcmp(filedat.cFileName,"..") != 0))
{
strcpy(str,dir);
if (str[strlen(str)-1] != '\\')
strcat(str,"\\");
strcat(str,filedat.cFileName);
if (filedat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(!lista_file_dir( str, lista_file, err))
{
FindClose(hfile);
return FALSE;
}
}
else
{
lista_file->pon_str(str);
}
}
} while (FindNextFile(hfile,&filedat));
FindClose(hfile);
}
else
{
if (poner_error)
Igt_error::pon_winerror("lista_file_dir",err);
return FALSE;
}
return TRUE;
*/
}
//*****************************************************************************************************
BOOL lista_file_dir( char *dir,char *omite,Cstr_array *lista_file,Cigt_error *err )
{
BOOL poner_error;
char str[256];
//int k;
WIN32_FIND_DATA filedat;
HANDLE hfile;
if (err)
poner_error=TRUE;
else
poner_error=FALSE;
if (!lista_file)
{
err->pon_error("lista_file_dir","Puntero de lista_file nulo",-1);
return FALSE;
}
strcpy(str,dir);
if (str[strlen(str)-1] != '\\')
strcat(str,"\\");
strcat(str,"*.*");
hfile = FindFirstFile(str,&filedat);
if (hfile != INVALID_HANDLE_VALUE)//existe dir
{
// existe el dir
do
{
if ((strcmp(filedat.cFileName,".") != 0) &&
(strcmp(filedat.cFileName,"..") != 0))
{
if (!omite||strcmp(omite,filedat.cFileName)!=0)
{
strcpy(str,dir);
if (str[strlen(str)-1] != '\\')
strcat(str,"\\");
strcat(str,filedat.cFileName);
if (filedat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(!lista_file_dir( str,NULL, lista_file, err))
{
FindClose(hfile);
return FALSE;
}
}
else
{
lista_file->pon_str(str);
}
}
}
} while (FindNextFile(hfile,&filedat));
FindClose(hfile);
}
else
{
if (poner_error)
Cigt_error::pon_winerror("lista_file_dir",err);
return FALSE;
}
return TRUE;
}
//*****************************************************************************************************
BOOL es_dir(char *dir)
{
WIN32_FIND_DATA filedat;
HANDLE hfile;
hfile = FindFirstFile(dir,&filedat);
if (hfile != INVALID_HANDLE_VALUE)//existe dir
{
if (filedat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
FindClose(hfile);
return TRUE;
}
FindClose(hfile);
}
return FALSE;
}
//*****************************************************************************************************
BOOL del_File(char *file,Cigt_error *err)
{
//borra archivos y carpetas
BOOL poner_error;
char str[256];
int n_aux;
//int k;
WIN32_FIND_DATA filedat;
HANDLE hfile;
if (err)
poner_error=TRUE;
else
poner_error=FALSE;
n_aux=strlen(file);
if (n_aux<3)
{
if (poner_error)
{
sprintf(str,"Error al borrar archivo: %s. Borrar este archivo puede ser peligroso");
err->pon_error("del_File",str,-1);
}
return FALSE;
}
strcpy(str,file);
if (str[strlen(str)-1] != '\\')
strcat(str,"\\");
strcat(str,"*.*");
hfile = FindFirstFile(str,&filedat);
if (hfile != INVALID_HANDLE_VALUE)
{
// existe el dir
// borralo y usalo
do
{
if ((strcmp(filedat.cFileName,".") != 0) &&
(strcmp(filedat.cFileName,"..") != 0))
{
strcpy(str,file);
if (str[strlen(str)-1] != '\\')
strcat(str,"\\");
strcat(str,filedat.cFileName);
if (filedat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(!del_File(str,err))
{
FindClose(hfile);
return FALSE;
}
}
else
{
SetFileAttributes(str,FILE_ATTRIBUTE_NORMAL);
if (!DeleteFile(str))
{
Cigt_error::pon_winerror("del_File",err);
FindClose(hfile);
return FALSE;
}
}
}
} while (FindNextFile(hfile,&filedat));
FindClose(hfile);
if (!RemoveDirectory(file))
{
Cigt_error::pon_winerror("del_File",err);
FindClose(hfile);
return FALSE;
}
}
return TRUE;
}
//*****************************************************************************************************