Attribute VB_Name = "mod_ctPackage_Update"
' Modul for Visual Basic 6
' Copyright (C) 2003-2006 Jan Vorel

' This program is free software; you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation; either version 2 of the License, or
' (at your option) any later version.

' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' GNU General Public License for more details.

' You should have received a copy of the GNU General Public License
' along with this program; if not, write to the Free Software
' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

' This is a shared modul, class modul, usercontrol or form. It is also
' published under the GNU General Public License.

' If you have any questions, suggestions or bug reports about this product,
' contact me: info@ctuser.net; Do not contact me about general B.A.S.I.C.
' language or A.P.I. issues

' ####################################################################################
' ####################################################################################
' ####################################################################################
' ####################################################################################
' ####################################################################################
' ####################################################################################
' Do not optimize too much using compiler constants... this is designed for editing
' programs, not 'end-user' products.
' ####################################################################################
' ####################################################################################
' ####################################################################################
' ####################################################################################
' ####################################################################################

Option Explicit
Option Base 0



' *3+0: <""> , adds directmemory internally (alreadypacked)
'       <0!byte> < ExtData >   if first=0!, add direct memory data
'       otherwise, the file to import
' *3+1: valid internal filename
' *3+2: internalsizedata when using directmemoryadding <IntData>
'           1xFlags pushes (copies) data directly, required if copying from package to package
'           1xFlag 4xPos 4xIntSize 4xExtSize as given with filelist-function
'       DO NOT copy from/to the same archive
'       or
'           1xFlags pushes (copies) data directly, required if copying from memory (packagedata!!!) to package
'           1xFlag 0000 4xIntSize 4xExtSize <InternalPackageData>
' MinimumCompress >100 => will always use compressed version, even if > 100%

'#ctPackage_Update_FlagA
'   1       = Reserved ctPackage_InternalUsage_EmptyHeader (Update, create, erase)
'   3   (2) = ctPackage_Update
'  11  (10) = ctPackage_Update_Create
'  21  (20) = ctPackage_Update_ErasePackage
'  40       = ctPackage_Update_ClearWaste
'  C0  (80) = ctPackage_Update_DestroyPackage (requires 40)
' 103 (100) = ctPackage_Update_AttacheFilesWrapper
' 203 (200) = ctPackage_Update_DeleteFilesProWrapper
' 403 (400) = ctPackage_Update_MergePackagesWrapper
' 803 (800) = ctPackage_Update_RenameFilesWrapper
'1000       = ctPackage_Update_CreateRawFileDataContent










#If (ctPackage_Update_FlagA And &H2&) = &H2& Then
  Public Enum ctPackage_IfExistsModes
    ctPackage_Exists_NoCheck = 0&
    ctPackage_Exists_Break = 1&
    ctPackage_Exists_Update = 2&
    ctPackage_Exists_Skip = 3&
    ctPackage_Exists_ExceptionError1 = 4&
    ctPackage_Exists_ExceptionStop = 5&
    ctPackage_Exists_ExceptionEnd = 6&
    ctPackage_Exists_ExceptionCrash = 7&
    End Enum
  Public Enum ctPackage_DoubleNewFilesModes
    ctPackage_DoubleNewFiles_NoCheck = 0&
    ctPackage_DoubleNewFiles_Break = 1&
    ctPackage_DoubleNewFiles_SkipFirst = 2&
    ctPackage_DoubleNewFiles_SkipLast = 3&
    ctPackage_DoubleNewFiles_ExceptionError1 = 4&
    ctPackage_DoubleNewFiles_ExceptionStop = 5&
    ctPackage_DoubleNewFiles_ExceptionEnd = 6&
    ctPackage_DoubleNewFiles_ExceptionCrash = 7&
    End Enum
  #End If

Private Const cByte1 As Byte = 1

Private Declare Function CreateFileA Lib "kernel32.dll" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function GetFileSize Lib "kernel32" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long
Private Declare Function SetFilePointer Lib "kernel32" (ByVal hFile As Long, ByVal lDistanceToMove As Long, lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long
Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As Any) As Long
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long

Private Declare Function LocalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal wBytes As Long) As Long
Private Declare Function LocalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function LocalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function LocalFree Lib "kernel32" (ByVal hMem As Long) As Long


#If (ctPackage_Update_FlagA And &H1&) = &H1& Then
  Private Function ctPackage_InternalUsage_EmptyHeader() As String
    ctPackage_InternalUsage_EmptyHeader = ctPackageConst_HeaderInfoText & String(ctPackageConst_HeaderEmptyNullsWidth, vbNullChar)
    End Function
  #End If

#If (ctPackage_Update_FlagA And &H3&) = &H3& Then
  Public Function ctPackage_Update( _
    ByVal ctPackagePointer As Long, _
    ByRef FilesExternInternOffsetArray() As String, _
    ByVal FileArrayCount As Long, _
    Optional ByVal DelFileOrNotByteStream As String, _
    Optional ByVal CanCompress As Boolean = True, _
    Optional ByVal BreakIfFileAccessError As Boolean = False, _
    Optional ByVal FileExistsHandling As ctPackage_IfExistsModes = ctPackage_Exists_Break, _
    Optional ByVal Reserved_DoubleAttacheFilesHandling As ctPackage_DoubleNewFilesModes = ctPackage_DoubleNewFiles_Break, _
    Optional ByVal ctPackagePointer_OutFile As Long, _
    Optional ByVal MinimumCompress As Long = ctPackage_MinimumCompressDefault, _
    Optional ByVal ProgressControl As Long = 0&) As Long



    Dim xFilenamesSize As Long
    Dim xFileNames As String
    Dim xDataSize As Long
    Dim xOldDataSize As Long
    Dim xTOC As String
    Dim xTOCNew As String
    Dim xDataPos As Long
    Dim xNewDataPos As Long
    Dim xLong3 As Long
    Dim xFileCount As Long
    Dim xLongA1(65535) As Long
    Dim xLongA2(65535) As Long
    'Dim xRemove As Long
    Dim xNewFlag As Long
    Dim xlong1 As Long
    Dim xLong2 As Long
    Dim xLong4 As Long
    Dim xLong6 As Long
    Dim xChar1 As String
    Dim xChar2 As String
    Dim xIsSameFile As Boolean
    
    Dim xLong5 As Long
    Dim xProgress1 As Long
    Dim xProgress2 As Long
    
    Dim ctPIType As ctPackage_InfoType
    Dim ctPITypeOut As ctPackage_InfoType
    
    Dim TempFileHandle As Long
    
