EnglishРусский  

   ..

   registry.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\registry\registry.g
  1 /******************************************************************************
  2 *
  3 * Copyright (C) 2004-2008, 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 /*-----------------------------------------------------------------------------
 15 * Id: registry L "Registry"
 16 * 
 17 * Summary: Working with the Registry. This library allows you to work with 
 18            the Windows Registry. For using this library, it is required to
 19            specify the file registry.g (from
 20             lib\registry subfolder) with include command. #srcg[
 21 |include : $"...\gentee\lib\registry\registry.g"]    
 22 *
 23 * List: *#lng/funcs#,regdelkey,regdelvalue,reggetmultistr,reggetnum,
 24          regkeys,regsetmultistr,regsetnum,regvaltype,regvalues,regverify, 
 25         *#lng/methods#,buf_regget,buf_regset,str_regget,str_regset
 26 * 
 27 -----------------------------------------------------------------------------*/
 28 
 29 define <export>
 30 {
 31 /*-----------------------------------------------------------------------------
 32 * Id: regroot D
 33 * 
 34 * Summary: Registry roots
 35 *
 36 -----------------------------------------------------------------------------*/
 37    HKEY_CLASSES_ROOT   = 0x80000000   // Classes Root.
 38    HKEY_CURRENT_USER   = 0x80000001   // Current user's settings.
 39    HKEY_LOCAL_MACHINE  = 0x80000002   // Local machine settings.
 40    HKEY_USERS          = 0x80000003   // All users' settings
 41 
 42 //-----------------------------------------------------------------------------
 43    REG_OPTION_NON_VOLATILE  = 0x00000000
 44 
 45    REG_CREATED_NEW_KEY      = 0x00000001
 46    REG_OPENED_EXISTING_KEY  = 0x00000002
 47 /*-----------------------------------------------------------------------------
 48 * Id: regtype D
 49 * 
 50 * Summary: Registry types
 51 *
 52 -----------------------------------------------------------------------------*/
 53    REG_NONE       = 0   // Unknown. 
 54    REG_SZ         = 1   // String.
 55    REG_EXPAND_SZ  = 2   // Expanded string. String with environment variables.
 56    REG_BINARY     = 3   // Binary data.
 57    REG_DWORD      = 4   // Number.
 58    REG_MULTI_SZ   = 7   // String sequence.
 59 
 60 //-----------------------------------------------------------------------------
 61    KEY_READ       = 0x20019
 62    KEY_WRITE      = 0x20006
 63    
 64 /*-----------------------------------------------------------------------------
 65 * Id: regsetret D
 66 * 
 67 * Summary: Result of buf.regset
 68 *
 69 -----------------------------------------------------------------------------
 70 #define   0    // No data has been written.
 71 #define   1    // The value of the key was created during the writing process.
 72 #define   2    // Data is written into the existing value.
 73 
 74 //-----------------------------------------------------------------------------
 75 -----------------------------------------------------------------------------*/
 76    REGSET_FALSE   = 0
 77    REGSET_CREATED = 1
 78    REGSET_OPENED  = 2
 79 
 80    ERROR_NO_MORE_ITEMS = 259
 81 }
 82 
 83 import "advapi32.dll"
 84 {
 85    int RegCloseKey( uint )
 86    int RegCreateKeyExA( uint, uint, uint, uint, uint, uint, uint, uint,
 87                         uint ) -> RegCreateKeyEx
 88    int RegDeleteKeyA( uint, uint ) -> RegDeleteKey
 89    int RegDeleteValueA( uint, uint ) -> RegDeleteValue
 90    int RegEnumKeyExA( uint, uint, uint, uint, uint, uint, uint, 
 91                       filetime ) -> RegEnumKeyEx   
 92    int RegEnumValueA( uint, uint, uint, uint, uint, uint, uint, 
 93                         uint ) -> RegEnumValue
 94    int RegOpenKeyExA( uint, uint, uint, uint, uint ) -> RegOpenKeyEx
 95    int RegQueryValueExA( uint, uint, uint, uint, 
 96                          uint, uint ) -> RegQueryValueEx
 97    int RegSetValueExA( uint, uint, uint, uint, uint, uint ) -> RegSetValueEx
 98 }
 99 
