summary refs log blame commit diff stats
path: root/lib/windows/registry.nim
blob: 207172f8ca29ea9377991cd5d9720d06b2b480a2 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11










                                                            
                   
 


                                   


































                                                                      
                    

                                            
                                                                      


                                                                            
                                                                       
                   
                                       
                                                                   

                                 

                               
                   
                                       
                                                               

                                 




                                                                             
                                                             




                                                                  
#
#
#            Nim's Runtime Library
#        (c) Copyright 2016 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

## This module is experimental and its interface may change.

import std/oserrors

when defined(nimPreviewSlimSystem):
  import std/widestrs

type
  HKEY* = uint

const
  HKEY_LOCAL_MACHINE* = HKEY(0x80000002u)
  HKEY_CURRENT_USER* = HKEY(2147483649)

  RRF_RT_ANY = 0x0000ffff
  KEY_WOW64_64KEY = 0x0100
  KEY_WOW64_32KEY = 0x0200
  KEY_READ = 0x00020019
  REG_SZ = 1

proc regOpenKeyEx(hKey: HKEY, lpSubKey: WideCString, ulOptions: int32,
                  samDesired: int32,
                  phkResult: var HKEY): int32 {.
  importc: "RegOpenKeyExW", dynlib: "Advapi32.dll", stdcall.}

proc regCloseKey(hkey: HKEY): int32 {.
  importc: "RegCloseKey", dynlib: "Advapi32.dll", stdcall.}

proc regGetValue(key: HKEY, lpSubKey, lpValue: WideCString;
                 dwFlags: int32 = RRF_RT_ANY, pdwType: ptr int32,
                 pvData: pointer,
                 pcbData: ptr int32): int32 {.
  importc: "RegGetValueW", dynlib: "Advapi32.dll", stdcall.}

template call(f) =
  let err = f
  if err != 0:
    raiseOSError(err.OSErrorCode, astToStr(f))

proc getUnicodeValue*(path, key: string; handle: HKEY): string =
  let hh = newWideCString path
  let kk = newWideCString key
  var bufSize: int32
  # try a couple of different flag settings:
  var flags: int32 = RRF_RT_ANY
  let err = regGetValue(handle, hh, kk, flags, nil, nil, addr bufSize)
  if err != 0:
    var newHandle: HKEY
    call regOpenKeyEx(handle, hh, 0, KEY_READ or KEY_WOW64_64KEY, newHandle)
    call regGetValue(newHandle, nil, kk, flags, nil, nil, addr bufSize)
    if bufSize > 0:
      var res = newWideCString(bufSize)
      call regGetValue(newHandle, nil, kk, flags, nil, addr res[0],
                    addr bufSize)
      result = res $ bufSize
    call regCloseKey(newHandle)
  else:
    if bufSize > 0:
      var res = newWideCString(bufSize)
      call regGetValue(handle, hh, kk, flags, nil, addr res[0],
                    addr bufSize)
      result = res $ bufSize

proc regSetValue(key: HKEY, lpSubKey, lpValueName: WideCString,
                 dwType: int32; lpData: WideCString; cbData: int32): int32 {.
  importc: "RegSetKeyValueW", dynlib: "Advapi32.dll", stdcall.}

proc setUnicodeValue*(path, key, val: string; handle: HKEY) =
  let hh = newWideCString path
  let kk = newWideCString key
  let vv = newWideCString val
  call regSetValue(handle, hh, kk, REG_SZ, vv, (vv.len.int32+1)*2)