# File lib/win32/file/stat.rb, line 50
   def initialize(file)
      @file = file
      
      @file_type = get_file_type(file)
      @chardev = @file_type == FILE_TYPE_CHAR

      case GetDriveType(file)
         when DRIVE_REMOVABLE, DRIVE_CDROM, DRIVE_RAMDISK
            @blockdev = true
         else
            @blockdev = false
      end

      stat_buf = [0,0,0,0,0,0,0,0,0,0,0,0,0].pack('ISSssssIIQQQQ')
      
      # The stat64 function doesn't seem to like character devices
      if stat64(file, stat_buf) != 0
          raise ArgumentError, get_last_error unless @chardev
      end

      # Some bytes skipped (padding for struct alignment)
      @dev   = stat_buf[0, 4].unpack('I').first  # Drive number
      @ino   = stat_buf[4, 2].unpack('S').first  # Meaningless
      @mode  = stat_buf[6, 2].unpack('S').first  # File mode bit mask
      @nlink = stat_buf[8, 2].unpack('s').first  # Always 1
      @uid   = stat_buf[10, 2].unpack('s').first # Always 0
      @gid   = stat_buf[12, 2].unpack('s').first # Always 0
      @rdev  = stat_buf[16, 4].unpack('I').first # Same as dev
      @size  = stat_buf[24, 8].unpack('Q').first # Size of file in bytes
      
      # This portion can fail in rare, FS related instances. If it does, set
      # the various times to Time.at(0).
      begin
         @atime = Time.at(stat_buf[32, 8].unpack('Q').first) # Access time
         @mtime = Time.at(stat_buf[40, 8].unpack('Q').first) # Mod time
         @ctime = Time.at(stat_buf[48, 8].unpack('Q').first) # Creation time
      rescue
         @atime = Time.at(0)
         @mtime = Time.at(0)
         @ctime = Time.at(0)
      end
      
      @mode = 33188 if @chardev

      attr = GetFileAttributes(file)
      error_num = GetLastError()
      
      # Ignore errors caused by empty/open/used block devices.
      if attr == INVALID_FILE_ATTRIBUTES
         unless error_num == ERROR_NOT_READY
            raise ArgumentError, get_last_error(error_num)
         end
      end
      
      @blksize = get_blksize(file)
      
      # This is a reasonable guess
      case @blksize
         when nil
            @blocks = nil
         when 0
            @blocks = 0
         else
            @blocks  = (@size.to_f / @blksize.to_f).ceil
      end
      
      @readonly      = attr & FILE_ATTRIBUTE_READONLY > 0
      @hidden        = attr & FILE_ATTRIBUTE_HIDDEN > 0
      @system        = attr & FILE_ATTRIBUTE_SYSTEM > 0
      @archive       = attr & FILE_ATTRIBUTE_ARCHIVE > 0
      @directory     = attr & FILE_ATTRIBUTE_DIRECTORY > 0
      @encrypted     = attr & FILE_ATTRIBUTE_ENCRYPTED > 0
      @normal        = attr & FILE_ATTRIBUTE_NORMAL > 0
      @temporary     = attr & FILE_ATTRIBUTE_TEMPORARY > 0
      @sparse        = attr & FILE_ATTRIBUTE_SPARSE_FILE > 0
      @reparse_point = attr & FILE_ATTRIBUTE_REPARSE_POINT > 0
      @compressed    = attr & FILE_ATTRIBUTE_COMPRESSED > 0
      @offline       = attr & FILE_ATTRIBUTE_OFFLINE > 0
      @indexed       = attr & ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED > 0
      
      @executable = GetBinaryType(file, '')
      @regular    = @file_type == FILE_TYPE_DISK
      @pipe       = @file_type == FILE_TYPE_PIPE
      
      # Not supported and/or meaningless
      @dev_major     = nil
      @dev_minor     = nil
      @grpowned      = true
      @owned         = true
      @readable      = true
      @readable_real = true
      @rdev_major    = nil
      @rdev_minor    = nil
      @setgid        = false
      @setuid        = false
      @sticky        = false
      @symlink       = false
      @writable      = true
      @writable_real = true
   end