def self.stat(path)
bytes_avail = FFI::MemoryPointer.new(:ulong_long)
bytes_free = FFI::MemoryPointer.new(:ulong_long)
total_bytes = FFI::MemoryPointer.new(:ulong_long)
mpoint = mount_point(path).to_s
mpoint << '/' unless mpoint.end_with?('/')
wpath = path.to_s.wincode
unless GetDiskFreeSpaceExW(wpath, bytes_avail, total_bytes, bytes_free)
raise SystemCallError.new('GetDiskFreeSpaceEx', FFI.errno)
end
bytes_avail = bytes_avail.read_ulong_long
bytes_free = bytes_free.read_ulong_long
total_bytes = total_bytes.read_ulong_long
sectors_ptr = FFI::MemoryPointer.new(:ulong_long)
bytes_ptr = FFI::MemoryPointer.new(:ulong_long)
free_ptr = FFI::MemoryPointer.new(:ulong_long)
total_ptr = FFI::MemoryPointer.new(:ulong_long)
unless GetDiskFreeSpaceW(wpath, sectors_ptr, bytes_ptr, free_ptr, total_ptr)
raise SystemCallError.new('GetDiskFreeSpace', FFI.errno)
end
sectors_per_cluster = sectors_ptr.read_ulong_long
bytes_per_sector = bytes_ptr.read_ulong_long
free_ptr.free
total_ptr.free
block_size = sectors_per_cluster * bytes_per_sector
blocks_avail = bytes_avail / block_size
blocks_free = bytes_free / block_size
total_blocks = total_bytes / block_size
vol_name_ptr = FFI::MemoryPointer.new(:char, MAXPATH)
base_type_ptr = FFI::MemoryPointer.new(:char, MAXPATH)
vol_serial_ptr = FFI::MemoryPointer.new(:ulong)
name_max_ptr = FFI::MemoryPointer.new(:ulong)
flags_ptr = FFI::MemoryPointer.new(:ulong)
bool = GetVolumeInformationW(
mpoint.wincode,
vol_name_ptr,
vol_name_ptr.size,
vol_serial_ptr,
name_max_ptr,
flags_ptr,
base_type_ptr,
base_type_ptr.size
)
unless bool
raise SystemCallError.new('GetVolumeInformation', FFI.errno)
end
vol_serial = vol_serial_ptr.read_ulong
name_max = name_max_ptr.read_ulong
flags = flags_ptr.read_ulong
base_type = base_type_ptr.read_string(base_type_ptr.size).tr(0.chr, '')
vol_name_ptr.free
vol_serial_ptr.free
name_max_ptr.free
flags_ptr.free
base_type_ptr.free
sectors_ptr.free
bytes_ptr.free
stat_obj = Stat.new
stat_obj.instance_variable_set(:@path, path)
stat_obj.instance_variable_set(:@block_size, block_size)
stat_obj.instance_variable_set(:@blocks, total_blocks)
stat_obj.instance_variable_set(:@blocks_available, blocks_avail)
stat_obj.instance_variable_set(:@blocks_free, blocks_free)
stat_obj.instance_variable_set(:@name_max, name_max)
stat_obj.instance_variable_set(:@base_type, base_type)
stat_obj.instance_variable_set(:@flags, flags)
stat_obj.instance_variable_set(:@filesystem_id, vol_serial)
stat_obj.instance_variable_set(:@bytes_free, bytes_free)
stat_obj.instance_variable_set(:@bytes_available, bytes_avail)
stat_obj.freeze
end