registry.nim 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. if bufSize > 0:
  48. var res = newWideCString(bufsize)
  49. call regGetValue(newHandle, nil, kk, flags, nil, addr res[0],
  50. addr bufsize)
  51. result = res $ bufsize
  52. call regCloseKey(newHandle)
  53. else:
  54. if bufSize > 0:
  55. var res = newWideCString(bufsize)
  56. call regGetValue(handle, hh, kk, flags, nil, addr res[0],
  57. addr bufsize)
  58. result = res $ bufsize
  59. proc regSetValue(key: HKEY, lpSubKey, lpValueName: WideCString,
  60. dwType: int32; lpData: WideCString; cbData: int32): int32 {.
  61. importc: "RegSetKeyValueW", dynlib: "Advapi32.dll", stdcall.}
  62. proc setUnicodeValue*(path, key, val: string; handle: HKEY) =
  63. let hh = newWideCString path
  64. let kk = newWideCString key
  65. let vv = newWideCString val
  66. call regSetValue(handle, hh, kk, REG_SZ, vv, (vv.len.int32+1)*2)