EnglishРусский  

   ..

   cab.g

   cab2g.dll

   cabdecode.g

   cabdemo.g

   cab-x.g

The project is closed! You can look at a new scripting language. It is available on GitHub.
Also, try our open source cross-platform automation software.

Ads

Installer and installation software
Commercial and Freeware installers.

source\lib\cab\cabdecode.g
  1 /******************************************************************************
  2 *
  3 * Copyright (C) 2009, The Gentee Group. All rights reserved. 
  4 * This file is part of the Gentee open source project - http://www.gentee.com. 
  5 * 
  6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT"). 
  7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS 
  8 * ACCEPTANCE OF THE AGREEMENT.
  9 *
 10 * Author: Alexey Krivonogov ( gentee )
 11 *
 12 ******************************************************************************/
 13 
 14 define
 15 {
 16    FDIERROR_NONE = 0
 17    FDIERROR_CABINET_NOT_FOUND
 18    FDIERROR_NOT_A_CABINET
 19    FDIERROR_UNKNOWN_CABINET_VERSION
 20    FDIERROR_CORRUPT_CABINET
 21    FDIERROR_ALLOC_FAIL
 22    FDIERROR_BAD_COMPR_TYPE
 23    FDIERROR_MDI_FAIL
 24    FDIERROR_TARGET_FILE
 25    FDIERROR_RESERVE_MISMATCH
 26    FDIERROR_WRONG_CABINET
 27    FDIERROR_USER_ABORT
 28 }
 29 
 30 type FDINOTIFICATION
 31 {
 32     uint      cb
 33     uint      psz1
 34     uint      psz2
 35     uint      psz3
 36     uint      pv
 37     uint      hf
 38     ushort    date
 39     ushort    time
 40     ushort    attribs
 41     ushort    setID
 42     ushort    iCabinet
 43     ushort    iFolder
 44     uint      fdie
 45 }
 46 
 47 type FDICABINETINFO 
 48 {
 49     uint        cbCabinet              // Total length of cabinet file
 50     ushort      cFolders               // Count of folders in cabinet
 51     ushort      cFiles                 // Count of files in cabinet
 52     ushort      setID                  // Cabinet set ID
 53     ushort      iCabinet               // Cabinet number in set (0 based)
 54     uint        fReserve               // TRUE => RESERVE present in cabinet
 55     uint        hasprev                // TRUE => Cabinet is chained prev
 56     uint        hasnext                // TRUE => Cabinet is chained next
 57 }
 58 
 59 type decabinfo
 60 {
 61    ERF            erf
 62    FDICABINETINFO fdic
 63    uint     call
 64    uint     islist
 65    uint     fncnotify
 66    uint     fncsysnotify
 67    uint     hf
 68    str      destfile
 69    uint     percent
 70    uint     cursize
 71    uint     fileinfo
 72    str      nextvolume
 73    str      destdir
 74    uint     param
 75 }
 76 
 77 
 78 func uint decab_notify( uint code, str param, decabinfo decab )
 79 {
 80    return 0
 81 }
 82 
 83 func uint decab_sysnotify( uint code, uint param, decabinfo decab )
 84 {
 85    str      stemp
 86    filetime lft
 87    uint     fdin
 88    
 89    fdin as param->FDINOTIFICATION
 90    switch code
 91    {
 92       case $FLN_NEXTVOLUME
 93       { 
 94          if !*decab.nextvolume : decab.nextvolume.copy( fdin.psz1 )
 95        }
 96       case $FLN_FILEBEGIN
 97       {
 98          uint item 
 99          
100          if decab.islist
101          {  
102             uint files = decab.fileinfo
103             files as arr of finfo
104             item as files[ files.expand(1) ]
105          }
106          else : item = decab.fileinfo
107          
108          item as finfo
109         
110          item.fullname.copy( fdin.psz1 )
111          item.name.fnameext( item.fullname )
112          item.attrib = fdin.attribs
113          item.sizelo = fdin.cb
114          DosDateTimeToFileTime( fdin.date, fdin.time, lft )
115          LocalFileTimeToFileTime( lft, item.lastwrite )
116          if decab.islist : return 0
117          ( decab.destfile = decab.destdir ).faddname( item.fullname )
118          return decab.fncnotify->func( $FLN_FILEBEGIN, decab.destfile, decab )
119       }
120       case $FLN_FILEEND
121       {
122          file fi
123          
124          setattribnormal( decab.destfile )
125          fi.open( decab.destfile, 0 )
126          fi.settime( decab.fileinfo->finfo.lastwrite )
127          fi.close()     
128          setfileattrib( decab.destfile, fdin.attribs )
129          decab.fncnotify->func( $FLN_FILEEND, decab.destfile, decab )
130          return 1
131       }
132       default : stemp.copy( param )
133    }
134    return decab.fncnotify->func( code, stemp, decab )
135 }
136 
137 
138 func decab_error( decabinfo decab, str prefix )
139 {
140    str strerr
141    
142    switch decab.erf.erfOper
143 	{
144    	case $FDIERROR_NONE: strerr =  "No error"
145 		case $FDIERROR_CABINET_NOT_FOUND:	strerr =  "Cabinet not found"
146 		case $FDIERROR_NOT_A_CABINET:	strerr =  "Not a cabinet"
147 		case $FDIERROR_UNKNOWN_CABINET_VERSION:	strerr =  "Unknown cabinet version"
148 		case $FDIERROR_CORRUPT_CABINET: strerr =  "Corrupt cabinet"
149 		case $FDIERROR_ALLOC_FAIL: strerr =  "Memory allocation failed"
150 		case $FDIERROR_BAD_COMPR_TYPE:	strerr =  "Unknown compression type"
151 		case $FDIERROR_MDI_FAIL:	strerr =  "Failure decompressing data"
152 		case $FDIERROR_TARGET_FILE:	strerr =  "Failure writing to target file"
153 		case $FDIERROR_RESERVE_MISMATCH
154       {
155          strerr =  "Cabinets in set have different RESERVE sizes"
156       }
157 		case $FDIERROR_WRONG_CABINET
158       {
159          strerr =  "Cabinet strerr = ed on fdintNEXT_CABINET is incorrect"
160       }
161 		case $FDIERROR_USER_ABORT:	strerr =  "User aborted"
162 		default : strerr = "Unknown error"
163 	}
164    decab.fncnotify->func( $FLN_ERROR, 
165                  "\(prefix) failed: \(decab.erf.erfOper) [\(strerr)]", decab )
166 }
167 
168 func uint cab_decodeinit( str cabfile, decabinfo decab )
169 {
170    uint hfdi ret
171    str  path name
172    
173    decab.fncsysnotify = &decab_sysnotify;
174    decab.call = gentee_ptr( 4 ); // GPTR_CALL
175   
176    if !( hfdi = gcabd_create( &decab ))
177    {
178       decab_error( decab, "FDICreate" )
179       return 0
180    }
181    if !gcabd_iscabinet( hfdi, cabfile.ptr(), &decab )
182    {
183       decab.fncnotify->func( $FLN_NOTVALID, cabfile, decab )
184       goto end
185    } 
186    path.fgetdir( cabfile ).fappendslash()
187    name.fnameext( cabfile )
188    do 
189    {
190       if !gcabd_copy( hfdi, name.ptr(), path.ptr(), &decab )
191       {
192          decab_error( decab, "FDICopy" )
193          goto end
194       }
195       name = decab.nextvolume
196       decab.nextvolume.clear()
197    } while *name
198    ret = 1
199 label end
200    gcabd_destroy( hfdi )
201    return ret  
202 }
203 
204 
205 func uint cab_list( str cabfile, arr files of finfo, uint notify )
206 {
207    decabinfo decab
208 
209    decab.fncnotify = ?( notify, notify, &decab_notify )
210    decab.islist = 1
211    decab.fileinfo = &files 
212 
213    return cab_decodeinit( cabfile, decab )     
214 }
215 
216 func uint cab_decode( str cabfile destdir, uint notify param )
217 {
218    decabinfo decab
219    finfo     fi
220 
221    decab.destdir = destdir
222    decab.fileinfo = &fi
223    decab.param = param
224    decab.fncnotify = ?( notify, notify, &decab_notify )
225 
226    return cab_decodeinit( cabfile, decab )     
227 }
228 
229 func uint cab_decode( str cabfile destdir, uint notify )
230 {
231    return cab_decode( cabfile, destdir, notify, 0 )
232 }