'    Stop
    If ctPackage_GetInfoEx(ctPackagePointer, ctPIType) Then
      If Not ctPackagePointer_OutFile = 0& Then
        If Not ctPackage_GetInfoEx(ctPackagePointer_OutFile, ctPITypeOut) Then GoTo Lb2
        If (ctPITypeOut.FileHandle = ctPIType.FileHandle) Then
          If ctPITypeOut.FileHeader = ctPIType.FileHeader Then
            xIsSameFile = True
            Else
            GoTo Lb2
            End If
          End If
        Else
        ctPITypeOut = ctPIType
        xIsSameFile = True
        End If
      If ctPITypeOut.CanModify Then
        
        
        On Error GoTo Er1
        
        For xlong1 = FileArrayCount - 1& To 0& Step -1&
          If FilesExternInternOffsetArray(xlong1 * 3 + 2&) = "" Then
            If Left(FilesExternInternOffsetArray(xlong1 * 3&), 1&) = vbNullChar Then
              xLongA2(xlong1) = Len(FilesExternInternOffsetArray(xlong1 * 3&)) - 1&
              Else
              'If (GetAttr(FilesExternInternOffsetArray(xLong1 * 3&)) Mod 32&) \ 16& = 1& Then
              '  Error 1
              '  Else
              '  Open FilesExternInternOffsetArray(xLong1 * 3&) For Input As FileAccessFileID
              '  Close FileAccessFileID
              '  Open FilesExternInternOffsetArray(xLong1 * 3&) For Binary Access Read As FileAccessFileID
              '  xLongA2(xLong1) = LOF(FileAccessFileID)
              '  Close FileAccessFileID
              '  End If
              xLong5 = CreateFileA(FilesExternInternOffsetArray(xlong1 * 3&), &H80000000, &H1, ByVal 0&, 3&, &H20&, 0&)
              If xLong5 = -1& Then
                Error 75
                Else
                xLongA2(xlong1) = GetFileSize(xLong5, 0&)
                Call CloseHandle(xLong5)
                End If
              End If
            Else
            'xLongA2(xLong1) = LenCharToLong(FilesExternInternOffsetArray(xLong1 * 3 + 2&), 10&)
            xLongA2(xlong1) = LenCharToLong(FilesExternInternOffsetArray(xlong1 * 3 + 2&), ctPackageConst_GetFileList_PosIntSize7)
            'If Not xLongA2(xLong1) + 13& = Len(FilesExternInternOffsetArray(xLong1 * 3& + 2&)) Then Stop
            End If
