registry.nim 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2016 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## This module is experimental and its interface may change.
  10. import winlean, os
  11. type
  12. HKEY* = uint
  13. const
  14. HKEY_LOCAL_MACHINE* = HKEY(0x80000002u)
  15. HKEY_CURRENT_USER* = HKEY(2147483649)
  16. RRF_RT_ANY = 0x0000ffff
  17. KEY_WOW64_64KEY = 0x0100
  18. KEY_WOW64_32KEY = 0x0200
  19. KEY_READ = 0x00020019
  20. REG_SZ = 1
  21. proc regOpenKeyEx(hKey: HKEY, lpSubKey: WideCString, ulOptions: int32,
  22. samDesired: int32,
  23. phkResult: var HKEY): int32 {.
  24. importc: "RegOpenKeyExW", dynlib: "Advapi32.dll", stdcall.}
  25. proc regCloseKey(hkey: HKEY): int32 {.
  26. importc: "RegCloseKey", dynlib: "Advapi32.dll", stdcall.}
  27. proc regGetValue(key: HKEY, lpSubKey, lpValue: WideCString;
  28. dwFlags: int32 = RRF_RT_ANY, pdwType: ptr int32,
  29. pvData: pointer,
  30. pcbData: ptr int32): int32 {.
  31. importc: "RegGetValueW", dynlib: "Advapi32.dll", stdcall.}
  32. template call(f) =
  33. let err = f
  34. if err != 0:
  35. raiseOSError(err.OSErrorCode, astToStr(f))
  36. proc getUnicodeValue*(path, key: string; handle: HKEY): string =
  37. let hh = newWideCString path
  38. let kk = newWideCString key
  39. var bufsize: int32
  40. # try a couple of different flag settings:
  41. var flags: int32 = RRF_RT_ANY
  42. let err = regGetValue(handle, hh, kk, flags, nil, nil, addr bufsize)
  43. if err != 0:
  44. var newHandle: HKEY
  45. call regOpenKeyEx(handle, hh, 0, KEY_READ or KEY_WOW64_64KEY, newHandle)
  46. call regGetValue(newHandle, nil, kk, flags, nil, nil, addr bufsize)
  47. var res = newWideCString("", bufsize)
  48. call regGetValue(newHandle, nil, kk, flags, nil, cast[pointer](res),
  49. addr bufsize)
  50. result = res $ bufsize
  51. call regCloseKey(newHandle)
  52. else:
  53. var res = newWideCString("", bufsize)
  54. call regGetValue(handle, hh, kk, flags, nil, cast[pointer](res),
  55. addr bufsize)
  56. result = res $ bufsize
  57. proc regSetValue(key: HKEY, lpSubKey, lpValueName: WideCString,
  58. dwType: int32; lpData: WideCString; cbData: int32): int32 {.
  59. importc: "RegSetKeyValueW", dynlib: "Advapi32.dll", stdcall.}
  60. proc setUnicodeValue*(path, key, val: string; handle: HKEY) =
  61. let hh = newWideCString path
  62. let kk = newWideCString key
  63. let vv = newWideCString val
  64. call regSetValue(handle, hh, kk, REG_SZ, vv, (vv.len.int32+1)*2)