Skip to content

Instantly share code, notes, and snippets.

@djberg96
Last active July 10, 2023 13:43
Show Gist options
  • Save djberg96/177bfba94d497217a7d869e09309497b to your computer and use it in GitHub Desktop.
Save djberg96/177bfba94d497217a7d869e09309497b to your computer and use it in GitHub Desktop.
# You will need Ruby on a Windows machine. Plus the ffi library.
require 'ffi'
class File::Temp
extend FFI::Library
ffi_lib :kernel32
attach_function :GetTempFileNameA, %i[string string uint buffer_out], :uint
attach_function :GetTempFileNameW, %i[buffer_in buffer_in uint buffer_out], :uint
def tmpfile_a
# Update as needed
file_name = "C:\\Users\\DANIEL~1\\AppData\\Local\\Temp"
buf = 0.chr * 1024
prefix = 'rb_'
if GetTempFileNameA(file_name, prefix, 0, buf) == 0
raise SystemCallError, FFI.errno, 'GetTempFileNameW'
end
file_name = buf.strip
end
def tmpfile_w
# Update as needed
file_name = "C:\\Users\\DANIEL~1\\AppData\\Local\\Temp"
buf = 0.chr * 1024
buf.encode!('UTF-16LE')
prefix = 'rb_'
prefix.encode!('UTF-16LE')
# I suspect "buf" is the culprit but I'm not sure what to do about it. But then
# why doesn't it blow up in the "A" version? Hmm...
if GetTempFileNameW(file_name, prefix, 0, buf) == 0
raise SystemCallError, FFI.errno, 'GetTempFileNameW'
end
file_name = buf.strip
end
end
puts "Starting A version" # This works
threads_a = []
20.times{ threads_a << Thread.new{ p File::Temp.new.tmpfile_a } }
threads_a.each(&:join)
puts "Done with A version"
puts "Starting W version" # This blows up
threads_a = []
20.times{ threads_a << Thread.new{ p File::Temp.new.tmpfile_w } }
threads_a.each(&:join)
puts "Done with W version"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment