Correccion aplicada:
Code: Select all
FUNCTION hb_UnzipFile( cFileName, bUpdate, lWithPath, cPassword, cPath, acFiles, bProgress )
LOCAL lRetVal := .T.
LOCAL hUnzip
LOCAL nErr
LOCAL nPos
LOCAL cZipName
LOCAL lExtract
LOCAL hHandle
LOCAL nSize
LOCAL nRead
LOCAL nLen
LOCAL dDate
LOCAL cTime
LOCAL cBuffer := Space( t_nReadBuffer )
LOCAL cTarget
LOCAL cDir
IF hb_defaultValue( lWithPath, .F. ) .AND. ! hb_DirExists( cPath ) .AND. ! Zip_MakeDirTree( cPath )
lRetVal := .F.
ENDIF
IF Empty( cPassword )
cPassword := NIL
ENDIF
IF Set( _SET_DEFEXTENSIONS )
cFileName := hb_FNameExtSetDef( cFileName, ".zip" )
ENDIF
IF Empty( hUnzip := hb_unzipOpen( cFileName ) )
lRetVal := .F.
ELSE
IF HB_ISNUMERIC( acFiles ) .OR. HB_ISSTRING( acFiles )
acFiles := { acFiles }
ENDIF
IF Empty( cPath )
cPath := hb_FNameDir( cFileName )
ENDIF
cPath := hb_DirSepAdd( cPath )
nPos := 0
nErr := hb_unzipFileFirst( hUnzip )
DO WHILE nErr == 0
nPos++
IF hb_unzipFileInfo( hUnzip, @cZipName, @dDate, @cTime,,,, @nSize ) == 0
lExtract := Empty( acFiles ) .OR. ;
AScan( acFiles, nPos ) > 0 .OR. ;
AScan( acFiles, {| cMask | hb_FileMatch( cZipName, cMask ) } ) > 0
IF lExtract
cTarget := cPath + cZipName
IF Right( cZipName, 1 ) == "/" .OR. Right( cZipName, 1 ) == "\"
/* FIX (3): entrada de directorio → crear el directorio,
no intentar FCreate() sobre un nombre con separador final */
IF ! Zip_MakeDirTree( cTarget )
lRetVal := .F.
ENDIF
ELSE
/* FIX (1)+(2): crear TODOS los directorios intermedios
antes de FCreate(), y NO silenciar el fallo */
cDir := hb_FNameDir( cTarget )
IF ! Empty( cDir ) .AND. ! Zip_MakeDirTree( cDir )
lRetVal := .F.
ELSEIF ( hHandle := FCreate( cTarget ) ) == F_ERROR
lRetVal := .F.
ELSE
IF hb_unzipFileOpen( hUnzip, cPassword ) != UNZ_OK
lRetVal := .F.
FClose( hHandle )
EXIT
ENDIF
nRead := 0
DO WHILE ( nLen := hb_unzipFileRead( hUnzip, @cBuffer, hb_BLen( cBuffer ) ) ) > 0
/* FIX (4): verificar la escritura */
IF FWrite( hHandle, cBuffer, nLen ) != nLen
lRetVal := .F.
ENDIF
IF HB_ISEVALITEM( bProgress )
nRead += nLen
Eval( bProgress, nRead, nSize )
ENDIF
ENDDO
hb_unzipFileClose( hUnzip )
FClose( hHandle )
hb_FSetDateTime( cTarget, dDate, cTime )
IF HB_ISEVALITEM( bUpdate )
Eval( bUpdate, cZipName, nPos )
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
nErr := hb_unzipFileNext( hUnzip )
ENDDO
hb_unzipClose( hUnzip )
ENDIF
RETURN lRetVal
STATIC FUNCTION Zip_MakeDirTree( cDir )
IF Empty( cDir )
RETURN .F.
ENDIF
IF hb_DirExists( cDir )
RETURN .T.
ENDIF
/* hb_DirBuild() crea el árbol completo, nivel por nivel */
hb_DirBuild( cDir )
RETURN hb_DirExists( cDir )
Funcion Original :
Code: Select all
FUNCTION hb_UnzipFile( cFileName, bUpdate, lWithPath, cPassword, cPath, acFiles, bProgress )
LOCAL lRetVal := .T.
LOCAL hUnzip
LOCAL nErr
LOCAL nPos
LOCAL cZipName
LOCAL lExtract
LOCAL hHandle
LOCAL nSize
LOCAL nRead
LOCAL nLen
LOCAL dDate
LOCAL cTime
LOCAL cBuffer := Space( t_nReadBuffer )
IF hb_defaultValue( lWithPath, .F. ) .AND. ! hb_DirExists( cPath ) .AND. hb_DirCreate( cPath ) != 0
lRetVal := .F.
ENDIF
IF Empty( cPassword )
cPassword := NIL
ENDIF
IF Set( _SET_DEFEXTENSIONS )
cFileName := hb_FNameExtSetDef( cFileName, ".zip" )
ENDIF
IF Empty( hUnzip := hb_unzipOpen( cFileName ) )
lRetVal := .F.
ELSE
IF HB_ISNUMERIC( acFiles ) .OR. ;
HB_ISSTRING( acFiles )
acFiles := { acFiles }
ENDIF
IF Empty( cPath )
cPath := hb_FNameDir( cFileName )
ENDIF
cPath := hb_DirSepAdd( cPath )
nPos := 0
nErr := hb_unzipFileFirst( hUnzip )
DO WHILE nErr == 0
nPos++
IF hb_unzipFileInfo( hUnzip, @cZipName, @dDate, @cTime,,,, @nSize ) == 0
/* NOTE: As opposed to original hbziparch we don't do a second match without path. */
lExtract := Empty( acFiles ) .OR. ;
AScan( acFiles, nPos ) > 0 .OR. ;
AScan( acFiles, {| cMask | hb_FileMatch( cZipName, cMask ) } ) > 0
IF lExtract .AND. ( hHandle := FCreate( cPath + cZipName ) ) != F_ERROR
IF hb_unzipFileOpen( hUnzip, cPassword ) != UNZ_OK
lRetVal := .F.
EXIT
ENDIF
nRead := 0
DO WHILE ( nLen := hb_unzipFileRead( hUnzip, @cBuffer, hb_BLen( cBuffer ) ) ) > 0
IF HB_ISEVALITEM( bProgress )
nRead += nLen
Eval( bProgress, nRead, nSize )
ENDIF
FWrite( hHandle, cBuffer, nLen )
ENDDO
hb_unzipFileClose( hUnzip )
FClose( hHandle )
hb_FSetDateTime( cPath + cZipName, dDate, cTime )
IF HB_ISEVALITEM( bUpdate )
Eval( bUpdate, cZipName, nPos )
ENDIF
ENDIF
ENDIF
nErr := hb_unzipFileNext( hUnzip )
ENDDO
hb_unzipClose( hUnzip )
ENDIF
RETURN lRetVal