nim-confutils/confutils/winreg/utils.nim

156 lines
4.4 KiB
Nim

import
strutils, os,
./types
type
SomePrimitives* = SomeInteger | enum | bool | SomeFloat | char
const
REG_SZ* = RegType(1)
REG_BINARY* = RegType(3)
REG_DWORD* = RegType(4)
REG_QWORD* = RegType(11)
RT_SZ* = 0x00000002
RT_BINARY* = 0x00000008
RT_DWORD* = 0x00000010
RT_QWORD* = 0x00000040
RT_ANY* = 0x0000ffff
MAX_ELEM_SIZE = 16_383'i32
proc regGetValue(hKey: HKEY, lpSubKey, lpValue: cstring,
dwFlags: int32, pdwType: ptr RegType,
pvData: pointer, pcbData: ptr int32): int32 {.
importc: "RegGetValueA", dynlib: "Advapi32.dll", stdcall.}
proc regSetValue(hKey: HKEY, lpSubKey, lpValueName: cstring,
dwType: RegType; lpData: pointer; cbData: int32): int32 {.
importc: "RegSetKeyValueA", dynlib: "Advapi32.dll", stdcall.}
template call(f) =
if f != 0:
return false
proc setValue*(hKey: HKEY, path, key: string, val: SomePrimitives): bool =
when sizeof(val) < 8:
var dw = cast[int32](val)
call regSetValue(hKey, path, key, REG_DWORD, dw.addr, sizeof(dw).int32)
else:
var dw = cast[int64](val)
call regSetValue(hKey, path, key, REG_QWORD, dw.addr, sizeof(dw).int32)
result = true
proc setValue*[T: SomePrimitives](hKey: HKEY, path, key: string, val: openArray[T]): bool =
call regSetValue(hKey, path, key, REG_BINARY, val[0].unsafeAddr, int32(val.len * sizeof(T)))
result = true
proc getValue*(hKey: HKEY, path, key: string, outVal: var string): bool =
var size: int32
call regGetValue(hKey, path, key, RT_BINARY, nil, nil, addr size)
outVal.setLen(size)
call regGetValue(hKey, path, key, RT_BINARY, nil, outVal[0].addr, addr size)
result = true
proc getValue*[T: SomePrimitives](hKey: HKEY, path, key: string, outVal: var seq[T]): bool =
var size: int32
call regGetValue(hKey, path, key, RT_BINARY, nil, nil, addr size)
outVal.setLen(size div sizeof(T))
call regGetValue(hKey, path, key, RT_BINARY, nil, outVal[0].addr, addr size)
result = true
proc getValue*[N, T: SomePrimitives](hKey: HKEY, path, key: string, outVal: var array[N, T]): bool =
var size: int32
call regGetValue(hKey, path, key, RT_BINARY, nil, nil, addr size)
if outVal.len != size div sizeof(T):
return false
call regGetValue(hKey, path, key, RT_BINARY, nil, outVal[0].addr, addr size)
result = true
proc getValue*(hKey: HKEY, path, key: string, outVal: var SomePrimitives): bool =
when sizeof(outVal) < 8:
type T = type outVal
var val: int32
var valSize = sizeof(val).int32
call regGetValue(hKey, path, key, RT_DWORD, nil, val.addr, valSize.addr)
outVal = cast[T](val)
else:
var valSize = sizeof(outVal).int32
call regGetValue(hKey, path, key, RT_QWORD, nil, outVal.addr, valSize.addr)
result = true
proc pathExists*(hKey: HKEY, path, key: string): bool {.inline.} =
result = regGetValue(hKey, path, key, RT_ANY, nil, nil, nil) == 0
proc parseWinregPath*(input: string): (HKEY, string) =
let pos = input.find('\\')
if pos < 0: return
result[1] = input.substr(pos + 1)
case input.substr(0, pos - 1)
of "HKEY_CLASSES_ROOT", "HKCR":
result[0] = HKCR
of "HKEY_CURRENT_USER", "HKCU":
result[0] = HKCU
of "HKEY_LOCAL_MACHINE", "HKLM":
result[0] = HKLM
of "HKEY_USERS", "HKU":
result[0] = HKU
else:
discard
proc `$`*(hKey: HKEY): string =
case hKey
of HKCR: result = "HKEY_CLASSES_ROOT"
of HKCU: result = "HKEY_CURRENT_USER"
of HKLM: result = "HKEY_LOCAL_MACHINE"
of HKU : result = "HKEY_USERS"
else: discard
template uTypeIsPrimitives*[T](_: type seq[T]): bool =
when T is SomePrimitives:
true
else:
false
template uTypeIsPrimitives*[N, T](_: type array[N, T]): bool =
when T is SomePrimitives:
true
else:
false
template uTypeIsPrimitives*[T](_: type openArray[T]): bool =
when T is SomePrimitives:
true
else:
false
template uTypeIsRecord*(_: typed): bool =
false
template uTypeIsRecord*[T](_: type seq[T]): bool =
when T is (object or tuple):
true
else:
false
template uTypeIsRecord*[N, T](_: type array[N, T]): bool =
when T is (object or tuple):
true
else:
false
func constructPath*(root: string, keys: openArray[string]): string =
if keys.len <= 1:
return root
var size = root.len + 1
for i in 0..<keys.len-1:
inc(size, keys[i].len + 1)
result = newStringOfCap(size)
result.add root
result. add '\\'
for i in 0..<keys.len-1:
result.add keys[i]
if i < keys.len-2:
result. add '\\'