100 /*-----------------------------------------------------------------------------
101 * Id: regvaltype F
102 * 
103 * Summary: Get the type of a registry key value.
104 *  
105 * Params: root - A root key. $$[regroot] 
106           subkey - A name of the registry key. 
107           valname - The name of the key value the type of which is being /
108                     determined. 
109 *
110 * Return: 0 is returned if the type is not determined or there is no such 
111           value. Besides, the following values are possible: $$[regtype]   
112 *
113 -----------------------------------------------------------------------------*/
114 
115 func uint regvaltype( uint root, str subkey, str valname )
116 {
117    uint hkey
118    uint result
119    
120    if !RegOpenKeyEx( root, subkey.ptr(), 0, $KEY_READ, &hkey )
121    {
122       if RegQueryValueEx( hkey, valname.ptr(), 0, &result, 0, 0 ) : result = 0
123       RegCloseKey( hkey )
124    }
125    return result
126 }
127 
128 /*-----------------------------------------------------------------------------
129 * Id: buf_regget F2
130 * 
131 * Summary: Getting a value. This method writes the value of a registry key 
132            into a #a(buffer) object.
133 *  
134 * Params: root - A root key. $$[regroot] 
135           subkey - A name of the registry key. 
136           valname - A name of the specified key value.
137           regtype - The pointer to uint the type of this value will be /
138                     written to. It can be 0. 
139 *
140 * Return: #lng/retobj#
141 *
142 -----------------------------------------------------------------------------*/
143 
144 method buf buf.regget( uint root, str subkey, str valname, uint regtype )
145 {
146    uint  size
147    uint  hkey
148    
149    this.clear()
150    if !RegOpenKeyEx( root, subkey.ptr(), 0, $KEY_READ, &hkey )
151    {
152       if !RegQueryValueEx( hkey, valname.ptr(), 0, regtype, 0, &size )
153       {
154          this.expand( size )
155          if !RegQueryValueEx( hkey, valname.ptr(), 0, 0, this.ptr(), &size )
156          {
157             this.use = size
158          }
159       }
160       elif regtype : regtype->uint = 0
161       RegCloseKey( hkey )
162    }
163    return this
164 }
165 
166 /*-----------------------------------------------------------------------------
167 * Id: str_regget F2
168 * 
169 * Summary: Getting a value. This method writes the value of a registry key 
170            into a #a(string) object.
171 *  
172 * Params: root - A root key. $$[regroot] 
173           subkey - A name of the registry key. 
174           valname - A name of the specified key value.
175 *
176 * Return: #lng/retobj#
177 *
178 -----------------------------------------------------------------------------*/
179 
180 method str str.regget( uint root, str subkey, str valname )
181 {
182    uint  size itype
183 
184    this->buf.regget( root, subkey, valname, &itype )
185 
186    if itype == $REG_SZ || itype == $REG_EXPAND_SZ || itype == $REG_MULTI_SZ
187    {
188       this.setlenptr()
189    } 
190    elif itype == $REG_DWORD
191    {
192       size = this.ptr()->uint
193       this = str( size )
194    }
195    else : this->buf += byte( 0 )
196 
197    return this
198 }
199 
200 /*-----------------------------------------------------------------------------
201 * Id: str_regget_1 FA
202 * 
203 * Summary: This method writes the value of a registry key 
204            into a #a(string) object.
205 *  
206 * Params: root - A root key. $$[regroot] 
207           subkey - A name of the registry key. 
208           valname - A name of the specified key value.
209           defval - The default string in case there is no value.
210 *
211 * Return: #lng/retobj#
212 *
213 -----------------------------------------------------------------------------*/
214 
215 method str str.regget( uint root, str subkey, str valname, str defval )
216 {
217    uint  size itype
218 
219    if !regvaltype( root, subkey, valname )
220    {
221       this = defval
222    }
223    else : this.regget( root, subkey, valname )
224    
225    return this
226 }
227 
228 /*-----------------------------------------------------------------------------
229 * Id: reggetnum F
230 * 
231 * Summary: Get the numerical value of a registry key.
232 *  
233 * Params: root - A root key. $$[regroot] 
234           subkey - A name of the registry key. 
235           valname - A name of the specified key value.
236 *
237 * Return: A numerical value is returned.
238 *
239 -----------------------------------------------------------------------------*/
240 
241 func uint reggetnum( uint root, str subkey, str valname )
242 {
243    uint  size itype
244    buf   data
245    
246    data.regget( root, subkey, valname, &itype )
247 
248    if itype == $REG_SZ || itype == $REG_EXPAND_SZ || itype == $REG_MULTI_SZ
249    {
250       return data->str.uint()
251    } 
252    elif itype == $REG_DWORD
253    {
254       return data.ptr()->uint
255    }
256 
257    return 0
258 }
259 
260 /*-----------------------------------------------------------------------------
261 * Id: reggetnum_1 F8
262 * 
263 * Summary: Get the numerical value of a registry key.
264 *  
265 * Params: root - A root key. $$[regroot] 
266           subkey - A name of the registry key. 
267           valname - A name of the specified key value.
268           defval - The default number in case there is no value.
269 *
270 * Return: A numerical value is returned.
271 *
272 -----------------------------------------------------------------------------*/
273 
274 func uint reggetnum( uint root, str subkey, str valname, uint defval  )
275 {
276    if !regvaltype( root, subkey, valname ) : return defval
277    return reggetnum( root, subkey, valname )
278 }
279 
280 /*-----------------------------------------------------------------------------
281 * Id: regverify F
282 * 
283 * Summary: Creating missing keys. Check if there is a certain key in the
284            registry and create it if it is not there.
285 *  
286 * Params: root - A root key. $$[regroot] 
287           subkey - The name of the registry key being checked. 
288           ret - The array of strings all the created keys will be written to./
289                 It can be 0.
290 *
291 * Return: #lng/retf#
292 *
293 -----------------------------------------------------------------------------*/
294 
295 func uint regverify( uint root, str subkey, arrstr ret )
296 {
297    arrstr   keys 
298    str   key
299    uint  i hkey dwi
300    
301    subkey.fdelslash()
302    subkey.split( keys, '\', 0 )
303    if ret : ret.clear()
304    
305    fornum i, *keys 
306    {
307       key.faddname( keys[ i ] )
308       
309       if !RegCreateKeyEx( root, key.ptr(), 0, 0,
310               $REG_OPTION_NON_VOLATILE, $KEY_WRITE, 0, &hkey, &dwi )
311       {
312          if dwi == $REG_CREATED_NEW_KEY && ret
313          {
314             ret += key
315          }
316          RegCloseKey( hkey )
317       }
318       else : return 0
319    }
320    return 1
321 }
322 
323 /*-----------------------------------------------------------------------------
324 * Id: buf_regset F2
325 * 
326 * Summary: Writing a value. Write the data of an buf object as registry 
327            key value. If there is no key, it will be created.
328 *  
329 * Params: root - A root key. $$[regroot] 
330           subkey - A name of the registry key. 
331           valname - The name of the value being written.
332           regtype - Value type. $$[regtype]
333           ret - The array of strings all the created keys will be written to. /
334                 It can be 0.
335 *
336 * Return: $$[regsetret]
337 *
338 -----------------------------------------------------------------------------*/
339 
340 method uint buf.regset( uint root, str subkey, str valname, uint regtype, 
341                         arrstr ret )
342 {
343    uint  result size exist
344    uint  hkey dwi
345    
346    subkey.fdelslash()
347    if regvaltype( root, subkey, valname ) : exist = 1
348    else : regverify( root, subkey, ret )
349    
350    if !RegCreateKeyEx( root, subkey.ptr(), 0, 0, $REG_OPTION_NON_VOLATILE, 
351                        $KEY_WRITE | $KEY_READ, 0, &hkey, &dwi )
352    {
353       size = ?( regtype == $REG_DWORD, 4, *this )
354       
355       if !RegSetValueEx( hkey, valname.ptr(), 0, regtype, this.ptr(),
356                          size ) : result = 1 + exist
357       RegCloseKey( hkey )
358    } 
359    
360    return result
361 }
362 
363 /*-----------------------------------------------------------------------------
364 * Id: str_regset F2
365 * 
366 * Summary: Write a string as a registry key value. If there is no key, 
367            it will be created.
368 *  
369 * Params: root - A root key. $$[regroot] 
370           subkey - A name of the registry key. 
371           valname - The name of the value being written.
372           ret - The array of strings all the created keys will be written to. /
373                 It can be 0.
374 *
375 * Return: $$[regsetret]
376 *
377 -----------------------------------------------------------------------------*/
378 
379 method uint str.regset( uint root, str subkey, str valname, arrstr ret )
380 {
381    return this->buf.regset( root, subkey, valname, $REG_SZ, ret )
382 }
383 
384 /*-----------------------------------------------------------------------------
385 * Id: str_regset_1 FA
386 * 
387 * Summary: Write a string as a registry key value. If there is no key, 
388            it will be created.
389 *  
390 * Params: root - A root key. $$[regroot] 
391           subkey - A name of the registry key. 
392           valname - The name of the value being written.
393 *
394 * Return: $$[regsetret].
395 *
396 -----------------------------------------------------------------------------*/
397 
398 method uint str.regset( uint root, str subkey, str valname )
399 {
400    return this->buf.regset( root, subkey, valname, $REG_SZ, 0->arrstr )
401 }
402 
403 /*-----------------------------------------------------------------------------
404 * Id: regsetnum F
405 * 
406 * Summary: Write a number as a registry key value. If there is no key, it 
407            will be created.
408 *  
409 * Params: root - A root key. $$[regroot] 
410           subkey - A name of the registry key. 
411           valname - The name of the value being written.
412           value - The number being written.
413           ret - The array of strings all the created keys will be written to. /
414                 It can be 0.
415 *
416 * Return: $$[regsetret]
417 *
418 -----------------------------------------------------------------------------*/
419 
420 func uint regsetnum( uint root, str subkey, str valname, uint value, 
421                      arrstr ret  )
422 {
423    buf bnum
424    
425    bnum += value
426    return bnum.regset( root, subkey, valname, $REG_DWORD, ret )
427 }
428 
429 /*-----------------------------------------------------------------------------
430 * Id: regsetmultistr F
431 * 
432 * Summary: Writing a string sequence. Write an array of strings as a value of 
433            a registry key of the $REG_MULTISZ type. If there is no key, 
434            it will be created. 
435 *  
436 * Params: root - A root key. $$[regroot] 
437           subkey - A name of the registry key. 
438           valname - The name of the value being written.
439           val - The arrays of strings being written.
440           ret - The array of strings all the created keys will be written to. /
441                 It can be 0.
442 *
443 * Return: $$[regsetret]
444 *
445 -----------------------------------------------------------------------------*/
446 
447 func uint regsetmultistr( uint root, str subkey, str valname, arrstr val, 
448                          arrstr ret  )
449 {
450    buf bmulti
451    
452    //bmulti.setmultistr( val )
453    val.setmultistr( bmulti )
454    return bmulti.regset( root, subkey, valname, $REG_MULTI_SZ, ret )
455 }
456 
457 /*-----------------------------------------------------------------------------
458 * Id: reggetmultistr F
459 * 
460 * Summary: Getting a string sequence. Get the value of a registry key of 
461            the $REG_MULTISZ type into a string array.
462 *  
463 * Params: root - A root key. $$[regroot] 
464           subkey - A name of the registry key. 
465           valname - A name of the specified key value.
466           val - The array strings are written to.
467 *
468 * Return: #lng/retpar( val )
469 *
470 -----------------------------------------------------------------------------*/
471 
472 func arrstr reggetmultistr( uint root, str subkey, str valname, arrstr val )
473 {
474    buf   bmulti
475    uint  regtype
476 
477    val.clear()
478    bmulti.regget( root, subkey, valname, ®type )
479       
480    if regtype == $REG_MULTI_SZ || regtype == $REG_SZ || 
481       regtype == $REG_EXPAND_SZ
482    {
483       bmulti.getmultistr( val )
484    }
485    
486    return val
487 }
488 
489 func uint regenum( uint root, str subkey, arrstr ret, uint enumtype )
490 {
491    uint hkey index size
492    filetime ft
493    str      stemp
494    
495    subfunc int enum
496    {
497       if enumtype
498       {
499          return RegEnumValue( hkey, index++, stemp.ptr(), &size, 0, 0, 
500                             0, 0 )      
501       }
502       return RegEnumKeyEx( hkey, index++, stemp.ptr(), &size, 0, 0, 
503                               0, ft )      
504    }
505    
506    ret.clear()
507    if RegOpenKeyEx( root, subkey.ptr(), 0, $KEY_READ, &hkey )
508    {
509       return 0
510    }
511    size = 512
512    stemp.reserve( size )
513    
514    while enum() != $ERROR_NO_MORE_ITEMS 
515    {
516       stemp.setlenptr()
517       ret += stemp
518       size = 512
519    }
520    RegCloseKey( hkey )
521    return 1
522 }
523 
524 /*-----------------------------------------------------------------------------
525 * Id: regkeys F
526 * 
527 * Summary: Getting the list of keys.
528 *  
529 * Params: root - A root key. $$[regroot] 
530           subkey - A name of the registry key. 
531           ret - The array the names of the keys will be written to. 
532 *
533 * Return: #lng/retf#
534 *
535 -----------------------------------------------------------------------------*/
536 
537 func uint regkeys( uint root, str subkey, arrstr ret )
538 {
539    return regenum( root, subkey, ret, 0 )
540 }
541 
542 /*-----------------------------------------------------------------------------
543 * Id: regvalues F
544 * 
545 * Summary: Getting the list of values in a key.
546 *  
547 * Params: root - A root key. $$[regroot] 
548           subkey - A name of the registry key. 
549           ret - The array the names of values in the keys will be written to. 
550 *
551 * Return: #lng/retf#
552 *
553 -----------------------------------------------------------------------------*/
554 
555 func uint regvalues( uint root, str subkey, arrstr ret )
556 {
557    return regenum( root, subkey, ret, 1 )
558 }
559 
560 /*-----------------------------------------------------------------------------
561 * Id: regdelkey F
562 * 
563 * Summary: Deleting a registry key.
564 *  
565 * Params: root - A root key. $$[regroot] 
566           subkey - The name of the registry key being deleted. 
567 *
568 * Return: #lng/retf#
569 *
570 -----------------------------------------------------------------------------*/
571 
572 func uint regdelkey( uint root, str subkey )
573 {
574    arrstr keys
575    uint  i
576    str   stemp
577    
578    if !regkeys( root, subkey, keys )
579    {
580       return 0
581    }
582    fornum i, *keys
583    {
584       stemp = subkey
585       if !regdelkey( root, stemp.faddname( keys[ i ] )) : return 0
586    }
587    return !RegDeleteKey( root, subkey.ptr())
588 }
589 
590 /*-----------------------------------------------------------------------------
591 ** Id: regdelvalue F
592 * 
593 * Summary: Deleting the value of a key.
594 *  
595 * Params: root - A root key. $$[regroot] 
596           subkey - A name of the registry key.
597           value - The name of the value being deleted. 
598 *
599 * Return: #lng/retf#
600 *
601 -----------------------------------------------------------------------------*/
602 
603 func uint regdelvalue( uint root, str subkey, str value )
604 {
605    uint hkey
606    uint result
607    
608    if !RegOpenKeyEx( root, subkey.ptr(), 0, $KEY_WRITE, &hkey )
609    {
610       result = !RegDeleteValue( hkey, value.ptr())
611       RegCloseKey( hkey )
612    }
613    return result
614 }
615