EnglishРусский  

   ..

   cab.g

   cab2g.dll

   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\cab-x.g
  1 #exe=1
  2 /******************************************************************************
  3 *
  4 * Copyright (C) 2009, The Gentee Group. All rights reserved. 
  5 * This file is part of the Gentee open source project - http://www.gentee.com. 
  6 * 
  7 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT"). 
  8 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS 
  9 * ACCEPTANCE OF THE AGREEMENT.
 10 *
 11 * Author: Alexey Krivonogov ( gentee )
 12 *
 13 ******************************************************************************/
 14 
 15 include : $"..\other\random.g"
 16 
 17 import "msvcrt"
 18 {
 19    int  _close( int ) 
 20    uint _get_errno( uint )
 21    int  _lseek( int, int, int )
 22    int  _open( uint, int, int )
 23    int  _read( int, uint, uint )
 24    int  remove( uint )
 25    int  _write( int, uint, uint )
 26 }
 27 
 28 define
 29 {
 30    CB_MAX_FILENAME          =  256
 31    CB_MAX_CABINET_NAME      =  256
 32    CB_MAX_CAB_PATH          =  256
 33    CB_MAX_DISK_NAME         =  256
 34    FOLDER_THRESHOLD         =  1000000 // 900000
 35    statusFile      = 0   // Add File to Folder callback
 36    statusFolder    = 1   // Add Folder to Cabinet callback
 37    statusCabinet   = 2   // Write out a completed cabinet callback
 38 
 39    FCIERR_NONE = 0  
 40    FCIERR_OPEN_SRC
 41    FCIERR_READ_SRC
 42    FCIERR_ALLOC_FAIL 
 43    FCIERR_TEMP_FILE 
 44    FCIERR_BAD_COMPR_TYPE 
 45    FCIERR_CAB_FILE
 46    FCIERR_USER_ABORT 
 47    FCIERR_MCI_FAIL 
 48 
 49 }
 50 
 51 type CCAB {
 52 // LONG
 53     uint  cb                  // size available for cabinet on this media
 54     uint  cbFolderThresh      // Thresshold for forcing a new Folder
 55 // UINT
 56     uint  cbReserveCFHeader   // Space to reserve in CFHEADER
 57     uint  cbReserveCFFolder   // Space to reserve in CFFOLDER
 58     uint  cbReserveCFData     // Space to reserve in CFDATA
 59     int   iCab                // sequential numbers for cabinets
 60     int   iDisk               // Disk number
 61 //ifndef REMOVE_CHICAGO_M6_HACK
 62     int   fFailOnIncompressible // TRUE => Fail if a block is incompressible
 63 //endif
 64     ushort setID                // Cabinet set ID
 65 
 66     reserved   szDisk[ $CB_MAX_DISK_NAME ]    // current disk name
 67     reserved   szCab[ $CB_MAX_CABINET_NAME ]  // current cabinet name
 68     reserved   szCabPath[ $CB_MAX_CAB_PATH ]  // path for creating cabinet
 69 } 
 70 
 71 type ERF
 72 {
 73     int     erfOper
 74     int     erfType
 75     uint    fError
 76 } 
 77 
 78 type cabinit
 79 {
 80    uint volumesize
 81    str  disk
 82    
 83    uint fncerror
 84    uint fncprogress
 85       
 86    uint finish    // 1 if finish for progress
 87    uint cabsize
 88    uint filesize
 89 }
 90 
 91 import "cabinet"
 92 {
 93    uint FCICreate( uint, uint, uint, uint, uint, uint, uint, uint, uint, uint,
 94                    uint, uint, uint )
 95    uint FCIDestroy( uint )
 96    uint FCIFlushCabinet( uint, uint, uint, uint )
 97 }
 98 
 99 import "cab2g.dll"<link>
100 {  
101    uint gcabe_addfile( uint, uint, uint, uint )
102    uint gcabe_close( uint )
103    uint gcabe_create( CCAB )
104 }
105 
106 method str str.gettempfile( str dir prefix ) 
107 { 
108    random rnd 
109    
110    rnd.init()
111    rnd.randseed( 'A', 'Z' ) 
112    do 
113    { 
114       str  name
115       uint i 
116       fornum i, 6 : name.appendch( rnd.randseed() ) 
117       ( this = dir ).faddname( "\( prefix )\( name ).tmp" ) 
118    } while fileexist( this )
119    
120    return this 
121 }
122 
123 func uint cab_alloc( uint size )
124 {
125    print("a=\( size )\n")
126    return malloc( size )
127 }
128 
129 // -----------------------------------------------------------------
130 
131 func cab_free( uint ptr )
132 {
133    print("0\n")
134    if ( ptr ) : mfree( ptr )
135 }
136 
137 // -----------------------------------------------------------------
138 
139 func int cab_open( uint name, int  oflag pmode, uint err pv )
140 {
141    int result
142 
143    print("1 \n")
144 //   print("1 \("".copy( name ))\n")
145 //   file ff
146 //   ff.open( "".copy( name ), $OP_ALWAYS )
147 //   result = ff.handle
148    result = _open( name, oflag, pmode)
149 
150    if result == -1 : _get_errno( err )
151    print("1 \(result) \(err)\n")
152 
153    return result
154 }
155 
156 // -----------------------------------------------------------------
157 
158 func uint cab_read( int hf, uint memory cb err userpar )
159 {
160    uint result
161 
162    print("2\n")
163    result = _read( hf, memory, cb )
164 
165    if result != cb : _get_errno( err )
166 
167    return result
168 }
169 
170 // -----------------------------------------------------------------
171 
172 func uint cab_write( int hf, uint memory cb err userpar )
173 {
174    uint result
175 
176    print("3\n")
177    result = _write( hf, memory, cb )
178 
179    if result != cb : _get_errno( err )
180 
181    return result
182 }
183 
184 // -----------------------------------------------------------------
185 
186 func int cab_close( int hf, uint err userpar )
187 {
188     int result
189 
190    print("4\n")
191     result = _close( hf )
192     if result != 0 : _get_errno( err )
193 
194     return result
195 }
196 
197 // -----------------------------------------------------------------
198 
199 func int cab_seek( int hf, int dist seektype, uint err userpar )
200 {
201     int result;
202 
203    print("5\n")
204     result = _lseek( hf, dist, seektype );
205 
206     if result == -1 : _get_errno( err )
207 
208     return result
209 }
210 
211 // -----------------------------------------------------------------
212 
213 func int cab_delete( uint name, uint err pv )
214 {
215     int result
216 
217    print("6\n")
218     result = remove( name )
219 
220     if result != 0 : _get_errno( err )
221 
222     return result
223 }
224 
225 //--------------------------------------------------------------------------
226 
227 func int cab_placed( CCAB pccab, uint filename, uint size continuation pv )
228 {
229    print("7 cab=\(&pccab ) \("".copy( filename )) \( size ) \(continuation) cabi=\(pv) \( pv->uint )\n")
230 /*	printf("Placed file '%s' (size %d) on cabinet '%s'\n",
231 		filename, size, pccab->szCab	);
232 
233 	if (fContinuation)
234 		printf("      (Above file is a later segment of a continued file)\n");
235 */
236 	return 0
237 }
238 
239 func uint cab_gettempfile( uint ret, int length, uint pv )
240 {
241    str dir filename
242    
243    print("8\n")
244    gettempdir( dir )
245 //   filename.gettempfile( dir, "cab_" )
246    uint i
247    do 
248    {
249       ( filename = dir ).faddname( "cab_\(i++).tmp" )      
250    } while fileexist( filename )
251    if ( *filename + 1 ) < length 
252    {
253       mcopy( ret, filename.ptr(), *filename + 1 )
254       print("81 \( filename )\n")
255       return 1
256    }
257    return 0
258 }                                       
259 
260 // -----------------------------------------------------------------
261 
262 func cab_error( cabinit cabi, uint code, str prefix )
263 {
264    str strerr
265    
266    print("9\n")
267    if !cabi.fncerror : return
268    
269    switch code
270 	{
271 		case $FCIERR_NONE : strerr = "No error"
272 		case $FCIERR_OPEN_SRC: strerr = "Failure opening file to be stored in cabinet"
273 		case $FCIERR_READ_SRC: strerr = "Failure reading file to be stored in cabinet"
274 		case $FCIERR_ALLOC_FAIL:	strerr = "Insufficient memory in FCI"
275 		case $FCIERR_TEMP_FILE: strerr = "Could not create a temporary file"
276 		case $FCIERR_BAD_COMPR_TYPE: strerr = "Unknown compression type"
277 		case $FCIERR_CAB_FILE: strerr = "Could not create cabinet file"
278 		case $FCIERR_USER_ABORT: strerr = "Client requested abort"
279 		case $FCIERR_MCI_FAIL: strerr = "Failure compressing data"
280 		default : strerr = "Unknown error"
281 	}
282    cabi.fncerror->func( "\(prefix) failed: \(code) [\(strerr)]")
283 }
284 
285 // -----------------------------------------------------------------
286 
287 func uint cab_progress( uint status cb1 cb2 pv )
288 {
289    uint percent cabi
290    
291    cabi = pv
292    cabi as cabinit
293 
294    if status == $statusFile && !cabi.finish
295 	{
296       cabi.cabsize += cb2;
297       if cabi.filesize : percent = 100 * cabi.cabsize / cabi.filesize
298       if cabi.fncprogress : cabi.fncprogress->func( cabi, percent )  
299    }
300 /*	else if (typeStatus == statusFolder)
301 	{
302 		int	percentage;
303 
304 		percentage = get_percentage(cb1, cb2);
305 
306 		printf("\nCopying folder to cabinet: %d%%      \r", percentage);
307 	}*/
308 	return 0;
309 }
310 
311 
312 func uint cab_netxcabinet( CCAB pccab, uint cbPrevCab pv )
313 {
314    uint cabi = pv
315    str name
316    
317    cabi as cabinit
318    
319    name.printf( cabi.disk, %{ pccab.iCab } )
320 	mcopy( &pccab.szCab, name.ptr(), *name + 1 )
321 	return 1
322 }
323 
324 
325 func uint mycallback( uint idfunc, uint parsize )
326 {     
327    buf  bc = '\h
328 50            
329 55            
330 53            
331 8B DC         
332 83 C3 \(byte( parsize * 4 + 0x0C ))      
333 8B EB         
334 83 ED \(byte( parsize * 4 ))      
335 3B EB         
336 74 08         
337 8B 03         
338 50            
339 83 EB 04      
340 EB F4         
341 83 ED 04      
342 55            
343 68 \( idfunc )
344 b8 \( calladdr() )
345 ff d0         
346 83 C4 \(byte( ( parsize +2 )* 4 ))      
347 5B            
348 5D            
349 58            
350 C2 \( parsize * 4 )         
351 00
352 '
353    uint pmem
354    pmem = VirtualAlloc( 0, *bc + 100, 0x3000,  0x40 )
355    //print( "mem = \(hex2strl(pmem))\n" )
356    mcopy( pmem, bc.ptr(), *bc )      
357    return pmem
358    
359 }
360 
361 // -----------------------------------------------------------------
362 
363 func uint cab_create( str path cabfile, arrstr files, cabinit cabi )
364 {
365    CCAB ccab
366    uint hfci ret
367    ERF  erf
368    arr  fncid of uint
369    arr  fnc of uint
370    uint i
371    
372    fncid = %{ &cab_placed, &cab_alloc, &cab_free,
373             &cab_open, &cab_read, &cab_write, &cab_close, 
374             &cab_seek, &cab_delete, &cab_gettempfile, &cab_progress,
375             &cab_netxcabinet }
376    fnc  = %{ 5, 1, 1, 5, 5, 5, 3, 5, 3, 3, 4, 3 }            
377    fornum i, *fnc
378    { 
379 //      uint par = fnc[i] 
380       fnc[i] = mycallback( fncid[i], fnc[i] )
381       print("\(i)=\(fncid[i]) \(fnc[i])\n")
382    }
383    cabi.finish = 0
384    cabi.cabsize = 0
385    cabi.filesize = 0
386    
387    ccab.cb = cabi.volumesize
388 	ccab.cbFolderThresh = $FOLDER_THRESHOLD
389 	ccab.cbReserveCFHeader = 0
390 	ccab.cbReserveCFFolder = 0
391 	ccab.cbReserveCFData   = 0
392 	ccab.iCab = 1
393 	ccab.iDisk = 0
394 	ccab.setID = 777
395    print("0 cab = \( &ccab ) cabi = \(&cabi )\n")
396 	mcopy( &ccab.szDisk, cabi.disk.ptr(), *cabi.disk + 1 )
397    mcopy( &ccab.szCabPath, path.ptr(), *path + 1 )
398    mcopy( &ccab.szCab, cabfile.ptr(), *cabfile + 1 )
399 //	store_cab_name(cab_parms->szCab, cab_parms->iCab);
400 
401    hfci = gcabe_create( ccab )
402 //   hfci = FCICreate( &erf, fnc[0], fnc[1], fnc[2], fnc[3], fnc[4], fnc[5], 
403 //                     fnc[6], fnc[7], fnc[8], fnc[9], &ccab, &cabi )
404    print("ОК 2\n")
405    if !hfci
406    {
407       cab_error( cabi, erf.erfOper, "FCICreate" )
408       goto end
409    }
410    cabi.finish = 1
411    print("ОК 3\n")
412 /*   if !FCIFlushCabinet( hfci, 0, fnc[11], fnc[10] )
413 	{
414       print("ОК 4\n")
415 
416       cab_error( cabi, erf.erfOper, "FCIFlushCabinet" )
417       goto end
418 	}
419    print("ОК 5\n")
420 
421    FCIDestroy( hfci )*/
422    fornum i = 0, *files
423    { 
424       ffind fd
425       
426       fd.init( files[i], $FIND_FILE | $FIND_RECURSE )
427       foreach cur, fd
428       {
429          gcabe_addfile( hfci, cur.fullname.ptr(), cur.name.ptr(), 0 )
430       }
431    }   
432    gcabe_close( hfci )
433    ret = 1
434 label end:   
435    fornum i = 0, *fnc : freecallback( fnc[i] )
436    return ret
437 }
438 
439 func main<main>
440 {
441    cabinit cabi
442    arrstr  files = %{"c:\\temp\\*.*"} 
443  
444    cabi.volumesize = 300000
445    cabi.disk = "mydisk"
446    cab_create( $"c:\\temp\\", "test.cab", files, cabi )
447    congetch("Press any key...")   
448 }