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