Zipfiles: Hbmzip and HbZipArc Question

Issues and Discussions related to Harbour

Moderator: Rathinagiri

Post Reply
User avatar
dhaine_adp
Posts: 457
Joined: Wed Aug 06, 2008 12:22 pm
Location: Manila, Philippines
Been thanked: 2 times

Zipfiles: Hbmzip and HbZipArc Question

Post by dhaine_adp » Fri Aug 14, 2015 8:39 pm

Hi everyone,

Is there anyone works with archive files? The code below under IF...ELSE...ENDIF condition block (IF lOrigPath) works fine when IF lOrigPath is set to logical .t. It fails when block under ELSE condition is executed. No files are extracted. The principle is simple. Using HMG GetFile() to pick a zip file from disk or folder. Then another TEXTBOX control holds the Target folder (restore path). Now when the Target Folder TEXTBOX is empty, the archive will be restored in the original location (drive and path) using HB_UnzipExtractCurrentFile(). When its not empty and the path or folder is a valid location it will be restored in the folder specified in the target folder TEXTBOX control. However this segment is not working as expected.

I have done trial and error and usually compile and link the apps with hbziparc and use harbour-32-x64.dll, hbmzip-32-x64.dll and hbziparc-32-x64.dll. Here I encountered the error quoted below:
Application Internal Error - D:\DAD\OUI\oui.exe
Terminated at: 2015-08-09 22:50:29
Unrecoverable error 6005: Exception error:

Exception Code:C0000005 ACCESS_VIOLATION
Exception Address:0000000062B20B60
RAX:0000000000000020 RBX:0000000000000000 RCX:0000000000000000 RDX:00000000003790B4
RSI:000000006A2057E0 RDI:00000000008747E4 RBP:000000000000000D
R8 :0000000000000000 R9 :FFFFFFFFF8AB4737 R10:E47374626477446C R11:8101010101010100
R12:000007FB99FD1290 R13:00000000003790B4 R14:0000000000000000 R15:0000000062CB91A8
CS:RIP:0033:0000000062B20B60 SS:RSP:002B:000000000023D9F0
DS:002B ES:002B FS:0053 GS:002B
Flags:00010246
Exception Parameters: 0000000000000001 00000000000002A0

Modules:
I wont be able to find the error in hbmziparc.prg from harbour contrib. So the next thing I did is to remove all those dlls' mentioned above and I copied the source file hbmziparc.prg and include it as a regular prg file in my application. The error is gone but no files is being extracted from this line

Code: Select all

lErr := HB_UNZIPFILE( cZipFile, NIL, .t., cPassword, cTargetFolder, aExtract_ )
as shown in the code below.

I'm using HMG 3.4.1 Patch 4 and Harbour 3.2.0dev (r1508071407). It seems that harbour minizip (hmzip) cannot restore in different path and I am not sure with hbmziparc if it is the same?

