mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/{dl,fiddle}/win32/lib/win32/registry.rb: hope that the final
resolution to fix the failure of test-all. and includes Win64 support (fixed a potential bug). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41856 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9ae509504b
commit
7212ee1328
3 changed files with 101 additions and 63 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
Tue Jul 9 16:58:30 2013 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||||
|
|
||||||
|
* ext/{dl,fiddle}/win32/lib/win32/registry.rb: hope that the final
|
||||||
|
resolution to fix the failure of test-all. and includes Win64
|
||||||
|
support (fixed a potential bug).
|
||||||
|
|
||||||
Tue Jul 9 15:57:20 2013 Akinori MUSHA <knu@iDaemons.org>
|
Tue Jul 9 15:57:20 2013 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
* object.c: Fix rdoc for Kernel#<=>. [Fix GH-352]
|
* object.c: Fix rdoc for Kernel#<=>. [Fix GH-352]
|
||||||
|
|
|
@ -64,7 +64,8 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
|
||||||
=end rdoc
|
=end rdoc
|
||||||
|
|
||||||
WCHAR = Encoding::UTF_16LE
|
WCHAR = Encoding::UTF_16LE
|
||||||
WCHAR_SPACE = "\0".encode(WCHAR).freeze
|
WCHAR_NUL = "\0".encode(WCHAR).freeze
|
||||||
|
WCHAR_SIZE = WCHAR_NUL.bytesize
|
||||||
LOCALE = Encoding.find(Encoding.locale_charmap)
|
LOCALE = Encoding.find(Encoding.locale_charmap)
|
||||||
|
|
||||||
class Registry
|
class Registry
|
||||||
|
@ -171,9 +172,9 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
|
||||||
FormatMessageW = Kernel32.extern "int FormatMessageW(int, void *, int, int, void *, int, void *)", :stdcall
|
FormatMessageW = Kernel32.extern "int FormatMessageW(int, void *, int, int, void *, int, void *)", :stdcall
|
||||||
def initialize(code)
|
def initialize(code)
|
||||||
@code = code
|
@code = code
|
||||||
msg = WCHAR_SPACE * 1024
|
msg = WCHAR_NUL * 1024
|
||||||
len = FormatMessageW.call(0x1200, 0, code, 0, msg, 1024, 0)
|
len = FormatMessageW.call(0x1200, 0, code, 0, msg, 1024, 0)
|
||||||
msg = msg[0, len].encode('locale')
|
msg = msg[0, len].encode(LOCALE)
|
||||||
super msg.tr("\r".encode(msg.encoding), '').chomp
|
super msg.tr("\r".encode(msg.encoding), '').chomp
|
||||||
end
|
end
|
||||||
attr_reader :code
|
attr_reader :code
|
||||||
|
@ -235,6 +236,18 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
|
||||||
raise Error, result, caller(1) if result != 0
|
raise Error, result, caller(1) if result != 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def win64?
|
||||||
|
/^(?:x64|x86_64)/ =~ RUBY_PLATFORM
|
||||||
|
end
|
||||||
|
|
||||||
|
def packhandle(h)
|
||||||
|
win64? ? packqw(h) : packdw(h)
|
||||||
|
end
|
||||||
|
|
||||||
|
def unpackhandle(h)
|
||||||
|
win64? ? unpackqw(h) : unpackdw(h)
|
||||||
|
end
|
||||||
|
|
||||||
def packdw(dw)
|
def packdw(dw)
|
||||||
[dw].pack('V')
|
[dw].pack('V')
|
||||||
end
|
end
|
||||||
|
@ -253,48 +266,47 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
|
||||||
(qw[1] << 32) | qw[0]
|
(qw[1] << 32) | qw[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def make_wstr(str)
|
||||||
|
str.encode(WCHAR) + WCHAR_NUL
|
||||||
|
end
|
||||||
|
|
||||||
def OpenKey(hkey, name, opt, desired)
|
def OpenKey(hkey, name, opt, desired)
|
||||||
result = packdw(0)
|
result = packhandle(0)
|
||||||
check RegOpenKeyExW.call(hkey, name.encode(WCHAR), opt, desired, result)
|
check RegOpenKeyExW.call(hkey, make_wstr(name), opt, desired, result)
|
||||||
unpackdw(result)
|
unpackhandle(result)
|
||||||
end
|
end
|
||||||
|
|
||||||
def CreateKey(hkey, name, opt, desired)
|
def CreateKey(hkey, name, opt, desired)
|
||||||
result = packdw(0)
|
result = packhandle(0)
|
||||||
disp = packdw(0)
|
disp = packdw(0)
|
||||||
check RegCreateKeyExW.call(hkey, name.encode(WCHAR), 0, 0, opt, desired,
|
check RegCreateKeyExW.call(hkey, make_wstr(name), 0, 0, opt, desired,
|
||||||
0, result, disp)
|
0, result, disp)
|
||||||
[ unpackdw(result), unpackdw(disp) ]
|
[ unpackhandle(result), unpackdw(disp) ]
|
||||||
end
|
end
|
||||||
|
|
||||||
def EnumValue(hkey, index)
|
def EnumValue(hkey, index)
|
||||||
name = WCHAR_SPACE * 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, 0, 0, 0, 0)
|
||||||
name[0, unpackdw(size)].encode
|
name[0, unpackdw(size)/WCHAR_SIZE].encode
|
||||||
end
|
end
|
||||||
|
|
||||||
def EnumKey(hkey, index)
|
def EnumKey(hkey, index)
|
||||||
name = WCHAR_SPACE * 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, 0, 0, 0, wtime)
|
||||||
[ name[0, unpackdw(size)].encode, unpackqw(wtime) ]
|
[ name[0, unpackdw(size)/WCHAR_SIZE].encode, unpackqw(wtime) ]
|
||||||
end
|
end
|
||||||
|
|
||||||
def QueryValue(hkey, name)
|
def QueryValue(hkey, name)
|
||||||
prev_gc = GC.disable
|
type = packdw(0)
|
||||||
begin
|
size = packdw(0)
|
||||||
type = packdw(0)
|
name = make_wstr(name)
|
||||||
size = packdw(0)
|
check RegQueryValueExW.call(hkey, name, 0, type, 0, size)
|
||||||
name = name.encode(WCHAR)
|
data = "\0".force_encoding('ASCII-8BIT') * unpackdw(size)
|
||||||
check RegQueryValueExW.call(hkey, name, 0, type, 0, size)
|
check RegQueryValueExW.call(hkey, name, 0, type, data, size)
|
||||||
data = WCHAR_SPACE * unpackdw(size)
|
[ unpackdw(type), data[0, unpackdw(size)] ]
|
||||||
check RegQueryValueExW.call(hkey, name, 0, type, data, size)
|
|
||||||
[ unpackdw(type), data[0, unpackdw(size)].encode ]
|
|
||||||
ensure
|
|
||||||
GC.enable if prev_gc
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def SetValue(hkey, name, type, data, size)
|
def SetValue(hkey, name, type, data, size)
|
||||||
|
@ -303,15 +315,15 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
|
||||||
data = data.encode(WCHAR)
|
data = data.encode(WCHAR)
|
||||||
size ||= data.size + 1
|
size ||= data.size + 1
|
||||||
end
|
end
|
||||||
check RegSetValueExW.call(hkey, name.encode(WCHAR), 0, type, data, size)
|
check RegSetValueExW.call(hkey, make_wstr(name), 0, type, data, size)
|
||||||
end
|
end
|
||||||
|
|
||||||
def DeleteValue(hkey, name)
|
def DeleteValue(hkey, name)
|
||||||
check RegDeleteValue.call(hkey, name.encode(WCHAR))
|
check RegDeleteValue.call(hkey, make_wstr(name))
|
||||||
end
|
end
|
||||||
|
|
||||||
def DeleteKey(hkey, name)
|
def DeleteKey(hkey, name)
|
||||||
check RegDeleteKey.call(hkey, name.encode(WCHAR))
|
check RegDeleteKey.call(hkey, make_wstr(name))
|
||||||
end
|
end
|
||||||
|
|
||||||
def FlushKey(hkey)
|
def FlushKey(hkey)
|
||||||
|
@ -345,7 +357,11 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
|
||||||
# For detail, see expandEnvironmentStrings[http://msdn.microsoft.com/library/en-us/sysinfo/base/expandenvironmentstrings.asp] \Win32 \API.
|
# For detail, see expandEnvironmentStrings[http://msdn.microsoft.com/library/en-us/sysinfo/base/expandenvironmentstrings.asp] \Win32 \API.
|
||||||
#
|
#
|
||||||
def self.expand_environ(str)
|
def self.expand_environ(str)
|
||||||
str.gsub(Regexp.compile("%([^%]+)%".encode(str.encoding))) { (e = ENV[$1.encode('locale')], e.encode(str.encoding) if e) || (e = ENV[$1.encode('locale').upcase], e.encode(str.encoding) if e) || $& }
|
str.gsub(Regexp.compile("%([^%]+)%".encode(str.encoding))) {
|
||||||
|
v = $1.encode(LOCALE)
|
||||||
|
(e = ENV[v] || ENV[v.upcase]; e.encode(str.encoding) if e) ||
|
||||||
|
$&
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@type2name = { }
|
@@type2name = { }
|
||||||
|
@ -605,9 +621,9 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
|
||||||
end
|
end
|
||||||
case type
|
case type
|
||||||
when REG_SZ, REG_EXPAND_SZ
|
when REG_SZ, REG_EXPAND_SZ
|
||||||
[ type, data.encode(name.encoding).rstrip ]
|
[ type, data.encode(name.encoding, WCHAR).chop ]
|
||||||
when REG_MULTI_SZ
|
when REG_MULTI_SZ
|
||||||
[ type, data.encode(name.encoding).split(/\0/) ]
|
[ type, data.encode(name.encoding, WCHAR).split(/\0/) ]
|
||||||
when REG_BINARY
|
when REG_BINARY
|
||||||
[ type, data ]
|
[ type, data ]
|
||||||
when REG_DWORD
|
when REG_DWORD
|
||||||
|
|
|
@ -64,7 +64,8 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
|
||||||
=end rdoc
|
=end rdoc
|
||||||
|
|
||||||
WCHAR = Encoding::UTF_16LE
|
WCHAR = Encoding::UTF_16LE
|
||||||
WCHAR_SPACE = "\0".encode(WCHAR).freeze
|
WCHAR_NUL = "\0".encode(WCHAR).freeze
|
||||||
|
WCHAR_SIZE = WCHAR_NUL.bytesize
|
||||||
LOCALE = Encoding.find(Encoding.locale_charmap)
|
LOCALE = Encoding.find(Encoding.locale_charmap)
|
||||||
|
|
||||||
class Registry
|
class Registry
|
||||||
|
@ -171,9 +172,9 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
|
||||||
FormatMessageW = Kernel32.extern "int FormatMessageW(int, void *, int, int, void *, int, void *)", :stdcall
|
FormatMessageW = Kernel32.extern "int FormatMessageW(int, void *, int, int, void *, int, void *)", :stdcall
|
||||||
def initialize(code)
|
def initialize(code)
|
||||||
@code = code
|
@code = code
|
||||||
msg = WCHAR_SPACE * 1024
|
msg = WCHAR_NUL * 1024
|
||||||
len = FormatMessageW.call(0x1200, 0, code, 0, msg, 1024, 0)
|
len = FormatMessageW.call(0x1200, 0, code, 0, msg, 1024, 0)
|
||||||
msg = msg[0, len].encode('locale')
|
msg = msg[0, len].encode(LOCALE)
|
||||||
super msg.tr("\r".encode(msg.encoding), '').chomp
|
super msg.tr("\r".encode(msg.encoding), '').chomp
|
||||||
end
|
end
|
||||||
attr_reader :code
|
attr_reader :code
|
||||||
|
@ -235,6 +236,18 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
|
||||||
raise Error, result, caller(1) if result != 0
|
raise Error, result, caller(1) if result != 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def win64?
|
||||||
|
/^(?:x64|x86_64)/ =~ RUBY_PLATFORM
|
||||||
|
end
|
||||||
|
|
||||||
|
def packhandle(h)
|
||||||
|
win64? ? packqw(h) : packdw(h)
|
||||||
|
end
|
||||||
|
|
||||||
|
def unpackhandle(h)
|
||||||
|
win64? ? unpackqw(h) : unpackdw(h)
|
||||||
|
end
|
||||||
|
|
||||||
def packdw(dw)
|
def packdw(dw)
|
||||||
[dw].pack('V')
|
[dw].pack('V')
|
||||||
end
|
end
|
||||||
|
@ -253,48 +266,47 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
|
||||||
(qw[1] << 32) | qw[0]
|
(qw[1] << 32) | qw[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def make_wstr(str)
|
||||||
|
str.encode(WCHAR) + WCHAR_NUL
|
||||||
|
end
|
||||||
|
|
||||||
def OpenKey(hkey, name, opt, desired)
|
def OpenKey(hkey, name, opt, desired)
|
||||||
result = packdw(0)
|
result = packhandle(0)
|
||||||
check RegOpenKeyExW.call(hkey, name.encode(WCHAR), opt, desired, result)
|
check RegOpenKeyExW.call(hkey, make_wstr(name), opt, desired, result)
|
||||||
unpackdw(result)
|
unpackhandle(result)
|
||||||
end
|
end
|
||||||
|
|
||||||
def CreateKey(hkey, name, opt, desired)
|
def CreateKey(hkey, name, opt, desired)
|
||||||
result = packdw(0)
|
result = packhandle(0)
|
||||||
disp = packdw(0)
|
disp = packdw(0)
|
||||||
check RegCreateKeyExW.call(hkey, name.encode(WCHAR), 0, 0, opt, desired,
|
check RegCreateKeyExW.call(hkey, make_wstr(name), 0, 0, opt, desired,
|
||||||
0, result, disp)
|
0, result, disp)
|
||||||
[ unpackdw(result), unpackdw(disp) ]
|
[ unpackhandle(result), unpackdw(disp) ]
|
||||||
end
|
end
|
||||||
|
|
||||||
def EnumValue(hkey, index)
|
def EnumValue(hkey, index)
|
||||||
name = WCHAR_SPACE * 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, 0, 0, 0, 0)
|
||||||
name[0, unpackdw(size)].encode
|
name[0, unpackdw(size)/WCHAR_SIZE].encode
|
||||||
end
|
end
|
||||||
|
|
||||||
def EnumKey(hkey, index)
|
def EnumKey(hkey, index)
|
||||||
name = WCHAR_SPACE * 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, 0, 0, 0, wtime)
|
||||||
[ name[0, unpackdw(size)].encode, unpackqw(wtime) ]
|
[ name[0, unpackdw(size)/WCHAR_SIZE].encode, unpackqw(wtime) ]
|
||||||
end
|
end
|
||||||
|
|
||||||
def QueryValue(hkey, name)
|
def QueryValue(hkey, name)
|
||||||
prev_gc = GC.disable
|
type = packdw(0)
|
||||||
begin
|
size = packdw(0)
|
||||||
type = packdw(0)
|
name = make_wstr(name)
|
||||||
size = packdw(0)
|
check RegQueryValueExW.call(hkey, name, 0, type, 0, size)
|
||||||
name = name.encode(WCHAR)
|
data = "\0".force_encoding('ASCII-8BIT') * unpackdw(size)
|
||||||
check RegQueryValueExW.call(hkey, name, 0, type, 0, size)
|
check RegQueryValueExW.call(hkey, name, 0, type, data, size)
|
||||||
data = WCHAR_SPACE * unpackdw(size)
|
[ unpackdw(type), data[0, unpackdw(size)] ]
|
||||||
check RegQueryValueExW.call(hkey, name, 0, type, data, size)
|
|
||||||
[ unpackdw(type), data[0, unpackdw(size)].encode ]
|
|
||||||
ensure
|
|
||||||
GC.enable if prev_gc
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def SetValue(hkey, name, type, data, size)
|
def SetValue(hkey, name, type, data, size)
|
||||||
|
@ -303,15 +315,15 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
|
||||||
data = data.encode(WCHAR)
|
data = data.encode(WCHAR)
|
||||||
size ||= data.size + 1
|
size ||= data.size + 1
|
||||||
end
|
end
|
||||||
check RegSetValueExW.call(hkey, name.encode(WCHAR), 0, type, data, size)
|
check RegSetValueExW.call(hkey, make_wstr(name), 0, type, data, size)
|
||||||
end
|
end
|
||||||
|
|
||||||
def DeleteValue(hkey, name)
|
def DeleteValue(hkey, name)
|
||||||
check RegDeleteValue.call(hkey, name.encode(WCHAR))
|
check RegDeleteValue.call(hkey, make_wstr(name))
|
||||||
end
|
end
|
||||||
|
|
||||||
def DeleteKey(hkey, name)
|
def DeleteKey(hkey, name)
|
||||||
check RegDeleteKey.call(hkey, name.encode(WCHAR))
|
check RegDeleteKey.call(hkey, make_wstr(name))
|
||||||
end
|
end
|
||||||
|
|
||||||
def FlushKey(hkey)
|
def FlushKey(hkey)
|
||||||
|
@ -345,7 +357,11 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
|
||||||
# For detail, see expandEnvironmentStrings[http://msdn.microsoft.com/library/en-us/sysinfo/base/expandenvironmentstrings.asp] \Win32 \API.
|
# For detail, see expandEnvironmentStrings[http://msdn.microsoft.com/library/en-us/sysinfo/base/expandenvironmentstrings.asp] \Win32 \API.
|
||||||
#
|
#
|
||||||
def self.expand_environ(str)
|
def self.expand_environ(str)
|
||||||
str.gsub(Regexp.compile("%([^%]+)%".encode(str.encoding))) { (e = ENV[$1.encode('locale')], e.encode(str.encoding) if e) || (e = ENV[$1.encode('locale').upcase], e.encode(str.encoding) if e) || $& }
|
str.gsub(Regexp.compile("%([^%]+)%".encode(str.encoding))) {
|
||||||
|
v = $1.encode(LOCALE)
|
||||||
|
(e = ENV[v] || ENV[v.upcase]; e.encode(str.encoding) if e) ||
|
||||||
|
$&
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@type2name = { }
|
@@type2name = { }
|
||||||
|
@ -605,9 +621,9 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
|
||||||
end
|
end
|
||||||
case type
|
case type
|
||||||
when REG_SZ, REG_EXPAND_SZ
|
when REG_SZ, REG_EXPAND_SZ
|
||||||
[ type, data.encode(name.encoding).rstrip ]
|
[ type, data.encode(name.encoding, WCHAR).chop ]
|
||||||
when REG_MULTI_SZ
|
when REG_MULTI_SZ
|
||||||
[ type, data.encode(name.encoding).split(/\0/) ]
|
[ type, data.encode(name.encoding, WCHAR).split(/\0/) ]
|
||||||
when REG_BINARY
|
when REG_BINARY
|
||||||
[ type, data ]
|
[ type, data ]
|
||||||
when REG_DWORD
|
when REG_DWORD
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue