registry.nim 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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. let hh = newWideCString path
  40. let kk = newWideCString key
  41. var bufSize: int32
  42. # try a couple of different flag settings:
  43. var flags: int32 = RRF_RT_ANY
  44. let err = regGetValue(handle, hh, kk, flags, nil, nil, addr bufSize)
  45. if err != 0:
  46. var newHandle: HKEY
  47. call regOpenKeyEx(handle, hh, 0, KEY_READ or KEY_WOW64_64KEY, newHandle)
  48. call regGetValue(newHandle, nil, kk, flags, nil, nil, addr bufSize)
  49. if bufSize > 0:
  50. var res = newWideCString(bufSize)
  51. call regGetValue(newHandle, nil, kk, flags, nil, addr res[0],
  52. addr bufSize)
  53. result = res $ bufSize
  54. call regCloseKey(newHandle)
  55. else:
  56. if bufSize > 0:
  57. var res = newWideCString(bufSize)
  58. call regGetValue(handle, hh, kk, flags, nil, addr res[0],
  59. addr bufSize)
  60. result = res $ bufSize
  61. proc regSetValue(key: HKEY, lpSubKey, lpValueName: WideCString,
  62. dwType: int32; lpData: WideCString; cbData: int32): int32 {.
  63. importc: "RegSetKeyValueW", dynlib: "Advapi32.dll", stdcall.}
  64. proc setUnicodeValue*(path, key, val: string; handle: HKEY) =
  65. let hh = newWideCString path
  66. let kk = newWideCString key
  67. let vv = newWideCString val
  68. call regSetValue(handle, hh, kk, REG_SZ, vv, (vv.len.int32+1)*2)