Skip to content

Commit

Permalink
Merge branch '32-bit'
Browse files Browse the repository at this point in the history
* 32-bit:
  Add examples of current registry key and value types
  Add the ability to manage 32 and 64-bit keys/values
  • Loading branch information
Jeff McCune committed Apr 24, 2012
2 parents f91128b + bb7e4f4 commit 92b1c40
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 51 deletions.
10 changes: 6 additions & 4 deletions lib/puppet/modules/registry/key_path.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@
class Puppet::Modules::Registry::KeyPath < Puppet::Parameter
include Puppet::Modules::Registry::RegistryBase

attr_reader :root, :hkey, :subkey
attr_reader :root, :hkey, :subkey, :access

def munge(path)
unless captures = /^([^\\]*)((?:\\[^\\]{1,255})*)$/.match(path)
unless captures = /^(32:)?([h|H][^\\]*)((?:\\[^\\]{1,255})*)$/.match(path)
raise ArgumentError, "Invalid registry key: #{path}"
end

@access = (captures[1] and captures[1] == '32:') ? KEY_WOW64_32KEY : KEY_WOW64_64KEY

# canonical root key symbol
@root = case captures[1].downcase
@root = case captures[2].downcase
when /hkey_local_machine/, /hklm/
:hklm
when /hkey_classes_root/, /hkcr/
Expand All @@ -32,7 +34,7 @@ def munge(path)
# the hkey object for the root key
@hkey = HKEYS[root]

@subkey = captures[2]
@subkey = captures[3]
if @subkey.empty?
canonical = root.to_s
else
Expand Down
11 changes: 5 additions & 6 deletions lib/puppet/modules/registry/registry_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ module Puppet::Modules::Registry::RegistryBase
# REG_RESOURCE_LIST REG_FULL_RESOURCE_DESCRIPTOR
# REG_RESOURCE_REQUIREMENTS_LIST

# For 64-bit OS, use 64-bit view. Ignored on 32-bit OS
KEY_WOW64_64KEY = 0x100
# For 64-bit OS, use 32-bit view. Ignored on 32-bit OS
KEY_WOW64_32KEY = 0x200

NAME2TYPE = {}
TYPE2NAME.each_pair {|k,v| NAME2TYPE[v] = k}

Expand All @@ -38,10 +43,4 @@ def name2type(name)
def hkeys
HKEYS
end

def access(mask = 0)
# REMIND: skip this if 32-bit OS?
#:redirect) == :true ? 0x200 : 0x100)
mask | (resource[:redirect] == 'true' ? 0x200 : 0x100)
end
end
6 changes: 3 additions & 3 deletions lib/puppet/provider/registry_key/registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@ def self.instances

def create
Puppet.debug("create key #{resource[:path]}")
keypath.hkey.create(keypath.subkey, access(Win32::Registry::KEY_ALL_ACCESS)) {|reg| true }
keypath.hkey.create(keypath.subkey, Win32::Registry::KEY_ALL_ACCESS | keypath.access) {|reg| true }
end

def exists?
Puppet.debug("exists? key #{resource[:path]}")
!!keypath.hkey.open(keypath.subkey, access(Win32::Registry::KEY_READ)) {|reg| true } rescue false
!!keypath.hkey.open(keypath.subkey, Win32::Registry::KEY_READ | keypath.access) {|reg| true } rescue false
end

def destroy
Puppet.debug("destroy key #{resource[:path]}")

raise "Cannot delete root key: #{resource[:path]}" unless keypath.subkey

if RegDeleteKeyEx.call(keypath.hkey.hkey, keypath.subkey, access, 0) != 0
if RegDeleteKeyEx.call(keypath.hkey.hkey, keypath.subkey, keypath.access, 0) != 0
raise "Failed to delete registry key: #{resource[:path]}"
end
end
Expand Down
10 changes: 5 additions & 5 deletions lib/puppet/provider/registry_value/registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def self.instances
def create
Puppet.info("creating: #{self}")

valuepath.hkey.open(valuepath.subkey, access(Win32::Registry::KEY_ALL_ACCESS)) do |reg|
valuepath.hkey.open(valuepath.subkey, Win32::Registry::KEY_ALL_ACCESS | valuepath.access) do |reg|
reg.write(valuepath.valuename, name2type(resource[:type]), resource[:data])
end
end
Expand All @@ -23,7 +23,7 @@ def exists?
Puppet.info("exists: #{self}")

found = false
valuepath.hkey.open(valuepath.subkey, access(Win32::Registry::KEY_READ)) do |reg|
valuepath.hkey.open(valuepath.subkey, Win32::Registry::KEY_READ | valuepath.access) do |reg|
type = [0].pack('L')
size = [0].pack('L')
found = RegQueryValueExA.call(reg.hkey, valuepath.valuename, 0, type, 0, size) == 0
Expand All @@ -36,15 +36,15 @@ def flush

Puppet.info("flushing: #{self}")

