registry.nim 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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 std/oserrors
  11. when defined(nimPreviewSlimSystem):
  12. import std/widestrs
  13. type
  14. HKEY* = uint
  15. const
  16. HKEY_LOCAL_MACHINE* = HKEY(0x80000002u)
  17. HKEY_CURRENT_USER* = HKEY(2147483649)
  18. RRF_RT_ANY = 0x0000ffff
  19. KEY_WOW64_64KEY = 0x0100
  20. KEY_WOW64_32KEY = 0x0200
  21. KEY_READ = 0x00020019
  22. REG_SZ = 1
  23. proc regOpenKeyEx(hKey: HKEY, lpSubKey: WideCString, ulOptions: int32,
  24. samDesired: int32,
  25. phkResult: var HKEY): int32 {.
  26. importc: "RegOpenKeyExW", dynlib: "Advapi32.dll", stdcall.}
  27. proc regCloseKey(hkey: HKEY): int32 {.
  28. importc: "RegCloseKey", dynlib: "Advapi32.dll", stdcall.}
  29. proc regGetValue(key: HKEY, lpSubKey, lpValue: WideCString;
  30. dwFlags: int32 = RRF_RT_ANY, pdwType: ptr int32,
  31. pvData: pointer,
  32. pcbData: ptr int32): int32 {.
  33. importc: "RegGetValueW", dynlib: "Advapi32.dll", stdcall.}
  34. template call(f) =
  35. let err = f
  36. if err != 0:
  37. raiseOSError(err.OSErrorCode, astToStr(f))
  38. proc getUnicodeValue*(path, key: string; handle: HKEY): string =
  39. result = ""
  40. let hh = newWideCString path
  41. let kk = newWideCString key
  42. var bufSize: int32 = int32(0)
  43. # try a couple of different flag settings:
  44. var flags: int32 = RRF_RT_ANY
  45. let err = regGetValue(handle, hh, kk, flags, nil, nil, addr bufSize)
  46. if err != 0:
  47. var newHandle: HKEY = default(HKEY)
  48. call regOpenKeyEx(handle, hh, 0, KEY_READ or KEY_WOW64_64KEY, newHandle)
  49. call regGetValue(newHandle, nil, kk, flags, nil, nil, addr bufSize)
  50. if bufSize > 0:
  51. var res = newWideCString(bufSize)
  52. call regGetValue(newHandle, nil, kk, flags, nil, addr res[0],
  53. addr bufSize)
  54. result = res $ bufSize
  55. call regCloseKey(newHandle)
  56. else:
  57. if bufSize > 0:
  58. var res = newWideCString(bufSize)
  59. call regGetValue(handle, hh, kk, flags, nil, addr res[0],
  60. addr bufSize)
  61. result = res $ bufSize
  62. proc regSetValue(key: HKEY, lpSubKey, lpValueName: WideCString,
  63. dwType: int32; lpData: WideCString; cbData: int32): int32 {.
  64. importc: "RegSetKeyValueW", dynlib: "Advapi32.dll", stdcall.}
  65. proc setUnicodeValue*(path, key, val: string; handle: HKEY) =
  66. let hh = newWideCString path
  67. let kk = newWideCString key
  68. let vv = newWideCString val
  69. call regSetValue(handle, hh, kk, REG_SZ, vv, (vv.len.int32+1)*2)