regUtil.vbs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. ' TODO: consider incorporating a json writer of some sort instead of adhoc solution like the following
  2. ' e.g: http://demon.tw/my-work/vbs-json.html
  3. const HKEY_CLASSES_ROOT = &H80000000
  4. const HKEY_CURRENT_USER = &H80000001
  5. const HKEY_LOCAL_MACHINE = &H80000002
  6. const HKEY_USERS = &H80000003
  7. const HKEY_CURRENT_CONFIG = &H80000005
  8. Sub LoadRegistryImplementationByOSArchitecture()
  9. If IsNull(OSArchitecture) Then
  10. WriteLineErr "missing OSArchitecture global. did not call util.DetermineOSArchitecture? or Forgot to load util.vbs?"
  11. WScript.Quit 25125
  12. End If
  13. If OSArchitecture = "A" Then
  14. Include "ArchitectureAgnosticRegistry.vbs"
  15. Else
  16. Include "ArchitectureSpecificRegistry.vbs"
  17. End If
  18. End Sub
  19. Function PutValue(constHive, strSubKey, strValueName, strValue, strType)
  20. Select Case UCase(strType)
  21. Case "REG_SZ"
  22. PutValue = SetStringValue(constHive, strSubKey, strValueName, strValue)
  23. Case "REG_EXPAND_SZ"
  24. PutValue = SetExpandedStringValue(constHive, strSubKey, strValueName, strValue)
  25. Case "REG_BINARY"
  26. PutValue = SetBinaryValue(constHive, strSubKey, strValueName, ToBinaryValue(strValue))
  27. Case "REG_NONE"
  28. PutValue = SetBinaryValue(constHive, strSubKey, strValueName, ToBinaryValue(strValue))
  29. ' TODO: need to check that indeed int is the right type here
  30. Case "REG_DWORD"
  31. PutValue = SetDWORDValue(constHive, strSubKey, strValueName, CDbl(strValue))
  32. Case "REG_MULTI_SZ"
  33. PutValue = SetMultiStringValue(constHive, strSubKey, strValueName, Split(strValue, ","))
  34. Case "REG_QWORD"
  35. PutValue = SetQWORDValue(constHive, strSubKey, strValueName, strValue)
  36. Case "REG_DEFAULT"
  37. PutValue = SetStringValue(constHive, strSubKey, "", strValue)
  38. Case Else
  39. PutValue = SetStringValue(constHive, strSubKey, strValueName, strValue)
  40. End Select
  41. End Function
  42. ' render the child of a sub path strSubKey in hive constHive
  43. ' as json.
  44. Sub ListChildrenAsJson(constHive, strSubKey)
  45. ' start outputting json to stdout
  46. Write "{"
  47. Dim e1: e1 = EnumKey (constHive, strSubKey, arrKeyNames)
  48. If e1 <> 0 Then
  49. Write """exists"": false,"
  50. Dim arrValueNames: arrValueNames = null
  51. Else
  52. Write """exists"": true,"
  53. Dim e2: e2 = EnumValues (constHive, strSubKey, arrValueNames, arrValueTypes)
  54. If e2 <> 0 Then
  55. WScript.Quit e2
  56. End If
  57. End If
  58. Write """keys"": ["
  59. If Not IsNull(arrKeyNames) Then
  60. For x = 0 To UBound(arrKeyNames)
  61. If (x > 0) Then
  62. Write ","
  63. End If
  64. Write """" & JsonSafe(arrKeyNames(x)) & """"
  65. Next
  66. End If
  67. Write "],"
  68. ' TODO: some duplicity of code between the two paths of this condition, this needs to be address at some point
  69. Write """values"":{"
  70. If Not IsNull(arrValueNames) Then
  71. For y = 0 To UBound(arrValueNames)
  72. If y > 0 Then
  73. Write ","
  74. End If
  75. strValueName = arrValueNames(y)
  76. intValueType = arrValueTypes(y)
  77. ' assign the value to varValue
  78. GetValueByType constHive, strSubKey, strValueName, intValueType, varValue
  79. WriteValue strValueName, intValueType, varValue
  80. Next
  81. Else
  82. ' fix for keys with only default values in them
  83. ' see http://stackoverflow.com/questions/8840343/how-to-read-the-default-value-from-registry-in-vbscript
  84. GetStringValue constHive, strSubKey, "", strDefaultValue
  85. If IsNull(strDefaultValue) = false and strDefaultValue <> "" Then
  86. ' write the default value with REG_SZ
  87. WriteValue "", 1, strDefaultValue
  88. End If
  89. End If
  90. Write "}}"
  91. End Sub
  92. Sub WriteValue (strValueName, intValueType, varValue)
  93. Write """"
  94. Write JsonSafe(strValueName)
  95. Write """:{"
  96. Write """type"": """
  97. Write RenderType(intValueType)
  98. Write ""","
  99. Write """value"":"
  100. Write RenderValueByType(intValueType, varValue)
  101. Write "}"
  102. End Sub
  103. ' give a raw HKLM\something\somewhere
  104. ' output the hive constant and the subkey, in this case:
  105. ' HKEY_LOCAL_MACHINE will be assigned to outConstHive
  106. ' and something\somewhere will be assigned to outStrSubKey
  107. Sub ParseHiveAndSubKey(strRawKey, outConstHive, outStrSubKey)
  108. ' split into two parts to deduce the hive and the sub key
  109. arrSplitted = Split(strRawKey, "\", 2, 1)
  110. If UBound(arrSplitted) > 0 Then
  111. strHive = arrSplitted(0)
  112. outStrSubKey = arrSplitted(1)
  113. Else
  114. strHive = strRawKey
  115. outStrSubKey = ""
  116. End If
  117. outConstHive = StringToHiveConst(UCase(strHive))
  118. End Sub
  119. Function ArrayRemoveAt(arr, pos)
  120. Dim i
  121. If IsArray(arr) Then
  122. If pos >= 0 And pos <= UBound(arr) Then
  123. For i = pos To UBound(arr) - 1
  124. arr(i) = arr(i + 1)
  125. Next
  126. ReDim Preserve arr(UBound(arr) - 1)
  127. End If
  128. End If
  129. End Function
  130. Sub ParseHiveAndSubKeyAndValue(strRawKey, outConstHive, outStrSubKey, outStrValue)
  131. ' split into two parts to deduce the hive and the sub key
  132. arrSplitted = Split(strRawKey, "\", -1, 1)
  133. If UBound(arrSplitted) > 0 Then
  134. strHive = arrSplitted(0)
  135. outStrValue = arrSplitted(UBound(arrSplitted))
  136. test = ArrayRemoveAt(arrSplitted, UBound(arrSplitted))
  137. test = ArrayRemoveAt(arrSplitted, 0)
  138. outStrSubKey = Join(arrSplitted, "\")
  139. Else
  140. strHive = strRawKey
  141. outStrSubKey = ""
  142. End If
  143. outConstHive = StringToHiveConst(UCase(strHive))
  144. End Sub
  145. Function StringToHiveConst(strHive)
  146. Select Case strHive
  147. Case "HKCR"
  148. StringToHiveConst = HKEY_CLASSES_ROOT
  149. Case "HKCU"
  150. StringToHiveConst = HKEY_CURRENT_USER
  151. Case "HKLM"
  152. StringToHiveConst = HKEY_LOCAL_MACHINE
  153. Case "HKU"
  154. StringToHiveConst = HKEY_USERS
  155. Case "HKCC"
  156. StringToHiveConst = HKEY_CURRENT_CONFIG
  157. Case Else
  158. StringToHiveConst = Null
  159. End Select
  160. End Function
  161. ' TODO: this entire "by type" should be transformed into OOP style
  162. ' where each type will have a class with render(), getValue() etc...
  163. ' convert a value type number into a string label
  164. Function RenderType(intType)
  165. RenderType = "REG_UNKNOWN"
  166. Select Case intType
  167. Case 0
  168. RenderType = "REG_NONE"
  169. Case 1
  170. RenderType = "REG_SZ"
  171. Case 2
  172. RenderType = "REG_EXPAND_SZ"
  173. Case 3
  174. RenderType = "REG_BINARY"
  175. Case 4
  176. RenderType = "REG_DWORD"
  177. Case 7
  178. RenderType = "REG_MULTI_SZ"
  179. Case 11
  180. RenderType = "REG_QWORD"
  181. Case Else
  182. ' TODO: should report / throw an error here
  183. WriteErr("invalid Registry Value Type " & intType)
  184. End Select
  185. End Function
  186. ' render by value type:
  187. ' string will return as a string with double quotes, e.g "value"
  188. ' multi string values which return as an array ot strings "["1", "2"]" (double quotes included ofc)
  189. ' numeric values like DWORD and QWORD just return as the number e.g. 1
  190. ' byte arrays such as reg_binary return as an array of ints, e.g [1,2,3]
  191. Function RenderValueByType(intType, varValue)
  192. Select Case intType
  193. ' REG_NONE
  194. Case 0
  195. RenderValueByType = "0"
  196. ' REG_SZ
  197. Case 1
  198. RenderValueByType = """" & JsonSafe(varValue) & """"
  199. ' REG_EXPAND_SZ
  200. Case 2
  201. RenderValueByType = """" & JsonSafe(varValue) & """"
  202. ' REG_BINARY
  203. Case 3
  204. RenderValueByType = RenderByteArray(varValue)
  205. ' REG_DWORD
  206. Case 4
  207. RenderValueByType= varValue
  208. ' REG_MULYI_SZ'
  209. Case 7
  210. RenderValueByType = RenderStringArray(varValue)
  211. ' REG_QWORD
  212. Case 11
  213. RenderValueByType = varValue
  214. Case Else
  215. ' TODO: should report / throw an error here
  216. WriteErr("invalid Registry Value Type " & intType)
  217. End Select
  218. End Function
  219. ' get the value of a registry based on its value type and assign it to out parameter outVarValue
  220. Sub GetValueByType(constHive, strKey, strValueName, intType, outVarValue)
  221. Select Case intType
  222. ' REG_NONE
  223. Case 0
  224. GetStringValue constHive, strKey, strValueName, "0"
  225. Exit Sub
  226. ' REG_SZ
  227. Case 1
  228. GetStringValue constHive, strKey, strValueName, outVarValue
  229. Exit Sub
  230. ' REG_EXPAND_SZ
  231. Case 2
  232. GetExpandedStringValue constHive, strKey, strValueName, outVarValue
  233. Exit Sub
  234. ' REG_BINARY
  235. Case 3
  236. GetBinaryValue constHive, strKey, strValueName, outVarValue
  237. Exit Sub
  238. ' REG_DWORD
  239. Case 4
  240. GetDWORDValue constHive, strKey, strValueName, outVarValue
  241. ' #21 - VBS does not support UInt32. This is the workaround
  242. If outVarValue < 0 Then outVarValue = 4294967296 + outVarValue
  243. Exit Sub
  244. ' REG_MULYI_SZ'
  245. Case 7
  246. GetMultiStringValue constHive, strKey, strValueName, outVarValue
  247. Exit Sub
  248. ' REG_QWORD
  249. Case 11
  250. GetQWORDValue constHive, strKey, strValueName, outVarValue
  251. Exit Sub
  252. Case Else
  253. ' TODO: should report / throw an error here
  254. WriteErr("invalid Registry Value Type " & intType)
  255. End Select
  256. End Sub
  257. ' render a byte array as a json array of numbers
  258. Function RenderByteArray(arr)
  259. RenderByteArray = "[]"
  260. If Not IsNull(arr) Then
  261. RenderByteArray = "[" & Join(arr, ",") & "]"
  262. End If
  263. End Function
  264. ' render a string array as json string array
  265. Function RenderStringArray(arr)
  266. Result = "["
  267. If Not IsNull(arr) Then
  268. For t = 0 To UBound(arr)
  269. If (t > 0) Then
  270. Result = Result & ","
  271. End If
  272. Result = Result & """" & JsonSafe(arr(t)) & """"
  273. Next
  274. End If
  275. Result = Result & "]"
  276. RenderStringArray = Result
  277. End Function
  278. Function ToBinaryValue(strValue)
  279. arrValue = Split(strValue, ",")
  280. If IsNull(arrValue) Then
  281. ToBinaryValue = Array()
  282. Exit Function
  283. End If
  284. For i = 0 To UBound(arrValue)
  285. arrValue(i) = CInt(arrValue(i))
  286. Next
  287. ToBinaryValue = arrValue
  288. End Function