Hmm, I tested that archive with 6.01b4 and you're right: it doesn't seem to decompress properly.
This might warrant a bug report. I wonder if it's the implode method that PB's packer is struggling with, or another characteristic of this archive (it's from '96, quite early days of ZIP!).
I did make additional adjustments to your code, since there was another issue which will prevent unpacking even given valid archives. The output directory for
UncompressPackFile(...) must always exist, otherwise it will fail to produce output.
For example, if decompressing a file to
"B:/testpack/FRFAQ/LISEZMOI.FAQ", you have to ensure the folder
"B:/testpack/FRFAQ/" exists first. You can feel free to use my
EnsureDirectoryExistsDeep(...) for that purpose (or peek the forum for alternatives, though some others at least are known not to function with UNC paths).
Code: Select all
EnableExplicit
UseZipPacker()
; Output directory path where files should be unpacked to.
#OUT_DIRECTORY_PATH = "B:/testpack/"
; Archive which all files should be extracted from (to above output directory).
#IN_PACK_FILE_PATH = "B:/testpack/frfaq21b.zip"
;; Ensures that a directory matching the given path exists, creating it if necessary,
;; along with any parent directories.
;;
;; @param directoryPath Path of the directory to be created.
;;
;; @returns Returns #True if the desired directory already existed or was created without
;; issue. Otherwise returns #False.
Procedure.i EnsureDirectoryExistsDeep(directoryPath.s)
; Cached length of the input directory path.
Protected directoryPathLength.i = Len(directoryPath)
; Current directory path constructed iteratively from amongst the given one, as the path
; tree is checked on the filesystem.
Protected currentPath.s
; Current directory path segment being examined before appending to the total path.
Protected currentPathSegment.s
; Index of the most recent delimiter character encountered.
Protected currentSeparatorIndex.i
; Index of the prior delimiter character encountered, just before currentSeparatorIndex.
Protected priorSeparatorIndex.i
; Normalise slashes to platform-respective form. This generally doesn't make a difference
; and Windows can usually handle both "/" and "\" just fine. It is, however, of critical
; importance when given UNC paths.
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
Protected pathSeparator.s = "\"
Protected charAtPos3.s = Mid(directoryPath, 3, 1)
; Handle UNC paths by skipping the first apparent slashes from normal directory-test logic.
If directoryPathLength > 3 And Left(directoryPath, 2) = "\\" And charAtPos3 <> "\" And charAtPos3 <> "/"
If charAtPos3 = "." Or charAtPos3 = "?" And Mid(directoryPath, 4, 1) = "\"
currentPath = "\\" + charAtPos3 + "\"
currentSeparatorIndex = 4
Else
currentPath = "\\"
currentSeparatorIndex = 2
EndIf
EndIf
directoryPath = ReplaceString(directoryPath, "/", "\")
CompilerElse
Protected pathSeparator.s = "/"
directoryPath = ReplaceString(directoryPath, "\", "/")
CompilerEndIf
Repeat
priorSeparatorIndex = currentSeparatorIndex
currentSeparatorIndex = FindString(directoryPath, pathSeparator, priorSeparatorIndex + 1)
If currentSeparatorIndex
currentPathSegment = Mid(directoryPath, priorSeparatorIndex + 1, currentSeparatorIndex - priorSeparatorIndex)
ElseIf priorSeparatorIndex < directoryPathLength
currentPathSegment = Mid(directoryPath, priorSeparatorIndex + 1, directoryPathLength - priorSeparatorIndex) + pathSeparator
Else
currentPathSegment = ""
EndIf
If currentPathSegment And currentPathSegment <> pathSeparator
currentPath + currentPathSegment
; If the current path doesn't already exist as a folder AND we've failed to create it, exit
; with fail state.
If FileSize(currentPath) <> -2 And Not CreateDirectory(currentPath)
; Perform one last check just in case we've a networked path which fails the test
; using `FileSize()` but passes with `ExamineDirectory()`.
; This prevents issues given networked paths on Windows at least.
Protected maybeDirectory.i = ExamineDirectory(#PB_Any, currentPath, "*.nil")
If Not maybeDirectory
ProcedureReturn #False
Else
FinishDirectory(maybeDirectory)
EndIf
EndIf
EndIf
Until Not currentSeparatorIndex
ProcedureReturn #True
EndProcedure
; Begin main.
; ---------------------------------------------------------
Define targetPack.i = OpenPack(#PB_Any, #IN_PACK_FILE_PATH)
If Not targetPack
DebuggerError("Failed to open desired pack file: " + #IN_PACK_FILE_PATH)
End
EndIf
If Not ExaminePack(targetPack)
DebuggerError("Failed to examine loaded pack file: " + #IN_PACK_FILE_PATH)
Goto cleanup
EndIf
While NextPackEntry(targetPack)
Define currentEntryName.s = PackEntryName(targetPack)
Debug " - " + currentEntryName
Debug " + Original size: " + PackEntrySize(targetPack, #PB_Packer_UncompressedSize)
Debug " + Compressed size: " + PackEntrySize(targetPack, #PB_Packer_CompressedSize)
Debug ""
; Build the output path.
Define currentEntryLocalPath.s = #OUT_DIRECTORY_PATH + currentEntryName
; Ensure the directory the file is being decompressed to exists beforehand.
If Not EnsureDirectoryExistsDeep(GetPathPart(currentEntryLocalPath))
DebuggerError("Failed to ensure local directory path for file: " + currentEntryLocalPath)
Goto cleanup
EndIf
; Finally, try and uncompress to the desired output path.
If UncompressPackFile(targetPack, currentEntryLocalPath) = -1
DebuggerError("Failed to extract pack file '" + currentEntryName + "' to local path: " + currentEntryLocalPath)
Goto cleanup
EndIf
Wend
cleanup:
ClosePack(targetPack)