@@ -182,6 +182,15 @@ reg_value(VALUE self, VALUE name)
182182 e = RegGetValueW (hkey , NULL , wname , RRF_RT_ANY , & type , NULL , & size );
183183 if (e == ERROR_FILE_NOT_FOUND ) return Qnil ;
184184 w32error_check (e );
185+ # define get_value_2nd (data , dsize ) do { \
186+ DWORD type2 = type; \
187+ w32error_check(RegGetValueW(hkey, NULL, wname, RRF_RT_ANY, &type2, data, dsize)); \
188+ if (type != type2) { \
189+ rb_raise(rb_eRuntimeError, "registry value type changed %lu -> %lu", \
190+ (unsigned long)type, (unsigned long)type2); \
191+ } \
192+ } while (0)
193+
185194 switch (type ) {
186195 case REG_DWORD : case REG_DWORD_BIG_ENDIAN :
187196 {
@@ -201,30 +210,30 @@ reg_value(VALUE self, VALUE name)
201210 case REG_SZ : case REG_MULTI_SZ : case REG_EXPAND_SZ :
202211 if (size % sizeof (WCHAR )) rb_raise (rb_eRuntimeError , "invalid size returned: %lu" , (unsigned long )size );
203212 buffer = ALLOCV_N (char , value_buffer , size );
213+ get_value_2nd (buffer , & size );
214+ if (type == REG_MULTI_SZ ) {
215+ const WCHAR * w = (WCHAR * )buffer ;
216+ result = rb_ary_new ();
217+ size /= sizeof (WCHAR );
218+ size -= 1 ;
219+ for (size_t i = 0 ; i < size ; ++ i ) {
220+ int n = lstrlenW (w + i );
221+ rb_ary_push (result , wchar_to_utf8 (w + i , n ));
222+ i += n ;
223+ }
224+ }
225+ else {
226+ result = wchar_to_utf8 ((WCHAR * )buffer , lstrlenW ((WCHAR * )buffer ));
227+ }
228+ ALLOCV_END (value_buffer );
204229 break ;
205230 default :
206231 result = rb_str_new (0 , size );
207- buffer = RSTRING_PTR (result );
208- }
209- w32error_check (RegGetValueW (hkey , NULL , wname , RRF_RT_ANY , & type , buffer , & size ));
210- switch (type ) {
211- case REG_MULTI_SZ : {
212- const WCHAR * w = (WCHAR * )buffer ;
213- result = rb_ary_new ();
214- size /= sizeof (WCHAR );
215- size -= 1 ;
216- for (size_t i = 0 ; i < size ; ++ i ) {
217- int n = lstrlenW (w + i );
218- rb_ary_push (result , wchar_to_utf8 (w + i , n ));
219- i += n ;
220- }
221- return result ;
222- }
223- case REG_SZ : case REG_EXPAND_SZ :
224- return wchar_to_utf8 ((WCHAR * )buffer , lstrlenW ((WCHAR * )buffer ));
225- default :
226- return result ;
232+ get_value_2nd (RSTRING_PTR (result ), & size );
233+ rb_str_set_len (result , size );
234+ break ;
227235 }
236+ return result ;
228237}
229238
230239void
0 commit comments