EnglishРусский  

   ..

   dll2bin.g

   ico.g

   linker.g

   res.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\linker\linker.g
  1 /******************************************************************************
  2 *
  3 * Copyright (C) 2004-2007, 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 * ID: linker 15.08.07 0.0.A.
 11 *
 12 * Author: Alexey Krivonogov ( gentee )
 13 *
 14 ******************************************************************************/
 15 
 16 define
 17 {
 18    LINK_GUI   = 0x0001    // GUI application
 19    LINK_ONE   = 0x0002    // Just one copy can be run
 20    LINK_SIZE  = 0x0004    // Check the minimum size of exe file
 21    LINK_PACK  = 0x0008    // Compress the byte-code & DLL
 22    LINK_DLL   = 0x0010    // Use gentee.dll
 23    LINK_CHAR  = 0x0020    // Print Window characters
 24    LINK_ASM   = 0x0040    // The bytecode can have ASM commands 
 25    LINK_ASMRT = 0x0080    // Run-time converting the bytecode to ASM commands
 26    LINK_TMPRAND = 0x0100  // Random temporary folder
 27    // res.flags
 28    RES_ACCESS = 0x1000 // Manifest uiAccess = true
 29    RES_ADMIN  = 0x2000 // Manifest level = requireAdministrator
 30 
 31    LINKSAVE_EXE  = 0x0001 // Установить exesize
 32    LINKSAVE_MIN  = 0x0002 // Установить minsize
 33    LINKSAVE_EXT  = 0x0004 // Добавить расширенный блок
 34    
 35    LINKFLD    = $"res\linker"
 36    
 37    // error codes
 38    LERR_OPEN = 0      
 39    LERR_NOTLAUNCH
 40    LERR_WRITE
 41    LERR_TMPRES
 42    LERR_ADDRES
 43    LERR_COPY
 44    LERR_READ
 45    LERR_SECTION
 46    LERR_MANIFEST
 47    RERR_LOADICON
 48    RERR_PACK
 49    LNFY_ADDTEMP = 255
 50 }
 51 
 52 type linker {
 53    str   input      // Input GE file
 54    str   output     // Output executable filename
 55    uint  flag       // Flags
 56    uint  param      // Additional parameter
 57    arrstr  icons    // Icons <idname,iconfile>
 58    arrstr  temps    // Temporary files <id,tempfile>
 59    arrstr  res      // Resource files to link
 60    str     geatemp  // Ready temporary GEA file
 61    uint    errfunc  // Error message function
 62    uint    geafunc  // GEA message function
 63    uint    nfyfunc  // Linker notify function
 64 }
 65 
 66 method  linker.nfy( uint code, str param )
 67 {
 68    if .nfyfunc : .nfyfunc->func( code, param ) 
 69 }               
 70 
 71 include
 72 { 
 73    $"..\gea\gea.g"
 74    "res.g"
 75 }
 76 
 77 type linkhead
 78 {
 79    uint   sign1           // 'Gentee Launcher' sign
 80    uint   sign2           // 
 81    uint   sign3           // 
 82    uint   sign4           // 
 83    uint   exesize         // Размер exe-файла.
 84                           // Если не 0, то файл является SFX 
 85                           // архивом и далее идут прикрепленныe данные
 86    uint   minsize         // Если не 0, то выдавать ошибку если размер файла
 87                           // меньше указанного
 88    ubyte  console         // 1 если консольное приложение
 89    ubyte  exeext          // Количество дополнительных блоков
 90    ubyte  pack            // 1 если байт код и dll упакованы
 91    ushort flags           // flags
 92    uint   dllsize         // Упакованный размер Dll файла. 
 93                           // Если 0, то динамическое подключение gentee.dll
 94    uint   gesize          // Упакованный размер байт-кода.
 95    uint   mutex           // ID для mutex, если не 0, то будет проверка
 96    uint   param           // Зашитый параметр
 97    uint   offset          // Смещение данной структуры
 98    reserved extsize[ 64 ] // Зарезервированно для размеров 8 ext блоков
 99                           // Каждый размер занимает long
100 }
101 
102 import "\$LINKFLD\\EXELink.dll"<exe>
103 {
104    uint Add_Res_Section( uint, uint )
105    uint Add_Data_Section( uint, uint, uint )
106    uint Set_Sub_System( uint, uint )
107    uint Set_OS_Version( uint, uint )
108 }
109 
110 import "kernel32.dll"
111 {
112         Sleep( uint )
113    uint GetTickCount()
114 }
115 
116 method  linker.error( uint code, str param )
117 {
118 //   print( "Linker error: \(msgtext)\nPress any key..." )
119 //   getch()
120    if .errfunc : .errfunc->func( code, param ) 
121    else : exit( 0 )
122 }
123 
124 method  linker.error( uint code )
125 {
126    this.error( code, 0->str ) 
127 }
128 
129 method uint linker.savehead( linkhead lnkhead, uint flags )
130 {
131    // Записываем заголовок linkhead
132    file fexe
133    uint handle fsize launchoff phead
134    spattern  pattern
135    buf       btemp
136    
137    if !fexe.open( .output, 0 ) : this.error( $LERR_OPEN, .output )
138 
139    pattern.init( '\"Gentee Launcher"', 0 )
140    btemp.expand( 0x20000 )
141    
142    btemp.use = fexe.read( btemp.ptr(), 0x20000 )
143    
144    launchoff = pattern.search( btemp, 0 )
145    if launchoff >= *btemp : this.error( $LERR_NOTLAUNCH, .output ) 
146 
147    phead as lnkhead
148    if !&lnkhead
149    {  // Читаем структуру linkhead из файла
150       phead as ( btemp.ptr() + launchoff )->linkhead
151    }
152    phead.offset = launchoff
153    fsize = fexe.getsize()
154    
155    if flags & $LINKSAVE_EXE : phead.exesize = fsize
156    if flags & $LINKSAVE_MIN : phead.minsize = fsize
157    if flags & $LINKSAVE_EXT
158    {
159       long prevsize
160       uint i ptr
161       prevsize = long( phead.exesize )
162       ptr = &phead.extsize
163        
164       fornum i, phead.exeext  
165       {
166          prevsize += ptr->long
167          ptr += sizeof( long )      
168       }
169       phead.exeext++
170       ptr->long = long( fsize ) - prevsize
171 //      print("EXt=\( phead.exeext ) size = \( ptr->long ) exe=\(phead.exesize)\n")
172    }
173    if !fexe.writepos( launchoff, &phead, sizeof( linkhead ))
174    {
175       this.error( $LERR_WRITE, .output )
176    }
177    fexe.close()
178    return fsize
179 }
180 
181 // gentee !!!
182 /*method uint buf.readappend( str filename )
183 {
184    file f
185    uint rd
186    
187    if f.open( filename, $OP_READONLY )
188    {   
189       uint size = f.getsize()
190       .expand( size + 128 ) // резервируем для возможного str
191       rd = f.read( this.data + this.use, size ) 
192       this.use += rd
193       f.close( )
194    }
195    return rd
196 }
197 */
198 
199 method  uint linker.create
200 {
201    buf       ge
202    str       pattern
203    linkhead  lnkhead
204    str       tempdir stemp launcher
205    uint      ret last
206    file      exefile
207    res       exeres
208 
209    this.input.ffullname( this.input )
210    if this.flag & $LINK_PACK
211    {
212       buf  in 
213       lzge lz 
214       
215       ge.expand( 4200000 )
216       getmodulepath( pattern, "\$LINKFLD\\genteert.bin" ) 
217       if !ge.read( pattern ) : this.error( $LERR_READ, pattern )
218       lnkhead.dllsize = *ge
219       lnkhead.pack = 1
220       this.flag &= ~( $LINK_ASMRT | $LINK_ASM | $LINK_DLL )
221 
222       in.read( this.input )
223       lz.order = 10
224       ge.use += lzge_encode( in.ptr(), *in, ge.ptr() + lnkhead.dllsize + 4, lz ) + 4
225       ( ge.ptr() + lnkhead.dllsize )->uint = *in
226 //      print("Exe=\(lnkhead.dllsize) \( *in) => \(ge.use - lnkhead.dllsize)\n")
227    }   
228    elif !ge.read( this.input ) : this.error( $LERR_READ, this.input ) 
229       
230    if this.flag & $LINK_DLL
231    {
232       if this.flag & $LINK_ASMRT : launcher = "launcherda"
233       else : launcher = "launcherd"
234    }
235    else
236    {
237       if this.flag & $LINK_ASMRT : launcher = "launcherart"
238       elif this.flag & $LINK_ASM : launcher = "launchera"
239       elif this.flag & $LINK_PACK : launcher = "minilauncher"
240       else : launcher = "launcher"
241    }      
242    getmodulepath( pattern, "\$LINKFLD\\\(launcher).exe" ) 
243    if !*this.output : .output.fsetext( .input, "exe" )   
244    this.output.ffullname( this.output )
245    if !( exefile.open( this.output, $OP_EXCLUSIVE | $OP_CREATE ))
246    {
247       this.error( $LERR_OPEN, .output )  
248    }
249    last = this.output[ *this.output - 1 ]
250    this.output[ *this.output - 1 ] = '_'
251    if !copyfile( pattern, .output ) : this.error( $LERR_OPEN, .output )
252 
253    lnkhead.sign1 = 0x746E6547
254    lnkhead.sign2 = 0x4C206565
255    lnkhead.sign3 = 0x636E7561
256    lnkhead.sign4 = 0x00726568
257    
258    if !( this.flag & $LINK_GUI )
259    {
260       lnkhead.console = $G_CONSOLE
261       Set_Sub_System( .output.ptr(), 1 )
262    }   
263    lnkhead.flags = 0
264    if this.flag & $LINK_CHAR : lnkhead.console |= $G_CHARPRN
265    if this.flag & $LINK_ONE : lnkhead.mutex = GetTickCount()
266    if this.flag & $LINK_TMPRAND : lnkhead.flags = $G_TMPRAND
267    
268    gettempdir( tempdir )
269    ( pattern = tempdir ).faddname( "gedata" )
270    lnkhead.gesize = *ge - lnkhead.dllsize 
271    
272    if !ge.write( pattern ) : this.error( $LERR_WRITE, pattern )
273    if ret = Add_Data_Section( .output.ptr(), ".gentee".ptr(), pattern.ptr())
274    {
275       this.error( $LERR_SECTION )
276 //      if ret == 4 : mustunicows()
277    }
278    
279    exeres.owner = &this
280 // Добавляем иконки
281    exeres.icons( this.icons )
282    exeres.temps( this.temps, this.geatemp )
283    exeres.resfiles( this.res )
284 
285    if !exeres.ismanifest && this.flag & $LINK_GUI
286    {
287       this.output.fgetparts( 0->str, stemp, 0->str )
288       exeres.flags |= this.flag & 0xF000
289       if !exeres.addmanifest( stemp ) : this.error( $LERR_MANIFEST )
290    }
291    if *exeres.data > 0x20 
292    {
293       stemp = "\(tempdir)\\temp.res"
294       if !exeres.write( stemp ) : this.error( $LERR_TMPRES, stemp )
295       if ret = Add_Res_Section( .output.ptr(), stemp.ptr())
296       {
297          this.error( $LERR_ADDRES, stemp )
298 //         if ret == 4 : mustunicows()
299       }
300    }
301    
302    ret = this.savehead( lnkhead, $LINKSAVE_EXE | ?( this.flag & $LINK_SIZE, 
303                         $LINKSAVE_MIN, 0 ))
304    stemp = .output
305    this.output[ *this.output - 1 ] = last
306    exefile.close()
307    deletefile( .output )
308    if !movefile( stemp, .output ) : this.error( $LERR_COPY, .output )
309    Sleep( 100 )
310 
311    return 1
312 }
313