Rs1:
          Next
        
        '''xLongA2(xLong1) = LenCharToLong(FilesExternInternOffsetArray(xLong1 * 3 + 1&), ctPackageConst_GetFileList_PosIntSize7)
        If CanCompress Then xNewFlag = 1&
        
        On Error GoTo 0
        xChar1 = String(ctPackageConst_HeaderSize, vbNullChar)
        
        
        
        'Get FileID, ctpitype.fileheader + 1&, xChar1
        If Not SetFilePointer(ctPIType.FileHandle, ctPIType.FileHeader, 0&, 0&) = -1& Then
          If Not ReadFile(ctPIType.FileHandle, ByVal xChar1, ctPackageConst_HeaderSize, 0&, ByVal 0&) = 0& Then
            ctPackage_Update = LenCharToLong(xChar1, ctPackageConst_HeaderPosFileCount + 1&)
            xFilenamesSize = LenCharToLong(xChar1, ctPackageConst_HeaderPosFileNames)
            xOldDataSize = LenCharToLong(xChar1, ctPackageConst_HeaderPosDataSize)
            
            
            'xDataPos = ctpitype.fileheader + ctPackageConst_HeaderSize + ctPackage_Update * ctPackageConst_TOCWidth + xFilenamesSize
            xTOC = String(ctPackage_Update * ctPackageConst_TOCWidth, vbNullChar)
            xFileNames = String(xFilenamesSize, vbNullChar)
            
            'Get FileID, ctpitype.fileheader + ctPackageConst_HeaderSize + 1, xTOC
            If Not ReadFile(ctPIType.FileHandle, ByVal xTOC, ctPackage_Update * ctPackageConst_TOCWidth, 0&, ByVal 0&) = 0& Then
            'Get FileID, , xFileNames
              If Not ReadFile(ctPIType.FileHandle, ByVal xFileNames, xFilenamesSize, 0&, ByVal 0&) = 0& Then
            
                TempFileHandle = -1&
                xDataPos = ctPIType.FileHeader + ctPackageConst_HeaderSize + ctPackage_Update * ctPackageConst_TOCWidth + xFilenamesSize
                xLong5 = xDataPos
                
            '    Stop
                'If Not (FileExistsHandling = ctPackage_Exists_NoCheck Or ctPackage_Update = 0&) And DelFileOrNotByteStream = String(Len(DelFileOrNotByteStream), vbNullChar) Then
                If Not ctPackage_Update = 0& Then
                  xChar1 = xFileNames
                  xFileNames = ""
                
                  
                  For xLong2 = 0& To ctPackage_Update - 1&
                    
                    xLong3 = LenCharToLong(xTOC, xLong2 * ctPackageConst_TOCWidth + ctPackageConst_TOCPosFileNameSize)
                    xLong4 = LenCharToLong(xTOC, xLong2 * ctPackageConst_TOCWidth + ctPackageConst_TOCPosIntSize)
                    xChar2 = UCase(Left(xChar1, xLong3))
                    
                    If Mid(DelFileOrNotByteStream, xLong2 + 1&, 1&) = Chr(1) Then
                      xChar2 = vbNullChar
                      Else
                    
                    
                    
                      For xlong1 = 0& To FileArrayCount - 1&
                        If UCase(FilesExternInternOffsetArray(xlong1 * 3& + 1&)) = xChar2 Then
                          Select Case FileExistsHandling
                            Case ctPackage_Exists_Break
                              Exit Function
                            Case ctPackage_Exists_Update
                              xChar2 = vbNullChar
                            Case ctPackage_Exists_Skip
                              For xLong6 = xlong1 * 3& To FileArrayCount * 3& - 4&
                                FilesExternInternOffsetArray(xLong6) = FilesExternInternOffsetArray(xLong6 + 3&)
                                Next
                              For xLong6 = xlong1 To FileArrayCount - 2&
                                xLongA2(xLong6) = xLongA2(xLong6 + 1&)
                                Next
                              FileArrayCount = FileArrayCount - 1&
                            Case ctPackage_Exists_ExceptionError1
                              Error 1
                              Exit Function
                            Case ctPackage_Exists_ExceptionStop
                              Stop
                            Case ctPackage_Exists_ExceptionEnd
                              End
                            Case ctPackage_Exists_ExceptionCrash
                              Stop
                              Stop
                              Stop
                            End Select
                          End If
                        Next
                      End If
                    
            '        Stop
                    If xChar2 = vbNullChar Then
                      ctPackage_Update = ctPackage_Update - 1&
                      Else
                      xDataSize = xDataSize + xLong4
                      xFileNames = xFileNames & Left(xChar1, xLong3)
                      xTOCNew = xTOCNew + Mid(xTOC, xLong2 * ctPackageConst_TOCWidth + 1&, ctPackageConst_TOCWidth)
                      If xFileCount = 0& Then
                        xLongA1(xFileCount * 2&) = xDataPos
                        xLongA1(xFileCount * 2& + 1&) = xLong4
                        xFileCount = xFileCount + 1&
                        Else
                        If xLongA1(xFileCount * 2& - 2&) + xLongA1(xFileCount * 2& - 1&) = xDataPos Then
                          xLongA1(xFileCount * 2& - 1&) = xLongA1(xFileCount * 2& - 1&) + xLong4
                          Else
                          xLongA1(xFileCount * 2&) = xDataPos
                          xLongA1(xFileCount * 2& + 1&) = xLong4
                          xFileCount = xFileCount + 1&
                          End If
                        End If
                      End If
                    xChar1 = Mid(xChar1, xLong3 + 1)
                    xDataPos = xDataPos + xLong4
                    Next
                  End If
                
            '    Stop
                xLong2 = xDataSize
                '''''''''xDataSize = xDataSize + xLongA2(xLong1)
                For xlong1 = 0& To FileArrayCount - 1&
                  ''''''xDataSize = xDataSize + xLongA2(xLong1)
                  xLong2 = xLong2 + xLongA2(xlong1)
                  xTOCNew = xTOCNew & vbNullChar & LenLongToChar(Len(FilesExternInternOffsetArray(xlong1 * 3& + 1&))) & _
                            String(4&, vbNullChar) & _
                            LenLongToChar(xLongA2(xlong1))
                  xFileNames = xFileNames & FilesExternInternOffsetArray(xlong1 * 3& + 1&)
                  Next
                '''xNewFileCount = ctPackage_update + FileArrayCount
                'ctPackage_update = ctPackage_update + FileArrayCount
                xNewDataPos = ctPITypeOut.FileHeader + ctPackageConst_HeaderSize + (ctPackage_Update + FileArrayCount) * ctPackageConst_TOCWidth + Len(xFileNames)
                
                xChar1 = ctPackage_InternalUsage_EmptyHeader
                
                
                
                If Not SetFilePointer(ctPITypeOut.FileHandle, ctPITypeOut.FileHeader, 0&, 0&) = -1& Then
                  'Put OutFileID, ctPITypeOut.FileHeader + 1&, xChar1
                  If Not WriteFile(ctPITypeOut.FileHandle, ByVal xChar1, ctPackageConst_HeaderSize, 0&, ByVal 0&) = 0& Then
                    'If xDataSize > xOldDataSize Then
                    
                    If xIsSameFile Then
                      'xOldDataSize = LOF(OutFileID) - ctPackageConst_EndSize
                      xOldDataSize = GetFileSize(ctPITypeOut.FileHandle, 0&) '- ctPackageConst_EndSize
                      End If
                    
                    'If xLong2 > xOldDataSize - xLong5 Or NoClearWaste Then
                      xProgress2 = xLong2 'xDataSize
                    '  Else
                    '  xProgress2 = xOldDataSize - xNewDataPos 'xLong5
                    '  End If
                        
                    
                    'xLong5 = xNewDataPos
                    For xLong4 = 0& To xFileCount - 1&
                      'If xLong5 <= xLongA1(xLong4 * 2&) Then
                      If xNewDataPos <= xLongA1(xLong4 * 2&) Then
                        Exit For
                        End If
                      'xLong5 = xLong5 + xLongA1(xLong4 * 2& + 1&)
                      xNewDataPos = xNewDataPos + xLongA1(xLong4 * 2& + 1&)
                      Next
                    
                    'For xLong1 = xLong4 To xFileCount - 1&
                    '  xNewDataPos = xNewDataPos + xLongA1(xLong1 * 2& + 1&)
                    '  Next
                    
                    'xLong2 = xNewDataPos
                    xLong2 = xNewDataPos
                    For xlong1 = xLong4 - 1& To 0& Step -1&
                      xLong3 = xLongA1(xlong1 * 2& + 1&)
                      xLong2 = xLong2 - xLong3
                      'xLong5 = xLong5 - xLong3
                    
                      Call BinaryMoveFileDataEx(ctPIType.FileHandle, xLong3, xLongA1(xlong1 * 2&), xLong2, ctPITypeOut.FileHandle, ctPackage_DefaultBlockSize, ProgressControl, xProgress1, xProgress2)
                    '  xDataSize = xDataSize + xLong3
                      xProgress1 = xProgress1 + xLong3
                      Next
                '    Stop
                    For xlong1 = xLong4 To xFileCount - 1&
                      xLong3 = xLongA1(xlong1 * 2& + 1&)
                      'Call BinaryMoveFileData(FileID, xLong3, xLongA1(xLong1 * 2&), xLong5, -1&,  ctPackage_DefaultBlockSize, ProgressControl, xProgress1, xProgress2)
                      Call BinaryMoveFileDataEx(ctPIType.FileHandle, xLong3, xLongA1(xlong1 * 2&), xNewDataPos, ctPITypeOut.FileHandle, ctPackage_DefaultBlockSize, ProgressControl, xProgress1, xProgress2)
                      xProgress1 = xProgress1 + xLong3
                    '  xDataSize = xDataSize + xLong3
                    '  xProgress1 = xProgress1 + xLong3
                      'xLong5 = xLong5 + xLong3
                      xNewDataPos = xNewDataPos + xLong3
                      Next
                    
                '    Stop
                    'xProgress1 = xOldDataSize
                    'xNewDataPos = xLong5
                    
                    'xLongA2(xLong1) = LenCharToLong(FilesExternInternOffsetArray(xLong1 * 3 + 1&), ctPackageConst_GetFileList_PosIntSize7)
                    
                    For xlong1& = 0& To FileArrayCount - 1&
                    
                    
'                      Stop
                      xLong5 = xLongA2(xlong1)
                      If xLongA2(xlong1) = 0& Then
                        xLong4 = 0& 'xNewFlag And Not 1&
                        Else
                        
                    '      xChar1 = Mid(FilesExternInternOffsetArray(xLong1 * 3&), 2&)
                        If Not FilesExternInternOffsetArray(xlong1 * 3&) = "" Then
                          If Not Left(FilesExternInternOffsetArray(xlong1 * 3&), 1&) = vbNullChar Then
                            If Not TempFileHandle = -1& Then
                              Call CloseHandle(TempFileHandle)
                              End If
                            'Close FileAccessFileID
                            'Open FilesExternInternOffsetArray(xLong1 * 3&) For Input As FileAccessFileID
                            'Close FileAccessFileID
                            'Open FilesExternInternOffsetArray(xLong1 * 3&) For Binary Access Read As FileAccessFileID
                            TempFileHandle = CreateFileA(FilesExternInternOffsetArray(xlong1 * 3&), &H80000000, &H1, ByVal 0&, 3&, &H20&, 0&)
                            If TempFileHandle = -1& Then
                              Error 75
                              'Else
                              'xLongA2(xLong1) = GetFileSize(xLong5, 0&)
                              'Call CloseHandle(xLong5)
                              End If
                            
                            End If
                          End If
                          
                        If FilesExternInternOffsetArray(xlong1 * 3& + 2&) = "" Then
                          If xNewFlag = 0& Then
                            If Left(FilesExternInternOffsetArray(xlong1 * 3&), 1&) = vbNullChar Then
                              xChar1 = Mid(FilesExternInternOffsetArray(xlong1 * 3&), 2&)
                              'Put OutFileID, xNewDataPos + 1&, xChar1
                              If SetFilePointer(ctPITypeOut.FileHandle, xNewDataPos, 0&, 0&) = -1& Then
                                Error 57
                                ElseIf WriteFile(ctPITypeOut.FileHandle, ByVal xChar1, Len(xChar1), 0&, ByVal 0&) = 0& Then
                                Error 61 '?
                                End If
                              
                              Else
                              Call BinaryMoveFileDataEx(TempFileHandle, xLongA2(xlong1), 0&, xNewDataPos, ctPITypeOut.FileHandle, ctPackage_DefaultBlockSize, ProgressControl, xProgress1, xProgress2)
                              End If
                            xLong4 = 0&
                            Else
                            xLong4 = xNewFlag
                            If Left(FilesExternInternOffsetArray(xlong1 * 3&), 1&) = vbNullChar Then
                              xChar1 = Mid(FilesExternInternOffsetArray(xlong1 * 3&), 2&)
                              Else
                              xChar1 = String(xLongA2(xlong1), vbNullChar)
                              'Get FileAccessFileID, 1&, xChar1
                              If ReadFile(ctPIType.FileHandle, ByVal xChar1, xLongA2(xlong1), 0&, ByVal 0&) = 0& Then
                                Error 75
                                'Else
                                End If
                              End If
                          
                            If CanCompress Then
                              xChar2 = ctCompressA_Compress(xChar1, ProgressControl, xProgress1, xProgress2, xLongA2(xlong1))
                              xLong4 = Len(xChar2)
                              If xLong4 < MinimumCompress / 100& * xLongA2(xlong1) Or MinimumCompress > 100& Then
                                xChar1 = xChar2
                                xLongA2(xlong1) = xLong4
                                xLong4 = xNewFlag
                                Else
                                xLong4 = xNewFlag And Not 1&
                                End If
                              Else
                              xLong4 = xNewFlag
                              End If
                              
                            'Put OutFileID, xNewDataPos + 1&, xChar1
                            If SetFilePointer(ctPITypeOut.FileHandle, xNewDataPos, 0&, 0&) = -1& Then
                              Error 57
                              ElseIf WriteFile(ctPITypeOut.FileHandle, ByVal xChar1, Len(xChar1), 0&, ByVal 0&) = 0& Then
                              Error 61 '?
                              End If
                            End If
                            
                            
                          Else
                          xLong6 = LenCharToLong(FilesExternInternOffsetArray(xlong1 * 3 + 2&), 2&)
                          If xLong6 = 0& Then
                            xChar1 = Mid(FilesExternInternOffsetArray(xlong1 * 3 + 2&), 14&)
                            'Put OutFileID, xNewDataPos + 1&, xChar1
                            If SetFilePointer(ctPITypeOut.FileHandle, xNewDataPos, 0&, 0&) = -1& Then
                              Error 57
                              ElseIf WriteFile(ctPITypeOut.FileHandle, ByVal xChar1, Len(xChar1), 0&, ByVal 0&) = 0& Then
                              Error 61 '?
                              End If
                            Else
                            Call BinaryMoveFileDataEx(TempFileHandle, xLongA2(xlong1), LenCharToLong(FilesExternInternOffsetArray(xlong1 * 3 + 2&), 2&), xNewDataPos, ctPITypeOut.FileHandle, ctPackage_DefaultBlockSize, ProgressControl, xProgress1, xProgress2)
                            End If
                          xLong4 = Asc(Left(FilesExternInternOffsetArray(xlong1 * 3 + 2&), 1&))
                          xTOCNew = Left(xTOCNew, (ctPackage_Update + xlong1) * ctPackageConst_TOCWidth + ctPackageConst_TOCOverWriteExtSizePos) & _
                                    Mid(FilesExternInternOffsetArray(xlong1 * 3 + 2&), ctPackageConst_GetFileList_PosExtSize7, 4&) & _
                                    Mid(xTOCNew, (ctPackage_Update + xlong1) * ctPackageConst_TOCWidth + ctPackageConst_TOCOverWriteExtSizePosRs)
                    '      xLong5 = LenCharToLong(FilesExternInternOffsetArray(xLong1 * 3 + 2&), ctPackageConst_TOCParamPosExtSize)
                          End If
                          
                        xDataSize = xDataSize + xLongA2(xlong1)
                        End If
                      xTOCNew = Left(xTOCNew, (ctPackage_Update + xlong1) * ctPackageConst_TOCWidth) & _
                                Chr(xLong4) & _
                                Mid(xTOCNew, (ctPackage_Update + xlong1) * ctPackageConst_TOCWidth + ctPackageConst_TOCPWSecondStart, ctPackageConst_TOCPWSecondWidth) & _
                                LenLongToChar(xLongA2(xlong1)) & _
                                Mid(xTOCNew, (ctPackage_Update + xlong1) * ctPackageConst_TOCWidth + ctPackageConst_TOCPosLast)
                    '  xTOCNew = Left(xTOCNew, (ctPackage_Update + xLong1) * ctPackageConst_TOCWidth) & _
                    '            Chr(xLong4) & _
                    '            Mid(xTOCNew, (ctPackage_Update + xLong1) * ctPackageConst_TOCWidth + ctPackageConst_TOCPWSecondStart, ctPackageConst_TOCPWSecondWidth) & _
                    '            LenLongToChar(xLong5) & _
                    '            Mid(xTOCNew, (ctPackage_Update + xLong1) * ctPackageConst_TOCWidth + ctPackageConst_TOCPosLast)
                      
                      'xDataSize = xDataSize + xLongA2(xLong1)
                      xNewDataPos = xNewDataPos + xLongA2(xlong1)
                      xProgress1 = xProgress1 + xLong5 'xLongA2(xLong1) ' + 1&)
                      ctProgressB_SetValue ProgressControl, xProgress1, xProgress2
                      DoEvents
                      
                      
                      
                      
                      
                    ''''''''''''''''''''''''''''''''  If xAbort Then Exit Function
                      Next
                    
                    If Not TempFileHandle = -1& Then
                      Call CloseHandle(TempFileHandle)
                      End If
                    'Close FileAccessFileID
                    'Stop
                    'If xOldDataSize > xNewDataPos And Not NoClearWaste Then
                      'Call BinaryClearFileData(OutFileID, xNewDataPos, xOldDataSize - xNewDataPos, ctPackage_DefaultBlockSize, ProgressControl, xProgress1, xProgress2)
                    '  Stop
                    '  End If
                    
                    
'                    Stop
                    'xChar1 = ctPackageConst_HeaderInfoText & LenLongToChar(ctPackage_Update + FileArrayCount) & LenLongToChar(Len(xFileNames)) & LenLongToChar(xDataSize) & xTOCNew & xFileNames
                    ctPackage_Update = ctPackage_Update + FileArrayCount
                    xChar1 = ctPackageConst_HeaderInfoText & LenLongToChar(ctPackage_Update) & LenLongToChar(Len(xFileNames)) & LenLongToChar(xDataSize) & xTOCNew & xFileNames
                    'Put OutFileID, ctPIType.FileHeader + 1&, xChar1
                    If SetFilePointer(ctPITypeOut.FileHandle, ctPIType.FileHeader, 0&, 0&) = -1& Then
                      Error 57
                      ElseIf WriteFile(ctPITypeOut.FileHandle, ByVal xChar1, Len(xChar1), 0&, ByVal 0&) = 0& Then
                      Error 61 '?
                      End If
                    
'                    Stop
                    xChar1 = ctPackageConst_EndSizeText1 & LenLongToChar(ctPITypeOut.FileHeader) & ctPackageConst_EndSizeText2
                    'xLong1 = LOF(OutFileID) - ctPackageConst_EndSize
                    'If xLong1 > xNewDataPos Then 'Or NoClearWaste Then
                    '  Put OutFileID, xLong1 + 1&, xChar1
                    '  Else
                    '  Put OutFileID, xNewDataPos + 1&, xChar1
                    '  End If
                    'If SetFilePointer(ctPITypeOut.FileHandle, GetFileSize(ctPITypeOut.FileHandle, 0&), 0&, 0&) = -1& Then
'                    Stop
                    If SetFilePointer(ctPITypeOut.FileHandle, xNewDataPos, 0&, 0&) = -1& Then
                      Error 57
                      ElseIf WriteFile(ctPITypeOut.FileHandle, ByVal xChar1, ctPackageConst_EndSize, 0&, ByVal 0&) = 0& Then
                      Error 61 '?
                      End If
                    If xOldDataSize > xNewDataPos + ctPackageConst_EndSize And xIsSameFile Then
                      Stop
                      End If
Lb1:
                    On Error GoTo 0
                    'Close FileAccessFileID
                  
                    End If
                  End If
                End If
              End If
            End If
          End If
        End If
      End If
Lb2:
    
    
    
    
    
    
    
    
    
    Exit Function
    
Er1:
    If BreakIfFileAccessError Then
      Resume Lb1
      Else
     ' For xLong2 = xLong1 To FileArrayCount - 3&
     '   FilesExternInternOffsetArray(xLong2 * 3&) = FilesExternInternOffsetArray(xLong2 * 3& + 3&)
     '   FilesExternInternOffsetArray(xLong2 * 3& + 1&) = FilesExternInternOffsetArray(xLong2 * 3& + 4&)
     '   FilesExternInternOffsetArray(xLong2 * 3& + 2&) = FilesExternInternOffsetArray(xLong2 * 3& + 5&)
     '   FileArrayCount = FileArrayCount - 1&
     '   Next
    '              For xLong5 = xLong1 * 3& To FileArrayCount * 3& - 4&
      For xLong2 = xlong1 * 3& To FileArrayCount * 3& - 4&
        FilesExternInternOffsetArray(xLong2) = FilesExternInternOffsetArray(xLong2 + 3&)
        Next
      
      For xLong2 = xlong1 To FileArrayCount - 2&
        xLongA2(xLong2) = xLongA2(xLong2 + 1&)
        Next
      Resume Rs1
      End If
    End Function
  #End If



#If (ctPackage_Update_FlagA And &H11&) = &H11& Then
  Public Function ctPackage_Update_Create(ByVal FileName As String, ByRef ctPackagePointer As Long, Optional ByVal CanUseExisting As Boolean = True) As Boolean
    Dim xlong1 As Long
    Dim xChar1 As String
    Dim ctPIType As ctPackage_InfoType

    'Stop
    ctPackage_Update_Create = ctPackage_Open(FileName, ctPackagePointer, True)
    If Not ctPackage_Update_Create Then
      'ctPackage_Update_Create = LOF(FileID)
      ctPIType.FileHandle = CreateFileA(FileName, &HC0000000, &H1, ByVal 0&, 3&, &H20&, 0&)
      If ctPIType.FileHandle = -1& Then
        xlong1 = 0&
        'Stop
        Else
        'Stop
        xlong1 = GetFileSize(ctPIType.FileHandle, 0&)
        
        End If
      If Not ctPIType.FileHandle = -1& Then
        xChar1 = ctPackage_InternalUsage_EmptyHeader & ctPackageConst_EndSizeText1 & LenLongToChar(xlong1) & ctPackageConst_EndSizeText2
        If Not SetFilePointer(ctPIType.FileHandle, xlong1, 0&, 0&) = -1& Then
          'Put FileID, ctPackage_Update_Create + 1&, xChar1
          If Not WriteFile(ctPIType.FileHandle, ByVal xChar1, ctPackageConst_HeaderSize + ctPackageConst_EndSize, 0&, ByVal 0&) = 0& Then
            ctPackagePointer = LocalAlloc(0&, ctPackage_InfoTypeSize)
            If Not ctPackagePointer = 0& Then
              xlong1 = LocalLock(ctPackagePointer)
              If xlong1 = 0& Then
                Call LocalFree(ctPackagePointer)
                ctPackagePointer = 0&
                Else
                ctPIType.CanModify = cByte1
                Call RtlMoveMemory(ByVal xlong1, ctPIType, ctPackage_InfoTypeSize)
                Call LocalUnlock(ctPackagePointer)
                ctPackage_Update_Create = True
                End If
              End If
            End If
          End If
        If Not ctPackage_Update_Create Then
          Call CloseHandle(ctPIType.FileHandle)
          End If
        End If
      Else
      If Not CanUseExisting Then
        If Not ctPackage_GetFileCount(ctPackagePointer) = 0& Then
          ctPackage_Update_Create = False
          End If 'ctPackage_Update_Create = True
        End If
      End If
    End Function
  #End If

  
#If (ctPackage_Update_FlagA And &H40&) = &H40& Then
  Public Function ctPackage_Update_ClearWaste(ByVal ctPackagePointer As Long, ByVal NewOrOverwriteFileName As String, Optional ByVal TempFileAccessID As Long = -1&, Optional ByVal TempFileName As String, Optional ByVal ProgressControl As Long = 0&) As Boolean
    'Dim xLong1 As Long
    'Dim xChar1 As String
    Dim ctPIType As ctPackage_InfoType
    
    If ctPackage_GetInfoEx(ctPackagePointer, ctPIType) Then
      Stop
'    If Not ctPIType.FileHandle = -1& Then
'      Stop
      'xChar1 = String(ctPackageConst_HeaderSize, vbNullChar)
      'If Not SetFilePointer(ctPIType.FileHandle, ctPIType.FileHeader - ctPackageConst_EndSizeMinus, 0&, 0&) = -1& Then
      '  If Not ReadFile(ctPIType.FileHandle, ByVal xChar1, Len(xChar1), 0&, ByVal 0&) = 0& Then
      '    'Get FileID, ctpitype.fileheader + 1&, xChar1
      '    xLong1 = ctpitype.fileheader + ctPackageConst_HeaderSize + _
      '                LenCharToLong(xChar1, ctPackageConst_HeaderPosFileCount + 1&) * ctPackageConst_TOCWidth + _
      '                LenCharToLong(xChar1, ctPackageConst_HeaderPosFileNames) + _
      '                LenCharToLong(xChar1, ctPackageConst_HeaderPosDataSize)
      '    xChar1 = ctPackageConst_EndSizeText1 & LenLongToChar(ctpitype.fileheader) & ctPackageConst_EndSizeText2
      '    Put FileID, xLong1 + 1&, xChar1
      '    ctPackage_Update_ClearWaste = ctPackage_Update_DestroyPackage(FileID, xLong1 + ctPackageConst_EndSize, NewOrOverwriteFileName, TempFileAccessID, TempFileName, ProgressControl)
      '    Close FileID
      '    Open NewOrOverwriteFileName For Binary Lock Read Write As FileID
      '    End If
      '  End If
      End If
    End Function
  #End If

#If (ctPackage_Update_FlagA And &H21&) = &H21& Then
  Public Function ctPackage_Update_ErasePackage(ByVal ctPackagePointer As Long, Optional ByVal ProgressControl As Long = 0&) As Long
    Dim xChar1 As String
    Dim xlong1 As Long
    Dim xLong2 As Long
    Dim xLong3 As Long
    
    Stop
    'xChar1 = ctPackage_InternalUsage_EmptyHeader
    'Put FileID, ctpitype.fileheader + 1&, xChar1
    'xLong1 = LOF(FileID) - ctPackageConst_EndSize - 1&
    'xLong2 = ctpitype.fileheader + ctPackageConst_HeaderSize
    'xLong3 = xLong1 - xLong2
    'If xLong3 > 0 Then
    '  Call BinaryClearFileData(FileID, xLong2, xLong3, ctPackage_DefaultBlockSize, ProgressControl, 0&, xLong3)
    '  End If
    End Function
  #End If

#If (ctPackage_Update_FlagA And &HC0&) = &HC0& Then
  Public Function ctPackage_Update_DestroyPackage(ByRef ctPackagePointer As Long, ByVal NewOrOverwriteFileName As String, Optional ByVal TempFileAccessID As Long = -1&, Optional ByVal TempFileName As String, Optional ByVal ProgressControl As Long = 0&) As Boolean
    'Dim xLong1 As Long
    
    Dim ctPIType As ctPackage_InfoType
    
    If ctPackage_GetInfoEx(ctPackagePointer, ctPIType) Then
      Stop
      'Close FileID
      'Kill NewOrOverwriteFileName
      'ctPackage_Update_DestroyPackage = True
      'ElseIf Not ctpitype.fileheader = -1& Then
      'If TempFileName = "" Then
'     '   Stop
      '  xLong1 = InStrRev(NewOrOverwriteFileName, ".")
      '  If xLong1 > InStrRev(NewOrOverwriteFileName, "\", 1&, 1&) Then
      '    TempFileName = Left(NewOrOverwriteFileName, xLong1 - 1) & ".TMP"
      '    Else
      '    Exit Function
      '    End If
      '  End If
'     ' Stop
      'If TempFileAccessID = -1& Or TempFileAccessID = FileID Then
      '  TempFileAccessID = FreeFile
      '  End If
      'Close TempFileAccessID
      'Open TempFileName For Output As TempFileAccessID
      'Close TempFileAccessID
      'Open TempFileName For Binary Access Read Write As TempFileAccessID
      'Call BinaryMoveFileDataEx(FileID, ctpitype.fileheader, 0&, 0&, TempFileAccessID, BinaryMoveFileData_NullstringNew, ctPackage_DefaultBlockSize, ProgressControl, 0&, ctpitype.fileheader - 1&)
      'Close TempFileAccessID
      'Close FileID
      'On Error Resume Next
      'Kill NewOrOverwriteFileName
      'On Error GoTo 0
      'Name TempFileName As NewOrOverwriteFileName
      'ctPackage_Update_DestroyPackage = True
      End If
    End Function
  #End If




#If (ctPackage_Update_FlagA And &H103&) = &H103& Then
  Public Function ctPackage_Update_AttacheFilesWrapper( _
    ByVal ctPackagePointer As Long, _
    ByRef FilesExternInternArray() As String, _
    ByVal FileArrayCount As Long, _
    Optional ByVal Compress As Boolean = True, _
    Optional ByVal BreakIfFileAccessError As Boolean = False, _
    Optional ByVal FileExistsHandling As ctPackage_IfExistsModes = ctPackage_Exists_Break, _
    Optional ByVal Reserved_DoubleAttacheFilesHandling As ctPackage_DoubleNewFilesModes = ctPackage_DoubleNewFiles_Break, _
    Optional ByVal ctPackagePointer_OutFile As Long, _
    Optional ByVal MinimumCompress As Long = ctPackage_MinimumCompressDefault, _
    Optional ByVal ProgressControl As Long = 0&) As Long
    
    Dim xlong1 As Long
    Dim xCharA1() As String
    
    ReDim xCharA1(FileArrayCount * 3& - 1&)
    For xlong1 = 0& To FileArrayCount - 1&
      xCharA1(xlong1 * 3&) = FilesExternInternArray(xlong1 * 2&)
      xCharA1(xlong1 * 3& + 1&) = FilesExternInternArray(xlong1 * 2& + 1&)
      Next
    
    ctPackage_Update_AttacheFilesWrapper = ctPackage_Update(ctPackagePointer, xCharA1(), FileArrayCount, "", Compress, BreakIfFileAccessError, FileExistsHandling, Reserved_DoubleAttacheFilesHandling, ctPackagePointer_OutFile, MinimumCompress, ProgressControl)
    End Function
  #End If


#If (ctPackage_Update_FlagA And &H203&) = &H203& Then
  Public Function ctPackage_Update_DeleteFilesProWrapper(ByVal ctPackagePointer As Long, ByVal DelFileOrNotByteStream As String, Optional ByVal ProgressControl As Long = 0&) As Long
    Dim xCharA1(0) As String
    
    ctPackage_Update_DeleteFilesProWrapper = ctPackage_Update(ctPackagePointer, xCharA1(), 0&, DelFileOrNotByteStream, False, False, ctPackage_Exists_NoCheck, , , , ProgressControl)
    End Function
  #End If


#If (ctPackage_Update_FlagA And &H403&) = &H403& And False Then
  Public Function ctPackage_Update_MergePackagesWrapper( _
    ByVal ctPackagePointer As Long, _
    ByVal FileToMergeFileName As String, _
    Optional ByVal FileToMergeOrNotByteStream As String, _
    Optional ByVal SourceDelFileOrNotByteStream As String, _
    Optional ByVal Reserved_ReCompress As Boolean = False, _
    Optional ByVal BreakIfFileAccessError As Boolean = False, _
    Optional ByVal FileExistsHandling As ctPackage_IfExistsModes = ctPackage_Exists_Break, _
    Optional ByVal Reserved_DoubleAttacheFilesHandling As ctPackage_DoubleNewFilesModes = ctPackage_DoubleNewFiles_Break, _
    Optional ByVal ctPackagePointer_OutFile As Long, _
    Optional ByVal MinimumCompress As Long = ctPackage_MinimumCompressDefault, _
    Optional ByVal ProgressControl As Long = 0&) As Long

    Dim xlong1 As Long
    Dim xLong2 As Long
    Dim xLong3 As Long
    Dim xCharA1(65535) As String
    
    ctPackage_Update_MergePackagesWrapper = -1&
    
    Dim FileAccessFileID As Long
    FileAccessFileID = FreeFile
    
    On Error GoTo Er1
    Close FileAccessFileID
    Open FileToMergeFileName For Input As FileAccessFileID
    Close FileAccessFileID
    Open FileToMergeFileName For Binary Access Read Lock Write As FileAccessFileID
    xlong1 = ctPackage_GetHeaderPos(FileAccessFileID)
    On Error GoTo 0
    If Not xlong1 = -1& Then
      xLong2 = ctPackage_GetFileList(FileAccessFileID, xlong1, xCharA1(), 65535, , 3&, 2&)
      ctPackage_Update_MergePackagesWrapper = 0&
      If Not xLong2 = 0& Then
        If FileToMergeOrNotByteStream = "" Then
          FileToMergeOrNotByteStream = String(xLong2, Chr(1&))
          End If
        Close FileAccessFileID
        xCharA1(0) = FileToMergeFileName
        For xLong2 = 0& To xLong2 - 1&
    '      Stop
          If Mid(FileToMergeOrNotByteStream, xLong2 + 1&, 1&) = Chr(1&) Then
            xCharA1(xLong3 * 3& + 1&) = Mid(xCharA1(xLong2 * 3& + 2&), ctPackageConst_GetFileList_PosFilename7)
            xCharA1(xLong3 * 3& + 2&) = Left(xCharA1(xLong2 * 3& + 2&), ctPackageConst_GetFileList_PWParams7)
            'Stop
            xLong3 = xLong3 + 1&
            End If
          Next
    '    Stop
        If Not xLong3 = 0& Then
          ctPackage_Update_MergePackagesWrapper = ctPackage_Update(ctPackagePointer, xCharA1(), xLong3, SourceDelFileOrNotByteStream, Reserved_ReCompress, BreakIfFileAccessError, FileExistsHandling, Reserved_DoubleAttacheFilesHandling, ctPackagePointer_OutFile, MinimumCompress, ProgressControl)
          End If
        End If
      End If
    
Rs1:
    On Error GoTo 0
    Close FileAccessFileID
    Exit Function
    
Er1:
    Resume Rs1
    End Function
  #End If




#If (ctPackage_Update_FlagA And &H1000&) = &H1000& Then
  Public Function ctPackage_Update_CreateRawFileDataContent(ByVal RawData As String, Optional ByVal CanCompress As Boolean = True, Optional ByVal MinimumCompress As Long = ctPackage_MinimumCompressDefault, Optional ByVal ProgressControl As Long = 0&, Optional ByVal ProgressStart As Long = 0&, Optional ByVal ProgressTotal As Long = 0&, Optional ByVal ProgressQueue As Long = 0&) As String
    
    Dim NewFlag As Long
    Dim xChar1 As String
    Dim xlong1 As Long
    Dim xLong2 As Long
    
    xlong1 = Len(RawData)
    If CanCompress Then
      xChar1 = ctCompressA_Compress(RawData, ProgressControl, ProgressStart, ProgressTotal, ProgressQueue)
      xLong2 = Len(xChar1)
      If xLong2 < MinimumCompress / 100& * xlong1 Or MinimumCompress > 100& Then
        RawData = xChar1
        NewFlag = 1&
        Else
        xLong2 = xlong1
        End If
      Else
      xLong2 = xlong1
      End If
    
    ctPackage_Update_CreateRawFileDataContent = Chr(NewFlag) & String(4, vbNullChar) & LenLongToChar(xLong2) & LenLongToChar(xlong1) & RawData
    End Function
  #End If

#If (ctPackage_Update_FlagA And &H803&) = &H803& Then
  'ctPackage_Update_RenameFilesWrapper(xCharA1(), xLong2 \ 2&, , , hWndProgress)
  Public Function ctPackage_Update_RenameFilesWrapper(ByVal ctPackagePointer As Long, ByRef RenamingArray() As String, ByVal RenamingArrayCount As Long, Optional ByVal Unknown1 As Long, Optional ByVal Unknown2 As Long, Optional ByVal ProgressControl As Long) As Long
    'Dim xCharA1(0) As String
    Stop
    'ctPackage_Update_RenameFilesWrapper = ctPackage_Update(ctPackagePointer,  xCharA1(), 0&, DelFileOrNotByteStream, False, False, ctPackage_Exists_NoCheck, , , , ProgressControl)
    End Function
  #End If

