153 lines
4.4 KiB
Nim
153 lines
4.4 KiB
Nim
|
import
|
||
|
strutils,
|
||
|
serialization/errors
|
||
|
|
||
|
type
|
||
|
HKEY* = distinct uint
|
||
|
RegType* = distinct int32
|
||
|
WinregError* = object of SerializationError
|
||
|
SomePrimitives* = SomeInteger | enum | bool | SomeFloat | char
|
||
|
|
||
|
const
|
||
|
HKEY_CLASSES_ROOT* = HKEY(0x80000000'u)
|
||
|
HKEY_CURRENT_USER* = HKEY(0x80000001'u)
|
||
|
HKEY_LOCAL_MACHINE* = HKEY(0x80000002'u)
|
||
|
HKEY_USERS* = HKEY(0x80000003'u)
|
||
|
|
||
|
HKLM* = HKEY_LOCAL_MACHINE
|
||
|
HKCU* = HKEY_CURRENT_USER
|
||
|
HKCR* = HKEY_CLASSES_ROOT
|
||
|
HKU* = HKEY_USERS
|
||
|
|
||
|
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
|
||
|
|
||
|
proc `==`*(a, b: HKEY): bool {.borrow.}
|
||
|
proc `==`*(a, b: RegType): bool {.borrow.}
|
||
|
|
||
|
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 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
|