@@ -178,16 +178,30 @@ def write_value
178178 raise error
179179 end
180180
181+ def wide_string_to_bytes ( data )
182+ bytes = Puppet ::Util ::Windows ::String . wide_string ( data ) . bytes . to_a
183+ # versions prior to 7 embedded a wide null in the string content to work
184+ # around ruby bugs, see PUP-3970
185+ if Puppet ::PUPPETVERSION [ 0 ] . to_i >= 7
186+ bytes << 0 << 0
187+ else
188+ bytes
189+ end
190+ end
191+
192+ # This method must include wide null terminators in the returned
193+ # byte array for string-based registry values like REG_SZ. In
194+ # addition REG_MULTI_SZ must append another wide null character
195+ # to signify there are no more entries in the array.
181196 def data_to_bytes ( type , data )
182197 bytes = [ ]
183198
184199 case type
185200 when Win32 ::Registry ::REG_SZ , Win32 ::Registry ::REG_EXPAND_SZ
186- bytes = Puppet :: Util :: Windows :: String . wide_string ( data ) . bytes . to_a
201+ bytes = wide_string_to_bytes ( data )
187202 when Win32 ::Registry ::REG_MULTI_SZ
188- # each wide string is already NULL terminated
189- bytes = data . map { |s | Puppet ::Util ::Windows ::String . wide_string ( s ) . bytes . to_a } . flat_map { |a | a }
190- # requires an additional NULL terminator to terminate properly
203+ bytes = data . map { |s | wide_string_to_bytes ( s ) } . flat_map { |a | a }
204+ # requires an additional wide NULL terminator
191205 bytes << 0 << 0
192206 when Win32 ::Registry ::REG_BINARY
193207 bytes = data . bytes . to_a
@@ -209,6 +223,8 @@ def write(reg, _name, type, data)
209223 bytes = data_to_bytes ( type , data )
210224 FFI ::MemoryPointer . new ( :uchar , bytes . length ) do |data_ptr |
211225 data_ptr . write_array_of_uchar ( bytes )
226+ # From https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regsetvalueexw
227+ # "cbData must include the size of the terminating null character or characters"
212228 if RegSetValueExW ( reg . hkey , name_ptr , 0 ,
213229 type , data_ptr , data_ptr . size ) != 0
214230 raise Puppet ::Util ::Windows ::Error , 'Failed to write registry value'
0 commit comments