require 'windows/error'
require 'windows/filesystem'
require 'windows/volume'
module Sys
class Filesystem
extend Windows::Error
extend Windows::FileSystem
extend Windows::Volume
# Error raised if any of the Windows API functions fail.
class Error < StandardError; end
VERSION = '0.1.0'
class Stat
CASE_SENSITIVE_SEARCH = 0x00000001
CASE_PRESERVED_NAMES = 0x00000002
UNICODE_ON_DISK = 0x00000004
PERSISTENT_ACLS = 0x00000008
FILE_COMPRESSION = 0x00000010
VOLUME_QUOTAS = 0x00000020
SUPPORTS_SPARSE_FILES = 0x00000040
SUPPORTS_REPARSE_POINTS = 0x00000080
SUPPORTS_REMOTE_STORAGE = 0x00000100
VOLUME_IS_COMPRESSED = 0x00008000
SUPPORTS_OBJECT_IDS = 0x00010000
SUPPORTS_ENCRYPTION = 0x00020000
NAMED_STREAMS = 0x00040000
READ_ONLY_VOLUME = 0x00080000
# The path of the file system.
attr_reader :path
# The file system block size. MS Windows typically defaults to 4096.
attr_reader :block_size
# Fragment size. Meaningless at the moment.
attr_reader :fragment_size
# The total number of blocks available (used or unused) on the file
# system.
attr_reader :blocks
# The total number of unused blocks.
attr_reader :blocks_free
# The total number of unused blocks available to unprivileged
# processes. Identical to +blocks+ at the moment.
attr_reader :blocks_available
# Total number of files/inodes that can be created on the file system.
# This attribute is always nil on MS Windows.
attr_reader :files
# Total number of free files/inodes that can be created on the file
# system. This attribute is always nil on MS Windows.
attr_reader :files_free
# Total number of available files/inodes for unprivileged processes
# that can be created on the file system. This attribute is always
# nil on MS Windows.
attr_reader :files_available
# The file system volume id.
attr_reader :filesystem_id
# A bit mask of file system flags.
attr_reader :flags
# The maximum length of a file name permitted on the file system.
attr_reader :name_max
# The file system type, e.g. NTFS, FAT, etc.
attr_reader :base_type
alias inodes files
alias inodes_free files_free
alias inodes_available files_available
end
# Returns a Filesystem::Stat object that contains information about the
# +path+ file system.
#
def self.stat(path)
bytes_avail = [0].pack('Q')
bytes_free = [0].pack('Q')
total_bytes = [0].pack('Q')
unless GetDiskFreeSpaceEx(path, bytes_avail, total_bytes, bytes_free)
raise Error, get_last_error
end
bytes_avail = bytes_avail.unpack('Q').first
bytes_free = bytes_free.unpack('Q').first
total_bytes = total_bytes.unpack('Q').first
sectors = [0].pack('Q')
bytes = [0].pack('Q')
free = [0].pack('Q')
total = [0].pack('Q')
unless GetDiskFreeSpace(path, sectors, bytes, free, total)
raise Error, get_last_error
end
sectors = sectors.unpack('Q').first
bytes = bytes.unpack('Q').first
free = free.unpack('Q').first
total = total.unpack('Q').first
block_size = sectors * bytes
blocks_avail = total_bytes / block_size
blocks_free = bytes_free / block_size
vol_name = 0.chr * 260
base_type = 0.chr * 260
vol_serial = [0].pack('L')
name_max = [0].pack('L')
flags = [0].pack('L')
bool = GetVolumeInformation(
path,
vol_name,
vol_name.size,
vol_serial,
name_max,
flags,
base_type,
base_type.size
)
unless bool
raise Error, get_last_error
end
vol_serial = vol_serial.unpack('L').first
name_max = name_max.unpack('L').first
flags = flags.unpack('L').first
base_type = base_type[/^[^\0]*/]
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, blocks_avail)
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.freeze # Read-only object
end
end
end
# Some convenient methods for converting bytes to kb, mb, and gb.
#
class Fixnum
# call-seq:
# fix.to_kb
#
# Returns +fix+ in terms of kilobytes.
def to_kb
self / 1024
end
# call-seq:
# fix.to_mb
#
# Returns +fix+ in terms of megabytes.
def to_mb
self / 1048576
end
# call-seq:
# fix.to_gb
#
# Returns +fix+ in terms of gigabytes.
def to_gb
self / 1073741824
end
end