summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanielsdeleo <dan@opscode.com>2013-01-28 10:30:51 -0800
committerdanielsdeleo <dan@opscode.com>2013-01-28 10:30:51 -0800
commitc9afae1142cc7f55bee00e4841c4335a870fde5a (patch)
tree9c870a93a3f8284ffe78d7e0d9727c38fe77597a
parent2a01bdb0d014e5021404ed29d367a08c5b6d49bb (diff)
parent4b212ebd703f2db29a45b887762f04174eb35869 (diff)
downloadchef-c9afae1142cc7f55bee00e4841c4335a870fde5a.tar.gz
Merge branch 'praj/fixing_win_2003_errors'
-rw-r--r--lib/chef/win32/registry.rb35
-rw-r--r--spec/functional/resource/registry_spec.rb18
-rw-r--r--spec/spec_helper.rb6
-rw-r--r--spec/unit/registry_helper_spec.rb12
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