[ruby/win32-registry] Fix compatibility with JRuby

JRuby's fiddle implementation has quite some shortcomings compared with the CRuby impl.
Add JRuby tests in CI.

https://github.com/ruby/win32-registry/commit/7f34184c2e
This commit is contained in:
Lars Kanis 2024-10-11 22:41:09 +02:00 committed by git
parent 6a49bbd734
commit 85ce3b177c
2 changed files with 21 additions and 16 deletions

View File

@ -178,7 +178,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
buff = WCHAR_NUL * 1024 buff = WCHAR_NUL * 1024
lang = 0 lang = 0
begin begin
len = FormatMessageW.call(0x1200, 0, code, lang, buff, 1024, 0) len = FormatMessageW.call(0x1200, nil, code, lang, buff, 1024, nil)
msg = buff.byteslice(0, len * WCHAR_SIZE) msg = buff.byteslice(0, len * WCHAR_SIZE)
msg.delete!(WCHAR_CR) msg.delete!(WCHAR_CR)
msg.chomp! msg.chomp!
@ -198,7 +198,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
# #
class PredefinedKey < Registry class PredefinedKey < Registry
def initialize(hkey, keyname) def initialize(hkey, keyname)
@hkey = hkey @hkey = Fiddle::Pointer.new(hkey)
@parent = nil @parent = nil
@keyname = keyname @keyname = keyname
@disposition = REG_OPENED_EXISTING_KEY @disposition = REG_OPENED_EXISTING_KEY
@ -238,7 +238,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
"long RegDeleteKeyW(void *, void *)", "long RegDeleteKeyW(void *, void *)",
"long RegFlushKey(void *)", "long RegFlushKey(void *)",
"long RegCloseKey(void *)", "long RegCloseKey(void *)",
"long RegQueryInfoKey(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *)", "long RegQueryInfoKeyW(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *)",
].each do |fn| ].each do |fn|
cfunc = extern fn, :stdcall cfunc = extern fn, :stdcall
const_set cfunc.name.intern, cfunc const_set cfunc.name.intern, cfunc
@ -285,7 +285,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
end end
def make_wstr(str) def make_wstr(str)
str.encode(WCHAR) (str+"\0").encode(WCHAR)
end end
def OpenKey(hkey, name, opt, desired) def OpenKey(hkey, name, opt, desired)
@ -298,14 +298,14 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
result = packhandle(0) result = packhandle(0)
disp = packdw(0) disp = packdw(0)
check RegCreateKeyExW.call(hkey, make_wstr(name), 0, 0, opt, desired, check RegCreateKeyExW.call(hkey, make_wstr(name), 0, 0, opt, desired,
0, result, disp) nil, result, disp)
[ unpackhandle(result), unpackdw(disp) ] [ unpackhandle(result), unpackdw(disp) ]
end end
def EnumValue(hkey, index) def EnumValue(hkey, index)
name = WCHAR_NUL * Constants::MAX_KEY_LENGTH name = WCHAR_NUL * Constants::MAX_KEY_LENGTH
size = packdw(Constants::MAX_KEY_LENGTH) size = packdw(Constants::MAX_KEY_LENGTH)
check RegEnumValueW.call(hkey, index, name, size, 0, 0, 0, 0) check RegEnumValueW.call(hkey, index, name, size, nil, nil, nil, nil)
name.byteslice(0, unpackdw(size) * WCHAR_SIZE) name.byteslice(0, unpackdw(size) * WCHAR_SIZE)
end end
@ -313,7 +313,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
name = WCHAR_NUL * Constants::MAX_KEY_LENGTH name = WCHAR_NUL * Constants::MAX_KEY_LENGTH
size = packdw(Constants::MAX_KEY_LENGTH) size = packdw(Constants::MAX_KEY_LENGTH)
wtime = ' ' * 8 wtime = ' ' * 8
check RegEnumKeyExW.call(hkey, index, name, size, 0, 0, 0, wtime) check RegEnumKeyExW.call(hkey, index, name, size, nil, nil, nil, wtime)
[ name.byteslice(0, unpackdw(size) * WCHAR_SIZE), unpackqw(wtime) ] [ name.byteslice(0, unpackdw(size) * WCHAR_SIZE), unpackqw(wtime) ]
end end
@ -321,9 +321,9 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
type = packdw(0) type = packdw(0)
size = packdw(0) size = packdw(0)
name = make_wstr(name) name = make_wstr(name)
check RegQueryValueExW.call(hkey, name, 0, type, 0, size) check RegQueryValueExW.call(hkey, name, nil, type, nil, size)
data = "\0".b * unpackdw(size) data = "\0".b * unpackdw(size)
check RegQueryValueExW.call(hkey, name, 0, type, data, size) check RegQueryValueExW.call(hkey, name, nil, type, data, size)
[ unpackdw(type), data[0, unpackdw(size)] ] [ unpackdw(type), data[0, unpackdw(size)] ]
end end
@ -360,7 +360,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
maxvaluelen = packdw(0) maxvaluelen = packdw(0)
secdescs = packdw(0) secdescs = packdw(0)
wtime = ' ' * 8 wtime = ' ' * 8
check RegQueryInfoKey.call(hkey, 0, 0, 0, subkeys, maxsubkeylen, 0, check RegQueryInfoKeyW.call(hkey, 0, 0, 0, subkeys, maxsubkeylen, 0,
values, maxvaluenamelen, maxvaluelen, secdescs, wtime) values, maxvaluenamelen, maxvaluelen, secdescs, wtime)
[ unpackdw(subkeys), unpackdw(maxsubkeylen), unpackdw(values), [ unpackdw(subkeys), unpackdw(maxsubkeylen), unpackdw(values),
unpackdw(maxvaluenamelen), unpackdw(maxvaluelen), unpackdw(maxvaluenamelen), unpackdw(maxvaluelen),
@ -430,7 +430,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
# If block is given, the key is closed automatically. # If block is given, the key is closed automatically.
def self.open(hkey, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED) def self.open(hkey, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED)
subkey = subkey.chomp('\\') subkey = subkey.chomp('\\')
newkey = API.OpenKey(hkey.hkey, subkey, opt, desired) newkey = API.OpenKey(hkey.instance_variable_get(:@hkey), subkey, opt, desired)
obj = new(newkey, hkey, subkey, REG_OPENED_EXISTING_KEY) obj = new(newkey, hkey, subkey, REG_OPENED_EXISTING_KEY)
if block_given? if block_given?
begin begin
@ -457,7 +457,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
# If block is given, the key is closed automatically. # If block is given, the key is closed automatically.
# #
def self.create(hkey, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED) def self.create(hkey, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED)
newkey, disp = API.CreateKey(hkey.hkey, subkey, opt, desired) newkey, disp = API.CreateKey(hkey.instance_variable_get(:@hkey), subkey, opt, desired)
obj = new(newkey, hkey, subkey, disp) obj = new(newkey, hkey, subkey, disp)
if block_given? if block_given?
begin begin
@ -479,7 +479,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
# initialize # initialize
# #
def initialize(hkey, parent, keyname, disposition) def initialize(hkey, parent, keyname, disposition)
@hkey = hkey @hkey = Fiddle::Pointer.new(hkey)
@parent = parent @parent = parent
@keyname = keyname @keyname = keyname
@disposition = disposition @disposition = disposition
@ -487,8 +487,6 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
ObjectSpace.define_finalizer self, @@final.call(@hkeyfinal) ObjectSpace.define_finalizer self, @@final.call(@hkeyfinal)
end end
# Returns key handle value.
attr_reader :hkey
# Win32::Registry object of parent key, or nil if predefeined key. # Win32::Registry object of parent key, or nil if predefeined key.
attr_reader :parent attr_reader :parent
# Same as subkey value of Registry.open or # Same as subkey value of Registry.open or
@ -497,6 +495,11 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
# Disposition value (REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY). # Disposition value (REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY).
attr_reader :disposition attr_reader :disposition
# Returns key handle value.
def hkey
@hkey.to_i
end
# #
# Returns if key is created ((*newly*)). # Returns if key is created ((*newly*)).
# (see Registry.create) -- basically you call create # (see Registry.create) -- basically you call create

View File

@ -1,6 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM require "rbconfig"
if /mswin|mingw|cygwin/ =~ RbConfig::CONFIG['host_os']
begin begin
require 'win32/registry' require 'win32/registry'
rescue LoadError rescue LoadError