Any idea? (Well I didn't post in harbour support, I know the answer already).

Code: Select all

static function StartRestoreEngine()

   LOCAL lErr := .f.
   LOCAL cMsg  := ""
   
   LOCAL cRestoreMsg := ""
   
   LOCAL ii := 0

   LOCAL hUnzip                                                              // Zip File handle
   LOCAL nErr                                                                // Zip file error code
   LOCAL cFile                                                               // Name of File to be restored
   LOCAL dDate                                                               // file date
   LOCAL cTime                                                               // file time
   LOCAL nSize                                                               // file size
   LOCAL nCompSize                                                           // compression size
   LOCAL nEntries                                                            // zip file total number of files
   LOCAL cComment                                                            // zip file comment
   
   LOCAL cMakeThisFolder := ""
   LOCAL cTargetFolder   := ALLTRIM( hWndUnzip.tbxTargetPath.Value )         // Unzip path
   LOCAL cPassword       := hWndUnzip.tbxEnKey.Value                         // Password
   LOCAL cZipFile        := ALLTRIM( hWndUnzip.tbxZipName.Value )            // Zip file to be expanded
   LOCAL lDecrypt        := .f.                                              // flag if the zip archive is encrypted

   LOCAL lOrigPath   := .f.                                                  // Expand the zip file to original location or folder
   LOCAL aExtract_

   LOCAL cZipFolder
   LOCAL cFileName

   IF EMPTY( cZipFile )
      oProcess:Hide()
      oProcess:Destroy()
      RETURN NIL
   ENDIF

   **--> If there's no path specified, files will be restored in the default drive and directory originally contained in the Zip file
   ***********************************************************************************************************************************
   IF EMPTY( cTargetFolder )
      lOrigPath := .t.
   ELSE
      **--> Extract in different root folder or different path
      *********************************************************
      IF .NOT. IsFolderExist( ALLTRIM( hWndUnzip.tbxTargetPath.Value ) )
         oProcess:Hide()
         oProcess:Destroy()
         MSGSTOP( "The folder " + ALLTRIM( hWndUnzip.tbxTargetPath.Value ) + " does not exist. Nothing will be done.", "Error" )
         RETURN NIL
      ENDIF
      SETCURRENTFOLDER( cTargetFolder )
      cTargetFolder := STRTRAN( cTargetFolder, "\", "/" ) // change path designator to unix path convention (Harbour default)
      lOrigPath := .f.
   ENDIF      

   IF EMPTY( cPassword )
      lDecrypt := .f.
      cPassword := ""
   ELSE
      lDecrypt := .t.
      cPassword := ALLTRIM( cPassword )
   ENDIF

   IF lOrigPath
      hUnzip := HB_UNZIPOPEN( cZipFile )                  // Open the backup set
      HB_UnzipGlobalInfo( hUnzip, @nEntries, @cComment )  // Retrieve archive informations
      
      ///////////////////////////////////////
      // issue a final warning to the user //
      ///////////////////////////////////////
      IF MSGOKCANCEL( cComment + HB_OSNEWLINE() + HB_OSNEWLINE() +;
                      "The process of restoring from the backup set " + cZipFile + " is about to begin." + HB_OSNEWLINE() +;
                      "It contains " + ALLTRIM( STR( nEntries ) ) + " files." + HB_OSNEWLINE() + HB_OSNEWLINE() +;
                      "Please click the button OK to proceed or click CANCEL to abort.", "Please confirm" ) = .f.
         HB_UNZIPCLOSE( hUnzip )
         oProcess:Hide()
         oProcess:Destroy()
         RETURN NIL
      ENDIF

      **--> Original file folders, always overwrite existing files and folder
      **    from source code: <HB install folder>\contrib\hbmzip
      ***********************************************************************
      nErr := HB_UNZIPFILEFIRST( hUnzip )
      WHILE nErr = 0
         /////////////////////////////////////////////////////////////////////////////////
         // Syntax
         /////////////////////////////////////////////////////////////////////////////////
         // hb_unzipFileInfo( hUnzip, @cZipName, @tDateTime, @cTime,
         //                   @nInternalAttr, @nExternalAttr,
         //                   @nMethod, @nSize, @nCompressedSize,
         //                   @lCrypted, @cComment ) --> nError
         /////////////////////////////////////////////////////////////////////////////////
         nErr := HB_UnzipFileInfo( hUnzip, @cFile, @dDate, @cTime,,,, @nSize, @nCompSize, @lDecrypt, @cComment )
         IF nErr > 0
            MultiMessage( { "File " + cFile, dDate, cTime, nSize, nCompSize } )
            EXIT
         ENDIF
         ii++
      
         cMsg := "Extracting " + cFile + " " +;
                 "Progress Status: " + ALLTRIM( STR( INT( ( ( ii / nEntries ) * 100 ) ) ) ) + "%"
         oProcess:UpdateBar( cMsg, INT( ( ( ii / nEntries ) * 100 ) ) )
   
         HB_UnzipExtractCurrentFile( hUnzip, NIL, cPassword )
         nErr := HB_UNZIPFILENEXT( hUnzip )
         DO EVENTS
      END
      HB_UNZIPCLOSE( hUnzip )
      IF nErr > 0; lErr := .t.; ENDIF
   ELSE
      ii := RAT( "\", cZipFile )
      cZipFolder := SUBSTR( cZipFile, 1, ii )
      cFileName  := SUBSTR( cZipFile, ii+1 )
      SETCURRENTFOLDER( cZipFolder )
      cTargetFolder := STRTRAN( cTargetFolder, "\", "/" ) // change path designator to unix path convention (Harbour default)
      cZipFile := STRTRAN( cZipFile, "\", "/" ) // change path designator to unix path convention (Harbour default)
      aExtract_ := hb_GetFilesInZip( cFileName )  // extract all files in zip

      *************************************************************************
      **--> restore in another folder from <HB Install Folder>\contrib\hbziparc
      **    hb_UnzipFile( <cFile>, <bBlock>, <lWithPath>, <cPassWord>, <cPath>,
      **                  <cFile> | <aFile>, <pFileProgress> ) --> lCompress
      *************************************************************************
      MSGDEBUG( aExtract_ )
      ii := 1
      lErr := HB_UNZIPFILE( cZipFile, NIL, .t., cPassword, cTargetFolder, aExtract_ )
   ENDIF
   SETCURRENTFOLDER( AppHome )
   IF lErr
      MSGSTOP( "Error occured while reading the archive set" + cZipFile + ".", "Zip File Error" )
   ELSE
      MSGINFO( cRestoreMsg + cZipFile + " successfully.", "Done." )
   ENDIF
   oProcess:Hide()
   oProcess:Destroy()
   RETURN NIL
Regards,

Danny
Manila, Philippines

User avatar
dhaine_adp
Posts: 457
Joined: Wed Aug 06, 2008 12:22 pm
Location: Manila, Philippines
Been thanked: 2 times

Post by dhaine_adp » Sat Aug 15, 2015 8:03 pm

Hi everyone,

I have solved my problem though there are some glitches. There are missing files during compression process but I believed I can worked that out. It can also restore the files in different folder or drive.

The root cause of my problem is my defective usb thumb drive. I just found out when I copied a file and copied it back and to my surprise it is also zero bytes. Reformatting doesn't fixed the problem. :)

Here is code that recreate folder from path, by product of troubleshooting:

Code: Select all

*************************************
static function HMG_dirBuild( cPath )

   LOCAL aFolders_ := {}
   LOCAL ii := 0
   LOCAL cDrive := SUBSTR( cPath, 1, 2 ) + "\"
   LOCAL cTmp := ""
   LOCAL lRetVal := .t.

   cPath := SUBSTR( cPath, 4 )   // strip out the drive designator
   **--> split the path into array
   FOR ii := 1 TO LEN( cPath )
      IF SUBSTR( cPath, ii, 1 ) == "/" .OR. SUBSTR( cPath, ii, 1 ) == "\"
         AADD( aFolders_, cTmp )
         cTmp := ""
      ELSE
         cTmp += SUBSTR( cPath, ii, 1 )
      ENDIF
   NEXT

   **--> rejoin the array and check each path. If the path does not exist create
   cTmp := cDrive
   FOR ii := 1 TO LEN( aFolders_ )
      IF .NOT. IsFolderExist( cTmp + aFolders_[ ii ] )
         SetCurrentFolder( cTmp )
         IF .NOT. ( MAKEDIR( cTmp + aFolders_[ ii ] ) == 0 )
            lRetVal := .f.
            EXIT
         ENDIF
      ENDIF
      cTmp += aFolders_[ ii ] + "\"
   NEXT
   RETURN lRetVal
Regards,

Danny
Manila, Philippines

User avatar
serge_girard
Posts: 2140
Joined: Sun Nov 25, 2012 2:44 pm
DBs Used: 1 MySQL - MariaDB
2 DBF
Location: Belgium
Has thanked: 449 times
Been thanked: 102 times
Contact:

Post by serge_girard » Sun Aug 16, 2015 7:19 am

Danny,

USB sticks are so vulnerable. Glad you found it!

Serge

Post Reply