valuepath.hkey.open(valuepath.subkey, access(Win32::Registry::KEY_ALL_ACCESS)) do |reg|
valuepath.hkey.open(valuepath.subkey, Win32::Registry::KEY_ALL_ACCESS | valuepath.access) do |reg|
reg.write(valuepath.valuename, name2type(regvalue[:type]), regvalue[:data])
end
end

def destroy
Puppet.info("destroying: #{self}")

valuepath.hkey.open(valuepath.subkey, access(Win32::Registry::KEY_ALL_ACCESS)) do |reg|
valuepath.hkey.open(valuepath.subkey, Win32::Registry::KEY_ALL_ACCESS | valuepath.access) do |reg|
reg.delete_value(valuepath.valuename)
end
end
Expand All @@ -68,7 +68,7 @@ def data=(value)
def regvalue
unless @regvalue
@regvalue = {}
valuepath.hkey.open(valuepath.subkey, access(Win32::Registry::KEY_ALL_ACCESS)) do |reg|
valuepath.hkey.open(valuepath.subkey, Win32::Registry::KEY_ALL_ACCESS | valuepath.access) do |reg|
type = [0].pack('L')
size = [0].pack('L')

Expand Down
5 changes: 0 additions & 5 deletions lib/puppet/type/registry_key.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ def self.title_patterns
newparam(:path, :parent => Puppet::Modules::Registry::KeyPath, :namevar => true) do
end

newparam(:redirect) do
newvalues(:true, :false)
defaultto :false
end

autorequire(:registry_key) do
parameter(:path).enum_for(:ascend).select { |p| self[:path] != p }
end
Expand Down
5 changes: 0 additions & 5 deletions lib/puppet/type/registry_value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ def self.title_patterns
newparam(:path, :parent => Puppet::Modules::Registry::ValuePath, :namevar => true) do
end

newparam(:redirect) do
newvalues(:true, :false)
defaultto :false
end

newproperty(:type) do
newvalues(:string, :array, :dword, :qword, :binary, :expand)
defaultto :string
Expand Down
14 changes: 4 additions & 10 deletions spec/unit/puppet/type/registry_key_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
end
end

%[hklm\\ hklm\foo\\ unknown unknown\subkey].each do |path|
%[hklm\\ hklm\foo\\ unknown unknown\subkey \:hkey].each do |path|
it "should reject #{path} as invalid" do
path = "hklm\\" + 'a' * 256
expect { key[:path] = path }.should raise_error(Puppet::Error, /Invalid registry key/)
Expand All @@ -49,16 +49,10 @@
it 'should be case-preserving'
it 'should be case-insensitive'
it 'should autorequire ancestor keys'
end

describe "redirect parameter" do
it 'should not redirect by default' do
key[:redirect].should == :false
end

it 'should allow redirection' do
key[:redirect] = true
key[:redirect].should be_true
it 'should support 32-bit keys' do
key[:path] = '32:hklm\software'
key.parameter(:path).access.should == 0x200
end
end
end
16 changes: 3 additions & 13 deletions spec/unit/puppet/type/registry_value_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,25 +54,15 @@
end
end


it 'should validate the length of the value name'
it 'should validate the length of the value data'
it 'should canonicalize the root key'
it 'should be case-preserving'
it 'should be case-insensitive'
it 'should autorequire ancestor keys'
end

describe "redirect parameter" do
let (:value) { described_class.new(:path => 'hklm\software\foo') }

it 'should not redirect by default' do
value[:redirect].should == :false
end

it 'should allow redirection' do
value[:redirect] = true
value[:redirect].should be_true
it 'should support 32-bit values' do
value = described_class.new(:path => '32:hklm\software\foo')
value.parameter(:path).access.should == 0x200
end
end

Expand Down
58 changes: 58 additions & 0 deletions tests/registry_examples.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# = Class: registry_example
#
# This is an example of how to manage registry keys and values.
#
# = Parameters
#
# = Actions
#
# = Requires
#
# = Sample Usage
#
# include registry_example
#
# (MARKUP: http://links.puppetlabs.com/puppet_manifest_documentation)
class registry_example {
registry_key { 'HKLM\Software\Vendor':
ensure => present,
}

# This should trigger a duplicate resource with HKLM
# registry_key { 'HKEY_LOCAL_MACHINE\Software\Vendor':
# ensure => present,
# }

registry_key { 'HKLM\Software\Vendor\Bar':
ensure => present,
}

registry_value { 'HKLM\Software\Vendor\Bar\valuename1':
ensure => present,
type => qword,
data => 100,
}

# # REVISIT We need to make this work
# registry_value { 'HKLM\Software\Vendor\Bar\valuearray1':
# ensure => present,
# type => array,
# data => [ 'one', 'two', 'three' ],
# }

# $some_string = "somestring"
# registry_value { 'HKLM\Software\Vendor\Bar\valuearray2':
# ensure => present,
# type => array,
# data => [ 'one', 'two', $some_string ],
# }

# $some_array = [ "array1", "array2", "array3" ]
# registry_value { 'HKLM\Software\Vendor\Bar\valuearray3':
# ensure => present,
# type => array,
# data => $some_array,
# }
}

include registry_example

0 comments on commit 92b1c40

Please sign in to comment.