ruby-changes:29804
From: usa <ko1@a...>
Date: Tue, 9 Jul 2013 17:00:40 +0900 (JST)
Subject: [ruby-changes:29804] usa:r41856 (trunk): * ext/{dl,fiddle}/win32/lib/win32/registry.rb: hope that the final
usa 2013-07-09 17:00:28 +0900 (Tue, 09 Jul 2013) New Revision: 41856 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41856 Log: * 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). Modified files: trunk/ChangeLog trunk/ext/dl/win32/lib/win32/registry.rb trunk/ext/fiddle/win32/lib/win32/registry.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 41855) +++ ChangeLog (revision 41856) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Jul 9 16:58:30 2013 NAKAMURA Usaku <usa@r...> + + * 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@i...> * object.c: Fix rdoc for Kernel#<=>. [Fix GH-352] Index: ext/dl/win32/lib/win32/registry.rb =================================================================== --- ext/dl/win32/lib/win32/registry.rb (revision 41855) +++ ext/dl/win32/lib/win32/registry.rb (revision 41856) @@ -64,7 +64,8 @@ For detail, see the MSDN[http://msdn.mic https://github.com/ruby/ruby/blob/trunk/ext/dl/win32/lib/win32/registry.rb#L64 =end rdoc 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) class Registry @@ -171,9 +172,9 @@ For detail, see the MSDN[http://msdn.mic https://github.com/ruby/ruby/blob/trunk/ext/dl/win32/lib/win32/registry.rb#L172 FormatMessageW = Kernel32.extern "int FormatMessageW(int, void *, int, int, void *, int, void *)", :stdcall def initialize(code) @code = code - msg = WCHAR_SPACE * 1024 + msg = WCHAR_NUL * 1024 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 end attr_reader :code @@ -235,6 +236,18 @@ For detail, see the MSDN[http://msdn.mic https://github.com/ruby/ruby/blob/trunk/ext/dl/win32/lib/win32/registry.rb#L236 raise Error, result, caller(1) if result != 0 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) [dw].pack('V') end @@ -253,48 +266,47 @@ For detail, see the MSDN[http://msdn.mic https://github.com/ruby/ruby/blob/trunk/ext/dl/win32/lib/win32/registry.rb#L266 (qw[1] << 32) | qw[0] end + def make_wstr(str) + str.encode(WCHAR) + WCHAR_NUL + end + def OpenKey(hkey, name, opt, desired) - result = packdw(0) - check RegOpenKeyExW.call(hkey, name.encode(WCHAR), opt, desired, result) - unpackdw(result) + result = packhandle(0) + check RegOpenKeyExW.call(hkey, make_wstr(name), opt, desired, result) + unpackhandle(result) end def CreateKey(hkey, name, opt, desired) - result = packdw(0) - disp = packdw(0) - check RegCreateKeyExW.call(hkey, name.encode(WCHAR), 0, 0, opt, desired, + result = packhandle(0) + disp = packdw(0) + check RegCreateKeyExW.call(hkey, make_wstr(name), 0, 0, opt, desired, 0, result, disp) - [ unpackdw(result), unpackdw(disp) ] + [ unpackhandle(result), unpackdw(disp) ] end def EnumValue(hkey, index) - name = WCHAR_SPACE * Constants::MAX_KEY_LENGTH + name = WCHAR_NUL * Constants::MAX_KEY_LENGTH size = packdw(Constants::MAX_KEY_LENGTH) check RegEnumValueW.call(hkey, index, name, size, 0, 0, 0, 0) - name[0, unpackdw(size)].encode + name[0, unpackdw(size)/WCHAR_SIZE].encode end def EnumKey(hkey, index) - name = WCHAR_SPACE * Constants::MAX_KEY_LENGTH + name = WCHAR_NUL * Constants::MAX_KEY_LENGTH size = packdw(Constants::MAX_KEY_LENGTH) wtime = ' ' * 8 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 def QueryValue(hkey, name) - prev_gc = GC.disable - begin - type = packdw(0) - size = packdw(0) - name = name.encode(WCHAR) - check RegQueryValueExW.call(hkey, name, 0, type, 0, size) - data = WCHAR_SPACE * 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 + type = packdw(0) + size = packdw(0) + name = make_wstr(name) + check RegQueryValueExW.call(hkey, name, 0, type, 0, size) + data = "\0".force_encoding('ASCII-8BIT') * unpackdw(size) + check RegQueryValueExW.call(hkey, name, 0, type, data, size) + [ unpackdw(type), data[0, unpackdw(size)] ] end def SetValue(hkey, name, type, data, size) @@ -303,15 +315,15 @@ For detail, see the MSDN[http://msdn.mic https://github.com/ruby/ruby/blob/trunk/ext/dl/win32/lib/win32/registry.rb#L315 data = data.encode(WCHAR) size ||= data.size + 1 end - check RegSetValueExW.call(hkey, name.encode(WCHAR), 0, type, data, size) + check RegSetValueExW.call(hkey, make_wstr(name), 0, type, data, size) end def DeleteValue(hkey, name) - check RegDeleteValue.call(hkey, name.encode(WCHAR)) + check RegDeleteValue.call(hkey, make_wstr(name)) end def DeleteKey(hkey, name) - check RegDeleteKey.call(hkey, name.encode(WCHAR)) + check RegDeleteKey.call(hkey, make_wstr(name)) end def FlushKey(hkey) @@ -345,7 +357,11 @@ For detail, see the MSDN[http://msdn.mic https://github.com/ruby/ruby/blob/trunk/ext/dl/win32/lib/win32/registry.rb#L357 # For detail, see expandEnvironmentStrings[http://msdn.microsoft.com/library/en-us/sysinfo/base/expandenvironmentstrings.asp] \Win32 \API. # 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 @@type2name = { } @@ -605,9 +621,9 @@ For detail, see the MSDN[http://msdn.mic https://github.com/ruby/ruby/blob/trunk/ext/dl/win32/lib/win32/registry.rb#L621 end case type when REG_SZ, REG_EXPAND_SZ - [ type, data.encode(name.encoding).rstrip ] + [ type, data.encode(name.encoding, WCHAR).chop ] when REG_MULTI_SZ - [ type, data.encode(name.encoding).split(/\0/) ] + [ type, data.encode(name.encoding, WCHAR).split(/\0/) ] when REG_BINARY [ type, data ] when REG_DWORD Index: ext/fiddle/win32/lib/win32/registry.rb =================================================================== --- ext/fiddle/win32/lib/win32/registry.rb (revision 41855) +++ ext/fiddle/win32/lib/win32/registry.rb (revision 41856) @@ -64,7 +64,8 @@ For detail, see the MSDN[http://msdn.mic https://github.com/ruby/ruby/blob/trunk/ext/fiddle/win32/lib/win32/registry.rb#L64 =end rdoc 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) class Registry @@ -171,9 +172,9 @@ For detail, see the MSDN[http://msdn.mic https://github.com/ruby/ruby/blob/trunk/ext/fiddle/win32/lib/win32/registry.rb#L172 FormatMessageW = Kernel32.extern "int FormatMessageW(int, void *, int, int, void *, int, void *)", :stdcall def initialize(code) @code = code - msg = WCHAR_SPACE * 1024 + msg = WCHAR_NUL * 1024 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 end attr_reader :code @@ -235,6 +236,18 @@ For detail, see the MSDN[http://msdn.mic https://github.com/ruby/ruby/blob/trunk/ext/fiddle/win32/lib/win32/registry.rb#L236 raise Error, result, caller(1) if result != 0 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) [dw].pack('V') end @@ -253,48 +266,47 @@ For detail, see the MSDN[http://msdn.mic https://github.com/ruby/ruby/blob/trunk/ext/fiddle/win32/lib/win32/registry.rb#L266 (qw[1] << 32) | qw[0] end + def make_wstr(str) + str.encode(WCHAR) + WCHAR_NUL + end + def OpenKey(hkey, name, opt, desired) - result = packdw(0) - check RegOpenKeyExW.call(hkey, name.encode(WCHAR), opt, desired, result) - unpackdw(result) + result = packhandle(0) + check RegOpenKeyExW.call(hkey, make_wstr(name), opt, desired, result) + unpackhandle(result) end def CreateKey(hkey, name, opt, desired) - result = packdw(0) + result = packhandle(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) - [ unpackdw(result), unpackdw(disp) ] + [ unpackhandle(result), unpackdw(disp) ] end def EnumValue(hkey, index) - name = WCHAR_SPACE * Constants::MAX_KEY_LENGTH + name = WCHAR_NUL * Constants::MAX_KEY_LENGTH size = packdw(Constants::MAX_KEY_LENGTH) check RegEnumValueW.call(hkey, index, name, size, 0, 0, 0, 0) - name[0, unpackdw(size)].encode + name[0, unpackdw(size)/WCHAR_SIZE].encode end def EnumKey(hkey, index) - name = WCHAR_SPACE * Constants::MAX_KEY_LENGTH + name = WCHAR_NUL * Constants::MAX_KEY_LENGTH size = packdw(Constants::MAX_KEY_LENGTH) wtime = ' ' * 8 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 def QueryValue(hkey, name) - prev_gc = GC.disable - begin - type = packdw(0) - size = packdw(0) - name = name.encode(WCHAR) - check RegQueryValueExW.call(hkey, name, 0, type, 0, size) - data = WCHAR_SPACE * 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 + type = packdw(0) + size = packdw(0) + name = make_wstr(name) + check RegQueryValueExW.call(hkey, name, 0, type, 0, size) + data = "\0".force_encoding('ASCII-8BIT') * unpackdw(size) + check RegQueryValueExW.call(hkey, name, 0, type, data, size) + [ unpackdw(type), data[0, unpackdw(size)] ] end def SetValue(hkey, name, type, data, size) @@ -303,15 +315,15 @@ For detail, see the MSDN[http://msdn.mic https://github.com/ruby/ruby/blob/trunk/ext/fiddle/win32/lib/win32/registry.rb#L315 data = data.encode(WCHAR) size ||= data.size + 1 end - check RegSetValueExW.call(hkey, name.encode(WCHAR), 0, type, data, size) + check RegSetValueExW.call(hkey, make_wstr(name), 0, type, data, size) end def DeleteValue(hkey, name) - check RegDeleteValue.call(hkey, name.encode(WCHAR)) + check RegDeleteValue.call(hkey, make_wstr(name)) end def DeleteKey(hkey, name) - check RegDeleteKey.call(hkey, name.encode(WCHAR)) + check RegDeleteKey.call(hkey, make_wstr(name)) end def FlushKey(hkey) @@ -345,7 +357,11 @@ For detail, see the MSDN[http://msdn.mic https://github.com/ruby/ruby/blob/trunk/ext/fiddle/win32/lib/win32/registry.rb#L357 # For detail, see expandEnvironmentStrings[http://msdn.microsoft.com/library/en-us/sysinfo/base/expandenvironmentstrings.asp] \Win32 \API. # 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 @@type2name = { } @@ -605,9 +621,9 @@ For detail, see the MSDN[http://msdn.mic https://github.com/ruby/ruby/blob/trunk/ext/fiddle/win32/lib/win32/registry.rb#L621 end case type when REG_SZ, REG_EXPAND_SZ - [ type, data.encode(name.encoding).rstrip ] + [ type, data.encode(name.encoding, WCHAR).chop ] when REG_MULTI_SZ - [ type, data.encode(name.encoding).split(/\0/) ] + [ type, data.encode(name.encoding, WCHAR).split(/\0/) ] when REG_BINARY [ type, data ] when REG_DWORD -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/