Class: Chef::Win32::Registry

Inherits:
Object
  • Object
show all
Extended by:
Mixin::WideString, ReservedNames::Win32::API::Registry
Includes:
Mixin::WideString, ReservedNames::Win32::API::Registry
Defined in:
lib/chef/win32/registry.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Mixin::WideString

utf8_to_wide, wide_to_utf8, wstring

Constructor Details

#initialize(run_context = nil, user_architecture = :machine) ⇒ Registry

Returns a new instance of Registry.



51
52
53
54
# File 'lib/chef/win32/registry.rb', line 51

def initialize(run_context = nil, user_architecture = :machine)
  @run_context = run_context
  self.architecture = user_architecture
end

Instance Attribute Details

#architectureObject

Returns the value of attribute architecture.



49
50
51
# File 'lib/chef/win32/registry.rb', line 49

def architecture
  @architecture
end

#run_contextObject

Returns the value of attribute run_context.



48
49
50
# File 'lib/chef/win32/registry.rb', line 48

def run_context
  @run_context
end

Instance Method Details

#create_key(key_path, recursive) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/chef/win32/registry.rb', line 112

def create_key(key_path, recursive)
  Chef::Log.trace("Creating registry key #{key_path}")
  if keys_missing?(key_path)
    if recursive == true
      Chef::Log.trace("Registry key #{key_path} has missing subkeys, and recursive specified, creating them....")
      create_missing(key_path)
    else
      raise Chef::Exceptions::Win32RegNoRecursive, "Registry key #{key_path} has missing subkeys, and recursive not specified"
    end
  end
  if key_exists?(key_path)
    Chef::Log.trace("Registry key #{key_path} already exists, doing nothing")
  else
    hive, key = get_hive_and_key(key_path)
    hive.create(key, ::Win32::Registry::KEY_WRITE | registry_system_architecture)
    Chef::Log.trace("Registry key #{key_path} created")
  end
  true
end

#data_exists!(key_path, value) ⇒ Object



243
244
245
246
247
248
249
# File 'lib/chef/win32/registry.rb', line 243

def data_exists!(key_path, value)
  unless data_exists?(key_path, value)
    raise Chef::Exceptions::Win32RegDataMissing, "Registry key #{key_path} has no value named #{value[:name]}, containing type #{value[:type]} and data #{value[:data]}"
  end

  true
end

#data_exists?(key_path, value) ⇒ Boolean

Returns:

  • (Boolean)


220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/chef/win32/registry.rb', line 220

def data_exists?(key_path, value)
  key_exists!(key_path)
  hive, key = get_hive_and_key(key_path)
  hive.open(key, ::Win32::Registry::KEY_READ | registry_system_architecture) do |reg|
    reg.each do |val_name, val_type, val_data|
      if safely_downcase(val_name) == safely_downcase(value[:name]) &&
          val_type == get_type_from_name(value[:type]) &&
          val_data == value[:data]
        return true
      end
    end
  end
  false
end

#delete_key(key_path, recursive) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/chef/win32/registry.rb', line 132

def delete_key(key_path, recursive)
  Chef::Log.trace("Deleting registry key #{key_path}")
  unless key_exists?(key_path)
    Chef::Log.trace("Registry key #{key_path}, does not exist, not deleting")
    return true
  end
  if has_subkeys?(key_path) && !recursive
    raise Chef::Exceptions::Win32RegNoRecursive, "Registry key #{key_path} has subkeys, and recursive not specified"
  end

  hive, key_including_parent = get_hive_and_key(key_path)
  # key_including_parent: Software\\Root\\Branch\\Fruit
  # key => Fruit
  # key_parent => Software\\Root\\Branch
  key_parts = key_including_parent.split("\\")
  key = key_parts.pop
  key_parent = key_parts.join("\\")
  hive.open(key_parent, ::Win32::Registry::KEY_WRITE | registry_system_architecture) do |reg|
    reg.delete_key(key, recursive)
  end
  Chef::Log.trace("Registry key #{key_path} deleted")
  true
end

#delete_value(key_path, value) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/chef/win32/registry.rb', line 94

def delete_value(key_path, value)
  Chef::Log.trace("Deleting value #{value[:name]} from registry key #{key_path}")
  if value_exists?(key_path, value)
    begin
      hive, key = get_hive_and_key(key_path)
    rescue Chef::Exceptions::Win32RegKeyMissing
      return true
    end
    hive.open(key, ::Win32::Registry::KEY_SET_VALUE | registry_system_architecture) do |reg|
      reg.delete_value(value[:name])
      Chef::Log.trace("Deleted value #{value[:name]} from registry key #{key_path}")
    end
  else
    Chef::Log.trace("Value #{value[:name]} in registry key #{key_path} does not exist, not updated")
  end
  true
end

#get_name_from_type(val_class) ⇒ Object



284
285
286
# File 'lib/chef/win32/registry.rb', line 284

def get_name_from_type(val_class)
  _name_type_map[val_class]
end

#get_subkeys(key_path) ⇒ Object



193
194
195
196
197
198
199
200
201
202
203
# File 'lib/chef/win32/registry.rb', line 193

def get_subkeys(key_path)
  subkeys = []
  key_exists!(key_path)
  hive, key = get_hive_and_key(key_path)
  hive.open(key, ::Win32::Registry::KEY_READ | registry_system_architecture) do |reg|
    reg.each_key do |current_key|
      subkeys << current_key
    end
  end
  subkeys
end

#get_type_from_name(val_type) ⇒ Object



280
281
282
# File 'lib/chef/win32/registry.rb', line 280

def get_type_from_name(val_type)
  _type_name_map[val_type]
end

#get_values(key_path) ⇒ Object



61
62
63
64
65
66
67
# File 'lib/chef/win32/registry.rb', line 61

def get_values(key_path)
  hive, key = get_hive_and_key(key_path)
  key_exists!(key_path)
  values = hive.open(key, ::Win32::Registry::KEY_READ | registry_system_architecture) do |reg|
    reg.map { |name, type, data| { name: name, type: get_name_from_type(type), data: data } }
  end
end

#has_subkeys?(key_path) ⇒ Boolean

Returns:

  • (Boolean)


184
185
186
187
188
189
190
191
# File 'lib/chef/win32/registry.rb', line 184

def has_subkeys?(key_path)
  key_exists!(key_path)
  hive, key = get_hive_and_key(key_path)
  hive.open(key, ::Win32::Registry::KEY_READ | registry_system_architecture) do |reg|
    reg.each_key { |key| return true }
  end
  false
end

#hive_exists?(key_path) ⇒ Boolean

Returns:

  • (Boolean)


175
176
177
178
179
180
181
182
# File 'lib/chef/win32/registry.rb', line 175

def hive_exists?(key_path)
  begin
    hive, key = get_hive_and_key(key_path)
  rescue Chef::Exceptions::Win32RegHiveMissing => e
    return false
  end
  true
end

#key_exists!(key_path) ⇒ Object



167
168
169
170
171
172
173
# File 'lib/chef/win32/registry.rb', line 167

def key_exists!(key_path)
  unless key_exists?(key_path)
    raise Chef::Exceptions::Win32RegKeyMissing, "Registry key #{key_path} does not exist"
  end

  true
end

#key_exists?(key_path) ⇒ Boolean

Returns:

  • (Boolean)


156
157
158
159
160
161
162
163
164
165
# File 'lib/chef/win32/registry.rb', line 156

def key_exists?(key_path)
  hive, key = get_hive_and_key(key_path)
  begin
    hive.open(key, ::Win32::Registry::KEY_READ | registry_system_architecture) do |current_key|
      return true
    end
  rescue ::Win32::Registry::Error => e
    false
  end
