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.

  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: res 15.08.07 0.0.A.
 11 *
 12 * Author: Alexey Krivonogov ( gentee )
 13 *
 14 ******************************************************************************/
 15 
 16 type reshead32 {
 17    uint    ressize
 18    uint    hdrsize
 19    ushort restypeid
 20    ushort restype
 21    ushort resnameid
 22    ushort resname
 23    uint   dversion
 24    ushort memflag
 25    ushort lang
 26    uint   version
 27    uint   characts
 28 } 
 29 
 30 type res
 31 {
 32    buf  data   
 33    uint iconid      // Последний занятый номер для иконок
 34    uint ismanifest  // Есть или нет манифест
 35    uint flags
 36    uint owner       // Linker
 37 }
 38 
 39 include : "ico.g"
 40 
 41 define
 42 {
 43    // Memory/ flags
 44    RCF_MOVEABLE    = 0x0010
 45    RCF_PURE          = 0x0020
 46    RCF_PRELOAD       = 0x0040
 47    RCF_DISCARDABLE =   0x1000
 48 
 49    // Resource type IDs 
 50    RC_CURSOR        = 1
 51    RC_BITMAP        = 2
 52    RC_ICON          = 3
 53    RC_MENU          = 4
 54    RC_DIALOG        = 5
 55    RC_STRING        = 6
 56    RC_FONTDIR       = 7
 57    RC_FONT          = 8
 58    RC_ACCELERATOR   = 9
 59    RC_RCDATA        = 10
 60    RC_MESSAGETABLE  = 11
 61    RC_GROUP_CURSOR  = 12
 62    RC_GROUP_ICON    = 14
 63    RC_VERSION       = 16
 64    RC_DLGINCLUDE    = 17
 65    RC_PLUGPLAY      = 19
 66    RC_VXD           = 20
 67    RC_ANICURSOR     = 21
 68    RC_ANIICON       = 22
 69    RC_MANIFEST      = 24
 70    RC_DLGINIT       = 240
 71    RC_TOOLBAR       = 241
 72    RC_BITMAPNEW     = 0x2002 
 73    RC_MENUNEW       = 0x2004 
 74    RC_DIALOGNEW     = 0x2005 
 75    
 76    CP_ACP           = 0           // default to ANSI code page
 77    CP_OEMCP         = 1           // default to OEM  code page
 78    MB_PRECOMPOSED   = 0x00000001  // use precomposed chars
 79 }
 80 
 81 method res res.init
 82 {
 83    // Добавляем пустой reshead32
 84    this.data = '\h4 0 20 ffff ffff 0 0 0 0'
 85    return this
 86 }
 87 
 88 method  res.error( uint code, str param )
 89 {
 90    if this.owner : this.owner->linker.errfunc->func( code, param ) 
 91    else : exit( 0 )
 92 /*   print( "Resource error: \(msgtext)\nPress any key..." )
 93    getch()
 94    exit( 0 )*/
 95 }
 96 
 97 method  res.nfy( uint code, str param )
 98 {
 99    if this.owner : this.owner->linker.nfy( code, param )
100 }
101 
102 method res.addresource( uint typeres, str name, buf data )
103 {
104    buf  uname
105    uint headsize
106    
107    if name[0] > '9'  // Указано имя ресурса
108    {
109       uname.expand( 128 )
110       // Переводим в Unicode
111       uname.use = MultiByteToWideChar( $CP_ACP, $MB_PRECOMPOSED,
112          name.ptr(), 0xFFFFFFFF, uname.ptr(), 64 ) * 2
113       uname.align()         
114    }
115    this.data += *data
116    if *uname 
117    {
118       this.data += sizeof( reshead32 ) + *uname - 4 
119          /* - 4 Включенный размер reshead32 resnameid resname  */
120    }
121    else : this.data += sizeof( reshead32 )
122    
123    this.data += ushort( 0xFFFF )
124    this.data += ushort( typeres )
125    
126    if *uname 
127    {
128       this.data += uname
129    }
130    else 
131    {
132       this.data += ushort( 0xFFFF )
133       this.data += ushort( uint( name ))
134    }   
135    this.data += '\h4 0 4090000 0 0'
136    this.data += data
137    this.data.align()
138 }
139 
140 method uint res.addicon( str idname iconfile )
141 {
142    uint i
143    buf  groupicon
144    arr  icons of iconinfo
145    
146    if !geticoninfo( iconfile, icons ) : return 0
147    groupicon += ushort( 0 )
148    groupicon += ushort( 1 )
149    groupicon += ushort( *icons )
150    fornum i, *icons
151    {
152       uint idir
153       idir as icons[i].icondir
154       
155       this.addresource( $RC_ICON, str( ++this.iconid ), icons[i].data )   
156       groupicon += byte( idir.bWidth )
157       groupicon += byte( idir.bHeight )
158       groupicon += byte( idir.bColorCount )
159       groupicon += byte( 0)
160       groupicon += ushort( idir.wPlanes )
161       groupicon += ushort( idir.wBitCount )
162       groupicon += idir.dwBytesInRes
163       groupicon += ushort( this.iconid )
164    }  
165    this.addresource( $RC_GROUP_ICON, idname, groupicon )   
166    return 1   
167 }
168 
169 method uint res.addmanifest( str name )
170 {
171    str manifest access level 
172    
173    access = ?( this.flags & $RES_ACCESS, "true", "false" )
174    level = ?( this.flags & $RES_ADMIN, "requireAdministrator", "asInvoker" )
175    
176    manifest = "\[..]<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity version="1.0.0.0" name="[..]\(name)\[..]" processorArchitecture="*" type="win32"/> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" language="*" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" /> </dependentAssembly> </dependency>
177    <description>Description</description> 
178    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
179     <security>
180       <requestedPrivileges>
181         <requestedExecutionLevel
182           level="[..]\(level)\[..]"
183           uiAccess="[..]\(access)\[..]"/>
184         </requestedPrivileges>
185        </security>
186   </trustInfo>
187 </assembly>[..]"
188 
189    /*   <requestedExecutionLevel
190           level="requireAdministrator"
191           uiAccess="false"/>
192         </requestedPrivileges>  */  
193    manifest->buf.use--
194    this.addresource( $RC_MANIFEST, "1", manifest->buf )
195    this.ismanifest = 1
196    return 1
197 }
198 
199 method uint res.addres( str filename )
200 {
201    buf  newres
202    uint cur end reshead maxicon data
203    
204    newres.read( filename )
205    if !*newres : return 0
206 
207    end = newres.ptr() + *newres
208    cur = newres.ptr() + 0x20
209    
210    while cur < end
211    {
212       reshead as cur->reshead32
213       if reshead.restypeid == 0xFFFF
214       {
215          switch reshead.restype
216          {
217             case $RC_ICON
218             {
219                if reshead.resnameid == 0xFFFF 
220                {
221                   reshead.resname += this.iconid
222                   if maxicon < reshead.resname : maxicon = reshead.resname
223                }
224             }
225             case $RC_GROUP_ICON
226             {
227                uint count
228                
229                data = cur + reshead.hdrsize + 4
230                count = data->ushort
231                data += 2
232                while count--
233                {
234                   ( data + 12 )->ushort += this.iconid
235                   data += 14
236                }
237             }
238             case $RC_MANIFEST
239             {
240                this.ismanifest = 1
241             }
242          }
243       } 
244       // Переход на следующий элемент
245       cur += reshead.ressize + reshead.hdrsize
246       // Выравнивание
247       if ( cur - newres.ptr())  & 0x3 : cur += 4 - ( ( cur - newres.ptr()) & 0x3 )      
248    }
249    this.data.append( newres.ptr() + 0x20, *newres - 0x20 )
250    this.data.align()
251    if maxicon : this.iconid = maxicon
252    return 1
253 }
254 
255 method uint res.write( str filename )
256 {
257    return this.data.write( filename )
258 }
259 
260 // Добавление иконок из проекта
261 method uint res.icons( arrstr icolist )
262 {
263    foreach curico, icolist
264    {
265       arrstr icons
266     
267       curico.split( icons, ',', $SPLIT_FIRST | $SPLIT_NOSYS )
268       if *icons == 1
269       {
270          icons += icons[0]
271          icons[0] = "ICON_APP"
272       }
273       if !fileexist( icons[1] ) || !this.addicon( icons[0], icons[1] )
274       {
275          this.error( $RERR_LOADICON, icons[1] )
276       }
277    }
278    return 1
279 }
280 
281 // Упаковка и добавление временных файлов
282 method res.temps( arrstr temps, str geaname )
283 {
284    uint     i
285    geae     egea
286    geaeinit geai
287    geacomp  gc
288    str      tempdir
289    buf      btemp
290 
291    if *geaname : goto readtemp
292    
293    if !*temps : return
294    
295    gc.compmethod = $GEA_LZGE
296    gc.order = 10
297    gc.solid = 0
298    geai.flags = $GEAI_IGNORECOPY
299    geai.userfunc = ?( this.owner, this.owner->linker.geafunc, 0 )
300    
301    gettempdir( tempdir )
302    geaname = "\(tempdir)\\setup_temp.gea"       
303    if !egea.create( geaname, geai )
304    {
305       this.error( $LERR_OPEN, geaname )
306    }
307 //   print("qqq \(geaname)\n")
308    this.nfy( $LNFY_ADDTEMP, "temporary" )
309 
310    fornum i, *temps
311    {
312       arrstr items
313       
314       temps[i].split( items, ',', $SPLIT_FIRST | $SPLIT_NOSYS )
315       if *items != 2 : continue
316 //      print("\(i)=\( temps[i] )\n")
317       gc.idgroup = uint( items[0] )
318       if !fileexist( items[1] ) || !egea.add( items[1], gc )
319       {
320          this.error( $RERR_PACK, items[1] )
321       }
322    }
323    egea.close()
324    label readtemp
325    btemp.read( geaname )
326    this.addresource( $RC_RCDATA, "SETUP_TEMP", btemp )   
327 }
328 
329 // Добавление файлов ресурсов
330 method res.resfiles( arrstr reslist )
331 {
332    foreach curres, reslist
333    {
334       if !fileexist( curres ) || !this.addres( curres )
335       {
336          this.error( $LERR_ADDRES, curres )
337       }
338    }
339 }