I’m porting some code from Linux to Windows which relies on direct
access to a CD’s block device. This “just works” on Linux if I
File.open("/dev/cdrom"), but I can’t see how to make it work on Windows.
While manually running a dl/imported CreateFile works and gives me a
valid handle, just running File.open("\\.\D:", “r”) crashes the
interpreter (1.9.3-p0), as does IO.sysopen.
Is there a built-in way to turn an open handle into a File object? I
blindly tried IO.for_fd, but that fails and I got no further.
Here’s the code I’ve tried (and yes, there is a CD in the drive ):
require 'dl/import' DriveTypes = [:unknown, :no_root_dir, :removable, :fixed, :remote, :cdrom, :ramdisk] module Kernel32 def self.stdcall(fn); extern fn, :stdcall; end extend DL::Importer dlload "kernel32.dll" stdcall "uint GetDriveType( void * )" stdcall "long CreateFile( void *, long, long, void *, long, long,
stdcall “int CloseHandle( long )”
case DriveTypes[Kernel32.GetDriveType( "D:\\" )] when :cdrom handle = Kernel32.CreateFile( "\\\\.\\D:", 0, 3, 0, 3, 128, 0 ) if handle == -1 puts "O NOES" else puts "Ok" Kernel32.CloseHandle( handle ) end else puts "Not a CD" end
This prints “Ok”, so I know that the handle I’m getting back is at least
valid from Windows’ point of view.