end

#keys_missing?(key_path) ⇒ Boolean

Returns:

  • (Boolean)


273
274
275
276
277
278
# File 'lib/chef/win32/registry.rb', line 273

def keys_missing?(key_path)
  missing_key_arr = key_path.split("\\")
  missing_key_arr.pop
  key = missing_key_arr.join("\\")
  !key_exists?(key)
end

#registry_system_architectureObject

32-bit chef clients running on 64-bit machines will default to reading the 64-bit registry



206
207
208
209
# File 'lib/chef/win32/registry.rb', line 206

def registry_system_architecture
  applied_arch = ( architecture == :machine ) ? machine_architecture : architecture
  ( applied_arch == :x86_64 ) ? 0x0100 : 0x0200
end

#set_value(key_path, value) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/chef/win32/registry.rb', line 69

def set_value(key_path, value)
  data = value[:data]
  data = data.to_s if value[:type] == :string
  Chef::Log.trace("Updating value #{value[:name]} in registry key #{key_path} with type #{value[:type]} and data #{data}")
  key_exists!(key_path)
  hive, key = get_hive_and_key(key_path)
  if value_exists?(key_path, value)
    if data_exists?(key_path, value)
      Chef::Log.trace("Value #{value[:name]} in registry key #{key_path} already had those values, not updated")
      return false
    else
      hive.open(key, ::Win32::Registry::KEY_SET_VALUE | ::Win32::Registry::KEY_QUERY_VALUE | registry_system_architecture) do |reg|
        reg.write(value[:name], get_type_from_name(value[:type]), data)
      end
      Chef::Log.trace("Value #{value[:name]} in registry key #{key_path} updated")
    end
  else
    hive.open(key, ::Win32::Registry::KEY_SET_VALUE | ::Win32::Registry::KEY_QUERY_VALUE | registry_system_architecture) do |reg|
      reg.write(value[:name], get_type_from_name(value[:type]), data)
    end
    Chef::Log.trace("Value #{value[:name]} in registry key #{key_path} created")
  end
  true
end

#type_matches!(key_path, value) ⇒ Object



267
268
269
270
271
# File 'lib/chef/win32/registry.rb', line 267

def type_matches!(key_path, value)
  unless type_matches?(key_path, value)
    raise Chef::Exceptions::Win32RegTypesMismatch, "Registry key #{key_path} has a value #{value[:name]} with a type that is not #{value[:type]}"
  end
end

#type_matches?(key_path, value) ⇒ Boolean

Returns:

  • (Boolean)


251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/chef/win32/registry.rb', line 251

def type_matches?(key_path, value)
  value_exists!(key_path, value)
  hive, key = get_hive_and_key(key_path)
  hive.open(key, ::Win32::Registry::KEY_READ | registry_system_architecture) do |reg|
    reg.each do |val_name, val_type|
      if val_name == value[:name]
        type_new = get_type_from_name(value[:type])
        if val_type == type_new
          return true
        end
      end
    end
  end
  false
end

#value_exists!(key_path, value) ⇒ Object



235
236
237
238
239
240
241
# File 'lib/chef/win32/registry.rb', line 235

def value_exists!(key_path, value)
  unless value_exists?(key_path, value)
    raise Chef::Exceptions::Win32RegValueMissing, "Registry key #{key_path} has no value named #{value[:name]}"
  end

  true
end

#value_exists?(key_path, value) ⇒ Boolean

Returns:

  • (Boolean)


211
212
213
214
215
216
217
218
# File 'lib/chef/win32/registry.rb', line 211

def value_exists?(key_path, value)
  key_exists!(key_path)
  hive, key = get_hive_and_key(key_path)
  hive.open(key, ::Win32::Registry::KEY_READ | registry_system_architecture) do |reg|
    return true if reg.any? { |val| safely_downcase(val) == safely_downcase(value[:name]) }
  end
  false
end