diff options
author | danielsdeleo <dan@opscode.com> | 2013-01-28 10:30:51 -0800 |
---|---|---|
committer | danielsdeleo <dan@opscode.com> | 2013-01-28 10:30:51 -0800 |
commit | c9afae1142cc7f55bee00e4841c4335a870fde5a (patch) | |
tree | 9c870a93a3f8284ffe78d7e0d9727c38fe77597a | |
parent | 2a01bdb0d014e5021404ed29d367a08c5b6d49bb (diff) | |
parent | 4b212ebd703f2db29a45b887762f04174eb35869 (diff) | |
download | chef-c9afae1142cc7f55bee00e4841c4335a870fde5a.tar.gz |
Merge branch 'praj/fixing_win_2003_errors'
-rw-r--r-- | lib/chef/win32/registry.rb | 35 | ||||
-rw-r--r-- | spec/functional/resource/registry_spec.rb | 18 | ||||
-rw-r--r-- | spec/spec_helper.rb | 6 | ||||
-rw-r--r-- | spec/unit/registry_helper_spec.rb | 12 |
4 files changed, 42 insertions, 29 deletions
diff --git a/lib/chef/win32/registry.rb b/lib/chef/win32/registry.rb index 03d34040a9..1e8f53b464 100644 --- a/lib/chef/win32/registry.rb +++ b/lib/chef/win32/registry.rb @@ -21,6 +21,7 @@ require 'chef/reserved_names' if RUBY_PLATFORM =~ /mswin|mingw32|windows/ require 'win32/registry' require 'ruby-wmi' + require 'win32/api' end class Chef @@ -115,28 +116,38 @@ class Chef Chef::Log.debug("Registry key #{key_path}, does not exist, not deleting") return true end - hive, key = get_hive_and_key(key_path) - key_parent = key.split("\\") - key_to_delete = key_parent.pop - key_parent = key_parent.join("\\") + #key_path is in the form "HKLM\Software\Opscode" for example, extracting + #hive = HKLM, + #hive_namespace = ::Win32::Registry::HKEY_LOCAL_MACHINE + hive = key_path.split("\\").shift + hive_namespace, key_including_parent = get_hive_and_key(key_path) if has_subkeys?(key_path) if recursive == true - hive.open(key_parent, ::Win32::Registry::KEY_WRITE | registry_system_architecture) do |reg| + subkeys = get_subkeys(key_path) + subkeys.each do |key| + keypath_to_check = hive+"\\"+key_including_parent+"\\"+key Chef::Log.debug("Deleting registry key #{key_path} recursively") - reg.delete_key(key_to_delete,recursive) + delete_key(keypath_to_check, true) end + delete_key_ex(hive_namespace, key_including_parent) else raise Chef::Exceptions::Win32RegNoRecursive, "Registry key #{key_path} has subkeys, and recursive not specified" end else - hive.open(key_parent, ::Win32::Registry::KEY_WRITE | registry_system_architecture) do |reg| - Chef::Log.debug("Deleting registry key #{key_path}") - reg.delete_key(key_to_delete) - end + delete_key_ex(hive_namespace, key_including_parent) + return true end true end + #Using the 'RegDeleteKeyEx' Windows API that correctly supports WOW64 systems (Win2003) + #instead of the 'RegDeleteKey' + def delete_key_ex(hive, key) + regDeleteKeyEx = ::Win32::API.new('RegDeleteKeyEx', 'LPLL', 'L', 'advapi32') + hive_num = hive.hkey - (1 << 32) + regDeleteKeyEx.call(hive_num, key, ::Win32::Registry::KEY_WRITE | registry_system_architecture, 0) + end + def key_exists?(key_path) hive, key = get_hive_and_key(key_path) begin @@ -204,8 +215,8 @@ class Chef hive.open(key, ::Win32::Registry::KEY_READ | registry_system_architecture) do |reg| reg.each do |val_name, val_type, val_data| if val_name == value[:name] && - val_type == get_type_from_name(value[:type]) && - val_data == value[:data] + val_type == get_type_from_name(value[:type]) && + val_data == value[:data] return true end end diff --git a/spec/functional/resource/registry_spec.rb b/spec/functional/resource/registry_spec.rb index 2ef359273d..2b7f1b52ee 100644 --- a/spec/functional/resource/registry_spec.rb +++ b/spec/functional/resource/registry_spec.rb @@ -55,19 +55,13 @@ describe Chef::Resource::RegistryKey, :windows_only do def clean_registry # clean 64-bit space on WOW64 - begin - hive_class.open(key_parent, Win32::Registry::KEY_WRITE | 0x0100) do |reg| - reg.delete_key(child, true) - end - rescue - end + @registry.architecture = :x86_64 + @registry.delete_key(reg_parent, true) + @registry.architecture = :machine # clean 32-bit space on WOW64 - begin - hive_class.open(key_parent, Win32::Registry::KEY_WRITE | 0x0200) do |reg| - reg.delete_key(child, true) - end - rescue - end + @registry.architecture = :i386 + @registry.delete_key(reg_parent, true) + @registry.architecture = :machine end def reset_registry diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3a5ca22868..6657a933e7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -18,6 +18,12 @@ # If you need to add anything in here, don't. # Add it to one of the files in spec/support +# Configure this first so it doesn't trigger annoying warning when we use it. +# Main rspec configuration comes later +RSpec.configure do |config| + config.treat_symbols_as_metadata_keys_with_true_values = true +end + # Abuse ruby's constant lookup to avoid undefined constant errors module Shell JUST_TESTING_MOVE_ALONG = true unless defined? JUST_TESTING_MOVE_ALONG diff --git a/spec/unit/registry_helper_spec.rb b/spec/unit/registry_helper_spec.rb index a83895ba20..49469b27e6 100644 --- a/spec/unit/registry_helper_spec.rb +++ b/spec/unit/registry_helper_spec.rb @@ -159,13 +159,16 @@ describe Chef::Provider::RegistryKey do end end - describe "delete_key" do + describe "delete_key", :windows_only do it "deletes key if it has subkeys and recursive is set to true" do @registry.should_receive(:key_exists?).with(key_path).and_return(true) @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key]) @registry.should_receive(:has_subkeys?).with(key_path).and_return(true) - @hive_mock.should_receive(:open).with(key_parent, ::Win32::Registry::KEY_WRITE | @registry.registry_system_architecture).and_yield(@reg_mock) - @reg_mock.should_receive(:delete_key).with(key_to_delete, true) + @registry.should_receive(:get_subkeys).with(key_path).and_return([sub_key]) + @registry.should_receive(:key_exists?).with(key_path+"\\"+sub_key).and_return(true) + @registry.should_receive(:get_hive_and_key).with(key_path+"\\"+sub_key).and_return([@hive_mock, key+"\\"+sub_key]) + @registry.should_receive(:has_subkeys?).with(key_path+"\\"+sub_key).and_return(false) + @registry.should_receive(:delete_key_ex).twice @registry.delete_key(key_path, true) end @@ -180,8 +183,7 @@ describe Chef::Provider::RegistryKey do @registry.should_receive(:key_exists?).with(key_path).and_return(true) @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key]) @registry.should_receive(:has_subkeys?).with(key_path).and_return(false) - @hive_mock.should_receive(:open).with(key_parent, ::Win32::Registry::KEY_WRITE | @registry.registry_system_architecture).and_yield(@reg_mock) - @reg_mock.should_receive(:delete_key).with(key_to_delete) + @registry.should_receive(:delete_key_ex) @registry.delete_key(key_path, true) end end |